00001 #include "RecoTracker/ConversionSeedGenerators/interface/PhotonConversionTrajectorySeedProducerFromSingleLegAlgo.h"
00002 #include "FWCore/Utilities/interface/Exception.h"
00003 #include "FWCore/Utilities/interface/isFinite.h"
00004
00005 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00006 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00007 #include "FWCore/Framework/interface/ESHandle.h"
00008 #include "MagneticField/Engine/interface/MagneticField.h"
00009
00010
00011
00012
00013 inline double sqr(double a){return a*a;}
00014
00015 PhotonConversionTrajectorySeedProducerFromSingleLegAlgo::
00016 PhotonConversionTrajectorySeedProducerFromSingleLegAlgo(const edm::ParameterSet & conf)
00017 :_conf(conf),seedCollection(0),seedCollectionOfSourceTracks(0),
00018 hitsfactoryPSet(conf.getParameter<edm::ParameterSet>("OrderedHitsFactoryPSet")),
00019 creatorPSet(conf.getParameter<edm::ParameterSet>("SeedCreatorPSet")),
00020 regfactoryPSet(conf.getParameter<edm::ParameterSet>("RegionFactoryPSet")),
00021 theClusterCheck(conf.getParameter<edm::ParameterSet>("ClusterCheckPSet")),
00022 theSilentOnClusterCheck(conf.getParameter<edm::ParameterSet>("ClusterCheckPSet").getUntrackedParameter<bool>("silentClusterCheck",false)),
00023 _vtxMinDoF(conf.getParameter<double>("vtxMinDoF")),
00024 _maxDZSigmas(conf.getParameter<double>("maxDZSigmas")),
00025 _maxNumSelVtx(conf.getParameter<uint32_t>("maxNumSelVtx")),
00026 _applyTkVtxConstraint(conf.getParameter<bool>("applyTkVtxConstraint")),
00027 _countSeedTracks(0),
00028 _primaryVtxInputTag(conf.getParameter<edm::InputTag>("primaryVerticesTag")),
00029 _beamSpotInputTag(conf.getParameter<edm::InputTag>("beamSpotInputTag"))
00030 {
00031 init();
00032 }
00033
00034 void PhotonConversionTrajectorySeedProducerFromSingleLegAlgo::
00035 clear(){
00036 if(theHitsGenerator!=NULL)
00037 delete theHitsGenerator;
00038 if(theSeedCreator!=NULL)
00039 delete theSeedCreator;
00040 if(theRegionProducer!=NULL)
00041 delete theRegionProducer;
00042 }
00043
00044 void PhotonConversionTrajectorySeedProducerFromSingleLegAlgo::
00045 init(){
00046 theHitsGenerator = new CombinedHitPairGeneratorForPhotonConversion(hitsfactoryPSet);
00047 theSeedCreator = new SeedForPhotonConversion1Leg(creatorPSet);
00048 theRegionProducer = new GlobalTrackingRegionProducerFromBeamSpot(regfactoryPSet);
00049 }
00050
00051 void PhotonConversionTrajectorySeedProducerFromSingleLegAlgo::
00052 analyze(const edm::Event & event, const edm::EventSetup &setup){
00053
00054 myEsetup = &setup;
00055 myEvent = &event;
00056
00057 if(seedCollection!=0)
00058 delete seedCollection;
00059
00060 if(seedCollectionOfSourceTracks!=0)
00061 delete seedCollectionOfSourceTracks;
00062
00063 seedCollection= new TrajectorySeedCollection();
00064 seedCollectionOfSourceTracks= new TrajectorySeedCollection();
00065
00066 size_t clustsOrZero = theClusterCheck.tooManyClusters(event);
00067 if (clustsOrZero){
00068 if (!theSilentOnClusterCheck)
00069 edm::LogError("TooManyClusters") << "Found too many clusters (" << clustsOrZero << "), bailing out.\n";
00070 return ;
00071 }
00072
00073
00074 edm::ESHandle<MagneticField> handleMagField;
00075 setup.get<IdealMagneticFieldRecord>().get(handleMagField);
00076 magField = handleMagField.product();
00077 if (unlikely(magField->inTesla(GlobalPoint(0.,0.,0.)).z()<0.01)) return;
00078
00079 _IdealHelixParameters.setMagnField(magField);
00080
00081
00082 event.getByLabel(_primaryVtxInputTag, vertexHandle);
00083 if (!vertexHandle.isValid() || vertexHandle->empty()){
00084 edm::LogError("PhotonConversionFinderFromTracks") << "Error! Can't get the product primary Vertex Collection "<< _primaryVtxInputTag << "\n";
00085 return;
00086 }
00087
00088 event.getByLabel(_beamSpotInputTag,recoBeamSpotHandle);
00089
00090
00091 regions = theRegionProducer->regions(event,setup);
00092
00093
00094 loopOnTracks();
00095
00096
00097 #ifdef debugTSPFSLA
00098 std::stringstream ss;
00099 ss.str("");
00100 ss << "\n++++++++++++++++++\n";
00101 ss << "seed collection size " << seedCollection->size();
00102 BOOST_FOREACH(TrajectorySeed tjS,*seedCollection){
00103 po.print(ss, tjS);
00104 }
00105 edm::LogInfo("debugTrajSeedFromSingleLeg") << ss.str();
00106
00107 #endif
00108
00109
00110 theHitsGenerator->clearLayerCache();
00111 for (IR ir=regions.begin(), irEnd=regions.end(); ir < irEnd; ++ir) delete (*ir);
00112
00113 }
00114
00115
00116 void PhotonConversionTrajectorySeedProducerFromSingleLegAlgo::
00117 loopOnTracks(){
00118
00119
00120 myEvent->getByLabel(_conf.getParameter<edm::InputTag>("TrackRefitter"),trackCollectionH);
00121
00122 if(trackCollectionH.isValid()==0){
00123 edm::LogError("MissingInput")<<" could not find track collecion:"<<_conf.getParameter<edm::InputTag>("TrackRefitter");
00124 return;
00125 }
00126 size_t idx=0, sel=0;
00127 _countSeedTracks=0;
00128
00129 ss.str("");
00130
00131 for( reco::TrackCollection::const_iterator tr = trackCollectionH->begin();
00132 tr != trackCollectionH->end(); tr++, idx++) {
00133
00134
00135
00136
00137
00138 if(rejectTrack(*tr)) continue;
00139 std::vector<reco::Vertex> selectedPriVtxCompatibleWithTrack;
00140 if(!_applyTkVtxConstraint){
00141 selectedPriVtxCompatibleWithTrack.push_back(*(vertexHandle->begin()));
00142 }else{
00143 if(!selectPriVtxCompatibleWithTrack(*tr,selectedPriVtxCompatibleWithTrack)) continue;
00144 }
00145
00146 sel++;
00147 loopOnPriVtx(*tr,selectedPriVtxCompatibleWithTrack);
00148 }
00149 #ifdef debugTSPFSLA
00150 edm::LogInfo("debugTrajSeedFromSingleLeg") << ss.str();
00151 edm::LogInfo("debugTrajSeedFromSingleLeg") << "Inspected " << sel << " tracks over " << idx << " tracks. \t # tracks providing at least one seed " << _countSeedTracks ;
00152 #endif
00153 }
00154
00155 bool PhotonConversionTrajectorySeedProducerFromSingleLegAlgo::
00156 selectPriVtxCompatibleWithTrack(const reco::Track& tk, std::vector<reco::Vertex>& selectedPriVtxCompatibleWithTrack){
00157
00158 std::vector< std::pair< double, short> > idx;
00159 short count=-1;
00160
00161 double cosPhi=tk.px()/tk.pt();
00162 double sinPhi=tk.py()/tk.pt();
00163 double sphi2=tk.covariance(2,2);
00164 double stheta2=tk.covariance(1,1);
00165
00166 BOOST_FOREACH(const reco::Vertex& vtx, *vertexHandle){
00167 count++;
00168 if(vtx.ndof()<= _vtxMinDoF) continue;
00169
00170 double _dz= tk.dz(vtx.position());
00171 double _dzError=tk.dzError();
00172
00173 double cotTheta=tk.pz()/tk.pt();
00174 double dx = vtx.position().x();
00175 double dy = vtx.position().y();
00176 double sx2=vtx.covariance(0,0);
00177 double sy2=vtx.covariance(1,1);
00178
00179 double sxy2= sqr(cosPhi*cotTheta)*sx2+
00180 sqr(sinPhi*cotTheta)*sy2+
00181 sqr(cotTheta*(-dx*sinPhi+dy*cosPhi))*sphi2+
00182 sqr((1+cotTheta*cotTheta)*(dx*cosPhi+dy*sinPhi))*stheta2;
00183
00184 _dzError=sqrt(_dzError*_dzError+vtx.covariance(2,2)+sxy2);
00185
00186 #ifdef debugTSPFSLA
00187 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;
00188 #endif
00189
00190 if(fabs(_dz)/_dzError > _maxDZSigmas) continue;
00191
00192 idx.push_back(std::pair<double,short>(fabs(_dz),count));
00193 }
00194 if(idx.size()==0) {
00195 #ifdef debugTSPFSLA
00196 ss << "no vertex selected " << std::endl;
00197 #endif
00198 return false;
00199 }
00200
00201 std::stable_sort(idx.begin(),idx.end(),lt_);
00202 for(size_t i=0;i<_maxNumSelVtx && i<idx.size();++i){
00203 selectedPriVtxCompatibleWithTrack.push_back((*vertexHandle)[idx[i].second]);
00204 #ifdef debugTSPFSLA
00205 ss << "selected vtx dz " << idx[0].first << " position" << idx[0].second << std::endl;
00206 #endif
00207 }
00208
00209 return true;
00210 }
00211
00212 void PhotonConversionTrajectorySeedProducerFromSingleLegAlgo::
00213 loopOnPriVtx(const reco::Track& tk, const std::vector<reco::Vertex>& selectedPriVtxCompatibleWithTrack){
00214
00215 bool foundAtLeastASeedCand=false;
00216 BOOST_FOREACH(const reco::Vertex vtx, selectedPriVtxCompatibleWithTrack){
00217
00218 math::XYZPoint primaryVertexPoint=math::XYZPoint(vtx.position());
00219
00220 for (IR ir=regions.begin(), irEnd=regions.end(); ir < irEnd; ++ir) {
00221 const TrackingRegion & region = **ir;
00222
00223 #ifdef debugTSPFSLA
00224 ss << "[PrintRegion] " << region.print() << std::endl;
00225 #endif
00226
00227
00228
00229
00230
00231 if(
00232 inspectTrack(&tk,region, primaryVertexPoint)
00233 and
00234 !foundAtLeastASeedCand
00235 ){
00236 foundAtLeastASeedCand=true;
00237 _countSeedTracks++;
00238 }
00239
00240 }
00241 }
00242 }
00243
00244 bool PhotonConversionTrajectorySeedProducerFromSingleLegAlgo::
00245 rejectTrack(const reco::Track& track){
00246
00247 math::XYZVector beamSpot;
00248 if(recoBeamSpotHandle.isValid()) {
00249 beamSpot = math::XYZVector(recoBeamSpotHandle->position());
00250
00251 _IdealHelixParameters.setData(&track,beamSpot);
00252 if(_IdealHelixParameters.GetTangentPoint().r()==0){
00253
00254 return true;
00255 }
00256
00257 float rMin=2.;
00258 if(_IdealHelixParameters.GetTangentPoint().rho()<rMin){
00259
00260
00261
00262
00263 return true;
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
00296
00297
00298
00299
00300
00301 return false;
00302 }
00303
00304
00305 bool PhotonConversionTrajectorySeedProducerFromSingleLegAlgo::
00306 inspectTrack(const reco::Track* track, const TrackingRegion & region, math::XYZPoint& primaryVertexPoint){
00307
00308 _IdealHelixParameters.setData(track,primaryVertexPoint);
00309
00310 if (edm::isNotFinite(_IdealHelixParameters.GetTangentPoint().r()) ||
00311 (_IdealHelixParameters.GetTangentPoint().r()==0)){
00312
00313 return false;
00314 }
00315
00316 float rMin=3.;
00317 if(_IdealHelixParameters.GetTangentPoint().rho()<rMin){
00318
00319
00320
00321
00322 return false;
00323 }
00324
00325 float ptmin = 0.5;
00326 float originRBound = 3;
00327 float originZBound = 3.;
00328
00329 GlobalPoint originPos;
00330 originPos = GlobalPoint(_IdealHelixParameters.GetTangentPoint().x(),
00331 _IdealHelixParameters.GetTangentPoint().y(),
00332 _IdealHelixParameters.GetTangentPoint().z()
00333 );
00334 float cotTheta;
00335 if( std::abs(_IdealHelixParameters.GetMomentumAtTangentPoint().rho()) > 1.e-4f ){
00336 cotTheta=_IdealHelixParameters.GetMomentumAtTangentPoint().z()/_IdealHelixParameters.GetMomentumAtTangentPoint().rho();
00337 }else{
00338 if(_IdealHelixParameters.GetMomentumAtTangentPoint().z()>0)
00339 cotTheta=99999.f;
00340 else
00341 cotTheta=-99999.f;
00342 }
00343 GlobalVector originBounds(originRBound,originRBound,originZBound);
00344
00345 GlobalPoint pvtxPoint(primaryVertexPoint.x(),
00346 primaryVertexPoint.y(),
00347 primaryVertexPoint.z()
00348 );
00349 ConversionRegion convRegion(originPos, pvtxPoint, cotTheta, track->thetaError(), -1*track->charge());
00350
00351 #ifdef debugTSPFSLA
00352 ss << "\nConversion Point " << originPos << " " << originPos.perp() << "\n";
00353 #endif
00354
00355 const OrderedSeedingHits & hitss = theHitsGenerator->run(convRegion, region, *myEvent, *myEsetup);
00356
00357 unsigned int nHitss = hitss.size();
00358
00359 if(nHitss==0)
00360 return false;
00361
00362 #ifdef debugTSPFSLA
00363 ss << "\n nHitss " << nHitss << "\n";
00364 #endif
00365
00366 if (seedCollection->empty()) seedCollection->reserve(nHitss);
00367
00368 for (unsigned int iHits = 0; iHits < nHitss; ++iHits) {
00369
00370 #ifdef debugTSPFSLA
00371 ss << "\n iHits " << iHits << "\n";
00372 #endif
00373 const SeedingHitSet & hits = hitss[iHits];
00374
00375
00376 theSeedCreator->trajectorySeed(*seedCollection,hits, originPos, originBounds, ptmin, *myEsetup,convRegion.cotTheta(),ss);
00377
00378
00379
00380
00381
00382 }
00383 return true;
00384 }
00385
00386