CMS 3D CMS Logo

DeepTauId.cc
Go to the documentation of this file.
1 /*
2  * \class DeepTauId
3  *
4  * Tau identification using Deep NN.
5  *
6  * \author Konstantin Androsov, INFN Pisa
7  * Christian Veelken, Tallinn
8  */
9 
13 
14 #include <fstream>
15 #include "tbb/concurrent_unordered_set.h"
16 
17 namespace deep_tau {
18  constexpr int NumberOfOutputs = 4;
19 }
20 
21 namespace {
22 
23  struct dnn_inputs_2017v1 {
24  enum vars {
25  pt = 0,
26  eta,
27  mass,
28  decayMode,
29  chargedIsoPtSum,
30  neutralIsoPtSum,
31  neutralIsoPtSumWeight,
32  photonPtSumOutsideSignalCone,
33  puCorrPtSum,
34  dxy,
35  dxy_sig,
36  dz,
37  ip3d,
38  ip3d_sig,
39  hasSecondaryVertex,
40  flightLength_r,
41  flightLength_dEta,
42  flightLength_dPhi,
43  flightLength_sig,
44  leadChargedHadrCand_pt,
45  leadChargedHadrCand_dEta,
46  leadChargedHadrCand_dPhi,
47  leadChargedHadrCand_mass,
52  leadingTrackNormChi2,
53  e_ratio,
54  gj_angle_diff,
55  n_photons,
56  emFraction,
57  has_gsf_track,
58  inside_ecal_crack,
59  gsf_ele_matched,
60  gsf_ele_pt,
61  gsf_ele_dEta,
62  gsf_ele_dPhi,
63  gsf_ele_mass,
64  gsf_ele_Ee,
65  gsf_ele_Egamma,
66  gsf_ele_Pin,
67  gsf_ele_Pout,
68  gsf_ele_EtotOverPin,
69  gsf_ele_Eecal,
70  gsf_ele_dEta_SeedClusterTrackAtCalo,
71  gsf_ele_dPhi_SeedClusterTrackAtCalo,
72  gsf_ele_mvaIn_sigmaEtaEta,
73  gsf_ele_mvaIn_hadEnergy,
74  gsf_ele_mvaIn_deltaEta,
75  gsf_ele_Chi2NormGSF,
76  gsf_ele_GSFNumHits,
77  gsf_ele_GSFTrackResol,
78  gsf_ele_GSFTracklnPt,
79  gsf_ele_Chi2NormKF,
80  gsf_ele_KFNumHits,
81  leadChargedCand_etaAtEcalEntrance,
82  leadChargedCand_pt,
83  leadChargedHadrCand_HoP,
84  leadChargedHadrCand_EoP,
85  tau_visMass_innerSigCone,
86  n_matched_muons,
87  muon_pt,
88  muon_dEta,
89  muon_dPhi,
90  muon_n_matches_DT_1,
91  muon_n_matches_DT_2,
92  muon_n_matches_DT_3,
93  muon_n_matches_DT_4,
94  muon_n_matches_CSC_1,
95  muon_n_matches_CSC_2,
96  muon_n_matches_CSC_3,
97  muon_n_matches_CSC_4,
98  muon_n_hits_DT_2,
99  muon_n_hits_DT_3,
100  muon_n_hits_DT_4,
101  muon_n_hits_CSC_2,
102  muon_n_hits_CSC_3,
103  muon_n_hits_CSC_4,
104  muon_n_hits_RPC_2,
105  muon_n_hits_RPC_3,
106  muon_n_hits_RPC_4,
107  muon_n_stations_with_matches_03,
108  muon_n_stations_with_hits_23,
109  signalChargedHadrCands_sum_innerSigCone_pt,
110  signalChargedHadrCands_sum_innerSigCone_dEta,
111  signalChargedHadrCands_sum_innerSigCone_dPhi,
112  signalChargedHadrCands_sum_innerSigCone_mass,
113  signalChargedHadrCands_sum_outerSigCone_pt,
114  signalChargedHadrCands_sum_outerSigCone_dEta,
115  signalChargedHadrCands_sum_outerSigCone_dPhi,
116  signalChargedHadrCands_sum_outerSigCone_mass,
117  signalChargedHadrCands_nTotal_innerSigCone,
118  signalChargedHadrCands_nTotal_outerSigCone,
119  signalNeutrHadrCands_sum_innerSigCone_pt,
120  signalNeutrHadrCands_sum_innerSigCone_dEta,
121  signalNeutrHadrCands_sum_innerSigCone_dPhi,
122  signalNeutrHadrCands_sum_innerSigCone_mass,
123  signalNeutrHadrCands_sum_outerSigCone_pt,
124  signalNeutrHadrCands_sum_outerSigCone_dEta,
125  signalNeutrHadrCands_sum_outerSigCone_dPhi,
126  signalNeutrHadrCands_sum_outerSigCone_mass,
127  signalNeutrHadrCands_nTotal_innerSigCone,
128  signalNeutrHadrCands_nTotal_outerSigCone,
129  signalGammaCands_sum_innerSigCone_pt,
130  signalGammaCands_sum_innerSigCone_dEta,
131  signalGammaCands_sum_innerSigCone_dPhi,
132  signalGammaCands_sum_innerSigCone_mass,
133  signalGammaCands_sum_outerSigCone_pt,
134  signalGammaCands_sum_outerSigCone_dEta,
135  signalGammaCands_sum_outerSigCone_dPhi,
136  signalGammaCands_sum_outerSigCone_mass,
137  signalGammaCands_nTotal_innerSigCone,
138  signalGammaCands_nTotal_outerSigCone,
139  isolationChargedHadrCands_sum_pt,
140  isolationChargedHadrCands_sum_dEta,
141  isolationChargedHadrCands_sum_dPhi,
142  isolationChargedHadrCands_sum_mass,
143  isolationChargedHadrCands_nTotal,
144  isolationNeutrHadrCands_sum_pt,
145  isolationNeutrHadrCands_sum_dEta,
146  isolationNeutrHadrCands_sum_dPhi,
147  isolationNeutrHadrCands_sum_mass,
148  isolationNeutrHadrCands_nTotal,
149  isolationGammaCands_sum_pt,
150  isolationGammaCands_sum_dEta,
151  isolationGammaCands_sum_dPhi,
152  isolationGammaCands_sum_mass,
153  isolationGammaCands_nTotal,
154  NumberOfInputs
155  };
156  };
157 
158  namespace dnn_inputs_2017_v2 {
159  constexpr int number_of_inner_cell = 11;
160  constexpr int number_of_outer_cell = 21;
161  constexpr int number_of_conv_features = 64;
162  namespace TauBlockInputs {
163  enum vars {
164  rho = 0,
165  tau_pt,
166  tau_eta,
167  tau_phi,
168  tau_mass,
169  tau_E_over_pt,
170  tau_charge,
171  tau_n_charged_prongs,
172  tau_n_neutral_prongs,
173  chargedIsoPtSum,
174  chargedIsoPtSumdR03_over_dR05,
175  footprintCorrection,
176  neutralIsoPtSum,
177  neutralIsoPtSumWeight_over_neutralIsoPtSum,
178  neutralIsoPtSumWeightdR03_over_neutralIsoPtSum,
179  neutralIsoPtSumdR03_over_dR05,
180  photonPtSumOutsideSignalCone,
181  puCorrPtSum,
182  tau_dxy_pca_x,
183  tau_dxy_pca_y,
184  tau_dxy_pca_z,
185  tau_dxy_valid,
186  tau_dxy,
187  tau_dxy_sig,
188  tau_ip3d_valid,
189  tau_ip3d,
190  tau_ip3d_sig,
191  tau_dz,
192  tau_dz_sig_valid,
193  tau_dz_sig,
194  tau_flightLength_x,
195  tau_flightLength_y,
196  tau_flightLength_z,
197  tau_flightLength_sig,
198  tau_pt_weighted_deta_strip,
199  tau_pt_weighted_dphi_strip,
200  tau_pt_weighted_dr_signal,
201  tau_pt_weighted_dr_iso,
202  tau_leadingTrackNormChi2,
203  tau_e_ratio_valid,
204  tau_e_ratio,
205  tau_gj_angle_diff_valid,
206  tau_gj_angle_diff,
207  tau_n_photons,
208  tau_emFraction,
209  tau_inside_ecal_crack,
210  leadChargedCand_etaAtEcalEntrance_minus_tau_eta,
211  NumberOfInputs
212  };
213  }
214 
215  namespace EgammaBlockInputs {
216  enum vars {
217  rho = 0,
218  tau_pt,
219  tau_eta,
220  tau_inside_ecal_crack,
221  pfCand_ele_valid,
222  pfCand_ele_rel_pt,
223  pfCand_ele_deta,
224  pfCand_ele_dphi,
225  pfCand_ele_pvAssociationQuality,
226  pfCand_ele_puppiWeight,
227  pfCand_ele_charge,
228  pfCand_ele_lostInnerHits,
229  pfCand_ele_numberOfPixelHits,
230  pfCand_ele_vertex_dx,
231  pfCand_ele_vertex_dy,
232  pfCand_ele_vertex_dz,
233  pfCand_ele_vertex_dx_tauFL,
234  pfCand_ele_vertex_dy_tauFL,
235  pfCand_ele_vertex_dz_tauFL,
236  pfCand_ele_hasTrackDetails,
237  pfCand_ele_dxy,
238  pfCand_ele_dxy_sig,
239  pfCand_ele_dz,
240  pfCand_ele_dz_sig,
241  pfCand_ele_track_chi2_ndof,
242  pfCand_ele_track_ndof,
243  ele_valid,
244  ele_rel_pt,
245  ele_deta,
246  ele_dphi,
247  ele_cc_valid,
248  ele_cc_ele_rel_energy,
249  ele_cc_gamma_rel_energy,
250  ele_cc_n_gamma,
251  ele_rel_trackMomentumAtVtx,
252  ele_rel_trackMomentumAtCalo,
253  ele_rel_trackMomentumOut,
254  ele_rel_trackMomentumAtEleClus,
255  ele_rel_trackMomentumAtVtxWithConstraint,
256  ele_rel_ecalEnergy,
257  ele_ecalEnergy_sig,
258  ele_eSuperClusterOverP,
259  ele_eSeedClusterOverP,
260  ele_eSeedClusterOverPout,
261  ele_eEleClusterOverPout,
262  ele_deltaEtaSuperClusterTrackAtVtx,
263  ele_deltaEtaSeedClusterTrackAtCalo,
264  ele_deltaEtaEleClusterTrackAtCalo,
265  ele_deltaPhiEleClusterTrackAtCalo,
266  ele_deltaPhiSuperClusterTrackAtVtx,
267  ele_deltaPhiSeedClusterTrackAtCalo,
268  ele_mvaInput_earlyBrem,
269  ele_mvaInput_lateBrem,
270  ele_mvaInput_sigmaEtaEta,
271  ele_mvaInput_hadEnergy,
272  ele_mvaInput_deltaEta,
273  ele_gsfTrack_normalizedChi2,
274  ele_gsfTrack_numberOfValidHits,
275  ele_rel_gsfTrack_pt,
276  ele_gsfTrack_pt_sig,
277  ele_has_closestCtfTrack,
278  ele_closestCtfTrack_normalizedChi2,
279  ele_closestCtfTrack_numberOfValidHits,
280  pfCand_gamma_valid,
281  pfCand_gamma_rel_pt,
282  pfCand_gamma_deta,
283  pfCand_gamma_dphi,
284  pfCand_gamma_pvAssociationQuality,
285  pfCand_gamma_fromPV,
286  pfCand_gamma_puppiWeight,
287  pfCand_gamma_puppiWeightNoLep,
288  pfCand_gamma_lostInnerHits,
289  pfCand_gamma_numberOfPixelHits,
290  pfCand_gamma_vertex_dx,
291  pfCand_gamma_vertex_dy,
292  pfCand_gamma_vertex_dz,
293  pfCand_gamma_vertex_dx_tauFL,
294  pfCand_gamma_vertex_dy_tauFL,
295  pfCand_gamma_vertex_dz_tauFL,
296  pfCand_gamma_hasTrackDetails,
297  pfCand_gamma_dxy,
298  pfCand_gamma_dxy_sig,
299  pfCand_gamma_dz,
300  pfCand_gamma_dz_sig,
301  pfCand_gamma_track_chi2_ndof,
302  pfCand_gamma_track_ndof,
303  NumberOfInputs
304  };
305  }
306 
307  namespace MuonBlockInputs {
308  enum vars {
309  rho = 0,
310  tau_pt,
311  tau_eta,
312  tau_inside_ecal_crack,
313  pfCand_muon_valid,
314  pfCand_muon_rel_pt,
315  pfCand_muon_deta,
316  pfCand_muon_dphi,
317  pfCand_muon_pvAssociationQuality,
318  pfCand_muon_fromPV,
319  pfCand_muon_puppiWeight,
320  pfCand_muon_charge,
321  pfCand_muon_lostInnerHits,
322  pfCand_muon_numberOfPixelHits,
323  pfCand_muon_vertex_dx,
324  pfCand_muon_vertex_dy,
325  pfCand_muon_vertex_dz,
326  pfCand_muon_vertex_dx_tauFL,
327  pfCand_muon_vertex_dy_tauFL,
328  pfCand_muon_vertex_dz_tauFL,
329  pfCand_muon_hasTrackDetails,
330  pfCand_muon_dxy,
331  pfCand_muon_dxy_sig,
332  pfCand_muon_dz,
333  pfCand_muon_dz_sig,
334  pfCand_muon_track_chi2_ndof,
335  pfCand_muon_track_ndof,
336  muon_valid,
337  muon_rel_pt,
338  muon_deta,
339  muon_dphi,
340  muon_dxy,
341  muon_dxy_sig,
342  muon_normalizedChi2_valid,
343  muon_normalizedChi2,
344  muon_numberOfValidHits,
345  muon_segmentCompatibility,
346  muon_caloCompatibility,
347  muon_pfEcalEnergy_valid,
348  muon_rel_pfEcalEnergy,
349  muon_n_matches_DT_1,
350  muon_n_matches_DT_2,
351  muon_n_matches_DT_3,
352  muon_n_matches_DT_4,
353  muon_n_matches_CSC_1,
354  muon_n_matches_CSC_2,
355  muon_n_matches_CSC_3,
356  muon_n_matches_CSC_4,
357  muon_n_matches_RPC_1,
358  muon_n_matches_RPC_2,
359  muon_n_matches_RPC_3,
360  muon_n_matches_RPC_4,
361  muon_n_hits_DT_1,
362  muon_n_hits_DT_2,
363  muon_n_hits_DT_3,
364  muon_n_hits_DT_4,
365  muon_n_hits_CSC_1,
366  muon_n_hits_CSC_2,
367  muon_n_hits_CSC_3,
368  muon_n_hits_CSC_4,
369  muon_n_hits_RPC_1,
370  muon_n_hits_RPC_2,
371  muon_n_hits_RPC_3,
372  muon_n_hits_RPC_4,
373  NumberOfInputs
374  };
375  }
376 
377  namespace HadronBlockInputs {
378  enum vars {
379  rho = 0,
380  tau_pt,
381  tau_eta,
382  tau_inside_ecal_crack,
383  pfCand_chHad_valid,
384  pfCand_chHad_rel_pt,
385  pfCand_chHad_deta,
386  pfCand_chHad_dphi,
387  pfCand_chHad_leadChargedHadrCand,
388  pfCand_chHad_pvAssociationQuality,
389  pfCand_chHad_fromPV,
390  pfCand_chHad_puppiWeight,
391  pfCand_chHad_puppiWeightNoLep,
392  pfCand_chHad_charge,
393  pfCand_chHad_lostInnerHits,
394  pfCand_chHad_numberOfPixelHits,
395  pfCand_chHad_vertex_dx,
396  pfCand_chHad_vertex_dy,
397  pfCand_chHad_vertex_dz,
398  pfCand_chHad_vertex_dx_tauFL,
399  pfCand_chHad_vertex_dy_tauFL,
400  pfCand_chHad_vertex_dz_tauFL,
401  pfCand_chHad_hasTrackDetails,
402  pfCand_chHad_dxy,
403  pfCand_chHad_dxy_sig,
404  pfCand_chHad_dz,
405  pfCand_chHad_dz_sig,
406  pfCand_chHad_track_chi2_ndof,
407  pfCand_chHad_track_ndof,
408  pfCand_chHad_hcalFraction,
409  pfCand_chHad_rawCaloFraction,
410  pfCand_nHad_valid,
411  pfCand_nHad_rel_pt,
412  pfCand_nHad_deta,
413  pfCand_nHad_dphi,
414  pfCand_nHad_puppiWeight,
415  pfCand_nHad_puppiWeightNoLep,
416  pfCand_nHad_hcalFraction,
417  NumberOfInputs
418  };
419  }
420  } // namespace dnn_inputs_2017_v2
421 
422  float getTauID(const pat::Tau& tau, const std::string& tauID, float default_value = -999., bool assert_input = true) {
423  static tbb::concurrent_unordered_set<std::string> isFirstWarning;
424  if (tau.isTauIDAvailable(tauID)) {
425  return tau.tauID(tauID);
426  } else {
427  if (assert_input) {
428  throw cms::Exception("DeepTauId")
429  << "Exception in <getTauID>: No tauID '" << tauID << "' available in pat::Tau given as function argument.";
430  }
431  if (isFirstWarning.insert(tauID).second) {
432  edm::LogWarning("DeepTauID") << "Warning in <getTauID>: No tauID '" << tauID
433  << "' available in pat::Tau given as function argument."
434  << " Using default_value = " << default_value << " instead." << std::endl;
435  }
436  return default_value;
437  }
438  }
439 
440  struct TauFunc {
441  const reco::TauDiscriminatorContainer* basicTauDiscriminatorCollection;
442  const reco::TauDiscriminatorContainer* basicTauDiscriminatordR03Collection;
444  pfTauTransverseImpactParameters;
445 
447  std::map<BasicDiscr, size_t> indexMap;
448  std::map<BasicDiscr, size_t> indexMapdR03;
449 
450  const float getChargedIsoPtSum(const reco::PFTau& tau, const edm::RefToBase<reco::BaseTau> tau_ref) const {
451  return (*basicTauDiscriminatorCollection)[tau_ref].rawValues.at(indexMap.at(BasicDiscr::ChargedIsoPtSum));
452  }
453  const float getChargedIsoPtSum(const pat::Tau& tau, const edm::RefToBase<reco::BaseTau> tau_ref) const {
454  return getTauID(tau, "chargedIsoPtSum");
455  }
456  const float getChargedIsoPtSumdR03(const reco::PFTau& tau, const edm::RefToBase<reco::BaseTau> tau_ref) const {
457  return (*basicTauDiscriminatordR03Collection)[tau_ref].rawValues.at(indexMapdR03.at(BasicDiscr::ChargedIsoPtSum));
458  }
459  const float getChargedIsoPtSumdR03(const pat::Tau& tau, const edm::RefToBase<reco::BaseTau> tau_ref) const {
460  return getTauID(tau, "chargedIsoPtSumdR03");
461  }
462  const float getFootprintCorrectiondR03(const reco::PFTau& tau, const edm::RefToBase<reco::BaseTau> tau_ref) const {
463  return (*basicTauDiscriminatordR03Collection)[tau_ref].rawValues.at(
464  indexMapdR03.at(BasicDiscr::FootprintCorrection));
465  }
466  const float getFootprintCorrectiondR03(const pat::Tau& tau, const edm::RefToBase<reco::BaseTau> tau_ref) const {
467  return getTauID(tau, "footprintCorrectiondR03");
468  }
469  const float getNeutralIsoPtSum(const reco::PFTau& tau, const edm::RefToBase<reco::BaseTau> tau_ref) const {
470  return (*basicTauDiscriminatorCollection)[tau_ref].rawValues.at(indexMap.at(BasicDiscr::NeutralIsoPtSum));
471  }
472  const float getNeutralIsoPtSum(const pat::Tau& tau, const edm::RefToBase<reco::BaseTau> tau_ref) const {
473  return getTauID(tau, "neutralIsoPtSum");
474  }
475  const float getNeutralIsoPtSumdR03(const reco::PFTau& tau, const edm::RefToBase<reco::BaseTau> tau_ref) const {
476  return (*basicTauDiscriminatordR03Collection)[tau_ref].rawValues.at(indexMapdR03.at(BasicDiscr::NeutralIsoPtSum));
477  }
478  const float getNeutralIsoPtSumdR03(const pat::Tau& tau, const edm::RefToBase<reco::BaseTau> tau_ref) const {
479  return getTauID(tau, "neutralIsoPtSumdR03");
480  }
481  const float getNeutralIsoPtSumWeight(const reco::PFTau& tau, const edm::RefToBase<reco::BaseTau> tau_ref) const {
482  return (*basicTauDiscriminatorCollection)[tau_ref].rawValues.at(indexMap.at(BasicDiscr::NeutralIsoPtSumWeight));
483  }
484  const float getNeutralIsoPtSumWeight(const pat::Tau& tau, const edm::RefToBase<reco::BaseTau> tau_ref) const {
485  return getTauID(tau, "neutralIsoPtSumWeight");
486  }
487  const float getNeutralIsoPtSumdR03Weight(const reco::PFTau& tau,
488  const edm::RefToBase<reco::BaseTau> tau_ref) const {
489  return (*basicTauDiscriminatordR03Collection)[tau_ref].rawValues.at(
490  indexMapdR03.at(BasicDiscr::NeutralIsoPtSumWeight));
491  }
492  const float getNeutralIsoPtSumdR03Weight(const pat::Tau& tau, const edm::RefToBase<reco::BaseTau> tau_ref) const {
493  return getTauID(tau, "neutralIsoPtSumWeightdR03");
494  }
495  const float getPhotonPtSumOutsideSignalCone(const reco::PFTau& tau,
496  const edm::RefToBase<reco::BaseTau> tau_ref) const {
497  return (*basicTauDiscriminatorCollection)[tau_ref].rawValues.at(
498  indexMap.at(BasicDiscr::PhotonPtSumOutsideSignalCone));
499  }
500  const float getPhotonPtSumOutsideSignalCone(const pat::Tau& tau,
501  const edm::RefToBase<reco::BaseTau> tau_ref) const {
502  return getTauID(tau, "photonPtSumOutsideSignalCone");
503  }
504  const float getPhotonPtSumOutsideSignalConedR03(const reco::PFTau& tau,
505  const edm::RefToBase<reco::BaseTau> tau_ref) const {
506  return (*basicTauDiscriminatordR03Collection)[tau_ref].rawValues.at(
507  indexMapdR03.at(BasicDiscr::PhotonPtSumOutsideSignalCone));
508  }
509  const float getPhotonPtSumOutsideSignalConedR03(const pat::Tau& tau,
510  const edm::RefToBase<reco::BaseTau> tau_ref) const {
511  return getTauID(tau, "photonPtSumOutsideSignalConedR03");
512  }
513  const float getPuCorrPtSum(const reco::PFTau& tau, const edm::RefToBase<reco::BaseTau> tau_ref) const {
514  return (*basicTauDiscriminatorCollection)[tau_ref].rawValues.at(indexMap.at(BasicDiscr::PUcorrPtSum));
515  }
516  const float getPuCorrPtSum(const pat::Tau& tau, const edm::RefToBase<reco::BaseTau> tau_ref) const {
517  return getTauID(tau, "puCorrPtSum");
518  }
519 
520  auto getdxyPCA(const reco::PFTau& tau, const size_t tau_index) const {
521  return pfTauTransverseImpactParameters->value(tau_index)->dxy_PCA();
522  }
523  auto getdxyPCA(const pat::Tau& tau, const size_t tau_index) const { return tau.dxy_PCA(); }
524  auto getdxy(const reco::PFTau& tau, const size_t tau_index) const {
525  return pfTauTransverseImpactParameters->value(tau_index)->dxy();
526  }
527  auto getdxy(const pat::Tau& tau, const size_t tau_index) const { return tau.dxy(); }
528  auto getdxyError(const reco::PFTau& tau, const size_t tau_index) const {
529  return pfTauTransverseImpactParameters->value(tau_index)->dxy_error();
530  }
531  auto getdxyError(const pat::Tau& tau, const size_t tau_index) const { return tau.dxy_error(); }
532  auto getdxySig(const reco::PFTau& tau, const size_t tau_index) const {
533  return pfTauTransverseImpactParameters->value(tau_index)->dxy_Sig();
534  }
535  auto getdxySig(const pat::Tau& tau, const size_t tau_index) const { return tau.dxy_Sig(); }
536  auto getip3d(const reco::PFTau& tau, const size_t tau_index) const {
537  return pfTauTransverseImpactParameters->value(tau_index)->ip3d();
538  }
539  auto getip3d(const pat::Tau& tau, const size_t tau_index) const { return tau.ip3d(); }
540  auto getip3dError(const reco::PFTau& tau, const size_t tau_index) const {
541  return pfTauTransverseImpactParameters->value(tau_index)->ip3d_error();
542  }
543  auto getip3dError(const pat::Tau& tau, const size_t tau_index) const { return tau.ip3d_error(); }
544  auto getip3dSig(const reco::PFTau& tau, const size_t tau_index) const {
545  return pfTauTransverseImpactParameters->value(tau_index)->ip3d_Sig();
546  }
547  auto getip3dSig(const pat::Tau& tau, const size_t tau_index) const { return tau.ip3d_Sig(); }
548  auto getHasSecondaryVertex(const reco::PFTau& tau, const size_t tau_index) const {
549  return pfTauTransverseImpactParameters->value(tau_index)->hasSecondaryVertex();
550  }
551  auto getHasSecondaryVertex(const pat::Tau& tau, const size_t tau_index) const { return tau.hasSecondaryVertex(); }
552  auto getFlightLength(const reco::PFTau& tau, const size_t tau_index) const {
553  return pfTauTransverseImpactParameters->value(tau_index)->flightLength();
554  }
555  auto getFlightLength(const pat::Tau& tau, const size_t tau_index) const { return tau.flightLength(); }
556  auto getFlightLengthSig(const reco::PFTau& tau, const size_t tau_index) const {
557  return pfTauTransverseImpactParameters->value(tau_index)->flightLengthSig();
558  }
559  auto getFlightLengthSig(const pat::Tau& tau, const size_t tau_index) const { return tau.flightLengthSig(); }
560 
561  auto getLeadingTrackNormChi2(const reco::PFTau& tau) { return reco::tau::lead_track_chi2(tau); }
562  auto getLeadingTrackNormChi2(const pat::Tau& tau) { return tau.leadingTrackNormChi2(); }
563  auto getEmFraction(const pat::Tau& tau) { return tau.emFraction_MVA(); }
564  auto getEmFraction(const reco::PFTau& tau) { return tau.emFraction(); }
565  auto getEtaAtEcalEntrance(const pat::Tau& tau) { return tau.etaAtEcalEntranceLeadChargedCand(); }
566  auto getEtaAtEcalEntrance(const reco::PFTau& tau) {
567  return tau.leadPFChargedHadrCand()->positionAtECALEntrance().eta();
568  }
569  auto getEcalEnergyLeadingChargedHadr(const reco::PFTau& tau) { return tau.leadPFChargedHadrCand()->ecalEnergy(); }
570  auto getEcalEnergyLeadingChargedHadr(const pat::Tau& tau) { return tau.ecalEnergyLeadChargedHadrCand(); }
571  auto getHcalEnergyLeadingChargedHadr(const reco::PFTau& tau) { return tau.leadPFChargedHadrCand()->hcalEnergy(); }
572  auto getHcalEnergyLeadingChargedHadr(const pat::Tau& tau) { return tau.hcalEnergyLeadChargedHadrCand(); }
573 
574  template <typename PreDiscrType>
575  bool passPrediscriminants(const PreDiscrType prediscriminants,
576  const size_t andPrediscriminants,
577  const edm::RefToBase<reco::BaseTau> tau_ref) {
578  bool passesPrediscriminants = (andPrediscriminants ? 1 : 0);
579  // check tau passes prediscriminants
580  size_t nPrediscriminants = prediscriminants.size();
581  for (size_t iDisc = 0; iDisc < nPrediscriminants; ++iDisc) {
582  // current discriminant result for this tau
583  double discResult = (*prediscriminants[iDisc].handle)[tau_ref];
584  uint8_t thisPasses = (discResult > prediscriminants[iDisc].cut) ? 1 : 0;
585 
586  // if we are using the AND option, as soon as one fails,
587  // the result is FAIL and we can quit looping.
588  // if we are using the OR option as soon as one passes,
589  // the result is pass and we can quit looping
590 
591  // truth table
592  // | result (thisPasses)
593  // | F | T
594  //-----------------------------------
595  // AND(T) | res=fails | continue
596  // | break |
597  //-----------------------------------
598  // OR (F) | continue | res=passes
599  // | | break
600 
601  if (thisPasses ^ andPrediscriminants) //XOR
602  {
603  passesPrediscriminants = (andPrediscriminants ? 0 : 1); //NOR
604  break;
605  }
606  }
607  return passesPrediscriminants;
608  }
609  };
610 
611  namespace candFunc {
612  auto getTauDz(const reco::PFCandidate& cand) { return cand.bestTrack()->dz(); }
613  auto getTauDz(const pat::PackedCandidate& cand) { return cand.dz(); }
614  auto getTauDZSigValid(const reco::PFCandidate& cand) {
615  return cand.bestTrack() != nullptr && std::isnormal(cand.bestTrack()->dz()) && std::isnormal(cand.dzError()) &&
616  cand.dzError() > 0;
617  }
618  auto getTauDZSigValid(const pat::PackedCandidate& cand) {
619  return cand.hasTrackDetails() && std::isnormal(cand.dz()) && std::isnormal(cand.dzError()) && cand.dzError() > 0;
620  }
621  auto getTauDxy(const reco::PFCandidate& cand) { return cand.bestTrack()->dxy(); }
622  auto getTauDxy(const pat::PackedCandidate& cand) { return cand.dxy(); }
623  auto getPvAssocationQuality(const reco::PFCandidate& cand) { return 0.7013f; }
624  auto getPvAssocationQuality(const pat::PackedCandidate& cand) { return cand.pvAssociationQuality(); }
625  auto getPuppiWeight(const reco::PFCandidate& cand, const float aod_value) { return aod_value; }
626  auto getPuppiWeight(const pat::PackedCandidate& cand, const float aod_value) { return cand.puppiWeight(); }
627  auto getPuppiWeightNoLep(const reco::PFCandidate& cand, const float aod_value) { return aod_value; }
628  auto getPuppiWeightNoLep(const pat::PackedCandidate& cand, const float aod_value) {
629  return cand.puppiWeightNoLep();
630  }
631  auto getLostInnerHits(const reco::PFCandidate& cand, float default_value) {
632  return cand.bestTrack() != nullptr
633  ? cand.bestTrack()->hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS)
634  : default_value;
635  }
636  auto getLostInnerHits(const pat::PackedCandidate& cand, float default_value) { return cand.lostInnerHits(); }
637  auto getNumberOfPixelHits(const reco::PFCandidate& cand, float default_value) {
638  return cand.bestTrack() != nullptr
639  ? cand.bestTrack()->hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS)
640  : default_value;
641  }
642  auto getNumberOfPixelHits(const pat::PackedCandidate& cand, float default_value) {
643  return cand.numberOfPixelHits();
644  }
645  auto getHasTrackDetails(const reco::PFCandidate& cand) { return cand.bestTrack() != nullptr; }
646  auto getHasTrackDetails(const pat::PackedCandidate& cand) { return cand.hasTrackDetails(); }
647  auto getPseudoTrack(const reco::PFCandidate& cand) { return *cand.bestTrack(); }
648  auto getPseudoTrack(const pat::PackedCandidate& cand) { return cand.pseudoTrack(); }
649  auto getFromPV(const reco::PFCandidate& cand) { return 0.9994f; }
650  auto getFromPV(const pat::PackedCandidate& cand) { return cand.fromPV(); }
651  auto getHCalFraction(const reco::PFCandidate& cand, bool disable_hcalFraction_workaround) {
652  return cand.rawHcalEnergy() / (cand.rawHcalEnergy() + cand.rawEcalEnergy());
653  }
654  auto getHCalFraction(const pat::PackedCandidate& cand, bool disable_hcalFraction_workaround) {
655  float hcal_fraction = 0.;
656  if (disable_hcalFraction_workaround) {
657  // CV: use consistent definition for pfCand_chHad_hcalFraction
658  // in DeepTauId.cc code and in TauMLTools/Production/plugins/TauTupleProducer.cc
659  hcal_fraction = cand.hcalFraction();
660  } else {
661  // CV: backwards compatibility with DeepTau training v2p1 used during Run 2
662  if (cand.pdgId() == 1 || cand.pdgId() == 130) {
663  hcal_fraction = cand.hcalFraction();
664  } else if (cand.isIsolatedChargedHadron()) {
665  hcal_fraction = cand.rawHcalFraction();
666  }
667  }
668  return hcal_fraction;
669  }
670  auto getRawCaloFraction(const reco::PFCandidate& cand) {
671  return (cand.rawEcalEnergy() + cand.rawHcalEnergy()) / cand.energy();
672  }
673  auto getRawCaloFraction(const pat::PackedCandidate& cand) { return cand.rawCaloFraction(); }
674  }; // namespace candFunc
675 
676  template <typename LVector1, typename LVector2>
677  float dEta(const LVector1& p4, const LVector2& tau_p4) {
678  return static_cast<float>(p4.eta() - tau_p4.eta());
679  }
680 
681  template <typename LVector1, typename LVector2>
682  float dPhi(const LVector1& p4_1, const LVector2& p4_2) {
683  return static_cast<float>(reco::deltaPhi(p4_2.phi(), p4_1.phi()));
684  }
685 
686  struct MuonHitMatchV1 {
687  static constexpr int n_muon_stations = 4;
688 
689  std::map<int, std::vector<UInt_t>> n_matches, n_hits;
690  unsigned n_muons{0};
691  const pat::Muon* best_matched_muon{nullptr};
692  double deltaR2_best_match{-1};
693 
694  MuonHitMatchV1() {
695  n_matches[MuonSubdetId::DT].assign(n_muon_stations, 0);
696  n_matches[MuonSubdetId::CSC].assign(n_muon_stations, 0);
697  n_matches[MuonSubdetId::RPC].assign(n_muon_stations, 0);
698  n_hits[MuonSubdetId::DT].assign(n_muon_stations, 0);
699  n_hits[MuonSubdetId::CSC].assign(n_muon_stations, 0);
700  n_hits[MuonSubdetId::RPC].assign(n_muon_stations, 0);
701  }
702 
703  void addMatchedMuon(const pat::Muon& muon, reco::BaseTau const& tau) {
704  static constexpr int n_stations = 4;
705 
706  ++n_muons;
707  const double dR2 = reco::deltaR2(tau.p4(), muon.p4());
708  if (!best_matched_muon || dR2 < deltaR2_best_match) {
709  best_matched_muon = &muon;
710  deltaR2_best_match = dR2;
711  }
712 
713  for (const auto& segment : muon.matches()) {
714  if (segment.segmentMatches.empty())
715  continue;
716  if (n_matches.count(segment.detector()))
717  ++n_matches.at(segment.detector()).at(segment.station() - 1);
718  }
719 
720  if (muon.outerTrack().isNonnull()) {
721  const auto& hit_pattern = muon.outerTrack()->hitPattern();
722  for (int hit_index = 0; hit_index < hit_pattern.numberOfAllHits(reco::HitPattern::TRACK_HITS); ++hit_index) {
723  auto hit_id = hit_pattern.getHitPattern(reco::HitPattern::TRACK_HITS, hit_index);
724  if (hit_id == 0)
725  break;
726  if (hit_pattern.muonHitFilter(hit_id) && (hit_pattern.getHitType(hit_id) == TrackingRecHit::valid ||
727  hit_pattern.getHitType(hit_id == TrackingRecHit::bad))) {
728  const int station = hit_pattern.getMuonStation(hit_id) - 1;
729  if (station > 0 && station < n_stations) {
730  std::vector<UInt_t>* muon_n_hits = nullptr;
731  if (hit_pattern.muonDTHitFilter(hit_id))
732  muon_n_hits = &n_hits.at(MuonSubdetId::DT);
733  else if (hit_pattern.muonCSCHitFilter(hit_id))
734  muon_n_hits = &n_hits.at(MuonSubdetId::CSC);
735  else if (hit_pattern.muonRPCHitFilter(hit_id))
736  muon_n_hits = &n_hits.at(MuonSubdetId::RPC);
737 
738  if (muon_n_hits)
739  ++muon_n_hits->at(station);
740  }
741  }
742  }
743  }
744  }
745 
746  template <typename TauCastType>
747  static std::vector<const pat::Muon*> findMatchedMuons(const TauCastType& tau,
748  const std::vector<pat::Muon>* muons,
749  double deltaR,
750  double minPt) {
751  const reco::Muon* hadr_cand_muon = nullptr;
752  if (tau.leadPFChargedHadrCand().isNonnull() && tau.leadPFChargedHadrCand()->muonRef().isNonnull())
753  hadr_cand_muon = tau.leadPFChargedHadrCand()->muonRef().get();
754  std::vector<const pat::Muon*> matched_muons;
755  const double dR2 = deltaR * deltaR;
756  for (const pat::Muon& muon : *muons) {
757  const reco::Muon* reco_muon = &muon;
758  if (muon.pt() <= minPt)
759  continue;
760  if (reco_muon == hadr_cand_muon)
761  continue;
762  if (reco::deltaR2(tau.p4(), muon.p4()) >= dR2)
763  continue;
764  matched_muons.push_back(&muon);
765  }
766  return matched_muons;
767  }
768 
769  template <typename dnn, typename TensorElemGet, typename TauCastType>
770  void fillTensor(const TensorElemGet& get, const TauCastType& tau, float default_value) const {
771  get(dnn::n_matched_muons) = n_muons;
772  get(dnn::muon_pt) = best_matched_muon != nullptr ? best_matched_muon->p4().pt() : default_value;
773  get(dnn::muon_dEta) = best_matched_muon != nullptr ? dEta(best_matched_muon->p4(), tau.p4()) : default_value;
774  get(dnn::muon_dPhi) = best_matched_muon != nullptr ? dPhi(best_matched_muon->p4(), tau.p4()) : default_value;
775  get(dnn::muon_n_matches_DT_1) = n_matches.at(MuonSubdetId::DT).at(0);
776  get(dnn::muon_n_matches_DT_2) = n_matches.at(MuonSubdetId::DT).at(1);
777  get(dnn::muon_n_matches_DT_3) = n_matches.at(MuonSubdetId::DT).at(2);
778  get(dnn::muon_n_matches_DT_4) = n_matches.at(MuonSubdetId::DT).at(3);
779  get(dnn::muon_n_matches_CSC_1) = n_matches.at(MuonSubdetId::CSC).at(0);
780  get(dnn::muon_n_matches_CSC_2) = n_matches.at(MuonSubdetId::CSC).at(1);
781  get(dnn::muon_n_matches_CSC_3) = n_matches.at(MuonSubdetId::CSC).at(2);
782  get(dnn::muon_n_matches_CSC_4) = n_matches.at(MuonSubdetId::CSC).at(3);
783  get(dnn::muon_n_hits_DT_2) = n_hits.at(MuonSubdetId::DT).at(1);
784  get(dnn::muon_n_hits_DT_3) = n_hits.at(MuonSubdetId::DT).at(2);
785  get(dnn::muon_n_hits_DT_4) = n_hits.at(MuonSubdetId::DT).at(3);
786  get(dnn::muon_n_hits_CSC_2) = n_hits.at(MuonSubdetId::CSC).at(1);
787  get(dnn::muon_n_hits_CSC_3) = n_hits.at(MuonSubdetId::CSC).at(2);
788  get(dnn::muon_n_hits_CSC_4) = n_hits.at(MuonSubdetId::CSC).at(3);
789  get(dnn::muon_n_hits_RPC_2) = n_hits.at(MuonSubdetId::RPC).at(1);
790  get(dnn::muon_n_hits_RPC_3) = n_hits.at(MuonSubdetId::RPC).at(2);
791  get(dnn::muon_n_hits_RPC_4) = n_hits.at(MuonSubdetId::RPC).at(3);
792  get(dnn::muon_n_stations_with_matches_03) = countMuonStationsWithMatches(0, 3);
793  get(dnn::muon_n_stations_with_hits_23) = countMuonStationsWithHits(2, 3);
794  }
795 
796  private:
797  unsigned countMuonStationsWithMatches(size_t first_station, size_t last_station) const {
798  static const std::map<int, std::vector<bool>> masks = {
799  {MuonSubdetId::DT, {false, false, false, false}},
800  {MuonSubdetId::CSC, {true, false, false, false}},
801  {MuonSubdetId::RPC, {false, false, false, false}},
802  };
803  unsigned cnt = 0;
804  for (unsigned n = first_station; n <= last_station; ++n) {
805  for (const auto& match : n_matches) {
806  if (!masks.at(match.first).at(n) && match.second.at(n) > 0)
807  ++cnt;
808  }
809  }
810  return cnt;
811  }
812 
813  unsigned countMuonStationsWithHits(size_t first_station, size_t last_station) const {
814  static const std::map<int, std::vector<bool>> masks = {
815  {MuonSubdetId::DT, {false, false, false, false}},
816  {MuonSubdetId::CSC, {false, false, false, false}},
817  {MuonSubdetId::RPC, {false, false, false, false}},
818  };
819 
820  unsigned cnt = 0;
821  for (unsigned n = first_station; n <= last_station; ++n) {
822  for (const auto& hit : n_hits) {
823  if (!masks.at(hit.first).at(n) && hit.second.at(n) > 0)
824  ++cnt;
825  }
826  }
827  return cnt;
828  }
829  };
830 
831  struct MuonHitMatchV2 {
832  static constexpr size_t n_muon_stations = 4;
833  static constexpr int first_station_id = 1;
834  static constexpr int last_station_id = first_station_id + n_muon_stations - 1;
835  using CountArray = std::array<unsigned, n_muon_stations>;
836  using CountMap = std::map<int, CountArray>;
837 
838  const std::vector<int>& consideredSubdets() {
839  static const std::vector<int> subdets = {MuonSubdetId::DT, MuonSubdetId::CSC, MuonSubdetId::RPC};
840  return subdets;
841  }
842 
843  const std::string& subdetName(int subdet) {
844  static const std::map<int, std::string> subdet_names = {
845  {MuonSubdetId::DT, "DT"}, {MuonSubdetId::CSC, "CSC"}, {MuonSubdetId::RPC, "RPC"}};
846  if (!subdet_names.count(subdet))
847  throw cms::Exception("MuonHitMatch") << "Subdet name for subdet id " << subdet << " not found.";
848  return subdet_names.at(subdet);
849  }
850 
851  size_t getStationIndex(int station, bool throw_exception) const {
852  if (station < first_station_id || station > last_station_id) {
853  if (throw_exception)
854  throw cms::Exception("MuonHitMatch") << "Station id is out of range";
856  }
857  return static_cast<size_t>(station - 1);
858  }
859 
860  MuonHitMatchV2(const pat::Muon& muon) {
861  for (int subdet : consideredSubdets()) {
862  n_matches[subdet].fill(0);
863  n_hits[subdet].fill(0);
864  }
865 
866  countMatches(muon, n_matches);
867  countHits(muon, n_hits);
868  }
869 
870  void countMatches(const pat::Muon& muon, CountMap& n_matches) {
871  for (const auto& segment : muon.matches()) {
872  if (segment.segmentMatches.empty() && segment.rpcMatches.empty())
873  continue;
874  if (n_matches.count(segment.detector())) {
875  const size_t station_index = getStationIndex(segment.station(), true);
876  ++n_matches.at(segment.detector()).at(station_index);
877  }
878  }
879  }
880 
881  void countHits(const pat::Muon& muon, CountMap& n_hits) {
882  if (muon.outerTrack().isNonnull()) {
883  const auto& hit_pattern = muon.outerTrack()->hitPattern();
884  for (int hit_index = 0; hit_index < hit_pattern.numberOfAllHits(reco::HitPattern::TRACK_HITS); ++hit_index) {
885  auto hit_id = hit_pattern.getHitPattern(reco::HitPattern::TRACK_HITS, hit_index);
886  if (hit_id == 0)
887  break;
888  if (hit_pattern.muonHitFilter(hit_id) && (hit_pattern.getHitType(hit_id) == TrackingRecHit::valid ||
889  hit_pattern.getHitType(hit_id) == TrackingRecHit::bad)) {
890  const size_t station_index = getStationIndex(hit_pattern.getMuonStation(hit_id), false);
891  if (station_index < n_muon_stations) {
892  CountArray* muon_n_hits = nullptr;
893  if (hit_pattern.muonDTHitFilter(hit_id))
894  muon_n_hits = &n_hits.at(MuonSubdetId::DT);
895  else if (hit_pattern.muonCSCHitFilter(hit_id))
896  muon_n_hits = &n_hits.at(MuonSubdetId::CSC);
897  else if (hit_pattern.muonRPCHitFilter(hit_id))
898  muon_n_hits = &n_hits.at(MuonSubdetId::RPC);
899 
900  if (muon_n_hits)
901  ++muon_n_hits->at(station_index);
902  }
903  }
904  }
905  }
906  }
907 
908  unsigned nMatches(int subdet, int station) const {
909  if (!n_matches.count(subdet))
910  throw cms::Exception("MuonHitMatch") << "Subdet " << subdet << " not found.";
911  const size_t station_index = getStationIndex(station, true);
912  return n_matches.at(subdet).at(station_index);
913  }
914 
915  unsigned nHits(int subdet, int station) const {
916  if (!n_hits.count(subdet))
917  throw cms::Exception("MuonHitMatch") << "Subdet " << subdet << " not found.";
918  const size_t station_index = getStationIndex(station, true);
919  return n_hits.at(subdet).at(station_index);
920  }
921 
922  unsigned countMuonStationsWithMatches(int first_station, int last_station) const {
923  static const std::map<int, std::vector<bool>> masks = {
924  {MuonSubdetId::DT, {false, false, false, false}},
925  {MuonSubdetId::CSC, {true, false, false, false}},
926  {MuonSubdetId::RPC, {false, false, false, false}},
927  };
928  const size_t first_station_index = getStationIndex(first_station, true);
929  const size_t last_station_index = getStationIndex(last_station, true);
930  unsigned cnt = 0;
931  for (size_t n = first_station_index; n <= last_station_index; ++n) {
932  for (const auto& match : n_matches) {
933  if (!masks.at(match.first).at(n) && match.second.at(n) > 0)
934  ++cnt;
935  }
936  }
937  return cnt;
938  }
939 
940  unsigned countMuonStationsWithHits(int first_station, int last_station) const {
941  static const std::map<int, std::vector<bool>> masks = {
942  {MuonSubdetId::DT, {false, false, false, false}},
943  {MuonSubdetId::CSC, {false, false, false, false}},
944  {MuonSubdetId::RPC, {false, false, false, false}},
945  };
946 
947  const size_t first_station_index = getStationIndex(first_station, true);
948  const size_t last_station_index = getStationIndex(last_station, true);
949  unsigned cnt = 0;
950  for (size_t n = first_station_index; n <= last_station_index; ++n) {
951  for (const auto& hit : n_hits) {
952  if (!masks.at(hit.first).at(n) && hit.second.at(n) > 0)
953  ++cnt;
954  }
955  }
956  return cnt;
957  }
958 
959  private:
960  CountMap n_matches, n_hits;
961  };
962 
963  enum class CellObjectType {
964  PfCand_electron,
965  PfCand_muon,
966  PfCand_chargedHadron,
967  PfCand_neutralHadron,
968  PfCand_gamma,
969  Electron,
970  Muon,
971  Other
972  };
973 
974  template <typename Object>
975  CellObjectType GetCellObjectType(const Object&);
976  template <>
977  CellObjectType GetCellObjectType(const pat::Electron&) {
979  }
980  template <>
981  CellObjectType GetCellObjectType(const pat::Muon&) {
982  return CellObjectType::Muon;
983  }
984 
985  template <>
986  CellObjectType GetCellObjectType(reco::Candidate const& cand) {
987  static const std::map<int, CellObjectType> obj_types = {{11, CellObjectType::PfCand_electron},
988  {13, CellObjectType::PfCand_muon},
989  {22, CellObjectType::PfCand_gamma},
990  {130, CellObjectType::PfCand_neutralHadron},
991  {211, CellObjectType::PfCand_chargedHadron}};
992 
993  auto iter = obj_types.find(std::abs(cand.pdgId()));
994  if (iter == obj_types.end())
995  return CellObjectType::Other;
996  return iter->second;
997  }
998 
999  using Cell = std::map<CellObjectType, size_t>;
1000  struct CellIndex {
1001  int eta, phi;
1002 
1003  bool operator<(const CellIndex& other) const {
1004  if (eta != other.eta)
1005  return eta < other.eta;
1006  return phi < other.phi;
1007  }
1008  };
1009 
1010  class CellGrid {
1011  public:
1012  using Map = std::map<CellIndex, Cell>;
1013  using const_iterator = Map::const_iterator;
1014 
1015  CellGrid(unsigned n_cells_eta,
1016  unsigned n_cells_phi,
1017  double cell_size_eta,
1018  double cell_size_phi,
1019  bool disable_CellIndex_workaround)
1020  : nCellsEta(n_cells_eta),
1021  nCellsPhi(n_cells_phi),
1022  nTotal(nCellsEta * nCellsPhi),
1023  cellSizeEta(cell_size_eta),
1024  cellSizePhi(cell_size_phi),
1025  disable_CellIndex_workaround_(disable_CellIndex_workaround) {
1026  if (nCellsEta % 2 != 1 || nCellsEta < 1)
1027  throw cms::Exception("DeepTauId") << "Invalid number of eta cells.";
1028  if (nCellsPhi % 2 != 1 || nCellsPhi < 1)
1029  throw cms::Exception("DeepTauId") << "Invalid number of phi cells.";
1030  if (cellSizeEta <= 0 || cellSizePhi <= 0)
1031  throw cms::Exception("DeepTauId") << "Invalid cell size.";
1032  }
1033 
1034  int maxEtaIndex() const { return static_cast<int>((nCellsEta - 1) / 2); }
1035  int maxPhiIndex() const { return static_cast<int>((nCellsPhi - 1) / 2); }
1036  double maxDeltaEta() const { return cellSizeEta * (0.5 + maxEtaIndex()); }
1037  double maxDeltaPhi() const { return cellSizePhi * (0.5 + maxPhiIndex()); }
1038  int getEtaTensorIndex(const CellIndex& cellIndex) const { return cellIndex.eta + maxEtaIndex(); }
1039  int getPhiTensorIndex(const CellIndex& cellIndex) const { return cellIndex.phi + maxPhiIndex(); }
1040 
1041  bool tryGetCellIndex(double deltaEta, double deltaPhi, CellIndex& cellIndex) const {
1042  const auto getCellIndex = [this](double x, double maxX, double size, int& index) {
1043  const double absX = std::abs(x);
1044  if (absX > maxX)
1045  return false;
1046  double absIndex;
1047  if (disable_CellIndex_workaround_) {
1048  // CV: use consistent definition for CellIndex
1049  // in DeepTauId.cc code and new DeepTau trainings
1050  absIndex = std::floor(absX / size + 0.5);
1051  } else {
1052  // CV: backwards compatibility with DeepTau training v2p1 used during Run 2
1053  absIndex = std::floor(std::abs(absX / size - 0.5));
1054  }
1055  index = static_cast<int>(std::copysign(absIndex, x));
1056  return true;
1057  };
1058 
1059  return getCellIndex(deltaEta, maxDeltaEta(), cellSizeEta, cellIndex.eta) &&
1060  getCellIndex(deltaPhi, maxDeltaPhi(), cellSizePhi, cellIndex.phi);
1061  }
1062 
1063  size_t num_valid_cells() const { return cells.size(); }
1064  Cell& operator[](const CellIndex& cellIndex) { return cells[cellIndex]; }
1065  const Cell& at(const CellIndex& cellIndex) const { return cells.at(cellIndex); }
1066  size_t count(const CellIndex& cellIndex) const { return cells.count(cellIndex); }
1067  const_iterator find(const CellIndex& cellIndex) const { return cells.find(cellIndex); }
1068  const_iterator begin() const { return cells.begin(); }
1069  const_iterator end() const { return cells.end(); }
1070 
1071  public:
1072  const unsigned nCellsEta, nCellsPhi, nTotal;
1073  const double cellSizeEta, cellSizePhi;
1074 
1075  private:
1076  std::map<CellIndex, Cell> cells;
1077  const bool disable_CellIndex_workaround_;
1078  };
1079 } // anonymous namespace
1080 
1082 const std::map<bd, std::string> deep_tau::DeepTauBase::stringFromDiscriminator_{
1083  {bd::ChargedIsoPtSum, "ChargedIsoPtSum"},
1084  {bd::NeutralIsoPtSum, "NeutralIsoPtSum"},
1085  {bd::NeutralIsoPtSumWeight, "NeutralIsoPtSumWeight"},
1086  {bd::FootprintCorrection, "TauFootprintCorrection"},
1087  {bd::PhotonPtSumOutsideSignalCone, "PhotonPtSumOutsideSignalCone"},
1088  {bd::PUcorrPtSum, "PUcorrPtSum"}};
1089 const std::vector<bd> deep_tau::DeepTauBase::requiredBasicDiscriminators_ = {bd::ChargedIsoPtSum,
1090  bd::NeutralIsoPtSum,
1091  bd::NeutralIsoPtSumWeight,
1092  bd::PhotonPtSumOutsideSignalCone,
1093  bd::PUcorrPtSum};
1094 const std::vector<bd> deep_tau::DeepTauBase::requiredBasicDiscriminatorsdR03_ = {bd::ChargedIsoPtSum,
1095  bd::NeutralIsoPtSum,
1096  bd::NeutralIsoPtSumWeight,
1097  bd::PhotonPtSumOutsideSignalCone,
1098  bd::FootprintCorrection};
1099 
1101 public:
1102  static constexpr float default_value = -999.;
1103 
1104  static const OutputCollection& GetOutputs() {
1105  static constexpr size_t e_index = 0, mu_index = 1, tau_index = 2, jet_index = 3;
1106  static const OutputCollection outputs_ = {
1107  {"VSe", Output({tau_index}, {e_index, tau_index})},
1108  {"VSmu", Output({tau_index}, {mu_index, tau_index})},
1109  {"VSjet", Output({tau_index}, {jet_index, tau_index})},
1110  };
1111  return outputs_;
1112  }
1113 
1114  const std::map<BasicDiscriminator, size_t> matchDiscriminatorIndices(
1115  edm::Event& event,
1116  edm::EDGetTokenT<reco::TauDiscriminatorContainer> discriminatorContainerToken,
1117  std::vector<BasicDiscriminator> requiredDiscr) {
1118  std::map<std::string, size_t> discrIndexMapStr;
1119  auto const aHandle = event.getHandle(discriminatorContainerToken);
1120  auto const aProv = aHandle.provenance();
1121  if (aProv == nullptr)
1122  aHandle.whyFailed()->raise();
1123  const auto& psetsFromProvenance = edm::parameterSet(*aProv, event.processHistory());
1124  auto const idlist = psetsFromProvenance.getParameter<std::vector<edm::ParameterSet>>("IDdefinitions");
1125  for (size_t j = 0; j < idlist.size(); ++j) {
1126  std::string idname = idlist[j].getParameter<std::string>("IDname");
1127  if (discrIndexMapStr.count(idname)) {
1128  throw cms::Exception("DeepTauId")
1129  << "basic discriminator " << idname << " appears more than once in the input.";
1130  }
1131  discrIndexMapStr[idname] = j;
1132  }
1133 
1134  //translate to a map of <BasicDiscriminator, index> and check if all discriminators are present
1135  std::map<BasicDiscriminator, size_t> discrIndexMap;
1136  for (size_t i = 0; i < requiredDiscr.size(); i++) {
1137  if (discrIndexMapStr.find(stringFromDiscriminator_.at(requiredDiscr[i])) == discrIndexMapStr.end())
1138  throw cms::Exception("DeepTauId") << "Basic Discriminator " << stringFromDiscriminator_.at(requiredDiscr[i])
1139  << " was not provided in the config file.";
1140  else
1141  discrIndexMap[requiredDiscr[i]] = discrIndexMapStr[stringFromDiscriminator_.at(requiredDiscr[i])];
1142  }
1143  return discrIndexMap;
1144  }
1145 
1148  desc.add<edm::InputTag>("electrons", edm::InputTag("slimmedElectrons"));
1149  desc.add<edm::InputTag>("muons", edm::InputTag("slimmedMuons"));
1150  desc.add<edm::InputTag>("taus", edm::InputTag("slimmedTaus"));
1151  desc.add<edm::InputTag>("pfcands", edm::InputTag("packedPFCandidates"));
1152  desc.add<edm::InputTag>("vertices", edm::InputTag("offlineSlimmedPrimaryVertices"));
1153  desc.add<edm::InputTag>("rho", edm::InputTag("fixedGridRhoAll"));
1154  desc.add<std::vector<std::string>>("graph_file",
1155  {"RecoTauTag/TrainingFiles/data/DeepTauId/deepTau_2017v2p6_e6.pb"});
1156  desc.add<bool>("mem_mapped", false);
1157  desc.add<unsigned>("version", 2);
1158  desc.add<int>("debug_level", 0);
1159  desc.add<bool>("disable_dxy_pca", false);
1160  desc.add<bool>("disable_hcalFraction_workaround", false);
1161  desc.add<bool>("disable_CellIndex_workaround", false);
1162  desc.add<bool>("save_inputs", false);
1163  desc.add<bool>("is_online", false);
1164 
1165  desc.add<std::vector<std::string>>("VSeWP");
1166  desc.add<std::vector<std::string>>("VSmuWP");
1167  desc.add<std::vector<std::string>>("VSjetWP");
1168 
1169  desc.addUntracked<edm::InputTag>("basicTauDiscriminators", edm::InputTag("basicTauDiscriminators"));
1170  desc.addUntracked<edm::InputTag>("basicTauDiscriminatorsdR03", edm::InputTag("basicTauDiscriminatorsdR03"));
1171  desc.add<edm::InputTag>("pfTauTransverseImpactParameters", edm::InputTag("hpsPFTauTransverseImpactParameters"));
1172 
1173  {
1174  edm::ParameterSetDescription pset_Prediscriminants;
1175  pset_Prediscriminants.add<std::string>("BooleanOperator", "and");
1176  {
1178  psd1.add<double>("cut");
1179  psd1.add<edm::InputTag>("Producer");
1180  pset_Prediscriminants.addOptional<edm::ParameterSetDescription>("decayMode", psd1);
1181  }
1182  desc.add<edm::ParameterSetDescription>("Prediscriminants", pset_Prediscriminants);
1183  }
1184 
1185  descriptions.add("DeepTau", desc);
1186  }
1187 
1188 public:
1191  electrons_token_(consumes<std::vector<pat::Electron>>(cfg.getParameter<edm::InputTag>("electrons"))),
1192  muons_token_(consumes<std::vector<pat::Muon>>(cfg.getParameter<edm::InputTag>("muons"))),
1193  rho_token_(consumes<double>(cfg.getParameter<edm::InputTag>("rho"))),
1195  cfg.getUntrackedParameter<edm::InputTag>("basicTauDiscriminators"))),
1197  cfg.getUntrackedParameter<edm::InputTag>("basicTauDiscriminatorsdR03"))),
1199  consumes<edm::AssociationVector<reco::PFTauRefProd, std::vector<reco::PFTauTransverseImpactParameterRef>>>(
1200  cfg.getParameter<edm::InputTag>("pfTauTransverseImpactParameters"))),
1201  version_(cfg.getParameter<unsigned>("version")),
1202  debug_level(cfg.getParameter<int>("debug_level")),
1203  disable_dxy_pca_(cfg.getParameter<bool>("disable_dxy_pca")),
1204  disable_hcalFraction_workaround_(cfg.getParameter<bool>("disable_hcalFraction_workaround")),
1205  disable_CellIndex_workaround_(cfg.getParameter<bool>("disable_CellIndex_workaround")),
1206  save_inputs_(cfg.getParameter<bool>("save_inputs")),
1207  json_file_(nullptr),
1208  file_counter_(0) {
1209  if (version_ == 1) {
1210  input_layer_ = cache_->getGraph().node(0).name();
1211  output_layer_ = cache_->getGraph().node(cache_->getGraph().node_size() - 1).name();
1212  const auto& shape = cache_->getGraph().node(0).attr().at("shape").shape();
1213  if (shape.dim(1).size() != dnn_inputs_2017v1::NumberOfInputs)
1214  throw cms::Exception("DeepTauId")
1215  << "number of inputs does not match the expected inputs for the given version";
1216  } else if (version_ == 2) {
1217  tauBlockTensor_ = std::make_unique<tensorflow::Tensor>(
1218  tensorflow::DT_FLOAT, tensorflow::TensorShape{1, dnn_inputs_2017_v2::TauBlockInputs::NumberOfInputs});
1219  for (size_t n = 0; n < 2; ++n) {
1220  const bool is_inner = n == 0;
1221  const auto n_cells =
1222  is_inner ? dnn_inputs_2017_v2::number_of_inner_cell : dnn_inputs_2017_v2::number_of_outer_cell;
1223  eGammaTensor_[is_inner] = std::make_unique<tensorflow::Tensor>(
1224  tensorflow::DT_FLOAT,
1225  tensorflow::TensorShape{1, 1, 1, dnn_inputs_2017_v2::EgammaBlockInputs::NumberOfInputs});
1226  muonTensor_[is_inner] = std::make_unique<tensorflow::Tensor>(
1227  tensorflow::DT_FLOAT,
1228  tensorflow::TensorShape{1, 1, 1, dnn_inputs_2017_v2::MuonBlockInputs::NumberOfInputs});
1229  hadronsTensor_[is_inner] = std::make_unique<tensorflow::Tensor>(
1230  tensorflow::DT_FLOAT,
1231  tensorflow::TensorShape{1, 1, 1, dnn_inputs_2017_v2::HadronBlockInputs::NumberOfInputs});
1232  convTensor_[is_inner] = std::make_unique<tensorflow::Tensor>(
1233  tensorflow::DT_FLOAT,
1234  tensorflow::TensorShape{1, n_cells, n_cells, dnn_inputs_2017_v2::number_of_conv_features});
1235  zeroOutputTensor_[is_inner] = std::make_unique<tensorflow::Tensor>(
1236  tensorflow::DT_FLOAT, tensorflow::TensorShape{1, 1, 1, dnn_inputs_2017_v2::number_of_conv_features});
1237 
1238  eGammaTensor_[is_inner]->flat<float>().setZero();
1239  muonTensor_[is_inner]->flat<float>().setZero();
1240  hadronsTensor_[is_inner]->flat<float>().setZero();
1241 
1242  setCellConvFeatures(*zeroOutputTensor_[is_inner], getPartialPredictions(is_inner), 0, 0, 0);
1243  }
1244  } else {
1245  throw cms::Exception("DeepTauId") << "version " << version_ << " is not supported.";
1246  }
1247  }
1248 
1249  static std::unique_ptr<deep_tau::DeepTauCache> initializeGlobalCache(const edm::ParameterSet& cfg) {
1250  return DeepTauBase::initializeGlobalCache(cfg);
1251  }
1252 
1253  static void globalEndJob(const deep_tau::DeepTauCache* cache_) { return DeepTauBase::globalEndJob(cache_); }
1254 
1255 private:
1256  static constexpr float pi = M_PI;
1257 
1258  template <typename T>
1259  static float getValue(T value) {
1260  return std::isnormal(value) ? static_cast<float>(value) : 0.f;
1261  }
1262 
1263  template <typename T>
1264  static float getValueLinear(T value, float min_value, float max_value, bool positive) {
1265  const float fixed_value = getValue(value);
1266  const float clamped_value = std::clamp(fixed_value, min_value, max_value);
1267  float transformed_value = (clamped_value - min_value) / (max_value - min_value);
1268  if (!positive)
1269  transformed_value = transformed_value * 2 - 1;
1270  return transformed_value;
1271  }
1272 
1273  template <typename T>
1274  static float getValueNorm(T value, float mean, float sigma, float n_sigmas_max = 5) {
1275  const float fixed_value = getValue(value);
1276  const float norm_value = (fixed_value - mean) / sigma;
1277  return std::clamp(norm_value, -n_sigmas_max, n_sigmas_max);
1278  }
1279 
1280  static bool isAbove(double value, double min) { return std::isnormal(value) && value > min; }
1281 
1283  float& cc_ele_energy,
1284  float& cc_gamma_energy,
1285  int& cc_n_gamma) {
1286  cc_ele_energy = cc_gamma_energy = 0;
1287  cc_n_gamma = 0;
1288  const auto& superCluster = ele.superCluster();
1289  if (superCluster.isNonnull() && superCluster.isAvailable() && superCluster->clusters().isNonnull() &&
1290  superCluster->clusters().isAvailable()) {
1291  for (auto iter = superCluster->clustersBegin(); iter != superCluster->clustersEnd(); ++iter) {
1292  const float energy = static_cast<float>((*iter)->energy());
1293  if (iter == superCluster->clustersBegin())
1294  cc_ele_energy += energy;
1295  else {
1296  cc_gamma_energy += energy;
1297  ++cc_n_gamma;
1298  }
1299  }
1300  return true;
1301  } else
1302  return false;
1303  }
1304 
1305  inline void checkInputs(const tensorflow::Tensor& inputs,
1306  const std::string& block_name,
1307  int n_inputs,
1308  const CellGrid* grid = nullptr) const {
1309  if (debug_level >= 1) {
1310  std::cout << "<checkInputs>: block_name = " << block_name << std::endl;
1311  if (block_name == "input_tau") {
1312  for (int input_index = 0; input_index < n_inputs; ++input_index) {
1313  float input = inputs.matrix<float>()(0, input_index);
1314  if (edm::isNotFinite(input)) {
1315  throw cms::Exception("DeepTauId")
1316  << "in the " << block_name
1317  << ", input is not finite, i.e. infinite or NaN, for input_index = " << input_index;
1318  }
1319  if (debug_level >= 2) {
1320  std::cout << block_name << "[var = " << input_index << "] = " << std::setprecision(5) << std::fixed << input
1321  << std::endl;
1322  }
1323  }
1324  } else {
1325  assert(grid);
1326  int n_eta, n_phi;
1327  if (block_name.find("input_inner") != std::string::npos) {
1328  n_eta = 5;
1329  n_phi = 5;
1330  } else if (block_name.find("input_outer") != std::string::npos) {
1331  n_eta = 10;
1332  n_phi = 10;
1333  } else
1334  assert(0);
1335  int eta_phi_index = 0;
1336  for (int eta = -n_eta; eta <= n_eta; ++eta) {
1337  for (int phi = -n_phi; phi <= n_phi; ++phi) {
1338  const CellIndex cell_index{eta, phi};
1339  const auto cell_iter = grid->find(cell_index);
1340  if (cell_iter != grid->end()) {
1341  for (int input_index = 0; input_index < n_inputs; ++input_index) {
1342  float input = inputs.tensor<float, 4>()(eta_phi_index, 0, 0, input_index);
1343  if (edm::isNotFinite(input)) {
1344  throw cms::Exception("DeepTauId")
1345  << "in the " << block_name << ", input is not finite, i.e. infinite or NaN, for eta = " << eta
1346  << ", phi = " << phi << ", input_index = " << input_index;
1347  }
1348  if (debug_level >= 2) {
1349  std::cout << block_name << "[eta = " << eta << "][phi = " << phi << "][var = " << input_index
1350  << "] = " << std::setprecision(5) << std::fixed << input << std::endl;
1351  }
1352  }
1353  eta_phi_index += 1;
1354  }
1355  }
1356  }
1357  }
1358  }
1359  }
1360 
1361  inline void saveInputs(const tensorflow::Tensor& inputs,
1362  const std::string& block_name,
1363  int n_inputs,
1364  const CellGrid* grid = nullptr) {
1365  if (debug_level >= 1) {
1366  std::cout << "<saveInputs>: block_name = " << block_name << std::endl;
1367  }
1368  if (!is_first_block_)
1369  (*json_file_) << ", ";
1370  (*json_file_) << "\"" << block_name << "\": [";
1371  if (block_name == "input_tau") {
1372  for (int input_index = 0; input_index < n_inputs; ++input_index) {
1373  float input = inputs.matrix<float>()(0, input_index);
1374  if (input_index != 0)
1375  (*json_file_) << ", ";
1376  (*json_file_) << input;
1377  }
1378  } else {
1379  assert(grid);
1380  int n_eta, n_phi;
1381  if (block_name.find("input_inner") != std::string::npos) {
1382  n_eta = 5;
1383  n_phi = 5;
1384  } else if (block_name.find("input_outer") != std::string::npos) {
1385  n_eta = 10;
1386  n_phi = 10;
1387  } else
1388  assert(0);
1389  int eta_phi_index = 0;
1390  for (int eta = -n_eta; eta <= n_eta; ++eta) {
1391  if (eta != -n_eta)
1392  (*json_file_) << ", ";
1393  (*json_file_) << "[";
1394  for (int phi = -n_phi; phi <= n_phi; ++phi) {
1395  if (phi != -n_phi)
1396  (*json_file_) << ", ";
1397  (*json_file_) << "[";
1398  const CellIndex cell_index{eta, phi};
1399  const auto cell_iter = grid->find(cell_index);
1400  for (int input_index = 0; input_index < n_inputs; ++input_index) {
1401  float input = 0.;
1402  if (cell_iter != grid->end()) {
1403  input = inputs.tensor<float, 4>()(eta_phi_index, 0, 0, input_index);
1404  }
1405  if (input_index != 0)
1406  (*json_file_) << ", ";
1407  (*json_file_) << input;
1408  }
1409  if (cell_iter != grid->end()) {
1410  eta_phi_index += 1;
1411  }
1412  (*json_file_) << "]";
1413  }
1414  (*json_file_) << "]";
1415  }
1416  }
1417  (*json_file_) << "]";
1418  is_first_block_ = false;
1419  }
1420 
1421 private:
1423  // Empty dummy vectors
1424  const std::vector<pat::Electron> electron_collection_default;
1425  const std::vector<pat::Muon> muon_collection_default;
1426  const reco::TauDiscriminatorContainer basicTauDiscriminators_default;
1427  const reco::TauDiscriminatorContainer basicTauDiscriminatorsdR03_default;
1429  pfTauTransverseImpactParameters_default;
1430 
1431  const std::vector<pat::Electron>* electron_collection;
1432  const std::vector<pat::Muon>* muon_collection;
1433  const reco::TauDiscriminatorContainer* basicTauDiscriminators;
1434  const reco::TauDiscriminatorContainer* basicTauDiscriminatorsdR03;
1436  pfTauTransverseImpactParameters;
1437 
1438  if (!is_online_) {
1439  electron_collection = &event.get(electrons_token_);
1440  muon_collection = &event.get(muons_token_);
1441  pfTauTransverseImpactParameters = &pfTauTransverseImpactParameters_default;
1442  basicTauDiscriminators = &basicTauDiscriminators_default;
1443  basicTauDiscriminatorsdR03 = &basicTauDiscriminatorsdR03_default;
1444  } else {
1445  electron_collection = &electron_collection_default;
1446  muon_collection = &muon_collection_default;
1447  pfTauTransverseImpactParameters = &event.get(pfTauTransverseImpactParameters_token_);
1448  basicTauDiscriminators = &event.get(basicTauDiscriminators_inputToken_);
1449  basicTauDiscriminatorsdR03 = &event.get(basicTauDiscriminatorsdR03_inputToken_);
1450 
1451  // Get indices for discriminators
1452  if (!discrIndicesMapped_) {
1457  discrIndicesMapped_ = true;
1458  }
1459  }
1460 
1461  TauFunc tauIDs = {basicTauDiscriminators,
1462  basicTauDiscriminatorsdR03,
1463  pfTauTransverseImpactParameters,
1466 
1468  event.getByToken(pfcandToken_, pfCands);
1469 
1471  event.getByToken(vtxToken_, vertices);
1472 
1474  event.getByToken(rho_token_, rho);
1475 
1476  tensorflow::Tensor predictions(tensorflow::DT_FLOAT, {static_cast<int>(taus->size()), deep_tau::NumberOfOutputs});
1477 
1478  for (size_t tau_index = 0; tau_index < taus->size(); ++tau_index) {
1479  const edm::RefToBase<reco::BaseTau> tauRef = taus->refAt(tau_index);
1480 
1481  std::vector<tensorflow::Tensor> pred_vector;
1482 
1483  bool passesPrediscriminants;
1484  if (is_online_) {
1485  passesPrediscriminants = tauIDs.passPrediscriminants<std::vector<TauDiscInfo<reco::PFTauDiscriminator>>>(
1487  } else {
1488  passesPrediscriminants = tauIDs.passPrediscriminants<std::vector<TauDiscInfo<pat::PATTauDiscriminator>>>(
1490  }
1491 
1492  if (passesPrediscriminants) {
1493  if (version_ == 1) {
1494  if (is_online_)
1495  getPredictionsV1<reco::PFCandidate, reco::PFTau>(
1496  taus->at(tau_index), tau_index, tauRef, electron_collection, muon_collection, pred_vector, tauIDs);
1497  else
1498  getPredictionsV1<pat::PackedCandidate, pat::Tau>(
1499  taus->at(tau_index), tau_index, tauRef, electron_collection, muon_collection, pred_vector, tauIDs);
1500  } else if (version_ == 2) {
1501  if (is_online_) {
1502  getPredictionsV2<reco::PFCandidate, reco::PFTau>(taus->at(tau_index),
1503  tau_index,
1504  tauRef,
1505  electron_collection,
1506  muon_collection,
1507  *pfCands,
1508  vertices->at(0),
1509  *rho,
1510  pred_vector,
1511  tauIDs);
1512  } else
1513  getPredictionsV2<pat::PackedCandidate, pat::Tau>(taus->at(tau_index),
1514  tau_index,
1515  tauRef,
1516  electron_collection,
1517  muon_collection,
1518  *pfCands,
1519  vertices->at(0),
1520  *rho,
1521  pred_vector,
1522  tauIDs);
1523  } else {
1524  throw cms::Exception("DeepTauId") << "version " << version_ << " is not supported.";
1525  }
1526 
1527  for (int k = 0; k < deep_tau::NumberOfOutputs; ++k) {
1528  const float pred = pred_vector[0].flat<float>()(k);
1529  if (!(pred >= 0 && pred <= 1))
1530  throw cms::Exception("DeepTauId")
1531  << "invalid prediction = " << pred << " for tau_index = " << tau_index << ", pred_index = " << k;
1532  predictions.matrix<float>()(tau_index, k) = pred;
1533  }
1534  }
1535  }
1536  return predictions;
1537  }
1538 
1539  template <typename CandidateCastType, typename TauCastType>
1541  const size_t tau_index,
1542  const edm::RefToBase<reco::BaseTau> tau_ref,
1543  const std::vector<pat::Electron>* electrons,
1544  const std::vector<pat::Muon>* muons,
1545  std::vector<tensorflow::Tensor>& pred_vector,
1546  TauFunc tau_funcs) {
1547  const tensorflow::Tensor& inputs = createInputsV1<dnn_inputs_2017v1, const CandidateCastType>(
1548  dynamic_cast<const TauCastType&>(tau), tau_index, tau_ref, electrons, muons, tau_funcs);
1549  tensorflow::run(&(cache_->getSession()), {{input_layer_, inputs}}, {output_layer_}, &pred_vector);
1550  }
1551 
1552  template <typename CandidateCastType, typename TauCastType>
1554  const size_t tau_index,
1555  const edm::RefToBase<reco::BaseTau> tau_ref,
1556  const std::vector<pat::Electron>* electrons,
1557  const std::vector<pat::Muon>* muons,
1558  const edm::View<reco::Candidate>& pfCands,
1559  const reco::Vertex& pv,
1560  double rho,
1561  std::vector<tensorflow::Tensor>& pred_vector,
1562  TauFunc tau_funcs) {
1563  if (debug_level >= 2) {
1564  std::cout << "<DeepTauId::getPredictionsV2 (moduleLabel = " << moduleDescription().moduleLabel()
1565  << ")>:" << std::endl;
1566  std::cout << " tau: pT = " << tau.pt() << ", eta = " << tau.eta() << ", phi = " << tau.phi() << std::endl;
1567  }
1568  CellGrid inner_grid(dnn_inputs_2017_v2::number_of_inner_cell,
1569  dnn_inputs_2017_v2::number_of_inner_cell,
1570  0.02,
1571  0.02,
1573  CellGrid outer_grid(dnn_inputs_2017_v2::number_of_outer_cell,
1574  dnn_inputs_2017_v2::number_of_outer_cell,
1575  0.05,
1576  0.05,
1578  fillGrids(dynamic_cast<const TauCastType&>(tau), *electrons, inner_grid, outer_grid);
1579  fillGrids(dynamic_cast<const TauCastType&>(tau), *muons, inner_grid, outer_grid);
1580  fillGrids(dynamic_cast<const TauCastType&>(tau), pfCands, inner_grid, outer_grid);
1581 
1582  createTauBlockInputs<CandidateCastType>(
1583  dynamic_cast<const TauCastType&>(tau), tau_index, tau_ref, pv, rho, tau_funcs);
1584  using namespace dnn_inputs_2017_v2;
1585  checkInputs(*tauBlockTensor_, "input_tau", TauBlockInputs::NumberOfInputs);
1586  createConvFeatures<CandidateCastType>(dynamic_cast<const TauCastType&>(tau),
1587  tau_index,
1588  tau_ref,
1589  pv,
1590  rho,
1591  electrons,
1592  muons,
1593  pfCands,
1594  inner_grid,
1595  tau_funcs,
1596  true);
1597  checkInputs(*eGammaTensor_[true], "input_inner_egamma", EgammaBlockInputs::NumberOfInputs, &inner_grid);
1598  checkInputs(*muonTensor_[true], "input_inner_muon", MuonBlockInputs::NumberOfInputs, &inner_grid);
1599  checkInputs(*hadronsTensor_[true], "input_inner_hadrons", HadronBlockInputs::NumberOfInputs, &inner_grid);
1600  createConvFeatures<CandidateCastType>(dynamic_cast<const TauCastType&>(tau),
1601  tau_index,
1602  tau_ref,
1603  pv,
1604  rho,
1605  electrons,
1606  muons,
1607  pfCands,
1608  outer_grid,
1609  tau_funcs,
1610  false);
1611  checkInputs(*eGammaTensor_[false], "input_outer_egamma", EgammaBlockInputs::NumberOfInputs, &outer_grid);
1612  checkInputs(*muonTensor_[false], "input_outer_muon", MuonBlockInputs::NumberOfInputs, &outer_grid);
1613  checkInputs(*hadronsTensor_[false], "input_outer_hadrons", HadronBlockInputs::NumberOfInputs, &outer_grid);
1614 
1615  if (save_inputs_) {
1616  std::string json_file_name = "DeepTauId_" + std::to_string(file_counter_) + ".json";
1617  json_file_ = new std::ofstream(json_file_name.data());
1618  is_first_block_ = true;
1619  (*json_file_) << "{";
1620  saveInputs(*tauBlockTensor_, "input_tau", dnn_inputs_2017_v2::TauBlockInputs::NumberOfInputs);
1621  saveInputs(*eGammaTensor_[true],
1622  "input_inner_egamma",
1623  dnn_inputs_2017_v2::EgammaBlockInputs::NumberOfInputs,
1624  &inner_grid);
1625  saveInputs(
1626  *muonTensor_[true], "input_inner_muon", dnn_inputs_2017_v2::MuonBlockInputs::NumberOfInputs, &inner_grid);
1627  saveInputs(*hadronsTensor_[true],
1628  "input_inner_hadrons",
1629  dnn_inputs_2017_v2::HadronBlockInputs::NumberOfInputs,
1630  &inner_grid);
1631  saveInputs(*eGammaTensor_[false],
1632  "input_outer_egamma",
1633  dnn_inputs_2017_v2::EgammaBlockInputs::NumberOfInputs,
1634  &outer_grid);
1635  saveInputs(
1636  *muonTensor_[false], "input_outer_muon", dnn_inputs_2017_v2::MuonBlockInputs::NumberOfInputs, &outer_grid);
1637  saveInputs(*hadronsTensor_[false],
1638  "input_outer_hadrons",
1639  dnn_inputs_2017_v2::HadronBlockInputs::NumberOfInputs,
1640  &outer_grid);
1641  (*json_file_) << "}";
1642  delete json_file_;
1643  ++file_counter_;
1644  }
1645 
1646  tensorflow::run(&(cache_->getSession("core")),
1647  {{"input_tau", *tauBlockTensor_},
1648  {"input_inner", *convTensor_.at(true)},
1649  {"input_outer", *convTensor_.at(false)}},
1650  {"main_output/Softmax"},
1651  &pred_vector);
1652  if (debug_level >= 1) {
1653  std::cout << "output = { ";
1654  for (int idx = 0; idx < deep_tau::NumberOfOutputs; ++idx) {
1655  if (idx > 0)
1656  std::cout << ", ";
1658  if (idx == 0)
1659  label = "e";
1660  else if (idx == 1)
1661  label = "mu";
1662  else if (idx == 2)
1663  label = "tau";
1664  else if (idx == 3)
1665  label = "jet";
1666  else
1667  assert(0);
1668  std::cout << label << " = " << pred_vector[0].flat<float>()(idx);
1669  }
1670  std::cout << " }" << std::endl;
1671  }
1672  }
1673 
1674  template <typename Collection, typename TauCastType>
1675  void fillGrids(const TauCastType& tau, const Collection& objects, CellGrid& inner_grid, CellGrid& outer_grid) {
1676  static constexpr double outer_dR2 = 0.25; //0.5^2
1677  const double inner_radius = getInnerSignalConeRadius(tau.polarP4().pt());
1678  const double inner_dR2 = std::pow(inner_radius, 2);
1679 
1680  const auto addObject = [&](size_t n, double deta, double dphi, CellGrid& grid) {
1681  const auto& obj = objects.at(n);
1682  const CellObjectType obj_type = GetCellObjectType(obj);
1683  if (obj_type == CellObjectType::Other)
1684  return;
1685  CellIndex cell_index;
1686  if (grid.tryGetCellIndex(deta, dphi, cell_index)) {
1687  Cell& cell = grid[cell_index];
1688  auto iter = cell.find(obj_type);
1689  if (iter != cell.end()) {
1690  const auto& prev_obj = objects.at(iter->second);
1691  if (obj.polarP4().pt() > prev_obj.polarP4().pt())
1692  iter->second = n;
1693  } else {
1694  cell[obj_type] = n;
1695  }
1696  }
1697  };
1698 
1699  for (size_t n = 0; n < objects.size(); ++n) {
1700  const auto& obj = objects.at(n);
1701  const double deta = obj.polarP4().eta() - tau.polarP4().eta();
1702  const double dphi = reco::deltaPhi(obj.polarP4().phi(), tau.polarP4().phi());
1703  const double dR2 = std::pow(deta, 2) + std::pow(dphi, 2);
1704  if (dR2 < inner_dR2)
1705  addObject(n, deta, dphi, inner_grid);
1706  if (dR2 < outer_dR2)
1707  addObject(n, deta, dphi, outer_grid);
1708  }
1709  }
1710 
1711  tensorflow::Tensor getPartialPredictions(bool is_inner) {
1712  std::vector<tensorflow::Tensor> pred_vector;
1713  if (is_inner) {
1714  tensorflow::run(&(cache_->getSession("inner")),
1715  {
1716  {"input_inner_egamma", *eGammaTensor_.at(is_inner)},
1717  {"input_inner_muon", *muonTensor_.at(is_inner)},
1718  {"input_inner_hadrons", *hadronsTensor_.at(is_inner)},
1719  },
1720  {"inner_all_dropout_4/Identity"},
1721  &pred_vector);
1722  } else {
1723  tensorflow::run(&(cache_->getSession("outer")),
1724  {
1725  {"input_outer_egamma", *eGammaTensor_.at(is_inner)},
1726  {"input_outer_muon", *muonTensor_.at(is_inner)},
1727  {"input_outer_hadrons", *hadronsTensor_.at(is_inner)},
1728  },
1729  {"outer_all_dropout_4/Identity"},
1730  &pred_vector);
1731  }
1732  return pred_vector.at(0);
1733  }
1734 
1735  template <typename CandidateCastType, typename TauCastType>
1736  void createConvFeatures(const TauCastType& tau,
1737  const size_t tau_index,
1738  const edm::RefToBase<reco::BaseTau> tau_ref,
1739  const reco::Vertex& pv,
1740  double rho,
1741  const std::vector<pat::Electron>* electrons,
1742  const std::vector<pat::Muon>* muons,
1743  const edm::View<reco::Candidate>& pfCands,
1744  const CellGrid& grid,
1745  TauFunc tau_funcs,
1746  bool is_inner) {
1747  if (debug_level >= 2) {
1748  std::cout << "<DeepTauId::createConvFeatures (is_inner = " << is_inner << ")>:" << std::endl;
1749  }
1750  tensorflow::Tensor& convTensor = *convTensor_.at(is_inner);
1751  eGammaTensor_[is_inner] = std::make_unique<tensorflow::Tensor>(
1752  tensorflow::DT_FLOAT,
1753  tensorflow::TensorShape{
1754  (long long int)grid.num_valid_cells(), 1, 1, dnn_inputs_2017_v2::EgammaBlockInputs::NumberOfInputs});
1755  muonTensor_[is_inner] = std::make_unique<tensorflow::Tensor>(
1756  tensorflow::DT_FLOAT,
1757  tensorflow::TensorShape{
1758  (long long int)grid.num_valid_cells(), 1, 1, dnn_inputs_2017_v2::MuonBlockInputs::NumberOfInputs});
1759  hadronsTensor_[is_inner] = std::make_unique<tensorflow::Tensor>(
1760  tensorflow::DT_FLOAT,
1761  tensorflow::TensorShape{
1762  (long long int)grid.num_valid_cells(), 1, 1, dnn_inputs_2017_v2::HadronBlockInputs::NumberOfInputs});
1763 
1764  eGammaTensor_[is_inner]->flat<float>().setZero();
1765  muonTensor_[is_inner]->flat<float>().setZero();
1766  hadronsTensor_[is_inner]->flat<float>().setZero();
1767 
1768  unsigned idx = 0;
1769  for (int eta = -grid.maxEtaIndex(); eta <= grid.maxEtaIndex(); ++eta) {
1770  for (int phi = -grid.maxPhiIndex(); phi <= grid.maxPhiIndex(); ++phi) {
1771  if (debug_level >= 2) {
1772  std::cout << "processing ( eta = " << eta << ", phi = " << phi << " )" << std::endl;
1773  }
1774  const CellIndex cell_index{eta, phi};
1775  const auto cell_iter = grid.find(cell_index);
1776  if (cell_iter != grid.end()) {
1777  if (debug_level >= 2) {
1778  std::cout << " creating inputs for ( eta = " << eta << ", phi = " << phi << " ): idx = " << idx
1779  << std::endl;
1780  }
1781  const Cell& cell = cell_iter->second;
1782  createEgammaBlockInputs<CandidateCastType>(
1783  idx, tau, tau_index, tau_ref, pv, rho, electrons, pfCands, cell, tau_funcs, is_inner);
1784  createMuonBlockInputs<CandidateCastType>(
1785  idx, tau, tau_index, tau_ref, pv, rho, muons, pfCands, cell, tau_funcs, is_inner);
1786  createHadronsBlockInputs<CandidateCastType>(
1787  idx, tau, tau_index, tau_ref, pv, rho, pfCands, cell, tau_funcs, is_inner);
1788  idx += 1;
1789  } else {
1790  if (debug_level >= 2) {
1791  std::cout << " skipping creation of inputs, because ( eta = " << eta << ", phi = " << phi
1792  << " ) is not in the grid !!" << std::endl;
1793  }
1794  }
1795  }
1796  }
1797 
1798  const auto predTensor = getPartialPredictions(is_inner);
1799  idx = 0;
1800  for (int eta = -grid.maxEtaIndex(); eta <= grid.maxEtaIndex(); ++eta) {
1801  for (int phi = -grid.maxPhiIndex(); phi <= grid.maxPhiIndex(); ++phi) {
1802  const CellIndex cell_index{eta, phi};
1803  const int eta_index = grid.getEtaTensorIndex(cell_index);
1804  const int phi_index = grid.getPhiTensorIndex(cell_index);
1805 
1806  const auto cell_iter = grid.find(cell_index);
1807  if (cell_iter != grid.end()) {
1808  setCellConvFeatures(convTensor, predTensor, idx, eta_index, phi_index);
1809  idx += 1;
1810  } else {
1811  setCellConvFeatures(convTensor, *zeroOutputTensor_[is_inner], 0, eta_index, phi_index);
1812  }
1813  }
1814  }
1815  }
1816 
1817  void setCellConvFeatures(tensorflow::Tensor& convTensor,
1818  const tensorflow::Tensor& features,
1819  unsigned batch_idx,
1820  int eta_index,
1821  int phi_index) {
1822  for (int n = 0; n < dnn_inputs_2017_v2::number_of_conv_features; ++n) {
1823  convTensor.tensor<float, 4>()(0, eta_index, phi_index, n) = features.tensor<float, 4>()(batch_idx, 0, 0, n);
1824  }
1825  }
1826 
1827  template <typename CandidateCastType, typename TauCastType>
1828  void createTauBlockInputs(const TauCastType& tau,
1829  const size_t& tau_index,
1830  const edm::RefToBase<reco::BaseTau> tau_ref,
1831  const reco::Vertex& pv,
1832  double rho,
1833  TauFunc tau_funcs) {
1834  namespace dnn = dnn_inputs_2017_v2::TauBlockInputs;
1835 
1836  tensorflow::Tensor& inputs = *tauBlockTensor_;
1837  inputs.flat<float>().setZero();
1838 
1839  const auto& get = [&](int var_index) -> float& { return inputs.matrix<float>()(0, var_index); };
1840 
1841  auto leadChargedHadrCand = dynamic_cast<const CandidateCastType*>(tau.leadChargedHadrCand().get());
1842 
1843  get(dnn::rho) = getValueNorm(rho, 21.49f, 9.713f);
1844  get(dnn::tau_pt) = getValueLinear(tau.polarP4().pt(), 20.f, 1000.f, true);
1845  get(dnn::tau_eta) = getValueLinear(tau.polarP4().eta(), -2.3f, 2.3f, false);
1846  get(dnn::tau_phi) = getValueLinear(tau.polarP4().phi(), -pi, pi, false);
1847  get(dnn::tau_mass) = getValueNorm(tau.polarP4().mass(), 0.6669f, 0.6553f);
1848  get(dnn::tau_E_over_pt) = getValueLinear(tau.p4().energy() / tau.p4().pt(), 1.f, 5.2f, true);
1849  get(dnn::tau_charge) = getValue(tau.charge());
1850  get(dnn::tau_n_charged_prongs) = getValueLinear(tau.decayMode() / 5 + 1, 1, 3, true);
1851  get(dnn::tau_n_neutral_prongs) = getValueLinear(tau.decayMode() % 5, 0, 2, true);
1852  get(dnn::chargedIsoPtSum) = getValueNorm(tau_funcs.getChargedIsoPtSum(tau, tau_ref), 47.78f, 123.5f);
1853  get(dnn::chargedIsoPtSumdR03_over_dR05) =
1854  getValue(tau_funcs.getChargedIsoPtSumdR03(tau, tau_ref) / tau_funcs.getChargedIsoPtSum(tau, tau_ref));
1855  get(dnn::footprintCorrection) = getValueNorm(tau_funcs.getFootprintCorrectiondR03(tau, tau_ref), 9.029f, 26.42f);
1856  get(dnn::neutralIsoPtSum) = getValueNorm(tau_funcs.getNeutralIsoPtSum(tau, tau_ref), 57.59f, 155.3f);
1857  get(dnn::neutralIsoPtSumWeight_over_neutralIsoPtSum) =
1858  getValue(tau_funcs.getNeutralIsoPtSumWeight(tau, tau_ref) / tau_funcs.getNeutralIsoPtSum(tau, tau_ref));
1859  get(dnn::neutralIsoPtSumWeightdR03_over_neutralIsoPtSum) =
1860  getValue(tau_funcs.getNeutralIsoPtSumdR03Weight(tau, tau_ref) / tau_funcs.getNeutralIsoPtSum(tau, tau_ref));
1861  get(dnn::neutralIsoPtSumdR03_over_dR05) =
1862  getValue(tau_funcs.getNeutralIsoPtSumdR03(tau, tau_ref) / tau_funcs.getNeutralIsoPtSum(tau, tau_ref));
1863  get(dnn::photonPtSumOutsideSignalCone) =
1864  getValueNorm(tau_funcs.getPhotonPtSumOutsideSignalCone(tau, tau_ref), 1.731f, 6.846f);
1865  get(dnn::puCorrPtSum) = getValueNorm(tau_funcs.getPuCorrPtSum(tau, tau_ref), 22.38f, 16.34f);
1866  // The global PCA coordinates were used as inputs during the NN training, but it was decided to disable
1867  // them for the inference, because modeling of dxy_PCA in MC poorly describes the data, and x and y coordinates
1868  // in data results outside of the expected 5 std. dev. input validity range. On the other hand,
1869  // these coordinates are strongly era-dependent. Kept as comment to document what NN expects.
1870  if (!disable_dxy_pca_) {
1871  auto const pca = tau_funcs.getdxyPCA(tau, tau_index);
1872  get(dnn::tau_dxy_pca_x) = getValueNorm(pca.x(), -0.0241f, 0.0074f);
1873  get(dnn::tau_dxy_pca_y) = getValueNorm(pca.y(), 0.0675f, 0.0128f);
1874  get(dnn::tau_dxy_pca_z) = getValueNorm(pca.z(), 0.7973f, 3.456f);
1875  } else {
1876  get(dnn::tau_dxy_pca_x) = 0;
1877  get(dnn::tau_dxy_pca_y) = 0;
1878  get(dnn::tau_dxy_pca_z) = 0;
1879  }
1880  const bool tau_dxy_valid =
1881  isAbove(tau_funcs.getdxy(tau, tau_index), -10) && isAbove(tau_funcs.getdxyError(tau, tau_index), 0);
1882  if (tau_dxy_valid) {
1883  get(dnn::tau_dxy_valid) = tau_dxy_valid;
1884  get(dnn::tau_dxy) = getValueNorm(tau_funcs.getdxy(tau, tau_index), 0.0018f, 0.0085f);
1885  get(dnn::tau_dxy_sig) = getValueNorm(
1886  std::abs(tau_funcs.getdxy(tau, tau_index)) / tau_funcs.getdxyError(tau, tau_index), 2.26f, 4.191f);
1887  }
1888  const bool tau_ip3d_valid =
1889  isAbove(tau_funcs.getip3d(tau, tau_index), -10) && isAbove(tau_funcs.getip3dError(tau, tau_index), 0);
1890  if (tau_ip3d_valid) {
1891  get(dnn::tau_ip3d_valid) = tau_ip3d_valid;
1892  get(dnn::tau_ip3d) = getValueNorm(tau_funcs.getip3d(tau, tau_index), 0.0026f, 0.0114f);
1893  get(dnn::tau_ip3d_sig) = getValueNorm(
1894  std::abs(tau_funcs.getip3d(tau, tau_index)) / tau_funcs.getip3dError(tau, tau_index), 2.928f, 4.466f);
1895  }
1896  if (leadChargedHadrCand) {
1897  const bool hasTrackDetails = candFunc::getHasTrackDetails(*leadChargedHadrCand);
1898  const float tau_dz = (is_online_ && !hasTrackDetails) ? 0 : candFunc::getTauDz(*leadChargedHadrCand);
1899  get(dnn::tau_dz) = getValueNorm(tau_dz, 0.f, 0.0190f);
1900  get(dnn::tau_dz_sig_valid) = candFunc::getTauDZSigValid(*leadChargedHadrCand);
1901  const double dzError = hasTrackDetails ? leadChargedHadrCand->dzError() : -999.;
1902  get(dnn::tau_dz_sig) = getValueNorm(std::abs(tau_dz) / dzError, 4.717f, 11.78f);
1903  }
1904  get(dnn::tau_flightLength_x) = getValueNorm(tau_funcs.getFlightLength(tau, tau_index).x(), -0.0003f, 0.7362f);
1905  get(dnn::tau_flightLength_y) = getValueNorm(tau_funcs.getFlightLength(tau, tau_index).y(), -0.0009f, 0.7354f);
1906  get(dnn::tau_flightLength_z) = getValueNorm(tau_funcs.getFlightLength(tau, tau_index).z(), -0.0022f, 1.993f);
1907  get(dnn::tau_flightLength_sig) = 0.55756444; //This value is set due to a bug in the training
1908  get(dnn::tau_pt_weighted_deta_strip) =
1909  getValueLinear(reco::tau::pt_weighted_deta_strip(tau, tau.decayMode()), 0, 1, true);
1910 
1911  get(dnn::tau_pt_weighted_dphi_strip) =
1912  getValueLinear(reco::tau::pt_weighted_dphi_strip(tau, tau.decayMode()), 0, 1, true);
1913  get(dnn::tau_pt_weighted_dr_signal) =
1914  getValueNorm(reco::tau::pt_weighted_dr_signal(tau, tau.decayMode()), 0.0052f, 0.01433f);
1915  get(dnn::tau_pt_weighted_dr_iso) = getValueLinear(reco::tau::pt_weighted_dr_iso(tau, tau.decayMode()), 0, 1, true);
1916  get(dnn::tau_leadingTrackNormChi2) = getValueNorm(tau_funcs.getLeadingTrackNormChi2(tau), 1.538f, 4.401f);
1917  const auto eratio = reco::tau::eratio(tau);
1918  const bool tau_e_ratio_valid = std::isnormal(eratio) && eratio > 0.f;
1919  get(dnn::tau_e_ratio_valid) = tau_e_ratio_valid;
1920  get(dnn::tau_e_ratio) = tau_e_ratio_valid ? getValueLinear(eratio, 0, 1, true) : 0.f;
1921  const double gj_angle_diff = calculateGottfriedJacksonAngleDifference(tau, tau_index, tau_funcs);
1922  const bool tau_gj_angle_diff_valid = (std::isnormal(gj_angle_diff) || gj_angle_diff == 0) && gj_angle_diff >= 0;
1923  get(dnn::tau_gj_angle_diff_valid) = tau_gj_angle_diff_valid;
1924  get(dnn::tau_gj_angle_diff) = tau_gj_angle_diff_valid ? getValueLinear(gj_angle_diff, 0, pi, true) : 0;
1925  get(dnn::tau_n_photons) = getValueNorm(reco::tau::n_photons_total(tau), 2.95f, 3.927f);
1926  get(dnn::tau_emFraction) = getValueLinear(tau_funcs.getEmFraction(tau), -1, 1, false);
1927 
1928  get(dnn::tau_inside_ecal_crack) = getValue(isInEcalCrack(tau.p4().eta()));
1929  get(dnn::leadChargedCand_etaAtEcalEntrance_minus_tau_eta) =
1930  getValueNorm(tau_funcs.getEtaAtEcalEntrance(tau) - tau.p4().eta(), 0.0042f, 0.0323f);
1931  }
1932 
1933  template <typename CandidateCastType, typename TauCastType>
1935  const TauCastType& tau,
1936  const size_t tau_index,
1937  const edm::RefToBase<reco::BaseTau> tau_ref,
1938  const reco::Vertex& pv,
1939  double rho,
1940  const std::vector<pat::Electron>* electrons,
1941  const edm::View<reco::Candidate>& pfCands,
1942  const Cell& cell_map,
1943  TauFunc tau_funcs,
1944  bool is_inner) {
1945  namespace dnn = dnn_inputs_2017_v2::EgammaBlockInputs;
1946 
1947  tensorflow::Tensor& inputs = *eGammaTensor_.at(is_inner);
1948 
1949  const auto& get = [&](int var_index) -> float& { return inputs.tensor<float, 4>()(idx, 0, 0, var_index); };
1950 
1951  const bool valid_index_pf_ele = cell_map.count(CellObjectType::PfCand_electron);
1952  const bool valid_index_pf_gamma = cell_map.count(CellObjectType::PfCand_gamma);
1953  const bool valid_index_ele = cell_map.count(CellObjectType::Electron);
1954 
1955  if (!cell_map.empty()) {
1956  get(dnn::rho) = getValueNorm(rho, 21.49f, 9.713f);
1957  get(dnn::tau_pt) = getValueLinear(tau.polarP4().pt(), 20.f, 1000.f, true);
1958  get(dnn::tau_eta) = getValueLinear(tau.polarP4().eta(), -2.3f, 2.3f, false);
1959  get(dnn::tau_inside_ecal_crack) = getValue(isInEcalCrack(tau.polarP4().eta()));
1960  }
1961  if (valid_index_pf_ele) {
1962  size_t index_pf_ele = cell_map.at(CellObjectType::PfCand_electron);
1963  const auto& ele_cand = dynamic_cast<const CandidateCastType&>(pfCands.at(index_pf_ele));
1964 
1965  get(dnn::pfCand_ele_valid) = valid_index_pf_ele;
1966  get(dnn::pfCand_ele_rel_pt) = getValueNorm(pfCands.at(index_pf_ele).polarP4().pt() / tau.polarP4().pt(),
1967  is_inner ? 0.9792f : 0.304f,
1968  is_inner ? 0.5383f : 1.845f);
1969  get(dnn::pfCand_ele_deta) = getValueLinear(pfCands.at(index_pf_ele).polarP4().eta() - tau.polarP4().eta(),
1970  is_inner ? -0.1f : -0.5f,
1971  is_inner ? 0.1f : 0.5f,
1972  false);
1973  get(dnn::pfCand_ele_dphi) = getValueLinear(dPhi(tau.polarP4(), pfCands.at(index_pf_ele).polarP4()),
1974  is_inner ? -0.1f : -0.5f,
1975  is_inner ? 0.1f : 0.5f,
1976  false);
1977  get(dnn::pfCand_ele_pvAssociationQuality) =
1978  getValueLinear<int>(candFunc::getPvAssocationQuality(ele_cand), 0, 7, true);
1979  get(dnn::pfCand_ele_puppiWeight) = is_inner ? getValue(candFunc::getPuppiWeight(ele_cand, 0.9906834f))
1980  : getValue(candFunc::getPuppiWeight(ele_cand, 0.9669586f));
1981  get(dnn::pfCand_ele_charge) = getValue(ele_cand.charge());
1982  get(dnn::pfCand_ele_lostInnerHits) = getValue<int>(candFunc::getLostInnerHits(ele_cand, 0));
1983  get(dnn::pfCand_ele_numberOfPixelHits) = getValueLinear(candFunc::getNumberOfPixelHits(ele_cand, 0), 0, 10, true);
1984  get(dnn::pfCand_ele_vertex_dx) =
1985  getValueNorm(pfCands.at(index_pf_ele).vertex().x() - pv.position().x(), 0.f, 0.1221f);
1986  get(dnn::pfCand_ele_vertex_dy) =
1987  getValueNorm(pfCands.at(index_pf_ele).vertex().y() - pv.position().y(), 0.f, 0.1226f);
1988  get(dnn::pfCand_ele_vertex_dz) =
1989  getValueNorm(pfCands.at(index_pf_ele).vertex().z() - pv.position().z(), 0.001f, 1.024f);
1990  get(dnn::pfCand_ele_vertex_dx_tauFL) = getValueNorm(
1991  pfCands.at(index_pf_ele).vertex().x() - pv.position().x() - tau_funcs.getFlightLength(tau, tau_index).x(),
1992  0.f,
1993  0.3411f);
1994  get(dnn::pfCand_ele_vertex_dy_tauFL) = getValueNorm(
1995  pfCands.at(index_pf_ele).vertex().y() - pv.position().y() - tau_funcs.getFlightLength(tau, tau_index).y(),
1996  0.0003f,
1997  0.3385f);
1998  get(dnn::pfCand_ele_vertex_dz_tauFL) = getValueNorm(
1999  pfCands.at(index_pf_ele).vertex().z() - pv.position().z() - tau_funcs.getFlightLength(tau, tau_index).z(),
2000  0.f,
2001  1.307f);
2002 
2003  const bool hasTrackDetails = candFunc::getHasTrackDetails(ele_cand);
2004  if (hasTrackDetails) {
2005  get(dnn::pfCand_ele_hasTrackDetails) = hasTrackDetails;
2006  get(dnn::pfCand_ele_dxy) = getValueNorm(candFunc::getTauDxy(ele_cand), 0.f, 0.171f);
2007  get(dnn::pfCand_ele_dxy_sig) =
2008  getValueNorm(std::abs(candFunc::getTauDxy(ele_cand)) / pfCands.at(index_pf_ele).dxyError(), 1.634f, 6.45f);
2009  get(dnn::pfCand_ele_dz) = getValueNorm(candFunc::getTauDz(ele_cand), 0.001f, 1.02f);
2010  get(dnn::pfCand_ele_dz_sig) =
2011  getValueNorm(std::abs(candFunc::getTauDz(ele_cand)) / ele_cand.dzError(), 24.56f, 210.4f);
2012  get(dnn::pfCand_ele_track_chi2_ndof) = getValueNorm(
2013  candFunc::getPseudoTrack(ele_cand).chi2() / candFunc::getPseudoTrack(ele_cand).ndof(), 2.272f, 8.439f);
2014  get(dnn::pfCand_ele_track_ndof) = getValueNorm(candFunc::getPseudoTrack(ele_cand).ndof(), 15.18f, 3.203f);
2015  }
2016  }
2017  if (valid_index_pf_gamma) {
2018  size_t index_pf_gamma = cell_map.at(CellObjectType::PfCand_gamma);
2019  const auto& gamma_cand = dynamic_cast<const CandidateCastType&>(pfCands.at(index_pf_gamma));
2020 
2021  get(dnn::pfCand_gamma_valid) = valid_index_pf_gamma;
2022  get(dnn::pfCand_gamma_rel_pt) = getValueNorm(pfCands.at(index_pf_gamma).polarP4().pt() / tau.polarP4().pt(),
2023  is_inner ? 0.6048f : 0.02576f,
2024  is_inner ? 1.669f : 0.3833f);
2025  get(dnn::pfCand_gamma_deta) = getValueLinear(pfCands.at(index_pf_gamma).polarP4().eta() - tau.polarP4().eta(),
2026  is_inner ? -0.1f : -0.5f,
2027  is_inner ? 0.1f : 0.5f,
2028  false);
2029  get(dnn::pfCand_gamma_dphi) = getValueLinear(dPhi(tau.polarP4(), pfCands.at(index_pf_gamma).polarP4()),
2030  is_inner ? -0.1f : -0.5f,
2031  is_inner ? 0.1f : 0.5f,
2032  false);
2033  get(dnn::pfCand_gamma_pvAssociationQuality) =
2034  getValueLinear<int>(candFunc::getPvAssocationQuality(gamma_cand), 0, 7, true);
2035  get(dnn::pfCand_gamma_fromPV) = getValueLinear<int>(candFunc::getFromPV(gamma_cand), 0, 3, true);
2036  get(dnn::pfCand_gamma_puppiWeight) = is_inner ? getValue(candFunc::getPuppiWeight(gamma_cand, 0.9084110f))
2037  : getValue(candFunc::getPuppiWeight(gamma_cand, 0.4211567f));
2038  get(dnn::pfCand_gamma_puppiWeightNoLep) = is_inner
2039  ? getValue(candFunc::getPuppiWeightNoLep(gamma_cand, 0.8857716f))
2040  : getValue(candFunc::getPuppiWeightNoLep(gamma_cand, 0.3822604f));
2041  get(dnn::pfCand_gamma_lostInnerHits) = getValue<int>(candFunc::getLostInnerHits(gamma_cand, 0));
2042  get(dnn::pfCand_gamma_numberOfPixelHits) =
2043  getValueLinear(candFunc::getNumberOfPixelHits(gamma_cand, 0), 0, 7, true);
2044  get(dnn::pfCand_gamma_vertex_dx) =
2045  getValueNorm(pfCands.at(index_pf_gamma).vertex().x() - pv.position().x(), 0.f, 0.0067f);
2046  get(dnn::pfCand_gamma_vertex_dy) =
2047  getValueNorm(pfCands.at(index_pf_gamma).vertex().y() - pv.position().y(), 0.f, 0.0069f);
2048  get(dnn::pfCand_gamma_vertex_dz) =
2049  getValueNorm(pfCands.at(index_pf_gamma).vertex().z() - pv.position().z(), 0.f, 0.0578f);
2050  get(dnn::pfCand_gamma_vertex_dx_tauFL) = getValueNorm(
2051  pfCands.at(index_pf_gamma).vertex().x() - pv.position().x() - tau_funcs.getFlightLength(tau, tau_index).x(),
2052  0.001f,
2053  0.9565f);
2054  get(dnn::pfCand_gamma_vertex_dy_tauFL) = getValueNorm(
2055  pfCands.at(index_pf_gamma).vertex().y() - pv.position().y() - tau_funcs.getFlightLength(tau, tau_index).y(),
2056  0.0008f,
2057  0.9592f);
2058  get(dnn::pfCand_gamma_vertex_dz_tauFL) = getValueNorm(
2059  pfCands.at(index_pf_gamma).vertex().z() - pv.position().z() - tau_funcs.getFlightLength(tau, tau_index).z(),
2060  0.0038f,
2061  2.154f);
2062  const bool hasTrackDetails = candFunc::getHasTrackDetails(gamma_cand);
2063  if (hasTrackDetails) {
2064  get(dnn::pfCand_gamma_hasTrackDetails) = hasTrackDetails;
2065  get(dnn::pfCand_gamma_dxy) = getValueNorm(candFunc::getTauDxy(gamma_cand), 0.0004f, 0.882f);
2066  get(dnn::pfCand_gamma_dxy_sig) =
2067  getValueNorm(std::abs(candFunc::getTauDxy(gamma_cand)) / gamma_cand.dxyError(), 4.271f, 63.78f);
2068  get(dnn::pfCand_gamma_dz) = getValueNorm(candFunc::getTauDz(gamma_cand), 0.0071f, 5.285f);
2069  get(dnn::pfCand_gamma_dz_sig) =
2070  getValueNorm(std::abs(candFunc::getTauDz(gamma_cand)) / gamma_cand.dzError(), 162.1f, 622.4f);
2071  get(dnn::pfCand_gamma_track_chi2_ndof) = candFunc::getPseudoTrack(gamma_cand).ndof() > 0
2072  ? getValueNorm(candFunc::getPseudoTrack(gamma_cand).chi2() /
2073  candFunc::getPseudoTrack(gamma_cand).ndof(),
2074  4.268f,
2075  15.47f)
2076  : 0;
2077  get(dnn::pfCand_gamma_track_ndof) =
2078  candFunc::getPseudoTrack(gamma_cand).ndof() > 0
2079  ? getValueNorm(candFunc::getPseudoTrack(gamma_cand).ndof(), 12.25f, 4.774f)
2080  : 0;
2081  }
2082  }
2083  if (valid_index_ele) {
2084  size_t index_ele = cell_map.at(CellObjectType::Electron);
2085 
2086  get(dnn::ele_valid) = valid_index_ele;
2087  get(dnn::ele_rel_pt) = getValueNorm(electrons->at(index_ele).polarP4().pt() / tau.polarP4().pt(),
2088  is_inner ? 1.067f : 0.5111f,
2089  is_inner ? 1.521f : 2.765f);
2090  get(dnn::ele_deta) = getValueLinear(electrons->at(index_ele).polarP4().eta() - tau.polarP4().eta(),
2091  is_inner ? -0.1f : -0.5f,
2092  is_inner ? 0.1f : 0.5f,
2093  false);
2094  get(dnn::ele_dphi) = getValueLinear(dPhi(tau.polarP4(), electrons->at(index_ele).polarP4()),
2095  is_inner ? -0.1f : -0.5f,
2096  is_inner ? 0.1f : 0.5f,
2097  false);
2098 
2099  float cc_ele_energy, cc_gamma_energy;
2100  int cc_n_gamma;
2101  const bool cc_valid =
2102  calculateElectronClusterVarsV2(electrons->at(index_ele), cc_ele_energy, cc_gamma_energy, cc_n_gamma);
2103  if (cc_valid) {
2104  get(dnn::ele_cc_valid) = cc_valid;
2105  get(dnn::ele_cc_ele_rel_energy) =
2106  getValueNorm(cc_ele_energy / electrons->at(index_ele).polarP4().pt(), 1.729f, 1.644f);
2107  get(dnn::ele_cc_gamma_rel_energy) = getValueNorm(cc_gamma_energy / cc_ele_energy, 0.1439f, 0.3284f);
2108  get(dnn::ele_cc_n_gamma) = getValueNorm(cc_n_gamma, 1.794f, 2.079f);
2109  }
2110  get(dnn::ele_rel_trackMomentumAtVtx) = getValueNorm(
2111  electrons->at(index_ele).trackMomentumAtVtx().R() / electrons->at(index_ele).polarP4().pt(), 1.531f, 1.424f);
2112  get(dnn::ele_rel_trackMomentumAtCalo) = getValueNorm(
2113  electrons->at(index_ele).trackMomentumAtCalo().R() / electrons->at(index_ele).polarP4().pt(), 1.531f, 1.424f);
2114  get(dnn::ele_rel_trackMomentumOut) = getValueNorm(
2115  electrons->at(index_ele).trackMomentumOut().R() / electrons->at(index_ele).polarP4().pt(), 0.7735f, 0.935f);
2116  get(dnn::ele_rel_trackMomentumAtEleClus) =
2117  getValueNorm(electrons->at(index_ele).trackMomentumAtEleClus().R() / electrons->at(index_ele).polarP4().pt(),
2118  0.7735f,
2119  0.935f);
2120  get(dnn::ele_rel_trackMomentumAtVtxWithConstraint) = getValueNorm(
2121  electrons->at(index_ele).trackMomentumAtVtxWithConstraint().R() / electrons->at(index_ele).polarP4().pt(),
2122  1.625f,
2123  1.581f);
2124  get(dnn::ele_rel_ecalEnergy) =
2125  getValueNorm(electrons->at(index_ele).ecalEnergy() / electrons->at(index_ele).polarP4().pt(), 1.993f, 1.308f);
2126  get(dnn::ele_ecalEnergy_sig) = getValueNorm(
2127  electrons->at(index_ele).ecalEnergy() / electrons->at(index_ele).ecalEnergyError(), 70.25f, 58.16f);
2128  get(dnn::ele_eSuperClusterOverP) = getValueNorm(electrons->at(index_ele).eSuperClusterOverP(), 2.432f, 15.13f);
2129  get(dnn::ele_eSeedClusterOverP) = getValueNorm(electrons->at(index_ele).eSeedClusterOverP(), 2.034f, 13.96f);
2130  get(dnn::ele_eSeedClusterOverPout) = getValueNorm(electrons->at(index_ele).eSeedClusterOverPout(), 6.64f, 36.8f);
2131  get(dnn::ele_eEleClusterOverPout) = getValueNorm(electrons->at(index_ele).eEleClusterOverPout(), 4.183f, 20.63f);
2132  get(dnn::ele_deltaEtaSuperClusterTrackAtVtx) =
2133  getValueNorm(electrons->at(index_ele).deltaEtaSuperClusterTrackAtVtx(), 0.f, 0.0363f);
2134  get(dnn::ele_deltaEtaSeedClusterTrackAtCalo) =
2135  getValueNorm(electrons->at(index_ele).deltaEtaSeedClusterTrackAtCalo(), -0.0001f, 0.0512f);
2136  get(dnn::ele_deltaEtaEleClusterTrackAtCalo) =
2137  getValueNorm(electrons->at(index_ele).deltaEtaEleClusterTrackAtCalo(), -0.0001f, 0.0541f);
2138  get(dnn::ele_deltaPhiEleClusterTrackAtCalo) =
2139  getValueNorm(electrons->at(index_ele).deltaPhiEleClusterTrackAtCalo(), 0.0002f, 0.0553f);
2140  get(dnn::ele_deltaPhiSuperClusterTrackAtVtx) =
2141  getValueNorm(electrons->at(index_ele).deltaPhiSuperClusterTrackAtVtx(), 0.0001f, 0.0523f);
2142  get(dnn::ele_deltaPhiSeedClusterTrackAtCalo) =
2143  getValueNorm(electrons->at(index_ele).deltaPhiSeedClusterTrackAtCalo(), 0.0004f, 0.0777f);
2144  get(dnn::ele_mvaInput_earlyBrem) = getValue(electrons->at(index_ele).mvaInput().earlyBrem);
2145  get(dnn::ele_mvaInput_lateBrem) = getValue(electrons->at(index_ele).mvaInput().lateBrem);
2146  get(dnn::ele_mvaInput_sigmaEtaEta) =
2147  getValueNorm(electrons->at(index_ele).mvaInput().sigmaEtaEta, 0.0008f, 0.0052f);
2148  get(dnn::ele_mvaInput_hadEnergy) = getValueNorm(electrons->at(index_ele).mvaInput().hadEnergy, 14.04f, 69.48f);
2149  get(dnn::ele_mvaInput_deltaEta) = getValueNorm(electrons->at(index_ele).mvaInput().deltaEta, 0.0099f, 0.0851f);
2150  const auto& gsfTrack = electrons->at(index_ele).gsfTrack();
2151  if (gsfTrack.isNonnull()) {
2152  get(dnn::ele_gsfTrack_normalizedChi2) = getValueNorm(gsfTrack->normalizedChi2(), 3.049f, 10.39f);
2153  get(dnn::ele_gsfTrack_numberOfValidHits) = getValueNorm(gsfTrack->numberOfValidHits(), 16.52f, 2.806f);
2154  get(dnn::ele_rel_gsfTrack_pt) =
2155  getValueNorm(gsfTrack->pt() / electrons->at(index_ele).polarP4().pt(), 1.355f, 16.81f);
2156  get(dnn::ele_gsfTrack_pt_sig) = getValueNorm(gsfTrack->pt() / gsfTrack->ptError(), 5.046f, 3.119f);
2157  }
2158  const auto& closestCtfTrack = electrons->at(index_ele).closestCtfTrackRef();
2159  const bool has_closestCtfTrack = closestCtfTrack.isNonnull();
2160  if (has_closestCtfTrack) {
2161  get(dnn::ele_has_closestCtfTrack) = has_closestCtfTrack;
2162  get(dnn::ele_closestCtfTrack_normalizedChi2) = getValueNorm(closestCtfTrack->normalizedChi2(), 2.411f, 6.98f);
2163  get(dnn::ele_closestCtfTrack_numberOfValidHits) =
2164  getValueNorm(closestCtfTrack->numberOfValidHits(), 15.16f, 5.26f);
2165  }
2166  }
2167  }
2168 
2169  template <typename CandidateCastType, typename TauCastType>
2171  const TauCastType& tau,
2172  const size_t tau_index,
2173  const edm::RefToBase<reco::BaseTau> tau_ref,
2174  const reco::Vertex& pv,
2175  double rho,
2176  const std::vector<pat::Muon>* muons,
2177  const edm::View<reco::Candidate>& pfCands,
2178  const Cell& cell_map,
2179  TauFunc tau_funcs,
2180  bool is_inner) {
2181  namespace dnn = dnn_inputs_2017_v2::MuonBlockInputs;
2182 
2183  tensorflow::Tensor& inputs = *muonTensor_.at(is_inner);
2184 
2185  const auto& get = [&](int var_index) -> float& { return inputs.tensor<float, 4>()(idx, 0, 0, var_index); };
2186 
2187  const bool valid_index_pf_muon = cell_map.count(CellObjectType::PfCand_muon);
2188  const bool valid_index_muon = cell_map.count(CellObjectType::Muon);
2189 
2190  if (!cell_map.empty()) {
2191  get(dnn::rho) = getValueNorm(rho, 21.49f, 9.713f);
2192  get(dnn::tau_pt) = getValueLinear(tau.polarP4().pt(), 20.f, 1000.f, true);
2193  get(dnn::tau_eta) = getValueLinear(tau.polarP4().eta(), -2.3f, 2.3f, false);
2194  get(dnn::tau_inside_ecal_crack) = getValue(isInEcalCrack(tau.polarP4().eta()));
2195  }
2196  if (valid_index_pf_muon) {
2197  size_t index_pf_muon = cell_map.at(CellObjectType::PfCand_muon);
2198  const auto& muon_cand = dynamic_cast<const CandidateCastType&>(pfCands.at(index_pf_muon));
2199 
2200  get(dnn::pfCand_muon_valid) = valid_index_pf_muon;
2201  get(dnn::pfCand_muon_rel_pt) = getValueNorm(pfCands.at(index_pf_muon).polarP4().pt() / tau.polarP4().pt(),
2202  is_inner ? 0.9509f : 0.0861f,
2203  is_inner ? 0.4294f : 0.4065f);
2204  get(dnn::pfCand_muon_deta) = getValueLinear(pfCands.at(index_pf_muon).polarP4().eta() - tau.polarP4().eta(),
2205  is_inner ? -0.1f : -0.5f,
2206  is_inner ? 0.1f : 0.5f,
2207  false);
2208  get(dnn::pfCand_muon_dphi) = getValueLinear(dPhi(tau.polarP4(), pfCands.at(index_pf_muon).polarP4()),
2209  is_inner ? -0.1f : -0.5f,
2210  is_inner ? 0.1f : 0.5f,
2211  false);
2212  get(dnn::pfCand_muon_pvAssociationQuality) =
2213  getValueLinear<int>(candFunc::getPvAssocationQuality(muon_cand), 0, 7, true);
2214  get(dnn::pfCand_muon_fromPV) = getValueLinear<int>(candFunc::getFromPV(muon_cand), 0, 3, true);
2215  get(dnn::pfCand_muon_puppiWeight) = is_inner ? getValue(candFunc::getPuppiWeight(muon_cand, 0.9786588f))
2216  : getValue(candFunc::getPuppiWeight(muon_cand, 0.8132477f));
2217  get(dnn::pfCand_muon_charge) = getValue(muon_cand.charge());
2218  get(dnn::pfCand_muon_lostInnerHits) = getValue<int>(candFunc::getLostInnerHits(muon_cand, 0));
2219  get(dnn::pfCand_muon_numberOfPixelHits) =
2220  getValueLinear(candFunc::getNumberOfPixelHits(muon_cand, 0), 0, 11, true);
2221  get(dnn::pfCand_muon_vertex_dx) =
2222  getValueNorm(pfCands.at(index_pf_muon).vertex().x() - pv.position().x(), -0.0007f, 0.6869f);
2223  get(dnn::pfCand_muon_vertex_dy) =
2224  getValueNorm(pfCands.at(index_pf_muon).vertex().y() - pv.position().y(), 0.0001f, 0.6784f);
2225  get(dnn::pfCand_muon_vertex_dz) =
2226  getValueNorm(pfCands.at(index_pf_muon).vertex().z() - pv.position().z(), -0.0117f, 4.097f);
2227  get(dnn::pfCand_muon_vertex_dx_tauFL) = getValueNorm(
2228  pfCands.at(index_pf_muon).vertex().x() - pv.position().x() - tau_funcs.getFlightLength(tau, tau_index).x(),
2229  -0.0001f,
2230  0.8642f);
2231  get(dnn::pfCand_muon_vertex_dy_tauFL) = getValueNorm(
2232  pfCands.at(index_pf_muon).vertex().y() - pv.position().y() - tau_funcs.getFlightLength(tau, tau_index).y(),
2233  0.0004f,
2234  0.8561f);
2235  get(dnn::pfCand_muon_vertex_dz_tauFL) = getValueNorm(
2236  pfCands.at(index_pf_muon).vertex().z() - pv.position().z() - tau_funcs.getFlightLength(tau, tau_index).z(),
2237  -0.0118f,
2238  4.405f);
2239 
2240  const bool hasTrackDetails = candFunc::getHasTrackDetails(muon_cand);
2241  if (hasTrackDetails) {
2242  get(dnn::pfCand_muon_hasTrackDetails) = hasTrackDetails;
2243  get(dnn::pfCand_muon_dxy) = getValueNorm(candFunc::getTauDxy(muon_cand), -0.0045f, 0.9655f);
2244  get(dnn::pfCand_muon_dxy_sig) =
2245  getValueNorm(std::abs(candFunc::getTauDxy(muon_cand)) / muon_cand.dxyError(), 4.575f, 42.36f);
2246  get(dnn::pfCand_muon_dz) = getValueNorm(candFunc::getTauDz(muon_cand), -0.0117f, 4.097f);
2247  get(dnn::pfCand_muon_dz_sig) =
2248  getValueNorm(std::abs(candFunc::getTauDz(muon_cand)) / muon_cand.dzError(), 80.37f, 343.3f);
2249  get(dnn::pfCand_muon_track_chi2_ndof) = getValueNorm(
2250  candFunc::getPseudoTrack(muon_cand).chi2() / candFunc::getPseudoTrack(muon_cand).ndof(), 0.69f, 1.711f);
2251  get(dnn::pfCand_muon_track_ndof) = getValueNorm(candFunc::getPseudoTrack(muon_cand).ndof(), 17.5f, 5.11f);
2252  }
2253  }
2254  if (valid_index_muon) {
2255  size_t index_muon = cell_map.at(CellObjectType::Muon);
2256 
2257  get(dnn::muon_valid) = valid_index_muon;
2258  get(dnn::muon_rel_pt) = getValueNorm(muons->at(index_muon).polarP4().pt() / tau.polarP4().pt(),
2259  is_inner ? 0.7966f : 0.2678f,
2260  is_inner ? 3.402f : 3.592f);
2261  get(dnn::muon_deta) = getValueLinear(muons->at(index_muon).polarP4().eta() - tau.polarP4().eta(),
2262  is_inner ? -0.1f : -0.5f,
2263  is_inner ? 0.1f : 0.5f,
2264  false);
2265  get(dnn::muon_dphi) = getValueLinear(dPhi(tau.polarP4(), muons->at(index_muon).polarP4()),
2266  is_inner ? -0.1f : -0.5f,
2267  is_inner ? 0.1f : 0.5f,
2268  false);
2269  get(dnn::muon_dxy) = getValueNorm(muons->at(index_muon).dB(pat::Muon::PV2D), 0.0019f, 1.039f);
2270  get(dnn::muon_dxy_sig) =
2271  getValueNorm(std::abs(muons->at(index_muon).dB(pat::Muon::PV2D)) / muons->at(index_muon).edB(pat::Muon::PV2D),
2272  8.98f,
2273  71.17f);
2274 
2275  const bool normalizedChi2_valid =
2276  muons->at(index_muon).globalTrack().isNonnull() && muons->at(index_muon).normChi2() >= 0;
2277  if (normalizedChi2_valid) {
2278  get(dnn::muon_normalizedChi2_valid) = normalizedChi2_valid;
2279  get(dnn::muon_normalizedChi2) = getValueNorm(muons->at(index_muon).normChi2(), 21.52f, 265.8f);
2280  if (muons->at(index_muon).innerTrack().isNonnull())
2281  get(dnn::muon_numberOfValidHits) = getValueNorm(muons->at(index_muon).numberOfValidHits(), 21.84f, 10.59f);
2282  }
2283  get(dnn::muon_segmentCompatibility) = getValue(muons->at(index_muon).segmentCompatibility());
2284  get(dnn::muon_caloCompatibility) = getValue(muons->at(index_muon).caloCompatibility());
2285 
2286  const bool pfEcalEnergy_valid = muons->at(index_muon).pfEcalEnergy() >= 0;
2287  if (pfEcalEnergy_valid) {
2288  get(dnn::muon_pfEcalEnergy_valid) = pfEcalEnergy_valid;
2289  get(dnn::muon_rel_pfEcalEnergy) =
2290  getValueNorm(muons->at(index_muon).pfEcalEnergy() / muons->at(index_muon).polarP4().pt(), 0.2273f, 0.4865f);
2291  }
2292 
2293  MuonHitMatchV2 hit_match(muons->at(index_muon));
2294  static const std::map<int, std::pair<int, int>> muonMatchHitVars = {
2295  {MuonSubdetId::DT, {dnn::muon_n_matches_DT_1, dnn::muon_n_hits_DT_1}},
2296  {MuonSubdetId::CSC, {dnn::muon_n_matches_CSC_1, dnn::muon_n_hits_CSC_1}},
2297  {MuonSubdetId::RPC, {dnn::muon_n_matches_RPC_1, dnn::muon_n_hits_RPC_1}}};
2298 
2299  static const std::map<int, std::vector<float>> muonMatchVarLimits = {
2300  {MuonSubdetId::DT, {2, 2, 2, 2}}, {MuonSubdetId::CSC, {6, 2, 2, 2}}, {MuonSubdetId::RPC, {7, 6, 4, 4}}};
2301 
2302  static const std::map<int, std::vector<float>> muonHitVarLimits = {{MuonSubdetId::DT, {12, 12, 12, 8}},
2303  {MuonSubdetId::CSC, {24, 12, 12, 12}},
2304  {MuonSubdetId::RPC, {4, 4, 2, 2}}};
2305 
2306  for (int subdet : hit_match.MuonHitMatchV2::consideredSubdets()) {
2307  const auto& matchHitVar = muonMatchHitVars.at(subdet);
2308  const auto& matchLimits = muonMatchVarLimits.at(subdet);
2309  const auto& hitLimits = muonHitVarLimits.at(subdet);
2310  for (int station = MuonHitMatchV2::first_station_id; station <= MuonHitMatchV2::last_station_id; ++station) {
2311  const unsigned n_matches = hit_match.nMatches(subdet, station);
2312  const unsigned n_hits = hit_match.nHits(subdet, station);
2313  get(matchHitVar.first + station - 1) = getValueLinear(n_matches, 0, matchLimits.at(station - 1), true);
2314  get(matchHitVar.second + station - 1) = getValueLinear(n_hits, 0, hitLimits.at(station - 1), true);
2315  }
2316  }
2317  }
2318  }
2319 
2320  template <typename CandidateCastType, typename TauCastType>
2322  const TauCastType& tau,
2323  const size_t tau_index,
2324  const edm::RefToBase<reco::BaseTau> tau_ref,
2325  const reco::Vertex& pv,
2326  double rho,
2327  const edm::View<reco::Candidate>& pfCands,
2328  const Cell& cell_map,
2329  TauFunc tau_funcs,
2330  bool is_inner) {
2331  namespace dnn = dnn_inputs_2017_v2::HadronBlockInputs;
2332 
2333  tensorflow::Tensor& inputs = *hadronsTensor_.at(is_inner);
2334 
2335  const auto& get = [&](int var_index) -> float& { return inputs.tensor<float, 4>()(idx, 0, 0, var_index); };
2336 
2337  const bool valid_chH = cell_map.count(CellObjectType::PfCand_chargedHadron);
2338  const bool valid_nH = cell_map.count(CellObjectType::PfCand_neutralHadron);
2339 
2340  if (!cell_map.empty()) {
2341  get(dnn::rho) = getValueNorm(rho, 21.49f, 9.713f);
2342  get(dnn::tau_pt) = getValueLinear(tau.polarP4().pt(), 20.f, 1000.f, true);
2343  get(dnn::tau_eta) = getValueLinear(tau.polarP4().eta(), -2.3f, 2.3f, false);
2344  get(dnn::tau_inside_ecal_crack) = getValue(isInEcalCrack(tau.polarP4().eta()));
2345  }
2346  if (valid_chH) {
2347  size_t index_chH = cell_map.at(CellObjectType::PfCand_chargedHadron);
2348  const auto& chH_cand = dynamic_cast<const CandidateCastType&>(pfCands.at(index_chH));
2349 
2350  get(dnn::pfCand_chHad_valid) = valid_chH;
2351  get(dnn::pfCand_chHad_rel_pt) = getValueNorm(pfCands.at(index_chH).polarP4().pt() / tau.polarP4().pt(),
2352  is_inner ? 0.2564f : 0.0194f,
2353  is_inner ? 0.8607f : 0.1865f);
2354  get(dnn::pfCand_chHad_deta) = getValueLinear(pfCands.at(index_chH).polarP4().eta() - tau.polarP4().eta(),
2355  is_inner ? -0.1f : -0.5f,
2356  is_inner ? 0.1f : 0.5f,
2357  false);
2358  get(dnn::pfCand_chHad_dphi) = getValueLinear(dPhi(tau.polarP4(), pfCands.at(index_chH).polarP4()),
2359  is_inner ? -0.1f : -0.5f,
2360  is_inner ? 0.1f : 0.5f,
2361  false);
2362  get(dnn::pfCand_chHad_leadChargedHadrCand) =
2363  getValue(&chH_cand == dynamic_cast<const CandidateCastType*>(tau.leadChargedHadrCand().get()));
2364  get(dnn::pfCand_chHad_pvAssociationQuality) =
2365  getValueLinear<int>(candFunc::getPvAssocationQuality(chH_cand), 0, 7, true);
2366  get(dnn::pfCand_chHad_fromPV) = getValueLinear<int>(candFunc::getFromPV(chH_cand), 0, 3, true);
2367  const float default_chH_pw_inner = 0.7614090f;
2368  const float default_chH_pw_outer = 0.1974930f;
2369  get(dnn::pfCand_chHad_puppiWeight) = is_inner
2370  ? getValue(candFunc::getPuppiWeight(chH_cand, default_chH_pw_inner))
2371  : getValue(candFunc::getPuppiWeight(chH_cand, default_chH_pw_outer));
2372  get(dnn::pfCand_chHad_puppiWeightNoLep) =
2373  is_inner ? getValue(candFunc::getPuppiWeightNoLep(chH_cand, default_chH_pw_inner))
2374  : getValue(candFunc::getPuppiWeightNoLep(chH_cand, default_chH_pw_outer));
2375  get(dnn::pfCand_chHad_charge) = getValue(chH_cand.charge());
2376  get(dnn::pfCand_chHad_lostInnerHits) = getValue<int>(candFunc::getLostInnerHits(chH_cand, 0));
2377  get(dnn::pfCand_chHad_numberOfPixelHits) =
2378  getValueLinear(candFunc::getNumberOfPixelHits(chH_cand, 0), 0, 12, true);
2379  get(dnn::pfCand_chHad_vertex_dx) =
2380  getValueNorm(pfCands.at(index_chH).vertex().x() - pv.position().x(), 0.0005f, 1.735f);
2381  get(dnn::pfCand_chHad_vertex_dy) =
2382  getValueNorm(pfCands.at(index_chH).vertex().y() - pv.position().y(), -0.0008f, 1.752f);
2383  get(dnn::pfCand_chHad_vertex_dz) =
2384  getValueNorm(pfCands.at(index_chH).vertex().z() - pv.position().z(), -0.0201f, 8.333f);
2385  get(dnn::pfCand_chHad_vertex_dx_tauFL) = getValueNorm(
2386  pfCands.at(index_chH).vertex().x() - pv.position().x() - tau_funcs.getFlightLength(tau, tau_index).x(),
2387  -0.0014f,
2388  1.93f);
2389  get(dnn::pfCand_chHad_vertex_dy_tauFL) = getValueNorm(
2390  pfCands.at(index_chH).vertex().y() - pv.position().y() - tau_funcs.getFlightLength(tau, tau_index).y(),
2391  0.0022f,
2392  1.948f);
2393  get(dnn::pfCand_chHad_vertex_dz_tauFL) = getValueNorm(
2394  pfCands.at(index_chH).vertex().z() - pv.position().z() - tau_funcs.getFlightLength(tau, tau_index).z(),
2395  -0.0138f,
2396  8.622f);
2397 
2398  const bool hasTrackDetails = candFunc::getHasTrackDetails(chH_cand);
2399  if (hasTrackDetails) {
2400  get(dnn::pfCand_chHad_hasTrackDetails) = hasTrackDetails;
2401  get(dnn::pfCand_chHad_dxy) = getValueNorm(candFunc::getTauDxy(chH_cand), -0.012f, 2.386f);
2402  get(dnn::pfCand_chHad_dxy_sig) =
2403  getValueNorm(std::abs(candFunc::getTauDxy(chH_cand)) / chH_cand.dxyError(), 6.417f, 36.28f);
2404  get(dnn::pfCand_chHad_dz) = getValueNorm(candFunc::getTauDz(chH_cand), -0.0246f, 7.618f);
2405  get(dnn::pfCand_chHad_dz_sig) =
2406  getValueNorm(std::abs(candFunc::getTauDz(chH_cand)) / chH_cand.dzError(), 301.3f, 491.1f);
2407  get(dnn::pfCand_chHad_track_chi2_ndof) =
2408  candFunc::getPseudoTrack(chH_cand).ndof() > 0
2409  ? getValueNorm(candFunc::getPseudoTrack(chH_cand).chi2() / candFunc::getPseudoTrack(chH_cand).ndof(),
2410  0.7876f,
2411  3.694f)
2412  : 0;
2413  get(dnn::pfCand_chHad_track_ndof) =
2414  candFunc::getPseudoTrack(chH_cand).ndof() > 0
2415  ? getValueNorm(candFunc::getPseudoTrack(chH_cand).ndof(), 13.92f, 6.581f)
2416  : 0;
2417  }
2418  float hcal_fraction = candFunc::getHCalFraction(chH_cand, disable_hcalFraction_workaround_);
2419  get(dnn::pfCand_chHad_hcalFraction) = getValue(hcal_fraction);
2420  get(dnn::pfCand_chHad_rawCaloFraction) = getValueLinear(candFunc::getRawCaloFraction(chH_cand), 0.f, 2.6f, true);
2421  }
2422  if (valid_nH) {
2423  size_t index_nH = cell_map.at(CellObjectType::PfCand_neutralHadron);
2424  const auto& nH_cand = dynamic_cast<const CandidateCastType&>(pfCands.at(index_nH));
2425 
2426  get(dnn::pfCand_nHad_valid) = valid_nH;
2427  get(dnn::pfCand_nHad_rel_pt) = getValueNorm(pfCands.at(index_nH).polarP4().pt() / tau.polarP4().pt(),
2428  is_inner ? 0.3163f : 0.0502f,
2429  is_inner ? 0.2769f : 0.4266f);
2430  get(dnn::pfCand_nHad_deta) = getValueLinear(pfCands.at(index_nH).polarP4().eta() - tau.polarP4().eta(),
2431  is_inner ? -0.1f : -0.5f,
2432  is_inner ? 0.1f : 0.5f,
2433  false);
2434  get(dnn::pfCand_nHad_dphi) = getValueLinear(
2435  dPhi(tau.polarP4(), pfCands.at(index_nH).polarP4()), is_inner ? -0.1f : -0.5f, is_inner ? 0.1f : 0.5f, false);
2436  get(dnn::pfCand_nHad_puppiWeight) = is_inner ? getValue(candFunc::getPuppiWeight(nH_cand, 0.9798355f))
2437  : getValue(candFunc::getPuppiWeight(nH_cand, 0.7813260f));
2438  get(dnn::pfCand_nHad_puppiWeightNoLep) = is_inner ? getValue(candFunc::getPuppiWeightNoLep(nH_cand, 0.9046796f))
2439  : getValue(candFunc::getPuppiWeightNoLep(nH_cand, 0.6554860f));
2440  float hcal_fraction = candFunc::getHCalFraction(nH_cand, disable_hcalFraction_workaround_);
2441  get(dnn::pfCand_nHad_hcalFraction) = getValue(hcal_fraction);
2442  }
2443  }
2444 
2445  template <typename dnn, typename CandidateCastType, typename TauCastType>
2446  tensorflow::Tensor createInputsV1(const TauCastType& tau,
2447  const size_t tau_index,
2448  const edm::RefToBase<reco::BaseTau> tau_ref,
2449  const std::vector<pat::Electron>* electrons,
2450  const std::vector<pat::Muon>* muons,
2451  TauFunc tau_funcs) const {
2452  static constexpr bool check_all_set = false;
2453  static constexpr float default_value_for_set_check = -42;
2454 
2455  tensorflow::Tensor inputs(tensorflow::DT_FLOAT, {1, dnn_inputs_2017v1::NumberOfInputs});
2456  const auto& get = [&](int var_index) -> float& { return inputs.matrix<float>()(0, var_index); };
2457  auto leadChargedHadrCand = dynamic_cast<const CandidateCastType*>(tau.leadChargedHadrCand().get());
2458 
2459  if (check_all_set) {
2460  for (int var_index = 0; var_index < dnn::NumberOfInputs; ++var_index) {
2461  get(var_index) = default_value_for_set_check;
2462  }
2463  }
2464 
2465  get(dnn::pt) = tau.p4().pt();
2466  get(dnn::eta) = tau.p4().eta();
2467  get(dnn::mass) = tau.p4().mass();
2468  get(dnn::decayMode) = tau.decayMode();
2469  get(dnn::chargedIsoPtSum) = tau_funcs.getChargedIsoPtSum(tau, tau_ref);
2470  get(dnn::neutralIsoPtSum) = tau_funcs.getNeutralIsoPtSum(tau, tau_ref);
2471  get(dnn::neutralIsoPtSumWeight) = tau_funcs.getNeutralIsoPtSumWeight(tau, tau_ref);
2472  get(dnn::photonPtSumOutsideSignalCone) = tau_funcs.getPhotonPtSumOutsideSignalCone(tau, tau_ref);
2473  get(dnn::puCorrPtSum) = tau_funcs.getPuCorrPtSum(tau, tau_ref);
2474  get(dnn::dxy) = tau_funcs.getdxy(tau, tau_index);
2475  get(dnn::dxy_sig) = tau_funcs.getdxySig(tau, tau_index);
2476  get(dnn::dz) = leadChargedHadrCand ? candFunc::getTauDz(*leadChargedHadrCand) : default_value;
2477  get(dnn::ip3d) = tau_funcs.getip3d(tau, tau_index);
2478  get(dnn::ip3d_sig) = tau_funcs.getip3dSig(tau, tau_index);
2479  get(dnn::hasSecondaryVertex) = tau_funcs.getHasSecondaryVertex(tau, tau_index);
2480  get(dnn::flightLength_r) = tau_funcs.getFlightLength(tau, tau_index).R();
2481  get(dnn::flightLength_dEta) = dEta(tau_funcs.getFlightLength(tau, tau_index), tau.p4());
2482  get(dnn::flightLength_dPhi) = dPhi(tau_funcs.getFlightLength(tau, tau_index), tau.p4());
2483  get(dnn::flightLength_sig) = tau_funcs.getFlightLengthSig(tau, tau_index);
2484  get(dnn::leadChargedHadrCand_pt) = leadChargedHadrCand ? leadChargedHadrCand->p4().Pt() : default_value;
2485  get(dnn::leadChargedHadrCand_dEta) =
2486  leadChargedHadrCand ? dEta(leadChargedHadrCand->p4(), tau.p4()) : default_value;
2487  get(dnn::leadChargedHadrCand_dPhi) =
2488  leadChargedHadrCand ? dPhi(leadChargedHadrCand->p4(), tau.p4()) : default_value;
2489  get(dnn::leadChargedHadrCand_mass) = leadChargedHadrCand ? leadChargedHadrCand->p4().mass() : default_value;
2494  get(dnn::leadingTrackNormChi2) = tau_funcs.getLeadingTrackNormChi2(tau);
2495  get(dnn::e_ratio) = reco::tau::eratio(tau);
2496  get(dnn::gj_angle_diff) = calculateGottfriedJacksonAngleDifference(tau, tau_index, tau_funcs);
2497  get(dnn::n_photons) = reco::tau::n_photons_total(tau);
2498  get(dnn::emFraction) = tau_funcs.getEmFraction(tau);
2499  get(dnn::has_gsf_track) = leadChargedHadrCand && std::abs(leadChargedHadrCand->pdgId()) == 11;
2500  get(dnn::inside_ecal_crack) = isInEcalCrack(tau.p4().Eta());
2501  auto gsf_ele = findMatchedElectron(tau, electrons, 0.3);
2502  get(dnn::gsf_ele_matched) = gsf_ele != nullptr;
2503  get(dnn::gsf_ele_pt) = gsf_ele != nullptr ? gsf_ele->p4().Pt() : default_value;
2504  get(dnn::gsf_ele_dEta) = gsf_ele != nullptr ? dEta(gsf_ele->p4(), tau.p4()) : default_value;
2505  get(dnn::gsf_ele_dPhi) = gsf_ele != nullptr ? dPhi(gsf_ele->p4(), tau.p4()) : default_value;
2506  get(dnn::gsf_ele_mass) = gsf_ele != nullptr ? gsf_ele->p4().mass() : default_value;
2507  calculateElectronClusterVars(gsf_ele, get(dnn::gsf_ele_Ee), get(dnn::gsf_ele_Egamma));
2508  get(dnn::gsf_ele_Pin) = gsf_ele != nullptr ? gsf_ele->trackMomentumAtVtx().R() : default_value;
2509  get(dnn::gsf_ele_Pout) = gsf_ele != nullptr ? gsf_ele->trackMomentumOut().R() : default_value;
2510  get(dnn::gsf_ele_EtotOverPin) = get(dnn::gsf_ele_Pin) > 0
2511  ? (get(dnn::gsf_ele_Ee) + get(dnn::gsf_ele_Egamma)) / get(dnn::gsf_ele_Pin)
2512  : default_value;
2513  get(dnn::gsf_ele_Eecal) = gsf_ele != nullptr ? gsf_ele->ecalEnergy() : default_value;
2514  get(dnn::gsf_ele_dEta_SeedClusterTrackAtCalo) =
2515  gsf_ele != nullptr ? gsf_ele->deltaEtaSeedClusterTrackAtCalo() : default_value;
2516  get(dnn::gsf_ele_dPhi_SeedClusterTrackAtCalo) =
2517  gsf_ele != nullptr ? gsf_ele->deltaPhiSeedClusterTrackAtCalo() : default_value;
2518  get(dnn::gsf_ele_mvaIn_sigmaEtaEta) = gsf_ele != nullptr ? gsf_ele->mvaInput().sigmaEtaEta : default_value;
2519  get(dnn::gsf_ele_mvaIn_hadEnergy) = gsf_ele != nullptr ? gsf_ele->mvaInput().hadEnergy : default_value;
2520  get(dnn::gsf_ele_mvaIn_deltaEta) = gsf_ele != nullptr ? gsf_ele->mvaInput().deltaEta : default_value;
2521 
2522  get(dnn::gsf_ele_Chi2NormGSF) = default_value;
2523  get(dnn::gsf_ele_GSFNumHits) = default_value;
2524  get(dnn::gsf_ele_GSFTrackResol) = default_value;
2525  get(dnn::gsf_ele_GSFTracklnPt) = default_value;
2526  if (gsf_ele != nullptr && gsf_ele->gsfTrack().isNonnull()) {
2527  get(dnn::gsf_ele_Chi2NormGSF) = gsf_ele->gsfTrack()->normalizedChi2();
2528  get(dnn::gsf_ele_GSFNumHits) = gsf_ele->gsfTrack()->numberOfValidHits();
2529  if (gsf_ele->gsfTrack()->pt() > 0) {
2530  get(dnn::gsf_ele_GSFTrackResol) = gsf_ele->gsfTrack()->ptError() / gsf_ele->gsfTrack()->pt();
2531  get(dnn::gsf_ele_GSFTracklnPt) = std::log10(gsf_ele->gsfTrack()->pt());
2532  }
2533  }
2534 
2535  get(dnn::gsf_ele_Chi2NormKF) = default_value;
2536  get(dnn::gsf_ele_KFNumHits) = default_value;
2537  if (gsf_ele != nullptr && gsf_ele->closestCtfTrackRef().isNonnull()) {
2538  get(dnn::gsf_ele_Chi2NormKF) = gsf_ele->closestCtfTrackRef()->normalizedChi2();
2539  get(dnn::gsf_ele_KFNumHits) = gsf_ele->closestCtfTrackRef()->numberOfValidHits();
2540  }
2541  get(dnn::leadChargedCand_etaAtEcalEntrance) = tau_funcs.getEtaAtEcalEntrance(tau);
2542  get(dnn::leadChargedCand_pt) = leadChargedHadrCand->pt();
2543 
2544  get(dnn::leadChargedHadrCand_HoP) = default_value;
2545  get(dnn::leadChargedHadrCand_EoP) = default_value;
2546  if (leadChargedHadrCand->pt() > 0) {
2547  get(dnn::leadChargedHadrCand_HoP) = tau_funcs.getEcalEnergyLeadingChargedHadr(tau) / leadChargedHadrCand->pt();
2548  get(dnn::leadChargedHadrCand_EoP) = tau_funcs.getHcalEnergyLeadingChargedHadr(tau) / leadChargedHadrCand->pt();
2549  }
2550 
2551  MuonHitMatchV1 muon_hit_match;
2552  if (tau.leadPFChargedHadrCand().isNonnull() && tau.leadPFChargedHadrCand()->muonRef().isNonnull())
2553  muon_hit_match.addMatchedMuon(*tau.leadPFChargedHadrCand()->muonRef(), tau);
2554 
2555  auto matched_muons = muon_hit_match.findMatchedMuons(tau, muons, 0.3, 5);
2556  for (auto muon : matched_muons)
2557  muon_hit_match.addMatchedMuon(*muon, tau);
2558  muon_hit_match.fillTensor<dnn>(get, tau, default_value);
2559 
2560  LorentzVectorXYZ signalChargedHadrCands_sumIn, signalChargedHadrCands_sumOut;
2562  tau.signalChargedHadrCands(),
2563  signalChargedHadrCands_sumIn,
2564  signalChargedHadrCands_sumOut,
2565  get(dnn::signalChargedHadrCands_sum_innerSigCone_pt),
2566  get(dnn::signalChargedHadrCands_sum_innerSigCone_dEta),
2567  get(dnn::signalChargedHadrCands_sum_innerSigCone_dPhi),
2568  get(dnn::signalChargedHadrCands_sum_innerSigCone_mass),
2569  get(dnn::signalChargedHadrCands_sum_outerSigCone_pt),
2570  get(dnn::signalChargedHadrCands_sum_outerSigCone_dEta),
2571  get(dnn::signalChargedHadrCands_sum_outerSigCone_dPhi),
2572  get(dnn::signalChargedHadrCands_sum_outerSigCone_mass),
2573  get(dnn::signalChargedHadrCands_nTotal_innerSigCone),
2574  get(dnn::signalChargedHadrCands_nTotal_outerSigCone));
2575 
2576  LorentzVectorXYZ signalNeutrHadrCands_sumIn, signalNeutrHadrCands_sumOut;
2578  tau.signalNeutrHadrCands(),
2579  signalNeutrHadrCands_sumIn,
2580  signalNeutrHadrCands_sumOut,
2581  get(dnn::signalNeutrHadrCands_sum_innerSigCone_pt),
2582  get(dnn::signalNeutrHadrCands_sum_innerSigCone_dEta),
2583  get(dnn::signalNeutrHadrCands_sum_innerSigCone_dPhi),
2584  get(dnn::signalNeutrHadrCands_sum_innerSigCone_mass),
2585  get(dnn::signalNeutrHadrCands_sum_outerSigCone_pt),
2586  get(dnn::signalNeutrHadrCands_sum_outerSigCone_dEta),
2587  get(dnn::signalNeutrHadrCands_sum_outerSigCone_dPhi),
2588  get(dnn::signalNeutrHadrCands_sum_outerSigCone_mass),
2589  get(dnn::signalNeutrHadrCands_nTotal_innerSigCone),
2590  get(dnn::signalNeutrHadrCands_nTotal_outerSigCone));
2591 
2592  LorentzVectorXYZ signalGammaCands_sumIn, signalGammaCands_sumOut;
2594  tau.signalGammaCands(),
2595  signalGammaCands_sumIn,
2596  signalGammaCands_sumOut,
2597  get(dnn::signalGammaCands_sum_innerSigCone_pt),
2598  get(dnn::signalGammaCands_sum_innerSigCone_dEta),
2599  get(dnn::signalGammaCands_sum_innerSigCone_dPhi),
2600  get(dnn::signalGammaCands_sum_innerSigCone_mass),
2601  get(dnn::signalGammaCands_sum_outerSigCone_pt),
2602  get(dnn::signalGammaCands_sum_outerSigCone_dEta),
2603  get(dnn::signalGammaCands_sum_outerSigCone_dPhi),
2604  get(dnn::signalGammaCands_sum_outerSigCone_mass),
2605  get(dnn::signalGammaCands_nTotal_innerSigCone),
2606  get(dnn::signalGammaCands_nTotal_outerSigCone));
2607 
2608  LorentzVectorXYZ isolationChargedHadrCands_sum;
2610  tau.isolationChargedHadrCands(),
2611  isolationChargedHadrCands_sum,
2612  get(dnn::isolationChargedHadrCands_sum_pt),
2613  get(dnn::isolationChargedHadrCands_sum_dEta),
2614  get(dnn::isolationChargedHadrCands_sum_dPhi),
2615  get(dnn::isolationChargedHadrCands_sum_mass),
2616  get(dnn::isolationChargedHadrCands_nTotal));
2617 
2618  LorentzVectorXYZ isolationNeutrHadrCands_sum;
2620  tau.isolationNeutrHadrCands(),
2621  isolationNeutrHadrCands_sum,
2622  get(dnn::isolationNeutrHadrCands_sum_pt),
2623  get(dnn::isolationNeutrHadrCands_sum_dEta),
2624  get(dnn::isolationNeutrHadrCands_sum_dPhi),
2625  get(dnn::isolationNeutrHadrCands_sum_mass),
2626  get(dnn::isolationNeutrHadrCands_nTotal));
2627 
2628  LorentzVectorXYZ isolationGammaCands_sum;
2630  tau.isolationGammaCands(),
2631  isolationGammaCands_sum,
2632  get(dnn::isolationGammaCands_sum_pt),
2633  get(dnn::isolationGammaCands_sum_dEta),
2634  get(dnn::isolationGammaCands_sum_dPhi),
2635  get(dnn::isolationGammaCands_sum_mass),
2636  get(dnn::isolationGammaCands_nTotal));
2637 
2638  get(dnn::tau_visMass_innerSigCone) = (signalGammaCands_sumIn + signalChargedHadrCands_sumIn).mass();
2639 
2640  if (check_all_set) {
2641  for (int var_index = 0; var_index < dnn::NumberOfInputs; ++var_index) {
2642  if (get(var_index) == default_value_for_set_check)
2643  throw cms::Exception("DeepTauId: variable with index = ") << var_index << " is not set.";
2644  }
2645  }
2646 
2647  return inputs;
2648  }
2649 
2650  static void calculateElectronClusterVars(const pat::Electron* ele, float& elecEe, float& elecEgamma) {
2651  if (ele) {
2652  elecEe = elecEgamma = 0;
2653  auto superCluster = ele->superCluster();
2654  if (superCluster.isNonnull() && superCluster.isAvailable() && superCluster->clusters().isNonnull() &&
2655  superCluster->clusters().isAvailable()) {
2656  for (auto iter = superCluster->clustersBegin(); iter != superCluster->clustersEnd(); ++iter) {
2657  const double energy = (*iter)->energy();
2658  if (iter == superCluster->clustersBegin())
2659  elecEe += energy;
2660  else
2661  elecEgamma += energy;
2662  }
2663  }
2664  } else {
2665  elecEe = elecEgamma = default_value;
2666  }
2667  }
2668 
2669  template <typename CandidateCollection, typename TauCastType>
2670  static void processSignalPFComponents(const TauCastType& tau,
2672  LorentzVectorXYZ& p4_inner,
2673  LorentzVectorXYZ& p4_outer,
2674  float& pt_inner,
2675  float& dEta_inner,
2676  float& dPhi_inner,
2677  float& m_inner,
2678  float& pt_outer,
2679  float& dEta_outer,
2680  float& dPhi_outer,
2681  float& m_outer,
2682  float& n_inner,
2683  float& n_outer) {
2684  p4_inner = LorentzVectorXYZ(0, 0, 0, 0);
2685  p4_outer = LorentzVectorXYZ(0, 0, 0, 0);
2686  n_inner = 0;
2687  n_outer = 0;
2688 
2689  const double innerSigCone_radius = getInnerSignalConeRadius(tau.pt());
2690  for (const auto& cand : candidates) {
2691  const double dR = reco::deltaR(cand->p4(), tau.leadChargedHadrCand()->p4());
2692  const bool isInside_innerSigCone = dR < innerSigCone_radius;
2693  if (isInside_innerSigCone) {
2694  p4_inner += cand->p4();
2695  ++n_inner;
2696  } else {
2697  p4_outer += cand->p4();
2698  ++n_outer;
2699  }
2700  }
2701 
2702  pt_inner = n_inner != 0 ? p4_inner.Pt() : default_value;
2703  dEta_inner = n_inner != 0 ? dEta(p4_inner, tau.p4()) : default_value;
2704  dPhi_inner = n_inner != 0 ? dPhi(p4_inner, tau.p4()) : default_value;
2705  m_inner = n_inner != 0 ? p4_inner.mass() : default_value;
2706 
2707  pt_outer = n_outer != 0 ? p4_outer.Pt() : default_value;
2708  dEta_outer = n_outer != 0 ? dEta(p4_outer, tau.p4()) : default_value;
2709  dPhi_outer = n_outer != 0 ? dPhi(p4_outer, tau.p4()) : default_value;
2710  m_outer = n_outer != 0 ? p4_outer.mass() : default_value;
2711  }
2712 
2713  template <typename CandidateCollection, typename TauCastType>
2714  static void processIsolationPFComponents(const TauCastType& tau,
2717  float& pt,
2718  float& d_eta,
2719  float& d_phi,
2720  float& m,
2721  float& n) {
2722  p4 = LorentzVectorXYZ(0, 0, 0, 0);
2723  n = 0;
2724 
2725  for (const auto& cand : candidates) {
2726  p4 += cand->p4();
2727  ++n;
2728  }
2729 
2730  pt = n != 0 ? p4.Pt() : default_value;
2731  d_eta = n != 0 ? dEta(p4, tau.p4()) : default_value;
2732  d_phi = n != 0 ? dPhi(p4, tau.p4()) : default_value;
2733  m = n != 0 ? p4.mass() : default_value;
2734  }
2735 
2736  static double getInnerSignalConeRadius(double pt) {
2737  static constexpr double min_pt = 30., min_radius = 0.05, cone_opening_coef = 3.;
2738  // This is equivalent of the original formula (std::max(std::min(0.1, 3.0/pt), 0.05)
2739  return std::max(cone_opening_coef / std::max(pt, min_pt), min_radius);
2740  }
2741 
2742  // Copied from https://github.com/cms-sw/cmssw/blob/CMSSW_9_4_X/RecoTauTag/RecoTau/plugins/PATTauDiscriminationByMVAIsolationRun2.cc#L218
2743  template <typename TauCastType>
2744  static bool calculateGottfriedJacksonAngleDifference(const TauCastType& tau,
2745  const size_t tau_index,
2746  double& gj_diff,
2747  TauFunc tau_funcs) {
2748  if (tau_funcs.getHasSecondaryVertex(tau, tau_index)) {
2749  static constexpr double mTau = 1.77682;
2750  const double mAOne = tau.p4().M();
2751  const double pAOneMag = tau.p();
2752  const double argumentThetaGJmax = (std::pow(mTau, 2) - std::pow(mAOne, 2)) / (2 * mTau * pAOneMag);
2753  const double argumentThetaGJmeasured = tau.p4().Vect().Dot(tau_funcs.getFlightLength(tau, tau_index)) /
2754  (pAOneMag * tau_funcs.getFlightLength(tau, tau_index).R());
2755  if (std::abs(argumentThetaGJmax) <= 1. && std::abs(argumentThetaGJmeasured) <= 1.) {
2756  double thetaGJmax = std::asin(argumentThetaGJmax);
2757  double thetaGJmeasured = std::acos(argumentThetaGJmeasured);
2758  gj_diff = thetaGJmeasured - thetaGJmax;
2759  return true;
2760  }
2761  }
2762  return false;
2763  }
2764 
2765  template <typename TauCastType>
2766  static float calculateGottfriedJacksonAngleDifference(const TauCastType& tau,
2767  const size_t tau_index,
2768  TauFunc tau_funcs) {
2769  double gj_diff;
2770  if (calculateGottfriedJacksonAngleDifference(tau, tau_index, gj_diff, tau_funcs))
2771  return static_cast<float>(gj_diff);
2772  return default_value;
2773  }
2774 
2775  static bool isInEcalCrack(double eta) {
2776  const double abs_eta = std::abs(eta);
2777  return abs_eta > 1.46 && abs_eta < 1.558;
2778  }
2779 
2780  template <typename TauCastType>
2781  static const pat::Electron* findMatchedElectron(const TauCastType& tau,
2782  const std::vector<pat::Electron>* electrons,
2783  double deltaR) {
2784  const double dR2 = deltaR * deltaR;
2785  const pat::Electron* matched_ele = nullptr;
2786  for (const auto& ele : *electrons) {
2787  if (reco::deltaR2(tau.p4(), ele.p4()) < dR2 && (!matched_ele || matched_ele->pt() < ele.pt())) {
2788  matched_ele = &ele;
2789  }
2790  }
2791  return matched_ele;
2792  }
2793 
2794 private:
2803  const unsigned version_;
2804  const int debug_level;
2805  const bool disable_dxy_pca_;
2808  std::unique_ptr<tensorflow::Tensor> tauBlockTensor_;
2809  std::array<std::unique_ptr<tensorflow::Tensor>, 2> eGammaTensor_, muonTensor_, hadronsTensor_, convTensor_,
2811  const bool save_inputs_;
2812  std::ofstream* json_file_;
2815 
2816  //boolean to check if discriminator indices are already mapped
2817  bool discrIndicesMapped_ = false;
2818  std::map<BasicDiscriminator, size_t> basicDiscrIndexMap_;
2819  std::map<BasicDiscriminator, size_t> basicDiscrdR03IndexMap_;
2820 };
2821 
reco::tau::pt_weighted_deta_strip
float pt_weighted_deta_strip(const reco::PFTau &tau, int dm)
Definition: PFRecoTauClusterVariables.h:36
deep_tau::DeepTauBase::cache_
const DeepTauCache * cache_
Definition: DeepTauBase.h:135
PDWG_BPHSkim_cff.muons
muons
Definition: PDWG_BPHSkim_cff.py:47
deep_tau::DeepTauBase::patPrediscriminants_
std::vector< TauDiscInfo< pat::PATTauDiscriminator > > patPrediscriminants_
Definition: DeepTauBase.h:112
alignBH_cfg.fixed
fixed
Definition: alignBH_cfg.py:54
MuonSubdetId::CSC
static constexpr int CSC
Definition: MuonSubdetId.h:12
DeepTauId::rho_token_
edm::EDGetTokenT< double > rho_token_
Definition: DeepTauId.cc:2797
dnn_inputs_2017_v2
Definition: DeepTauId.cc:158
DeepTauId::calculateElectronClusterVars
static void calculateElectronClusterVars(const pat::Electron *ele, float &elecEe, float &elecEgamma)
Definition: DeepTauId.cc:2650
DeepTauBase.h
DeepTauId::DeepTauId
DeepTauId(const edm::ParameterSet &cfg, const deep_tau::DeepTauCache *cache)
Definition: DeepTauId.cc:1189
electrons_cff.bool
bool
Definition: electrons_cff.py:393
mps_fire.i
i
Definition: mps_fire.py:428
edm::ParameterSetDescription::add
ParameterDescriptionBase * add(U const &iLabel, T const &value)
Definition: ParameterSetDescription.h:95
DeepTauId::getInnerSignalConeRadius
static double getInnerSignalConeRadius(double pt)
Definition: DeepTauId.cc:2736
input
static const std::string input
Definition: EdmProvDump.cc:48
dqmMemoryStats.float
float
Definition: dqmMemoryStats.py:127
deep_tau::DeepTauCache::getSession
tensorflow::Session & getSession(const std::string &name="") const
Definition: DeepTauBase.h:57
SiStripPI::mean
Definition: SiStripPayloadInspectorHelper.h:169
dqmiodumpmetadata.n
n
Definition: dqmiodumpmetadata.py:28
edm::View::const_reference
T const & const_reference
Definition: View.h:82
deep_tau::DeepTauBase::pfcandToken_
edm::EDGetTokenT< CandidateCollection > pfcandToken_
Definition: DeepTauBase.h:130
runTauDisplay.tau_eta
tau_eta
Definition: runTauDisplay.py:126
reco::PFTauTransverseImpactParameterRef
edm::Ref< PFTauTransverseImpactParameterCollection > PFTauTransverseImpactParameterRef
presistent reference to a PFTauTransverseImpactParameter
Definition: PFTauTransverseImpactParameterFwd.h:13
dnn_inputs_2017_v2::MuonBlockInputs
Definition: DeepTauId.cc:307
f
double f[11][100]
Definition: MuScleFitUtils.cc:78
metsig::tau
Definition: SignAlgoResolutions.h:49
muon
Definition: MuonCocktails.h:17
edm::isNotFinite
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
DeepTauId::isInEcalCrack
static bool isInEcalCrack(double eta)
Definition: DeepTauId.cc:2775
DeepTauId::pi
static constexpr float pi
Definition: DeepTauId.cc:1256
DeepTauId::getValue
static float getValue(T value)
Definition: DeepTauId.cc:1259
DeepTauId::setCellConvFeatures
void setCellConvFeatures(tensorflow::Tensor &convTensor, const tensorflow::Tensor &features, unsigned batch_idx, int eta_index, int phi_index)
Definition: DeepTauId.cc:1817
DeepTauId::version_
const unsigned version_
Definition: DeepTauId.cc:2803
DiDispStaMuonMonitor_cfi.pt
pt
Definition: DiDispStaMuonMonitor_cfi.py:39
min
T min(T a, T b)
Definition: MathUtil.h:58
reco::deltaPhi
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
postprocess-scan-build.features
features
Definition: postprocess-scan-build.py:8
edm::EDGetTokenT
Definition: EDGetToken.h:33
Tau3MuMonitor_cff.taus
taus
Definition: Tau3MuMonitor_cff.py:7
Electron
Definition: Electron.py:1
relativeConstraints.station
station
Definition: relativeConstraints.py:67
edm
HLT enums.
Definition: AlignableModifier.h:19
reco::tau::eratio
float eratio(const reco::PFTau &tau)
return ratio of energy in ECAL over sum of energy in ECAL and HCAL
Definition: PFRecoTauClusterVariables.cc:78
PFTauTransverseImpactParameterAssociation.h
deep_tau::DeepTauBase::BasicDiscriminator
BasicDiscriminator
Definition: DeepTauBase.h:115
fireworks::subdets
static const std::string subdets[7]
Definition: TrackUtils.cc:60
pat::Tau
Analysis-level tau class.
Definition: Tau.h:53
deep_tau::DeepTauBase::OutputCollection
std::map< std::string, Output > OutputCollection
Definition: DeepTauBase.h:91
gather_cfg.cout
cout
Definition: gather_cfg.py:144
DeepTauId::matchDiscriminatorIndices
const std::map< BasicDiscriminator, size_t > matchDiscriminatorIndices(edm::Event &event, edm::EDGetTokenT< reco::TauDiscriminatorContainer > discriminatorContainerToken, std::vector< BasicDiscriminator > requiredDiscr)
Definition: DeepTauId.cc:1114
objects
Definition: __init__.py:1
ZElectronSkim_cff.rho
rho
Definition: ZElectronSkim_cff.py:38
DeepTauId::hadronsTensor_
std::array< std::unique_ptr< tensorflow::Tensor >, 2 > hadronsTensor_
Definition: DeepTauId.cc:2809
HLT_FULL_cff.InputTag
InputTag
Definition: HLT_FULL_cff.py:89287
reco::PFTauRefProd
edm::RefProd< PFTauCollection > PFTauRefProd
references to PFTau collection
Definition: PFTauFwd.h:15
edm::ParameterSetDescription
Definition: ParameterSetDescription.h:52
DeepTauId::debug_level
const int debug_level
Definition: DeepTauId.cc:2804
deep_tau::DeepTauBase::requiredBasicDiscriminatorsdR03_
static const std::vector< BasicDiscriminator > requiredBasicDiscriminatorsdR03_
Definition: DeepTauBase.h:139
DeepTauId::getValueNorm
static float getValueNorm(T value, float mean, float sigma, float n_sigmas_max=5)
Definition: DeepTauId.cc:1274
getRunAppsInfo.grid
grid
Definition: getRunAppsInfo.py:92
cms::cuda::assert
assert(be >=bs)
deep_tau::DeepTauBase::vtxToken_
edm::EDGetTokenT< reco::VertexCollection > vtxToken_
Definition: DeepTauBase.h:131
DeepTauId::initializeGlobalCache
static std::unique_ptr< deep_tau::DeepTauCache > initializeGlobalCache(const edm::ParameterSet &cfg)
Definition: DeepTauId.cc:1249
deep_tau
Definition: DeepTauBase.h:36
reco::PFTau
Definition: PFTau.h:36
DeepTauId::createEgammaBlockInputs
void createEgammaBlockInputs(unsigned idx, const TauCastType &tau, const size_t tau_index, const edm::RefToBase< reco::BaseTau > tau_ref, const reco::Vertex &pv, double rho, const std::vector< pat::Electron > *electrons, const edm::View< reco::Candidate > &pfCands, const Cell &cell_map, TauFunc tau_funcs, bool is_inner)
Definition: DeepTauId.cc:1934
DeepTauId::muons_token_
edm::EDGetTokenT< std::vector< pat::Muon > > muons_token_
Definition: DeepTauId.cc:2796
DDAxes::x
deep_tau::DeepTauBase::LorentzVectorXYZ
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzE4D< double > > LorentzVectorXYZ
Definition: DeepTauBase.h:75
reco::LeafCandidate::pt
double pt() const final
transverse momentum
Definition: LeafCandidate.h:146
reco
fixed size matrix
Definition: AlignmentAlgorithmBase.h:45
pat::Muon
Analysis-level muon class.
Definition: Muon.h:51
hltPixelTracks_cff.chi2
chi2
Definition: hltPixelTracks_cff.py:25
HLT_FULL_cff.dPhi
dPhi
Definition: HLT_FULL_cff.py:13702
DeepTauId::disable_dxy_pca_
const bool disable_dxy_pca_
Definition: DeepTauId.cc:2805
spr::find
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
edm::Handle< TauCollection >
edm::ParameterSetDescription::addOptional
ParameterDescriptionBase * addOptional(U const &iLabel, T const &value)
Definition: ParameterSetDescription.h:105
DeepTauId::zeroOutputTensor_
std::array< std::unique_ptr< tensorflow::Tensor >, 2 > zeroOutputTensor_
Definition: DeepTauId.cc:2809
DeepTauId::basicDiscrIndexMap_
std::map< BasicDiscriminator, size_t > basicDiscrIndexMap_
Definition: DeepTauId.cc:2818
deep_tau::NumberOfOutputs
constexpr int NumberOfOutputs
Definition: DeepTauId.cc:18
edm::LogWarning
Log< level::Warning, false > LogWarning
Definition: MessageLogger.h:122
cosmictrackSelector_cfi.min_pt
min_pt
Definition: cosmictrackSelector_cfi.py:18
GetRecoTauVFromDQM_MC_cff.Output
Output
Definition: GetRecoTauVFromDQM_MC_cff.py:12
Muon
Definition: Muon.py:1
reco::Muon
Definition: Muon.h:27
heavyIonCSV_trainingSettings.idx
idx
Definition: heavyIonCSV_trainingSettings.py:5
DeepTauId::default_value
static constexpr float default_value
Definition: DeepTauId.cc:1102
ndof
Definition: HIMultiTrackSelector.h:49
DeepTauId::json_file_
std::ofstream * json_file_
Definition: DeepTauId.cc:2812
deep_tau::DeepTauBase
Definition: DeepTauBase.h:66
deep_tau::DeepTauBase::DeepTauBase
DeepTauBase(const edm::ParameterSet &cfg, const OutputCollection &outputs, const DeepTauCache *cache)
Definition: DeepTauBase.cc:86
MakerMacros.h
reco::tau::pt_weighted_dphi_strip
float pt_weighted_dphi_strip(const reco::PFTau &tau, int dm)
Definition: PFRecoTauClusterVariables.h:44
DEFINE_FWK_MODULE
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
spr::deltaEta
static const double deltaEta
Definition: CaloConstants.h:8
edm::ConfigurationDescriptions::add
void add(std::string const &label, ParameterSetDescription const &psetDescription)
Definition: ConfigurationDescriptions.cc:57
DeepTauId::processIsolationPFComponents
static void processIsolationPFComponents(const TauCastType &tau, const CandidateCollection &candidates, LorentzVectorXYZ &p4, float &pt, float &d_eta, float &d_phi, float &m, float &n)
Definition: DeepTauId.cc:2714
reco::BaseTau
Definition: BaseTau.h:18
SiPixelRawToDigiRegional_cfi.deltaPhi
deltaPhi
Definition: SiPixelRawToDigiRegional_cfi.py:9
deep_tau::DeepTauBase::requiredBasicDiscriminators_
static const std::vector< BasicDiscriminator > requiredBasicDiscriminators_
Definition: DeepTauBase.h:138
reco::tau::countMatches
void countMatches(const reco::Muon &muon, std::vector< int > &numMatchesDT, std::vector< int > &numMatchesCSC, std::vector< int > &numMatchesRPC)
Definition: RecoTauMuonTools.cc:46
vars
vars
Definition: DeepTauId.cc:163
HLT_FULL_cff.muon
muon
Definition: HLT_FULL_cff.py:11710
PVValHelper::eta
Definition: PVValidationHelpers.h:69
visualization-live-secondInstance_cfg.m
m
Definition: visualization-live-secondInstance_cfg.py:72
mps_fire.end
end
Definition: mps_fire.py:242
DeepTauId::basicTauDiscriminators_inputToken_
edm::EDGetTokenT< reco::TauDiscriminatorContainer > basicTauDiscriminators_inputToken_
Definition: DeepTauId.cc:2798
dnn_inputs_2017_v2::HadronBlockInputs
Definition: DeepTauId.cc:377
deep_tau::DeepTauBase::is_online_
const bool is_online_
Definition: DeepTauBase.h:133
submitPVResolutionJobs.count
count
Definition: submitPVResolutionJobs.py:352
trackingPlots.other
other
Definition: trackingPlots.py:1467
DeepTauId::checkInputs
void checkInputs(const tensorflow::Tensor &inputs, const std::string &block_name, int n_inputs, const CellGrid *grid=nullptr) const
Definition: DeepTauId.cc:1305
HCALHighEnergyHPDFilter_cfi.energy
energy
Definition: HCALHighEnergyHPDFilter_cfi.py:5
DeepTauId::getValueLinear
static float getValueLinear(T value, float min_value, float max_value, bool positive)
Definition: DeepTauId.cc:1264
MuonSubdetId::DT
static constexpr int DT
Definition: MuonSubdetId.h:11
DeepTauId::findMatchedElectron
static const pat::Electron * findMatchedElectron(const TauCastType &tau, const std::vector< pat::Electron > *electrons, double deltaR)
Definition: DeepTauId.cc:2781
DeepTauId::createHadronsBlockInputs
void createHadronsBlockInputs(unsigned idx, const TauCastType &tau, const size_t tau_index, const edm::RefToBase< reco::BaseTau > tau_ref, const reco::Vertex &pv, double rho, const edm::View< reco::Candidate > &pfCands, const Cell &cell_map, TauFunc tau_funcs, bool is_inner)
Definition: DeepTauId.cc:2321
dqmdumpme.k
k
Definition: dqmdumpme.py:60
hcaldqm::quantity::min_value
const std::map< ValueQuantityType, double > min_value
Definition: ValueQuantity.h:130
DeepTauId::file_counter_
int file_counter_
Definition: DeepTauId.cc:2814
CommPDSkim_cfg.maxDeltaEta
maxDeltaEta
Definition: CommPDSkim_cfg.py:75
DeepTauId::convTensor_
std::array< std::unique_ptr< tensorflow::Tensor >, 2 > convTensor_
Definition: DeepTauId.cc:2809
DeepTauId::calculateElectronClusterVarsV2
static bool calculateElectronClusterVarsV2(const pat::Electron &ele, float &cc_ele_energy, float &cc_gamma_energy, int &cc_n_gamma)
Definition: DeepTauId.cc:1282
taus_cff.decayMode
decayMode
Definition: taus_cff.py:58
utilities.cache
def cache(function)
Definition: utilities.py:3
getGTfromDQMFile.obj
obj
Definition: getGTfromDQMFile.py:32
PbPb_ZMuSkimMuonDPG_cff.deltaR
deltaR
Definition: PbPb_ZMuSkimMuonDPG_cff.py:63
DeepTauId::disable_hcalFraction_workaround_
const bool disable_hcalFraction_workaround_
Definition: DeepTauId.cc:2806
runTauDisplay.tau_phi
tau_phi
Definition: runTauDisplay.py:127
edm::ConfigurationDescriptions
Definition: ConfigurationDescriptions.h:28
DDAxes::rho
edm::AssociationVector::value
const CVal::value_type value(size_type i) const
Definition: AssociationVector.h:102
AlCaHLTBitMon_QueryRunRegistry.string
string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
TrackingRecHit::bad
Definition: TrackingRecHit.h:49
DeepTauId::basicTauDiscriminatorsdR03_inputToken_
edm::EDGetTokenT< reco::TauDiscriminatorContainer > basicTauDiscriminatorsdR03_inputToken_
Definition: DeepTauId.cc:2799
edm::AssociationVector
Definition: AssociationVector.h:67
deep_tau::DeepTauBase::outputs_
OutputCollection outputs_
Definition: DeepTauBase.h:134
edm::View
Definition: CaloClusterFwd.h:14
edm::View::at
const_reference at(size_type pos) const
DeepTauId::calculateGottfriedJacksonAngleDifference
static bool calculateGottfriedJacksonAngleDifference(const TauCastType &tau, const size_t tau_index, double &gj_diff, TauFunc tau_funcs)
Definition: DeepTauId.cc:2744
DeepTauId::pfTauTransverseImpactParameters_token_
edm::EDGetTokenT< edm::AssociationVector< reco::PFTauRefProd, std::vector< reco::PFTauTransverseImpactParameterRef > > > pfTauTransverseImpactParameters_token_
Definition: DeepTauId.cc:2801
candFunc
Definition: DeepTauId.cc:611
DeepTauId::isAbove
static bool isAbove(double value, double min)
Definition: DeepTauId.cc:1280
DeepTauId::output_layer_
std::string output_layer_
Definition: DeepTauId.cc:2802
edm::ParameterSet
Definition: ParameterSet.h:47
Cell
Definition: LogEleMapdb.h:8
reco::tau::lead_track_chi2
float lead_track_chi2(const reco::PFTau &tau)
return chi2 of the leading track ==> deprecated? <==
Definition: PFRecoTauClusterVariables.cc:58
SiStripPI::max
Definition: SiStripPayloadInspectorHelper.h:169
pat::PackedCandidate
Definition: PackedCandidate.h:22
reco::deltaR2
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:16
dnn_inputs_2017_v2::EgammaBlockInputs
Definition: DeepTauId.cc:215
deep_tau::DeepTauBase::stringFromDiscriminator_
static const std::map< BasicDiscriminator, std::string > stringFromDiscriminator_
Definition: DeepTauBase.h:137
DeepTauId
Definition: DeepTauId.cc:1100
match
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
reco::tau::n_photons_total
unsigned int n_photons_total(const reco::PFTau &tau)
return total number of pf photon candidates with pT>500 MeV, which are associated to signal
Definition: PFRecoTauClusterVariables.cc:157
cand
Definition: decayParser.h:32
electrons_cff.ip3d
ip3d
Definition: electrons_cff.py:384
runTauDisplay.tau_mass
tau_mass
Definition: runTauDisplay.py:128
createfilelist.int
int
Definition: createfilelist.py:10
MetAnalyzer.pv
def pv(vc)
Definition: MetAnalyzer.py:7
dumpRecoGeometry_cfg.Muon
Muon
Definition: dumpRecoGeometry_cfg.py:190
DeepTauId::disable_CellIndex_workaround_
const bool disable_CellIndex_workaround_
Definition: DeepTauId.cc:2807
p4
double p4[4]
Definition: TauolaWrapper.h:92
value
Definition: value.py:1
pat::Muon::PV2D
Definition: Muon.h:237
M_PI
#define M_PI
Definition: BXVectorInputProducer.cc:49
PixelMapPlotter.inputs
inputs
Definition: PixelMapPlotter.py:490
trackerHitRTTI::vector
Definition: trackerHitRTTI.h:21
DeepTauId::GetOutputs
static const OutputCollection & GetOutputs()
Definition: DeepTauId.cc:1104
pat
Definition: HeavyIon.h:7
DeepTauId::globalEndJob
static void globalEndJob(const deep_tau::DeepTauCache *cache_)
Definition: DeepTauId.cc:1253
beam_dqm_sourceclient-live_cfg.minPt
minPt
Definition: beam_dqm_sourceclient-live_cfg.py:323
DeepTauId::eGammaTensor_
std::array< std::unique_ptr< tensorflow::Tensor >, 2 > eGammaTensor_
Definition: DeepTauId.cc:2809
get
#define get
DeepTauId::tauBlockTensor_
std::unique_ptr< tensorflow::Tensor > tauBlockTensor_
Definition: DeepTauId.cc:2808
TrackingRecHit::valid
Definition: TrackingRecHit.h:46
reco::HitPattern::TRACK_HITS
Definition: HitPattern.h:155
looper.cfg
cfg
Definition: looper.py:297
reco::Candidate
Definition: Candidate.h:27
DeepTauId::createMuonBlockInputs
void createMuonBlockInputs(unsigned idx, const TauCastType &tau, const size_t tau_index, const edm::RefToBase< reco::BaseTau > tau_ref, const reco::Vertex &pv, double rho, const std::vector< pat::Muon > *muons, const edm::View< reco::Candidate > &pfCands, const Cell &cell_map, TauFunc tau_funcs, bool is_inner)
Definition: DeepTauId.cc:2170
TopDecayID::tauID
static const int tauID
Definition: TopGenEvent.h:20
nanoDQM_cff.Electron
Electron
Definition: nanoDQM_cff.py:62
DDAxes::phi
edm::ValueMap::get
const_reference_type get(ProductID id, size_t idx) const
Definition: ValueMap.h:144
DeepTauId::is_first_block_
bool is_first_block_
Definition: DeepTauId.cc:2813
DeepTauId::getPredictions
tensorflow::Tensor getPredictions(edm::Event &event, edm::Handle< TauCollection > taus) override
Definition: DeepTauId.cc:1422
DeepTauId::basicDiscrdR03IndexMap_
std::map< BasicDiscriminator, size_t > basicDiscrdR03IndexMap_
Definition: DeepTauId.cc:2819
submitPVResolutionJobs.desc
string desc
Definition: submitPVResolutionJobs.py:251
std
Definition: JetResolutionObject.h:76
hcaldqm::quantity::max_value
const std::map< ValueQuantityType, double > max_value
Definition: ValueQuantity.h:190
PVValHelper::dxy
Definition: PVValidationHelpers.h:47
pat::Electron::superCluster
reco::SuperClusterRef superCluster() const override
override the reco::GsfElectron::superCluster method, to access the internal storage of the superclust...
isFinite.h
pwdgSkimBPark_cfi.electrons
electrons
Definition: pwdgSkimBPark_cfi.py:6
DeepTauId::muonTensor_
std::array< std::unique_ptr< tensorflow::Tensor >, 2 > muonTensor_
Definition: DeepTauId.cc:2809
DeepTauId::electrons_token_
edm::EDGetTokenT< std::vector< pat::Electron > > electrons_token_
Definition: DeepTauId.cc:2795
PVValHelper::dz
Definition: PVValidationHelpers.h:50
HLT_FULL_cff.dEta
dEta
Definition: HLT_FULL_cff.py:13701
MuonSubdetId::RPC
static constexpr int RPC
Definition: MuonSubdetId.h:13
deep_tau::DeepTauBase::recoPrediscriminants_
std::vector< TauDiscInfo< reco::PFTauDiscriminator > > recoPrediscriminants_
Definition: DeepTauBase.h:113
T
long double T
Definition: Basic3DVectorLD.h:48
CellObjectType
CellObjectType
Definition: DeepTauId.cc:963
HLT_FULL_cff.candidates
candidates
Definition: HLT_FULL_cff.py:54985
edm::ValueMap
Definition: ValueMap.h:107
runTauDisplay.tau_pt
tau_pt
Definition: runTauDisplay.py:125
Exception
Definition: hltDiff.cc:246
DeepTauId::createTauBlockInputs
void createTauBlockInputs(const TauCastType &tau, const size_t &tau_index, const edm::RefToBase< reco::BaseTau > tau_ref, const reco::Vertex &pv, double rho, TauFunc tau_funcs)
Definition: DeepTauId.cc:1828
postprocess-scan-build.cells
cells
Definition: postprocess-scan-build.py:13
reco::HitPattern::MISSING_INNER_HITS
Definition: HitPattern.h:155
DeepTauId::getPredictionsV2
void getPredictionsV2(TauCollection::const_reference &tau, const size_t tau_index, const edm::RefToBase< reco::BaseTau > tau_ref, const std::vector< pat::Electron > *electrons, const std::vector< pat::Muon > *muons, const edm::View< reco::Candidate > &pfCands, const reco::Vertex &pv, double rho, std::vector< tensorflow::Tensor > &pred_vector, TauFunc tau_funcs)
Definition: DeepTauId.cc:1553
reco::tau::pt_weighted_dr_signal
float pt_weighted_dr_signal(const reco::PFTau &tau, int dm)
Definition: PFRecoTauClusterVariables.h:32
DeepTauId::saveInputs
void saveInputs(const tensorflow::Tensor &inputs, const std::string &block_name, int n_inputs, const CellGrid *grid=nullptr)
Definition: DeepTauId.cc:1361
tensorflow::run
void run(Session *session, const NamedTensorList &inputs, const std::vector< std::string > &outputNames, std::vector< Tensor > *outputs, const thread::ThreadPoolOptions &threadPoolOptions)
Definition: TensorFlow.cc:211
edm::parameterSet
ParameterSet const & parameterSet(Provenance const &provenance, ProcessHistory const &history)
Definition: Provenance.cc:11
DeepTauId::getPredictionsV1
void getPredictionsV1(TauCollection::const_reference &tau, const size_t tau_index, const edm::RefToBase< reco::BaseTau > tau_ref, const std::vector< pat::Electron > *electrons, const std::vector< pat::Muon > *muons, std::vector< tensorflow::Tensor > &pred_vector, TauFunc tau_funcs)
Definition: DeepTauId.cc:1540
EgHLTOffHistBins_cfi.mass
mass
Definition: EgHLTOffHistBins_cfi.py:34
CommPDSkim_cfg.maxDeltaPhi
maxDeltaPhi
Definition: CommPDSkim_cfg.py:74
DeepTauId::input_layer_
std::string input_layer_
Definition: DeepTauId.cc:2802
Skims_PA_cff.name
name
Definition: Skims_PA_cff.py:17
reco::tau::countHits
void countHits(const reco::Muon &muon, std::vector< int > &numHitsDT, std::vector< int > &numHitsCSC, std::vector< int > &numHitsRPC)
Definition: RecoTauMuonTools.cc:7
reco::tau::pt_weighted_dr_iso
float pt_weighted_dr_iso(const reco::PFTau &tau, int dm)
Definition: PFRecoTauClusterVariables.h:52
reco::deltaR
constexpr auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:30
edm::ParameterSet::getParameter
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
edm::RefToBase
Definition: AssociativeIterator.h:54
DeepTauId::fillGrids
void fillGrids(const TauCastType &tau, const Collection &objects, CellGrid &inner_grid, CellGrid &outer_grid)
Definition: DeepTauId.cc:1675
DeepTauId::save_inputs_
const bool save_inputs_
Definition: DeepTauId.cc:2811
AlignmentPI::index
index
Definition: AlignmentPayloadInspectorHelper.h:46
reco::PFCandidate
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:41
deep_tau::DeepTauBase::andPrediscriminants_
uint8_t andPrediscriminants_
Definition: DeepTauBase.h:111
funct::pow
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
cms::Exception
Definition: Exception.h:70
pat::Electron
Analysis-level electron class.
Definition: Electron.h:51
deep_tau::DeepTauCache
Definition: DeepTauBase.h:48
funct::abs
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
DeepTauId::createConvFeatures
void createConvFeatures(const TauCastType &tau, const size_t tau_index, const edm::RefToBase< reco::BaseTau > tau_ref, const reco::Vertex &pv, double rho, const std::vector< pat::Electron > *electrons, const std::vector< pat::Muon > *muons, const edm::View< reco::Candidate > &pfCands, const CellGrid &grid, TauFunc tau_funcs, bool is_inner)
Definition: DeepTauId.cc:1736
operator<
bool operator<(DTCELinkId const &lhs, DTCELinkId const &rhs)
Definition: DTCELinkId.h:70
HGC3DClusterGenMatchSelector_cfi.dR
dR
Definition: HGC3DClusterGenMatchSelector_cfi.py:7
operator[]
T operator[](int i) const
Definition: extBasic3DVector.h:222
DeepTauId::calculateGottfriedJacksonAngleDifference
static float calculateGottfriedJacksonAngleDifference(const TauCastType &tau, const size_t tau_index, TauFunc tau_funcs)
Definition: DeepTauId.cc:2766
DeepTauId::fillDescriptions
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
Definition: DeepTauId.cc:1146
dqmiolumiharvest.j
j
Definition: dqmiolumiharvest.py:66
DeepTauId::createInputsV1
tensorflow::Tensor createInputsV1(const TauCastType &tau, const size_t tau_index, const edm::RefToBase< reco::BaseTau > tau_ref, const std::vector< pat::Electron > *electrons, const std::vector< pat::Muon > *muons, TauFunc tau_funcs) const
Definition: DeepTauId.cc:2446
event
Definition: event.py:1
reco::TauDiscriminatorContainer
edm::ValueMap< SingleTauDiscriminatorContainer > TauDiscriminatorContainer
Definition: TauDiscriminatorContainer.h:17
edm::Event
Definition: Event.h:73
dnn_inputs_2017_v2::TauBlockInputs
Definition: DeepTauId.cc:162
edm::InputTag
Definition: InputTag.h:15
DeepTauId::getPartialPredictions
tensorflow::Tensor getPartialPredictions(bool is_inner)
Definition: DeepTauId.cc:1711
label
const char * label
Definition: PFTauDecayModeTools.cc:11
deep_tau::DeepTauCache::getGraph
const tensorflow::GraphDef & getGraph(const std::string &name="") const
Definition: DeepTauBase.h:58
reco::Vertex
Definition: Vertex.h:35
hit
Definition: SiStripHitEffFromCalibTree.cc:88
DeepTauId::discrIndicesMapped_
bool discrIndicesMapped_
Definition: DeepTauId.cc:2817
HGVHistoProducerAlgoBlock_cfi.maxX
maxX
Definition: HGVHistoProducerAlgoBlock_cfi.py:154
findQualityFiles.size
size
Write out results.
Definition: findQualityFiles.py:443
pwdgSkimBPark_cfi.vertices
vertices
Definition: pwdgSkimBPark_cfi.py:7
DeepTauId::processSignalPFComponents
static void processSignalPFComponents(const TauCastType &tau, const CandidateCollection &candidates, LorentzVectorXYZ &p4_inner, LorentzVectorXYZ &p4_outer, float &pt_inner, float &dEta_inner, float &dPhi_inner, float &m_inner, float &pt_outer, float &dEta_outer, float &dPhi_outer, float &m_outer, float &n_inner, float &n_outer)
Definition: DeepTauId.cc:2670