CMS 3D CMS Logo

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