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  */
8 
11 
12 namespace deep_tau {
14 }
15 
16 namespace {
17 
18 struct dnn_inputs_2017v1 {
19  enum vars {
22  dxy, dxy_sig, dz, ip3d, ip3d_sig,
23  hasSecondaryVertex, flightLength_r, flightLength_dEta, flightLength_dPhi,
24  flightLength_sig, leadChargedHadrCand_pt, leadChargedHadrCand_dEta,
25  leadChargedHadrCand_dPhi, leadChargedHadrCand_mass, pt_weighted_deta_strip,
27  leadingTrackNormChi2, e_ratio, gj_angle_diff, n_photons, emFraction,
28  has_gsf_track, inside_ecal_crack,
29  gsf_ele_matched, gsf_ele_pt, gsf_ele_dEta, gsf_ele_dPhi, gsf_ele_mass, gsf_ele_Ee,
30  gsf_ele_Egamma, gsf_ele_Pin, gsf_ele_Pout, gsf_ele_EtotOverPin, gsf_ele_Eecal,
31  gsf_ele_dEta_SeedClusterTrackAtCalo, gsf_ele_dPhi_SeedClusterTrackAtCalo, gsf_ele_mvaIn_sigmaEtaEta,
32  gsf_ele_mvaIn_hadEnergy,
33  gsf_ele_mvaIn_deltaEta, gsf_ele_Chi2NormGSF, gsf_ele_GSFNumHits, gsf_ele_GSFTrackResol,
34  gsf_ele_GSFTracklnPt, gsf_ele_Chi2NormKF, gsf_ele_KFNumHits,
35  leadChargedCand_etaAtEcalEntrance, leadChargedCand_pt, leadChargedHadrCand_HoP,
36  leadChargedHadrCand_EoP, tau_visMass_innerSigCone,
37  n_matched_muons, muon_pt, muon_dEta, muon_dPhi,
38  muon_n_matches_DT_1, muon_n_matches_DT_2, muon_n_matches_DT_3, muon_n_matches_DT_4,
39  muon_n_matches_CSC_1, muon_n_matches_CSC_2, muon_n_matches_CSC_3, muon_n_matches_CSC_4,
40  muon_n_hits_DT_2, muon_n_hits_DT_3, muon_n_hits_DT_4,
41  muon_n_hits_CSC_2, muon_n_hits_CSC_3, muon_n_hits_CSC_4,
42  muon_n_hits_RPC_2, muon_n_hits_RPC_3, muon_n_hits_RPC_4,
43  muon_n_stations_with_matches_03, muon_n_stations_with_hits_23,
44  signalChargedHadrCands_sum_innerSigCone_pt, signalChargedHadrCands_sum_innerSigCone_dEta,
45  signalChargedHadrCands_sum_innerSigCone_dPhi, signalChargedHadrCands_sum_innerSigCone_mass,
46  signalChargedHadrCands_sum_outerSigCone_pt, signalChargedHadrCands_sum_outerSigCone_dEta,
47  signalChargedHadrCands_sum_outerSigCone_dPhi, signalChargedHadrCands_sum_outerSigCone_mass,
48  signalChargedHadrCands_nTotal_innerSigCone, signalChargedHadrCands_nTotal_outerSigCone,
49  signalNeutrHadrCands_sum_innerSigCone_pt, signalNeutrHadrCands_sum_innerSigCone_dEta,
50  signalNeutrHadrCands_sum_innerSigCone_dPhi, signalNeutrHadrCands_sum_innerSigCone_mass,
51  signalNeutrHadrCands_sum_outerSigCone_pt, signalNeutrHadrCands_sum_outerSigCone_dEta,
52  signalNeutrHadrCands_sum_outerSigCone_dPhi, signalNeutrHadrCands_sum_outerSigCone_mass,
53  signalNeutrHadrCands_nTotal_innerSigCone, signalNeutrHadrCands_nTotal_outerSigCone,
54  signalGammaCands_sum_innerSigCone_pt, signalGammaCands_sum_innerSigCone_dEta,
55  signalGammaCands_sum_innerSigCone_dPhi, signalGammaCands_sum_innerSigCone_mass,
56  signalGammaCands_sum_outerSigCone_pt, signalGammaCands_sum_outerSigCone_dEta,
57  signalGammaCands_sum_outerSigCone_dPhi, signalGammaCands_sum_outerSigCone_mass,
58  signalGammaCands_nTotal_innerSigCone, signalGammaCands_nTotal_outerSigCone,
59  isolationChargedHadrCands_sum_pt, isolationChargedHadrCands_sum_dEta,
60  isolationChargedHadrCands_sum_dPhi, isolationChargedHadrCands_sum_mass,
61  isolationChargedHadrCands_nTotal,
62  isolationNeutrHadrCands_sum_pt, isolationNeutrHadrCands_sum_dEta,
63  isolationNeutrHadrCands_sum_dPhi, isolationNeutrHadrCands_sum_mass,
64  isolationNeutrHadrCands_nTotal,
65  isolationGammaCands_sum_pt, isolationGammaCands_sum_dEta,
66  isolationGammaCands_sum_dPhi, isolationGammaCands_sum_mass,
67  isolationGammaCands_nTotal,
68  NumberOfInputs
69  };
70 };
71 
72 namespace dnn_inputs_2017_v2 {
73  constexpr int number_of_inner_cell = 11;
74  constexpr int number_of_outer_cell = 21;
75  constexpr int number_of_conv_features = 64;
76  namespace TauBlockInputs {
77  enum vars {
78  rho = 0, tau_pt, tau_eta, tau_phi, tau_mass, tau_E_over_pt, tau_charge, tau_n_charged_prongs,
79  tau_n_neutral_prongs, chargedIsoPtSum, chargedIsoPtSumdR03_over_dR05, footprintCorrection,
80  neutralIsoPtSum, neutralIsoPtSumWeight_over_neutralIsoPtSum, neutralIsoPtSumWeightdR03_over_neutralIsoPtSum,
81  neutralIsoPtSumdR03_over_dR05, photonPtSumOutsideSignalCone, puCorrPtSum,
82  tau_dxy_pca_x, tau_dxy_pca_y, tau_dxy_pca_z, tau_dxy_valid, tau_dxy, tau_dxy_sig,
83  tau_ip3d_valid, tau_ip3d, tau_ip3d_sig, tau_dz, tau_dz_sig_valid, tau_dz_sig,
84  tau_flightLength_x, tau_flightLength_y, tau_flightLength_z, tau_flightLength_sig,
85  tau_pt_weighted_deta_strip, tau_pt_weighted_dphi_strip, tau_pt_weighted_dr_signal,
86  tau_pt_weighted_dr_iso, tau_leadingTrackNormChi2, tau_e_ratio_valid, tau_e_ratio,
87  tau_gj_angle_diff_valid, tau_gj_angle_diff, tau_n_photons, tau_emFraction,
88  tau_inside_ecal_crack, leadChargedCand_etaAtEcalEntrance_minus_tau_eta, NumberOfInputs
89  };
90  }
91 
92  namespace EgammaBlockInputs {
93  enum vars {
94  rho = 0, tau_pt, tau_eta, tau_inside_ecal_crack, pfCand_ele_valid, pfCand_ele_rel_pt,
95  pfCand_ele_deta, pfCand_ele_dphi, pfCand_ele_pvAssociationQuality, pfCand_ele_puppiWeight,
96  pfCand_ele_charge, pfCand_ele_lostInnerHits, pfCand_ele_numberOfPixelHits, pfCand_ele_vertex_dx,
97  pfCand_ele_vertex_dy, pfCand_ele_vertex_dz, pfCand_ele_vertex_dx_tauFL, pfCand_ele_vertex_dy_tauFL,
98  pfCand_ele_vertex_dz_tauFL, pfCand_ele_hasTrackDetails, pfCand_ele_dxy, pfCand_ele_dxy_sig,
99  pfCand_ele_dz, pfCand_ele_dz_sig, pfCand_ele_track_chi2_ndof, pfCand_ele_track_ndof,
100  ele_valid, ele_rel_pt, ele_deta, ele_dphi, ele_cc_valid, ele_cc_ele_rel_energy, ele_cc_gamma_rel_energy,
101  ele_cc_n_gamma, ele_rel_trackMomentumAtVtx, ele_rel_trackMomentumAtCalo, ele_rel_trackMomentumOut,
102  ele_rel_trackMomentumAtEleClus, ele_rel_trackMomentumAtVtxWithConstraint,
103  ele_rel_ecalEnergy, ele_ecalEnergy_sig, ele_eSuperClusterOverP,
104  ele_eSeedClusterOverP, ele_eSeedClusterOverPout, ele_eEleClusterOverPout,
105  ele_deltaEtaSuperClusterTrackAtVtx, ele_deltaEtaSeedClusterTrackAtCalo,
106  ele_deltaEtaEleClusterTrackAtCalo, ele_deltaPhiEleClusterTrackAtCalo,
107  ele_deltaPhiSuperClusterTrackAtVtx, ele_deltaPhiSeedClusterTrackAtCalo,
108  ele_mvaInput_earlyBrem, ele_mvaInput_lateBrem, ele_mvaInput_sigmaEtaEta,
109  ele_mvaInput_hadEnergy, ele_mvaInput_deltaEta, ele_gsfTrack_normalizedChi2,
110  ele_gsfTrack_numberOfValidHits, ele_rel_gsfTrack_pt, ele_gsfTrack_pt_sig,
111  ele_has_closestCtfTrack, ele_closestCtfTrack_normalizedChi2, ele_closestCtfTrack_numberOfValidHits,
112  pfCand_gamma_valid, pfCand_gamma_rel_pt, pfCand_gamma_deta, pfCand_gamma_dphi,
113  pfCand_gamma_pvAssociationQuality, pfCand_gamma_fromPV, pfCand_gamma_puppiWeight,
114  pfCand_gamma_puppiWeightNoLep, pfCand_gamma_lostInnerHits, pfCand_gamma_numberOfPixelHits,
115  pfCand_gamma_vertex_dx, pfCand_gamma_vertex_dy, pfCand_gamma_vertex_dz, pfCand_gamma_vertex_dx_tauFL,
116  pfCand_gamma_vertex_dy_tauFL, pfCand_gamma_vertex_dz_tauFL, pfCand_gamma_hasTrackDetails,
117  pfCand_gamma_dxy, pfCand_gamma_dxy_sig, pfCand_gamma_dz, pfCand_gamma_dz_sig,
118  pfCand_gamma_track_chi2_ndof, pfCand_gamma_track_ndof,
119  NumberOfInputs
120  };
121  }
122 
123  namespace MuonBlockInputs {
124  enum vars {
125  rho = 0, tau_pt, tau_eta, tau_inside_ecal_crack, pfCand_muon_valid, pfCand_muon_rel_pt,
126  pfCand_muon_deta, pfCand_muon_dphi, pfCand_muon_pvAssociationQuality, pfCand_muon_fromPV,
127  pfCand_muon_puppiWeight, pfCand_muon_charge, pfCand_muon_lostInnerHits, pfCand_muon_numberOfPixelHits,
128  pfCand_muon_vertex_dx, pfCand_muon_vertex_dy, pfCand_muon_vertex_dz, pfCand_muon_vertex_dx_tauFL,
129  pfCand_muon_vertex_dy_tauFL, pfCand_muon_vertex_dz_tauFL,pfCand_muon_hasTrackDetails, pfCand_muon_dxy,
130  pfCand_muon_dxy_sig, pfCand_muon_dz, pfCand_muon_dz_sig, pfCand_muon_track_chi2_ndof,
131  pfCand_muon_track_ndof, muon_valid, muon_rel_pt, muon_deta, muon_dphi, muon_dxy, muon_dxy_sig,
132  muon_normalizedChi2_valid, muon_normalizedChi2, muon_numberOfValidHits, muon_segmentCompatibility,
133  muon_caloCompatibility, muon_pfEcalEnergy_valid, muon_rel_pfEcalEnergy, muon_n_matches_DT_1,
134  muon_n_matches_DT_2, muon_n_matches_DT_3, muon_n_matches_DT_4, muon_n_matches_CSC_1,
135  muon_n_matches_CSC_2, muon_n_matches_CSC_3, muon_n_matches_CSC_4, muon_n_matches_RPC_1,
136  muon_n_matches_RPC_2, muon_n_matches_RPC_3, muon_n_matches_RPC_4, muon_n_hits_DT_1, muon_n_hits_DT_2,
137  muon_n_hits_DT_3, muon_n_hits_DT_4, muon_n_hits_CSC_1, muon_n_hits_CSC_2, muon_n_hits_CSC_3,
138  muon_n_hits_CSC_4, muon_n_hits_RPC_1, muon_n_hits_RPC_2, muon_n_hits_RPC_3, muon_n_hits_RPC_4,
139  NumberOfInputs
140  };
141  }
142 
143  namespace HadronBlockInputs {
144  enum vars {
145  rho = 0, tau_pt, tau_eta, tau_inside_ecal_crack, pfCand_chHad_valid,
146  pfCand_chHad_rel_pt, pfCand_chHad_deta, pfCand_chHad_dphi, pfCand_chHad_leadChargedHadrCand,
147  pfCand_chHad_pvAssociationQuality, pfCand_chHad_fromPV, pfCand_chHad_puppiWeight,
148  pfCand_chHad_puppiWeightNoLep, pfCand_chHad_charge, pfCand_chHad_lostInnerHits,
149  pfCand_chHad_numberOfPixelHits, pfCand_chHad_vertex_dx, pfCand_chHad_vertex_dy,
150  pfCand_chHad_vertex_dz, pfCand_chHad_vertex_dx_tauFL, pfCand_chHad_vertex_dy_tauFL,
151  pfCand_chHad_vertex_dz_tauFL, pfCand_chHad_hasTrackDetails, pfCand_chHad_dxy,
152  pfCand_chHad_dxy_sig, pfCand_chHad_dz, pfCand_chHad_dz_sig, pfCand_chHad_track_chi2_ndof,
153  pfCand_chHad_track_ndof, pfCand_chHad_hcalFraction, pfCand_chHad_rawCaloFraction,
154  pfCand_nHad_valid, pfCand_nHad_rel_pt, pfCand_nHad_deta, pfCand_nHad_dphi,
155  pfCand_nHad_puppiWeight, pfCand_nHad_puppiWeightNoLep, pfCand_nHad_hcalFraction, NumberOfInputs
156  };
157  }
158 }
159 
160 template<typename LVector1, typename LVector2>
161 float dEta(const LVector1& p4, const LVector2& tau_p4)
162 {
163  return static_cast<float>(p4.eta() - tau_p4.eta());
164 }
165 
166 template<typename LVector1, typename LVector2>
167 float dPhi(const LVector1& p4_1, const LVector2& p4_2)
168 {
169  return static_cast<float>(reco::deltaPhi(p4_2.phi(), p4_1.phi()));
170 }
171 
172 struct MuonHitMatchV1 {
173  static constexpr int n_muon_stations = 4;
174 
175  std::map<int, std::vector<UInt_t>> n_matches, n_hits;
176  unsigned n_muons{0};
177  const pat::Muon* best_matched_muon{nullptr};
178  double deltaR2_best_match{-1};
179 
180  MuonHitMatchV1()
181  {
182  n_matches[MuonSubdetId::DT].assign(n_muon_stations, 0);
183  n_matches[MuonSubdetId::CSC].assign(n_muon_stations, 0);
184  n_matches[MuonSubdetId::RPC].assign(n_muon_stations, 0);
185  n_hits[MuonSubdetId::DT].assign(n_muon_stations, 0);
186  n_hits[MuonSubdetId::CSC].assign(n_muon_stations, 0);
187  n_hits[MuonSubdetId::RPC].assign(n_muon_stations, 0);
188  }
189 
190  void addMatchedMuon(const pat::Muon& muon, const pat::Tau& tau)
191  {
192  static constexpr int n_stations = 4;
193 
194  ++n_muons;
195  const double dR2 = reco::deltaR2(tau.p4(), muon.p4());
196  if(!best_matched_muon || dR2 < deltaR2_best_match) {
197  best_matched_muon = &muon;
198  deltaR2_best_match = dR2;
199  }
200 
201  for(const auto& segment : muon.matches()) {
202  if(segment.segmentMatches.empty()) continue;
203  if(n_matches.count(segment.detector()))
204  ++n_matches.at(segment.detector()).at(segment.station() - 1);
205  }
206 
207  if(muon.outerTrack().isNonnull()) {
208  const auto& hit_pattern = muon.outerTrack()->hitPattern();
209  for(int hit_index = 0; hit_index < hit_pattern.numberOfAllHits(reco::HitPattern::TRACK_HITS); ++hit_index) {
210  auto hit_id = hit_pattern.getHitPattern(reco::HitPattern::TRACK_HITS, hit_index);
211  if(hit_id == 0) break;
212  if(hit_pattern.muonHitFilter(hit_id) && (hit_pattern.getHitType(hit_id) == TrackingRecHit::valid
213  || hit_pattern.getHitType(hit_id == TrackingRecHit::bad))) {
214  const int station = hit_pattern.getMuonStation(hit_id) - 1;
215  if(station > 0 && station < n_stations) {
216  std::vector<UInt_t>* muon_n_hits = nullptr;
217  if(hit_pattern.muonDTHitFilter(hit_id))
218  muon_n_hits = &n_hits.at(MuonSubdetId::DT);
219  else if(hit_pattern.muonCSCHitFilter(hit_id))
220  muon_n_hits = &n_hits.at(MuonSubdetId::CSC);
221  else if(hit_pattern.muonRPCHitFilter(hit_id))
222  muon_n_hits = &n_hits.at(MuonSubdetId::RPC);
223 
224  if(muon_n_hits)
225  ++muon_n_hits->at(station);
226  }
227  }
228  }
229  }
230  }
231 
232  static std::vector<const pat::Muon*> findMatchedMuons(const pat::Tau& tau, const pat::MuonCollection& muons,
233  double deltaR, double minPt)
234  {
235  const reco::Muon* hadr_cand_muon = nullptr;
236  if(tau.leadPFChargedHadrCand().isNonnull() && tau.leadPFChargedHadrCand()->muonRef().isNonnull())
237  hadr_cand_muon = tau.leadPFChargedHadrCand()->muonRef().get();
238  std::vector<const pat::Muon*> matched_muons;
239  const double dR2 = deltaR*deltaR;
240  for(const pat::Muon& muon : muons) {
241  const reco::Muon* reco_muon = &muon;
242  if(muon.pt() <= minPt) continue;
243  if(reco_muon == hadr_cand_muon) continue;
244  if(reco::deltaR2(tau.p4(), muon.p4()) >= dR2) continue;
245  matched_muons.push_back(&muon);
246  }
247  return matched_muons;
248  }
249 
250  template<typename dnn, typename TensorElemGet>
251  void fillTensor(const TensorElemGet& get, const pat::Tau& tau, float default_value) const
252  {
253  get(dnn::n_matched_muons) = n_muons;
254  get(dnn::muon_pt) = best_matched_muon != nullptr ? best_matched_muon->p4().pt() : default_value;
255  get(dnn::muon_dEta) = best_matched_muon != nullptr
256  ? dEta(best_matched_muon->p4(), tau.p4()) : default_value;
257  get(dnn::muon_dPhi) = best_matched_muon != nullptr
258  ? dPhi(best_matched_muon->p4(), tau.p4()) : default_value;
259  get(dnn::muon_n_matches_DT_1) = n_matches.at(MuonSubdetId::DT).at(0);
260  get(dnn::muon_n_matches_DT_2) = n_matches.at(MuonSubdetId::DT).at(1);
261  get(dnn::muon_n_matches_DT_3) = n_matches.at(MuonSubdetId::DT).at(2);
262  get(dnn::muon_n_matches_DT_4) = n_matches.at(MuonSubdetId::DT).at(3);
263  get(dnn::muon_n_matches_CSC_1) = n_matches.at(MuonSubdetId::CSC).at(0);
264  get(dnn::muon_n_matches_CSC_2) = n_matches.at(MuonSubdetId::CSC).at(1);
265  get(dnn::muon_n_matches_CSC_3) = n_matches.at(MuonSubdetId::CSC).at(2);
266  get(dnn::muon_n_matches_CSC_4) = n_matches.at(MuonSubdetId::CSC).at(3);
267  get(dnn::muon_n_hits_DT_2) = n_hits.at(MuonSubdetId::DT).at(1);
268  get(dnn::muon_n_hits_DT_3) = n_hits.at(MuonSubdetId::DT).at(2);
269  get(dnn::muon_n_hits_DT_4) = n_hits.at(MuonSubdetId::DT).at(3);
270  get(dnn::muon_n_hits_CSC_2) = n_hits.at(MuonSubdetId::CSC).at(1);
271  get(dnn::muon_n_hits_CSC_3) = n_hits.at(MuonSubdetId::CSC).at(2);
272  get(dnn::muon_n_hits_CSC_4) = n_hits.at(MuonSubdetId::CSC).at(3);
273  get(dnn::muon_n_hits_RPC_2) = n_hits.at(MuonSubdetId::RPC).at(1);
274  get(dnn::muon_n_hits_RPC_3) = n_hits.at(MuonSubdetId::RPC).at(2);
275  get(dnn::muon_n_hits_RPC_4) = n_hits.at(MuonSubdetId::RPC).at(3);
276  get(dnn::muon_n_stations_with_matches_03) = countMuonStationsWithMatches(0, 3);
277  get(dnn::muon_n_stations_with_hits_23) = countMuonStationsWithHits(2, 3);
278  }
279 
280 private:
281  unsigned countMuonStationsWithMatches(size_t first_station, size_t last_station) const
282  {
283  static const std::map<int, std::vector<bool>> masks = {
284  { MuonSubdetId::DT, { false, false, false, false } },
285  { MuonSubdetId::CSC, { true, false, false, false } },
286  { MuonSubdetId::RPC, { false, false, false, false } },
287  };
288  unsigned cnt = 0;
289  for(unsigned n = first_station; n <= last_station; ++n) {
290  for(const auto& match : n_matches) {
291  if(!masks.at(match.first).at(n) && match.second.at(n) > 0) ++cnt;
292  }
293  }
294  return cnt;
295  }
296 
297  unsigned countMuonStationsWithHits(size_t first_station, size_t last_station) const
298  {
299  static const std::map<int, std::vector<bool>> masks = {
300  { MuonSubdetId::DT, { false, false, false, false } },
301  { MuonSubdetId::CSC, { false, false, false, false } },
302  { MuonSubdetId::RPC, { false, false, false, false } },
303  };
304 
305  unsigned cnt = 0;
306  for(unsigned n = first_station; n <= last_station; ++n) {
307  for(const auto& hit : n_hits) {
308  if(!masks.at(hit.first).at(n) && hit.second.at(n) > 0) ++cnt;
309  }
310  }
311  return cnt;
312  }
313 };
314 
315 
316 
317 struct MuonHitMatchV2 {
318 
319  static constexpr size_t n_muon_stations = 4;
320  static constexpr int first_station_id = 1;
321  static constexpr int last_station_id = first_station_id + n_muon_stations - 1;
322  using CountArray = std::array<unsigned, n_muon_stations>;
323  using CountMap = std::map<int, CountArray>;
324 
325  const std::vector<int>& consideredSubdets()
326  {
327  static const std::vector<int> subdets = { MuonSubdetId::DT, MuonSubdetId::CSC, MuonSubdetId::RPC };
328  return subdets;
329  }
330 
331  const std::string& subdetName(int subdet)
332  {
333  static const std::map<int, std::string> subdet_names = {
334  { MuonSubdetId::DT, "DT" }, { MuonSubdetId::CSC, "CSC" }, { MuonSubdetId::RPC, "RPC" }
335  };
336  if(!subdet_names.count(subdet))
337  throw cms::Exception("MuonHitMatch") << "Subdet name for subdet id " << subdet << " not found.";
338  return subdet_names.at(subdet);
339  }
340 
341  size_t getStationIndex(int station, bool throw_exception) const
342  {
343  if(station < first_station_id || station > last_station_id) {
344  if(throw_exception)
345  throw cms::Exception("MuonHitMatch") << "Station id is out of range";
347  }
348  return static_cast<size_t>(station - 1);
349  }
350 
351  MuonHitMatchV2(const pat::Muon& muon)
352  {
353  for(int subdet : consideredSubdets()) {
354  n_matches[subdet].fill(0);
355  n_hits[subdet].fill(0);
356  }
357 
358  countMatches(muon, n_matches);
359  countHits(muon, n_hits);
360  }
361 
362  void countMatches(const pat::Muon& muon, CountMap& n_matches)
363  {
364  for(const auto& segment : muon.matches()) {
365  if(segment.segmentMatches.empty() && segment.rpcMatches.empty()) continue;
366  if(n_matches.count(segment.detector())) {
367  const size_t station_index = getStationIndex(segment.station(), true);
368  ++n_matches.at(segment.detector()).at(station_index);
369  }
370  }
371  }
372 
373  void countHits(const pat::Muon& muon, CountMap& n_hits)
374  {
375  if(muon.outerTrack().isNonnull()) {
376  const auto& hit_pattern = muon.outerTrack()->hitPattern();
377  for(int hit_index = 0; hit_index < hit_pattern.numberOfAllHits(reco::HitPattern::TRACK_HITS); ++hit_index) {
378  auto hit_id = hit_pattern.getHitPattern(reco::HitPattern::TRACK_HITS, hit_index);
379  if(hit_id == 0) break;
380  if(hit_pattern.muonHitFilter(hit_id) && (hit_pattern.getHitType(hit_id) == TrackingRecHit::valid
381  || hit_pattern.getHitType(hit_id) == TrackingRecHit::bad)) {
382  const size_t station_index = getStationIndex(hit_pattern.getMuonStation(hit_id), false);
383  if(station_index < n_muon_stations) {
384  CountArray* muon_n_hits = nullptr;
385  if(hit_pattern.muonDTHitFilter(hit_id))
386  muon_n_hits = &n_hits.at(MuonSubdetId::DT);
387  else if(hit_pattern.muonCSCHitFilter(hit_id))
388  muon_n_hits = &n_hits.at(MuonSubdetId::CSC);
389  else if(hit_pattern.muonRPCHitFilter(hit_id))
390  muon_n_hits = &n_hits.at(MuonSubdetId::RPC);
391 
392  if(muon_n_hits)
393  ++muon_n_hits->at(station_index);
394  }
395  }
396  }
397  }
398  }
399 
400  unsigned nMatches(int subdet, int station) const
401  {
402  if(!n_matches.count(subdet))
403  throw cms::Exception("MuonHitMatch") << "Subdet " << subdet << " not found.";
404  const size_t station_index = getStationIndex(station, true);
405  return n_matches.at(subdet).at(station_index);
406  }
407 
408  unsigned nHits(int subdet, int station) const
409  {
410  if(!n_hits.count(subdet))
411  throw cms::Exception("MuonHitMatch") << "Subdet " << subdet << " not found.";
412  const size_t station_index = getStationIndex(station, true);
413  return n_hits.at(subdet).at(station_index);
414  }
415 
416  unsigned countMuonStationsWithMatches(int first_station, int last_station) const
417  {
418  static const std::map<int, std::vector<bool>> masks = {
419  { MuonSubdetId::DT, { false, false, false, false } },
420  { MuonSubdetId::CSC, { true, false, false, false } },
421  { MuonSubdetId::RPC, { false, false, false, false } },
422  };
423  const size_t first_station_index = getStationIndex(first_station, true);
424  const size_t last_station_index = getStationIndex(last_station, true);
425  unsigned cnt = 0;
426  for(size_t n = first_station_index; n <= last_station_index; ++n) {
427  for(const auto& match : n_matches) {
428  if(!masks.at(match.first).at(n) && match.second.at(n) > 0) ++cnt;
429  }
430  }
431  return cnt;
432  }
433 
434  unsigned countMuonStationsWithHits(int first_station, int last_station) const
435  {
436  static const std::map<int, std::vector<bool>> masks = {
437  { MuonSubdetId::DT, { false, false, false, false } },
438  { MuonSubdetId::CSC, { false, false, false, false } },
439  { MuonSubdetId::RPC, { false, false, false, false } },
440  };
441 
442  const size_t first_station_index = getStationIndex(first_station, true);
443  const size_t last_station_index = getStationIndex(last_station, true);
444  unsigned cnt = 0;
445  for(size_t n = first_station_index; n <= last_station_index; ++n) {
446  for(const auto& hit : n_hits) {
447  if(!masks.at(hit.first).at(n) && hit.second.at(n) > 0) ++cnt;
448  }
449  }
450  return cnt;
451  }
452 
453  private:
454  CountMap n_matches, n_hits;
455 };
456 
457 enum class CellObjectType { PfCand_electron, PfCand_muon, PfCand_chargedHadron, PfCand_neutralHadron,
458  PfCand_gamma, Electron, Muon, Other };
459 
460 template<typename Object>
461 CellObjectType GetCellObjectType(const Object&);
462 template<>
463 CellObjectType GetCellObjectType(const pat::Electron&) { return CellObjectType::Electron; }
464 template<>
465 CellObjectType GetCellObjectType(const pat::Muon&) { return CellObjectType::Muon; }
466 
467 template<>
468 CellObjectType GetCellObjectType(const pat::PackedCandidate& cand)
469 {
470  static const std::map<int, CellObjectType> obj_types = {
471  { 11, CellObjectType::PfCand_electron },
472  { 13, CellObjectType::PfCand_muon },
473  { 22, CellObjectType::PfCand_gamma },
474  { 130, CellObjectType::PfCand_neutralHadron },
475  { 211, CellObjectType::PfCand_chargedHadron }
476  };
477 
478  auto iter = obj_types.find(std::abs(cand.pdgId()));
479  if(iter == obj_types.end())
480  return CellObjectType::Other;
481  return iter->second;
482 }
483 
484 
485 using Cell = std::map<CellObjectType, size_t>;
486 struct CellIndex {
487  int eta, phi;
488 
489  bool operator<(const CellIndex& other) const
490  {
491  if(eta != other.eta) return eta < other.eta;
492  return phi < other.phi;
493  }
494 };
495 
496 class CellGrid {
497 public:
498  using Map = std::map<CellIndex, Cell>;
499  using const_iterator = Map::const_iterator;
500 
501  CellGrid(unsigned n_cells_eta, unsigned n_cells_phi, double cell_size_eta, double cell_size_phi) :
502  nCellsEta(n_cells_eta), nCellsPhi(n_cells_phi), nTotal(nCellsEta * nCellsPhi),
503  cellSizeEta(cell_size_eta), cellSizePhi(cell_size_phi)
504  {
505  if(nCellsEta % 2 != 1 || nCellsEta < 1)
506  throw cms::Exception("DeepTauId") << "Invalid number of eta cells.";
507  if(nCellsPhi % 2 != 1 || nCellsPhi < 1)
508  throw cms::Exception("DeepTauId") << "Invalid number of phi cells.";
509  if(cellSizeEta <= 0 || cellSizePhi <= 0)
510  throw cms::Exception("DeepTauId") << "Invalid cell size.";
511  }
512 
513  int maxEtaIndex() const { return static_cast<int>((nCellsEta - 1) / 2); }
514  int maxPhiIndex() const { return static_cast<int>((nCellsPhi - 1) / 2); }
515  double maxDeltaEta() const { return cellSizeEta * (0.5 + maxEtaIndex()); }
516  double maxDeltaPhi() const { return cellSizePhi * (0.5 + maxPhiIndex()); }
517  int getEtaTensorIndex(const CellIndex& cellIndex) const { return cellIndex.eta + maxEtaIndex(); }
518  int getPhiTensorIndex(const CellIndex& cellIndex) const { return cellIndex.phi + maxPhiIndex(); }
519 
520  bool tryGetCellIndex(double deltaEta, double deltaPhi, CellIndex& cellIndex) const
521  {
522  static auto getCellIndex = [](double x, double maxX, double size, int& index) {
523  const double absX = std::abs(x);
524  if(absX > maxX) return false;
525  const double absIndex = std::floor(std::abs(absX / size - 0.5));
526  index = static_cast<int>(std::copysign(absIndex, x));
527  return true;
528  };
529 
530  return getCellIndex(deltaEta, maxDeltaEta(), cellSizeEta, cellIndex.eta)
531  && getCellIndex(deltaPhi, maxDeltaPhi(), cellSizePhi, cellIndex.phi);
532  }
533 
534  Cell& operator[](const CellIndex& cellIndex) { return cells[cellIndex]; }
535  const Cell& at(const CellIndex& cellIndex) const { return cells.at(cellIndex); }
536  size_t count(const CellIndex& cellIndex) const { return cells.count(cellIndex); }
537  const_iterator find(const CellIndex& cellIndex) const { return cells.find(cellIndex); }
538  const_iterator begin() const { return cells.begin(); }
539  const_iterator end() const { return cells.end(); }
540 
541 public:
542  const unsigned nCellsEta, nCellsPhi, nTotal;
543  const double cellSizeEta, cellSizePhi;
544 
545 private:
546  std::map<CellIndex, Cell> cells;
547 };
548 
549 } // anonymous namespace
550 
552 public:
553 
554  static constexpr float default_value = -999.;
555 
556  static const OutputCollection& GetOutputs()
557  {
558  static constexpr size_t e_index = 0, mu_index = 1, tau_index = 2, jet_index = 3;
559  static const OutputCollection outputs_ = {
560  { "VSe", Output({tau_index}, {e_index, tau_index}) },
561  { "VSmu", Output({tau_index}, {mu_index, tau_index}) },
562  { "VSjet", Output({tau_index}, {jet_index, tau_index}) },
563  };
564  return outputs_;
565  }
566 
568  {
570  desc.add<edm::InputTag>("electrons", edm::InputTag("slimmedElectrons"));
571  desc.add<edm::InputTag>("muons", edm::InputTag("slimmedMuons"));
572  desc.add<edm::InputTag>("taus", edm::InputTag("slimmedTaus"));
573  desc.add<edm::InputTag>("pfcands", edm::InputTag("packedPFCandidates"));
574  desc.add<edm::InputTag>("vertices", edm::InputTag("offlineSlimmedPrimaryVertices"));
575  desc.add<edm::InputTag>("rho", edm::InputTag("fixedGridRhoAll"));
576  desc.add<std::vector<std::string>>("graph_file", {"RecoTauTag/TrainingFiles/data/DeepTauId/deepTau_2017v2p6_e6.pb"});
577  desc.add<bool>("mem_mapped", false);
578  desc.add<unsigned>("version", 2);
579  desc.add<int>("debug_level", 0);
580 
582  descWP.add<std::string>("VVVLoose", "0");
583  descWP.add<std::string>("VVLoose", "0");
584  descWP.add<std::string>("VLoose", "0");
585  descWP.add<std::string>("Loose", "0");
586  descWP.add<std::string>("Medium", "0");
587  descWP.add<std::string>("Tight", "0");
588  descWP.add<std::string>("VTight", "0");
589  descWP.add<std::string>("VVTight", "0");
590  descWP.add<std::string>("VVVTight", "0");
591  desc.add<edm::ParameterSetDescription>("VSeWP", descWP);
592  desc.add<edm::ParameterSetDescription>("VSmuWP", descWP);
593  desc.add<edm::ParameterSetDescription>("VSjetWP", descWP);
594  descriptions.add("DeepTau", desc);
595  }
596 
597 public:
599  DeepTauBase(cfg, GetOutputs(), cache),
600  electrons_token_(consumes<ElectronCollection>(cfg.getParameter<edm::InputTag>("electrons"))),
601  muons_token_(consumes<MuonCollection>(cfg.getParameter<edm::InputTag>("muons"))),
602  rho_token_(consumes<double>(cfg.getParameter<edm::InputTag>("rho"))),
603  version(cfg.getParameter<unsigned>("version")),
604  debug_level(cfg.getParameter<int>("debug_level"))
605  {
606  if(version == 1) {
607  input_layer_ = cache_->getGraph().node(0).name();
608  output_layer_ = cache_->getGraph().node(cache_->getGraph().node_size() - 1).name();
609  const auto& shape = cache_->getGraph().node(0).attr().at("shape").shape();
610  if(shape.dim(1).size() != dnn_inputs_2017v1::NumberOfInputs)
611  throw cms::Exception("DeepTauId") << "number of inputs does not match the expected inputs for the given version";
612  } else if(version == 2) {
613  tauBlockTensor_ = std::make_shared<tensorflow::Tensor>(tensorflow::DT_FLOAT, tensorflow::TensorShape{ 1,
614  dnn_inputs_2017_v2::TauBlockInputs::NumberOfInputs});
615  for(size_t n = 0; n < 2; ++n) {
616  const bool is_inner = n == 0;
617  const auto n_cells = is_inner ? dnn_inputs_2017_v2::number_of_inner_cell
618  : dnn_inputs_2017_v2::number_of_outer_cell;
619  eGammaTensor_[is_inner] = std::make_shared<tensorflow::Tensor>(tensorflow::DT_FLOAT,
620  tensorflow::TensorShape{1, 1, 1, dnn_inputs_2017_v2::EgammaBlockInputs::NumberOfInputs});
621  muonTensor_[is_inner] = std::make_shared<tensorflow::Tensor>(tensorflow::DT_FLOAT,
622  tensorflow::TensorShape{1, 1, 1, dnn_inputs_2017_v2::MuonBlockInputs::NumberOfInputs});
623  hadronsTensor_[is_inner] = std::make_shared<tensorflow::Tensor>(tensorflow::DT_FLOAT,
624  tensorflow::TensorShape{1, 1, 1, dnn_inputs_2017_v2::HadronBlockInputs::NumberOfInputs});
625  convTensor_[is_inner] = std::make_shared<tensorflow::Tensor>(tensorflow::DT_FLOAT,
626  tensorflow::TensorShape{1, n_cells, n_cells, dnn_inputs_2017_v2::number_of_conv_features});
627  zeroOutputTensor_[is_inner] = std::make_shared<tensorflow::Tensor>(tensorflow::DT_FLOAT,
628  tensorflow::TensorShape{1, 1, 1, dnn_inputs_2017_v2::number_of_conv_features});
629 
630 
631  eGammaTensor_[is_inner]->flat<float>().setZero();
632  muonTensor_[is_inner]->flat<float>().setZero();
633  hadronsTensor_[is_inner]->flat<float>().setZero();
634  getPartialPredictions(*zeroOutputTensor_[is_inner], is_inner, 0, 0);
635 
636  }
637  } else {
638  throw cms::Exception("DeepTauId") << "version " << version << " is not supported.";
639  }
640 
641  }
642 
643  static std::unique_ptr<deep_tau::DeepTauCache> initializeGlobalCache(const edm::ParameterSet& cfg)
644  {
646  }
647 
648  static void globalEndJob(const deep_tau::DeepTauCache* cache_)
649  {
650  return DeepTauBase::globalEndJob(cache_);
651  }
652 private:
653  static constexpr float pi = M_PI;
654 
655  template<typename T>
656  static float getValue(T value)
657  {
658  return std::isnormal(value) ? static_cast<float>(value) : 0.f;
659  }
660 
661  template<typename T>
662  static float getValueLinear(T value, float min_value, float max_value, bool positive)
663  {
664  const float fixed_value = getValue(value);
665  const float clamped_value = std::clamp(fixed_value, min_value, max_value);
666  float transformed_value = (clamped_value - min_value) / (max_value - min_value);
667  if(!positive)
668  transformed_value = transformed_value * 2 - 1;
669  return transformed_value;
670  }
671 
672  template<typename T>
673  static float getValueNorm(T value, float mean, float sigma, float n_sigmas_max = 5)
674  {
675  const float fixed_value = getValue(value);
676  const float norm_value = (fixed_value - mean) / sigma;
677  return std::clamp(norm_value, -n_sigmas_max, n_sigmas_max);
678  }
679 
680  static bool calculateElectronClusterVarsV2(const pat::Electron& ele, float& cc_ele_energy, float& cc_gamma_energy,
681  int& cc_n_gamma)
682  {
683  cc_ele_energy = cc_gamma_energy = 0;
684  cc_n_gamma = 0;
685  const auto& superCluster = ele.superCluster();
686  if(superCluster.isNonnull() && superCluster.isAvailable() && superCluster->clusters().isNonnull()
687  && superCluster->clusters().isAvailable()) {
688  for(auto iter = superCluster->clustersBegin(); iter != superCluster->clustersEnd(); ++iter) {
689  const float energy = static_cast<float>((*iter)->energy());
690  if(iter == superCluster->clustersBegin())
691  cc_ele_energy += energy;
692  else {
693  cc_gamma_energy += energy;
694  ++cc_n_gamma;
695  }
696  }
697  return true;
698  } else
699  return false;
700  }
701 
702  inline void checkInputs(const tensorflow::Tensor& inputs, const char* block_name, int n_inputs, int n_eta = 1,
703  int n_phi = 1) const
704  {
705  if(debug_level >= 1){
706  for(int eta = 0; eta < n_eta; ++eta){
707  for(int phi = 0; phi < n_phi; phi++){
708  for(int k = 0; k < n_inputs; ++k) {
709  const float input = n_eta == 1 && n_phi == 1
710  ? inputs.matrix<float>()(0, k) : inputs.tensor<float,4>()(0, eta, phi, k);
711  if(edm::isNotFinite(input))
712  throw cms::Exception("DeepTauId") << "in the " << block_name << ", input is not finite, i.e. infinite or NaN, for eta_index = "
713  << n_eta << ", phi_index = " << n_phi << ", input_index = " << k;
714  if(debug_level >= 2)
715  std::cout << block_name << "," << eta << ","<< phi << "," << k << "," << std::setprecision(5) << std::fixed << input << '\n';
716  }
717  }
718  }
719  }
720  }
721 
722 private:
723  tensorflow::Tensor getPredictions(edm::Event& event, const edm::EventSetup& es,
725  {
727  event.getByToken(electrons_token_, electrons);
728 
730  event.getByToken(muons_token_, muons);
731 
733  event.getByToken(pfcandToken_, pfCands);
734 
736  event.getByToken(vtxToken_, vertices);
737 
739  event.getByToken(rho_token_, rho);
740 
741  tensorflow::Tensor predictions(tensorflow::DT_FLOAT, { static_cast<int>(taus->size()),
743  for(size_t tau_index = 0; tau_index < taus->size(); ++tau_index) {
744  std::vector<tensorflow::Tensor> pred_vector;
745  if(version == 1)
746  getPredictionsV1(taus->at(tau_index), *electrons, *muons, pred_vector);
747  else if(version == 2)
748  getPredictionsV2(taus->at(tau_index), *electrons, *muons, *pfCands, vertices->at(0), *rho, pred_vector);
749  else
750  throw cms::Exception("DeepTauId") << "version " << version << " is not supported.";
751  for(int k = 0; k < deep_tau::NumberOfOutputs; ++k) {
752  const float pred = pred_vector[0].flat<float>()(k);
753  if(!(pred >= 0 && pred <= 1))
754  throw cms::Exception("DeepTauId") << "invalid prediction = " << pred << " for tau_index = "
755  << tau_index << ", pred_index = " << k;
756  predictions.matrix<float>()(tau_index, k) = pred;
757  }
758  }
759  return predictions;
760  }
761 
763  const pat::MuonCollection& muons, std::vector<tensorflow::Tensor>& pred_vector)
764  {
765  const tensorflow::Tensor& inputs = createInputsV1<dnn_inputs_2017v1>(tau, electrons, muons);
766  tensorflow::run(&(cache_->getSession()), { { input_layer_, inputs } }, { output_layer_ }, &pred_vector);
767  }
768 
771  const reco::Vertex& pv, double rho, std::vector<tensorflow::Tensor>& pred_vector)
772  {
773  CellGrid inner_grid(dnn_inputs_2017_v2::number_of_inner_cell, dnn_inputs_2017_v2::number_of_inner_cell,
774  0.02, 0.02);
775  CellGrid outer_grid(dnn_inputs_2017_v2::number_of_outer_cell, dnn_inputs_2017_v2::number_of_outer_cell,
776  0.05, 0.05);
777  fillGrids(tau, electrons, inner_grid, outer_grid);
778  fillGrids(tau, muons, inner_grid, outer_grid);
779  fillGrids(tau, pfCands, inner_grid, outer_grid);
780 
781  createTauBlockInputs(tau, pv, rho);
782  createConvFeatures(tau, pv, rho, electrons, muons, pfCands, inner_grid, true);
783  createConvFeatures(tau, pv, rho, electrons, muons, pfCands, outer_grid, false);
784 
785  tensorflow::run(&(cache_->getSession("core")),
786  { { "input_tau", *tauBlockTensor_ },
787  { "input_inner", *convTensor_.at(true)}, { "input_outer", *convTensor_.at(false) } },
788  { "main_output/Softmax" }, &pred_vector);
789  }
790 
791  template<typename Collection>
792  void fillGrids(const TauType& tau, const Collection& objects, CellGrid& inner_grid, CellGrid& outer_grid)
793  {
794  static constexpr double outer_dR2 = 0.25;//0.5^2
795  const double inner_radius = getInnerSignalConeRadius(tau.polarP4().pt());
796  const double inner_dR2 = std::pow(inner_radius, 2);
797 
798  const auto addObject = [&](size_t n, double deta, double dphi, CellGrid& grid) {
799  const auto& obj = objects.at(n);
800  const CellObjectType obj_type = GetCellObjectType(obj);
801  if(obj_type == CellObjectType::Other) return;
802  CellIndex cell_index;
803  if(grid.tryGetCellIndex(deta, dphi, cell_index)) {
804  Cell& cell = grid[cell_index];
805  auto iter = cell.find(obj_type);
806  if(iter != cell.end()) {
807  const auto& prev_obj = objects.at(iter->second);
808  if(obj.polarP4().pt() > prev_obj.polarP4().pt())
809  iter->second = n;
810  } else {
811  cell[obj_type] = n;
812  }
813  }
814  };
815 
816  for(size_t n = 0; n < objects.size(); ++n) {
817  const auto& obj = objects.at(n);
818  const double deta = obj.polarP4().eta() - tau.polarP4().eta();
819  const double dphi = reco::deltaPhi(obj.polarP4().phi(), tau.polarP4().phi());
820  const double dR2 = std::pow(deta, 2) + std::pow(dphi, 2);
821  if(dR2 < inner_dR2)
822  addObject(n, deta, dphi, inner_grid);
823  if(dR2 < outer_dR2)
824  addObject(n, deta, dphi, outer_grid);
825  }
826  }
827 
828  void getPartialPredictions(tensorflow::Tensor& convTensor, bool is_inner, int eta_index, int phi_index)
829  {
830  std::vector<tensorflow::Tensor> pred_vector;
831  if(is_inner) {
832  tensorflow::run(&(cache_->getSession("inner")),
833  { { "input_inner_egamma", *eGammaTensor_.at(is_inner) },
834  { "input_inner_muon", *muonTensor_.at(is_inner) },
835  { "input_inner_hadrons", *hadronsTensor_.at(is_inner) }, },
836  { "inner_all_dropout_4/Identity" }, &pred_vector);
837  } else {
838  tensorflow::run(&(cache_->getSession("outer")),
839  { { "input_outer_egamma", *eGammaTensor_.at(is_inner) },
840  { "input_outer_muon", *muonTensor_.at(is_inner) },
841  { "input_outer_hadrons", *hadronsTensor_.at(is_inner) }, },
842  { "outer_all_dropout_4/Identity" }, &pred_vector);
843  }
844  setCellConvFeatures(convTensor, pred_vector.at(0), eta_index, phi_index);
845  }
846 
847  void createConvFeatures(const TauType& tau, const reco::Vertex& pv, double rho,
849  const pat::PackedCandidateCollection& pfCands, const CellGrid& grid, bool is_inner)
850  {
851  tensorflow::Tensor& convTensor = *convTensor_.at(is_inner);
852  for(int eta = -grid.maxEtaIndex(); eta <= grid.maxEtaIndex(); ++eta) {
853  for(int phi = -grid.maxPhiIndex(); phi <= grid.maxPhiIndex(); ++phi) {
854  const CellIndex cell_index{eta, phi};
855  const int eta_index = grid.getEtaTensorIndex(cell_index);
856  const int phi_index = grid.getPhiTensorIndex(cell_index);
857 
858  const auto cell_iter = grid.find(cell_index);
859  if(cell_iter != grid.end()) {
860  const Cell& cell = cell_iter->second;
861  createEgammaBlockInputs(tau, pv, rho, electrons, pfCands, cell, is_inner);
862  createMuonBlockInputs(tau, pv, rho, muons, pfCands, cell, is_inner);
863  createHadronsBlockInputs(tau, pv, rho, pfCands, cell, is_inner);
864  getPartialPredictions(convTensor, is_inner, eta_index, phi_index);
865  } else {
866  setCellConvFeatures(convTensor, *zeroOutputTensor_[is_inner], eta_index, phi_index);
867  }
868  }
869  }
870  }
871 
872  void setCellConvFeatures(tensorflow::Tensor& convTensor, const tensorflow::Tensor& features,
873  int eta_index, int phi_index)
874  {
875  for(int n = 0; n < dnn_inputs_2017_v2::number_of_conv_features; ++n)
876  convTensor.tensor<float, 4>()(0, eta_index, phi_index, n) = features.tensor<float, 4>()(0, 0, 0, n);
877  }
878 
879  void createTauBlockInputs(const TauType& tau, const reco::Vertex& pv, double rho)
880  {
881  namespace dnn = dnn_inputs_2017_v2::TauBlockInputs;
882 
883  tensorflow::Tensor& inputs = *tauBlockTensor_;
884  inputs.flat<float>().setZero();
885 
886  const auto& get = [&](int var_index) -> float& { return inputs.matrix<float>()(0, var_index); };
887 
888  auto leadChargedHadrCand = dynamic_cast<const pat::PackedCandidate*>(tau.leadChargedHadrCand().get());
889 
890  get(dnn::rho) = getValueNorm(rho, 21.49f, 9.713f);
891  get(dnn::tau_pt) = getValueLinear(tau.polarP4().pt(), 20.f, 1000.f, true);
892  get(dnn::tau_eta) = getValueLinear(tau.polarP4().eta(), -2.3f, 2.3f, false);
893  get(dnn::tau_phi) = getValueLinear(tau.polarP4().phi(), -pi, pi, false);
894  get(dnn::tau_mass) = getValueNorm(tau.polarP4().mass(), 0.6669f, 0.6553f);
895  get(dnn::tau_E_over_pt) = getValueLinear(tau.p4().energy() / tau.p4().pt(), 1.f, 5.2f, true);
896  get(dnn::tau_charge) = getValue(tau.charge());
897  get(dnn::tau_n_charged_prongs) = getValueLinear(tau.decayMode() / 5 + 1, 1, 3, true);
898  get(dnn::tau_n_neutral_prongs) = getValueLinear(tau.decayMode() % 5, 0, 2, true);
899  get(dnn::chargedIsoPtSum) = getValueNorm(tau.tauID("chargedIsoPtSum"), 47.78f, 123.5f);
900  get(dnn::chargedIsoPtSumdR03_over_dR05) = getValue(tau.tauID("chargedIsoPtSumdR03") / tau.tauID("chargedIsoPtSum"));
901  get(dnn::footprintCorrection) = getValueNorm(tau.tauID("footprintCorrectiondR03"), 9.029f, 26.42f);
902  get(dnn::neutralIsoPtSum) = getValueNorm(tau.tauID("neutralIsoPtSum"), 57.59f, 155.3f);
903  get(dnn::neutralIsoPtSumWeight_over_neutralIsoPtSum) =
904  getValue(tau.tauID("neutralIsoPtSumWeight") / tau.tauID("neutralIsoPtSum"));
905  get(dnn::neutralIsoPtSumWeightdR03_over_neutralIsoPtSum) =
906  getValue(tau.tauID("neutralIsoPtSumWeightdR03") / tau.tauID("neutralIsoPtSum"));
907  get(dnn::neutralIsoPtSumdR03_over_dR05) = getValue(tau.tauID("neutralIsoPtSumdR03") / tau.tauID("neutralIsoPtSum"));
908  get(dnn::photonPtSumOutsideSignalCone) = getValueNorm(tau.tauID("photonPtSumOutsideSignalConedR03"), 1.731f, 6.846f);
909  get(dnn::puCorrPtSum) = getValueNorm(tau.tauID("puCorrPtSum"), 22.38f, 16.34f);
910  get(dnn::tau_dxy_pca_x) = getValueNorm(tau.dxy_PCA().x(), -0.0241f, 0.0074f);
911  get(dnn::tau_dxy_pca_y) = getValueNorm(tau.dxy_PCA().y(),0.0675f, 0.0128f);
912  get(dnn::tau_dxy_pca_z) = getValueNorm(tau.dxy_PCA().z(), 0.7973f, 3.456f);
913 
914  const bool tau_dxy_valid = std::isnormal(tau.dxy()) && tau.dxy() > - 10 && std::isnormal(tau.dxy_error())
915  && tau.dxy_error() > 0;
916  if(tau_dxy_valid){
917  get(dnn::tau_dxy_valid) = tau_dxy_valid;
918  get(dnn::tau_dxy) = getValueNorm(tau.dxy(), 0.0018f, 0.0085f);
919  get(dnn::tau_dxy_sig) = getValueNorm(std::abs(tau.dxy())/tau.dxy_error(), 2.26f, 4.191f);
920  }
921  const bool tau_ip3d_valid = std::isnormal(tau.ip3d()) && tau.ip3d() > - 10 && std::isnormal(tau.ip3d_error())
922  && tau.ip3d_error() > 0;
923  if(tau_ip3d_valid){
924  get(dnn::tau_ip3d_valid) = tau_ip3d_valid;
925  get(dnn::tau_ip3d) = getValueNorm(tau.ip3d(), 0.0026f, 0.0114f);
926  get(dnn::tau_ip3d_sig) = getValueNorm(std::abs(tau.ip3d()) / tau.ip3d_error(), 2.928f, 4.466f);
927  }
928  if(leadChargedHadrCand){
929  get(dnn::tau_dz) = getValueNorm(leadChargedHadrCand->dz(), 0.f, 0.0190f);
930  const bool tau_dz_sig_valid = leadChargedHadrCand->hasTrackDetails() && std::isnormal(leadChargedHadrCand->dz())
931  && std::isnormal(leadChargedHadrCand->dzError()) && leadChargedHadrCand->dzError() > 0;
932  get(dnn::tau_dz_sig_valid) = tau_dz_sig_valid;
933  const double dzError = leadChargedHadrCand->hasTrackDetails() ? leadChargedHadrCand->dzError() : default_value;
934  get(dnn::tau_dz_sig) = getValueNorm(std::abs(leadChargedHadrCand->dz()) / dzError, 4.717f, 11.78f);
935  }
936  get(dnn::tau_flightLength_x) = getValueNorm(tau.flightLength().x(), -0.0003f, 0.7362f);
937  get(dnn::tau_flightLength_y) = getValueNorm(tau.flightLength().y(), -0.0009f, 0.7354f);
938  get(dnn::tau_flightLength_z) = getValueNorm(tau.flightLength().z(), -0.0022f, 1.993f);
939  // get(dnn::tau_flightLength_sig) = getValueNorm(tau.flightLengthSig(), -4.78f, 9.573f);
940  get(dnn::tau_flightLength_sig) = 0.55756444; //This value is set due to a bug in the training
941  get(dnn::tau_pt_weighted_deta_strip) = getValueLinear(reco::tau::pt_weighted_deta_strip(tau, tau.decayMode()), 0, 1, true);
942 
943  get(dnn::tau_pt_weighted_dphi_strip) = getValueLinear(reco::tau::pt_weighted_dphi_strip(tau, tau.decayMode()), 0, 1, true);
944  get(dnn::tau_pt_weighted_dr_signal) = getValueNorm(reco::tau::pt_weighted_dr_signal(tau, tau.decayMode()), 0.0052f, 0.01433f);
945  get(dnn::tau_pt_weighted_dr_iso) = getValueLinear(reco::tau::pt_weighted_dr_iso(tau,tau.decayMode()), 0, 1, true);
946  get(dnn::tau_leadingTrackNormChi2) = getValueNorm(tau.leadingTrackNormChi2(), 1.538f, 4.401f);
947  const auto eratio = reco::tau::eratio(tau);
948  const bool tau_e_ratio_valid = std::isnormal(eratio) && eratio > 0.f;
949  get(dnn::tau_e_ratio_valid) = tau_e_ratio_valid;
950  get(dnn::tau_e_ratio) = tau_e_ratio_valid ? getValueLinear(eratio, 0, 1, true) : 0.f;
951  const double gj_angle_diff = calculateGottfriedJacksonAngleDifference(tau);
952  const bool tau_gj_angle_diff_valid = (std::isnormal(gj_angle_diff) || gj_angle_diff == 0) && gj_angle_diff >= 0;
953  get(dnn::tau_gj_angle_diff_valid) = tau_gj_angle_diff_valid;
954  get(dnn::tau_gj_angle_diff) = tau_gj_angle_diff_valid ? getValueLinear(gj_angle_diff, 0, pi, true) : 0;
955  get(dnn::tau_n_photons) = getValueNorm(reco::tau::n_photons_total(tau), 2.95f, 3.927f);
956  get(dnn::tau_emFraction) = getValueLinear(tau.emFraction_MVA(), -1, 1, false);
957  get(dnn::tau_inside_ecal_crack) = getValue(isInEcalCrack(tau.p4().eta()));
958  get(dnn::leadChargedCand_etaAtEcalEntrance_minus_tau_eta) =
959  getValueNorm(tau.etaAtEcalEntranceLeadChargedCand() - tau.p4().eta(), 0.0042f, 0.0323f);
960 
961  checkInputs(inputs, "tau_block", dnn::NumberOfInputs);
962  }
963 
964  void createEgammaBlockInputs(const TauType& tau, const reco::Vertex& pv, double rho,
966  const pat::PackedCandidateCollection& pfCands,
967  const Cell& cell_map, bool is_inner)
968  {
970 
971  tensorflow::Tensor& inputs = *eGammaTensor_.at(is_inner);
972  inputs.flat<float>().setZero();
973 
974  const auto& get = [&](int var_index) -> float& {
975  return inputs.tensor<float,4>()(0, 0, 0, var_index);
976  };
977 
978  const bool valid_index_pf_ele = cell_map.count(CellObjectType::PfCand_electron);
979  const bool valid_index_pf_gamma = cell_map.count(CellObjectType::PfCand_gamma);
980  const bool valid_index_ele = cell_map.count(CellObjectType::Electron);
981 
982  if(!cell_map.empty()){
983  get(dnn::rho) = getValueNorm(rho, 21.49f, 9.713f);
984  get(dnn::tau_pt) = getValueLinear(tau.polarP4().pt(), 20.f, 1000.f, true);
985  get(dnn::tau_eta) = getValueLinear(tau.polarP4().eta(), -2.3f, 2.3f, false);
986  get(dnn::tau_inside_ecal_crack) = getValue(isInEcalCrack(tau.polarP4().eta()));
987  }
988  if(valid_index_pf_ele){
989  size_t index_pf_ele = cell_map.at(CellObjectType::PfCand_electron);
990 
991  get(dnn::pfCand_ele_valid) = valid_index_pf_ele;
992  get(dnn::pfCand_ele_rel_pt) = getValueNorm(pfCands.at(index_pf_ele).polarP4().pt() / tau.polarP4().pt(),
993  is_inner ? 0.9792f : 0.304f, is_inner ? 0.5383f : 1.845f);
994  get(dnn::pfCand_ele_deta) = getValueLinear(pfCands.at(index_pf_ele).polarP4().eta() - tau.polarP4().eta(),
995  is_inner ? -0.1f : -0.5f, is_inner ? 0.1f : 0.5f, false);
996  get(dnn::pfCand_ele_dphi) = getValueLinear(dPhi(tau.polarP4(), pfCands.at(index_pf_ele).polarP4()),
997  is_inner ? -0.1f : -0.5f, is_inner ? 0.1f : 0.5f, false);
998  get(dnn::pfCand_ele_pvAssociationQuality) = getValueLinear<int>(pfCands.at(index_pf_ele).pvAssociationQuality(), 0, 7, true);
999  get(dnn::pfCand_ele_puppiWeight) = getValue(pfCands.at(index_pf_ele).puppiWeight());
1000  get(dnn::pfCand_ele_charge) = getValue(pfCands.at(index_pf_ele).charge());
1001  get(dnn::pfCand_ele_lostInnerHits) = getValue<int>(pfCands.at(index_pf_ele).lostInnerHits());
1002  get(dnn::pfCand_ele_numberOfPixelHits) = getValueLinear(pfCands.at(index_pf_ele).numberOfPixelHits(), 0, 10, true);
1003  get(dnn::pfCand_ele_vertex_dx) = getValueNorm(pfCands.at(index_pf_ele).vertex().x() - pv.position().x(), 0.f, 0.1221f);
1004  get(dnn::pfCand_ele_vertex_dy) = getValueNorm(pfCands.at(index_pf_ele).vertex().y() - pv.position().y(), 0.f, 0.1226f);
1005  get(dnn::pfCand_ele_vertex_dz) = getValueNorm(pfCands.at(index_pf_ele).vertex().z() - pv.position().z(), 0.001f, 1.024f);
1006  get(dnn::pfCand_ele_vertex_dx_tauFL) = getValueNorm(pfCands.at(index_pf_ele).vertex().x() -
1007  pv.position().x() - tau.flightLength().x(), 0.f, 0.3411f);
1008  get(dnn::pfCand_ele_vertex_dy_tauFL) = getValueNorm(pfCands.at(index_pf_ele).vertex().y() -
1009  pv.position().y() - tau.flightLength().y(), 0.0003f, 0.3385f);
1010  get(dnn::pfCand_ele_vertex_dz_tauFL) = getValueNorm(pfCands.at(index_pf_ele).vertex().z() -
1011  pv.position().z() - tau.flightLength().z(), 0.f, 1.307f);
1012 
1013  const bool hasTrackDetails = pfCands.at(index_pf_ele).hasTrackDetails();
1014  if(hasTrackDetails){
1015  get(dnn::pfCand_ele_hasTrackDetails) = hasTrackDetails;
1016  get(dnn::pfCand_ele_dxy) = getValueNorm(pfCands.at(index_pf_ele).dxy(), 0.f, 0.171f);
1017  get(dnn::pfCand_ele_dxy_sig) = getValueNorm(std::abs(pfCands.at(index_pf_ele).dxy()) /
1018  pfCands.at(index_pf_ele).dxyError(), 1.634f, 6.45f);
1019  get(dnn::pfCand_ele_dz) = getValueNorm(pfCands.at(index_pf_ele).dz(), 0.001f, 1.02f);
1020  get(dnn::pfCand_ele_dz_sig) = getValueNorm(std::abs(pfCands.at(index_pf_ele).dz()) /
1021  pfCands.at(index_pf_ele).dzError(), 24.56f, 210.4f);
1022  get(dnn::pfCand_ele_track_chi2_ndof) = getValueNorm(pfCands.at(index_pf_ele).pseudoTrack().chi2() /
1023  pfCands.at(index_pf_ele).pseudoTrack().ndof(), 2.272f, 8.439f);
1024  get(dnn::pfCand_ele_track_ndof) = getValueNorm(pfCands.at(index_pf_ele).pseudoTrack().ndof(), 15.18f, 3.203f);
1025  }
1026  }
1027  if(valid_index_pf_gamma){
1028  size_t index_pf_gamma = cell_map.at(CellObjectType::PfCand_gamma);
1029  get(dnn::pfCand_gamma_valid) = valid_index_pf_gamma;
1030  get(dnn::pfCand_gamma_rel_pt) = getValueNorm(pfCands.at(index_pf_gamma).polarP4().pt() / tau.polarP4().pt(),
1031  is_inner ? 0.6048f : 0.02576f, is_inner ? 1.669f : 0.3833f);
1032  get(dnn::pfCand_gamma_deta) = getValueLinear(pfCands.at(index_pf_gamma).polarP4().eta() - tau.polarP4().eta(),
1033  is_inner ? -0.1f : -0.5f, is_inner ? 0.1f : 0.5f, false);
1034  get(dnn::pfCand_gamma_dphi) = getValueLinear(dPhi(tau.polarP4(), pfCands.at(index_pf_gamma).polarP4()),
1035  is_inner ? -0.1f : -0.5f, is_inner ? 0.1f : 0.5f, false);
1036  get(dnn::pfCand_gamma_pvAssociationQuality) =
1037  getValueLinear<int>(pfCands.at(index_pf_gamma).pvAssociationQuality(), 0, 7, true);
1038  get(dnn::pfCand_gamma_fromPV) = getValueLinear<int>(pfCands.at(index_pf_gamma).fromPV(), 0, 3, true);
1039  get(dnn::pfCand_gamma_puppiWeight) = getValue(pfCands.at(index_pf_gamma).puppiWeight());
1040  get(dnn::pfCand_gamma_puppiWeightNoLep) = getValue(pfCands.at(index_pf_gamma).puppiWeightNoLep());
1041  get(dnn::pfCand_gamma_lostInnerHits) = getValue<int>(pfCands.at(index_pf_gamma).lostInnerHits());
1042  get(dnn::pfCand_gamma_numberOfPixelHits) = getValueLinear(pfCands.at(index_pf_gamma).numberOfPixelHits(), 0, 7, true);
1043  get(dnn::pfCand_gamma_vertex_dx) = getValueNorm(pfCands.at(index_pf_gamma).vertex().x() - pv.position().x(), 0.f, 0.0067f);
1044  get(dnn::pfCand_gamma_vertex_dy) = getValueNorm(pfCands.at(index_pf_gamma).vertex().y() - pv.position().y(), 0.f, 0.0069f);
1045  get(dnn::pfCand_gamma_vertex_dz) = getValueNorm(pfCands.at(index_pf_gamma).vertex().z() - pv.position().z(), 0.f, 0.0578f);
1046  get(dnn::pfCand_gamma_vertex_dx_tauFL) = getValueNorm(pfCands.at(index_pf_gamma).vertex().x() -
1047  pv.position().x() - tau.flightLength().x(), 0.001f, 0.9565f);
1048  get(dnn::pfCand_gamma_vertex_dy_tauFL) = getValueNorm(pfCands.at(index_pf_gamma).vertex().y() -
1049  pv.position().y() - tau.flightLength().y(), 0.0008f, 0.9592f);
1050  get(dnn::pfCand_gamma_vertex_dz_tauFL) = getValueNorm(pfCands.at(index_pf_gamma).vertex().z() -
1051  pv.position().z() - tau.flightLength().z(), 0.0038f, 2.154f);
1052 
1053  const bool hasTrackDetails = pfCands.at(index_pf_gamma).hasTrackDetails();
1054  if(hasTrackDetails){
1055  get(dnn::pfCand_gamma_hasTrackDetails) = hasTrackDetails;
1056  get(dnn::pfCand_gamma_dxy) = getValueNorm(pfCands.at(index_pf_gamma).dxy(), 0.0004f, 0.882f);
1057  get(dnn::pfCand_gamma_dxy_sig) = getValueNorm(std::abs(pfCands.at(index_pf_gamma).dxy()) /
1058  pfCands.at(index_pf_gamma).dxyError(), 4.271f, 63.78f);
1059  get(dnn::pfCand_gamma_dz) = getValueNorm(pfCands.at(index_pf_gamma).dz(), 0.0071f, 5.285f);
1060  get(dnn::pfCand_gamma_dz_sig) = getValueNorm(std::abs(pfCands.at(index_pf_gamma).dz()) /
1061  pfCands.at(index_pf_gamma).dzError(), 162.1f, 622.4f);
1062  get(dnn::pfCand_gamma_track_chi2_ndof) = pfCands.at(index_pf_gamma).pseudoTrack().ndof() > 0 ?
1063  getValueNorm(pfCands.at(index_pf_gamma).pseudoTrack().chi2() /
1064  pfCands.at(index_pf_gamma).pseudoTrack().ndof(), 4.268f, 15.47f) : 0;
1065  get(dnn::pfCand_gamma_track_ndof) = pfCands.at(index_pf_gamma).pseudoTrack().ndof() > 0 ?
1066  getValueNorm(pfCands.at(index_pf_gamma).pseudoTrack().ndof(), 12.25f, 4.774f) : 0;
1067  }
1068  }
1069  if(valid_index_ele){
1070  size_t index_ele = cell_map.at(CellObjectType::Electron);
1071 
1072  get(dnn::ele_valid) = valid_index_ele;
1073  get(dnn::ele_rel_pt) = getValueNorm(electrons.at(index_ele).polarP4().pt() / tau.polarP4().pt(),
1074  is_inner ? 1.067f : 0.5111f, is_inner ? 1.521f : 2.765f);
1075  get(dnn::ele_deta) = getValueLinear(electrons.at(index_ele).polarP4().eta() - tau.polarP4().eta(),
1076  is_inner ? -0.1f : -0.5f, is_inner ? 0.1f : 0.5f, false);
1077  get(dnn::ele_dphi) = getValueLinear(dPhi(tau.polarP4(), electrons.at(index_ele).polarP4()),
1078  is_inner ? -0.1f : -0.5f, is_inner ? 0.1f : 0.5f, false);
1079 
1080  float cc_ele_energy, cc_gamma_energy;
1081  int cc_n_gamma;
1082  const bool cc_valid = calculateElectronClusterVarsV2(electrons.at(index_ele), cc_ele_energy, cc_gamma_energy, cc_n_gamma);
1083  if(cc_valid){
1084  get(dnn::ele_cc_valid) = cc_valid;
1085  get(dnn::ele_cc_ele_rel_energy) = getValueNorm(cc_ele_energy / electrons.at(index_ele).polarP4().pt(), 1.729f, 1.644f);
1086  get(dnn::ele_cc_gamma_rel_energy) = getValueNorm(cc_gamma_energy / cc_ele_energy, 0.1439f, 0.3284f);
1087  get(dnn::ele_cc_n_gamma) = getValueNorm(cc_n_gamma, 1.794f, 2.079f);
1088  }
1089  get(dnn::ele_rel_trackMomentumAtVtx) = getValueNorm(electrons.at(index_ele).trackMomentumAtVtx().R() /
1090  electrons.at(index_ele).polarP4().pt(), 1.531f, 1.424f);
1091  get(dnn::ele_rel_trackMomentumAtCalo) = getValueNorm(electrons.at(index_ele).trackMomentumAtCalo().R() /
1092  electrons.at(index_ele).polarP4().pt(), 1.531f, 1.424f);
1093  get(dnn::ele_rel_trackMomentumOut) = getValueNorm(electrons.at(index_ele).trackMomentumOut().R() /
1094  electrons.at(index_ele).polarP4().pt(), 0.7735f, 0.935f);
1095  get(dnn::ele_rel_trackMomentumAtEleClus) = getValueNorm(electrons.at(index_ele).trackMomentumAtEleClus().R() /
1096  electrons.at(index_ele).polarP4().pt(), 0.7735f, 0.935f);
1097  get(dnn::ele_rel_trackMomentumAtVtxWithConstraint) =
1098  getValueNorm(electrons.at(index_ele).trackMomentumAtVtxWithConstraint().R() /
1099  electrons.at(index_ele).polarP4().pt(), 1.625f, 1.581f);
1100  get(dnn::ele_rel_ecalEnergy) = getValueNorm(electrons.at(index_ele).ecalEnergy() /
1101  electrons.at(index_ele).polarP4().pt(), 1.993f, 1.308f);
1102  get(dnn::ele_ecalEnergy_sig) = getValueNorm(electrons.at(index_ele).ecalEnergy() /
1103  electrons.at(index_ele).ecalEnergyError(), 70.25f, 58.16f);
1104  get(dnn::ele_eSuperClusterOverP) = getValueNorm(electrons.at(index_ele).eSuperClusterOverP(), 2.432f, 15.13f);
1105  get(dnn::ele_eSeedClusterOverP) = getValueNorm(electrons.at(index_ele).eSeedClusterOverP(), 2.034f, 13.96f);
1106  get(dnn::ele_eSeedClusterOverPout) = getValueNorm(electrons.at(index_ele).eSeedClusterOverPout(), 6.64f, 36.8f);
1107  get(dnn::ele_eEleClusterOverPout) = getValueNorm(electrons.at(index_ele).eEleClusterOverPout(), 4.183f, 20.63f);
1108  get(dnn::ele_deltaEtaSuperClusterTrackAtVtx) =
1109  getValueNorm(electrons.at(index_ele).deltaEtaSuperClusterTrackAtVtx(),0.f, 0.0363f);
1110  get(dnn::ele_deltaEtaSeedClusterTrackAtCalo) =
1111  getValueNorm(electrons.at(index_ele).deltaEtaSeedClusterTrackAtCalo(), -0.0001f, 0.0512f);
1112  get(dnn::ele_deltaEtaEleClusterTrackAtCalo) =
1113  getValueNorm(electrons.at(index_ele).deltaEtaEleClusterTrackAtCalo(), -0.0001f, 0.0541f);
1114  get(dnn::ele_deltaPhiEleClusterTrackAtCalo) =
1115  getValueNorm(electrons.at(index_ele).deltaPhiEleClusterTrackAtCalo(), 0.0002f, 0.0553f);
1116  get(dnn::ele_deltaPhiSuperClusterTrackAtVtx) =
1117  getValueNorm(electrons.at(index_ele).deltaPhiSuperClusterTrackAtVtx(), 0.0001f, 0.0523f);
1118  get(dnn::ele_deltaPhiSeedClusterTrackAtCalo) =
1119  getValueNorm(electrons.at(index_ele).deltaPhiSeedClusterTrackAtCalo(), 0.0004f, 0.0777f);
1120  get(dnn::ele_mvaInput_earlyBrem) = getValue(electrons.at(index_ele).mvaInput().earlyBrem);
1121  get(dnn::ele_mvaInput_lateBrem) = getValue(electrons.at(index_ele).mvaInput().lateBrem);
1122  get(dnn::ele_mvaInput_sigmaEtaEta) = getValueNorm(electrons.at(index_ele).mvaInput().sigmaEtaEta,0.0008f, 0.0052f);
1123  get(dnn::ele_mvaInput_hadEnergy) = getValueNorm(electrons.at(index_ele).mvaInput().hadEnergy, 14.04f, 69.48f);
1124  get(dnn::ele_mvaInput_deltaEta) = getValueNorm(electrons.at(index_ele).mvaInput().deltaEta, 0.0099f, 0.0851f);
1125 
1126  const auto& gsfTrack = electrons.at(index_ele).gsfTrack();
1127  if(gsfTrack.isNonnull()){
1128  get(dnn::ele_gsfTrack_normalizedChi2) = getValueNorm(gsfTrack->normalizedChi2(), 3.049f, 10.39f);
1129  get(dnn::ele_gsfTrack_numberOfValidHits) = getValueNorm(gsfTrack->numberOfValidHits(), 16.52f, 2.806f);
1130  get(dnn::ele_rel_gsfTrack_pt) = getValueNorm(gsfTrack->pt() / electrons.at(index_ele).polarP4().pt(), 1.355f, 16.81f);
1131  get(dnn::ele_gsfTrack_pt_sig) = getValueNorm(gsfTrack->pt() / gsfTrack->ptError(), 5.046f, 3.119f);
1132  }
1133  const auto& closestCtfTrack = electrons.at(index_ele).closestCtfTrackRef();
1134  const bool has_closestCtfTrack = closestCtfTrack.isNonnull();
1135  if(has_closestCtfTrack){
1136  get(dnn::ele_has_closestCtfTrack) = has_closestCtfTrack;
1137  get(dnn::ele_closestCtfTrack_normalizedChi2) = getValueNorm(closestCtfTrack->normalizedChi2(), 2.411f, 6.98f);
1138  get(dnn::ele_closestCtfTrack_numberOfValidHits) = getValueNorm(closestCtfTrack->numberOfValidHits(), 15.16f, 5.26f);
1139  }
1140  }
1141  checkInputs(inputs, is_inner ? "egamma_inner_block" : "egamma_outer_block", dnn::NumberOfInputs);
1142  }
1143 
1144  void createMuonBlockInputs(const TauType& tau, const reco::Vertex& pv, double rho,
1145  const pat::MuonCollection& muons,
1146  const pat::PackedCandidateCollection& pfCands,
1147  const Cell& cell_map, bool is_inner)
1148  {
1149  namespace dnn = dnn_inputs_2017_v2::MuonBlockInputs;
1150 
1151  tensorflow::Tensor& inputs = *muonTensor_.at(is_inner);
1152  inputs.flat<float>().setZero();
1153 
1154  const auto& get = [&](int var_index) -> float& {
1155  return inputs.tensor<float,4>()(0, 0, 0, var_index);
1156  };
1157 
1158  const bool valid_index_pf_muon = cell_map.count(CellObjectType::PfCand_muon);
1159  const bool valid_index_muon = cell_map.count(CellObjectType::Muon);
1160 
1161  if(!cell_map.empty()){
1162  get(dnn::rho) = getValueNorm(rho, 21.49f, 9.713f);
1163  get(dnn::tau_pt) = getValueLinear(tau.polarP4().pt(), 20.f, 1000.f, true);
1164  get(dnn::tau_eta) = getValueLinear(tau.polarP4().eta(), -2.3f, 2.3f, false);
1165  get(dnn::tau_inside_ecal_crack) = getValue(isInEcalCrack(tau.polarP4().eta()));
1166  }
1167  if(valid_index_pf_muon){
1168  size_t index_pf_muon = cell_map.at(CellObjectType::PfCand_muon);
1169 
1170  get(dnn::pfCand_muon_valid) = valid_index_pf_muon;
1171  get(dnn::pfCand_muon_rel_pt) = getValueNorm(pfCands.at(index_pf_muon).polarP4().pt() / tau.polarP4().pt(),
1172  is_inner ? 0.9509f : 0.0861f, is_inner ? 0.4294f : 0.4065f);
1173  get(dnn::pfCand_muon_deta) = getValueLinear(pfCands.at(index_pf_muon).polarP4().eta() - tau.polarP4().eta(),
1174  is_inner ? -0.1f : -0.5f, is_inner ? 0.1f : 0.5f, false);
1175  get(dnn::pfCand_muon_dphi) = getValueLinear(dPhi(tau.polarP4(), pfCands.at(index_pf_muon).polarP4()),
1176  is_inner ? -0.1f : -0.5f, is_inner ? 0.1f : 0.5f, false);
1177  get(dnn::pfCand_muon_pvAssociationQuality) = getValueLinear<int>(pfCands.at(index_pf_muon).pvAssociationQuality(), 0, 7, true);
1178  get(dnn::pfCand_muon_fromPV) = getValueLinear<int>(pfCands.at(index_pf_muon).fromPV(), 0, 3, true);
1179  get(dnn::pfCand_muon_puppiWeight) = getValue(pfCands.at(index_pf_muon).puppiWeight());
1180  get(dnn::pfCand_muon_charge) = getValue(pfCands.at(index_pf_muon).charge());
1181  get(dnn::pfCand_muon_lostInnerHits) = getValue<int>(pfCands.at(index_pf_muon).lostInnerHits());
1182  get(dnn::pfCand_muon_numberOfPixelHits) = getValueLinear(pfCands.at(index_pf_muon).numberOfPixelHits(), 0, 11, true);
1183  get(dnn::pfCand_muon_vertex_dx) = getValueNorm(pfCands.at(index_pf_muon).vertex().x() - pv.position().x(), -0.0007f, 0.6869f);
1184  get(dnn::pfCand_muon_vertex_dy) = getValueNorm(pfCands.at(index_pf_muon).vertex().y() - pv.position().y(), 0.0001f, 0.6784f);
1185  get(dnn::pfCand_muon_vertex_dz) = getValueNorm(pfCands.at(index_pf_muon).vertex().z() - pv.position().z(), -0.0117f, 4.097f);
1186  get(dnn::pfCand_muon_vertex_dx_tauFL) = getValueNorm(pfCands.at(index_pf_muon).vertex().x() -
1187  pv.position().x() - tau.flightLength().x(), -0.0001f, 0.8642f);
1188  get(dnn::pfCand_muon_vertex_dy_tauFL) = getValueNorm(pfCands.at(index_pf_muon).vertex().y() -
1189  pv.position().y() - tau.flightLength().y(), 0.0004f, 0.8561f);
1190  get(dnn::pfCand_muon_vertex_dz_tauFL) = getValueNorm(pfCands.at(index_pf_muon).vertex().z() -
1191  pv.position().z() - tau.flightLength().z(), -0.0118f, 4.405f);
1192 
1193  const bool hasTrackDetails = pfCands.at(index_pf_muon).hasTrackDetails();
1194  if(hasTrackDetails){
1195  get(dnn::pfCand_muon_hasTrackDetails) = hasTrackDetails;
1196  get(dnn::pfCand_muon_dxy) = getValueNorm(pfCands.at(index_pf_muon).dxy(), -0.0045f, 0.9655f);
1197  get(dnn::pfCand_muon_dxy_sig) = getValueNorm(std::abs(pfCands.at(index_pf_muon).dxy()) /
1198  pfCands.at(index_pf_muon).dxyError(), 4.575f, 42.36f);
1199  get(dnn::pfCand_muon_dz) = getValueNorm(pfCands.at(index_pf_muon).dz(), -0.0117f, 4.097f);
1200  get(dnn::pfCand_muon_dz_sig) = getValueNorm(std::abs(pfCands.at(index_pf_muon).dz()) /
1201  pfCands.at(index_pf_muon).dzError(), 80.37f, 343.3f);
1202  get(dnn::pfCand_muon_track_chi2_ndof) = getValueNorm(pfCands.at(index_pf_muon).pseudoTrack().chi2() /
1203  pfCands.at(index_pf_muon).pseudoTrack().ndof(), 0.69f, 1.711f);
1204  get(dnn::pfCand_muon_track_ndof) = getValueNorm(pfCands.at(index_pf_muon).pseudoTrack().ndof(), 17.5f, 5.11f);
1205  }
1206  }
1207  if(valid_index_muon){
1208  size_t index_muon = cell_map.at(CellObjectType::Muon);
1209 
1210  get(dnn::muon_valid) = valid_index_muon;
1211  get(dnn::muon_rel_pt) = getValueNorm(muons.at(index_muon).polarP4().pt() / tau.polarP4().pt(),
1212  is_inner ? 0.7966f : 0.2678f, is_inner ? 3.402f : 3.592f);
1213  get(dnn::muon_deta) = getValueLinear(muons.at(index_muon).polarP4().eta() - tau.polarP4().eta(),
1214  is_inner ? -0.1f : -0.5f, is_inner ? 0.1f : 0.5f, false);
1215  get(dnn::muon_dphi) = getValueLinear(dPhi(tau.polarP4(), muons.at(index_muon).polarP4()),
1216  is_inner ? -0.1f : -0.5f, is_inner ? 0.1f : 0.5f, false);
1217  get(dnn::muon_dxy) = getValueNorm(muons.at(index_muon).dB(pat::Muon::PV2D), 0.0019f, 1.039f);
1218  get(dnn::muon_dxy_sig) = getValueNorm(std::abs(muons.at(index_muon).dB(pat::Muon::PV2D)) /
1219  muons.at(index_muon).edB(pat::Muon::PV2D), 8.98f, 71.17f);
1220 
1221  const bool normalizedChi2_valid = muons.at(index_muon).globalTrack().isNonnull() && muons.at(index_muon).normChi2() >= 0;
1222  if(normalizedChi2_valid){
1223  get(dnn::muon_normalizedChi2_valid) = normalizedChi2_valid;
1224  get(dnn::muon_normalizedChi2) = getValueNorm(muons.at(index_muon).normChi2(), 21.52f, 265.8f);
1225  if(muons.at(index_muon).innerTrack().isNonnull())
1226  get(dnn::muon_numberOfValidHits) = getValueNorm(muons.at(index_muon).numberOfValidHits(), 21.84f, 10.59f);
1227  }
1228  get(dnn::muon_segmentCompatibility) = getValue(muons.at(index_muon).segmentCompatibility());
1229  get(dnn::muon_caloCompatibility) = getValue(muons.at(index_muon).caloCompatibility());
1230 
1231  const bool pfEcalEnergy_valid = muons.at(index_muon).pfEcalEnergy() >= 0;
1232  if(pfEcalEnergy_valid){
1233  get(dnn::muon_pfEcalEnergy_valid) = pfEcalEnergy_valid;
1234  get(dnn::muon_rel_pfEcalEnergy) = getValueNorm(muons.at(index_muon).pfEcalEnergy() /
1235  muons.at(index_muon).polarP4().pt(), 0.2273f, 0.4865f);
1236  }
1237 
1238  MuonHitMatchV2 hit_match(muons.at(index_muon));
1239  static const std::map<int, std::pair<int, int>> muonMatchHitVars = {
1240  { MuonSubdetId::DT, { dnn::muon_n_matches_DT_1, dnn::muon_n_hits_DT_1 } },
1241  { MuonSubdetId::CSC, { dnn::muon_n_matches_CSC_1, dnn::muon_n_hits_CSC_1 } },
1242  { MuonSubdetId::RPC, { dnn::muon_n_matches_RPC_1, dnn::muon_n_hits_RPC_1 } }
1243  };
1244 
1245  static const std::map<int, std::vector<float>> muonMatchVarLimits = {
1246  { MuonSubdetId::DT, { 2, 2, 2, 2 } },
1247  { MuonSubdetId::CSC, { 6, 2, 2, 2 } },
1248  { MuonSubdetId::RPC, { 7, 6, 4, 4 } }
1249  };
1250 
1251  static const std::map<int, std::vector<float>> muonHitVarLimits = {
1252  { MuonSubdetId::DT, { 12, 12, 12, 8 } },
1253  { MuonSubdetId::CSC, { 24, 12, 12, 12 } },
1254  { MuonSubdetId::RPC, { 4, 4, 2, 2 } }
1255  };
1256 
1257  for(int subdet : hit_match.MuonHitMatchV2::consideredSubdets()) {
1258  const auto& matchHitVar = muonMatchHitVars.at(subdet);
1259  const auto& matchLimits = muonMatchVarLimits.at(subdet);
1260  const auto& hitLimits = muonHitVarLimits.at(subdet);
1261  for(int station = MuonHitMatchV2::first_station_id; station <= MuonHitMatchV2::last_station_id; ++station) {
1262  const unsigned n_matches = hit_match.nMatches(subdet, station);
1263  const unsigned n_hits = hit_match.nHits(subdet, station);
1264  get(matchHitVar.first + station - 1) = getValueLinear(n_matches, 0, matchLimits.at(station - 1), true);
1265  get(matchHitVar.second + station - 1) = getValueLinear(n_hits, 0, hitLimits.at(station - 1), true);
1266  }
1267  }
1268  }
1269  checkInputs(inputs, is_inner ? "muon_inner_block" : "muon_outer_block", dnn::NumberOfInputs);
1270  }
1271 
1273  const pat::PackedCandidateCollection& pfCands,
1274  const Cell& cell_map, bool is_inner)
1275  {
1276  namespace dnn = dnn_inputs_2017_v2::HadronBlockInputs;
1277 
1278  tensorflow::Tensor& inputs = *hadronsTensor_.at(is_inner);
1279  inputs.flat<float>().setZero();
1280 
1281 
1282  const auto& get = [&](int var_index) -> float& {
1283  return inputs.tensor<float,4>()(0, 0, 0, var_index);
1284  };
1285 
1286  const bool valid_chH = cell_map.count(CellObjectType::PfCand_chargedHadron);
1287  const bool valid_nH = cell_map.count(CellObjectType::PfCand_neutralHadron);
1288 
1289  if(!cell_map.empty()){
1290  get(dnn::rho) = getValueNorm(rho, 21.49f, 9.713f);
1291  get(dnn::tau_pt) = getValueLinear(tau.polarP4().pt(), 20.f, 1000.f, true);
1292  get(dnn::tau_eta) = getValueLinear(tau.polarP4().eta(), -2.3f, 2.3f, false);
1293  get(dnn::tau_inside_ecal_crack) = getValue(isInEcalCrack(tau.polarP4().eta()));
1294  }
1295  if(valid_chH){
1296  size_t index_chH = cell_map.at(CellObjectType::PfCand_chargedHadron);
1297 
1298  get(dnn::pfCand_chHad_valid) = valid_chH;
1299  get(dnn::pfCand_chHad_rel_pt) = getValueNorm(pfCands.at(index_chH).polarP4().pt() / tau.polarP4().pt(),
1300  is_inner ? 0.2564f : 0.0194f, is_inner ? 0.8607f : 0.1865f);
1301  get(dnn::pfCand_chHad_deta) = getValueLinear(pfCands.at(index_chH).polarP4().eta() - tau.polarP4().eta(),
1302  is_inner ? -0.1f : -0.5f, is_inner ? 0.1f : 0.5f, false);
1303  get(dnn::pfCand_chHad_dphi) = getValueLinear(dPhi(tau.polarP4(),pfCands.at(index_chH).polarP4()),
1304  is_inner ? -0.1f : -0.5f, is_inner ? 0.1f : 0.5f, false);
1305  get(dnn::pfCand_chHad_leadChargedHadrCand) = getValue(&pfCands.at(index_chH) ==
1306  dynamic_cast<const pat::PackedCandidate*>(tau.leadChargedHadrCand().get()));
1307  get(dnn::pfCand_chHad_pvAssociationQuality) =
1308  getValueLinear<int>(pfCands.at(index_chH).pvAssociationQuality(), 0, 7, true);
1309  get(dnn::pfCand_chHad_fromPV) = getValueLinear<int>(pfCands.at(index_chH).fromPV(), 0, 3, true);
1310  get(dnn::pfCand_chHad_puppiWeight) = getValue(pfCands.at(index_chH).puppiWeight());
1311  get(dnn::pfCand_chHad_puppiWeightNoLep) = getValue(pfCands.at(index_chH).puppiWeightNoLep());
1312  get(dnn::pfCand_chHad_charge) = getValue(pfCands.at(index_chH).charge());
1313  get(dnn::pfCand_chHad_lostInnerHits) = getValue<int>(pfCands.at(index_chH).lostInnerHits());
1314  get(dnn::pfCand_chHad_numberOfPixelHits) = getValueLinear(pfCands.at(index_chH).numberOfPixelHits(), 0, 12, true);
1315  get(dnn::pfCand_chHad_vertex_dx) = getValueNorm(pfCands.at(index_chH).vertex().x() - pv.position().x(), 0.0005f, 1.735f);
1316  get(dnn::pfCand_chHad_vertex_dy) = getValueNorm(pfCands.at(index_chH).vertex().y() - pv.position().y(), -0.0008f, 1.752f);
1317  get(dnn::pfCand_chHad_vertex_dz) = getValueNorm(pfCands.at(index_chH).vertex().z() - pv.position().z(), -0.0201f, 8.333f);
1318  get(dnn::pfCand_chHad_vertex_dx_tauFL) = getValueNorm(pfCands.at(index_chH).vertex().x() - pv.position().x()
1319  - tau.flightLength().x(), -0.0014f, 1.93f);
1320  get(dnn::pfCand_chHad_vertex_dy_tauFL) = getValueNorm(pfCands.at(index_chH).vertex().y() - pv.position().y()
1321  - tau.flightLength().y(), 0.0022f, 1.948f);
1322  get(dnn::pfCand_chHad_vertex_dz_tauFL) = getValueNorm(pfCands.at(index_chH).vertex().z() - pv.position().z()
1323  - tau.flightLength().z(), -0.0138f, 8.622f);
1324 
1325  const bool hasTrackDetails = pfCands.at(index_chH).hasTrackDetails();
1326  if(hasTrackDetails){
1327  get(dnn::pfCand_chHad_hasTrackDetails) = hasTrackDetails;
1328  get(dnn::pfCand_chHad_dxy) = getValueNorm(pfCands.at(index_chH).dxy(), -0.012f, 2.386f);
1329  get(dnn::pfCand_chHad_dxy_sig) = getValueNorm(std::abs(pfCands.at(index_chH).dxy()) /
1330  pfCands.at(index_chH).dxyError(), 6.417f, 36.28f);
1331  get(dnn::pfCand_chHad_dz) = getValueNorm(pfCands.at(index_chH).dz(), -0.0246f, 7.618f);
1332  get(dnn::pfCand_chHad_dz_sig) = getValueNorm(std::abs(pfCands.at(index_chH).dz()) /
1333  pfCands.at(index_chH).dzError(), 301.3f, 491.1f);
1334  get(dnn::pfCand_chHad_track_chi2_ndof) = pfCands.at(index_chH).pseudoTrack().ndof() > 0 ?
1335  getValueNorm(pfCands.at(index_chH).pseudoTrack().chi2() /
1336  pfCands.at(index_chH).pseudoTrack().ndof(), 0.7876f, 3.694f) : 0;
1337  get(dnn::pfCand_chHad_track_ndof) = pfCands.at(index_chH).pseudoTrack().ndof() > 0 ?
1338  getValueNorm(pfCands.at(index_chH).pseudoTrack().ndof(), 13.92f, 6.581f) : 0;
1339  }
1340  float hcal_fraction = 0.;
1341  if(pfCands.at(index_chH).pdgId() == 1 || pfCands.at(index_chH).pdgId() == 130) {
1342  hcal_fraction = pfCands.at(index_chH).hcalFraction();
1343  } else if(pfCands.at(index_chH).isIsolatedChargedHadron()) {
1344  hcal_fraction = pfCands.at(index_chH).rawHcalFraction();
1345  }
1346  get(dnn::pfCand_chHad_hcalFraction) = getValue(hcal_fraction);
1347  get(dnn::pfCand_chHad_rawCaloFraction) = getValueLinear(pfCands.at(index_chH).rawCaloFraction(), 0.f, 2.6f, true);
1348  }
1349  if(valid_nH){
1350  size_t index_nH = cell_map.at(CellObjectType::PfCand_neutralHadron);
1351 
1352  get(dnn::pfCand_nHad_valid) = valid_nH;
1353  get(dnn::pfCand_nHad_rel_pt) = getValueNorm(pfCands.at(index_nH).polarP4().pt() / tau.polarP4().pt(),
1354  is_inner ? 0.3163f : 0.0502f, is_inner ? 0.2769f : 0.4266f);
1355  get(dnn::pfCand_nHad_deta) = getValueLinear(pfCands.at(index_nH).polarP4().eta() - tau.polarP4().eta(),
1356  is_inner ? -0.1f : -0.5f, is_inner ? 0.1f : 0.5f, false);
1357  get(dnn::pfCand_nHad_dphi) = getValueLinear(dPhi(tau.polarP4(),pfCands.at(index_nH).polarP4()),
1358  is_inner ? -0.1f : -0.5f, is_inner ? 0.1f : 0.5f, false);
1359  get(dnn::pfCand_nHad_puppiWeight) = getValue(pfCands.at(index_nH).puppiWeight());
1360  get(dnn::pfCand_nHad_puppiWeightNoLep) = getValue(pfCands.at(index_nH).puppiWeightNoLep());
1361  float hcal_fraction = 0.;
1362  if(pfCands.at(index_nH).pdgId() == 1 || pfCands.at(index_nH).pdgId() == 130) {
1363  hcal_fraction = pfCands.at(index_nH).hcalFraction();
1364  } else if(pfCands.at(index_nH).isIsolatedChargedHadron()) {
1365  hcal_fraction = pfCands.at(index_nH).rawHcalFraction();
1366  }
1367  get(dnn::pfCand_nHad_hcalFraction) = getValue(hcal_fraction);
1368  }
1369  checkInputs(inputs, is_inner ? "hadron_inner_block" : "hadron_outer_block", dnn::NumberOfInputs);
1370  }
1371 
1372  template<typename dnn>
1373  tensorflow::Tensor createInputsV1(const TauType& tau, const ElectronCollection& electrons,
1374  const MuonCollection& muons) const
1375  {
1376  static constexpr bool check_all_set = false;
1377  static constexpr float default_value_for_set_check = -42;
1378 
1379  tensorflow::Tensor inputs(tensorflow::DT_FLOAT, { 1, dnn_inputs_2017v1::NumberOfInputs});
1380  const auto& get = [&](int var_index) -> float& { return inputs.matrix<float>()(0, var_index); };
1381  auto leadChargedHadrCand = dynamic_cast<const pat::PackedCandidate*>(tau.leadChargedHadrCand().get());
1382 
1383  if(check_all_set) {
1384  for(int var_index = 0; var_index < dnn::NumberOfInputs; ++var_index) {
1385  get(var_index) = default_value_for_set_check;
1386  }
1387  }
1388 
1389  get(dnn::pt) = tau.p4().pt();
1390  get(dnn::eta) = tau.p4().eta();
1391  get(dnn::mass) = tau.p4().mass();
1392  get(dnn::decayMode) = tau.decayMode();
1393  get(dnn::chargedIsoPtSum) = tau.tauID("chargedIsoPtSum");
1394  get(dnn::neutralIsoPtSum) = tau.tauID("neutralIsoPtSum");
1395  get(dnn::neutralIsoPtSumWeight) = tau.tauID("neutralIsoPtSumWeight");
1396  get(dnn::photonPtSumOutsideSignalCone) = tau.tauID("photonPtSumOutsideSignalCone");
1397  get(dnn::puCorrPtSum) = tau.tauID("puCorrPtSum");
1398  get(dnn::dxy) = tau.dxy();
1399  get(dnn::dxy_sig) = tau.dxy_Sig();
1400  get(dnn::dz) = leadChargedHadrCand ? leadChargedHadrCand->dz() : default_value;
1401  get(dnn::ip3d) = tau.ip3d();
1402  get(dnn::ip3d_sig) = tau.ip3d_Sig();
1403  get(dnn::hasSecondaryVertex) = tau.hasSecondaryVertex();
1404  get(dnn::flightLength_r) = tau.flightLength().R();
1405  get(dnn::flightLength_dEta) = dEta(tau.flightLength(), tau.p4());
1406  get(dnn::flightLength_dPhi) = dPhi(tau.flightLength(), tau.p4());
1407  get(dnn::flightLength_sig) = tau.flightLengthSig();
1408  get(dnn::leadChargedHadrCand_pt) = leadChargedHadrCand ? leadChargedHadrCand->p4().Pt() : default_value;
1409  get(dnn::leadChargedHadrCand_dEta) = leadChargedHadrCand
1410  ? dEta(leadChargedHadrCand->p4(), tau.p4()) : default_value;
1411  get(dnn::leadChargedHadrCand_dPhi) = leadChargedHadrCand
1412  ? dPhi(leadChargedHadrCand->p4(), tau.p4()) : default_value;
1413  get(dnn::leadChargedHadrCand_mass) = leadChargedHadrCand
1414  ? leadChargedHadrCand->p4().mass() : default_value;
1419  get(dnn::leadingTrackNormChi2) = tau.leadingTrackNormChi2();
1420  get(dnn::e_ratio) = reco::tau::eratio(tau);
1421  get(dnn::gj_angle_diff) = calculateGottfriedJacksonAngleDifference(tau);
1422  get(dnn::n_photons) = reco::tau::n_photons_total(tau);
1423  get(dnn::emFraction) = tau.emFraction_MVA();
1424  get(dnn::has_gsf_track) = leadChargedHadrCand && std::abs(leadChargedHadrCand->pdgId()) == 11;
1425  get(dnn::inside_ecal_crack) = isInEcalCrack(tau.p4().Eta());
1426  auto gsf_ele = findMatchedElectron(tau, electrons, 0.3);
1427  get(dnn::gsf_ele_matched) = gsf_ele != nullptr;
1428  get(dnn::gsf_ele_pt) = gsf_ele != nullptr ? gsf_ele->p4().Pt() : default_value;
1429  get(dnn::gsf_ele_dEta) = gsf_ele != nullptr ? dEta(gsf_ele->p4(), tau.p4()) : default_value;
1430  get(dnn::gsf_ele_dPhi) = gsf_ele != nullptr ? dPhi(gsf_ele->p4(), tau.p4()) : default_value;
1431  get(dnn::gsf_ele_mass) = gsf_ele != nullptr ? gsf_ele->p4().mass() : default_value;
1432  calculateElectronClusterVars(gsf_ele, get(dnn::gsf_ele_Ee), get(dnn::gsf_ele_Egamma));
1433  get(dnn::gsf_ele_Pin) = gsf_ele != nullptr ? gsf_ele->trackMomentumAtVtx().R() : default_value;
1434  get(dnn::gsf_ele_Pout) = gsf_ele != nullptr ? gsf_ele->trackMomentumOut().R() : default_value;
1435  get(dnn::gsf_ele_EtotOverPin) = get(dnn::gsf_ele_Pin) > 0
1436  ? (get(dnn::gsf_ele_Ee) + get(dnn::gsf_ele_Egamma)) / get(dnn::gsf_ele_Pin)
1437  : default_value;
1438  get(dnn::gsf_ele_Eecal) = gsf_ele != nullptr ? gsf_ele->ecalEnergy() : default_value;
1439  get(dnn::gsf_ele_dEta_SeedClusterTrackAtCalo) = gsf_ele != nullptr
1440  ? gsf_ele->deltaEtaSeedClusterTrackAtCalo() : default_value;
1441  get(dnn::gsf_ele_dPhi_SeedClusterTrackAtCalo) = gsf_ele != nullptr
1442  ? gsf_ele->deltaPhiSeedClusterTrackAtCalo() : default_value;
1443  get(dnn::gsf_ele_mvaIn_sigmaEtaEta) = gsf_ele != nullptr
1444  ? gsf_ele->mvaInput().sigmaEtaEta : default_value;
1445  get(dnn::gsf_ele_mvaIn_hadEnergy) = gsf_ele != nullptr ? gsf_ele->mvaInput().hadEnergy : default_value;
1446  get(dnn::gsf_ele_mvaIn_deltaEta) = gsf_ele != nullptr ? gsf_ele->mvaInput().deltaEta : default_value;
1447 
1448  get(dnn::gsf_ele_Chi2NormGSF) = default_value;
1449  get(dnn::gsf_ele_GSFNumHits) = default_value;
1450  get(dnn::gsf_ele_GSFTrackResol) = default_value;
1451  get(dnn::gsf_ele_GSFTracklnPt) = default_value;
1452  if(gsf_ele != nullptr && gsf_ele->gsfTrack().isNonnull()) {
1453  get(dnn::gsf_ele_Chi2NormGSF) = gsf_ele->gsfTrack()->normalizedChi2();
1454  get(dnn::gsf_ele_GSFNumHits) = gsf_ele->gsfTrack()->numberOfValidHits();
1455  if(gsf_ele->gsfTrack()->pt() > 0) {
1456  get(dnn::gsf_ele_GSFTrackResol) = gsf_ele->gsfTrack()->ptError() / gsf_ele->gsfTrack()->pt();
1457  get(dnn::gsf_ele_GSFTracklnPt) = std::log10(gsf_ele->gsfTrack()->pt());
1458  }
1459  }
1460 
1461  get(dnn::gsf_ele_Chi2NormKF) = default_value;
1462  get(dnn::gsf_ele_KFNumHits) = default_value;
1463  if(gsf_ele != nullptr && gsf_ele->closestCtfTrackRef().isNonnull()) {
1464  get(dnn::gsf_ele_Chi2NormKF) = gsf_ele->closestCtfTrackRef()->normalizedChi2();
1465  get(dnn::gsf_ele_KFNumHits) = gsf_ele->closestCtfTrackRef()->numberOfValidHits();
1466  }
1467  get(dnn::leadChargedCand_etaAtEcalEntrance) = tau.etaAtEcalEntranceLeadChargedCand();
1468  get(dnn::leadChargedCand_pt) = tau.ptLeadChargedCand();
1469 
1470  get(dnn::leadChargedHadrCand_HoP) = default_value;
1471  get(dnn::leadChargedHadrCand_EoP) = default_value;
1472  if(tau.leadChargedHadrCand()->pt() > 0) {
1473  get(dnn::leadChargedHadrCand_HoP) = tau.hcalEnergyLeadChargedHadrCand()
1474  / tau.leadChargedHadrCand()->pt();
1475  get(dnn::leadChargedHadrCand_EoP) = tau.ecalEnergyLeadChargedHadrCand()
1476  / tau.leadChargedHadrCand()->pt();
1477  }
1478 
1479  MuonHitMatchV1 muon_hit_match;
1480  if(tau.leadPFChargedHadrCand().isNonnull() && tau.leadPFChargedHadrCand()->muonRef().isNonnull())
1481  muon_hit_match.addMatchedMuon(*tau.leadPFChargedHadrCand()->muonRef(), tau);
1482 
1483  auto matched_muons = muon_hit_match.findMatchedMuons(tau, muons, 0.3, 5);
1484  for(auto muon : matched_muons)
1485  muon_hit_match.addMatchedMuon(*muon, tau);
1486  muon_hit_match.fillTensor<dnn>(get, tau, default_value);
1487 
1488  LorentzVectorXYZ signalChargedHadrCands_sumIn, signalChargedHadrCands_sumOut;
1489  processSignalPFComponents(tau, tau.signalChargedHadrCands(),
1490  signalChargedHadrCands_sumIn, signalChargedHadrCands_sumOut,
1491  get(dnn::signalChargedHadrCands_sum_innerSigCone_pt),
1492  get(dnn::signalChargedHadrCands_sum_innerSigCone_dEta),
1493  get(dnn::signalChargedHadrCands_sum_innerSigCone_dPhi),
1494  get(dnn::signalChargedHadrCands_sum_innerSigCone_mass),
1495  get(dnn::signalChargedHadrCands_sum_outerSigCone_pt),
1496  get(dnn::signalChargedHadrCands_sum_outerSigCone_dEta),
1497  get(dnn::signalChargedHadrCands_sum_outerSigCone_dPhi),
1498  get(dnn::signalChargedHadrCands_sum_outerSigCone_mass),
1499  get(dnn::signalChargedHadrCands_nTotal_innerSigCone),
1500  get(dnn::signalChargedHadrCands_nTotal_outerSigCone));
1501 
1502  LorentzVectorXYZ signalNeutrHadrCands_sumIn, signalNeutrHadrCands_sumOut;
1503  processSignalPFComponents(tau, tau.signalNeutrHadrCands(),
1504  signalNeutrHadrCands_sumIn, signalNeutrHadrCands_sumOut,
1505  get(dnn::signalNeutrHadrCands_sum_innerSigCone_pt),
1506  get(dnn::signalNeutrHadrCands_sum_innerSigCone_dEta),
1507  get(dnn::signalNeutrHadrCands_sum_innerSigCone_dPhi),
1508  get(dnn::signalNeutrHadrCands_sum_innerSigCone_mass),
1509  get(dnn::signalNeutrHadrCands_sum_outerSigCone_pt),
1510  get(dnn::signalNeutrHadrCands_sum_outerSigCone_dEta),
1511  get(dnn::signalNeutrHadrCands_sum_outerSigCone_dPhi),
1512  get(dnn::signalNeutrHadrCands_sum_outerSigCone_mass),
1513  get(dnn::signalNeutrHadrCands_nTotal_innerSigCone),
1514  get(dnn::signalNeutrHadrCands_nTotal_outerSigCone));
1515 
1516 
1517  LorentzVectorXYZ signalGammaCands_sumIn, signalGammaCands_sumOut;
1518  processSignalPFComponents(tau, tau.signalGammaCands(),
1519  signalGammaCands_sumIn, signalGammaCands_sumOut,
1520  get(dnn::signalGammaCands_sum_innerSigCone_pt),
1521  get(dnn::signalGammaCands_sum_innerSigCone_dEta),
1522  get(dnn::signalGammaCands_sum_innerSigCone_dPhi),
1523  get(dnn::signalGammaCands_sum_innerSigCone_mass),
1524  get(dnn::signalGammaCands_sum_outerSigCone_pt),
1525  get(dnn::signalGammaCands_sum_outerSigCone_dEta),
1526  get(dnn::signalGammaCands_sum_outerSigCone_dPhi),
1527  get(dnn::signalGammaCands_sum_outerSigCone_mass),
1528  get(dnn::signalGammaCands_nTotal_innerSigCone),
1529  get(dnn::signalGammaCands_nTotal_outerSigCone));
1530 
1531  LorentzVectorXYZ isolationChargedHadrCands_sum;
1532  processIsolationPFComponents(tau, tau.isolationChargedHadrCands(), isolationChargedHadrCands_sum,
1533  get(dnn::isolationChargedHadrCands_sum_pt),
1534  get(dnn::isolationChargedHadrCands_sum_dEta),
1535  get(dnn::isolationChargedHadrCands_sum_dPhi),
1536  get(dnn::isolationChargedHadrCands_sum_mass),
1537  get(dnn::isolationChargedHadrCands_nTotal));
1538 
1539  LorentzVectorXYZ isolationNeutrHadrCands_sum;
1540  processIsolationPFComponents(tau, tau.isolationNeutrHadrCands(), isolationNeutrHadrCands_sum,
1541  get(dnn::isolationNeutrHadrCands_sum_pt),
1542  get(dnn::isolationNeutrHadrCands_sum_dEta),
1543  get(dnn::isolationNeutrHadrCands_sum_dPhi),
1544  get(dnn::isolationNeutrHadrCands_sum_mass),
1545  get(dnn::isolationNeutrHadrCands_nTotal));
1546 
1547  LorentzVectorXYZ isolationGammaCands_sum;
1548  processIsolationPFComponents(tau, tau.isolationGammaCands(), isolationGammaCands_sum,
1549  get(dnn::isolationGammaCands_sum_pt),
1550  get(dnn::isolationGammaCands_sum_dEta),
1551  get(dnn::isolationGammaCands_sum_dPhi),
1552  get(dnn::isolationGammaCands_sum_mass),
1553  get(dnn::isolationGammaCands_nTotal));
1554 
1555  get(dnn::tau_visMass_innerSigCone) = (signalGammaCands_sumIn + signalChargedHadrCands_sumIn).mass();
1556 
1557  if(check_all_set) {
1558  for(int var_index = 0; var_index < dnn::NumberOfInputs; ++var_index) {
1559  if(get(var_index) == default_value_for_set_check)
1560  throw cms::Exception("DeepTauId: variable with index = ") << var_index << " is not set.";
1561  }
1562  }
1563 
1564  return inputs;
1565  }
1566 
1567  static void calculateElectronClusterVars(const pat::Electron* ele, float& elecEe, float& elecEgamma)
1568  {
1569  if(ele) {
1570  elecEe = elecEgamma = 0;
1571  auto superCluster = ele->superCluster();
1572  if(superCluster.isNonnull() && superCluster.isAvailable() && superCluster->clusters().isNonnull()
1573  && superCluster->clusters().isAvailable()) {
1574  for(auto iter = superCluster->clustersBegin(); iter != superCluster->clustersEnd(); ++iter) {
1575  const double energy = (*iter)->energy();
1576  if(iter == superCluster->clustersBegin()) elecEe += energy;
1577  else elecEgamma += energy;
1578  }
1579  }
1580  } else {
1581  elecEe = elecEgamma = default_value;
1582  }
1583  }
1584 
1585  template<typename CandidateCollection>
1587  LorentzVectorXYZ& p4_inner, LorentzVectorXYZ& p4_outer,
1588  float& pt_inner, float& dEta_inner, float& dPhi_inner, float& m_inner,
1589  float& pt_outer, float& dEta_outer, float& dPhi_outer, float& m_outer,
1590  float& n_inner, float& n_outer)
1591  {
1592  p4_inner = LorentzVectorXYZ(0, 0, 0, 0);
1593  p4_outer = LorentzVectorXYZ(0, 0, 0, 0);
1594  n_inner = 0;
1595  n_outer = 0;
1596 
1597  const double innerSigCone_radius = getInnerSignalConeRadius(tau.pt());
1598  for(const auto& cand : candidates) {
1599  const double dR = reco::deltaR(cand->p4(), tau.leadChargedHadrCand()->p4());
1600  const bool isInside_innerSigCone = dR < innerSigCone_radius;
1601  if(isInside_innerSigCone) {
1602  p4_inner += cand->p4();
1603  ++n_inner;
1604  } else {
1605  p4_outer += cand->p4();
1606  ++n_outer;
1607  }
1608  }
1609 
1610  pt_inner = n_inner != 0 ? p4_inner.Pt() : default_value;
1611  dEta_inner = n_inner != 0 ? dEta(p4_inner, tau.p4()) : default_value;
1612  dPhi_inner = n_inner != 0 ? dPhi(p4_inner, tau.p4()) : default_value;
1613  m_inner = n_inner != 0 ? p4_inner.mass() : default_value;
1614 
1615  pt_outer = n_outer != 0 ? p4_outer.Pt() : default_value;
1616  dEta_outer = n_outer != 0 ? dEta(p4_outer, tau.p4()) : default_value;
1617  dPhi_outer = n_outer != 0 ? dPhi(p4_outer, tau.p4()) : default_value;
1618  m_outer = n_outer != 0 ? p4_outer.mass() : default_value;
1619  }
1620 
1621  template<typename CandidateCollection>
1623  LorentzVectorXYZ& p4, float& pt, float& d_eta, float& d_phi, float& m,
1624  float& n)
1625  {
1626  p4 = LorentzVectorXYZ(0, 0, 0, 0);
1627  n = 0;
1628 
1629  for(const auto& cand : candidates) {
1630  p4 += cand->p4();
1631  ++n;
1632  }
1633 
1634  pt = n != 0 ? p4.Pt() : default_value;
1635  d_eta = n != 0 ? dEta(p4, tau.p4()) : default_value;
1636  d_phi = n != 0 ? dPhi(p4, tau.p4()) : default_value;
1637  m = n != 0 ? p4.mass() : default_value;
1638  }
1639 
1640  static double getInnerSignalConeRadius(double pt)
1641  {
1642  static constexpr double min_pt = 30., min_radius = 0.05, cone_opening_coef = 3.;
1643  // This is equivalent of the original formula (std::max(std::min(0.1, 3.0/pt), 0.05)
1644  return std::max(cone_opening_coef / std::max(pt, min_pt), min_radius);
1645  }
1646 
1647  // Copied from https://github.com/cms-sw/cmssw/blob/CMSSW_9_4_X/RecoTauTag/RecoTau/plugins/PATTauDiscriminationByMVAIsolationRun2.cc#L218
1648  static bool calculateGottfriedJacksonAngleDifference(const pat::Tau& tau, double& gj_diff)
1649  {
1650  if(tau.hasSecondaryVertex()) {
1651  static constexpr double mTau = 1.77682;
1652  const double mAOne = tau.p4().M();
1653  const double pAOneMag = tau.p();
1654  const double argumentThetaGJmax = (std::pow(mTau,2) - std::pow(mAOne,2) ) / ( 2 * mTau * pAOneMag );
1655  const double argumentThetaGJmeasured = tau.p4().Vect().Dot(tau.flightLength())
1656  / ( pAOneMag * tau.flightLength().R() );
1657  if ( std::abs(argumentThetaGJmax) <= 1. && std::abs(argumentThetaGJmeasured) <= 1. ) {
1658  double thetaGJmax = std::asin( argumentThetaGJmax );
1659  double thetaGJmeasured = std::acos( argumentThetaGJmeasured );
1660  gj_diff = thetaGJmeasured - thetaGJmax;
1661  return true;
1662  }
1663  }
1664  return false;
1665  }
1666 
1668  {
1669  double gj_diff;
1670  if(calculateGottfriedJacksonAngleDifference(tau, gj_diff))
1671  return static_cast<float>(gj_diff);
1672  return default_value;
1673  }
1674 
1675  static bool isInEcalCrack(double eta)
1676  {
1677  const double abs_eta = std::abs(eta);
1678  return abs_eta > 1.46 && abs_eta < 1.558;
1679  }
1680 
1682  double deltaR)
1683  {
1684  const double dR2 = deltaR*deltaR;
1685  const pat::Electron* matched_ele = nullptr;
1686  for(const auto& ele : electrons) {
1687  if(reco::deltaR2(tau.p4(), ele.p4()) < dR2 && (!matched_ele || matched_ele->pt() < ele.pt())) {
1688  matched_ele = &ele;
1689  }
1690  }
1691  return matched_ele;
1692  }
1693 
1694 private:
1699  const unsigned version;
1700  const int debug_level;
1701  std::shared_ptr<tensorflow::Tensor> tauBlockTensor_;
1702  std::array<std::shared_ptr<tensorflow::Tensor>, 2> eGammaTensor_, muonTensor_, hadronsTensor_,
1703  convTensor_, zeroOutputTensor_;
1704 };
1705 
size
Write out results.
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:22
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
Definition: DeepTauId.cc:567
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 ...
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:251
edm::EDGetTokenT< ElectronCollection > electrons_token_
Definition: DeepTauId.cc:1695
const PolarLorentzVector & polarP4() const final
four-momentum Lorentz vector
void createHadronsBlockInputs(const TauType &tau, const reco::Vertex &pv, double rho, const pat::PackedCandidateCollection &pfCands, const Cell &cell_map, bool is_inner)
Definition: DeepTauId.cc:1272
static std::unique_ptr< deep_tau::DeepTauCache > initializeGlobalCache(const edm::ParameterSet &cfg)
Definition: DeepTauId.cc:643
void createConvFeatures(const TauType &tau, const reco::Vertex &pv, double rho, const pat::ElectronCollection &electrons, const pat::MuonCollection &muons, const pat::PackedCandidateCollection &pfCands, const CellGrid &grid, bool is_inner)
Definition: DeepTauId.cc:847
int pdgId() const override
PDG identifier.
float pt_weighted_dr_signal(const reco::PFTau &tau, int dm)
float hcalEnergyLeadChargedHadrCand() const
return hcal energy from LeadChargedHadrCand
Definition: Tau.h:346
static float getValueLinear(T value, float min_value, float max_value, bool positive)
Definition: DeepTauId.cc:662
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
float dxy() const
Definition: Tau.h:315
int NumberOfOutputs
Definition: DeepTauId.cc:13
void getPredictionsV2(const TauType &tau, const pat::ElectronCollection &electrons, const pat::MuonCollection &muons, const pat::PackedCandidateCollection &pfCands, const reco::Vertex &pv, double rho, std::vector< tensorflow::Tensor > &pred_vector)
Definition: DeepTauId.cc:769
T const * get() const
Returns C++ pointer to the item.
Definition: Ptr.h:159
static double getInnerSignalConeRadius(double pt)
Definition: DeepTauId.cc:1640
std::vector< pat::PackedCandidate > PackedCandidateCollection
const reco::PFCandidatePtr leadPFChargedHadrCand() const
static void globalEndJob(const DeepTauCache *cache)
Definition: DeepTauBase.h:91
static bool isInEcalCrack(double eta)
Definition: DeepTauId.cc:1675
double pt() const final
transverse momentum
int charge() const final
electric charge
Definition: LeafCandidate.h:91
static void processIsolationPFComponents(const pat::Tau &tau, const CandidateCollection &candidates, LorentzVectorXYZ &p4, float &pt, float &d_eta, float &d_phi, float &m, float &n)
Definition: DeepTauId.cc:1622
void createTauBlockInputs(const TauType &tau, const reco::Vertex &pv, double rho)
Definition: DeepTauId.cc:879
float ip3d_Sig() const
float tauID(const std::string &name) const
void countMatches(const reco::Muon &muon, std::vector< int > &numMatchesDT, std::vector< int > &numMatchesCSC, std::vector< int > &numMatchesRPC)
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
const std::map< ValueQuantityType, double > min_value
const Point & position() const
position
Definition: Vertex.h:109
std::map< std::string, Output > OutputCollection
Definition: DeepTauBase.h:82
static const double deltaEta
Definition: CaloConstants.h:8
static const OutputCollection & GetOutputs()
Definition: DeepTauId.cc:556
static std::string const input
Definition: EdmProvDump.cc:48
const Double_t pi
DeepTauId(const edm::ParameterSet &cfg, const deep_tau::DeepTauCache *cache)
Definition: DeepTauId.cc:598
float ip3d_error() const
Definition: Tau.h:329
void fillGrids(const TauType &tau, const Collection &objects, CellGrid &inner_grid, CellGrid &outer_grid)
Definition: DeepTauId.cc:792
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
std::string output_layer_
Definition: DeepTauId.cc:1698
std::vector< Electron > ElectronCollection
Definition: Electron.h:37
tensorflow::Tensor createInputsV1(const TauType &tau, const ElectronCollection &electrons, const MuonCollection &muons) const
Definition: DeepTauId.cc:1373
static float getValue(T value)
Definition: DeepTauId.cc:656
reco::TrackRef outerTrack() const override
reference to Track reconstructed in the muon detector only (reimplemented from reco::Muon) ...
Definition: Muon.h:77
CellObjectType
Definition: DeepTauId.cc:457
static float calculateGottfriedJacksonAngleDifference(const pat::Tau &tau)
Definition: DeepTauId.cc:1667
float ip3d() const
Definition: Tau.h:328
float pt_weighted_deta_strip(const reco::PFTau &tau, int dm)
double p4[4]
Definition: TauolaWrapper.h:92
const pat::tau::TauPFEssential::Vector & flightLength() const
Definition: Tau.h:322
std::array< std::shared_ptr< tensorflow::Tensor >, 2 > zeroOutputTensor_
Definition: DeepTauId.cc:1702
float ecalEnergyLeadChargedHadrCand() const
Definition: Tau.h:344
static float getValueNorm(T value, float mean, float sigma, float n_sigmas_max=5)
Definition: DeepTauId.cc:673
void getPredictionsV1(const TauType &tau, const pat::ElectronCollection &electrons, const pat::MuonCollection &muons, std::vector< tensorflow::Tensor > &pred_vector)
Definition: DeepTauId.cc:762
pat::ElectronCollection ElectronCollection
Definition: DeepTauBase.h:65
def pv(vc)
Definition: MetAnalyzer.py:7
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
float pt_weighted_dr_iso(const reco::PFTau &tau, int dm)
T operator[](int i) const
double f[11][100]
const LorentzVector & p4() const final
four-momentum Lorentz vector
Definition: LeafCandidate.h:99
static void globalEndJob(const deep_tau::DeepTauCache *cache_)
Definition: DeepTauId.cc:648
bool hasSecondaryVertex() const
Definition: Tau.h:321
#define end
Definition: vmac.h:39
Definition: value.py:1
const reco::CandidatePtr leadChargedHadrCand() const
ParameterDescriptionBase * add(U const &iLabel, T const &value)
Analysis-level tau class.
Definition: Tau.h:56
void getPartialPredictions(tensorflow::Tensor &convTensor, bool is_inner, int eta_index, int phi_index)
Definition: DeepTauId.cc:828
std::shared_ptr< tensorflow::Tensor > tauBlockTensor_
Definition: DeepTauId.cc:1701
#define M_PI
bool isNonnull() const
Checks for non-null.
Definition: Ptr.h:168
const unsigned version
Definition: DeepTauId.cc:1699
constexpr auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:28
int k[5][pyjets_maxn]
float ptLeadChargedCand() const
return pt from LeadChargedCand
Definition: Tau.h:354
const pat::tau::TauPFEssential::Point & dxy_PCA() const
Definition: Tau.h:314
tensorflow::Tensor getPredictions(edm::Event &event, const edm::EventSetup &es, edm::Handle< TauCollection > taus) override
Definition: DeepTauId.cc:723
double p() const final
magnitude of momentum vector
pat::MuonCollection MuonCollection
Definition: DeepTauBase.h:66
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:16
float pt_weighted_dphi_strip(const reco::PFTau &tau, int dm)
int decayMode() const
reconstructed tau decay mode (specific to PFTau)
Definition: Tau.h:366
float eratio(const reco::PFTau &tau)
return ratio of energy in ECAL over sum of energy in ECAL and HCAL
static constexpr int RPC
Definition: MuonSubdetId.h:14
void createEgammaBlockInputs(const TauType &tau, const reco::Vertex &pv, double rho, const pat::ElectronCollection &electrons, const pat::PackedCandidateCollection &pfCands, const Cell &cell_map, bool is_inner)
Definition: DeepTauId.cc:964
void checkInputs(const tensorflow::Tensor &inputs, const char *block_name, int n_inputs, int n_eta=1, int n_phi=1) const
Definition: DeepTauId.cc:702
Analysis-level electron class.
Definition: Electron.h:52
std::vector< MuonChamberMatch > & matches()
get muon matching information
Definition: Muon.h:144
void add(std::string const &label, ParameterSetDescription const &psetDescription)
static std::unique_ptr< DeepTauCache > initializeGlobalCache(const edm::ParameterSet &cfg)
Definition: DeepTauBase.cc:116
std::vector< Muon > MuonCollection
Definition: Muon.h:34
static void processSignalPFComponents(const pat::Tau &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:1586
void setCellConvFeatures(tensorflow::Tensor &convTensor, const tensorflow::Tensor &features, int eta_index, int phi_index)
Definition: DeepTauId.cc:872
static bool calculateGottfriedJacksonAngleDifference(const pat::Tau &tau, double &gj_diff)
Definition: DeepTauId.cc:1648
float emFraction_MVA() const
return emFraction_MVA
Definition: Tau.h:356
bool operator<(DTCELinkId const &lhs, DTCELinkId const &rhs)
Definition: DTCELinkId.h:73
static bool calculateElectronClusterVarsV2(const pat::Electron &ele, float &cc_ele_energy, float &cc_gamma_energy, int &cc_n_gamma)
Definition: DeepTauId.cc:680
float flightLengthSig() const
Definition: Tau.h:323
float dxy_Sig() const
#define begin
Definition: vmac.h:32
HLT enums.
edm::EDGetTokenT< MuonCollection > muons_token_
Definition: DeepTauId.cc:1696
#define Output(cl)
Definition: vmac.h:194
float leadingTrackNormChi2() const
return normalized chi2 of leading track
Definition: Tau.h:339
def cache(function)
Definition: utilities.py:3
const std::map< ValueQuantityType, double > max_value
static const pat::Electron * findMatchedElectron(const pat::Tau &tau, const pat::ElectronCollection &electrons, double deltaR)
Definition: DeepTauId.cc:1681
void run(Session *session, const NamedTensorList &inputs, const std::vector< std::string > &outputNames, const std::vector< std::string > &targetNodes, std::vector< Tensor > *outputs)
Definition: TensorFlow.cc:210
const JetExtendedData & getValue(const Container &, const reco::JetBaseRef &)
get value for the association. Throw exception if no association found
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
const int debug_level
Definition: DeepTauId.cc:1700
vars
Definition: DeepTauId.cc:77
static constexpr int DT
Definition: MuonSubdetId.h:12
float etaAtEcalEntranceLeadChargedCand() const
return etaAtEcalEntrance from LeadChargedCand
Definition: Tau.h:352
edm::OwnVector< Candidate > CandidateCollection
collection of Candidate objects
Definition: CandidateFwd.h:21
long double T
static constexpr int CSC
Definition: MuonSubdetId.h:13
edm::EDGetTokenT< double > rho_token_
Definition: DeepTauId.cc:1697
static void calculateElectronClusterVars(const pat::Electron *ele, float &elecEe, float &elecEgamma)
Definition: DeepTauId.cc:1567
static const std::string subdets[7]
Definition: TrackUtils.cc:60
Analysis-level muon class.
Definition: Muon.h:50
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzE4D< double >> LorentzVectorXYZ
Definition: DeepTauBase.h:67
reco::SuperClusterRef superCluster() const override
override the reco::GsfElectron::superCluster method, to access the internal storage of the superclust...
void countHits(const reco::Muon &muon, std::vector< int > &numHitsDT, std::vector< int > &numHitsCSC, std::vector< int > &numHitsRPC)
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
#define constexpr
Definition: event.py:1
void createMuonBlockInputs(const TauType &tau, const reco::Vertex &pv, double rho, const pat::MuonCollection &muons, const pat::PackedCandidateCollection &pfCands, const Cell &cell_map, bool is_inner)
Definition: DeepTauId.cc:1144
float dxy_error() const
Definition: Tau.h:316