CMS 3D CMS Logo

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