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