CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_2_9_HLT1_bphpatch4/src/RecoEgamma/EgammaPhotonAlgos/src/OutInConversionSeedFinder.cc

Go to the documentation of this file.
00001 #include "RecoEgamma/EgammaPhotonAlgos/interface/OutInConversionSeedFinder.h"
00002 #include "RecoEgamma/EgammaPhotonAlgos/interface/ConversionBarrelEstimator.h"
00003 #include "RecoEgamma/EgammaPhotonAlgos/interface/ConversionForwardEstimator.h"
00004 //
00005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00006 // Field
00007 #include "MagneticField/Engine/interface/MagneticField.h"
00008 //
00009 #include "DataFormats/CLHEP/interface/AlgebraicObjects.h"
00010 // Geometry
00011 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00012 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00013 //
00014 #include "TrackingTools/TrajectoryParametrization/interface/GlobalTrajectoryParameters.h"
00015 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00016 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00017 #include "TrackingTools/MeasurementDet/interface/LayerMeasurements.h"
00018 //
00019 #include "RecoTracker/TkDetLayers/interface/GeometricSearchTracker.h" 
00020 #include "RecoTracker/MeasurementDet/interface/MeasurementTracker.h"
00021 
00022 //
00023 #include "CLHEP/Units/GlobalPhysicalConstants.h"
00024 #include "CLHEP/Geometry/Point3D.h"
00025 #include "CLHEP/Geometry/Vector3D.h" 
00026  #include "CLHEP/Geometry/Transform3D.h"  
00027 #include <cfloat>
00028 
00029 
00030 OutInConversionSeedFinder::OutInConversionSeedFinder( const edm::ParameterSet& conf ): ConversionSeedFinder( conf ), conf_(conf)  
00031 {
00032 
00033   LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder CTOR " << "\n";      
00034 
00035   maxNumberOfOutInSeedsPerBC_ =  conf_.getParameter<int>("maxNumOfSeedsOutIn");
00036    //the2ndHitdphi_ = 0.01; 
00037   the2ndHitdphi_ = 0.03; 
00038   the2ndHitdzConst_ = 5.;
00039   the2ndHitdznSigma_ = 2.;
00040 
00041    
00042     
00043 }
00044  
00045 
00046 
00047 
00048 OutInConversionSeedFinder::~OutInConversionSeedFinder() {
00049   LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder DTOR " << "\n";
00050  
00051 }
00052 
00053 
00054 
00055 void OutInConversionSeedFinder::makeSeeds( const edm::Handle<edm::View<reco::CaloCluster> > &  allBC )  const  {
00056 
00057   theSeeds_.clear();
00058   
00059   //  std::cout  << "  OutInConversionSeedFinder::makeSeeds() " << "\n";
00060 
00061   // debug  
00062   //  std::cout << "  OutInConversionSeedFinder::makeSeeds() SC position " << theSCPosition_.x() << " " << theSCPosition_.y() << " " << theSCPosition_.z() << "\n";
00063   // std::cout << " SC eta  " <<  theSCPosition_.eta() <<  " SC phi  " <<  theSCPosition_.phi() << "\n";  
00064   // std::cout << "  OutInConversionSeedFinder::makeSeeds() SC energy " << theSCenergy_  << "\n";  
00065   //
00066 
00067   findLayers();
00068 
00069   
00070   //  std::cout  << " Check Calo cluster collection size " << allBC->size() << "\n";
00071   
00072   float  theSCPhi=theSCPosition_.phi();
00073   float  theSCEta=theSCPosition_.eta();
00074 
00075   
00076 
00077   //  Loop over the Calo Clusters  in the event looking for seeds 
00078   reco::CaloClusterCollection::const_iterator bcItr;
00079   LogDebug("OutInConversionSeedFinder") << "  OutInConversionSeedFinder::makeSeeds() All BC in the event " << "\n";
00080   for (unsigned i = 0; i < allBC->size(); ++i ) {
00081   
00082     //for(bcItr = allBC.begin(); bcItr != allBC.end(); bcItr++) {
00083     nSeedsPerBC_=0;
00084 
00085     theBCEnergy_=allBC->ptrAt(i)->energy();
00086     theBCPosition_ = GlobalPoint(allBC->ptrAt(i)->position().x(), allBC->ptrAt(i)->position().y(), allBC->ptrAt(i)->position().z() ) ;
00087     float theBcEta=  theBCPosition_.eta();
00088     float theBcPhi=  theBCPosition_.phi();
00089     //    float  dPhi= theBcPhi-theSCPhi;
00090 
00091     //    std::cout << "  OutInConversionSeedFinder::makeSeeds() BC eta  " << theBcEta << " phi " <<  theBcPhi << " BC energy " << theBCEnergy_ << " dPhi " << fabs(theBcPhi-theSCPhi) << " dEta " <<  fabs(theBcEta-theSCEta) << "\n";
00092     
00093     if ( theBCEnergy_ < 1.5 ) continue;
00094 
00095     LogDebug("OutInConversionSeedFinder") << "  OutInConversionSeedFinder::makeSeeds() Passing the >=1.5 GeV cut  BC eta  " << theBcEta << " phi " <<  theBcPhi << " BC energy " << theBCEnergy_ << "\n";
00096 
00097     if (  fabs(theBcEta-theSCEta) < 0.015  && fabs(theBcPhi-theSCPhi) < 0.3 ) { 
00098       LogDebug("OutInConversionSeedFinder") << "  OutInConversionSeedFinder::makeSeeds() in et and phi range passed to the analysis " << "\n";
00099       fillClusterSeeds( allBC->ptrAt(i)  );
00100     }
00101     
00102 
00103   }
00104 
00105 
00106   //  std::cout << "Built vector of seeds of size  " << theSeeds_.size() <<  "\n" ;
00107   
00109   /*
00110   int nSeed=0;
00111   for ( std::vector<TrajectorySeed>::const_iterator iSeed= theSeeds_.begin(); iSeed != theSeeds_.end(); ++iSeed) {
00112     nSeed++;
00113     PTrajectoryStateOnDet  ptsod=iSeed->startingState();
00114     LogDebug("OutInConversionSeedFinder") << nSeed << ")  Direction " << iSeed->direction() << " Num of hits " << iSeed->nHits() <<  " starting state position " << ptsod.parameters().position() << " R " << ptsod.parameters().position().perp() << " phi " << ptsod.parameters().position().phi() << " eta " << ptsod.parameters().position().eta() << "\n" ;
00115     
00116     
00117     DetId tmpId = DetId( iSeed->startingState().detId());
00118     const GeomDet* tmpDet  = this->getMeasurementTracker()->geomTracker()->idToDet( tmpId );
00119     GlobalVector gv = tmpDet->surface().toGlobal( iSeed->startingState().parameters().momentum() );
00120     
00121     LogDebug("OutInConversionSeedFinder") << "seed perp,phi,eta : " 
00122                                           << gv.perp() << " , " 
00123                                           << gv.phi() << " , " 
00124                                           << gv.eta() << "\n" ; ;
00125     
00126 
00127 
00128 
00129     TrajectorySeed::range hitRange = iSeed->recHits();
00130     for (TrajectorySeed::const_iterator ihit = hitRange.first; ihit != hitRange.second; ihit++) {
00131    
00132       if ( ihit->isValid() ) {
00133 
00134         LogDebug("OutInConversionSeedFinder") << " Valid hit global position " << this->getMeasurementTracker()->geomTracker()->idToDet((ihit)->geographicalId())->surface().toGlobal((ihit)->localPosition()) << " R " << this->getMeasurementTracker()->geomTracker()->idToDet((ihit)->geographicalId())->surface().toGlobal((ihit)->localPosition()).perp() << " phi " << this->getMeasurementTracker()->geomTracker()->idToDet((ihit)->geographicalId())->surface().toGlobal((ihit)->localPosition()).phi() << " eta " << this->getMeasurementTracker()->geomTracker()->idToDet((ihit)->geographicalId())->surface().toGlobal((ihit)->localPosition()).eta() <<    "\n" ;
00135 
00136       }
00137     }
00138   } 
00139   
00140   */
00141 
00142   
00143   
00144 }
00145 
00146 
00147 
00148 void OutInConversionSeedFinder::makeSeeds( const reco::CaloClusterPtr&  aBC )  const  {
00149 
00150   theSeeds_.clear();
00151 
00152   findLayers();
00153 
00154   float  theSCPhi=theSCPosition_.phi();
00155   float  theSCEta=theSCPosition_.eta();
00156 
00157   nSeedsPerBC_=0;
00158 
00159   theBCEnergy_=aBC->energy();
00160   theBCPosition_ = GlobalPoint(aBC->position().x(), aBC->position().y(), aBC->position().z() ) ;
00161   float theBcEta=  theBCPosition_.eta();
00162   float theBcPhi=  theBCPosition_.phi();
00163   //  float  dPhi= theBcPhi-theSCPhi;
00164 
00165   if ( theBCEnergy_ < 1.5 ) return;
00166 
00167   if (  fabs(theBcEta-theSCEta) < 0.015  && fabs(theBcPhi-theSCPhi) < 0.25 ) {
00168     fillClusterSeeds( aBC);
00169   }
00170 
00171 }
00172 
00173 
00174  
00175 
00176 
00177 void OutInConversionSeedFinder::fillClusterSeeds(const reco::CaloClusterPtr& bc) const {
00178 
00179   
00180   theFirstMeasurements_.clear();
00181   FreeTrajectoryState fts;  
00182 
00184   if ( makeTrackState(-1).second ) {
00185     fts = makeTrackState(-1).first;
00186     startSeed(fts);
00187   }
00189 
00190   if ( makeTrackState(1).second ) {
00191     fts = makeTrackState(1).first;
00192     startSeed(fts);
00193   }
00194   theFirstMeasurements_.clear();
00195 }
00196 
00197 
00198 
00199 std::pair<FreeTrajectoryState,bool>  OutInConversionSeedFinder::makeTrackState(int  charge) const {
00200 
00201   std::pair<FreeTrajectoryState,bool> result;
00202   result.second=false;
00203  
00204 
00205   //std::cout << "  OutInConversionSeedFinder:makeTrackState " << "\n";
00206 
00207 
00208   //  Old GlobalPoint gpOrigine(theBCPosition_.x()*0.3, theBCPosition_.y()*0.3, theBCPosition_.z()*0.3) ;
00209  //  GlobalPoint gpOrigine(0.,0.,0.);
00210 
00211   GlobalPoint  gpOrigine(theBeamSpot_.position().x(),theBeamSpot_.position().y(),theBeamSpot_.position().z()); 
00212   GlobalVector gvBcRadius = theBCPosition_ - gpOrigine ;
00213   HepGeom::Point3D<double>  radiusBc(gvBcRadius.x(),gvBcRadius.y(),gvBcRadius.z()) ;
00214   HepGeom::Point3D<double>  momentumWithoutCurvature = radiusBc.unit() * theBCEnergy_ ;
00215 
00216   // compute momentum direction at calo
00217   double curvature = theMF_->inTesla(theBCPosition_).z() * c_light * 1.e-3 / momentumWithoutCurvature.perp() ;
00218   curvature /= 100. ; // in cm-1 !!
00219 
00220   LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::makeTrackState gpOrigine " << gpOrigine.x() << " " <<  gpOrigine.y() << " " <<  gpOrigine.z() << " momentumWithoutCurvature " << momentumWithoutCurvature.mag() << " curvature " << curvature << "\n";
00221 
00222   // define rotation angle
00223   float R = theBCPosition_.perp();
00224   float r = gpOrigine.perp();
00225   float rho = 1./curvature;
00226   // from the formula for the intersection of two circles
00227   // turns out to be about 2/3 of the deflection of the old formula
00228   float d = sqrt(r*r+rho*rho);
00229   float u = rho + rho/d/d*(R*R-rho*rho) - r/d/d*sqrt((R*R-r*r+2*rho*R)*(R*R-r*r+2*rho*R));
00230   //float u = rho + rho/d/d*(R*R-rho*rho) ;
00231   if ( u <=R )   result.second=true;
00232 
00233   double sinAlpha = 0.5*u/R;
00234   if ( sinAlpha>(1.-10*DBL_EPSILON) )  sinAlpha = 1.-10*DBL_EPSILON;
00235   else if ( sinAlpha<-(1.-10*DBL_EPSILON) )  sinAlpha = -(1.-10*DBL_EPSILON);
00236   
00237   double newdphi = charge * asin( sinAlpha) ;
00238 
00239   LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::makeTrackState charge " << charge << " R " << R << " u/R " << u/R << " asin(0.5*u/R) " << asin(sinAlpha) << "\n";
00240 
00241   HepGeom::Transform3D rotation =  HepGeom::Rotate3D(newdphi, HepGeom::Vector3D<double> (0., 0. ,1.));
00242 
00243 
00244   HepGeom::Point3D<double>  momentumInTracker = momentumWithoutCurvature.transform(rotation) ;
00245   LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::makeTrackState  R " << R << " r " << r << " rho " << rho  << " d " << d  << " u " << u << " newdphi " << newdphi << " momentumInTracker " <<  momentumInTracker << "\n";
00246 
00247   HepGeom::Point3D<double>  hepStartingPoint(gpOrigine.x(), gpOrigine.y(), gpOrigine.z()) ;
00248 
00249   LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::makeTrackState hepStartingPoint " << hepStartingPoint << "\n";
00250 
00251   hepStartingPoint.transform(rotation);
00252 
00253   GlobalPoint startingPoint(hepStartingPoint.x(), hepStartingPoint.y(), hepStartingPoint.z());
00254 
00255   LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::makeTrackState startingPoint " << startingPoint << " calo position " << theBCPosition_ << "\n";
00256   GlobalVector gvTracker(momentumInTracker.x(), momentumInTracker.y(), momentumInTracker.z());
00257   GlobalTrajectoryParameters gtp(startingPoint, gvTracker, charge, &(*theMF_) );
00258   // error matrix
00259   AlgebraicSymMatrix55 m = AlgebraicMatrixID();
00260   m(0,0) = 0.1; m(1,1) = 0.1 ; m(2,2) = 0.1 ;
00261   m(3,3) = 0.1 ; m(4,4) = 0.1;
00262   
00263   //std::cout << "OutInConversionSeedFinder::makeTrackState " <<  FreeTrajectoryState(gtp, CurvilinearTrajectoryError(m) ) << "\n";
00264    
00265   result.first= FreeTrajectoryState(gtp, CurvilinearTrajectoryError(m) ) ;
00266   return result;
00267 
00268 }
00269 
00270 
00271 void OutInConversionSeedFinder::startSeed(const FreeTrajectoryState & fts) const {
00272 
00273 
00274   //  std::cout << "OutInConversionSeedFinder::startSeed layer list " << this->layerList().size() <<  "\n";
00275   //std::cout << "OutInConversionSeedFinder::startSeed  fts " << fts <<  "\n";  
00276 
00277   std::vector<const DetLayer*> myLayers=layerList();
00278   if ( myLayers.size() > 3 ) {
00279     
00280     for(unsigned int ilayer = myLayers.size()-1; ilayer >= myLayers.size()-2; --ilayer) {
00281       const DetLayer * layer = myLayers[ilayer];
00282       
00283       
00284       // allow the z of the hit to be within a straight line from a vertex
00285       // of +-15 cm to the cluster
00286       //      float dphi = 0.015;
00287       float dphi = 0.030;
00288 
00289       MeasurementEstimator * newEstimator = makeEstimator(layer, dphi);
00290 
00291      
00292       //std::cout << "OutInSeedFinder::startSeed propagationDirection  " << int(thePropagatorAlongMomentum_->propagationDirection() ) << "\n";       
00293       
00294       TSOS tsos(fts, layer->surface() );
00295       
00296       LogDebug("OutInConversionSeedFinder") << "OutInSeedFinder::startSeed  after  TSOS tsos(fts, layer->surface() ) " << "\n";
00297       
00298       LayerMeasurements theLayerMeasurements_(this->getMeasurementTracker() );
00299       theFirstMeasurements_ = theLayerMeasurements_.measurements( *layer, tsos, *thePropagatorAlongMomentum_, *newEstimator);
00300       
00301       //std::cout << "OutInSeedFinder::startSeed  after  theFirstMeasurements_   " << theFirstMeasurements_.size() <<  "\n";
00302       
00303       if(theFirstMeasurements_.size() > 1) // always a dummy returned, too
00304         LogDebug("OutInConversionSeedFinder") <<  " Found " << theFirstMeasurements_.size()-1 << " 1st hits in seed" << "\n";
00305       
00306       delete newEstimator;
00307       
00308       LogDebug("OutInConversionSeedFinder") << "OutInSeedFinder::startSeed Layer " << ilayer << " theFirstMeasurements_.size " << theFirstMeasurements_.size() << "\n";
00309       
00310       for(unsigned int i = 0; i < theFirstMeasurements_.size(); ++i) {
00311         TrajectoryMeasurement m1 = theFirstMeasurements_[i];
00312         if(m1.recHit()->isValid()) {
00313           
00314           // update the fts to start from this point.  much better than starting from
00315           // extrapolated point along the line
00316           GlobalPoint hitPoint = m1.recHit()->globalPosition();
00317           LogDebug("OutInConversionSeedFinder")  << " Valid hit at R  " <<   m1.recHit()->globalPosition().perp() << " Z " <<  m1.recHit()->globalPosition().z() << " eta " << m1.recHit()->globalPosition().eta() << " phi " << m1.recHit()->globalPosition().phi()  << " xyz " <<  m1.recHit()->globalPosition() << "\n";
00318 
00319           
00320           FreeTrajectoryState newfts = trackStateFromClusters(fts.charge(), hitPoint, alongMomentum, 0.8);
00321           LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::startSeed  newfts " << newfts << "\n";
00322           LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::startSeed propagationDirection  after switching " << int(thePropagatorOppositeToMomentum_->propagationDirection() ) << "\n";        
00323           //  std::cout << "OutInConversionSeedFinder::startSeed propagationDirection  after switching " << int(thePropagatorOppositeToMomentum_->propagationDirection() ) << "\n";        
00324 
00325        
00326           completeSeed(m1, newfts, thePropagatorOppositeToMomentum_, ilayer-1);
00327           // skip a layer, if you haven't already skipped the first layer
00328           if(ilayer == myLayers.size()-1) {
00329             completeSeed(m1, newfts, thePropagatorOppositeToMomentum_, ilayer-2);
00330           }
00331         }
00332       }
00333       
00334     } // loop over layers
00335   }
00336 
00337 
00338 
00339   
00340 }
00341 
00342 
00343 
00344 MeasurementEstimator * OutInConversionSeedFinder::makeEstimator(const DetLayer * layer, float dphi) const {
00345  
00346   //std::cout  << "OutInConversionSeedFinder::makeEstimator  " << "\n";
00347 
00348   MeasurementEstimator * newEstimator=0;
00349 
00350   if (layer->location() == GeomDetEnumerators::barrel ) {
00351     
00352     const BarrelDetLayer * barrelLayer = dynamic_cast<const BarrelDetLayer*>(layer);
00353     LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::makeEstimator Barrel  r = " << barrelLayer->specificSurface().radius() << " " << "\n";        
00354     float r = barrelLayer->specificSurface().radius();
00355     float zrange = 15.* (1.-r/theBCPosition_.perp());
00356     newEstimator = new ConversionBarrelEstimator(-dphi, dphi, -zrange, zrange);
00357   }
00358 
00359 
00360 
00361   if (layer->location() == GeomDetEnumerators::endcap ) {   
00362    
00363     const ForwardDetLayer * forwardLayer = dynamic_cast<const ForwardDetLayer*>(layer);
00364     LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::makeEstimator Endcap r = " << forwardLayer->specificSurface().innerRadius() << " R " << forwardLayer->specificSurface().outerRadius()  <<  " Z " << forwardLayer->specificSurface().position().z() << "\n";  
00365     
00366     float zc = fabs(theBCPosition_.z());
00367     float z =  fabs(forwardLayer->surface().position().z());
00368     
00369     float rrange = 15. * theBCPosition_.perp() * (zc - z) / (zc*zc - 15.*zc);
00370     newEstimator = new ConversionForwardEstimator(-dphi, dphi, rrange);
00371   }
00372 
00373 
00374 
00375 
00376   return newEstimator;
00377 }
00378 
00379 
00380 
00381 
00382 void OutInConversionSeedFinder::completeSeed(const TrajectoryMeasurement & m1, 
00383                                              FreeTrajectoryState & fts, 
00384                                              const Propagator* propagator, int ilayer) const {
00385 
00386   //std::cout <<  "OutInConversionSeedFinder::completeSeed ilayer " << ilayer << "\n";
00387 
00388   MeasurementEstimator * newEstimator=0;
00389   const DetLayer * layer = theLayerList_[ilayer];
00390   
00391 
00392   if ( layer->location() == GeomDetEnumerators::barrel ) {
00393     // z error for 2nd hit is  2 sigma quadded with 5 cm
00394     LogDebug("OutInConversionSeedFinder") << " Barrel OutInConversionSeedFinder::completeSeed " << the2ndHitdznSigma_ << " " << the2ndHitdzConst_ << " " << the2ndHitdphi_ << "\n";
00395     float dz = sqrt(the2ndHitdznSigma_*the2ndHitdznSigma_*m1.recHit()->globalPositionError().czz() 
00396                     + the2ndHitdzConst_*the2ndHitdzConst_);
00397     newEstimator =
00398       new ConversionBarrelEstimator(-the2ndHitdphi_, the2ndHitdphi_, -dz, dz);
00399   }
00400   else {
00401     LogDebug("OutInConversionSeedFinder") << " EndCap OutInConversionSeedFinder::completeSeed " << the2ndHitdznSigma_ << " " << the2ndHitdzConst_ << " " << the2ndHitdphi_ << "\n";
00402     // z error for 2nd hit is 2sigma quadded with 5 cm
00403     //float m1dr = m1.recHit().globalPositionError().rerr(m1.recHit().globalPosition());
00404     float m1dr = sqrt(m1.recHit()->localPositionError().yy());
00405     float dr = sqrt(the2ndHitdznSigma_*the2ndHitdznSigma_*m1dr*m1dr 
00406                     + the2ndHitdzConst_*the2ndHitdznSigma_);
00407     // LogDebug("OutInConversionSeedFinder") << "second hit forward dr " << dr << " this hit " << m1dr << endl;
00408     newEstimator =
00409       new ConversionForwardEstimator(-the2ndHitdphi_, the2ndHitdphi_, dr);
00410   }
00411 
00412   LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::completeSeed  ilayer " << ilayer <<  "\n"; 
00413   
00414   // Get the measurements consistent with the FTS and the Estimator
00415   TSOS tsos(fts, layer->surface() );
00416   LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::completeSeed propagationDirection  " << int(propagator->propagationDirection() ) << "\n";               
00417   LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::completeSeed pointer to estimator " << newEstimator << "\n";
00418 
00419   LayerMeasurements theLayerMeasurements_(this->getMeasurementTracker() );
00420   std::vector<TrajectoryMeasurement> measurements = theLayerMeasurements_.measurements( *layer, tsos, *propagator, *newEstimator);
00421   //std::cout << "OutInConversionSeedFinder::completeSeed Found " << measurements.size() << " second hits " << "\n";
00422   delete newEstimator;
00423 
00424   for(unsigned int i = 0; i < measurements.size(); ++i) {
00425     if( measurements[i].recHit()->isValid()  ) {
00426       createSeed(m1, measurements[i]);
00427     }
00428   }
00429 
00430 
00431 
00432   //LogDebug("OutInConversionSeedFinder") << "COMPLETED " << theSeeds_.size() << " SEEDS " << "\n";
00433 }
00434 
00435 
00436 
00437 void OutInConversionSeedFinder::createSeed(const TrajectoryMeasurement & m1, 
00438                                            const TrajectoryMeasurement & m2) const {
00439 
00440   //std::cout  << "OutInConversionSeedFinder::createSeed  from hit1 " << m1.recHit()->globalPosition() << " r1 " << m1.recHit()->globalPosition().perp() << " and hit2 " << m2.recHit()->globalPosition() << " r2 " << m2.recHit()->globalPosition().perp() << "\n";
00441   
00442 
00443   FreeTrajectoryState fts = createSeedFTS(m1, m2);
00444 
00445 
00446   LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::createSeed First point errors " <<m1.recHit()->parametersError() << "\n";
00447   LogDebug("OutInConversionSeedFinder") << "original cluster FTS " << fts <<"\n";
00448 
00449 
00450 
00451   //std::cout  << "OutInConversionSeedFinder::createSeed propagation dir " << int( thePropagatorOppositeToMomentum_->propagationDirection() ) << "\n"; 
00452   TrajectoryStateOnSurface state1 = thePropagatorOppositeToMomentum_->propagate(fts,  m1.recHit()->det()->surface());
00453 
00454   // LogDebug("OutInConversionSeedFinder") << "hit surface " << h1.det().surface().position() << endl;
00455   // LogDebug("OutInConversionSeedFinder") << "prop to " << typeid(h1.det().surface()).name() << endl;
00456   // LogDebug("OutInConversionSeedFinder") << "prop to first hit " << state1 << endl; 
00457   // LogDebug("OutInConversionSeedFinder") << "update to " << h1.globalPosition() << endl;
00458 
00459   if ( state1.isValid() ) {
00460     TrajectoryStateOnSurface updatedState1 = theUpdator_.update(state1,  *m1.recHit() );
00461 
00462     if ( updatedState1.isValid() ) {
00463       TrajectoryStateOnSurface state2 = thePropagatorOppositeToMomentum_->propagate(*updatedState1.freeTrajectoryState(),  m2.recHit()->det()->surface());
00464 
00465       if ( state2.isValid() ) {
00466 
00467         TrajectoryStateOnSurface updatedState2 = theUpdator_.update(state2, *m2.recHit() );
00468         TrajectoryMeasurement meas1(state1, updatedState1,  m1.recHit()  , m1.estimate(), m1.layer());
00469         TrajectoryMeasurement meas2(state2, updatedState2,  m2.recHit()  , m2.estimate(), m2.layer());
00470         
00471         edm::OwnVector<TrackingRecHit> myHits;
00472         myHits.push_back(meas1.recHit()->hit()->clone());
00473         myHits.push_back(meas2.recHit()->hit()->clone());
00474 
00475         if ( nSeedsPerBC_ >= maxNumberOfOutInSeedsPerBC_ ) return;
00476    
00477         TrajectoryStateTransform tsTransform;
00478         PTrajectoryStateOnDet* ptsod= tsTransform.persistentState(state2, meas2.recHit()->hit()->geographicalId().rawId()  );
00479 
00480         LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::createSeed new seed  from state " << state2.globalPosition()  <<  "\n";
00481         LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::createSeed new seed  ptsod " <<  ptsod->parameters().position() << " R " << ptsod->parameters().position().perp() << " phi " << ptsod->parameters().position().phi() << " eta " << ptsod->parameters().position().eta() << "\n" ;
00482         
00483 
00484 
00485         theSeeds_.push_back(TrajectorySeed( *ptsod, myHits, oppositeToMomentum ));
00486         nSeedsPerBC_++;
00487  
00488         delete ptsod;  
00489         
00490 
00491       }
00492     }
00493   }
00494 
00495 
00496 
00497 
00498 
00499 }
00500 
00501 
00502 
00503 
00504 
00505 FreeTrajectoryState OutInConversionSeedFinder::createSeedFTS(const TrajectoryMeasurement & m1,
00506                                                              const TrajectoryMeasurement & m2) const {
00507 
00508   //std::cout  << "OutInConversionSeedFinder::createSeedFTS " << "\n";
00509 
00510   GlobalPoint xmeas = fixPointRadius(m1);
00511   GlobalPoint xvert = fixPointRadius(m2);
00512 
00513 
00514   float pt = theSCenergy_ * sin(theSCPosition_.theta());
00515   float pz = theSCenergy_ * cos(theSCPosition_.theta());
00516 
00517 
00518 
00519   // doesn't work at all for endcap, where r is badly measured
00520   //float dphidr = (p1.phi()-p2.phi())/(p1.perp()-p2.perp());
00521   //int charge = (dphidr > 0.) ? -1 : 1;
00522   int charge = m2.predictedState().charge();
00523 
00524   double BInTesla = theMF_->inTesla(xmeas).z();
00525   GlobalVector xdiff = xmeas -xvert;
00526  
00527   double phi= xdiff.phi();
00528   double pxOld = pt*cos(phi);
00529   double pyOld = pt*sin(phi);
00530   double RadCurv = 100*pt/(BInTesla*0.29979);
00531   double alpha = asin(0.5*xdiff.perp()/RadCurv);
00532   float ca = cos(charge*alpha);
00533   float sa = sin(charge*alpha);
00534   double pxNew =   ca*pxOld + sa*pyOld;
00535   double pyNew =  -sa*pxOld + ca*pyOld;
00536   GlobalVector pNew(pxNew, pyNew, pz);
00537 
00538   GlobalTrajectoryParameters gp(xmeas, pNew, charge, &(*theMF_) );
00539 
00540   AlgebraicSymMatrix55 m = AlgebraicMatrixID();
00541   m(0,0) = 0.05; m(1,1) = 0.02 ; m(2,2) = 0.007 ;
00542   m(3,3) = 10. ; m(4,4) = 10. ;
00543   return FreeTrajectoryState(gp, CurvilinearTrajectoryError(m));
00544 
00545 
00546 }
00547 
00548 
00549 
00550 
00551 GlobalPoint OutInConversionSeedFinder::fixPointRadius(const  TrajectoryMeasurement& m1) const {
00552   GlobalPoint p1 = m1.recHit()->globalPosition();
00553   GlobalPoint p2;
00554   if(m1.layer()->location() == GeomDetEnumerators::barrel) {
00555     p2 = p1;
00556   } else {
00557     float z = p1.z();
00558     float phi = p1.phi();
00559     float theta = theSCPosition_.theta();
00560     float r = p1.z() * tan(theta);
00561     p2 = GlobalPoint(r*cos(phi), r*sin(phi), z);
00562     // LogDebug("OutInConversionSeedFinder") << "fixing point radius " << p2 << " from " << p1 << endl;
00563   }
00564   return p2;
00565 }
00566 
00567 
00568 
00569 
00570