ATLAS Offline Software
Loading...
Searching...
No Matches
MuonMDT_CablingAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <fstream>
8#include <map>
12#include "CoralBase/Attribute.h"
13#include "CoralBase/AttributeListSpecification.h"
18
19#include <CoralBase/Blob.h>
21
22
24
25MuonMDT_CablingAlg::MuonMDT_CablingAlg(const std::string& name, ISvcLocator* pSvcLocator) :
26 AthCondAlgorithm(name, pSvcLocator) {}
27
29 ATH_MSG_DEBUG("initialize " << name());
30 const bool initCondKey = m_mezzJSON.value().empty() &&
31 m_chambJSON.value().empty();
32 ATH_CHECK(m_readKeyMez.initialize(initCondKey));
33 ATH_CHECK(m_readKeyMap.initialize(initCondKey));
34 ATH_CHECK(m_writeKey.initialize());
35 ATH_CHECK(m_idHelperSvc.retrieve());
36 return StatusCode::SUCCESS;
37}
38
39StatusCode MuonMDT_CablingAlg::execute(const EventContext& ctx) const {
40 ATH_MSG_VERBOSE("MuonMDT_CablingAlg::execute()");
41 // Write Cond Handle
43 if (writeHandle.isValid()) {
44 ATH_MSG_DEBUG("CondHandle " << writeHandle.fullKey() << " is already valid."
45 << ". In theory this should not be called, but may happen"
46 << " if multiple concurrent events are being processed out of order.");
47 return StatusCode::SUCCESS;
48 }
49 writeHandle.addDependency(EventIDRange(IOVInfiniteRange::infiniteRunLB()));
50 ATH_MSG_INFO("Load the Mdt cabling");
51 std::unique_ptr<MuonMDT_CablingMap> writeCdo{std::make_unique<MuonMDT_CablingMap>()};
52
53 ATH_CHECK(loadMezzanineSchema(ctx, writeHandle, *writeCdo));
54 ATH_CHECK(loadCablingSchema(ctx, writeHandle, *writeCdo));
55 if (!writeCdo->finalize_init(msgStream())) return StatusCode::FAILURE;
56
57 ATH_CHECK(writeHandle.record(std::move(writeCdo)));
58 ATH_MSG_INFO("recorded new " << writeHandle.key() << " with range " << writeHandle.getRange() << " into Conditions Store");
59 return StatusCode::SUCCESS;
60}
61
63 for (CondAttrListCollection::const_iterator itr = readHandle->begin();
64 itr != readHandle->end(); ++itr) {
65 const coral::AttributeList& atr = itr->second;
66 std::string data{};
67 if (atr["data"].specification().type() == typeid(coral::Blob)) {
68
69 ATH_MSG_VERBOSE("Loading data as a BLOB, uncompressing...");
71 ATH_MSG_FATAL("Cannot uncompress BLOB! Aborting...");
72 return StatusCode::FAILURE;
73 }
74 } else {
75 data = *(static_cast<const std::string*>((atr["data"]).addressOfData()));
76 }
77 json = nlohmann::json::parse(data);
78 }
79 return StatusCode::SUCCESS;
80}
81
83 MuonMDT_CablingMap& cabling_map) const {
84
85 if (m_chambJSON.value().size()){
86 std::ifstream in_json{m_chambJSON};
87 if (!in_json.good()) {
88 ATH_MSG_FATAL("Failed to open external JSON file "<<m_chambJSON);
89 return StatusCode::FAILURE;
90 }
91 nlohmann::json payload{};
92 in_json >> payload;
93 ATH_CHECK(loadCablingSchemaFromJSON( std::move(payload), cabling_map));
94 return StatusCode::SUCCESS;
95 }
97 if (!readHandleMap.isValid()) {
98 ATH_MSG_ERROR("Null pointer to the read conditions object "<<readHandleMap.fullKey());
99 return StatusCode::FAILURE;
100 }
101 writeHandle.addDependency(readHandleMap);
102
103 ATH_MSG_INFO("Size of CondAttrListCollection " << readHandleMap.fullKey()
104 << " readCdoMap->size()= " << readHandleMap->size());
105
106 ATH_MSG_VERBOSE("Collection CondAttrListCollection CLID " << readHandleMap->clID());
107 if (m_useJSONFormat) {
108 nlohmann::json json;
109 ATH_CHECK(dbPayloadToJson(readHandleMap, json));
110 ATH_CHECK(loadCablingSchemaFromJSON(std::move(json),cabling_map));
111 return StatusCode::SUCCESS;
112 }
113 // access to Map Schema Table to obtained the Map
115 for (itrMap = readHandleMap->begin(); itrMap != readHandleMap->end(); ++itrMap) {
116 const coral::AttributeList& atr = itrMap->second;
117
118 CablingData map_data;
119 if (!extractStationInfo(atr, map_data)) continue;
120
121 constexpr std::string_view delimiter{","};
122 const std::string map = *(static_cast<const std::string*>((atr["Map"]).addressOfData()));
123 std::vector<std::string> info_map = CxxUtils::tokenize(map, delimiter);
124
125 while (extractLayerInfo(info_map, map_data)) {
127 ATH_MSG_VERBOSE("Adding new mezzanine stationName: " << m_idHelperSvc->mdtIdHelper().stationNameString(map_data.stationIndex)
128 << " " << map_data);
129 if (!cabling_map.addMezzanine(map_data, DataSource::LegacyCOOL, msgStream())) {
130 ATH_MSG_ERROR("Failed to add cabling " << map_data);
131 return StatusCode::FAILURE;
132 } else
133 ATH_MSG_VERBOSE("Added new cabling channel " << map_data);
134 }
135 } // end of CondAttrListCollection loop
137 if (m_isRun3) {
138 ATH_MSG_INFO("Found a round 3 setup. Will add the cabling for BIS78 manually");
139 const int BIS_stat = m_idHelperSvc->mdtIdHelper().stationNameIndex("BIS");
140 constexpr int eta_index = 7;
141 for (unsigned int sector = 1; sector <= 8; ++sector) {
142 int is_biy{0}, tdcId{0};
143 auto increment_tdc = [&is_biy, &tdcId]() {
144 ++tdcId;
145 constexpr int tdcMax = 17; // Maximum 18 tdcs per CSM
146 if (tdcId > tdcMax) {
147 tdcId = 0;
148 ++is_biy;
149 }
150 };
151 constexpr int tubesPerCsm = 54;
152 bool added_tdc = true;
153 while (added_tdc) {
154 added_tdc = false;
155 for (int ml = 1; ml <= 2; ++ml) {
156 const Identifier layer_id = m_idHelperSvc->mdtIdHelper().channelID(BIS_stat, eta_index, sector, ml, 1, 1);
157 const int tubes_per_layer = m_idHelperSvc->mdtIdHelper().tubeMax(layer_id);
158
159 const int first_tube = 6 * (1 + tdcId / 2) + tubesPerCsm * is_biy;
160 const bool valid_tube = (first_tube <= tubes_per_layer);
161 added_tdc |= valid_tube;
162 if (!valid_tube) {
163 increment_tdc();
164 continue;
165 }
166
167 CablingData bis78_data{};
169 bis78_data.stationIndex = BIS_stat;
170 bis78_data.eta = eta_index;
171 bis78_data.phi = sector;
174 bis78_data.mrod = (is_biy ? -1 : 7) + sector;
175 bis78_data.csm = is_biy ? 5 : 0;
176 bis78_data.subdetectorId = 99;
177
178 bis78_data.mezzanine_type = sector != 6 ? 61 : 71;
179 const unsigned int tube_coding = first_tube + bis78_data.tubes_per_layer * (4 + bis78_data.layer_block * ml);
180 ATH_MSG_VERBOSE("ooooh BIS78 is being hacked in " << m_idHelperSvc->toString(layer_id) << " tubes_per_layer "
181 << m_idHelperSvc->mdtIdHelper().tubeMax(layer_id) << " tdcId: "
182 << tdcId << " is_Biy: " << is_biy << " first_tube: " << first_tube);
183
184 std::vector<std::string> db_coding{std::to_string(tdcId), "0", std::to_string(tube_coding)};
185 if (extractLayerInfo(db_coding, bis78_data)) {
186 ATH_MSG_VERBOSE("Adding new mezzanine stationName: "
187 << m_idHelperSvc->mdtIdHelper().stationNameString(bis78_data.stationIndex) << " " << bis78_data);
188 if (!cabling_map.addMezzanine(bis78_data, DataSource::LegacyCOOL, msgStream())) {
189 ATH_MSG_ERROR("Failed to add mezzanine card " << bis78_data);
190 return StatusCode::FAILURE;
191 }
192 }
193 if (bis78_data.tube != first_tube) {
194 ATH_MSG_ERROR("BIS78 data tube encoding failed. Expected " << first_tube << " got " << bis78_data.tube << ".");
195 return StatusCode::FAILURE;
196 } else if (bis78_data.multilayer != ml) {
197 ATH_MSG_ERROR("BIS78 data ml encoding failed. Expected " << ml << " got " << bis78_data.multilayer << ".");
198 return StatusCode::FAILURE;
199 }
200 increment_tdc();
201 }
202 }
203 }
204 }
205 return StatusCode::SUCCESS;
206}
207
208bool MuonMDT_CablingAlg::extractStationInfo(const coral::AttributeList& atr, CablingData& map_data) const {
209 map_data.eta = *(static_cast<const int*>((atr["Eta"]).addressOfData()));
210 map_data.phi = *(static_cast<const int*>((atr["Phi"]).addressOfData()));
211 map_data.mrod = *(static_cast<const int*>((atr["MROD"]).addressOfData()));
212 map_data.csm = *(static_cast<const int*>((atr["CSM"]).addressOfData()));
213 map_data.channelId = *(static_cast<const int*>((atr["Chan"]).addressOfData()));
214 map_data.mezzanine_type = *(static_cast<const int*>((atr["Mezzanine_Type"]).addressOfData()));
215
216 const std::string chamber_name = *(static_cast<const std::string*>((atr["Chamber_Name"]).addressOfData()));
217 const std::string subdetector_id = *(static_cast<const std::string*>((atr["SubDet_Id"]).addressOfData()));
218
219 // convert the string name to index
220 std::string stationNameString = chamber_name.substr(0, 3);
221 // fix for the BOE chambers, which in the offline are treated as BOL
222 if (stationNameString == "BOE") { stationNameString = "BOL"; }
224 if (stationNameString == "BIX" || stationNameString == "BIY") {
225 stationNameString = "BIS";
226 static std::atomic<bool> sInfoPrinted{false};
227 if (!sInfoPrinted)
228 ATH_MSG_INFO("Found an entry concerning the new BIS78 chambers. Will increase the number of tube per layer to "
230 sInfoPrinted = true;
231
233 }
235 if (m_isRun3) {
237 if ((stationNameString == "EIS" && (!m_idHelperSvc->hasCSC() || chamber_name.find('A') != std::string::npos)) ||
238 chamber_name.find("BIS7A") != std::string::npos) {
239 ATH_MSG_VERBOSE("It's sooo sad but the chamber " << chamber_name << " is no longer with us");
240 return false;
241 }
242 }
243 map_data.stationIndex = m_idHelperSvc->mdtIdHelper().stationNameIndex(stationNameString);
244 ATH_MSG_VERBOSE("station name: " << stationNameString << " index: " << static_cast<int>(map_data.stationIndex));
245 // convert the subdetector id to integer
246 map_data.subdetectorId = CxxUtils::atoi(subdetector_id);
247
248 ATH_MSG_VERBOSE("Data load is chamber_Name = " << chamber_name <<" translated to "<<map_data<<" FINISHED HERE ");
249
250 if (map_data.stationIndex < 0) {
251 static std::atomic<bool> stWarningPrinted{false};
252 if (!stWarningPrinted) {
253 ATH_MSG_WARNING("Found stationIndex=" << static_cast<int>(map_data.stationIndex)
254 << " which is not reasonable, maybe related to ATLASRECTS-5961, continuing...");
255 stWarningPrinted = true;
256 }
257 }
258 return map_data.stationIndex >= 0;
259}
260bool MuonMDT_CablingAlg::extractLayerInfo(std::vector<std::string>& info_map, CablingData& map_data) const {
261 ATH_MSG_VERBOSE(" parsing of the map");
264 constexpr unsigned int coding_block_size = 3;
265 const unsigned int n = info_map.size() >= coding_block_size ? coding_block_size : info_map.size();
266 bool decoded_full_block{false};
267 for (unsigned int i = 0; i < n; ++i) {
268 ATH_MSG_VERBOSE(i << "..." << info_map[i]);
269 int info = CxxUtils::atoi(info_map[i]);
270 // this is a tdcid
271 if (i == 0) {
272 map_data.tdcId = info;
273 }
274 // this is a channel Id
275 else if (i == 1) {
276 map_data.channelId = info;
277 }
278 // this is a tube id that must be unpacked
279 else if (i == 2) {
281 map_data.tube = info % map_data.tubes_per_layer;
282 map_data.layer = ((info - map_data.tube) / map_data.tubes_per_layer) % map_data.layer_block;
283 map_data.multilayer = (((info - map_data.tube) / map_data.tubes_per_layer) - map_data.layer) / map_data.layer_block;
284 decoded_full_block = true;
285 }
286 }
287
288 // the stationIndex is later on passed to the MdtIdHelper, thus, it must be a reasonable station name, i.e. not < 0
289 if (decoded_full_block) info_map.erase(info_map.begin(), info_map.begin() + coding_block_size);
290 return decoded_full_block;
291}
292
294 MuonMDT_CablingMap& cabling_map) const{
295 if (m_mezzJSON.value().size()){
296 std::ifstream in_json{m_mezzJSON};
297 if (!in_json.good()) {
298 ATH_MSG_FATAL("Failed to open external JSON file "<<m_mezzJSON);
299 return StatusCode::FAILURE;
300 }
301 nlohmann::json payload{};
302 in_json >> payload;
303 ATH_CHECK(loadMezzanineFromJSON(std::move(payload), cabling_map));
304 return StatusCode::SUCCESS;
305 }
306
309 if (!readHandleMez.isValid()) {
310 ATH_MSG_ERROR("Null pointer to the read conditions object "<<m_readKeyMez.fullKey());
311 return StatusCode::FAILURE;
312 }
313 writeHandle.addDependency(readHandleMez);
314
315 ATH_MSG_INFO("Size of CondAttrListCollection " << readHandleMez.fullKey()
316 << " readCdoMez->size()= " << readHandleMez->size());
317
318 if (m_useJSONFormat) {
319 nlohmann::json json;
320 ATH_CHECK(dbPayloadToJson(readHandleMez, json));
321 ATH_CHECK(loadMezzanineFromJSON(std::move(json),cabling_map));
322 return StatusCode::SUCCESS;
323 }
325 for (itrMez = readHandleMez->begin(); itrMez != readHandleMez->end(); ++itrMez) {
326 const coral::AttributeList& atr = itrMez->second;
327 int sequence{0}, layer{0}, mezzanine_type{0};
328
329 mezzanine_type = *(static_cast<const int*>((atr["Mezzanine_Type"]).addressOfData()));
330 layer = *(static_cast<const int*>((atr["Layer"]).addressOfData()));
331 sequence = *(static_cast<const int*>((atr["Sequence"]).addressOfData()));
332 ATH_MSG_VERBOSE("Sequence load is " << sequence << " for the mezzanine type = " << mezzanine_type
333 << " for the layer number = " << layer);
334
335 // here add the mezzanine type to the cabling class
336 if (!cabling_map.addMezzanineLine(mezzanine_type, layer, sequence, msgStream())) {
337 ATH_MSG_ERROR("Could not add the mezzanine sequence to the map ");
338 return StatusCode::FAILURE;
339 } else {
340 ATH_MSG_VERBOSE("Sequence added successfully to the map");
341 }
342 }
343 return StatusCode::SUCCESS;
344}
345StatusCode MuonMDT_CablingAlg::loadMezzanineFromJSON(nlohmann::json&& payload, MuonMDT_CablingMap& cabling_map) const {
346 using MezzMapping = MdtMezzanineCard::Mapping;
347 for (const auto &cabl_chan : payload.items()) {
348 nlohmann::json mezz_payload = cabl_chan.value();
349 const uint8_t id = mezz_payload["mezzId"];
350 const uint8_t nLay = mezz_payload["nTubeLayer"];
351 const MezzMapping mapping = mezz_payload["tdcToTubeMap"];
352 if(!cabling_map.addMezanineLayout(std::make_unique<MdtMezzanineCard>(mapping, nLay, id),
353 msgStream())) return StatusCode::FAILURE;
354 }
355 return StatusCode::SUCCESS;
356}
357StatusCode MuonMDT_CablingAlg::loadCablingSchemaFromJSON(nlohmann::json&& payload, MuonMDT_CablingMap& cabling_map) const {
358 const MdtIdHelper& id_helper = m_idHelperSvc->mdtIdHelper();
359 for (const auto &db_channel : payload.items()) {
360 nlohmann::json ms_payload = db_channel.value();
361 CablingData ms_channel{};
362 ms_channel.stationIndex = id_helper.stationNameIndex(ms_payload["station"]);
363 ms_channel.eta = ms_payload["eta"];
364 ms_channel.phi = ms_payload["phi"];
365 ms_channel.multilayer = ms_payload["ml"];
366
367 ms_channel.subdetectorId = ms_payload["subDet"];
368 ms_channel.csm = ms_payload["csm"];
369 ms_channel.mrod = ms_payload["mrod"];
370
371 ms_channel.mezzanine_type = ms_payload["mezzId"];
372 ms_channel.tdcId = ms_payload["tdcId"];
373 ms_channel.tube = ms_payload["tubeZero"];
374
375 ms_channel.layer = 1;
376 MdtMezzanineCard::MezzCardPtr hedgeHogCard = cabling_map.getHedgeHogMapping(ms_channel.mezzanine_type);
377 ms_channel.channelId = hedgeHogCard ? (*std::min_element(
378 hedgeHogCard->tubeToTdcMap().begin(),
379 hedgeHogCard->tubeToTdcMap().end())) : 0;
380 if (!cabling_map.addMezzanine(std::move(ms_channel), DataSource::JSON, msgStream())) return StatusCode::FAILURE;
381 }
382 return StatusCode::SUCCESS;
383}
384
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
This file defines the class for a collection of AttributeLists where each one is associated with a ch...
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
nlohmann::json json
MuonMDT_CablingMap::DataSource DataSource
Base class for conditions algorithms.
ChanAttrListMap::const_iterator const_iterator
static EventIDRange infiniteRunLB()
Produces an EventIDRange that is infinite in RunLumi and invalid in Time.
static constexpr int maxNTubesPerLayer
The maxNTubesPerLayer represents the absolute maximum of tubes which are built into a single multilay...
Definition MdtIdHelper.h:68
const Mapping & tubeToTdcMap() const
Returns the underlying Tube -> Tdc conversion map.
std::shared_ptr< const MdtMezzanineCard > MezzCardPtr
std::array< uint8_t, 24 > Mapping
int stationNameIndex(const std::string &name) const
Gaudi::Property< bool > m_useJSONFormat
StatusCode loadCablingSchema(const EventContext &ctx, SG::WriteCondHandle< MuonMDT_CablingMap > &writeHandle, MuonMDT_CablingMap &cabling_map) const
Load the cabling schema of the tubes.
StatusCode dbPayloadToJson(SG::ReadCondHandle< CondAttrListCollection > &readHandle, nlohmann::json &json) const
StatusCode loadCablingSchemaFromJSON(nlohmann::json &&payload, MuonMDT_CablingMap &cabling_map) const
SG::WriteCondHandleKey< MuonMDT_CablingMap > m_writeKey
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
virtual StatusCode execute(const EventContext &ctx) const override
StatusCode loadMezzanineSchema(const EventContext &ctx, SG::WriteCondHandle< MuonMDT_CablingMap > &writeHandle, MuonMDT_CablingMap &cabling_map) const
Load the mezzanine schema into the cabling.
Gaudi::Property< bool > m_isRun3
bool extractStationInfo(const coral::AttributeList &atr, CablingData &map_data) const
Retrieves the general MDT station info from the coral attribute.
MuonMDT_CablingAlg(const std::string &name, ISvcLocator *pSvcLocator)
SG::ReadCondHandleKey< CondAttrListCollection > m_readKeyMap
Gaudi::Property< std::string > m_chambJSON
StatusCode loadMezzanineFromJSON(nlohmann::json &&payload, MuonMDT_CablingMap &cabling_map) const
bool extractLayerInfo(std::vector< std::string > &, CablingData &map_data) const
Retrieves the channel info from the coral attribute.
SG::ReadCondHandleKey< CondAttrListCollection > m_readKeyMez
MuonMDT_CablingMap::CablingData CablingData
Gaudi::Property< std::string > m_mezzJSON
virtual StatusCode initialize() override
MezzCardPtr getHedgeHogMapping(uint8_t mezzCardId) const
bool addMezanineLayout(std::unique_ptr< MdtMezzanineCard > card, MsgStream &log)
Adds a new mezzanine card mapping.
bool addMezzanine(CablingData cabling_data, DataSource source, MsgStream &log)
Add a new fully configured mezzanine card.
bool addMezzanineLine(const int type, const int layer, const int sequence, MsgStream &log)
Add a new line describing a mezzanine type.
const DataObjID & fullKey() const
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
STL class.
bool readBlobAsString(const coral::Blob &, std::string &)
std::vector< std::string > tokenize(const std::string &the_str, std::string_view delimiters)
Splits the string into smaller substrings.
int atoi(std::string_view str)
Helper functions to unpack numbers decoded in string into integers and doubles The strings are requir...
uint8_t tdcId
Mezzanine type.
int tubes_per_layer
Helper constants to extract tube,layer, multilayer information.
uint8_t mezzanine_type
Tube number in the layer.
int tube
Layer inside the multilayer.
uint8_t channelId
Identifier of the corresponding tdc.
int8_t & multilayer
Phi sector of the MDT station.
int8_t & eta
Station of the chamber (i.e, BIL,BIS,etc.)
int8_t & phi
Eta of the MDT station.
uint8_t & subdetectorId
CSM number.
uint8_t & csm
MROD number.