ATLAS Offline Software
Public Member Functions | Public Attributes | List of all members
xAOD::RAuxStore::impl Struct Reference
Collaboration diagram for xAOD::RAuxStore::impl:

Public Member Functions

StatusCode scanInputTuple ()
 Scans the input ntuple for auxiliary data fields and sets up the necessary structures to access them. More...
 
const std::type_info * auxFieldType (const ROOT::RFieldBase &field, std::string *expectedClassName=nullptr)
 This function retrieves the type information for a given auxiliary field. More...
 
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 the auxiliary type registry. More...
 

Public Attributes

Membersm_data
 Variables coming from AuxStoreBase. More...
 
ROOT::RNTupleReader * m_inTuple = nullptr
 The ntuple being read from. More...
 
ROOT::RNTupleWriter * m_outTuple = nullptr
 The ntuple being written to. More...
 
bool m_inputScanned = false
 "Scan status" of the input RNTuple More...
 
::Long64_t m_entry
 The entry to load from the ntuple. More...
 
std::vector< std::unique_ptr< RFieldHandle > > m_fields
 Fields containing the various auxiliary variables. More...
 
std::vector< boolm_fieldsWritten
 "Write status" of the different variables More...
 
std::vector< boolm_missingFields
 Mark fields we've found to be missing. More...
 
mutex_t m_mutex
 Mutex object used for multithreaded synchronisation. More...
 

Detailed Description

Definition at line 249 of file RAuxStore.cxx.

Member Function Documentation

◆ auxFieldType()

const std::type_info* xAOD::RAuxStore::impl::auxFieldType ( const ROOT::RFieldBase &  field,
std::string *  expectedClassName = nullptr 
)
inline

This function retrieves the type information for a given auxiliary field.

It uses the field's inspector to determine the type and handles cases where the expected class or collection proxy is not available.

Parameters
fieldThe field to get the type of
expectedClassNameThe (optional) name of the expected (on disk) class
Returns
A pointer to the type information for the field

Definition at line 347 of file RAuxStore.cxx.

348  {
349 
350  // Get the type name of the field. Not worrying about automatic schema
351  // evolution for now.
352  const std::string typeName = field.GetTypeName();
353  ::TClass* expectedClass = ::TClass::GetClass(typeName.c_str());
354  if (expectedClassName) {
355  if (expectedClass) {
356  *expectedClassName = expectedClass->GetName();
357  } else {
358  *expectedClassName = typeName;
359  }
360  }
361 
362  // If this is a primitive variable, and we're still not sure whether this
363  // is a store for an object or a container, the answer is given...
367  }
368 
369  // Get the type_info of the branch.
370  const std::type_info* ti = nullptr;
372  if (expectedClass) {
373  ti = expectedClass->GetTypeInfo();
374  } else {
375  ti = &(Utils::getTypeInfo(typeName));
376  }
377  } else {
378  if (!expectedClass) {
379  ::Warning("xAOD::RAuxStore::impl::auxFieldType",
380  "Couldn't get the type of field \"%s\"",
381  field.GetFieldName().c_str());
382  } else {
383  ::TVirtualCollectionProxy* prox = expectedClass->GetCollectionProxy();
384 
385  if (!prox) {
386  TClass* cl2 = details::lookupVectorType(*expectedClass);
387  if (cl2) {
388  prox = cl2->GetCollectionProxy();
389  }
390  }
391 
392  if (!prox) {
393  ::Warning("xAOD::RAuxStore::impl::auxFieldType",
394  "Couldn't get the type of field \"%s\"",
395  field.GetFieldName().c_str());
396  } else {
397  if (prox->GetValueClass()) {
398  ti = prox->GetValueClass()->GetTypeInfo();
399  } else {
400  ti = &(Utils::getTypeInfo(prox->GetType()));
401  }
402  }
403  }
404  }
405 
406  return ti;
407  }

◆ scanInputTuple()

StatusCode xAOD::RAuxStore::impl::scanInputTuple ( )
inline

Scans the input ntuple for auxiliary data fields and sets up the necessary structures to access them.

It ensures that the input ntuple is properly scanned and the auxiliary data fields are set up.

Returns
StatusCode::SUCCESS if the function was successful, something else otherwise

Definition at line 258 of file RAuxStore.cxx.

