Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
DefectsEmulatorAlg.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 #include "Identifier/Identifier.h"
5 #include "AtlasDetDescr/AtlasDetectorID.h"
6 #include "EventContainers/IdentifiableContainerBase.h"
7 #include "InDetRawData/InDetRawDataCollection.h"
8 #include "InDetRawData/SCT3_RawData.h"
9 #include "InDetRawData/Pixel1RawData.h"
10 
11 #include "AthenaKernel/RNGWrapper.h"
12 #include "CLHEP/Random/RandPoisson.h"
13 #include "CLHEP/Random/RandFlat.h"
14 
15 #include "StoreGate/WriteHandle.h"
16 
17 #include <vector>
18 #include <memory>
19 #include <mutex>
20 
21 namespace InDet{
22 
23  template <class T_RDO_Container>
24  bool DefectsEmulatorAlg<T_RDO_Container>::setModuleData(const ActsDetectorElement &acts_detector_element,
25  ModuleIdentifierMatchUtil::ModuleData_t &module_data) const {
26  // It is assumed that a module is unambiguously identified by the detector type and the id hash,
27  // and all modules with the same detector type are relevant for the given RDO container.
28  if (acts_detector_element.detectorType() == DETECTOR_TYPE) {
29  const auto*si_detector_element = dynamic_cast<const InDetDD::SiDetectorElement*>(acts_detector_element.upstreamDetectorElement());
30  if(si_detector_element != nullptr) {
31  const T_ModuleDesign &moduleDesign = dynamic_cast<const T_ModuleDesign &>(si_detector_element->design());
32  ModuleIdentifierMatchUtil::setModuleData(*m_idHelper,
33  acts_detector_element.identify(),
34  moduleDesign,
35  module_data);
36  return true;
37  }
38  }
39  return false;
40  }
41 
42  template <class T_RDO_Container>
43  StatusCode DefectsEmulatorAlg<T_RDO_Container>::initialize(){
44  ATH_CHECK( m_emulatedDefects.initialize() );
45  ATH_CHECK( m_rdoOutContainerKey.initialize() );
46  ATH_CHECK( m_origRdoContainerKey.initialize() );
47  ATH_CHECK( detStore()->retrieve(m_idHelper, m_idHelperName.value()) );
48 
49  return DefectsEmulatorBase::initializeBase(m_idHelper->wafer_hash_max());
50  }
51 
52  template <class T_RDO_Container>
53  StatusCode DefectsEmulatorAlg<T_RDO_Container>::execute(const EventContext& ctx) const {
54  SG::ReadCondHandle<T_DefectsData> emulatedDefects(m_emulatedDefects,ctx);
55  ATH_CHECK(emulatedDefects.isValid());
56  SG::ReadHandle<T_RDO_Container> origRdoContainer(m_origRdoContainerKey, ctx);
57  ATH_CHECK(origRdoContainer.isValid());
58  SG::WriteHandle<T_RDO_Container> rdoOutContainer(m_rdoOutContainerKey, ctx);
59  ATH_CHECK( rdoOutContainer.record (std::make_unique<T_RDO_Container>(origRdoContainer->size(), EventContainers::Mode::OfflineFast)) );
60 
61  CLHEP::HepRandomEngine *rndmEngine{};
62  if (!m_noiseProbability.value().empty()){
63  m_rndmSvc->getEngine(this, m_rngName);
64  ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, m_rngName);
65  rngWrapper->setSeed( m_rngName, ctx );
66  rndmEngine = rngWrapper->getEngine(ctx);
67  }
68 
69  unsigned int n_rejected=0u;
70  unsigned int n_split_rdos=0u;
71  unsigned int n_new=0;
72  T_ID_Adapter id_helper(m_idHelper);
73  unsigned int n_added_noise_hits=0u;
74  unsigned int n_defect_noise_hits=0u;
75 
76  std::vector<typename T_ModuleHelper::KEY_TYPE> sorted_keys;
77  for(const InDetRawDataCollection<T_RDORawData>* collection : *origRdoContainer ) {
78  const IdentifierHash idHash = collection->identifyHash();
79  T_ModuleHelper module_helper( emulatedDefects->getDetectorElement(idHash).design() );
80  std::unique_ptr<InDetRawDataCollection<T_RDORawData> >
81  clone = std::make_unique<InDetRawDataCollection<T_RDORawData> >(idHash);
82  clone->setIdentifier(collection->identify());
83  unsigned int rejected_per_mod=0u;
84  unsigned int noise_per_mod=0u;
85  if (!emulatedDefects->isModuleDefect(idHash)) {
86  unsigned int n_cells = module_helper.nCells();
87  unsigned int n_noise_hits=rndmEngine && m_noiseParamIdx.at(idHash)<m_noiseProbability.size()
88  ? CLHEP::RandPoisson::shoot(rndmEngine,
89  n_cells * m_noiseProbability.value()[ m_noiseParamIdx[idHash] ] )
90  : 0u;
91  clone->reserve( collection->size() + n_noise_hits);
92  if (!module_helper) {
93  ATH_MSG_ERROR( "Not module design for " << idHash);
94  return StatusCode::FAILURE;
95  }
96  TH2 *h2_rejected_hits=nullptr;
97  TH2 *h2_noise_hits=nullptr;
98  TH1 *h1_noise_shape=nullptr;
99  if (m_histogrammingEnabled) {
100  std::lock_guard<std::mutex> lock(m_histMutex);
101  std::tuple<TH2 *, TH2 *, TH1 *> hists = findHist(module_helper.nSensorRows(), module_helper.nSensorColumns());
102  h2_rejected_hits=std::get<0>(hists);
103  h2_noise_hits=std::get<1>(hists);
104  h1_noise_shape=std::get<2>(hists);
105  }
106 
107  sorted_keys.clear();
108  sorted_keys.reserve( collection->size()+n_noise_hits);
109  for(const auto *const rdo : *collection) {
110  const Identifier rdoID = rdo->identify();
111 
112  auto row_idx = id_helper.row_index(rdoID);
113  auto col_idx = id_helper.col_index(rdoID);
114 
115  unsigned int n_new_hits = id_helper.cloneOrRejectHit( module_helper, *(emulatedDefects.cptr()), idHash, row_idx, col_idx, *rdo, *clone);
116  if (n_new_hits>0) {
117  n_split_rdos += (n_new_hits-1);
118  for (unsigned int hit_i=n_new_hits; hit_i>0; --hit_i) {
119  auto new_hit = clone->at(clone->size()-hit_i);
120 
121  const Identifier rdoID = new_hit->identify();
122  auto row_idx = id_helper.row_index(rdoID);
123  auto col_idx = id_helper.col_index(rdoID);
124  unsigned int key = module_helper.hardwareCoordinates(row_idx,col_idx);
125  auto iter = std::lower_bound(sorted_keys.begin(), sorted_keys.end(), key);
126  if (iter == sorted_keys.end()) {
127  sorted_keys.push_back(key);
128  }
129  else {
130  if (*iter != key) {
131  sorted_keys.insert(iter, key);
132  }
133  }
134  }
135  }
136  else {
137  if (m_histogrammingEnabled && h2_rejected_hits) {
138  std::lock_guard<std::mutex> lock(m_histMutex);
139  h2_rejected_hits->Fill(col_idx, row_idx);
140  }
141  ++rejected_per_mod;
142  }
143 
144  }
145 
146  // add random noise hits
147  for (unsigned int i=0; i<n_noise_hits; ++i) {
148  for (unsigned int attempt_i=0; attempt_i<10; ++attempt_i) {
149  unsigned int cell_idx=CLHEP::RandFlat::shoot(rndmEngine,n_cells); // %pixels;
150  unsigned int row_idx = cell_idx % module_helper.rows();
151  unsigned int col_idx = cell_idx / module_helper.rows();
152  unsigned int key = module_helper.hardwareCoordinates(row_idx,col_idx);
153  if (emulatedDefects->isDefect(module_helper, idHash, row_idx, col_idx)) {
154  ++n_defect_noise_hits;
155  break;
156  }
157  auto iter = std::lower_bound(sorted_keys.begin(), sorted_keys.end(), key);
158  if (iter == sorted_keys.end()) {
159  sorted_keys.push_back(key);
160  }
161  else {
162  if (*iter != key) {
163  sorted_keys.insert(iter, key);
164  }
165  else {
166  continue;
167  }
168  }
169  float prob = CLHEP::RandFlat::shoot(rndmEngine,1.);
170  assert( m_noiseParamIdx[idHash] < m_noiseShapeCummulative.size() );
171  const std::vector<float> &noise_shape = m_noiseShapeCummulative[ m_noiseParamIdx[idHash] ];
172  unsigned int noise_value=0;
173  for (noise_value=0; noise_value<noise_shape.size(); ++noise_value) {
174  if (noise_shape[noise_value]>prob) {
175  break;
176  }
177  }
178 
179  clone->push_back( id_helper.createNoiseHit( module_helper, collection->identify(), cell_idx, noise_value).release() );
180  if (m_histogrammingEnabled && h2_noise_hits) {
181  unsigned int row_idx = cell_idx % module_helper.rows();
182  unsigned int col_idx = cell_idx / module_helper.rows();
183 
184  std::lock_guard<std::mutex> lock(m_histMutex);
185  h2_noise_hits->Fill(col_idx, row_idx);
186  h1_noise_shape->Fill(noise_value);
187  }
188  ++noise_per_mod;
189  break;
190  }
191  }
192 
193 
194  }
195  else {
196  rejected_per_mod += collection->size();
197  }
198  if (m_histogrammingEnabled) {
199  std::lock_guard<std::mutex> lock(m_histMutex);
200  unsigned int bin_i=m_moduleHist[kRejectedHits]->GetBin( idHash%100+1, idHash/100+1);
201  assert(m_moduleHist[kRejectedHits]->GetNbinsX() == m_moduleHist[kNoiseHits]->GetNbinsX());
202  assert(m_moduleHist[kRejectedHits]->GetNbinsY() == m_moduleHist[kNoiseHits]->GetNbinsY());
203  m_moduleHist[kRejectedHits]->SetBinContent(bin_i, rejected_per_mod );
204  m_moduleHist[kNoiseHits]->SetBinContent(bin_i, noise_per_mod );
205  }
206  n_added_noise_hits += noise_per_mod;
207  n_rejected += rejected_per_mod;
208  n_new += clone->size();
209  rdoOutContainer->addCollection( clone.release(), idHash).ignore();
210  }
211  m_rejectedRDOs += n_rejected;
212  m_totalRDOs += n_new;
213  m_totalNoise += n_added_noise_hits;
214  m_splitRDOs += n_split_rdos;
215  ATH_MSG_DEBUG("rejected " << m_rejectedRDOs << ", copied " << m_totalRDOs << " RDOs"
216  << " noise " << n_added_noise_hits << " (+" << n_defect_noise_hits << ")"
217  << " split hits: " << n_split_rdos);
218 
219  return StatusCode::SUCCESS;
220  }
221 
222 }