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