26#include <ROOT/RNTuple.hxx>
27#include <ROOT/RNTupleReader.hxx>
29#include "Gaudi/Property.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"
39#include "GaudiKernel/IClassIDSvc.h"
54#include "EventInfo/EventInfo.h"
69#include "GaudiKernel/ServiceHandle.h"
82 bool isRNTupleFile(
const TFile&
file) {
86 if (!key)
return false;
87 const TClass*
cl = TClass::GetClass(
key->GetClassName(), kFALSE, kTRUE);
88 return cl &&
cl->InheritsFrom(ROOT::RNTuple::Class());
108 const std::vector<std::string>&
files()
const {
return m_evtsel->m_inputCollectionsName.value(); }
126 ISvcLocator* svcLoc ) :
127 base_class ( name, svcLoc ),
129 m_imetaStore(
"StoreGateSvc/InputMetaDataStore", name ),
135 m_ppSvc (
"ProxyProviderSvc" , name ),
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" );
151 declareProperty(
"FillEventInfo",
m_fillEventInfo=
false,
"If True, will fill old EDM EventInfo with xAOD::EventInfo content, necessary for database reading (IOVDbSvc)");
153 declareProperty(
"PrintPerfStats",
m_printPerfStats=
false,
"If True, at end of job will print the xAOD perf stats");
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");
161 declareProperty(
"ReadMetaDataWithPool",
m_readMetadataWithPool=
false,
"If true, metadata is read with POOL (by MetaDataSvc) instead of xAOD::Event");
179 if ( nbrInputFiles < 1 ) {
181 <<
"(Got [" << nbrInputFiles <<
"] file instead !)");
182 return StatusCode::FAILURE;
184 ATH_MSG_INFO(
"Selector configured to read [" << nbrInputFiles <<
"] file(s)...");
188 int old_level = gErrorIgnoreLevel;
189 gErrorIgnoreLevel = kWarning;
191 gErrorIgnoreLevel = old_level;
193 if(serviceLocator()->existsService(
"AthROOTErrorHandlerSvc")) {
195 CHECK( ehSvc.retrieve() );
196 CHECK( ehSvc->initialize() );
197 CHECK( ehSvc.release() );
205 return StatusCode::FAILURE;
210 ATH_MSG_INFO(
"First file is not POOL file (e.g. is CxAOD), so reading metadata with xAOD::Event instead");
217 ATH_MSG_INFO(
"Using RNTuple xAOD access (AccessMode is only used for TTree input)");
218 m_event = std::make_unique<xAOD::xAODREvent>();
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;
229 m_event = std::make_unique<xAOD::xAODTEvent>();
238 if (!iomgr.retrieve().isSuccess()) {
240 return StatusCode::FAILURE;
242 if (!iomgr->io_register(
this).isSuccess()) {
243 ATH_MSG_FATAL(
"Could not register myself with the IoComponentMgr !");
244 return StatusCode::FAILURE;
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 !");
256 ATH_MSG_VERBOSE(
"io_register[" << this->name() <<
"](" << incol[icol] <<
") [ok]");
260 return StatusCode::FAILURE;
265 return StatusCode::FAILURE;
297 std::vector<std::string> propVal;
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; }
304 if(!foundSvc) propVal.push_back(
"Athena::xAODCnvSvc");
308 CHECK( epSvc->setProperty(
"CnvServices", Gaudi::Utils::toString( propVal ) ));
317 std::vector<std::string> propVal;
318 IProperty* prop =
dynamic_cast<IProperty*
>(&*
m_ppSvc);
320 return StatusCode::FAILURE;
323 bool foundSvc(
false);
324 for(
const std::string& s : propVal) {
325 if(s==
"MetaDataSvc") { foundSvc=
true;
break; }
328 propVal.push_back(
"MetaDataSvc");
329 IProperty* prop =
dynamic_cast<IProperty*
>(&*
m_ppSvc);
331 return StatusCode::FAILURE;
333 CHECK( prop->setProperty(
"ProviderNames", Gaudi::Utils::toString( propVal ) ));
361 return StatusCode::SUCCESS;
369 return StatusCode::SUCCESS;
385 return StatusCode::SUCCESS;
403 throw GaudiException(
"xAODEventSelector::next() - Unable to get xAODEventContext",
"xAODEventSelector",StatusCode::FAILURE);
416 auto& fnames = rctx->
files();
418 if( rctx->setFile(
"").isFailure() ) {
419 throw GaudiException(
"xAODEventSelector::next() - Fatal error when trying to setFile('')",
"xAODEventSelector",StatusCode::FAILURE);
425 if( rctx->setFile( fname ).isFailure() ) {
426 throw GaudiException(
"xAODEventSelector::next() - Fatal error when trying to setFile('" + fname +
"')",
"xAODEventSelector",StatusCode::FAILURE);
431 rctx->
file()->GetName(), {},
432 rctx->
file()->GetName());
435 return StatusCode::FAILURE;
449 int64_t global_entry = rctx->
entry();
450 int64_t
entry = global_entry;
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);
478 if(
m_event->retrieve( xaodEventInfo ,
"EventInfo").isFailure()) {
480 throw GaudiException(
"xAODEventSelector::next() - Could not find xAOD::EventInfo",
"xAODEventSelector",StatusCode::FAILURE);
483 EventType* evtType =
new EventType;
487 if ( !
m_dataStore->record( evtInfo,
"EventInfo" ).isSuccess() ) {
489 delete evtInfo; evtInfo = 0;
490 throw GaudiException(
"xAODEventSelector::next() - Could not record EventInfo",
"xAODEventSelector",StatusCode::FAILURE);
493 return StatusCode::SUCCESS;
522 iaddr.second =
false;
523 SG::TransientAddress* taddr = iaddr.first;
526 const bool forceRemove =
false;
531 CHECK( rctx->setFile(
"") );
546 return StatusCode::FAILURE;
554 return next( ctx, -1 );
560 return next( ctx, -jump );
566 ATH_MSG_ERROR (
"............. Last Event Not Implemented .............");
567 return StatusCode::FAILURE;
582 return StatusCode::SUCCESS;
587 IOpaqueAddress*& )
const
590 return StatusCode::SUCCESS;
596 if(refCtxt==0)
return StatusCode::SUCCESS;
600 return StatusCode::SUCCESS;
603 return StatusCode::FAILURE;
609 ATH_MSG_ERROR (
"............. resetCriteria Not Implemented .............");
610 return StatusCode::FAILURE;
634 if (coll_idx == -1 && evtnum <
m_curEvt) {
638 if (coll_idx == -1) {
640 return StatusCode::RECOVERABLE;
647 return StatusCode::FAILURE;
655 return StatusCode::SUCCESS;
676 if (!iomgr.retrieve().isSuccess()) {
678 return StatusCode::FAILURE;
680 if (!iomgr->io_hasitem(
this)) {
681 ATH_MSG_FATAL(
"IoComponentMgr does not know about myself !");
682 return StatusCode::FAILURE;
691 std::string &fname = inputCollections[i];
693 if (!iomgr->io_contains(
this, fname)) {
694 ATH_MSG_ERROR(
"IoComponentMgr does not know about [" << fname <<
"] !");
695 return StatusCode::FAILURE;
697 if (!iomgr->io_retrieve(
this, fname).isSuccess()) {
698 ATH_MSG_FATAL(
"Could not retrieve new value for [" << fname <<
"] !");
699 return StatusCode::FAILURE;
719 return StatusCode::FAILURE;
723 return StatusCode::SUCCESS;
737 return StatusCode::SUCCESS;
749 return StatusCode::SUCCESS;
755 const EventContext& )
761 return StatusCode::SUCCESS;
764 << tad->
name() <<
") NOT known to us.");
765 return StatusCode::FAILURE;
769 return StatusCode::SUCCESS;
786 return(StatusCode::SUCCESS);
791 return StatusCode::FAILURE;
794 TTree* inputTree =
nullptr;
795 std::unique_ptr<ROOT::RNTupleReader> inputNTuple;
796 std::string ntupleName;
809 auto hasInputObject = [&](
const std::string& name) {
810 if (inputTree)
return inputTree->GetBranch(name.c_str()) !=
nullptr;
811 const ROOT::RNTupleDescriptor& descriptor = inputNTuple->GetDescriptor();
815 if(inputTree !=
nullptr || inputNTuple !=
nullptr) {
822 const void* value_ptr =
m_event.get();
824 std::set<std::string> missingAux;
826 for(
auto itr =
m_event->inputEventFormat()->begin(); itr!=
m_event->inputEventFormat()->end();++itr) {
827 if(!hasInputObject(itr->second.branchName()))
continue;
828 ATH_MSG_VERBOSE(
"EFE:" << itr->first <<
" branchName = " << itr->second.branchName() <<
" className=" << itr->second.className());
830 if(
m_clidsvc->getIDOfTypeInfoName(itr->second.className(),
id).isFailure() &&
831 m_clidsvc->getIDOfTypeName(itr->second.className(),
id).isFailure()) {
833 if(itr->second.branchName().compare(itr->second.branchName().length()-4,4,
"Aux.")==0) {
834 missingAux.insert( itr->second.className() );
continue;
837 TString className = itr->second.className();
841 TClass *cls = TClass::GetClass(className);
843 const std::type_info *ti = cls->GetTypeInfo();
844 if(ti) className = System::typeinfoName(*ti);
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());
855 const std::string br_name = itr->second.branchName();
861 (
unsigned long)(value_ptr),
874 if (old->clID() ==
id &&
875 old->name() == br_name) {
878 old->setAddress(addr);
880 iaddr->second =
true;
890 tads.push_back(taddr);
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);
911 ATH_MSG_DEBUG(
"In xAODEventSelector::createRootBranchAddresses end ...");
913 return StatusCode::SUCCESS;
920 ATH_MSG_DEBUG(
"In xAODEventSelector::createMetaDataRootBranchAddresses start ...");
924 throw "xAODEventSelector: Unable to get m_tfile";
932 std::vector<std::pair<std::string, std::string>> objects;
936 for (
const auto& field : reader->GetDescriptor().GetTopLevelFields()) {
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());
945 if (!
tree) std::abort();
946 TObjArray *leaves =
tree->GetListOfLeaves();
949 return StatusCode::SUCCESS;
951 for (Int_t i = 0; i < leaves->GetEntries(); ++i) {
952 TLeaf *leaf = (TLeaf *)leaves->At(i);
953 TBranch *branch = leaf->GetBranch();
955 objects.emplace_back(branch->GetName(), leaf->GetTypeName());
961 const std::string toCheck =
"xAOD::";
962 for (
const auto& [br_name, type_name] : objects) {
965 const void* value_ptr =
m_event.get();
967 if (!type_name.contains(toCheck)) {
968 ATH_MSG_DEBUG(
"** Skip type-name = " << type_name <<
", br_name = " << br_name );
971 const std::string sg_key = br_name;
972 TClass *cls = TClass::GetClass(type_name.c_str());
973 const std::type_info *ti = 0;
977 if( br_name ==
"EventFormat" )
continue;
980 ti = cls->GetTypeInfo();
996 << type_name <<
"]");
1002 ATH_MSG_DEBUG(
"id = " <<
id <<
", br_name = " << br_name <<
", value_ptr = " << value_ptr);
1008 (
unsigned long)(value_ptr),
1009 (
unsigned long)(1)));
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 ["
1022 ATH_MSG_DEBUG(
"In xAODEventSelector::createMetaDataRootBranchAddresses end ...");
1024 return StatusCode::SUCCESS;
1032 if(fname.empty())
return file;
1035 file = (TFile*)gROOT->GetListOfFiles()->FindObject(fname.c_str());
1038 file = TFile::Open(fname.c_str(),
"READ");
1039 if (
file)
file->SetName(fname.c_str());
1043 ATH_MSG_ERROR(
"could not open next file in input collection ["
1057 if(!newFile && !fname.empty()) {
1058 ATH_MSG_FATAL(
"xAODEventSelector: Unable to fetch Ntuple: " << fname);
1059 return StatusCode::FAILURE;
1063 const std::string currFile =
m_tfile->GetName();
1065 m_poolSvc->disconnectDb(
"PFN:"+currFile).ignore();
1073 if(!
m_tfile)
return StatusCode::SUCCESS;
1077 ATH_MSG_FATAL(
"xAODEventSelector: Cannot read " << fname <<
", mixing TTree and RNTuple input files is not supported");
1078 return StatusCode::FAILURE;
1081 if(
m_event->readFrom( *m_tfile ).isFailure()) {
1082 ATH_MSG_FATAL(
"xAODEventSelector: xAOD::Event cannot read " << fname);
1083 return StatusCode::FAILURE;
1091 return StatusCode::FAILURE;
1104 return StatusCode::SUCCESS;
1117 zero.min_entries = -1;
1118 zero.max_entries = -1;
1138 return StatusCode::SUCCESS;
1171 throw "xAODEventSelector: Unable to fetch ntuple";
#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...
This class provides general information about an event.
uint32_t CLID
The Class ID type.
Include TBranchElement.h, suppressing clang warnings.
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
bool m_readMetadataWithPool
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.
bool m_printEventProxyWarnings
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.
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)
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.
static const char *const EVENT_TREE_NAME
Default name of the event TTree.
static const char *const EVENT_RNTUPLE_NAME
Name of the event RNTuple.
ReadStats & stats()
Access the object belonging to the current thread.
static IOStats & instance()
Singleton object accessor.
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.
EAuxMode
Auxiliary store "mode".
void zero(TH2 *h)
zero the contents of a 2d histogram
Some weak symbol referencing magic... These are declared in AthenaKernel/getMessageSvc....
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
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.
EventInfo_v1 EventInfo
Definition of the latest event info version.