ATLAS Offline Software
Loading...
Searching...
No Matches
TrigByteStreamCnvSvc.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Trigger includes
8
9// Athena includes
13
14// Gaudi includes
15#include "GaudiKernel/ITHistSvc.h"
16
17// TDAQ includes
18#include "eformat/FullEventFragmentNoTemplates.h"
19#include "eformat/ROBFragmentNoTemplates.h"
20#include "eformat/StreamTag.h"
21#include "hltinterface/DataCollector.h"
22
23// System includes
24#include <sstream>
25#include <iomanip>
26#include <chrono>
27
28// Local helper functions
29namespace {
30 constexpr float wordsToKiloBytes = 0.001*sizeof(uint32_t);
31 template<typename T> inline bool contains(const std::vector<T>& vec, const T& val) {
32 return std::find(vec.cbegin(), vec.cend(), val)!=vec.cend();
33 }
34 template<typename T> inline int index(const std::vector<T>& vec, const T& val) {
35 typename std::vector<T>::const_iterator it = std::find(vec.cbegin(), vec.cend(), val);
36 return it==vec.cend() ? -1 : std::distance(vec.cbegin(), it);
37 }
38 template<typename T> struct printWordHex {
39 printWordHex(const T w) : word(w) {}
40 T word;
41 };
42 template<typename T> std::ostream& operator<<(std::ostream& str, const printWordHex<T>& pw) {
43 str << "0x" << std::hex << std::setfill('0') << std::setw(2*sizeof(T));
44 // Prevent printing char as ASCII character
45 if (sizeof(T)==1)
46 str << static_cast<int>(pw.word);
47 else
48 str << pw.word;
49 str << std::dec;
50 return str;
51 }
52 template<typename T> struct printNWordsHex {
53 printNWordsHex(const size_t n, const T* w, const std::string& s=" ") : nwords(n), words(w), sep(s) {}
54 size_t nwords;
55 const T* words;
56 std::string sep;
57 };
58 template<typename T> std::ostream& operator<<(std::ostream& str, const printNWordsHex<T>& pnw) {
59 for (size_t i=0; i<pnw.nwords; ++i) {
60 str << printWordHex<T>(pnw.words[i]);
61 if (i!=pnw.nwords-1) str << pnw.sep;
62 }
63 return str;
64 }
65 // StreamTag monitoring accessors
66 inline const std::string mon_streamTypeName(const eformat::helper::StreamTag& st){
67 return st.type+"_"+st.name;
68 }
69 inline const std::string& mon_streamType(const eformat::helper::StreamTag& st){
70 return st.type;
71 }
72 inline bool mon_streamIsPeb(const eformat::helper::StreamTag& st){
73 return st.robs.size()>0 || st.dets.size()>0;
74 }
75 inline size_t mon_streamPebRobsNum(const eformat::helper::StreamTag& st){
76 return st.robs.size();
77 }
78 inline size_t mon_streamPebSubDetsNum(const eformat::helper::StreamTag& st){
79 return st.dets.size();
80 }
81}
82
83// =============================================================================
84// Standard constructor
85// =============================================================================
86TrigByteStreamCnvSvc::TrigByteStreamCnvSvc(const std::string& name, ISvcLocator* svcLoc)
87 : base_class(name, svcLoc) {}
88
89// =============================================================================
90// Standard destructor
91// =============================================================================
93
94// =============================================================================
95// Implementation of Service::initialize
96// =============================================================================
98 ATH_MSG_VERBOSE("start of " << __FUNCTION__);
100 ATH_CHECK(m_evtStore.retrieve());
102 if (!m_monTool.empty()) ATH_CHECK(m_monTool.retrieve());
103 ATH_MSG_VERBOSE("end of " << __FUNCTION__);
104 return StatusCode::SUCCESS;
105}
106
107// =============================================================================
108// Implementation of Service::finalize
109// =============================================================================
111 ATH_MSG_VERBOSE("start of " << __FUNCTION__);
112 if (m_robDataProviderSvc.release().isFailure())
113 ATH_MSG_WARNING("Failed to release service " << m_robDataProviderSvc.typeAndName());
114 if (m_evtStore.release().isFailure())
115 ATH_MSG_WARNING("Failed to release service " << m_evtStore.typeAndName());
116 ATH_MSG_VERBOSE("end of " << __FUNCTION__);
117 ATH_CHECK(ByteStreamCnvSvcBase::finalize());
118 return StatusCode::SUCCESS;
119}
120
121// =============================================================================
122// Implementation of (unsupported) IByteStreamCnvSvc
123// =============================================================================
125 ATH_MSG_ERROR("Bytestream creation is not supported by TrigByteStreamCnvSvc");
126 return nullptr;
127}
128
129StatusCode TrigByteStreamCnvSvc::storeFullEventAssembler(std::unique_ptr<FullEventAssemblerBase> /*fea*/,
130 const std::string& /*name*/) {
131 ATH_MSG_ERROR("Bytestream creation is not supported by TrigByteStreamCnvSvc");
132 return StatusCode::FAILURE;
133}
134
135// =============================================================================
136// Implementation of IConversionSvc::connectOutput
137// The argument outputFile is not used
138// =============================================================================
139StatusCode TrigByteStreamCnvSvc::connectOutput(const std::string& outputFile) {
140 const EventContext* eventContext = currentContext();
141 if (eventContext == nullptr) return StatusCode::FAILURE;
142 return connectOutput(outputFile, *eventContext);
143}
144
145StatusCode TrigByteStreamCnvSvc::connectOutput(const std::string& /*outputFile*/, const EventContext& eventContext) {
146 ATH_MSG_VERBOSE("start of " << __FUNCTION__);
147
148 ATH_MSG_DEBUG("Creating new RawEventWrite for EventContext = " << eventContext);
149 // Create a new RawEventWrite and copy the header from the input RawEvent
150 RawEventWrite* re = setRawEvent(std::make_unique<RawEventWrite>(), eventContext);
151 const uint32_t* inputRawEvent = m_robDataProviderSvc->getEvent(eventContext)->start();
152 if (!inputRawEvent) {
153 ATH_MSG_ERROR("Input RawEvent is nullptr, cannot create output");
154 return StatusCode::FAILURE;
155 }
156 re->copy_header(inputRawEvent);
157
158 ATH_MSG_VERBOSE("Created RawEventWrite pointer = " << re);
159
160 ATH_MSG_VERBOSE("end of " << __FUNCTION__);
161 return StatusCode::SUCCESS;
162}
163
164// =============================================================================
165// Implementation of IConversionSvc::connectOutput
166// The arguments are not used, this overload is implemented only for interface compatibility
167// =============================================================================
168StatusCode TrigByteStreamCnvSvc::connectOutput(const std::string& outputFile, const std::string& /*openMode*/) {
169 return connectOutput(outputFile);
170}
171
172// =============================================================================
173// Implementation of IConversionSvc::commitOutput
174// The arguments outputFile and do_commit are not used
175// NOTE: In online HLT, m_rawEventWrite is not a full event, it contains only the HLTResult ROBFragments
176// =============================================================================
177StatusCode TrigByteStreamCnvSvc::commitOutput(const std::string& outputFile, bool do_commit) {
178 const EventContext* eventContext = currentContext();
179 if (eventContext == nullptr) return StatusCode::FAILURE;
180 return commitOutput(outputFile, do_commit, *eventContext);
181}
182
183StatusCode TrigByteStreamCnvSvc::commitOutput(const std::string& /*outputFile*/, bool /*do_commit*/, const EventContext& eventContext) {
184 ATH_MSG_VERBOSE("start of " << __FUNCTION__);
185
186 if (msgLvl(MSG::DEBUG)) printRawEvent(eventContext);
187
188 RawEventWrite* re = getRawEvent(eventContext);
189
190 // Serialise the output FullEventFragment
191 std::unique_ptr<uint32_t[]> rawEventPtr;
192 try {
193 const eformat::write::node_t* top = re->bind();
194 uint32_t rawEventSize = re->size_word();
195 rawEventPtr = std::make_unique<uint32_t[]>(rawEventSize);
196 uint32_t copiedSize = eformat::write::copy(*top,rawEventPtr.get(),rawEventSize);
197 if(copiedSize!=rawEventSize) {
198 ATH_MSG_ERROR("FullEventFragment serialisation failed");
199 return StatusCode::FAILURE;
200 }
201 }
202 catch (const std::exception& e) {
203 ATH_MSG_ERROR("FullEventFragment serialisation failed, caught an unexpected std::exception " << e.what());
204 clearRawEvent(eventContext);
205 return StatusCode::FAILURE;
206 }
207 catch (...) {
208 ATH_MSG_ERROR("FullEventFragment serialisation failed, caught an unexpected exception");
209 clearRawEvent(eventContext);
210 return StatusCode::FAILURE;
211 }
212
213 {
214 auto t_mon = Monitored::Timer("TIME_monitorRawEvent");
215 monitorRawEvent(rawEventPtr);
217 }
218
219 // Send output to the DataCollector
220 StatusCode result = StatusCode::SUCCESS;
221 try {
222 auto t_eventDone = Monitored::Timer<std::chrono::duration<float, std::milli>>("TIME_eventDone");
223 hltinterface::DataCollector::instance()->eventDone(std::move(rawEventPtr));
224 Monitored::Group(m_monTool, t_eventDone);
225 ATH_MSG_DEBUG("Serialised FullEventFragment with HLT result was returned to DataCollector successfully, "
226 << "the eventDone call took " << (double)t_eventDone << " milliseconds");
227 }
228 catch (const std::exception& e) {
229 ATH_MSG_ERROR("Sending output to DataCollector failed, caught an unexpected std::exception " << e.what());
230 result = StatusCode::FAILURE;
231 }
232 catch (...) {
233 ATH_MSG_ERROR("Sending output to DataCollector failed, caught an unexpected exception");
234 result = StatusCode::FAILURE;
235 }
236
237 clearRawEvent(eventContext);
238
239 ATH_MSG_VERBOSE("end of " << __FUNCTION__);
240 return result;
241}
242
243// =============================================================================
244const EventContext* TrigByteStreamCnvSvc::currentContext() const {
245 // Get the EventContext via event store because the base class doesn't allow passing it explicitly as an argument
246 // and we don't want to use ThreadLocalContext. Don't use ReadHandle here because it calls ThreadLocalContext if
247 // not given a context (which we want to retrieve). This relies on IHiveWhiteBoard::selectStore being called on the
248 // current thread before we arrive here (it is done in HltEventLoopMgr).
249 const EventContext* eventContext = nullptr;
250 if (m_evtStore->retrieve(eventContext).isFailure()) {
251 ATH_MSG_ERROR("Failed to retrieve EventContext from the event store");
252 }
253 return eventContext;
254}
255
256// =============================================================================
258 const EventContext* eventContext = currentContext();
259 if (eventContext == nullptr) return nullptr;
260 return getRawEvent(*eventContext);
261}
262
263// =============================================================================
264RawEventWrite* TrigByteStreamCnvSvc::getRawEvent(const EventContext& eventContext) const {
265 return m_rawEventWriteCache.get(eventContext)->get();
266}
267
268// =============================================================================
269RawEventWrite* TrigByteStreamCnvSvc::setRawEvent(std::unique_ptr<RawEventWrite>&& rawEventWrite, const EventContext& eventContext) {
270 *(m_rawEventWriteCache.get(eventContext)) = std::move(rawEventWrite);
271 return getRawEvent(eventContext);
272}
273
274// =============================================================================
275void TrigByteStreamCnvSvc::clearRawEvent(const EventContext& eventContext) {
276 m_rawEventWriteCache.get(eventContext)->reset();
277}
278
279// =============================================================================
280void TrigByteStreamCnvSvc::monitorRawEvent(const std::unique_ptr<uint32_t[]>& rawEventPtr) const {
281 // Create a read fragment from the pointer
282 eformat::read::FullEventFragment rawEvent(rawEventPtr.get());
283
284 // Monitor error code
285 if (rawEvent.nstatus() > 1) {
286 HLT::OnlineErrorCode errorCode = static_cast<HLT::OnlineErrorCode>(rawEvent.status()[1]);
287 std::ostringstream ss;
288 ss << errorCode;
289 auto monOnlineErrorCode = Monitored::Scalar<std::string>("OnlineErrorCode", ss.str());
290 Monitored::Group(m_monTool, monOnlineErrorCode);
291 }
292
293 // Decode stream tags
294 std::vector<eformat::helper::StreamTag> streamTags;
295 try {
296 eformat::helper::decode(rawEvent.nstream_tag(), rawEvent.stream_tag(), streamTags);
297 }
298 catch (const std::exception& ex) {
299 ATH_MSG_ERROR("StreamTag decoding failed, caught an unexpected std::exception " << ex.what());
300 return;
301 }
302 catch (...) {
303 ATH_MSG_ERROR("StreamTag decoding failed, caught an unexpected exception");
304 return;
305 }
306
307 // Get HLT result sizes
308 std::vector<eformat::read::ROBFragment> robs;
309 rawEvent.robs(robs);
310 std::vector<uint16_t> resultSizeMap_moduleID;
311 std::vector<uint32_t> resultSizeMap_size;
312 uint32_t totalSizeWords = 0;
313 try {
314 for (const eformat::read::ROBFragment& rob : robs) {
315 eformat::helper::SourceIdentifier sid(rob.rob_source_id());
316 if (sid.subdetector_id() != eformat::SubDetector::TDAQ_HLT)
317 continue;
318 const uint16_t module_id = sid.module_id();
319 const uint32_t size = rob.fragment_size_word();
320 totalSizeWords += size;
321 if (!contains(resultSizeMap_moduleID, module_id)) {
322 resultSizeMap_moduleID.push_back(module_id);
323 resultSizeMap_size.push_back(size);
324 }
325 else {
326 ATH_MSG_ERROR("HLT result ROB monitoring found multiple HLT ROBs with the same module ID " << module_id);
327 }
328 }
329 }
330 catch (const std::exception& ex) {
331 ATH_MSG_ERROR("HLT result ROB monitoring failed, caught an unexpected std::exception " << ex.what());
332 return;
333 }
334 catch (...) {
335 ATH_MSG_ERROR("HLT result ROB monitoring failed, caught an unexpected exception");
336 return;
337 }
338
339 // Fill helper containers for monitoring
340 std::vector<std::string> sdFromRobList;
341 std::vector<std::string> sdFromSubDetList;
342 std::vector<std::string> streamTagCorrA;
343 std::vector<std::string> streamTagCorrB;
344 std::vector<float> streamResultSize; // Correlated with streamTags vector
345 streamTagCorrA.reserve(streamTags.size() * streamTags.size());
346 streamTagCorrB.reserve(streamTags.size() * streamTags.size());
347 streamResultSize.reserve(streamTags.size());
348 for (const eformat::helper::StreamTag& st : streamTags) {
349 bool hasHLTSubDet = st.dets.find(eformat::SubDetector::TDAQ_HLT) != st.dets.end();
350 bool includeAll = st.robs.empty() && (st.dets.empty() || hasHLTSubDet);
351 // includeAll means a stream with full event building or all HLT results included
352 uint32_t sizeWords = includeAll ? totalSizeWords : 0;
353 for (const eformat::SubDetector sd : st.dets) {
354 const std::string& detName = eformat::helper::SubDetectorDictionary.string(sd);
355 if (!contains(sdFromSubDetList, detName)) sdFromSubDetList.push_back(detName);
356 }
357 for (const uint32_t robid : st.robs) {
358 eformat::helper::SourceIdentifier sid(robid);
359 const std::string& detName = sid.human_detector();
360 if (!contains(sdFromRobList, detName)) sdFromRobList.push_back(detName);
361 if (!includeAll && sid.subdetector_id() == eformat::SubDetector::TDAQ_HLT) {
362 if (const int ix = index(resultSizeMap_moduleID, sid.module_id()); ix >= 0) {
363 sizeWords += resultSizeMap_size[ix];
364 }
365 else {
366 ATH_MSG_WARNING("Stream tag " << st.type << "_" << st.name << " declares " << sid.human()
367 << " in ROB list, but the ROBFragment is missing");
368 }
369 }
370 }
371 streamResultSize.push_back(sizeWords*wordsToKiloBytes);
372 for (const eformat::helper::StreamTag& st2 : streamTags) {
373 streamTagCorrA.push_back(mon_streamTypeName(st));
374 streamTagCorrB.push_back(mon_streamTypeName(st2));
375 }
376 }
377
378 // General stream tag monitoring
379 auto monStreamTagsNum = Monitored::Scalar<size_t>("StreamTagsNum", streamTags.size());
380 auto monStreamTags = Monitored::Collection("StreamTags", streamTags, mon_streamTypeName);
381 auto monStreamTagsType = Monitored::Collection("StreamTagsType", streamTags, mon_streamType);
382 auto monStreamTagCorrA = Monitored::Collection("StreamTagCorrA", streamTagCorrA);
383 auto monStreamTagCorrB = Monitored::Collection("StreamTagCorrB", streamTagCorrB);
384 // PEB stream tag monitoring
385 auto monStreamIsPeb = Monitored::Collection("StreamTagIsPeb", streamTags, mon_streamIsPeb);
386 auto monPebRobsNum = Monitored::Collection("StreamTagsPebRobsNum", streamTags, mon_streamPebRobsNum);
387 auto monPebSubDetsNum = Monitored::Collection("StreamTagsPebSubDetsNum", streamTags, mon_streamPebSubDetsNum);
388 auto monSubDetsFromRobList = Monitored::Collection("StreamTagsPebSubDetsFromRobList", sdFromRobList);
389 auto monSubDetsFromSubDetList = Monitored::Collection("StreamTagsPebSubDetsFromSubDetList", sdFromSubDetList);
390 // Result size monitoring
391 auto monResultSizeTotal = Monitored::Scalar<float>("ResultSizeTotal", totalSizeWords*wordsToKiloBytes);
392 auto monResultSizeFullEvFrag = Monitored::Scalar<float>("ResultSizeFullEvFrag", rawEvent.fragment_size_word()*wordsToKiloBytes);
393 auto monResultCollModuleID = Monitored::Collection("ResultModuleID", resultSizeMap_moduleID);
394 auto monResultCollModuleSize = Monitored::Collection("ResultModuleSize", resultSizeMap_size, [](uint32_t sw){return sw*wordsToKiloBytes;});
395 auto monResultSizeByStream = Monitored::Collection("ResultSizeStream", streamResultSize);
396 // Collect all variables
397 Monitored::Group(m_monTool, monStreamTagsNum, monStreamTags, monStreamTagsType, monStreamTagCorrA,
398 monStreamTagCorrB, monStreamIsPeb, monPebRobsNum, monPebSubDetsNum, monSubDetsFromRobList,
399 monSubDetsFromSubDetList, monResultSizeTotal, monResultSizeFullEvFrag, monResultCollModuleID,
400 monResultCollModuleSize, monResultSizeByStream);
401}
402
403// =============================================================================
404void TrigByteStreamCnvSvc::printRawEvent(const EventContext& eventContext) const {
405 RawEventWrite* re = getRawEvent(eventContext);
406
407 if (!re) {
408 ATH_MSG_WARNING("RawEventWrite pointer is null");
409 return;
410 }
411 std::ostringstream ss;
412 ss << "Dumping header of the FullEventFragment with HLT result:" << std::endl;
413 ss << "--> status = "
414 << printNWordsHex<uint32_t>(re->nstatus(), re->status())
415 << std::endl;
416 ss << "--> source_id = " << printWordHex<uint32_t>(re->source_id()) << std::endl;
417 ss << "--> checksum_type = " << printWordHex<uint32_t>(re->checksum_type()) << std::endl;
418 ss << "--> compression_type = " << printWordHex<uint32_t>(re->compression_type()) << std::endl;
419 ss << "--> compression_level = " << re->compression_level() << std::endl;
420 ss << "--> bc_time_seconds = " << re->bc_time_seconds() << std::endl;
421 ss << "--> bc_time_nanoseconds = " << re->bc_time_nanoseconds() << std::endl;
422 ss << "--> global_id = " << re->global_id() << std::endl;
423 ss << "--> run_type = " << re->run_type() << std::endl;
424 ss << "--> run_no = " << re->run_no() << std::endl;
425 ss << "--> lumi_block = " << re->lumi_block() << std::endl;
426 ss << "--> lvl1_id = " << re->lvl1_id() << std::endl;
427 ss << "--> bc_id = " << re->bc_id() << std::endl;
428 ss << "--> lvl1_trigger_type = " << printWordHex<uint8_t>(re->lvl1_trigger_type()) << std::endl;
429 ss << "--> lvl1_trigger_info = "
430 << printNWordsHex<uint32_t>(re->nlvl1_trigger_info(), re->lvl1_trigger_info())
431 << std::endl;
432 ss << "--> lvl2_trigger_info = "
433 << printNWordsHex<uint32_t>(re->nlvl2_trigger_info(), re->lvl2_trigger_info())
434 << std::endl;
435 ss << "--> event_filter_info = "
436 << printNWordsHex<uint32_t>(re->nevent_filter_info(), re->event_filter_info())
437 << std::endl;
438 ss << "--> hlt_info = "
439 << printNWordsHex<uint32_t>(re->nhlt_info(), re->hlt_info())
440 << std::endl;
441
442 std::vector<eformat::helper::StreamTag> stream_tags;
443 try {
444 eformat::helper::decode(re->nstream_tag(), re->stream_tag(), stream_tags);
445 }
446 catch (const std::exception& ex) {
447 ATH_MSG_ERROR("StreamTag decoding failed, caught an unexpected std::exception " << ex.what());
448 return;
449 }
450 catch (...) {
451 ATH_MSG_ERROR("StreamTag decoding failed, caught an unexpected exception");
452 return;
453 }
454 ss << "--> stream_tags = ";
455 bool first = true;
456 for (const auto& st : stream_tags) {
457 if (first) first=false;
458 else ss << " ";
459 ss << "{" << st.name << ", " << st.type << ", obeysLB=" << st.obeys_lumiblock << ", robs=[";
460 for (const auto& robid : st.robs) ss << printWordHex<uint32_t>(robid) << ", ";
461 ss << "], dets = [";
462 for (const auto& detid : st.dets) ss << printWordHex<uint8_t>(detid) << ", ";
463 ss << "]}" << std::endl;
464 }
465
466 ATH_MSG_DEBUG(ss.str());
467}
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)
std::vector< size_t > vec
Assign a CLID to EventContext.
static Double_t ss
OFFLINE_FRAGMENTS_NAMESPACE_WRITE::FullEventFragment RawEventWrite
data type for writing raw event
Definition RawEvent.h:39
std::ostream & operator<<(std::ostream &lhs, const TestGaudiProperty &rhs)
@ top
virtual StatusCode initialize() override
Required of all Gaudi Services.
base class for assembling a full atlas raw event from subfragments
Group of local monitoring quantities and retain correlation when filling histograms
Declare a monitored scalar variable.
A monitored timer.
const EventContext * currentContext() const
Hack used in HLT to avoid using ThreadLocalContext, see explanation in the implementation.
RawEventWrite * setRawEvent(std::unique_ptr< RawEventWrite > &&rawEventWrite, const EventContext &eventContext)
Store new raw event in the cache.
virtual StatusCode finalize() override
TrigByteStreamCnvSvc(const std::string &name, ISvcLocator *svcLoc)
Standard constructor.
void monitorRawEvent(const std::unique_ptr< uint32_t[]> &rawEventPtr) const
Fill histograms from contents of a FullEventFragment.
virtual StatusCode connectOutput(const std::string &outputFile) override
In the case of online BS data, this method creates the output FullEventFragment and fills its header.
virtual StatusCode storeFullEventAssembler(std::unique_ptr< FullEventAssemblerBase > fea, const std::string &name) override
virtual ~TrigByteStreamCnvSvc()
Standard destructor.
virtual StatusCode commitOutput(const std::string &outputFile, bool do_commit) override
In the case of online BS data, this method binds and sends out the output FullEventFragment.
virtual StatusCode initialize() override
virtual RawEventWrite * getRawEvent() override
Return a pointer to the raw event for the current event context.
SG::SlotSpecificObj< std::unique_ptr< RawEventWrite > > m_rawEventWriteCache
void printRawEvent(const EventContext &eventContext) const
Print contents of the raw event.
ServiceHandle< StoreGateSvc > m_evtStore
ToolHandle< GenericMonitoringTool > m_monTool
virtual FullEventAssemblerBase * findFullEventAssembler(const std::string &name) const override
void clearRawEvent(const EventContext &eventContext)
Delete raw event from the cache.
ServiceHandle< IROBDataProviderSvc > m_robDataProviderSvc
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition hcg.cxx:114
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
unsigned long long T
Definition index.py:1
setEventNumber uint32_t