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

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

◆ 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 type of this sub-field.
296  const std::string& typeName = subField->GetTypeName();
297 
298  // Skip this entry if it refers to a base class.
299  if (typeName.starts_with("xAOD::") ||
300  typeName.starts_with("SG::") ||
301  typeName.starts_with("ILockable")) {
302  continue;
303  }
304 
305  // Set up this field.
306  RETURN_CHECK("xAOD::RAuxStore::impl::scanInputNtuple",
307  setupAuxField(*subField, subField->GetFieldName()));
308  }
309  // Don't check the rest of the loop's body:
310  continue;
311  }
312 
313  // if fieldname doesnt start with the value of m_dynPrefix, skip
314  if (fieldName.starts_with(m_data.m_dynPrefix) == false) {
315  continue;
316  }
317  if (fieldName == m_data.m_dynPrefix) {
318  ::Error("xAOD::RAuxStore::impl::scanInputNtuple",
319  "Dynamic field with empty name found on container: %s",
320  m_data.m_prefix.c_str());
321  continue;
322  }
323  // The auxiliary property name:
324  std::string_view auxName = fieldName;
325  auxName = auxName.substr(auxName.find(':') + 1);
326  // Leave the rest up to the function that is shared with the
327  // dynamic fields:
328  RETURN_CHECK("xAOD::RAuxStore::scanInputNtuple",
329  setupAuxField(*field, auxName));
330  }
331 
332  // the input was successfully scanned:
333  m_inputScanned = true;
334  return StatusCode::SUCCESS;
335  }

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

421  {
422 
423  // Get the (on disk) type of the field.
424  std::string expectedClassName;
425  const std::type_info* ti = auxFieldType(field, &expectedClassName);
426  if (ti == nullptr) {
427  // If we didn't find a type_info for the field, give up now...
428  return StatusCode::SUCCESS;
429  }
430 
431  // Get the registry:
433 
434  // Check if the registry already knows this variable name. If yes, let's
435  // use the type known by the registry. To be able to deal with simple
436  // schema evolution in dynamic fields.
437  const std::string auxNameStr{auxName};//Get rid of this if everything is migrated to string_view
438  if (const SG::auxid_t regAuxid = registry.findAuxID(auxNameStr);
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(auxNameStr)) {
449  } else if (SG::AuxTypeRegistry::classNameHasLink(expectedClassName)) {
450  const std::string linkedAttr =
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, auxNameStr, "", 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, auxNameStr, "", 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, auxNameStr, "",
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:420
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:640
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:1303
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:280
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:1313
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:354
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:1293
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:346
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