ATLAS Offline Software
Loading...
Searching...
No Matches
PixelCablingCondAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "GaudiKernel/EventIDRange.h"
8
9
11#include "Identifier/Identifier.h"
13#include "CoralBase/Blob.h"
14
15#include <iostream>
16#include <fstream>
17#include <sstream>
18
19PixelCablingCondAlg::PixelCablingCondAlg(const std::string& name, ISvcLocator* pSvcLocator):
20 ::AthCondAlgorithm(name, pSvcLocator)
21{
22}
23
25 ATH_MSG_DEBUG("PixelCablingCondAlg::initialize()");
26
27 ATH_CHECK(detStore()->retrieve(m_pixelID,"PixelID"));
28
29 ATH_CHECK(m_moduleDataKey.initialize());
30 ATH_CHECK(m_readoutspeedKey.initialize());
32
33 ATH_CHECK(m_writeKey.initialize());
34
35 return StatusCode::SUCCESS;
36}
37
38StatusCode PixelCablingCondAlg::execute(const EventContext& ctx) const {
39 ATH_MSG_DEBUG("PixelCablingCondAlg::execute()");
40
42 ATH_MSG_DEBUG("Conditions updates every event!!! This should be avoided once RegionSelectorTable is fixed!!");
43 if (writeHandle.isValid()) {
44 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.");
45 return StatusCode::SUCCESS;
46 }
47
48 // Construct the output Cond Object and fill it in
49 std::unique_ptr<PixelCablingCondData> writeCdo(std::make_unique<PixelCablingCondData>());
50
51 // Signed values
52 int barrel_ec{}, eta_module{};
53
54 // Unsigned 32 bit values
55 uint32_t layer_disk{}, phi_module{};
56 uint32_t robid{}, rodid{};
57 uint32_t sl_40_fmt{}, sl_40_link{}, sl_80_fmt{}, sl_80_link{};
58
59 // Unsigned 64-bit values
60 uint64_t onlineId = 0;
61 uint64_t linknumber = 0;
62
63 // Strings
64 std::string DCSname;
65 std::string line;
66
68 const PixelModuleData *moduleData = *moduleDataHandle;
69
70 // For debugging purposes
71 std::ofstream output_mapping_file_raw;
72 if (moduleData->getCablingMapToFile()) { output_mapping_file_raw.open("pixel_cabling_map_raw.txt"); }
73 std::ofstream output_mapping_file_interpreted;
74 if (moduleData->getCablingMapToFile()) { output_mapping_file_interpreted.open("pixel_cabling_map_interpreted.txt"); }
75
76 std::stringstream instr;
77 if (!m_readKey.empty()) {
79 const AthenaAttributeList* readCdo = *readHandle;
80 if (readCdo==nullptr) {
81 ATH_MSG_FATAL("Null pointer to the read conditions object");
82 return StatusCode::FAILURE;
83 }
84 writeHandle.addDependency(readHandle);
85
86 ATH_MSG_DEBUG("Size of AthenaAttributeList " << readHandle.fullKey() << " readCdo->size()= " << readCdo->size());
87 ATH_MSG_DEBUG("Range of input is " << readHandle.getRange());
88
89 const coral::Blob& blob_cabling=(*readCdo)["CablingMapData"].data<coral::Blob>();
90 const char* p_cabling = static_cast<const char*>(blob_cabling.startingAddress());
91
92 unsigned int len_cabling = blob_cabling.size()/sizeof(char);
93 ATH_MSG_DEBUG("blob_cabling.size() = " << blob_cabling.size() << ", len_cabling = " << len_cabling);
94
95 instr.str(std::string(p_cabling,blob_cabling.size()));
96 }
97 else {
98 const std::string &cablingFilename = moduleData->getCablingMapFileName();
99 const std::string filename = PathResolverFindCalibFile(cablingFilename);
100 if (filename.empty()) {
101 ATH_MSG_FATAL("Mapping File: " << cablingFilename << " not found!");
102 return StatusCode::FAILURE;
103 }
104 std::ifstream fin(filename.c_str());
105 if (!fin) { return StatusCode::FAILURE; }
106 instr << fin.rdbuf();
107
108 writeHandle.addDependency(IOVInfiniteRange::infiniteRunLB()); //When reading from file, use infinite IOV
109 ATH_MSG_DEBUG("Refilled pixel cabling from file \"" << cablingFilename << "\"");
110 }
111
112 // Each entry in the mapping is sepated by a newline.
113 // Loop over all lines and parse the values
114 std::map<uint32_t,bool> rodReadoutMap = SG::ReadCondHandle<PixelReadoutSpeedData>(m_readoutspeedKey, ctx)->getReadoutMap();
115
116 while (instr.good() && getline(instr, line)) {
117
118 if (moduleData->getCablingMapToFile()) { output_mapping_file_raw << line << std::endl; }
119
120 // Skip empty lines and comments (i.e. starting with a hash or a space)
121 if (line.empty()) { continue; }
122 if (line[0]==' ' || line[0]=='#') { continue; }
123
124 // There are 11 columns, so there must be at least 21 characters in a valid line.
125 if (line.length()<21) { continue; }
126
127 // If reading from COOL, skip the datestamp
128 if (line.substr(line.length()-3,line.length())=="GMT") { continue; }
129
130 std::istringstream parse(line);
131 // coverity[tainted_data_argument]
132 parse >> barrel_ec >> layer_disk >> phi_module >> eta_module >> std::hex >> robid >> rodid >> sl_40_fmt >> sl_40_link >> sl_80_fmt >> sl_80_link >> DCSname;
133
134 // Debug
135 if (moduleData->getCablingMapToFile()) {
136 output_mapping_file_interpreted << barrel_ec << "\t" << layer_disk << "\t" << phi_module << "\t"
137 << eta_module << "\t" << std::hex << robid << "\t" << rodid << "\t"
138 << sl_40_fmt << "\t" << sl_40_link << "\t" << sl_80_fmt << "\t"
139 << sl_80_link << "\t" << DCSname << std::dec << std::endl;
140 }
141
142 // Get the offline ID for this module
143 // check layer_disk value is inside some very wide range
144 if (layer_disk>100){
145 ATH_MSG_ERROR("Value for layer_disk is insane: "<<layer_disk);
146 return StatusCode::FAILURE;
147 }
148 Identifier offlineId = m_pixelID->wafer_id(barrel_ec,layer_disk,phi_module,eta_module);
149
150 // Set linknumber for IBL / DBM entries
151 if ((robid & 0xFFFFFF)>=0x140000) {
152 linknumber = sl_40_link | (sl_40_fmt<<4) | (sl_80_link<<8) | (sl_80_fmt<<12);
153 }
154 // Set linknumber for pixel entries
155 else {
156 bool readoutSpeed = false;
157 if (rodReadoutMap.find(rodid)!=rodReadoutMap.end()) { readoutSpeed=rodReadoutMap[rodid]; }
158
159 if (!readoutSpeed) { linknumber=(sl_40_link & 0xF) | ((sl_40_fmt & 0xF)<<4); }
160 else { linknumber=(sl_80_link & 0xF) | ((sl_80_fmt & 0xF)<<4); }
161 }
162
163 // Compute onlineId
164 onlineId = (robid & 0xFFFFFF) | (linknumber<<24);
165
166 IdentifierHash hashId;
167
168 // Do checks to verify consistency
169 IdContext cntxpixel = m_pixelID->wafer_context();
170 if (m_pixelID->get_hash(offlineId, hashId, &cntxpixel)) {
171 ATH_MSG_WARNING("Could not get hash from offlineId");
172 }
173
174 if (hashId>m_pixelID->wafer_hash_max()) {
175 ATH_MSG_ERROR("IdHash overflow! HashId is 0x" << std::hex << hashId);
176 ATH_MSG_ERROR("not mapped OfflineID: " << std::hex << offlineId << std::dec << " barrel_ec: " << barrel_ec
177 << " layer_disk: " << layer_disk << " phi_module: " << phi_module << " eta_module: " << eta_module);
178 ATH_MSG_ERROR("to OnlineID: 0x" << std::hex << onlineId << " robid: 0x" << robid << " rodid: 0x" << rodid << std::dec
179 << " link: 0x" << std::hex /*<< link*/ << " -> Linknumber: 0x" << linknumber << " HashId: 0x" << hashId << std::dec);
180
181 // Check if offlineId fail was caused by exceeding eta_module range
182 if (eta_module>m_pixelID->eta_module_max(offlineId) || eta_module<m_pixelID->eta_module_min(offlineId)) {
183 // eta_module_max == -999 indicates the module does not exist
184 if (m_pixelID->eta_module_max(offlineId)==-999 && m_pixelID->eta_module_min(offlineId)==-999) {
185 ATH_MSG_ERROR("Module does not exist in geometry");
186 }
187 else {
188 ATH_MSG_ERROR("eta_module range exceeded: Got eta_module = " << eta_module
189 << ", but allowed range is [" << m_pixelID->eta_module_min(offlineId)
190 << "," << m_pixelID->eta_module_max(offlineId) << "]");
191 ATH_MSG_ERROR("Input geometry tag may not be compatible with mapping file");
192 }
193 }
194 }
195
196 // Fill the maps
197 writeCdo->add_entry_onoff(onlineId, offlineId);
198 writeCdo->add_entry_offon(offlineId, onlineId);
199 writeCdo->add_entry_offlineList(robid,offlineId);
200 writeCdo->add_entry_offrob(offlineId, robid);
201 writeCdo->add_entry_rodrob(rodid, robid);
202 writeCdo->add_entry_robrod(robid, rodid);
203 writeCdo->add_entry_DCSoffline(DCSname, offlineId);
204
205 // Debug messages
206 ATH_MSG_DEBUG("Mapped offlineID: " << std::hex << offlineId << " to onlineID: 0x" << onlineId
207 << ", robID: 0x" << robid << ", barrel_ec: " << std::dec << barrel_ec << ", layer_disk: " << layer_disk
208 << ", eta_module: " << eta_module << ", phi_module: " << phi_module << ", linknumber: 0x" << std::hex << linknumber);
209 }
210
211 if (moduleData->getCablingMapToFile()) {
212 output_mapping_file_raw.close();
213 output_mapping_file_interpreted.close();
214 }
215
216 ATH_MSG_DEBUG("Size of ROD readoutspeed map: " << rodReadoutMap.size());
217 writeCdo->set_readout_map(std::move(rodReadoutMap));
218
219 if (writeHandle.record(std::move(writeCdo)).isFailure()) {
220 ATH_MSG_FATAL("Could not record PixelCablingCondData " << writeHandle.key() << " with EventRange " << writeHandle.getRange() << " into Conditions Store");
221 return StatusCode::FAILURE;
222 }
223 ATH_MSG_DEBUG("recorded new CDO " << writeHandle.key() << " with range " << writeHandle.getRange() << " into Conditions Store");
224
225 return StatusCode::SUCCESS;
226}
227
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
const ServiceHandle< StoreGateSvc > & detStore() const
Base class for conditions algorithms.
An AttributeList represents a logical row of attributes in a metadata table.
static EventIDRange infiniteRunLB()
Produces an EventIDRange that is infinite in RunLumi and invalid in Time.
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
Definition IdContext.h:26
This is a "hash" representation of an Identifier.
SG::ReadCondHandleKey< AthenaAttributeList > m_readKey
virtual StatusCode initialize() override final
SG::ReadCondHandleKey< PixelModuleData > m_moduleDataKey
SG::ReadCondHandleKey< PixelReadoutSpeedData > m_readoutspeedKey
virtual StatusCode execute(const EventContext &ctx) const override final
SG::WriteCondHandleKey< PixelCablingCondData > m_writeKey
PixelCablingCondAlg(const std::string &name, ISvcLocator *pSvcLocator)
const PixelID * m_pixelID
const std::string & getCablingMapFileName() const
bool getCablingMapToFile() const
const DataObjID & fullKey() const
const EventIDRange & getRange()
const std::string & key() const
void addDependency(const EventIDRange &range)
const EventIDRange & getRange() const
StatusCode record(const EventIDRange &range, T *t)
record handle, with explicit range DEPRECATED
const DataObjID & fullKey() const
std::map< std::string, std::string > parse(const std::string &list)