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