ATLAS Offline Software
Loading...
Searching...
No Matches
MixingEventSelector.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6ATLAS_NO_CHECK_FILE_THREAD_SAFETY; // non-MT EventSelector
7
11#include "EventInfo/EventInfo.h"
12#include "EventInfo/EventID.h"
13#include "EventInfo/EventType.h"
18#include "SGTools/DataProxy.h"
20
21#include "GaudiKernel/GaudiException.h"
22#include "GaudiKernel/TypeNameString.h"
23#include "GaudiKernel/MsgStream.h"
24#include "GaudiKernel/GenericAddress.h"
25#include "CLHEP/Random/RandFlat.h"
26#include <charconv>
27#include <boost/tokenizer.hpp>
28#include <algorithm>
29#include <cassert>
30#include <functional>
31#include <iostream>
32#include <fstream>
33#include <stdexcept>
34#include <sstream>
35#include <string>
36
37using namespace std;
38using boost::tokenizer;
39using boost::char_separator;
40using SG::DataProxy;
41
42#ifdef DEBUG_OUTPUT_STATUS
43ofstream outfile2("status.txt");
44#endif
45
46MixingEventSelector::MixingEventSelector(const string& name, ISvcLocator* svc) :
47 base_class(name,svc),
49 m_pEventStore( "StoreGateSvc", name )
50{
51}
52
55
56StatusCode
58 ATH_MSG_INFO ("Initializing " << name());
59
60// defer this (it triggers a init loop via PPS
61// if (!m_pEventStore.retrieve().isSuccess())
62// return StatusCode::FAILURE;
63
64 //setup random stream
65 CLHEP::HepRandomEngine* collEng(m_atRndmSvc->GetEngine(m_randomStreamName.value()));
66 if(nullptr == collEng ) {
67 ATH_MSG_ERROR ("can not get random stream " << m_randomStreamName.value());
68 return StatusCode::FAILURE;
69 }
70 //flat distribution in [0,1] range
71 m_chooseRangeRand = std::make_unique<CLHEP::RandFlat>(*(collEng), 0.0, 1.0);
72
73 ATH_CHECK( m_helperTools.retrieve() );
74 for (ToolHandle<IAthenaSelectorTool>& tool : m_helperTools) {
75 ATH_CHECK( tool->postInitialize() );
76 }
77
78 return StatusCode::SUCCESS;
79}
80
81StatusCode
83 ATH_MSG_DEBUG ("Finalizing " << name());
84
85 for (ToolHandle<IAthenaSelectorTool>& tool : m_helperTools) {
86 tool->preFinalize().ignore();
87 }
88
89 const std::string& fname(m_statusFileName.value());
90 ofstream outfile(fname.c_str());
91 if ( outfile ) {
94 while (i != iEnd) outfile << (*i++).toString();
95 } else if (!fname.empty()) {
96 ATH_MSG_WARNING("unable to open trigger list status file " << fname);
97 }
98
99 return StatusCode::SUCCESS;
100}
101
102
103void
104MixingEventSelector::setUpTriggerList(Gaudi::Details::PropertyBase&) {
105 using std::placeholders::_1;
107 for_each(m_triggerListProp.value().begin(), m_triggerListProp.value().end(),
108 bind(&MixingEventSelector::decodeTrigger, this, _1));
110}
111
112void
114 //all this would be much more readable without error reporting...
115 typedef tokenizer<char_separator<char> > Tokenizer;
116 Tokenizer tokens(triggDescr, char_separator<char>(" :"));
117 //we need exactly three tokens: selector name, first and last event 2 B read
118 if ( (distance(tokens.begin(), tokens.end()) == 3) ||
119 (distance(tokens.begin(), tokens.end()) == 3) ){
120 Tokenizer::iterator iToken(tokens.begin());
121 Gaudi::Utils::TypeNameString selTN(*iToken++);
122 //get selector
123 SmartIF<IEvtSelector> pSelector(serviceLocator()->service(selTN));
124 if (pSelector) {
125 //FIXME if (!pSelector.done()) {
126 //try to add to trig list
127 unsigned int firstEvt{};
128 unsigned int lastEvt{};
129 auto string1 = *iToken++;
130 auto string2 = *iToken;
131 auto [ptr1, ec1] = std::from_chars(string1.data(), string1.data() + string1.size(), firstEvt);
132 auto [ptr2, ec2] = std::from_chars(string2.data(), string2.data() + string2.size(), lastEvt);
133 if ( ec1 != std::errc() || ec2 != std::errc() ) {
134 ATH_MSG_ERROR("decodeTrigger: Can't cast ["<< string1 << " " << string2 << "] to double(frequency). SKIPPING");
135 } else {
136 if (m_trigList.add(Trigger(pSelector, firstEvt, lastEvt))) {
137 if (msgLvl(MSG::DEBUG)) {
138 SmartIF<INamedInterface> pNamed(pSelector);
139 if (pNamed) {
140 msg() << "decodeTrigger: added selector " << pNamed->name()
141 << " first event to be read " << firstEvt
142 << " last event to be read " << lastEvt << endmsg;
143 }
144 }
145 } else {
147 ("decodeTrigger: Selector ["
148 << selTN.type() << '/' << selTN.name()
149 << "] not added");
150 } //can add to range
151 }
152 } else {
154 ("decodeTrigger: Selector ["
155 << selTN.type() << '/' << selTN.name()
156 << "] can not be found or created");
157 } //selector available
158 } else {
160 ("decodeTrigger: Badly formatted descriptor ["
161 << triggDescr << "]. SKIPPING");
162 } //can parse property string
163}
164
165#ifndef NDEBUG
166#define FORWARD___DEBUG( METHOD )\
167 { ATH_MSG_VERBOSE ("forwarding " << #METHOD << " to service "\
168 << (validTrigger() ? currentTrigger()->name() : "NONE")); }
169#else
170#define FORWARD___DEBUG( METHOD )
171#endif
172
173StatusCode MixingEventSelector::createContext(IEvtSelector::Context*& pctxt) const {
174 pctxt=nullptr;
175 if (!validTrigger()) return StatusCode::FAILURE;
177 StatusCode sc(StatusCode::FAILURE);
178 while (iTr != m_trigList.end() && (sc=(iTr++)->createContext(pctxt)).isSuccess()) ;
179 return sc;
180}
181
182StatusCode
183MixingEventSelector::next(IEvtSelector::Context& /*c*/) const {
184 StatusCode sc(StatusCode::FAILURE);
185 do {
186#ifdef DEBUG_OUTPUT_STATUS
189 while (i != iEnd) outfile2 << (*i++).toString(); //output status
190#endif
192 sc = currentTrigger()->next();
193 if (sc.isFailure()){
195 continue; // we have to add "continue;" after "m_trigList.remove(m_pCurrentTrigger);
196 }
197 } while ((sc.isFailure() || currentTrigger()->done()) && !m_trigList.empty() );
198 // use !m_trigList.empty() to replace validTrigger(), which is not working well
199
200 std::vector<ToolHandle<IAthenaSelectorTool> >::const_iterator
201 i(m_helperTools.begin()), iE(m_helperTools.end());
202 while (i != iE) ((*i++)->preNext()).ignore();
203
204 ++m_eventPos;
206
207 i=m_helperTools.begin(); iE=m_helperTools.end();
208 while (sc.isSuccess() && (i != iE)) {
209 sc =(*i)->postNext();
210 if (sc.isRecoverable())
211 ATH_MSG_INFO("Request skipping event from: " << (*i)->name());
212 else if (sc.isFailure())
213 ATH_MSG_WARNING((*i)->name() << ":postNext failed");
214 ++i;
215 }
216 return sc;
217}
218
219
220StatusCode
221MixingEventSelector::createAddress(const IEvtSelector::Context& /*c*/,
222 IOpaqueAddress*& pAddr) const {
223 pAddr=nullptr;
224 if (!validTrigger()) return StatusCode::FAILURE;
225
227 return (currentTrigger()->createAddress(pAddr).isSuccess() &&
228 pAddr != nullptr) ? StatusCode::SUCCESS : StatusCode::FAILURE;
229}
230
231StatusCode
233 IAddressProvider::tadList& /*tads*/ ) {
234 return StatusCode::SUCCESS;
235}
236
237StatusCode
239 IAddressProvider::tadList& /*tads*/ )
240{
241 if (storeID != StoreID::EVENT_STORE && storeID != StoreID::PILEUP_STORE)
242 return StatusCode::SUCCESS;
243
245 if (!m_pEventStore->contains (mclid, m_mergedEventInfoKey)) {
246 // We create the DataProxy here rather than relying on ProxyProvideSvc
247 // to do it because we want to set a non-default dataloader on the proxy.
248 SG::TransientAddress tad (mclid,
250 new GenericAddress (0, mclid),
251 false);
252 auto dp = std::make_unique<SG::DataProxy> (std::move(tad),
253 this,
254 true);
255 ATH_CHECK( m_pEventStore->addToStore (mclid, dp.release()) );
256 }
257 return StatusCode::SUCCESS;
258}
259
260StatusCode
262 const EventContext&) {
263 return StatusCode::FAILURE;
264}
265
266#undef FORWARD___DEBUG
267
268unsigned long MixingEventSelector::getEventNo() const {
269 return ( (m_eventNumbers.value().size() > m_eventPos) ?
270 m_eventNumbers.value()[m_eventPos] :
271 m_eventPos );
272}
273
274//remember that m_pCurrentTrigger and m_trigList are mutable
277 //we look for the first trigger which is not done
278 do {
279 //if called before initialize, choose the last trigger in list
280 unsigned int iTrig = (nullptr != m_chooseRangeRand) ?
281 (unsigned int)(m_chooseRangeRand->fire() * double(m_trigList.todo())) :
282 m_trigList.todo();
283 m_pCurrentTrigger = m_trigList.elementInRange(iTrig);
284 } while (validTrigger() && m_pCurrentTrigger->done() &&
285 m_trigList.remove(m_pCurrentTrigger)); //remove a done trigger
286
287 //printouts
288 if (!validTrigger()) {
289 ATH_MSG_INFO ("setCurrentTrigger: end of input");
290 } else {
291 ATH_MSG_DEBUG ("setCurrentTrigger: now using selector "
292 << currentTrigger()->name());
293 }
294
295 return m_pCurrentTrigger;
296}
297
302
303bool
305 bool newElem(end() == find(begin(), end() , trig));
306 if (newElem) {
307 m_todo += trig.todo();
308 m_trigs.push_back(trig);
309 m_rangeEnd.push_back(m_todo);
310#ifndef NDEBUG
311 MsgStream log(Athena::getMessageSvc(), "MixingEventSelector::TriggerList");
312 if (log.level() <= MSG::DEBUG) {
313 log << MSG::DEBUG << "add: trigger "
314 << trig.name() << ". New trigger table: \n" << toString() <<endmsg;
315 }
316#endif
317 }
318 return newElem;
319}
320
321bool
323 bool removed(false);
324 unsigned int nElem(m_trigs.size());
325 if (nElem) {
326 unsigned int trigTodo(iTrig->todo());
327 unsigned int trigIndex(iTrig - begin());
328#ifndef NDEBUG
329 string trigName(iTrig->name());
330#endif
331 m_trigs.erase(iTrig);
332 removed = nElem > m_trigs.size();
333 if (removed) {
334 //this means we erased iTrig. Remove its todo count from total
335 m_todo -= trigTodo;
336 //and from each of the subsequent ranges
337 for (unsigned int i=trigIndex+1; i<m_rangeEnd.size(); ++i)
338 m_rangeEnd[i] -= trigTodo;
339 //finally erase the corresponding rangeEnd element
340 m_rangeEnd.erase(m_rangeEnd.begin()+trigIndex);
341#ifndef NDEBUG
342 MsgStream log(Athena::getMessageSvc(), "MixingEventSelector::TriggerList"); //FIXME
343 if (log.level() <= MSG::DEBUG) {
344 log << MSG::DEBUG << "remove: trigger "
345 << trigName
346 << ". New trigger table: \n" << toString() <<endmsg;
347 }
348#endif
349 }
350 }
351 return removed;
352}
353
354string
356 ostringstream os;
357 for (unsigned int i=0; i<m_trigs.size(); ++i) {
358 //cant do os << m_trigs[i].toString();
359 os << m_trigs[i].name() << ", already read=" << m_trigs[i].read()
360 << ", to do=" << m_trigs[i].todo()
361 << (m_trigs[i].done() ? " done " : " ")
362 << " - endRange: " << m_rangeEnd[i] << '\n';
363 }
364 os << endl;
365 return string(os.str());
366}
367
370 iterator iTrig(m_trigs.begin()), eTrig(m_trigs.end());
371 std::vector<unsigned int>::const_iterator iRange(m_rangeEnd.begin());
372 std::vector<unsigned int>::const_iterator eRange(m_rangeEnd.end());
373 while (eRange != iRange && eTrig != iTrig && i > *iRange){
374 ++iRange; ++iTrig;
375 }
376#ifndef NDEBUG
377 MsgStream log(Athena::getMessageSvc(), "MixingEventSelector::TriggerList");
378 if (log.level() <= MSG::VERBOSE) {
379 if (eRange != iRange) log << MSG::VERBOSE
380 << "elementInRange: rangeEnd=" << *iRange
381 << " matches i=" << i << endmsg;
382 }
383#endif
384 return iTrig;
385}
386
388 unsigned int firstEvt,
389 unsigned int lastEvt):
390 m_pSelector(pSel), m_firstEvent(firstEvt),
391 m_toRead(lastEvt+1), m_todo(m_toRead-firstEvt), m_reads(0),
392 m_current(nullptr)
393 { }
394
395IEvtSelector::Context& MixingEventSelector::Trigger::currentContext() const {
396 //make sure we have a context!
397 if (nullptr == m_current) {
398 IEvtSelector::Context* pTmp(nullptr);
399 if ((createContext(pTmp)).isFailure())
400 throw GaudiException("MixingEventSelector::Trigger::currentContext(): can't create context",
401 name(),StatusCode::FAILURE);
402 }
403 // cppcheck-suppress nullPointerRedundantCheck; createContext() sets m_current
404 return *m_current;
405}
406
407std::string
409 ostringstream os;
410 os << name() << ", already read=" << m_reads
411 << ", to do=" << todo() << endl;
412 return string(os.str());
413}
414
415StatusCode
417 StatusCode sc(StatusCode::FAILURE);
418 if (!done()) {
419 sc= selector().next(currentContext());
420 while (sc.isSuccess() && (++m_reads < m_firstEvent))
421 sc = selector().next(currentContext());// m_reads, m_current are mutable
422 }
423 // cout << "calling next on Trigger " << this << " " << dynamic_cast<IService&>(selector()).name() << endl;
424 return sc;
425}
426
427StatusCode
429 return selector().previous(currentContext());
430}
431
432StatusCode
434 return (done() ?
435 StatusCode::FAILURE :
437}
438
439StatusCode
440MixingEventSelector::Trigger::createContext(IEvtSelector::Context*& pCtxt) const{
441 StatusCode sc(StatusCode::FAILURE);
442 if (!done()) {
443 sc = selector().createContext(pCtxt);
444 m_current = pCtxt;
445 }
446 return sc;
447}
448
449bool
451 // cout << "calling done on Trigger " << this << " " << dynamic_cast<IService&>(selector()).name() << endl;
452 // cout << refCtxt << " " << selector().end() << endl;
453 // cout << toRead() << " " << m_reads << endl;
454 // cout << "done returns " << ((m_current && (currentContext() == *selector().end())) || (toRead() <= m_reads)) << endl;
455 return (toRead() <= m_reads);
456}
457
458
459StatusCode MixingEventSelector::last(IEvtSelector::Context&) const {
460 return StatusCode::FAILURE;
461}
462StatusCode MixingEventSelector::next(IEvtSelector::Context&, int) const {
463 return StatusCode::FAILURE;
464}
465StatusCode MixingEventSelector::previous(IEvtSelector::Context&) const {
466 return StatusCode::FAILURE;
467}
468StatusCode MixingEventSelector::previous(IEvtSelector::Context&,int) const {
469 return StatusCode::FAILURE;
470}
471StatusCode MixingEventSelector::rewind(IEvtSelector::Context&) const {
472 return StatusCode::FAILURE;
473}
474StatusCode MixingEventSelector::releaseContext(IEvtSelector::Context*&) const {
475 return StatusCode::FAILURE;
476}
477StatusCode MixingEventSelector::resetCriteria(const std::string&,
478 IEvtSelector::Context&)const {
479 return StatusCode::FAILURE;
480}
481
482
483// IConverter implementation.
489{
490 return 0;
491}
492
493
505StatusCode MixingEventSelector::createObj(IOpaqueAddress* /*pAddress*/,
506 DataObject*& refpObject)
507{
508 const EventInfo* pEInfo(nullptr);
509 if (!(m_pEventStore->retrieve(pEInfo)).isSuccess()) {
511 ("addMergedEventInfo: event store does not contain "\
512 "an EventInfo object!");
513 return StatusCode::RECOVERABLE;
514 }
515
516 // copy the original event to a new MergedEventInfo
517 auto mei = std::make_unique<MergedEventInfo> (*pEInfo,
519 getEventNo());
520 refpObject = SG::asStorable (std::move (mei));
521
522
523 //finally slam a new EventID in place of the old! HACK!!! FIXME!!
524 (const_cast<EventInfo*>(pEInfo))->setEventID(
526
527 return StatusCode::SUCCESS;
528}
529
530
531// IConverter dummies.
532StatusCode MixingEventSelector::setDataProvider(IDataProviderSvc* /*pService*/)
533{
534 std::abort();
535}
536SmartIF<IDataProviderSvc>& MixingEventSelector::dataProvider() const
537{
538 std::abort();
539}
540StatusCode MixingEventSelector::setConversionSvc(IConversionSvc* /*pService*/)
541{
542 std::abort();
543}
544SmartIF<IConversionSvc>& MixingEventSelector::conversionSvc() const
545{
546 std::abort();
547}
548StatusCode MixingEventSelector::setAddressCreator(IAddressCreator* /*creator*/)
549{
550 std::abort();
551}
552SmartIF<IAddressCreator>& MixingEventSelector::addressCreator() const
553{
554 std::abort();
555}
556StatusCode MixingEventSelector::fillObjRefs(IOpaqueAddress* /*pAddress*/, DataObject* /*pObject*/)
557{
558 std::abort();
559}
560StatusCode MixingEventSelector::updateObj(IOpaqueAddress* /*pAddress*/, DataObject* /*refpObject*/)
561{
562 std::abort();
563}
564StatusCode MixingEventSelector::updateObjRefs(IOpaqueAddress* /*pAddress*/, DataObject* /*pObject*/)
565{
566 std::abort();
567}
568StatusCode MixingEventSelector::createRep(DataObject* /*pObject*/, IOpaqueAddress*& /*refpAddress*/)
569{
570 std::abort();
571}
572StatusCode MixingEventSelector::fillRepRefs(IOpaqueAddress* /*pAddress*/, DataObject* /*pObject*/)
573{
574 std::abort();
575}
576StatusCode MixingEventSelector::updateRep(IOpaqueAddress* /*pAddress*/, DataObject* /*pObject*/)
577{
578 std::abort();
579}
580StatusCode MixingEventSelector::updateRepRefs(IOpaqueAddress* /*pAddress*/, DataObject* /*pObject*/)
581{
582 std::abort();
583}
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(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...
This class provides a unique identification for each event, in terms of run/event number and/or a tim...
This class provides general information about an event.
uint32_t CLID
The Class ID type.
static Double_t sc
This class provides general information about an event.
#define FORWARD___DEBUG(METHOD)
a stream of events read from different selectors.
convert to and from a SG storable
This class contains trigger related information.
Define macros for attributes used to control the static checker.
#define ATLAS_NO_CHECK_FILE_THREAD_SAFETY
This class provides a unique identification for each event, in terms of run/event number and/or a tim...
Definition EventID.h:35
std::list< SG::TransientAddress * > tadList
the list of available selectors with their frequency range
std::vector< Trigger >::iterator iterator
std::vector< unsigned int > m_rangeEnd
std::vector< Trigger >::const_iterator const_iterator
a selector with an associated frequency
StatusCode createContext(IEvtSelector::Context *&pCtxt) const
Trigger(IEvtSelector *pSel, unsigned int firstEvt, unsigned int lastEvt)
const std::string & name() const
StatusCode createAddress(IOpaqueAddress *&) const
IEvtSelector & selector() const
IEvtSelector::Context * m_current
IEvtSelector::Context & currentContext() const
Gaudi::Property< std::string > m_mergedEventInfoKey
virtual StatusCode setConversionSvc(IConversionSvc *pService) override
TriggerList::iterator currentTrigger() const
"intelligent" accessor to the above
Gaudi::Property< std::string > m_statusFileName
virtual StatusCode createContext(IEvtSelector::Context *&refpCtxt) const override
virtual StatusCode initialize() override
TriggerList::iterator setCurrentTrigger() const
choose current trigger at random. Actually modifies state (use mutables)
virtual StatusCode next(IEvtSelector::Context &refCtxt) const override
virtual SmartIF< IDataProviderSvc > & dataProvider() const override
virtual StatusCode createAddress(const IEvtSelector::Context &refCtxt, IOpaqueAddress *&) const override
virtual StatusCode rewind(IEvtSelector::Context &refCtxt) const override
Gaudi::Property< int > m_outputRunNumber
virtual StatusCode previous(IEvtSelector::Context &) const override
Gaudi::Property< std::vector< unsigned long > > m_eventNumbers
unsigned long getEventNo() const
setup and lookup m_evtsNotUsedSoFar. Returns next event no
void decodeTrigger(std::string triggDescr)
functor that creates a Trigger object and adds it to m_trigList
virtual StatusCode updateObj(IOpaqueAddress *pAddress, DataObject *refpObject) override
virtual StatusCode last(IEvtSelector::Context &) const override
MixingEventSelector(const std::string &name, ISvcLocator *svc)
Gaudi::Property< std::string > m_randomStreamName
virtual StatusCode createRep(DataObject *pObject, IOpaqueAddress *&refpAddress) override
Gaudi::Property< std::vector< std::string > > m_triggerListProp
virtual StatusCode setAddressCreator(IAddressCreator *creator) override
virtual StatusCode updateObjRefs(IOpaqueAddress *pAddress, DataObject *pObject) override
virtual StatusCode updateAddress(StoreID::type storeID, SG::TransientAddress *tad, const EventContext &ctx) override
virtual StatusCode releaseContext(IEvtSelector::Context *&refCtxt) const override
virtual const CLID & objType() const override
TriggerList m_trigList
the ingredients
virtual StatusCode updateRepRefs(IOpaqueAddress *pAddress, DataObject *pObject) override
virtual StatusCode fillRepRefs(IOpaqueAddress *pAddress, DataObject *pObject) override
virtual StatusCode fillObjRefs(IOpaqueAddress *pAddress, DataObject *pObject) override
virtual StatusCode finalize() override
virtual StatusCode loadAddresses(StoreID::type storeID, IAddressProvider::tadList &tads) override
virtual StatusCode updateRep(IOpaqueAddress *pAddress, DataObject *pObject) override
virtual SmartIF< IAddressCreator > & addressCreator() const override
virtual StatusCode preLoadAddresses(StoreID::type storeID, IAddressProvider::tadList &tads) override
TriggerList::iterator m_pCurrentTrigger
the current trigger
ServiceHandle< StoreGateSvc > m_pEventStore
virtual StatusCode setDataProvider(IDataProviderSvc *pService) override
ServiceHandle< IAtRndmGenSvc > m_atRndmSvc
virtual long repSvcType() const override
unsigned long m_eventPos
the internal event number
void setUpTriggerList(Gaudi::Details::PropertyBase &trigList)
TriggerList property call-back.
std::unique_ptr< CLHEP::RandFlat > m_chooseRangeRand
ToolHandleArray< IAthenaSelectorTool > m_helperTools
virtual StatusCode createObj(IOpaqueAddress *pAddress, DataObject *&refpObject) override
Create the transient representation of an object.
virtual SmartIF< IConversionSvc > & conversionSvc() const override
virtual StatusCode resetCriteria(const std::string &cr, IEvtSelector::Context &c) const override
@ EVENT_STORE
Definition StoreID.h:26
@ PILEUP_STORE
Definition StoreID.h:31
singleton-like access to IMessageSvc via open function and helper
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138
IMessageSvc * getMessageSvc(bool quiet=false)
DataObject * asStorable(SG::DataObjectSharedPtr< T > pObject)
STL namespace.
MsgStream & msg
Definition testRead.cxx:32