ATLAS Offline Software
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"
11 #include "CxxUtils/ArrayHelper.h"
12 #include "StoreGate/StoreGateSvc.h"
13 #include "Identifier/Identifier.h"
15 #include "GeoModelKernel/throwExcept.h"
16 #include <cmath>
17 
18 namespace {
22 static 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  }
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)
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 
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()
144  : make_array<uint8_t, 24>(MdtMezzanineCard::NOTSET);
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 }
187  MsgStream& log) {
188  bool debug = (log.level() <= MSG::VERBOSE);
189 
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 }
349  const {
350  return m_toOfflineConv;
351 }
353  const {
354  return m_toOnlineConv;
355 }
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
478 std::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 
501 const 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 
513 std::vector<IdentifierHash> MuonMDT_CablingMap::getMultiLayerHashVec(
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 
532  return m_listOfROB;
533 }
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 =
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;
610  MezzMapping chMap{make_array<uint8_t, 24>(MdtMezzanineCard::NOTSET)};
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 
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;
745  chMap = make_array<uint8_t, 24>(MdtMezzanineCard::NOTSET);
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 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
MdtIdHelper::multilayer
int multilayer(const Identifier &id) const
Access to components of the ID.
Definition: MdtIdHelper.cxx:727
MuonIdHelper::stationNameIndex
int stationNameIndex(const std::string &name) const
Definition: MuonIdHelper.cxx:852
MuonMDT_CablingMap::m_ROBToMultiLayer
ROBToChamberMap m_ROBToMultiLayer
map returning a detector element hashes associated with a given ROD
Definition: MuonMDT_CablingMap.h:173
MuonMDT_CablingMap::getStationCode
bool getStationCode(const CablingData &map_data, IdentifierHash &mdtHashId, MsgStream &log) const
Transforms the identifier to an IdentifierHash corresponding to the module.
Definition: MuonMDT_CablingMap.cxx:414
MuonMDT_CablingMap::MuonMDT_CablingMap
MuonMDT_CablingMap()
Definition: MuonMDT_CablingMap.cxx:26
MdtTdcOffSorter
Helper struct to search through the std::set if a conversion from offline -> online is needed.
Definition: MdtTdcMap.h:88
MuonMDT_CablingMap::MdtOffChModule::cards
TdcOffSet cards
Mezzanine cards mounted on the chamber.
Definition: MuonMDT_CablingMap.h:49
MuonMDT_CablingMap::getMultiLayerHashVec
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
Definition: MuonMDT_CablingMap.cxx:513
MuonMDT_CablingMap::legacyHedgehogCard
MezzCardPtr legacyHedgehogCard(CablingData &cabling, MsgStream &msg) const
In the legacy data format several transformations on the hedgehog layout were applied during the fina...
Definition: MuonMDT_CablingMap.cxx:607
MdtTdcMap::offlineId
bool offlineId(MdtCablingData &cabling_data, MsgStream &log) const
retrieve the full information
Definition: MdtTdcMap.cxx:24
MdtCablingData::tube
int tube
Layer inside the multilayer.
Definition: MdtCablingData.h:88
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:558
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
MdtCablingOffData::eta
int8_t & eta
Station of the chamber (i.e, BIL,BIS,etc.)
Definition: MdtCablingData.h:29
MdtCablingOnData
Definition: MdtCablingData.h:51
MdtMezzanineCard::numTubesPerLayer
uint8_t numTubesPerLayer() const
returns the number of tubes per layer;
Definition: MdtMezzanineCard.h:69
MuonMDT_CablingMap::addChamberToROBMap
bool addChamberToROBMap(const CablingData &cabling_data, MsgStream &log)
private function to add a chamber to the ROD map
Definition: MuonMDT_CablingMap.cxx:357
dumpTgcDigiDeadChambers.stationName
dictionary stationName
Definition: dumpTgcDigiDeadChambers.py:30
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
MuonMDT_CablingMap::addMezzanine
bool addMezzanine(CablingData cabling_data, DataSource source, MsgStream &log)
Add a new fully configured mezzanine card.
Definition: MuonMDT_CablingMap.cxx:186
MuonMDT_CablingMap::ListOfROB
std::vector< uint32_t > ListOfROB
Definition: MuonMDT_CablingMap.h:78
MuonIdHelper::is_mdt
bool is_mdt(const Identifier &id) const
Definition: MuonIdHelper.cxx:792
MdtCablingData::mezzanine_type
uint8_t mezzanine_type
Tube number in the layer.
Definition: MdtCablingData.h:90
MdtCablingOffData::stationIndex
int8_t & stationIndex
Definition: MdtCablingData.h:27
MdtCablingOnData::mrod
uint8_t & mrod
Definition: MdtCablingData.h:53
runITkAlign.accumulate
accumulate
Update flags based on parser line args.
Definition: runITkAlign.py:62
MdtMezzanineCard::Mapping
std::array< uint8_t, 24 > Mapping
Definition: MdtMezzanineCard.h:40
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
MdtMezzanineCard::offlineTube
OfflineCh offlineTube(uint8_t tdc, MsgStream &msg) const
Definition: MdtMezzanineCard.cxx:126
ReadCellNoiseFromCool.cabling
cabling
Definition: ReadCellNoiseFromCool.py:154
skel.it
it
Definition: skel.GENtoEVGEN.py:407
MuonMDT_CablingMap::m_toOfflineConv
OnlToOffMap m_toOfflineConv
Definition: MuonMDT_CablingMap.h:169
MuonMDT_CablingMap::convert
bool convert(const CablingData &cabling_data, Identifier &id, bool check_valid=true) const
converts the cabling data into an identifier.
Definition: MuonMDT_CablingMap.cxx:44
MdtIdHelper::tubeLayer
int tubeLayer(const Identifier &id) const
Definition: MdtIdHelper.cxx:729
createCablingJSON.cabling_data
dictionary cabling_data
Definition: createCablingJSON.py:51
MuonMDT_CablingMap::m_mezzCards
MezzCardList m_mezzCards
Definition: MuonMDT_CablingMap.h:187
JetTiledMap::N
@ N
Definition: TiledEtaPhiMap.h:44
postInclude.sorter
sorter
Definition: postInclude.SortInput.py:23
MuonIdHelper::stationName
int stationName(const Identifier &id) const
Definition: MuonIdHelper.cxx:810
MdtTdcOnlSorter
Helper struct to search through the std::set if a conversion from online -> offline is needed.
Definition: MdtTdcMap.h:100
MdtMezzanineCard::NOTSET
static constexpr uint8_t NOTSET
Definition: MdtMezzanineCard.h:37
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
MdtMezzanineCard::tubeNumber
uint8_t tubeNumber(uint8_t tubeLay, uint8_t tube) const
returns the tube number
Definition: MdtMezzanineCard.cxx:122
MuonMDT_CablingMap::csmNumOnChamber
unsigned int csmNumOnChamber(const CablingData &map_data, MsgStream &log) const
Returns whether the channel belongs to the first or second mounted CSM card.
Definition: MuonMDT_CablingMap.cxx:402
MuonMDT_CablingMap::MezzCardPtr
MdtMezzanineCard::MezzCardPtr MezzCardPtr
Definition: MuonMDT_CablingMap.h:154
MdtMezzanineCard
MdtMezzanineCard - Helper struct to represent the structure of a mezzanine card in a consistent way E...
Definition: MdtMezzanineCard.h:35
MdtCablingOffData::phi
int8_t & phi
Eta of the MDT station.
Definition: MdtCablingData.h:30
MuonMDT_CablingMap::OffToOnlMap
std::map< MdtCablingOffData, MdtOffChModule > OffToOnlMap
Definition: MuonMDT_CablingMap.h:54
MuonMDT_CablingMap::m_tdcs
std::vector< std::unique_ptr< MdtTdcMap > > m_tdcs
Definition: MuonMDT_CablingMap.h:170
MuonMDT_CablingMap::getHedgeHogMapping
MezzCardPtr getHedgeHogMapping(uint8_t mezzCardId) const
Definition: MuonMDT_CablingMap.cxx:178
calibdata.valid
list valid
Definition: calibdata.py:44
MuonMDT_CablingMap::m_chamberToROB
ChamberToROBMap m_chamberToROB
map returning the RODid for a given chamber ID
Definition: MuonMDT_CablingMap.h:179
MdtCablingOffData
Split the offline part of the cabling apart to use it later for sorting.
Definition: MdtCablingData.h:16
maskDeadModules.mod
mod
Definition: maskDeadModules.py:36
MdtMezzanineCard::OfflineCh
Helper struct to pipe the result from the tdc -> offline channel translation.
Definition: MdtMezzanineCard.h:73
lumiFormat.i
int i
Definition: lumiFormat.py:85
ReadCellNoiseFromCool.chan
chan
Definition: ReadCellNoiseFromCool.py:52
MuonMDT_CablingMap.h
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
MuonMDT_CablingMap::MdtOffChModule::csm
std::array< MdtCablingOnData, 2 > csm
The up to 2 CSMs to which the cards are connected.
Definition: MuonMDT_CablingMap.h:51
jobOptions.card
card
Definition: jobOptions.GenevaPy8_Zmumu.py:11
ArrayHelper.h
MdtIdHelper::tube
int tube(const Identifier &id) const
Definition: MdtIdHelper.cxx:731
MdtIdHelper.h
MdtCablingData
Definition: MdtCablingData.h:84
RunTileMonitoring.rod
rod
Definition: RunTileMonitoring.py:134
Identifier::show
void show() const
Print out in hex form.
Definition: Identifier.cxx:30
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
MuonMDT_CablingMap::m_toOnlineConv
OffToOnlMap m_toOnlineConv
Definition: MuonMDT_CablingMap.h:168
MuonMDT_CablingMap::finalize_init
bool finalize_init(MsgStream &log)
Definition: MuonMDT_CablingMap.cxx:535
MuonIdHelper::stationPhi
int stationPhi(const Identifier &id) const
Definition: MuonIdHelper.cxx:820
MuonMDT_CablingMap::OnlToOffMap
std::map< MdtCablingOnData, MdtTdcModule > OnlToOffMap
Definition: MuonMDT_CablingMap.h:72
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
MdtCablingData::tdcId
uint8_t tdcId
Mezzanine type.
Definition: MdtCablingData.h:92
python.selection.number
number
Definition: selection.py:20
debug
const bool debug
Definition: MakeUncertaintyPlots.cxx:53
MdtCablingData::layer
int layer
Definition: MdtCablingData.h:87
MdtIdHelper::channelID
Identifier channelID(int stationName, int stationEta, int stationPhi, int multilayer, int tubeLayer, int tube) const
Definition: MdtIdHelper.cxx:664
MuonMDT_CablingMap::m_2CSM_cham
bool m_2CSM_cham
Switch to check whether the layout has chambers with 2 CSM chips.
Definition: MuonMDT_CablingMap.h:183
IdentifierHash.h
MuonMDT_CablingMap::~MuonMDT_CablingMap
~MuonMDT_CablingMap()
MuonMDT_CablingMap::getOnlineId
bool getOnlineId(CablingData &cabling_data, MsgStream &log) const
return the online id given the offline id
Definition: MuonMDT_CablingMap.cxx:317
MuonIdHelper::stationEta
int stationEta(const Identifier &id) const
Definition: MuonIdHelper.cxx:815
MdtCablingOnData::csm
uint8_t & csm
MROD number.
Definition: MdtCablingData.h:54
THROW_EXCEPTION
#define THROW_EXCEPTION(MESSAGE)
Definition: throwExcept.h:10
MuonMDT_CablingMap::getROBId
uint32_t getROBId(const IdentifierHash &stationCode, MsgStream &log) const
return the ROD id of a given chamber, given the hash id
Definition: MuonMDT_CablingMap.cxx:467
MdtCablingData::channelId
uint8_t channelId
Identifier of the corresponding tdc.
Definition: MdtCablingData.h:94
MuonMDT_CablingMap::getMultiLayerCode
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,...
Definition: MuonMDT_CablingMap.cxx:431
MuonMDT_CablingMap::getOfflineConvMap
const OffToOnlMap & getOfflineConvMap() const
Returns hte map to convert the offline -> online identifiers.
Definition: MuonMDT_CablingMap.cxx:352
MuonMDT_CablingMap::DataSource::LegacyCOOL
@ LegacyCOOL
MuonMDT_CablingMap::getAllROBId
const ListOfROB & getAllROBId() const
return the ROD id of a given chamber
Definition: MuonMDT_CablingMap.cxx:531
MdtCablingOffData::multilayer
int8_t & multilayer
Phi sector of the MDT station.
Definition: MdtCablingData.h:31
MuonMDT_CablingMap::TdcOnlSet
std::vector< MdtTdcOnlSorter > TdcOnlSet
Definition: MuonMDT_CablingMap.h:33
MdtIdHelper::elementID
Identifier elementID(int stationName, int stationEta, int stationPhi) const
Definition: MdtIdHelper.cxx:635
MuonMDT_CablingMap::m_multilayerToROB
ChamberToROBMap m_multilayerToROB
map raturning the RODid for a given multi layer ID
Definition: MuonMDT_CablingMap.h:181
MuonMDT_CablingMap::MdtOffChModule
Helper struct to group the Mezzanine cards mounted on each multilayer The object provides the followi...
Definition: MuonMDT_CablingMap.h:42
MuonMDT_CablingMap::getOnlineConvMap
const OnlToOffMap & getOnlineConvMap() const
Returns the map to convert the online -> offline identifiers.
Definition: MuonMDT_CablingMap.cxx:348
MuonMDT_CablingMap::addMezanineLayout
bool addMezanineLayout(std::unique_ptr< MdtMezzanineCard > card, MsgStream &log)
Adds a new mezzanine card mapping.
Definition: MuonMDT_CablingMap.cxx:588
python.Constants.INFO
int INFO
Definition: Control/AthenaCommon/python/Constants.py:15
MdtIdHelper::get_detectorElement_hash
virtual int get_detectorElement_hash(const Identifier &id, IdentifierHash &hash_id) const override
Definition: MdtIdHelper.cxx:331
MuonMDT_CablingMap::DataSource
DataSource
Definition: MuonMDT_CablingMap.h:91
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
MdtCablingOnData::subdetectorId
uint8_t & subdetectorId
CSM number.
Definition: MdtCablingData.h:55
MuonMDT_CablingMap::getOfflineId
bool getOfflineId(CablingData &cabling_data, MsgStream &log) const
return the offline id given the online id
Definition: MuonMDT_CablingMap.cxx:252
copySelective.source
string source
Definition: copySelective.py:31
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:13
MdtIdHelper::get_module_hash
virtual int get_module_hash(const Identifier &id, IdentifierHash &hash_id) const override
Definition: MdtIdHelper.cxx:324
Muon::nsw::STGTPSegments::moduleIDBits::stationEta
constexpr uint8_t stationEta
1 to 3
Definition: NSWSTGTPDecodeBitmaps.h:159
IdentifierHash
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
Definition: IdentifierHash.h:25
MdtIdHelper::maxNTubesPerLayer
static constexpr int maxNTubesPerLayer
The maxNTubesPerLayer represents the absolute maximum of tubes which are built into a single multilay...
Definition: MdtIdHelper.h:68
StoreGateSvc.h
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
MuonMDT_CablingMap::m_mdtIdHelper
const MdtIdHelper * m_mdtIdHelper
Pointer to the MdtIdHelper.
Definition: MuonMDT_CablingMap.h:162
calibdata.tube
tube
Definition: calibdata.py:30
MuonMDT_CablingMap::m_listOfROB
ListOfROB m_listOfROB
full list of ROBs
Definition: MuonMDT_CablingMap.h:176
MuonMDT_CablingMap::TdcOffSet
std::set< MdtTdcOffSorter, std::less<> > TdcOffSet
Definition: MuonMDT_CablingMap.h:32
MuonMDT_CablingMap::addMezzanineLine
bool addMezzanineLine(const int type, const int layer, const int sequence, MsgStream &log)
Add a new line describing a mezzanine type.
Definition: MuonMDT_CablingMap.cxx:71
MuonMDT_CablingMap::has2CsmML
bool has2CsmML() const
Returns if the cabling map has found multilayers connected to 2 CSM cards.
Definition: MuonMDT_CablingMap.cxx:428
MezzCardPtr
MuonMDT_CablingMap::MezzCardPtr MezzCardPtr
Definition: MuonMDT_CablingMap.cxx:24
Identifier
Definition: IdentifierFieldParser.cxx:14