ATLAS Offline Software
Loading...
Searching...
No Matches
STGC_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
5
8#include "eformat/SourceIdentifier.h"
9using eformat::helper::SourceIdentifier;
10
11using namespace OFFLINE_FRAGMENTS_NAMESPACE;
12
13
14//==============================================================================
16
17
18 ATH_CHECK(m_idHelperSvc.retrieve());
19 ATH_CHECK(m_decoder.retrieve());
20 ATH_CHECK(m_robDataProvider.retrieve()); // ROBDataProviderSvc
21 ATH_CHECK(m_rdoContainerKey.initialize());
22
23 m_maxhashtoUse = m_idHelperSvc->stgcIdHelper().module_hash_max();
24 // generate all the Source Identifiers to request the fragments.
25 // assume 16 RODs per side (one per sector) and that ROB ID = ROD ID.
26 for (uint32_t detID : {eformat::MUON_STGC_ENDCAP_A_SIDE, eformat::MUON_STGC_ENDCAP_C_SIDE}) { //0x6D, 0x6E
27 for (uint8_t sectorID(0); sectorID < 16; ++sectorID) {
28 // for now lets build all the possible ROB ids of all possible readout configurations
29 // 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
30 // reference: slide 6 of https://indico.cern.ch/event/1260377/contributions/5294286/attachments/2603399/4495810/NSW-SwRod-Felix-v3.pdf
31
32 uint16_t moduleID = (0x0 << 8) | sectorID; // combined/single ROB
33 SourceIdentifier sid(static_cast<eformat::SubDetector>(detID), moduleID);
34 m_allRobIds.push_back(sid.simple_code());
35
36 moduleID = (0x1 << 8) | sectorID; // full device ROB (split configuration)
37 sid = SourceIdentifier(static_cast<eformat::SubDetector>(detID), moduleID);
38 m_allRobIds.push_back(sid.simple_code());
39
40 moduleID = (0x2 << 8) | sectorID; // shared device ROB (split configuration)
41 sid = SourceIdentifier(static_cast<eformat::SubDetector>(detID), moduleID);
42 m_allRobIds.push_back(sid.simple_code());
43
44 moduleID = (0x3 << 8) | sectorID; // spare device ROB (split configuration)
45 sid = SourceIdentifier(static_cast<eformat::SubDetector>(detID), moduleID);
46 m_allRobIds.push_back(sid.simple_code());
47 }
48 }
49
51 return StatusCode::SUCCESS;
52}
53
54
55//==============================================================================
57 const ROBFragmentList& vecRobs,
58 const std::vector<IdentifierHash>& rdoIdhVect,
59 STGC_RawDataContainer& stgcRdoContainer) const
60{
61 // 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
62 std::unordered_map<IdentifierHash, std::unique_ptr<STGC_RawDataCollection>> rdo_map;
63
64
65 // Loop on the passed ROB fragments, and call the decoder for each one to fill the RDO container.
66 for (const ROBFragment* fragment : vecRobs)
67 ATH_CHECK( m_decoder->fillCollection(ctx, *fragment, rdoIdhVect, rdo_map) ); // always returns StatusCode::SUCCESS
68
69
70 // error counters
71 int nerr_duplicate{0}, nerr_rdo{0};
72
73 // add the RDO collections created from the data of this ROB into the identifiable container.
74 for (auto& [hash, collection]: rdo_map) {
75
76 if ((!collection) or collection->empty()) continue; // skip empty collections
77
78 STGC_RawDataContainer::IDC_WriteHandle lock = stgcRdoContainer.getWriteHandle(hash);
79
80 if (lock.alreadyPresent()) {
81 ++nerr_duplicate;
82 } else if (!lock.addOrDelete(std::move(collection)).isSuccess()) {
83 // since we prevent duplicates above, this error should never happen.
84 ++nerr_rdo;
85 }
86 }
87
88
89 // error summary (to reduce the number of messages)
90 if (nerr_duplicate) ATH_MSG_WARNING(nerr_duplicate << " elinks skipped since the same module hash has been added by a previous ROB fragment");
91 if (nerr_rdo) {
92 ATH_MSG_ERROR("Failed to add "<<nerr_rdo<<" RDOs into the identifiable container");
93 return StatusCode::FAILURE;
94 }
95
96 ATH_MSG_DEBUG("Size of sTgcRdoContainer is " << stgcRdoContainer.size());
97 return StatusCode::SUCCESS;
98}
99
100
101//==============================================================================
102StatusCode Muon::STGC_RawDataProviderTool::initRdoContainer(const EventContext& ctx, STGC_RawDataContainer*& rdoContainer) const
103{
104 // Create the identifiable RdoContainer in StoreGate to be filled with decoded fragment contents.
105 SG::WriteHandle rdoContainerHandle(m_rdoContainerKey, ctx);
106
107 const bool externalCacheRDO = !m_rdoContainerCacheKey.key().empty();
108 if(!externalCacheRDO){
109 ATH_CHECK(rdoContainerHandle.record(std::make_unique<STGC_RawDataContainer>(m_maxhashtoUse)));
110 ATH_MSG_DEBUG("Created STGC RDO container");
111 } else {
113 ATH_CHECK(update.isValid());
114 ATH_CHECK(rdoContainerHandle.record(std::make_unique<STGC_RawDataContainer>(update.ptr())));
115 ATH_MSG_DEBUG("Created STGC RDO container using cache for " << m_rdoContainerCacheKey.key());
116 }
117
118 // this should never happen, but since we dereference the pointer, we should check
119 if (!(rdoContainer = rdoContainerHandle.ptr())) {
120 ATH_MSG_ERROR("The STGC RDO container is null, cannot decode STGC data");
121 return StatusCode::FAILURE;
122 }
123
124 return StatusCode::SUCCESS;
125}
126
127
128//==============================================================================
129StatusCode Muon::STGC_RawDataProviderTool::convert(const std::vector<IdentifierHash>& rdoIdhVect, const EventContext& ctx) const
130{
131 // method for RoI-seeded mode. we don't let empty hash containers reach the decoder,
132 // since an empty container means unseeded mode (decode everything).
133
134 STGC_RawDataContainer* rdoContainer{nullptr};
135 ATH_CHECK(initRdoContainer(ctx, rdoContainer));
136
137 if (rdoIdhVect.empty() || m_skipDecoding) return StatusCode::SUCCESS;
138
139 ROBFragmentList vecRobf;
140 m_robDataProvider->getROBData(ctx, m_allRobIds, vecRobf);
141
142 return convertIntoContainer(ctx, vecRobf, rdoIdhVect, *rdoContainer);
143}
144
145
146//==============================================================================
147StatusCode Muon::STGC_RawDataProviderTool::convert(const EventContext& ctx) const {
148 // method for unseeded mode. just decode everything.
149
150 STGC_RawDataContainer* rdoContainer{nullptr};
151 ATH_CHECK(initRdoContainer(ctx, rdoContainer));
152 if(m_skipDecoding) return StatusCode::SUCCESS;
153
154 ROBFragmentList vecRobf;
155 m_robDataProvider->getROBData(ctx, m_allRobIds, vecRobf);
156
157 // dummy hashID vector for the decoder (empty = unseeded mode)
158 const std::vector<IdentifierHash> rdoIdhVect;
159
160 return convertIntoContainer(ctx, vecRobf, rdoIdhVect, *rdoContainer);
161}
162
163StatusCode Muon::STGC_RawDataProviderTool::convert(const std::vector<uint32_t>& robIds, const EventContext& ctx) const
164{
165 STGC_RawDataContainer* rdoContainer{nullptr};
166 ATH_CHECK(initRdoContainer(ctx, rdoContainer));
167
168 if (robIds.empty() || m_skipDecoding) return StatusCode::SUCCESS;
169
170 ROBFragmentList vecRobf;
171
172 m_robDataProvider->getROBData(ctx, robIds, vecRobf);
173
174 // pass empty list of ID hashes, every ROB ID in list will be decoded
175 const std::vector<IdentifierHash> hashIDList;
176
177 return convertIntoContainer(ctx, vecRobf, hashIDList, *rdoContainer);
178
179}
#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.
StatusCode convertIntoContainer(const EventContext &ctx, const ROBFragmentList &fragements, const std::vector< IdentifierHash > &chamberHashes, STGC_RawDataContainer &target) const
Method that converts the ROBFragments into the passed container.
SG::WriteHandleKey< STGC_RawDataContainer > m_rdoContainerKey
RDO container key.
Gaudi::Property< bool > m_skipDecoding
Flag to skip decoding and write empty container.
StatusCode initRdoContainer(const EventContext &, STGC_RawDataContainer *&) const
ToolHandle< ISTGC_ROD_Decoder > m_decoder
Decoder for ROB fragment RDO conversion.
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
The ID helper.
virtual StatusCode initialize() override
Standard AlgTool method.
SG::UpdateHandleKey< STGC_RawDataCollection_Cache > m_rdoContainerCacheKey
virtual StatusCode convert(const EventContext &ctx) const override
ServiceHandle< IROBDataProviderSvc > m_robDataProvider
Rob Data Provider handle.
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