ATLAS Offline Software
Loading...
Searching...
No Matches
RootNtupleEventSelector.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// RootNtupleEventSelector.cxx
8// Implementation file for class RootNtupleEventSelector
9// Author: S.Binet<binet@cern.ch>
11
12// STL includes
13#include <sstream>
14#include <string>
15#include <vector>
16#include <stdint.h>
17#include <unordered_map>
18#include <unordered_set>
19
20// ROOT includes
21#include "TROOT.h"
23#include "TClass.h"
24#include "TClassEdit.h"
25#include "TFile.h"
26#include "TKey.h"
27#include "TLeaf.h"
28
29// Framework includes
30//#include "GaudiKernel/GenericAddress.h"
31#include "GaudiKernel/FileIncident.h"
32#include "GaudiKernel/IIoComponentMgr.h"
33#include "GaudiKernel/ISvcLocator.h"
34#include "GaudiKernel/ITHistSvc.h"
35#include "GaudiKernel/MsgStream.h"
36#include "GaudiKernel/StatusCode.h"
37#include "GaudiKernel/System.h"
40
41// StoreGate includes
42
43#include "SGTools/BuiltinsClids.h" // to make sure we have their clids
44#include "SGTools/StlMapClids.h" // to make sure we have their clids
45#include "SGTools/StlVectorClids.h" // to make sure we have their clids
48
49#include "TObject.h"
50#include "TTree.h"
51CLASS_DEF( TObject, 74939790 , 1 )
52#include "AthenaRootComps/TransferTree.h"
53
54// EventInfo includes
55#include "EventInfo/EventInfo.h"
56#include "EventInfo/EventType.h"
57#include "EventInfo/EventID.h"
60
61
62// Package includes
64#include "RootBranchAddress.h"
65#include "RootGlobalsRestore.h"
66
67#include "boost/tokenizer.hpp"
68
69namespace {
70 std::string
71 root_typename(const std::string& root_type_name)
72 {
73 static const std::unordered_map<std::string,std::string> s = {
74 {"Int_t", System::typeinfoName(typeid(Int_t))},
75 {"UInt_t", System::typeinfoName(typeid(UInt_t))},
76
77 {"Long_t", System::typeinfoName(typeid(Long_t))},
78 {"ULong_t", System::typeinfoName(typeid(ULong_t))},
79
80 {"Long64_t", System::typeinfoName(typeid(Long64_t))},
81 {"ULong64_t", System::typeinfoName(typeid(ULong64_t))},
82
83 {"Float_t", System::typeinfoName(typeid(Float_t))},
84 {"Float16_t", System::typeinfoName(typeid(Float16_t))},
85 {"Double_t", System::typeinfoName(typeid(Double_t))},
86 {"Double32_t", System::typeinfoName(typeid(Double32_t))},
87
88 {"Bool_t", System::typeinfoName(typeid(Bool_t))},
89 {"Char_t", System::typeinfoName(typeid(Char_t))},
90 {"UChar_t", System::typeinfoName(typeid(UChar_t))},
91
92 {"Short_t", System::typeinfoName(typeid(Short_t))},
93 {"UShort_t", System::typeinfoName(typeid(UShort_t))}
94 };
95
96 return s.at(root_type_name);
97 }
98
99#if 0
100 std::vector<std::string>
101 get_active_leaves(TTree *tuple)
102 {
103 std::vector<std::string> active;
104 TObjArray *leaves = tuple->GetListOfLeaves();
105 if (leaves) {
106 // loop over leaves
107 for (Int_t i = 0; i < leaves->GetEntries(); ++i) {
108 TLeaf *leaf = (TLeaf *)leaves->At(i);
109 TBranch *branch = leaf->GetBranch();
110 if (branch) {
111 const char *brname = branch->GetName();
112 if (tuple->GetBranchStatus(brname)) {
113 active.push_back(std::string(brname));
114 }
115 }
116 }
117 }
118 return active;
119 }
120#endif
121
122}
123
124namespace Athena {
125
130 public ::IEvtSelector::Context
131{
132public:
134 typedef std::vector<std::string> FileNames_t;
135
136private:
139
142
145
147 std::string m_fid;
148
149public:
150
158
161
162 // access to the container of files
163 const FileNames_t& files() const
164 { return m_evtsel->m_inputCollectionsName.value(); }
165
167 virtual void* identifier() const
168 { return (void*)(m_evtsel); }
169
171 std::size_t fileIndex() const
172 { return m_collIdx; }
173
175 void setFileIndex(std::size_t idx)
176 { m_collIdx = idx; }
177
178 std::size_t tupleIndex() const
179 { return m_tupleIdx; }
180
181 void setTupleIndex(std::size_t idx)
182 { m_tupleIdx = idx; }
183
185 int64_t entry() const { return m_evtsel->m_curEvt; }
186
188 void setFID(const std::string& fid) { m_fid = fid; }
189
191 const std::string& fid() const { return m_fid; }
192
194 TTree* tree() const { return m_evtsel->m_tuple; }
195
197 void setTree(TTree* tree) {
198 // make sure we clean-up and close the file holding
199 // the previous tree, if any.
200 // dont close if it is the same tree though!
201 TTree *cur = m_evtsel->m_tuple;
202 if (cur && tree != cur) {
203 TFile *old_file = cur->GetCurrentFile();
204 if (old_file) {
205 old_file->Close();
206 }
207 }
208
209 m_evtsel->m_tuple = tree;
210 }
211};
212
214
216// Public methods:
218
219// Constructors
221
223 ISvcLocator* svcLoc ) :
224 extends ( name, svcLoc ),
225 m_dataStore( "StoreGateSvc/StoreGateSvc", name ),
226 m_imetaStore( "StoreGateSvc/InputMetaDataStore", name ),
227 m_ometaStore( "StoreGateSvc/MetaDataStore", name ),
228 m_clidsvc ( "ClassIDSvc", name ),
229 m_dictsvc ( "AthDictLoaderSvc", name ),
230 m_incsvc ( "IncidentSvc", name ),
231 m_nbrEvts ( 0 ),
232 m_curEvt ( 0 ),
233 m_collEvts ( ),
234 m_tuple (NULL),
235 m_needReload (true)
236{
237 declareProperty( "DataStore",
238 m_dataStore,
239 "Store where to publish data");
240
241 declareProperty( "InputMetaStore",
242 m_imetaStore,
243 "Store where to publish (input) metadata");
244
245 declareProperty( "MetaStore",
246 m_ometaStore,
247 "Store where to publish (output) metadata");
248
249 declareProperty( "InputCollections",
250 m_inputCollectionsName,
251 "List of input (ROOT) file names" );
252 m_inputCollectionsName.declareUpdateHandler
254
255 declareProperty( "TupleName",
256 m_tupleName = "CollectionTree",
257 "Name of the TTree to load/read from input file(s). "
258 "May be a semicolon-separated string to read multiple TTrees.");
259
260 declareProperty( "SkipEvents",
261 m_skipEvts = 0,
262 "Number of events to skip at the beginning" );
263
264 declareProperty( "ActiveBranches",
265 m_activeBranchNames,
266 "List of branch names to activate" );
267}
268
269// Destructor
273
275{
276 ATH_MSG_INFO ("Enter RootNtupleEventSelector initialization...");
277
278 // retrieve clidsvc
279 if ( !m_clidsvc.retrieve().isSuccess() ) {
281 ("Could not retrieve [" << m_clidsvc.typeAndName() << "]");
282 return StatusCode::FAILURE;
283 }
284
285 // retrieve dictsvc
286 if ( !m_dictsvc.retrieve().isSuccess() ) {
288 ("Could not retrieve [" << m_dictsvc.typeAndName() << "]");
289 return StatusCode::FAILURE;
290 }
291
292 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
293 boost::char_separator<char> sep (" ;");
294 tokenizer tokens (m_tupleName.value(), sep);
295 m_tupleNames.assign (tokens.begin(), tokens.end());
296
297 if ( m_tupleNames.empty() ) {
299 ("You have to give a TTree name to read from the ROOT files !");
300 return StatusCode::FAILURE;
301 }
302
303 CHECK( m_incsvc.retrieve() );
304 m_incsvc->addListener(this,IncidentType::BeginEvent,99); //used to trigger BeginInputFile on start of first event of file - 99 priority so AFTER storegatesvc done
305
306
307 setupInputCollection( m_inputCollectionsName );
308 const std::size_t nbrInputFiles = m_inputCollectionsName.value().size();
309 if ( nbrInputFiles < 1 ) {
311 ("You need to give at least 1 input file !!" << endmsg
312 << "(Got [" << nbrInputFiles << "] file instead !)");
313 return StatusCode::FAILURE;
314 } else {
316 ("Selector configured to read [" << nbrInputFiles << "] file(s)..."
317 << endmsg
318 << " TTree [" << m_tupleName.value() << "]");
319 }
320
321 {
322 // register this service for 'I/O' events
323 ServiceHandle<IIoComponentMgr> iomgr("IoComponentMgr", name());
324 if (!iomgr.retrieve().isSuccess()) {
325 ATH_MSG_FATAL("Could not retrieve IoComponentMgr !");
326 return StatusCode::FAILURE;
327 }
328 if (!iomgr->io_register(this).isSuccess()) {
329 ATH_MSG_FATAL("Could not register myself with the IoComponentMgr !");
330 return StatusCode::FAILURE;
331 }
332 // register input file's names with the I/O manager
333 const std::vector<std::string>& incol = m_inputCollectionsName.value();
334 bool allGood = true;
335 for (std::size_t icol = 0, imax = incol.size(); icol < imax; icol++) {
336 if (!iomgr->io_register(this,
337 IIoComponentMgr::IoMode::READ,
338 incol[icol]).isSuccess()) {
339 ATH_MSG_FATAL("could not register [" << incol[icol] << "] for output !");
340 allGood = false;
341 } else {
342 ATH_MSG_VERBOSE("io_register[" << this->name() << "](" << incol[icol] << ") [ok]");
343 }
344 }
345 if (!allGood) {
346 return StatusCode::FAILURE;
347 }
348 }
349
350 if (!do_init_io().isSuccess()) {
351 return StatusCode::FAILURE;
352 }
353 // retrieve event store
354 // this needs to happen *after* having initialized the i/o
355 // as our branches (which need a valid m_ntuple pointer)
356 // may be asked to be registered as we are a ProxyProvider.
357 // retrieving the event store will poke the ProxyProviderSvc...
358 /*
359 if ( !m_dataStore.retrieve().isSuccess() ) {
360 ATH_MSG_ERROR
361 ("Could not retrieve [" << m_dataStore.typeAndName() << "] !!");
362 return StatusCode::FAILURE;
363 }
364
365 // ditto for (input) meta data store
366 if (!m_imetaStore.retrieve().isSuccess()) {
367 ATH_MSG_ERROR
368 ("Could not retrieve [" << m_imetaStore.typeAndName() << "] !!");
369 return StatusCode::FAILURE;
370 }
371
372 // ditto for (output) meta data store
373 if (!m_ometaStore.retrieve().isSuccess()) {
374 ATH_MSG_ERROR
375 ("Could not retrieve [" << m_ometaStore.typeAndName() << "] !!");
376 return StatusCode::FAILURE;
377 }
378 */
379
380 //ensure the Athena::NtupleCnvSvc is in the EventPersistencySvc
381 ServiceHandle<IProperty> epSvc("EventPersistencySvc",name());
382 std::vector<std::string> propVal;
383 CHECK( Gaudi::Parsers::parse( propVal , epSvc->getProperty("CnvServices").toString() ) );
384 bool foundSvc(false);
385 for(const std::string& s : propVal) {
386 if(s=="Athena::xAODCnvSvc") { foundSvc=true; break; }
387 }
388 if(!foundSvc) {
389 propVal.push_back("Athena::NtupleCnvSvc");
390 CHECK( epSvc->setProperty("CnvServices", Gaudi::Utils::toString( propVal ) ));
391 }
392
393 //we should also add ourself as a proxy provider
394 ServiceHandle<IProxyProviderSvc> ppSvc("ProxyProviderSvc",name());
395 CHECK( ppSvc.retrieve() );
396 ppSvc->addProvider( this );
397
398
399
400 return StatusCode::SUCCESS;
401}
402
404{
405 // Fire EndInputFile for any file still open (the event loop may end
406 // before the file is fully read).
407 m_inputFileGuard.reset();
408 m_fireBIF = false;
409 return StatusCode::SUCCESS;
410}
411
413{
414 ATH_MSG_INFO ("Finalize...");
415 // FIXME: this should be tweaked/updated if/when a selection function
416 // or filtering predicate is applied (one day?)
417 ATH_MSG_INFO ("Total events read: " << (m_nbrEvts - m_skipEvts));
418
419 // Explicitly delete all the files we created.
420 // If we leave it up to root, then xrootd can get cleaned up before
421 // the root destructors run, leading to a crash.
422 for (TFile* f : m_files)
423 delete f;
424 m_files.clear();
425
426 return StatusCode::SUCCESS;
427}
428
430// Const methods:
432
434{
435 // Fire EndInputFile via guard reset
436 m_inputFileGuard.reset();
437
438 // prepare for next file, if any...
439 // std::cout << "=========================================================="
440 // << std::endl;
441 // std::cerr << "::switch to next file...\n";
442
443 // iterate over proxies and
444 // mark as garbage and drop the RootBranchAddress (as a side effect of
445 // ::setAddress(NULL).
446 // this way, the next time we hit ::createRootBranchAddress or ::updateAddress
447 // all internal states are kosher.
448 for (const SG::DataProxy* cdp : m_dataStore->proxies()) {
449 if (dynamic_cast<Athena::RootBranchAddress*> (cdp->address()) != nullptr) {
450 if (SG::DataProxy* dp = m_dataStore->proxy_exact (cdp->sgkey())) {
451 dp->setAddress (nullptr);
452 }
453 }
454 }
455
456 const bool forceRemove = false;
457 CHECK( m_dataStore->clearStore(forceRemove) ); //must clear the storegate so that any tampering user did in EndInputFile incident is cleared
458 m_needReload = true;
459 // Defer BeginInputFile for the next file to the next BeginEvent.
460 // The actual file name is resolved in handle() from m_tuple.
461 m_fireBIF = true;
462
463 return StatusCode::SUCCESS;
464}
465
466StatusCode
467RootNtupleEventSelector::next( IEvtSelector::Context& ctx ) const
468{
469 // std::cout << "::next(fidx=" << ctx->fileIndex() << ", eidx=" << m_curEvt << ")"
470 // << std::endl;
471 ATH_MSG_DEBUG ("next() : iEvt " << m_curEvt);
472
473 // get evt context
474 RootNtupleEventContext* rctx = dynamic_cast<RootNtupleEventContext*>(&ctx);
475 if ( 0 == rctx ) {
476 ATH_MSG_ERROR ("Could not dyn-cast to RootNtupleEventContext !!");
477 throw "RootNtupleEventSelector: Unable to get RootNtupleEventContext";
478 }
479
480 TTree *tree = rctx->tree();
481 if (!tree) {
482 const FileNames_t& fnames = rctx->files();
483 std::size_t fidx = rctx->fileIndex();
484 rctx->setTree(NULL);
485 //rctx->setEntry(-1);
486
487 while (!tree && rctx->tupleIndex() < m_tupleNames.size()) {
488 if (fidx < rctx->files().size()) {
489 const std::string& fname = fnames[fidx];
490 tree = fetchNtuple(fname, m_tupleNames[rctx->tupleIndex()]);
491 if (!tree) {
492 throw "RootNtupleEventSelector: Unable to get tree";
493 }
494 rctx->setTree(tree);
495
496 }
497 else {
498 // end of collections; go to next tuple.
499 rctx->setTupleIndex (rctx->tupleIndex()+1);
500 rctx->setFileIndex (0);
501 fidx = 0;
502 }
503 }
504
505 if (!tree) {
506 return StatusCode::FAILURE;
507 }
508 }
509 int64_t global_entry = rctx->entry();
510 size_t collIdx = rctx->fileIndex();
511 size_t tupleIdx = rctx->tupleIndex();
512 int64_t entry = global_entry;
513 if (m_collEvts[tupleIdx][collIdx].min_entries < 0) {
514 // need to trigger collmetadata...
515 long coll_idx, tuple_idx;
516 const_cast<RootNtupleEventSelector*>(this)->find_coll_idx(entry,
517 coll_idx,
518 tuple_idx);
519 }
520 // rctx::entry is the *global* entry number.
521 // we need the local one...
522 entry = global_entry - m_collEvts[tupleIdx][collIdx].min_entries;
523
524 Long64_t nentries = tree->GetEntriesFast();
525 // std::cout << "::entry=" << global_entry
526 // << ", nentries=" << nentries
527 // << ", local=" << entry
528 // << " (min=" << m_collEvts[collIdx].min_entries
529 // << ", max=" << m_collEvts[collIdx].max_entries << ")"
530 // << " (tree=" << tree << ")"
531 // << std::endl;
532 if ( nentries > entry ) {
533
534 // load data from tuple
535 //std::cout << "--load-data--" << " " << tree->GetReadEntry() << std::endl;
536 if (tree->LoadTree(entry) < 0) {
538 ("Problem loading tree for event [" << m_curEvt << "] !!");
539 throw "RootNtupleEventSelector: Problem loading input tree";
540 } else {
541 ATH_MSG_DEBUG("==> loaded-tree(" << m_curEvt << ")");
542 }
543
544 ++m_nbrEvts;
545 m_curEvt = global_entry + 1;
546
547 unsigned long long eventNumber = global_entry;
548 if (!m_eventNumberVar.value().empty()) {
549 if (TLeaf* leaf = tree->GetLeaf (m_eventNumberVar.value().c_str())) {
550 leaf->GetBranch()->GetEntry(entry);
551 eventNumber = leaf->GetValueLong64();
552 }
553 else {
554 ATH_MSG_ERROR("Cannot find event number variable: " << m_eventNumberVar);
555 }
556 }
557
558 unsigned long runNumber = 0;
559 if (!m_runNumberVar.value().empty()) {
560 if (TLeaf* leaf = tree->GetLeaf (m_runNumberVar.value().c_str())) {
561 leaf->GetBranch()->GetEntry(entry);
562 runNumber = std::abs(leaf->GetValue());
563 }
564 else {
565 ATH_MSG_ERROR("Cannot find run number variable: " << m_runNumberVar);
566 }
567 }
568
569 EventIDBase::number_type lbn = EventIDBase::UNDEFNUM;
570 if (!m_lbnVar.value().empty()) {
571 if (TLeaf* leaf = tree->GetLeaf (m_lbnVar.value().c_str())) {
572 leaf->GetBranch()->GetEntry(entry);
573 lbn = std::abs(leaf->GetValue());
574 }
575 else {
576 ATH_MSG_ERROR("Cannot find LBN variable: " << m_lbnVar);
577 }
578 }
579
580 // std::cout << "--event-info--" << std::endl;
581 // event info
582 EventType* evtType = new EventType;
583 EventInfo* evtInfo = new EventInfo(new EventID(runNumber, eventNumber, 0), evtType);
584 evtInfo->event_ID()->set_lumi_block (lbn);
585 if ( !m_dataStore->record( evtInfo, "TTreeEventInfo" ).isSuccess() ) {
586 ATH_MSG_ERROR ("Could not record TTreeEventInfo !");
587 delete evtInfo; evtInfo = 0;
588 return StatusCode::FAILURE;
589 }
590
591 {
592 auto ei = std::make_unique<xAOD::EventInfo>();
593 auto ei_store = std::make_unique<xAOD::EventAuxInfo>();
594 ei->setStore (ei_store.get());
595 ei->setRunNumber (runNumber);
596 ei->setEventNumber (eventNumber);
597 ei->setLumiBlock (lbn);
598
599 static const SG::AuxElement::Accessor<std::string> tupleName ("tupleName");
600 static const SG::AuxElement::Accessor<std::string> collName ("collectionName");
601 tupleName(*ei) = m_tupleNames[tupleIdx];
602 collName(*ei) = m_inputCollectionsName[collIdx];
603
604 CHECK( m_dataStore->record (std::move(ei), "EventInfo") );
605 CHECK( m_dataStore->record (std::move(ei_store), "EventInfoAux.") );
606 }
607
608 // BeginInputFile is deferred to handle() on BeginEvent — data must
609 // be loaded in the store before listeners' handle() is called.
610 return StatusCode::SUCCESS;
611
612 } else {
613 // file is depleted
614 CHECK( endInputFile (rctx) );
615 rctx->setFileIndex (rctx->fileIndex() + 1);
616 rctx->setTree(NULL);
617 return next(*rctx);
618 }
619
620 // NOT REACHED
621 // std::cout << "***end of collections***" << std::endl;
622 // end of collections
623 //return StatusCode::FAILURE;
624}
625
626StatusCode RootNtupleEventSelector::next( Context& ctx, int jump ) const
627{
628 ATH_MSG_DEBUG ("next(" << jump << ") : iEvt " << m_curEvt);
629
630 if (self()->seek(ctx, m_curEvt + jump).isSuccess()) {
631 return StatusCode::FAILURE;
632 }
633 return next(ctx);
634}
635
636StatusCode
637RootNtupleEventSelector::previous( IEvtSelector::Context& ctx ) const
638{
639 return next( ctx, -1 );
640}
641
642StatusCode
643RootNtupleEventSelector::previous( Context& ctx, int jump ) const
644{
645 return next( ctx, -jump );
646}
647
648StatusCode
649RootNtupleEventSelector::last( Context& /*ctxt*/ ) const
650{
651 ATH_MSG_ERROR ("............. Last Event Not Implemented .............");
652 return StatusCode::FAILURE;
653}
654
655
656StatusCode
657RootNtupleEventSelector::rewind( Context& ctxt ) const
658{
659 return self()->seek(ctxt, 0);
660}
661
662StatusCode
664{
666 refCtx = ctx;
667 return StatusCode::SUCCESS;
668}
669
670StatusCode
671RootNtupleEventSelector::createAddress( const Context& /*refCtx*/,
672 IOpaqueAddress*& /*addr*/ ) const
673{
674 //std::cerr << "::TTES::createAddress()...\n";
675 return StatusCode::SUCCESS;
676}
677
678StatusCode
680{
681 RootNtupleEventContext *ctx = dynamic_cast<RootNtupleEventContext*>(refCtxt);
682 if ( ctx ) {
683 delete ctx; ctx = 0;
684 return StatusCode::SUCCESS;
685 }
686
687 return StatusCode::FAILURE;
688}
689
690StatusCode
691RootNtupleEventSelector::resetCriteria( const std::string&, Context& ) const
692{
693 ATH_MSG_ERROR ("............. resetCriteria Not Implemented .............");
694 return StatusCode::FAILURE;
695}
696
698// Non-const methods:
700
705StatusCode
706RootNtupleEventSelector::seek (Context& ctx, int evtnum) const
707{
708 RootNtupleEventContext* rctx = dynamic_cast<RootNtupleEventContext*>(&ctx);
709 if (!rctx) {
710 return StatusCode::FAILURE;
711 }
712
713 // std::cout << "::seek - evtnum=" << evtnum
714 // << " curevt=" << m_curEvt
715 // << " curcol=" << rctx->fileIndex()
716 // << std::endl;
717 long coll_idx, tuple_idx;
718 find_coll_idx(evtnum, coll_idx, tuple_idx);
719 // std::cout << "::seek - evtnum=" << evtnum
720 // << " curevt=" << m_curEvt
721 // << " curcol=" << rctx->fileIndex()
722 // << " colidx=" << coll_idx
723 // << std::endl;
724 if ((coll_idx == -1 || tuple_idx == -1) && evtnum < m_curEvt) {
725 coll_idx = rctx->fileIndex();
726 tuple_idx = rctx->tupleIndex();
727 }
728
729 if (coll_idx == -1 || tuple_idx == -1) {
730 ATH_MSG_INFO("seek: reached end of input.");
731 return StatusCode::RECOVERABLE;
732 }
733
734 if (coll_idx != static_cast<int>(rctx->fileIndex()) ||
735 tuple_idx != static_cast<int>(rctx->tupleIndex()))
736 {
737 // tell everyone we switched files...
738 m_tuple = NULL;
739 CHECK( endInputFile (rctx) );
740 }
741
742 rctx->setFileIndex (coll_idx);
743 rctx->setTupleIndex (tuple_idx);
744 m_curEvt = evtnum;
745
746 return StatusCode::SUCCESS;
747}
748
753int
754RootNtupleEventSelector::curEvent (const Context& /*refCtxt*/) const
755{
756 return m_curEvt;
757}
758
761StatusCode
763{
764 ATH_MSG_INFO("I/O reinitialization...");
765
766 ServiceHandle<IIoComponentMgr> iomgr("IoComponentMgr", name());
767 if (!iomgr.retrieve().isSuccess()) {
768 ATH_MSG_FATAL("Could not retrieve IoComponentMgr !");
769 return StatusCode::FAILURE;
770 }
771 if (!iomgr->io_hasitem(this)) {
772 ATH_MSG_FATAL("IoComponentMgr does not know about myself !");
773 return StatusCode::FAILURE;
774 }
775 std::vector<std::string> inputCollections = m_inputCollectionsName.value();
776
777 for (std::size_t
778 i = 0,
779 imax = m_inputCollectionsName.value().size();
780 i < imax;
781 ++i) {
782 std::string &fname = inputCollections[i];
783 // std::cout << "--retrieve new name for [" << fname << "]...\n";
784 if (!iomgr->io_contains(this, fname)) {
785 ATH_MSG_ERROR("IoComponentMgr does not know about [" << fname << "] !");
786 return StatusCode::FAILURE;
787 }
788 if (!iomgr->io_retrieve(this, fname).isSuccess()) {
789 ATH_MSG_FATAL("Could not retrieve new value for [" << fname << "] !");
790 return StatusCode::FAILURE;
791 }
792 // std::cout << "--> [" << fname << "]\n" << std::flush;
793 }
794 // all good... copy over.
795 m_inputCollectionsName = inputCollections;
796
797 // remove our EventInfo if any...
798 // {
799 // const bool force_remove = true;
800 // if (!m_dataStore->clearStore(force_remove).isSuccess()) {
801 // ATH_MSG_ERROR("could not clear event store!");
802 // return StatusCode::FAILURE;
803 // } else {
804 // ATH_MSG_INFO("sgdump: \n" << m_dataStore->dump());
805 // }
806 // }
807
808 // std::cout << "--> do_init_io...\n" << std::flush;
809 if (!do_init_io().isSuccess()) {
810 return StatusCode::FAILURE;
811 }
812
813 ATH_MSG_INFO("I/O reinitialization... [done]");
814 return StatusCode::SUCCESS;
815}
816
817
821StatusCode
823 tadList& /*tads*/)
824{
825 // std::cerr << "TTES::preLoadAddresses(" << int(storeID)
826 // << "," << tads.size()
827 // << ")...\n";
828 return StatusCode::SUCCESS;
829}
830
832StatusCode
834{
835 if (m_needReload) {
836 return createRootBranchAddresses(storeID, tads);
837 }
838
839 return StatusCode::SUCCESS;
840}
841
843StatusCode
845 const EventContext& /*ctx*/)
846{
847 if (tad) {
848 if (m_dataStore->proxy_exact (tad->sgkey())) {
849 return StatusCode::SUCCESS;
850 }
851 return StatusCode::FAILURE;
852 }
853 // do nothing.
854 return StatusCode::SUCCESS;
855}
856
857
859// Protected methods:
861
863void
864RootNtupleEventSelector::setupInputCollection( Gaudi::Details::PropertyBase& /*inputCollectionsName*/ )
865{
866 // nothing ?
867 return;
868}
869
870StatusCode
872 tadList &tads)
873{
874 if (storeID != StoreID::EVENT_STORE) {
875 ATH_MSG_INFO("-- not the event-store --");
876 return(StatusCode::SUCCESS);
877 }
878
879 if (0 == m_tuple) {
880 ATH_MSG_ERROR("null pointer to n-tuple !");
881 return StatusCode::FAILURE;
882 }
883
884 TObjArray *leaves = m_tuple->GetListOfLeaves();
885 if (!leaves) {
886 ATH_MSG_INFO("no leaves!!");
887 return StatusCode::SUCCESS;
888 }
889
890 // loop over leaves
891 for (Int_t i = 0; i < leaves->GetEntries(); ++i) {
892 TLeaf *leaf = (TLeaf *)leaves->At(i);
893 TBranch *branch = leaf->GetBranch();
894 if (branch) {
895
896 CLID id = 0;
897 const void* value_ptr = m_tuple;
898 const std::string type_name = leaf->GetTypeName();
899 const std::string br_name = branch->GetName();
900 const std::string sg_key = br_name;//m_tupleName.value()+"/"+br_name;
901 TClass *cls = TClass::GetClass(type_name.c_str());
902 const std::type_info *ti = 0;
903
904 if (cls) {
905 ti = cls->GetTypeInfo();
906 // first, try to load a dict for that class...
907 if (ti) {
908 m_dictsvc->load_type(*ti);
909 }
910 if (!ti) {
911 ATH_MSG_WARNING("could not find a type-info for [" <<
912 type_name << "]");
913 continue;
914 }
915 std::string ti_typename = System::typeinfoName(*ti);
916 if (!m_clidsvc->getIDOfTypeInfoName(ti_typename, id)
917 .isSuccess()) {
918 // try another one...
919 {
920 // Protect against data race inside TClassEdit.
921 // https://github.com/root-project/root/issues/10353
922 // Should be fixed in root 6.26.02.
923 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
924 ti_typename = TClassEdit::ShortType(ti_typename.c_str(),
925 TClassEdit::kDropAllDefault);
926 }
927 if (!m_clidsvc->getIDOfTypeInfoName(ti_typename, id)
928 .isSuccess()) {
929 ATH_MSG_DEBUG("** could not find a CLID from type-info ["
930 << System::typeinfoName(*ti) << "]");
931 ATH_MSG_DEBUG("** could not find a CLID from type-info-alias ["
932 << ti_typename << "]");
933 continue;
934 }
935 }
936 } else {
937 // probably a built-in type...
938 if (!m_clidsvc->getIDOfTypeName(::root_typename(type_name), id)
939 .isSuccess()) {
940 ATH_MSG_DEBUG("** could not find a CLID for type-name ["
941 << type_name << "]");
942 continue;
943 }
944 }
945 if (id == 0) {
946 ATH_MSG_DEBUG("** could not find a CLID for type-name ["
947 << type_name << "]");
948 continue;
949 }
951 (ROOT_StorageType, id,
952 m_tuple->GetName(),
953 br_name,
954 (unsigned long)(value_ptr),
955 (unsigned long)(m_curEvt-1));
956
957 // recycle old rootaddress, if any.
958 SG::DataProxy* proxy = m_dataStore->proxy (id, sg_key);
959 if (proxy) {
960 proxy->setAddress (addr);
961 }
962 else {
963 auto taddr = new SG::TransientAddress(id, sg_key, addr, false);
964 taddr->setProvider(this, storeID);
965 // only add the *new* TransientAddress to the input list as the *old* ones
966 // are already tracked by the datastore (via the sticky proxies)
967 tads.push_back(taddr);
968 }
969 }
970 }
971 m_needReload = false;
972 // BeginInputFile is deferred to handle() on BeginEvent — see comment there.
973
974 return StatusCode::SUCCESS;
975}
976
977StatusCode
979 TTree *tree,
980 const std::string& prefix) const
981{
982 if (0 == store) {
983 ATH_MSG_ERROR("null pointer to store !");
984 return StatusCode::FAILURE;
985 }
986
987 if (0 == tree) {
988 ATH_MSG_ERROR("null pointer to n-tuple !");
989 return StatusCode::FAILURE;
990 }
991
992 // Record tree in Storegate for later writing
993 TransferTree* temp = new TransferTree(tree);
994 if (store->record(temp,prefix).isFailure()) ATH_MSG_ERROR("Unable to record metadata tree " << tree->GetName());
995
996 const std::string tree_name = tree->GetName();
997 TObjArray *branches = tree->GetListOfBranches();
998 if (!branches) {
999 ATH_MSG_INFO("no branches!!");
1000 return StatusCode::SUCCESS;
1001 }
1002
1003 // loop over branches
1004 for (Int_t i = 0; i < branches->GetEntries(); ++i) {
1005 TBranch *branch = (TBranch *)branches->At(i);
1006 if (branch) {
1007
1008 CLID id = 0;
1009 const void* value_ptr = tree;
1010 const std::string type_name = branch->GetClassName();
1011 const std::string br_name = branch->GetName();
1012 const std::string sg_key = prefix.empty()
1013 ? br_name
1014 : prefix + "/" + br_name;
1015 TClass *cls = NULL;
1016 if (!type_name.empty()) {
1017 cls = TClass::GetClass(type_name.c_str());
1018 }
1019 const std::type_info *ti = 0;
1020
1021 if (cls) {
1022 ti = cls->GetTypeInfo();
1023 // first, try to load a dict for that class...
1024 if (ti) {
1025 m_dictsvc->load_type(*ti);
1026 }
1027 if (!ti) {
1028 ATH_MSG_WARNING("could not find a type-info for [" <<
1029 type_name << "]");
1030 continue;
1031 }
1032 std::string ti_typename = System::typeinfoName(*ti);
1033 if (!m_clidsvc->getIDOfTypeInfoName(ti_typename, id)
1034 .isSuccess()) {
1035 // try another one...
1036 {
1037 // Protect against data race inside TClassEdit.
1038 // https://github.com/root-project/root/issues/10353
1039 // Should be fixed in root 6.26.02.
1040 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
1041 ti_typename = TClassEdit::ShortType(ti_typename.c_str(),
1042 TClassEdit::kDropAllDefault);
1043 }
1044 if (!m_clidsvc->getIDOfTypeInfoName(ti_typename, id)
1045 .isSuccess()) {
1046 ATH_MSG_INFO("** could not find a CLID from type-info ["
1047 << System::typeinfoName(*ti) << "]");
1048 ATH_MSG_INFO("** could not find a CLID from type-info-alias ["
1049 << ti_typename << "]");
1050 continue;
1051 }
1052 }
1053 } else {
1054 // probably a built-in type...
1055 TObjArray *leaves = branch->GetListOfLeaves();
1056 if (leaves &&
1057 leaves->GetEntries() == 1) {
1058 const std::string type_name = ((TLeaf*)leaves->At(0))->GetTypeName();
1059 if (!m_clidsvc->getIDOfTypeName(::root_typename(type_name), id)
1060 .isSuccess()) {
1061 ATH_MSG_INFO("** could not find a CLID for type-name ["
1062 << type_name << "]");
1063 continue;
1064 }
1065 }
1066 }
1067 if (id == 0) {
1068 ATH_MSG_INFO("** could not find a CLID for type-name ["
1069 << type_name << "]");
1070 continue;
1071 }
1074 (ROOT_StorageType, id,
1075 tree_name,
1076 br_name,
1077 (unsigned long)(value_ptr),
1078 (unsigned long)(0)));
1079 if (!store->recordAddress(sg_key, std::move(addr), true).isSuccess()) {
1080 ATH_MSG_ERROR("could not record address at [" << sg_key << "] in store ["
1081 << store->name() << "]");
1082 }
1083 // SG::TransientAddress* taddr = new SG::TransientAddress
1084 // (id, sg_key, addr);
1085 // taddr->setProvider(this);
1086 // taddr->clearAddress(true);
1087 // tads.push_back(taddr);
1088 }
1089 }
1090 return StatusCode::SUCCESS;
1091}
1092
1093TTree*
1095 const std::string& tupleName) const
1096{
1097 // std::cout << "::fetchNtuple(" << fname << ")..." << std::endl;
1098 TTree* tree = NULL;
1100 // std::cout << "::TFile::Open()..." << std::endl;
1101 TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(fname.c_str());
1102 TFile* fnew = nullptr;
1103 if (!f) {
1104 f = TFile::Open(fname.c_str(), "READ");
1105 fnew = f;
1106 if (f) {
1107 f->SetName(fname.c_str());
1108 }
1109 }
1110 if (!f || f->IsZombie()) {
1111 ATH_MSG_ERROR("could not open next file in input collection ["
1112 << fname << "]");
1113 if (f) {
1114 f->Close();
1115 }
1116 return tree;
1117 }
1118 // std::cout << "::TFile::GetTree(" << m_tupleName << ")..." << std::endl;
1119 tree = (TTree*)f->Get(tupleName.c_str());
1120 if (!tree) {
1121 ATH_MSG_ERROR("could not retrieve tree [" << tupleName << "]"
1122 << " from file [" << fname << "]");
1123 f->Close();
1124 return tree;
1125 }
1126
1127 if (fnew)
1128 m_files.push_back(fnew);
1129
1130 // std::cout << "::TTree::SetBranchStatus()..." << std::endl;
1131 // disable all branches
1132 tree->SetBranchStatus("*", 0);
1133 if (!m_eventNumberVar.value().empty()) {
1134 tree->SetBranchStatus(m_eventNumberVar.value().c_str(), 1);
1135 }
1136 if (!m_runNumberVar.value().empty()) {
1137 tree->SetBranchStatus(m_runNumberVar.value().c_str(), 1);
1138 }
1139 if (!m_lbnVar.value().empty()) {
1140 tree->SetBranchStatus(m_lbnVar.value().c_str(), 1);
1141 }
1142
1143 if (!m_imetaStore->clearStore().isSuccess()) {
1144 ATH_MSG_INFO("could not clear store [" << m_imetaStore.typeAndName() << "]");
1145 return tree;
1146 }
1147
1148 addMetadataFromDirectoryName(tupleName+"Meta", f);
1149 addMetadataFromDirectoryName("Lumi", f, "Lumi");
1150 return tree;
1151}
1152
1153void RootNtupleEventSelector::addMetadataFromDirectoryName(const std::string &metadirname, TFile *fileObj, const std::string &prefix) const
1154{
1155 TDirectoryFile *metadir = (TDirectoryFile*)fileObj->Get(metadirname.c_str());
1156 if (!metadir) return;
1157 addMetadataFromDirectory(metadir, prefix);
1158}
1159
1160void RootNtupleEventSelector::addMetadataFromDirectory(TDirectoryFile *metadir, const std::string &prefix) const
1161{
1162 std::unordered_set<std::string> meta_keys;
1163 const TList *keys = metadir->GetListOfKeys();
1164 for (Int_t i=0; i < keys->GetSize(); ++i) {
1165 TKey* key = dynamic_cast<TKey*>(keys->At(i));
1166 if (!key) {
1167 continue;
1168 }
1169
1170 const std::string meta_key = key->GetName();
1171 if (!meta_keys.emplace(key->GetName()).second) {
1172 // key was already in the set:
1173 // meta_key is another cycle from a previous key entry.
1174 // *ASSUME* the highest cycle is the one we are interested in
1175 // *AND* that it was the previous one...
1176 continue;
1177 }
1178
1179 std::string fullPrefix(prefix);
1180 if (prefix != "") fullPrefix += "/";
1181 const std::string path = fullPrefix + key->GetName();
1182
1183 TString fullKeyName(TString::Format("%s;%hi", key->GetName(), key->GetCycle()));
1184 TObject *objRef = metadir->Get(fullKeyName);
1185
1186 TTree *metatree = dynamic_cast<TTree*>(objRef);
1187 if (metatree) {
1188 addMetadata(metatree, path);
1189 continue;
1190 }
1191
1192 TObjString *metaObjString = dynamic_cast<TObjString*>(objRef);
1193 if (metaObjString) {
1194 addMetadata(metaObjString, path);
1195 continue;
1196 }
1197
1198 ATH_MSG_WARNING("Unsupported metadata type: " << objRef->ClassName());
1199 }
1200}
1201
1202void RootNtupleEventSelector::addMetadata(TTree *metatree, const std::string &path) const
1203{
1204 if (metatree->GetEntry(0) < 0) {
1205 ATH_MSG_INFO("Problem retrieving data from metadata-tree [" << path << "] !!");
1206 return;
1207 }
1208
1209 if (!createMetaDataRootBranchAddresses(m_imetaStore.get(), metatree, path).isSuccess()) {
1210 ATH_MSG_INFO("Could not create metadata for tree [" << path << "]");
1211 }
1212}
1213
1214void RootNtupleEventSelector::addMetadata(TObjString *metastring, const std::string &path) const
1215{
1216 std::string *converted = new std::string(metastring->String());
1217 if (!m_imetaStore->record(converted, path).isSuccess()) {
1218 ATH_MSG_INFO("Could not create metadata for string [" << path << "]");
1219 }
1220}
1221
1222StatusCode
1224{
1225 // std::cout << "::fetchNtuple..." << std::endl;
1226
1227 // initialize some helper structures and data
1228 {
1229 CollMetaData zero;
1230 zero.min_entries = -1;
1231 zero.max_entries = -1;
1232 zero.entries = -1;
1233 m_collEvts.resize (m_tupleNames.size());
1234 for (size_t i = 0; i < m_collEvts.size(); i++) {
1235 m_collEvts[i].resize(m_inputCollectionsName.value().size(), zero);
1236 }
1237 }
1238
1239 m_tuple = fetchNtuple(m_inputCollectionsName.value()[0],
1240 m_tupleNames[0]);
1241 if (!m_tuple) {
1242 throw "RootNtupleEventSelector: Unable to fetch Ntuple";
1243 }
1244
1245 // std::cout << "::clear-root-addresses..." << std::endl;
1246 // reset the list of branches
1247 m_needReload = true;
1248
1249 // skip events we are asked to skip
1250 m_curEvt = m_skipEvts;
1251 m_nbrEvts = 0;
1252
1253 // std::cout << "::fetchNtuple...[done]" << std::endl;
1254 return StatusCode::SUCCESS;
1255}
1256
1261void
1262RootNtupleEventSelector::find_coll_idx (int evtidx,
1263 long& coll_idx,
1264 long& tuple_idx) const
1265{
1266 coll_idx = -1;
1267 tuple_idx = -1;
1268
1269 // std::cout << "--find_coll_idx(" << evtidx << ")..." << std::endl
1270 // << "--collsize: " << m_collEvts.size() << std::endl;
1271 for (size_t ituple = 0; ituple < m_collEvts.size(); ++ituple) {
1272 for (size_t icoll = 0; icoll < m_collEvts[ituple].size(); ++icoll) {
1273 CollMetaData &itr = m_collEvts[ituple][icoll];
1274 if (itr.min_entries == -1) {
1275 TTree *tree = fetchNtuple(m_inputCollectionsName.value()[icoll],
1276 m_tupleNames[ituple]);
1277 if (tree) {
1278 long offset = 0;
1279 if (icoll > 0) {
1280 offset = m_collEvts[ituple][icoll-1].max_entries;
1281 }
1282 else if (ituple > 0) {
1283 offset = m_collEvts[ituple-1].back().max_entries;
1284 }
1285 itr.entries = tree->GetEntriesFast();
1286 itr.min_entries = offset;
1287 itr.max_entries = offset + itr.entries;
1288 } else {
1289 throw "RootNtupleEventSelector: Unable to fetch ntuple";
1290 }
1291 }
1292 // std::cout << "--[" << i << "] => [" << itr.min_entries << ", "
1293 // << itr.max_entries << ") evtidx=[" << evtidx << "]"
1294 // << std::endl;
1295 if (itr.min_entries <= evtidx && evtidx < itr.max_entries) {
1296 coll_idx = icoll;
1297 tuple_idx = ituple;
1298 return;
1299 }
1300 }
1301 }
1302}
1303
1305int RootNtupleEventSelector::size (Context& /*refCtxt*/) const {
1306 //use find_coll_idx to trigger a population of the m_collEvts
1307 long coll_idx, tuple_idx;
1308 find_coll_idx(-1, coll_idx, tuple_idx);
1309 return m_collEvts.back().back().max_entries;
1310}
1311
1312
1313void RootNtupleEventSelector::handle(const Incident& incident) {
1314 if (m_fireBIF && incident.type() == IncidentType::BeginEvent) {
1315 std::string fname = m_tuple->GetCurrentFile()->GetName();
1317 fname, {},
1318 /*endFileName=*/fname);
1319 m_fireBIF = false;
1320 }
1321}
1322
1323} //> namespace Athena
#define endmsg
#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)
macros to associate a CLID to a type
#define CLASS_DEF(NAME, CID, VERSION)
associate a clid and a version to a type eg
#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.
size_t size() const
Number of registered mappings.
Include TBranchElement.h, suppressing clang warnings.
int imax(int i, int j)
A simple class to hold the buffer of a TBranch from a TTree.
state of a few global resources from ROOT and restores their initial value upon d-tor call.
ROOT specific event selector context.
virtual void * identifier() const
context identifier
long m_tupleIdx
current tuple index (into `m_tupleNames')
void setTree(TTree *tree)
set the tree used to iterate
std::size_t fileIndex() const
access to the file iterator
std::vector< std::string > FileNames_t
definition of the file container
const std::string & fid() const
access to the connection FID
virtual ~RootNtupleEventContext()
standard d-tor
void setFileIndex(std::size_t idx)
set file iterator
long m_collIdx
current collection index (into m_inputCollectionsName)
int64_t entry() const
access to the current event entry number
const RootNtupleEventSelector * m_evtsel
reference to the hosting event selector instance
TTree * tree() const
access to the tree used to iterate
void setFID(const std::string &fid)
set connection FID
RootNtupleEventContext(const RootNtupleEventSelector *sel)
standard c-tor with initialization
Class implementing the GAUDI IEvtSelector interface using ROOT TTree as a backend.
virtual StatusCode seek(Context &refCtxt, int evtnum) const override
Seek to a given event number.
virtual StatusCode finalize() override
virtual int size(Context &refCtxt) const override
ICollectionSize interface
RootNtupleEventSelector(const std::string &name, ISvcLocator *svcLoc)
Constructor with parameters:
virtual StatusCode releaseContext(Context *&refCtxt) const override
virtual int curEvent(const Context &refCtxt) const override
return the current event number.
void setupInputCollection(Gaudi::Details::PropertyBase &inputCollectionsName)
callback to synchronize the list of input files
virtual StatusCode loadAddresses(StoreID::type storeID, tadList &list) override
get all new addresses from Provider for this Event.
virtual StatusCode last(Context &refContext) const override
virtual StatusCode resetCriteria(const std::string &cr, Context &ctx) const override
virtual StatusCode preLoadAddresses(StoreID::type storeID, tadList &list) override
TTree * m_tuple
current tree being read
std::vector< std::vector< CollMetaData > > m_collEvts
helper method to get the collection index (into m_inputCollectionsName) and tuple index (into m_tuple...
bool m_needReload
The (python) selection function to apply on the TChain we are reading.
virtual StatusCode updateAddress(StoreID::type storeID, SG::TransientAddress *tad, const EventContext &ctx) override
update a transient Address
virtual StatusCode next(Context &refCtxt) const override
StatusCode endInputFile(RootNtupleEventContext *rctx) const
StatusCode do_init_io()
helper method to init the i/o components
StatusCode createMetaDataRootBranchAddresses(StoreGateSvc *store, TTree *tree, const std::string &prefix) const
helper method to create proxies for the metadata store
bool m_fireBIF
Flag to fire BeginInputFile on the next BeginEvent incident.
void addMetadataFromDirectoryName(const std::string &metadirname, TFile *fileObj, const std::string &prefix="") const
virtual StatusCode createContext(Context *&refpCtxt) const override
std::optional< InputFileIncidentGuard > m_inputFileGuard
RAII guard: guarantees a matching EndInputFile for every BeginInputFile.
void addMetadataFromDirectory(TDirectoryFile *metadir, const std::string &prefix="") const
void addMetadata(TTree *metatree, const std::string &path="") const
TTree * fetchNtuple(const std::string &fname, const std::string &tupleName) const
helper method to retrieve the correct tuple
virtual void handle(const Incident &incident) override
StatusCode createRootBranchAddresses(StoreID::type storeID, tadList &tads)
helper method to create proxies
virtual StatusCode initialize() override
virtual StatusCode previous(Context &refCtxt) const override
virtual StatusCode io_reinit() override
Callback method to reinitialize the internal state of the component for I/O purposes (e....
virtual StatusCode rewind(Context &refCtxt) const override
virtual StatusCode createAddress(const Context &refCtxt, IOpaqueAddress *&) const override
Simple smart pointer for Gaudi-style refcounted objects.
EventID * event_ID()
the unique identification of the event.
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.
void record(const T *p, const std::string &key)
Definition TestStore.h:81
virtual const std::string & name() const override
Definition TestStore.cxx:97
sgkey_t sgkey() const
Set the primary (hashed) SG key.
The Athena Transient Store API.
@ EVENT_STORE
Definition StoreID.h:26
void zero(TH2 *h)
zero the contents of a 2d histogram
std::vector< std::string > files
file names and file pointers
Definition hcg.cxx:52
Some weak symbol referencing magic... These are declared in AthenaKernel/getMessageSvc....
Definition AthDsoUtils.h:10
RootNtupleEventContext::FileNames_t FileNames_t
find_coll_idx(-1, coll_idx, tuple_idx)
StatusCode ROOTMessageFilterSvc::initialize ATLAS_NOT_THREAD_SAFE()
Return the file descriptor fataldump() uses for output.
StatusCode parse(std::tuple< Tup... > &tup, const Gaudi::Parsers::InputData &input)
@ active
Definition Layer.h:47
EventInfo_v1 EventInfo
Definition of the latest event info version.
TChain * tree