CMS 3D CMS Logo

DeepTauIdSONIC.cc
Go to the documentation of this file.
1 /*
2  * \class DeepTauIdSONIC
3  *
4  * Tau identification using Deep NN with SONIC
5  *
6  */
7 
10 
11 class DeepTauIdSonicProducer : public DeepTauIdBase<TritonEDProducer<>> {
12 public:
14 
15  void acquire(edm::Event const& iEvent, edm::EventSetup const& iSetup, Input& iInput) override;
16  void produce(edm::Event& iEvent, edm::EventSetup const& iSetup, Output const& iOutput) override;
17  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
18 
19 private:
20  std::vector<size_t> tau_indices_;
21 
22  std::vector<float>* p_tauBlockInputs;
23  std::vector<float>* p_egammaInnerBlockInputs;
24  std::vector<float>* p_muonInnerBlockInputs;
25  std::vector<float>* p_hadronInnerBlockInputs;
26  std::vector<float>* p_egammaOuterBlockInputs;
27  std::vector<float>* p_muonOuterBlockInputs;
28  std::vector<float>* p_hadronOuterBlockInputs;
29  std::vector<int64_t>* p_innerGridposInputs;
30  std::vector<int64_t>* p_outerGridposInputs;
31 
32  template <typename CandidateCastType, typename TauCastType>
34  const size_t tau_index,
35  const edm::RefToBase<reco::BaseTau> tau_ref,
36  const std::vector<pat::Electron>* electrons,
37  const std::vector<pat::Muon>* muons,
38  const edm::View<reco::Candidate>& pfCands,
39  const reco::Vertex& pv,
40  double rho,
41  const TauFunc& tau_funcs);
42 
43  template <typename CandidateCastType, typename TauCastType>
44  void createConvFeatures(const TauCastType& tau,
45  const size_t tau_index,
46  const edm::RefToBase<reco::BaseTau> tau_ref,
47  const reco::Vertex& pv,
48  double rho,
49  const std::vector<pat::Electron>* electrons,
50  const std::vector<pat::Muon>* muons,
51  const edm::View<reco::Candidate>& pfCands,
52  const CellGrid& grid,
53  const TauFunc& tau_funcs,
54  bool is_inner,
55  std::vector<float>* p_egammaBlockInputs,
56  std::vector<float>* p_muonBlockInputs,
57  std::vector<float>* p_hadronBlockInputs,
58  std::vector<int64_t>* p_GridposInputs);
59 };
60 
63  iEvent.getByToken(tausToken_, taus);
64 
66 
67  const std::vector<pat::Electron> electron_collection_default;
68  const std::vector<pat::Muon> muon_collection_default;
69  const reco::TauDiscriminatorContainer basicTauDiscriminators_default;
70  const reco::TauDiscriminatorContainer basicTauDiscriminatorsdR03_default;
72  pfTauTransverseImpactParameters_default;
73 
74  const std::vector<pat::Electron>* electron_collection;
75  const std::vector<pat::Muon>* muon_collection;
80 
81  if (!is_online_) {
82  electron_collection = &iEvent.get(electrons_token_);
83  muon_collection = &iEvent.get(muons_token_);
84  pfTauTransverseImpactParameters = &pfTauTransverseImpactParameters_default;
85  basicTauDiscriminators = &basicTauDiscriminators_default;
86  basicTauDiscriminatorsdR03 = &basicTauDiscriminatorsdR03_default;
87  } else {
88  electron_collection = &electron_collection_default;
89  muon_collection = &muon_collection_default;
93 
94  // Get indices for discriminators
95  if (!discrIndicesMapped_) {
100  discrIndicesMapped_ = true;
101  }
102  }
103 
104  TauFunc tauIDs = {basicTauDiscriminators,
109 
111  iEvent.getByToken(pfcandToken_, pfCands);
112 
114  iEvent.getByToken(vtxToken_, vertices);
115 
117  iEvent.getByToken(rho_token_, rho);
118 
119  // vector to store the indices for the taus passing the selections
120  tau_indices_.clear();
121 
122  for (size_t tau_index = 0; tau_index < taus->size(); ++tau_index) {
123  const edm::RefToBase<reco::BaseTau> tauRef = taus->refAt(tau_index);
124  bool passesPrediscriminants;
125  if (is_online_) {
126  passesPrediscriminants = tauIDs.passPrediscriminants<std::vector<TauDiscInfo<reco::PFTauDiscriminator>>>(
128  } else {
129  passesPrediscriminants = tauIDs.passPrediscriminants<std::vector<TauDiscInfo<pat::PATTauDiscriminator>>>(
131  }
132  if (!passesPrediscriminants)
133  continue;
134 
135  // tau index that passes the selection
136  tau_indices_.push_back(tau_index);
137  }
138 
139  if (tau_indices_.empty()) {
140  // no tau passing the requirement
141  // no need to run acquire and inference
142  client_->setBatchSize(0);
143  return;
144  }
145 
146  int n_taus = tau_indices_.size();
147  // for the regular non-split deep-tau model, set the
148  // batch size to the number of taus per event
149  client_->setBatchSize(n_taus);
150 
151  auto& input_tauBlock = iInput.at("input_tau");
152  auto& input_innerEgammaBlock = iInput.at("input_inner_egamma");
153  auto& input_outerEgammaBlock = iInput.at("input_outer_egamma");
154  auto& input_innerMuonBlock = iInput.at("input_inner_muon");
155  auto& input_outerMuonBlock = iInput.at("input_outer_muon");
156  auto& input_innerHadronBlock = iInput.at("input_inner_hadrons");
157  auto& input_outerHadronBlock = iInput.at("input_outer_hadrons");
158 
159  p_innerGridposInputs = nullptr;
160  p_outerGridposInputs = nullptr;
161 
162  auto data_tauBlock = input_tauBlock.allocate<float>();
163  auto data_innerEgammaBlock = input_innerEgammaBlock.allocate<float>();
164  auto data_outerEgammaBlock = input_outerEgammaBlock.allocate<float>();
165  auto data_innerMuonBlock = input_innerMuonBlock.allocate<float>();
166  auto data_outerMuonBlock = input_outerMuonBlock.allocate<float>();
167  auto data_innerHadronBlock = input_innerHadronBlock.allocate<float>();
168  auto data_outerHadronBlock = input_outerHadronBlock.allocate<float>();
169 
170  for (unsigned itau_passed = 0; itau_passed < tau_indices_.size(); ++itau_passed) {
171  // batch size is not one, needs to go to corresponding itau
172  p_tauBlockInputs = &((*data_tauBlock)[itau_passed]);
173 
174  p_egammaInnerBlockInputs = &((*data_innerEgammaBlock)[itau_passed]);
175  p_muonInnerBlockInputs = &((*data_innerMuonBlock)[itau_passed]);
176  p_hadronInnerBlockInputs = &((*data_innerHadronBlock)[itau_passed]);
177 
178  p_egammaOuterBlockInputs = &((*data_outerEgammaBlock)[itau_passed]);
179  p_muonOuterBlockInputs = &((*data_outerMuonBlock)[itau_passed]);
180  p_hadronOuterBlockInputs = &((*data_outerHadronBlock)[itau_passed]);
181 
182  int tau_index = tau_indices_[itau_passed];
183  const edm::RefToBase<reco::BaseTau> tauRef = taus->refAt(tau_index);
184  prepareInputsV2<pat::PackedCandidate, pat::Tau>(taus->at(tau_index),
185  tau_index,
186  tauRef,
187  electron_collection,
188  muon_collection,
189  *pfCands,
190  vertices->at(0),
191  *rho,
192  tauIDs);
193  }
194 
195  // set all input data to the server
196  input_tauBlock.toServer(data_tauBlock);
197 
198  input_innerEgammaBlock.toServer(data_innerEgammaBlock);
199  input_innerMuonBlock.toServer(data_innerMuonBlock);
200  input_innerHadronBlock.toServer(data_innerHadronBlock);
201 
202  input_outerEgammaBlock.toServer(data_outerEgammaBlock);
203  input_outerMuonBlock.toServer(data_outerMuonBlock);
204  input_outerHadronBlock.toServer(data_outerHadronBlock);
205 }
206 
209  iEvent.getByToken(tausToken_, taus);
210 
211  if (taus->empty()) {
212  std::vector<std::vector<float>> pred_all(0, std::vector<float>(deep_tau::NumberOfOutputs, 0.));
213  createOutputs(iEvent, pred_all, taus);
214  return;
215  }
216 
217  const auto& output_tauval = iOutput.at("main_output/Softmax");
218  const auto& outputs_tauval = output_tauval.fromServer<float>();
219 
220  // fill the taus passing the selections with the results from produce,
221  // and the taus failing the selections with 2 and -1.0
222  std::vector<std::vector<float>> pred_all(taus->size(), std::vector<float>(deep_tau::NumberOfOutputs, 0.));
223  for (unsigned itau = 0; itau < taus->size(); ++itau) {
224  for (int k = 0; k < deep_tau::NumberOfOutputs; ++k) {
225  pred_all[itau][k] = (k == 2) ? -1.f : 2.f;
226  }
227  }
228  for (unsigned itau_passed = 0; itau_passed < tau_indices_.size(); ++itau_passed) {
229  int tau_index = tau_indices_[itau_passed];
230  std::copy(outputs_tauval[itau_passed].begin(), outputs_tauval[itau_passed].end(), pred_all[tau_index].begin());
231 
232  if (debug_level >= 2) {
233  for (int i = 0; i < 4; ++i) {
234  std::cout << "tau index " << itau_passed << " k " << i << " pred " << pred_all[tau_index][i] << std::endl;
235  }
236  }
237  }
238  createOutputs(iEvent, pred_all, taus);
239 }
240 
241 template <typename CandidateCastType, typename TauCastType>
243  const size_t tau_index,
244  const edm::RefToBase<reco::BaseTau> tau_ref,
245  const std::vector<pat::Electron>* electrons,
246  const std::vector<pat::Muon>* muons,
247  const edm::View<reco::Candidate>& pfCands,
248  const reco::Vertex& pv,
249  double rho,
250  const TauFunc& tau_funcs) {
251  using namespace dnn_inputs_v2;
252  CellGrid inner_grid(number_of_inner_cell, number_of_inner_cell, 0.02, 0.02, disable_CellIndex_workaround_);
253  CellGrid outer_grid(number_of_outer_cell, number_of_outer_cell, 0.05, 0.05, disable_CellIndex_workaround_);
254  auto tau_casted = dynamic_cast<const TauCastType&>(tau);
255  // fill in the inner and outer grids for electrons, muons, and pfCands
256  fillGrids(tau_casted, *electrons, inner_grid, outer_grid);
257  fillGrids(tau_casted, *muons, inner_grid, outer_grid);
258  fillGrids(tau_casted, pfCands, inner_grid, outer_grid);
259 
260  p_tauBlockInputs->insert(p_tauBlockInputs->end(), TauBlockInputs::NumberOfInputs, 0.);
261  std::vector<float>::iterator tauIter = p_tauBlockInputs->begin();
262 
263  createTauBlockInputs<CandidateCastType>(tau_casted, tau_index, tau_ref, pv, rho, tau_funcs, tauIter);
264 
265  // egamma, muon, and hadron inner and outer inputs for the grids
266  createConvFeatures<CandidateCastType>(tau_casted,
267  tau_index,
268  tau_ref,
269  pv,
270  rho,
271  electrons,
272  muons,
273  pfCands,
274  inner_grid,
275  tau_funcs,
276  true,
281  createConvFeatures<CandidateCastType>(tau_casted,
282  tau_index,
283  tau_ref,
284  pv,
285  rho,
286  electrons,
287  muons,
288  pfCands,
289  outer_grid,
290  tau_funcs,
291  false,
296 }
297 
298 template <typename CandidateCastType, typename TauCastType>
300  const size_t tau_index,
301  const edm::RefToBase<reco::BaseTau> tau_ref,
302  const reco::Vertex& pv,
303  double rho,
304  const std::vector<pat::Electron>* electrons,
305  const std::vector<pat::Muon>* muons,
306  const edm::View<reco::Candidate>& pfCands,
307  const CellGrid& grid,
308  const TauFunc& tau_funcs,
309  bool is_inner,
310  std::vector<float>* p_egammaBlockInputs,
311  std::vector<float>* p_muonBlockInputs,
312  std::vector<float>* p_hadronBlockInputs,
313  std::vector<int64_t>* p_GridposInputs) {
314  // fill in the block inputs with zeros
315  int n_cells = 0;
316  int n_cell_oneside = is_inner ? dnn_inputs_v2::number_of_inner_cell : dnn_inputs_v2::number_of_outer_cell;
317 
318  n_cells = is_inner ? (dnn_inputs_v2::number_of_inner_cell * dnn_inputs_v2::number_of_inner_cell)
319  : (dnn_inputs_v2::number_of_outer_cell * dnn_inputs_v2::number_of_outer_cell);
320 
321  p_egammaBlockInputs->insert(
322  p_egammaBlockInputs->end(), n_cells * dnn_inputs_v2::EgammaBlockInputs::NumberOfInputs, 0.);
323  std::vector<float>::iterator egammaIter = p_egammaBlockInputs->begin();
324 
325  p_muonBlockInputs->insert(p_muonBlockInputs->end(), n_cells * dnn_inputs_v2::MuonBlockInputs::NumberOfInputs, 0.);
326  std::vector<float>::iterator muonIter = p_muonBlockInputs->begin();
327 
328  p_hadronBlockInputs->insert(
329  p_hadronBlockInputs->end(), n_cells * dnn_inputs_v2::HadronBlockInputs::NumberOfInputs, 0.);
330  std::vector<float>::iterator hadronIter = p_hadronBlockInputs->begin();
331 
332  unsigned idx = 0;
333  for (int eta = -grid.maxEtaIndex(); eta <= grid.maxEtaIndex(); ++eta) {
334  for (int phi = -grid.maxPhiIndex(); phi <= grid.maxPhiIndex(); ++phi) {
335  if (debug_level >= 2) {
336  std::cout << "processing ( eta = " << eta << ", phi = " << phi << " )" << std::endl;
337  }
338  const CellIndex cell_index{eta, phi};
339 
340  const auto cell_iter = grid.find(cell_index);
341  if (cell_iter != grid.end()) {
342  if (debug_level >= 2) {
343  std::cout << " creating inputs for ( eta = " << eta << ", phi = " << phi << " ): idx = " << idx << std::endl;
344  }
345  const Cell& cell = cell_iter->second;
346  const int eta_index = grid.getEtaTensorIndex(cell_index);
347  const int phi_index = grid.getPhiTensorIndex(cell_index);
348  std::vector<float>::iterator egammaIterCell =
349  egammaIter + (eta_index * n_cell_oneside + phi_index) * dnn_inputs_v2::EgammaBlockInputs::NumberOfInputs;
350  std::vector<float>::iterator muonIterCell =
351  muonIter + (eta_index * n_cell_oneside + phi_index) * dnn_inputs_v2::MuonBlockInputs::NumberOfInputs;
352  std::vector<float>::iterator hadronIterCell =
353  hadronIter + (eta_index * n_cell_oneside + phi_index) * dnn_inputs_v2::HadronBlockInputs::NumberOfInputs;
354 
355  createEgammaBlockInputs<CandidateCastType>(
356  idx, tau, tau_index, tau_ref, pv, rho, electrons, pfCands, cell, tau_funcs, is_inner, egammaIterCell);
357  createMuonBlockInputs<CandidateCastType>(
358  idx, tau, tau_index, tau_ref, pv, rho, muons, pfCands, cell, tau_funcs, is_inner, muonIterCell);
359  createHadronsBlockInputs<CandidateCastType>(
360  idx, tau, tau_index, tau_ref, pv, rho, pfCands, cell, tau_funcs, is_inner, hadronIterCell);
361 
362  idx += 1;
363  } else {
364  if (debug_level >= 2) {
365  std::cout << " skipping creation of inputs, because ( eta = " << eta << ", phi = " << phi
366  << " ) is not in the grid !!" << std::endl;
367  }
368  // we need to fill in the zeros for the input tensors
369  idx += 1;
370  }
371  }
372  }
373 }
374 
379  descriptions.add("DeepTauIdSonicProducer", desc);
380 }
381 
edm::EDGetTokenT< std::vector< pat::Electron > > electrons_token_
std::vector< TauDiscInfo< pat::PATTauDiscriminator > > patPrediscriminants_
std::vector< float > * p_egammaInnerBlockInputs
std::vector< float > * p_hadronOuterBlockInputs
edm::EDGetTokenT< double > rho_token_
DeepTauIdSonicProducer(edm::ParameterSet const &cfg)
std::map< BasicDiscriminator, size_t > basicDiscrIndexMap_
void produce(edm::Event &iEvent, edm::EventSetup const &iSetup, Output const &iOutput) override
std::vector< float > * p_tauBlockInputs
const std::vector< BasicDiscriminator > requiredBasicDiscriminators_
std::vector< float > * p_egammaOuterBlockInputs
std::vector< float > * p_hadronInnerBlockInputs
muons
the two sets of parameters below are mutually exclusive, depending if RECO or ALCARECO is used the us...
Definition: DiMuonV_cfg.py:214
edm::EDGetTokenT< CandidateCollection > pfcandToken_
edm::EDGetTokenT< std::vector< pat::Muon > > muons_token_
static void fillDescriptionsHelper(edm::ParameterSetDescription &desc)
int iEvent
Definition: GenABIO.cc:224
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, const TauFunc &tau_funcs, bool is_inner, std::vector< float > *p_egammaBlockInputs, std::vector< float > *p_muonBlockInputs, std::vector< float > *p_hadronBlockInputs, std::vector< int64_t > *p_GridposInputs)
std::vector< float > * p_muonInnerBlockInputs
edm::EDGetTokenT< reco::TauDiscriminatorContainer > basicTauDiscriminators_inputToken_
edm::EDGetTokenT< TauCollection > tausToken_
std::map< BasicDiscriminator, size_t > basicDiscrdR03IndexMap_
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
edm::EDGetTokenT< reco::TauDiscriminatorContainer > basicTauDiscriminatorsdR03_inputToken_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
void acquire(edm::Event const &iEvent, edm::EventSetup const &iSetup, Input &iInput) override
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)
std::vector< float > * p_muonOuterBlockInputs
void loadPrediscriminants(edm::Event const &event, edm::Handle< TauCollection > const &taus)
std::vector< int64_t > * p_outerGridposInputs
void add(std::string const &label, ParameterSetDescription const &psetDescription)
void fillGrids(const TauCastType &tau, const Collection &objects, CellGrid &inner_grid, CellGrid &outer_grid)
edm::EDGetTokenT< reco::VertexCollection > vtxToken_
static void fillPSetDescription(edm::ParameterSetDescription &iDesc)
std::vector< TauDiscInfo< reco::PFTauDiscriminator > > recoPrediscriminants_
std::vector< int64_t > * p_innerGridposInputs
T const & const_reference
Definition: View.h:84
void prepareInputsV2(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 TauFunc &tau_funcs)
std::vector< size_t > tau_indices_
constexpr int NumberOfOutputs
Definition: DeepTauIdBase.h:50
edm::EDGetTokenT< edm::AssociationVector< reco::PFTauRefProd, std::vector< reco::PFTauTransverseImpactParameterRef > > > pfTauTransverseImpactParameters_token_