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