ATLAS Offline Software
DefectsEmulatorBase.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 #include "DefectsEmulatorBase.h"
5 #include "TH2.h"
6 #include <sstream>
7 #include "HistUtil.h"
8 #include "Acts/Surfaces/Surface.hpp"
9 #include "Acts/Geometry/TrackingGeometry.hpp"
10 
11 namespace InDet{
12  const std::array<std::string_view,DefectsEmulatorBase::kNHistTypes> DefectsEmulatorBase::s_histNames{
13  "rejected",
14  "noise"
15  };
16  const std::array<std::string_view,DefectsEmulatorBase::kNHistTypes> DefectsEmulatorBase::s_histTitles{
17  "Rejected",
18  "Noise"
19  };
20 
21  DefectsEmulatorBase::DefectsEmulatorBase(const std::string &name, ISvcLocator *pSvcLocator)
22  : AthReentrantAlgorithm(name, pSvcLocator)
23  {}
24 
25  StatusCode DefectsEmulatorBase::initializeBase(unsigned int wafer_hash_max){
26  ATH_CHECK( m_trackingGeometryTool.retrieve( DisableTool{m_noiseProbability.empty()} ));
27  if (!m_noiseProbability.value().empty()) {
28  if (m_modulePattern.value().size() != m_noiseProbability.value().size()) {
29  ATH_MSG_FATAL("Number of module patterns and noise probabilities differs: "
30  << m_modulePattern.value().size() << " != " << m_noiseProbability.size() );
31  return StatusCode::FAILURE;
32  }
33 
34  if (m_noiseProbability.value().size() != m_noiseShape.value().size()) {
35  ATH_MSG_FATAL("Number of noise probabilities and number of noise shapes differs: "
36  << m_noiseProbability.size() << " != " << m_noiseShape.size());
37  return StatusCode::FAILURE;
38  }
39  ATH_CHECK(m_rndmSvc.retrieve());
40  m_rngName = name()+"RandomEngine";
41 
42  if (wafer_hash_max>std::numeric_limits<unsigned short>::max()) {
43  ATH_MSG_FATAL("Maximjum wafer hash too large (" << wafer_hash_max
44  << "). This algorithm only supports wafer hashes up to "
46  return StatusCode::FAILURE;
47  }
48  m_noiseParamIdx.resize(wafer_hash_max, static_cast<unsigned short>(m_noiseProbability.size()));
49  m_maxNShape=0;
50  std::shared_ptr<const Acts::TrackingGeometry> tracking_geometry = m_trackingGeometryTool->trackingGeometry();
51 
53  std::vector<unsigned int> module_pattern_idx;
54  module_pattern_idx.reserve( m_modulePattern.value().size() );
55 
56  // Associate noise probabilities and noise shapes to module identifier hashes.
57  // The association is done according to the module match criteria. The derived
58  // class has to ensure that only modules with umambigous identifier hash are
59  // considered.
60  using Counter = struct { unsigned int n_detector_elements, n_missing_detector_elements, n_wrong_type,
61  n_no_matching_pattern, n_detector_elements_of_correct_type; };
62  Counter counter {0u,0u,0u,0u,0u};
63  tracking_geometry->visitSurfaces([&counter, &module_data, &module_pattern_idx, this](const Acts::Surface *surface_ptr) {
64  if (!surface_ptr) return;
65  const Acts::Surface &surface = *surface_ptr;
66  const Acts::DetectorElementBase*detector_element = surface.associatedDetectorElement();
67  if (detector_element) {
68  const ActsDetectorElement *acts_detector_element = dynamic_cast<const ActsDetectorElement*>(detector_element);
69  if (acts_detector_element) {
70  if (setModuleData(*acts_detector_element, module_data)) {
71  ModuleIdentifierMatchUtil::moduleMatches(m_modulePattern.value(), module_data, module_pattern_idx);
72  if (module_pattern_idx.empty()) {
73  ++counter.n_no_matching_pattern;
74  }
75  else {
76  m_noiseParamIdx.at(acts_detector_element->identifyHash()) = module_pattern_idx.front();
77  }
78  ++counter.n_detector_elements_of_correct_type;
79  }
80  }
81  else {
82  ++counter.n_wrong_type;
83  }
84  ++counter.n_detector_elements;
85  }
86  else {
87  ++counter.n_missing_detector_elements;
88  }
89  }, true /*sensitive surfaces*/);
90  ATH_MSG_DEBUG("Visited surfaces with " << counter.n_detector_elements << " / "
91  << (counter.n_missing_detector_elements + counter.n_detector_elements)
92  << " (wrong type " << counter.n_wrong_type << ")"
93  << " expected detector type " << counter.n_detector_elements_of_correct_type
94  << " without match " << counter.n_no_matching_pattern);
95  if (counter.n_missing_detector_elements || counter.n_wrong_type>0) {
96  ATH_MSG_ERROR("Encountered " << counter.n_wrong_type << " associated detector elements with wrong type and "
97  << counter.n_missing_detector_elements << " surfaces without detector element.");
98  }
99 
100  // create normalised cummulative distributions of noise shape distributions
101  m_noiseShapeCummulative.resize( m_noiseShape.size());
102  unsigned int pattern_i=0;
103  for (const std::vector<double> &shape : m_noiseShape.value()) {
104  m_noiseShapeCummulative[pattern_i].reserve( shape.size());
105  double scale=std::accumulate(shape.begin(), shape.end(),0.);
106  if (std::abs(scale-1.)>1e-5) {
107  ATH_MSG_FATAL("Noise shape integral for pattern " << pattern_i << " not 1. but " << scale);
108  return StatusCode::FAILURE;
109  }
110  scale = 1./scale;
111  double sum =0.;
112  for (double value : shape) {
113  sum += value * scale;
114  m_noiseShapeCummulative[pattern_i].push_back( sum );
115  }
116  m_maxNShape=std::max(m_maxNShape,static_cast<unsigned int>(shape.size()));
117  ++pattern_i;
118  }
120  }
121 
122  if (!m_histSvc.name().empty() && !m_histogramGroupName.value().empty()) {
123  ATH_CHECK( m_histSvc.retrieve() );
124  // reserve space for histograms for 6 different sensor types
125  constexpr unsigned int n_different_pixel_matrices_max=6;
126  m_dimPerHist.reserve(n_different_pixel_matrices_max);
127  for (unsigned int hist_type_i=0; hist_type_i<kNHistTypes; ++hist_type_i) {
128  m_hist[hist_type_i].reserve(n_different_pixel_matrices_max);
129  }
130 
131  // create per id-hash histograms
132  m_noiseShapeHist.reserve(n_different_pixel_matrices_max);
133 
134  unsigned int max_y_axis = (((wafer_hash_max+99)/100+9)/10)*10;
135  for (unsigned int hist_type_i=0; hist_type_i<kNHistTypes; ++hist_type_i) {
136  {
137  HistUtil::StringCat hist_name;
138  hist_name << s_histNames.at(hist_type_i) << "_hits_per_module";
139  HistUtil::StringCat hist_title;
140  hist_title << s_histTitles.at(hist_type_i) << " hits per module";
141 
143  m_moduleHist.at(hist_type_i) = new TH2F(hist_name.str().c_str(), hist_title.str().c_str(),
144  100, -0.5, 100-0.5,
145  max_y_axis, -0.5, max_y_axis-0.5
146  );
147  }
148  m_moduleHist[hist_type_i]->GetXaxis()->SetTitle("ID hash % 100");
149  m_moduleHist[hist_type_i]->GetYaxis()->SetTitle("ID hash / 100");
150  if ( m_histSvc->regHist(m_histogramGroupName.value() + m_moduleHist[hist_type_i]->GetName(),m_moduleHist[hist_type_i]).isFailure() ) {
151  return StatusCode::FAILURE;
152  }
153  }
155  }
156  return StatusCode::SUCCESS;
157  }
159  ATH_MSG_INFO( "Total number of rejected RDOs " << m_rejectedRDOs << ", kept " << m_totalRDOs
160  << (m_splitRDOs>0 ? (", split " + std::to_string(m_splitRDOs) ) : "")
161  << ", additional noise " << m_totalNoise);
162  return StatusCode::SUCCESS;
163  }
164 
165  std::tuple<TH2 *,TH2 *, TH1 *> DefectsEmulatorBase::findHist(unsigned int n_rows, unsigned int n_cols) const {
166  unsigned int key=(n_rows << 16) | n_cols;
167  std::vector<unsigned int>::const_iterator iter = std::find(m_dimPerHist.begin(),m_dimPerHist.end(), key );
168  if (iter == m_dimPerHist.end()) {
169  if (m_dimPerHist.size() == m_dimPerHist.capacity()) {
170  if (m_dimPerHist.capacity()==0) {
171  return std::make_tuple(nullptr,nullptr,nullptr);
172  }
173  else {
174  return std::make_tuple(m_hist[kRejectedHits].back(),
175  m_hist[kNoiseHits].empty() ? nullptr : m_hist[kNoiseHits].back(),
176  m_noiseShapeHist.empty() ? nullptr : m_noiseShapeHist.back());
177  }
178  }
179  else {
180  // if no "sensor" with this dimensions has been registered yet, create histograms
181  // and register it.
182  for (unsigned int hist_type_i=0; hist_type_i<kNHistTypes; ++hist_type_i) {
184  name << s_histNames.at(hist_type_i) << "_hits_" << n_rows << "_" << n_cols;
186  title << s_histTitles.at(hist_type_i) << "hits for " << n_rows << "(rows) #times " << n_cols << " (columns)";
187  {
189  m_hist.at(hist_type_i).push_back(new TH2F(name.str().c_str(), title.str().c_str(),
190  n_cols, -0.5, n_cols-0.5,
191  n_rows, -0.5, n_rows-0.5
192  ));
193  }
194  m_hist[hist_type_i].back()->GetXaxis()->SetTitle("offline column");
195  m_hist[hist_type_i].back()->GetYaxis()->SetTitle("offline row");
196  if ( m_histSvc->regHist(m_histogramGroupName.value() + name.str(),m_hist[hist_type_i].back()).isFailure() ) {
197  throw std::runtime_error("Failed to register histogram.");
198  }
199  }
200  {
201  std::stringstream name;
202  name << "noise_shape_" << n_rows << "_" << n_cols;
203  std::stringstream title;
204  title << "Noise shape for " << n_rows << "(rows) #times " << n_cols << " (columns)";
205  m_noiseShapeHist.push_back(new TH1F(name.str().c_str(), title.str().c_str(), m_maxNShape+1, -0.5, m_maxNShape+.5));
206  m_noiseShapeHist.back()->GetXaxis()->SetTitle("offline column");
207  m_noiseShapeHist.back()->GetYaxis()->SetTitle("offline row");
208  if ( m_histSvc->regHist(m_histogramGroupName.value() + name.str(),m_noiseShapeHist.back()).isFailure() ) {
209  throw std::runtime_error("Failed to register histogram.");
210  }
211  }
212  m_dimPerHist.push_back(key);
213  return std::make_tuple(m_hist[kRejectedHits].back(),
214  m_hist[kNoiseHits].empty() ? nullptr : m_hist[kNoiseHits].back(),
215  m_noiseShapeHist.empty() ? nullptr : m_noiseShapeHist.back()
216  );
217  }
218  }
219  else {
220  return std::make_tuple(m_hist[kRejectedHits].at(iter-m_dimPerHist.begin()),
221  m_hist[kNoiseHits].empty() ? nullptr : m_hist[kNoiseHits].at(iter-m_dimPerHist.begin()),
222  m_noiseShapeHist.empty() ? nullptr : m_noiseShapeHist.at(iter-m_dimPerHist.begin()));
223  }
224  }
225 
226 }// namespace closure
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
createLinkingScheme.iter
iter
Definition: createLinkingScheme.py:62
InDet::DefectsEmulatorBase::m_histSvc
ServiceHandle< ITHistSvc > m_histSvc
Definition: DefectsEmulatorBase.h:57
InDet::DefectsEmulatorBase::finalize
virtual StatusCode finalize() override
Definition: DefectsEmulatorBase.cxx:158
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
InDet::DefectsEmulatorBase::m_rngName
std::string m_rngName
Definition: DefectsEmulatorBase.h:97
InDet::DefectsEmulatorBase::m_totalRDOs
std::atomic< std::size_t > m_totalRDOs
Definition: DefectsEmulatorBase.h:89
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
InDet
Primary Vertex Finder.
Definition: VP1ErrorUtils.h:36
InDet::DefectsEmulatorBase::m_trackingGeometryTool
PublicToolHandle< ActsTrk::ITrackingGeometryTool > m_trackingGeometryTool
Definition: DefectsEmulatorBase.h:94
python.ROOTUtils.protect
def protect(obj)
Definition: python/ROOTUtils.py:14
InDet::DefectsEmulatorBase::m_maxNShape
unsigned int m_maxNShape
Definition: DefectsEmulatorBase.h:101
athena.value
value
Definition: athena.py:124
HistUtil::StringCat
Definition: HistUtil.h:41
yodamerge_tmp.scale
scale
Definition: yodamerge_tmp.py:138
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
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
InDet::DefectsEmulatorBase::setModuleData
virtual bool setModuleData(const ActsDetectorElement &acts_detector_element, ModuleIdentifierMatchUtil::ModuleData_t &module_data) const =0
Set the module data for matching for the given detector element.
InDet::DefectsEmulatorBase::m_noiseShape
Gaudi::Property< std::vector< std::vector< double > > > m_noiseShape
Definition: DefectsEmulatorBase.h:69
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:74
InDet::DefectsEmulatorBase::s_histNames
static const std::array< std::string_view, kNHistTypes > s_histNames
Definition: DefectsEmulatorBase.h:77
InDet::DefectsEmulatorBase::kNoiseHits
@ kNoiseHits
Definition: DefectsEmulatorBase.h:74
InDet::ModuleIdentifierMatchUtil::ModuleData_t
std::array< int, ModuleIdentifierMatchUtil::kAllRows/2 > ModuleData_t
Definition: ModuleIdentifierMatchUtil.h:67
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
InDet::DefectsEmulatorBase::DefectsEmulatorBase
DefectsEmulatorBase(const std::string &name, ISvcLocator *pSvcLocator)
Definition: DefectsEmulatorBase.cxx:21
InDet::DefectsEmulatorBase::m_noiseProbability
Gaudi::Property< std::vector< float > > m_noiseProbability
Definition: DefectsEmulatorBase.h:67
InDet::DefectsEmulatorBase::m_noiseShapeCummulative
std::vector< std::vector< float > > m_noiseShapeCummulative
Definition: DefectsEmulatorBase.h:99
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
covarianceTool.title
title
Definition: covarianceTool.py:542
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
InDet::DefectsEmulatorBase::m_histogrammingEnabled
bool m_histogrammingEnabled
Definition: DefectsEmulatorBase.h:103
ActsDetectorElement
Definition: ActsDetectorElement.h:44
HistUtil.h
InDet::DefectsEmulatorBase::s_histTitles
static const std::array< std::string_view, kNHistTypes > s_histTitles
Definition: DefectsEmulatorBase.h:78
InDet::DefectsEmulatorBase::m_splitRDOs
std::atomic< std::size_t > m_splitRDOs
Definition: DefectsEmulatorBase.h:90
InDet::DefectsEmulatorBase::m_totalNoise
std::atomic< std::size_t > m_totalNoise
Definition: DefectsEmulatorBase.h:91
InDet::DefectsEmulatorBase::kNHistTypes
@ kNHistTypes
Definition: DefectsEmulatorBase.h:75
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
ActsDetectorElement::identifyHash
IdentifierHash identifyHash() const
Identifier hash.
Definition: ActsDetectorElement.h:75
InDet::DefectsEmulatorBase::m_modulePattern
Gaudi::Property< std::vector< std::vector< int > > > m_modulePattern
Definition: DefectsEmulatorBase.h:62
InDet::ModuleIdentifierMatchUtil::moduleMatches
void moduleMatches(const std::vector< std::vector< int > > &module_pattern, const ModuleData_t &module_data, std::vector< unsigned int > &module_pattern_idx)
Test whether an identifier, which is split into various parts, matches some of the given patterns.
Definition: ModuleIdentifierMatchUtil.h:150
InDet::DefectsEmulatorBase::m_rndmSvc
ServiceHandle< IAthRNGSvc > m_rndmSvc
Definition: DefectsEmulatorBase.h:96
runIDAlign.accumulate
accumulate
Update flags based on parser line args.
Definition: runIDAlign.py:60
InDet::DefectsEmulatorBase::m_histogramGroupName
Gaudi::Property< std::string > m_histogramGroupName
Definition: DefectsEmulatorBase.h:59
HistUtil::ProtectHistogramCreation
Definition: HistUtil.h:14
DefectsEmulatorBase.h
InDet::DefectsEmulatorBase::kRejectedHits
@ kRejectedHits
Definition: DefectsEmulatorBase.h:73
InDet::DefectsEmulatorBase::initializeBase
StatusCode initializeBase(unsigned int wafer_hash_max)
Definition: DefectsEmulatorBase.cxx:25
python.TrigEgammaMonitorHelper.TH1F
def TH1F(name, title, nxbins, bins_par2, bins_par3=None, path='', **kwargs)
Definition: TrigEgammaMonitorHelper.py:24
InDet::DefectsEmulatorBase::m_rejectedRDOs
std::atomic< std::size_t > m_rejectedRDOs
Definition: DefectsEmulatorBase.h:88
test_pyathena.counter
counter
Definition: test_pyathena.py:15
InDet::DefectsEmulatorBase::findHist
std::tuple< TH2 *, TH2 *, TH1 * > findHist(unsigned int n_rows, unsigned int n_cols) const
Get rejected hits and noise histograms for a certain module design.
Definition: DefectsEmulatorBase.cxx:165
InDet::DefectsEmulatorBase::m_noiseParamIdx
std::vector< unsigned short > m_noiseParamIdx
Definition: DefectsEmulatorBase.h:98
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
HistUtil::StringCat::str
const std::string & str() const
Definition: HistUtil.h:47