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