ATLAS Offline Software
Loading...
Searching...
No Matches
ByteStreamCnvSvc.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "ByteStreamCnvSvc.h"
9
13
14#include "eformat/SourceIdentifier.h"
15#include "eformat/StreamTag.h"
16
17#include "GaudiKernel/IClassIDSvc.h"
18
20
21#include <algorithm>
22
23namespace {
25 std::set<eformat::SubDetector> detsOnline(const std::set<uint32_t>& detsOffline) {
26 std::set<eformat::SubDetector> out;
27 for (const uint32_t detid : detsOffline)
28 out.insert(static_cast<eformat::SubDetector>(detid));
29 return out;
30 }
31}
32
34ByteStreamCnvSvc::ByteStreamCnvSvc(const std::string& name, ISvcLocator* pSvcLocator)
35 : base_class(name, pSvcLocator)
36{
37}
38
40{
41 const EventContext& ctx = Gaudi::Hive::currentContext();
42 const auto& feaMap = m_slots.get(ctx)->m_feaMap;
43 const auto& fea = feaMap.find(name);
44 return fea!=feaMap.end() ? fea->second.get() : nullptr;
45}
46
47StatusCode ByteStreamCnvSvc::storeFullEventAssembler(std::unique_ptr<FullEventAssemblerBase> fea, const std::string& name)
48{
49 const EventContext& ctx = Gaudi::Hive::currentContext();
50 m_slots.get(ctx)->m_feaMap[name] = std::move(fea);
51 return StatusCode::SUCCESS;
52}
53
57
58 ATH_CHECK(m_evtStore.retrieve());
59
60 // get ready for output
61 std::vector<std::string> ioSvcNames = m_ioSvcNameList.value();
62 if (!m_ioSvcName.empty()) {
63 // add ioSvcName if ioSvcNameList is missing it
64 auto it = find(ioSvcNames.begin(), ioSvcNames.end(), m_ioSvcName);
65 if (it == ioSvcNames.end()) {
66 ioSvcNames.push_back(m_ioSvcName);
67 }
68 }
69 if (!ioSvcNames.empty()) {
70 // Check ByteStreamCnvSvc
71 for (const std::string& svcName : ioSvcNames) {
72 ATH_MSG_DEBUG("Retrieving " << svcName);
73 // get service
74 SmartIF<IByteStreamOutputSvc> ioSvc{service(svcName)};
75 ATH_CHECK(ioSvc.isValid());
76
77 // get stream name
78 std::string bsOutputStreamName;
79 SimpleProperty<std::string> propBSO("BSOutputStreamName", bsOutputStreamName);
80 ATH_CHECK(ioSvc.as<IProperty>()->getProperty(&propBSO));
81 bsOutputStreamName = propBSO.value();
82 // append
83 m_ioSvcMap[bsOutputStreamName] = ioSvc;
84 }
85 }
86 return StatusCode::SUCCESS;
87}
88
90 return ByteStreamCnvSvcBase::finalize();
91}
92
93StatusCode ByteStreamCnvSvc::connectOutput(const std::string& t, const std::string& /*mode*/) {
94 return connectOutput(t);
95}
96
97StatusCode ByteStreamCnvSvc::connectOutput(const std::string& /*t*/) {
98 ATH_MSG_DEBUG("In connectOutput");
99
100 const EventContext& ctx = Gaudi::Hive::currentContext();
101 SlotData& slot = *m_slots.get(ctx);
102
103 // Get the EventInfo obj for run/event number
104 const xAOD::EventInfo* evtInfo{nullptr};
105 ATH_CHECK( m_evtStore->retrieve(evtInfo) );
106 uint64_t event = evtInfo->eventNumber();
107 uint32_t run_no = evtInfo->runNumber();
108 uint32_t bc_time_sec = evtInfo->timeStamp();
109 uint32_t bc_time_ns = evtInfo->timeStampNSOffset();
110 uint32_t run_type = 0;
111 uint32_t lvl1_id = evtInfo->extendedLevel1ID();
112 if (lvl1_id == 0) {
113 lvl1_id = event;
114 }
115 uint8_t lvl1_type = evtInfo->level1TriggerType();
116 uint64_t global_id = event;
117 uint16_t lumi_block = evtInfo->lumiBlock();
118 uint16_t bc_id = evtInfo->bcid();
119 uint8_t nevt = 0;
120 // create an empty RawEvent
121 eformat::helper::SourceIdentifier sid = eformat::helper::SourceIdentifier(eformat::FULL_SD_EVENT, nevt);
122 RawEventWrite* re = setRawEvent (std::make_unique<RawEventWrite>(sid.code(), bc_time_sec, bc_time_ns, global_id, run_type, run_no, lumi_block, lvl1_id, bc_id, lvl1_type));
123
124 // set stream tags
125 std::vector<eformat::helper::StreamTag> on_streamTags;
126 for (const auto& sTag : evtInfo->streamTags()) {
127 on_streamTags.emplace_back(sTag.name(), sTag.type(), sTag.obeysLumiblock(), sTag.robs(), detsOnline(sTag.dets()));
128 }
129 uint32_t nStreamTagWords = eformat::helper::size_word(on_streamTags);
130 slot.m_tagBuff.resize (nStreamTagWords);
131 eformat::helper::encode(on_streamTags, nStreamTagWords, slot.m_tagBuff.data());
132 re->stream_tag(nStreamTagWords, slot.m_tagBuff.data());
133
134 // Nothing left to do, unless processing trigger bits
135 if (!m_fillTriggerBits.value()) {
136 return StatusCode::SUCCESS;
137 }
138
139 // try to get TrigDecision
140 const xAOD::TrigDecision *trigDecision{nullptr};
141 if (m_evtStore->retrieve(trigDecision, "xTrigDecision") != StatusCode::SUCCESS) {
142 ATH_MSG_WARNING("Property " << m_fillTriggerBits.name() << " set to True but failed to retrieve xAOD::TrigDecision. Leaving empty trigger bits in the event header.");
143 return StatusCode::SUCCESS;
144 }
145
146 // LVL1 info
147 const std::vector<uint32_t> &tbp = trigDecision->tbp();
148 const std::vector<uint32_t> &tap = trigDecision->tap();
149 const std::vector<uint32_t> &tav = trigDecision->tav();
150 const size_t l1TotSize = tbp.size() + tap.size() + tav.size();
151 if (l1TotSize > 0) {
152 slot.m_l1Buff.resize (l1TotSize);
153 size_t l1Size{0};
154 for (const uint32_t tb : tbp) {
155 slot.m_l1Buff[l1Size++] = tb;
156 }
157 for (const uint32_t tb : tap) {
158 slot.m_l1Buff[l1Size++] = tb;
159 }
160 for (const uint32_t tb : tav) {
161 slot.m_l1Buff[l1Size++] = tb;
162 }
163 re->lvl1_trigger_info(l1TotSize, slot.m_l1Buff.data());
164 }
165
166 // LVL2 info
167 const std::vector<uint32_t>& lvl2PP = trigDecision->lvl2PassedPhysics();
168 if (lvl2PP.size() > 0) {
169 slot.m_l2Buff = lvl2PP;
170 re->lvl2_trigger_info(lvl2PP.size(), slot.m_l2Buff.data());
171 }
172
173 // EF info
174 const std::vector<uint32_t>& efPP = trigDecision->efPassedPhysics();
175 if (efPP.size() > 0) {
176 slot.m_efBuff = efPP;
177 re->event_filter_info(efPP.size(), slot.m_efBuff.data());
178 }
179
180 return StatusCode::SUCCESS;
181}
182
183StatusCode ByteStreamCnvSvc::commitOutput(const std::string& outputConnection, bool /*b*/) {
184 ATH_MSG_DEBUG("In flushOutput " << outputConnection);
185
186 const EventContext& ctx = Gaudi::Hive::currentContext();
187 SlotData& slot = *m_slots.get(ctx);
188
189 if (m_ioSvcMap.size() == 0) {
190 ATH_MSG_ERROR("ByteStreamCnvSvc not configured for output");
191 return StatusCode::FAILURE;
192 }
193
194 writeFEA (slot);
195
196 // convert RawEventWrite to RawEvent
197 RawEventWrite* re = slot.m_rawEventWrite.get();
198 uint32_t rawSize = re->size_word();
199 std::vector<uint32_t> buffer (rawSize);
200 uint32_t count = eformat::write::copy(*(re->bind()), buffer.data(), rawSize);
201 if (count != rawSize) {
202 ATH_MSG_ERROR("Memcopy failed");
203 return StatusCode::FAILURE;
204 }
205 RawEvent rawEvent(buffer.data());
206 // check validity
207 try {
208 rawEvent.check_tree();
209 } catch (...) {
210 ATH_MSG_ERROR("commitOutput failed, because FullEventFragment invalid");
211 return StatusCode::FAILURE;
212 }
213 ATH_MSG_DEBUG("commitOutput: Size of Event (words) = " << rawEvent.fragment_size_word());
214 // put event to OutputSvc
215 if ((m_ioSvcMap.size() == 1) or (m_ioSvcMap.count(outputConnection) > 0)) {
216 std::map<std::string, IByteStreamOutputSvc*>::iterator itSvc = m_ioSvcMap.find(outputConnection);
217 // for backward compatibility
218 if (itSvc == m_ioSvcMap.end()) {
219 itSvc = m_ioSvcMap.begin();
220 }
221 // put
222 if (!itSvc->second->putEvent(&rawEvent)) {
223 ATH_MSG_ERROR("commitOutput failed to send output");
224 return StatusCode::FAILURE;
225 }
226 }
227 // Clear slot-specific data.
228 slot.clear();
229 return StatusCode::SUCCESS;
230}
231
233{
234 const auto& feaMap = slot.m_feaMap;
235 ATH_MSG_DEBUG("before FEAMAP size = " << feaMap.size());
236 for (auto& p : feaMap) {
237 MsgStream log(msgSvc(), name());
238 p.second->fill(slot.m_rawEventWrite.get(), log);
239 }
240 ATH_MSG_DEBUG("after FEAMAP size = " << feaMap.size());
241}
242
244ByteStreamCnvSvc::setRawEvent (std::unique_ptr<RawEventWrite> rawEventWrite)
245{
246 RawEventWrite* ptr = rawEventWrite.get();
247 m_slots->m_rawEventWrite = std::move (rawEventWrite);
248 // cppcheck-suppress returnDanglingLifetime
249 return ptr;
250}
251
const boost::regex re(r_e)
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
This file defines the class for a collection of AttributeLists where each one is associated with a ch...
This file contains the interface for the ByteStreamOutputSvc classes.
OFFLINE_FRAGMENTS_NAMESPACE_WRITE::FullEventFragment RawEventWrite
data type for writing raw event
Definition RawEvent.h:39
OFFLINE_FRAGMENTS_NAMESPACE::FullEventFragment RawEvent
data type for reading raw event
Definition RawEvent.h:37
virtual StatusCode initialize() override
Required of all Gaudi Services.
void writeFEA(SlotData &slot)
Write the FEA to RawEvent.
virtual StatusCode commitOutput(const std::string &outputConnection, bool b) override
Implements ConversionSvc's commitOutput.
Gaudi::Property< std::string > m_ioSvcName
name of the service
virtual StatusCode storeFullEventAssembler(std::unique_ptr< FullEventAssemblerBase > fea, const std::string &name) override
ByteStreamCnvSvc(const std::string &name, ISvcLocator *svc)
Standard Constructor.
Gaudi::Property< std::vector< std::string > > m_ioSvcNameList
list of service names
std::map< std::string, IByteStreamOutputSvc * > m_ioSvcMap
Services for writing output.
virtual StatusCode initialize() override
Gaudi Service Interface method implementations:
virtual StatusCode connectOutput(const std::string &t, const std::string &mode) override
Implements ConversionSvc's connectOutput.
SG::SlotSpecificObj< SlotData > m_slots
virtual FullEventAssemblerBase * findFullEventAssembler(const std::string &name) const override
Implementation of IByteStreamCnvSvc interface.
Gaudi::Property< bool > m_fillTriggerBits
fill trigger bits
ServiceHandle< StoreGateSvc > m_evtStore
Event store.
RawEventWrite * setRawEvent(std::unique_ptr< RawEventWrite > rawEventWrite)
virtual StatusCode finalize() override
base class for assembling a full atlas raw event from subfragments
uint32_t lumiBlock() const
The current event's luminosity block number.
uint32_t bcid() const
The bunch crossing ID of the event.
uint16_t level1TriggerType() const
The Level-1 trigger type.
uint32_t timeStamp() const
POSIX time in seconds from 1970. January 1st.
const std::vector< StreamTag > & streamTags() const
Get the streams that the event was put in.
uint32_t runNumber() const
The current event's run number.
uint32_t timeStampNSOffset() const
Nanosecond time offset wrt. the time stamp.
uint64_t eventNumber() const
The current event's event number.
uint32_t extendedLevel1ID() const
The extended Level-1 identifier.
const std::vector< uint32_t > & tav() const
Get the Trigger After Veto bits.
const std::vector< uint32_t > & lvl2PassedPhysics() const
Get the LVL2 physics decision bits.
const std::vector< uint32_t > & efPassedPhysics() const
Get the EF physics decision bits.
const std::vector< uint32_t > & tap() const
Get the Trigger After Prescale bits.
const std::vector< uint32_t > & tbp() const
Get the Trigger Before Prescale bits.
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146
EventInfo_v1 EventInfo
Definition of the latest event info version.
TrigDecision_v1 TrigDecision
Define the latest version of the trigger decision class.
std::vector< uint32_t > m_l2Buff
std::map< std::string, std::unique_ptr< FullEventAssemblerBase > > m_feaMap
std::vector< uint32_t > m_l1Buff
std::vector< uint32_t > m_tagBuff
std::vector< uint32_t > m_efBuff
std::unique_ptr< RawEventWrite > m_rawEventWrite