ATLAS Offline Software
Loading...
Searching...
No Matches
L1TriggerResultByteStreamCnv.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Trigger includes
9
10// Athena includes
15
16// Gaudi includes
17#include "GaudiKernel/IRegistry.h"
18#include "GaudiKernel/ThreadLocalContext.h"
19
20// TDAQ includes
21#include "eformat/Issue.h"
22#include "eformat/SourceIdentifier.h"
23
25
26// =============================================================================
27// Standard constructor
28// =============================================================================
30 Converter(storageType(), classID(), svcLoc),
31 AthMessaging(msgSvc(), "L1TriggerResultByteStreamCnv") {}
32
33// =============================================================================
34// Standard destructor
35// =============================================================================
37
38// =============================================================================
39// Implementation of Converter::initialize
40// =============================================================================
42 ATH_MSG_VERBOSE("start of " << __FUNCTION__);
44
45 // Initialise ReadHandleKey for CTPResult used to encode L1 trigger bits for RawEventWrite
46 ATH_CHECK(m_inKeyCTPResult.initialize());
47
48 // Check one property of the encoder tools to determine if the tools are configured in the job
49 const bool doMuon = not serviceLocator()->getOptsSvc().get("ToolSvc.L1MuonBSEncoderTool.ROBIDs").empty();
50 ATH_MSG_DEBUG("MUCTPI BS encoding is " << (doMuon ? "enabled" : "disabled"));
51 ATH_CHECK(m_muonEncoderTool.retrieve(EnableTool(doMuon)));
52
53 const bool doMuonDaq = not serviceLocator()->getOptsSvc().get("ToolSvc.L1MuonBSEncoderToolDAQ.ROBIDs").empty();
54 ATH_MSG_DEBUG("MUCTPI DAQ ROB encoding is " << (doMuonDaq ? "enabled" : "disabled"));
55 ATH_CHECK(m_muonEncoderToolDaq.retrieve(EnableTool(doMuonDaq)));
56
57 const bool doCTP = not serviceLocator()->getOptsSvc().get("ToolSvc.CTPResultBSEncoderTool.ROBIDs").empty();
58 ATH_MSG_DEBUG("CTP BS encoding is " << (doCTP ? "enabled" : "disabled"));
59 ATH_CHECK(m_ctpResultEncoderTool.retrieve(EnableTool(doCTP)));
60
61 ATH_MSG_VERBOSE("end of " << __FUNCTION__);
62 return StatusCode::SUCCESS;
63}
64
65// =============================================================================
66// Implementation of Converter::finalize
67// =============================================================================
69 ATH_MSG_VERBOSE("start of " << __FUNCTION__);
70 if (m_ByteStreamEventAccess.release().isFailure())
71 ATH_MSG_WARNING("Failed to release service " << m_ByteStreamEventAccess.typeAndName());
72 if (m_muonEncoderTool.isEnabled() && m_muonEncoderTool.release().isFailure())
73 ATH_MSG_WARNING("Failed to release tool " << m_muonEncoderTool.typeAndName());
74 if (m_muonEncoderToolDaq.isEnabled() && m_muonEncoderToolDaq.release().isFailure())
75 ATH_MSG_WARNING("Failed to release tool " << m_muonEncoderToolDaq.typeAndName());
76 if (m_ctpResultEncoderTool.isEnabled() && m_ctpResultEncoderTool.release().isFailure())
77 ATH_MSG_WARNING("Failed to release tool " << m_ctpResultEncoderTool.typeAndName());
78 ATH_MSG_VERBOSE("end of " << __FUNCTION__);
79 return StatusCode::SUCCESS;
80}
81
82// =============================================================================
83// Implementation of Converter::createObj
84// =============================================================================
85StatusCode L1TriggerResultByteStreamCnv::createObj(IOpaqueAddress* /*pAddr*/, DataObject*& /*pObj*/) {
86 ATH_MSG_ERROR("L1TriggerResult cannot be created directly from ByteStream!"
87 << " Use the L1TriggerResultMaker algorithm instead");
88 return StatusCode::FAILURE;
89}
90
91// =============================================================================
92// Implementation of Converter::createRep
93// =============================================================================
94StatusCode L1TriggerResultByteStreamCnv::createRep(DataObject* pObj, IOpaqueAddress*& pAddr) {
95 ATH_MSG_VERBOSE("start of " << __FUNCTION__);
96
97 const EventContext& ctx = Gaudi::Hive::currentContext();
98
99 // Cast the DataObject to L1TriggerResult
100 xAOD::TrigCompositeContainer* l1TriggerResult = nullptr;
101 bool castSuccessful = SG::fromStorable(pObj, l1TriggerResult);
102 if (!castSuccessful || !l1TriggerResult) {
103 ATH_MSG_ERROR("Failed to convert DataObject to xAOD::TrigCompositeContainer for L1TriggerResult");
104 return StatusCode::FAILURE;
105 }
106
107 // Obtain the RawEventWrite (aka eformat::write::FullEventFragment) pointer
108 RawEventWrite* re = m_ByteStreamEventAccess->getRawEvent();
109 if (!re) {
110 ATH_MSG_ERROR("Failed to obtain a pointer to RawEventWrite");
111 return StatusCode::FAILURE;
112 }
113 ATH_MSG_VERBOSE("Obtained RawEventWrite pointer = " << re);
114
115 // ===== CTPResult encoding =================
116
117 // Only perform encoding if tool was enabled, hence only when xAOD::CTPResult is used instead of ROIB::CTPResult (as part of ROIB::RoIBResult)
118 if (m_ctpResultEncoderTool.isEnabled()) {
119
120 // Update RawEventWrite with L1 trigger bits from xAOD::CTPResult
122 ATH_CHECK(ctpResultHandle.isValid());
123 const xAOD::CTPResult* result = ctpResultHandle.get();
124
125 // Helpful lambda function to convert from vectors of 32-bit words to bitsets
126 auto wordsToBitset = [](const std::vector<uint32_t>& words) {
127 std::bitset<512> out;
128 for (size_t i = 0; i < words.size(); ++i) {
129 uint32_t w = words[i];
130 for (size_t b = 0; b < 32; ++b) {
131 if (w & (1u << b)) {
132 out.set(i * 32 + b);
133 }
134 }
135 }
136 return out;
137 };
138
139 std::bitset<512> tbp = wordsToBitset(result->getTBPWords());
140 std::bitset<512> tap = wordsToBitset(result->getTAPWords());
141 std::bitset<512> tav = wordsToBitset(result->getTAVWords());
142
143 // Number of L1 words computed from TBP/TAP/TAV
144 constexpr size_t wordSize = 32;
145 constexpr size_t wordsPerSet = 512 / wordSize;
146 constexpr size_t numWords = 3 * wordsPerSet;
147
148 // Allocate per-event storage
149 std::vector<uint32_t> l1BitsData(numWords, 0);
150
151 // Fill l1BitsData from TBP/TAP/TAV
152 size_t iset{0};
153 for (const std::bitset<512>& bset : {tbp, tap, tav}) {
154 const std::string sbits = bset.to_string();
155 const size_t iWordOutputStart = wordsPerSet * iset;
156 for (size_t iWordInSet = 0; iWordInSet < wordsPerSet; ++iWordInSet) {
157 const size_t bwordPos = 512 - (iWordInSet + 1) * wordSize;
158 std::bitset<wordSize> bword{sbits.substr(bwordPos, wordSize)};
159 l1BitsData[iWordOutputStart + iWordInSet] = static_cast<uint32_t>(bword.to_ulong());
160 }
161 ++iset;
162 }
163 const uint32_t triggerType = result->triggerType();
164
165 // Update RawEventWrite
166 re->lvl1_trigger_info(l1BitsData.size(), l1BitsData.data());
167 re->lvl1_trigger_type(static_cast<uint8_t>(triggerType & 0xFF));
168
169 // Encode payload trigger information of xAOD::CTPResult
170 std::vector<WROBF*> ctpResultROBs; // Will just be one ROB in the vector
171 ATH_CHECK(m_ctpResultEncoderTool->convertToBS(ctpResultROBs, ctx)); // TODO: find a way to avoid ThreadLocalContext
172 ATH_MSG_DEBUG(m_ctpResultEncoderTool->name() << " created " << ctpResultROBs.size() << " CTP ROB Fragments");
173 for (WROBF* rob : ctpResultROBs) {
174 printRob(*rob);
175 // Set LVL1 Trigger Type from the full event
176 rob->rod_lvl1_type(re->lvl1_trigger_type());
177 // Set LVL1 ID from the full event
178 rob->rod_lvl1_id(re->lvl1_id());
179 // Add the ROBFragment to the full event
180 re->append(rob);
181 ATH_MSG_DEBUG("Added ROB fragment 0x" << MSG::hex << rob->source_id() << MSG::dec << " to the output raw event");
182 }
183 }
184
185 // ===== MuonRoI encoding =================
186
187 for (ToolHandle<IL1TriggerByteStreamTool>& tool : {std::reference_wrapper(m_muonEncoderTool), std::reference_wrapper(m_muonEncoderToolDaq)}) {
188 if (not tool.isEnabled()) {continue;}
189 std::vector<WROBF*> muon_robs;
190 ATH_CHECK(tool->convertToBS(muon_robs, ctx)); // TODO: find a way to avoid ThreadLocalContext
191 ATH_MSG_DEBUG(tool.name() << " created " << muon_robs.size() << " L1Muon ROB Fragments");
192 for (WROBF* rob : muon_robs) {
193 printRob(*rob);
194 // Set LVL1 Trigger Type from the full event
195 rob->rod_lvl1_type(re->lvl1_trigger_type());
196 // Set LVL1 ID from the full event
197 rob->rod_lvl1_id(re->lvl1_id());
198 // Add the ROBFragment to the full event
199 re->append(rob);
200 ATH_MSG_DEBUG("Added ROB fragment 0x" << MSG::hex << rob->source_id() << MSG::dec << " to the output raw event");
201 }
202 }
203
204 // Placeholder for other systems: L1Topo, L1Calo
205
206 // Create a ByteStreamAddress for L1TriggerResult
207 if ( pAddr != nullptr ) pAddr->release();
208 ByteStreamAddress* bsAddr = new ByteStreamAddress(classID(), pObj->registry()->name(), "");
209 pAddr = static_cast<IOpaqueAddress*>(bsAddr);
210 pAddr->addRef();
211
212 ATH_MSG_VERBOSE("end of " << __FUNCTION__);
213 return StatusCode::SUCCESS;
214}
215
216// =============================================================================
217// Debug print helper
218// =============================================================================
220 if (not msgLvl(MSG::DEBUG)) {return;}
221 const uint32_t ndata = rob.rod_ndata();
222 const uint32_t* data = rob.rod_data();
223 ATH_MSG_DEBUG("This ROB has " << ndata << " data words");
224 for (uint32_t i=0; i<ndata; ++i, ++data) {
225 ATH_MSG_DEBUG("--- 0x" << MSG::hex << *data << MSG::dec);
226 }
227}
228
229// =============================================================================
230// CLID / storageType
231// =============================================================================
235
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
#define sbits(u, n)
Intrinsic functions which do not work correctly due to differences in byte ordering.
bool msgLvl(const MSG::Level lvl) const
Test the output level.
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
IOpaqueAddress for ByteStreamCnvSvc, with ROB ids.
static constexpr long storageType()
void printRob(const OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment &rob) const
Helper method for debug printouts.
ToolHandle< IL1TriggerByteStreamTool > m_ctpResultEncoderTool
Encoder tool for CTP result.
virtual StatusCode createRep(DataObject *pObj, IOpaqueAddress *&pAddr) override
Create ByteStream from xAOD (L1TriggerResult)
static long storageType()
Storage type used by this converter.
SG::ReadHandleKey< xAOD::CTPResult > m_inKeyCTPResult
virtual StatusCode finalize() override
ToolHandle< IL1TriggerByteStreamTool > m_muonEncoderTool
Encoder tools for L1Muon RoIs (one writing RoIB ROB, one writing DAQ ROB)
ServiceHandle< IByteStreamEventAccess > m_ByteStreamEventAccess
Helper to obtain the RawEvent pointer.
virtual ~L1TriggerResultByteStreamCnv()
Standard destructor.
virtual StatusCode initialize() override
ToolHandle< IL1TriggerByteStreamTool > m_muonEncoderToolDaq
L1TriggerResultByteStreamCnv(ISvcLocator *svcLoc)
Standard constructor.
virtual StatusCode createObj(IOpaqueAddress *pAddr, DataObject *&pObj) override
Create xAOD (L1TriggerResult) from ByteStream.
static const CLID & classID()
CLID of the class of the L1TriggerResult converted by this converter (xAOD::TrigCompositeContainer)
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type get() const
Dereference the pointer, but don't cache anything.
OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment WROBF
eformat::write::ROBFragment ROBFragment
Definition RawEvent.h:33
bool fromStorable(DataObject *pDObj, T *&pTrans, bool quiet=false, IRegisterTransient *irt=0, bool isConst=true)
TrigCompositeContainer_v1 TrigCompositeContainer
Declare the latest version of the container.
CTPResult_v1 CTPResult
Define the latest version of the CTPResult class.