 |
ATLAS Offline Software
|
Go to the documentation of this file.
26 #include <ROOT/RNTupleInspector.hxx>
27 #include <ROOT/RNTupleReader.hxx>
28 #include <ROOT/RNTupleView.hxx>
29 #include <ROOT/RNTupleWriter.hxx>
39 #if ROOT_VERSION_CODE < ROOT_VERSION(6, 36, 0)
41 using Experimental::DescriptorId_t;
43 using Experimental::RFieldDescriptor;
44 using Experimental::RNTupleInspector;
47 using Experimental::RNTupleView;
49 #if ROOT_VERSION_CODE < ROOT_VERSION(6, 35, 1)
50 using Experimental::RException;
52 #endif // ROOT_VERSION_CODE < ROOT_VERSION(6, 35, 1)
54 #endif // ROOT_VERSION_CODE < ROOT_VERSION(6, 36, 0)
67 bool isContainerField(
const ROOT::RFieldDescriptor& fieldDesc,
82 TClass*
cl = TClass::GetClass(fieldDesc.GetTypeName().c_str());
88 ::Warning(
"::isPContainerField",
89 XAOD_MESSAGE(
"Couldn't get a dictionary for type \"%s\""),
90 fieldDesc.GetTypeName().c_str());
95 const std::type_info* root_ti =
cl->GetTypeInfo();
103 typeName.ReplaceAll(
"basic_string<char>",
"string");
104 ::TClass* newCl = ::TClass::GetClass(
typeName);
106 root_ti = newCl->GetTypeInfo();
111 XAOD_MESSAGE(
"Couldn't get an std::type_info object out of "
118 const std::type_info* aux_obj_ti =
124 static_cast<int>(auxid));
127 const std::type_info* aux_vec_ti =
133 static_cast<int>(auxid));
138 if (*root_ti == *aux_obj_ti) {
141 }
else if (*root_ti == *aux_vec_ti) {
149 if (
cl->GetCollectionProxy() && (*aux_vec_ti ==
typeid(std::vector<int>))) {
155 if (*cl2->GetTypeInfo() == *aux_vec_ti) {
171 aux_vec_cl->GetConversionStreamerInfo(
cl,
cl->GetClassVersion())) {
177 aux_obj_cl->GetConversionStreamerInfo(
cl,
cl->GetClassVersion())) {
183 XAOD_MESSAGE(
"Couldn't determine if field describes a single "
184 "object or a container"));
200 std::string_view
prefix,
void*
object,
const std::type_info* ti)
201 : m_field(std::move(
field)),
211 if ((m_entry ==
entry) && (!m_needsRead)) {
212 return StatusCode::SUCCESS;
218 }
catch (
const ROOT::RException&
e) {
219 ::Error(
"::RFieldInfo::getEntry",
220 "Failed to load entry %lld for field %s.%s: %s",
entry,
224 return StatusCode::FAILURE;
230 return StatusCode::SUCCESS;
239 void* objectPtr() {
return m_object; }
242 const std::type_info* typeInfo()
const {
return m_typeInfo; }
245 void reset() { m_needsRead =
true; }
249 ROOT::RNTupleView<void> m_field;
253 std::string_view m_prefix;
255 void* m_object =
nullptr;
257 const std::type_info* m_typeInfo =
nullptr;
259 ::Long64_t m_entry = -1;
261 bool m_needsRead =
true;
265 bool fieldExists(std::string_view
fieldName,
269 return (ntupleReader.GetDescriptor().FindFieldId(
fieldName) !=
291 return StatusCode::SUCCESS;
296 return StatusCode::SUCCESS;
301 #
if ROOT_VERSION_CODE >= ROOT_VERSION(6, 35, 0)
302 m_inTuple->GetModel().GetConstFieldZero().GetConstSubfields()
304 m_inTuple->GetModel().GetConstFieldZero().GetSubFields()
316 #
if ROOT_VERSION_CODE >= ROOT_VERSION(6, 35, 0)
317 field->GetConstSubFields()
319 field->GetSubFields()
324 const std::string subFieldName = subField->GetQualifiedFieldName();
325 const std::string subAuxName =
326 subFieldName.substr(subFieldName.find(
".") + 1);
329 if (subAuxName.starts_with(
"xAOD::") ||
330 subAuxName.starts_with(
"SG::") ||
331 subAuxName.starts_with(
"ILockable")) {
348 ::Error(
"xAOD::RAuxStore::impl::scanInputNtuple",
349 "Dynamic field with empty name found on container: %s",
363 return StatusCode::SUCCESS;
376 std::string* expectedClassName =
nullptr) {
381 ::TClass* expectedClass = ::TClass::GetClass(
typeName.c_str());
382 if (expectedClassName) {
384 *expectedClassName = expectedClass->GetName();
398 const std::type_info* ti =
nullptr;
401 ti = expectedClass->GetTypeInfo();
406 if (!expectedClass) {
407 ::Warning(
"xAOD::RAuxStore::impl::auxFieldType",
408 "Couldn't get the type of field \"%s\"",
409 field.GetFieldName().c_str());
411 ::TVirtualCollectionProxy* prox = expectedClass->GetCollectionProxy();
416 prox = cl2->GetCollectionProxy();
421 ::Warning(
"xAOD::RAuxStore::impl::auxFieldType",
422 "Couldn't get the type of field \"%s\"",
423 field.GetFieldName().c_str());
425 if (prox->GetValueClass()) {
426 ti = prox->GetValueClass()->GetTypeInfo();
450 std::string_view auxName) {
453 std::string expectedClassName;
457 return StatusCode::SUCCESS;
467 regAuxid != SG::null_auxid) {
469 return StatusCode::SUCCESS;
478 const std::string linkedAttr =
480 const std::string linkedFieldName =
482 const std::type_info* linkedTi =
nullptr;
483 if (::fieldExists(linkedFieldName, *
m_inTuple)) {
489 *linkedTi, linkedAttr,
"",
492 if (linkedAuxId == SG::null_auxid) {
493 ::Error(
"xAOD::RAuxStore::setupAuxField",
494 "Could not find linked variable for %s type %s", auxName.data(),
495 expectedClassName.c_str());
501 registry.getAuxID(*ti, std::string{auxName},
"",
flags, linkedAuxId);
504 if (auxid == SG::null_auxid) {
512 if (
typeName.starts_with(
"std::vector<"))
514 std::string factoryClassName =
516 if (factoryClassName[factoryClassName.size() - 1] ==
'>') {
517 factoryClassName +=
' ';
519 factoryClassName +=
"> >";
522 ::TClass* factoryClass = TClass::GetClass(factoryClassName.c_str());
523 if (factoryClass && factoryClass->IsLoaded()) {
524 ::TClass* baseClass = ::TClass::GetClass(
"SG::IAuxTypeVectorFactory");
525 if (baseClass && baseClass->IsLoaded()) {
526 const Int_t
offset = factoryClass->GetBaseClassOffset(baseClass);
528 void* factoryVoidPointer = factoryClass->New();
529 if (factoryVoidPointer) {
531 reinterpret_cast<unsigned long>(factoryVoidPointer) +
offset;
536 std::unique_ptr<SG::IAuxTypeVectorFactory>(factory));
537 auxid =
registry.getAuxID(*ti, std::string{auxName},
"",
flags,
546 if (auxid == SG::null_auxid && linkedAuxId == SG::null_auxid) {
549 if (vectorClassName[vectorClassName.size() - 1] ==
'>') {
550 vectorClassName +=
' ';
552 vectorClassName +=
'>';
555 ::TClass* vectorClass = ::TClass::GetClass(vectorClassName.c_str());
556 if (vectorClass && vectorClass->IsLoaded()) {
557 auto factory = std::make_unique<TAuxVectorFactory>(vectorClass);
558 if (factory->tiAlloc()) {
559 const std::type_info* tiAlloc = factory->tiAlloc();
560 registry.addFactory(*ti, *tiAlloc, std::move(factory));
562 std::string tiAllocName = factory->tiAllocName();
563 registry.addFactory(*ti, tiAllocName, std::move(factory));
565 auxid =
registry.getAuxID(*ti, std::string{auxName},
"",
568 ::Warning(
"xAOD::RAuxStore::setupAuxField",
569 "Couldn't find dictionary for type: %s",
570 vectorClassName.c_str());
575 if (auxid == SG::null_auxid) {
576 if (linkedAuxId != SG::null_auxid) {
577 ::Error(
"xAOD::RAuxStore::setupAuxField",
578 XAOD_MESSAGE(
"Dynamic ROOT vector factory not implemented for "
579 "linked types; field \"%s\""),
580 field.GetFieldName().c_str());
582 ::Error(
"xAOD::RAuxStore::setupAuxField",
583 XAOD_MESSAGE(
"Couldn't assign auxiliary ID to field \"%s\""),
584 field.GetFieldName().c_str());
586 return StatusCode::FAILURE;
591 return StatusCode::SUCCESS;
609 std::vector<std::unique_ptr<RFieldHandle> >
m_fields;
622 m_impl{std::make_unique<impl>(
m_data)} {
651 m_impl->m_missingFields.clear();
660 return StatusCode::SUCCESS;
688 return StatusCode::SUCCESS;
726 return StatusCode::SUCCESS;
737 return StatusCode::SUCCESS;
750 void* fieldPtr =
const_cast<void*
>(
getIOData(
id));
759 return StatusCode::SUCCESS;
771 m_impl->m_inputScanned =
false;
777 return ((
m_impl->m_fields.size() > auxid) &&
m_impl->m_fields[auxid]);
783 assert(
m_impl->m_fields.size() > auxid);
784 assert(
m_impl->m_fields[auxid]);
787 return StatusCode::SUCCESS;
793 return (
m_impl->m_outTuple !=
nullptr);
806 if ((auxid < m_impl->m_missingFields.size()) &&
807 m_impl->m_missingFields[auxid]) {
808 return StatusCode::RECOVERABLE;
813 if (
m_impl->m_inTuple ==
nullptr) {
814 return StatusCode::RECOVERABLE;
821 if (
m_impl->m_fields.size() <= auxid) {
822 m_impl->m_fields.resize(auxid + 1);
830 return (
m_impl->m_fields[auxid] ? StatusCode::SUCCESS
831 : StatusCode::RECOVERABLE);
838 const std::string statFieldName =
840 const std::string dynFieldName =
845 ROOT::DescriptorId_t fieldId;
846 if ((fieldId =
m_impl->m_inTuple->GetDescriptor().FindFieldId(
848 if ((fieldId =
m_impl->m_inTuple->GetDescriptor().FindFieldId(
851 if (
m_impl->m_missingFields.size() <= auxid) {
852 m_impl->m_missingFields.resize(auxid + 1);
854 m_impl->m_missingFields[auxid] =
true;
857 return StatusCode::RECOVERABLE;
864 const ROOT::RFieldDescriptor& fieldDesc =
865 m_impl->m_inTuple->GetDescriptor().GetFieldDescriptor(fieldId);
870 const bool containerField =
871 (primitiveField ? false : isContainerField(fieldDesc, auxid));
880 if ((containerField &&
882 !
r.isLinked(auxid)) ||
883 ((!containerField) &&
885 ::Error(
"xAOD::RAuxStore::setupInputData",
887 "differ for field: %s"),
889 return StatusCode::FAILURE;
893 const std::type_info* fieldType =
nullptr;
896 fieldType = (containerField ?
r.getVecType(auxid) :
r.getType(auxid));
899 TClass* clDummy = ::TClass::GetClass(fieldDesc.GetTypeName().c_str());
900 fieldType = (clDummy ? clDummy->GetTypeInfo()
904 ::Error(
"xAOD::RAuxStore::setupInputData",
906 fieldDesc.GetTypeName().c_str());
907 return StatusCode::RECOVERABLE;
912 ::TClass* fieldClass =
nullptr;
913 if (!primitiveField) {
915 fieldClass = ::TClass::GetClass(*fieldType,
true,
true);
917 fieldClass = ::TClass::GetClass(fieldTypeName);
920 ::Error(
"xAOD::RAuxStore::setupInputData",
921 XAOD_MESSAGE(
"No dictionary available for class \"%s\""),
922 fieldTypeName.Data());
923 return StatusCode::FAILURE;
929 m_data.
m_vecs[auxid] =
r.makeVector(auxid, (
size_t)0, (
size_t)0);
930 if (!containerField) {
934 strncmp(fieldClass->GetName(),
"SG::PackedContainer<", 20) == 0) {
935 std::unique_ptr<SG::IAuxTypeVector>
packed =
940 ::Error(
"xAOD::RAuxStore::setupInputData",
943 fieldName.c_str(),
static_cast<int>(auxid));
944 return StatusCode::FAILURE;
948 void* objectPtr = (containerField ?
m_data.
m_vecs[auxid]->toVector()
950 m_impl->m_fields[auxid] = std::make_unique<RFieldHandle>(
964 const std::string auxname =
r.getName(auxid);
976 const std::string testname =
r.getName(
i);
978 if (testname != auxname) {
983 ::Error(
"xAOD::RAuxStore::setupInputData",
995 if (linked_auxid != SG::null_auxid) {
1000 return StatusCode::SUCCESS;
1015 if (!
m_impl->m_outTuple) {
1016 return StatusCode::SUCCESS;
1021 return StatusCode::SUCCESS;
1028 if (
m_impl->m_fieldsWritten.size() <= auxid) {
1029 m_impl->m_fieldsWritten.resize(auxid + 1);
1033 if (
m_impl->m_fieldsWritten[auxid]) {
1034 return StatusCode::SUCCESS;
1040 m_impl->m_fieldsWritten[auxid] =
true;
1053 ::Fatal(
"xAOD::RAuxStore::setupOutputData",
1055 return StatusCode::FAILURE;
1062 ::Error(
"xAOD::RAuxStore::setupOutputData",
1065 return StatusCode::FAILURE;
1071 ::Error(
"xAOD::RAuxStore::setupOutputData",
1074 static_cast<int>(auxid));
1075 return StatusCode::FAILURE;
1080 ::Error(
"xAOD::RAuxStore::setupOutputData",
1081 XAOD_MESSAGE(
"No factory found for transient variable "
1083 static_cast<int>(auxid));
1084 return StatusCode::FAILURE;
1102 (!
m_impl->m_fields[auxid])) {
1109 ::Error(
"xAOD::RAuxStore::setupOutputData",
1110 XAOD_MESSAGE(
"Structure mode unknown for variable %s"),
1112 return StatusCode::FAILURE;
1134 auto updater =
m_impl->m_outTuple->CreateModelUpdater();
1135 updater->BeginUpdate();
1136 updater->AddField(std::move(
field));
1137 updater->CommitUpdate();
1144 return StatusCode::SUCCESS;
1150 assert(
m_impl->m_fields.size() > auxid);
1151 assert(
m_impl->m_fields[auxid]);
1152 return m_impl->m_fields[auxid]->objectPtr();
1158 assert(
m_impl->m_fields.size() > auxid);
1159 assert(
m_impl->m_fields[auxid]);
1160 return m_impl->m_fields[auxid]->typeInfo();
const IAuxTypeVectorFactory * getFactory(const std::type_info &ti, const std::type_info &ti_alloc)
Return the vector factory for a given vector element type.
virtual bool hasOutput() const override
Check if an output is being written by the object.
const std::string & prefix() const
Get the currently configured object name prefix.
std::vector< bool > m_fieldsWritten
"Write status" of the different variables
#define RETURN_CHECK(CONTEXT, EXP)
Helper macro for checking return codes in a compact form in the code.
::Long64_t m_entry
The entry to load from the ntuple.
StatusCode setupAuxField(const ROOT::RFieldBase &field, std::string_view auxName)
This function sets up an auxiliary field by determining its type and attempting to register it with t...
TClass * lookupVectorType(TClass &cl)
Internal function used by xAOD::TAuxStore and xAOD::RAuxStore.
std::vector< std::unique_ptr< SG::IAuxTypeVector > > m_vecs
Variables handled currently by the object (indexed by auxiliary ID)
virtual void setPrefix(std::string_view prefix) override
Set the object name prefix.
std::vector< bool > m_missingFields
Mark fields we've found to be missing.
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Make an AuxVectorData object from either a raw vector or an aux store.
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...
ROOT::RFieldBase RFieldBase
std::string getName(SG::auxid_t auxid) const
Return the name of an aux data item.
SG::auxid_set_t m_auxIDs
Internal list of auxiliary variable IDs handled currently by the object.
Exceptions that can be thrown from AthContainers.
EStructMode
"Structural" modes of the object
virtual ~RAuxStore()
Destructor.
virtual const void * getInputObject(SG::auxid_t auxid) const override
Get a pointer to an input object, as it is in memory, for getIOData()
Helper for getting a const version of a pointer.
AthContainers_detail::lock_guard< mutex_t > guard_t
Guard type for multithreaded synchronisation.
std::unique_ptr< SG::AuxStoreInternal > m_transientStore
Store for the in-memory-only variables.
ROOT::RNTupleWriter * m_outTuple
The ntuple being written to.
std::string dynFieldPrefix(const std::string &key)
This function is used to figure out what to name dynamic auxiliary field coming from a container call...
mutex_t m_mutex
Mutex object used for multithreaded synchronisation.
ROOT::Experimental::RNTupleReader RNTupleReader
The RNTuple reader type.
std::size_t m_size
The current size of the container being described.
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
std::vector< std::unique_ptr< RFieldHandle > > m_fields
Fields containing the various auxiliary variables.
bool isRegisteredType(SG::auxid_t auxid)
Check if the auxiliary variable has a registered type.
static std::string linkedName(const std::string &name)
Given a variable name, return the name of the corresponding linked variable.
bool isPrimitiveType(std::string_view typeName)
Check if the type name describes a primitive type.
virtual StatusCode getEntryFor(SG::auxid_t auxid) override
Load a single variable from the input.
StatusCode getEntry(std::int64_t entry, int getall=0)
Get entry from the input RNTuple.
static bool classNameHasLink(const std::string &className)
Test to see if a class name corresponds to a class with a linked variable.
Members & m_data
Variables coming from AuxStoreBase.
@ kObjectStore
The object describes a single object.
virtual StatusCode setupOutputData(SG::auxid_t auxid) override
Connect a variable to the output.
@ kContainerStore
The object describes an entire container.
StatusCode scanInputTuple()
Scans the input ntuple for auxiliary data fields and sets up the necessary structures to access them.
StatusCode commitTo(REntry &entry)
Commit a new entry to the output RNTuple.
SG::auxid_set_t m_decorIDs
Internal list of auxiliary decoration IDs handled currently by the object.
Handle mappings between names and auxid_t.
@ Linked
Mark that this variable is linked to another one.
ROOT::RNTupleReader * m_inTuple
The ntuple being read from.
size_t auxid_t
Identifier for a particular aux data item.
const std::type_info * getType(SG::auxid_t auxid) const
Return the type of an aux data item.
H5::CompType packed(H5::CompType in)
Members m_data
Member variables of the base class.
virtual bool hasEntryFor(SG::auxid_t auxid) const override
Check if a given variable is available from the input.
AthContainers_detail::mutex mutex_t
Mutex type for multithread synchronization.
std::string getTypeName(const std::type_info &ti)
This function is necessary in order to create type names that ROOT can understand.
StatusCode writeTo(RNTupleWriter &writer)
Add the variables of the store to an output RNTuple.
ConcurrentBitset & insert(bit_t bit, bit_t new_nbits=0)
Set a bit to 1.
::StatusCode StatusCode
StatusCode definition for legacy code.
Interface for factory objects that create vectors.
virtual const std::type_info * tiAlloc() const =0
Return the type_info of the vector allocator.
std::string m_prefix
Static prefix for the branch names.
ROOT::Experimental::RNTupleWriter RNTupleWriter
static bool isLinkedName(const std::string &name)
Test if a variable name corresponds to a linked variable.
virtual void copy(SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, const AuxVectorData &src, size_t src_index, size_t n) const =0
Copy elements between vectors.
const std::type_info * getVecType(SG::auxid_t auxid) const
Return the type of the STL vector used to hold an aux data item.
virtual const std::type_info * getInputType(SG::auxid_t auxid) const override
Get the type of an input object, for getIOType()
AuxVarFlags
Additional flags to qualify an auxiliary variable.
virtual SG::auxid_set_t getSelectedAuxIDs() const override
Get the IDs of the selected aux variables.
bool isAuxIDSelected(SG::auxid_t auxid) const
Check if an auxiliary variable is selected for ouput writing.
std::unique_ptr< IAuxTypeVector > makeVector(SG::auxid_t auxid, size_t size, size_t capacity) const
Construct a new vector to hold an aux item.
EStructMode m_structMode
The "structural" mode of the object.
virtual StatusCode setupInputData(SG::auxid_t auxid) override
Connect a variable to the input.
const std::type_info * auxFieldType(const ROOT::RFieldBase &field, std::string *expectedClassName=nullptr)
This function retrieves the type information for a given auxiliary field.
const std::type_info & getTypeInfo(EDataType type)
This function is used when reading a primitive branch from an input file without the user explicitly ...
Make an AuxVectorData object from either a raw array or an aux store.
ROOT::Experimental::RNTupleModel RNTupleModel
StatusCode readFrom(RNTupleReader &reader)
Connect the object to an input RNTuple.
constexpr std::enable_if_t< is_bitmask_v< E >, E & > reset(E &lhs, E rhs)
Convenience function to clear bits in a class enum bitmask.
Handle mappings between names and auxid_t.
ROOT::Experimental::RNTupleReader RNTupleReader
ROOT::Experimental::REntry REntry
virtual const void * getIOData(SG::auxid_t auxid) const override
Get a pointer to the data being stored for one aux data item.
virtual void reset() override
Tell the object that all branches will need to be re-read.
RAuxStore(std::string_view prefix="", bool topStore=true, EStructMode mode=EStructMode::kUndefinedStore)
Constructor.
@ kUndefinedStore
The structure mode is not defined.
A set of aux data identifiers.
Error
The different types of error that can be flagged in the L1TopoRDO.
std::unique_ptr< impl > m_impl
Pointer to the internal object.
reader
read the goodrunslist xml file(s)
ConcurrentBitset & erase(bit_t bit)
Turn off one bit.
std::vector< bool > m_isDecoration
Per variable lock status (indexed by auxiliary ID)
writer
show summary of content
An auxiliary data store that holds data internally.
std::string m_dynPrefix
Dynamic prefix for the branch names.
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
bool m_topStore
Flag stating whether this is a "top store".
Selection rules: declare transient members.
bool m_inputScanned
"Scan status" of the input RNTuple
Struct collecting all member variables of this base class.
bool test(bit_t bit) const
Test to see if a bit is set.