ATLAS Offline Software
Loading...
Searching...
No Matches
HLTResultMTByteStreamCnv.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Trigger includes
8
9// Athena includes
15
16// Gaudi includes
17#include "GaudiKernel/IRegistry.h"
18
19// TDAQ includes
20#include "eformat/Issue.h"
21#include "eformat/SourceIdentifier.h"
22
23// Local constants
24namespace {
29 constexpr uint16_t fullResultModuleId = 0;
30}
31
32// Local helper methods
33namespace {
35 bool isStreamTagType(const eformat::helper::StreamTag& st, const eformat::TagType type) {
36 return eformat::helper::string_to_tagtype(st.type) == type;
37 }
39 bool isDebugStreamTag(const eformat::helper::StreamTag& st) {
40 return isStreamTagType(st, eformat::TagType::DEBUG_TAG);
41 }
43 bool isUnknownStreamTag(const eformat::helper::StreamTag& st) {
44 return isStreamTagType(st, eformat::TagType::UNKNOWN_TAG);
45 }
46}
47
48// =============================================================================
49// Standard constructor
50// =============================================================================
52 Converter(storageType(), classID(), svcLoc),
53 AthMessaging(msgSvc(), "HLTResultMTByteStreamCnv"),
54 m_ByteStreamEventAccess("ByteStreamCnvSvc", "HLTResultMTByteStreamCnv") {}
55
56// =============================================================================
57// Standard destructor
58// =============================================================================
60
61// =============================================================================
62// Implementation of Converter::initialize
63// =============================================================================
65 ATH_MSG_VERBOSE("start of " << __FUNCTION__);
67 ATH_MSG_VERBOSE("end of " << __FUNCTION__);
68 return StatusCode::SUCCESS;
69}
70
71// =============================================================================
72// Implementation of Converter::finalize
73// =============================================================================
75 ATH_MSG_VERBOSE("start of " << __FUNCTION__);
76 if (m_ByteStreamEventAccess.release().isFailure())
77 ATH_MSG_WARNING("Failed to release service " << m_ByteStreamEventAccess.typeAndName());
78 ATH_MSG_VERBOSE("end of " << __FUNCTION__);
79 return StatusCode::SUCCESS;
80}
81
82// =============================================================================
83// Implementation of Converter::createObj
84// =============================================================================
85StatusCode HLT::HLTResultMTByteStreamCnv::createObj(IOpaqueAddress* /*pAddr*/, DataObject*& /*pObj*/) {
86 ATH_MSG_ERROR("Using BS converter to decode HLTResultMT is not supported!"
87 << " Use HLTResultMTByteStreamDecoderAlg instead");
88 return StatusCode::FAILURE;
89}
90
91// =============================================================================
92// Implementation of Converter::createRep
93// =============================================================================
94StatusCode HLT::HLTResultMTByteStreamCnv::createRep(DataObject* pObj, IOpaqueAddress*& pAddr) {
95 ATH_MSG_VERBOSE("start of " << __FUNCTION__);
96
97 // Find the cache corresponding to the current slot
98 Cache* cache = m_cache.get(); // TODO: find a way to avoid using thread-local context here
99
100 // Clear the cache which is required to remain valid between being filled here
101 // and sending out the correspoding RawEventWrite in (Trig)ByteStreamCnvSvc::commitOutput
102 cache->clear();
103
104 // Cast the DataObject to HLTResultMT
105 HLT::HLTResultMT* hltResult = nullptr;
106 bool castSuccessful = SG::fromStorable(pObj, hltResult);
107 if (!castSuccessful || !hltResult) {
108 ATH_MSG_ERROR("Failed to convert DataObject to HLTResultMT");
109 return StatusCode::FAILURE;
110 }
111
112 // Check ROD minor version
113 const HLT::HLTResultMT::RODMinorVersion hltRodMinorVersion = hltResult->getVersion();
114 if (hltRodMinorVersion == HLT::HLTResultMT::RODMinorVersion{0xff,0xff}) {
115 ATH_MSG_ERROR("Invalid HLT ROD minor version {0xff, 0xff}");
116 return StatusCode::FAILURE;
117 }
118 // Encode version X.Y (two 8-bit numbers) into a single 16-bit number
119 const uint16_t hltRodMinorVersion16 = (hltRodMinorVersion.first << 8u) | hltRodMinorVersion.second;
120 ATH_MSG_DEBUG("HLT ROD minor version is " << hltRodMinorVersion.first << "." << hltRodMinorVersion.second
121 << " (0x" << MSG::hex << hltRodMinorVersion16 << MSG::dec << ")");
122
123 // Obtain the RawEventWrite (aka eformat::write::FullEventFragment) pointer
124 RawEventWrite* re = m_ByteStreamEventAccess->getRawEvent();
125 if (!re) {
126 ATH_MSG_ERROR("Failed to obtain a pointer to RawEventWrite");
127 return StatusCode::FAILURE;
128 }
129 ATH_MSG_VERBOSE("Obtained RawEventWrite pointer = " << re);
130
131 // Fill the status words (error code)
132 re->status(hltResult->getStatus().size(), hltResult->getStatus().data());
133
134 // Read the stream tags to check for debug stream tag and decide which HLT ROBFragments to write out
135 std::set<eformat::helper::SourceIdentifier> resultIdsToWrite;
136 bool debugEvent=false;
137 std::string unknownTypeStreams;
138 for (const eformat::helper::StreamTag& st : hltResult->getStreamTags()) {
139 // Flag events with unknown stream type
140 if (isUnknownStreamTag(st)) {
141 unknownTypeStreams += st.type + "_" + st.name + " ";
142 }
143 // Flag debug stream events
144 if (isDebugStreamTag(st)) debugEvent=true;
145 // In case of full event building, add the full result ID
146 if (st.robs.empty() && st.dets.empty()) {
147 eformat::helper::SourceIdentifier sid(eformat::SubDetector::TDAQ_HLT, fullResultModuleId);
148 resultIdsToWrite.insert(sid);
149 }
150 // In case of partial event building, add the results explicitly requested in the stream tag
151 for (const uint32_t robid : st.robs) {
152 eformat::helper::SourceIdentifier sid(robid);
153 if (sid.subdetector_id() == eformat::SubDetector::TDAQ_HLT)
154 resultIdsToWrite.insert(sid);
155 }
156 }
157 // Fail if the event is not already failed (debug stream) and unknown stream type was found
158 if (!debugEvent && !unknownTypeStreams.empty()) {
159 ATH_MSG_ERROR("Found stream tag(s) with unknown type: " << unknownTypeStreams);
160 return StatusCode::FAILURE;
161 }
162
163 // If the event goes to the debug stream, remove all non-debug stream tags
164 // and force full event building in all debug streams
165 if (debugEvent) {
166 std::vector<eformat::helper::StreamTag>& writableStreamTags = hltResult->getStreamTagsNonConst();
167 writableStreamTags.erase(
168 std::remove_if(writableStreamTags.begin(),writableStreamTags.end(),std::not_fn(isDebugStreamTag)),
169 writableStreamTags.end()
170 );
171 for (eformat::helper::StreamTag& st : writableStreamTags) {
172 st.robs.clear();
173 st.dets.clear();
174 }
175 }
176
177 // Fill the stream tags
178 uint32_t nStreamTagWords = eformat::helper::size_word(hltResult->getStreamTags());
179 cache->streamTagData = std::make_unique<uint32_t[]>(nStreamTagWords);
180 try {
181 // encode can throw exceptions if the encoding fails
182 eformat::helper::encode(hltResult->getStreamTags(),nStreamTagWords,cache->streamTagData.get());
183 }
184 catch (const std::exception& e) {
185 ATH_MSG_ERROR("StreamTag encoding failed, caught an unexpected std::exception " << e.what());
186 return StatusCode::FAILURE;
187 }
188 catch (...) {
189 ATH_MSG_ERROR("StreamTag encoding failed, caught an unexpected exception");
190 return StatusCode::FAILURE;
191 }
192 ATH_MSG_DEBUG("Encoded the stream tags successfully");
193 re->stream_tag(nStreamTagWords, cache->streamTagData.get());
194
195 // Fill the HLT bits
196 const std::vector<uint32_t>& hltBits = hltResult->getHltBitsAsWords();
197 re->hlt_info(hltBits.size(), hltBits.data());
198
199 // Loop over the module IDs and fill the ROBFragments
200 ATH_MSG_DEBUG("Iterating over " << resultIdsToWrite.size() << " HLT result IDs to assemble output data");
201 const std::unordered_map<uint16_t, std::vector<uint32_t>>& serialisedData = hltResult->getSerialisedData();
202 for (const eformat::helper::SourceIdentifier& resultId : resultIdsToWrite) {
203 // Find the serialised data for this module ID
204 const auto it = serialisedData.find(resultId.module_id());
205 if (it==serialisedData.end()) {
206 if (debugEvent) {
207 ATH_MSG_DEBUG("HLT result with ID 0x" << MSG::hex << resultId.code() << MSG::dec
208 << " requested by a debug stream tag, but missing in the serialised data - skipping this result");
209 continue;
210 }
211 ATH_MSG_ERROR("HLT result with ID 0x" << MSG::hex << resultId.code() << MSG::dec
212 << " requested by a stream tag, but missing in the serialised data");
213 return StatusCode::FAILURE;
214 }
215 const std::vector<uint32_t>& data = it->second;
216
217 // Create an HLT ROBFragment and append it to the full event
218 auto hltROB = std::make_unique<OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment>(
219 resultId.code(),
220 re->run_no(),
221 re->lvl1_id(),
222 re->bc_id(),
223 re->lvl1_trigger_type(),
224 0, // detev_type not used by HLT
225 data.size(),
226 data.data(),
227 eformat::STATUS_BACK
228 );
229 hltROB->rod_minor_version(hltRodMinorVersion16);
230 // Fill the ROB status words
231 const std::vector<uint32_t>& status = hltResult->getRobStatus(resultId.module_id());
232 hltROB->status(status.size(), status.data());
233
234 re->append(hltROB.get());
235 cache->robFragments.push_back(std::move(hltROB));
236 ATH_MSG_DEBUG("Appended data for HLT result ID 0x" << MSG::hex << resultId.code() << MSG::dec << " with "
237 << data.size() << " words of serialised payload to the output full event");
238 }
239
240 // Create a ByteStreamAddress for HLTResultMT
241 if ( pAddr != nullptr ) pAddr->release();
242 ByteStreamAddress* bsAddr = new ByteStreamAddress(classID(), pObj->registry()->name(), "");
243 pAddr = static_cast<IOpaqueAddress*>(bsAddr);
244 pAddr->addRef();
245
246 ATH_MSG_VERBOSE("end of " << __FUNCTION__);
247 return StatusCode::SUCCESS;
248}
249
250// =============================================================================
251// CLID / storageType
252// =============================================================================
256
const boost::regex re(r_e)
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
a traits class that associates a CLID to a type T It also detects whether T inherits from Gaudi DataO...
uint32_t CLID
The Class ID type.
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
OFFLINE_FRAGMENTS_NAMESPACE_WRITE::FullEventFragment RawEventWrite
data type for writing raw event
Definition RawEvent.h:39
convert to and from a SG storable
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
IOpaqueAddress for ByteStreamCnvSvc, with ROB ids.
static constexpr long storageType()
virtual StatusCode initialize() override
virtual StatusCode createRep(DataObject *pObj, IOpaqueAddress *&pAddr) override
Create ByteStream from RDO (HLTResultMT)
SG::SlotSpecificObj< Cache > m_cache
static const CLID & classID()
CLID of the class HLTResultMT converted by this converter.
virtual StatusCode finalize() override
virtual ~HLTResultMTByteStreamCnv()
Standard destructor.
HLTResultMTByteStreamCnv(ISvcLocator *svcLoc)
Standard constructor.
virtual StatusCode createObj(IOpaqueAddress *pAddr, DataObject *&pObj) override
Create RDO (HLTResultMT) from ByteStream.
static long storageType()
Storage type used by this converter.
ServiceHandle< IByteStreamEventAccess > m_ByteStreamEventAccess
Helper to obtain the RawEvent pointer.
A container class for data required to build online output from HLT.
Definition HLTResultMT.h:38
const std::vector< uint32_t > & getHltBitsAsWords() const
Const-getter for HLT bits as uint32_t array. Ordering: PassRaw, Prescaled.
RODMinorVersion getVersion() const
ROD minor version getter.
const std::vector< eformat::helper::StreamTag > & getStreamTags() const
Const-getter for stream tags.
std::pair< uint8_t, uint8_t > RODMinorVersion
Type to store decoded ROD minor version (16-bit version split into two 8-bit numbers)
Definition HLTResultMT.h:50
const std::unordered_map< uint16_t, std::vector< uint32_t > > & getSerialisedData() const
Serialised data getter.
const std::vector< uint32_t > & getStatus() const
Full event status reference getter (1 bit-mask status word + error code words)
const std::vector< uint32_t > & getRobStatus(uint16_t moduleId) const
Status words for ROB with given moduleId.
std::vector< eformat::helper::StreamTag > & getStreamTagsNonConst()
Non-const-getter for stream tags needed by the result maker to remove disabled ROBs/SubDets.
bool fromStorable(DataObject *pDObj, T *&pTrans, bool quiet=false, IRegisterTransient *irt=0, bool isConst=true)
DataModel_detail::iterator< DVL > remove_if(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, Predicate pred)
Specialization of remove_if for DataVector/List.
setWord1 uint16_t
Cache tracking memory allocation for serialised stream tag data and ROBFragment objects.
std::vector< std::unique_ptr< OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment > > robFragments