ATLAS Offline Software
MdtCablingJsonDumpAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
7 #include "CxxUtils/ArrayHelper.h"
9 #include <fstream>
10 
11 namespace {
12  struct TdcIdentifier: public MdtCablingOnData {
13  uint8_t tdcId{0};
15  bool operator==(const TdcIdentifier& other) const noexcept{
16  return this->MdtCablingOnData::operator==(other) && tdcId == other.tdcId;
17  }
18  bool operator<(const TdcIdentifier& other) const noexcept {
19  if (this->MdtCablingOnData::operator!=(other)) return this->MdtCablingOnData::operator<(other);
20  return tdcId < other.tdcId;
21  }
22  TdcIdentifier(const MdtCablingData& cabling):
24  tdcId{cabling.tdcId} {}
25  };
26 
27  using Mapping = MdtMezzanineCard::Mapping;
28  using OfflineCh = MdtMezzanineCard::OfflineCh;
29 
30 }
31 
32 MdtCablingJsonDumpAlg::MdtCablingJsonDumpAlg(const std::string& name, ISvcLocator* pSvcLocator):
33  AthAlgorithm(name,pSvcLocator) {}
34 
35 
37  ATH_CHECK(m_idHelperSvc.retrieve());
40  return StatusCode::SUCCESS;
41 }
42 
44  const EventContext& ctx = Gaudi::Hive::currentContext();
45  ATH_MSG_INFO("Dump cabling & mezzanines into JSON file");
46 
48  if (!detectorMgr.isValid()){
49  ATH_MSG_FATAL("Failed to retrieve the Detector manager "<<m_DetectorManagerKey.fullKey());
50  return StatusCode::FAILURE;
51  }
52 
54  if (!cabling.isValid()) {
55  ATH_MSG_ERROR("Failed to retrieve the Mdt cabling "<<m_cablingKey.fullKey());
56  return StatusCode::FAILURE;
57  }
58  const MdtIdHelper& idHelper = m_idHelperSvc->mdtIdHelper();
59 
60  std::vector<MdtMezzanineCard> cached_cards{};
61  std::set<MdtCablingData> cached_chnls{};
62  constexpr auto unsetArray{make_array<uint8_t,24>(MdtMezzanineCard::NOTSET)};
63  for (auto det_itr = idHelper.detectorElement_begin(); det_itr != idHelper.detectorElement_end(); ++det_itr){
64  const MuonGM::MdtReadoutElement* readEle = detectorMgr->getMdtReadoutElement(*det_itr);
65  if (!readEle) {
66  ATH_MSG_DEBUG("Detector element does not exist. ");
67  continue;
68  }
69  const Identifier station_id = idHelper.elementID(readEle->identify());
70  ATH_MSG_DEBUG("Check station "<<m_idHelperSvc->toString(station_id));
72  MdtMezzanineCard dummy_card(Mapping{}, readEle->getNLayers(), -1);
73  std::map<TdcIdentifier, Mapping> chamber_mezz{};
74  const int nLayers{readEle->getNLayers()};
75  const int nTubes{readEle->getNtubesperlayer()};
76  const int multiLayer{readEle->getMultilayer()};
77  for (int layer = 1 ; layer <= nLayers; ++layer){
78  for (int tubeInLayer = 1 ; tubeInLayer <= nTubes; ++tubeInLayer) {
79  bool is_valid{false};
80  const Identifier tube_id = idHelper.channelID(station_id, multiLayer,
81  layer, tubeInLayer, is_valid);
82  if (!is_valid) {
83  ATH_MSG_VERBOSE("Invalid element");
84  continue;
85  }
88  cabling->convert(tube_id,cabling_data);
90  if (!cabling->getOnlineId(cabling_data, msgStream())) {
91  ATH_MSG_ERROR("Could no retrieve a valid online channel for "<<m_idHelperSvc->toString(tube_id));
92  return StatusCode::FAILURE;
93  }
94  const TdcIdentifier tdc_id{cabling_data};
95  chamber_mezz.try_emplace(tdc_id,unsetArray);
96  chamber_mezz[tdc_id][cabling_data.channelId] = dummy_card.tubeNumber(layer, tubeInLayer);
97  }
98  }
100  for (auto&[tdc, mezz_mapping] : chamber_mezz) {
101  MdtCablingData mezzCablingId{};
102 
104  static_cast<MdtCablingOnData&>(mezzCablingId) = tdc;
105  mezzCablingId.tdcId = tdc.tdcId;
106 
107  MdtTdcOnlSorter chipInCab = cabling->getOnlineConvMap().at(tdc).all_modules.at(tdc.tdcId);
109  static_cast<MdtCablingOffData&>(mezzCablingId) = chipInCab->offId();
111  mezzCablingId.tube = chipInCab->tubeZero();
112 
113  const uint8_t tubeOffSet = (mezzCablingId.tube-1)%dummy_card.numTubesPerLayer();
116  if (tubeOffSet) {
117  MdtMezzanineCard remap{mezz_mapping, dummy_card.numTubeLayers(), 0};
118  for (size_t chan = 0 ; chan < mezz_mapping.size(); ++chan) {
119  const OfflineCh tube_lay = remap.offlineTube(chan, msgStream());
120  if (!tube_lay.isValid) continue;
121  uint8_t tubeNumber = tube_lay.tube + tubeOffSet + 1;
122  mezz_mapping[chan] = remap.tubeNumber(tube_lay.layer, tubeNumber);
123  }
124  }
126  Mapping& mtmp = mezz_mapping; // Work around clang15 compilation error.
127  std::vector<MdtMezzanineCard>::const_iterator itr = std::find_if(cached_cards.begin(), cached_cards.end(),
128  [&dummy_card, &mtmp](const MdtMezzanineCard& card ){
129  if (dummy_card.numTubeLayers() != card.numTubeLayers()) return false;
130  for (size_t ch =0; ch < mtmp.size(); ++ch) {
131  if (mtmp[ch] != card.tdcToTubeMap()[ch]) return false;
132  }
133  return true;
134  });
135  if (itr != cached_cards.end()) {
136  mezzCablingId.mezzanine_type = itr->id();
137  } else {
138  cached_cards.emplace_back(mezz_mapping, dummy_card.numTubeLayers(), cached_cards.size() + 10);
139  if (!cached_cards.back().checkConsistency(msgStream())) {
140  ATH_MSG_ERROR("Wrong assignment for "<<mezzCablingId);
141  return StatusCode::FAILURE;
142  }
143  mezzCablingId.mezzanine_type = cached_cards.back().id();
144  }
145  cached_chnls.insert(std::move(mezzCablingId));
146  }
147 
148 
149 
150  }
152  {
153  std::ofstream summary{m_summaryTxt};
154  if (!summary.good()) {
155  ATH_MSG_ERROR("Failed to write "<<m_summaryTxt);
156  return StatusCode::FAILURE;
157  }
158  summary<<"Extracted "<<cached_cards.size()<<" mezzanine card layouts and "
159  <<cached_chnls.size()<<" chamber channels. \n\n\n";
160  for (const MdtMezzanineCard& card : cached_cards) {
161  summary<<card;
162  MdtCablingOffData chamb{};
163  for (const MdtCablingData& cabling : cached_chnls) {
164  if (cabling.mezzanine_type != card.id()) continue;
165  if (chamb != cabling) {
166  chamb = cabling;
167  summary<<std::endl<<" *** "<<idHelper.stationNameString(chamb.stationIndex);
168  summary<<static_cast<int>(std::abs(chamb.eta));
169  summary<<(chamb.eta > 0 ? "A" : "C");
170  summary<<static_cast<int>(chamb.phi);
171  summary<<"M"<<static_cast<int>(chamb.multilayer);
172  summary<<" --- tdcs: ";
173  }
174  summary<<static_cast<int>(cabling.tdcId)<<", ";
175  }
176  summary<<"\n\n"
177  <<"##############################################################\n";
178  }
179  }
181  {
182  std::ofstream mezz_json{m_mezzJSON};
183  if (!mezz_json.good()) {
184  ATH_MSG_ERROR("Failed to write "<<m_summaryTxt);
185  return StatusCode::FAILURE;
186  }
187  mezz_json<<"["<<std::endl;
188  for (size_t i = 0; i < cached_cards.size() ; ++i) {
189  const MdtMezzanineCard& card = cached_cards[i];
190  mezz_json<<" {\n";
191  mezz_json<<" \"mezzId\": "<<static_cast<int>(card.id())<<",\n";
192  mezz_json<<" \"nTubeLayer\": "<<static_cast<int>(card.numTubeLayers())<<",\n";
193  mezz_json<<" \"tdcToTubeMap\": [";
194  for (size_t ch = 0 ; ch < card.tdcToTubeMap().size(); ++ch) {
195  mezz_json<<static_cast<int>(card.tdcToTubeMap()[ch]);
196  if (ch + 1 != card.tdcToTubeMap().size())mezz_json<<",";
197  }
198  mezz_json<<"]\n";
199  mezz_json<<" }";
200  if (i +1 != cached_cards.size()) mezz_json<<",";
201  mezz_json<<"\n";
202  }
203  mezz_json<<"]";
204  }
205  {
206  std::ofstream chamb_json{m_cablingJSON};
207  if (!chamb_json.good()) {
208  ATH_MSG_FATAL("Failed to write "<<m_cablingJSON);
209  return StatusCode::FAILURE;
210  }
211  chamb_json<<"[\n";
212  size_t i =0;
213  for (const MdtCablingData& chamb : cached_chnls){
214  chamb_json<<" {\n";
215  chamb_json<<" \"station\": \""<<idHelper.stationNameString(chamb.stationIndex)<<"\",\n";
216  chamb_json<<" \"eta\": "<<static_cast<int>(chamb.eta)<<",\n";
217  chamb_json<<" \"phi\": "<<static_cast<int>(chamb.phi)<<",\n";
218  chamb_json<<" \"ml\": "<<static_cast<int>(chamb.multilayer)<<",\n";
219  chamb_json<<" \"subDet\": "<<static_cast<int>(chamb.subdetectorId)<<",\n";
220  chamb_json<<" \"csm\": "<<static_cast<int>(chamb.csm)<<",\n";
221  chamb_json<<" \"mrod\": "<<static_cast<int>(chamb.mrod)<<",\n";
222  chamb_json<<" \"tdcId\": "<<static_cast<int>(chamb.tdcId)<<",\n";
223  chamb_json<<" \"mezzId\": "<<static_cast<int>(chamb.mezzanine_type)<<",\n";
224  chamb_json<<" \"tubeZero\": "<<static_cast<int>(chamb.tube)<<"\n";
225  chamb_json<<" }";
226  if (i +1 != cached_chnls.size()) chamb_json<<",";
227  chamb_json<<"\n";
228  ++i;
229  }
230  chamb_json<<"]"<<std::endl;
231  }
232 
233 
234  return StatusCode::SUCCESS;
235 }
MdtCablingOnData::operator<
bool operator<(const MdtCablingOnData &other) const
Definition: MdtCablingData.h:71
MdtMezzanineCard.h
MdtCablingJsonDumpAlg::MdtCablingJsonDumpAlg
MdtCablingJsonDumpAlg(const std::string &name, ISvcLocator *pSvcLocator)
Definition: MdtCablingJsonDumpAlg.cxx:32
MdtReadoutElement.h
MuonGM::MdtReadoutElement::getNLayers
int getNLayers() const
Returns the number of tube layers inside the multilayer.
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
sendEI_SPB.ch
ch
Definition: sendEI_SPB.py:35
MuonIdHelper::detectorElement_begin
const_id_iterator detectorElement_begin() const
Iterators over full set of ids.
Definition: MuonIdHelper.cxx:758
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:557
MdtCablingOnData
Definition: MdtCablingData.h:50
MdtMezzanineCard::numTubesPerLayer
uint8_t numTubesPerLayer() const
returns the number of tubes per layer;
Definition: MdtMezzanineCard.h:68
MdtMezzanineCard::Mapping
std::array< uint8_t, 24 > Mapping
Definition: MdtMezzanineCard.h:39
ReadCellNoiseFromCool.cabling
cabling
Definition: ReadCellNoiseFromCool.py:154
MdtMezzanineCard::numTubeLayers
uint8_t numTubeLayers() const
returns the number of layers
Definition: MdtMezzanineCard.h:66
MdtCablingJsonDumpAlg::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: MdtCablingJsonDumpAlg.h:32
createCablingJSON.cabling_data
dictionary cabling_data
Definition: createCablingJSON.py:46
MuonIdHelper::detectorElement_end
const_id_iterator detectorElement_end() const
Definition: MuonIdHelper.cxx:760
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
MdtCablingOnData::operator==
bool operator==(const MdtCablingOnData &other) const
Definition: MdtCablingData.h:65
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
ReadCondHandle.h
MdtMezzanineCard::tubeNumber
uint8_t tubeNumber(uint8_t tubeLay, uint8_t tube) const
returns the tube number
Definition: MdtMezzanineCard.cxx:122
MdtMezzanineCard
MdtMezzanineCard - Helper struct to represent the structure of a mezzanine card in a consistent way E...
Definition: MdtMezzanineCard.h:34
calibdata.tube_id
tube_id
Definition: calibdata.py:30
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
MdtCablingOffData
Split the offline part of the cabling apart to use it later for sorting.
Definition: MdtCablingData.h:16
MdtMezzanineCard::OfflineCh
Helper struct to pipe the result from the tdc -> offline channel translation.
Definition: MdtMezzanineCard.h:72
MuonGM::MdtReadoutElement
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/MdtReadoutElement.h:51
MdtCablingJsonDumpAlg::m_cablingKey
SG::ReadCondHandleKey< MuonMDT_CablingMap > m_cablingKey
Definition: MdtCablingJsonDumpAlg.h:37
lumiFormat.i
int i
Definition: lumiFormat.py:85
ReadCellNoiseFromCool.chan
chan
Definition: ReadCellNoiseFromCool.py:52
MdtTdcMap::offId
const MdtCablingOffData & offId() const
get the offline identifier
Definition: MdtTdcMap.h:57
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
jobOptions.card
card
Definition: jobOptions.GenevaPy8_Zmumu.py:11
ArrayHelper.h
MdtIdHelper
Definition: MdtIdHelper.h:61
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
MdtCablingData
Definition: MdtCablingData.h:82
MuonGM::MdtReadoutElement::getMultilayer
int getMultilayer() const
Returns the multilayer represented by the readout element.
MdtCablingJsonDumpAlg::m_DetectorManagerKey
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_DetectorManagerKey
Definition: MdtCablingJsonDumpAlg.h:34
AthAlgorithm
Definition: AthAlgorithm.h:47
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
MdtIdHelper::channelID
Identifier channelID(int stationName, int stationEta, int stationPhi, int multilayer, int tubeLayer, int tube) const
Definition: MdtIdHelper.cxx:659
MdtTdcMap::tubeZero
uint8_t tubeZero() const
Definition: MdtTdcMap.h:72
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
MdtIdHelper::elementID
Identifier elementID(int stationName, int stationEta, int stationPhi) const
Definition: MdtIdHelper.cxx:630
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
remap
std::map< std::string, std::string > remap
list of directories to be explicitly remapped
Definition: hcg.cxx:92
MdtCablingJsonDumpAlg::execute
virtual StatusCode execute() override
Definition: MdtCablingJsonDumpAlg.cxx:43
MuonGM::MuonReadoutElement::identify
Identifier identify() const override final
Returns the ATLAS Identifier of the MuonReadOutElement.
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/MuonReadoutElement.h:184
MdtCablingJsonDumpAlg.h
MdtCablingJsonDumpAlg::initialize
virtual StatusCode initialize() override
Definition: MdtCablingJsonDumpAlg.cxx:36
MuonGM::MdtReadoutElement::getNtubesperlayer
int getNtubesperlayer() const
Returns the number of tubes in each tube layer.
sTgcDigitEffiDump.multiLayer
int multiLayer
Definition: sTgcDigitEffiDump.py:36
Identifier
Definition: IdentifierFieldParser.cxx:14
SCT_Monitoring::summary
@ summary
Definition: SCT_MonitoringNumbers.h:65