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