1 // Dear emacs, this is -*- c++ -*-
4 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
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"
16 #include "PathResolver/PathResolver.h"
18 #include "CoralBase/Blob.h"
24 //____________________________________________________________________
26 TileCondProxyFile<T>::TileCondProxyFile(const std::string& type, const std::string& name,
27 const IInterface* parent)
28 : AthAlgTool(type, name, parent)
31 declareInterface<ITileCondProxy<T> >(this);
32 declareProperty("Source", m_source = "", "The ASCII file to read");
36 //_____________________________________________________________________________
38 StatusCode TileCondProxyFile<T>::initialize() {
40 return StatusCode::SUCCESS;
45 StatusCode TileCondProxyFile<T>::fillCalibData(TileCalibData<T>& calibData,
46 EventIDRange& eventRange) const {
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;
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;
61 ATH_MSG_INFO( "Creating TileCondProxyFile(" << name()
62 << ") for ASCII file name: \"" << fileName << "\"" );
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;
73 //========================================================
75 //=== loop through the file and fill data maps
76 //========================================================
77 std::map<unsigned int, unsigned int> drawerStat;
82 while (std::getline(file, line)) {
84 //=== read the objVersion specifier
85 if (line.starts_with( "OBJVERSION") && objVersion < 0) {
86 std::istringstream iss(line);
88 iss >> dummy >> objVersion;
89 ATH_MSG_DEBUG( "Found objVersion: " << objVersion );
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) {
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);
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;
114 //=== Mark module as affected
116 unsigned int& stat = drawerStat[drawerIdx];
117 stat = std::max(stat, channel);
120 //=== Loop through all data rows
122 typename DataVec::value_type value;
123 while (iss >> std::skipws >> value) {
124 dataVec.push_back(value);
127 //=== ensure that all dataVec have the same length
128 if (dataVecSize < 0) {
129 dataVecSize = dataVec.size();
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;
138 //=== Save dataVector in map
139 dataMap[std::make_tuple(drawerIdx, channel, gain)] = dataVec;
141 } // End loop over file
145 //==== Check that objVersion is specified
146 if (objVersion < 0) {
147 ATH_MSG_ERROR( "No OBJVERSION specified in file \"" << fileName << "\"" );
148 return StatusCode::FAILURE;
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;
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) {
163 //=== if no data for drawer, link to default drawer...
164 if (drawerStat.find(drawerIdx) == drawerStat.end()) {
166 unsigned int defaultDrawerIdx = TileCalibUtils::getDefaultDrawerIdx(drawerIdx);
167 calibData.setCalibDrawer(drawerIdx, calibData.getCalibDrawer(defaultDrawerIdx));
169 ATH_MSG_VERBOSE( "Using default drawer " << defaultDrawerIdx
170 << " for drawerIdx=" << drawerIdx << endmsg
171 << "... i.e. TileCalibDrawer @ " << calibData.getCalibDrawer(drawerIdx));
176 unsigned int nChannels = drawerStat[drawerIdx] + 1;
178 calibData.setCalibDrawer(drawerIdx, createCalibDrawer(drawerIdx, nChannels, objVersion, dataMap).release());
183 eventRange = EventIDRange{
184 EventIDBase{0, // Run number
185 EventIDBase::UNDEFEVT,
186 EventIDBase::UNDEFNUM,
187 EventIDBase::UNDEFNUM,
189 EventIDBase{EventIDBase::UNDEFNUM - 1, // Run number
190 EventIDBase::UNDEFEVT,
191 EventIDBase::UNDEFNUM,
192 EventIDBase::UNDEFNUM,
193 EventIDBase::UNDEFNUM - 1} // Lumi block
196 return StatusCode::SUCCESS;
202 //_____________________________________________________________________________
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;
212 unsigned int gain(0);
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);
218 iDataMap = dataMap.find(std::make_tuple(drawerIdx, 0, gain));
221 unsigned int nGains(gain);
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,
229 // Trick to make calib drawer to own blob
230 std::unique_ptr<T> calibDrawer = std::make_unique<T>(*tmpCalibDrawer);
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);
246 //_____________________________________________________________________________
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 //-------------------------------------------------------------------------------
260 //=== prepare vector with defaults (no bad channels)
261 TileCalibDrawerBch::DefType defaultVec{{0}, {0}, {0}};
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,
270 // Trick to make calib drawer to own blob
271 std::unique_ptr<TileCalibDrawerBch> calibDrawer = std::make_unique<TileCalibDrawerBch>(*tmpCalibDrawer);
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));
290 //_____________________________________________________________________________
292 StatusCode TileCondProxyFile<T>::finalize() {
294 ATH_MSG_DEBUG( "finalize called for " << name() );
295 return StatusCode::SUCCESS;