ATLAS Offline Software
DefectsEmulatorCondAlgBase.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
5 
7 #include "CLHEP/Random/RandPoisson.h"
8 #include "CLHEP/Random/RandFlat.h"
9 
10 #include "HistUtil.h"
12 #include <numeric>
13 #include <cmath>
14 
15 namespace {
16  bool hasExtensions(const std::string &name, const std::string_view &ext) {
17  return name.size()>=ext.size() && name.substr(name.size()-ext.size(),ext.size())==ext;
18  }
19 }
20 
21 namespace InDet{
22 
23  DefectsEmulatorCondAlgBase::DefectsEmulatorCondAlgBase(const std::string &name, ISvcLocator *pSvcLocator)
24  : AthReentrantAlgorithm(name, pSvcLocator)
25  {}
26 
27  StatusCode DefectsEmulatorCondAlgBase::initializeBase(unsigned int n_masks, unsigned int wafer_hash_max){
28  ATH_CHECK(m_rndmSvc.retrieve());
29  m_rngName.reserve( m_rngPerDefectType.value() ? kMaskDefects + n_masks : 1);
30  if (m_rngPerDefectType.value() ) {
31  m_rngName.push_back(name()+"RngModuleDefects");
32  m_rngName.push_back(name()+"RngCornerDefects");
33  for (unsigned int mask_i=0; mask_i<n_masks; ++mask_i) {
34  std::stringstream rng_name;
35  rng_name << name() << "RngMaskDefect" << mask_i;
36  m_rngName.push_back(rng_name.str());
37  }
38  assert(kMaskDefects+n_masks == m_rngName.size());
39  }
40  else {
41  m_rngName.push_back(name()+"RandomEngine");
42  }
45  if (!m_outputFile.empty() && (!hasExtensions(m_outputFile.value(), ".root") && !hasExtensions(m_outputFile.value(), ".json"))) {
46  ATH_MSG_ERROR("Output file \"" << m_outputFile.value() << "\" does not have extensions \".root\" or \".json\".");
47  return StatusCode::FAILURE;
48  }
49  for (const std::string &input_file : m_inputFiles.value()) {
50  if ((!hasExtensions(input_file, ".root") && !hasExtensions(input_file, ".json"))) {
51  ATH_MSG_ERROR("Input file \"" << input_file << "\" does not have extensions \".root\" or \".json\".");
52  return StatusCode::FAILURE;
53  }
54  }
55 
56  if (!m_histSvc.name().empty() && !m_histogramGroupName.value().empty()) {
57  ATH_CHECK(m_histSvc.retrieve());
59  // allow histogramming for at most 6 different pixel module types
60  // histgram for additional module types will end up in the last histogram
61  unsigned int n_pattern_for_histogramming = m_fillHistogramsPerPattern ? m_modulePattern.size() : 1;
62  constexpr unsigned int n_different_matrices_max=6;
63  m_dimPerHist.resize(n_pattern_for_histogramming);
64  m_hist.resize(n_pattern_for_histogramming);
65  if (!m_groupDefectHistNames.empty()) {
66  m_groupDefectHists.resize(n_pattern_for_histogramming);
67  }
68  for (unsigned int pattern_i=0; pattern_i < n_pattern_for_histogramming; ++pattern_i) {
69  m_dimPerHist[pattern_i].reserve(n_different_matrices_max);
70  m_hist[pattern_i].reserve(n_different_matrices_max);
71  }
72  std::vector<std::string> hist_name {
73  "matrix_type_id_per_module;Matrix type ID per module",
74  "defect_module;Module is defect",
75  "defects_per_module;Defect cells per module"};
76  for (const std::string &group_name: m_groupDefectHistNames) {
78  hname << group_name << "defects_per_module;" << group_name <<" defects per module";
79  hist_name.push_back(hname.str());
80  }
81  m_moduleHist.resize(n_pattern_for_histogramming);
82  unsigned int max_y_axis = (((wafer_hash_max+99)/100+9)/10)*10;
83 
84  for (unsigned int pattern_i=0; pattern_i<m_moduleHist.size(); ++pattern_i) {
85  m_moduleHist.at(pattern_i).resize(hist_name.size(), nullptr);
86  for (unsigned int hist_i=0; hist_i<hist_name.size(); ++hist_i) {
87  // support idHashes from 0 to 10k
88  std::string::size_type pos = hist_name.at(hist_i).find(";");
89  HistUtil::StringCat a_name;
90  a_name << hist_name[hist_i].substr(0, (pos != std::string::npos ? pos : hist_name[hist_i].size())) << "_" << pattern_i;
91  HistUtil::StringCat a_title;
92  a_title << hist_name[hist_i].substr((pos != std::string::npos ? pos+1 : 0), hist_name[hist_i].size())
93  << " ( module pattern " << pattern_i << ")";
94  {
96  m_moduleHist.at(pattern_i).at(hist_i) = new TH2F(a_name.str().c_str(), a_title.str().c_str(),
97  100, -0.5, 100-0.5,
98  max_y_axis, -0.5, max_y_axis-0.5);
99  }
100  m_moduleHist[pattern_i][hist_i]->GetXaxis()->SetTitle("ID hash % 100");
101  m_moduleHist[pattern_i][hist_i]->GetYaxis()->SetTitle("ID hash / 100");
102  ATH_MSG_VERBOSE("Create histogram pattern " << pattern_i << " hist " << hist_i << " name " << a_name.str().c_str()
103  << " -> " << m_moduleHist[pattern_i][hist_i]->GetName());
104  if ( m_histSvc->regHist(m_histogramGroupName.value() + m_moduleHist[pattern_i][hist_i]->GetName(),
105  m_moduleHist[pattern_i][hist_i]).isFailure() ) {
106  return StatusCode::FAILURE;
107  }
108  }
109  }
110 
111  unsigned int n_eta_phi_histograms = m_fillEtaPhiHistogramsPerPattern ? m_modulePattern.size() : 1;
112  for (unsigned int pos_i=0; pos_i<m_defectModuleEtaPhiHist.size(); ++pos_i) {
113  m_defectModuleEtaPhiHist.at(pos_i).resize(n_eta_phi_histograms, nullptr);
114  m_defectModuleEtaLayerHist.at(pos_i).resize(n_eta_phi_histograms, nullptr);
115  }
116  std::array<std::string_view, kNPosHists> pos_hist_name {
117  "defect_modules",
118  "modules_with_defects"
119  };
120  std::array<std::string_view, kNPosHists> pos_hist_title {
121  "Defect modules",
122  "Modules with defects"
123  };
124  for (unsigned pattern_i=0; pattern_i< n_eta_phi_histograms; ++pattern_i) {
125  for (unsigned int pos_i=0; pos_i<m_defectModuleEtaPhiHist.size(); ++pos_i) {
126  {
127  HistUtil::StringCat a_name;
128  a_name << pos_hist_name.at(pos_i) << "_zr" << "_" << pattern_i;
129  HistUtil::StringCat a_title;
130  a_title << pos_hist_title.at(pos_i) << " vs global zr" << " ( module pattern " << pattern_i << ")";
131  {
133  m_defectModuleEtaPhiHist.at(pos_i).at(pattern_i) = new TH2F(a_name.str().c_str(), a_title.str().c_str(),
134  200, -3000, 3000,
135  200, 0, 1050
136  );
137  }
138  if ( m_histSvc->regHist(m_histogramGroupName.value() + m_defectModuleEtaPhiHist.at(pos_i).at(pattern_i)->GetName(),
139  m_defectModuleEtaPhiHist.at(pos_i).at(pattern_i)).isFailure() ) {
140  return StatusCode::FAILURE;
141  }
142  }
143  {
144  HistUtil::StringCat a_name;
145  a_name << pos_hist_name.at(pos_i) << "_xy" << "_" << pattern_i;
146  HistUtil::StringCat a_title;
147  a_title << pos_hist_title.at(pos_i) << " vs global xy" << " ( module pattern " << pattern_i << ")";
148  {
150  m_defectModuleEtaLayerHist.at(pos_i).at(pattern_i) = new TH2F(a_name.str().c_str(), a_title.str().c_str(),
151  200, -1050,1050,
152  200, -1050,1050
153  );
154  }
155  if ( m_histSvc->regHist(m_histogramGroupName.value() + m_defectModuleEtaLayerHist.at(pos_i).at(pattern_i)->GetName(),
156  m_defectModuleEtaLayerHist.at(pos_i).at(pattern_i)).isFailure() ) {
157  return StatusCode::FAILURE;
158  }
159  }
160  }
161  }
162 
163  if (n_masks>1) {
164  m_maxNGroupDefects.resize( n_masks-1, 0u);
165  for (const std::vector<std::vector<float> > &fractions_per_pattern : m_perPatternAndMaskFractions) {
166  for (unsigned int mask_i=0; mask_i<n_masks-1; ++mask_i) {
167  m_maxNGroupDefects[mask_i] = std::max(m_maxNGroupDefects[mask_i], static_cast<unsigned int>(fractions_per_pattern[mask_i].size()));
168  }
169  }
170 
171  if (m_groupDefectHistNames.size() != n_masks-1) {
172  ATH_MSG_FATAL("m_groupDefectHistNames does not contain a name per mask starting from the second mask "
173  "(the first mask must be the full matrix)");
174  return StatusCode::FAILURE;
175  }
176  if (m_maxNGroupDefects.size() != n_masks-1) {
177  ATH_MSG_FATAL("m_maxNGroupDefects does not contain a upper bin value for number of expected defects "
178  "per mask starting from the second mask (the first mask must be the full matrix)");
179  return StatusCode::FAILURE;
180  }
181  }
182  }
183 
184  return StatusCode::SUCCESS;
185  }
186 
187 
188  StatusCode DefectsEmulatorCondAlgBase::checkProbabilities(unsigned int n_probabilities) const {
189  if (!(m_modulePattern.size() == m_defectProbability.size()
191  && ModuleIdentifierMatchUtil::verifyElementCount<double>(m_defectProbability.value(), n_probabilities))) {
192  if (m_modulePattern.size() != m_defectProbability.size()) {
193  ATH_MSG_ERROR( "size difference modulePattern vs defectProbability : " << m_modulePattern.size() << " != " << m_defectProbability.size() << "?");
194  }
196  if (!ret) {
197  ATH_MSG_ERROR( "Order problem in modulePattern : " << ret << "?");
198  }
199  ret = ModuleIdentifierMatchUtil::verifyElementCount<double>(m_defectProbability.value(), n_probabilities);
200  if (!ret) {
201  ATH_MSG_ERROR( "Size problem in defectProbability : " << ret << " ( n_prob" << n_probabilities << ")?");
202  }
203  }
204  return m_modulePattern.size() == m_defectProbability.size()
206  && ModuleIdentifierMatchUtil::verifyElementCount<double>(m_defectProbability.value(), n_probabilities)
207  ? StatusCode::SUCCESS : StatusCode::FAILURE;
208  }
209 
212  ATH_MSG_WARNING("No defect parameters for " << m_modulesWithoutDefectParameters << " modules.");
213  }
214  return StatusCode::SUCCESS;
215  }
216 
217 
218  unsigned int DefectsEmulatorCondAlgBase::throwNumberOfDefects(std::span<CLHEP::HepRandomEngine *>rndmEngine,
219  const std::vector<unsigned int> &module_pattern_idx,
220  unsigned int n_masks,
221  unsigned int n_cells,
222  std::vector<unsigned int> &n_mask_defects) const
223  {
224  n_mask_defects.clear();
225  n_mask_defects.resize(n_masks, 0u);
226 
227  // to avoid throwing random numbers if not necessary
228  // first identify the masks for which random numbers need to be thrown.
229  std::vector<bool> has(n_masks, false);
230  for (unsigned int mask_i=n_masks; mask_i-->1; ) {
231  for (unsigned int match_i: module_pattern_idx) {
232  assert(!m_perPatternAndMaskFractions.at(match_i).at(mask_i-1).empty());
233  if (m_perPatternAndMaskFractions.at(match_i).at(mask_i-1).back()>0.) {
234  has[mask_i]=true;
235  break;
236  }
237  }
238  }
239 
240  for (unsigned int mask_i=n_masks; mask_i-->1; ) {
241  assert(mask_i>0 && mask_i<rndmEngine.size());
242  float prob = !has.at(mask_i) ? 1. : CLHEP::RandFlat::shoot(rndmEngine[mask_i],1.);
243 
244  for (unsigned int match_i: module_pattern_idx) {
245  unsigned int n_mask_defects_idx=m_perPatternAndMaskFractions.at(match_i).at(mask_i-1).size();
246  for (; n_mask_defects_idx-->0 && prob <= m_perPatternAndMaskFractions[match_i][mask_i-1][n_mask_defects_idx];);
247  if (++n_mask_defects_idx < m_perPatternAndMaskFractions[match_i][mask_i-1].size()) {
248  n_mask_defects[mask_i] = n_mask_defects_idx+1;
249  break;
250  }
251 
252  prob -= m_perPatternAndMaskFractions[match_i][mask_i-1].back();
253  if (prob<=0.f) break;
254  }
255  }
256  double defect_prob = totalProbability(module_pattern_idx,kCellDefectProb);
257  n_mask_defects[0]= static_cast<unsigned int>(std::max(0,static_cast<int>(
258  CLHEP::RandPoisson::shoot(rndmEngine[0],
259  n_cells * defect_prob))));
260  return std::accumulate(n_mask_defects.begin(),n_mask_defects.end(), 0u);
261  }
262 
263  void DefectsEmulatorCondAlgBase::printSummaryOfDefectGeneration([[maybe_unused]] unsigned int n_masks,
264  unsigned int n_error,
265  unsigned int n_defects_total,
266  const std::vector<std::array<unsigned int,kNCounts> >&counts) const {
267  assert(counts.size() == n_masks+1 );
268  msg(MSG::INFO) << "Total cells: " << counts[0][kNElements] << ", module design of wrong type: " << n_error << ", defects "
269  << n_defects_total << ".\n";
270  for (unsigned int mask_i=0; mask_i < counts.size(); ++mask_i) {
271  msg() << "Defect " << (mask_i==0 ? "cells" : (mask_i>m_groupDefectHistNames.size() ? "modules" : m_groupDefectHistNames.at(mask_i-1)))
272  << " " << counts[mask_i][kNDefects] << " / " << counts[mask_i][kNElements];
273  if (counts[mask_i][kNRetries]>0 || counts[mask_i][kNMaxRtriesExceeded]>0) {
274  msg() << "(";
275  if (counts[mask_i][kNRetries]>0) {
276  msg() << "retries " << counts[mask_i][kNRetries];
277  if (counts[mask_i][kNMaxRtriesExceeded]>0) {
278  msg() << ";";
279  }
280  }
281  if (counts[mask_i][kNMaxRtriesExceeded]>0) {
282  msg() << "exceeded max attempts " << counts[mask_i][kNMaxRtriesExceeded];
283  }
284  msg() << ")";
285  }
286  if (counts[mask_i][kMaxDefectsPerModule]>0) {
287  msg() << " max/module " <<counts[mask_i][kMaxDefectsPerModule];
288  }
289  if (mask_i+1<counts.size()) {
290  msg() << ".\n";
291  }
292  }
293  msg() << endmsg;
294  }
295 
296  std::pair<unsigned int,unsigned int> DefectsEmulatorCondAlgBase::findHist(unsigned int pattern_i, unsigned int n_rows, unsigned int n_cols) const {
297  unsigned int key=(n_rows << 16) | n_cols;
298  assert( pattern_i < m_dimPerHist.size());
299  assert( pattern_i < m_hist.size());
300  unsigned int matrix_type_id;
301  {
302  std::vector<unsigned int>::const_iterator global_iter = std::find(m_matrixTypeId.begin(), m_matrixTypeId.end(), key );
303  if (global_iter != m_matrixTypeId.end()) {
304  matrix_type_id = global_iter - m_matrixTypeId.begin();
305  }
306  else {
307  matrix_type_id =m_matrixTypeId.size();
308  m_matrixTypeId.push_back(key);
309  }
310  }
311 
312  std::vector<unsigned int>::const_iterator iter = std::find(m_dimPerHist[pattern_i].begin(), m_dimPerHist[pattern_i].end(), key );
313  if (iter == m_dimPerHist[pattern_i].end()) {
315  name << "defects_" << pattern_i << "_" << (matrix_type_id) << "_" << n_rows << "_" << n_cols;
317  title << "Defects for " << n_rows << "(rows) #times " << n_cols << " (columns) ID " << (matrix_type_id) << ", pattern " << pattern_i;
318  {
320  m_hist[pattern_i].push_back(new TH2F(name.str().c_str(), title.str().c_str(),
321  n_cols, -0.5, n_cols-0.5,
322  n_rows, -0.5, n_rows-0.5
323  ));
324  }
325  m_hist[pattern_i].back()->GetXaxis()->SetTitle("offline column");
326  m_hist[pattern_i].back()->GetYaxis()->SetTitle("offline row");
327  if ( m_histSvc->regHist(m_histogramGroupName.value() + name.str(),m_hist[pattern_i].back()).isFailure() ) {
328  throw std::runtime_error("Failed to register histogram.");
329  }
330  m_dimPerHist[pattern_i].push_back(key);
331 
332  if (!m_groupDefectHists.empty()) {
333  assert( pattern_i < m_groupDefectHists.size());
334  assert( m_groupDefectHistNames.size() == m_maxNGroupDefects.size());
335  m_groupDefectHists[pattern_i].emplace_back();
336  m_groupDefectHists[pattern_i].back().resize(m_groupDefectHistNames.size());
337  for (unsigned int group_i=0u; group_i < m_groupDefectHistNames.size(); ++group_i) {
338  const std::string &group_name = m_groupDefectHistNames[group_i];
340  hname << "n_" << group_name << "_" << pattern_i << "_" << matrix_type_id << "_" << n_rows << "_" << n_cols;
341  HistUtil::StringCat htitle;
342  htitle << "Number of " << group_name << " defects for " << n_rows << "(rows) #times " << n_cols << " (columns) ID "
343  << (matrix_type_id) << ", pattern " << pattern_i;
344 
345  {
347  assert(group_i < m_groupDefectHists[pattern_i].back().size());
348  m_groupDefectHists[pattern_i].back()[group_i]= new TH1F(hname.str().c_str(), htitle.str().c_str(),
349  m_maxNGroupDefects[group_i]+1, -0.5,m_maxNGroupDefects[group_i]+.5);
350  }
351  if (m_histSvc->regHist(m_histogramGroupName.value() + m_groupDefectHists[pattern_i].back()[group_i]->GetName(),
352  m_groupDefectHists[pattern_i].back()[group_i]).isFailure() ) {
353  throw std::runtime_error("Failed to register histogram.");
354  }
355  }
356  }
357  return std::make_pair(static_cast<unsigned int>(m_hist[pattern_i].size()-1), matrix_type_id);
358  }
359  else {
360  return std::make_pair(static_cast<unsigned int>(iter-m_dimPerHist[pattern_i].begin()), matrix_type_id);
361  }
362  }
363 
364  namespace {
365  MsgStream &operator<<(MsgStream &out, const std::vector<float> &values) {
366  for (float value : values) {
367  out << " " << value;
368  }
369  return out;
370  }
371  }
372 
374  if (n_masks>1) {
375  if (m_nDefectFractionsPerPattern.size() != m_modulePattern.size()) {
376  ATH_MSG_ERROR("The number of fraction lists per pattern does not match the number of module patterns: "
377  << m_nDefectFractionsPerPattern.size() << " != " << m_modulePattern.size());
378  return StatusCode::FAILURE;
379  }
380  if (m_defectProbability.size() != m_modulePattern.size()) {
381  ATH_MSG_ERROR("The number of probability lists per pattern does not match the number of module patterns: "
382  << m_defectProbability.size() << " != " << m_modulePattern.size());
383  return StatusCode::FAILURE;
384  }
386  for (unsigned int pattern_i=0; pattern_i< m_perPatternAndMaskFractions.size(); ++pattern_i) {
387  m_perPatternAndMaskFractions[pattern_i].reserve( n_masks-1);
388  m_perPatternAndMaskFractions[pattern_i].emplace_back();
389  if (m_defectProbability[pattern_i].size() != kCellDefectProb + n_masks) {
390  ATH_MSG_ERROR("There should be one probability for the module to be defect, one probability for a pixel/strip etc. "
391  "to be defect and one probability for each group to be defect i.e. "
392  << (kCellDefectProb + n_masks) << " probabilities, but there are "
393  << m_defectProbability.size() << " for pattern " << pattern_i);
394  return StatusCode::FAILURE;
395  }
396  double sum=0.;
397  for (unsigned int value_i=0; value_i< m_nDefectFractionsPerPattern[pattern_i].size(); ++value_i) {
398  if (m_nDefectFractionsPerPattern[pattern_i][value_i]<0.) {
399  if (value_i+1 < m_nDefectFractionsPerPattern[pattern_i].size()) {
400  if (m_perPatternAndMaskFractions[pattern_i].size() == n_masks-1) {
401  ATH_MSG_ERROR("More fraction lists than number of masks: "
402  << m_perPatternAndMaskFractions[pattern_i].size()+1 << " > " << (n_masks-1)
403  << " for pattern " << pattern_i);
404  return StatusCode::FAILURE;
405  }
406  m_perPatternAndMaskFractions[pattern_i].emplace_back();
407  sum=0.;
408  }
409  }
410  else {
411  sum += m_nDefectFractionsPerPattern[pattern_i][value_i];
412  m_perPatternAndMaskFractions[pattern_i].back().push_back(sum);
413  }
414  }
415  for (unsigned int mask_i=0; mask_i< m_perPatternAndMaskFractions[pattern_i].size(); ++mask_i) {
416  if ( m_perPatternAndMaskFractions[pattern_i][mask_i].empty()
417  || std::abs(m_perPatternAndMaskFractions[pattern_i][mask_i].back()-1.)>1e-5) {
418  ATH_MSG_ERROR("Empty fraction list or fractions do not add up to 1: "
419  << (!m_perPatternAndMaskFractions[pattern_i][mask_i].empty()
420  ?m_perPatternAndMaskFractions[pattern_i][mask_i].back() : -1.f)
421  << " for pattern " << pattern_i << ", mask " << mask_i
422  << " (" << m_groupDefectHistNames.at(mask_i) << ")");
423  return StatusCode::FAILURE;
424  }
425  ATH_MSG_DEBUG("Fractions for pattern " << pattern_i << " mask " << mask_i
426  << " (" << m_groupDefectHistNames.at(mask_i) << "):"
427  << m_perPatternAndMaskFractions[pattern_i][mask_i]);
428  assert( pattern_i < m_defectProbability.size() );
429  assert( kNProb + mask_i < m_defectProbability[pattern_i].size() );
430  for (float &value : m_perPatternAndMaskFractions[pattern_i][mask_i] ) {
431  value *= m_defectProbability[pattern_i][kNProb+mask_i];
432  }
433  ATH_MSG_DEBUG("Probabilities for pattern " << pattern_i << " mask " << mask_i
434  << " (" << m_groupDefectHistNames.at(mask_i) << ") for 1.."
435  << m_perPatternAndMaskFractions[pattern_i][mask_i].size() << " defects:"
436  << m_perPatternAndMaskFractions[pattern_i][mask_i]);
437  }
438  }
439  }
440  return checkProbabilities(kCellDefectProb+n_masks);
441  }
442 
444  if (!m_cornerDefectParamsPerPattern.empty()) {
445  if (m_cornerDefectParamsPerPattern.size() != m_modulePattern.size()) {
446  ATH_MSG_ERROR("Expected exactly one set of corner defect parameters per module pattern but the numbers disagree "
447  << m_cornerDefectParamsPerPattern.size() << " != " << m_modulePattern.size());
448  return StatusCode::FAILURE;
449  }
451  ATH_MSG_ERROR("Expected exactly one set of n corner fractions per module pattern but the numbers disagree "
453  return StatusCode::FAILURE;
454  }
456  for (unsigned int pattern_i=0; pattern_i < m_cornerDefectParamsPerPattern.size(); ++pattern_i) {
457  if (m_cornerDefectParamsPerPattern[pattern_i].empty()) continue;
459  ATH_MSG_ERROR("Mismatch in number of corner defect parameters for pattern " << pattern_i << ". Expected " << kNCornerDefectParams
460  << " but got " << m_cornerDefectParamsPerPattern[pattern_i].size() );
461  return StatusCode::FAILURE;
462  }
463  if (m_cornerDefectNCornerFractionsPerPattern[pattern_i].size()>4) {
464  ATH_MSG_ERROR("Too many Fractions for corner defects for pattern " << pattern_i <<
465  ". Expected fractions for at most 4 corners but got " << m_cornerDefectNCornerFractionsPerPattern[pattern_i].size()
466  << ".");
467  return StatusCode::FAILURE;
468  }
469  double scale = std::accumulate( m_cornerDefectNCornerFractionsPerPattern.value()[pattern_i].begin(),
470  m_cornerDefectNCornerFractionsPerPattern.value()[pattern_i].end(),
471  0.);
472  if (std::abs(scale-1.)>1e-3) {
473  ATH_MSG_ERROR("The fractions for corner defects in 1.." << m_cornerDefectNCornerFractionsPerPattern[pattern_i].size()
474  << " corner(s) for pattern " << pattern_i << " do not add up to ~1 but " << scale);
475  return StatusCode::FAILURE;
476  }
479  double total = 0.;
480  for (double fraction : m_cornerDefectNCornerFractionsPerPattern[pattern_i]) {
481  total += fraction * scale;
482  m_perPatternCornerDefectNCornerCummulativeProb[pattern_i].push_back( static_cast<float>(total) );
483  }
484  }
485  }
486  return StatusCode::SUCCESS;
487  }
488 
489 
490  void DefectsEmulatorCondAlgBase::histogramDefectModule(unsigned int module_pattern_i,
491  unsigned int hist_pattern_i,
492  unsigned int id_hash,
493  const Amg::Vector3D &center) const {
494  assert( hist_pattern_i < m_moduleHist.size() );
495  unsigned int ids_per_col = static_cast<unsigned int>(m_moduleHist[hist_pattern_i][kDefectModule]->GetNbinsX());
496  unsigned int bin_i=m_moduleHist[hist_pattern_i][kDefectModule]->GetBin( id_hash%ids_per_col+1, id_hash/ids_per_col+1);
497  m_moduleHist[hist_pattern_i][kDefectModule]->SetBinContent(bin_i,1);
498  unsigned int eta_phi_pattern_i = m_fillEtaPhiHistogramsPerPattern ? module_pattern_i : 0;
499  assert( kDefectModulePos < m_defectModuleEtaPhiHist.size());
500  assert( eta_phi_pattern_i < m_defectModuleEtaPhiHist[kDefectModulePos].size() );
501  m_defectModuleEtaPhiHist[kDefectModulePos][eta_phi_pattern_i]->Fill(center.z(), center.perp());
502  m_defectModuleEtaLayerHist[kDefectModulePos][eta_phi_pattern_i]->Fill(center.x(), center.y());
503  }
504 
505  void DefectsEmulatorCondAlgBase::fillPerModuleHistograms(unsigned int module_pattern_i,
506  unsigned int pattern_hist_i,
507  unsigned int matrix_histogram_index,
508  unsigned int matrix_index,
509  unsigned int module_i,
510  unsigned int n_masks,
511  const std::vector<unsigned int> &n_mask_defects,
512  const Amg::Vector3D &center) const
513  {
514  // all the following histograms are expected to have the same binning
515  // i.e. one bin per ID hash organised in a matrix
516  assert( pattern_hist_i < m_moduleHist.size());
517  assert( kMatrixTypeId < m_moduleHist[pattern_hist_i].size());
518  assert( kDefectModule < m_moduleHist[pattern_hist_i].size());
519  unsigned int ids_per_col = static_cast<unsigned int>(m_moduleHist[pattern_hist_i][kDefectModule]->GetNbinsX());
520  unsigned int bin_i=m_moduleHist[pattern_hist_i][kDefectModule]->GetBin( module_i%ids_per_col+1, module_i/ids_per_col+1);
521  unsigned int mask_i=n_masks;
522  for (; --mask_i>0; ) {
523  assert( mask_i < n_mask_defects.size() && mask_i>0);
524  if (!m_groupDefectHists.empty()) {
525  m_groupDefectHists[pattern_hist_i][matrix_histogram_index][mask_i-1]->Fill(n_mask_defects[mask_i]);
526  }
527  assert( (kDefectCell+mask_i) < m_moduleHist[pattern_hist_i].size());
528  m_moduleHist[pattern_hist_i][kDefectCell+mask_i]->SetBinContent(bin_i, n_mask_defects[mask_i]);
529  }
530  assert( (kDefectCell+mask_i) < m_moduleHist[pattern_hist_i].size());
531  m_moduleHist[pattern_hist_i][kDefectCell+mask_i]->SetBinContent(bin_i, n_mask_defects[mask_i]);
532  m_moduleHist[pattern_hist_i][kMatrixTypeId]->SetBinContent(bin_i, matrix_index+1 );
533  unsigned int n_defects_total = std::accumulate(n_mask_defects.begin(),n_mask_defects.end(), 0u);
534  if (n_defects_total>0) {
535  unsigned int eta_phi_pattern_i = m_fillEtaPhiHistogramsPerPattern ? module_pattern_i : 0;
536  assert( kModulesWithDefectsPos < m_defectModuleEtaPhiHist.size());
537  assert( eta_phi_pattern_i < m_defectModuleEtaPhiHist[kModulesWithDefectsPos].size() );
538  m_defectModuleEtaPhiHist[kModulesWithDefectsPos][eta_phi_pattern_i]->Fill(center.z(), center.perp());
539  m_defectModuleEtaLayerHist[kModulesWithDefectsPos][eta_phi_pattern_i]->Fill(center.x(), center.y(),n_defects_total);
540  }
541  }
542 
543 
544 }// namespace closure
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
createLinkingScheme.iter
iter
Definition: createLinkingScheme.py:62
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
InDet::DefectsEmulatorCondAlgBase::m_rndmSvc
ServiceHandle< IAthRNGSvc > m_rndmSvc
Definition: DefectsEmulatorCondAlgBase.h:47
InDet::DefectsEmulatorCondAlgBase::kMaxDefectsPerModule
@ kMaxDefectsPerModule
Definition: DefectsEmulatorCondAlgBase.h:165
InDet::DefectsEmulatorCondAlgBase::m_nDefectFractionsPerPattern
Gaudi::Property< std::vector< std::vector< double > > > m_nDefectFractionsPerPattern
Definition: DefectsEmulatorCondAlgBase.h:57
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
dqt_zlumi_pandas.hname
string hname
Definition: dqt_zlumi_pandas.py:280
InDet::DefectsEmulatorCondAlgBase::findHist
std::pair< unsigned int, unsigned int > findHist(unsigned int pattern_i, unsigned int n_rows, unsigned int n_cols) const
Definition: DefectsEmulatorCondAlgBase.cxx:296
InDet::DefectsEmulatorCondAlgBase::kDefectModulePos
@ kDefectModulePos
Definition: DefectsEmulatorCondAlgBase.h:237
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
InDet
Primary Vertex Finder.
Definition: VP1ErrorUtils.h:36
InDet::DefectsEmulatorCondAlgBase::initializeCornerDefects
StatusCode initializeCornerDefects()
Definition: DefectsEmulatorCondAlgBase.cxx:443
InDet::DefectsEmulatorCondAlgBase::totalProbability
double totalProbability(const std::vector< unsigned int > &module_pattern_idx, unsigned int prob_idx) const
Compute the total probability using the probabilities associated to the given list of patterns.
Definition: DefectsEmulatorCondAlgBase.h:132
PlotCalibFromCool.begin
begin
Definition: PlotCalibFromCool.py:94
python.ROOTUtils.protect
def protect(obj)
Definition: python/ROOTUtils.py:14
InDet::DefectsEmulatorCondAlgBase::DefectsEmulatorCondAlgBase
DefectsEmulatorCondAlgBase(const std::string &name, ISvcLocator *pSvcLocator)
Definition: DefectsEmulatorCondAlgBase.cxx:23
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:70
InDet::DefectsEmulatorCondAlgBase::m_histogramGroupName
Gaudi::Property< std::string > m_histogramGroupName
Definition: DefectsEmulatorCondAlgBase.h:87
InDet::DefectsEmulatorCondAlgBase::m_outputFile
Gaudi::Property< std::string > m_outputFile
Definition: DefectsEmulatorCondAlgBase.h:94
python.resample_meson.input_file
input_file
Definition: resample_meson.py:164
athena.value
value
Definition: athena.py:124
InDet::DefectsEmulatorCondAlgBase::kNElements
@ kNElements
Definition: DefectsEmulatorCondAlgBase.h:160
InDet::DefectsEmulatorCondAlgBase::m_perPatternAndMaskFractions
std::vector< std::vector< std::vector< float > > > m_perPatternAndMaskFractions
Definition: DefectsEmulatorCondAlgBase.h:68
HistUtil::StringCat
Definition: HistUtil.h:41
InDet::DefectsEmulatorCondAlgBase::m_histSvc
ServiceHandle< ITHistSvc > m_histSvc
Definition: DefectsEmulatorCondAlgBase.h:85
InDet::DefectsEmulatorCondAlgBase::m_fillEtaPhiHistogramsPerPattern
Gaudi::Property< bool > m_fillEtaPhiHistogramsPerPattern
Definition: DefectsEmulatorCondAlgBase.h:91
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
yodamerge_tmp.scale
scale
Definition: yodamerge_tmp.py:138
covarianceTool.prob
prob
Definition: covarianceTool.py:678
python.TrigEgammaMonitorHelper.TH2F
def TH2F(name, title, nxbins, bins_par2, bins_par3, bins_par4, bins_par5=None, bins_par6=None, path='', **kwargs)
Definition: TrigEgammaMonitorHelper.py:45
DefectsEmulatorCondAlgBase.h
InDet::DefectsEmulatorCondAlgBase::kMaskDefects
@ kMaskDefects
Definition: DefectsEmulatorCondAlgBase.h:103
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
python.Bindings.values
values
Definition: Control/AthenaPython/python/Bindings.py:808
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:92
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:74
InDet::DefectsEmulatorCondAlgBase::m_perPatternCornerDefectNCornerCummulativeProb
std::vector< std::vector< float > > m_perPatternCornerDefectNCornerCummulativeProb
Definition: DefectsEmulatorCondAlgBase.h:69
InDet::DefectsEmulatorCondAlgBase::m_rngPerDefectType
Gaudi::Property< bool > m_rngPerDefectType
Definition: DefectsEmulatorCondAlgBase.h:72
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
InDet::DefectsEmulatorCondAlgBase::m_defectProbability
Gaudi::Property< std::vector< std::vector< double > > > m_defectProbability
Definition: DefectsEmulatorCondAlgBase.h:54
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
L1TopoRatesCalculator_submatrix_plotter.counts
counts
Definition: L1TopoRatesCalculator_submatrix_plotter.py:74
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
InDet::DefectsEmulatorCondAlgBase::printSummaryOfDefectGeneration
void printSummaryOfDefectGeneration(unsigned int n_masks, unsigned int n_error, unsigned int n_defects_total, const std::vector< std::array< unsigned int, kNCounts > > &counts) const
Definition: DefectsEmulatorCondAlgBase.cxx:263
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
InDet::DefectsEmulatorCondAlgBase::histogramDefectModule
void histogramDefectModule(unsigned int module_pattern_i, unsigned int hist_pattern_i, unsigned int id_hash, const Amg::Vector3D &center) const
Definition: DefectsEmulatorCondAlgBase.cxx:490
InDet::DefectsEmulatorCondAlgBase::kNCornerDefectParams
@ kNCornerDefectParams
Definition: DefectsEmulatorCondAlgBase.h:120
covarianceTool.title
title
Definition: covarianceTool.py:542
mc.group_name
group_name
Definition: mc.PhPy8EG_A14NNPDF23_NNLOPS_example.py:33
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
InDet::DefectsEmulatorCondAlgBase::initializeProbabilities
StatusCode initializeProbabilities(unsigned int n_masks)
Definition: DefectsEmulatorCondAlgBase.cxx:373
InDet::ModuleIdentifierMatchUtil::verifyModulePatternList
bool verifyModulePatternList(const std::vector< std::vector< int > > &arr)
Verify whether a list of module identifier patterns is consistent.
Definition: ModuleIdentifierMatchUtil.h:99
InDet::DefectsEmulatorCondAlgBase::kNDefects
@ kNDefects
Definition: DefectsEmulatorCondAlgBase.h:161
hist_file_dump.f
f
Definition: hist_file_dump.py:140
MakeFileForMJB.ext
string ext
Definition: Moriond2016/MakeFileForMJB.py:41
InDet::DefectsEmulatorCondAlgBase::finalize
virtual StatusCode finalize() override
Definition: DefectsEmulatorCondAlgBase.cxx:210
HistUtil.h
InDet::DefectsEmulatorCondAlgBase::m_modulePattern
Gaudi::Property< std::vector< std::vector< int > > > m_modulePattern
Definition: DefectsEmulatorCondAlgBase.h:50
InDet::DefectsEmulatorCondAlgBase::m_cornerDefectNCornerFractionsPerPattern
Gaudi::Property< std::vector< std::vector< double > > > m_cornerDefectNCornerFractionsPerPattern
Definition: DefectsEmulatorCondAlgBase.h:65
InDet::DefectsEmulatorCondAlgBase::kNMaxRtriesExceeded
@ kNMaxRtriesExceeded
Definition: DefectsEmulatorCondAlgBase.h:163
InDet::DefectsEmulatorCondAlgBase::kMatrixTypeId
@ kMatrixTypeId
Definition: DefectsEmulatorCondAlgBase.h:245
InDet::DefectsEmulatorCondAlgBase::kCornerDefectProb
@ kCornerDefectProb
Definition: DefectsEmulatorCondAlgBase.h:113
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
InDet::DefectsEmulatorCondAlgBase::m_inputFiles
Gaudi::Property< std::vector< std::string > > m_inputFiles
Definition: DefectsEmulatorCondAlgBase.h:96
InDet::DefectsEmulatorCondAlgBase::m_fillHistogramsPerPattern
Gaudi::Property< bool > m_fillHistogramsPerPattern
Definition: DefectsEmulatorCondAlgBase.h:89
InDet::DefectsEmulatorCondAlgBase::kNProb
@ kNProb
Definition: DefectsEmulatorCondAlgBase.h:109
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
RNGWrapper.h
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:16
InDet::operator<<
MsgStream & operator<<(MsgStream &, const GNNTrackFinderTritonTool &)
runIDAlign.accumulate
accumulate
Update flags based on parser line args.
Definition: runIDAlign.py:107
InDet::DefectsEmulatorCondAlgBase::checkProbabilities
StatusCode checkProbabilities(unsigned int n_probabilities) const
Consistency check of module patterns, probabilities.
Definition: DefectsEmulatorCondAlgBase.cxx:188
InDet::DefectsEmulatorCondAlgBase::initializeBase
StatusCode initializeBase(unsigned int n_masks, unsigned int wafer_hash_max)
Definition: DefectsEmulatorCondAlgBase.cxx:27
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.Constants.INFO
int INFO
Definition: Control/AthenaCommon/python/Constants.py:15
InDet::DefectsEmulatorCondAlgBase::m_histogrammingEnabled
bool m_histogrammingEnabled
Definition: DefectsEmulatorCondAlgBase.h:253
InDet::DefectsEmulatorCondAlgBase::kModulesWithDefectsPos
@ kModulesWithDefectsPos
Definition: DefectsEmulatorCondAlgBase.h:238
AthCommonMsg< Gaudi::Algorithm >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
InDet::DefectsEmulatorCondAlgBase::m_rngName
std::vector< std::string > m_rngName
Definition: DefectsEmulatorCondAlgBase.h:98
HistUtil::ProtectHistogramCreation
Definition: HistUtil.h:14
InDet::DefectsEmulatorCondAlgBase::m_maxNGroupDefects
std::vector< unsigned int > m_maxNGroupDefects
Definition: DefectsEmulatorCondAlgBase.h:226
InDet::DefectsEmulatorCondAlgBase::kNRetries
@ kNRetries
Definition: DefectsEmulatorCondAlgBase.h:162
InDet::DefectsEmulatorCondAlgBase::throwNumberOfDefects
unsigned int throwNumberOfDefects(std::span< CLHEP::HepRandomEngine * > rndmEngine, const std::vector< unsigned int > &module_pattern_idx, unsigned int n_masks, unsigned int n_cells, std::vector< unsigned int > &n_mask_defects) const
Definition: DefectsEmulatorCondAlgBase.cxx:218
InDet::DefectsEmulatorCondAlgBase::m_modulesWithoutDefectParameters
std::atomic< unsigned int > m_modulesWithoutDefectParameters
Definition: DefectsEmulatorCondAlgBase.h:251
ModuleIdentifierMatchUtil.h
python.TrigEgammaMonitorHelper.TH1F
def TH1F(name, title, nxbins, bins_par2, bins_par3=None, path='', **kwargs)
Definition: TrigEgammaMonitorHelper.py:24
InDet::DefectsEmulatorCondAlgBase::kDefectCell
@ kDefectCell
Definition: DefectsEmulatorCondAlgBase.h:247
InDet::DefectsEmulatorCondAlgBase::kCellDefectProb
@ kCellDefectProb
Definition: DefectsEmulatorCondAlgBase.h:108
InDet::DefectsEmulatorCondAlgBase::m_cornerDefectParamsPerPattern
Gaudi::Property< std::vector< std::vector< double > > > m_cornerDefectParamsPerPattern
Definition: DefectsEmulatorCondAlgBase.h:61
InDet::DefectsEmulatorCondAlgBase::m_groupDefectHistNames
std::vector< std::string > m_groupDefectHistNames
Definition: DefectsEmulatorCondAlgBase.h:225
InDet::DefectsEmulatorCondAlgBase::kDefectModule
@ kDefectModule
Definition: DefectsEmulatorCondAlgBase.h:246
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
HistUtil::StringCat::str
const std::string & str() const
Definition: HistUtil.h:47
InDet::DefectsEmulatorCondAlgBase::fillPerModuleHistograms
void fillPerModuleHistograms(unsigned int module_pattern_i, unsigned int pattern_hist_i, unsigned int matrix_histogram_index, unsigned int matrix_index, unsigned int module_i, unsigned int n_masks, const std::vector< unsigned int > &n_mask_defects, const Amg::Vector3D &center) const
Definition: DefectsEmulatorCondAlgBase.cxx:505