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