Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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::RNTupleReaderm_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 254 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 352 of file RAuxStore.cxx.

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

◆ 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 263 of file RAuxStore.cxx.

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

◆ 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 426 of file RAuxStore.cxx.

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

Member Data Documentation

◆ m_data

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

Variables coming from AuxStoreBase.

Definition at line 572 of file RAuxStore.cxx.

◆ m_entry

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

The entry to load from the ntuple.

Definition at line 583 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 586 of file RAuxStore.cxx.

◆ m_fieldsWritten

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

"Write status" of the different variables

Definition at line 588 of file RAuxStore.cxx.

◆ m_inputScanned

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

"Scan status" of the input RNTuple

Definition at line 580 of file RAuxStore.cxx.

◆ m_inTuple

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

The ntuple being read from.

Definition at line 575 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 590 of file RAuxStore.cxx.

◆ m_mutex

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

Mutex object used for multithreaded synchronisation.

Definition at line 593 of file RAuxStore.cxx.

◆ m_outTuple

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

The ntuple being written to.

Definition at line 577 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:159
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:426
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
RootStorageSvc::RFieldBase
ROOT::RFieldBase RFieldBase
Definition: RNTupleWriterHelper.h:24
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:278
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:572
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:575
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:352
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:492
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:352
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:580