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