ATLAS Offline Software
Loading...
Searching...
No Matches
MM_RawDataProviderTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
8#include "eformat/SourceIdentifier.h"
9#include <atomic>
10#include <memory>
11#include <unordered_map>
12
14using eformat::helper::SourceIdentifier;
15
16//================ Initialisation ==============================================
17StatusCode
19{
20 ATH_CHECK(m_idHelperSvc.retrieve());
21 ATH_CHECK(m_decoder.retrieve());
22 ATH_CHECK(m_robDataProvider.retrieve());
23 ATH_CHECK(m_rdoContainerKey.initialize());
24
25 m_maxhashtoUse = m_idHelperSvc->mmIdHelper().module_hash_max();
26
27 // generate all the Source Identifiers for MicroMegas to request the fragments.
28 // assume 16 RODs per side (one per sector) and that ROB ID = ROD ID.
29 for (uint32_t detID : {eformat::MUON_MMEGA_ENDCAP_A_SIDE, eformat::MUON_MMEGA_ENDCAP_C_SIDE}) { //0x6B, 0x6C
30 for (uint8_t sectorID(0); sectorID < 16; ++sectorID) {
31 // for now lets build all the possible ROB ids of all possible readout configurations
32 // maybe later we can come up with a smart way to detect which readout sheme is running and only request the relevant ROB ids from the ROBDataProviderSvc
33
34 uint16_t moduleID = (0x0 << 8) | sectorID; // combined/single ROB
35 SourceIdentifier sid(static_cast<eformat::SubDetector>(detID), moduleID);
36 m_allRobIds.push_back(sid.simple_code());
37
38 moduleID = (0x1 << 8) | sectorID; // full device ROB (split configuration)
39 sid = SourceIdentifier(static_cast<eformat::SubDetector>(detID), moduleID);
40 m_allRobIds.push_back(sid.simple_code());
41
42 moduleID = (0x2 << 8) | sectorID; // shared device ROB (split configuration)
43 sid = SourceIdentifier(static_cast<eformat::SubDetector>(detID), moduleID);
44 m_allRobIds.push_back(sid.simple_code());
45 }
46 }
47
49
50 return StatusCode::SUCCESS;
51}
52
53//==============================================================================
54StatusCode
55Muon::MM_RawDataProviderTool::convertIntoContainer(const EventContext& ctx, const std::vector<const ROBFragment*>& vecRobs, const std::vector<IdentifierHash>& rdoIdhVect, MM_RawDataContainer& mmRdoContainer) const
56{
57 // Since there can be multiple ROBFragments contributing to the same RDO collection a temporary cache is setup and passed to fillCollection by reference. Once all ROBFragments are processed the collections are added into the rdo container
58
59 std::unordered_map<IdentifierHash, std::unique_ptr<MM_RawDataCollection>> rdo_map;
60
61 // Loop on the passed ROB fragments, and call the decoder for each one to fill the RDO container.
62 for (const ROBFragment* fragment : vecRobs)
63 ATH_CHECK( m_decoder->fillCollection(ctx, *fragment, rdoIdhVect, rdo_map) ); // always returns StatusCode::SUCCESS
64
65 // error counters
66 int nerr_duplicate{0}, nerr_rdo{0};
67
68 // add the RDO collections created from the data of this ROB into the identifiable container.
69 for (auto& [hash, collection]: rdo_map) {
70
71 if ((!collection) or collection->empty()) continue; // skip empty collections
72
73 MM_RawDataContainer::IDC_WriteHandle lock = mmRdoContainer.getWriteHandle(hash);
74
75 if (lock.alreadyPresent()) {
76 ++nerr_duplicate;
77 } else if (!lock.addOrDelete(std::move(collection)).isSuccess()) {
78 // since we prevent duplicates above, this error should never happen.
79 ++nerr_rdo;
80 }
81 }
82
83 // error summary (to reduce the number of messages)
84 if (nerr_duplicate) ATH_MSG_WARNING(nerr_duplicate << " elinks skipped since the same module hash has been added by a previous ROB fragment");
85 if (nerr_rdo){
86 ATH_MSG_ERROR("Failed to add "<<nerr_rdo<<" RDOs into the identifiable container");
87 return StatusCode::FAILURE;
88 }
89
90 ATH_MSG_DEBUG("Size of mmRdoContainer is " << mmRdoContainer.size());
91 return StatusCode::SUCCESS;
92}
93
94//==============================================================================
95StatusCode Muon::MM_RawDataProviderTool::initRdoContainer(const EventContext& ctx, MM_RawDataContainer*& rdoContainer) const
96{
97 // Create the identifiable RdoContainer in StoreGate to be filled with decoded fragment contents.
99
100 const bool externalCacheRDO = !m_rdoContainerCacheKey.key().empty();
101 if(!externalCacheRDO){
102 ATH_CHECK(rdoContainerHandle.record(std::make_unique<MM_RawDataContainer>(m_maxhashtoUse)));
103 ATH_MSG_DEBUG("Created MM container");
104 } else {
106 ATH_CHECK(update.isValid());
107 ATH_CHECK(rdoContainerHandle.record(std::make_unique<MM_RawDataContainer>(update.ptr())));
108 ATH_MSG_DEBUG("Created MM container using cache for " << m_rdoContainerCacheKey.key());
109 }
110
111 // this should never happen, but since we dereference the pointer, we should check
112 if (!(rdoContainer = rdoContainerHandle.ptr())) {
113 ATH_MSG_ERROR("the MM RDO container is null, cannot decode MM data");
114 return StatusCode::FAILURE;
115 }
116
117 return StatusCode::SUCCESS;
118}
119
120//==============================================================================
121StatusCode Muon::MM_RawDataProviderTool::convert(const std::vector<uint32_t>& robIds, const EventContext& ctx) const {
122 // method for RoI-seeded mode via ROB IDs
123 MM_RawDataContainer* rdoContainer{nullptr};
124 ATH_CHECK(initRdoContainer(ctx, rdoContainer));
125
126 if (robIds.empty() || m_skipDecoding) return StatusCode::SUCCESS;
127
128 ROBFragmentList vecRobf;
129 m_robDataProvider->getROBData(ctx, robIds, vecRobf);
130
131 // pass empty list of ID hashes, every ROB ID in list will be decoded
132 const std::vector<IdentifierHash> hashIDList;
133 return convertIntoContainer(ctx, vecRobf, hashIDList, *rdoContainer);
134}
135
136//==============================================================================
137StatusCode Muon::MM_RawDataProviderTool::convert(const std::vector<IdentifierHash>& rdoIdhVect, const EventContext& ctx) const
138{
139 // method for RoI-seeded mode via hash IDs. we don't let empty hash containers reach the decoder,
140 // since an empty container means unseeded mode (decode everything).
141
142 MM_RawDataContainer* rdoContainer{nullptr};
143 ATH_CHECK(initRdoContainer(ctx, rdoContainer));
144
145 if (rdoIdhVect.empty() || m_skipDecoding) return StatusCode::SUCCESS;
146
147 ROBFragmentList vecRobf;
148 m_robDataProvider->getROBData(ctx, m_allRobIds, vecRobf);
149
150 return convertIntoContainer(ctx, vecRobf, rdoIdhVect, *rdoContainer);
151}
152
153//==============================================================================
154StatusCode Muon::MM_RawDataProviderTool::convert(const EventContext& ctx) const
155{
156 // method for unseeded mode. just decode everything.
157
158 MM_RawDataContainer* rdoContainer{nullptr};
159 ATH_CHECK(initRdoContainer(ctx, rdoContainer));
160 if(m_skipDecoding) return StatusCode::SUCCESS;
161
162 ROBFragmentList vecRobf;
163 m_robDataProvider->getROBData(ctx, m_allRobIds, vecRobf);
164
165 // dummy hashID vector for the decoder (empty = unseeded mode)
166 const std::vector<IdentifierHash> rdoIdhVect;
167
168 return convertIntoContainer(ctx, vecRobf, rdoIdhVect, *rdoContainer);
169}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
StatusCode addOrDelete(std::unique_ptr< T > ptr)
IDC_WriteHandle getWriteHandle(IdentifierHash hash)
size_t size() const
Duplicate of fullSize for backwards compatability.
std::vector< uint32_t > m_allRobIds
virtual StatusCode initialize() override
Standard AlgTool method.
StatusCode initRdoContainer(const EventContext &, MM_RawDataContainer *&) const
Gaudi::Property< bool > m_skipDecoding
Flag to skip decoding and write empty container.
SG::UpdateHandleKey< MM_RawDataCollection_Cache > m_rdoContainerCacheKey
ToolHandle< IMM_ROD_Decoder > m_decoder
Decoder for ROB fragment RDO conversion.
virtual StatusCode convert() const
the new ones
virtual StatusCode convertIntoContainer(const EventContext &ctx, const ROBFragmentList &, const std::vector< IdentifierHash > &, MM_RawDataContainer &) const
Method that converts the ROBFragments into the passed container.
ServiceHandle< IROBDataProviderSvc > m_robDataProvider
SG::WriteHandleKey< MM_RawDataContainer > m_rdoContainerKey
RDO container key.
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
The ID helper.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
pointer_type ptr()
Dereference the pointer.
eformat::ROBFragment< PointerType > ROBFragment
Definition RawEvent.h:27