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
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
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
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
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
00127
00128
00129
00130 if(rejectTrack(*tr)) continue;
00131 std::vector<reco::Vertex> selectedPriVtxCompatibleWithTrack;
00132 if(!_applyTkVtxConstraint){
00133 selectedPriVtxCompatibleWithTrack.push_back(*(vertexHandle->begin()));
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);
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
00220
00221
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
00246 return true;
00247 }
00248
00249 float rMin=2.;
00250 if(_IdealHelixParameters.GetTangentPoint().rho()<rMin){
00251
00252
00253
00254
00255 return true;
00256 }
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 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
00304 return false;
00305 }
00306
00307 float rMin=3.;
00308 if(_IdealHelixParameters.GetTangentPoint().rho()<rMin){
00309
00310
00311
00312
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);
00358
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
00366
00367 theSeedCreator->trajectorySeed(*seedCollection,hits, originPos, originBounds, ptmin, *myEsetup,convRegion.cotTheta(),ss);
00368
00369
00370
00371
00372
00373 }
00374 return true;
00375 }
00376
00377