40bool isContainerField(
const ROOT::RFieldDescriptor& fieldDesc,
55 TClass*
cl = TClass::GetClass(fieldDesc.GetTypeName().c_str());
61 ::Warning(
"::isPContainerField",
62 XAOD_MESSAGE(
"Couldn't get a dictionary for type \"%s\""),
63 fieldDesc.GetTypeName().c_str());
68 const std::type_info* root_ti =
cl->GetTypeInfo();
76 typeName.ReplaceAll(
"basic_string<char>",
"string");
77 ::TClass* newCl = ::TClass::GetClass(typeName);
79 root_ti = newCl->GetTypeInfo();
83 ::Error(
"::isContainerField",
84 XAOD_MESSAGE(
"Couldn't get an std::type_info object out of "
91 const std::type_info* aux_obj_ti =
94 ::Error(
"::isContainerField",
97 static_cast<int>(auxid));
100 const std::type_info* aux_vec_ti =
103 ::Error(
"::isContainerField",
106 static_cast<int>(auxid));
111 if (*root_ti == *aux_obj_ti) {
114 }
else if (*root_ti == *aux_vec_ti) {
122 if (
cl->GetCollectionProxy() && (*aux_vec_ti ==
typeid(std::vector<int>))) {
128 if (*cl2->GetTypeInfo() == *aux_vec_ti) {
144 aux_vec_cl->GetConversionStreamerInfo(cl,
cl->GetClassVersion())) {
150 aux_obj_cl->GetConversionStreamerInfo(cl,
cl->GetClassVersion())) {
155 ::Error(
"::isContainerField",
156 XAOD_MESSAGE(
"Couldn't determine if field describes a single "
157 "object or a container"));
158 ::Error(
"::isContainerField",
XAOD_MESSAGE(
"ROOT type : %s"),
160 ::Error(
"::isContainerField",
XAOD_MESSAGE(
"Object type: %s"),
162 ::Error(
"::isContainerField",
XAOD_MESSAGE(
"Vector type: %s"),
172 RFieldHandle(ROOT::RNTupleView<void> field,
SG::auxid_t auxid,
173 std::string_view prefix,
void*
object,
const std::type_info* ti)
174 : m_field(std::move(
field)),
184 if ((m_entry == entry) && (!m_needsRead)) {
185 return StatusCode::SUCCESS;
191 }
catch (
const ROOT::RException& e) {
192 ::Error(
"::RFieldInfo::getEntry",
193 "Failed to load entry %lld for field %s.%s: %s", entry,
197 return StatusCode::FAILURE;
203 return StatusCode::SUCCESS;
212 void* objectPtr() {
return m_object; }
215 const std::type_info* typeInfo()
const {
return m_typeInfo; }
218 void reset() { m_needsRead =
true; }
222 ROOT::RNTupleView<void> m_field;
226 std::string_view m_prefix;
228 void* m_object =
nullptr;
230 const std::type_info* m_typeInfo =
nullptr;
232 ::Long64_t m_entry = -1;
234 bool m_needsRead =
true;
238bool fieldExists(std::string_view fieldName,
239 ROOT::RNTupleReader& ntupleReader) {
242 return (ntupleReader.GetDescriptor().FindFieldId(fieldName) !=
243 std::numeric_limits<unsigned long>::max());
264 return StatusCode::SUCCESS;
269 return StatusCode::SUCCESS;
273 for (
const ROOT::RFieldBase* field :
274#
if ROOT_VERSION_CODE >= ROOT_VERSION(6, 35, 0)
275 m_inTuple->GetModel().GetConstFieldZero().GetConstSubfields()
277 m_inTuple->GetModel().GetConstFieldZero().GetSubFields()
282 const std::string fieldName = field->GetQualifiedFieldName();
285 if (
m_data.m_topStore && (fieldName ==
m_data.m_prefix)) {
288 for (
const ROOT::RFieldBase* subField :
289#
if ROOT_VERSION_CODE >= ROOT_VERSION(6, 35, 0)
290 field->GetConstSubfields()
292 field->GetSubFields()
297 const std::string& typeName = subField->GetTypeName();
300 if (typeName.starts_with(
"xAOD::") ||
301 typeName.starts_with(
"SG::") ||
302 typeName.starts_with(
"DMTest::") ||
303 typeName.starts_with(
"ILockable")) {
316 if (fieldName.starts_with(
m_data.m_dynPrefix) ==
false) {
319 if (fieldName ==
m_data.m_dynPrefix) {
320 ::Error(
"xAOD::RAuxStore::impl::scanInputNtuple",
321 "Dynamic field with empty name found on container: %s",
326 std::string_view auxName = fieldName;
327 std::string::size_type spos = auxName.find(
':');
328 if (spos != std::string::npos) {
329 auxName = auxName.substr(spos + 1);
339 return StatusCode::SUCCESS;
352 std::string* expectedClassName =
nullptr) {
356 const std::string typeName = field.GetTypeName();
357 ::TClass* expectedClass = ::TClass::GetClass(typeName.c_str());
358 if (expectedClassName) {
360 *expectedClassName = expectedClass->GetName();
362 *expectedClassName = typeName;
374 const std::type_info* ti =
nullptr;
377 ti = expectedClass->GetTypeInfo();
382 if (!expectedClass) {
383 ::Warning(
"xAOD::RAuxStore::impl::auxFieldType",
384 "Couldn't get the type of field \"%s\"",
385 field.GetFieldName().c_str());
387 ::TVirtualCollectionProxy* prox = expectedClass->GetCollectionProxy();
392 prox = cl2->GetCollectionProxy();
397 ::Warning(
"xAOD::RAuxStore::impl::auxFieldType",
398 "Couldn't get the type of field \"%s\"",
399 field.GetFieldName().c_str());
401 if (prox->GetValueClass()) {
402 ti = prox->GetValueClass()->GetTypeInfo();
426 std::string_view auxName) {
429 std::string expectedClassName;
430 const std::type_info* ti =
auxFieldType(field, &expectedClassName);
433 return StatusCode::SUCCESS;
442 const std::string auxNameStr{auxName};
445 m_data.m_auxIDs.insert(regAuxid);
446 return StatusCode::SUCCESS;
453 flags |= SG::AuxVarFlags::Linked;
455 const std::string linkedAttr =
457 const std::string linkedFieldName =
459 const std::type_info* linkedTi =
nullptr;
460 if (::fieldExists(linkedFieldName, *
m_inTuple)) {
466 *linkedTi, linkedAttr,
"",
467 SG::AuxVarFlags::SkipNameCheck | SG::AuxVarFlags::Linked);
470 ::Error(
"xAOD::RAuxStore::setupAuxField",
471 "Could not find linked variable for %s type %s", auxName.data(),
472 expectedClassName.c_str());
478 registry.
getAuxID(*ti, auxNameStr,
"", flags, linkedAuxId);
489 if (typeName.starts_with(
"std::vector<"))
490 typeName.erase(0, 5);
491 std::string factoryClassName =
492 "SG::AuxTypeVectorFactory<" + typeName +
",allocator<" + typeName;
493 if (factoryClassName[factoryClassName.size() - 1] ==
'>') {
494 factoryClassName +=
' ';
496 factoryClassName +=
"> >";
499 ::TClass* factoryClass = TClass::GetClass(factoryClassName.c_str());
500 if (factoryClass && factoryClass->IsLoaded()) {
501 ::TClass* baseClass = ::TClass::GetClass(
"SG::IAuxTypeVectorFactory");
502 if (baseClass && baseClass->IsLoaded()) {
503 const Int_t offset = factoryClass->GetBaseClassOffset(baseClass);
505 void* factoryVoidPointer = factoryClass->New();
506 if (factoryVoidPointer) {
508 reinterpret_cast<unsigned long>(factoryVoidPointer) + offset;
513 std::unique_ptr<SG::IAuxTypeVectorFactory>(factory));
514 auxid = registry.
getAuxID(*ti, auxNameStr,
"", flags,
526 if (vectorClassName[vectorClassName.size() - 1] ==
'>') {
527 vectorClassName +=
' ';
529 vectorClassName +=
'>';
532 ::TClass* vectorClass = ::TClass::GetClass(vectorClassName.c_str());
533 if (vectorClass && vectorClass->IsLoaded()) {
534 auto factory = std::make_unique<TAuxVectorFactory>(vectorClass);
535 if (factory->tiAlloc()) {
536 const std::type_info* tiAlloc = factory->tiAlloc();
537 registry.
addFactory(*ti, *tiAlloc, std::move(factory));
539 std::string tiAllocName = factory->tiAllocName();
540 registry.
addFactory(*ti, tiAllocName, std::move(factory));
542 auxid = registry.
getAuxID(*ti, auxNameStr,
"",
543 SG::AuxVarFlags::SkipNameCheck);
545 ::Warning(
"xAOD::RAuxStore::setupAuxField",
546 "Couldn't find dictionary for type: %s",
547 vectorClassName.c_str());
554 ::Error(
"xAOD::RAuxStore::setupAuxField",
555 XAOD_MESSAGE(
"Dynamic ROOT vector factory not implemented for "
556 "linked types; field \"%s\""),
557 field.GetFieldName().c_str());
559 ::Error(
"xAOD::RAuxStore::setupAuxField",
560 XAOD_MESSAGE(
"Couldn't assign auxiliary ID to field \"%s\""),
561 field.GetFieldName().c_str());
563 return StatusCode::FAILURE;
567 m_data.m_auxIDs.insert(auxid);
568 return StatusCode::SUCCESS;
593 std::vector<std::unique_ptr<RFieldHandle> >
m_fields;
636 m_impl->m_missingFields.clear();
639 m_impl->m_inTuple = &reader;
645 return StatusCode::SUCCESS;
673 return StatusCode::SUCCESS;
690 if (
m_data.m_transientStore && (getall != 99)) {
692 m_data.m_auxIDs -=
m_data.m_transientStore->getAuxIDs();
693 m_data.m_decorIDs -=
m_data.m_transientStore->getDecorIDs();
695 m_data.m_transientStore.reset();
701 if (!
m_data.m_isDecoration[auxid]) {
704 m_data.m_auxIDs.erase(auxid);
705 m_data.m_decorIDs.erase(auxid);
711 return StatusCode::SUCCESS;
717 RETURN_CHECK(
"xAOD::RAuxStore::getEntry", field->getEntry(entry));
718#ifndef XAOD_STANDALONE
726 return StatusCode::SUCCESS;
736 const std::string fieldName =
737 std::format(
"{}{}",
m_data.m_dynPrefix,
739 void* fieldPtr =
const_cast<void*
>(
getIOData(
id));
741 entry.BindRawPtr(fieldName, fieldPtr);
743 entry.EmplaceNewValue(fieldName);
748 return StatusCode::SUCCESS;
755 for (
auto& field :
m_impl->m_fields) {
760 m_impl->m_inputScanned =
false;
766 return ((
m_impl->m_fields.size() > auxid) &&
m_impl->m_fields[auxid]);
775 assert(
m_impl->m_fields.size() > auxid);
776 assert(
m_impl->m_fields[auxid]);
779#ifndef XAOD_STANDALONE
782 return StatusCode::SUCCESS;
788 return (
m_impl->m_outTuple !=
nullptr);
801 if ((auxid < m_impl->m_missingFields.size()) &&
802 m_impl->m_missingFields[auxid]) {
803 return StatusCode::RECOVERABLE;
808 if (
m_impl->m_inTuple ==
nullptr) {
809 return StatusCode::RECOVERABLE;
813 if (
m_data.m_vecs.size() <= auxid) {
814 m_data.m_vecs.resize(auxid + 1);
816 if (
m_impl->m_fields.size() <= auxid) {
817 m_impl->m_fields.resize(auxid + 1);
824 if (
m_data.m_vecs[auxid]) {
825 return (
m_impl->m_fields[auxid] ? StatusCode::SUCCESS
826 : StatusCode::RECOVERABLE);
833 const std::string statFieldName =
834 std::format(
"{}{}",
m_data.m_prefix,
r.getName(auxid));
835 const std::string dynFieldName =
836 std::format(
"{}{}",
m_data.m_dynPrefix,
r.getName(auxid));
839 std::string fieldName = statFieldName;
840 ROOT::DescriptorId_t fieldId;
841 if ((fieldId =
m_impl->m_inTuple->GetDescriptor().FindFieldId(
842 statFieldName)) == std::numeric_limits<unsigned long>::max()) {
843 if ((fieldId =
m_impl->m_inTuple->GetDescriptor().FindFieldId(
844 dynFieldName)) == std::numeric_limits<unsigned long>::max()) {
846 if (
m_impl->m_missingFields.size() <= auxid) {
847 m_impl->m_missingFields.resize(auxid + 1);
849 m_impl->m_missingFields[auxid] =
true;
852 return StatusCode::RECOVERABLE;
855 fieldName = std::move(dynFieldName);
859 const ROOT::RFieldDescriptor& fieldDesc =
860 m_impl->m_inTuple->GetDescriptor().GetFieldDescriptor(fieldId);
865 const bool containerField =
866 (primitiveField ? false : isContainerField(fieldDesc, auxid));
875 if ((containerField &&
877 !
r.isLinked(auxid)) ||
878 ((!containerField) &&
880 ::Error(
"xAOD::RAuxStore::setupInputData",
882 "differ for field: %s"),
884 return StatusCode::FAILURE;
888 const std::type_info* fieldType =
nullptr;
891 fieldType = (containerField ?
r.getVecType(auxid) :
r.getType(auxid));
894 TClass* clDummy = ::TClass::GetClass(fieldDesc.GetTypeName().c_str());
895 fieldType = (clDummy ? clDummy->GetTypeInfo()
899 ::Error(
"xAOD::RAuxStore::setupInputData",
900 XAOD_MESSAGE(
"Can't read/copy variable %s (%s)"), fieldName.c_str(),
901 fieldDesc.GetTypeName().c_str());
902 return StatusCode::RECOVERABLE;
907 ::TClass* fieldClass =
nullptr;
908 if (!primitiveField) {
910 fieldClass = ::TClass::GetClass(*fieldType,
true,
true);
912 fieldClass = ::TClass::GetClass(fieldTypeName);
915 ::Error(
"xAOD::RAuxStore::setupInputData",
916 XAOD_MESSAGE(
"No dictionary available for class \"%s\""),
917 fieldTypeName.Data());
918 return StatusCode::FAILURE;
924 m_data.m_vecs[auxid] =
r.makeVector(auxid, (
size_t)0, (
size_t)0);
925 if (!containerField) {
926 m_data.m_vecs[auxid]->resize(1);
929 strncmp(fieldClass->GetName(),
"SG::PackedContainer<", 20) == 0) {
930 std::unique_ptr<SG::IAuxTypeVector> packed =
931 m_data.m_vecs[auxid]->toPacked();
935 ::Error(
"xAOD::RAuxStore::setupInputData",
938 fieldName.c_str(),
static_cast<int>(auxid));
939 return StatusCode::FAILURE;
943 void* objectPtr = (containerField ?
m_data.m_vecs[auxid]->toVector()
944 :
m_data.m_vecs[auxid]->toPtr());
945 m_impl->m_fields[auxid] = std::make_unique<RFieldHandle>(
946 m_impl->m_inTuple->GetView<
void>(fieldName.c_str(), objectPtr), auxid,
947 m_data.m_prefix, objectPtr, fieldType);
952#ifndef XAOD_STANDALONE
957 m_data.m_auxIDs.insert(auxid);
962 const std::string auxname =
r.getName(auxid);
974 const std::string testname =
r.getName(i);
976 if (testname != auxname) {
981 ::Error(
"xAOD::RAuxStore::setupInputData",
987 m_impl->m_fields[i].reset();
998 return StatusCode::SUCCESS;
1013 if (!
m_impl->m_outTuple) {
1014 return StatusCode::SUCCESS;
1019 return StatusCode::SUCCESS;
1023 if (
m_data.m_vecs.size() <= auxid) {
1024 m_data.m_vecs.resize(auxid + 1);
1026 if (
m_impl->m_fieldsWritten.size() <= auxid) {
1027 m_impl->m_fieldsWritten.resize(auxid + 1);
1031 if (
m_impl->m_fieldsWritten[auxid]) {
1032 return StatusCode::SUCCESS;
1038 m_impl->m_fieldsWritten[auxid] =
true;
1045 if ((!
m_data.m_vecs[auxid]) &&
m_data.m_transientStore &&
1046 (
m_data.m_transientStore->getAuxIDs().test(auxid))) {
1049 const void* pptr =
m_data.m_transientStore->getData(auxid);
1051 ::Fatal(
"xAOD::RAuxStore::setupOutputData",
1053 return StatusCode::FAILURE;
1058 void* ptr =
m_data.m_vecs[auxid]->toPtr();
1060 ::Error(
"xAOD::RAuxStore::setupOutputData",
1063 return StatusCode::FAILURE;
1067 const std::type_info*
type = reg.getType(auxid);
1069 ::Error(
"xAOD::RAuxStore::setupOutputData",
1072 static_cast<int>(auxid));
1073 return StatusCode::FAILURE;
1078 ::Error(
"xAOD::RAuxStore::setupOutputData",
1079 XAOD_MESSAGE(
"No factory found for transient variable "
1081 static_cast<int>(auxid));
1082 return StatusCode::FAILURE;
1086 if (
m_data.m_isDecoration.size() <= auxid) {
1087 m_data.m_isDecoration.resize(auxid + 1);
1089 m_data.m_isDecoration[auxid] =
true;
1099 if ((
m_data.m_auxIDs.test(auxid)) && (!
m_data.m_vecs[auxid]) &&
1100 (!
m_impl->m_fields[auxid])) {
1107 ::Error(
"xAOD::RAuxStore::setupOutputData",
1108 XAOD_MESSAGE(
"Structure mode unknown for variable %s"),
1109 reg.getName(auxid).c_str());
1110 return StatusCode::FAILURE;
1114 if (!
m_data.m_vecs[auxid]) {
1115 m_data.m_vecs[auxid] = reg.makeVector(auxid, (
size_t)0, (
size_t)0);
1117 m_data.m_vecs[auxid]->resize(1);
1122 const std::string fieldName =
1123 std::format(
"{}{}",
m_data.m_dynPrefix, reg.getName(auxid));
1126 ? reg.getVecType(auxid)
1127 : reg.getType(auxid)));
1131 auto field = ROOT::RFieldBase::Create(fieldName, typeName).Unwrap();
1132 auto updater =
m_impl->m_outTuple->CreateModelUpdater();
1133 updater->BeginUpdate();
1134 updater->AddField(std::move(field));
1135 updater->CommitUpdate();
1139 m_data.m_auxIDs.insert(auxid);
1142 return StatusCode::SUCCESS;
1148 assert(
m_impl->m_fields.size() > auxid);
1149 assert(
m_impl->m_fields[auxid]);
1150 return m_impl->m_fields[auxid]->objectPtr();
1156 assert(
m_impl->m_fields.size() > auxid);
1157 assert(
m_impl->m_fields[auxid]);
1158 return m_impl->m_fields[auxid]->typeInfo();
An auxiliary data store that holds data internally.
Handle mappings between names and auxid_t.
Make an AuxVectorData object from either a raw vector or an aux store.
std::shared_ptr< HepMC3::Writer > writer
#define RETURN_CHECK(CONTEXT, EXP)
Helper macro for checking return codes in a compact form in the code.
Handle mappings between names and auxid_t.
const std::type_info * getType(SG::auxid_t auxid) const
Return the type of an aux data item.
SG::auxid_t getAuxID(const std::string &name, const std::string &clsname="", const Flags flags=Flags::None, const SG::auxid_t linkedVariable=SG::null_auxid)
Look up a name -> auxid_t mapping.
SG::auxid_t findAuxID(const std::string &name, const std::string &clsname="") const
Look up a name -> auxid_t mapping.
static bool isLinkedName(const std::string &name)
Test if a variable name corresponds to a linked variable.
std::string getName(SG::auxid_t auxid) const
Return the name of an aux data item.
static std::string linkedName(const std::string &name)
Given a variable name, return the name of the corresponding linked variable.
const std::type_info * getVecType(SG::auxid_t auxid) const
Return the type of the STL vector used to hold an aux data item.
static bool classNameHasLink(const std::string &className)
Test to see if a class name corresponds to a class with a linked variable.
static AuxTypeRegistry & instance()
Return the singleton registry instance.
const IAuxTypeVectorFactory * addFactory(const std::type_info &ti, const std::type_info &ti_alloc, std::unique_ptr< const IAuxTypeVectorFactory > factory)
Add a new type -> factory mapping.
Make an AuxVectorData object from either a raw array or an aux store.
Interface for factory objects that create vectors.
virtual const std::type_info * tiAlloc() const =0
Return the type_info of the vector allocator.
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.
A set of aux data identifiers.
StatusCode readFrom(ROOT::RNTupleReader &reader)
Connect the object to an input RNTuple.
virtual const std::type_info * getInputType(SG::auxid_t auxid) const override
Get the type of an input object, for getIOType().
StatusCode writeTo(ROOT::RNTupleWriter &writer)
Add the variables of the store to an output RNTuple.
StatusCode getEntry(std::int64_t entry, int getall=0)
Get entry from the input RNTuple.
virtual StatusCode setupInputData(SG::auxid_t auxid) override
Connect a variable to the input.
virtual StatusCode getEntryFor(SG::auxid_t auxid) override
Load a single variable from the input.
std::unique_ptr< impl > m_impl
Pointer to the internal object.
virtual const void * getInputObject(SG::auxid_t auxid) const override
Get a pointer to an input object, as it is in memory, for getIOData().
virtual bool hasEntryFor(SG::auxid_t auxid) const override
Check if a given variable is available from the input.
virtual void setPrefix(std::string_view prefix) override
Set the object name prefix.
RAuxStore(const EventContext &ctx, std::string_view prefix="", bool topStore=true, EStructMode mode=EStructMode::kUndefinedStore)
Constructor.
StatusCode commitTo(ROOT::REntry &entry)
Commit a new entry to the output RNTuple.
virtual StatusCode setupOutputData(SG::auxid_t auxid) override
Connect a variable to the output.
virtual bool hasOutput() const override
Check if an output is being written by the object.
virtual ~RAuxStore()
Destructor.
virtual void reset() override
Tell the object that all branches will need to be re-read.
virtual const void * getIOData(SG::auxid_t auxid) const override
Get a pointer to the data being stored for one aux data item.
const std::string & prefix() const
Get the currently configured object name prefix.
bool isAuxIDSelected(SG::auxid_t auxid) const
Check if an auxiliary variable is selected for ouput writing.
virtual SG::auxid_set_t getSelectedAuxIDs() const override
Get the IDs of the selected aux variables.
AthContainers_detail::mutex mutex_t
Mutex type for multithread synchronization.
EStructMode
"Structural" modes of the object
@ kUndefinedStore
The structure mode is not defined.
@ kObjectStore
The object describes a single object.
@ kContainerStore
The object describes an entire container.
AuxStoreBase(bool topStore=true, EStructMode mode=EStructMode::kUndefinedStore)
Constructor.
Members m_data
Member variables of the base class.
AthContainers_detail::lock_guard< mutex_t > guard_t
Guard type for multithreaded synchronisation.
::StatusCode StatusCode
StatusCode definition for legacy code.
AuxVarFlags
Additional flags to qualify an auxiliary variable.
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...
static const auxid_t null_auxid
To signal no aux data item.
SG::auxid_t auxid() const
Return the aux id for this variable.
virtual void reset() override
Free all allocated elements.
size_t auxid_t
Identifier for a particular aux data item.
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)
const std::type_info & getTypeInfo(EDataType type)
This function is used when reading a primitive branch from an input file without the user explicitly ...
bool isPrimitiveType(std::string_view typeName)
Check if the type name describes a primitive type.
std::string getTypeName(const std::type_info &ti)
This function is necessary in order to create type names that ROOT can understand.
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...
TClass * lookupVectorType(TClass &cl)
Internal function used by xAOD::TAuxStore and xAOD::RAuxStore.
bool isRegisteredType(SG::auxid_t auxid)
Check if the auxiliary variable has a registered type.
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
bool m_inputScanned
"Scan status" of the input RNTuple
std::vector< bool > m_fieldsWritten
"Write status" of the different variables
::Long64_t m_entry
The entry to load from the ntuple.
std::vector< bool > m_missingFields
Mark fields we've found to be missing.
const EventContext & m_ctx
The context for this event.
Members & m_data
Variables coming from AuxStoreBase.
ROOT::RNTupleWriter * m_outTuple
The ntuple being written to.
impl(const EventContext &ctx, Members &data)
std::vector< std::unique_ptr< RFieldHandle > > m_fields
Fields containing the various auxiliary variables.
StatusCode scanInputTuple()
Scans the input ntuple for auxiliary data fields and sets up the necessary structures to access them.
ROOT::RNTupleReader * m_inTuple
The ntuple being read from.
const std::type_info * auxFieldType(const ROOT::RFieldBase &field, std::string *expectedClassName=nullptr)
This function retrieves the type information for a given auxiliary field.
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...
mutex_t m_mutex
Mutex object used for multithreaded synchronisation.
Struct collecting all member variables of this base class.