ATLAS Offline Software
ByteStreamCnvSvc.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
9 
10 #include "StoreGate/StoreGateSvc.h"
13 
14 #include "eformat/SourceIdentifier.h"
15 #include "eformat/StreamTag.h"
16 
17 #include "GaudiKernel/IClassIDSvc.h"
18 
20 
21 #include <algorithm>
22 
23 namespace {
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 
34 ByteStreamCnvSvc::ByteStreamCnvSvc(const std::string& name, ISvcLocator* pSvcLocator)
35  : ByteStreamCnvSvcBase(name, pSvcLocator),
36  m_evtStore ("StoreGateSvc", name)
37 {
38  declareProperty("ByteStreamOutputSvc", m_ioSvcName);
39  declareProperty("UserType", m_userType = "RawEvent");
40  declareProperty("EventStore", m_evtStore);
41 }
42 
45 }
46 
49  if (!ByteStreamCnvSvcBase::initialize().isSuccess()) {
50  ATH_MSG_FATAL("ByteStreamCnvSvcBase::initialize() failed");
51  return(StatusCode::FAILURE);
52  }
53 
54  ATH_CHECK( m_evtStore.retrieve() );
55 
56  // get ready for output
57  std::vector<std::string> ioSvcNames = m_ioSvcNameList.value();
58  if (!m_ioSvcName.empty()) {
59  // add ioSvcName if ioSvcNameList is missing it
60  std::vector<std::string>::iterator it = find(ioSvcNames.begin(), ioSvcNames.end(), m_ioSvcName);
61  if (it == ioSvcNames.end()) {
62  ioSvcNames.push_back(m_ioSvcName);
63  }
64  }
65  if (ioSvcNames.size() != 0) {
66  // Check ByteStreamCnvSvc
67  for (std::vector<std::string>::iterator itSvc = ioSvcNames.begin(), itSvcE = ioSvcNames.end();
68  itSvc != itSvcE; ++itSvc) {
69  ATH_MSG_DEBUG("get " << *itSvc);
70  // get service
71  IService* svc;
72  if (!service(*itSvc, svc).isSuccess()) {
73  ATH_MSG_FATAL("Cannot get ByteStreamOutputSvc");
74  return(StatusCode::FAILURE);
75  }
76  ByteStreamOutputSvc* ioSvc = dynamic_cast<ByteStreamOutputSvc*>(svc);
77  if (ioSvc == 0) {
78  ATH_MSG_FATAL("Cannot cast to ByteStreamOutputSvc");
79  return(StatusCode::FAILURE);
80  }
81  // get stream name
82  std::string bsOutputStreamName;
83  SimpleProperty<std::string> propBSO("BSOutputStreamName", bsOutputStreamName);
84  if (!ioSvc->getProperty(&propBSO).isSuccess()) {
85  ATH_MSG_FATAL("Cannot get BSOutputStreamName from " << *itSvc);
86  return(StatusCode::FAILURE);
87  }
88  bsOutputStreamName = propBSO.value();
89  // append
90  m_ioSvcMap[bsOutputStreamName] = ioSvc;
91  }
92  }
93  return(StatusCode::SUCCESS);
94 }
95 
98 }
99 
100 StatusCode ByteStreamCnvSvc::connectOutput(const std::string& t, const std::string& /*mode*/) {
101  return(connectOutput(t));
102 }
103 
104 StatusCode ByteStreamCnvSvc::connectOutput(const std::string& /*t*/) {
105  ATH_MSG_DEBUG("In connectOutput");
106 
107  const EventContext& ctx = Gaudi::Hive::currentContext();
108  SlotData& slot = *m_slots.get(ctx);
109 
110  // Get the EventInfo obj for run/event number
111  const xAOD::EventInfo* evtInfo{nullptr};
112  ATH_CHECK( m_evtStore->retrieve(evtInfo) );
113  uint64_t event = evtInfo->eventNumber();
114  uint32_t run_no = evtInfo->runNumber();
115  uint32_t bc_time_sec = evtInfo->timeStamp();
116  uint32_t bc_time_ns = evtInfo->timeStampNSOffset();
117  uint32_t run_type = 0;
118  uint32_t lvl1_id = evtInfo->extendedLevel1ID();
119  if (lvl1_id == 0) {
120  lvl1_id = event;
121  }
122  uint8_t lvl1_type = evtInfo->level1TriggerType();
123  uint64_t global_id = event;
124  uint16_t lumi_block = evtInfo->lumiBlock();
125  uint16_t bc_id = evtInfo->bcid();
126  uint8_t nevt = 0;
127  // create an empty RawEvent
128  eformat::helper::SourceIdentifier sid = eformat::helper::SourceIdentifier(eformat::FULL_SD_EVENT, nevt);
129  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));
130 
131  // set stream tags
132  std::vector<eformat::helper::StreamTag> on_streamTags;
133  for (const auto& sTag : evtInfo->streamTags()) {
134  on_streamTags.emplace_back(sTag.name(), sTag.type(), sTag.obeysLumiblock(), sTag.robs(), detsOnline(sTag.dets()));
135  }
136  uint32_t nStreamTagWords = eformat::helper::size_word(on_streamTags);
137  slot.m_tagBuff.resize (nStreamTagWords);
138  eformat::helper::encode(on_streamTags, nStreamTagWords, slot.m_tagBuff.data());
139  re->stream_tag(nStreamTagWords, slot.m_tagBuff.data());
140 
141  // Nothing left to do, unless processing trigger bits
142  if (!m_fillTriggerBits.value()) {
143  return StatusCode::SUCCESS;
144  }
145 
146  // try to get TrigDecision
147  const xAOD::TrigDecision *trigDecision{nullptr};
148  if (m_evtStore->retrieve(trigDecision, "xTrigDecision") != StatusCode::SUCCESS) {
149  ATH_MSG_WARNING("Property " << m_fillTriggerBits.name() << " set to True but failed to retrieve xAOD::TrigDecision. Leaving empty trigger bits in the event header.");
150  return StatusCode::SUCCESS;
151  }
152 
153  // LVL1 info
154  const std::vector<uint32_t> &tbp = trigDecision->tbp();
155  const std::vector<uint32_t> &tap = trigDecision->tap();
156  const std::vector<uint32_t> &tav = trigDecision->tav();
157  const size_t l1TotSize = tbp.size() + tap.size() + tav.size();
158  if (l1TotSize > 0) {
159  slot.m_l1Buff.resize (l1TotSize);
160  size_t l1Size{0};
161  for (const uint32_t tb : tbp) {
162  slot.m_l1Buff[l1Size++] = tb;
163  }
164  for (const uint32_t tb : tap) {
165  slot.m_l1Buff[l1Size++] = tb;
166  }
167  for (const uint32_t tb : tav) {
168  slot.m_l1Buff[l1Size++] = tb;
169  }
170  re->lvl1_trigger_info(l1TotSize, slot.m_l1Buff.data());
171  }
172 
173  // LVL2 info
174  const std::vector<uint32_t>& lvl2PP = trigDecision->lvl2PassedPhysics();
175  if (lvl2PP.size() > 0) {
176  slot.m_l2Buff = lvl2PP;
177  re->lvl2_trigger_info(lvl2PP.size(), slot.m_l2Buff.data());
178  }
179 
180  // EF info
181  const std::vector<uint32_t>& efPP = trigDecision->efPassedPhysics();
182  if (efPP.size() > 0) {
183  slot.m_efBuff = efPP;
184  re->event_filter_info(efPP.size(), slot.m_efBuff.data());
185  }
186 
187  return(StatusCode::SUCCESS);
188 }
189 
190 StatusCode ByteStreamCnvSvc::commitOutput(const std::string& outputConnection, bool /*b*/) {
191  ATH_MSG_DEBUG("In flushOutput " << outputConnection);
192 
193  const EventContext& ctx = Gaudi::Hive::currentContext();
194  SlotData& slot = *m_slots.get(ctx);
195 
196  if (m_ioSvcMap.size() == 0) {
197  ATH_MSG_ERROR("ByteStreamCnvSvc not configure for output");
198  return(StatusCode::FAILURE);
199  }
200 
201  writeFEA (slot);
202 
203  // convert RawEventWrite to RawEvent
204  RawEventWrite* re = slot.m_rawEventWrite.get();
205  uint32_t rawSize = re->size_word();
206  std::vector<uint32_t> buffer (rawSize);
207  uint32_t count = eformat::write::copy(*(re->bind()), buffer.data(), rawSize);
208  if (count != rawSize) {
209  ATH_MSG_ERROR("Memcopy failed");
210  return(StatusCode::FAILURE);
211  }
212  RawEvent rawEvent(buffer.data());
213  // check validity
214  try {
215  rawEvent.check_tree();
216  } catch (...) {
217  ATH_MSG_ERROR("commitOutput failed, because FullEventFragment invalid");
218  return(StatusCode::FAILURE);
219  }
220  ATH_MSG_DEBUG("commitOutput: Size of Event (words) = " << rawEvent.fragment_size_word());
221  // put event to OutputSvc
222  if ((m_ioSvcMap.size() == 1) or (m_ioSvcMap.count(outputConnection) > 0)) {
224  // for backward compatibility
225  if (itSvc == m_ioSvcMap.end()) {
226  itSvc = m_ioSvcMap.begin();
227  }
228  // put
229  if (!itSvc->second->putEvent(&rawEvent)) {
230  ATH_MSG_ERROR("commitOutput failed to send output");
231  return(StatusCode::FAILURE);
232  }
233  }
234  // Clear slot-specific data.
235  slot.clear();
236  return(StatusCode::SUCCESS);
237 }
238 
240 {
241  FEAMap_t& feaMap = slot.m_feaMap;
242  ATH_MSG_DEBUG("before FEAMAP size = " << feaMap.size());
243  for (auto& p : feaMap) {
244  MsgStream log(msgSvc(), name());
245  p.second->fill(slot.m_rawEventWrite.get(), log);
246  }
247  ATH_MSG_DEBUG("after FEAMAP size = " << feaMap.size());
248 }
249 
250 
251 StatusCode ByteStreamCnvSvc::queryInterface(const InterfaceID& riid, void** ppvInterface)
252 {
253  if ( interfaceID().versionMatch(riid) ) {
254  *ppvInterface = (StoreGateSvc*)this;
255  }
256  else {
257  // Interface is not directly available: try out a base class
258  return ByteStreamCnvSvcBase::queryInterface(riid, ppvInterface);
259  }
260  addRef();
261  return StatusCode::SUCCESS;
262 }
263 
264 
265 const InterfaceID&
267  static const InterfaceID IDByteStreamCnvSvc("ByteStreamCnvSvc", 1, 0);
268  return IDByteStreamCnvSvc;
269 }
270 
271 
273 ByteStreamCnvSvc::setRawEvent (std::unique_ptr<RawEventWrite> rawEventWrite)
274 {
275  RawEventWrite* ptr = rawEventWrite.get();
276  m_slots->m_rawEventWrite = std::move (rawEventWrite);
277  // cppcheck-suppress returnDanglingLifetime
278  return ptr;
279 }
280 
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
ByteStreamCnvSvc::commitOutput
virtual StatusCode commitOutput(const std::string &outputConnection, bool b) override
Implements ConversionSvc's commitOutput.
Definition: ByteStreamCnvSvc.cxx:190
ByteStreamCnvSvc::SlotData
Slot-specific state.
Definition: ByteStreamCnvSvc.h:96
RawEventWrite
OFFLINE_FRAGMENTS_NAMESPACE_WRITE::FullEventFragment RawEventWrite
data type for writing raw event
Definition: RawEvent.h:39
ByteStreamOutputSvc.h
This file contains the class definition for the ByteStreamOutputSvc class.
AthCnvSvc::finalize
virtual StatusCode finalize()
Definition: AthCnvSvc.cxx:116
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
ByteStreamCnvSvc::SlotData::m_efBuff
std::vector< uint32_t > m_efBuff
Definition: ByteStreamCnvSvc.h:102
ByteStreamCnvSvc::SlotData::clear
void clear()
Definition: ByteStreamCnvSvc.h:104
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
TrigDecision.h
CondAttrListCollection.h
This file defines the class for a collection of AttributeLists where each one is associated with a ch...
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:575
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
ByteStreamCnvSvc::~ByteStreamCnvSvc
virtual ~ByteStreamCnvSvc()
Standard Destructor.
Definition: ByteStreamCnvSvc.cxx:44
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
ByteStreamCnvSvc::m_ioSvcMap
std::map< std::string, ByteStreamOutputSvc * > m_ioSvcMap
Services for writing output.
Definition: ByteStreamCnvSvc.h:82
RawEvent
OFFLINE_FRAGMENTS_NAMESPACE::FullEventFragment RawEvent
data type for reading raw event
Definition: RawEvent.h:37
skel.it
it
Definition: skel.GENtoEVGEN.py:423
ByteStreamCnvSvc::m_evtStore
ServiceHandle< StoreGateSvc > m_evtStore
Event store.
Definition: ByteStreamCnvSvc.h:85
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
ByteStreamCnvSvc::m_slots
SG::SlotSpecificObj< SlotData > m_slots
Definition: ByteStreamCnvSvc.h:114
ByteStreamCnvSvc::ByteStreamCnvSvc
ByteStreamCnvSvc(const std::string &name, ISvcLocator *svc)
Standard Constructor.
Definition: ByteStreamCnvSvc.cxx:34
RunTileTBRec.run_type
run_type
Definition: RunTileTBRec.py:65
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
ByteStreamCnvSvc::SlotData::m_l1Buff
std::vector< uint32_t > m_l1Buff
Definition: ByteStreamCnvSvc.h:100
ByteStreamCnvSvcBase::queryInterface
virtual StatusCode queryInterface(const InterfaceID &riid, void **ppvInterface) override
Required of all Gaudi services: see Gaudi documentation for details.
Definition: ByteStreamCnvSvcBase.cxx:42
xAOD::tap
setBGCode tap
Definition: TrigDecision_v1.cxx:43
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
ByteStreamCnvSvc::m_ioSvcName
std::string m_ioSvcName
name of the service
Definition: ByteStreamCnvSvc.h:73
ByteStreamCnvSvc::queryInterface
virtual StatusCode queryInterface(const InterfaceID &riid, void **ppvInterface) override
Required of all Gaudi services: see Gaudi documentation for details.
Definition: ByteStreamCnvSvc.cxx:251
ByteStreamCnvSvc::FEAMap_t
std::map< std::string, FEAPtr_t > FEAMap_t
Definition: ByteStreamCnvSvc.h:92
Execution.tb
tb
Definition: Execution.py:15
StoreGateSvc
The Athena Transient Store API.
Definition: StoreGateSvc.h:128
createCoolChannelIdFile.buffer
buffer
Definition: createCoolChannelIdFile.py:12
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
xAOD::uint16_t
setWord1 uint16_t
Definition: eFexEMRoI_v1.cxx:88
event
POOL::TEvent event(POOL::TEvent::kClassAccess)
StdJOSetup.msgSvc
msgSvc
Provide convenience handles for various services.
Definition: StdJOSetup.py:36
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ByteStreamCnvSvc::SlotData::m_feaMap
FEAMap_t m_feaMap
Definition: ByteStreamCnvSvc.h:98
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
ByteStreamCnvSvc::SlotData::m_l2Buff
std::vector< uint32_t > m_l2Buff
Definition: ByteStreamCnvSvc.h:101
xAOD::uint64_t
uint64_t
Definition: EventInfo_v1.cxx:123
ByteStreamCnvSvc::SlotData::m_rawEventWrite
std::unique_ptr< RawEventWrite > m_rawEventWrite
Definition: ByteStreamCnvSvc.h:97
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
ByteStreamCnvSvc::m_userType
std::string m_userType
user type
Definition: ByteStreamCnvSvc.h:88
ByteStreamCnvSvc::interfaceID
static const InterfaceID & interfaceID()
Should rather be in IByteStreamSvc.h if we had one.
Definition: ByteStreamCnvSvc.cxx:266
ByteStreamCnvSvc::initialize
virtual StatusCode initialize() override
Gaudi Service Interface method implementations:
Definition: ByteStreamCnvSvc.cxx:48
ByteStreamAddress.h
Handler::svc
AthROOTErrorHandlerSvc * svc
Definition: AthROOTErrorHandlerSvc.cxx:10
ByteStreamCnvSvc.h
FullEventAssembler.h
ByteStreamCnvSvc::finalize
virtual StatusCode finalize() override
Definition: ByteStreamCnvSvc.cxx:96
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
EventInfo.h
xAOD::EventInfo_v1
Class describing the basic event information.
Definition: EventInfo_v1.h:43
ByteStreamCnvSvcBase
The base class for offline and HLT ByteStream conversion services.
Definition: ByteStreamCnvSvcBase.h:19
ByteStreamCnvSvc::writeFEA
void writeFEA(SlotData &slot)
Write the FEA to RawEvent.
Definition: ByteStreamCnvSvc.cxx:239
ByteStreamCnvSvc::m_fillTriggerBits
Gaudi::Property< bool > m_fillTriggerBits
fill trigger bits
Definition: ByteStreamCnvSvc.h:79
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
ByteStreamCnvSvc::SlotData::m_tagBuff
std::vector< uint32_t > m_tagBuff
Definition: ByteStreamCnvSvc.h:99
re
const boost::regex re(r_e)
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
declareProperty
#define declareProperty(n, p, h)
Definition: BaseFakeBkgTool.cxx:15
ByteStreamOutputSvc
This class provides the base class to services to write bytestream data. The concrete class can provi...
Definition: ByteStreamOutputSvc.h:25
calibdata.copy
bool copy
Definition: calibdata.py:27
ByteStreamCnvSvc::setRawEvent
RawEventWrite * setRawEvent(std::unique_ptr< RawEventWrite > rawEventWrite)
Definition: ByteStreamCnvSvc.cxx:273
ByteStreamCnvSvc::connectOutput
virtual StatusCode connectOutput(const std::string &t, const std::string &mode) override
Implements ConversionSvc's connectOutput.
Definition: ByteStreamCnvSvc.cxx:100
ByteStreamCnvSvc::m_ioSvcNameList
Gaudi::Property< std::vector< std::string > > m_ioSvcNameList
list of service names
Definition: ByteStreamCnvSvc.h:76
python.PerfMonSerializer.encode
def encode(data, use_base64=True)
Definition: PerfMonSerializer.py:375
StoreGateSvc.h
xAOD::TrigDecision_v1
Interface to the raw trigger decision information of the event.
Definition: TrigDecision_v1.h:44
ByteStreamCnvSvcBase::initialize
virtual StatusCode initialize() override
Required of all Gaudi Services.
Definition: ByteStreamCnvSvcBase.cxx:27