ATLAS Offline Software
PixelDistortionAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "PixelDistortionAlg.h"
6 #include "GaudiKernel/EventIDRange.h"
7 
8 // Random Number Generation
10 #include "CLHEP/Random/RandomEngine.h"
11 
12 #include "CLHEP/Random/RandGaussZiggurat.h"
14 #include "CLHEP/Units/SystemOfUnits.h"
16 #include <cmath>
17 
18 #include <cstdint>
19 #include <istream>
20 #include <map>
21 #include <string>
22 
23 PixelDistortionAlg::PixelDistortionAlg(const std::string& name, ISvcLocator* pSvcLocator):
24  ::AthAlgorithm(name, pSvcLocator)
25 {
26 }
27 
29  ATH_MSG_DEBUG("PixelDistortionAlg::initialize()");
30 
31  ATH_CHECK(detStore()->retrieve(m_pixelID,"PixelID"));
32 
33  ATH_CHECK(m_rndmSvc.retrieve());
36 
37  return StatusCode::SUCCESS;
38 }
39 
41  ATH_MSG_DEBUG("PixelDistortionAlg::execute()");
42 
44  if (writeHandle.isValid()) {
45  ATH_MSG_DEBUG("CondHandle " << writeHandle.fullKey() << " is already valid.. In theory this should not be called, but may happen if multiple concurrent events are being processed out of order.");
46  return StatusCode::SUCCESS;
47  }
48 
49  // Construct the output Cond Object and fill it in
50  std::unique_ptr<PixelDistortionData> writeCdo(std::make_unique<PixelDistortionData>());
51 
52 
53 
54  constexpr int nmodule_max = 2048;
55  std::unordered_map<uint32_t,std::vector<float>> distortionMap;
56  std::unordered_map<uint32_t,unsigned long long> ids;
57  if (m_distortionInputSource==0) { // no bow correction
58  ATH_MSG_DEBUG("No bow correction");
59  writeCdo -> setVersion(m_distortionVersion);
60  for (int i=0; i<nmodule_max; i++) {
61  distortionMap[i].push_back(0.0);
62  distortionMap[i].push_back(0.0);
63  distortionMap[i].push_back(0.0);
64  }
65  }
66  else if (m_distortionInputSource==1) { // constant bow
67  ATH_MSG_DEBUG("Using constant pixel distortions ");
68  writeCdo -> setVersion(m_distortionVersion);
69  for (int i=0; i<nmodule_max; i++) {
70  distortionMap[i].push_back(0.1); // 1/mm
71  distortionMap[i].push_back(0.1); // 1/mm
72  distortionMap[i].push_back(2.0*std::atan(0.0005)/CLHEP::degree); // convert to degree
73  }
74  }
75  else if (m_distortionInputSource==2) { // read from file
76  const std::string &file_name = m_inputFileName;
77  if (file_name.empty()) {
78  ATH_MSG_ERROR("Distortion filename is empty not found! No pixel distortion will be applied.");
79  return StatusCode::FAILURE;
80  }
81 
82  ATH_MSG_DEBUG("Reading pixel distortions from file: " << file_name);
83  writeCdo -> setVersion(m_distortionVersion);
84 
85  if (file_name[0] != '/') {
87  }
88  std::ifstream input(file_name);
89  if (!input.good()) {
90  ATH_MSG_ERROR("Cannot open " << file_name);
91  return StatusCode::FAILURE;
92  }
93 
94  int distosize;
95  if (m_distortionVersion < 2) distosize = 3;
96  else distosize = 441;
97 
98  while (!input.eof()) {
99  unsigned int idmod;
100  unsigned int hashID = 0;
101  float data;
102 
103  if (m_distortionVersion == 1) {
104  input >> idmod;
105  hashID = idmod;
106  } else {
107  input >> std::hex >> idmod >> std::dec;
108  hashID = m_pixelID->wafer_hash((Identifier)idmod);
109  }
110  Identifier modId = m_pixelID->wafer_id((IdentifierHash)hashID);
111  ids[hashID] = modId.get_compact();
112  ATH_MSG_DEBUG("Identifier = 0x" << std::hex << ids[hashID] << std::dec);
113 
114  std::stringstream s;
115  for (int i = 0; i < distosize; ++i) {
116  input >> data;
117  s << data << " ";
118  distortionMap[hashID].push_back(data);
119  }
120  ATH_MSG_DEBUG(s.str());
121  }
122  input.close();
123  }
124  else if (m_distortionInputSource==3) { // random generation
125  ATH_MSG_DEBUG("Using random pixel distortions");
126  writeCdo -> setVersion(m_distortionVersion);
127 
128  ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this);
129  rngWrapper->setSeed(name(),Gaudi::Hive::currentContext());
130  CLHEP::HepRandomEngine *rndmEngine = *rngWrapper;
131  //these numbers could become properties, but seems unnecessary now (they are the same in all cases):
132  constexpr double distortionMeanR{0.12/CLHEP::meter};
133  constexpr double distortionRMSR{0.08};
134  constexpr double distortionMeanTwist{-0.0005};
135 
136  for (int i=0; i<nmodule_max; i++) {
137  float r1 = CLHEP::RandGaussZiggurat::shoot(rndmEngine,distortionMeanR,distortionRMSR);
138  float r2 = CLHEP::RandGaussZiggurat::shoot(rndmEngine,r1,distortionRMSR/10.);//to implement a correlation between distortions on 2 sides of the module
139  float twist = CLHEP::RandGaussZiggurat::shoot(rndmEngine,distortionMeanTwist,distortionMeanTwist);
140  distortionMap[i].push_back(r1*CLHEP::meter); // convert to 1/mm
141  distortionMap[i].push_back(r2*CLHEP::meter); // convert to 1/mm
142  distortionMap[i].push_back(2.0*std::atan(twist)/CLHEP::degree); // convert to degree
143  }
144  }
145  else if (m_distortionInputSource==4) { // read from database here
146  ATH_MSG_DEBUG("Using pixel distortions from database");
148  const DetCondCFloat* readCdo = *readHandle;
149  if (readCdo==nullptr) {
150  ATH_MSG_FATAL("Null pointer to the read conditions object");
151  return StatusCode::FAILURE;
152  }
153  // Get the validitiy range
154  ATH_MSG_DEBUG("Size of DetCondCFloat " << readHandle.fullKey() << " readCdo->size()= " << readCdo->size());
155 
156  int version = 0;
157  if (readCdo->tag()=="/Indet/PixelDist") {
158  version = 0; // For reproducing bug in earlier versions for backward compatibility
159  ATH_MSG_INFO("Detected old version of pixel distortions data.");
160  }
161  else {
162  bool gotVersion = false;
163  // Get version number, expecting string to have the form /Indet/PixelDist_v#
164  // If not recongnized will default to latest version.
165  std::string baseStr = "/Indet/PixelDist_v";
166  if (readCdo->tag().compare(0,baseStr.size(),baseStr)==0) {
167  std::istringstream istr(readCdo->tag().substr(baseStr.size()));
168  int version_tmp = 0;
169  istr >> version_tmp;
170  if (istr.eof()) { // Should be have read whole stream if its a number
171  version = version_tmp;
172  gotVersion = true;
173  }
174  }
175  if (!gotVersion) {
176  ATH_MSG_WARNING("Unable to determine version number of pixel distortions data. Version string: " << readCdo->tag());
177  }
178  }
179  writeCdo -> setVersion(version);
180  ATH_MSG_DEBUG("Distortions data version = " << version);
181 
182  int distosize = readCdo->size();
183 
184  for (int i=0; i<nmodule_max; i++) {
185  if (readCdo->find(m_pixelID->wafer_id(IdentifierHash(i)))) {
187  const float *disto = readCdo->find(modId);
188  ids[i] = modId.get_compact();
189 
190  ATH_MSG_DEBUG("Identifier = 0x" << std::hex << ids[i] << std::dec);
191  std::stringstream s;
192  for (int j = 0; j < distosize; ++j) {
193  distortionMap[i].push_back(disto[j]);
194  s << disto[j] << " ";
195  }
196  ATH_MSG_DEBUG(s.str());
197  }
198  }
199  }
200  writeCdo -> setDistortionMap(distortionMap);
201  writeCdo -> setIds(ids);
202 
203  if (m_writeToFile) {
204  std::ofstream* outfile = new std::ofstream("output_distortion.txt");
205  for (int i=0; i<nmodule_max; i++) {
206  if (!distortionMap[i].empty()) {
207  if (m_distortionVersion==0) {
208  *outfile << m_pixelID->wafer_id(IdentifierHash(i)) << " " << distortionMap[i].at(0) << " " << distortionMap[i].at(1) << " " << distortionMap[i].at(2) << std::endl;
209  }
210  else if (m_distortionVersion>0) {
211  *outfile << i << " " << distortionMap[i].at(0) << " " << distortionMap[i].at(1) << " " << distortionMap[i].at(2) << std::endl;
212  }
213  }
214  }
215  outfile->close();
216  delete outfile;
217  }
218 
219  const EventIDBase start{EventIDBase::UNDEFNUM, EventIDBase::UNDEFEVT, 0, 0, EventIDBase::UNDEFNUM, EventIDBase::UNDEFNUM};
220  const EventIDBase stop {EventIDBase::UNDEFNUM, EventIDBase::UNDEFEVT, EventIDBase::UNDEFNUM-1, EventIDBase::UNDEFNUM-1, EventIDBase::UNDEFNUM, EventIDBase::UNDEFNUM};
221  const EventIDRange rangeW{start, stop};
222 
223  if (writeHandle.record(rangeW, std::move(writeCdo)).isFailure()) {
224  ATH_MSG_FATAL("Could not record PixelDistortionData " << writeHandle.key() << " with EventRange " << rangeW << " into Conditions Store");
225  return StatusCode::FAILURE;
226  }
227  ATH_MSG_DEBUG("recorded new CDO " << writeHandle.key() << " with range " << rangeW << " into Conditions Store");
228 
229  return StatusCode::SUCCESS;
230 }
231 
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
PixelID.h
This is an Identifier helper class for the Pixel subdetector. This class is a factory for creating co...
ATHRNG::RNGWrapper::setSeed
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
Definition: RNGWrapper.h:169
DetCondCFloat
DetCondCFloat is a class to hold sets of Identifiers and arrays of floats for detector element specif...
Definition: DetCondCFloat.h:45
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
SG::ReadCondHandle::fullKey
const DataObjID & fullKey() const
Definition: ReadCondHandle.h:60
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
PathResolver::find_file
static std::string find_file(const std::string &logical_file_name, const std::string &search_path, SearchType search_type=LocalSearch)
Definition: PathResolver.cxx:251
PixelDistortionAlg::m_distortionVersion
Gaudi::Property< int > m_distortionVersion
Definition: PixelDistortionAlg.h:49
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:14
Identifier::get_compact
value_type get_compact() const
Get the compact id.
PixelModuleFeMask_create_db.stop
int stop
Definition: PixelModuleFeMask_create_db.py:76
PixelDistortionAlg::execute
virtual StatusCode execute() override
Definition: PixelDistortionAlg.cxx:40
PixelDistortionAlg::m_writeKey
SG::WriteCondHandleKey< PixelDistortionData > m_writeKey
Definition: PixelDistortionAlg.h:43
SG::WriteCondHandle::record
StatusCode record(const EventIDRange &range, T *t)
record handle, with explicit range DEPRECATED
Definition: WriteCondHandle.h:157
PixelDistortionAlg::m_writeToFile
Gaudi::Property< bool > m_writeToFile
Definition: PixelDistortionAlg.h:52
empty
bool empty(TH1 *h)
Definition: computils.cxx:295
PixelID::wafer_id
Identifier wafer_id(int barrel_ec, int layer_disk, int phi_module, int eta_module) const
For a single crystal.
Definition: PixelID.h:364
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
AthCommonDataStore< AthCommonMsg< Algorithm > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
PixelDistortionAlg.h
physics_parameters.file_name
string file_name
Definition: physics_parameters.py:32
PixelDistortionAlg::m_readKey
SG::ReadCondHandleKey< DetCondCFloat > m_readKey
Definition: PixelDistortionAlg.h:40
PixelID::wafer_hash
IdentifierHash wafer_hash(Identifier wafer_id) const
wafer hash from id
Definition: PixelID.h:387
SG::WriteCondHandle::fullKey
const DataObjID & fullKey() const
Definition: WriteCondHandle.h:41
python.SystemOfUnits.meter
int meter
Definition: SystemOfUnits.py:61
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
PixelDistortionAlg::initialize
virtual StatusCode initialize() override
Definition: PixelDistortionAlg.cxx:28
lumiFormat.i
int i
Definition: lumiFormat.py:85
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
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
PixelDistortionAlg::PixelDistortionAlg
PixelDistortionAlg(const std::string &name, ISvcLocator *pSvcLocator)
Definition: PixelDistortionAlg.cxx:23
AthAlgorithm
Definition: AthAlgorithm.h:47
PathResolver.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
ATHRNG::RNGWrapper
A wrapper class for event-slot-local random engines.
Definition: RNGWrapper.h:56
SG::WriteCondHandle::key
const std::string & key() const
Definition: WriteCondHandle.h:40
python.subdetectors.mmg.ids
ids
Definition: mmg.py:8
DetCondCFloat::size
int size() const
Definition: DetCondCFloat.h:85
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
RNGWrapper.h
get_generator_info.version
version
Definition: get_generator_info.py:33
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
PixelDistortionAlg::m_inputFileName
Gaudi::Property< std::string > m_inputFileName
Definition: PixelDistortionAlg.h:55
SG::WriteCondHandle::isValid
bool isValid() const
Definition: WriteCondHandle.h:248
DetCondCFloat::tag
const std::string & tag() const
Definition: DetCondCFloat.h:87
IdentifierHash
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
Definition: IdentifierHash.h:25
PrepareReferenceFile.outfile
outfile
Definition: PrepareReferenceFile.py:42
DetCondCFloat::find
const float * find(const Identifier &ident) const
Definition: DetCondCFloat.cxx:29
PixelDistortionAlg::m_distortionInputSource
Gaudi::Property< int > m_distortionInputSource
Definition: PixelDistortionAlg.h:46
SG::WriteCondHandle
Definition: WriteCondHandle.h:26
PixelDistortionAlg::m_rndmSvc
ServiceHandle< IAthRNGSvc > m_rndmSvc
Random number service.
Definition: PixelDistortionAlg.h:37
python.SystemOfUnits.degree
tuple degree
Definition: SystemOfUnits.py:106
PixelDistortionAlg::m_pixelID
const PixelID * m_pixelID
Definition: PixelDistortionAlg.h:36
Identifier
Definition: IdentifierFieldParser.cxx:14