ATLAS Offline Software
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
24 namespace {
29  constexpr uint16_t fullResultModuleId = 0;
30 }
31 
32 // Local helper methods
33 namespace {
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__);
66  ATH_CHECK(m_ByteStreamEventAccess.retrieve());
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 // =============================================================================
85 StatusCode 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 // =============================================================================
94 StatusCode 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 // =============================================================================
255 }
256 
258 {
260 }
HLT::HLTResultMTByteStreamCnv::createRep
virtual StatusCode createRep(DataObject *pObj, IOpaqueAddress *&pAddr) override
Create ByteStream from RDO (HLTResultMT)
Definition: HLTResultMTByteStreamCnv.cxx:94
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
RawEventWrite
OFFLINE_FRAGMENTS_NAMESPACE_WRITE::FullEventFragment RawEventWrite
data type for writing raw event
Definition: RawEvent.h:39
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
HLT::HLTResultMT::getStreamTags
const std::vector< eformat::helper::StreamTag > & getStreamTags() const
Const-getter for stream tags.
Definition: HLTResultMT.cxx:43
AthCheckMacros.h
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
SG::fromStorable
bool fromStorable(DataObject *pDObj, T *&pTrans, bool quiet=false, IRegisterTransient *irt=0, bool isConst=true)
Definition: StorableConversions.h:180
StorableConversions.h
convert to and from a SG storable
skel.it
it
Definition: skel.GENtoEVGEN.py:396
HLT::HLTResultMT
A container class for data required to build online output from HLT.
Definition: HLTResultMT.h:38
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
HLT::HLTResultMTByteStreamCnv::Cache::robFragments
std::vector< std::unique_ptr< OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment > > robFragments
Definition: HLTResultMTByteStreamCnv.h:53
HLT::HLTResultMTByteStreamCnv::Cache::streamTagData
std::unique_ptr< uint32_t[]> streamTagData
Definition: HLTResultMTByteStreamCnv.h:52
ClassID_traits::ID
static const CLID & ID()
the CLID of T
Definition: Control/AthenaKernel/AthenaKernel/ClassID_traits.h:50
HLT::HLTResultMT::getRobStatus
const std::vector< uint32_t > & getRobStatus(uint16_t moduleId) const
Status words for ROB with given moduleId.
Definition: HLTResultMT.cxx:226
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
AtlasMcWeight::encode
number_type encode(double weight)
Definition: AtlasMcWeight.cxx:65
xAOD::uint16_t
setWord1 uint16_t
Definition: eFexEMRoI_v1.cxx:88
StdJOSetup.msgSvc
msgSvc
Provide convenience handles for various services.
Definition: StdJOSetup.py:36
ClassID_traits.h
a traits class that associates a CLID to a type T It also detects whether T inherits from Gaudi DataO...
RawEvent.h
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
HLTResultMTByteStreamCnv.h
ByteStreamAddress
IOpaqueAddress for ByteStreamCnvSvc, with ROB ids.
Definition: ByteStreamAddress.h:28
calibdata.exception
exception
Definition: calibdata.py:496
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
HLT::HLTResultMTByteStreamCnv::storageType
static long storageType()
Storage type used by this converter.
Definition: HLTResultMTByteStreamCnv.cxx:257
ByteStreamAddress.h
HLT::HLTResultMT::getVersion
RODMinorVersion getVersion() const
ROD minor version getter.
Definition: HLTResultMT.cxx:239
CLID
uint32_t CLID
The Class ID type.
Definition: Event/xAOD/xAODCore/xAODCore/ClassID_traits.h:47
HLT::HLTResultMTByteStreamCnv::Cache
Cache tracking memory allocation for serialised stream tag data and ROBFragment objects.
Definition: HLTResultMTByteStreamCnv.h:51
ByteStreamAddress::storageType
static constexpr long storageType()
Definition: ByteStreamAddress.h:51
HLT::HLTResultMTByteStreamCnv::Cache::clear
void clear()
Definition: HLTResultMTByteStreamCnv.h:55
Converter
Definition: Converter.h:27
HLT::HLTResultMT::getSerialisedData
const std::unordered_map< uint16_t, std::vector< uint32_t > > & getSerialisedData() const
Serialised data getter.
Definition: HLTResultMT.cxx:147
HLT::HLTResultMT::getStreamTagsNonConst
std::vector< eformat::helper::StreamTag > & getStreamTagsNonConst()
Non-const-getter for stream tags needed by the result maker to remove disabled ROBs/SubDets.
Definition: HLTResultMT.cxx:48
HLT::HLTResultMTByteStreamCnv::initialize
virtual StatusCode initialize() override
Definition: HLTResultMTByteStreamCnv.cxx:64
HLT::HLTResultMT::RODMinorVersion
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
HLTResultMT.h
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
re
const boost::regex re(r_e)
HLT::HLTResultMT::getStatus
const std::vector< uint32_t > & getStatus() const
Full event status reference getter (1 bit-mask status word + error code words)
Definition: HLTResultMT.cxx:196
JiveXML::TagType
std::pair< std::string, std::string > TagType
Defines a tag as a pair of strings.
Definition: DataType.h:62
HLT::HLTResultMTByteStreamCnv::classID
static const CLID & classID()
CLID of the class HLTResultMT converted by this converter.
Definition: HLTResultMTByteStreamCnv.cxx:253
merge.status
status
Definition: merge.py:17
HLT::HLTResultMTByteStreamCnv::HLTResultMTByteStreamCnv
HLTResultMTByteStreamCnv(ISvcLocator *svcLoc)
Standard constructor.
Definition: HLTResultMTByteStreamCnv.cxx:51
HLT::HLTResultMT::getHltBitsAsWords
const std::vector< uint32_t > & getHltBitsAsWords() const
Const-getter for HLT bits as uint32_t array. Ordering: PassRaw, Prescaled.
Definition: HLTResultMT.cxx:100
HLT::HLTResultMTByteStreamCnv::~HLTResultMTByteStreamCnv
virtual ~HLTResultMTByteStreamCnv()
Standard destructor.
Definition: HLTResultMTByteStreamCnv.cxx:59
HLT::HLTResultMTByteStreamCnv::finalize
virtual StatusCode finalize() override
Definition: HLTResultMTByteStreamCnv.cxx:74
HLT::HLTResultMTByteStreamCnv::createObj
virtual StatusCode createObj(IOpaqueAddress *pAddr, DataObject *&pObj) override
Create RDO (HLTResultMT) from ByteStream.
Definition: HLTResultMTByteStreamCnv.cxx:85