CMS 3D CMS Logo

PATIsolatedTrackProducer.cc
Go to the documentation of this file.
1 #include <string>
2 
10 
12 
29 
33 
39 
41 
42 namespace pat {
43 
45  public:
48 
50  ~PATIsolatedTrackProducer() override;
51 
52  void produce(edm::Event&, const edm::EventSetup&) override;
53 
54  // compute iso/miniiso
55  void getIsolation(const PolarLorentzVector& p4,
57  int pc_idx,
58  pat::PFIsolation& iso,
59  pat::PFIsolation& miniiso) const;
60 
62 
63  float getPFNeutralSum(const PolarLorentzVector& p4, const pat::PackedCandidateCollection* pc, int pc_idx) const;
64 
65  void getNearestPCRef(const PolarLorentzVector& p4,
67  int pc_idx,
68  int& pc_ref_idx) const;
69 
70  float getDeDx(const reco::DeDxHitInfo* hitInfo, bool doPixel, bool doStrip) const;
71 
73 
74  void getCaloJetEnergy(const PolarLorentzVector&, const reco::CaloJetCollection*, float&, float&) const;
75 
76  private:
95  const float pT_cut_; // only save cands with pT>pT_cut_
96  const float pT_cut_noIso_; // above this pT, don't apply any iso cut
97  const float pfIsolation_DR_; // isolation radius
98  const float pfIsolation_DZ_; // used in determining if pfcand is from PV or PU
99  const float absIso_cut_; // save if ANY of absIso, relIso, or miniRelIso pass the cuts
100  const float relIso_cut_;
101  const float miniRelIso_cut_;
102  const float caloJet_DR_; // save energy of nearest calojet within caloJet_DR_
103  const float pflepoverlap_DR_; // pf lepton overlap radius
104  const float pflepoverlap_pTmin_; // pf lepton overlap min pT (only look at PF candidates with pT>pflepoverlap_pTmin_)
105  const float pcRefNearest_DR_; // radius for nearest charged packed candidate
106  const float pcRefNearest_pTmin_; // min pT for nearest charged packed candidate
107  const float pfneutralsum_DR_; // pf lepton overlap radius
108  const bool useHighPurity_;
109  const bool saveDeDxHitInfo_;
111 
112  std::vector<double> miniIsoParams_;
113 
116  };
117 } // namespace pat
118 
120  : pc_(consumes<pat::PackedCandidateCollection>(iConfig.getParameter<edm::InputTag>("packedPFCandidates"))),
121  lt_(consumes<pat::PackedCandidateCollection>(iConfig.getParameter<edm::InputTag>("lostTracks"))),
122  gt_(consumes<reco::TrackCollection>(iConfig.getParameter<edm::InputTag>("generalTracks"))),
123  pv_(consumes<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("primaryVertices"))),
124  gt2pc_(consumes<edm::Association<pat::PackedCandidateCollection>>(
125  iConfig.getParameter<edm::InputTag>("packedPFCandidates"))),
126  gt2lt_(consumes<edm::Association<pat::PackedCandidateCollection>>(
127  iConfig.getParameter<edm::InputTag>("lostTracks"))),
128  pc2pf_(consumes<edm::Association<reco::PFCandidateCollection>>(
129  iConfig.getParameter<edm::InputTag>("packedPFCandidates"))),
130  caloJets_(consumes<reco::CaloJetCollection>(iConfig.getParameter<edm::InputTag>("caloJets"))),
131  gt2dedxStrip_(consumes<edm::ValueMap<reco::DeDxData>>(iConfig.getParameter<edm::InputTag>("dEdxDataStrip"))),
132  gt2dedxPixel_(consumes<edm::ValueMap<reco::DeDxData>>(iConfig.getParameter<edm::InputTag>("dEdxDataPixel"))),
133  gt2dedxHitInfo_(consumes<reco::DeDxHitInfoAss>(iConfig.getParameter<edm::InputTag>("dEdxHitInfo"))),
134  hcalQToken_(esConsumes(edm::ESInputTag("", "withTopo"))),
135  ecalSToken_(esConsumes()),
136  bFieldToken_(esConsumes()),
137  addPrescaledDeDxTracks_(iConfig.getParameter<bool>("addPrescaledDeDxTracks")),
138  gt2dedxHitInfoPrescale_(addPrescaledDeDxTracks_ ? consumes<edm::ValueMap<int>>(
139  iConfig.getParameter<edm::InputTag>("dEdxHitInfoPrescale"))
140  : edm::EDGetTokenT<edm::ValueMap<int>>()),
141  usePrecomputedDeDxStrip_(iConfig.getParameter<bool>("usePrecomputedDeDxStrip")),
142  usePrecomputedDeDxPixel_(iConfig.getParameter<bool>("usePrecomputedDeDxPixel")),
143  pT_cut_(iConfig.getParameter<double>("pT_cut")),
144  pT_cut_noIso_(iConfig.getParameter<double>("pT_cut_noIso")),
145  pfIsolation_DR_(iConfig.getParameter<double>("pfIsolation_DR")),
146  pfIsolation_DZ_(iConfig.getParameter<double>("pfIsolation_DZ")),
147  absIso_cut_(iConfig.getParameter<double>("absIso_cut")),
148  relIso_cut_(iConfig.getParameter<double>("relIso_cut")),
149  miniRelIso_cut_(iConfig.getParameter<double>("miniRelIso_cut")),
150  caloJet_DR_(iConfig.getParameter<double>("caloJet_DR")),
151  pflepoverlap_DR_(iConfig.getParameter<double>("pflepoverlap_DR")),
152  pflepoverlap_pTmin_(iConfig.getParameter<double>("pflepoverlap_pTmin")),
153  pcRefNearest_DR_(iConfig.getParameter<double>("pcRefNearest_DR")),
154  pcRefNearest_pTmin_(iConfig.getParameter<double>("pcRefNearest_pTmin")),
155  pfneutralsum_DR_(iConfig.getParameter<double>("pfneutralsum_DR")),
156  useHighPurity_(iConfig.getParameter<bool>("useHighPurity")),
157  saveDeDxHitInfo_(iConfig.getParameter<bool>("saveDeDxHitInfo")),
158  saveDeDxHitInfoCut_(iConfig.getParameter<std::string>("saveDeDxHitInfoCut")) {
159  // TrackAssociator parameters
160  edm::ParameterSet parameters = iConfig.getParameter<edm::ParameterSet>("TrackAssociatorParameters");
161  edm::ConsumesCollector iC = consumesCollector();
163 
165 
166  miniIsoParams_ = iConfig.getParameter<std::vector<double>>("miniIsoParams");
167  if (miniIsoParams_.size() != 3)
168  throw cms::Exception("ParameterError") << "miniIsoParams must have exactly 3 elements.\n";
169 
170  produces<pat::IsolatedTrackCollection>();
171 
172  if (saveDeDxHitInfo_) {
173  produces<reco::DeDxHitInfoCollection>();
174  produces<reco::DeDxHitInfoAss>();
175  }
176 }
177 
179 
181  // packedPFCandidate collection
183  iEvent.getByToken(pc_, pc_h);
184  const pat::PackedCandidateCollection* pc = pc_h.product();
185 
186  // lostTracks collection
188  iEvent.getByToken(lt_, lt_h);
189  const pat::PackedCandidateCollection* lt = lt_h.product();
190 
191  // generalTracks collection
193  iEvent.getByToken(gt_, gt_h);
195 
196  // get the primary vertex
198  iEvent.getByToken(pv_, pvs);
199  const reco::Vertex& pv = (*pvs)[0];
200 
201  // generalTracks-->packedPFCandidate association
203  iEvent.getByToken(gt2pc_, gt2pc);
204 
205  // generalTracks-->lostTracks association
207  iEvent.getByToken(gt2lt_, gt2lt);
208 
209  // packedPFCandidates-->particleFlow(reco::PFCandidate) association
211  iEvent.getByToken(pc2pf_, pc2pf);
212 
214  iEvent.getByToken(caloJets_, caloJets);
215 
216  // associate generalTracks with their DeDx data (estimator for strip dE/dx)
218  iEvent.getByToken(gt2dedxStrip_, gt2dedxStrip);
219 
220  // associate generalTracks with their DeDx data (estimator for pixel dE/dx)
222  iEvent.getByToken(gt2dedxPixel_, gt2dedxPixel);
223 
224  // associate generalTracks with their DeDx hit info (used to estimate pixel dE/dx)
225  edm::Handle<reco::DeDxHitInfoAss> gt2dedxHitInfo;
226  iEvent.getByToken(gt2dedxHitInfo_, gt2dedxHitInfo);
227  edm::Handle<edm::ValueMap<int>> gt2dedxHitInfoPrescale;
228  if (addPrescaledDeDxTracks_) {
229  iEvent.getByToken(gt2dedxHitInfoPrescale_, gt2dedxHitInfoPrescale);
230  }
231 
232  const HcalChannelQuality* hcalQ = &iSetup.getData(hcalQToken_);
233 
234  const EcalChannelStatus* ecalS = &iSetup.getData(ecalSToken_);
235 
236  auto outDeDxC = std::make_unique<reco::DeDxHitInfoCollection>();
237  std::vector<int> dEdXass;
238 
239  auto outPtrP = std::make_unique<std::vector<pat::IsolatedTrack>>();
240 
241  //add general tracks
242  for (unsigned int igt = 0; igt < generalTracks->size(); igt++) {
243  const reco::Track& gentk = (*gt_h)[igt];
244  if (useHighPurity_)
245  if (!(gentk.quality(reco::TrackBase::qualityByName("highPurity"))))
246  continue;
247  reco::TrackRef tkref = reco::TrackRef(gt_h, igt);
248  pat::PackedCandidateRef pcref = (*gt2pc)[tkref];
249  pat::PackedCandidateRef ltref = (*gt2lt)[tkref];
250  const pat::PackedCandidate* pfCand = pcref.get();
251  const pat::PackedCandidate* lostTrack = ltref.get();
252 
253  // Determine if this general track is associated with anything in packedPFCandidates or lostTracks
254  // Sometimes, a track gets associated w/ a neutral pfCand.
255  // In this case, ignore the pfCand and take from lostTracks
256  bool isInPackedCands = (pcref.isNonnull() && pcref.id() == pc_h.id() && pfCand->charge() != 0);
257  bool isInLostTracks = (ltref.isNonnull() && ltref.id() == lt_h.id());
258 
259  PolarLorentzVector polarP4;
260  LorentzVector p4;
261  pat::PackedCandidateRef refToCand;
262  int pdgId, charge, fromPV;
263  float dz, dxy, dzError, dxyError;
264  int pfCandInd; //to avoid counting packedPFCands in their own isolation
265  int ltCandInd; //to avoid pointing lost track to itself when looking for closest
266 
267  // get the four-momentum and charge
268  if (isInPackedCands) {
269  p4 = pfCand->p4();
270  polarP4 = pfCand->p4();
271  charge = pfCand->charge();
272  pfCandInd = pcref.key();
273  ltCandInd = -1;
274  } else if (isInLostTracks) {
275  p4 = lostTrack->p4();
276  polarP4 = lostTrack->p4();
277  charge = lostTrack->charge();
278  pfCandInd = -1;
279  ltCandInd = ltref.key();
280  } else {
281  double m = 0.13957018; //assume pion mass
282  double E = sqrt(m * m + gentk.p() * gentk.p());
283  p4.SetPxPyPzE(gentk.px(), gentk.py(), gentk.pz(), E);
284  polarP4.SetCoordinates(gentk.pt(), gentk.eta(), gentk.phi(), m);
285  charge = gentk.charge();
286  pfCandInd = -1;
287  ltCandInd = -1;
288  }
289 
290  int prescaled = 0;
291  if (addPrescaledDeDxTracks_) {
292  const auto& dedxRef = (*gt2dedxHitInfo)[tkref];
293  if (dedxRef.isNonnull()) {
294  prescaled = (*gt2dedxHitInfoPrescale)[dedxRef];
295  }
296  }
297 
298  if (polarP4.pt() < pT_cut_ && prescaled <= 1)
299  continue;
300  if (charge == 0)
301  continue;
302 
303  // get the isolation of the track
304  pat::PFIsolation isolationDR03;
305  pat::PFIsolation miniIso;
306  getIsolation(polarP4, pc, pfCandInd, isolationDR03, miniIso);
307 
308  // isolation cut
309  if (polarP4.pt() < pT_cut_noIso_ && prescaled <= 1 &&
310  !(isolationDR03.chargedHadronIso() < absIso_cut_ ||
311  isolationDR03.chargedHadronIso() / polarP4.pt() < relIso_cut_ ||
312  miniIso.chargedHadronIso() / polarP4.pt() < miniRelIso_cut_))
313  continue;
314 
315  // get the rest after the pt/iso cuts. Saves some runtime
316  if (isInPackedCands) {
317  pdgId = pfCand->pdgId();
318  dz = pfCand->dz();
319  dxy = pfCand->dxy();
320  dzError = pfCand->hasTrackDetails() ? pfCand->dzError() : gentk.dzError();
321  dxyError = pfCand->hasTrackDetails() ? pfCand->dxyError() : gentk.dxyError();
322  fromPV = pfCand->fromPV();
323  refToCand = pcref;
324  } else if (isInLostTracks) {
325  pdgId = lostTrack->pdgId();
326  dz = lostTrack->dz();
327  dxy = lostTrack->dxy();
328  dzError = lostTrack->hasTrackDetails() ? lostTrack->dzError() : gentk.dzError();
329  dxyError = lostTrack->hasTrackDetails() ? lostTrack->dxyError() : gentk.dxyError();
330  fromPV = lostTrack->fromPV();
331  refToCand = ltref;
332  } else {
333  pdgId = 0;
334  dz = gentk.dz(pv.position());
335  dxy = gentk.dxy(pv.position());
336  dzError = gentk.dzError();
337  dxyError = gentk.dxyError();
338  fromPV = -1;
339  refToCand = pat::PackedCandidateRef(); //NULL reference
340  }
341 
342  float caloJetEm, caloJetHad;
343  getCaloJetEnergy(polarP4, caloJets.product(), caloJetEm, caloJetHad);
344 
345  bool pfLepOverlap = getPFLeptonOverlap(polarP4, pc);
346  float pfNeutralSum = getPFNeutralSum(polarP4, pc, pfCandInd);
347 
349  int refToNearestPF_idx = -1;
350  getNearestPCRef(polarP4, pc, pfCandInd, refToNearestPF_idx);
351  if (refToNearestPF_idx != -1)
352  refToNearestPF = pat::PackedCandidateRef(pc_h, refToNearestPF_idx);
353 
354  pat::PackedCandidateRef refToNearestLostTrack = pat::PackedCandidateRef();
355  int refToNearestLostTrack_idx = -1;
356  getNearestPCRef(polarP4, lt, ltCandInd, refToNearestLostTrack_idx);
357  if (refToNearestLostTrack_idx != -1)
358  refToNearestLostTrack = pat::PackedCandidateRef(lt_h, refToNearestLostTrack_idx);
359 
360  // if no dEdx info exists, just store -1
361  float dEdxPixel = -1, dEdxStrip = -1;
362  if (usePrecomputedDeDxStrip_ && gt2dedxStrip.isValid() && gt2dedxStrip->contains(tkref.id())) {
363  dEdxStrip = (*gt2dedxStrip)[tkref].dEdx();
364  } else if (gt2dedxHitInfo.isValid() && gt2dedxHitInfo->contains(tkref.id())) {
365  const reco::DeDxHitInfo* hitInfo = (*gt2dedxHitInfo)[tkref].get();
366  dEdxStrip = getDeDx(hitInfo, false, true);
367  }
368  if (usePrecomputedDeDxPixel_ && gt2dedxPixel.isValid() && gt2dedxPixel->contains(tkref.id())) {
369  dEdxPixel = (*gt2dedxPixel)[tkref].dEdx();
370  } else if (gt2dedxHitInfo.isValid() && gt2dedxHitInfo->contains(tkref.id())) {
371  const reco::DeDxHitInfo* hitInfo = (*gt2dedxHitInfo)[tkref].get();
372  dEdxPixel = getDeDx(hitInfo, true, false);
373  }
374 
375  int trackQuality = gentk.qualityMask();
376 
377  // get the associated ecal/hcal detectors
378  TrackDetMatchInfo trackDetInfo = getTrackDetMatchInfo(iEvent, iSetup, gentk);
379 
380  // fill ecal/hcal status vectors
381  std::vector<uint32_t> crossedHcalStatus;
382  for (auto const& did : trackDetInfo.crossedHcalIds) {
383  crossedHcalStatus.push_back(hcalQ->getValues(did.rawId())->getValue());
384  }
385  std::vector<uint16_t> crossedEcalStatus;
386  for (auto const& did : trackDetInfo.crossedEcalIds) {
387  crossedEcalStatus.push_back(ecalS->find(did.rawId())->getStatusCode());
388  }
389 
390  int deltaEta = int((trackDetInfo.trkGlobPosAtEcal.eta() - gentk.eta()) / 0.5 * 250);
391  int deltaPhi = int((trackDetInfo.trkGlobPosAtEcal.phi() - gentk.phi()) / 0.5 * 250);
392  if (deltaEta < -250)
393  deltaEta = -250;
394  if (deltaEta > 250)
395  deltaEta = 250;
396  if (deltaPhi < -250)
397  deltaPhi = -250;
398  if (deltaPhi > 250)
399  deltaPhi = 250;
400 
401  outPtrP->push_back(pat::IsolatedTrack(isolationDR03,
402  miniIso,
403  caloJetEm,
404  caloJetHad,
405  pfLepOverlap,
406  pfNeutralSum,
407  p4,
408  charge,
409  pdgId,
410  dz,
411  dxy,
412  dzError,
413  dxyError,
414  gentk.hitPattern(),
415  dEdxStrip,
416  dEdxPixel,
417  fromPV,
418  trackQuality,
419  crossedEcalStatus,
420  crossedHcalStatus,
421  deltaEta,
422  deltaPhi,
423  refToCand,
424  refToNearestPF,
425  refToNearestLostTrack));
426  outPtrP->back().setStatus(prescaled);
427 
428  if (saveDeDxHitInfo_) {
429  const auto& dedxRef = (*gt2dedxHitInfo)[tkref];
430  if (saveDeDxHitInfoCut_(outPtrP->back()) && dedxRef.isNonnull()) {
431  outDeDxC->push_back(*dedxRef);
432  dEdXass.push_back(outDeDxC->size() - 1);
433  } else {
434  dEdXass.push_back(-1);
435  }
436  }
437  }
438 
439  // there are some number of pfcandidates with no associated track
440  // (mostly electrons, with a handful of muons)
441  // here we find these and store. Track-specific variables get some default values
442  for (unsigned int ipc = 0; ipc < pc->size(); ipc++) {
443  const pat::PackedCandidate& pfCand = pc->at(ipc);
445  reco::PFCandidateRef pfref = (*pc2pf)[pcref];
446 
447  // already counted if it has a track reference in the generalTracks collection
448  if (pfref.get()->trackRef().isNonnull() && pfref.get()->trackRef().id() == gt_h.id())
449  continue;
450 
451  PolarLorentzVector polarP4;
452  pat::PackedCandidateRef refToCand;
453  int pdgId, charge, fromPV;
454  float dz, dxy, dzError, dxyError;
455 
456  polarP4 = pfCand.polarP4();
457  charge = pfCand.charge();
458 
459  if (polarP4.pt() < pT_cut_)
460  continue;
461  if (charge == 0)
462  continue;
463 
464  // get the isolation of the track
465  pat::PFIsolation isolationDR03;
466  pat::PFIsolation miniIso;
467  getIsolation(polarP4, pc, ipc, isolationDR03, miniIso);
468 
469  // isolation cut
470  if (polarP4.pt() < pT_cut_noIso_ && !(isolationDR03.chargedHadronIso() < absIso_cut_ ||
471  isolationDR03.chargedHadronIso() / polarP4.pt() < relIso_cut_ ||
472  miniIso.chargedHadronIso() / polarP4.pt() < miniRelIso_cut_))
473  continue;
474 
475  pdgId = pfCand.pdgId();
476  dz = pfCand.dz();
477  dxy = pfCand.dxy();
478  if (pfCand.hasTrackDetails()) {
479  dzError = pfCand.dzError();
480  dxyError = pfCand.dxyError();
481  } else {
482  dzError = 0;
483  dxyError = 0;
484  }
485  fromPV = pfCand.fromPV();
486  refToCand = pcref;
487 
488  float caloJetEm, caloJetHad;
489  getCaloJetEnergy(polarP4, caloJets.product(), caloJetEm, caloJetHad);
490 
491  bool pfLepOverlap = getPFLeptonOverlap(polarP4, pc);
492  float pfNeutralSum = getPFNeutralSum(polarP4, pc, ipc);
493 
495  int refToNearestPF_idx = -1;
496  getNearestPCRef(polarP4, pc, ipc, refToNearestPF_idx);
497  if (refToNearestPF_idx != -1)
498  refToNearestPF = pat::PackedCandidateRef(pc_h, refToNearestPF_idx);
499 
500  pat::PackedCandidateRef refToNearestLostTrack = pat::PackedCandidateRef();
501  int refToNearestLostTrack_idx = -1;
502  getNearestPCRef(polarP4, lt, -1, refToNearestLostTrack_idx);
503  if (refToNearestLostTrack_idx != -1)
504  refToNearestLostTrack = pat::PackedCandidateRef(lt_h, refToNearestLostTrack_idx);
505 
506  // fill with default values
508  float dEdxPixel = -1, dEdxStrip = -1;
509  int trackQuality = 0;
510  std::vector<uint16_t> ecalStatus;
511  std::vector<uint32_t> hcalStatus;
512  int deltaEta = 0;
513  int deltaPhi = 0;
514 
515  outPtrP->push_back(pat::IsolatedTrack(isolationDR03,
516  miniIso,
517  caloJetEm,
518  caloJetHad,
519  pfLepOverlap,
520  pfNeutralSum,
521  pfCand.p4(),
522  charge,
523  pdgId,
524  dz,
525  dxy,
526  dzError,
527  dxyError,
528  hp,
529  dEdxStrip,
530  dEdxPixel,
531  fromPV,
532  trackQuality,
533  ecalStatus,
534  hcalStatus,
535  deltaEta,
536  deltaPhi,
537  refToCand,
538  refToNearestPF,
539  refToNearestLostTrack));
540 
541  dEdXass.push_back(-1); // these never have dE/dx hit info, as there's no track
542  }
543 
544  auto orphHandle = iEvent.put(std::move(outPtrP));
545  if (saveDeDxHitInfo_) {
546  auto dedxOH = iEvent.put(std::move(outDeDxC));
547  auto dedxMatch = std::make_unique<reco::DeDxHitInfoAss>(dedxOH);
549  filler.insert(orphHandle, dEdXass.begin(), dEdXass.end());
550  filler.fill();
551  iEvent.put(std::move(dedxMatch));
552  }
553 }
554 
557  int pc_idx,
558  pat::PFIsolation& iso,
559  pat::PFIsolation& miniiso) const {
560  float chiso = 0, nhiso = 0, phiso = 0, puiso = 0; // standard isolation
561  float chmiso = 0, nhmiso = 0, phmiso = 0, pumiso = 0; // mini isolation
562  float miniDR = std::max(miniIsoParams_[0], std::min(miniIsoParams_[1], miniIsoParams_[2] / p4.pt()));
563  for (pat::PackedCandidateCollection::const_iterator pf_it = pc->begin(); pf_it != pc->end(); pf_it++) {
564  if (int(pf_it - pc->begin()) == pc_idx) //don't count itself
565  continue;
566  int id = std::abs(pf_it->pdgId());
567  bool fromPV = (pf_it->fromPV() > 1 || fabs(pf_it->dz()) < pfIsolation_DZ_);
568  float pt = pf_it->p4().pt();
569  float dr = deltaR(p4, *pf_it);
570 
571  if (dr < pfIsolation_DR_) {
572  // charged cands from PV get added to trackIso
573  if (id == 211 && fromPV)
574  chiso += pt;
575  // charged cands not from PV get added to pileup iso
576  else if (id == 211)
577  puiso += pt;
578  // neutral hadron iso
579  if (id == 130)
580  nhiso += pt;
581  // photon iso
582  if (id == 22)
583  phiso += pt;
584  }
585  // same for mini isolation
586  if (dr < miniDR) {
587  if (id == 211 && fromPV)
588  chmiso += pt;
589  else if (id == 211)
590  pumiso += pt;
591  if (id == 130)
592  nhmiso += pt;
593  if (id == 22)
594  phmiso += pt;
595  }
596  }
597 
598  iso = pat::PFIsolation(chiso, nhiso, phiso, puiso);
599  miniiso = pat::PFIsolation(chmiso, nhmiso, phmiso, pumiso);
600 }
601 
602 //get overlap of isolated track with a PF lepton
604  const pat::PackedCandidateCollection* pc) const {
605  bool isOverlap = false;
606  float dr_min = pflepoverlap_DR_;
607  int id_drmin = 0;
608  for (const auto& pf : *pc) {
609  int id = std::abs(pf.pdgId());
610  int charge = std::abs(pf.charge());
611  bool fromPV = (pf.fromPV() > 1 || std::abs(pf.dz()) < pfIsolation_DZ_);
612  float pt = pf.pt();
613  if (charge == 0) // exclude neutral candidates
614  continue;
615  if (!(fromPV)) // exclude candidates not from PV
616  continue;
617  if (pt < pflepoverlap_pTmin_) // exclude pf candidates w/ pT below threshold
618  continue;
619 
620  float dr = deltaR(p4, pf);
621  if (dr > pflepoverlap_DR_) // exclude pf candidates far from isolated track
622  continue;
623 
624  if (dr < dr_min) {
625  dr_min = dr;
626  id_drmin = id;
627  }
628  }
629 
630  if (dr_min < pflepoverlap_DR_ && (id_drmin == 11 || id_drmin == 13))
631  isOverlap = true;
632 
633  return isOverlap;
634 }
635 
636 //get ref to nearest pf packed candidate
639  int pc_idx,
640  int& pc_ref_idx) const {
641  float dr_min = pcRefNearest_DR_;
642  float dr_min_pu = pcRefNearest_DR_;
643  int pc_ref_idx_pu = -1;
644  for (pat::PackedCandidateCollection::const_iterator pf_it = pc->begin(); pf_it != pc->end(); pf_it++) {
645  if (int(pf_it - pc->begin()) == pc_idx) //don't count itself
646  continue;
647  int charge = std::abs(pf_it->charge());
648  bool fromPV = (pf_it->fromPV() > 1 || fabs(pf_it->dz()) < pfIsolation_DZ_);
649  float pt = pf_it->p4().pt();
650  float dr = deltaR(p4, *pf_it);
651  if (charge == 0) // exclude neutral candidates
652  continue;
653  if (pt < pcRefNearest_pTmin_) // exclude candidates w/ pT below threshold
654  continue;
655  if (dr > dr_min && dr > dr_min_pu) // exclude too far candidates
656  continue;
657 
658  if (fromPV) { // Priority to candidates from PV
659  if (dr < dr_min) {
660  dr_min = dr;
661  pc_ref_idx = int(pf_it - pc->begin());
662  }
663  } else { // Otherwise, store candidate from non-PV if no candidate from PV found
664  if (dr < dr_min_pu) {
665  dr_min_pu = dr;
666  pc_ref_idx_pu = int(pf_it - pc->begin());
667  }
668  }
669  }
670 
671  if (pc_ref_idx == -1 &&
672  pc_ref_idx_pu != -1) // If no candidate from PV was found, store candidate from non-PV (if found)
673  pc_ref_idx = pc_ref_idx_pu;
674 }
675 
676 // get PF neutral pT sum around isolated track
679  int pc_idx) const {
680  float nsum = 0;
681  float nhsum = 0, phsum = 0;
682  for (pat::PackedCandidateCollection::const_iterator pf_it = pc->begin(); pf_it != pc->end(); pf_it++) {
683  if (int(pf_it - pc->begin()) == pc_idx) //don't count itself
684  continue;
685  int id = std::abs(pf_it->pdgId());
686  float pt = pf_it->p4().pt();
687  float dr = deltaR(p4, *pf_it);
688 
689  if (dr < pfneutralsum_DR_) {
690  // neutral hadron sum
691  if (id == 130)
692  nhsum += pt;
693  // photon iso
694  if (id == 22)
695  phsum += pt;
696  }
697  }
698 
699  nsum = nhsum + phsum;
700 
701  return nsum;
702 }
703 
704 // get the estimated DeDx in either the pixels or strips (or both)
706  if (hitInfo == nullptr) {
707  return -1;
708  }
709 
710  std::vector<float> charge_vec;
711  for (unsigned int ih = 0; ih < hitInfo->size(); ih++) {
712  bool isPixel = (hitInfo->pixelCluster(ih) != nullptr);
713  bool isStrip = (hitInfo->stripCluster(ih) != nullptr);
714 
715  if (isPixel && !doPixel)
716  continue;
717  if (isStrip && !doStrip)
718  continue;
719 
720  // probably shouldn't happen
721  if (!isPixel && !isStrip)
722  continue;
723 
724  // shape selection for strips
725  if (isStrip && !deDxTools::shapeSelection(*(hitInfo->stripCluster(ih))))
726  continue;
727 
728  float Norm = 0;
729  if (isPixel)
730  Norm = 3.61e-06; //compute the normalization factor to get the energy in MeV/mm
731  if (isStrip)
732  Norm = 3.61e-06 * 265;
733 
734  //save the dE/dx in MeV/mm to a vector.
735  charge_vec.push_back(Norm * hitInfo->charge(ih) / hitInfo->pathlength(ih));
736  }
737 
738  int size = charge_vec.size();
739  float result = 0.0;
740 
741  //build the harmonic 2 dE/dx estimator
742  float expo = -2;
743  for (int i = 0; i < size; i++) {
744  result += pow(charge_vec[i], expo);
745  }
746  result = (size > 0) ? pow(result / size, 1. / expo) : 0.0;
747 
748  return result;
749 }
750 
752  const edm::EventSetup& iSetup,
753  const reco::Track& track) {
754  auto const& bField = iSetup.getData(bFieldToken_);
756 
757  // can't use the associate() using reco::Track directly, since
758  // track->extra() is non-null but segfaults when trying to use it
759  return trackAssociator_.associate(iEvent, iSetup, trackAssocParameters_, &initialState);
760 }
761 
763  const reco::CaloJetCollection* cJets,
764  float& caloJetEm,
765  float& caloJetHad) const {
766  float nearestDR = 999;
767  int ind = -1;
768  for (unsigned int i = 0; i < cJets->size(); i++) {
769  float dR = deltaR(cJets->at(i), p4);
770  if (dR < caloJet_DR_ && dR < nearestDR) {
771  nearestDR = dR;
772  ind = i;
773  }
774  }
775 
776  if (ind == -1) {
777  caloJetEm = 0;
778  caloJetHad = 0;
779  } else {
780  const reco::CaloJet& cJet = cJets->at(ind);
781  caloJetEm = cJet.emEnergyInEB() + cJet.emEnergyInEE() + cJet.emEnergyInHF();
782  caloJetHad = cJet.hadEnergyInHB() + cJet.hadEnergyInHE() + cJet.hadEnergyInHF();
783  }
784 }
785 
bool quality(const TrackQuality) const
Track quality.
Definition: TrackBase.h:552
size
Write out results.
float pathlength(size_t i) const
Definition: DeDxHitInfo.h:43
PATIsolatedTrackProducer(const edm::ParameterSet &)
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
const edm::EDGetTokenT< reco::TrackCollection > gt_
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
const edm::EDGetTokenT< edm::ValueMap< reco::DeDxData > > gt2dedxStrip_
Jets made from CaloTowers.
Definition: CaloJet.h:27
const edm::EDGetTokenT< edm::ValueMap< int > > gt2dedxHitInfoPrescale_
ProductID id() const
Accessor for product ID.
Definition: Ref.h:244
float emEnergyInHF() const
Definition: CaloJet.h:111
ProductID id() const
Definition: HandleBase.cc:29
TrackDetectorAssociator trackAssociator_
int charge() const override
electric charge
bool getPFLeptonOverlap(const PolarLorentzVector &p4, const pat::PackedCandidateCollection *pc) const
float emEnergyInEE() const
Definition: CaloJet.h:109
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
double px() const
x coordinate of momentum vector
Definition: TrackBase.h:640
double p() const
momentum vector magnitude
Definition: TrackBase.h:631
std::vector< DetId > crossedEcalIds
std::vector< l1t::PFCandidate > PFCandidateCollection
Definition: PFCandidate.h:57
float getDeDx(const reco::DeDxHitInfo *hitInfo, bool doPixel, bool doStrip) const
T const * product() const
Definition: Handle.h:70
void useDefaultPropagator()
use the default propagator
std::vector< pat::PackedCandidate > PackedCandidateCollection
void getNearestPCRef(const PolarLorentzVector &p4, const pat::PackedCandidateCollection *pc, int pc_idx, int &pc_ref_idx) const
std::vector< Track > TrackCollection
collection of Tracks
Definition: TrackFwd.h:14
void loadParameters(const edm::ParameterSet &, edm::ConsumesCollector &)
double py() const
y coordinate of momentum vector
Definition: TrackBase.h:643
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
const PVAssoc fromPV(size_t ipv=0) const
const PolarLorentzVector & polarP4() const override
four-momentum Lorentz vector
float emEnergyInEB() const
Definition: CaloJet.h:107
int pdgId() const override
PDG identifier.
const edm::EDGetTokenT< edm::Association< pat::PackedCandidateCollection > > gt2pc_
std::vector< Vertex > VertexCollection
Definition: Vertex.h:31
std::vector< DetId > crossedHcalIds
key_type key() const
Accessor for product key.
Definition: Ref.h:250
static const double deltaEta
Definition: CaloConstants.h:8
const Item * getValues(DetId fId, bool throwOnFail=true) const
Definition: HeavyIon.h:7
const edm::EDGetTokenT< reco::DeDxHitInfoAss > gt2dedxHitInfo_
double pt() const
track transverse momentum
Definition: TrackBase.h:637
pat::IsolatedTrack::PolarLorentzVector PolarLorentzVector
int charge() const
track electric charge
Definition: TrackBase.h:596
double dz() const
dz parameter (= dsz/cos(lambda)). This is the track z0 w.r.t (0,0,0) only if the refPoint is close to...
Definition: TrackBase.h:622
int iEvent
Definition: GenABIO.cc:224
const edm::ESGetToken< EcalChannelStatus, EcalChannelStatusRcd > ecalSToken_
edm::Association< DeDxHitInfoCollection > DeDxHitInfoAss
Definition: DeDxHitInfo.h:116
double dxyError() const
error on dxy
Definition: TrackBase.h:769
float getPFNeutralSum(const PolarLorentzVector &p4, const pat::PackedCandidateCollection *pc, int pc_idx) const
void getCaloJetEnergy(const PolarLorentzVector &, const reco::CaloJetCollection *, float &, float &) const
double dzError() const
error on dz
Definition: TrackBase.h:778
T sqrt(T t)
Definition: SSEVec.h:19
float dzError() const override
uncertainty on dz
TrackAssociatorParameters trackAssocParameters_
edm::Ref< pat::PackedCandidateCollection > PackedCandidateRef
float chargedHadronIso() const
Definition: PFIsolation.h:28
def pv(vc)
Definition: MetAnalyzer.py:7
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
const SiStripCluster * stripCluster(size_t i) const
Definition: DeDxHitInfo.h:66
double phi() const
azimuthal angle of momentum vector
Definition: TrackBase.h:649
void getIsolation(const PolarLorentzVector &p4, const pat::PackedCandidateCollection *pc, int pc_idx, pat::PFIsolation &iso, pat::PFIsolation &miniiso) const
bool getData(T &iHolder) const
Definition: EventSetup.h:122
float dxyError() const override
uncertainty on dxy
const_iterator find(uint32_t rawId) const
int qualityMask() const
Definition: TrackBase.h:843
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:652
bool lt_(std::pair< double, short > a, std::pair< double, short > b)
pat::IsolatedTrack::LorentzVector LorentzVector
const edm::EDGetTokenT< pat::PackedCandidateCollection > pc_
static TrackQuality qualityByName(const std::string &name)
Definition: TrackBase.cc:126
StringCutObjectSelector< pat::IsolatedTrack > saveDeDxHitInfoCut_
const HitPattern & hitPattern() const
Access the hit pattern, indicating in which Tracker layers the track has hits.
Definition: TrackBase.h:504
float hadEnergyInHF() const
Definition: CaloJet.h:105
float hadEnergyInHE() const
Definition: CaloJet.h:103
const edm::EDGetTokenT< edm::Association< reco::PFCandidateCollection > > pc2pf_
bool shapeSelection(const SiStripCluster &ampls)
Definition: DeDxTools.cc:13
size_t size() const
Definition: DeDxHitInfo.h:41
const edm::EDGetTokenT< pat::PackedCandidateCollection > lt_
edm::Ref< TrackCollection > TrackRef
persistent reference to a Track
Definition: TrackFwd.h:20
double pz() const
z coordinate of momentum vector
Definition: TrackBase.h:646
bool contains(ProductID id) const
Definition: Association.h:63
void produce(edm::Event &, const edm::EventSetup &) override
float hadEnergyInHB() const
Definition: CaloJet.h:99
const edm::EDGetTokenT< reco::VertexCollection > pv_
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:36
bool isValid() const
Definition: HandleBase.h:70
const edm::EDGetTokenT< edm::Association< pat::PackedCandidateCollection > > gt2lt_
const edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > bFieldToken_
fixed size matrix
HLT enums.
TrackDetMatchInfo getTrackDetMatchInfo(const edm::Event &, const edm::EventSetup &, const reco::Track &)
const SiPixelCluster * pixelCluster(size_t i) const
Definition: DeDxHitInfo.h:46
bool isPixel(HitType hitType)
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:232
const edm::ESGetToken< HcalChannelQuality, HcalChannelQualityRcd > hcalQToken_
math::XYZPoint trkGlobPosAtEcal
Track position at different parts of the calorimeter.
const JetExtendedData & getValue(const Container &, const reco::JetBaseRef &)
get value for the association. Throw exception if no association found
virtual float dxy() const
dxy with respect to the PV ref
float charge(size_t i) const
Definition: DeDxHitInfo.h:42
virtual float dz(size_t ipv=0) const
dz with respect to the PV[ipv]
FreeTrajectoryState initialFreeState(const reco::Track &tk, const MagneticField *field, bool withErr=true)
const LorentzVector & p4() const override
four-momentum Lorentz vecto r
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
def move(src, dest)
Definition: eostools.py:511
const edm::EDGetTokenT< reco::CaloJetCollection > caloJets_
std::vector< CaloJet > CaloJetCollection
collection of CaloJet objects
double dxy() const
dxy parameter. (This is the transverse impact parameter w.r.t. to (0,0,0) ONLY if refPoint is close t...
Definition: TrackBase.h:608
const edm::EDGetTokenT< edm::ValueMap< reco::DeDxData > > gt2dedxPixel_
bool hasTrackDetails() const
Return true if a bestTrack can be extracted from this Candidate.
math::PtEtaPhiMLorentzVector PolarLorentzVector
Lorentz vector.
Definition: Candidate.h:38