ATLAS Offline Software
Loading...
Searching...
No Matches
MCEventInfoByteStreamTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include "eformat/SourceIdentifier.h"
8#include "eformat/Status.h"
9#include "CxxUtils/span.h"
11
12#include <bit>
13#include <format>
14
15namespace {
16 const SG::AuxElement::Accessor<uint64_t> acc_pileUpMixtureLow("pileUpMixtureIDLowBits");
17 const SG::AuxElement::Accessor<uint64_t> acc_pileUpMixtureHigh("pileUpMixtureIDHighBits");
18}
19
22
24 const std::string& name,
25 const IInterface* parent)
26 : base_class(type, name, parent) {}
27
29 ATH_MSG_DEBUG("Initializing MCEventInfoByteStreamTool");
30
31 // Check if we're in encoding mode (reading EventInfo from store)
32 if (!m_eventInfoReadKey.empty()) {
33 ATH_CHECK(m_eventInfoReadKey.initialize());
34 ATH_MSG_DEBUG(std::format("Encoding mode: will read EventInfo from {}", m_eventInfoReadKey.key()));
35 } else {
36 ATH_MSG_DEBUG("Decoding mode: will decode MC EventInfo from ROB fragment");
37 }
38
39 ATH_MSG_DEBUG("ROB IDs: " << MSG::hex << m_robIds.value() << MSG::dec);
40 return StatusCode::SUCCESS;
41}
42
43StatusCode MCEventInfoByteStreamTool::convertToBS(std::vector<WROBF*>& vrobf,
44 const EventContext& eventContext) {
45 ATH_MSG_DEBUG("convertToBS called");
46
47 if (m_eventInfoReadKey.empty()) {
48 ATH_MSG_ERROR("EventInfoReadKey not configured for encoding");
49 return StatusCode::FAILURE;
50 }
51
52 // Retrieve EventInfo
53 auto evtInfoHandle = SG::makeHandle(m_eventInfoReadKey, eventContext);
54 if (!evtInfoHandle.isValid()) {
55 ATH_MSG_ERROR("Failed to retrieve EventInfo from " << m_eventInfoReadKey.key());
56 return StatusCode::FAILURE;
57 }
58 const xAOD::EventInfo* evtInfo = evtInfoHandle.cptr();
59
60 // Check if this is simulation
62 ATH_MSG_DEBUG("Event is not simulation, skipping MC EventInfo encoding");
63 return StatusCode::SUCCESS;
64 }
65
66 // Clear BS data cache
67 clearCache(eventContext);
68
69 // Get MC fields
70 uint32_t mcChannelNumber = evtInfo->mcChannelNumber();
71 uint64_t mcEventNumber = evtInfo->mcEventNumber();
72 float actualMu = evtInfo->actualInteractionsPerCrossing();
73 float averageMu = evtInfo->averageInteractionsPerCrossing();
74 uint32_t eventTypeBitmask = evtInfo->eventTypeBitmask();
75 uint32_t extendedLevel1ID = evtInfo->extendedLevel1ID();
76 uint32_t backgroundFlags = evtInfo->eventFlags(xAOD::EventInfo::Background);
77
78 // Get pileup mixture ID
79 uint64_t pileUpMixtureLow = 0;
80 uint64_t pileUpMixtureHigh = 0;
81 if (acc_pileUpMixtureLow.isAvailable(*evtInfo)) {
82 pileUpMixtureLow = acc_pileUpMixtureLow(*evtInfo);
83 }
84 if (acc_pileUpMixtureHigh.isAvailable(*evtInfo)) {
85 pileUpMixtureHigh = acc_pileUpMixtureHigh(*evtInfo);
86 }
87
88 // Get MC weights
89 const std::vector<float>& weights = evtInfo->mcEventWeights();
90 uint32_t nWeights = static_cast<uint32_t>(weights.size());
91
92 // Calculate total data size
93 size_t ndata = MIN_DATA_WORDS + nWeights;
94
95 ATH_MSG_DEBUG("Encoding MC EventInfo: mcChannelNumber=" << mcChannelNumber
96 << ", mcEventNumber=" << mcEventNumber
97 << ", actualMu=" << actualMu
98 << ", averageMu=" << averageMu
99 << ", eventTypeBitmask=0x" << std::hex << eventTypeBitmask << std::dec
100 << ", extendedLevel1ID=" << extendedLevel1ID
101 << ", backgroundFlags=0x" << std::hex << backgroundFlags << std::dec
102 << ", nWeights=" << nWeights);
103
104 // Allocate ROD data
105 uint32_t* data = newRodData(eventContext, ndata);
106
107 // Fill ROD data
108 size_t idx = 0;
109
110 // Word 0: Version
111 data[idx++] = FORMAT_VERSION;
112
113 // Word 1: mcChannelNumber
114 data[idx++] = mcChannelNumber;
115
116 // Word 2-3: mcEventNumber (low, high)
117 data[idx++] = static_cast<uint32_t>(mcEventNumber & 0xFFFFFFFF);
118 data[idx++] = static_cast<uint32_t>(mcEventNumber >> 32);
119
120 // Word 4: actualInteractionsPerCrossing
121 data[idx++] = std::bit_cast<uint32_t>(actualMu);
122
123 // Word 5: averageInteractionsPerCrossing
124 data[idx++] = std::bit_cast<uint32_t>(averageMu);
125
126 // Word 6: eventTypeBitmask
127 data[idx++] = eventTypeBitmask;
128
129 // Word 7-8: pileUpMixtureIDLowBits (low, high)
130 data[idx++] = static_cast<uint32_t>(pileUpMixtureLow & 0xFFFFFFFF);
131 data[idx++] = static_cast<uint32_t>(pileUpMixtureLow >> 32);
132
133 // Word 9-10: pileUpMixtureIDHighBits (low, high)
134 data[idx++] = static_cast<uint32_t>(pileUpMixtureHigh & 0xFFFFFFFF);
135 data[idx++] = static_cast<uint32_t>(pileUpMixtureHigh >> 32);
136
137 // Word 11: extendedLevel1ID
138 data[idx++] = extendedLevel1ID;
139
140 // Word 12: backgroundFlags
141 data[idx++] = backgroundFlags;
142
143 // Word 13: number of weights
144 data[idx++] = nWeights;
145
146 // Words 14+: mcEventWeights
147 for (size_t i = 0; i < nWeights; ++i) {
148 data[idx++] = std::bit_cast<uint32_t>(weights[i]);
149 }
150
151 // Create ROB fragment
152 vrobf.push_back(newRobFragment(eventContext, m_robIds.value().at(0), ndata, data));
153
154 ATH_MSG_DEBUG("Created MC EventInfo ROB fragment with " << ndata << " words");
155 return StatusCode::SUCCESS;
156}
157
159 xAOD::EventInfo& evtInfo) const {
160 if (!rob) {
161 ATH_MSG_ERROR("Null ROB fragment pointer");
162 return StatusCode::FAILURE;
163 }
164
165 // Get ROD data
166 const uint32_t ndata = rob->rod_ndata();
167 const uint32_t* data = rob->rod_data();
168
169 ATH_MSG_DEBUG("Decoding MC EventInfo ROB fragment with " << ndata << " words");
170
171 if (ndata < MIN_DATA_WORDS) {
172 ATH_MSG_ERROR("ROB data too short: " << ndata << " words, expected at least " << MIN_DATA_WORDS);
173 return StatusCode::FAILURE;
174 }
175
176 // Read version
177 uint32_t version = data[0];
178 if ((version & 0xFFFF0000) != (FORMAT_VERSION & 0xFFFF0000)) {
179 ATH_MSG_ERROR("Unsupported MC EventInfo format version: 0x" << std::hex << version << std::dec);
180 return StatusCode::FAILURE;
181 }
182
183 // Read MC fields
184 uint32_t mcChannelNumber = data[1];
185 uint64_t mcEventNumber = static_cast<uint64_t>(data[2]) | (static_cast<uint64_t>(data[3]) << 32);
186 float actualMu = std::bit_cast<float>(data[4]);
187 float averageMu = std::bit_cast<float>(data[5]);
188 uint32_t eventTypeBitmask = data[6];
189 uint64_t pileUpMixtureLow = static_cast<uint64_t>(data[7]) | (static_cast<uint64_t>(data[8]) << 32);
190 uint64_t pileUpMixtureHigh = static_cast<uint64_t>(data[9]) | (static_cast<uint64_t>(data[10]) << 32);
191 uint32_t extendedLevel1ID = data[11];
192 uint32_t backgroundFlags = data[12];
193 uint32_t nWeights = data[13];
194
195 // Validate weight count
196 if (ndata < MIN_DATA_WORDS + nWeights) {
197 ATH_MSG_ERROR("ROB data too short for " << nWeights << " weights: " << ndata << " words");
198 return StatusCode::FAILURE;
199 }
200
201 // Read weights
202 std::vector<float> weights(nWeights);
203 for (size_t i = 0; i < nWeights; ++i) {
204 weights[i] = std::bit_cast<float>(data[MIN_DATA_WORDS + i]);
205 }
206
207 ATH_MSG_DEBUG("Decoded MC EventInfo: mcChannelNumber=" << mcChannelNumber
208 << ", mcEventNumber=" << mcEventNumber
209 << ", actualMu=" << actualMu
210 << ", averageMu=" << averageMu
211 << ", eventTypeBitmask=0x" << std::hex << eventTypeBitmask << std::dec
212 << ", extendedLevel1ID=" << std::dec << extendedLevel1ID
213 << ", backgroundFlags=0x" << std::hex << backgroundFlags << std::dec
214 << ", nWeights=" << nWeights);
215
216 // Fill EventInfo
217 evtInfo.setMCChannelNumber(mcChannelNumber);
218 evtInfo.setMCEventNumber(mcEventNumber);
219 evtInfo.setMCEventWeights(weights);
220 evtInfo.setActualInteractionsPerCrossing(actualMu);
221 evtInfo.setAverageInteractionsPerCrossing(averageMu);
222 evtInfo.setEventTypeBitmask(eventTypeBitmask);
223 evtInfo.setExtendedLevel1ID(extendedLevel1ID);
224 evtInfo.setEventFlags(xAOD::EventInfo::Background, backgroundFlags);
225
226 // Set pileup mixture ID as auxiliary data
227 acc_pileUpMixtureLow(evtInfo) = pileUpMixtureLow;
228 acc_pileUpMixtureHigh(evtInfo) = pileUpMixtureHigh;
229
230 return StatusCode::SUCCESS;
231}
232
233void MCEventInfoByteStreamTool::clearCache(const EventContext& eventContext) {
234 m_cache.get(eventContext)->clear();
235}
236
237uint32_t* MCEventInfoByteStreamTool::newRodData(const EventContext& eventContext, size_t size) {
238 Cache* cache = m_cache.get(eventContext);
239 cache->rodData.push_back(std::make_unique<uint32_t[]>(size));
240 return cache->rodData.back().get();
241}
242
243WROBF* MCEventInfoByteStreamTool::newRobFragment(const EventContext& eventContext,
244 uint32_t source_id,
245 uint32_t ndata,
246 const uint32_t* data) {
247 Cache* cache = m_cache.get(eventContext);
248 const EventIDBase& eid = eventContext.eventID();
249 cache->robFragments.push_back(std::make_unique<WROBF>(
250 source_id,
251 eid.run_number(),
252 0, // lvl1_id will be overwritten downstream
253 eid.bunch_crossing_id(),
254 0, // lvl1_type will be overwritten downstream
255 0, // detev_type
256 ndata,
257 data,
258 eformat::STATUS_BACK
259 ));
260 return cache->robFragments.back().get();
261}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
Base class for elements of a container that can have aux data.
OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment ROBF
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment WROBF
Tool for encoding/decoding MC EventInfo to/from ByteStream.
size_t size() const
Number of registered mappings.
virtual StatusCode convertFromBS(const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment *rob, xAOD::EventInfo &evtInfo) const override
Decode MC EventInfo from ROB fragment and fill xAOD::EventInfo.
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoReadKey
virtual StatusCode convertToBS(std::vector< OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment * > &vrobf, const EventContext &eventContext) override
Convert xAOD::EventInfo MC fields to ByteStream ROB fragment.
MCEventInfoByteStreamTool(const std::string &type, const std::string &name, const IInterface *parent)
static constexpr uint32_t FORMAT_VERSION
Version word for the data format.
void clearCache(const EventContext &eventContext)
Helper to clear the ByteStream data cache for a given event slot.
OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment * newRobFragment(const EventContext &eventContext, uint32_t source_id, uint32_t ndata, const uint32_t *data)
Allocate new ROBFragment for output ByteStream data.
virtual StatusCode initialize() override
static constexpr uint32_t MIN_DATA_WORDS
Minimum number of words in the ROB data (excluding weights).
SG::SlotSpecificObj< Cache > m_cache
Gaudi::Property< std::vector< uint32_t > > m_robIds
uint32_t * newRodData(const EventContext &eventContext, size_t size)
Allocate new array of raw ROD words for output ByteStream data.
uint64_t mcEventNumber() const
The MC generator's event number.
const std::vector< float > & mcEventWeights() const
The weights of all the MC events used in the simulation.
void setAverageInteractionsPerCrossing(float value)
Set average interactions per crossing for all BCIDs.
void setMCEventNumber(uint64_t value)
Set the MC generator's event number.
bool eventType(EventType type) const
Check for one particular bitmask value.
uint32_t eventTypeBitmask() const
The event type bitmask.
@ Background
The beam background detectors.
bool setEventFlags(EventFlagSubDet subDet, uint32_t flags)
Set the event flags for a particular sub-detector.
float averageInteractionsPerCrossing() const
Average interactions per crossing for all BCIDs - for out-of-time pile-up.
float actualInteractionsPerCrossing() const
Average interactions per crossing for the current BCID - for in-time pile-up.
void setEventTypeBitmask(uint32_t value)
Set the event type bitmask.
void setMCChannelNumber(uint32_t value)
Set the MC generator's channel number.
void setExtendedLevel1ID(uint32_t value)
Set the extended Level-1 identifier.
uint32_t eventFlags(EventFlagSubDet subDet) const
Get the event flags for a particular sub-detector.
void setMCEventWeights(const std::vector< float > &value)
Set the weights of all the MC events used in the simulation.
@ IS_SIMULATION
true: simulation, false: data
uint32_t mcChannelNumber() const
The MC generator's channel number.
uint32_t extendedLevel1ID() const
The extended Level-1 identifier.
void setActualInteractionsPerCrossing(float value)
Set average interactions per crossing for the current BCID.
eformat::write::ROBFragment ROBFragment
Definition RawEvent.h:33
eformat::ROBFragment< PointerType > ROBFragment
Definition RawEvent.h:27
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
EventInfo_v1 EventInfo
Definition of the latest event info version.
Simplified version of the C++20 std::span.