ATLAS Offline Software
Loading...
Searching...
No Matches
TileCondProxyFile.icc
Go to the documentation of this file.
1// Dear emacs, this is -*- c++ -*-
2
3/*
4 Copyright (C) 2002-2025 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//____________________________________________________________________
25template<typename T>
26TileCondProxyFile<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//_____________________________________________________________________________
37template<typename T>
38StatusCode TileCondProxyFile<T>::initialize() {
39
40 return StatusCode::SUCCESS;
41}
42
43
44template<typename T>
45StatusCode 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)] = std::move(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//_____________________________________________________________________________
203template<typename T>
204std::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//_____________________________________________________________________________
247template<>
248std::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//_____________________________________________________________________________
291template<typename T>
292StatusCode TileCondProxyFile<T>::finalize() {
293
294 ATH_MSG_DEBUG( "finalize called for " << name() );
295 return StatusCode::SUCCESS;
296}