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