ATLAS Offline Software
MdtCablingJsonDumpAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 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 {
16  return this->MdtCablingOnData::operator==(other) && tdcId == other.tdcId;
17  }
19  bool operator!=(const TdcIdentifier& other) const { return !((*this) == other); }
20  bool operator<(const TdcIdentifier& other) const {
21  if (this->MdtCablingOnData::operator!=(other)) return this->MdtCablingOnData::operator<(other);
22  return tdcId < other.tdcId;
23  }
24  TdcIdentifier(const MdtCablingData& cabling):
26  tdcId{cabling.tdcId} {}
27  };
28 
29  using Mapping = MdtMezzanineCard::Mapping;
30  using OfflineCh = MdtMezzanineCard::OfflineCh;
31 
32 }
33 
34 MdtCablingJsonDumpAlg::MdtCablingJsonDumpAlg(const std::string& name, ISvcLocator* pSvcLocator):
35  AthAlgorithm(name,pSvcLocator) {}
36 
37 
39  ATH_CHECK(m_idHelperSvc.retrieve());
42  return StatusCode::SUCCESS;
43 }
44 
46  const EventContext& ctx = Gaudi::Hive::currentContext();
47  ATH_MSG_INFO("Dump cabling & mezzanines into JSON file");
48 
50  if (!detectorMgr.isValid()){
51  ATH_MSG_FATAL("Failed to retrieve the Detector manager "<<m_DetectorManagerKey.fullKey());
52  return StatusCode::FAILURE;
53  }
54 
56  if (!cabling.isValid()) {
57  ATH_MSG_ERROR("Failed to retrieve the Mdt cabling "<<m_cablingKey.fullKey());
58  return StatusCode::FAILURE;
59  }
60  const MdtIdHelper& idHelper = m_idHelperSvc->mdtIdHelper();
61 
62  std::vector<MdtMezzanineCard> cached_cards{};
63  std::set<MdtCablingData> cached_chnls{};
64 
65  for (auto det_itr = idHelper.detectorElement_begin(); det_itr != idHelper.detectorElement_end(); ++det_itr){
66  const MuonGM::MdtReadoutElement* readEle = detectorMgr->getMdtReadoutElement(*det_itr);
67  if (!readEle) {
68  ATH_MSG_DEBUG("Detector element does not exist. ");
69  continue;
70  }
71  const Identifier station_id = idHelper.elementID(readEle->identify());
72  ATH_MSG_DEBUG("Check station "<<m_idHelperSvc->toString(station_id));
74  MdtMezzanineCard dummy_card(Mapping{}, readEle->getNLayers(), -1);
75 
76  std::map<TdcIdentifier, Mapping> chamber_mezz{};
77  for (int layer = 1 ; layer <= readEle->getNLayers(); ++layer){
78  for (int tubeInLayer = 1 ; tubeInLayer <= readEle->getNtubesperlayer(); ++tubeInLayer) {
79  bool is_valid{false};
80  const Identifier tube_id = idHelper.channelID(station_id, readEle->getMultilayer(),
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  if (chamber_mezz.find(tdc_id) == chamber_mezz.end()) {
96  chamber_mezz[tdc_id] = make_array<uint8_t,24>(MdtMezzanineCard::NOTSET);
97  }
98  chamber_mezz[tdc_id][cabling_data.channelId] = dummy_card.tubeNumber(layer, tubeInLayer);
99  }
100  }
102  for (auto&[tdc, mezz_mapping] : chamber_mezz) {
103  MdtCablingData mezzCablingId{};
104 
106  static_cast<MdtCablingOnData&>(mezzCablingId) = tdc;
107  mezzCablingId.tdcId = tdc.tdcId;
108 
109  MdtTdcOnlSorter chipInCab = cabling->getOnlineConvMap().at(tdc).all_modules.at(tdc.tdcId);
111  static_cast<MdtCablingOffData&>(mezzCablingId) = chipInCab->offId();
113  mezzCablingId.tube = chipInCab->tubeZero();
114 
115  const uint8_t tubeOffSet = (mezzCablingId.tube-1)%dummy_card.numTubesPerLayer();
118  if (tubeOffSet) {
119  MdtMezzanineCard remap{mezz_mapping, dummy_card.numTubeLayers(), 0};
120  for (size_t chan = 0 ; chan < mezz_mapping.size(); ++chan) {
121  const OfflineCh tube_lay = remap.offlineTube(chan, msgStream());
122  if (!tube_lay.isValid) continue;
123  uint8_t tubeNumber = tube_lay.tube + tubeOffSet + 1;
124  mezz_mapping[chan] = remap.tubeNumber(tube_lay.layer, tubeNumber);
125  }
126  }
128  Mapping& mtmp = mezz_mapping; // Work around clang15 compilation error.
129  std::vector<MdtMezzanineCard>::const_iterator itr = std::find_if(cached_cards.begin(), cached_cards.end(),
130  [&dummy_card, &mtmp](const MdtMezzanineCard& card ){
131  if (dummy_card.numTubeLayers() != card.numTubeLayers()) return false;
132  for (size_t ch =0; ch < mtmp.size(); ++ch) {
133  if (mtmp[ch] != card.tdcToTubeMap()[ch]) return false;
134  }
135  return true;
136  });
137  if (itr != cached_cards.end()) {
138  mezzCablingId.mezzanine_type = itr->id();
139  } else {
140  cached_cards.emplace_back(mezz_mapping, dummy_card.numTubeLayers(), cached_cards.size() + 10);
141  if (!cached_cards.back().checkConsistency(msgStream())) {
142  ATH_MSG_ERROR("Wrong assignment for "<<mezzCablingId);
143  return StatusCode::FAILURE;
144  }
145  mezzCablingId.mezzanine_type = cached_cards.back().id();
146  }
147  cached_chnls.insert(std::move(mezzCablingId));
148  }
149 
150 
151 
152  }
154  {
155  std::ofstream summary{m_summaryTxt};
156  if (!summary.good()) {
157  ATH_MSG_ERROR("Failed to write "<<m_summaryTxt);
158  return StatusCode::FAILURE;
159  }
160  summary<<"Extracted "<<cached_cards.size()<<" mezzanine card layouts and "
161  <<cached_chnls.size()<<" chamber channels. "<<std::endl<<std::endl<<std::endl;
162  for (const MdtMezzanineCard& card : cached_cards) {
163  summary<<card;
164  MdtCablingOffData chamb{};
165  for (const MdtCablingData& cabling : cached_chnls) {
166  if (cabling.mezzanine_type != card.id()) continue;
167  if (chamb != cabling) {
168  chamb = cabling;
169  summary<<std::endl<<" *** "<<idHelper.stationNameString(chamb.stationIndex);
170  summary<<static_cast<int>(std::abs(chamb.eta));
171  summary<<(chamb.eta > 0 ? "A" : "C");
172  summary<<static_cast<int>(chamb.phi);
173  summary<<"M"<<static_cast<int>(chamb.multilayer);
174  summary<<" --- tdcs: ";
175  }
176  summary<<static_cast<int>(cabling.tdcId)<<", ";
177  }
178  summary<<std::endl<<std::endl
179  <<"##############################################################"<<std::endl;
180  }
181  }
183  {
184  std::ofstream mezz_json{m_mezzJSON};
185  if (!mezz_json.good()) {
186  ATH_MSG_ERROR("Failed to write "<<m_summaryTxt);
187  return StatusCode::FAILURE;
188  }
189  mezz_json<<"["<<std::endl;
190  for (size_t i = 0; i < cached_cards.size() ; ++i) {
191  const MdtMezzanineCard& card = cached_cards[i];
192  mezz_json<<" {"<<std::endl;
193  mezz_json<<" \"mezzId\": "<<static_cast<int>(card.id())<<","<<std::endl;
194  mezz_json<<" \"nTubeLayer\": "<<static_cast<int>(card.numTubeLayers())<<","<<std::endl;
195  mezz_json<<" \"tdcToTubeMap\": [";
196  for (size_t ch = 0 ; ch < card.tdcToTubeMap().size(); ++ch) {
197  mezz_json<<static_cast<int>(card.tdcToTubeMap()[ch]);
198  if (ch + 1 != card.tdcToTubeMap().size())mezz_json<<",";
199  }
200  mezz_json<<"]"<<std::endl;
201  mezz_json<<" }";
202  if (i +1 != cached_cards.size()) mezz_json<<",";
203  mezz_json<<std::endl;
204  }
205  mezz_json<<"]";
206  }
207  {
208  std::ofstream chamb_json{m_cablingJSON};
209  if (!chamb_json.good()) {
210  ATH_MSG_FATAL("Failed to write "<<m_cablingJSON);
211  return StatusCode::FAILURE;
212  }
213  chamb_json<<"["<<std::endl;
214  size_t i =0;
215  for (const MdtCablingData& chamb : cached_chnls){
216  chamb_json<<" {"<<std::endl;
217  chamb_json<<" \"station\": \""<<idHelper.stationNameString(chamb.stationIndex)<<"\","<<std::endl;
218  chamb_json<<" \"eta\": "<<static_cast<int>(chamb.eta)<<","<<std::endl;
219  chamb_json<<" \"phi\": "<<static_cast<int>(chamb.phi)<<","<<std::endl;
220  chamb_json<<" \"ml\": "<<static_cast<int>(chamb.multilayer)<<","<<std::endl;
221  chamb_json<<" \"subDet\": "<<static_cast<int>(chamb.subdetectorId)<<","<<std::endl;
222  chamb_json<<" \"csm\": "<<static_cast<int>(chamb.csm)<<","<<std::endl;
223  chamb_json<<" \"mrod\": "<<static_cast<int>(chamb.mrod)<<","<<std::endl;
224  chamb_json<<" \"tdcId\": "<<static_cast<int>(chamb.tdcId)<<","<<std::endl;
225  chamb_json<<" \"mezzId\": "<<static_cast<int>(chamb.mezzanine_type)<<","<<std::endl;
226  chamb_json<<" \"tubeZero\": "<<static_cast<int>(chamb.tube)<<std::endl;
227  chamb_json<<" }";
228  if (i +1 != cached_chnls.size()) chamb_json<<",";
229  chamb_json<<std::endl;
230  ++i;
231  }
232  chamb_json<<"]"<<std::endl;
233  }
234 
235 
236  return StatusCode::SUCCESS;
237 }
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:34
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:762
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:575
MdtCablingOnData
Definition: MdtCablingData.h:50
MdtMezzanineCard::tdcToTubeMap
const Mapping & tdcToTubeMap() const
Returns the underlying TDC -> Tube conversion map.
Definition: MdtMezzanineCard.h:80
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:18
MuonIdHelper::detectorElement_end
const_id_iterator detectorElement_end() const
Definition: MuonIdHelper.cxx:764
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
MdtMezzanineCard::id
uint8_t id() const
returns mezzanine database identifier
Definition: MdtMezzanineCard.h:64
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:50
MdtCablingJsonDumpAlg::m_cablingKey
SG::ReadCondHandleKey< MuonMDT_CablingMap > m_cablingKey
Definition: MdtCablingJsonDumpAlg.h:37
lumiFormat.i
int i
Definition: lumiFormat.py:92
ReadCellNoiseFromCool.chan
chan
Definition: ReadCellNoiseFromCool.py:52
MdtTdcMap::offId
const MdtCablingOffData & offId() const
get the offline identifier
Definition: MdtTdcMap.h:57
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
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
MdtCablingOnData::operator!=
bool operator!=(const MdtCablingOnData &other) const
Definition: MdtCablingData.h:68
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:195
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:45
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:38
MuonGM::MdtReadoutElement::getNtubesperlayer
int getNtubesperlayer() const
Returns the number of tubes in each tube layer.
SCT_Monitoring::summary
@ summary
Definition: SCT_MonitoringNumbers.h:65