ATLAS Offline Software
Loading...
Searching...
No Matches
ROBDataProviderSvc.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//===================================================================
6// Implementation of ROBDataProviderSvc
7// Revision: November 2017
8// MT readiness
9// Revision: July 11, 2002
10// Modified for eformat
11// Revision: Aug 18, 2003
12// Modified to use ROBFragments directly and include methods
13// for online
14// Revision: Apr 21, 2005
15// Remove dependency on Level-2 Data Collector, create special
16// version for online
17// Revision: Oct 29, 2006
18// Increase MAX_ROBFRAGMENTS to 2048 to cover the special case
19// when in a "localhost" partition the complete event is given
20// to the Event Filter as one single ROS fragment (this case
21// should not happen for normal running when several ROSes are
22// used and the ROB fragments are grouped under different ROS
23// fragments)
24// Revision: Nov 10, 2008
25// Mask off the module ID from the ROB source identifier of the
26// L2 and EF result when storing it in the ROB map. This is necessary
27// when the L2/PT node ID is stored in the source identifier as
28// module ID. With this modification the L2 and EF result can still be
29// found as 0x7b0000 and 0x7c0000
30// Revision: Jan 12, 2009
31// Allow removal of individual ROBs and ROBs from given subdetectors
32// from the internal ROB map according to a given status code.
33// This may be necessary when corrupted and incomplete ROB fragments
34// are forwarded to the algorithms and the converters are not yet
35// prepared to handle the specific cases.
36// The filtering can be configured with job options as:
37//
38// for individual ROBs as :
39// ------------------------
40// ROBDataProviderSvc.filterRobWithStatus = [ (ROB SourceId, StatusCode to remove),
41// (ROB SourceId 2, StatusCode to remove 2), ... ]
42// and:
43// ROBDataProviderSvc.filterRobWithStatus += [ (ROB SourceId n, StatusCode to remove n) ]
44//
45// Example:
46// ROBDataProviderSvc.filterRobWithStatus = [ (0x42002a,0x0000000f), (0x42002e,0x00000008) ]
47// ROBDataProviderSvc.filterRobWithStatus += [ (0x42002b,0x00000000) ]
48//
49// for all ROBs of a given sub detector as :
50// -----------------------------------------
51// ROBDataProviderSvc.filterSubDetWithStatus = [ (Sub Det Id, StatusCode to remove),
52// (Sub Det Id 2, StatusCode to remove 2), ... ]
53// and:
54// ROBDataProviderSvc.filterSubDetWithStatus += [ (Sub Det Id n, StatusCode to remove n) ]
55//
56// Example:
57// ROBDataProviderSvc.filterSubDetWithStatus = [ (0x41,0x00000000), (0x42,0x00000000) ]
58// ROBDataProviderSvc.filterSubDetWithStatus += [ (0x41,0xcb0002) ]
59//
60// For valid ROB Source Ids, Sub Det Ids and ROB Status elements see the event format
61// document ATL-D-ES-0019 (EDMS)
62// Revision: Jan 28, 2014
63// For Run 1 the module ID from the ROB source identifier of the
64// L2 and EF result needed to be masked off before storing the ROB fragment
65// in the ROB map. The module ID for these fragments contained an identifier
66// of the machine on which they were produced. This produced as many different ROB IDs
67// for these fragments as HLT processors were used. The module IDs were not useful
68// for analysis and needed to be masked off from these fragments in the ROB map in order
69// to allow the access to the L2 or the EF result with the generic identifiers
70// 0x7b0000 and 0x7c0000. Also an event contained only one L2 and EF result.
71// From Run 2 on (eformat version 5) the HLT processor identifier is not anymore
72// stored in the module ID of the HLT result. Further there can be in one event several HLT result
73// records with the source identifier 0x7c. The different HLT results are distinguished
74// now with the module ID. A module ID 0 indicates a physiscs HLT result as before, while
75// HLT results with module IDs different from zero are produced by data scouting chains.
76// In Run 2 the module ID should be therefore not any more masked.
77// The masking of the moduleID is switched on when a L2 result is found in the event or the
78// event header contains L2 trigger info words. This means the data were produced with run 1 HLT system.
79// Revision: Aug 2026
80// Remove HLT-specific interfaces related to ROB requests and partial events.
81// Remove support for Run-1 data, i.e. the L2/EF module ID masking.
82//
83//===================================================================
84
86#include "eformat/Status.h"
87
88#include <algorithm>
89
90
93 ATH_MSG_INFO("Initializing");
94
95 for (const auto& [srcid, status] : m_filterRobWithStatus) {
96 eformat::helper::SourceIdentifier src(srcid);
97 if (src.human_detector() != "UNKNOWN") {
98 m_filterRobMap[src.code()].push_back(status);
99 }
100 }
101 for (const auto& [subdet, status] : m_filterSubDetWithStatus) {
102 eformat::helper::SourceIdentifier src(static_cast<eformat::SubDetector>(subdet), 0);
103 if (src.human_detector() != "UNKNOWN") {
104 m_filterSubDetMap[src.subdetector_id()].push_back(status);
105 }
106 }
107 ATH_MSG_INFO("---> Filter out empty ROB fragments = " << std::boolalpha << m_filterEmptyROB.value());
108 ATH_MSG_INFO("---> Filter out specific ROBs by Status Code: # ROBs = " << m_filterRobMap.size());
109
110 for (const auto& [id, status_vec] : m_filterRobMap) {
111 eformat::helper::SourceIdentifier src(id);
112 ATH_MSG_INFO(" RobId=0x" << MSG::hex << id << " -> in Sub Det = " << src.human_detector());
113 for (uint32_t status : status_vec) {
114 eformat::helper::Status tmpstatus(status);
115 ATH_MSG_INFO(" Status Code=0x"
116 << MSG::hex << std::setfill( '0' ) << std::setw(8) << tmpstatus.code()
117 << " Generic Part=0x" << std::setw(4) << tmpstatus.generic()
118 << " Specific Part=0x" << std::setw(4) << tmpstatus.specific());
119 }
120 }
121
122 ATH_MSG_INFO("---> Filter out Sub Detector ROBs by Status Code: # Sub Detectors = " <<
123 m_filterSubDetMap.size());
124
125 for (const auto& [det, status_vec] : m_filterSubDetMap) {
126 eformat::helper::SourceIdentifier src(det, 0);
127 ATH_MSG_INFO(" SubDetId=0x" << MSG::hex << det << " -> " << src.human_detector());
128 for (uint32_t status : status_vec) {
129 eformat::helper::Status tmpstatus(status);
130 ATH_MSG_INFO(" Status Code=0x" <<
131 MSG::hex << std::setfill( '0' ) << std::setw(8) << tmpstatus.code() <<
132 " Generic Part=0x" << std::setw(4) << tmpstatus.generic() <<
133 " Specific Part=0x" << std::setw(4) << tmpstatus.specific());
134 }
135 }
136 return StatusCode::SUCCESS;
137}
138
139
141void ROBDataProviderSvc::setNextEvent( const EventContext& ctx, const RawEvent* re ) {
142
143 EventCache* cache = m_eventsCache.get(ctx);
144 // assign the event
145 cache->event=re;
146 // clear the old map
147 cache->robmap.clear();
148 // set the LVL1 id
149 cache->currentLvl1ID = re->lvl1_id();
150
151 // loop over all ROBs
152 auto iter = re->child_iter();
153 while (OFFLINE_FRAGMENTS_NAMESPACE::PointerType fp = iter.next()) {
154 // create ROBFragment
155 auto rob = std::make_unique<const ROBF>(fp);
156 const uint32_t id = rob->source_id();
157
158 if (filterRobWithStatus(rob.get())) {
159 if (rob->nstatus() > 0) {
160 const uint32_t* it_status;
161 rob->status(it_status);
162 eformat::helper::Status tmpstatus(*it_status);
163 ATH_MSG_DEBUG("---> ROB Id = 0x" << MSG::hex << id << std::setfill('0') <<
164 " with Generic Status Code = 0x" << std::setw(4) << tmpstatus.generic() <<
165 " and Specific Status Code = 0x" << std::setw(4) << tmpstatus.specific() << MSG::dec <<
166 " removed for L1 Id = " << cache->currentLvl1ID);
167 }
168 rob.reset();
169 } else if ((rob->rod_ndata() == 0) && m_filterEmptyROB) {
170 ATH_MSG_DEBUG("---> Empty ROB Id = 0x" << MSG::hex << id << MSG::dec <<
171 " removed for L1 Id = " << cache->currentLvl1ID);
172 rob.reset();
173 } else {
174 // add to the map, warn in case of overwrite
175 const auto& [itr, new_entry] = cache->robmap.insert_or_assign(id, std::move(rob));
176 if (!new_entry) {
177 ATH_MSG_WARNING("ROBDataProviderSvc:: Duplicate ROBID 0x" << MSG::hex << id <<
178 " found. " << MSG::dec << "Overwriting the previous one.");
179 }
180 }
181 }
182 ATH_MSG_DEBUG("---> setNextEvent offline for " << name() <<
183 ", current LVL1 id = " << cache->currentLvl1ID <<
184 ", size of ROB cache = " << cache->robmap.size());
185}
186
187
189void ROBDataProviderSvc::getROBData(const EventContext& ctx, const std::vector<uint32_t>& ids,
190 VROBFRAG& robFragments, const std::string_view callerName) {
191
192 EventCache* cache = m_eventsCache.get(ctx);
193
194 for (uint32_t id : ids) {
195 const auto map_it = cache->robmap.find(id);
196 if (map_it != cache->robmap.end()) {
197 robFragments.push_back(map_it->second.get());
198 } else {
199 ATH_MSG_DEBUG("Failed to find ROB for id 0x" << MSG::hex << id << MSG::dec << ", Caller Name = " << callerName);
200 }
201 }
202}
203
204
206const RawEvent* ROBDataProviderSvc::getEvent( const EventContext& ctx ) {
207 return m_eventsCache.get(ctx)->event;
208}
209
210
212void ROBDataProviderSvc::setEventStatus(const EventContext& ctx, uint32_t status) {
213 m_eventsCache.get(ctx)->eventStatus = status;
214}
215
216
218uint32_t ROBDataProviderSvc::getEventStatus( const EventContext& ctx ) {
219 return m_eventsCache.get(ctx)->eventStatus;
220}
221
222
223void ROBDataProviderSvc::processCachedROBs(const EventContext& ctx,
224 const std::function< void(const ROBF* )>& fn ) const {
225 for ( const auto& el : m_eventsCache.get(ctx)->robmap ) {
226 fn( el.second.get() );
227 }
228}
229
230
233 // No filter criteria defined
234 if (m_filterRobMap.empty() && m_filterSubDetMap.empty()) {
235 return false;
236 }
237 // There should be at least one status element if there was an error
238 // in case there are 0 status elements then there was no known error
239 // (see event format document ATL-D-ES-0019 (EDMS))
240 if (rob->nstatus() == 0) {
241 return false;
242 }
243 // The ROB has at least one status element, access it via an iterator
244 const uint32_t* rob_it_status;
245 rob->status(rob_it_status);
246
247 // Build the full ROB Sourceidentifier
248 eformat::helper::SourceIdentifier src(rob->rob_source_id());
249 // Check if there is a ROB specific filter rule defined for this ROB Id and match the status code
250 if (auto it = m_filterRobMap.find(src.code()); it != m_filterRobMap.end()) {
251 if (std::ranges::contains(it->second, *rob_it_status))
252 return true;
253 }
254
255 // Check if there is a sub detector specific filter rule defined for this ROB Id and match the status code
256 if (auto it = m_filterSubDetMap.find(src.subdetector_id()); it != m_filterSubDetMap.end()) {
257 if (std::ranges::contains(it->second, *rob_it_status))
258 return true;
259 }
260
261 return false;
262}
const std::regex re(r_e)
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_INFO(x,...)
OFFLINE_FRAGMENTS_NAMESPACE::FullEventFragment RawEvent
data type for reading raw event
Definition RawEvent.h:37
virtual uint32_t getEventStatus(const EventContext &ctx) override
Retrieve the status for the event.
virtual void processCachedROBs(const EventContext &ctx, const std::function< void(const ROBF *)> &fn) const override
virtual const RawEvent * getEvent(const EventContext &ctx) override
Retrieve the whole event.
virtual StatusCode initialize() override
Initialize.
std::unordered_map< uint32_t, std::vector< uint32_t > > m_filterRobMap
map of full ROB Source ids and status words to be ignored for the ROB map
virtual void setNextEvent(const EventContext &ctx, const RawEvent *re) override
Add all ROBFragments of a RawEvent to cache.
Gaudi::Property< std::vector< std::pair< int, int > > > m_filterSubDetWithStatus
Gaudi::Property< bool > m_filterEmptyROB
virtual void getROBData(const EventContext &ctx, const std::vector< uint32_t > &robIds, VROBFRAG &robFragments, const std::string_view callerName="UNKNOWN") override
Retrieve ROBFragments for given ROB ids from cache.
bool filterRobWithStatus(const ROBF *rob)
method to filter ROBs with given Status code
virtual void setEventStatus(const EventContext &ctx, uint32_t status) override
Store the status for the event.
Gaudi::Property< std::vector< std::pair< int, int > > > m_filterRobWithStatus
OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment ROBF
ROB Fragment class.
SG::SlotSpecificObj< EventCache > m_eventsCache
std::unordered_map< eformat::SubDetector, std::vector< uint32_t > > m_filterSubDetMap
map of Sub Det Source ids and status words to be ignored for the ROB map
const DataType * PointerType
Definition RawEvent.h:25
ROB fragment cache per slot.