CMS 3D CMS Logo

ParticleNetFeatureEvaluator.cc
Go to the documentation of this file.
1 #include <TVector3.h>
2 #include <TTree.h>
3 
5 
14 
22 
27 
31 
32 using namespace btagbtvdeep;
33 
35 public:
36  explicit ParticleNetFeatureEvaluator(const edm::ParameterSet &);
37  ~ParticleNetFeatureEvaluator() override;
38 
39  static void fillDescriptions(edm::ConfigurationDescriptions &descriptions);
40 
41 private:
42  void beginStream(edm::StreamID) override {}
43  void produce(edm::Event &, const edm::EventSetup &) override;
44  void endStream() override {}
45  void fillParticleFeatures(DeepBoostedJetFeatures &fts,
46  const reco::Jet &jet,
47  const std::vector<math::XYZTLorentzVector> &tau_pfcandidates,
51  void fillSVFeatures(DeepBoostedJetFeatures &fts, const reco::Jet &jet);
52  void fillLostTrackFeatures(DeepBoostedJetFeatures &fts, const reco::Jet &jet);
53  bool useTrackProperties(const pat::PackedCandidate *cand);
54 
55  const double jet_radius_;
56  const double min_jet_pt_;
57  const double max_jet_eta_;
58  const double min_jet_eta_;
61  const double min_pt_for_losttrack_;
62  const double max_dr_for_losttrack_;
63  const double min_pt_for_taus_;
64  const double max_eta_for_taus_;
65  const bool include_neutrals_;
66  const bool flip_ip_sign_;
67  const double max_sip3dsig_for_flip_;
68 
79 
85 
86  const static std::vector<std::string> particle_features_;
87  const static std::vector<std::string> sv_features_;
88  const static std::vector<std::string> losttrack_features_;
89  const reco::Vertex *pv_ = nullptr;
90 
91  TTree *tree;
92  unsigned int event;
93  float jet_pt;
94  float jet_pt_raw;
95  float jet_eta;
96  float jet_phi;
97  float jet_mass;
98  unsigned int ijet;
99  std::vector<float> jet_pfcand_pt_log;
100  std::vector<float> jet_pfcand_energy_log;
101  std::vector<float> jet_pfcand_deta;
102  std::vector<float> jet_pfcand_dphi;
103  std::vector<float> jet_pfcand_eta;
104  std::vector<float> jet_pfcand_charge;
105  std::vector<float> jet_pfcand_frompv;
106  std::vector<float> jet_pfcand_nlostinnerhits;
107  std::vector<float> jet_pfcand_track_chi2;
108  std::vector<float> jet_pfcand_track_qual;
109  std::vector<float> jet_pfcand_dz;
110  std::vector<float> jet_pfcand_dzsig;
111  std::vector<float> jet_pfcand_dxy;
112  std::vector<float> jet_pfcand_dxysig;
113  std::vector<float> jet_pfcand_etarel;
114  std::vector<float> jet_pfcand_pperp_ratio;
115  std::vector<float> jet_pfcand_ppara_ratio;
116  std::vector<float> jet_pfcand_trackjet_d3d;
117  std::vector<float> jet_pfcand_trackjet_d3dsig;
118  std::vector<float> jet_pfcand_trackjet_dist;
119  std::vector<float> jet_pfcand_npixhits;
120  std::vector<float> jet_pfcand_nstriphits;
121  std::vector<float> jet_pfcand_trackjet_decayL;
122  std::vector<float> jet_pfcand_id;
123  std::vector<float> jet_pfcand_calofraction;
124  std::vector<float> jet_pfcand_hcalfraction;
125  std::vector<float> jet_pfcand_puppiw;
126  std::vector<float> jet_pfcand_muon_id;
127  std::vector<float> jet_pfcand_muon_isglobal;
128  std::vector<float> jet_pfcand_muon_chi2;
129  std::vector<float> jet_pfcand_muon_segcomp;
130  std::vector<float> jet_pfcand_muon_nvalidhit;
131  std::vector<float> jet_pfcand_muon_nstation;
132  std::vector<float> jet_pfcand_electron_detaIn;
133  std::vector<float> jet_pfcand_electron_dphiIn;
136  std::vector<float> jet_pfcand_electron_r9;
137  std::vector<float> jet_pfcand_electron_convProb;
138  std::vector<float> jet_pfcand_photon_sigIetaIeta;
139  std::vector<float> jet_pfcand_photon_r9;
140  std::vector<float> jet_pfcand_photon_eVeto;
141  std::vector<float> jet_pfcand_tau_signal;
142  std::vector<float> jet_sv_pt_log;
143  std::vector<float> jet_sv_mass;
144  std::vector<float> jet_sv_deta;
145  std::vector<float> jet_sv_dphi;
146  std::vector<float> jet_sv_eta;
147  std::vector<float> jet_sv_ntrack;
148  std::vector<float> jet_sv_chi2;
149  std::vector<float> jet_sv_dxy;
150  std::vector<float> jet_sv_dxysig;
151  std::vector<float> jet_sv_d3d;
152  std::vector<float> jet_sv_d3dsig;
153  std::vector<float> jet_losttrack_pt_log;
154  std::vector<float> jet_losttrack_eta;
155  std::vector<float> jet_losttrack_deta;
156  std::vector<float> jet_losttrack_dphi;
157  std::vector<float> jet_losttrack_charge;
158  std::vector<float> jet_losttrack_frompv;
159  std::vector<float> jet_losttrack_track_chi2;
160  std::vector<float> jet_losttrack_track_qual;
161  std::vector<float> jet_losttrack_dz;
162  std::vector<float> jet_losttrack_dxy;
163  std::vector<float> jet_losttrack_dzsig;
164  std::vector<float> jet_losttrack_dxysig;
165  std::vector<float> jet_losttrack_etarel;
166  std::vector<float> jet_losttrack_trackjet_d3d;
167  std::vector<float> jet_losttrack_trackjet_d3dsig;
168  std::vector<float> jet_losttrack_trackjet_dist;
169  std::vector<float> jet_losttrack_trackjet_decayL;
170  std::vector<float> jet_losttrack_npixhits;
171  std::vector<float> jet_losttrack_nstriphits;
172 };
173 
174 const std::vector<std::string> ParticleNetFeatureEvaluator::particle_features_{"jet_pfcand_pt_log",
175  "jet_pfcand_energy_log",
176  "jet_pfcand_deta",
177  "jet_pfcand_dphi",
178  "jet_pfcand_eta",
179  "jet_pfcand_charge",
180  "jet_pfcand_frompv",
181  "jet_pfcand_nlostinnerhits",
182  "jet_pfcand_track_chi2",
183  "jet_pfcand_track_qual",
184  "jet_pfcand_dz",
185  "jet_pfcand_dzsig",
186  "jet_pfcand_dxy",
187  "jet_pfcand_dxysig",
188  "jet_pfcand_etarel",
189  "jet_pfcand_pperp_ratio",
190  "jet_pfcand_ppara_ratio",
191  "jet_pfcand_trackjet_d3d",
192  "jet_pfcand_trackjet_d3dsig",
193  "jet_pfcand_trackjet_dist",
194  "jet_pfcand_nhits",
195  "jet_pfcand_npixhits",
196  "jet_pfcand_nstriphits",
197  "jet_pfcand_trackjet_decayL",
198  "jet_pfcand_id",
199  "jet_pfcand_calofraction",
200  "jet_pfcand_hcalfraction",
201  "jet_pfcand_puppiw",
202  "jet_pfcand_muon_id",
203  "jet_pfcand_muon_isglobal",
204  "jet_pfcand_muon_segcomp",
205  "jet_pfcand_muon_chi2",
206  "jet_pfcand_muon_nvalidhit",
207  "jet_pfcand_muon_nstation",
208  "jet_pfcand_electron_detaIn",
209  "jet_pfcand_electron_dphiIn",
210  "jet_pfcand_electron_sigIetaIeta",
211  "jet_pfcand_electron_sigIphiIphi",
212  "jet_pfcand_electron_r9",
213  "jet_pfcand_electron_convProb",
214  "jet_pfcand_photon_sigIetaIeta",
215  "jet_pfcand_photon_r9",
216  "jet_pfcand_photon_eVeto",
217  "jet_pfcand_tau_signal",
218  "pfcand_mask"};
219 
220 const std::vector<std::string> ParticleNetFeatureEvaluator::sv_features_{"jet_sv_pt_log",
221  "jet_sv_mass",
222  "jet_sv_deta",
223  "jet_sv_dphi",
224  "jet_sv_eta",
225  "jet_sv_ntrack",
226  "jet_sv_chi2",
227  "jet_sv_dxy",
228  "jet_sv_dxysig",
229  "jet_sv_d3d",
230  "jet_sv_d3dsig",
231  "sv_mask"};
232 
233 const std::vector<std::string> ParticleNetFeatureEvaluator::losttrack_features_{"jet_losttrack_pt_log",
234  "jet_losttrack_eta",
235  "jet_losttrack_deta",
236  "jet_losttrack_dphi",
237  "jet_losttrack_charge",
238  "jet_losttrack_frompv",
239  "jet_losttrack_track_chi2",
240  "jet_losttrack_track_qual",
241  "jet_losttrack_dz",
242  "jet_losttrack_dxy",
243  "jet_losttrack_dzsig",
244  "jet_losttrack_dxysig",
245  "jet_losttrack_etarel",
246  "jet_losttrack_trackjet_d3d",
247  "jet_losttrack_trackjet_d3dsig",
248  "jet_losttrack_trackjet_dist",
249  "jet_losttrack_trackjet_decayL",
250  "jet_losttrack_npixhits",
251  "jet_losttrack_nstriphits",
252  "lt_mask"};
253 
255  : jet_radius_(iConfig.getParameter<double>("jet_radius")),
256  min_jet_pt_(iConfig.getParameter<double>("min_jet_pt")),
257  max_jet_eta_(iConfig.getParameter<double>("max_jet_eta")),
258  min_jet_eta_(iConfig.getParameter<double>("min_jet_eta")),
259  min_pt_for_track_properties_(iConfig.getParameter<double>("min_pt_for_track_properties")),
260  min_pt_for_pfcandidates_(iConfig.getParameter<double>("min_pt_for_pfcandidates")),
261  min_pt_for_losttrack_(iConfig.getParameter<double>("min_pt_for_losttrack")),
262  max_dr_for_losttrack_(iConfig.getParameter<double>("max_dr_for_losttrack")),
263  min_pt_for_taus_(iConfig.getParameter<double>("min_pt_for_taus")),
264  max_eta_for_taus_(iConfig.getParameter<double>("max_eta_for_taus")),
265  include_neutrals_(iConfig.getParameter<bool>("include_neutrals")),
266  flip_ip_sign_(iConfig.getParameter<bool>("flip_ip_sign")),
267  max_sip3dsig_for_flip_(iConfig.getParameter<double>("max_sip3dsig_for_flip")),
268  muon_token_(consumes<pat::MuonCollection>(iConfig.getParameter<edm::InputTag>("muons"))),
269  electron_token_(consumes<pat::ElectronCollection>(iConfig.getParameter<edm::InputTag>("electrons"))),
270  photon_token_(consumes<pat::PhotonCollection>(iConfig.getParameter<edm::InputTag>("photons"))),
271  tau_token_(consumes<pat::TauCollection>(iConfig.getParameter<edm::InputTag>("taus"))),
272  jet_token_(consumes<edm::View<reco::Jet>>(iConfig.getParameter<edm::InputTag>("jets"))),
273  losttrack_token_(consumes<pat::PackedCandidateCollection>(iConfig.getParameter<edm::InputTag>("losttracks"))),
274  vtx_token_(consumes<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("vertices"))),
275  sv_token_(consumes<reco::VertexCompositePtrCandidateCollection>(
276  iConfig.getParameter<edm::InputTag>("secondary_vertices"))),
277  pfcand_token_(consumes<edm::View<reco::Candidate>>(iConfig.getParameter<edm::InputTag>("pf_candidates"))),
278  track_builder_token_(
279  esConsumes<TransientTrackBuilder, TransientTrackRecord>(edm::ESInputTag("", "TransientTrackBuilder"))) {
280  produces<std::vector<reco::DeepBoostedJetTagInfo>>();
281 }
282 
284 
286  // pfDeepBoostedJetTagInfos
288  desc.add<double>("jet_radius", 0.8);
289  desc.add<double>("min_jet_pt", 150);
290  desc.add<double>("max_jet_eta", 99);
291  desc.add<double>("min_jet_eta", 0.0);
292  desc.add<double>("min_pt_for_track_properties", -1);
293  desc.add<double>("min_pt_for_pfcandidates", -1);
294  desc.add<double>("min_pt_for_losttrack", 1);
295  desc.add<double>("max_dr_for_losttrack", 0.4);
296  desc.add<double>("min_pt_for_taus", 20.);
297  desc.add<double>("max_eta_for_taus", 2.5);
298  desc.add<bool>("include_neutrals", true);
299  desc.add<bool>("flip_ip_sign", false);
300  desc.add<double>("max_sip3dsig_for_flip", 99999);
301  desc.add<edm::InputTag>("vertices", edm::InputTag("offlineSlimmedPrimaryVertices"));
302  desc.add<edm::InputTag>("secondary_vertices", edm::InputTag("slimmedSecondaryVertices"));
303  desc.add<edm::InputTag>("pf_candidates", edm::InputTag("packedPFCandidates"));
304  desc.add<edm::InputTag>("losttracks", edm::InputTag("lostTracks"));
305  desc.add<edm::InputTag>("jets", edm::InputTag("slimmedJetsAK8"));
306  desc.add<edm::InputTag>("muons", edm::InputTag("slimmedMuons"));
307  desc.add<edm::InputTag>("taus", edm::InputTag("slimmedTaus"));
308  desc.add<edm::InputTag>("electrons", edm::InputTag("slimmedElectrons"));
309  desc.add<edm::InputTag>("photons", edm::InputTag("slimmedPhotons"));
310  descriptions.add("ParticleNetFeatureEvaluator", desc);
311 }
312 
314  // output collection
315  auto output_tag_infos = std::make_unique<std::vector<reco::DeepBoostedJetTagInfo>>();
316  // Input jets
317  auto jets = iEvent.getHandle(jet_token_);
318  // Input muons
319  auto muons = iEvent.getHandle(muon_token_);
320  // Input taus
321  auto taus = iEvent.getHandle(tau_token_);
322  // Input electrons
323  auto electrons = iEvent.getHandle(electron_token_);
324  // Input photons
325  auto photons = iEvent.getHandle(photon_token_);
326  // Input lost tracks
327  iEvent.getByToken(losttrack_token_, losttracks_);
328  // Primary vertexes
329  iEvent.getByToken(vtx_token_, vtxs_);
330  if (vtxs_->empty()) {
331  // produce empty TagInfos in case no primary vertex
332  iEvent.put(std::move(output_tag_infos));
333  return; // exit event
334  }
335  // Leading vertex
336  pv_ = &vtxs_->at(0);
337  // Secondary vertexs
338  iEvent.getByToken(sv_token_, svs_);
339  // PF candidates
340  iEvent.getByToken(pfcand_token_, pfcands_);
341  // Track builder
342  track_builder_ = iSetup.getHandle(track_builder_token_);
343 
344  // tau signal candidates
345  std::vector<math::XYZTLorentzVector> tau_pfcandidates;
346  for (size_t itau = 0; itau < taus->size(); itau++) {
347  if (taus->at(itau).pt() < min_pt_for_taus_)
348  continue;
349  if (fabs(taus->at(itau).eta()) > max_eta_for_taus_)
350  continue;
351  for (unsigned ipart = 0; ipart < taus->at(itau).signalCands().size(); ipart++) {
353  dynamic_cast<const pat::PackedCandidate *>(taus->at(itau).signalCands()[ipart].get());
354  tau_pfcandidates.push_back(pfcand->p4());
355  }
356  }
357 
358  // Loop over jet
359  for (std::size_t jet_n = 0; jet_n < jets->size(); jet_n++) {
360  const auto &jet = (*jets)[jet_n];
361  edm::RefToBase<reco::Jet> jet_ref(jets, jet_n);
362 
363  // create jet features
365  for (const auto &name : particle_features_)
366  features.add(name);
367  for (const auto &name : sv_features_)
368  features.add(name);
369 
370  // fill values only if above pt threshold and has daughters, otherwise left
371  bool fill_vars = true;
372  if ((jet.pt() < min_jet_pt_ and
373  dynamic_cast<const pat::Jet *>(&jet)->correctedJet("Uncorrected").pt() < min_jet_pt_) or
374  std::abs(jet.eta()) >= max_jet_eta_ or std::abs(jet.eta()) < min_jet_eta_)
375  fill_vars = false;
376  if (jet.numberOfDaughters() == 0)
377  fill_vars = false;
378 
379  // fill features
380  if (fill_vars) {
381  fillParticleFeatures(features, jet, tau_pfcandidates, *muons, *electrons, *photons);
382  fillSVFeatures(features, jet);
383  fillLostTrackFeatures(features, jet);
384  features.check_consistency(particle_features_);
385  features.check_consistency(sv_features_);
386  features.check_consistency(losttrack_features_);
387  }
388 
389  // this should always be done even if features are not filled
390  output_tag_infos->emplace_back(features, jet_ref);
391  }
392  // move output collection
393  iEvent.put(std::move(output_tag_infos));
394 }
395 
397  const auto *track = cand->bestTrack();
398  return track != nullptr and track->pt() > min_pt_for_track_properties_;
399 };
400 
402  const reco::Jet &jet,
403  const std::vector<math::XYZTLorentzVector> &tau_pfcandidates,
404  const pat::MuonCollection &muons,
407  // some jet properties
408  math::XYZVector jet_dir = jet.momentum().Unit();
409  TVector3 jet_direction(jet.momentum().Unit().x(), jet.momentum().Unit().y(), jet.momentum().Unit().z());
410  GlobalVector jet_ref_track_dir(jet.px(), jet.py(), jet.pz());
411  // vertexes
412  reco::VertexRefProd PVRefProd(vtxs_);
413  // track builder
414  TrackInfoBuilder trackinfo(track_builder_);
415 
416  // make list of pf-candidates to be considered
417  std::vector<const pat::PackedCandidate *> daughters;
418  for (const auto &dau : jet.daughterPtrVector()) {
419  // remove particles w/ extremely low puppi weights
420  const pat::PackedCandidate *cand = dynamic_cast<const pat::PackedCandidate *>(&(*dau));
421  if (not cand)
422  throw edm::Exception(edm::errors::InvalidReference) << "Cannot convert to either pat::PackedCandidate";
423  // base requirements on PF candidates
424  if (cand->pt() < min_pt_for_pfcandidates_)
425  continue;
426  // charged candidate selection (for Higgs Interaction Net)
427  if (!include_neutrals_ and (cand->charge() == 0 or cand->pt() < min_pt_for_track_properties_))
428  continue;
429  // filling daughters
430  daughters.push_back(cand);
431  }
432 
433  // sort by original pt (not Puppi-weighted)
434  std::sort(daughters.begin(), daughters.end(), [](const auto &a, const auto &b) { return a->pt() > b->pt(); });
435 
436  // reserve space
437  for (const auto &name : particle_features_)
438  fts.reserve(name, daughters.size());
439 
440  // Build observables
441  for (const auto &cand : daughters) {
442  if (!include_neutrals_ and !useTrackProperties(cand))
443  continue;
444 
445  // input particle is a packed PF candidate
446  auto candP4 = cand->p4();
447  auto candP3 = cand->momentum();
448 
449  // candidate track
450  const reco::Track *track = nullptr;
451  if (useTrackProperties(cand))
452  track = cand->bestTrack();
453 
454  // reco-vertex association
455  reco::VertexRef pv_ass = reco::VertexRef(vtxs_, 0);
456  math::XYZPoint pv_ass_pos = pv_ass->position();
457 
458  TVector3 cand_direction(candP3.x(), candP3.y(), candP3.z());
459 
460  // only when computing the nagative tagger: remove charged candidates with high sip3d
461  if (flip_ip_sign_ && track) {
462  reco::TransientTrack transientTrack = track_builder_->build(*track);
463  Measurement1D meas_ip3d = IPTools::signedImpactParameter3D(transientTrack, jet_ref_track_dir, *pv_).second;
464  if (!std::isnan(meas_ip3d.significance()) && meas_ip3d.significance() > max_sip3dsig_for_flip_) {
465  continue;
466  }
467  }
468  float ip_sign = flip_ip_sign_ ? -1.f : 1.f;
469 
470  fts.fill("jet_pfcand_pt_log", std::isnan(std::log(candP4.pt())) ? 0 : std::log(candP4.pt()));
471  fts.fill("jet_pfcand_energy_log", std::isnan(std::log(candP4.energy())) ? 0 : std::log(candP4.energy()));
472  fts.fill("jet_pfcand_eta", candP4.eta());
473  fts.fill("jet_pfcand_deta", jet_direction.Eta() - cand_direction.Eta());
474  fts.fill("jet_pfcand_dphi", jet_direction.DeltaPhi(cand_direction));
475  fts.fill("jet_pfcand_charge", cand->charge());
476  fts.fill("jet_pfcand_etarel",
477  std::isnan(reco::btau::etaRel(jet_dir, candP3)) ? 0 : reco::btau::etaRel(jet_dir, candP3));
478  fts.fill("jet_pfcand_pperp_ratio",
479  std::isnan(jet_direction.Perp(cand_direction) / cand_direction.Mag())
480  ? 0
481  : jet_direction.Perp(cand_direction) / cand_direction.Mag());
482  fts.fill("jet_pfcand_ppara_ratio",
483  std::isnan(jet_direction.Dot(cand_direction) / cand_direction.Mag())
484  ? 0
485  : jet_direction.Dot(cand_direction) / cand_direction.Mag());
486  fts.fill("jet_pfcand_frompv", cand->fromPV());
487  fts.fill("jet_pfcand_dz", ip_sign * (std::isnan(cand->dz(pv_ass_pos)) ? 0 : cand->dz(pv_ass_pos)));
488  fts.fill("jet_pfcand_dxy", ip_sign * (std::isnan(cand->dxy(pv_ass_pos)) ? 0 : cand->dxy(pv_ass_pos)));
489  fts.fill("jet_pfcand_puppiw", cand->puppiWeight());
490  fts.fill("jet_pfcand_nlostinnerhits", cand->lostInnerHits());
491  fts.fill("jet_pfcand_nhits", cand->numberOfHits());
492  fts.fill("jet_pfcand_npixhits", cand->numberOfPixelHits());
493  fts.fill("jet_pfcand_nstriphits", cand->stripLayersWithMeasurement());
494 
495  if (abs(cand->pdgId()) == 11 and cand->charge() != 0)
496  fts.fill("jet_pfcand_id", 0);
497  else if (abs(cand->pdgId()) == 13 and cand->charge() != 0)
498  fts.fill("jet_pfcand_id", 1);
499  else if (abs(cand->pdgId()) == 22 and cand->charge() == 0)
500  fts.fill("jet_pfcand_id", 2);
501  else if (abs(cand->pdgId()) != 22 and cand->charge() == 0 and abs(cand->pdgId()) != 1 and abs(cand->pdgId()) != 2)
502  fts.fill("jet_pfcand_id", 3);
503  else if (abs(cand->pdgId()) != 11 and abs(cand->pdgId()) != 13 and cand->charge() != 0)
504  fts.fill("jet_pfcand_id", 4);
505  else if (cand->charge() == 0 and abs(cand->pdgId()) == 1)
506  fts.fill("jet_pfcand_id", 5);
507  else if (cand->charge() == 0 and abs(cand->pdgId()) == 2)
508  fts.fill("jet_pfcand_id", 6);
509  else
510  fts.fill("jet_pfcand_id", -1);
511 
512  fts.fill("jet_pfcand_hcalfraction", std::isnan(cand->hcalFraction()) ? 0 : cand->hcalFraction());
513  fts.fill("jet_pfcand_calofraction", std::isnan(cand->caloFraction()) ? 0 : cand->caloFraction());
514  fts.fill("pfcand_mask", 1);
515 
516  if (track) {
517  fts.fill(
518  "jet_pfcand_dzsig",
519  std::isnan(fabs(cand->dz(pv_ass_pos)) / cand->dzError()) ? 0 : fabs(cand->dz(pv_ass_pos)) / cand->dzError());
520  fts.fill("jet_pfcand_dxysig",
521  std::isnan(fabs(cand->dxy(pv_ass_pos)) / cand->dxyError())
522  ? 0
523  : fabs(cand->dxy(pv_ass_pos)) / cand->dxyError());
524  fts.fill("jet_pfcand_track_chi2", track->normalizedChi2());
525  fts.fill("jet_pfcand_track_qual", track->qualityMask());
526 
527  reco::TransientTrack transientTrack = track_builder_->build(*track);
528  Measurement1D meas_ip2d =
529  IPTools::signedTransverseImpactParameter(transientTrack, jet_ref_track_dir, *pv_).second;
530  Measurement1D meas_ip3d = IPTools::signedImpactParameter3D(transientTrack, jet_ref_track_dir, *pv_).second;
531  Measurement1D meas_jetdist = IPTools::jetTrackDistance(transientTrack, jet_ref_track_dir, *pv_).second;
532  Measurement1D meas_decayl = IPTools::signedDecayLength3D(transientTrack, jet_ref_track_dir, *pv_).second;
533 
534  fts.fill("jet_pfcand_trackjet_d3d", ip_sign * (std::isnan(meas_ip3d.value()) ? 0 : meas_ip3d.value()));
535  fts.fill("jet_pfcand_trackjet_d3dsig",
536  std::isnan(fabs(meas_ip3d.significance())) ? 0 : fabs(meas_ip3d.significance()));
537  fts.fill("jet_pfcand_trackjet_dist", std::isnan(-meas_jetdist.value()) ? 0 : -meas_jetdist.value());
538  fts.fill("jet_pfcand_trackjet_decayL", std::isnan(meas_decayl.value()) ? 0 : meas_decayl.value());
539  } else {
540  fts.fill("jet_pfcand_dzsig", 0);
541  fts.fill("jet_pfcand_dxysig", 0);
542  fts.fill("jet_pfcand_track_chi2", 0);
543  fts.fill("jet_pfcand_track_qual", 0);
544  fts.fill("jet_pfcand_trackjet_d3d", 0);
545  fts.fill("jet_pfcand_trackjet_d3dsig", 0);
546  fts.fill("jet_pfcand_trackjet_dist", 0);
547  fts.fill("jet_pfcand_trackjet_decayL", 0);
548  }
549 
550  // muons specific
551  if (abs(cand->pdgId()) == 13) {
552  std::vector<unsigned int> muonsToSkip;
553  int ipos = -1;
554  float minDR = 1000;
555  for (size_t i = 0; i < muons.size(); i++) {
556  if (not muons[i].isPFMuon())
557  continue;
558  if (std::find(muonsToSkip.begin(), muonsToSkip.end(), i) != muonsToSkip.end())
559  continue;
560  float dR = reco::deltaR(muons[i].p4(), candP4);
561  if (dR < jet_radius_ and dR < minDR) {
562  minDR = dR;
563  ipos = i;
564  muonsToSkip.push_back(i);
565  }
566  }
567  if (ipos >= 0) {
568  int muonId = 0;
570  muonId++;
572  muonId++;
574  muonId++;
576  muonId++;
578  muonId++;
579  fts.fill("jet_pfcand_muon_id", muonId);
580  fts.fill("jet_pfcand_muon_isglobal", muons[ipos].isGlobalMuon());
581  fts.fill("jet_pfcand_muon_chi2",
582  (muons[ipos].isGlobalMuon()) ? muons[ipos].globalTrack()->normalizedChi2() : 0);
583  fts.fill("jet_pfcand_muon_nvalidhit",
584  (muons[ipos].isGlobalMuon()) ? muons[ipos].globalTrack()->hitPattern().numberOfValidMuonHits() : 0);
585  fts.fill("jet_pfcand_muon_nstation", muons[ipos].numberOfMatchedStations());
586  fts.fill("jet_pfcand_muon_segcomp", muon::segmentCompatibility(muons[ipos]));
587  } else {
588  fts.fill("jet_pfcand_muon_id", 0);
589  fts.fill("jet_pfcand_muon_isglobal", 0);
590  fts.fill("jet_pfcand_muon_chi2", 0);
591  fts.fill("jet_pfcand_muon_nvalidhit", 0);
592  fts.fill("jet_pfcand_muon_nstation", 0);
593  fts.fill("jet_pfcand_muon_segcomp", 0);
594  }
595  } else {
596  fts.fill("jet_pfcand_muon_id", 0);
597  fts.fill("jet_pfcand_muon_isglobal", 0);
598  fts.fill("jet_pfcand_muon_chi2", 0);
599  fts.fill("jet_pfcand_muon_nvalidhit", 0);
600  fts.fill("jet_pfcand_muon_nstation", 0);
601  fts.fill("jet_pfcand_muon_segcomp", 0);
602  }
603 
604  // electrons specific
605  if (abs(cand->pdgId()) == 11) {
606  int ipos = -1;
607  for (size_t i = 0; i < electrons.size(); i++) {
608  if (electrons[i].isPF()) {
609  for (const auto &element : electrons[i].associatedPackedPFCandidates()) {
610  if (abs(element->pdgId()) == 11 and element->p4() == candP4)
611  ipos = i;
612  }
613  }
614  }
615  if (ipos >= 0) {
616  fts.fill("jet_pfcand_electron_detaIn",
617  std::isnan(electrons[ipos].deltaEtaSuperClusterTrackAtVtx())
618  ? 0
619  : electrons[ipos].deltaEtaSuperClusterTrackAtVtx());
620  fts.fill("jet_pfcand_electron_dphiIn",
621  std::isnan(electrons[ipos].deltaPhiSuperClusterTrackAtVtx())
622  ? 0
623  : electrons[ipos].deltaPhiSuperClusterTrackAtVtx());
624  fts.fill("jet_pfcand_electron_sigIetaIeta",
626  fts.fill("jet_pfcand_electron_sigIphiIphi",
627  std::isnan(electrons[ipos].full5x5_sigmaIphiIphi()) ? 0 : electrons[ipos].full5x5_sigmaIphiIphi());
628  fts.fill("jet_pfcand_electron_r9", std::isnan(electrons[ipos].full5x5_r9()) ? 0 : electrons[ipos].full5x5_r9());
629  fts.fill("jet_pfcand_electron_convProb",
631  } else {
632  fts.fill("jet_pfcand_electron_detaIn", 0);
633  fts.fill("jet_pfcand_electron_dphiIn", 0);
634  fts.fill("jet_pfcand_electron_sigIetaIeta", 0);
635  fts.fill("jet_pfcand_electron_sigIphiIphi", 0);
636  fts.fill("jet_pfcand_electron_r9", 0);
637  fts.fill("jet_pfcand_electron_convProb", 0);
638  }
639  } else {
640  fts.fill("jet_pfcand_electron_detaIn", 0);
641  fts.fill("jet_pfcand_electron_dphiIn", 0);
642  fts.fill("jet_pfcand_electron_sigIetaIeta", 0);
643  fts.fill("jet_pfcand_electron_sigIphiIphi", 0);
644  fts.fill("jet_pfcand_electron_r9", 0);
645  fts.fill("jet_pfcand_electron_convProb", 0);
646  }
647 
648  // photons specific
649  if (abs(cand->pdgId()) == 22) {
650  int ipos = -1;
651  for (size_t i = 0; i < photons.size(); i++) {
652  for (const auto &element : photons[i].associatedPackedPFCandidates()) {
653  if (abs(element->pdgId()) == 22 and element->p4() == candP4)
654  ipos = i;
655  }
656  }
657  if (ipos >= 0) {
658  fts.fill("jet_pfcand_photon_sigIetaIeta",
660  fts.fill("jet_pfcand_photon_r9", std::isnan(photons[ipos].full5x5_r9()) ? 0 : photons[ipos].full5x5_r9());
661  fts.fill("jet_pfcand_photon_eVeto", photons[ipos].passElectronVeto());
662  } else {
663  fts.fill("jet_pfcand_photon_sigIetaIeta", 0);
664  fts.fill("jet_pfcand_photon_r9", 0);
665  fts.fill("jet_pfcand_photon_eVeto", 0);
666  }
667  } else {
668  fts.fill("jet_pfcand_photon_sigIetaIeta", 0);
669  fts.fill("jet_pfcand_photon_r9", 0);
670  fts.fill("jet_pfcand_photon_eVeto", 0);
671  }
672 
673  // tau specific prior to any puppi weight application
674  if (std::find(tau_pfcandidates.begin(), tau_pfcandidates.end(), cand->p4()) != tau_pfcandidates.end())
675  fts.fill("jet_pfcand_tau_signal", 1);
676  else
677  fts.fill("jet_pfcand_tau_signal", 0);
678  }
679 }
680 
682  // secondary vertexes matching jet
683  std::vector<const reco::VertexCompositePtrCandidate *> jetSVs;
684  for (const auto &sv : *svs_) {
685  if (reco::deltaR2(sv, jet) < jet_radius_ * jet_radius_) {
686  jetSVs.push_back(&sv);
687  }
688  }
689 
690  // sort by dxy significance
691  std::sort(jetSVs.begin(),
692  jetSVs.end(),
694  return sv_vertex_comparator(*sva, *svb, *pv_);
695  });
696 
697  // reserve space
698  for (const auto &name : sv_features_)
699  fts.reserve(name, jetSVs.size());
700 
701  GlobalVector jet_global_vec(jet.px(), jet.py(), jet.pz());
702 
703  float ip_sign = flip_ip_sign_ ? -1.f : 1.f;
704 
705  for (const auto *sv : jetSVs) {
706  fts.fill("sv_mask", 1);
707  fts.fill("jet_sv_pt_log", std::isnan(std::log(sv->pt())) ? 0 : std::log(sv->pt()));
708  fts.fill("jet_sv_eta", sv->eta());
709  fts.fill("jet_sv_mass", sv->mass());
710  fts.fill("jet_sv_deta", sv->eta() - jet.eta());
711  fts.fill("jet_sv_dphi", sv->phi() - jet.phi());
712  fts.fill("jet_sv_ntrack", sv->numberOfDaughters());
713  fts.fill("jet_sv_chi2", sv->vertexNormalizedChi2());
714 
716  sv->fillVertexCovariance(csv);
717  reco::Vertex svtx(sv->vertex(), csv);
718 
720  auto valxy = dxy.signedDistance(svtx, *pv_, jet_global_vec);
721  fts.fill("jet_sv_dxy", ip_sign * (std::isnan(valxy.value()) ? 0 : valxy.value()));
722  fts.fill("jet_sv_dxysig", std::isnan(fabs(valxy.significance())) ? 0 : fabs(valxy.significance()));
723 
724  VertexDistance3D d3d;
725  auto val3d = d3d.signedDistance(svtx, *pv_, jet_global_vec);
726  fts.fill("jet_sv_d3d", ip_sign * (std::isnan(val3d.value()) ? 0 : val3d.value()));
727  fts.fill("jet_sv_d3dsig", std::isnan(fabs(val3d.significance())) ? 0 : fabs(val3d.significance()));
728  }
729 }
730 
732  // some jet properties
733  TVector3 jet_direction(jet.momentum().Unit().x(), jet.momentum().Unit().y(), jet.momentum().Unit().z());
734  GlobalVector jet_ref_track_dir(jet.px(), jet.py(), jet.pz());
735  math::XYZVector jet_dir = jet.momentum().Unit();
736 
737  std::vector<pat::PackedCandidate> jet_lost_tracks;
738  for (size_t itrk = 0; itrk < losttracks_->size(); itrk++) {
739  if (reco::deltaR(losttracks_->at(itrk).p4(), jet.p4()) < max_dr_for_losttrack_ and
740  losttracks_->at(itrk).pt() > min_pt_for_losttrack_) {
741  jet_lost_tracks.push_back(losttracks_->at(itrk));
742  }
743  }
744  std::sort(
745  jet_lost_tracks.begin(), jet_lost_tracks.end(), [](const auto &a, const auto &b) { return a.pt() > b.pt(); });
746 
747  // reserve space
748  for (const auto &name : losttrack_features_)
749  fts.reserve(name, jet_lost_tracks.size());
750 
751  reco::VertexRef pv_ass = reco::VertexRef(vtxs_, 0);
752  math::XYZPoint pv_ass_pos = pv_ass->position();
753 
754  for (auto const &ltrack : jet_lost_tracks) {
755  const reco::Track *track = ltrack.bestTrack();
756 
757  // only when computing the nagative tagger: remove charged candidates with high sip3d
758  if (flip_ip_sign_) {
759  reco::TransientTrack transientTrack = track_builder_->build(*track);
760  Measurement1D meas_ip3d = IPTools::signedImpactParameter3D(transientTrack, jet_ref_track_dir, *pv_).second;
761  if (!std::isnan(meas_ip3d.significance()) && meas_ip3d.significance() > max_sip3dsig_for_flip_) {
762  continue;
763  }
764  }
765  float ip_sign = flip_ip_sign_ ? -1.f : 1.f;
766 
767  fts.fill("jet_losttrack_pt_log", std::isnan(std::log(ltrack.pt())) ? 0 : std::log(ltrack.pt()));
768  fts.fill("jet_losttrack_eta", ltrack.eta());
769  fts.fill("jet_losttrack_charge", ltrack.charge());
770  fts.fill("jet_losttrack_frompv", ltrack.fromPV());
771  fts.fill("jet_losttrack_dz", ip_sign * (std::isnan(ltrack.dz(pv_ass_pos)) ? 0 : ltrack.dz(pv_ass_pos)));
772  fts.fill("jet_losttrack_dxy", ip_sign * (std::isnan(ltrack.dxy(pv_ass_pos)) ? 0 : ltrack.dxy(pv_ass_pos)));
773  fts.fill("jet_losttrack_npixhits", ltrack.numberOfPixelHits());
774  fts.fill("jet_losttrack_nstriphits", ltrack.stripLayersWithMeasurement());
775 
776  TVector3 ltrack_momentum(ltrack.momentum().x(), ltrack.momentum().y(), ltrack.momentum().z());
777  fts.fill("jet_losttrack_deta", jet_direction.Eta() - ltrack_momentum.Eta());
778  fts.fill("jet_losttrack_dphi", jet_direction.DeltaPhi(ltrack_momentum));
779  fts.fill("jet_losttrack_etarel",
780  std::isnan(reco::btau::etaRel(jet_dir, ltrack.momentum()))
781  ? 0
782  : reco::btau::etaRel(jet_dir, ltrack.momentum()));
783 
784  if (track) {
785  fts.fill("jet_losttrack_track_chi2", track->normalizedChi2());
786  fts.fill("jet_losttrack_track_qual", track->qualityMask());
787  fts.fill("jet_losttrack_dxysig",
788  std::isnan(fabs(ltrack.dxy(pv_ass_pos)) / ltrack.dxyError())
789  ? 0
790  : fabs(ltrack.dxy(pv_ass_pos)) / ltrack.dxyError());
791  fts.fill("jet_losttrack_dzsig",
792  std::isnan(fabs(ltrack.dz(pv_ass_pos)) / ltrack.dzError())
793  ? 0
794  : fabs(ltrack.dz(pv_ass_pos)) / ltrack.dzError());
795 
796  reco::TransientTrack transientTrack = track_builder_->build(*track);
797  Measurement1D meas_ip3d = IPTools::signedImpactParameter3D(transientTrack, jet_ref_track_dir, *pv_).second;
798  Measurement1D meas_jetdist = IPTools::jetTrackDistance(transientTrack, jet_ref_track_dir, *pv_).second;
799  Measurement1D meas_decayl = IPTools::signedDecayLength3D(transientTrack, jet_ref_track_dir, *pv_).second;
800 
801  fts.fill("jet_losttrack_trackjet_d3d", ip_sign * (std::isnan(meas_ip3d.value()) ? 0 : meas_ip3d.value()));
802  fts.fill("jet_losttrack_trackjet_d3dsig",
803  std::isnan(fabs(meas_ip3d.significance())) ? 0 : fabs(meas_ip3d.significance()));
804  fts.fill("jet_losttrack_trackjet_dist", std::isnan(-meas_jetdist.value()) ? 0 : -meas_jetdist.value());
805  fts.fill("jet_losttrack_trackjet_decayL", std::isnan(meas_decayl.value()) ? 0 : meas_decayl.value());
806  } else {
807  fts.fill("jet_losttrack_track_chi2", 0);
808  fts.fill("jet_losttrack_track_qual", 0);
809  fts.fill("jet_losttrack_dxysig", 0);
810  fts.fill("jet_losttrack_dzsig", 0);
811  fts.fill("jet_losttrack_trackjet_d3d", 0);
812  fts.fill("jet_losttrack_trackjet_d3dsig", 0);
813  fts.fill("jet_losttrack_trackjet_dist", 0);
814  fts.fill("jet_losttrack_trackjet_decayL", 0);
815  }
816 
817  fts.fill("lt_mask", 1);
818  }
819 }
820 
821 // define this as a plug-in
822 DEFINE_FWK_MODULE(ParticleNetFeatureEvaluator);
edm::Handle< reco::VertexCompositePtrCandidateCollection > svs_
def isnan(num)
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
std::vector< float > jet_losttrack_trackjet_dist
double pt() const final
transverse momentum
edm::Handle< reco::VertexCollection > vtxs_
Base class for all types of Jets.
Definition: Jet.h:20
double etaRel(const math::XYZVector &dir, const math::XYZVector &track)
void beginStream(edm::StreamID) override
edm::EDGetTokenT< pat::ElectronCollection > electron_token_
std::pair< bool, Measurement1D > signedTransverseImpactParameter(const reco::TransientTrack &track, const GlobalVector &direction, const reco::Vertex &vertex)
Definition: IPTools.cc:57
std::vector< float > jet_pfcand_electron_sigIetaIeta
std::vector< pat::PackedCandidate > PackedCandidateCollection
std::pair< bool, Measurement1D > signedDecayLength3D(const TrajectoryStateOnSurface &state, const GlobalVector &direction, const reco::Vertex &vertex)
Definition: IPTools.cc:105
edm::Handle< edm::View< reco::Candidate > > pfcands_
std::pair< bool, Measurement1D > signedImpactParameter3D(const reco::TransientTrack &track, const GlobalVector &direction, const reco::Vertex &vertex)
Definition: IPTools.cc:81
std::vector< Tau > TauCollection
Definition: Tau.h:35
std::vector< float > jet_losttrack_trackjet_d3dsig
edm::ESHandle< TransientTrackBuilder > track_builder_
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
std::vector< Vertex > VertexCollection
Definition: Vertex.h:31
muons
the two sets of parameters below are mutually exclusive, depending if RECO or ALCARECO is used the us...
Definition: DiMuonV_cfg.py:214
edm::EDGetTokenT< pat::TauCollection > tau_token_
math::Error< dimension >::type CovarianceMatrix
covariance error matrix (3x3)
Definition: Vertex.h:47
std::vector< VertexCompositePtrCandidate > VertexCompositePtrCandidateCollection
collection of Candidate objects
std::vector< Muon > MuonCollection
collection of Muon objects
Definition: MuonFwd.h:9
std::pair< double, Measurement1D > jetTrackDistance(const reco::TransientTrack &track, const GlobalVector &direction, const reco::Vertex &vertex)
Definition: IPTools.cc:206
Definition: HeavyIon.h:7
edm::EDGetTokenT< pat::MuonCollection > muon_token_
static const std::vector< std::string > particle_features_
int iEvent
Definition: GenABIO.cc:224
edm::EDGetTokenT< pat::PackedCandidateCollection > losttrack_token_
std::vector< Electron > ElectronCollection
Definition: Electron.h:36
void reserve(const std::string &name, unsigned capacity)
edm::Handle< pat::PackedCandidateCollection > losttracks_
Definition: Jet.py:1
std::vector< float > features(const reco::PreId &ecal, const reco::PreId &hcal, double rho, const reco::BeamSpot &spot, noZS::EcalClusterLazyTools &ecalTools)
std::vector< float > jet_losttrack_trackjet_decayL
std::vector< float > jet_pfcand_photon_sigIetaIeta
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
edm::EDGetTokenT< edm::View< reco::Jet > > jet_token_
static const std::vector< std::string > losttrack_features_
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::vector< float > jet_pfcand_electron_sigIphiIphi
void produce(edm::Event &, const edm::EventSetup &) override
ParticleNetFeatureEvaluator(const edm::ParameterSet &)
float segmentCompatibility(const reco::Muon &muon, reco::Muon::ArbitrationType arbitrationType=reco::Muon::SegmentAndTrackArbitration)
void fillLostTrackFeatures(DeepBoostedJetFeatures &fts, const reco::Jet &jet)
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
Measurement1D signedDistance(const reco::Vertex &primVtx, const reco::Vertex &secVtx, const GlobalVector &momentum) const override
void fillParticleFeatures(DeepBoostedJetFeatures &fts, const reco::Jet &jet, const std::vector< math::XYZTLorentzVector > &tau_pfcandidates, const pat::MuonCollection &muons, const pat::ElectronCollection &electrons, const pat::PhotonCollection &photons)
edm::EDGetTokenT< reco::VertexCompositePtrCandidateCollection > sv_token_
edm::ESGetToken< TransientTrackBuilder, TransientTrackRecord > track_builder_token_
std::vector< Electron > ElectronCollection
collectin of Electron objects
Definition: ElectronFwd.h:9
edm::Ref< VertexCollection > VertexRef
persistent reference to a Vertex
Definition: VertexFwd.h:13
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:130
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
constexpr auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:30
std::vector< float > jet_pfcand_electron_convProb
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:16
edm::EDGetTokenT< pat::PhotonCollection > photon_token_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
bool sv_vertex_comparator(const SVType &sva, const SVType &svb, const PVType &pv)
Definition: deep_helpers.h:54
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
std::vector< Photon > PhotonCollection
collectin of Photon objects
Definition: PhotonFwd.h:9
double b
Definition: hdecay.h:120
Analysis-level calorimeter jet class.
Definition: Jet.h:77
void add(std::string const &label, ParameterSetDescription const &psetDescription)
bool useTrackProperties(const pat::PackedCandidate *cand)
void fill(const std::string &name, float value)
double value() const
Definition: Measurement1D.h:25
std::vector< Muon > MuonCollection
Definition: Muon.h:35
double significance() const
Definition: Measurement1D.h:29
fixed size matrix
HLT enums.
double a
Definition: hdecay.h:121
static const std::vector< std::string > sv_features_
edm::EDGetTokenT< reco::VertexCollection > vtx_token_
std::vector< Photon > PhotonCollection
Definition: Photon.h:31
def move(src, dest)
Definition: eostools.py:511
void fillSVFeatures(DeepBoostedJetFeatures &fts, const reco::Jet &jet)
edm::EDGetTokenT< edm::View< reco::Candidate > > pfcand_token_