30#include <TMethodCall.h>
32#include <ROOT/RNTuple.hxx>
51std::string getFirstFieldMatch(ROOT::RNTupleReader& reader,
52 const std::string& pre) {
54 const std::regex pattern(
".*" + pre +
".*");
55 for (
const auto& field : reader.GetDescriptor().GetTopLevelFields()) {
57 if (std::regex_match(field.GetFieldName(), pattern)) {
58 return field.GetFieldName();
115 <<
"\" in file: " << fileName);
121 ROOT::RNTupleDescriptor::RCreateModelOptions opts;
122 opts.SetEmulateUnknownTypes(
true);
126 <<
"\" tree in input file: " << fileName);
127 return StatusCode::FAILURE;
130 <<
"\" in file: " << fileName);
135 static const std::string eventFormatTypeName =
137 if (::TClass::GetClass(eventFormatTypeName.c_str()) ==
nullptr) {
144 auto readEventFormatMetadata = [&](std::string_view tupleName) -> StatusCode {
147 auto metaReader = ROOT::RNTupleReader::Open(tupleName, fileName);
150 << tupleName <<
"\" ntuple in input file: " << fileName);
151 return StatusCode::FAILURE;
154 << tupleName <<
"\" in file: " << fileName);
157 const std::string eventFormatFieldName =
162 for (
const auto& [key, element] : ef(0u)) {
165 }
catch (
const ROOT::RException&) {
167 return StatusCode::RECOVERABLE;
173 return StatusCode::SUCCESS;
178 if (
sc.isRecoverable()) {
180 return StatusCode::SUCCESS;
187 std::set<std::string> lOtherMetaTupleNames;
189 std::unique_ptr<TFile> inFile(TFile::Open(fileName.data(),
"READ"));
190 TList* lKeys = inFile->GetListOfKeys();
191 if (lKeys ==
nullptr) {
192 ATH_MSG_ERROR(
"Could not get list of keys for input file: " << fileName);
193 return StatusCode::FAILURE;
195 for (
const TObject* obj : *lKeys) {
196 const std::string keyName = obj->GetName();
201 (keyName.find(
"MetaData") != std::string::npos) &&
202 (keyName.find(
"MetaDataHdr") == std::string::npos)) {
204 const TKey* key =
dynamic_cast<const TKey*
>(obj);
205 if (key ==
nullptr) {
206 ATH_MSG_ERROR(
"Object describing \"" << keyName <<
"\" in file \""
208 <<
"\" is not a TKey?");
209 return StatusCode::FAILURE;
211 const char* className = key->GetClassName();
212 static constexpr bool LOAD = kFALSE;
213 static constexpr bool SILENT = kTRUE;
214 ::TClass* cl = ::TClass::GetClass(className, LOAD, SILENT);
215 if ((cl !=
nullptr) && cl->InheritsFrom(ROOT::RNTuple::Class())) {
216 lOtherMetaTupleNames.insert(std::move(keyName));
223 for (
const std::string& tupleName : lOtherMetaTupleNames) {
224 ATH_CHECK(readEventFormatMetadata(tupleName));
231 <<
"\" in file: " << fileName);
232 return StatusCode::FAILURE;
235 <<
"\" in file: " << fileName);
241 stats.setNEvents(stats.nEvents() +
m_eventReader->GetNEntries());
246 listener->handle(beginIncident);
255 listener->handle(endIncident);
259 return StatusCode::SUCCESS;
300 ATH_MSG_DEBUG(
"Entry " << entry <<
" is already the active one");
315 result += inObj->getEntry(getall);
322 listener->handle(incident);
340 std::vector<std::string>& ,
344 return StatusCode::FAILURE;
369 return StatusCode::FAILURE;
377 return StatusCode::SUCCESS;
384 return StatusCode::RECOVERABLE;
394 std::string key_to_read = key;
395 if (key.ends_with(
"Aux.")) {
396 key_to_read.replace(key_to_read.size() - 1, 1,
":");
408 if (
m_eventReader->GetDescriptor().FindFieldId(key_to_read.c_str()) ==
409 ROOT::kInvalidDescriptorId) {
412 ATH_MSG_WARNING(
"Field \"" << key_to_read <<
"\" not available on input");
415 return StatusCode::RECOVERABLE;
423 ROOT::RNTupleView<void> view =
425 std::string className = view.GetField().GetTypeName();
426 if (className ==
"") {
430 className = ef->className();
433 "Couldn't find an appropriate type with a dictionary for field \""
434 << key_to_read <<
"\"");
435 return StatusCode::FAILURE;
438 ::TClass* realClass = ::TClass::GetClass(className.c_str());
439 if (((!realClass) || (!realClass->IsLoaded())) && ef) {
443 className = ef->className();
444 realClass = ::TClass::GetClass(className.c_str());
446 if ((!realClass) || (!realClass->IsLoaded())) {
449 "Couldn't find an appropriate type with a dictionary for field \""
450 << key_to_read <<
"\"");
451 return StatusCode::FAILURE;
468 if (ptr ==
nullptr) {
469 ptr = realClass->New();
473 auto mgr = std::make_unique<RObjectManager>(
475 std::make_unique<THolder>(ptr, realClass));
491 return StatusCode::SUCCESS;
507 return StatusCode::FAILURE;
512 return StatusCode::SUCCESS;
516 std::string key_to_read = key;
517 if (key.ends_with(
"Aux.")) {
518 key_to_read.replace(key_to_read.size() - 1, 1,
":");
522 if (
m_metaReader->GetDescriptor().FindFieldId(key_to_read.c_str()) ==
523 ROOT::kInvalidDescriptorId) {
526 ATH_MSG_WARNING(
"Field \"" << key_to_read <<
"\" not available on input");
528 return StatusCode::RECOVERABLE;
536 ROOT::RNTupleView<void> view =
537 m_metaReader->GetView<
void>(key_to_read.c_str(),
nullptr);
538 std::string className = view.GetField().GetTypeName();
539 if (className ==
"") {
541 "Couldn't find an appropriate type with a dictionary for field \""
542 << key_to_read <<
"\"");
543 return StatusCode::FAILURE;
545 ::TClass* realClass = ::TClass::GetClass(className.c_str());
546 if ((!realClass) || (!realClass->IsLoaded())) {
549 "Couldn't find an appropriate type with a dictionary for field \""
550 << key_to_read <<
"\"");
551 return StatusCode::FAILURE;
555 void* ptr = realClass->New();
556 static const ::Long64_t FIRST_ENTRY = 0;
557 auto mgr = std::make_unique<RObjectManager>(
558 m_metaReader->GetView(key_to_read, ptr, className), FIRST_ENTRY,
559 std::make_unique<THolder>(ptr, realClass));
575 static constexpr bool METADATA =
true;
580 return StatusCode::SUCCESS;
598 return StatusCode::FAILURE;
603 return StatusCode::SUCCESS;
607 static constexpr bool SILENT =
false;
614 return StatusCode::FAILURE;
618 if (omgr ==
nullptr) {
620 return StatusCode::FAILURE;
624 static const TClass*
const holderClass =
626 if (omgr->
holder()->
getClass()->InheritsFrom(holderClass) ==
false) {
628 return StatusCode::SUCCESS;
636 return StatusCode::FAILURE;
645 ATH_MSG_ERROR(
"Requested store types inconsistent for: " << prefix);
647 << standalone <<
", getStoreType() = "
649 return StatusCode::FAILURE;
653 return StatusCode::SUCCESS;
666 ::Bool_t standalone) {
671 return StatusCode::FAILURE;
676 return StatusCode::SUCCESS;
680 static constexpr bool SILENT =
false;
687 return StatusCode::FAILURE;
691 if (omgr ==
nullptr) {
693 return StatusCode::FAILURE;
697 static const TClass*
const holderClass =
699 if (omgr->
holder()->
getClass()->InheritsFrom(holderClass) ==
false) {
701 return StatusCode::SUCCESS;
709 return StatusCode::FAILURE;
718 ATH_MSG_ERROR(
"Requested store types inconsistent for: " << prefix);
720 << standalone <<
", getStoreType() = "
722 return StatusCode::FAILURE;
726 return StatusCode::SUCCESS;
746 return StatusCode::SUCCESS;
759 auto itr = objects.find(key +
"Aux.");
760 if (itr == objects.end()) {
763 return StatusCode::SUCCESS;
765 auxMgr = itr->second.get();
766 auxKey = key +
"Aux:";
771 ::Int_t readBytes = auxMgr->
getEntry();
775 const std::string dynAuxKey = auxKey +
"Dynamic";
776 auto dynAuxMgr = objects.find(dynAuxKey);
777 if ((dynAuxMgr != objects.end()) && (readBytes || (auxMgr == &mgr))) {
780 dynAuxMgr->second->getEntry();
785 if (auxMgr == &mgr) {
786 return StatusCode::SUCCESS;
792 switch (mgr.holder()->typeKind()) {
807 if (
vec && (!
vec->trackIndices())) {
808 Details::forceTrackIndices(*
vec);
814 << mgr.holder()->getClass()->GetName()
815 <<
"\" as SG::AuxVectorBase or SG::AuxElement");
816 return StatusCode::FAILURE;
823 <<
"\" is not of the right type");
824 return StatusCode::FAILURE;
829 if (store ==
nullptr) {
831 return StatusCode::FAILURE;
836 vec->setStore(store);
838 aux->setStore(store);
841 return StatusCode::FAILURE;
845 return StatusCode::SUCCESS;
852 return StatusCode::FAILURE;
857 ATH_MSG_ERROR(
"xAOD::REvent::recordAux not yet implemented");
858 return StatusCode::FAILURE;
872 return StatusCode::FAILURE;
881 ATH_MSG_DEBUG(
"Investigating object \"" << key <<
"\" of class \""
882 << format.className() <<
"\"");
885 if (key.ends_with(
"Aux.")) {
890 TClass* cl = TClass::GetClass(format.className().c_str());
891 if ((cl ==
nullptr) || (cl->IsLoaded() ==
false)) {
893 "Couldn't find the dictionary for type: " << format.className());
899 static TClass*
const auxContCl = TClass::GetClass(
901 static TClass*
const auxInfoCl = TClass::GetClass(
903 if ((auxContCl ==
nullptr) || (auxInfoCl ==
nullptr)) {
905 "Couldn't get dictionary for xAOD::AuxContainerBase or "
906 "xAOD::AuxInfoBase");
907 return StatusCode::FAILURE;
909 const bool isContainer = cl->InheritsFrom(auxContCl);
910 const bool isInfo = cl->InheritsFrom(auxInfoCl);
911 if ((isContainer ==
false) && (isInfo ==
false)) {
914 <<
"\" is of an unknown type: " << format.className());
918 <<
", isInfo = " << isInfo);
921 const std::string fieldName = key.substr(0, key.size() - 1) +
":";
925 static constexpr bool TOP_STORE =
true;
926 RAuxStore temp(fieldName, TOP_STORE, mode);
932 stats.branch(fieldName,
id);
936 stats.setBranchNum(stats.branchNum() + temp.getAuxIDs().size());
942 ROOT::kInvalidDescriptorId) {
949 return StatusCode::SUCCESS;
961 ROOT::RNTupleReader& reader) {
964 const std::string fieldName = mgr.field().GetField().GetFieldName();
967 ::TMethodCall setNameCall;
968 setNameCall.InitWithPrototype(mgr.holder()->getClass(),
"setName",
970 if (setNameCall.IsValid()) {
973 const ::TString params = ::TString::Format(
"\"%s\"", fieldName.c_str());
974 const char* charParams = params.Data();
975 setNameCall.Execute(mgr.holder()->get(), charParams);
979 << fieldName <<
"\" (type: "
980 << mgr.holder()->getClass()->GetName() <<
")");
984 static const TClass*
const holderClass =
986 if (!mgr.holder()->getClass()->InheritsFrom(holderClass)) {
988 return StatusCode::SUCCESS;
996 return StatusCode::FAILURE;
1003 static constexpr bool TOP_STORE =
false;
1004 auto store = std::make_unique<RAuxStore>(
1005 fieldName, TOP_STORE,
1021 static constexpr bool SHARED_OWNER =
false;
1023 std::make_unique<RAuxManager>(store.get(),
m_entry, SHARED_OWNER);
1026 storeHolder->
setStore(store.release());
1029 return StatusCode::SUCCESS;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
Base class for elements of a container that can have aux data.
Manage index tracking and synchronization of auxiliary data.
std::vector< size_t > vec
void upgrade()
Convert the lock from upgrade to exclusive.
Base class for elements of a container that can have aux data.
Manage index tracking and synchronization of auxiliary data.
Interface for objects taking part in direct ROOT I/O.
@ AST_ContainerStore
The store describes a container.
@ AST_ObjectStore
The store describes a single object.
virtual AuxStoreType getStoreType() const =0
Return the type of the store object.
virtual void setStore(IAuxStore *store)=0
Give an auxiliary store object to the holder object.
Interface for const operations on an auxiliary store.
Common base class for the auxiliary containers.
Common base class for auxiliary info objects.
Manager for EDM objects created by ROOT.
const THolder * holder() const
Accessor to the Holder object.
EventFormat m_inputEventFormat
Format of the current input file.
std::set< std::string > m_inputMissingObjects
Objects that have been asked for, but were found to be missing in the current input.
upgrade_mutex_t m_branchesMutex
Mutex for multithread synchronization.
AthContainers_detail::upgrading_lock< upgrade_mutex_t > upgrading_lock_t
Lock type for multithread synchronization.
Object_t m_inputObjects
Collection of all the managed input objects.
Event(std::string_view name)
Constructor with a name.
std::unordered_map< std::string, std::unique_ptr< TVirtualManager > > Object_t
Definition of the internal data structure type.
void setActive() const
Set this event object as the currently active one.
Object_t m_inputMetaObjects
Collection of all the managed input meta-objects.
Object_t m_outputObjects
Collection of all the managed output object.
std::vector< TVirtualIncidentListener * > m_listeners
Listeners who should be notified when certain incidents happen.
bool m_inputNTupleIsMissing
Whether the input has an event RNTuple or not.
StatusCode setUpDynamicStore(RObjectManager &mgr, ROOT::RNTupleReader &ntupleReader)
event uses RNTupleReader:
StatusCode record(void *obj, const std::string &typeName, const std::string &key, bool overwrite, bool metadata, bool isOwner) override
Record an object into a connected output file.
std::unique_ptr< ROOT::RNTupleReader > m_eventReader
The main event data reader.
StatusCode connectMetaAux(const std::string &prefix, bool standalone) override
Function setting up access to a set of auxiliary branches for a metadata object.
StatusCode readFrom(std::string_view fileName)
Set up the reading of an input file.
std::unique_ptr< ROOT::RNTupleReader > m_metaReader
The metadata reader.
StatusCode recordAux(TVirtualManager &mgr, const std::string &key, bool metadata) override
Record an auxiliary store into a connected output file.
::Long64_t getEntries() const
Get how many entries are available from the current input file(s)
StatusCode setAuxStore(const std::string &key, Details::IObjectManager &mgr, bool metadata) override
Function connecting a DV object to its auxiliary store.
bool hasOutput() const override
Check if an output file is connected to the object.
::Int_t getEntry(::Long64_t entry, ::Int_t getall=0)
Function loading a given entry of the input TTree.
StatusCode getNames(const std::string &targetClassName, std::vector< std::string > &vkeys, bool metadata) const override
Function determining the list keys associated with a type name.
StatusCode connectObject(const std::string &key, bool silent) override
Function setting up access to a particular object.
::Long64_t m_entry
The entry to look at from the input tree.
REvent()
Default constructor.
virtual ~REvent()
Destructor.
StatusCode connectAux(const std::string &prefix, bool standalone) override
Function setting up access to a set of auxiliary branches.
StatusCode initStats()
Function to initialise the statistics for all Tree content.
StatusCode connectMetaObject(const std::string &key, bool silent) override
Function setting up access to a particular metadata object.
bool hasInput() const override
Check if an input file is connected to the object.
Manager for EDM objects created by ROOT.
ReadStats & stats()
Access the object belonging to the current thread.
static IOStats & instance()
Singleton object accessor.
"ROOT @c RNTuple implementation" of IAuxStore
Class describing the access statistics of a collection of branches.
void nextEvent()
Function incrementing the processed event counter.
BranchStats * container(const std::string &name)
Access the description of a container. Creating it if necessary.
void setBranchNum(::Int_t num)
Set the total number of branches on the input.
void readContainer(const std::string &name)
Function incrementing the read counter on a specific container.
const ::TClass * getClass() const
virtual void * getAs(const std::type_info &tid, ::Bool_t silent=kFALSE) const
Return the object as a specific pointer.
@ DATAVECTOR
A DataVector container.
@ AUXELEMENT
A type inheriting from SG::AuxElement.
Class describing a certain "incident" that is communicated to user code.
Class providing an interface for classes listening to xAOD incidents.
Interface class for the "manager classes".
virtual::Int_t getEntry(::Int_t getall=0)=0
Function for updating the object in memory if needed.
EStructMode
"Structural" modes of the object
@ kObjectStore
The object describes a single object.
@ kContainerStore
The object describes an entire container.
std::string normalizedTypeinfoName(const std::type_info &info)
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
size_t auxid_t
Identifier for a particular aux data item.
bool hasAuxStore(const TClass &cl)
Helper function deciding if a given type "has an auxiliary store".
bool isAuxStore(const TClass &cl)
Helper function deciding if a given type "is an auxiliary store".
bool isStandalone(const TClass &cl)
Helper function deciding if a given type "is a standalone object".
static const char *const METADATA_NTUPLE_NAME
static const char *const EVENT_NTUPLE_NAME
static const ::Int_t BeginEvent
A new event was just loaded.
static const ::Int_t EndInputFile
The processing of an input file has finished.
static const ::Int_t BeginInputFile
A new input file was just opened.
std::string getTypeName(const std::type_info &ti)
This function is necessary in order to create type names that ROOT can understand.
EventFormat_v1 EventFormat
Definition of the current event format version.
Convert a type_info to a normalized string representation (matching the names used in the root dictio...