258  {
259 
260  // Check if an input ntuple is even available.
261  if (!m_inTuple) {
262  // It's not an error if it isn't.
263  return StatusCode::SUCCESS;
264  }
265 
266  // Check if the input was already scanned.
267  if (m_inputScanned) {
268  return StatusCode::SUCCESS;
269  }
270 
271  // Iterate over all fields of the input ntuple.
272  for (const ROOT::RFieldBase* field :
273 #if ROOT_VERSION_CODE >= ROOT_VERSION(6, 35, 0)
274  m_inTuple->GetModel().GetConstFieldZero().GetConstSubfields()
275 #else
276  m_inTuple->GetModel().GetConstFieldZero().GetSubFields()
277 #endif // ROOT_VERSION_CODE >= ROOT_VERSION(6, 35, 0)
278  ) {
279 
280  // Get the name of the current field.
281  const std::string fieldName = field->GetQualifiedFieldName();
282 
283  // Look for static fields.
284  if (m_data.m_topStore && (fieldName == m_data.m_prefix)) {
285 
286  // Loop over the sub-fields of this field.
287  for (const ROOT::RFieldBase* subField :
288 #if ROOT_VERSION_CODE >= ROOT_VERSION(6, 35, 0)
289  field->GetConstSubfields()
290 #else
291  field->GetSubFields()
292 #endif // ROOT_VERSION_CODE >= ROOT_VERSION(6, 35, 0)
293  ) {
294 
295  // Get the name of this sub-field.
296  const std::string subFieldName = subField->GetQualifiedFieldName();
297  const std::string subAuxName =
298  subFieldName.substr(subFieldName.find(".") + 1);
299 
300  // Skip this entry if it refers to a base class.
301  if (subAuxName.starts_with("xAOD::") ||
302  subAuxName.starts_with("SG::") ||
303  subAuxName.starts_with("ILockable")) {
304  continue;
305  }
306 
307  // Set up this field.
308  RETURN_CHECK("xAOD::RAuxStore::impl::scanInputNtuple",
309  setupAuxField(*subField, subAuxName));
310  }
311  // Don't check the rest of the loop's body:
312  continue;
313  }
314 
315  // if fieldname doesnt start with the value of m_dynPrefix, skip
316  if (fieldName.starts_with(m_data.m_dynPrefix) == false) {
317  continue;
318  }
319  if (fieldName == m_data.m_dynPrefix) {
320  ::Error("xAOD::RAuxStore::impl::scanInputNtuple",
321  "Dynamic field with empty name found on container: %s",
322  m_data.m_prefix.c_str());
323  continue;
324  }
325  // The auxiliary property name:
326  const std::string auxName = fieldName.substr(fieldName.find(":") + 1);
327  // Leave the rest up to the function that is shared with the
328  // dynamic fields:
329  RETURN_CHECK("xAOD::RAuxStore::scanInputNtuple",
330  setupAuxField(*field, auxName));
331  }
332 
333  // the input was successfully scanned:
334  m_inputScanned = true;
335  return StatusCode::SUCCESS;
336  }

◆ setupAuxField()

StatusCode xAOD::RAuxStore::impl::setupAuxField ( const ROOT::RFieldBase &  field,
std::string_view  auxName 
)
inline

This function sets up an auxiliary field by determining its type and attempting to register it with the auxiliary type registry.

If the field type is not known, it tries to create a factory for the field's type. The function handles both static and dynamic fields and updates the set of known auxiliary IDs upon success.

Parameters
fieldThe field to set up
auxNameThe name of the auxiliary property, extracted from the field's name
Returns
StatusCode::SUCCESS if the function was successful, something else otherwise

Definition at line 421 of file RAuxStore.cxx.

