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  crossedHcalStatus.reserve(trackDetInfo.crossedHcalIds.size());
383  for (auto const& did : trackDetInfo.crossedHcalIds) {
384  crossedHcalStatus.push_back(hcalQ->getValues(did.rawId())->getValue());
385  }
386  std::vector<uint16_t> crossedEcalStatus;
387  crossedEcalStatus.reserve(trackDetInfo.crossedEcalIds.size());
388  for (auto const& did : trackDetInfo.crossedEcalIds) {
389  crossedEcalStatus.push_back(ecalS->find(did.rawId())->getStatusCode());
390  }
391 
392  int deltaEta = int((trackDetInfo.trkGlobPosAtEcal.eta() - gentk.eta()) / 0.5 * 250);
393  int deltaPhi = int((trackDetInfo.trkGlobPosAtEcal.phi() - gentk.phi()) / 0.5 * 250);
394  if (deltaEta < -250)
395  deltaEta = -250;
396  if (deltaEta > 250)
397  deltaEta = 250;
398  if (deltaPhi < -250)
399  deltaPhi = -250;
400  if (deltaPhi > 250)
401  deltaPhi = 250;
402 
403  outPtrP->push_back(pat::IsolatedTrack(isolationDR03,
404  miniIso,
405  caloJetEm,
406  caloJetHad,
407  pfLepOverlap,
408  pfNeutralSum,
409  p4,
410  charge,
411  pdgId,
412  dz,
413  dxy,
414  dzError,
415  dxyError,
416  gentk.hitPattern(),
417  dEdxStrip,
418  dEdxPixel,
419  fromPV,
420  trackQuality,
421  crossedEcalStatus,
422  crossedHcalStatus,
423  deltaEta,
424  deltaPhi,
425  refToCand,
426  refToNearestPF,
427  refToNearestLostTrack));
428  outPtrP->back().setStatus(prescaled);
429 
430  if (saveDeDxHitInfo_) {
431  const auto& dedxRef = (*gt2dedxHitInfo)[tkref];
432  if (saveDeDxHitInfoCut_(outPtrP->back()) && dedxRef.isNonnull()) {
433  outDeDxC->push_back(*dedxRef);
434  dEdXass.push_back(outDeDxC->size() - 1);
435  } else {
436  dEdXass.push_back(-1);
437  }
438  }
439  }
440 
441  // there are some number of pfcandidates with no associated track
442  // (mostly electrons, with a handful of muons)
443  // here we find these and store. Track-specific variables get some default values
444  for (unsigned int ipc = 0; ipc < pc->size(); ipc++) {
445  const pat::PackedCandidate& pfCand = pc->at(ipc);
447  reco::PFCandidateRef pfref = (*pc2pf)[pcref];
448 
449  // already counted if it has a track reference in the generalTracks collection
450  if (pfref.get()->trackRef().isNonnull() && pfref.get()->trackRef().id() == gt_h.id())
451  continue;
452 
453  PolarLorentzVector polarP4;
454  pat::PackedCandidateRef refToCand;
455  int pdgId, charge, fromPV;
456  float dz, dxy, dzError, dxyError;
457 
458  polarP4 = pfCand.polarP4();
459  charge = pfCand.charge();
460 
461  if (polarP4.pt() < pT_cut_)
462  continue;
463  if (charge == 0)
464  continue;
465 
466  // get the isolation of the track
467  pat::PFIsolation isolationDR03;
468  pat::PFIsolation miniIso;
469  getIsolation(polarP4, pc, ipc, isolationDR03, miniIso);
470 
471  // isolation cut
472  if (polarP4.pt() < pT_cut_noIso_ && !(isolationDR03.chargedHadronIso() < absIso_cut_ ||
473  isolationDR03.chargedHadronIso() / polarP4.pt() < relIso_cut_ ||
474  miniIso.chargedHadronIso() / polarP4.pt() < miniRelIso_cut_))
475  continue;
476 
477  pdgId = pfCand.pdgId();
478  dz = pfCand.dz();
479  dxy = pfCand.dxy();
480  if (pfCand.hasTrackDetails()) {
481  dzError = pfCand.dzError();
482  dxyError = pfCand.dxyError();
483  } else {
484  dzError = 0;
485  dxyError = 0;
486  }
487  fromPV = pfCand.fromPV();
488  refToCand = pcref;
489 
490  float caloJetEm, caloJetHad;
491  getCaloJetEnergy(polarP4, caloJets.product(), caloJetEm, caloJetHad);
492 
493  bool pfLepOverlap = getPFLeptonOverlap(polarP4, pc);
494  float pfNeutralSum = getPFNeutralSum(polarP4, pc, ipc);
495 
497  int refToNearestPF_idx = -1;
498  getNearestPCRef(polarP4, pc, ipc, refToNearestPF_idx);
499  if (refToNearestPF_idx != -1)
500  refToNearestPF = pat::PackedCandidateRef(pc_h, refToNearestPF_idx);
501 
502  pat::PackedCandidateRef refToNearestLostTrack = pat::PackedCandidateRef();
503  int refToNearestLostTrack_idx = -1;
504  getNearestPCRef(polarP4, lt, -1, refToNearestLostTrack_idx);
505  if (refToNearestLostTrack_idx != -1)
506  refToNearestLostTrack = pat::PackedCandidateRef(lt_h, refToNearestLostTrack_idx);
507 
508  // fill with default values
510  float dEdxPixel = -1, dEdxStrip = -1;
511  int trackQuality = 0;
512  std::vector<uint16_t> ecalStatus;
513  std::vector<uint32_t> hcalStatus;
514  int deltaEta = 0;
515  int deltaPhi = 0;
516 
517  outPtrP->push_back(pat::IsolatedTrack(isolationDR03,
518  miniIso,
519  caloJetEm,
520  caloJetHad,
521  pfLepOverlap,
522  pfNeutralSum,
523  pfCand.p4(),
524  charge,
525  pdgId,
526  dz,
527  dxy,
528  dzError,
529  dxyError,
530  hp,
531  dEdxStrip,
532  dEdxPixel,
533  fromPV,
534  trackQuality,
535  ecalStatus,
536  hcalStatus,
537  deltaEta,
538  deltaPhi,
539  refToCand,
540  refToNearestPF,
541  refToNearestLostTrack));
542 
543  dEdXass.push_back(-1); // these never have dE/dx hit info, as there's no track
544  }
545 
546  auto orphHandle = iEvent.put(std::move(outPtrP));
547  if (saveDeDxHitInfo_) {
548  auto dedxOH = iEvent.put(std::move(outDeDxC));
549  auto dedxMatch = std::make_unique<reco::DeDxHitInfoAss>(dedxOH);
551  filler.insert(orphHandle, dEdXass.begin(), dEdXass.end());
552  filler.fill();
553  iEvent.put(std::move(dedxMatch));
554  }
555 }
556 
559  int pc_idx,
560  pat::PFIsolation& iso,
561  pat::PFIsolation& miniiso) const {
562  float chiso = 0, nhiso = 0, phiso = 0, puiso = 0; // standard isolation
563  float chmiso = 0, nhmiso = 0, phmiso = 0, pumiso = 0; // mini isolation
564  float miniDR = std::max(miniIsoParams_[0], std::min(miniIsoParams_[1], miniIsoParams_[2] / p4.pt()));
565  for (pat::PackedCandidateCollection::const_iterator pf_it = pc->begin(); pf_it != pc->end(); pf_it++) {
566  if (int(pf_it - pc->begin()) == pc_idx) //don't count itself
567  continue;
568  int id = std::abs(pf_it->pdgId());
569  bool fromPV = (pf_it->fromPV() > 1 || fabs(pf_it->dz()) < pfIsolation_DZ_);
570  float pt = pf_it->p4().pt();
571  float dr = deltaR(p4, *pf_it);
572 
573  if (dr < pfIsolation_DR_) {
574  // charged cands from PV get added to trackIso
575  if (id == 211 && fromPV)
576  chiso += pt;
577  // charged cands not from PV get added to pileup iso
578  else if (id == 211)
579  puiso += pt;
580  // neutral hadron iso
581  if (id == 130)
582  nhiso += pt;
583  // photon iso
584  if (id == 22)
585  phiso += pt;
586  }
587  // same for mini isolation
588  if (dr < miniDR) {
589  if (id == 211 && fromPV)
590  chmiso += pt;
591  else if (id == 211)
592  pumiso += pt;
593  if (id == 130)
594  nhmiso += pt;
595  if (id == 22)
596  phmiso += pt;
597  }
598  }
599 
600  iso = pat::PFIsolation(chiso, nhiso, phiso, puiso);
601  miniiso = pat::PFIsolation(chmiso, nhmiso, phmiso, pumiso);
602 }
603 
604 //get overlap of isolated track with a PF lepton
606  const pat::PackedCandidateCollection* pc) const {
607  bool isOverlap = false;
608  float dr_min = pflepoverlap_DR_;
609  int id_drmin = 0;
610  for (const auto& pf : *pc) {
611  int id = std::abs(pf.pdgId());
612  int charge = std::abs(pf.charge());
613  bool fromPV = (pf.fromPV() > 1 || std::abs(pf.dz()) < pfIsolation_DZ_);
614  float pt = pf.pt();
615  if (charge == 0) // exclude neutral candidates
616  continue;
617  if (!(fromPV)) // exclude candidates not from PV
618  continue;
619  if (pt < pflepoverlap_pTmin_) // exclude pf candidates w/ pT below threshold
620  continue;
621 
622  float dr = deltaR(p4, pf);
623  if (dr > pflepoverlap_DR_) // exclude pf candidates far from isolated track
624  continue;
625 
626  if (dr < dr_min) {
627  dr_min = dr;
628  id_drmin = id;
629  }
630  }
631 
632  if (dr_min < pflepoverlap_DR_ && (id_drmin == 11 || id_drmin == 13))
633  isOverlap = true;
634 
635  return isOverlap;
636 }
637 
638 //get ref to nearest pf packed candidate
641  int pc_idx,
642  int& pc_ref_idx) const {
643  float dr_min = pcRefNearest_DR_;
644  float dr_min_pu = pcRefNearest_DR_;
645  int pc_ref_idx_pu = -1;
646  for (pat::PackedCandidateCollection::const_iterator pf_it = pc->begin(); pf_it != pc->end(); pf_it++) {
647  if (int(pf_it - pc->begin()) == pc_idx) //don't count itself
648  continue;
649  int charge = std::abs(pf_it->charge());
650  bool fromPV = (pf_it->fromPV() > 1 || fabs(pf_it->dz()) < pfIsolation_DZ_);
651  float pt = pf_it->p4().pt();
652  float dr = deltaR(p4, *pf_it);
653  if (charge == 0) // exclude neutral candidates
654  continue;
655  if (pt < pcRefNearest_pTmin_) // exclude candidates w/ pT below threshold
656  continue;
657  if (dr > dr_min && dr > dr_min_pu) // exclude too far candidates
658  continue;
659 
660  if (fromPV) { // Priority to candidates from PV
661  if (dr < dr_min) {
662  dr_min = dr;
663  pc_ref_idx = int(pf_it - pc->begin());
664  }
665  } else { // Otherwise, store candidate from non-PV if no candidate from PV found
666  if (dr < dr_min_pu) {
667  dr_min_pu = dr;
668  pc_ref_idx_pu = int(pf_it - pc->begin());
669  }
670  }
671  }
672 
673  if (pc_ref_idx == -1 &&
674  pc_ref_idx_pu != -1) // If no candidate from PV was found, store candidate from non-PV (if found)
675  pc_ref_idx = pc_ref_idx_pu;
676 }
677 
678 // get PF neutral pT sum around isolated track
681  int pc_idx) const {
682  float nsum = 0;
683  float nhsum = 0, phsum = 0;
684  for (pat::PackedCandidateCollection::const_iterator pf_it = pc->begin(); pf_it != pc->end(); pf_it++) {
685  if (int(pf_it - pc->begin()) == pc_idx) //don't count itself
686  continue;
687  int id = std::abs(pf_it->pdgId());
688  float pt = pf_it->p4().pt();
689  float dr = deltaR(p4, *pf_it);
690 
691  if (dr < pfneutralsum_DR_) {
692  // neutral hadron sum
693  if (id == 130)
694  nhsum += pt;
695  // photon iso
696  if (id == 22)
697  phsum += pt;
698  }
699  }
700 
701  nsum = nhsum + phsum;
702 
703  return nsum;
704 }
705 
706 // get the estimated DeDx in either the pixels or strips (or both)
708  if (hitInfo == nullptr) {
709  return -1;
710  }
711 
712  std::vector<float> charge_vec;
713  for (unsigned int ih = 0; ih < hitInfo->size(); ih++) {
714  bool isPixel = (hitInfo->pixelCluster(ih) != nullptr);
715  bool isStrip = (hitInfo->stripCluster(ih) != nullptr);
716 
717  if (isPixel && !doPixel)
718  continue;
719  if (isStrip && !doStrip)
720  continue;
721 
722  // probably shouldn't happen
723  if (!isPixel && !isStrip)
724  continue;
725 
726  // shape selection for strips
727  if (isStrip && !deDxTools::shapeSelection(*(hitInfo->stripCluster(ih))))
728  continue;
729 
730  float Norm = 0;
731  if (isPixel)
732  Norm = 3.61e-06; //compute the normalization factor to get the energy in MeV/mm
733  if (isStrip)
734  Norm = 3.61e-06 * 265;
735 
736  //save the dE/dx in MeV/mm to a vector.
737  charge_vec.push_back(Norm * hitInfo->charge(ih) / hitInfo->pathlength(ih));
738  }
739 
740  int size = charge_vec.size();
741  float result = 0.0;
742 
743  //build the harmonic 2 dE/dx estimator
744  float expo = -2;
745  for (int i = 0; i < size; i++) {
746  result += pow(charge_vec[i], expo);
747  }
748  result = (size > 0) ? pow(result / size, 1. / expo) : 0.0;
749 
750  return result;
751 }
752 
754  const edm::EventSetup& iSetup,
755  const reco::Track& track) {
756  auto const& bField = iSetup.getData(bFieldToken_);
758 
759  // can't use the associate() using reco::Track directly, since
760  // track->extra() is non-null but segfaults when trying to use it
761  return trackAssociator_.associate(iEvent, iSetup, trackAssocParameters_, &initialState);
762 }
763 
765  const reco::CaloJetCollection* cJets,
766  float& caloJetEm,
767  float& caloJetHad) const {
768  float nearestDR = 999;
769  int ind = -1;
770  for (unsigned int i = 0; i < cJets->size(); i++) {
771  float dR = deltaR(cJets->at(i), p4);
772  if (dR < caloJet_DR_ && dR < nearestDR) {
773  nearestDR = dR;
774  ind = i;
775  }
776  }
777 
778  if (ind == -1) {
779  caloJetEm = 0;
780  caloJetHad = 0;
781  } else {
782  const reco::CaloJet& cJet = cJets->at(ind);
783  caloJetEm = cJet.emEnergyInEB() + cJet.emEnergyInEE() + cJet.emEnergyInHF();
784  caloJetHad = cJet.hadEnergyInHB() + cJet.hadEnergyInHE() + cJet.hadEnergyInHF();
785  }
786 }
787 
bool quality(const TrackQuality) const
Track quality.
Definition: TrackBase.h:552
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
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
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
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:86
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
constexpr int pow(int x)
Definition: conifer.h:24
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
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
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
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
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