ATLAS Offline Software
Loading...
Searching...
No Matches
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
15namespace {
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
21namespace 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) {
77 HistUtil::StringCat hname;
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 {
95 HistUtil::ProtectHistogramCreation protect;
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 {
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 }
200 if (!ret) {
201 ATH_MSG_ERROR( "Size problem in defectProbability : " << ret << " ( n_prob" << n_probabilities << ")?");
202 }
204 return m_modulePattern.size() == m_defectProbability.size()
207 ? StatusCode::SUCCESS : StatusCode::FAILURE;
208 }
209
212 ATH_MSG_WARNING("No defect parameters for " << m_modulesWithoutDefectParameters << " modules.");
213 }
214 return StatusCode::SUCCESS;
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).empty());
233 if (m_perPatternAndMaskFractions.at(match_i).at(mask_i).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).size();
246 for (; n_mask_defects_idx-->0 && prob <= m_perPatternAndMaskFractions[match_i][mask_i][n_mask_defects_idx];);
247 if (++n_mask_defects_idx < m_perPatternAndMaskFractions[match_i][mask_i].size()) {
248 n_mask_defects[mask_i] = n_mask_defects_idx+1;
249 break;
250 }
251
252 prob -= m_perPatternAndMaskFractions[match_i][mask_i].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
387 // there should be one vector with fractions for each mask 0:cell, 1:1st group mask, ...
388 for (unsigned int pattern_i=0; pattern_i< m_perPatternAndMaskFractions.size(); ++pattern_i) {
389 m_perPatternAndMaskFractions[pattern_i].reserve( n_masks);
390 m_perPatternAndMaskFractions[pattern_i].emplace_back();
391 if (m_defectProbability[pattern_i].size() != kCellDefectProb + n_masks) {
392 ATH_MSG_ERROR("There should be one probability for the module to be defect, one probability for a pixel/strip etc. "
393 "to be defect and one probability for each group to be defect i.e. "
394 << (kCellDefectProb + n_masks) << " probabilities, but there are "
395 << m_defectProbability.size() << " for pattern " << pattern_i);
396 return StatusCode::FAILURE;
397 }
398 double sum=0.;
399 for (unsigned int value_i=0; value_i< m_nDefectFractionsPerPattern[pattern_i].size(); ++value_i) {
400 if (m_nDefectFractionsPerPattern[pattern_i][value_i]<0.) {
401 if (value_i+1 < m_nDefectFractionsPerPattern[pattern_i].size()) {
402 if (m_perPatternAndMaskFractions[pattern_i].size() == n_masks) {
403 ATH_MSG_ERROR("More fraction lists than number of masks: "
404 << m_perPatternAndMaskFractions[pattern_i].size()+1 << " > " << (n_masks)
405 << " for pattern " << pattern_i);
406 return StatusCode::FAILURE;
407 }
408 m_perPatternAndMaskFractions[pattern_i].emplace_back();
409 sum=0.;
410 }
411 }
412 else {
413 sum += m_nDefectFractionsPerPattern[pattern_i][value_i];
414 m_perPatternAndMaskFractions[pattern_i].back().push_back(sum);
415 }
416 }
417 std::vector<std::string> defect_names;
418 assert( 1+m_groupDefectHistNames.size() == n_masks);
419 defect_names.resize( 1+m_groupDefectHistNames.size() );
420 defect_names[0]="cell";
421 std::copy(m_groupDefectHistNames.begin(), m_groupDefectHistNames.end(), defect_names.begin()+1);
422
423 // mask_i: 0: cell, 1: first group, ...
424 for (unsigned int mask_i=0; mask_i< m_perPatternAndMaskFractions[pattern_i].size(); ++mask_i) {
425 if ( m_perPatternAndMaskFractions[pattern_i][mask_i].empty()
426 || std::abs(m_perPatternAndMaskFractions[pattern_i][mask_i].back()-1.)>1e-5) {
427 ATH_MSG_ERROR("Empty fraction list or fractions do not add up to 1: "
428 << (!m_perPatternAndMaskFractions[pattern_i][mask_i].empty()
429 ?m_perPatternAndMaskFractions[pattern_i][mask_i].back() : -1.f)
430 << " for pattern " << pattern_i << ", mask " << mask_i
431 << " (" << defect_names.at(mask_i) << ")");
432 return StatusCode::FAILURE;
433 }
434 ATH_MSG_DEBUG("Fractions for pattern " << pattern_i << " mask " << mask_i
435 << " (" << defect_names.at(mask_i) << "):"
436 << m_perPatternAndMaskFractions[pattern_i][mask_i]);
437 assert( pattern_i < m_defectProbability.size() );
438 assert( kCellDefectProb + mask_i < m_defectProbability[pattern_i].size() );
439 if (mask_i>0) {
440 // only scale the fractions to the total probability to have at least one defect
441 // for group defects.
442 // For cell defects the fractions mean fractions for group sizes 1,2, ....
443 for (float &value : m_perPatternAndMaskFractions[pattern_i][mask_i] ) {
444 value *= m_defectProbability[pattern_i][kCellDefectProb+mask_i];
445 }
446 }
447 ATH_MSG_DEBUG("Probabilities for pattern " << pattern_i << " mask " << mask_i
448 << " (" << defect_names.at(mask_i) << ") for 1.."
449 << m_perPatternAndMaskFractions[pattern_i][mask_i].size() << " defects:"
450 << m_perPatternAndMaskFractions[pattern_i][mask_i]);
451 }
452 }
453 }
454 return checkProbabilities(kCellDefectProb+n_masks);
455 }
456
458 if (!m_cornerDefectParamsPerPattern.empty()) {
459 if (m_cornerDefectParamsPerPattern.size() != m_modulePattern.size()) {
460 ATH_MSG_ERROR("Expected exactly one set of corner defect parameters per module pattern but the numbers disagree "
461 << m_cornerDefectParamsPerPattern.size() << " != " << m_modulePattern.size());
462 return StatusCode::FAILURE;
463 }
465 ATH_MSG_ERROR("Expected exactly one set of n corner fractions per module pattern but the numbers disagree "
467 return StatusCode::FAILURE;
468 }
470 for (unsigned int pattern_i=0; pattern_i < m_cornerDefectParamsPerPattern.size(); ++pattern_i) {
471 if (m_cornerDefectParamsPerPattern[pattern_i].empty()) continue;
472 if (m_cornerDefectParamsPerPattern[pattern_i].size() != kNCornerDefectParams) {
473 ATH_MSG_ERROR("Mismatch in number of corner defect parameters for pattern " << pattern_i << ". Expected " << kNCornerDefectParams
474 << " but got " << m_cornerDefectParamsPerPattern[pattern_i].size() );
475 return StatusCode::FAILURE;
476 }
477 if (m_cornerDefectNCornerFractionsPerPattern[pattern_i].size()>4) {
478 ATH_MSG_ERROR("Too many Fractions for corner defects for pattern " << pattern_i <<
479 ". Expected fractions for at most 4 corners but got " << m_cornerDefectNCornerFractionsPerPattern[pattern_i].size()
480 << ".");
481 return StatusCode::FAILURE;
482 }
483 double scale = std::accumulate( m_cornerDefectNCornerFractionsPerPattern.value()[pattern_i].begin(),
484 m_cornerDefectNCornerFractionsPerPattern.value()[pattern_i].end(),
485 0.);
486 if (std::abs(scale-1.)>1e-3) {
487 ATH_MSG_ERROR("The fractions for corner defects in 1.." << m_cornerDefectNCornerFractionsPerPattern[pattern_i].size()
488 << " corner(s) for pattern " << pattern_i << " do not add up to ~1 but " << scale);
489 return StatusCode::FAILURE;
490 }
492 scale = m_cornerDefectParamsPerPattern[pattern_i][kCornerDefectProb]/scale;
493 double total = 0.;
494 for (double fraction : m_cornerDefectNCornerFractionsPerPattern[pattern_i]) {
495 total += fraction * scale;
496 m_perPatternCornerDefectNCornerCummulativeProb[pattern_i].push_back( static_cast<float>(total) );
497 }
498 }
499 }
500 return StatusCode::SUCCESS;
501 }
502
503
504 void DefectsEmulatorCondAlgBase::histogramDefectModule(unsigned int module_pattern_i,
505 unsigned int hist_pattern_i,
506 unsigned int id_hash,
507 const Amg::Vector3D &center) const {
508 assert( hist_pattern_i < m_moduleHist.size() );
509 unsigned int ids_per_col = static_cast<unsigned int>(m_moduleHist[hist_pattern_i][kDefectModule]->GetNbinsX());
510 unsigned int bin_i=m_moduleHist[hist_pattern_i][kDefectModule]->GetBin( id_hash%ids_per_col+1, id_hash/ids_per_col+1);
511 m_moduleHist[hist_pattern_i][kDefectModule]->SetBinContent(bin_i,1);
512 unsigned int eta_phi_pattern_i = m_fillEtaPhiHistogramsPerPattern ? module_pattern_i : 0;
513 assert( kDefectModulePos < m_defectModuleEtaPhiHist.size());
514 assert( eta_phi_pattern_i < m_defectModuleEtaPhiHist[kDefectModulePos].size() );
515 m_defectModuleEtaPhiHist[kDefectModulePos][eta_phi_pattern_i]->Fill(center.z(), center.perp());
516 m_defectModuleEtaLayerHist[kDefectModulePos][eta_phi_pattern_i]->Fill(center.x(), center.y());
517 }
518
519 void DefectsEmulatorCondAlgBase::fillPerModuleHistograms(unsigned int module_pattern_i,
520 unsigned int pattern_hist_i,
521 unsigned int matrix_histogram_index,
522 unsigned int matrix_index,
523 unsigned int module_i,
524 unsigned int n_masks,
525 const std::vector<unsigned int> &n_mask_defects,
526 const Amg::Vector3D &center) const
527 {
528 // all the following histograms are expected to have the same binning
529 // i.e. one bin per ID hash organised in a matrix
530 assert( pattern_hist_i < m_moduleHist.size());
531 assert( kMatrixTypeId < m_moduleHist[pattern_hist_i].size());
532 assert( kDefectModule < m_moduleHist[pattern_hist_i].size());
533 unsigned int ids_per_col = static_cast<unsigned int>(m_moduleHist[pattern_hist_i][kDefectModule]->GetNbinsX());
534 unsigned int bin_i=m_moduleHist[pattern_hist_i][kDefectModule]->GetBin( module_i%ids_per_col+1, module_i/ids_per_col+1);
535 unsigned int mask_i=n_masks;
536 for (; --mask_i>0; ) {
537 assert( mask_i < n_mask_defects.size() && mask_i>0);
538 if (!m_groupDefectHists.empty()) {
539 m_groupDefectHists[pattern_hist_i][matrix_histogram_index][mask_i-1]->Fill(n_mask_defects[mask_i]);
540 }
541 assert( (kDefectCell+mask_i) < m_moduleHist[pattern_hist_i].size());
542 m_moduleHist[pattern_hist_i][kDefectCell+mask_i]->SetBinContent(bin_i, n_mask_defects[mask_i]);
543 }
544 assert( (kDefectCell+mask_i) < m_moduleHist[pattern_hist_i].size());
545 m_moduleHist[pattern_hist_i][kDefectCell+mask_i]->SetBinContent(bin_i, n_mask_defects[mask_i]);
546 m_moduleHist[pattern_hist_i][kMatrixTypeId]->SetBinContent(bin_i, matrix_index+1 );
547 unsigned int n_defects_total = std::accumulate(n_mask_defects.begin(),n_mask_defects.end(), 0u);
548 if (n_defects_total>0) {
549 unsigned int eta_phi_pattern_i = m_fillEtaPhiHistogramsPerPattern ? module_pattern_i : 0;
550 assert( kModulesWithDefectsPos < m_defectModuleEtaPhiHist.size());
551 assert( eta_phi_pattern_i < m_defectModuleEtaPhiHist[kModulesWithDefectsPos].size() );
552 m_defectModuleEtaPhiHist[kModulesWithDefectsPos][eta_phi_pattern_i]->Fill(center.z(), center.perp());
553 m_defectModuleEtaLayerHist[kModulesWithDefectsPos][eta_phi_pattern_i]->Fill(center.x(), center.y(),n_defects_total);
554 }
555 }
556
557
558}// namespace closure
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
static const Attributes_t empty
An algorithm that can be simultaneously executed in multiple threads.
const std::string & str() const
Definition HistUtil.h:47
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.
std::atomic< unsigned int > m_modulesWithoutDefectParameters
std::pair< unsigned int, unsigned int > findHist(unsigned int pattern_i, unsigned int n_rows, unsigned int n_cols) const
std::vector< std::string > m_groupDefectHistNames
Gaudi::Property< std::vector< std::vector< double > > > m_cornerDefectNCornerFractionsPerPattern
Gaudi::Property< std::vector< std::vector< int > > > m_modulePattern
std::vector< std::vector< std::vector< float > > > m_perPatternAndMaskFractions
StatusCode checkProbabilities(unsigned int n_probabilities) const
Consistency check of module patterns, probabilities.
Gaudi::Property< std::string > m_histogramGroupName
StatusCode initializeProbabilities(unsigned int n_masks)
std::vector< unsigned int > m_maxNGroupDefects
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
DefectsEmulatorCondAlgBase(const std::string &name, ISvcLocator *pSvcLocator)
Gaudi::Property< std::vector< std::vector< double > > > m_cornerDefectParamsPerPattern
Gaudi::Property< bool > m_fillEtaPhiHistogramsPerPattern
std::vector< std::vector< float > > m_perPatternCornerDefectNCornerCummulativeProb
void histogramDefectModule(unsigned int module_pattern_i, unsigned int hist_pattern_i, unsigned int id_hash, const Amg::Vector3D &center) const
Gaudi::Property< std::vector< std::vector< double > > > m_defectProbability
Gaudi::Property< std::vector< std::vector< double > > > m_nDefectFractionsPerPattern
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
Gaudi::Property< std::vector< std::string > > m_inputFiles
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
StatusCode initializeBase(unsigned int n_masks, unsigned int wafer_hash_max)
Eigen::Matrix< double, 3, 1 > Vector3D
bool verifyElementCount(const std::vector< std::vector< T > > &arr, std::size_t n_expected)
test whether the 2D vector arr has the expected number of elements.
bool verifyModulePatternList(const std::vector< std::vector< int > > &arr)
Verify whether a list of module identifier patterns is consistent.
Primary Vertex Finder.
MsgStream & operator<<(MsgStream &, const GNNTrackFinderTritonTool &)
TH2F(name, title, nxbins, bins_par2, bins_par3, bins_par4, bins_par5=None, bins_par6=None, path='', **kwargs)