CMS 3D CMS Logo

DeepTauId.cc
Go to the documentation of this file.
1 /*
2  * \class DeepTauId
3  *
4  * Tau identification using Deep NN.
5  *
6  * \author Konstantin Androsov, INFN Pisa
7  * Christian Veelken, Tallinn
8  */
9 
13 
14 namespace deep_tau {
15  class DeepTauCache {
16  public:
17  using GraphPtr = std::shared_ptr<tensorflow::GraphDef>;
18 
19  DeepTauCache(const std::map<std::string, std::string>& graph_names, bool mem_mapped) {
20  for (const auto& graph_entry : graph_names) {
21  // Backend : to be parametrized from the python config
23 
24  const std::string& entry_name = graph_entry.first;
25  const std::string& graph_file = graph_entry.second;
26  if (mem_mapped) {
27  memmappedEnv_[entry_name] = std::make_unique<tensorflow::MemmappedEnv>(tensorflow::Env::Default());
28  const tensorflow::Status mmap_status = memmappedEnv_.at(entry_name)->InitializeFromFile(graph_file);
29  if (!mmap_status.ok()) {
30  throw cms::Exception("DeepTauCache: unable to initalize memmapped environment for ")
31  << graph_file << ". \n"
32  << mmap_status.ToString();
33  }
34 
35  graphs_[entry_name] = std::make_unique<tensorflow::GraphDef>();
36  const tensorflow::Status load_graph_status =
37  ReadBinaryProto(memmappedEnv_.at(entry_name).get(),
38  tensorflow::MemmappedFileSystem::kMemmappedPackageDefaultGraphDef,
39  graphs_.at(entry_name).get());
40  if (!load_graph_status.ok())
41  throw cms::Exception("DeepTauCache: unable to load graph from ") << graph_file << ". \n"
42  << load_graph_status.ToString();
43 
44  options.getSessionOptions().config.mutable_graph_options()->mutable_optimizer_options()->set_opt_level(
45  ::tensorflow::OptimizerOptions::L0);
46  options.getSessionOptions().env = memmappedEnv_.at(entry_name).get();
47 
48  sessions_[entry_name] = tensorflow::createSession(graphs_.at(entry_name).get(), options);
49 
50  } else {
51  graphs_[entry_name].reset(tensorflow::loadGraphDef(graph_file));
52  sessions_[entry_name] = tensorflow::createSession(graphs_.at(entry_name).get(), options);
53  }
54  }
55  };
57  for (auto& session_entry : sessions_)
58  tensorflow::closeSession(session_entry.second);
59  }
60 
61  // A Session allows concurrent calls to Run(), though a Session must
62  // be created / extended by a single thread.
63  tensorflow::Session& getSession(const std::string& name = "") const { return *sessions_.at(name); }
64  const tensorflow::GraphDef& getGraph(const std::string& name = "") const { return *graphs_.at(name); }
65 
66  private:
67  std::map<std::string, GraphPtr> graphs_;
68  std::map<std::string, tensorflow::Session*> sessions_;
69  std::map<std::string, std::unique_ptr<tensorflow::MemmappedEnv>> memmappedEnv_;
70  };
71 } // namespace deep_tau
72 
73 class DeepTauIdWrapper : public edm::stream::EDProducer<edm::GlobalCache<deep_tau::DeepTauCache>> {
74 public:
76 };
77 
78 class DeepTauId : public DeepTauIdBase<DeepTauIdWrapper> {
79 public:
80  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
83  desc.add<std::vector<std::string>>("graph_file",
84  {"RecoTauTag/TrainingFiles/data/DeepTauId/deepTau_2017v2p6_e6.pb"});
85  descriptions.add("DeepTau", desc);
86  }
87 
88 public:
91  if (version_ == 2) {
92  using namespace dnn_inputs_v2;
93  if (sub_version_ == 1) {
94  tauBlockTensor_ = std::make_unique<tensorflow::Tensor>(
95  tensorflow::DT_FLOAT, tensorflow::TensorShape{1, TauBlockInputs::NumberOfInputs});
96  } else if (sub_version_ == 5) {
97  tauBlockTensor_ = std::make_unique<tensorflow::Tensor>(
98  tensorflow::DT_FLOAT,
99  tensorflow::TensorShape{1,
100  static_cast<int>(TauBlockInputs::NumberOfInputs) -
101  static_cast<int>(TauBlockInputs::varsToDrop.size())});
102  }
103 
104  for (size_t n = 0; n < 2; ++n) {
105  const bool is_inner = n == 0;
106  const auto n_cells = is_inner ? number_of_inner_cell : number_of_outer_cell;
107  eGammaTensor_[is_inner] = std::make_unique<tensorflow::Tensor>(
108  tensorflow::DT_FLOAT, tensorflow::TensorShape{1, 1, 1, EgammaBlockInputs::NumberOfInputs});
109  muonTensor_[is_inner] = std::make_unique<tensorflow::Tensor>(
110  tensorflow::DT_FLOAT, tensorflow::TensorShape{1, 1, 1, MuonBlockInputs::NumberOfInputs});
111  hadronsTensor_[is_inner] = std::make_unique<tensorflow::Tensor>(
112  tensorflow::DT_FLOAT, tensorflow::TensorShape{1, 1, 1, HadronBlockInputs::NumberOfInputs});
113  convTensor_[is_inner] = std::make_unique<tensorflow::Tensor>(
114  tensorflow::DT_FLOAT, tensorflow::TensorShape{1, n_cells, n_cells, number_of_conv_features});
115  zeroOutputTensor_[is_inner] = std::make_unique<tensorflow::Tensor>(
116  tensorflow::DT_FLOAT, tensorflow::TensorShape{1, 1, 1, number_of_conv_features});
117 
118  eGammaTensor_[is_inner]->flat<float>().setZero();
119  muonTensor_[is_inner]->flat<float>().setZero();
120  hadronsTensor_[is_inner]->flat<float>().setZero();
121 
122  setCellConvFeatures(*zeroOutputTensor_[is_inner], getPartialPredictions(is_inner), 0, 0, 0);
123  }
124  }
125  }
126 
127  void produce(edm::Event& event, const edm::EventSetup& es) override {
129  event.getByToken(tausToken_, taus);
130 
131  // store empty output collection(s) if tau collection is empty
132  if (taus->empty()) {
133  const tensorflow::Tensor emptyPrediction(tensorflow::DT_FLOAT, {0, deep_tau::NumberOfOutputs});
134  createOutputs(event, emptyPrediction, taus);
135  return;
136  }
137 
139 
140  const tensorflow::Tensor& pred = getPredictions(event, taus);
141  createOutputs(event, pred, taus);
142  }
143 
144  static std::unique_ptr<deep_tau::DeepTauCache> initializeGlobalCache(const edm::ParameterSet& cfg) {
145  const auto graph_name_vector = cfg.getParameter<std::vector<std::string>>("graph_file");
146  std::map<std::string, std::string> graph_names;
147  for (const auto& entry : graph_name_vector) {
148  const size_t sep_pos = entry.find(':');
149  std::string entry_name, graph_file;
150  if (sep_pos != std::string::npos) {
151  entry_name = entry.substr(0, sep_pos);
152  graph_file = entry.substr(sep_pos + 1);
153  } else {
154  entry_name = "";
155  graph_file = entry;
156  }
158  if (graph_names.count(entry_name))
159  throw cms::Exception("DeepTauCache") << "Duplicated graph entries";
160  graph_names[entry_name] = graph_file;
161  }
162  bool mem_mapped = cfg.getParameter<bool>("mem_mapped");
163  return std::make_unique<deep_tau::DeepTauCache>(graph_names, mem_mapped);
164  }
165 
167 
168 private:
169  inline void checkInputs(const tensorflow::Tensor& inputs,
170  const std::string& block_name,
171  int n_inputs,
172  const CellGrid* grid = nullptr) const {
173  if (debug_level >= 1) {
174  std::cout << "<checkInputs>: block_name = " << block_name << std::endl;
175  if (block_name == "input_tau") {
176  for (int input_index = 0; input_index < n_inputs; ++input_index) {
177  float input = inputs.matrix<float>()(0, input_index);
178  if (edm::isNotFinite(input)) {
179  throw cms::Exception("DeepTauId")
180  << "in the " << block_name
181  << ", input is not finite, i.e. infinite or NaN, for input_index = " << input_index;
182  }
183  if (debug_level >= 2) {
184  std::cout << block_name << "[var = " << input_index << "] = " << std::setprecision(5) << std::fixed << input
185  << std::endl;
186  }
187  }
188  } else {
189  assert(grid);
190  int n_eta, n_phi;
191  if (block_name.find("input_inner") != std::string::npos) {
192  n_eta = 5;
193  n_phi = 5;
194  } else if (block_name.find("input_outer") != std::string::npos) {
195  n_eta = 10;
196  n_phi = 10;
197  } else
198  assert(0);
199  int eta_phi_index = 0;
200  for (int eta = -n_eta; eta <= n_eta; ++eta) {
201  for (int phi = -n_phi; phi <= n_phi; ++phi) {
202  const CellIndex cell_index{eta, phi};
203  const auto cell_iter = grid->find(cell_index);
204  if (cell_iter != grid->end()) {
205  for (int input_index = 0; input_index < n_inputs; ++input_index) {
206  float input = inputs.tensor<float, 4>()(eta_phi_index, 0, 0, input_index);
207  if (edm::isNotFinite(input)) {
208  throw cms::Exception("DeepTauId")
209  << "in the " << block_name << ", input is not finite, i.e. infinite or NaN, for eta = " << eta
210  << ", phi = " << phi << ", input_index = " << input_index;
211  }
212  if (debug_level >= 2) {
213  std::cout << block_name << "[eta = " << eta << "][phi = " << phi << "][var = " << input_index
214  << "] = " << std::setprecision(5) << std::fixed << input << std::endl;
215  }
216  }
217  eta_phi_index += 1;
218  }
219  }
220  }
221  }
222  }
223  }
224 
225  inline void saveInputs(const tensorflow::Tensor& inputs,
226  const std::string& block_name,
227  int n_inputs,
228  const CellGrid* grid = nullptr) {
229  if (debug_level >= 1) {
230  std::cout << "<saveInputs>: block_name = " << block_name << std::endl;
231  }
232  if (!is_first_block_)
233  (*json_file_) << ", ";
234  (*json_file_) << "\"" << block_name << "\": [";
235  if (block_name == "input_tau") {
236  for (int input_index = 0; input_index < n_inputs; ++input_index) {
237  float input = inputs.matrix<float>()(0, input_index);
238  if (input_index != 0)
239  (*json_file_) << ", ";
240  (*json_file_) << input;
241  }
242  } else {
243  assert(grid);
244  int n_eta, n_phi;
245  if (block_name.find("input_inner") != std::string::npos) {
246  n_eta = 5;
247  n_phi = 5;
248  } else if (block_name.find("input_outer") != std::string::npos) {
249  n_eta = 10;
250  n_phi = 10;
251  } else
252  assert(0);
253  int eta_phi_index = 0;
254  for (int eta = -n_eta; eta <= n_eta; ++eta) {
255  if (eta != -n_eta)
256  (*json_file_) << ", ";
257  (*json_file_) << "[";
258  for (int phi = -n_phi; phi <= n_phi; ++phi) {
259  if (phi != -n_phi)
260  (*json_file_) << ", ";
261  (*json_file_) << "[";
262  const CellIndex cell_index{eta, phi};
263  const auto cell_iter = grid->find(cell_index);
264  for (int input_index = 0; input_index < n_inputs; ++input_index) {
265  float input = 0.;
266  if (cell_iter != grid->end()) {
267  input = inputs.tensor<float, 4>()(eta_phi_index, 0, 0, input_index);
268  }
269  if (input_index != 0)
270  (*json_file_) << ", ";
271  (*json_file_) << input;
272  }
273  if (cell_iter != grid->end()) {
274  eta_phi_index += 1;
275  }
276  (*json_file_) << "]";
277  }
278  (*json_file_) << "]";
279  }
280  }
281  (*json_file_) << "]";
282  is_first_block_ = false;
283  }
284 
285 private:
287  // Empty dummy vectors
288  const std::vector<pat::Electron> electron_collection_default;
289  const std::vector<pat::Muon> muon_collection_default;
290  const reco::TauDiscriminatorContainer basicTauDiscriminators_default;
291  const reco::TauDiscriminatorContainer basicTauDiscriminatorsdR03_default;
293  pfTauTransverseImpactParameters_default;
294 
295  const std::vector<pat::Electron>* electron_collection;
296  const std::vector<pat::Muon>* muon_collection;
301 
302  if (!is_online_) {
303  electron_collection = &event.get(electrons_token_);
304  muon_collection = &event.get(muons_token_);
305  pfTauTransverseImpactParameters = &pfTauTransverseImpactParameters_default;
306  basicTauDiscriminators = &basicTauDiscriminators_default;
307  basicTauDiscriminatorsdR03 = &basicTauDiscriminatorsdR03_default;
308  } else {
309  electron_collection = &electron_collection_default;
310  muon_collection = &muon_collection_default;
314 
315  // Get indices for discriminators
316  if (!discrIndicesMapped_) {
321  discrIndicesMapped_ = true;
322  }
323  }
324 
325  TauFunc tauIDs = {basicTauDiscriminators,
330 
332  event.getByToken(pfcandToken_, pfCands);
333 
335  event.getByToken(vtxToken_, vertices);
336 
338  event.getByToken(rho_token_, rho);
339 
340  auto const& eventnr = event.id().event();
341 
342  tensorflow::Tensor predictions(tensorflow::DT_FLOAT, {static_cast<int>(taus->size()), deep_tau::NumberOfOutputs});
343 
344  for (size_t tau_index = 0; tau_index < taus->size(); ++tau_index) {
345  const edm::RefToBase<reco::BaseTau> tauRef = taus->refAt(tau_index);
346 
347  std::vector<tensorflow::Tensor> pred_vector;
348 
349  bool passesPrediscriminants;
350  if (is_online_) {
351  passesPrediscriminants = tauIDs.passPrediscriminants<std::vector<TauDiscInfo<reco::PFTauDiscriminator>>>(
353  } else {
354  passesPrediscriminants = tauIDs.passPrediscriminants<std::vector<TauDiscInfo<pat::PATTauDiscriminator>>>(
356  }
357 
358  if (passesPrediscriminants) {
359  if (version_ == 2) {
360  if (is_online_) {
361  getPredictionsV2<reco::PFCandidate, reco::PFTau>(taus->at(tau_index),
362  tau_index,
363  tauRef,
364  electron_collection,
365  muon_collection,
366  *pfCands,
367  vertices->at(0),
368  *rho,
369  eventnr,
370  pred_vector,
371  tauIDs);
372  } else
373  getPredictionsV2<pat::PackedCandidate, pat::Tau>(taus->at(tau_index),
374  tau_index,
375  tauRef,
376  electron_collection,
377  muon_collection,
378  *pfCands,
379  vertices->at(0),
380  *rho,
381  eventnr,
382  pred_vector,
383  tauIDs);
384  } else {
385  throw cms::Exception("DeepTauId") << "version " << version_ << " is not supported.";
386  }
387 
388  for (int k = 0; k < deep_tau::NumberOfOutputs; ++k) {
389  const float pred = pred_vector[0].flat<float>()(k);
390  if (!(pred >= 0 && pred <= 1))
391  throw cms::Exception("DeepTauId")
392  << "invalid prediction = " << pred << " for tau_index = " << tau_index << ", pred_index = " << k;
393  predictions.matrix<float>()(tau_index, k) = pred;
394  }
395  } else {
396  // This else statement was added as a part of the DeepTau@HLT development. It does not affect the current state
397  // of offline DeepTauId code as there the preselection is not used (it was added in the DeepTau@HLT). It returns
398  // default values for deepTau score if the preselection failed. Before this statement the values given for this tau
399  // were random. k == 2 corresponds to the tau score and all other k values to e, mu and jets. By defining in this way
400  // the final score is -1.
401  for (int k = 0; k < deep_tau::NumberOfOutputs; ++k) {
402  predictions.matrix<float>()(tau_index, k) = (k == 2) ? -1.f : 2.f;
403  }
404  }
405  }
406  return predictions;
407  }
408 
409  template <typename CandidateCastType, typename TauCastType>
411  const size_t tau_index,
412  const edm::RefToBase<reco::BaseTau> tau_ref,
413  const std::vector<pat::Electron>* electrons,
414  const std::vector<pat::Muon>* muons,
415  const edm::View<reco::Candidate>& pfCands,
416  const reco::Vertex& pv,
417  double rho,
418  const edm::EventNumber_t& eventnr,
419  std::vector<tensorflow::Tensor>& pred_vector,
420  TauFunc tau_funcs) {
421  using namespace dnn_inputs_v2;
422  if (debug_level >= 2) {
423  std::cout << "<DeepTauId::getPredictionsV2 (moduleLabel = " << moduleDescription().moduleLabel()
424  << ")>:" << std::endl;
425  std::cout << " tau: pT = " << tau.pt() << ", eta = " << tau.eta() << ", phi = " << tau.phi()
426  << ", eventnr = " << eventnr << std::endl;
427  }
428  CellGrid inner_grid(number_of_inner_cell, number_of_inner_cell, 0.02, 0.02, disable_CellIndex_workaround_);
429  CellGrid outer_grid(number_of_outer_cell, number_of_outer_cell, 0.05, 0.05, disable_CellIndex_workaround_);
430  fillGrids(dynamic_cast<const TauCastType&>(tau), *electrons, inner_grid, outer_grid);
431  fillGrids(dynamic_cast<const TauCastType&>(tau), *muons, inner_grid, outer_grid);
432  fillGrids(dynamic_cast<const TauCastType&>(tau), pfCands, inner_grid, outer_grid);
433 
434  tauBlockTensor_->flat<float>().setZero();
435  createTauBlockInputs<CandidateCastType>(
436  dynamic_cast<const TauCastType&>(tau), tau_index, tau_ref, pv, rho, tau_funcs, *tauBlockTensor_);
437  checkInputs(*tauBlockTensor_, "input_tau", static_cast<int>(tauBlockTensor_->shape().dim_size(1)));
438  createConvFeatures<CandidateCastType>(dynamic_cast<const TauCastType&>(tau),
439  tau_index,
440  tau_ref,
441  pv,
442  rho,
443  electrons,
444  muons,
445  pfCands,
446  inner_grid,
447  tau_funcs,
448  true);
449  checkInputs(*eGammaTensor_[true], "input_inner_egamma", EgammaBlockInputs::NumberOfInputs, &inner_grid);
450  checkInputs(*muonTensor_[true], "input_inner_muon", MuonBlockInputs::NumberOfInputs, &inner_grid);
451  checkInputs(*hadronsTensor_[true], "input_inner_hadrons", HadronBlockInputs::NumberOfInputs, &inner_grid);
452  createConvFeatures<CandidateCastType>(dynamic_cast<const TauCastType&>(tau),
453  tau_index,
454  tau_ref,
455  pv,
456  rho,
457  electrons,
458  muons,
459  pfCands,
460  outer_grid,
461  tau_funcs,
462  false);
463  checkInputs(*eGammaTensor_[false], "input_outer_egamma", EgammaBlockInputs::NumberOfInputs, &outer_grid);
464  checkInputs(*muonTensor_[false], "input_outer_muon", MuonBlockInputs::NumberOfInputs, &outer_grid);
465  checkInputs(*hadronsTensor_[false], "input_outer_hadrons", HadronBlockInputs::NumberOfInputs, &outer_grid);
466 
467  if (save_inputs_) {
468  std::string json_file_name = "DeepTauId_" + std::to_string(eventnr) + "_" + std::to_string(tau_index) + ".json";
469  json_file_ = new std::ofstream(json_file_name.data());
470  is_first_block_ = true;
471  (*json_file_) << "{";
472  saveInputs(*tauBlockTensor_, "input_tau", static_cast<int>(tauBlockTensor_->shape().dim_size(1)));
473  saveInputs(*eGammaTensor_[true], "input_inner_egamma", EgammaBlockInputs::NumberOfInputs, &inner_grid);
474  saveInputs(*muonTensor_[true], "input_inner_muon", MuonBlockInputs::NumberOfInputs, &inner_grid);
475  saveInputs(*hadronsTensor_[true], "input_inner_hadrons", HadronBlockInputs::NumberOfInputs, &inner_grid);
476  saveInputs(*eGammaTensor_[false], "input_outer_egamma", EgammaBlockInputs::NumberOfInputs, &outer_grid);
477  saveInputs(*muonTensor_[false], "input_outer_muon", MuonBlockInputs::NumberOfInputs, &outer_grid);
478  saveInputs(*hadronsTensor_[false], "input_outer_hadrons", HadronBlockInputs::NumberOfInputs, &outer_grid);
479  (*json_file_) << "}";
480  delete json_file_;
481  ++file_counter_;
482  }
483 
484  tensorflow::run(&(cache_->getSession("core")),
485  {{"input_tau", *tauBlockTensor_},
486  {"input_inner", *convTensor_.at(true)},
487  {"input_outer", *convTensor_.at(false)}},
488  {"main_output/Softmax"},
489  &pred_vector);
490  if (debug_level >= 1) {
491  std::cout << "output = { ";
492  for (int idx = 0; idx < deep_tau::NumberOfOutputs; ++idx) {
493  if (idx > 0)
494  std::cout << ", ";
496  if (idx == 0)
497  label = "e";
498  else if (idx == 1)
499  label = "mu";
500  else if (idx == 2)
501  label = "tau";
502  else if (idx == 3)
503  label = "jet";
504  else
505  assert(0);
506  std::cout << label << " = " << pred_vector[0].flat<float>()(idx);
507  }
508  std::cout << " }" << std::endl;
509  }
510  }
511 
512  tensorflow::Tensor getPartialPredictions(bool is_inner) {
513  std::vector<tensorflow::Tensor> pred_vector;
514  if (is_inner) {
515  tensorflow::run(&(cache_->getSession("inner")),
516  {
517  {"input_inner_egamma", *eGammaTensor_.at(is_inner)},
518  {"input_inner_muon", *muonTensor_.at(is_inner)},
519  {"input_inner_hadrons", *hadronsTensor_.at(is_inner)},
520  },
521  {"inner_all_dropout_4/Identity"},
522  &pred_vector);
523  } else {
524  tensorflow::run(&(cache_->getSession("outer")),
525  {
526  {"input_outer_egamma", *eGammaTensor_.at(is_inner)},
527  {"input_outer_muon", *muonTensor_.at(is_inner)},
528  {"input_outer_hadrons", *hadronsTensor_.at(is_inner)},
529  },
530  {"outer_all_dropout_4/Identity"},
531  &pred_vector);
532  }
533  return pred_vector.at(0);
534  }
535 
536  template <typename CandidateCastType, typename TauCastType>
537  void createConvFeatures(const TauCastType& tau,
538  const size_t tau_index,
539  const edm::RefToBase<reco::BaseTau> tau_ref,
540  const reco::Vertex& pv,
541  double rho,
542  const std::vector<pat::Electron>* electrons,
543  const std::vector<pat::Muon>* muons,
544  const edm::View<reco::Candidate>& pfCands,
545  const CellGrid& grid,
546  TauFunc tau_funcs,
547  bool is_inner) {
548  if (debug_level >= 2) {
549  std::cout << "<DeepTauId::createConvFeatures (is_inner = " << is_inner << ")>:" << std::endl;
550  }
551  tensorflow::Tensor& convTensor = *convTensor_.at(is_inner);
552  eGammaTensor_[is_inner] = std::make_unique<tensorflow::Tensor>(
553  tensorflow::DT_FLOAT,
554  tensorflow::TensorShape{
555  (long long int)grid.num_valid_cells(), 1, 1, dnn_inputs_v2::EgammaBlockInputs::NumberOfInputs});
556  muonTensor_[is_inner] = std::make_unique<tensorflow::Tensor>(
557  tensorflow::DT_FLOAT,
558  tensorflow::TensorShape{
559  (long long int)grid.num_valid_cells(), 1, 1, dnn_inputs_v2::MuonBlockInputs::NumberOfInputs});
560  hadronsTensor_[is_inner] = std::make_unique<tensorflow::Tensor>(
561  tensorflow::DT_FLOAT,
562  tensorflow::TensorShape{
563  (long long int)grid.num_valid_cells(), 1, 1, dnn_inputs_v2::HadronBlockInputs::NumberOfInputs});
564 
565  eGammaTensor_[is_inner]->flat<float>().setZero();
566  muonTensor_[is_inner]->flat<float>().setZero();
567  hadronsTensor_[is_inner]->flat<float>().setZero();
568 
569  unsigned idx = 0;
570  for (int eta = -grid.maxEtaIndex(); eta <= grid.maxEtaIndex(); ++eta) {
571  for (int phi = -grid.maxPhiIndex(); phi <= grid.maxPhiIndex(); ++phi) {
572  if (debug_level >= 2) {
573  std::cout << "processing ( eta = " << eta << ", phi = " << phi << " )" << std::endl;
574  }
575  const CellIndex cell_index{eta, phi};
576  const auto cell_iter = grid.find(cell_index);
577  if (cell_iter != grid.end()) {
578  if (debug_level >= 2) {
579  std::cout << " creating inputs for ( eta = " << eta << ", phi = " << phi << " ): idx = " << idx
580  << std::endl;
581  }
582  const Cell& cell = cell_iter->second;
583  createEgammaBlockInputs<CandidateCastType>(idx,
584  tau,
585  tau_index,
586  tau_ref,
587  pv,
588  rho,
589  electrons,
590  pfCands,
591  cell,
592  tau_funcs,
593  is_inner,
594  *eGammaTensor_[is_inner]);
595  createMuonBlockInputs<CandidateCastType>(
596  idx, tau, tau_index, tau_ref, pv, rho, muons, pfCands, cell, tau_funcs, is_inner, *muonTensor_[is_inner]);
597  createHadronsBlockInputs<CandidateCastType>(
598  idx, tau, tau_index, tau_ref, pv, rho, pfCands, cell, tau_funcs, is_inner, *hadronsTensor_[is_inner]);
599  idx += 1;
600  } else {
601  if (debug_level >= 2) {
602  std::cout << " skipping creation of inputs, because ( eta = " << eta << ", phi = " << phi
603  << " ) is not in the grid !!" << std::endl;
604  }
605  }
606  }
607  }
608 
609  const auto predTensor = getPartialPredictions(is_inner);
610  idx = 0;
611  for (int eta = -grid.maxEtaIndex(); eta <= grid.maxEtaIndex(); ++eta) {
612  for (int phi = -grid.maxPhiIndex(); phi <= grid.maxPhiIndex(); ++phi) {
613  const CellIndex cell_index{eta, phi};
614  const int eta_index = grid.getEtaTensorIndex(cell_index);
615  const int phi_index = grid.getPhiTensorIndex(cell_index);
616 
617  const auto cell_iter = grid.find(cell_index);
618  if (cell_iter != grid.end()) {
619  setCellConvFeatures(convTensor, predTensor, idx, eta_index, phi_index);
620  idx += 1;
621  } else {
622  setCellConvFeatures(convTensor, *zeroOutputTensor_[is_inner], 0, eta_index, phi_index);
623  }
624  }
625  }
626  }
627 
628  void setCellConvFeatures(tensorflow::Tensor& convTensor,
629  const tensorflow::Tensor& features,
630  unsigned batch_idx,
631  int eta_index,
632  int phi_index) {
633  for (int n = 0; n < dnn_inputs_v2::number_of_conv_features; ++n) {
634  convTensor.tensor<float, 4>()(0, eta_index, phi_index, n) = features.tensor<float, 4>()(batch_idx, 0, 0, n);
635  }
636  }
637 
638 private:
640 
641  std::unique_ptr<tensorflow::Tensor> tauBlockTensor_;
642  std::array<std::unique_ptr<tensorflow::Tensor>, 2> eGammaTensor_, muonTensor_, hadronsTensor_, convTensor_,
644 };
645 
void createConvFeatures(const TauCastType &tau, const size_t tau_index, const edm::RefToBase< reco::BaseTau > tau_ref, const reco::Vertex &pv, double rho, const std::vector< pat::Electron > *electrons, const std::vector< pat::Muon > *muons, const edm::View< reco::Candidate > &pfCands, const CellGrid &grid, TauFunc tau_funcs, bool is_inner)
Definition: DeepTauId.cc:537
edm::EDGetTokenT< std::vector< pat::Electron > > electrons_token_
size
Write out results.
std::vector< TauDiscInfo< pat::PATTauDiscriminator > > patPrediscriminants_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
Definition: DeepTauId.cc:80
tensorflow::Tensor getPredictions(edm::Event &event, edm::Handle< TauCollection > taus)
Definition: DeepTauId.cc:286
std::array< std::unique_ptr< tensorflow::Tensor >, 2 > hadronsTensor_
Definition: DeepTauId.cc:642
static std::unique_ptr< deep_tau::DeepTauCache > initializeGlobalCache(const edm::ParameterSet &cfg)
Definition: DeepTauId.cc:144
edm::EDGetTokenT< double > rho_token_
DeepTauCache(const std::map< std::string, std::string > &graph_names, bool mem_mapped)
Definition: DeepTauId.cc:19
std::string fullPath() const
Definition: FileInPath.cc:161
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
std::array< std::unique_ptr< tensorflow::Tensor >, 2 > zeroOutputTensor_
Definition: DeepTauId.cc:642
std::map< std::string, tensorflow::Session * > sessions_
Definition: DeepTauId.cc:68
GraphDef * loadGraphDef(const std::string &pbFile)
Definition: TensorFlow.cc:120
std::map< BasicDiscriminator, size_t > basicDiscrIndexMap_
const std::vector< BasicDiscriminator > requiredBasicDiscriminators_
unsigned long long EventNumber_t
void setCellConvFeatures(tensorflow::Tensor &convTensor, const tensorflow::Tensor &features, unsigned batch_idx, int eta_index, int phi_index)
Definition: DeepTauId.cc:628
void getPredictionsV2(TauCollection::const_reference &tau, const size_t tau_index, const edm::RefToBase< reco::BaseTau > tau_ref, const std::vector< pat::Electron > *electrons, const std::vector< pat::Muon > *muons, const edm::View< reco::Candidate > &pfCands, const reco::Vertex &pv, double rho, const edm::EventNumber_t &eventnr, std::vector< tensorflow::Tensor > &pred_vector, TauFunc tau_funcs)
Definition: DeepTauId.cc:410
muons
the two sets of parameters below are mutually exclusive, depending if RECO or ALCARECO is used the us...
Definition: DiMuonV_cfg.py:212
assert(be >=bs)
static std::string to_string(const XMLCh *ch)
static std::string const input
Definition: EdmProvDump.cc:50
std::array< std::unique_ptr< tensorflow::Tensor >, 2 > convTensor_
Definition: DeepTauId.cc:642
edm::EDGetTokenT< CandidateCollection > pfcandToken_
DeepTauId(const edm::ParameterSet &cfg, const deep_tau::DeepTauCache *cache)
Definition: DeepTauId.cc:89
edm::EDGetTokenT< std::vector< pat::Muon > > muons_token_
const deep_tau::DeepTauCache * cache_
Definition: DeepTauId.cc:639
char const * label
static void fillDescriptionsHelper(edm::ParameterSetDescription &desc)
std::shared_ptr< tensorflow::GraphDef > GraphPtr
Definition: DeepTauId.cc:17
const tensorflow::GraphDef & getGraph(const std::string &name="") const
Definition: DeepTauId.cc:64
std::vector< float > features(const reco::PreId &ecal, const reco::PreId &hcal, double rho, const reco::BeamSpot &spot, noZS::EcalClusterLazyTools &ecalTools)
edm::EDGetTokenT< reco::TauDiscriminatorContainer > basicTauDiscriminators_inputToken_
edm::EDGetTokenT< TauCollection > tausToken_
std::map< BasicDiscriminator, size_t > basicDiscrdR03IndexMap_
void run(Session *session, const NamedTensorList &inputs, const std::vector< std::string > &outputNames, std::vector< Tensor > *outputs, const thread::ThreadPoolOptions &threadPoolOptions)
Definition: TensorFlow.cc:259
void saveInputs(const tensorflow::Tensor &inputs, const std::string &block_name, int n_inputs, const CellGrid *grid=nullptr)
Definition: DeepTauId.cc:225
bool closeSession(Session *&session)
Definition: TensorFlow.cc:234
const std::vector< BasicDiscriminator > requiredBasicDiscriminatorsdR03_
def pv(vc)
Definition: MetAnalyzer.py:7
double f[11][100]
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
static void globalEndJob(const deep_tau::DeepTauCache *cache_)
Definition: DeepTauId.cc:166
edm::EDGetTokenT< reco::TauDiscriminatorContainer > basicTauDiscriminatorsdR03_inputToken_
void checkInputs(const tensorflow::Tensor &inputs, const std::string &block_name, int n_inputs, const CellGrid *grid=nullptr) const
Definition: DeepTauId.cc:169
tensorflow::Session & getSession(const std::string &name="") const
Definition: DeepTauId.cc:63
const std::map< BasicDiscriminator, size_t > matchDiscriminatorIndices(edm::Event const &event, edm::EDGetTokenT< reco::TauDiscriminatorContainer > discriminatorContainerToken, std::vector< BasicDiscriminator > requiredDiscr)
void createOutputs(edm::Event &event, const PredType &pred, edm::Handle< TauCollection > taus)
Session * createSession()
Definition: TensorFlow.cc:137
tensorflow::Tensor getPartialPredictions(bool is_inner)
Definition: DeepTauId.cc:512
void loadPrediscriminants(edm::Event const &event, edm::Handle< TauCollection > const &taus)
constexpr bool Default
Definition: SoACommon.h:75
void add(std::string const &label, ParameterSetDescription const &psetDescription)
void fillGrids(const TauCastType &tau, const Collection &objects, CellGrid &inner_grid, CellGrid &outer_grid)
std::array< std::unique_ptr< tensorflow::Tensor >, 2 > eGammaTensor_
Definition: DeepTauId.cc:642
def cache(function)
Definition: utilities.py:3
std::map< std::string, GraphPtr > graphs_
Definition: DeepTauId.cc:67
DeepTauIdWrapper(const edm::ParameterSet &cfg)
Definition: DeepTauId.cc:75
edm::EDGetTokenT< reco::VertexCollection > vtxToken_
std::vector< TauDiscInfo< reco::PFTauDiscriminator > > recoPrediscriminants_
std::map< std::string, std::unique_ptr< tensorflow::MemmappedEnv > > memmappedEnv_
Definition: DeepTauId.cc:69
std::array< std::unique_ptr< tensorflow::Tensor >, 2 > muonTensor_
Definition: DeepTauId.cc:642
void produce(edm::Event &event, const edm::EventSetup &es) override
Definition: DeepTauId.cc:127
T const & const_reference
Definition: View.h:84
Definition: event.py:1
constexpr int NumberOfOutputs
Definition: DeepTauIdBase.h:50
edm::EDGetTokenT< edm::AssociationVector< reco::PFTauRefProd, std::vector< reco::PFTauTransverseImpactParameterRef > > > pfTauTransverseImpactParameters_token_
std::unique_ptr< tensorflow::Tensor > tauBlockTensor_
Definition: DeepTauId.cc:641