ATLAS Offline Software
TileCondProxyFile.icc
Go to the documentation of this file.
1 // Dear emacs, this is -*- c++ -*-
2 
3 /*
4  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
5 */
6 
7 
8 // Tile includes
9 #include "TileConditions/TileCondProxyFile.h"
10 #include "TileCalibBlobObjs/TileCalibDrawerFlt.h"
11 #include "TileCalibBlobObjs/TileCalibDrawerBch.h"
12 #include "TileCalibBlobObjs/TileCalibDrawerInt.h"
13 #include "TileCalibBlobObjs/TileBchDecoder.h"
14 #include "TileCalibBlobObjs/TileCalibUtils.h"
15 
16 #include "PathResolver/PathResolver.h"
17 
18 #include "CoralBase/Blob.h"
19 
20 #include <fstream>
21 
22 
23 //
24 //____________________________________________________________________
25 template<typename T>
26 TileCondProxyFile<T>::TileCondProxyFile(const std::string& type, const std::string& name,
27  const IInterface* parent)
28  : AthAlgTool(type, name, parent)
29  , m_source("")
30 {
31  declareInterface<ITileCondProxy<T> >(this);
32  declareProperty("Source", m_source = "", "The ASCII file to read");
33 }
34 
35 //
36 //_____________________________________________________________________________
37 template<typename T>
38 StatusCode TileCondProxyFile<T>::initialize() {
39 
40  return StatusCode::SUCCESS;
41 }
42 
43 
44 template<typename T>
45 StatusCode TileCondProxyFile<T>::fillCalibData(TileCalibData<T>& calibData,
46  EventIDRange& eventRange) const {
47 
48  //=== file name needs to be set to read correct defaults
49  if (!m_source.size()) {
50  ATH_MSG_ERROR( name() << ": Empty file name detected, initialization not possible." );
51  return StatusCode::FAILURE;
52  }
53 
54  //=== Try to resolve file location
55  std::string fileName = PathResolver::find_file(m_source, "DATAPATH");
56  if (!fileName.size()) {
57  ATH_MSG_ERROR( name() << ": Could not find file \"" << m_source << "\"" );
58  return StatusCode::FAILURE;
59  }
60 
61  ATH_MSG_INFO( "Creating TileCondProxyFile(" << name()
62  << ") for ASCII file name: \"" << fileName << "\"" );
63 
64 
65  //=== Open input file
66  std::ifstream file(fileName.c_str());
67  if (!file.is_open()) {
68  ATH_MSG_ERROR( ": Could not open file \"" << fileName << "\"" );
69  return StatusCode::FAILURE;
70  }
71 
72 
73  //========================================================
74 
75  //=== loop through the file and fill data maps
76  //========================================================
77  std::map<unsigned int, unsigned int> drawerStat;
78  DataMap dataMap;
79  int dataVecSize(-1);
80  int objVersion(-1);
81  std::string line;
82  while (std::getline(file, line)) {
83 
84  //=== read the objVersion specifier
85  if (line.starts_with( "OBJVERSION") && objVersion < 0) {
86  std::istringstream iss(line);
87  std::string dummy;
88  iss >> dummy >> objVersion;
89  ATH_MSG_DEBUG( "Found objVersion: " << objVersion );
90  continue;
91  }
92 
93  //=== Ensure that we have a data line starting
94  //=== with '0x' for the fragmentID in hex
95  std::string::size_type lineId = line.find("0x", 0);
96  if (lineId == std::string::npos || lineId > 0) {
97  continue;
98  }
99 
100  //=== read data line
101  std::istringstream iss(line);
102  unsigned int frag, channel, gain;
103  iss >> std::hex >> frag >> std::dec >> channel >> std::dec >> gain;
104  unsigned int drawerIdx = TileCalibUtils::getDrawerIdxFromFragId(frag);
105 
106  //=== some sanity checks
107  if (drawerIdx >= TileCalibUtils::MAX_DRAWERIDX) {
108  ATH_MSG_ERROR( "Detected invalid drawer index in file \""
109  << fileName << "\": " << std::hex << frag );
110  return StatusCode::FAILURE;
111  }
112 
113 
114  //=== Mark module as affected
115  {
116  unsigned int& stat = drawerStat[drawerIdx];
117  stat = std::max(stat, channel);
118  }
119 
120  //=== Loop through all data rows
121  DataVec dataVec;
122  typename DataVec::value_type value;
123  while (iss >> std::skipws >> value) {
124  dataVec.push_back(value);
125  }
126 
127  //=== ensure that all dataVec have the same length
128  if (dataVecSize < 0) {
129  dataVecSize = dataVec.size();
130  }
131 
132  if (dataVecSize != static_cast<int>(dataVec.size())) {
133  ATH_MSG_ERROR( "Inconsistent number of data elements in \"" << fileName << "\". " );
134  ATH_MSG_ERROR( "The offending line is: " << line );
135  return StatusCode::FAILURE;
136  }
137 
138  //=== Save dataVector in map
139  dataMap[std::make_tuple(drawerIdx, channel, gain)] = dataVec;
140 
141  } // End loop over file
142 
143  file.close();
144 
145  //==== Check that objVersion is specified
146  if (objVersion < 0) {
147  ATH_MSG_ERROR( "No OBJVERSION specified in file \"" << fileName << "\"" );
148  return StatusCode::FAILURE;
149  }
150 
151  //==== Check that global detector default (drawerIdx=0) is specified
152  if (drawerStat.find(0) == drawerStat.end()) {
153  ATH_MSG_ERROR( "No global default (fragId=0x000) specified in file \"" << fileName << "\"" );
154  return StatusCode::FAILURE;
155  }
156 
157  //====================================================
158  //=== Initialize drawers, following the default policy
159  //=== implemented in TileCalibUtils::getDefaultDrawerIdx()
160  //====================================================
161  for (unsigned int drawerIdx = 0; drawerIdx < TileCalibUtils::MAX_DRAWERIDX; ++drawerIdx) {
162 
163  //=== if no data for drawer, link to default drawer...
164  if (drawerStat.find(drawerIdx) == drawerStat.end()) {
165 
166  unsigned int defaultDrawerIdx = TileCalibUtils::getDefaultDrawerIdx(drawerIdx);
167  calibData.setCalibDrawer(drawerIdx, calibData.getCalibDrawer(defaultDrawerIdx));
168 
169  ATH_MSG_VERBOSE( "Using default drawer " << defaultDrawerIdx
170  << " for drawerIdx=" << drawerIdx << endmsg
171  << "... i.e. TileCalibDrawer @ " << calibData.getCalibDrawer(drawerIdx));
172 
173  continue;
174  }
175 
176  unsigned int nChannels = drawerStat[drawerIdx] + 1;
177 
178  calibData.setCalibDrawer(drawerIdx, createCalibDrawer(drawerIdx, nChannels, objVersion, dataMap).release());
179 
180  } // End drawerIdx
181 
182 
183  eventRange = EventIDRange{
184  EventIDBase{0, // Run number
185  EventIDBase::UNDEFEVT,
186  EventIDBase::UNDEFNUM,
187  EventIDBase::UNDEFNUM,
188  0}, // Lumi block
189  EventIDBase{EventIDBase::UNDEFNUM - 1, // Run number
190  EventIDBase::UNDEFEVT,
191  EventIDBase::UNDEFNUM,
192  EventIDBase::UNDEFNUM,
193  EventIDBase::UNDEFNUM - 1} // Lumi block
194  };
195 
196  return StatusCode::SUCCESS;
197 
198 }
199 
200 
201 //
202 //_____________________________________________________________________________
203 template<typename T>
204 std::unique_ptr<const T> TileCondProxyFile<T>::createCalibDrawer(unsigned int drawerIdx,
205  unsigned int nChannels,
206  unsigned int objVers,
207  const DataMap& dataMap) const {
208  //=== Prepare vector with defaults
209  //--- Low gain is always there
210  typename T::DefType defaultVec;
211 
212  unsigned int gain(0);
213 
214  typename TileCondProxyFile::DataMap::const_iterator iDataMap = dataMap.find(std::make_tuple(drawerIdx, 0, gain));
215  while (iDataMap != dataMap.end()) {
216  defaultVec.push_back(iDataMap->second);
217  ++gain;
218  iDataMap = dataMap.find(std::make_tuple(drawerIdx, 0, gain));
219  }
220 
221  unsigned int nGains(gain);
222 
223  //=== create the calibDrawer
224  std::unique_ptr<coral::Blob> blob = std::make_unique<coral::Blob>(0);
225  std::unique_ptr<T> tmpCalibDrawer(T::getInstance(*blob,
226  defaultVec,
227  nChannels,
228  objVers));
229  // Trick to make calib drawer to own blob
230  std::unique_ptr<T> calibDrawer = std::make_unique<T>(*tmpCalibDrawer);
231 
232  //=== fill calibDrawer with settings in dataMap
233  for (unsigned int channel = 0; channel < nChannels; ++channel) {
234  for (unsigned int adc = 0; adc < nGains; ++adc) {
235  iDataMap = dataMap.find(std::make_tuple(drawerIdx, channel, adc));
236  if (iDataMap != dataMap.end()) {
237  calibDrawer->setData(channel, adc, iDataMap->second);
238  }
239  }
240  }
241 
242  return calibDrawer;
243 }
244 
245 //
246 //_____________________________________________________________________________
247 template<>
248 std::unique_ptr<const TileCalibDrawerBch> TileCondProxyFile<TileCalibDrawerBch>::createCalibDrawer(unsigned int drawerIdx,
249  unsigned int nChannels,
250  unsigned int objVers,
251  const DataMap& dataMap) const {
252  //-------------------------------------------------------------------------------
253  //--- Observed special case for TileCalibDrawerBch, which always expects 3 gains:
254  //--- 0=low gain, 1=high gain, 2=common channel problems!
255  //--- However, in the file format only up to 2 gains can be encoded.
256  //--- Therefore the convention is assumed that the words for the three gains are
257  //--- all listed under gain 0 in the file.
258  //-------------------------------------------------------------------------------
259 
260  //=== prepare vector with defaults (no bad channels)
261  TileCalibDrawerBch::DefType defaultVec{{0}, {0}, {0}};
262 
263  //=== create the calibDrawer
264  std::unique_ptr<coral::Blob> blob = std::make_unique<coral::Blob>(0);
265  TileBchDecoder::BitPatVer bitPatVer = static_cast<TileBchDecoder::BitPatVer>(objVers);
266  std::unique_ptr<TileCalibDrawerBch> tmpCalibDrawer(TileCalibDrawerBch::getInstance(*blob,
267  defaultVec,
268  nChannels,
269  bitPatVer));
270  // Trick to make calib drawer to own blob
271  std::unique_ptr<TileCalibDrawerBch> calibDrawer = std::make_unique<TileCalibDrawerBch>(*tmpCalibDrawer);
272 
273 
274  //=== fill calibDrawer with settings in dataMap
275  for (unsigned int channel = 0; channel < nChannels; ++channel) {
276  TileCondProxyFile::DataMap::const_iterator iDataMap = dataMap.find( std::make_tuple(drawerIdx, channel, 0));
277  if (iDataMap != dataMap.end()) {
278  const DataVec& dataVec = iDataMap->second;
279  for (unsigned int idx = 0; idx < dataVec.size(); ++idx) {
280  float data = dataVec[idx];
281  calibDrawer->setData(channel, idx, 0, static_cast<uint32_t>(data > 0. ? data + 0.5 : data - 0.5));
282  }
283  }
284  }
285 
286  return calibDrawer;
287 }
288 
289 //
290 //_____________________________________________________________________________
291 template<typename T>
292 StatusCode TileCondProxyFile<T>::finalize() {
293 
294  ATH_MSG_DEBUG( "finalize called for " << name() );
295  return StatusCode::SUCCESS;
296 }