422  {
423 
424  // Get the (on disk) type of the field.
425  std::string expectedClassName;
426  const std::type_info* ti = auxFieldType(field, &expectedClassName);
427  if (ti == nullptr) {
428  // If we didn't find a type_info for the field, give up now...
429  return StatusCode::SUCCESS;
430  }
431 
432  // Get the registry:
434 
435  // Check if the registry already knows this variable name. If yes, let's
436  // use the type known by the registry. To be able to deal with simple
437  // schema evolution in dynamic fields.
438  if (const SG::auxid_t regAuxid = registry.findAuxID(std::string{auxName});
439  regAuxid != SG::null_auxid) {
440  m_data.m_auxIDs.insert(regAuxid);
441  return StatusCode::SUCCESS;
442  }
443 
445  SG::auxid_t linkedAuxId = SG::null_auxid;
446 
447  if (SG::AuxTypeRegistry::isLinkedName(std::string{auxName})) {
449  } else if (SG::AuxTypeRegistry::classNameHasLink(expectedClassName)) {
450  const std::string linkedAttr =
451  SG::AuxTypeRegistry::linkedName(std::string{auxName});
452  const std::string linkedFieldName =
453  SG::AuxTypeRegistry::linkedName(field.GetFieldName());
454  const std::type_info* linkedTi = nullptr;
455  if (::fieldExists(linkedFieldName, *m_inTuple)) {
456  linkedTi =
457  auxFieldType(m_inTuple->GetModel().GetConstField(linkedFieldName));
458  }
459  if (linkedTi) {
460  linkedAuxId = registry.getAuxID(
461  *linkedTi, linkedAttr, "",
463  }
464  if (linkedAuxId == SG::null_auxid) {
465  ::Error("xAOD::RAuxStore::setupAuxField",
466  "Could not find linked variable for %s type %s", auxName.data(),
467  expectedClassName.c_str());
468  }
469  }
470 
471  // Check for an auxiliary ID for this field:
472  SG::auxid_t auxid =
473  registry.getAuxID(*ti, std::string{auxName}, "", flags, linkedAuxId);
474 
475  // First try to find a compiled factory for the vector type:
476  if (auxid == SG::null_auxid) {
477 
478  // Construct the name of the factory's class:
479  // But be careful --- if we don't exactly match the name
480  // in TClassTable, then we may trigger autoparsing. Besides the
481  // resource usage that implies, that can lead to crashes in dbg
482  // builds due to cling bugs.
483  std::string typeName = Utils::getTypeName(*ti);
484  if (typeName.starts_with("std::vector<"))
485  typeName.erase(0, 5);
486  std::string factoryClassName =
487  "SG::AuxTypeVectorFactory<" + typeName + ",allocator<" + typeName;
488  if (factoryClassName[factoryClassName.size() - 1] == '>') {
489  factoryClassName += ' ';
490  }
491  factoryClassName += "> >";
492 
493  // Look for the dictionary of this type:
494  ::TClass* factoryClass = TClass::GetClass(factoryClassName.c_str());
495  if (factoryClass && factoryClass->IsLoaded()) {
496  ::TClass* baseClass = ::TClass::GetClass("SG::IAuxTypeVectorFactory");
497  if (baseClass && baseClass->IsLoaded()) {
498  const Int_t offset = factoryClass->GetBaseClassOffset(baseClass);
499  if (offset >= 0) {
500  void* factoryVoidPointer = factoryClass->New();
501  if (factoryVoidPointer) {
502  unsigned long tmp =
503  reinterpret_cast<unsigned long>(factoryVoidPointer) + offset;
504  SG::IAuxTypeVectorFactory* factory =
505  reinterpret_cast<SG::IAuxTypeVectorFactory*>(tmp);
506  registry.addFactory(
507  *ti, *factory->tiAlloc(),
508  std::unique_ptr<SG::IAuxTypeVectorFactory>(factory));
509  auxid = registry.getAuxID(*ti, std::string{auxName}, "", flags,
510  linkedAuxId);
511  }
512  }
513  }
514  }
515  }
516 
517  // If that didn't succeed, let's assign a generic factory to this type:
518  if (auxid == SG::null_auxid && linkedAuxId == SG::null_auxid) {
519  // Construct the name of the vector type:
520  std::string vectorClassName = "std::vector<" + Utils::getTypeName(*ti);
521  if (vectorClassName[vectorClassName.size() - 1] == '>') {
522  vectorClassName += ' ';
523  }
524  vectorClassName += '>';
525 
526  // Get the dictionary for the type:
527  ::TClass* vectorClass = ::TClass::GetClass(vectorClassName.c_str());
528  if (vectorClass && vectorClass->IsLoaded()) {
529  auto factory = std::make_unique<TAuxVectorFactory>(vectorClass);
530  if (factory->tiAlloc()) {
531  const std::type_info* tiAlloc = factory->tiAlloc();
532  registry.addFactory(*ti, *tiAlloc, std::move(factory));
533  } else {
534  std::string tiAllocName = factory->tiAllocName();
535  registry.addFactory(*ti, tiAllocName, std::move(factory));
536  }
537  auxid = registry.getAuxID(*ti, std::string{auxName}, "",
539  } else {
540  ::Warning("xAOD::RAuxStore::setupAuxField",
541  "Couldn't find dictionary for type: %s",
542  vectorClassName.c_str());
543  }
544  }
545 
546  // Check if we succeeded:
547  if (auxid == SG::null_auxid) {
548  if (linkedAuxId != SG::null_auxid) {
549  ::Error("xAOD::RAuxStore::setupAuxField",
550  XAOD_MESSAGE("Dynamic ROOT vector factory not implemented for "
551  "linked types; field \"%s\""),
552  field.GetFieldName().c_str());
553  } else {
554  ::Error("xAOD::RAuxStore::setupAuxField",
555  XAOD_MESSAGE("Couldn't assign auxiliary ID to field \"%s\""),
556  field.GetFieldName().c_str());
557  }
558  return StatusCode::FAILURE;
559  }
560 
561  // Remember the auxiliary ID:
562  m_data.m_auxIDs.insert(auxid);
563  return StatusCode::SUCCESS;
564  }

Member Data Documentation

◆ m_data

Members& xAOD::RAuxStore::impl::m_data

Variables coming from AuxStoreBase.

Definition at line 567 of file RAuxStore.cxx.

◆ m_entry

::Long64_t xAOD::RAuxStore::impl::m_entry

The entry to load from the ntuple.

Definition at line 578 of file RAuxStore.cxx.

◆ m_fields

std::vector<std::unique_ptr<RFieldHandle> > xAOD::RAuxStore::impl::m_fields

Fields containing the various auxiliary variables.

Definition at line 581 of file RAuxStore.cxx.

◆ m_fieldsWritten

std::vector<bool> xAOD::RAuxStore::impl::m_fieldsWritten

"Write status" of the different variables

Definition at line 583 of file RAuxStore.cxx.

◆ m_inputScanned

bool xAOD::RAuxStore::impl::m_inputScanned = false

"Scan status" of the input RNTuple

Definition at line 575 of file RAuxStore.cxx.

◆ m_inTuple

ROOT::RNTupleReader* xAOD::RAuxStore::impl::m_inTuple = nullptr

The ntuple being read from.

Definition at line 570 of file RAuxStore.cxx.

◆ m_missingFields

std::vector<bool> xAOD::RAuxStore::impl::m_missingFields

Mark fields we've found to be missing.

Definition at line 585 of file RAuxStore.cxx.

◆ m_mutex

mutex_t xAOD::RAuxStore::impl::m_mutex
mutable

Mutex object used for multithreaded synchronisation.

Definition at line 588 of file RAuxStore.cxx.

◆ m_outTuple

ROOT::RNTupleWriter* xAOD::RAuxStore::impl::m_outTuple = nullptr

The ntuple being written to.

Definition at line 572 of file RAuxStore.cxx.


The documentation for this struct was generated from the following file:
python.Dso.registry
registry
Definition: Control/AthenaServices/python/Dso.py:158
RETURN_CHECK
#define RETURN_CHECK(CONTEXT, EXP)
Helper macro for checking return codes in a compact form in the code.
Definition: ReturnCheck.h:26
xAOD::RAuxStore::impl::setupAuxField
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...
Definition: RAuxStore.cxx:421
xAOD::details::lookupVectorType
TClass * lookupVectorType(TClass &cl)
Internal function used by xAOD::TAuxStore and xAOD::RAuxStore.
Definition: lookupVectorType.cxx:12
SG::SkipNameCheck
@ SkipNameCheck
Definition: AuxTypes.h:81
SG::AuxTypeRegistry::instance
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Definition: AuxTypeRegistry.cxx:639
AthenaPoolTestRead.flags
flags
Definition: AthenaPoolTestRead.py:8
xAOD::details::AuxStoreBase::Members::m_auxIDs
SG::auxid_set_t m_auxIDs
Internal list of auxiliary variable IDs handled currently by the object.
Definition: AuxStoreBase.h:186
SG::AuxTypeRegistry::linkedName
static std::string linkedName(const std::string &name)
Given a variable name, return the name of the corresponding linked variable.
Definition: AuxTypeRegistry.cxx:1302
XAOD_MESSAGE
#define XAOD_MESSAGE(MESSAGE)
Simple macro for printing error/verbose messages.
Definition: Control/xAODRootAccess/xAODRootAccess/tools/Message.h:19
xAOD::Utils::isPrimitiveType
bool isPrimitiveType(std::string_view typeName)
Check if the type name describes a primitive type.
Definition: Control/xAODRootAccess/Root/Utils.cxx:279
ReadOfcFromCool.field
field
Definition: ReadOfcFromCool.py:48
SG::AuxTypeRegistry::classNameHasLink
static bool classNameHasLink(const std::string &className)
Test to see if a class name corresponds to a class with a linked variable.
Definition: AuxTypeRegistry.cxx:1312
xAOD::RAuxStore::impl::m_data
Members & m_data
Variables coming from AuxStoreBase.
Definition: RAuxStore.cxx:567
xAOD::details::AuxStoreBase::EStructMode::kObjectStore
@ kObjectStore
The object describes a single object.
SG::AuxTypeRegistry
Handle mappings between names and auxid_t.
Definition: AuxTypeRegistry.h:61
SG::Linked
@ Linked
Mark that this variable is linked to another one.
Definition: AuxTypes.h:77
xAOD::RAuxStore::impl::m_inTuple
ROOT::RNTupleReader * m_inTuple
The ntuple being read from.
Definition: RAuxStore.cxx:570
SG::auxid_t
size_t auxid_t
Identifier for a particular aux data item.
Definition: AuxTypes.h:27
xAOD::Utils::getTypeName
std::string getTypeName(const std::type_info &ti)
This function is necessary in order to create type names that ROOT can understand.
Definition: Control/xAODRootAccess/Root/Utils.cxx:353
CxxUtils::ConcurrentBitset::insert
ConcurrentBitset & insert(bit_t bit, bit_t new_nbits=0)
Set a bit to 1.
SG::IAuxTypeVectorFactory
Interface for factory objects that create vectors.
Definition: IAuxTypeVectorFactory.h:50
SG::IAuxTypeVectorFactory::tiAlloc
virtual const std::type_info * tiAlloc() const =0
Return the type_info of the vector allocator.
taskman.fieldName
fieldName
Definition: taskman.py:489
xAOD::details::AuxStoreBase::Members::m_prefix
std::string m_prefix
Static prefix for the branch names.
Definition: AuxStoreBase.h:178
SG::AuxTypeRegistry::isLinkedName
static bool isLinkedName(const std::string &name)
Test if a variable name corresponds to a linked variable.
Definition: AuxTypeRegistry.cxx:1292
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
SG::AuxVarFlags
AuxVarFlags
Additional flags to qualify an auxiliary variable.
Definition: AuxTypes.h:58
xAOD::details::AuxStoreBase::Members::m_structMode
EStructMode m_structMode
The "structural" mode of the object.
Definition: AuxStoreBase.h:174
xAOD::RAuxStore::impl::auxFieldType
const std::type_info * auxFieldType(const ROOT::RFieldBase &field, std::string *expectedClassName=nullptr)
This function retrieves the type information for a given auxiliary field.
Definition: RAuxStore.cxx:347
xAOD::Utils::getTypeInfo
const std::type_info & getTypeInfo(EDataType type)
This function is used when reading a primitive branch from an input file without the user explicitly ...
Definition: Control/xAODRootAccess/Root/Utils.cxx:194
convertTimingResiduals.offset
offset
Definition: convertTimingResiduals.py:71
xAOD::details::AuxStoreBase::EStructMode::kUndefinedStore
@ kUndefinedStore
The structure mode is not defined.
ReadCalibFromCool.typeName
typeName
Definition: ReadCalibFromCool.py:477
xAOD::details::AuxStoreBase::Members::m_dynPrefix
std::string m_dynPrefix
Dynamic prefix for the branch names.
Definition: AuxStoreBase.h:180
xAOD::details::AuxStoreBase::Members::m_topStore
bool m_topStore
Flag stating whether this is a "top store".
Definition: AuxStoreBase.h:176
xAOD::RAuxStore::impl::m_inputScanned
bool m_inputScanned
"Scan status" of the input RNTuple
Definition: RAuxStore.cxx:575