ATLAS Offline Software
Loading...
Searching...
No Matches
MdtDigitToMdtRDO.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "MdtDigitToMdtRDO.h"
6
7#include <algorithm>
8#include <atomic>
9#include <cmath>
10
15#include "MuonRDO/MdtCsm.h"
18
21namespace {
25 std::atomic<bool> bmgWarningPrinted = false;
26
27} // namespace
28
29MdtDigitToMdtRDO::MdtDigitToMdtRDO(const std::string& name, ISvcLocator* pSvcLocator) : AthReentrantAlgorithm(name, pSvcLocator) {}
30
31// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
32
34 ATH_MSG_DEBUG(" in initialize()");
35 ATH_CHECK(m_csmContainerKey.initialize());
36 ATH_CHECK(m_digitContainerKey.initialize());
37 ATH_CHECK(m_idHelperSvc.retrieve());
38 ATH_CHECK(m_cablingKey.initialize());
39 ATH_CHECK(m_condKey.initialize());
40
41 if (fillTagInfo().isFailure()) { ATH_MSG_WARNING("Could not fill the tagInfo for MDT cabling"); }
42
43 m_BMG_station_name = m_idHelperSvc->mdtIdHelper().stationNameIndex("BMG");
45 if (m_BMGpresent) {
46 ATH_MSG_DEBUG("Processing configuration for layouts with BME chambers (stationID: " << m_BMG_station_name << ").");
47 }
48 return StatusCode::SUCCESS;
49}
50
51// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
52// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
53
54StatusCode MdtDigitToMdtRDO::execute(const EventContext& ctx) const {
55 ATH_MSG_DEBUG("in execute() : fill_MDTdata");
56 // create an empty pad container and record it
58 ATH_CHECK(csmContainer.record(std::make_unique<MdtCsmContainer>()));
59 ATH_MSG_DEBUG("Recorded MdtCsmContainer called " << csmContainer.fullKey());
60
62 if (!container.isValid()) {
63 ATH_MSG_ERROR("Could not find MdtDigitContainer called " << container.fullKey());
64 return StatusCode::SUCCESS;
65 }
66 ATH_MSG_DEBUG("Found MdtDigitContainer called " << container.fullKey());
67
69 const MuonMDT_CablingMap* cabling_ptr{*readHandle_Cabling};
70 if (!cabling_ptr) {
71 ATH_MSG_ERROR("Null pointer to the read conditions object");
72 return StatusCode::FAILURE;
73 }
74
75 SG::ReadCondHandle<MdtCondDbData> readHandle_Conditions{m_condKey, ctx};
76 const MdtCondDbData* condtionsPtr{*readHandle_Conditions};
77 if (!condtionsPtr) {
78 ATH_MSG_ERROR("Null pointer to the read conditions object");
79 return StatusCode::FAILURE;
80 }
81 const MdtIdHelper& id_helper = m_idHelperSvc->mdtIdHelper();
83 std::vector<std::unique_ptr<MdtCsm>> csm_cache{};
84 csm_cache.resize(id_helper.detectorElement_hash_max());
85 // Iterate on the collections
86 for (const MdtDigitCollection* mdtCollection : *container) {
87 const Identifier chid1 = mdtCollection->identify();
89 if (!condtionsPtr->isGood(chid1)) continue;
90
92 if (!cabling_ptr->convert(chid1, cabling_data)) {
93 ATH_MSG_FATAL("Found a non mdt identifier " << m_idHelperSvc->toString(chid1));
94 return StatusCode::FAILURE;
95 }
96
98 for (const MdtDigit* mdtDigit : *mdtCollection) {
99 const Identifier channelId = mdtDigit->identify();
100
101 if (!id_helper.valid(channelId) || !cabling_ptr->convert(channelId, cabling_data)) {
102 ATH_MSG_DEBUG("Found invalid mdt identifier " << channelId);
103 continue;
104 }
105
107 bool cabling = cabling_ptr->getOnlineId(cabling_data, msgStream());
108
109 if (!cabling) {
110 if (cabling_data.stationIndex == m_BMG_station_name) {
111 if (!bmgWarningPrinted) {
112 ATH_MSG_WARNING("Apparently BMG chambers are disconnected to the cabling. "
113 << "This has been checked to only appear in mc16a-like setups as the chambers were installed in "
114 "the end-of-the-year shutdown 2016. "
115 << "In any other case, be despaired in facing the villian and check what has gone wrong");
116 bmgWarningPrinted = true;
117 }
118 continue;
119 }
120 ATH_MSG_ERROR("MDTcabling can't return an online ID for the channel : " << cabling_data);
121 return StatusCode::FAILURE;
122 }
123
124 // Create the new AMT hit
125 auto amtHit = std::make_unique<MdtAmtHit>(cabling_data.tdcId, cabling_data.channelId, mdtDigit->isMasked());
126 // Get coarse time and fine time
127 int tdc_counts = mdtDigit->tdc();
128
129 uint16_t coarse = (tdc_counts >> 5) & 0xfff;
130 uint16_t fine = tdc_counts & 0x1f;
131 uint16_t width = mdtDigit->adc();
132
133 amtHit->setValues(coarse, fine, width);
134
135 ATH_MSG_DEBUG("Adding a new AmtHit -- " << cabling_data);
136 ATH_MSG_DEBUG(" Coarse time : " << coarse << " Fine time : " << fine << " Width : " << width);
137
139 IdentifierHash csm_hash{0};
140 Identifier csmId{0};
142 if (!cabling_ptr->getMultiLayerCode(cabling_data, csmId, csm_hash, msgStream())) {
143 ATH_MSG_ERROR("Hash generation failed for " << cabling_data);
144 return StatusCode::FAILURE;
145 }
146
148 std::unique_ptr<MdtCsm>& mdtCsm = csm_cache[csm_hash];
149 if (!mdtCsm) {
150 ATH_MSG_DEBUG("Insert new CSM module using " << cabling_data << " " << m_idHelperSvc->toString(csmId));
151 mdtCsm = std::make_unique<MdtCsm>(csmId, csm_hash, cabling_data.subdetectorId, cabling_data.mrod, cabling_data.csm);
152 }
153 // Check that the CSM is correct
154 if (cabling_data.csm != mdtCsm->CsmId() || cabling_data.subdetectorId != mdtCsm->SubDetId() || cabling_data.mrod != mdtCsm->MrodId()) {
155 MdtCablingData wrongCsm{};
156 wrongCsm.csm = mdtCsm->CsmId();
157 wrongCsm.mrod = mdtCsm->MrodId();
158 wrongCsm.subdetectorId = mdtCsm->SubDetId();
159 wrongCsm.channelId =0;
160 wrongCsm.tdcId =0;
161
162 cabling_ptr->getOfflineId(wrongCsm, msgStream());
163 Identifier wrongId{};
164 cabling_ptr->convert(wrongCsm,wrongId);
165
166 ATH_MSG_FATAL("CSM collection "<<static_cast<const MdtCablingOnData&>(wrongCsm) <<" ("<<m_idHelperSvc->toStringDetEl(wrongId)
167 <<") does not match with " <<static_cast<const MdtCablingOnData&>(cabling_data)<<" ("<<m_idHelperSvc->toStringDetEl(chid1)<<")");
168 return StatusCode::FAILURE;
169 }
170 // Add the digit to the CSM
171 mdtCsm->push_back(std::move(amtHit));
172 }
173 }
175 for (unsigned int hash= 0; hash < csm_cache.size(); ++hash) {
176 if (!csm_cache[hash]) continue;
177 ATH_CHECK(csmContainer->addCollection(csm_cache[hash].release(), hash));
178 }
179 return StatusCode::SUCCESS;
180}
181
182// NOTE: although this function has no clients in release 22, currently the Run2 trigger simulation is still run in
183// release 21 on RDOs produced in release 22. Since release 21 accesses the TagInfo, it needs to be written to the
184// RDOs produced in release 22. The fillTagInfo() function thus needs to stay in release 22 until the workflow changes
186 ServiceHandle<ITagInfoMgr> tagInfoMgr("TagInfoMgr", name());
187 if (tagInfoMgr.retrieve().isFailure()) { return StatusCode::FAILURE; }
188
189 std::string cablingType = "NewMDT_Cabling"; // everything starting from Run2 should be 'New'
190 StatusCode sc = tagInfoMgr->addTag("MDT_CablingType", cablingType);
191
192 if (sc.isFailure()) {
193 ATH_MSG_WARNING("MDT_CablingType " << cablingType << " not added to TagInfo ");
194 return sc;
195 } else {
196 ATH_MSG_DEBUG("MDT_CablingType " << cablingType << " is Added TagInfo ");
197 }
198
199 return StatusCode::SUCCESS;
200}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
static Double_t sc
const double width
An algorithm that can be simultaneously executed in multiple threads.
This is a "hash" representation of an Identifier.
bool isGood(const Identifier &Id) const
Returns if the identifier (tube/multiLayer/chamber) is masked in the conditions database.
virtual StatusCode execute(const EventContext &ctx) const override final
SG::ReadCondHandleKey< MdtCondDbData > m_condKey
SG::ReadCondHandleKey< MuonMDT_CablingMap > m_cablingKey
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
MdtDigitToMdtRDO(const std::string &name, ISvcLocator *pSvcLocator)
SG::WriteHandleKey< MdtCsmContainer > m_csmContainerKey
SG::ReadHandleKey< MdtDigitContainer > m_digitContainerKey
StatusCode fillTagInfo() const
virtual StatusCode initialize() override final
bool valid(const Identifier &id) const
Public validation of levels.
size_type detectorElement_hash_max() const
MdtCablingData CablingData
bool getOnlineId(CablingData &cabling_data, MsgStream &log) const
return the online id given the offline id
bool getOfflineId(CablingData &cabling_data, MsgStream &log) const
return the offline id given the online id
bool convert(const CablingData &cabling_data, Identifier &id, bool check_valid=true) const
converts the cabling data into an identifier.
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,...
const DataObjID & fullKey() const
Return the key as a DataObjID.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
uint8_t tdcId
Mezzanine type.
uint8_t channelId
Identifier of the corresponding tdc.
uint8_t & subdetectorId
CSM number.
uint8_t & csm
MROD number.