CMS 3D CMS Logo

PFElecTkProducer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: PFTracking
4 // Class: PFElecTkProducer
5 //
6 // Original Author: Michele Pioppi
7 // Created: Tue Jan 23 15:26:39 CET 2007
8 
9 
10 
11 // system include files
12 #include <memory>
13 
14 // user include files
36 
37 #include "TMath.h"
38 using namespace std;
39 using namespace edm;
40 using namespace reco;
42  conf_(iConfig)
43 {
44 
45 
46  gsfTrackLabel_ = consumes<reco::GsfTrackCollection>(iConfig.getParameter<InputTag>
47  ("GsfTrackModuleLabel"));
48 
49  pfTrackLabel_ = consumes<reco::PFRecTrackCollection>(iConfig.getParameter<InputTag>
50  ("PFRecTrackLabel"));
51 
52  primVtxLabel_ = consumes<reco::VertexCollection>(iConfig.getParameter<InputTag>
53  ("PrimaryVertexLabel"));
54 
55  pfEcalClusters_ = consumes<reco::PFClusterCollection>(iConfig.getParameter<InputTag>
56  ("PFEcalClusters"));
57 
58  pfNuclear_ = consumes<reco::PFDisplacedTrackerVertexCollection>(iConfig.getParameter<InputTag>
59  ("PFNuclear"));
60 
61  pfConv_ = consumes<reco::PFConversionCollection>(iConfig.getParameter<InputTag>
62  ("PFConversions"));
63 
64  pfV0_ = consumes<reco::PFV0Collection>(iConfig.getParameter<InputTag>
65  ("PFV0"));
66 
67  useNuclear_ = iConfig.getParameter<bool>("useNuclear");
68  useConversions_ = iConfig.getParameter<bool>("useConversions");
69  useV0_ = iConfig.getParameter<bool>("useV0");
70  debugGsfCleaning_ = iConfig.getParameter<bool>("debugGsfCleaning");
71 
72  produces<GsfPFRecTrackCollection>();
73  produces<GsfPFRecTrackCollection>( "Secondary" ).setBranchAlias( "secondary" );
74 
75 
76  trajinev_ = iConfig.getParameter<bool>("TrajInEvents");
77  modemomentum_ = iConfig.getParameter<bool>("ModeMomentum");
78  applySel_ = iConfig.getParameter<bool>("applyEGSelection");
79  applyGsfClean_ = iConfig.getParameter<bool>("applyGsfTrackCleaning");
80  applyAngularGsfClean_ = iConfig.getParameter<bool>("applyAlsoGsfAngularCleaning");
81  detaCutGsfClean_ = iConfig.getParameter<double>("maxDEtaGsfAngularCleaning");
82  dphiCutGsfClean_ = iConfig.getParameter<double>("maxDPhiBremTangGsfAngularCleaning");
83  useFifthStepForTrackDriven_ = iConfig.getParameter<bool>("useFifthStepForTrackerDrivenGsf");
84  useFifthStepForEcalDriven_ = iConfig.getParameter<bool>("useFifthStepForEcalDrivenGsf");
85  maxPtConvReco_ = iConfig.getParameter<double>("MaxConvBremRecoPT");
86  detaGsfSC_ = iConfig.getParameter<double>("MinDEtaGsfSC");
87  dphiGsfSC_ = iConfig.getParameter<double>("MinDPhiGsfSC");
88  SCEne_ = iConfig.getParameter<double>("MinSCEnergy");
89 
90  // set parameter for convBremFinder
91  useConvBremFinder_ = iConfig.getParameter<bool>("useConvBremFinder");
92 
93  mvaConvBremFinderIDBarrelLowPt_ = iConfig.getParameter<double>("pf_convBremFinderID_mvaCutBarrelLowPt");
94  mvaConvBremFinderIDBarrelHighPt_ = iConfig.getParameter<double>("pf_convBremFinderID_mvaCutBarrelHighPt");
95  mvaConvBremFinderIDEndcapsLowPt_ = iConfig.getParameter<double>("pf_convBremFinderID_mvaCutEndcapsLowPt");
96  mvaConvBremFinderIDEndcapsHighPt_ = iConfig.getParameter<double>("pf_convBremFinderID_mvaCutEndcapsHighPt");
97 
98 }
99 
100 
102 { }
103 
104 
105 //
106 // member functions
107 //
108 
109 // ------------ method called to produce the data ------------
110 void
112 {
113 
114 
115  //create the empty collections
116  auto gsfPFRecTrackCollection = std::make_unique<GsfPFRecTrackCollection>();
117 
118  auto gsfPFRecTrackCollectionSecondary = std::make_unique<GsfPFRecTrackCollection>();
119 
120  //read collections of tracks
121  Handle<GsfTrackCollection> gsftrackscoll;
122  iEvent.getByToken(gsfTrackLabel_,gsftrackscoll);
123 
124  //read collections of trajectories
126 
127  //read pfrectrack collection
128  Handle<PFRecTrackCollection> thePfRecTrackCollection;
129  iEvent.getByToken(pfTrackLabel_,thePfRecTrackCollection);
130  const PFRecTrackCollection& PfRTkColl = *(thePfRecTrackCollection.product());
131 
132  // PFClusters
133  Handle<PFClusterCollection> theECPfClustCollection;
134  iEvent.getByToken(pfEcalClusters_,theECPfClustCollection);
135  const PFClusterCollection& theEcalClusters = *(theECPfClustCollection.product());
136 
137  //Primary Vertexes
138  Handle<reco::VertexCollection> thePrimaryVertexColl;
139  iEvent.getByToken(primVtxLabel_,thePrimaryVertexColl);
140 
141  // Displaced Vertex
143  if( useNuclear_ )
144  iEvent.getByToken(pfNuclear_, pfNuclears);
145 
146  // Conversions
148  if( useConversions_ )
149  iEvent.getByToken(pfConv_,pfConversions);
150 
151  // V0
153  if( useV0_ )
154  iEvent.getByToken(pfV0_, pfV0);
155 
156 
157 
158 
159  GsfTrackCollection gsftracks = *(gsftrackscoll.product());
160  vector<Trajectory> tjvec(0);
161  if (trajinev_){
162  iEvent.getByToken(gsfTrackLabel_,TrajectoryCollection);
163 
164  tjvec= *(TrajectoryCollection.product());
165  }
166 
167 
168  vector<reco::GsfPFRecTrack> selGsfPFRecTracks;
169  vector<reco::GsfPFRecTrack> primaryGsfPFRecTracks;
170  std::map<unsigned int, std::vector<reco::GsfPFRecTrack> > GsfPFMap;
171 
172  for( unsigned igsf = 0; igsf < gsftracks.size(); igsf++ ) {
173  GsfTrackRef trackRef(gsftrackscoll, igsf);
174  gsfInnerMomentumCache_.push_back(trackRef->pMode());
176  GlobalVector i_innMom;
177  if(i_inTSOS.isValid()){
179  gsfInnerMomentumCache_.back() = i_innMom.mag();
180  }
181  }
182 
183  for (unsigned int igsf=0; igsf<gsftracks.size();igsf++) {
184 
185  GsfTrackRef trackRef(gsftrackscoll, igsf);
186 
187  int kf_ind=FindPfRef(PfRTkColl,gsftracks[igsf],false);
188 
189  if (kf_ind>=0) {
190 
191  PFRecTrackRef kf_ref(thePfRecTrackCollection,
192  kf_ind);
193 
194  // remove fifth step tracks
195  if( useFifthStepForEcalDriven_ == false
196  || useFifthStepForTrackDriven_ == false) {
197 
198  bool isFifthStepTrack = PFTrackAlgoTools::isFifthStep(kf_ref->trackRef()->algo());
199  bool isEcalDriven = true;
200  bool isTrackerDriven = true;
201 
202  if (trackRef->seedRef().get()==nullptr) {
203  isEcalDriven = false;
204  isTrackerDriven = false;
205  }
206  else {
207  auto const& SeedFromRef= static_cast<ElectronSeed const&>(*(trackRef->extra()->seedRef()) );
208  if(SeedFromRef.caloCluster().isNull())
209  isEcalDriven = false;
210  if(SeedFromRef.ctfTrack().isNull())
211  isTrackerDriven = false;
212  }
213  //note: the same track could be both ecalDriven and trackerDriven
214  if(isFifthStepTrack &&
215  isEcalDriven &&
216  isTrackerDriven == false &&
217  useFifthStepForEcalDriven_ == false) {
218  continue;
219  }
220 
221  if(isFifthStepTrack &&
222  isTrackerDriven &&
223  isEcalDriven == false &&
224  useFifthStepForTrackDriven_ == false) {
225  continue;
226  }
227 
228  if(isFifthStepTrack &&
229  isTrackerDriven &&
230  isEcalDriven &&
231  useFifthStepForTrackDriven_ == false &&
232  useFifthStepForEcalDriven_ == false) {
233  continue;
234  }
235  }
236 
237  pftrack_=GsfPFRecTrack( gsftracks[igsf].charge(),
239  igsf, trackRef,
240  kf_ref);
241  } else {
242  PFRecTrackRef dummyRef;
243  pftrack_=GsfPFRecTrack( gsftracks[igsf].charge(),
245  igsf, trackRef,
246  dummyRef);
247  }
248 
249 
250  bool validgsfbrem = false;
251  if(trajinev_) {
252  validgsfbrem = pfTransformer_->addPointsAndBrems(pftrack_,
253  gsftracks[igsf],
254  tjvec[igsf],
255  modemomentum_);
256  } else {
257  validgsfbrem = pfTransformer_->addPointsAndBrems(pftrack_,
258  gsftracks[igsf],
259  mtsTransform_);
260  }
261 
262  bool passSel = true;
263  if(applySel_)
264  passSel = applySelection(gsftracks[igsf]);
265 
266  if(validgsfbrem && passSel)
267  selGsfPFRecTracks.push_back(pftrack_);
268  }
269 
270 
271  unsigned int count_primary = 0;
272  if(!selGsfPFRecTracks.empty()) {
273  for(unsigned int ipfgsf=0; ipfgsf<selGsfPFRecTracks.size();ipfgsf++) {
274 
275  vector<unsigned int> secondaries(0);
276  secondaries.clear();
277  bool keepGsf = true;
278 
279  if(applyGsfClean_) {
280  keepGsf = resolveGsfTracks(selGsfPFRecTracks,ipfgsf,secondaries,theEcalClusters);
281  }
282 
283  //is primary?
284  if(keepGsf == true) {
285 
286  // Find kf tracks from converted brem photons
287  if(convBremFinder_->foundConvBremPFRecTrack(thePfRecTrackCollection,thePrimaryVertexColl,
288  pfNuclears,pfConversions,pfV0,
289  globalCache(),
291  theEcalClusters,selGsfPFRecTracks[ipfgsf])) {
292  const vector<PFRecTrackRef>& convBremPFRecTracks(convBremFinder_->getConvBremPFRecTracks());
293  for(unsigned int ii = 0; ii<convBremPFRecTracks.size(); ii++) {
294  selGsfPFRecTracks[ipfgsf].addConvBremPFRecTrackRef(convBremPFRecTracks[ii]);
295  }
296  }
297 
298  // save primaries gsf tracks
299  // gsfPFRecTrackCollection->push_back(selGsfPFRecTracks[ipfgsf]);
300  primaryGsfPFRecTracks.push_back(selGsfPFRecTracks[ipfgsf]);
301 
302 
303  // NOTE:: THE TRACKID IS USED TO LINK THE PRIMARY GSF TRACK. THIS NEEDS
304  // TO BE CHANGED AS SOON AS IT IS POSSIBLE TO CHANGE DATAFORMATS
305  // A MODIFICATION HERE IMPLIES A MODIFICATION IN PFBLOCKALGO.CC/H
306  unsigned int primGsfIndex = selGsfPFRecTracks[ipfgsf].trackId();
307  vector<reco::GsfPFRecTrack> trueGsfPFRecTracks;
308  if(!secondaries.empty()) {
309  // loop on secondaries gsf tracks (from converted brems)
310  for(unsigned int isecpfgsf=0; isecpfgsf<secondaries.size();isecpfgsf++) {
311 
312  PFRecTrackRef refsecKF = selGsfPFRecTracks[(secondaries[isecpfgsf])].kfPFRecTrackRef();
313 
314  unsigned int secGsfIndex = selGsfPFRecTracks[(secondaries[isecpfgsf])].trackId();
315  GsfTrackRef secGsfRef = selGsfPFRecTracks[(secondaries[isecpfgsf])].gsfTrackRef();
316 
317  if(refsecKF.isNonnull()) {
318  // NOTE::IT SAVED THE TRACKID OF THE PRIMARY!!! THIS IS USED IN PFBLOCKALGO.CC/H
319  secpftrack_= GsfPFRecTrack( gsftracks[secGsfIndex].charge(),
321  primGsfIndex, secGsfRef,
322  refsecKF);
323  }
324  else{
325  PFRecTrackRef dummyRef;
326  // NOTE::IT SAVED THE TRACKID OF THE PRIMARY!!! THIS IS USED IN PFBLOCKALGO.CC/H
327  secpftrack_= GsfPFRecTrack( gsftracks[secGsfIndex].charge(),
329  primGsfIndex, secGsfRef,
330  dummyRef);
331  }
332 
333  bool validgsfbrem = false;
334  if(trajinev_) {
335  validgsfbrem = pfTransformer_->addPointsAndBrems(secpftrack_,
336  gsftracks[secGsfIndex],
337  tjvec[secGsfIndex],
338  modemomentum_);
339  } else {
340  validgsfbrem = pfTransformer_->addPointsAndBrems(secpftrack_,
341  gsftracks[secGsfIndex],
342  mtsTransform_);
343  }
344 
345  if(validgsfbrem) {
346  gsfPFRecTrackCollectionSecondary->push_back(secpftrack_);
347  trueGsfPFRecTracks.push_back(secpftrack_);
348  }
349  }
350  }
351  GsfPFMap.insert(pair<unsigned int,std::vector<reco::GsfPFRecTrack> >(count_primary,trueGsfPFRecTracks));
352  trueGsfPFRecTracks.clear();
353  count_primary++;
354  }
355  }
356  }
357 
358 
359  const edm::OrphanHandle<GsfPFRecTrackCollection> gsfPfRefProd =
360  iEvent.put(std::move(gsfPFRecTrackCollectionSecondary),"Secondary");
361 
362 
363  //now the secondary GsfPFRecTracks are in the event, the Ref can be created
364  createGsfPFRecTrackRef(gsfPfRefProd,primaryGsfPFRecTracks,GsfPFMap);
365 
366  for(unsigned int iGSF = 0; iGSF<primaryGsfPFRecTracks.size();iGSF++){
367  gsfPFRecTrackCollection->push_back(primaryGsfPFRecTracks[iGSF]);
368  }
369  iEvent.put(std::move(gsfPFRecTrackCollection));
370 
371  selGsfPFRecTracks.clear();
372  GsfPFMap.clear();
373  primaryGsfPFRecTracks.clear();
374 
375  std::vector<double>().swap(gsfInnerMomentumCache_);
376 }
377 
378 // create the secondary GsfPFRecTracks Ref
379 void
381  std::vector<reco::GsfPFRecTrack>& gsfPFRecTrackPrimary,
382  const std::map<unsigned int, std::vector<reco::GsfPFRecTrack> >& MapPrimSec) {
383  unsigned int cgsf=0;
384  unsigned int csecgsf=0;
385  for (std::map<unsigned int, std::vector<reco::GsfPFRecTrack> >::const_iterator igsf = MapPrimSec.begin();
386  igsf != MapPrimSec.end(); igsf++,cgsf++) {
387  vector<reco::GsfPFRecTrack> SecGsfPF = igsf->second;
388  for (unsigned int iSecGsf=0; iSecGsf < SecGsfPF.size(); iSecGsf++) {
389  edm::Ref<reco::GsfPFRecTrackCollection> refgprt(gsfPfHandle,csecgsf);
390  gsfPFRecTrackPrimary[cgsf].addConvBremGsfPFRecTrackRef(refgprt);
391  ++csecgsf;
392  }
393  }
394 
395  return;
396 }
397 // ------------- method for find the corresponding kf pfrectrack ---------------------
398 int
400  const reco::GsfTrack& gsftk,
401  bool otherColl){
402 
403 
404  if (gsftk.seedRef().get()==nullptr) return -1;
405  auto const & ElSeedFromRef=static_cast<ElectronSeed const&>( *(gsftk.extra()->seedRef()) );
406  //CASE 1 ELECTRONSEED DOES NOT HAVE A REF TO THE CKFTRACK
407  if (ElSeedFromRef.ctfTrack().isNull()){
408  reco::PFRecTrackCollection::const_iterator pft=PfRTkColl.begin();
409  reco::PFRecTrackCollection::const_iterator pftend=PfRTkColl.end();
410  unsigned int i_pf=0;
411  int ibest=-1;
412  unsigned int ish_max=0;
413  float dr_min=1000;
414  //SEARCH THE PFRECTRACK THAT SHARES HITS WITH THE ELECTRON SEED
415  // Here the cpu time can be improved.
416  for(;pft!=pftend;++pft){
417  unsigned int ish=0;
418 
419  float dph= fabs(pft->trackRef()->phi()-gsftk.phi());
420  if (dph>TMath::Pi()) dph-= TMath::TwoPi();
421  float det=fabs(pft->trackRef()->eta()-gsftk.eta());
422  float dr =sqrt(dph*dph+det*det);
423 
424  for(auto const& hhit : pft->trackRef()->recHits()) {
425  if (!hhit->isValid()) continue;
427  TrajectorySeed::const_iterator hit_end = gsftk.seedRef()->recHits().second;
428  for(;hit!=hit_end;++hit) {
429  if (!(hit->isValid())) continue;
430  if(hhit->sharesInput(&*(hit),TrackingRecHit::all)) ish++;
431  // if((hit->geographicalId()==hhit->geographicalId())&&
432  // ((hhit->localPosition()-hit->localPosition()).mag()<0.01)) ish++;
433  }
434  }
435 
436 
437  if ((ish>ish_max)||
438  ((ish==ish_max)&&(dr<dr_min))){
439  ish_max=ish;
440  dr_min=dr;
441  ibest=i_pf;
442  }
443 
444 
445 
446  i_pf++;
447  }
448  if (ibest<0) return -1;
449 
450  if((ish_max==0) || (dr_min>0.05))return -1;
451  if(otherColl && (ish_max==0)) return -1;
452  return ibest;
453  }
454  else{
455  //ELECTRON SEED HAS A REFERENCE
456 
457  reco::PFRecTrackCollection::const_iterator pft=PfRTkColl.begin();
458  reco::PFRecTrackCollection::const_iterator pftend=PfRTkColl.end();
459  unsigned int i_pf=0;
460 
461  for(;pft!=pftend;++pft){
462  //REF COMPARISON
463  if (pft->trackRef()==ElSeedFromRef.ctfTrack()){
464  return i_pf;
465  }
466  i_pf++;
467  }
468  }
469  return -1;
470 }
471 
472 // -- method to apply gsf electron selection to EcalDriven seeds
473 bool
475  if (gsftk.seedRef().get()==nullptr) return false;
476  auto const& ElSeedFromRef=static_cast<ElectronSeed const&>( *(gsftk.extra()->seedRef()) );
477 
478  bool passCut = false;
479  if (ElSeedFromRef.ctfTrack().isNull()){
480  if(ElSeedFromRef.caloCluster().isNull()) return passCut;
481  auto const* scRef = static_cast<SuperCluster const*>(ElSeedFromRef.caloCluster().get());
482  //do this just to know if exist a SC?
483  if(scRef) {
484  float caloEne = scRef->energy();
485  float feta = fabs(scRef->eta()-gsftk.etaMode());
486  float fphi = fabs(scRef->phi()-gsftk.phiMode());
487  if (fphi>TMath::Pi()) fphi-= TMath::TwoPi();
488  if(caloEne > SCEne_ && feta < detaGsfSC_ && fabs(fphi) < dphiGsfSC_)
489  passCut = true;
490  }
491  }
492  else {
493  // get all the gsf found by tracker driven
494  passCut = true;
495  }
496  return passCut;
497 }
498 bool
499 PFElecTkProducer::resolveGsfTracks(const vector<reco::GsfPFRecTrack> & GsfPFVec,
500  unsigned int ngsf,
501  vector<unsigned int> &secondaries,
502  const reco::PFClusterCollection & theEClus) {
503  bool debugCleaning = debugGsfCleaning_;
504  bool n_keepGsf = true;
505 
506  const reco::GsfTrackRef& nGsfTrack = GsfPFVec[ngsf].gsfTrackRef();
507 
508  if (nGsfTrack->seedRef().get()==nullptr) return false;
509  auto const& nElSeedFromRef=static_cast<ElectronSeed const&>( *(nGsfTrack->extra()->seedRef()) );
510 
511  /* // now gotten from cache below
512  TrajectoryStateOnSurface inTSOS = mtsTransform_.innerStateOnSurface((*nGsfTrack));
513  GlobalVector ninnMom;
514  float nPin = nGsfTrack->pMode();
515  if(inTSOS.isValid()){
516  multiTrajectoryStateMode::momentumFromModeCartesian(inTSOS,ninnMom);
517  nPin = ninnMom.mag();
518  }
519  */
520  float nPin = gsfInnerMomentumCache_[nGsfTrack.key()];
521 
522  float neta = nGsfTrack->innerMomentum().eta();
523  float nphi = nGsfTrack->innerMomentum().phi();
524 
525 
526 
527 
528  if(debugCleaning)
529  cout << " PFElecTkProducer:: considering track " << nGsfTrack->pt()
530  << " eta,phi " << nGsfTrack->eta() << ", " << nGsfTrack->phi() << endl;
531 
532 
533  for (unsigned int igsf=0; igsf< GsfPFVec.size();igsf++) {
534  if(igsf != ngsf ) {
535  reco::GsfTrackRef iGsfTrack = GsfPFVec[igsf].gsfTrackRef();
536 
537  if(debugCleaning)
538  cout << " PFElecTkProducer:: and comparing with track " << iGsfTrack->pt()
539  << " eta,phi " << iGsfTrack->eta() << ", " << iGsfTrack->phi() << endl;
540 
541  float ieta = iGsfTrack->innerMomentum().eta();
542  float iphi = iGsfTrack->innerMomentum().phi();
543  float feta = fabs(neta - ieta);
544  float fphi = fabs(nphi - iphi);
545  if (fphi>TMath::Pi()) fphi-= TMath::TwoPi();
546 
547 
548  // apply a superloose preselection only to avoid un-useful cpu time: hard-coded for this reason
549  if(feta < 0.5 && fabs(fphi) < 1.0) {
550  if(debugCleaning)
551  cout << " Entering angular superloose preselection " << endl;
552 
553  /* //now taken from cache below
554  TrajectoryStateOnSurface i_inTSOS = mtsTransform_.innerStateOnSurface((*iGsfTrack));
555  GlobalVector i_innMom;
556  float iPin = iGsfTrack->pMode();
557  if(i_inTSOS.isValid()){
558  multiTrajectoryStateMode::momentumFromModeCartesian(i_inTSOS,i_innMom);
559  iPin = i_innMom.mag();
560  }
561  */
562  float iPin = gsfInnerMomentumCache_[iGsfTrack.key()];
563 
564  if (iGsfTrack->seedRef().get()==nullptr) continue;
565  auto const& iElSeedFromRef=static_cast<ElectronSeed const&>( *(iGsfTrack->extra()->seedRef()) );
566 
567  float SCEnergy = -1.;
568  // Check if two tracks match the same SC
569  bool areBothGsfEcalDriven = false;;
570  bool isSameSC = isSameEgSC(nElSeedFromRef,iElSeedFromRef,areBothGsfEcalDriven,SCEnergy);
571 
572  // CASE1 both GsfTracks ecalDriven and match the same SC
573  if(areBothGsfEcalDriven ) {
574  if(isSameSC) {
575  float nEP = SCEnergy/nPin;
576  float iEP = SCEnergy/iPin;
577  if(debugCleaning)
578  cout << " Entering SAME supercluster case "
579  << " nEP " << nEP
580  << " iEP " << iEP << endl;
581 
582 
583 
584  // if same SC take the closest or if same
585  // distance the best E/p
586 
587  // Innermost using LostHits technology
588  bool isSameLayer = false;
589  bool iGsfInnermostWithLostHits =
590  isInnerMostWithLostHits(nGsfTrack,iGsfTrack,isSameLayer);
591 
592 
593  if(debugCleaning)
594  cout << " iGsf is InnerMostWithLostHits " << iGsfInnermostWithLostHits
595  << " isSameLayer " << isSameLayer << endl;
596 
597  if (iGsfInnermostWithLostHits) {
598  n_keepGsf = false;
599  return n_keepGsf;
600  }
601  else if(isSameLayer){
602  if(fabs(iEP-1) < fabs(nEP-1)) {
603  n_keepGsf = false;
604  return n_keepGsf;
605  }
606  else{
607  secondaries.push_back(igsf);
608  }
609  }
610  else {
611  // save secondaries gsf track (put selection)
612  secondaries.push_back(igsf);
613  }
614  } // end same SC case
615  }
616  else {
617  // enter in the condition where at least one track is trackerDriven
618  float minBremDphi = minTangDist(GsfPFVec[ngsf],GsfPFVec[igsf]);
619  float nETot = 0.;
620  float iETot = 0.;
621  bool isBothGsfTrackerDriven = false;
622  bool nEcalDriven = false;
623  bool iEcalDriven = false;
624  bool isSameScEgPf = isSharingEcalEnergyWithEgSC(GsfPFVec[ngsf],
625  GsfPFVec[igsf],
626  nElSeedFromRef,
627  iElSeedFromRef,
628  theEClus,
629  isBothGsfTrackerDriven,
630  nEcalDriven,
631  iEcalDriven,
632  nETot,
633  iETot);
634 
635  // check if the first hit of iGsfTrack < nGsfTrack
636  bool isSameLayer = false;
637  bool iGsfInnermostWithLostHits =
638  isInnerMostWithLostHits(nGsfTrack,iGsfTrack,isSameLayer);
639 
640  if(isSameScEgPf) {
641  // CASE 2 : One Gsf has reference to a SC and the other one not or both not
642 
643  if(debugCleaning) {
644  cout << " Sharing ECAL energy passed "
645  << " nEtot " << nETot
646  << " iEtot " << iETot << endl;
647  if(isBothGsfTrackerDriven)
648  cout << " Both Track are trackerDriven " << endl;
649  }
650 
651  // Innermost using LostHits technology
652  if (iGsfInnermostWithLostHits) {
653  n_keepGsf = false;
654  return n_keepGsf;
655  }
656  else if(isSameLayer){
657  // Thirt Case: One Gsf has reference to a SC and the other one not or both not
658  // gsf tracks starts from the same layer
659  // check number of sharing modules (at least 50%)
660  // check number of sharing hits (at least 2)
661  // check charge flip inner/outer
662 
663 
664  // they share energy
665  if(isBothGsfTrackerDriven == false) {
666  // if at least one Gsf track is EcalDriven choose that one.
667  if(iEcalDriven) {
668  n_keepGsf = false;
669  return n_keepGsf;
670  }
671  else {
672  secondaries.push_back(igsf);
673  }
674  }
675  else {
676  // if both tracks are tracker driven choose that one with the best E/p
677  // with ETot = max(En,Ei)
678 
679  float ETot = -1;
680  if(nETot != iETot) {
681  if(nETot > iETot)
682  ETot = nETot;
683  else
684  ETot = iETot;
685  }
686  else {
687  ETot = nETot;
688  }
689  float nEP = ETot/nPin;
690  float iEP = ETot/iPin;
691 
692 
693  if(debugCleaning)
694  cout << " nETot " << nETot
695  << " iETot " << iETot
696  << " ETot " << ETot << endl
697  << " nPin " << nPin
698  << " iPin " << iPin
699  << " nEP " << nEP
700  << " iEP " << iEP << endl;
701 
702 
703  if(fabs(iEP-1) < fabs(nEP-1)) {
704  n_keepGsf = false;
705  return n_keepGsf;
706  }
707  else{
708  secondaries.push_back(igsf);
709  }
710  }
711  }
712  else {
713  secondaries.push_back(igsf);
714  }
715  }
716  else if(feta < detaCutGsfClean_ && minBremDphi < dphiCutGsfClean_) {
717  // very close tracks
718  bool secPushedBack = false;
719  if(nEcalDriven == false && nETot == 0.) {
720  n_keepGsf = false;
721  return n_keepGsf;
722  }
723  else if(iEcalDriven == false && iETot == 0.) {
724  secondaries.push_back(igsf);
725  secPushedBack = true;
726  }
727  if(debugCleaning)
728  cout << " Close Tracks "
729  << " feta " << feta << " fabs(fphi) " << fabs(fphi)
730  << " minBremDphi " << minBremDphi
731  << " nETot " << nETot
732  << " iETot " << iETot
733  << " nLostHits " << nGsfTrack->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS)
734  << " iLostHits " << iGsfTrack->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS) << endl;
735 
736  // apply selection only if one track has lost hits
738  if (iGsfInnermostWithLostHits) {
739  n_keepGsf = false;
740  return n_keepGsf;
741  }
742  else if(isSameLayer == false) {
743  if(secPushedBack == false)
744  secondaries.push_back(igsf);
745  }
746  }
747  }
748  else if(feta < 0.1 && minBremDphi < 0.2){
749  // failed all the conditions, discard only tracker driven tracks
750  // with no PFClusters linked.
751  if(debugCleaning)
752  cout << " Close Tracks and failed all the conditions "
753  << " feta " << feta << " fabs(fphi) " << fabs(fphi)
754  << " minBremDphi " << minBremDphi
755  << " nETot " << nETot
756  << " iETot " << iETot
757  << " nLostHits " << nGsfTrack->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS)
758  << " iLostHits " << iGsfTrack->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS) << endl;
759 
760  if(nEcalDriven == false && nETot == 0.) {
761  n_keepGsf = false;
762  return n_keepGsf;
763  }
764  // Here I do not push back the secondary because considered fakes...
765  }
766  }
767  }
768  }
769  }
770 
771  return n_keepGsf;
772 }
773 float
775  const reco::GsfPFRecTrack& secGsf) {
776 
777  float minDphi = 1000.;
778 
779 
780  std::vector<reco::PFBrem> primPFBrem = primGsf.PFRecBrem();
781  std::vector<reco::PFBrem> secPFBrem = secGsf.PFRecBrem();
782 
783 
784  unsigned int cbrem = 0;
785  for (unsigned isbrem = 0; isbrem < secPFBrem.size(); isbrem++) {
786  if(secPFBrem[isbrem].indTrajPoint() == 99) continue;
787  const reco::PFTrajectoryPoint& atSecECAL
788  = secPFBrem[isbrem].extrapolatedPoint( reco::PFTrajectoryPoint::ECALEntrance );
789  if( ! atSecECAL.isValid() ) continue;
790  float secPhi = atSecECAL.positionREP().Phi();
791 
792  unsigned int sbrem = 0;
793  for(unsigned ipbrem = 0; ipbrem < primPFBrem.size(); ipbrem++) {
794  if(primPFBrem[ipbrem].indTrajPoint() == 99) continue;
795  const reco::PFTrajectoryPoint& atPrimECAL
796  = primPFBrem[ipbrem].extrapolatedPoint( reco::PFTrajectoryPoint::ECALEntrance );
797  if( ! atPrimECAL.isValid() ) continue;
798  sbrem++;
799  if(sbrem <= 3) {
800  float primPhi = atPrimECAL.positionREP().Phi();
801 
802  float dphi = fabs(primPhi - secPhi);
803  if (dphi>TMath::Pi()) dphi-= TMath::TwoPi();
804  if(fabs(dphi) < minDphi) {
805  minDphi = fabs(dphi);
806  }
807  }
808  }
809 
810 
811  cbrem++;
812  if(cbrem == 3)
813  break;
814  }
815  return minDphi;
816 }
817 bool
819  const reco::ElectronSeed& iSeed,
820  bool& bothGsfEcalDriven,
821  float& SCEnergy) {
822 
823  bool isSameSC = false;
824 
825  if(nSeed.caloCluster().isNonnull() && iSeed.caloCluster().isNonnull()) {
826  auto const* nscRef = static_cast<SuperCluster const*>(nSeed.caloCluster().get());
827  auto const* iscRef = static_cast<SuperCluster const*>(iSeed.caloCluster().get());
828 
829  if(nscRef && iscRef) {
830  bothGsfEcalDriven = true;
831  if(nscRef == iscRef) {
832  isSameSC = true;
833  // retrieve the supercluster energy
834  SCEnergy = nscRef->energy();
835  }
836  }
837  }
838  return isSameSC;
839 }
840 bool
842  const reco::GsfPFRecTrack& iGsfPFRecTrack,
843  const reco::ElectronSeed& nSeed,
844  const reco::ElectronSeed& iSeed,
845  const reco::PFClusterCollection& theEClus,
846  bool& bothGsfTrackerDriven,
847  bool& nEcalDriven,
848  bool& iEcalDriven,
849  float& nEnergy,
850  float& iEnergy) {
851 
852  bool isSharingEnergy = false;
853 
854  //which is EcalDriven?
855  bool oneEcalDriven = true;
856  SuperCluster const* scRef = nullptr;
857  GsfPFRecTrack gsfPfTrack;
858 
859  if(nSeed.caloCluster().isNonnull()) {
860  scRef = static_cast<SuperCluster const*>(nSeed.caloCluster().get());
861  assert(scRef);
862  nEnergy = scRef->energy();
863  nEcalDriven = true;
864  gsfPfTrack = iGsfPFRecTrack;
865  }
866  else if(iSeed.caloCluster().isNonnull()){
867  scRef = static_cast<SuperCluster const*>(iSeed.caloCluster().get());
868  assert(scRef);
869  iEnergy = scRef->energy();
870  iEcalDriven = true;
871  gsfPfTrack = nGsfPFRecTrack;
872  }
873  else{
874  oneEcalDriven = false;
875  }
876 
877  if(oneEcalDriven) {
878  //run a basic reconstruction for the particle flow
879 
880  vector<PFCluster> vecPFClusters;
881  vecPFClusters.clear();
882 
883  for (PFClusterCollection::const_iterator clus = theEClus.begin();
884  clus != theEClus.end();
885  clus++ ) {
886  PFCluster clust = *clus;
887  clust.calculatePositionREP();
888 
889  float deta = fabs(scRef->position().eta() - clust.position().eta());
890  float dphi = fabs(scRef->position().phi() - clust.position().phi());
891  if (dphi>TMath::Pi()) dphi-= TMath::TwoPi();
892 
893  // Angle preselection between the supercluster and pfclusters
894  // this is needed just to save some cpu-time for this is hard-coded
895  if(deta < 0.5 && fabs(dphi) < 1.0) {
896  double distGsf = gsfPfTrack.extrapolatedPoint( reco::PFTrajectoryPoint::ECALShowerMax ).isValid() ?
897  LinkByRecHit::testTrackAndClusterByRecHit(gsfPfTrack , clust ) : -1.;
898  // check if it touch the GsfTrack
899  if(distGsf > 0.) {
900  if(nEcalDriven)
901  iEnergy += clust.energy();
902  else
903  nEnergy += clust.energy();
904  vecPFClusters.push_back(clust);
905  }
906  // check if it touch the Brem-tangents
907  else {
908  vector<PFBrem> primPFBrem = gsfPfTrack.PFRecBrem();
909  for(unsigned ipbrem = 0; ipbrem < primPFBrem.size(); ipbrem++) {
910  if(primPFBrem[ipbrem].indTrajPoint() == 99) continue;
911  const reco::PFRecTrack& pfBremTrack = primPFBrem[ipbrem];
912  double dist = pfBremTrack.extrapolatedPoint( reco::PFTrajectoryPoint::ECALShowerMax ).isValid() ?
913  LinkByRecHit::testTrackAndClusterByRecHit(pfBremTrack , clust, true ) : -1.;
914  if(dist > 0.) {
915  if(nEcalDriven)
916  iEnergy += clust.energy();
917  else
918  nEnergy += clust.energy();
919  vecPFClusters.push_back(clust);
920  }
921  }
922  }
923  } // END if angle preselection
924  } // PFClusters Loop
925  if(!vecPFClusters.empty() ) {
926  for(unsigned int pf = 0; pf < vecPFClusters.size(); pf++) {
927  bool isCommon = ClusterClusterMapping::overlap(vecPFClusters[pf],*scRef);
928  if(isCommon) {
929  isSharingEnergy = true;
930  }
931  break;
932  }
933  }
934  }
935  else {
936  // both tracks are trackerDriven, try ECAL energy matching also in this case.
937 
938  bothGsfTrackerDriven = true;
939  vector<PFCluster> nPFCluster;
940  vector<PFCluster> iPFCluster;
941 
942  nPFCluster.clear();
943  iPFCluster.clear();
944 
945  for (PFClusterCollection::const_iterator clus = theEClus.begin();
946  clus != theEClus.end();
947  clus++ ) {
948  PFCluster clust = *clus;
949  clust.calculatePositionREP();
950 
951  float ndeta = fabs(nGsfPFRecTrack.gsfTrackRef()->eta() - clust.position().eta());
952  float ndphi = fabs(nGsfPFRecTrack.gsfTrackRef()->phi() - clust.position().phi());
953  if (ndphi>TMath::Pi()) ndphi-= TMath::TwoPi();
954  // Apply loose preselection with the track
955  // just to save cpu time, for this hard-coded
956  if(ndeta < 0.5 && fabs(ndphi) < 1.0) {
957 
958  double distGsf = nGsfPFRecTrack.extrapolatedPoint( reco::PFTrajectoryPoint::ECALShowerMax ).isValid() ?
959  LinkByRecHit::testTrackAndClusterByRecHit(nGsfPFRecTrack , clust ) : -1.;
960  if(distGsf > 0.) {
961  nPFCluster.push_back(clust);
962  nEnergy += clust.energy();
963  }
964  else {
965  const vector<PFBrem>& primPFBrem = nGsfPFRecTrack.PFRecBrem();
966  for(unsigned ipbrem = 0; ipbrem < primPFBrem.size(); ipbrem++) {
967  if(primPFBrem[ipbrem].indTrajPoint() == 99) continue;
968  const reco::PFRecTrack& pfBremTrack = primPFBrem[ipbrem];
969  double dist = pfBremTrack.extrapolatedPoint( reco::PFTrajectoryPoint::ECALShowerMax ).isValid() ?
970  LinkByRecHit::testTrackAndClusterByRecHit(pfBremTrack , clust, true ) : -1.;
971  if(dist > 0.) {
972  nPFCluster.push_back(clust);
973  nEnergy += clust.energy();
974  break;
975  }
976  }
977  }
978  }
979 
980  float ideta = fabs(iGsfPFRecTrack.gsfTrackRef()->eta() - clust.position().eta());
981  float idphi = fabs(iGsfPFRecTrack.gsfTrackRef()->phi() - clust.position().phi());
982  if (idphi>TMath::Pi()) idphi-= TMath::TwoPi();
983  // Apply loose preselection with the track
984  // just to save cpu time, for this hard-coded
985  if(ideta < 0.5 && fabs(idphi) < 1.0) {
986  double dist = iGsfPFRecTrack.extrapolatedPoint( reco::PFTrajectoryPoint::ECALShowerMax ).isValid() ?
987  LinkByRecHit::testTrackAndClusterByRecHit(iGsfPFRecTrack , clust ) : -1.;
988  if(dist > 0.) {
989  iPFCluster.push_back(clust);
990  iEnergy += clust.energy();
991  }
992  else {
993  vector<PFBrem> primPFBrem = iGsfPFRecTrack.PFRecBrem();
994  for(unsigned ipbrem = 0; ipbrem < primPFBrem.size(); ipbrem++) {
995  if(primPFBrem[ipbrem].indTrajPoint() == 99) continue;
996  const reco::PFRecTrack& pfBremTrack = primPFBrem[ipbrem];
997  double dist = LinkByRecHit::testTrackAndClusterByRecHit(pfBremTrack , clust, true );
998  if(dist > 0.) {
999  iPFCluster.push_back(clust);
1000  iEnergy += clust.energy();
1001  break;
1002  }
1003  }
1004  }
1005  }
1006  }
1007 
1008 
1009  if(!nPFCluster.empty() && !iPFCluster.empty()) {
1010  for(unsigned int npf = 0; npf < nPFCluster.size(); npf++) {
1011  for(unsigned int ipf = 0; ipf < iPFCluster.size(); ipf++) {
1012  bool isCommon = ClusterClusterMapping::overlap(nPFCluster[npf],iPFCluster[ipf]);
1013  if(isCommon) {
1014  isSharingEnergy = true;
1015  break;
1016  }
1017  }
1018  if(isSharingEnergy)
1019  break;
1020  }
1021  }
1022  }
1023 
1024  return isSharingEnergy;
1025 }
1027  const reco::GsfTrackRef& iGsfTrack,
1028  bool& sameLayer) {
1029 
1030  // copied by the class RecoEgamma/EgammaElectronAlgos/src/EgAmbiguityTools.cc
1031  // obsolete but the code is kept: now using lost hits method
1032 
1033  const reco::HitPattern &gsfHitPattern1 = nGsfTrack->hitPattern();
1034  const reco::HitPattern &gsfHitPattern2 = iGsfTrack->hitPattern();
1035 
1036  // retrieve first valid hit
1037  int gsfHitCounter1 = 0 ;
1038  for(auto const& hit : nGsfTrack->recHits()) {
1039  if (hit->isValid()) break ;
1040  gsfHitCounter1++;
1041  }
1042 
1043  int gsfHitCounter2 = 0 ;
1044  for(auto const& hit : iGsfTrack->recHits()) {
1045  if (hit->isValid()) break ;
1046  gsfHitCounter2++;
1047  }
1048 
1049  uint32_t gsfHit1 = gsfHitPattern1.getHitPattern(HitPattern::TRACK_HITS, gsfHitCounter1) ;
1050  uint32_t gsfHit2 = gsfHitPattern2.getHitPattern(HitPattern::TRACK_HITS, gsfHitCounter2) ;
1051 
1052 
1053  if (gsfHitPattern1.getSubStructure(gsfHit1)!=gsfHitPattern2.getSubStructure(gsfHit2))
1054  {
1055  return (gsfHitPattern2.getSubStructure(gsfHit2)<gsfHitPattern1.getSubStructure(gsfHit1));
1056  }
1057  else if (gsfHitPattern1.getLayer(gsfHit1)!=gsfHitPattern2.getLayer(gsfHit2))
1058  {
1059  return (gsfHitPattern2.getLayer(gsfHit2)<gsfHitPattern1.getLayer(gsfHit1));
1060  }
1061  else
1062  {
1063  sameLayer = true;
1064  return false;
1065  }
1066 }
1068  const reco::GsfTrackRef& iGsfTrack,
1069  bool& sameLayer) {
1070 
1071  // define closest using the lost hits on the expectedhitsineer
1072  unsigned int nLostHits = nGsfTrack->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS);
1073  unsigned int iLostHits = iGsfTrack->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS);
1074 
1075  if (nLostHits!=iLostHits) {
1076  return (nLostHits > iLostHits);
1077  }
1078  else {
1079  sameLayer = true;
1080  return false;
1081  }
1082 }
1083 
1084 
1085 
1086 // ------------ method called once each job just before starting event loop ------------
1087 void
1089  const EventSetup& iSetup)
1090 {
1092  iSetup.get<IdealMagneticFieldRecord>().get(magneticField);
1093 
1095  iSetup.get<TrackerDigiGeometryRecord>().get(tracker);
1096 
1097  mtsTransform_ = MultiTrajectoryStateTransform(tracker.product(),magneticField.product());
1098 
1099  pfTransformer_.reset( new PFTrackTransformer(math::XYZVector(magneticField->inTesla(GlobalPoint(0,0,0)))) );
1100 
1102  iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder", builder);
1103  TransientTrackBuilder thebuilder = *(builder.product());
1104 
1105  convBremFinder_.reset( new ConvBremPFTrackFinder(thebuilder,
1110 
1111 }
1112 
1113 // ------------ method called once each job just after ending the event loop ------------
1114 void
1116  const EventSetup& iSetup) {
1117  pfTransformer_.reset();
1118  convBremFinder_.reset();
1119 }
1120 
1121 //define this as a plug-in
const REPPoint & positionREP() const
trajectory position in (rho, eta, phi) base
bool trajinev_
Trajectory of GSfTracks in the event?
const double TwoPi
const double Pi
const edm::RefToBase< TrajectorySeed > & seedRef() const
Definition: Track.h:218
value_type const * get() const
Definition: RefToBase.h:234
T getParameter(std::string const &) const
const math::XYZPoint & position() const
cluster centroid position
Definition: CaloCluster.h:131
reconstructed track used as an input to particle flow
Definition: PFRecTrack.h:22
edm::EDGetTokenT< reco::PFRecTrackCollection > pfTrackLabel_
static uint32_t getLayer(uint16_t pattern)
Definition: HitPattern.h:759
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:125
static bool overlap(const reco::CaloCluster &sc1, const reco::CaloCluster &sc, float minfrac=0.01, bool debug=false)
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:251
edm::EDGetTokenT< reco::GsfTrackCollection > gsfTrackLabel_
void createGsfPFRecTrackRef(const edm::OrphanHandle< reco::GsfPFRecTrackCollection > &gsfPfHandle, std::vector< reco::GsfPFRecTrack > &gsfPFRecTrackPrimary, const std::map< unsigned int, std::vector< reco::GsfPFRecTrack > > &MapPrimSec)
const TrackExtraRef & extra() const
reference to "extra" object
Definition: Track.h:194
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
Definition: PFCluster.h:47
double mvaConvBremFinderIDEndcapsLowPt_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
const std::vector< reco::PFBrem > & PFRecBrem() const
Definition: GsfPFRecTrack.h:51
const CaloClusterRef & caloCluster() const
Definition: ElectronSeed.h:94
double phi() const
azimuthal angle of momentum vector
Definition: TrackBase.h:678
bool applySelection(const reco::GsfTrack &)
bool isNonnull() const
Checks for non-null.
Definition: RefToBase.h:340
key_type key() const
Accessor for product key.
Definition: Ref.h:263
reco::GsfPFRecTrack secpftrack_
std::unique_ptr< ConvBremPFTrackFinder > convBremFinder_
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:116
~PFElecTkProducer() override
Destructor.
edm::EDGetTokenT< reco::VertexCollection > primVtxLabel_
double mvaConvBremFinderIDBarrelLowPt_
int iEvent
Definition: GenABIO.cc:224
T mag() const
Definition: PV3DBase.h:67
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:684
void calculatePositionREP()
computes posrep_ once and for all
Definition: PFCluster.h:100
edm::EDGetTokenT< reco::PFV0Collection > pfV0_
const reco::GsfTrackRef & gsfTrackRef() const
Definition: GsfPFRecTrack.h:39
recHitContainer::const_iterator const_iterator
T sqrt(T t)
Definition: SSEVec.h:18
std::vector< GsfTrack > GsfTrackCollection
collection of GsfTracks
Definition: GsfTrackFwd.h:9
double energy() const
cluster energy
Definition: CaloCluster.h:126
edm::EDGetTokenT< reco::PFDisplacedTrackerVertexCollection > pfNuclear_
const reco::PFTrajectoryPoint & extrapolatedPoint(unsigned layerid) const
Definition: PFTrack.cc:76
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:243
bool isSameEgSC(const reco::ElectronSeed &nSeed, const reco::ElectronSeed &iSeed, bool &bothGsfEcalDriven, float &SCEnergy)
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
static uint32_t getSubStructure(uint16_t pattern)
Definition: HitPattern.h:750
double energy() const
cluster energy
Definition: PFCluster.h:82
ii
Definition: cuy.py:590
bool isInnerMostWithLostHits(const reco::GsfTrackRef &nGsfTrack, const reco::GsfTrackRef &iGsfTrack, bool &sameLayer)
PFElecTkProducer(const edm::ParameterSet &, const convbremhelpers::HeavyObjectCache *)
Constructor.
void endRun(const edm::Run &, const edm::EventSetup &) override
int FindPfRef(const reco::PFRecTrackCollection &PfRTkColl, const reco::GsfTrack &, bool)
bool resolveGsfTracks(const std::vector< reco::GsfPFRecTrack > &GsfPFVec, unsigned int ngsf, std::vector< unsigned int > &secondaries, const reco::PFClusterCollection &theEClus)
bool isValid() const
is this point valid ?
T const * product() const
Definition: Handle.h:74
bool isFifthStep(const reco::TrackBase::TrackAlgorithm &)
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:30
range recHits() const
double mvaConvBremFinderIDBarrelHighPt_
double mvaConvBremFinderIDEndcapsHighPt_
edm::EDGetTokenT< reco::PFConversionCollection > pfConv_
std::vector< Trajectory > TrajectoryCollection
TrajectoryStateOnSurface innerStateOnSurface(const reco::GsfTrack &tk) const
void beginRun(const edm::Run &, const edm::EventSetup &) override
fixed size matrix
HLT enums.
double etaMode() const
pseudorapidity of momentum vector from mode
Definition: GsfTrack.h:59
T get() const
Definition: EventSetup.h:71
reco::GsfPFRecTrack pftrack_
void produce(edm::Event &, const edm::EventSetup &) override
Produce the PFRecTrack collection.
double phiMode() const
azimuthal angle of momentum vector from mode
Definition: GsfTrack.h:57
bool useConvBremFinder_
Conv Brem Finder.
std::vector< PFCluster > PFClusterCollection
collection of PFCluster objects
Definition: PFClusterFwd.h:9
A PFTrack holds several trajectory points, which basically contain the position and momentum of a tra...
std::unique_ptr< PFTrackTransformer > pfTransformer_
PFTrackTransformer.
std::vector< double > gsfInnerMomentumCache_
bool momentumFromModeCartesian(TrajectoryStateOnSurface const &tsos, GlobalVector &momentum)
uint16_t getHitPattern(HitCategory category, int position) const
Definition: HitPattern.h:553
T const * product() const
Definition: ESHandle.h:86
static double testTrackAndClusterByRecHit(const reco::PFRecTrack &track, const reco::PFCluster &cluster, bool isBrem=false, bool debug=false)
Definition: LinkByRecHit.cc:18
float minTangDist(const reco::GsfPFRecTrack &primGsf, const reco::GsfPFRecTrack &secGsf)
std::vector< PFRecTrack > PFRecTrackCollection
collection of PFRecTrack objects
Definition: PFRecTrackFwd.h:9
edm::EDGetTokenT< reco::PFClusterCollection > pfEcalClusters_
bool isSharingEcalEnergyWithEgSC(const reco::GsfPFRecTrack &nGsfPFRecTrack, const reco::GsfPFRecTrack &iGsfPFRecTrack, const reco::ElectronSeed &nSeed, const reco::ElectronSeed &iSeed, const reco::PFClusterCollection &theEClus, bool &bothGsfTrackerDriven, bool &nEcalDriven, bool &iEcalDriven, float &nEnergy, float &iEnergy)
def move(src, dest)
Definition: eostools.py:511
Definition: Run.h:45
MultiTrajectoryStateTransform mtsTransform_
bool isInnerMost(const reco::GsfTrackRef &nGsfTrack, const reco::GsfTrackRef &iGsfTrack, bool &sameLayer)