ATLAS Offline Software
MuonMDT_CablingMap.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include <cmath>
8 
9 #include "GaudiKernel/ISvcLocator.h"
11 #include "CxxUtils/ArrayHelper.h"
12 #include "StoreGate/StoreGateSvc.h"
13 #include "Identifier/Identifier.h"
14 #include "GeoModelKernel/throwExcept.h"
15 
16 namespace {
20 static const std::set<uint8_t> special_cards{50, 60, 61, 71};
21 } // namespace
23 
25  // initialize the message service
26 
27  // retrieve the MdtIdHelper
28  ISvcLocator* svcLocator = Gaudi::svcLocator();
29  SmartIF<StoreGateSvc> detStore{svcLocator->service("DetectorStore")};
30  if (!detStore) {
31  THROW_EXCEPTION("Could not find the detctor store");
32  }
33  StatusCode sc = detStore->retrieve(m_mdtIdHelper, "MDTIDHELPER");
34  if (sc != StatusCode::SUCCESS) {
35  THROW_EXCEPTION("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 
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 && !mezzaType->checkConsistency(log)){
197  return false;
198  }
199  auto newTdc = std::make_unique<MdtTdcMap>(mezzaType, map_data);
200  if (debug) {
201  log << MSG::VERBOSE << " Added new readout channel " << map_data<< endmsg;
202  }
203  MdtOffChModule& offModule = m_toOnlineConv[map_data];
204  offModule.cards.emplace(newTdc.get());
205  if (!offModule.csm[0]) {
206  offModule.csm[0] = map_data;
207  if (debug){
208  log<< MSG::VERBOSE<<"Assign first CSM "<<map_data<<endmsg;
209  }
211  if (map_data.multilayer == 1) {
212  CablingData secondMl = map_data;
213  secondMl.multilayer = 2;
214  MdtOffChModule& secondModule{m_toOnlineConv[secondMl]};
215  if (!secondModule.csm[0]){
216  secondModule.csm[0] = map_data;
217  } else if (secondModule.csm[0] != map_data && !secondModule.csm[1]) {
218  secondModule.csm[1] = map_data;
219  std::swap(secondModule.csm[1], secondModule.csm[0]);
220  }
221  }
222  } else if (offModule.csm[0] != map_data) {
223  if (!offModule.csm[1]) {
224  offModule.csm[1] = map_data;
225  if (debug) {
226  log << MSG::VERBOSE << " Add second CSM for " << map_data << endmsg;
227  }
228  } else if (offModule.csm[1] != map_data) {
229  log << MSG::ERROR << "The mulit layer " << map_data
230  << " has already associated the CSMs " << std::endl
231  << " *** " << offModule.csm[0] << std::endl
232  << " *** " << offModule.csm[1] << std::endl
233  << ", while this one is a third one and not supported"
234  << endmsg;
235  return false;
236  }
237  }
238  TdcOnlSet& attachedTdcs = m_toOfflineConv[map_data].all_modules;
239  if (attachedTdcs.size() <= map_data.tdcId)
240  attachedTdcs.resize(map_data.tdcId + 1);
241  attachedTdcs[map_data.tdcId] = MdtTdcOnlSorter{newTdc.get()};
242  m_tdcs.push_back(std::move(newTdc));
243 
244  if (!addChamberToROBMap(map_data, log) && debug) {
245  log << MSG::VERBOSE << "Station already in the map !" << endmsg;
246  }
247 
248  return true;
249 }
251  MsgStream& log) const {
252  OnlToOffMap::const_iterator module_itr = m_toOfflineConv.find(cabling_map);
253  if (module_itr == m_toOfflineConv.end()) {
254  log << MSG::WARNING
255  << "Could not find a cabling module to recieve offline Id for "
256  << cabling_map << endmsg;
257  return false;
258  }
260  if (cabling_map.tdcId == 0xff && cabling_map.channelId == 0xff) {
261  cabling_map.channelId = 0;
262  if (!module_itr->second.zero_module) {
263  log << MSG::WARNING << " No tdc with channel zero found for "
264  << module_itr->first << endmsg;
265  return false;
266  }
267  if (!module_itr->second.zero_module->offlineId(cabling_map, log)) {
268  log << MSG::WARNING << "MdtTdMap::getOfflineId() -- Channel: "
269  << static_cast<unsigned>(cabling_map.channelId)
270  << " Tdc: " << static_cast<unsigned>(cabling_map.tdcId)
271  << " not found in "
272  << static_cast<const MdtCablingOnData&>(cabling_map) << endmsg;
273  return false;
274  }
275  } else {
276  const TdcOnlSet& attachedTdcs = module_itr->second.all_modules;
277  if (attachedTdcs.size() <= cabling_map.tdcId) {
278  log << MSG::WARNING << "getOfflineId() -- Tdc: "
279  << static_cast<unsigned>(cabling_map.tdcId)
280  << " is not part of " << module_itr->first << ". Maximally "
281  << attachedTdcs.size() << " Tdcs were attached. " << endmsg;
282  return false;
283  }
284  const MdtTdcOnlSorter& TdcItr = attachedTdcs.at(cabling_map.tdcId);
285  if (!TdcItr) {
286  log << MSG::WARNING << "getOfflineId() -- Tdc: "
287  << static_cast<unsigned>(cabling_map.tdcId) << " not found in "
288  << static_cast<const MdtCablingOnData&>(cabling_map) << endmsg;
289  return false;
290  }
291  if (!TdcItr->offlineId(cabling_map, log)) {
292  log << MSG::WARNING << "MdtTdMap::getOfflineId() -- channel: "
293  << static_cast<unsigned>(cabling_map.channelId)
294  << " Tdc: " << static_cast<unsigned>(cabling_map.tdcId)
295  << " not found in "
296  << static_cast<const MdtCablingOnData&>(cabling_map) << endmsg;
297  return false;
298  }
299  }
300  if (log.level() <= MSG::VERBOSE) {
301  log << MSG::VERBOSE
302  << "Channel: " << static_cast<unsigned>(cabling_map.channelId)
303  << " Tdc: " << static_cast<unsigned>(cabling_map.tdcId) << " "
304  << static_cast<const MdtCablingOnData&>(cabling_map) << endmsg;
305 
306  log << MSG::VERBOSE << "Mapped to "
307  << static_cast<const MdtCablingOffData&>(cabling_map)
308  << " layer: " << cabling_map.layer << " tube: " << cabling_map.tube
309  << endmsg;
310  }
311  return true;
312 }
313 
316  MsgStream& log) const {
317  OffToOnlMap::const_iterator module_itr = m_toOnlineConv.find(cabling_map);
318  if (module_itr == m_toOnlineConv.end()) {
319  log << MSG::WARNING
320  << "getOnlineId() --- Could not find a cabling CSM set recieve "
321  "online Id for "
322  << static_cast<MdtCablingOffData&>(cabling_map) << endmsg;
323  return false;
324  }
325  const TdcOffSet& attachedTdcs = module_itr->second.cards;
326  TdcOffSet::const_iterator tdc_itr = attachedTdcs.find(cabling_map);
327  if (tdc_itr == attachedTdcs.end()) {
328  log << MSG::WARNING << "No matching Tdc channel was found for "
329  << cabling_map << endmsg;
330  } else if ((*tdc_itr)->onlineId(cabling_map, log))
331  return true;
333  TdcOffSet::const_iterator control_itr =
334  std::find_if(attachedTdcs.begin(), attachedTdcs.end(),
335  [&cabling_map, &log](const MdtTdcOffSorter& tdc) {
336  return tdc->onlineId(cabling_map, log);
337  });
338  if (control_itr == attachedTdcs.end()) {
339  log << MSG::WARNING
340  << "Second trial to find a valid cabling channel for "
341  << cabling_map << " failed as well. " << endmsg;
342  return false;
343  }
344  return true;
345 }
347  const {
348  return m_toOfflineConv;
349 }
351  const {
352  return m_toOnlineConv;
353 }
354 
356  MsgStream& log) {
357  bool debug = (log.level() <= MSG::VERBOSE);
358  IdentifierHash chamberId, multiLayerId{0};
359  Identifier ml{0};
360  if (!getStationCode(map_data, chamberId, log)) {
361  log << MSG::ERROR << "Could not find hashId for station: " << map_data
362  << endmsg;
363  return false;
364  }
365  if (!getMultiLayerCode(map_data, ml, multiLayerId, log)) {
366  log << MSG::ERROR << "Could not find hashId for multi layer: " << map_data << endmsg;
367  return false;
368  }
369  int sub = map_data.subdetectorId;
370  int rod = map_data.mrod;
371 
372  uint32_t hardId = (sub << 16) | rod;
373  if (debug) {
374  log << MSG::VERBOSE << "Adding the chamber with Id: " << chamberId
375  << " and subdetector+rod ID: " << hardId << endmsg;
376  }
377 
378  // check if the chamber has already been put into the map
379  ChamberToROBMap::const_iterator it = m_multilayerToROB.find(multiLayerId);
380  if (it != m_multilayerToROB.end()) {
381  return false;
382  }
383  m_multilayerToROB.insert(std::make_pair(multiLayerId, hardId));
384  m_chamberToROB.insert(std::make_pair(chamberId, hardId));
385  // new function to do the opposite of the above
386  m_ROBToMultiLayer[hardId].push_back(multiLayerId);
387  // now check if the ROB is already in the list of ROB vector
388  const bool robInitialized =
389  std::find(m_listOfROB.begin(), m_listOfROB.end(), hardId) !=
390  m_listOfROB.end();
391  if (!robInitialized) {
392  if (debug) {
393  log << MSG::VERBOSE << "Adding the ROB " << hardId << " to the list"
394  << endmsg;
395  }
396  m_listOfROB.push_back(hardId);
397  }
398  return true;
399 }
401  MsgStream& log) const {
403  OffToOnlMap::const_iterator off_itr = m_toOnlineConv.find(map_data);
404  if (off_itr == m_toOnlineConv.end()) {
405  log << MSG::ERROR << "csmNumOnChamber() -- Nothing is saved under "
406  << map_data << endmsg;
407  return 0;
408  }
409  return (1 * (off_itr->second.csm[0] == map_data)) +
410  (2 * (off_itr->second.csm[1] == map_data));
411 }
413  IdentifierHash& mdtHashId,
414  MsgStream& log) const {
415  const Identifier elementId = m_mdtIdHelper->elementID(
416  map_data.stationIndex, map_data.eta, map_data.phi);
417  if (m_mdtIdHelper->get_module_hash(elementId, mdtHashId)) {
418  log << MSG::ERROR
419  << "getstationCode() -- Could not find HashId for module: "
420  << map_data << endmsg;
421  elementId.show();
422  return false;
423  }
424  return true;
425 }
427  return m_2CSM_cham;
428 }
430  Identifier& elementId,
431  IdentifierHash& mdtHashId,
432  MsgStream& log) const {
433  const unsigned int ml = m_2CSM_cham ? csmNumOnChamber(map_data, log) : 1;
434  if (!ml) {
435  log << MSG::ERROR
436  << "getMultiLayerCode() -- Could not determine the detector layer "
437  << map_data << endmsg;
438  return false;
439  }
441  elementId = m_mdtIdHelper->channelID(map_data.stationIndex, map_data.eta,
442  map_data.phi, ml, 1, 1);
445  if (m_2CSM_cham &&
446  m_mdtIdHelper->get_detectorElement_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  }
455  else if (!m_2CSM_cham &&
456  m_mdtIdHelper->get_module_hash(elementId, mdtHashId)) {
457  log << MSG::ERROR
458  << "getMultiLayerCode() -- Could not find HashId for module: "
459  << map_data << endmsg;
460  elementId.show();
461  return false;
462  }
463  return true;
464 }
466  MsgStream& log) const {
467  ChamberToROBMap::const_iterator it = m_chamberToROB.find(stationCode);
468  if (it != m_chamberToROB.end()) {
469  return it->second;
470  }
471  log << MSG::WARNING << "ROB ID " << stationCode << " not found !" << endmsg;
472  return 0;
473 }
474 // get the robs corresponding to a vector of hashIds, copied from Svc before the
475 // readCdo migration
476 std::vector<uint32_t> MuonMDT_CablingMap::getROBId(
477  const std::vector<IdentifierHash>& mdtHashVector, MsgStream& log) const {
478  std::vector<uint32_t> robVector;
479  bool debug = (log.level() <= MSG::VERBOSE);
480  for (unsigned int i = 0; i < mdtHashVector.size(); ++i) {
481  int robId = getROBId(mdtHashVector[i], log);
482  if (!robId) {
483  log << MSG::ERROR
484  << "ROB id not found for Hash Id: " << mdtHashVector[i]
485  << endmsg;
486  } else if (debug) {
487  log << MSG::VERBOSE << "Found ROB id " << robId << " for hashId "
488  << mdtHashVector[i] << endmsg;
489  }
490  robVector.push_back(robId);
491  }
492  if (debug) {
493  log << MSG::VERBOSE << "Size of ROB vector is: " << robVector.size()
494  << endmsg;
495  }
496  return robVector;
497 }
498 
499 const std::vector<IdentifierHash>& MuonMDT_CablingMap::getMultiLayerHashVec(
500  const uint32_t ROBId, MsgStream& log) const {
501  ROBToChamberMap::const_iterator Rob_it = m_ROBToMultiLayer.find(ROBId);
502  if (Rob_it != m_ROBToMultiLayer.end()) {
503  return Rob_it->second;
504  }
505 
506  log << MSG::WARNING << "Rod ID not found !" << endmsg;
507  static const std::vector<IdentifierHash> emptyIdHashVec{};
508  return emptyIdHashVec;
509 }
510 
511 std::vector<IdentifierHash> MuonMDT_CablingMap::getMultiLayerHashVec(
512  const std::vector<uint32_t>& ROBId_list, MsgStream& log) const {
513  std::vector<IdentifierHash> HashVec;
514  for (unsigned int i = 0; i < ROBId_list.size(); ++i) {
515  ROBToChamberMap::const_iterator Rob_it =
516  m_ROBToMultiLayer.find(ROBId_list[i]);
517  if (Rob_it == m_ROBToMultiLayer.end()) {
518  log << MSG::WARNING << "Rod ID " << ROBId_list[i]
519  << " not found, continuing with the rest of the ROBId"
520  << endmsg;
521  continue;
522  }
523  HashVec.insert(HashVec.end(), Rob_it->second.begin(),
524  Rob_it->second.end());
525  }
526  return HashVec;
527 }
528 
530  return m_listOfROB;
531 }
532 
534  if (m_tdcs.empty()) {
535  log << MSG::ERROR << "No tdc maps were loaded " << endmsg;
536  return false;
537  }
538  for (const MezzCardPtr& card : m_mezzCards) {
539  if (!card->checkConsistency(log))
540  return false;
541  }
542 
543  const unsigned int offToOnlChan =
545  [](unsigned int N, const auto& map) {
546  return N + map.second.cards.size();
547  });
548  const unsigned int onlToOffChan = std::accumulate(
549  m_toOfflineConv.begin(), m_toOfflineConv.end(), 0,
550  [](unsigned int N, const auto& map) {
551  return N + std::accumulate(map.second.begin(), map.second.end(), 0,
552  [](unsigned int M, const auto& tdc) {
553  return M + tdc;
554  });
555  });
556 
557  if (offToOnlChan != onlToOffChan || onlToOffChan != m_tdcs.size()) {
558  log << MSG::ERROR
559  << "Offline <-> online conversion channels were lost. Expect "
560  << m_tdcs.size()
561  << " cabling channels. Counted Offline -> online channels "
562  << offToOnlChan << ". Conted Online -> offline channels "
563  << onlToOffChan << endmsg;
564  return false;
565  }
566  for (auto& toOff : m_toOfflineConv) {
567  MdtTdcModule& mod = toOff.second;
568  TdcOnlSet::const_iterator itr = std::find_if(
569  mod.begin(), mod.end(), [](const MdtTdcOnlSorter& sorter) {
570  return sorter && sorter->tdcZero() == 0;
571  });
572  if (itr == mod.end()) {
573  log << MSG::ERROR << "There is no tdc with channel 0 in "
574  << toOff.first
575  << ". That is important to decode the station names later"
576  << endmsg;
577  return false;
578  }
579  mod.zero_module = (*itr);
580  }
581  m_mezzCards.clear();
582  log << MSG::INFO << "MdtCabling successfully loaded. Found in total "
583  << m_tdcs.size() << " channels." << endmsg;
584  return true;
585 }
587  std::unique_ptr<MdtMezzanineCard> card, MsgStream& log) {
588  if (!card->checkConsistency(log))
589  return false;
590  MezzCardList::const_iterator itr =
591  std::find_if(m_mezzCards.begin(), m_mezzCards.end(),
592  [&card](const MezzCardPtr& existing) {
593  return existing->id() == card->id();
594  });
595  if (itr != m_mezzCards.end()) {
596  log << MSG::ERROR << "Mezzanine card " << std::endl
597  << (*card) << " has already been added " << std::endl
598  << (**itr) << std::endl
599  << " please check. " << endmsg;
600  return false;
601  }
602  m_mezzCards.push_back(std::move(card));
603  return true;
604 }
606  MsgStream& msg) const {
607  using MezzMapping = MdtMezzanineCard::Mapping;
608  MezzMapping chMap{make_array<uint8_t, 24>(MdtMezzanineCard::NOTSET)};
609 
610  const int mezzType = cabling.mezzanine_type;
611  const int chanZero = cabling.channelId;
612  const int layerZero = cabling.layer;
613  const int tubeZero = cabling.tube;
614 
616  const bool debug = msg.level() <= MSG::VERBOSE;
617 
618  if (special_cards.count(mezzType)) {
619  const MdtMezzanineCard dummy_card(chMap, 4, mezzType);
620  if (debug)
621  msg << MSG::VERBOSE
622  << "legacyHedgehogCard() -- Special layout given " << mezzType
623  << endmsg;
624  for (size_t chan = 0; chan < chMap.size(); ++chan) {
625  uint8_t tube_chan = ((chan - chan % 4) / 4);
628  if (mezzType == 71) {
629  tube_chan = 5 - tube_chan;
630  }
631  int layer{0}, tube{0};
632  // special case of the BME of end 2013 and BMG 2017
633  /*
634  * cases 50 and 60 follow the same rules. hedgehog card 50 is the
635  * mirror image of card 60, but the rules concerning how to decode
636  * the tube mapping are the same. channel 0 of a mezzanine card for
637  * case 50 is either top right or bottom left, while for case 60 it
638  * is top left or bottom right. Another thing to keep in mind for
639  * BMG is, that tube counting in some cases is along |z|, while in
640  * some other cases it is opposite.
641  *
642  * E.g: Numbering from top to bottom -> Tube counting along z
643  *
644  * Layer | Tube number
645  * 4 | 0 4 8 12 16 20
646  * 3 | 1 5 9 13 17 21
647  * 2 | 2 6 10 14 18 22
648  * 1 | 3 7 11 15 19 23
649  */
650  if (mezzType == 50 || mezzType == 60 || mezzType == 61) {
652  if (layerZero == 1) {
653  layer = chan % 4 + 1;
654  }
655  // Tube numbering is from top to bottom
656  else {
657  layer = 4 - chan % 4;
658  }
659  if ((tubeZero - 1) % 6 == 0) {
660  tube = tubeZero + tube_chan;
661  } else {
662  tube = tubeZero - tube_chan;
663  }
664  }
665  /* Few mezzanine cards in the BIS78 chambers are collateral vicitms
666  * of the famous regional customs happening in the Bavarian autumun.
667  * The tube staggering is kind of discontinous where the upper two
668  * layers are swapped with the bottom two 1 5 9 13 17
669  * 21 0 4 8 12 16 20 3 7 11 15 19
670  * 23 2 6 10 14 18 22
671  */
672  else if (mezzType == 71) {
673  layer = (chan % 4);
674  layer += 2 * (layer > 1 ? -1 : +1) + 1;
675  tube = tubeZero - tube_chan;
676  }
677  cabling.tube = std::min(cabling.tube, tube);
678  chMap[chan] = dummy_card.tubeNumber(layer, tube);
679  if (debug)
680  msg << MSG::VERBOSE << "legacyHedgehogCard() -- Channel "
681  << chan << " mapped to " << layer << ", " << tube << endmsg;
682  }
683  return std::make_unique<MdtMezzanineCard>(chMap, 4, mezzType);
684  }
686  MezzCardPtr card = getHedgeHogMapping(mezzType);
687  if (!card)
688  return nullptr;
689  if (debug)
690  msg << MSG::VERBOSE << "Assign local tube mapping from " << (*card)
691  << std::endl
692  << "to connect " << cabling << " tubeZero: " << tubeZero << endmsg;
693  const int stationName = cabling.stationIndex;
694  const int stationEta = std::abs(cabling.eta);
695 
696  for (size_t chan = 0; chan < chMap.size(); ++chan) {
697  // calculate the layer
698  int layer{0}, tube{0};
699  if (layerZero == 1) {
700  layer = chan / (card->numTubesPerLayer()) + 1;
701  } else {
702  layer = layerZero - chan / (card->numTubesPerLayer());
703  }
704 
705  // calculate the tube in layer
706  uint8_t localchan = chan % (card->numTubesPerLayer());
707 
708  // special case of the BIR with 3 tubes overlapping to another mezzanine
709  if ((chanZero == 5 && stationName == 7 && stationEta == 3) &&
710  ((card->id() > 40 && localchan % 2 == 0) ||
711  (card->id() < 40 && localchan < 3)))
712  continue;
713 
714  using OfflineCh = MdtMezzanineCard::OfflineCh;
715  OfflineCh locTubeLay = card->offlineTube(
716  localchan + (layer - 1) * card->numTubesPerLayer(), msg);
717  OfflineCh zeroTubeLay = card->offlineTube(
718  chanZero + (layer - 1) * card->numTubesPerLayer(), msg);
719  if (!locTubeLay.isValid || !zeroTubeLay.isValid)
720  continue;
721 
722  tube = (static_cast<int>(locTubeLay.tube) -
723  static_cast<int>(zeroTubeLay.tube) + tubeZero);
724 
725  if (debug)
726  msg << MSG::VERBOSE << "legacyHedgehogCard() -- Channel " << chan
727  << " mapped to " << layer << ", " << tube
728  << " locTube: " << static_cast<int>(locTubeLay.tube)
729  << " zeroTubeLay: " << static_cast<int>(zeroTubeLay.tube)
730  << endmsg;
731 
732  if (tube < 1 || tube >= MdtIdHelper::maxNTubesPerLayer)
733  continue;
734  cabling.tube = std::min(cabling.tube, tube);
735  chMap[chan] = card->tubeNumber(layer, tube);
736  }
737  std::unique_ptr<MdtMezzanineCard> to_ret =
738  std::make_unique<MdtMezzanineCard>(chMap, card->numTubeLayers(),
739  mezzType);
740  const uint8_t tubeZeroOff = (cabling.tube - 1) % to_ret->numTubesPerLayer();
741  if (!tubeZeroOff)
742  return to_ret;
743  chMap = make_array<uint8_t, 24>(MdtMezzanineCard::NOTSET);
744  for (size_t chan = 0; chan < chMap.size(); ++chan) {
745  using OfflineCh = MdtMezzanineCard::OfflineCh;
746  OfflineCh tube_lay = to_ret->offlineTube(chan, msg);
747  if (!tube_lay.isValid)
748  continue;
749  uint8_t tubeNumber = tube_lay.tube + tubeZeroOff + 1;
750  chMap[chan] = card->tubeNumber(tube_lay.layer, tubeNumber);
751  }
752  if (debug)
753  msg << MSG::VERBOSE << "Final mapping " << cabling << endmsg;
754 
755  return std::make_unique<MdtMezzanineCard>(chMap, card->numTubeLayers(),
756  mezzType);
757 }
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:842
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:412
MuonMDT_CablingMap::MuonMDT_CablingMap
MuonMDT_CablingMap()
Definition: MuonMDT_CablingMap.cxx:24
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:511
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:605
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:557
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
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:355
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:78
MuonIdHelper::is_mdt
bool is_mdt(const Identifier &id) const
Definition: MuonIdHelper.cxx:782
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
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
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:396
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:42
MdtIdHelper::tubeLayer
int tubeLayer(const Identifier &id) const
Definition: MdtIdHelper.cxx:724
createCablingJSON.cabling_data
dictionary cabling_data
Definition: createCablingJSON.py:46
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:800
MdtTdcOnlSorter
Helper struct to search through the std::set if a conversion from online -> offline is needed.
Definition: MdtTdcMap.h:100
THROW_EXCEPTION
#define THROW_EXCEPTION(MSG)
Definition: MMReadoutElement.cxx:48
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:400
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: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: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:176
calibdata.valid
list valid
Definition: calibdata.py:45
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:72
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: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: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:533
MuonIdHelper::stationPhi
int stationPhi(const Identifier &id) const
Definition: MuonIdHelper.cxx:810
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: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:183
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:315
MuonIdHelper::stationEta
int stationEta(const Identifier &id) const
Definition: MuonIdHelper.cxx:805
MdtCablingOnData::csm
uint8_t & csm
MROD number.
Definition: MdtCablingData.h:53
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:465
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:429
MuonMDT_CablingMap::getOfflineConvMap
const OffToOnlMap & getOfflineConvMap() const
Returns hte map to convert the offline -> online identifiers.
Definition: MuonMDT_CablingMap.cxx:350
MuonMDT_CablingMap::DataSource::LegacyCOOL
@ LegacyCOOL
MuonMDT_CablingMap::getAllROBId
const ListOfROB & getAllROBId() const
return the ROD id of a given chamber
Definition: MuonMDT_CablingMap.cxx:529
MdtCablingOffData::multilayer
int8_t & multilayer
Phi sector of the MDT station.
Definition: MdtCablingData.h:30
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:630
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:346
MuonMDT_CablingMap::addMezanineLayout
bool addMezanineLayout(std::unique_ptr< MdtMezzanineCard > card, MsgStream &log)
Adds a new mezzanine card mapping.
Definition: MuonMDT_CablingMap.cxx:586
MdtIdHelper::get_detectorElement_hash
virtual int get_detectorElement_hash(const Identifier &id, IdentifierHash &hash_id) const override
Definition: MdtIdHelper.cxx:326
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
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:54
MuonMDT_CablingMap::getOfflineId
bool getOfflineId(CablingData &cabling_data, MsgStream &log) const
return the offline id given the online id
Definition: MuonMDT_CablingMap.cxx:250
copySelective.source
string source
Definition: copySelective.py:32
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:319
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:31
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:69
MuonMDT_CablingMap::has2CsmML
bool has2CsmML() const
Returns if the cabling map has found multilayers connected to 2 CSM cards.
Definition: MuonMDT_CablingMap.cxx:426
MezzCardPtr
MuonMDT_CablingMap::MezzCardPtr MezzCardPtr
Definition: MuonMDT_CablingMap.cxx:22
Identifier
Definition: IdentifierFieldParser.cxx:14