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