CMS 3D CMS Logo

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