CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/RecoTracker/ConversionSeedGenerators/src/PhotonConversionTrajectorySeedProducerFromSingleLegAlgo.cc

Go to the documentation of this file.
00001 #include "RecoTracker/ConversionSeedGenerators/interface/PhotonConversionTrajectorySeedProducerFromSingleLegAlgo.h"
00002 #include "FWCore/Utilities/interface/Exception.h"
00003 
00004 //#define debugTSPFSLA
00005 
00006 inline double sqr(double a){return a*a;}
00007 
00008 PhotonConversionTrajectorySeedProducerFromSingleLegAlgo::
00009 PhotonConversionTrajectorySeedProducerFromSingleLegAlgo(const edm::ParameterSet & conf)
00010   :_conf(conf),seedCollection(0),seedCollectionOfSourceTracks(0),
00011    hitsfactoryPSet(conf.getParameter<edm::ParameterSet>("OrderedHitsFactoryPSet")),   
00012    creatorPSet(conf.getParameter<edm::ParameterSet>("SeedCreatorPSet")),
00013    regfactoryPSet(conf.getParameter<edm::ParameterSet>("RegionFactoryPSet")),
00014    theClusterCheck(conf.getParameter<edm::ParameterSet>("ClusterCheckPSet")),
00015    theSilentOnClusterCheck(conf.getParameter<edm::ParameterSet>("ClusterCheckPSet").getUntrackedParameter<bool>("silentClusterCheck",false)),
00016    _vtxMinDoF(conf.getParameter<double>("vtxMinDoF")),
00017    _maxDZSigmas(conf.getParameter<double>("maxDZSigmas")),
00018    _maxNumSelVtx(conf.getParameter<uint32_t>("maxNumSelVtx")),
00019    _applyTkVtxConstraint(conf.getParameter<bool>("applyTkVtxConstraint")),
00020    _countSeedTracks(0),
00021    _primaryVtxInputTag(conf.getParameter<edm::InputTag>("primaryVerticesTag")),
00022    _beamSpotInputTag(conf.getParameter<edm::InputTag>("beamSpotInputTag"))
00023 {
00024    init();  
00025 }
00026      
00027 void PhotonConversionTrajectorySeedProducerFromSingleLegAlgo::
00028 clear(){
00029   if(theHitsGenerator!=NULL)
00030     delete theHitsGenerator;
00031   if(theSeedCreator!=NULL)
00032     delete theSeedCreator;
00033   if(theRegionProducer!=NULL)
00034     delete theRegionProducer;
00035 }
00036 
00037 void PhotonConversionTrajectorySeedProducerFromSingleLegAlgo::
00038 init(){
00039   theHitsGenerator  = new CombinedHitPairGeneratorForPhotonConversion(hitsfactoryPSet);
00040   theSeedCreator    = new SeedForPhotonConversion1Leg(creatorPSet);
00041   theRegionProducer = new GlobalTrackingRegionProducerFromBeamSpot(regfactoryPSet);
00042 }
00043 
00044 void PhotonConversionTrajectorySeedProducerFromSingleLegAlgo::
00045 analyze(const edm::Event & event, const edm::EventSetup &setup){
00046 
00047   myEsetup = &setup;
00048   myEvent = &event;
00049 
00050   if(seedCollection!=0)
00051     delete seedCollection;
00052 
00053   if(seedCollectionOfSourceTracks!=0)
00054     delete seedCollectionOfSourceTracks;
00055 
00056   seedCollection= new TrajectorySeedCollection();
00057   seedCollectionOfSourceTracks= new TrajectorySeedCollection();
00058 
00059   size_t clustsOrZero = theClusterCheck.tooManyClusters(event);
00060   if (clustsOrZero){
00061     if (!theSilentOnClusterCheck)
00062       edm::LogError("TooManyClusters") << "Found too many clusters (" << clustsOrZero << "), bailing out.\n";
00063     return ;
00064   }
00065 
00066 
00067   edm::ESHandle<MagneticField> handleMagField;
00068   setup.get<IdealMagneticFieldRecord>().get(handleMagField);
00069   magField = handleMagField.product();
00070 
00071   _IdealHelixParameters.setMagnField(magField);
00072 
00073 
00074   event.getByLabel(_primaryVtxInputTag, vertexHandle);
00075   if (!vertexHandle.isValid() || vertexHandle->empty()){
00076       edm::LogError("PhotonConversionFinderFromTracks") << "Error! Can't get the product primary Vertex Collection "<< _primaryVtxInputTag <<  "\n";
00077       return;
00078   }
00079 
00080   event.getByLabel(_beamSpotInputTag,recoBeamSpotHandle);
00081   
00082 
00083   regions = theRegionProducer->regions(event,setup);
00084   
00085   //Do the analysis
00086   loopOnTracks();
00087 
00088  
00089 #ifdef debugTSPFSLA 
00090   std::stringstream ss;
00091   ss.str("");
00092   ss << "\n++++++++++++++++++\n";
00093   ss << "seed collection size " << seedCollection->size();
00094   BOOST_FOREACH(TrajectorySeed tjS,*seedCollection){
00095     po.print(ss, tjS);
00096   }
00097   edm::LogInfo("debugTrajSeedFromSingleLeg") << ss.str();
00098   //-------------------------------------------------
00099 #endif
00100 
00101    // clear memory
00102   theHitsGenerator->clearLayerCache();
00103   for (IR ir=regions.begin(), irEnd=regions.end(); ir < irEnd; ++ir) delete (*ir);
00104 
00105 }
00106 
00107 
00108 void PhotonConversionTrajectorySeedProducerFromSingleLegAlgo::
00109 loopOnTracks(){
00110 
00111   //--- Get Tracks
00112   myEvent->getByLabel(_conf.getParameter<edm::InputTag>("TrackRefitter"),trackCollectionH);
00113 
00114   if(trackCollectionH.isValid()==0){
00115     edm::LogError("MissingInput")<<" could not find track collecion:"<<_conf.getParameter<edm::InputTag>("TrackRefitter");
00116     return;
00117   }
00118   size_t idx=0, sel=0;
00119   _countSeedTracks=0;
00120 
00121   ss.str("");
00122   
00123   for( reco::TrackCollection::const_iterator tr = trackCollectionH->begin(); 
00124        tr != trackCollectionH->end(); tr++, idx++) {
00125     
00126     // #ifdef debugTSPFSLA 
00127     //     ss << "\nStuding track Nb " << idx;
00128     // #endif
00129 
00130     if(rejectTrack(*tr))  continue;
00131     std::vector<reco::Vertex> selectedPriVtxCompatibleWithTrack;  
00132     if(!_applyTkVtxConstraint){
00133       selectedPriVtxCompatibleWithTrack.push_back(*(vertexHandle->begin())); //Same approach as before
00134     }else{
00135       if(!selectPriVtxCompatibleWithTrack(*tr,selectedPriVtxCompatibleWithTrack)) continue;
00136     }
00137 
00138     sel++;
00139     loopOnPriVtx(*tr,selectedPriVtxCompatibleWithTrack);
00140   }
00141 #ifdef debugTSPFSLA 
00142   edm::LogInfo("debugTrajSeedFromSingleLeg") << ss.str();
00143   edm::LogInfo("debugTrajSeedFromSingleLeg") << "Inspected " << sel << " tracks over " << idx << " tracks. \t # tracks providing at least one seed " << _countSeedTracks ;
00144 #endif
00145 }
00146 
00147 bool PhotonConversionTrajectorySeedProducerFromSingleLegAlgo::
00148 selectPriVtxCompatibleWithTrack(const reco::Track& tk, std::vector<reco::Vertex>& selectedPriVtxCompatibleWithTrack){
00149   
00150   std::vector< std::pair< double, short> > idx;
00151   short count=-1;
00152 
00153   double cosPhi=tk.px()/tk.pt();
00154   double sinPhi=tk.py()/tk.pt();
00155   double sphi2=tk.covariance(2,2);
00156   double stheta2=tk.covariance(1,1);
00157 
00158   BOOST_FOREACH(const reco::Vertex& vtx,  *vertexHandle){
00159     count++;
00160     if(vtx.ndof()<= _vtxMinDoF) continue;
00161 
00162     double _dz= tk.dz(vtx.position());
00163     double _dzError=tk.dzError();
00164 
00165     double cotTheta=tk.pz()/tk.pt();
00166     double dx = vtx.position().x();
00167     double dy = vtx.position().y();
00168     double sx2=vtx.covariance(0,0);
00169     double sy2=vtx.covariance(1,1);
00170 
00171     double sxy2= sqr(cosPhi*cotTheta)*sx2+
00172       sqr(sinPhi*cotTheta)*sy2+
00173       sqr(cotTheta*(-dx*sinPhi+dy*cosPhi))*sphi2+
00174       sqr((1+cotTheta*cotTheta)*(dx*cosPhi+dy*sinPhi))*stheta2;
00175       
00176     _dzError=sqrt(_dzError*_dzError+vtx.covariance(2,2)+sxy2); //there is a missing component, related to the element (vtx.x*px+vtx.y*py)/pt * pz/pt. since the tk ref point is at the point of closest approach, this scalar product should be almost zero.
00177 
00178 #ifdef debugTSPFSLA
00179     ss << " primary vtx " << vtx.position()  << " \tk vz " << tk.vz() << " vx " << tk.vx() << " vy " << tk.vy() << " pz/pt " << tk.pz()/tk.pt() << " \t dz " << _dz << " \t " << _dzError << " sxy2 "<< sxy2<< " \t dz/dzErr " << _dz/_dzError<< std::endl;
00180 #endif
00181 
00182     if(fabs(_dz)/_dzError > _maxDZSigmas) continue; 
00183       
00184     idx.push_back(std::pair<double,short>(fabs(_dz),count));
00185   }
00186   if(idx.size()==0) {
00187 #ifdef debugTSPFSLA
00188     ss << "no vertex selected " << std::endl; 
00189 #endif
00190     return false;
00191 }
00192   
00193   std::stable_sort(idx.begin(),idx.end(),lt_);
00194   for(size_t i=0;i<_maxNumSelVtx && i<idx.size();++i){
00195     selectedPriVtxCompatibleWithTrack.push_back((*vertexHandle)[idx[i].second]);
00196 #ifdef debugTSPFSLA
00197     ss << "selected vtx dz " << idx[0].first << "  position" << idx[0].second << std::endl;
00198 #endif
00199   }
00200 
00201   return true;
00202 }
00203 
00204 void PhotonConversionTrajectorySeedProducerFromSingleLegAlgo::
00205 loopOnPriVtx(const reco::Track& tk, const std::vector<reco::Vertex>& selectedPriVtxCompatibleWithTrack){
00206 
00207   bool foundAtLeastASeedCand=false;
00208   BOOST_FOREACH(const reco::Vertex vtx, selectedPriVtxCompatibleWithTrack){
00209 
00210     math::XYZPoint primaryVertexPoint=math::XYZPoint(vtx.position());
00211     
00212     for (IR ir=regions.begin(), irEnd=regions.end(); ir < irEnd; ++ir) {
00213       const TrackingRegion & region = **ir;
00214 
00215 #ifdef debugTSPFSLA 
00216       ss << "[PrintRegion] " << region.print() << std::endl;
00217 #endif
00218       
00219       //This if is just for the _countSeedTracks. otherwise 
00220       //inspectTrack(&tk,region, primaryVertexPoint);
00221       //would be enough
00222 
00223       if(
00224          inspectTrack(&tk,region, primaryVertexPoint)
00225          and
00226          !foundAtLeastASeedCand
00227          ){
00228         foundAtLeastASeedCand=true;
00229         _countSeedTracks++; 
00230       }
00231 
00232     }
00233   }
00234 }
00235   
00236 bool PhotonConversionTrajectorySeedProducerFromSingleLegAlgo::
00237 rejectTrack(const reco::Track& track){
00238   
00239   math::XYZVector beamSpot;
00240   if(recoBeamSpotHandle.isValid()) {
00241     beamSpot =  math::XYZVector(recoBeamSpotHandle->position());
00242 
00243     _IdealHelixParameters.setData(&track,beamSpot);   
00244     if(_IdealHelixParameters.GetTangentPoint().r()==0){
00245       //this case means a null results on the _IdealHelixParameters side
00246       return true;
00247       }
00248       
00249     float rMin=2.; //cm
00250     if(_IdealHelixParameters.GetTangentPoint().rho()<rMin){
00251       //this case means a track that has the tangent point nearby the primary vertex
00252       // if the track is primary, this number tends to be the primary vertex itself
00253       //Rejecting all the potential photon conversions having a "vertex" inside the beampipe
00254       //We should not miss too much, seen that the conversions at the beam pipe are the better reconstructed
00255       return true;
00256     }
00257   }
00258 
00259   //-------------------------------------------------------
00260   /*
00261   float maxPt2=64.; //Cut on pt^2 Indeed doesn't do almost nothing
00262   if(track.momentum().Perp2() > maxPt2)
00263     return true;
00264   */
00265   //-------------------------------------------------------
00266   //Cut in the barrel eta region FIXME: to be extended to endcaps
00267   /*
00268   float maxEta=1.3; 
00269   if(fabs(track.eta()) > maxEta)
00270     return true;
00271   */
00272   //-------------------------------------------------------
00273   //Reject tracks that have a first valid hit in the pixel barrel/endcap layer/disk 1
00274   //assume that the hits are aligned along momentum
00275   /*
00276   const reco::HitPattern& p=track.hitPattern();
00277   for (int i=0; i<p.numberOfHits(); i++) {
00278     uint32_t hit = p.getHitPattern(i);
00279     // if the hit is valid and in pixel barrel, print out the layer
00280     if (! p.validHitFilter(hit) ) continue;
00281     if( (p.pixelBarrelHitFilter(hit) || p.pixelEndcapHitFilter(hit))
00282         &&
00283         p.getLayer(hit) == 1
00284         )
00285       return true;
00286     else
00287       break; //because the first valid hit is in a different layer
00288   }
00289   */
00290   //-------------------------------------------------------
00291 
00292 
00293   return false;
00294 }
00295 
00296 
00297 bool PhotonConversionTrajectorySeedProducerFromSingleLegAlgo::
00298 inspectTrack(const reco::Track* track, const TrackingRegion & region, math::XYZPoint& primaryVertexPoint){
00299 
00300   _IdealHelixParameters.setData(track,primaryVertexPoint);   
00301     
00302   if(_IdealHelixParameters.GetTangentPoint().r()==0){
00303     //this case means a null results on the _IdealHelixParameters side
00304     return false;
00305   }
00306 
00307   float rMin=3.; //cm
00308   if(_IdealHelixParameters.GetTangentPoint().rho()<rMin){
00309     //this case means a track that has the tangent point nearby the primary vertex
00310     // if the track is primary, this number tends to be the primary vertex itself
00311     //Rejecting all the potential photon conversions having a "vertex" inside the beampipe
00312     //We should not miss too much, seen that the conversions at the beam pipe are the better reconstructed
00313     return false;
00314   }
00315 
00316   float ptmin = 0.5;
00317   float originRBound = 3;
00318   float originZBound  = 3.;
00319 
00320   GlobalPoint originPos;
00321   originPos = GlobalPoint(_IdealHelixParameters.GetTangentPoint().x(),
00322                           _IdealHelixParameters.GetTangentPoint().y(),
00323                           _IdealHelixParameters.GetTangentPoint().z()
00324                           );
00325   float cotTheta;
00326   if( std::abs(_IdealHelixParameters.GetMomentumAtTangentPoint().rho()) > 1.e-4f ){
00327     cotTheta=_IdealHelixParameters.GetMomentumAtTangentPoint().z()/_IdealHelixParameters.GetMomentumAtTangentPoint().rho();
00328   }else{
00329     if(_IdealHelixParameters.GetMomentumAtTangentPoint().z()>0)
00330       cotTheta=99999.f; 
00331     else
00332       cotTheta=-99999.f; 
00333   }
00334   GlobalVector originBounds(originRBound,originRBound,originZBound);
00335 
00336   GlobalPoint pvtxPoint(primaryVertexPoint.x(),
00337                         primaryVertexPoint.y(),
00338                         primaryVertexPoint.z()
00339                         );
00340   ConversionRegion convRegion(originPos, pvtxPoint, cotTheta, track->thetaError(), -1*track->charge());
00341 
00342 #ifdef debugTSPFSLA 
00343   ss << "\nConversion Point " << originPos << " " << originPos.perp() << "\n";
00344 #endif
00345 
00346   const OrderedSeedingHits & hitss = theHitsGenerator->run(convRegion, region, *myEvent, *myEsetup);
00347   
00348   unsigned int nHitss =  hitss.size();
00349 
00350   if(nHitss==0)
00351     return false;
00352 
00353 #ifdef debugTSPFSLA 
00354   ss << "\n nHitss " << nHitss << "\n";
00355 #endif
00356 
00357   if (seedCollection->empty()) seedCollection->reserve(nHitss); // don't do multiple reserves in the case of multiple regions: it would make things even worse
00358                                                                // as it will cause N re-allocations instead of the normal log(N)/log(2)
00359   for (unsigned int iHits = 0; iHits < nHitss; ++iHits) { 
00360 
00361 #ifdef debugTSPFSLA 
00362     ss << "\n iHits " << iHits << "\n";
00363 #endif
00364     const SeedingHitSet & hits =  hitss[iHits];
00365     //if (!theComparitor || theComparitor->compatible( hits, es) ) {
00366     //try{
00367     theSeedCreator->trajectorySeed(*seedCollection,hits, originPos, originBounds, ptmin, *myEsetup,convRegion.cotTheta(),ss);
00368     //}catch(cms::Exception& er){
00369     //  edm::LogError("SeedingConversion") << " Problem in the Single Leg Seed creator " <<er.what()<<std::endl;
00370     //}catch(std::exception& er){
00371     //  edm::LogError("SeedingConversion") << " Problem in the Single Leg Seed creator " << er.what()<<std::endl;
00372     //}
00373   }
00374   return true;
00375 }
00376 
00377