ATLAS Offline Software
Loading...
Searching...
No Matches
xAODEventSelector.cxx
Go to the documentation of this file.
1
2
3/*
4 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
5*/
6
7// xAODEventSelector.cxx
8// Implementation file for class xAODEventSelector
9// Author: Johannes Elmsheuser, Will Buttinger
11
12// STL includes
13#include <sstream>
14#include <string>
15#include <algorithm>
16#include <vector>
17#include <stdint.h>
18
19// ROOT includes
20#include "TROOT.h"
22#include "TClass.h"
23#include "TFile.h"
24#include "TKey.h"
25#include "TLeaf.h"
26
27#include "Gaudi/Property.h"
28
29// Framework includes
30#include "GaudiKernel/FileIncident.h"
31#include "GaudiKernel/IIoComponentMgr.h"
32#include "GaudiKernel/ISvcLocator.h"
33#include "GaudiKernel/ITHistSvc.h"
34#include "GaudiKernel/MsgStream.h"
35#include "GaudiKernel/StatusCode.h"
36#include "GaudiKernel/System.h"
37#include "GaudiKernel/IClassIDSvc.h"
42#include "StorageSvc/DbType.h"
45
46// StoreGate includes
47
48#include "SGTools/BuiltinsClids.h" // to make sure we have their clids
49#include "SGTools/StlMapClids.h" // to make sure we have their clids
50#include "SGTools/StlVectorClids.h" // to make sure we have their clids
53
54// EventInfo includes
55#include "EventInfo/EventInfo.h"
56#include "EventInfo/EventType.h"
57#include "EventInfo/EventID.h"
59
60// Package includes
61#include "xAODEventSelector.h"
62#include "xAODBranchAddress.h"
63#include "RootGlobalsRestore.h"
64
65// xAOD include(s):
66#include "xAODRootAccess/Init.h"
67
68#include "GaudiKernel/ServiceHandle.h"
70#include <map>
71
72
76
77namespace Athena {
78
82class xAODEventContext : public ::IEvtSelector::Context
83{
84public:
88 virtual ~xAODEventContext() {}
90 virtual void* identifier() const override {
91 void* id ATLAS_THREAD_SAFE = const_cast<xAODEventSelector*>(m_evtsel);
92 return id;
93 }
94
95 const std::vector<std::string>& files() const { return m_evtsel->m_inputCollectionsName.value(); }
97 const TFile* file() const { return m_evtsel->m_tfile; }
99 StatusCode setFile ATLAS_NOT_THREAD_SAFE (const std::string& fname) {
100 return const_cast<xAODEventSelector*>(m_evtsel)->setFile(fname);
101 }
102
103 std::size_t fileIndex() const { return m_evtsel->m_collIdx; }
105 int64_t entry() const { return m_evtsel->m_curEvt; }
106
107private:
110};
111
113 ISvcLocator* svcLoc ) :
114 base_class ( name, svcLoc ),
115 m_dataStore( "StoreGateSvc/StoreGateSvc", name ),
116 m_imetaStore( "StoreGateSvc/InputMetaDataStore", name ),
117 m_ometaStore( "StoreGateSvc/MetaDataStore", name ),
118 m_clidsvc ( "ClassIDSvc", name ),
119 m_dictsvc ( "AthDictLoaderSvc", name ),
120 m_incsvc ( "IncidentSvc", name ),
121 m_poolSvc ( "PoolSvc" , name ),
122 m_ppSvc ( "ProxyProviderSvc" , name ),
123 m_nbrEvts ( 0 ),
124 m_curEvt ( 0 ),
125 m_collIdx ( 0 ),
126 m_collEvts ( ),
127 m_needReload (true),
129 m_tevent(NULL),
130 m_tfile(NULL),
132{
133//Properties important to end user:
134 declareProperty( "InputCollections", m_inputCollectionsName,"List of input (ROOT) file names" );
135 declareProperty( "SkipEvents",m_skipEvts = 0,"Number of events to skip at the beginning" );
136 declareProperty( "AccessMode", m_accessMode = -1, "-1 = use TEvent Default; 0 = BranchAccess; 1 = ClassAccess; 2 = AthenaAccess" );
137
138 declareProperty( "FillEventInfo", m_fillEventInfo=false,"If True, will fill old EDM EventInfo with xAOD::EventInfo content, necessary for database reading (IOVDbSvc)");
139
140 declareProperty( "PrintPerfStats", m_printPerfStats=false,"If True, at end of job will print the xAOD perf stats");
141
142//Expert Properties:
143 declareProperty( "EvtStore", m_dataStore, "Store where to publish data");
144 declareProperty( "ProxyProviderSvc" , m_ppSvc , "The ProxyProviderSvc that we should register ourself in and connect the EvtStore to");
145 declareProperty( "InputMetaStore",m_imetaStore, "Store where to publish (input) metadata");
146 declareProperty( "MetaStore",m_ometaStore, "Store where to publish (output) metadata");
147 declareProperty( "TreeName",m_tupleName = "CollectionTree","Name of the TTree to load/read from input file(s)" );
148 declareProperty( "MetaDataTreeName", m_metadataName = "MetaData","Name of the TTree to load/read metadata from input file(s)" );
149
150 declareProperty( "ReadMetaDataWithPool", m_readMetadataWithPool=false, "If true, using POOL to read metadata, will ensure input file is registered with catalog");
151 declareProperty( "printEventProxyWarnings", m_printEventProxyWarnings);
152
153}
154
155// Destructor
159
161{
162 ATH_MSG_VERBOSE ("Enter xAODEventSelector initialization...");
163
164 CHECK( m_clidsvc.retrieve() );
165 CHECK( m_dictsvc.retrieve() );
166
167 if ( m_tupleName.value().empty() ) {
168 ATH_MSG_ERROR("You have to give a TTree name to read from the ROOT files !");
169 return StatusCode::FAILURE;
170 }
171
172 const std::size_t nbrInputFiles = m_inputCollectionsName.value().size();
173 if ( nbrInputFiles < 1 ) {
174 ATH_MSG_ERROR("You need to give at least 1 input file !!" << endmsg
175 << "(Got [" << nbrInputFiles << "] file instead !)");
176 return StatusCode::FAILURE;
177 } else {
178 ATH_MSG_INFO("Selector configured to read [" << nbrInputFiles << "] file(s)...");
179 }
180
181 ATH_MSG_DEBUG("Calling xAOD::Init...");
182 int old_level = gErrorIgnoreLevel;
183 gErrorIgnoreLevel = kWarning;
184 xAOD::Init().ignore();
185 gErrorIgnoreLevel = old_level;
186 //if using the AthROOTErrorHandlerSvc, need to initialize it once again to give back error handling control to svc
187 if(serviceLocator()->existsService("AthROOTErrorHandlerSvc")) {
188 ServiceHandle<IService> ehSvc("AthROOTErrorHandlerSvc",name());
189 CHECK( ehSvc.retrieve() );
190 CHECK( ehSvc->initialize() ); //gives back control to svc
191 CHECK( ehSvc.release() );
192 }
193 switch(m_accessMode) {
194 case -1: ATH_MSG_INFO("Using DEFAULT xAOD access mode (usually same as CLASS mode)"); break;
195 case 0: ATH_MSG_INFO("Using BRANCH xAOD access mode"); break;
196 case 1: ATH_MSG_INFO("Using CLASS xAOD access mode"); break;
197 case 2: ATH_MSG_INFO("Using ATHENA xAOD access mode"); break;
198 }
199 if(m_accessMode != -1) {
200 m_tevent = new xAOD::xAODTEvent(xAOD::TEvent::EAuxMode(m_accessMode)); //our special class inheriting from xAOD::TEvent
201 } else {
202 m_tevent = new xAOD::xAODTEvent(); //our special class inheriting from xAOD::TEvent
203 }
204 m_tevent->printProxyWarnings(m_printEventProxyWarnings);
205
206 //use the first file to decide if reading metadata with POOL is ok
208 std::unique_ptr<TFile> f( TFile::Open( m_inputCollectionsName.value()[0].c_str() ) );
209 if(!f) {
210 ATH_MSG_ERROR("Failed to open first input file: " << m_inputCollectionsName.value()[0]);
211 return StatusCode::FAILURE;
212 }
213 if(!f->Get("##Shapes")) {
214 ATH_MSG_INFO("First file is not POOL file (e.g. is CxAOD), so reading metadata with xAOD::TEvent instead");
216 }
217 f->Close();
218 }
219
220
221 {
222 // register this service for 'I/O' events
223 ServiceHandle<IIoComponentMgr> iomgr("IoComponentMgr", name());
224 if (!iomgr.retrieve().isSuccess()) {
225 ATH_MSG_FATAL("Could not retrieve IoComponentMgr !");
226 return StatusCode::FAILURE;
227 }
228 if (!iomgr->io_register(this).isSuccess()) {
229 ATH_MSG_FATAL("Could not register myself with the IoComponentMgr !");
230 return StatusCode::FAILURE;
231 }
232 // register input file's names with the I/O manager
233 const std::vector<std::string>& incol = m_inputCollectionsName.value();
234 bool allGood = true;
235 for (std::size_t icol = 0, imax = incol.size(); icol < imax; icol++) {
236 if (!iomgr->io_register(this,
237 IIoComponentMgr::IoMode::READ,
238 incol[icol]).isSuccess()) {
239 ATH_MSG_FATAL("could not register [" << incol[icol] << "] for output !");
240 allGood = false;
241 } else {
242 ATH_MSG_VERBOSE("io_register[" << this->name() << "](" << incol[icol] << ") [ok]");
243 }
244 }
245 if (!allGood) {
246 return StatusCode::FAILURE;
247 }
248 }
249
250 if (!do_init_io().isSuccess()) {
251 return StatusCode::FAILURE;
252 }
253
254 // retrieve event stores
255 // this needs to happen *after* having initialized the i/o
256 // as our branches (which need a valid m_ntuple pointer)
257 // may be asked to be registered as we are a ProxyProvider.
258 // retrieving the event store will poke the ProxyProviderSvc...
259/*
260 if ( !m_dataStore.retrieve().isSuccess() ) {
261 ATH_MSG_ERROR("Could not retrieve [" << m_dataStore.typeAndName() << "] !!");
262 return StatusCode::FAILURE;
263 }
264
265 // ditto for (input) meta data store
266 if (!m_imetaStore.retrieve().isSuccess()) {
267 ATH_MSG_ERROR("Could not retrieve [" << m_imetaStore.typeAndName() << "] !!");
268 return StatusCode::FAILURE;
269 }
270
271 // ditto for (output) meta data store
272 if (!m_ometaStore.retrieve().isSuccess()) {
273 ATH_MSG_ERROR
274 ("Could not retrieve [" << m_ometaStore.typeAndName() << "] !!");
275 return StatusCode::FAILURE;
276 }
277*/
278
279 //ensure the xAODCnvSvc is listed in the EventPersistencySvc
280 ServiceHandle<IProperty> epSvc("EventPersistencySvc",name());
281
282
283 std::vector<std::string> propVal;
284 CHECK( Gaudi::Parsers::parse( propVal , epSvc->getProperty("CnvServices").toString() ) );
285 bool foundSvc(false); bool foundPoolSvc(false);
286 for(const std::string& s : propVal) {
287 if(s=="Athena::xAODCnvSvc") { foundSvc=true; }
288 if(s=="AthenaPoolCnvSvc") { foundPoolSvc=true; } //only need this if in hybrid mode
289 }
290 if(!foundSvc) propVal.push_back("Athena::xAODCnvSvc");
291 if(!foundPoolSvc && m_readMetadataWithPool) propVal.push_back("AthenaPoolCnvSvc");
292
293 if(!foundSvc || (!foundPoolSvc && m_readMetadataWithPool)) {
294 CHECK( epSvc->setProperty("CnvServices", Gaudi::Utils::toString( propVal ) ));
295 }
296
297
298 //we should also add ourself as a proxy provider
299 CHECK( m_ppSvc.retrieve() );
300
301 //ensure the MetaDataSvc is added as a provider first, if we are in hybrid mode
303 std::vector<std::string> propVal;
304 IProperty* prop = dynamic_cast<IProperty*>(&*m_ppSvc);
305 if (!prop) {
306 return StatusCode::FAILURE;
307 }
308 CHECK( Gaudi::Parsers::parse( propVal , prop->getProperty("ProviderNames").toString() ) );
309 bool foundSvc(false);
310 for(const std::string& s : propVal) {
311 if(s=="MetaDataSvc") { foundSvc=true; break; }
312 }
313 if(!foundSvc) {
314 propVal.push_back("MetaDataSvc");
315 IProperty* prop = dynamic_cast<IProperty*>(&*m_ppSvc);
316 if (!prop) {
317 return StatusCode::FAILURE;
318 }
319 CHECK( prop->setProperty("ProviderNames", Gaudi::Utils::toString( propVal ) ));
320 }
321 }
322
323 //now we add ourself as a provider
324 m_ppSvc->addProvider( this );
325 //trigger a reload of proxies in the storegate, which will poke the proxyprovidersvc
326 //not actually needed
327 //CHECK( m_dataStore->loadEventProxies() );
328
329
330 //finally ensure the storegate has our proxy set in it
331 //FIXME: this doesnt seem to allow multi storegates on the fly ???
332 //m_dataStore->setProxyProviderSvc( &*m_ppSvc );
333
334 CHECK( m_ppSvc.release() );
335
336
337 //load the first file .. this is so metadata can be read even if no events present
338 //checked above that there's at least one file
339 CHECK( setFile(m_inputCollectionsName.value()[0]) );
340
341 //first FirstInputFile incident so that input metadata store is populated by MetaDataSvc
342 m_incsvc->fireIncident(FileIncident(name(), "FirstInputFile", m_inputCollectionsName.value()[0]));
343
345
346
347 return StatusCode::SUCCESS;
348}
349
351{
352 // Fire EndInputFile for any file still open (the event loop may end
353 // before the file is fully read).
354 m_inputFileGuard.reset();
355 return StatusCode::SUCCESS;
356}
357
359{
360 ATH_MSG_VERBOSE ("Finalize...");
361 // FIXME: this should be tweaked/updated if/when a selection function
362 // or filtering predicate is applied (one day?)
363 ATH_MSG_INFO ("Total events read: " << (m_nbrEvts - m_skipEvts));
364
365 if(m_printPerfStats) {
368 }
369
370
371 return StatusCode::SUCCESS;
372}
373
375// Const methods:
377
378StatusCode
379xAODEventSelector::next( IEvtSelector::Context& ctx ) const
380{
381 // std::cout << "::next(fidx=" << m_collIdx << ", eidx=" << m_curEvt << ")"
382 // << std::endl;
383 ATH_MSG_DEBUG ("next() : iEvt " << m_curEvt);
384
385 // get evt context
386 xAODEventContext* rctx = dynamic_cast<xAODEventContext*>(&ctx);
387 if ( 0 == rctx ) {
388 ATH_MSG_ERROR ("Could not dyn-cast to xAODEventContext !!");
389 throw GaudiException("xAODEventSelector::next() - Unable to get xAODEventContext","xAODEventSelector",StatusCode::FAILURE);
390 }
391
392
393 const TFile *file = rctx->file();
394 if(file && m_nbrEvts==0) {
395 //fire the BeginInputFile incident for the first file
397 file->GetName(), {},
398 /*endFileName=*/file->GetName());
399 }
400
401 if (!file) { //must be starting another file ...
402 auto& fnames = rctx->files();
403 //std::size_t fidx = rctx->fileIndex();
404 if( rctx->setFile("").isFailure() ) {
405 throw GaudiException("xAODEventSelector::next() - Fatal error when trying to setFile('')","xAODEventSelector",StatusCode::FAILURE);
406 }
407
408 while( m_tevent_entries == 0 ) { //iterate through files until we have one with entries
409 if (m_collIdx < int(rctx->files().size())) {
410 const std::string& fname = fnames[m_collIdx];
411 if( rctx->setFile( fname ).isFailure() ) {
412 throw GaudiException("xAODEventSelector::next() - Fatal error when trying to setFile('" + fname + "')","xAODEventSelector",StatusCode::FAILURE);
413 }
414 ATH_MSG_DEBUG("TEvent entries = " << m_tevent_entries);
415 //fire incident for this file ..
417 rctx->file()->GetName(), {},
418 /*endFileName=*/rctx->file()->GetName());
419 } else {
420 // end of collections
421 return StatusCode::FAILURE; //this is a valid failure ... athena will interpret as 'finished looping'
422 }
423 if( m_tevent_entries==0) m_collIdx++;
424
425
426 } //end of while loop
427
428 }
429
430
431 ATH_MSG_DEBUG("m_curEvt=" << m_curEvt);
432
433 //Infer the local entry (entry of current file) from the global entry
434
435 int64_t global_entry = rctx->entry(); //the actual event counter
436 int64_t entry = global_entry;
437 if (m_collEvts[m_collIdx].min_entries < 0) {
438 // need to trigger collmetadata...
439 const_cast<xAODEventSelector*>(this)->find_coll_idx(entry);
440 }
441 // rctx::entry is the *global* entry number.
442 // we need the local one...
443 entry = global_entry - m_collEvts[m_collIdx].min_entries; //actual entry in the current file
444
445
446
447 if ( m_tevent_entries > entry ) {
448
449 // Load the event:
450 if( m_tevent->getEntry( entry ) < 0 ) {
451 ATH_MSG_ERROR( "Failed to load entry " << static_cast< int >( entry ) );
452 throw GaudiException("xAODEventSelector::next() - xAOD::TEvent::getEntry returned less than 0 bytes","xAODEventSelector",StatusCode::FAILURE);
453 }
454
455 ++m_nbrEvts;
456 m_curEvt = global_entry + 1;
457
458 // std::cout << "--event-info--" << std::endl;
459 // event info
460
461 // EventInfo is required, otherwise Athena will crash
462 const xAOD::EventInfo* xaodEventInfo = 0;
463 if(m_fillEventInfo) {
464 if(m_tevent->retrieve( xaodEventInfo , "EventInfo").isFailure()) {
465 ATH_MSG_ERROR("Could not find xAOD::EventInfo");
466 throw GaudiException("xAODEventSelector::next() - Could not find xAOD::EventInfo","xAODEventSelector",StatusCode::FAILURE);
467 }
468 }
469 EventType* evtType = new EventType;
470 //const std::size_t runNbr = (xaodEventInfo) ? xaodEventInfo->runNumber() : 0;
471 EventInfo* evtInfo = new EventInfo(
472 (xaodEventInfo) ? new EventID(xaodEventInfo->runNumber(), xaodEventInfo->eventNumber(), xaodEventInfo->timeStamp(), xaodEventInfo->timeStampNSOffset(), xaodEventInfo->lumiBlock(), xaodEventInfo->bcid()) : new EventID(0, m_curEvt-1,0 ), evtType);
473 if ( !m_dataStore->record( evtInfo, "EventInfo" ).isSuccess() ) {
474 ATH_MSG_ERROR ("Could not record EventInfo !");
475 delete evtInfo; evtInfo = 0;
476 throw GaudiException("xAODEventSelector::next() - Could not record EventInfo","xAODEventSelector",StatusCode::FAILURE);
477 }
478
479 return StatusCode::SUCCESS;
480
481 } else {
482 // file is depleted — fire EndInputFile
483 m_inputFileGuard.reset();
484
485 // prepare for next file, if any...
486 // std::cout << "=========================================================="
487 // << std::endl;
488 // std::cerr << "::switch to next file...\n";
489
490 // iterate over our "cached" transient addresses,
491 // marking them as garbage and dropping the RootBranchAddress (as a side effect of
492 // ::setAddress(NULL).
493 // this way, the next time we hit ::createRootBranchAddress or ::updateAddress
494 // all internal states are kosher.
495
496 /*
497 * Problem for rel22 --
498 * The proxyProviderSvc 'moves' the transient addresses created in this class
499 * and thus invalidates them.
500 * The sequence is proxyProviderSvc will call "loadAddresses" method below but
501 * when it puts them into a DataProxy it will move the addresses so they are now invalid
502 *
503 * Shortest route to fixing this is just to clear the addresses and not touch them again
504 */
505 self()->m_rootAddresses.clear();
506
507 for (auto& iaddr : self()->m_rootAddresses) {
508 iaddr.second = false; // mark as invalid
509 SG::TransientAddress* taddr = iaddr.first;
510 taddr->setAddress(NULL);
511 }
512 const bool forceRemove = false;
513 CHECK( m_dataStore->clearStore(forceRemove) ); //must clear the storegate so that any tampering user did in EndInputFile incident is cleared
514 m_needReload = true;
515
516 m_collIdx += 1;
517 CHECK( rctx->setFile("") );
518 return next(*rctx);
519 }
520
521 // NOT REACHED
522 // std::cout << "***end of collections***" << std::endl;
523 // end of collections
524 //return StatusCode::FAILURE;
525}
526
527StatusCode xAODEventSelector::next( Context& ctx, int jump ) const
528{
529 ATH_MSG_DEBUG ("next(" << jump << ") : iEvt " << m_curEvt);
530
531 if (self()->seek(ctx, m_curEvt + jump).isSuccess()) {
532 return StatusCode::FAILURE;
533 }
534 return next(ctx);
535}
536
537StatusCode
538xAODEventSelector::previous( IEvtSelector::Context& ctx ) const
539{
540 return next( ctx, -1 );
541}
542
543StatusCode
544xAODEventSelector::previous( Context& ctx, int jump ) const
545{
546 return next( ctx, -jump );
547}
548
549StatusCode
550xAODEventSelector::last( Context& /*ctxt*/ ) const
551{
552 ATH_MSG_ERROR ("............. Last Event Not Implemented .............");
553 return StatusCode::FAILURE;
554}
555
556
557StatusCode
558xAODEventSelector::rewind( Context& ctxt ) const
559{
560 return self()->seek(ctxt, 0);
561}
562
563StatusCode
564xAODEventSelector::createContext( Context*& refCtx ) const
565{
566 xAODEventContext *ctx = new xAODEventContext(this);
567 refCtx = ctx;
568 return StatusCode::SUCCESS;
569}
570
571StatusCode
572xAODEventSelector::createAddress( const Context& /*refCtx*/,
573 IOpaqueAddress*& /*addr*/ ) const
574{
575 //std::cerr << "::TTES::createAddress()...\n";
576 return StatusCode::SUCCESS;
577}
578
579StatusCode
580xAODEventSelector::releaseContext( Context*& refCtxt ) const
581{
582 if(refCtxt==0) return StatusCode::SUCCESS; //added to avoid warning from MetaDataSvc, which passes an empty context
583 xAODEventContext *ctx = dynamic_cast<xAODEventContext*>(refCtxt);
584 if ( ctx ) {
585 delete ctx; ctx = 0;
586 return StatusCode::SUCCESS;
587 }
588
589 return StatusCode::FAILURE;
590}
591
592StatusCode
593xAODEventSelector::resetCriteria( const std::string&, Context& ) const
594{
595 ATH_MSG_ERROR ("............. resetCriteria Not Implemented .............");
596 return StatusCode::FAILURE;
597}
598
600// Non-const methods:
602
607StatusCode
608xAODEventSelector::seek (Context& refCtxt, int evtnum) const
609{
610 // std::cout << "::seek - evtnum=" << evtnum
611 // << " curevt=" << m_curEvt
612 // << " curcol=" << m_collIdx
613 // << std::endl;
614 long coll_idx = find_coll_idx(evtnum);
615 // std::cout << "::seek - evtnum=" << evtnum
616 // << " curevt=" << m_curEvt
617 // << " curcol=" << m_collIdx
618 // << " colidx=" << coll_idx
619 // << std::endl;
620 if (coll_idx == -1 && evtnum < m_curEvt) {
621 coll_idx = m_collIdx;
622 }
623
624 if (coll_idx == -1) {
625 ATH_MSG_INFO("seek: reached end of input.");
626 return StatusCode::RECOVERABLE;
627 }
628
629 if (coll_idx != m_collIdx) {
630 // tell everyone we switched files...
631 xAODEventContext* rctx = dynamic_cast<xAODEventContext*>(&refCtxt);
632 if (!rctx) {
633 return StatusCode::FAILURE;
634 }
635 ATH_CHECK(rctx->setFile(""));
636 }
637
638 m_collIdx = coll_idx;
639 m_curEvt = evtnum;
640
641 return StatusCode::SUCCESS;
642}
643
648int
649xAODEventSelector::curEvent (const Context& /*refCtxt*/) const
650{
651 return m_curEvt;
652}
653
656StatusCode
658{
659 ATH_MSG_VERBOSE("I/O reinitialization...");
660
661 ServiceHandle<IIoComponentMgr> iomgr("IoComponentMgr", name());
662 if (!iomgr.retrieve().isSuccess()) {
663 ATH_MSG_FATAL("Could not retrieve IoComponentMgr !");
664 return StatusCode::FAILURE;
665 }
666 if (!iomgr->io_hasitem(this)) {
667 ATH_MSG_FATAL("IoComponentMgr does not know about myself !");
668 return StatusCode::FAILURE;
669 }
670 std::vector<std::string> inputCollections = m_inputCollectionsName.value();
671
672 for (std::size_t
673 i = 0,
674 imax = m_inputCollectionsName.value().size();
675 i < imax;
676 ++i) {
677 std::string &fname = inputCollections[i];
678 // std::cout << "--retrieve new name for [" << fname << "]...\n";
679 if (!iomgr->io_contains(this, fname)) {
680 ATH_MSG_ERROR("IoComponentMgr does not know about [" << fname << "] !");
681 return StatusCode::FAILURE;
682 }
683 if (!iomgr->io_retrieve(this, fname).isSuccess()) {
684 ATH_MSG_FATAL("Could not retrieve new value for [" << fname << "] !");
685 return StatusCode::FAILURE;
686 }
687 // std::cout << "--> [" << fname << "]\n" << std::flush;
688 }
689 // all good... copy over.
690 m_inputCollectionsName = inputCollections;
691
692 // remove our EventInfo if any...
693 // {
694 // const bool force_remove = true;
695 // if (!m_dataStore->clearStore(force_remove).isSuccess()) {
696 // ATH_MSG_ERROR("could not clear event store!");
697 // return StatusCode::FAILURE;
698 // } else {
699 // ATH_MSG_INFO("sgdump: \n" << m_dataStore->dump());
700 // }
701 // }
702
703 // std::cout << "--> do_init_io...\n" << std::flush;
704 if (!do_init_io().isSuccess()) {
705 return StatusCode::FAILURE;
706 }
707
708 ATH_MSG_INFO("I/O reinitialization... [done]");
709 return StatusCode::SUCCESS;
710}
711
712
716StatusCode
718 tadList& /*tads*/)
719{
720 // std::cerr << "TTES::preLoadAddresses(" << int(storeID)
721 // << "," << tads.size()
722 // << ")...\n";
723 return StatusCode::SUCCESS;
724}
725
727StatusCode
729{
730 if (m_needReload || m_rootAddresses.empty()) {
731 //CHECK(createMetaDataRootBranchAddresses());
732 return createRootBranchAddresses(storeID, tads);
733 }
734
735 return StatusCode::SUCCESS;
736}
737
739StatusCode
741 const EventContext& /*ctx*/)
742{
743 // check if this tad is known to us.
744 if (tad) {
745 auto itr = m_rootAddresses.find(tad);
746 if ( itr != m_rootAddresses.end() && itr->second ) {
747 return StatusCode::SUCCESS;
748 }
749 ATH_MSG_DEBUG("updateAddress: address [" << tad->clID() << "#"
750 << tad->name() << ") NOT known to us.");
751 return StatusCode::FAILURE;
752 }
753
754 // do nothing.
755 return StatusCode::SUCCESS;
756}
757
758
760// Protected methods:
762
763
764
765
766StatusCode
768 tadList &tads)
769{
770 if (storeID != StoreID::EVENT_STORE) {
771 ATH_MSG_INFO("-- not the event-store --");
772 return(StatusCode::SUCCESS);
773 }
774
775 if (0 == m_tfile) {
776 ATH_MSG_ERROR("null pointer to n-tuple !");
777 return StatusCode::FAILURE;
778 }
779
780 TTree* inputTree = dynamic_cast<TTree*>(m_tfile->Get(m_tupleName.value().c_str()));
781
782 if(inputTree!=0) {
783
784
785 ATH_MSG_DEBUG("Reading xAOD::EventFormat");
786
787 // m_tevent->dump();
788
789 const void* value_ptr = m_tevent; //passed as 'parameter' to the address object
790
791 std::set<std::string> missingAux;
792
793 for( auto itr = m_tevent->inputEventFormat()->begin(); itr!=m_tevent->inputEventFormat()->end();++itr) {
794 if(inputTree->GetBranch(itr->second.branchName().c_str())==0) continue; //skip branches that are not available in the input collection
795 ATH_MSG_VERBOSE("EFE:" << itr->first << " branchName = " << itr->second.branchName() << " className=" << itr->second.className());
796 CLID id = 0;
797 if( m_clidsvc->getIDOfTypeInfoName(itr->second.className(), id).isFailure() &&
798 m_clidsvc->getIDOfTypeName(itr->second.className(), id).isFailure()) {
799 //if this is an AuxStore (infer if key ends in Aux.), its possible we schema-evolved away from the version in the input file, but that this evolution is actually 'ok' in some cases. So don't print an error if the CLID is missing for an Aux, but we will print a warning at the end for these aux stores
800 if(itr->second.branchName().compare(itr->second.branchName().length()-4,4,"Aux.")==0) {
801 missingAux.insert( itr->second.className() );continue;
802 } else {
803 //vectors can be missing their std:: prefix, so add that and retry before failing
804 TString className = itr->second.className();
806 //ALT solution to this is do what RootNtupleEventSelector does: uses TClass:GetClass
807 //and GetTypeInfo() method to get the proper type info
808 TClass *cls = TClass::GetClass(className);
809 if(cls) {
810 const std::type_info *ti = cls->GetTypeInfo();
811 if(ti) className = System::typeinfoName(*ti);
812 }
813
814 if( m_clidsvc->getIDOfTypeInfoName(className.Data(), id).isFailure() &&
815 m_clidsvc->getIDOfTypeName(className.Data(), id).isFailure()) {
816 ATH_MSG_WARNING("No CLID for class " << itr->second.className() << " , cannot read " << itr->second.branchName());
817 continue;
818 }
819 }
820 }
821
822 const std::string br_name = itr->second.branchName();
823
826 m_tupleName.value(),
827 br_name,
828 (unsigned long)(value_ptr),
829 (unsigned long)(0)); //IMPORTANT THIS IS 0: signals to xAODBranchAddress to read event-level info (see setTEventAddress)
830 // recycle old rootaddress, if any.
831 SG::TransientAddress* taddr = NULL;
832 // FIXME: should we only iterate over m_rootAddresses which have been marked
833 // as invalid ? (ie: iaddr->second == false)
834 // probably not worth it... (but depends on the "occupancy")
835 for (auto
836 iaddr = m_rootAddresses.begin(),
837 iaddre= m_rootAddresses.end();
838 iaddr != iaddre;
839 ++iaddr) {
840 SG::TransientAddress *old = iaddr->first;
841 if (old->clID() == id &&
842 old->name() == br_name) {
843 // found a "cached" transient address which corresponds to this clid+key
844 // bind it to our new RootBranchAddress...
845 old->setAddress(addr);
846 taddr = old;
847 iaddr->second = true; // mark as valid
848 break;
849 }
850 }
851 if (taddr == NULL) {
852 taddr = new SG::TransientAddress(id, br_name, addr);
853 taddr->setProvider(this, storeID);
854 taddr->clearAddress(false);
855 // only add the *new* TransientAddress to the input list as the *old* ones
856 // are already tracked by the datastore (via the sticky proxies)
857 tads.push_back(taddr);
858 // note: we can store this taddr *b/c* we don't clearAddress it
859 // ie: b/c we just called clearAddress(false) so it will be recycled
860 // over the events.
861 m_rootAddresses.insert(std::make_pair(taddr, true));
862 }
863 // }
864 }
865
866
867 if(missingAux.size()) {
868 std::string allAux; for(auto& s : missingAux) allAux += s + ", ";
869 ATH_MSG_WARNING("The following AuxStore types are not directly accessible (missing CLID, possibly from schema evolution): " << allAux);
870 }
871 } //end if block of requiring input tree to exist
872 else {
873 ATH_MSG_DEBUG("No input collection " << m_tupleName.value() << " found in input file " << m_tfile->GetTitle() );
874 }
875
876 m_needReload = false;
877
878 ATH_MSG_DEBUG("In xAODEventSelector::createRootBranchAddresses end ...");
879
880 return StatusCode::SUCCESS;
881}
882
883StatusCode
885{
886
887 ATH_MSG_DEBUG("In xAODEventSelector::createMetaDataRootBranchAddresses start ...");
888
889 if ( 0 == m_tfile ) {
890 ATH_MSG_ERROR ("Could not get m_tfile !!");
891 throw "xAODEventSelector: Unable to get m_tfile";
892 }
893
894 //FIXME JE
895 ATH_MSG_DEBUG("m_metadataName.value().c_str() = " << m_metadataName.value().c_str() );
896 TTree* tree = dynamic_cast<TTree*>(m_tfile->Get(m_metadataName.value().c_str()));
897 ATH_MSG_DEBUG("m_tfile = " << m_tfile );
898 ATH_MSG_DEBUG("tree = " << tree );
899 if (!tree) std::abort();
900 TObjArray *leaves = tree->GetListOfLeaves();
901 if (!leaves) {
902 ATH_MSG_INFO("no leaves!!");
903 return StatusCode::SUCCESS;
904 }
905
906 // loop over leaves
907 for (Int_t i = 0; i < leaves->GetEntries(); ++i) {
908 TLeaf *leaf = (TLeaf *)leaves->At(i);
909 TBranch *branch = leaf->GetBranch();
910 if (branch) {
911
912 CLID id = 0;
913 const void* value_ptr = m_tevent;
914 const std::string type_name = leaf->GetTypeName();
915 const std::string br_name = branch->GetName();
916 // Skip if type_name does contain xAOD, ie. is not an xAOD container
917 const std::string toCheck = "xAOD::";
918 if (type_name.find(toCheck) == std::string::npos) {
919 ATH_MSG_DEBUG("** Skip type-name = " << type_name << ", br_name = " << br_name );
920 continue;
921 }
922 const std::string sg_key = br_name;//m_tupleName.value()+"/"+br_name;
923 TClass *cls = TClass::GetClass(type_name.c_str());
924 const std::type_info *ti = 0;
925
926 // Skip the EventFormat branch. That must not be disturbed by the
927 // generic metadata handling.
928 if( br_name == "EventFormat" ) continue;
929
930 if (cls) {
931 ti = cls->GetTypeInfo();
932 // first, try to load a dict for that class...
933 if (ti) {
934 m_dictsvc->load_type(*ti);
935 }
936 if (!ti) {
937 ATH_MSG_DEBUG("could not find a type-info for [" <<
938 type_name << "]");
939 continue;
940 }
941
942 // Find the clid for the typeInfo
944
945 if (id == 0) {
946 ATH_MSG_DEBUG("** could not find a CLID for type-name ["
947 << type_name << "]");
948 continue;
949 }
950
951
952
953 ATH_MSG_DEBUG("id = " << id << ", m_metadataName.value() = " << m_metadataName.value() << ", br_name = " << br_name << ", value_ptr = " << value_ptr);
957 m_metadataName.value(),
958 br_name,
959 (unsigned long)(value_ptr),
960 (unsigned long)(1))); //IMPORTANT THIS IS 1: signals to BranchAddress to read metadata
961 if (!m_imetaStore->recordAddress(br_name, std::move(addr), true).isSuccess()) {
962 ATH_MSG_ERROR("could not record address at [" << br_name << "] in store ["
963 << m_imetaStore->name() << "]");
964 }
965 // SG::TransientAddress* taddr = new SG::TransientAddress
966 // (id, sg_key, addr);
967 // taddr->setProvider(this);
968 // taddr->clearAddress(true);
969 // tads.push_back(taddr);
970 }
971 }
972 }
973
974 ATH_MSG_DEBUG("In xAODEventSelector::createMetaDataRootBranchAddresses end ...");
975
976 return StatusCode::SUCCESS;
977}
978
979
980TFile*
981xAODEventSelector::fetchNtupleFile(const std::string& fname) const
982{
983 TFile* file = NULL;
984 if(fname.empty()) return file; //if blank, return 0
986 //see if file already open
987 file = (TFile*)gROOT->GetListOfFiles()->FindObject(fname.c_str());
988 if (!file) {
989 //open the file
990 file = TFile::Open(fname.c_str(), "READ");
991 if (file) file->SetName(fname.c_str());
992 }
993 //check file is ok before returning
994 if (!file || file->IsZombie()) {
995 ATH_MSG_ERROR("could not open next file in input collection ["
996 << fname << "]");
997 if (file) {
998 file->Close();
999 }
1000 return 0;
1001 }
1002 return file;
1003}
1004
1005//move onto given file
1006StatusCode xAODEventSelector::setFile(const std::string& fname) {
1007
1008 TFile* newFile = fetchNtupleFile(fname);
1009 if(!newFile && !fname.empty()) {
1010 ATH_MSG_FATAL( "xAODEventSelector: Unable to fetch Ntuple: " << fname);
1011 return StatusCode::FAILURE; //failed to load file
1012 }
1013
1014 if(m_tfile && m_tfile != newFile) {
1015 const std::string currFile = m_tfile->GetName();
1016 //disconnect pool if necessary ... always fire this, hopefully it is safe even if not needed
1017 m_poolSvc->disconnectDb("PFN:"+currFile).ignore();
1018 //close existing file
1019 m_tfile->Close();
1020 //we should also cleanup after pool, in case it has left open files dangling
1021 }
1022 m_tfile = newFile;
1023 m_tevent_entries = 0; //will set in a moment
1024
1025 if(!m_tfile) return StatusCode::SUCCESS; //must have been setting to blank file
1026
1027 if(m_tevent->readFrom( m_tfile ).isFailure()) {
1028 ATH_MSG_FATAL( "xAODEventSelector: TEvent cannot read " << fname);
1029 return StatusCode::FAILURE;
1030 }
1031
1032 m_tevent_entries = m_tevent->getEntries();
1033
1034 //need to load metadata for file
1035 if (!m_imetaStore->clearStore().isSuccess()) {
1036 ATH_MSG_INFO("could not clear store [" << m_imetaStore.typeAndName() << "]");
1037 return StatusCode::FAILURE;
1038 }
1039
1040
1042 //ensure input file collection created
1043 ATH_MSG_DEBUG("Creating poolsvc collection for " << fname);
1044 StatusCode sc = m_poolSvc->connectCollection( "PFN:"+fname , fname );
1045 pool::ICollection* collPtr ATLAS_THREAD_SAFE = nullptr;
1046 // Try to open EventTags Collection in the input file
1047 try {
1048 collPtr = pool::CollectionService::open(fname, "PFN:"+fname, m_poolSvc->getInputContextSession(IPoolSvc::kInputStream));
1049 } catch (std::exception &e) {
1050 collPtr = nullptr;
1051 }
1052 if (sc.isRecoverable() || collPtr == nullptr) {
1053 m_poolSvc->checkCollection("PFN:"+fname, IPoolSvc::kInputStream, collPtr == nullptr).ignore();
1054 }
1055 //metadata will be read by MetaDataSvc, triggered by the BeginInputFile call
1056 } else {
1057 if (!createMetaDataRootBranchAddresses().isSuccess()) {
1058 ATH_MSG_ERROR("Could not load metadata");
1059 }
1060 }
1061
1062
1063
1064 return StatusCode::SUCCESS;
1065
1066}
1067
1068
1069StatusCode
1071{
1072 // std::cout << "::fetchNtuple..." << std::endl;
1073
1074 // initialize some helper structures and data
1075 {
1077 zero.min_entries = -1;
1078 zero.max_entries = -1;
1079 m_collEvts.resize(m_inputCollectionsName.value().size(), zero);
1080 m_collIdx = 0;
1081 }
1082
1083
1084
1085 //CHECK( setFile( m_inputCollectionsName.value()[m_collIdx] ) );
1086
1087
1088 // std::cout << "::clear-root-addresses..." << std::endl;
1089 // reset the list of branches
1090 //m_rootAddresses.clear();
1091 m_needReload = true;
1092
1093 // skip events we are asked to skip
1095 m_nbrEvts = 0;
1096
1097 // std::cout << "::fetchNtuple...[done]" << std::endl;
1098 return StatusCode::SUCCESS;
1099}
1100
1104int
1106{
1107 // std::cout << "--find_coll_idx(" << evtidx << ")..." << std::endl
1108 // << "--collsize: " << m_collEvts.size() << std::endl;
1109 for (std::size_t i = 0, imax = m_collEvts.size();
1110 i < imax;
1111 ++i) {
1112 // std::cout << "--[" << i << "]...\n";
1113 CollMetaData &itr = m_collEvts[i];
1114 if (itr.min_entries == -1) {
1115 TFile *file = fetchNtupleFile(m_inputCollectionsName.value()[i]);
1116 if (file) {
1117 long offset = 0;
1118 if (i > 0) {
1119 CollMetaData &jtr = m_collEvts[i-1];
1120 offset += jtr.max_entries;
1121 }
1122 itr.min_entries = offset;
1123 TTree* tree = dynamic_cast<TTree*>(file->Get(m_tupleName.value().c_str()));
1124 itr.max_entries = offset + ( (tree) ? tree->GetEntriesFast() : 0);
1125 } else {
1126 throw "xAODEventSelector: Unable to fetch ntuple";
1127 }
1128 }
1129 // std::cout << "--[" << i << "] => [" << itr.min_entries << ", "
1130 // << itr.max_entries << ") evtidx=[" << evtidx << "]"
1131 // << std::endl;
1132 if (itr.min_entries <= evtidx && evtidx < itr.max_entries) {
1133 return i;
1134 }
1135 }
1136 return -1;
1137}
1138
1139
1140int xAODEventSelector::size (Context& /*refCtxt*/) const {
1141 //use find_coll_idx to trigger a population of the m_collEvts ... dummy call with -1 to trigger all colls loaded
1142 find_coll_idx(-1);
1143 return m_collEvts.back().max_entries;
1144}
1145
1146//not used for anything
1147void xAODEventSelector::handle(const Incident& /*incident*/) {
1148
1149}
1150
1151} //> namespace Athena
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(x,...)
a static registry of CLID->typeName entries.
macros to associate a CLID to a type
#define CHECK(...)
Evaluate an expression and check for errors.
This class provides a unique identification for each event, in terms of run/event number and/or a tim...
EventInfo
This class provides general information about an event.
uint32_t CLID
The Class ID type.
static Double_t sc
Include TBranchElement.h, suppressing clang warnings.
int imax(int i, int j)
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
state of a few global resources from ROOT and restores their initial value upon d-tor call.
A simple class to do the retrieve from TEvent.
event selector context ... just holds reference back to the selector
int64_t entry() const
access to the current event entry number
StatusCode setFile ATLAS_NOT_THREAD_SAFE(const std::string &fname)
call to setFile on evtSel
std::size_t fileIndex() const
access to the file iterator
virtual void * identifier() const override
identifier method required by IEvtSelector::Context
const std::vector< std::string > & files() const
access to the container of files
xAODEventContext(const xAODEventSelector *sel)
standard c-tor with initialization
const xAODEventSelector * m_evtsel
reference to the hosting event selector instance
const TFile * file() const
access to the current file
virtual ~xAODEventContext()
standard d-tor
Class implementing the GAUDI IEvtSelector interface using ROOT TTree as a backend.
ServiceHandle< StoreGateSvc > m_ometaStore
Pointer to the StoreGateSvc output metadata store.
std::optional< InputFileIncidentGuard > m_inputFileGuard
RAII guard: guarantees a matching EndInputFile for every BeginInputFile.
virtual StatusCode updateAddress(StoreID::type storeID, SG::TransientAddress *tad, const EventContext &ctx) override
update a transient Address
virtual int size(Context &refCtxt) const override
ICollectionSize interface
StringProperty m_tupleName
Name of TTree to load from collection of input files.
virtual StatusCode next(Context &refCtxt) const override
xAODEventSelector(const std::string &name, ISvcLocator *svcLoc)
Constructor with parameters:
long m_nbrEvts
Number of Events read so far.
ServiceHandle< IDictLoaderSvc > m_dictsvc
Pointer to the IDictLoaderSvc.
TFile * m_tfile
current TFile being read
virtual StatusCode resetCriteria(const std::string &cr, Context &ctx) const override
StringArrayProperty m_inputCollectionsName
List of input files containing TTree.
StatusCode createRootBranchAddresses(StoreID::type storeID, tadList &tads)
helper method to create proxies
int find_coll_idx(int evtidx) const
helper method to get the collection index (into m_inputCollectionsName) for a given event index evtid...
StatusCode createMetaDataRootBranchAddresses() const
helper method to create proxies for the metadata store
virtual StatusCode releaseContext(Context *&refCtxt) const override
friend class Athena::xAODEventContext
StringProperty m_metadataName
Name of TTree to load from metadata of input files.
xAOD::xAODTEvent * m_tevent
current TEvent being read
xAODEventSelector * self() const
non-const access to self (b/c next() is const)
std::vector< CollMetaData > m_collEvts
cache of the number of entries for each collection
StatusCode do_init_io()
helper method to init the i/o components
virtual StatusCode initialize() override
virtual StatusCode io_reinit() override
Callback method to reinitialize the internal state of the component for I/O purposes (e....
ServiceHandle< IProxyProviderSvc > m_ppSvc
Handle to the proxy provider svc.
virtual StatusCode loadAddresses(StoreID::type storeID, tadList &list) override
get all new addresses from Provider for this Event.
ServiceHandle< StoreGateSvc > m_dataStore
Pointer to the StoreGateSvc event store.
StatusCode setFile(const std::string &fname)
switch to given file, loading metadata and triggering a beginInputFile incident
virtual StatusCode previous(Context &refCtxt) const override
std::unordered_map< SG::TransientAddress *, bool > m_rootAddresses
virtual int curEvent(const Context &refCtxt) const override
return the current event number.
ServiceHandle< IIncidentSvc > m_incsvc
Handle to the incident service.
virtual StatusCode createAddress(const Context &refCtxt, IOpaqueAddress *&) const override
virtual StatusCode finalize() override
ServiceHandle< IClassIDSvc > m_clidsvc
Pointer to the IClassIDSvc.
virtual StatusCode last(Context &refContext) const override
virtual StatusCode seek(Context &refCtxt, int evtnum) const override
Seek to a given event number.
TFile * fetchNtupleFile(const std::string &fname) const
helper method to retrieve the correct tuple
long m_curEvt
current event index
ServiceHandle< IPoolSvc > m_poolSvc
Handle to the PoolSvc (used in Hybrid mode when user is reading metadata with pool).
virtual StatusCode createContext(Context *&refpCtxt) const override
virtual ~xAODEventSelector()
Destructor:
long m_skipEvts
Number of events to skip at the beginning.
virtual StatusCode rewind(Context &refCtxt) const override
long m_collIdx
current collection index (into m_inputCollectionsName)
virtual void handle(const Incident &incident) override
virtual StatusCode stop() override
virtual StatusCode preLoadAddresses(StoreID::type storeID, tadList &list) override
ServiceHandle< StoreGateSvc > m_imetaStore
Pointer to the StoreGateSvc input metadata store.
static CLID typeinfoToCLID(const std::type_info &ti)
Return the CLID corresponding to a type_info.
Simple smart pointer for Gaudi-style refcounted objects.
@ kInputStream
Definition IPoolSvc.h:39
static InputFileIncidentGuard begin(IIncidentSvc &incSvc, std::string_view source, std::string_view beginFileName, std::string_view guid, std::string_view endFileName={}, std::string_view beginType=IncidentType::BeginInputFile, std::string_view endType=IncidentType::EndInputFile)
Factory: fire the begin incident and return a guard whose destructor fires the matching end incident.
static void transition(std::optional< InputFileIncidentGuard > &guard, IIncidentSvc &incSvc, std::string_view source, std::string_view beginFileName, std::string_view guid, std::string_view endFileName={}, std::string_view beginType=IncidentType::BeginInputFile, std::string_view endType=IncidentType::EndInputFile)
Replace the guard in an optional, with strict End-before-Begin ordering.
CLID clID() const
Retrieve string key:
void clearAddress(const bool &flag)
Return the clearAddress flag.
const std::string & name() const
Get the primary (hashed) SG key.
void setAddress(CxxUtils::RefCountedPtr< IOpaqueAddress > pAddress)
Retrieve primary clid.
void setProvider(IAddressProvider *provider, StoreID::type storeID)
@ EVENT_STORE
Definition StoreID.h:26
static ICollection * open(const std::string &name, const std::string &connection="", ISession *session=0)
Opens an existing collection for reading.
An interface to a storage technology specific collection of event references and attributes.
Definition ICollection.h:24
uint32_t lumiBlock() const
The current event's luminosity block number.
uint32_t bcid() const
The bunch crossing ID of the event.
uint32_t timeStamp() const
POSIX time in seconds from 1970. January 1st.
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.
ReadStats & stats()
Access the object belonging to the current thread.
Definition IOStats.cxx:17
static IOStats & instance()
Singleton object accessor.
Definition IOStats.cxx:11
void stop()
Stop the statistics collection.
void start(bool clear=true)
Start the statistics collection.
static PerfStats & instance()
Function accessing the singleton instance.
void Print(::Option_t *option="") const
Print information about the collected statistics.
void zero(TH2 *h)
zero the contents of a 2d histogram
Some weak symbol referencing magic... These are declared in AthenaKernel/getMessageSvc....
Definition AthDsoUtils.h:10
StatusCode parse(std::tuple< Tup... > &tup, const Gaudi::Parsers::InputData &input)
static const DbType ROOT_StorageType
Definition DbType.h:85
StatusCode Init(const char *appname)
Function initialising ROOT/PyROOT for using the ATLAS EDM.
Definition Init.cxx:31
EventInfo_v1 EventInfo
Definition of the latest event info version.
long max_entries
number of entries after this collection
long min_entries
number of entries up to this collection
TChain * tree
TFile * file