ATLAS Offline Software
Loading...
Searching...
No Matches
MuonMDT_CablingMap.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
7
8
9#include "GaudiKernel/ISvcLocator.h"
13#include "Identifier/Identifier.h"
15#include "GeoModelKernel/throwExcept.h"
16#include <cmath>
17
18namespace {
22static const std::set<uint8_t> special_cards{50, 60, 61, 71};
23} // namespace
25
27 // initialize the message service
28
29 // retrieve the MdtIdHelper
30 ISvcLocator* svcLocator = Gaudi::svcLocator();
31 SmartIF<StoreGateSvc> detStore{svcLocator->service("DetectorStore")};
32 if (!detStore) {
33 THROW_EXCEPTION("Could not find the detctor store");
34 }
35 StatusCode sc = detStore->retrieve(m_mdtIdHelper, "MDTIDHELPER");
36 if (sc != StatusCode::SUCCESS) {
37 THROW_EXCEPTION("Could not retrieve the MdtIdHelper");
38 }
39 m_2CSM_cham = m_mdtIdHelper->stationNameIndex("BME") != -1;
40}
41
43
45 Identifier& id, bool check_valid) const {
46 bool valid{!check_valid};
47 id = check_valid ? m_mdtIdHelper->channelID(
48 cabling_data.stationIndex, cabling_data.eta,
49 cabling_data.phi, cabling_data.multilayer,
50 cabling_data.layer, cabling_data.tube, valid)
51 : m_mdtIdHelper->channelID(
52 cabling_data.stationIndex, cabling_data.eta,
53 cabling_data.phi, cabling_data.multilayer,
54 cabling_data.layer, cabling_data.tube);
55 return valid;
56}
58 CablingData& cabling_data) const {
59 if (!m_mdtIdHelper->is_mdt(module_id))
60 return false;
61 cabling_data.stationIndex = m_mdtIdHelper->stationName(module_id);
62 cabling_data.eta = m_mdtIdHelper->stationEta(module_id);
63 cabling_data.phi = m_mdtIdHelper->stationPhi(module_id);
64 cabling_data.tube = m_mdtIdHelper->tube(module_id);
65 cabling_data.multilayer = m_mdtIdHelper->multilayer(module_id);
66 cabling_data.layer = m_mdtIdHelper->tubeLayer(module_id);
67 return true;
68}
69
71bool MuonMDT_CablingMap::addMezzanineLine(const int type, const int layer,
72 const int sequence, MsgStream& log) {
73 const bool debug = (log.level() <= MSG::VERBOSE);
74 if (special_cards.count(type)) {
75 if (debug)
76 log << MSG::VERBOSE << "Mezzanine type " << type
77 << " breaks the legacy database format. No need to add the "
78 "card if it's hardcoded in C++"
79 << endmsg;
80 return true;
81 }
82
83 int nOfLayers{0}, ntubes{0}, number{sequence};
84 std::array<int, 8> newseq{};
85 // now decode the sequence, up to 8 tubes per sequence
86 int tube = number % 10;
87
88 while (tube != 0) {
89 // add the tube to the tube sequence
90 if (ntubes > 7) {
91 log << MSG::ERROR << "More than 8 tubes in a layer, not possible !"
92 << endmsg;
93 return false;
94 }
95 if (debug) {
96 log << MSG::VERBOSE << "Adding tube number: " << tube
97 << " to the layer " << layer << " of mezzanine type " << type
98 << endmsg;
99 }
100
101 newseq[ntubes] = tube;
102
103 ++ntubes;
104 number = (number - tube) / 10;
105 tube = number % 10;
106 }
107
108 if (ntubes != 8 && ntubes != 6) {
109 log << MSG::ERROR << "in type " << type
110 << ": number of tubes per mezzanine layer can be only 6 or 8 ! "
111 "what are you doing ???"
112 << endmsg;
113 return false;
114 }
115 nOfLayers = 24 / ntubes;
116 if (layer > nOfLayers) {
117 log << MSG::ERROR
118 << "The maximum number of layers for this mezzanine is: "
119 << nOfLayers << " so you can't initialize layer: " << layer
120 << endmsg;
121 return false;
122 }
123
124 if (debug) {
125 log << MSG::VERBOSE << "Found " << ntubes << " tubes in layer " << layer
126 << endmsg;
127 log << MSG::VERBOSE << "This is a " << nOfLayers
128 << " layers mezzanine - OK, OK..." << endmsg;
129 }
130
131 // now swap the sequence to have it as in the DB and create the real layers
132 std::array<uint8_t, 8> newLayer{};
133 for (int i = 0; i < ntubes; ++i) {
134 newLayer[i] = newseq[ntubes - i - 1];
135 }
136 MezzCardList::iterator itr = std::find_if(
137 m_mezzCards.begin(), m_mezzCards.end(),
138 [type](const MezzCardPtr& card) { return type == card->id(); });
139
140 using MezzMapping = MdtMezzanineCard::Mapping;
141 MezzMapping new_map =
142 itr != m_mezzCards.end()
143 ? (**itr).tdcToTubeMap()
145
146 MdtMezzanineCard dummy_card(new_map, nOfLayers, 0);
147
148 for (int i = 0; i < ntubes; ++i) {
149 if (layer) {
150 const int chStart = ntubes * (layer - 1);
151 new_map[chStart + i] = dummy_card.tubeNumber(layer, newLayer[i]);
152 } else {
153 for (int lay = 1; lay <= nOfLayers; ++lay) {
154 const int chStart = ntubes * (lay - 1);
155 new_map[chStart + i] = dummy_card.tubeNumber(lay, newLayer[i]);
156 }
157 }
158 }
160 if (itr != m_mezzCards.end()) {
161 if (!layer) {
162 log << MSG::ERROR << "The mezzanine type " << type
163 << "has been already initialized" << endmsg;
164 return false;
165 }
166 (*itr) = std::make_unique<MdtMezzanineCard>(new_map, nOfLayers, type);
167 if (debug)
168 log << MSG::VERBOSE << "Updated mezzanine " << (**itr) << endmsg;
169 } else {
170 m_mezzCards.emplace_back(
171 std::make_unique<MdtMezzanineCard>(new_map, nOfLayers, type));
172 if (debug)
173 log << MSG::VERBOSE << " Added new mezzanine "
174 << (*m_mezzCards.back()) << endmsg;
175 }
176 return true;
177}
179 MezzCardPtr mezzaType{nullptr};
180 MezzCardList::const_iterator it = std::find_if(
181 m_mezzCards.begin(), m_mezzCards.end(),
182 [&](const MezzCardPtr& card) { return card->id() == mezzCardId; });
183 return it != m_mezzCards.end() ? (*it) : nullptr;
184}
185
187 MsgStream& log) {
188 bool debug = (log.level() <= MSG::VERBOSE);
189
190 MezzCardPtr mezzaType = source == DataSource::LegacyCOOL
191 ? legacyHedgehogCard(map_data, log)
193 if (!mezzaType) {
194 log << MSG::ERROR
195 << "Mezzanine Type: " << static_cast<int>(map_data.mezzanine_type)
196 << " not found in the list !" << endmsg;
197 return false;
198 } else if (source == DataSource::LegacyCOOL && !mezzaType->checkConsistency(log)){
199 return false;
200 }
201 auto newTdc = std::make_unique<MdtTdcMap>(mezzaType, map_data);
202 if (debug) {
203 log << MSG::VERBOSE << " Added new readout channel " << map_data<< endmsg;
204 }
205 MdtOffChModule& offModule = m_toOnlineConv[map_data];
206 offModule.cards.emplace(newTdc.get());
207 if (!offModule.csm[0]) {
208 offModule.csm[0] = map_data;
209 if (debug){
210 log<< MSG::VERBOSE<<"Assign first CSM "<<map_data<<endmsg;
211 }
213 if (map_data.multilayer == 1) {
214 CablingData secondMl = map_data;
215 secondMl.multilayer = 2;
216 MdtOffChModule& secondModule{m_toOnlineConv[secondMl]};
217 if (!secondModule.csm[0]){
218 secondModule.csm[0] = map_data;
219 } else if (secondModule.csm[0] != map_data && !secondModule.csm[1]) {
220 secondModule.csm[1] = map_data;
221 std::swap(secondModule.csm[1], secondModule.csm[0]);
222 }
223 }
224 } else if (offModule.csm[0] != map_data) {
225 if (!offModule.csm[1]) {
226 offModule.csm[1] = map_data;
227 if (debug) {
228 log << MSG::VERBOSE << " Add second CSM for " << map_data << endmsg;
229 }
230 } else if (offModule.csm[1] != map_data) {
231 log << MSG::ERROR << "The mulit layer " << map_data
232 << " has already associated the CSMs " << std::endl
233 << " *** " << offModule.csm[0] << std::endl
234 << " *** " << offModule.csm[1] << std::endl
235 << ", while this one is a third one and not supported"
236 << endmsg;
237 return false;
238 }
239 }
240 TdcOnlSet& attachedTdcs = m_toOfflineConv[map_data].all_modules;
241 if (attachedTdcs.size() <= map_data.tdcId)
242 attachedTdcs.resize(map_data.tdcId + 1);
243 attachedTdcs[map_data.tdcId] = MdtTdcOnlSorter{newTdc.get()};
244 m_tdcs.push_back(std::move(newTdc));
245
246 if (!addChamberToROBMap(map_data, log) && debug) {
247 log << MSG::VERBOSE << "Station already in the map !" << endmsg;
248 }
249
250 return true;
251}
253 MsgStream& log) const {
254 OnlToOffMap::const_iterator module_itr = m_toOfflineConv.find(cabling_map);
255 if (module_itr == m_toOfflineConv.end()) {
256 log << MSG::WARNING
257 << "Could not find a cabling module to recieve offline Id for "
258 << cabling_map << endmsg;
259 return false;
260 }
262 if (cabling_map.tdcId == 0xff && cabling_map.channelId == 0xff) {
263 cabling_map.channelId = 0;
264 if (!module_itr->second.zero_module) {
265 log << MSG::WARNING << " No tdc with channel zero found for "
266 << module_itr->first << endmsg;
267 return false;
268 }
269 if (!module_itr->second.zero_module->offlineId(cabling_map, log)) {
270 log << MSG::WARNING << "MdtTdMap::getOfflineId() -- Channel: "
271 << static_cast<unsigned>(cabling_map.channelId)
272 << " Tdc: " << static_cast<unsigned>(cabling_map.tdcId)
273 << " not found in "
274 << static_cast<const MdtCablingOnData&>(cabling_map) << endmsg;
275 return false;
276 }
277 } else {
278 const TdcOnlSet& attachedTdcs = module_itr->second.all_modules;
279 if (attachedTdcs.size() <= cabling_map.tdcId) {
280 log << MSG::WARNING << "getOfflineId() -- Tdc: "
281 << static_cast<unsigned>(cabling_map.tdcId)
282 << " is not part of " << module_itr->first << ". Maximally "
283 << attachedTdcs.size() << " Tdcs were attached. " << endmsg;
284 return false;
285 }
286 const MdtTdcOnlSorter& TdcItr = attachedTdcs.at(cabling_map.tdcId);
287 if (!TdcItr) {
288 log << MSG::WARNING << "getOfflineId() -- Tdc: "
289 << static_cast<unsigned>(cabling_map.tdcId) << " not found in "
290 << static_cast<const MdtCablingOnData&>(cabling_map) << endmsg;
291 return false;
292 }
293 if (!TdcItr->offlineId(cabling_map, log)) {
294 log << MSG::WARNING << "MdtTdMap::getOfflineId() -- channel: "
295 << static_cast<unsigned>(cabling_map.channelId)
296 << " Tdc: " << static_cast<unsigned>(cabling_map.tdcId)
297 << " not found in "
298 << static_cast<const MdtCablingOnData&>(cabling_map) << endmsg;
299 return false;
300 }
301 }
302 if (log.level() <= MSG::VERBOSE) {
303 log << MSG::VERBOSE
304 << "Channel: " << static_cast<unsigned>(cabling_map.channelId)
305 << " Tdc: " << static_cast<unsigned>(cabling_map.tdcId) << " "
306 << static_cast<const MdtCablingOnData&>(cabling_map) << endmsg;
307
308 log << MSG::VERBOSE << "Mapped to "
309 << static_cast<const MdtCablingOffData&>(cabling_map)
310 << " layer: " << cabling_map.layer << " tube: " << cabling_map.tube
311 << endmsg;
312 }
313 return true;
314}
315
318 MsgStream& log) const {
319 OffToOnlMap::const_iterator module_itr = m_toOnlineConv.find(cabling_map);
320 if (module_itr == m_toOnlineConv.end()) {
321 log << MSG::WARNING
322 << "getOnlineId() --- Could not find a cabling CSM set recieve "
323 "online Id for "
324 << static_cast<MdtCablingOffData&>(cabling_map) << endmsg;
325 return false;
326 }
327 const TdcOffSet& attachedTdcs = module_itr->second.cards;
328 TdcOffSet::const_iterator tdc_itr = attachedTdcs.find(cabling_map);
329 if (tdc_itr == attachedTdcs.end()) {
330 log << MSG::WARNING << "No matching Tdc channel was found for "
331 << cabling_map << endmsg;
332 } else if ((*tdc_itr)->onlineId(cabling_map, log))
333 return true;
335 TdcOffSet::const_iterator control_itr =
336 std::find_if(attachedTdcs.begin(), attachedTdcs.end(),
337 [&cabling_map, &log](const MdtTdcOffSorter& tdc) {
338 return tdc->onlineId(cabling_map, log);
339 });
340 if (control_itr == attachedTdcs.end()) {
341 log << MSG::WARNING
342 << "Second trial to find a valid cabling channel for "
343 << cabling_map << " failed as well. " << endmsg;
344 return false;
345 }
346 return true;
347}
356
358 MsgStream& log) {
359 bool debug = (log.level() <= MSG::VERBOSE);
360 IdentifierHash chamberId, multiLayerId{0};
361 Identifier ml{0};
362 if (!getStationCode(map_data, chamberId, log)) {
363 log << MSG::ERROR << "Could not find hashId for station: " << map_data
364 << endmsg;
365 return false;
366 }
367 if (!getMultiLayerCode(map_data, ml, multiLayerId, log)) {
368 log << MSG::ERROR << "Could not find hashId for multi layer: " << map_data << endmsg;
369 return false;
370 }
371 int sub = map_data.subdetectorId;
372 int rod = map_data.mrod;
373
374 uint32_t hardId = (sub << 16) | rod;
375 if (debug) {
376 log << MSG::VERBOSE << "Adding the chamber with Id: " << chamberId
377 << " and subdetector+rod ID: " << hardId << endmsg;
378 }
379
380 // check if the chamber has already been put into the map
381 ChamberToROBMap::const_iterator it = m_multilayerToROB.find(multiLayerId);
382 if (it != m_multilayerToROB.end()) {
383 return false;
384 }
385 m_multilayerToROB.insert(std::make_pair(multiLayerId, hardId));
386 m_chamberToROB.insert(std::make_pair(chamberId, hardId));
387 // new function to do the opposite of the above
388 m_ROBToMultiLayer[hardId].push_back(multiLayerId);
389 // now check if the ROB is already in the list of ROB vector
390 const bool robInitialized =
391 std::find(m_listOfROB.begin(), m_listOfROB.end(), hardId) !=
392 m_listOfROB.end();
393 if (!robInitialized) {
394 if (debug) {
395 log << MSG::VERBOSE << "Adding the ROB " << hardId << " to the list"
396 << endmsg;
397 }
398 m_listOfROB.push_back(hardId);
399 }
400 return true;
401}
403 MsgStream& log) const {
405 OffToOnlMap::const_iterator off_itr = m_toOnlineConv.find(map_data);
406 if (off_itr == m_toOnlineConv.end()) {
407 log << MSG::ERROR << "csmNumOnChamber() -- Nothing is saved under "
408 << map_data << endmsg;
409 return 0;
410 }
411 return (1 * (off_itr->second.csm[0] == map_data)) +
412 (2 * (off_itr->second.csm[1] == map_data));
413}
415 IdentifierHash& mdtHashId,
416 MsgStream& log) const {
417 const Identifier elementId = m_mdtIdHelper->elementID(
418 map_data.stationIndex, map_data.eta, map_data.phi);
419 if (m_mdtIdHelper->get_module_hash(elementId, mdtHashId)) {
420 log << MSG::ERROR
421 << "getstationCode() -- Could not find HashId for module: "
422 << map_data << endmsg;
423 elementId.show();
424 return false;
425 }
426 return true;
427}
429 return m_2CSM_cham;
430}
432 Identifier& elementId,
433 IdentifierHash& mdtHashId,
434 MsgStream& log) const {
435 const unsigned int ml = m_2CSM_cham ? csmNumOnChamber(map_data, log) : 1;
436 if (!ml) {
437 log << MSG::ERROR
438 << "getMultiLayerCode() -- Could not determine the detector layer "
439 << map_data << endmsg;
440 return false;
441 }
443 elementId = m_mdtIdHelper->channelID(map_data.stationIndex, map_data.eta,
444 map_data.phi, ml, 1, 1);
447 if (m_2CSM_cham &&
448 m_mdtIdHelper->get_detectorElement_hash(elementId, mdtHashId)) {
449 log << MSG::ERROR
450 << "getMultiLayerCode() -- Could not find HashId for module: "
451 << map_data << endmsg;
452 elementId.show();
453 return false;
454 }
457 else if (!m_2CSM_cham &&
458 m_mdtIdHelper->get_module_hash(elementId, mdtHashId)) {
459 log << MSG::ERROR
460 << "getMultiLayerCode() -- Could not find HashId for module: "
461 << map_data << endmsg;
462 elementId.show();
463 return false;
464 }
465 return true;
466}
468 MsgStream& log) const {
469 ChamberToROBMap::const_iterator it = m_chamberToROB.find(stationCode);
470 if (it != m_chamberToROB.end()) {
471 return it->second;
472 }
473 log << MSG::WARNING << "ROB ID " << stationCode << " not found !" << endmsg;
474 return 0;
475}
476// get the robs corresponding to a vector of hashIds, copied from Svc before the
477// readCdo migration
478std::vector<uint32_t> MuonMDT_CablingMap::getROBId(
479 const std::vector<IdentifierHash>& mdtHashVector, MsgStream& log) const {
480 std::vector<uint32_t> robVector;
481 bool debug = (log.level() <= MSG::VERBOSE);
482 for (unsigned int i = 0; i < mdtHashVector.size(); ++i) {
483 int robId = getROBId(mdtHashVector[i], log);
484 if (!robId) {
485 log << MSG::ERROR
486 << "ROB id not found for Hash Id: " << mdtHashVector[i]
487 << endmsg;
488 } else if (debug) {
489 log << MSG::VERBOSE << "Found ROB id " << robId << " for hashId "
490 << mdtHashVector[i] << endmsg;
491 }
492 robVector.push_back(robId);
493 }
494 if (debug) {
495 log << MSG::VERBOSE << "Size of ROB vector is: " << robVector.size()
496 << endmsg;
497 }
498 return robVector;
499}
500
501const std::vector<IdentifierHash>& MuonMDT_CablingMap::getMultiLayerHashVec(
502 const uint32_t ROBId, MsgStream& log) const {
503 ROBToChamberMap::const_iterator Rob_it = m_ROBToMultiLayer.find(ROBId);
504 if (Rob_it != m_ROBToMultiLayer.end()) {
505 return Rob_it->second;
506 }
507
508 log << MSG::WARNING << "Rod ID not found !" << endmsg;
509 static const std::vector<IdentifierHash> emptyIdHashVec{};
510 return emptyIdHashVec;
511}
512
514 const std::vector<uint32_t>& ROBId_list, MsgStream& log) const {
515 std::vector<IdentifierHash> HashVec;
516 for (unsigned int i = 0; i < ROBId_list.size(); ++i) {
517 ROBToChamberMap::const_iterator Rob_it =
518 m_ROBToMultiLayer.find(ROBId_list[i]);
519 if (Rob_it == m_ROBToMultiLayer.end()) {
520 log << MSG::WARNING << "Rod ID " << ROBId_list[i]
521 << " not found, continuing with the rest of the ROBId"
522 << endmsg;
523 continue;
524 }
525 HashVec.insert(HashVec.end(), Rob_it->second.begin(),
526 Rob_it->second.end());
527 }
528 return HashVec;
529}
530
534
536 if (m_tdcs.empty()) {
537 log << MSG::ERROR << "No tdc maps were loaded " << endmsg;
538 return false;
539 }
540 for (const MezzCardPtr& card : m_mezzCards) {
541 if (!card->checkConsistency(log))
542 return false;
543 }
544
545 const unsigned int offToOnlChan =
546 std::accumulate(m_toOnlineConv.begin(), m_toOnlineConv.end(), 0,
547 [](unsigned int N, const auto& map) {
548 return N + map.second.cards.size();
549 });
550 const unsigned int onlToOffChan = std::accumulate(
551 m_toOfflineConv.begin(), m_toOfflineConv.end(), 0,
552 [](unsigned int N, const auto& map) {
553 return N + std::accumulate(map.second.begin(), map.second.end(), 0,
554 [](unsigned int M, const auto& tdc) {
555 return M + tdc;
556 });
557 });
558
559 if (offToOnlChan != onlToOffChan || onlToOffChan != m_tdcs.size()) {
560 log << MSG::ERROR
561 << "Offline <-> online conversion channels were lost. Expect "
562 << m_tdcs.size()
563 << " cabling channels. Counted Offline -> online channels "
564 << offToOnlChan << ". Conted Online -> offline channels "
565 << onlToOffChan << endmsg;
566 return false;
567 }
568 for (auto& toOff : m_toOfflineConv) {
569 MdtTdcModule& mod = toOff.second;
570 TdcOnlSet::const_iterator itr = std::find_if(
571 mod.begin(), mod.end(), [](const MdtTdcOnlSorter& sorter) {
572 return sorter && sorter->tdcZero() == 0;
573 });
574 if (itr == mod.end()) {
575 log << MSG::ERROR << "There is no tdc with channel 0 in "
576 << toOff.first
577 << ". That is important to decode the station names later"
578 << endmsg;
579 return false;
580 }
581 mod.zero_module = (*itr);
582 }
583 m_mezzCards.clear();
584 log << MSG::INFO << "MdtCabling successfully loaded. Found in total "
585 << m_tdcs.size() << " channels." << endmsg;
586 return true;
587}
589 std::unique_ptr<MdtMezzanineCard> card, MsgStream& log) {
590 if (!card->checkConsistency(log))
591 return false;
592 MezzCardList::const_iterator itr =
593 std::find_if(m_mezzCards.begin(), m_mezzCards.end(),
594 [&card](const MezzCardPtr& existing) {
595 return existing->id() == card->id();
596 });
597 if (itr != m_mezzCards.end()) {
598 log << MSG::ERROR << "Mezzanine card " << std::endl
599 << (*card) << " has already been added " << std::endl
600 << (**itr) << std::endl
601 << " please check. " << endmsg;
602 return false;
603 }
604 m_mezzCards.push_back(std::move(card));
605 return true;
606}
608 MsgStream& msg) const {
609 using MezzMapping = MdtMezzanineCard::Mapping;
611
612 const int mezzType = cabling.mezzanine_type;
613 const int chanZero = cabling.channelId;
614 const int layerZero = cabling.layer;
615 const int tubeZero = cabling.tube;
616
617 cabling.tube = MdtIdHelper::maxNTubesPerLayer;
618 const bool debug = msg.level() <= MSG::VERBOSE;
619
620 if (special_cards.count(mezzType)) {
621 const MdtMezzanineCard dummy_card(chMap, 4, mezzType);
622 if (debug)
623 msg << MSG::VERBOSE
624 << "legacyHedgehogCard() -- Special layout given " << mezzType
625 << endmsg;
626 for (size_t chan = 0; chan < chMap.size(); ++chan) {
627 uint8_t tube_chan = ((chan - chan % 4) / 4);
630 if (mezzType == 71) {
631 tube_chan = 5 - tube_chan;
632 }
633 int layer{0}, tube{0};
634 // special case of the BME of end 2013 and BMG 2017
635 /*
636 * cases 50 and 60 follow the same rules. hedgehog card 50 is the
637 * mirror image of card 60, but the rules concerning how to decode
638 * the tube mapping are the same. channel 0 of a mezzanine card for
639 * case 50 is either top right or bottom left, while for case 60 it
640 * is top left or bottom right. Another thing to keep in mind for
641 * BMG is, that tube counting in some cases is along |z|, while in
642 * some other cases it is opposite.
643 *
644 * E.g: Numbering from top to bottom -> Tube counting along z
645 *
646 * Layer | Tube number
647 * 4 | 0 4 8 12 16 20
648 * 3 | 1 5 9 13 17 21
649 * 2 | 2 6 10 14 18 22
650 * 1 | 3 7 11 15 19 23
651 */
652 if (mezzType == 50 || mezzType == 60 || mezzType == 61) {
654 if (layerZero == 1) {
655 layer = chan % 4 + 1;
656 }
657 // Tube numbering is from top to bottom
658 else {
659 layer = 4 - chan % 4;
660 }
661 if ((tubeZero - 1) % 6 == 0) {
662 tube = tubeZero + tube_chan;
663 } else {
664 tube = tubeZero - tube_chan;
665 }
666 }
667 /* Few mezzanine cards in the BIS78 chambers are collateral vicitms
668 * of the famous regional customs happening in the Bavarian autumun.
669 * The tube staggering is kind of discontinous where the upper two
670 * layers are swapped with the bottom two 1 5 9 13 17
671 * 21 0 4 8 12 16 20 3 7 11 15 19
672 * 23 2 6 10 14 18 22
673 */
674 else if (mezzType == 71) {
675 layer = (chan % 4);
676 layer += 2 * (layer > 1 ? -1 : +1) + 1;
677 tube = tubeZero - tube_chan;
678 }
679 cabling.tube = std::min(cabling.tube, tube);
680 chMap[chan] = dummy_card.tubeNumber(layer, tube);
681 if (debug)
682 msg << MSG::VERBOSE << "legacyHedgehogCard() -- Channel "
683 << chan << " mapped to " << layer << ", " << tube << endmsg;
684 }
685 return std::make_unique<MdtMezzanineCard>(chMap, 4, mezzType);
686 }
688 MezzCardPtr card = getHedgeHogMapping(mezzType);
689 if (!card)
690 return nullptr;
691 if (debug)
692 msg << MSG::VERBOSE << "Assign local tube mapping from " << (*card)
693 << std::endl
694 << "to connect " << cabling << " tubeZero: " << tubeZero << endmsg;
695 const int stationName = cabling.stationIndex;
696 const int stationEta = std::abs(cabling.eta);
697
698 for (size_t chan = 0; chan < chMap.size(); ++chan) {
699 // calculate the layer
700 int layer{0}, tube{0};
701 if (layerZero == 1) {
702 layer = chan / (card->numTubesPerLayer()) + 1;
703 } else {
704 layer = layerZero - chan / (card->numTubesPerLayer());
705 }
706
707 // calculate the tube in layer
708 uint8_t localchan = chan % (card->numTubesPerLayer());
709
710 // special case of the BIR with 3 tubes overlapping to another mezzanine
711 if ((chanZero == 5 && stationName == 7 && stationEta == 3) &&
712 ((card->id() > 40 && localchan % 2 == 0) ||
713 (card->id() < 40 && localchan < 3)))
714 continue;
715
716 using OfflineCh = MdtMezzanineCard::OfflineCh;
717 OfflineCh locTubeLay = card->offlineTube(
718 localchan + (layer - 1) * card->numTubesPerLayer(), msg);
719 OfflineCh zeroTubeLay = card->offlineTube(
720 chanZero + (layer - 1) * card->numTubesPerLayer(), msg);
721 if (!locTubeLay.isValid || !zeroTubeLay.isValid)
722 continue;
723
724 tube = (static_cast<int>(locTubeLay.tube) -
725 static_cast<int>(zeroTubeLay.tube) + tubeZero);
726
727 if (debug)
728 msg << MSG::VERBOSE << "legacyHedgehogCard() -- Channel " << chan
729 << " mapped to " << layer << ", " << tube
730 << " locTube: " << static_cast<int>(locTubeLay.tube)
731 << " zeroTubeLay: " << static_cast<int>(zeroTubeLay.tube)
732 << endmsg;
733
734 if (tube < 1 || tube >= MdtIdHelper::maxNTubesPerLayer)
735 continue;
736 cabling.tube = std::min(cabling.tube, tube);
737 chMap[chan] = card->tubeNumber(layer, tube);
738 }
739 std::unique_ptr<MdtMezzanineCard> to_ret =
740 std::make_unique<MdtMezzanineCard>(chMap, card->numTubeLayers(),
741 mezzType);
742 const uint8_t tubeZeroOff = (cabling.tube - 1) % to_ret->numTubesPerLayer();
743 if (!tubeZeroOff)
744 return to_ret;
746 for (size_t chan = 0; chan < chMap.size(); ++chan) {
747 using OfflineCh = MdtMezzanineCard::OfflineCh;
748 OfflineCh tube_lay = to_ret->offlineTube(chan, msg);
749 if (!tube_lay.isValid)
750 continue;
751 uint8_t tubeNumber = tube_lay.tube + tubeZeroOff + 1;
752 chMap[chan] = card->tubeNumber(tube_lay.layer, tubeNumber);
753 }
754 if (debug)
755 msg << MSG::VERBOSE << "Final mapping " << cabling << endmsg;
756
757 return std::make_unique<MdtMezzanineCard>(chMap, card->numTubeLayers(),
758 mezzType);
759}
#define endmsg
constexpr std::array< T, N > make_array(const T &def_val)
Helper function to initialize in-place arrays with non-zero values.
Definition ArrayHelper.h:10
const bool debug
MuonMDT_CablingMap::MezzCardPtr MezzCardPtr
This is a "hash" representation of an Identifier.
void show() const
Print out in hex form.
static constexpr int maxNTubesPerLayer
The maxNTubesPerLayer represents the absolute maximum of tubes which are built into a single multilay...
Definition MdtIdHelper.h:68
MdtMezzanineCard - Helper struct to represent the structure of a mezzanine card in a consistent way E...
static constexpr uint8_t NOTSET
bool checkConsistency(MsgStream &msg) const
checks whether the tdc mapping is complete.
OfflineCh offlineTube(uint8_t tdc, MsgStream &msg) const
uint8_t numTubesPerLayer() const
returns the number of tubes per layer;
uint8_t id() const
returns mezzanine database identifier
std::array< uint8_t, 24 > Mapping
uint8_t numTubeLayers() const
returns the number of layers
uint8_t tubeNumber(uint8_t tubeLay, uint8_t tube) const
returns the tube number
bool offlineId(MdtCablingData &cabling_data, MsgStream &log) const
retrieve the full information
Definition MdtTdcMap.cxx:24
unsigned int csmNumOnChamber(const CablingData &map_data, MsgStream &log) const
Returns whether the channel belongs to the first or second mounted CSM card.
ROBToChamberMap m_ROBToMultiLayer
map returning a detector element hashes associated with a given ROD
const ListOfROB & getAllROBId() const
return the ROD id of a given chamber
MezzCardPtr getHedgeHogMapping(uint8_t mezzCardId) const
std::vector< MdtTdcOnlSorter > TdcOnlSet
ChamberToROBMap m_chamberToROB
map returning the RODid for a given chamber ID
const OnlToOffMap & getOnlineConvMap() const
Returns the map to convert the online -> offline identifiers.
const OffToOnlMap & getOfflineConvMap() const
Returns hte map to convert the offline -> online identifiers.
std::map< MdtCablingOffData, MdtOffChModule > OffToOnlMap
MdtCablingData CablingData
bool getOnlineId(CablingData &cabling_data, MsgStream &log) const
return the online id given the offline id
bool addMezanineLayout(std::unique_ptr< MdtMezzanineCard > card, MsgStream &log)
Adds a new mezzanine card mapping.
bool m_2CSM_cham
Switch to check whether the layout has chambers with 2 CSM chips.
const MdtIdHelper * m_mdtIdHelper
Pointer to the MdtIdHelper.
bool getOfflineId(CablingData &cabling_data, MsgStream &log) const
return the offline id given the online id
ChamberToROBMap m_multilayerToROB
map raturning the RODid for a given multi layer ID
std::vector< uint32_t > ListOfROB
bool addChamberToROBMap(const CablingData &cabling_data, MsgStream &log)
private function to add a chamber to the ROD map
uint32_t getROBId(const IdentifierHash &stationCode, MsgStream &log) const
return the ROD id of a given chamber, given the hash id
std::vector< IdentifierHash > getMultiLayerHashVec(const std::vector< uint32_t > &ROBId_list, MsgStream &log) const
return a vector of HashId lists for a given list of ROD's
std::set< MdtTdcOffSorter, std::less<> > TdcOffSet
bool convert(const CablingData &cabling_data, Identifier &id, bool check_valid=true) const
converts the cabling data into an identifier.
bool addMezzanine(CablingData cabling_data, DataSource source, MsgStream &log)
Add a new fully configured mezzanine card.
bool getStationCode(const CablingData &map_data, IdentifierHash &mdtHashId, MsgStream &log) const
Transforms the identifier to an IdentifierHash corresponding to the module.
MezzCardPtr legacyHedgehogCard(CablingData &cabling, MsgStream &msg) const
In the legacy data format several transformations on the hedgehog layout were applied during the fina...
MdtMezzanineCard::MezzCardPtr MezzCardPtr
bool addMezzanineLine(const int type, const int layer, const int sequence, MsgStream &log)
Add a new line describing a mezzanine type.
bool finalize_init(MsgStream &log)
std::vector< std::unique_ptr< MdtTdcMap > > m_tdcs
std::map< MdtCablingOnData, MdtTdcModule > OnlToOffMap
ListOfROB m_listOfROB
full list of ROBs
bool has2CsmML() const
Returns if the cabling map has found multilayers connected to 2 CSM cards.
bool getMultiLayerCode(const CablingData &map_data, Identifier &multiLayer, IdentifierHash &mdtHashId, MsgStream &log) const
Transforms the identifier to an IdentifierHash corresponding to the multilayer In this case,...
STL class.
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)
uint8_t tdcId
Mezzanine type.
uint8_t mezzanine_type
Tube number in the layer.
int tube
Layer inside the multilayer.
uint8_t channelId
Identifier of the corresponding tdc.
Split the offline part of the cabling apart to use it later for sorting.
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.
Helper struct to pipe the result from the tdc -> offline channel translation.
Helper struct to search through the std::set if a conversion from offline -> online is needed.
Definition MdtTdcMap.h:88
Helper struct to search through the std::set if a conversion from online -> offline is needed.
Definition MdtTdcMap.h:100
Helper struct to group the Mezzanine cards mounted on each multilayer The object provides the followi...
TdcOffSet cards
Mezzanine cards mounted on the chamber.
std::array< MdtCablingOnData, 2 > csm
The up to 2 CSMs to which the cards are connected.
MsgStream & msg
Definition testRead.cxx:32
#define THROW_EXCEPTION(MESSAGE)
Definition throwExcept.h:10
std::string number(const double &d, const std::string &s)
Definition utils.cxx:186