00001 #include "RecoTracker/ConversionSeedGenerators/interface/PhotonConversionTrajectorySeedProducerFromSingleLegAlgo.h"
00002 #include "FWCore/Utilities/interface/Exception.h"
00003 #include "FWCore/Utilities/interface/isFinite.h"
00004
00005
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
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
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
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
00129
00130
00131
00132 if(rejectTrack(*tr)) continue;
00133 std::vector<reco::Vertex> selectedPriVtxCompatibleWithTrack;
00134 if(!_applyTkVtxConstraint){
00135 selectedPriVtxCompatibleWithTrack.push_back(*(vertexHandle->begin()));
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);
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
00222
00223
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
00248 return true;
00249 }
00250
00251 float rMin=2.;
00252 if(_IdealHelixParameters.GetTangentPoint().rho()<rMin){
00253
00254
00255
00256
00257 return true;
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
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
00307 return false;
00308 }
00309
00310 float rMin=3.;
00311 if(_IdealHelixParameters.GetTangentPoint().rho()<rMin){
00312
00313
00314
00315
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);
00361
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
00369
00370 theSeedCreator->trajectorySeed(*seedCollection,hits, originPos, originBounds, ptmin, *myEsetup,convRegion.cotTheta(),ss);
00371
00372
00373
00374
00375
00376 }
00377 return true;
00378 }
00379
00380