00001 #include "RecoTracker/ConversionSeedGenerators/interface/PhotonConversionTrajectorySeedProducerFromSingleLegAlgo.h"
00002 #include "FWCore/Utilities/interface/Exception.h"
00003
00004
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
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
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
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
00128
00129
00130
00131 if(rejectTrack(*tr)) continue;
00132 std::vector<reco::Vertex> selectedPriVtxCompatibleWithTrack;
00133 if(!_applyTkVtxConstraint){
00134 selectedPriVtxCompatibleWithTrack.push_back(*(vertexHandle->begin()));
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);
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
00221
00222
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
00247 return true;
00248 }
00249
00250 float rMin=2.;
00251 if(_IdealHelixParameters.GetTangentPoint().rho()<rMin){
00252
00253
00254
00255
00256 return true;
00257 }
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
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
00306 return false;
00307 }
00308
00309 float rMin=3.;
00310 if(_IdealHelixParameters.GetTangentPoint().rho()<rMin){
00311
00312
00313
00314
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);
00360
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
00368
00369 theSeedCreator->trajectorySeed(*seedCollection,hits, originPos, originBounds, ptmin, *myEsetup,convRegion.cotTheta(),ss);
00370
00371
00372
00373
00374
00375 }
00376 return true;
00377 }
00378
00379