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 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("DMTest::") ||
302  typeName.starts_with("ILockable")) {
303  continue;
304  }
305 
306  // Set up this field.
307  RETURN_CHECK("xAOD::RAuxStore::impl::scanInputNtuple",
308  setupAuxField(*subField, subField->GetFieldName()));
309  }
310  // Don't check the rest of the loop's body:
311  continue;
312  }
313 
314  // if fieldname doesnt start with the value of m_dynPrefix, skip
315  if (fieldName.starts_with(m_data.m_dynPrefix) == false) {
316  continue;
317  }
318  if (fieldName == m_data.m_dynPrefix) {
319  ::Error("xAOD::RAuxStore::impl::scanInputNtuple",
320  "Dynamic field with empty name found on container: %s",
321  m_data.m_prefix.c_str());
322  continue;
323  }
324  // The auxiliary property name:
325  std::string_view auxName = fieldName;
326  auxName = auxName.substr(auxName.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  const std::string auxNameStr{auxName};//Get rid of this if everything is migrated to string_view
439  if (const SG::auxid_t regAuxid = registry.findAuxID(auxNameStr);
440  regAuxid != SG::null_auxid) {
441  m_data.m_auxIDs.insert(regAuxid);
442  return StatusCode::SUCCESS;
443  }
444 
446  SG::auxid_t linkedAuxId = SG::null_auxid;
447 
448  if (SG::AuxTypeRegistry::isLinkedName(auxNameStr)) {
450  } else if (SG::AuxTypeRegistry::classNameHasLink(expectedClassName)) {
451  const std::string linkedAttr =
453  const std::string linkedFieldName =
454  SG::AuxTypeRegistry::linkedName(field.GetFieldName());
455  const std::type_info* linkedTi = nullptr;
456  if (::fieldExists(linkedFieldName, *m_inTuple)) {
457  linkedTi =
458  auxFieldType(m_inTuple->GetModel().GetConstField(linkedFieldName));
459  }
460  if (linkedTi) {
461  linkedAuxId = registry.getAuxID(
462  *linkedTi, linkedAttr, "",
464  }
465  if (linkedAuxId == SG::null_auxid) {
466  ::Error("xAOD::RAuxStore::setupAuxField",
467  "Could not find linked variable for %s type %s", auxName.data(),
468  expectedClassName.c_str());
469  }
470  }
471 
472  // Check for an auxiliary ID for this field:
473  SG::auxid_t auxid =
474  registry.getAuxID(*ti, auxNameStr, "", flags, linkedAuxId);
475 
476  // First try to find a compiled factory for the vector type:
477  if (auxid == SG::null_auxid) {
478 
479  // Construct the name of the factory's class:
480  // But be careful --- if we don't exactly match the name
481  // in TClassTable, then we may trigger autoparsing. Besides the
482  // resource usage that implies, that can lead to crashes in dbg
483  // builds due to cling bugs.
484  std::string typeName = Utils::getTypeName(*ti);
485  if (typeName.starts_with("std::vector<"))
486  typeName.erase(0, 5);
487  std::string factoryClassName =
488  "SG::AuxTypeVectorFactory<" + typeName + ",allocator<" + typeName;
489  if (factoryClassName[factoryClassName.size() - 1] == '>') {
490  factoryClassName += ' ';
491  }
492  factoryClassName += "> >";
493 
494  // Look for the dictionary of this type:
495  ::TClass* factoryClass = TClass::GetClass(factoryClassName.c_str());
496  if (factoryClass && factoryClass->IsLoaded()) {
497  ::TClass* baseClass = ::TClass::GetClass("SG::IAuxTypeVectorFactory");
498  if (baseClass && baseClass->IsLoaded()) {
499  const Int_t offset = factoryClass->GetBaseClassOffset(baseClass);
500  if (offset >= 0) {
501  void* factoryVoidPointer = factoryClass->New();
502  if (factoryVoidPointer) {
503  unsigned long tmp =
504  reinterpret_cast<unsigned long>(factoryVoidPointer) + offset;
505  SG::IAuxTypeVectorFactory* factory =
506  reinterpret_cast<SG::IAuxTypeVectorFactory*>(tmp);
507  registry.addFactory(
508  *ti, *factory->tiAlloc(),
509  std::unique_ptr<SG::IAuxTypeVectorFactory>(factory));
510  auxid = registry.getAuxID(*ti, auxNameStr, "", flags,
511  linkedAuxId);
512  }
513  }
514  }
515  }
516  }
517 
518  // If that didn't succeed, let's assign a generic factory to this type:
519  if (auxid == SG::null_auxid && linkedAuxId == SG::null_auxid) {
520  // Construct the name of the vector type:
521  std::string vectorClassName = "std::vector<" + Utils::getTypeName(*ti);
522  if (vectorClassName[vectorClassName.size() - 1] == '>') {
523  vectorClassName += ' ';
524  }
525  vectorClassName += '>';
526 
527  // Get the dictionary for the type:
528  ::TClass* vectorClass = ::TClass::GetClass(vectorClassName.c_str());
529  if (vectorClass && vectorClass->IsLoaded()) {
530  auto factory = std::make_unique<TAuxVectorFactory>(vectorClass);
531  if (factory->tiAlloc()) {
532  const std::type_info* tiAlloc = factory->tiAlloc();
533  registry.addFactory(*ti, *tiAlloc, std::move(factory));
534  } else {
535  std::string tiAllocName = factory->tiAllocName();
536  registry.addFactory(*ti, tiAllocName, std::move(factory));
537  }
538  auxid = registry.getAuxID(*ti, auxNameStr, "",
540  } else {
541  ::Warning("xAOD::RAuxStore::setupAuxField",
542  "Couldn't find dictionary for type: %s",
543  vectorClassName.c_str());
544  }
545  }
546 
547  // Check if we succeeded:
548  if (auxid == SG::null_auxid) {
549  if (linkedAuxId != SG::null_auxid) {
550  ::Error("xAOD::RAuxStore::setupAuxField",
551  XAOD_MESSAGE("Dynamic ROOT vector factory not implemented for "
552  "linked types; field \"%s\""),
553  field.GetFieldName().c_str());
554  } else {
555  ::Error("xAOD::RAuxStore::setupAuxField",
556  XAOD_MESSAGE("Couldn't assign auxiliary ID to field \"%s\""),
557  field.GetFieldName().c_str());
558  }
559  return StatusCode::FAILURE;
560  }
561 
562  // Remember the auxiliary ID:
563  m_data.m_auxIDs.insert(auxid);
564  return StatusCode::SUCCESS;
565  }

Member Data Documentation

◆ m_data

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

Variables coming from AuxStoreBase.

Definition at line 568 of file RAuxStore.cxx.

◆ m_entry

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

The entry to load from the ntuple.

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

◆ m_fieldsWritten

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

"Write status" of the different variables

Definition at line 584 of file RAuxStore.cxx.

◆ m_inputScanned

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

"Scan status" of the input RNTuple

Definition at line 576 of file RAuxStore.cxx.

◆ m_inTuple

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

The ntuple being read from.

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

◆ m_mutex

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

Mutex object used for multithreaded synchronisation.

Definition at line 589 of file RAuxStore.cxx.

◆ m_outTuple

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

The ntuple being written to.

Definition at line 573 of file RAuxStore.cxx.


The documentation for this struct was generated from the following file:
RETURN_CHECK
#define RETURN_CHECK(CONTEXT, EXP)
Helper macro for checking return codes in a compact form in the code.
Definition: ReturnCheck.h:26
SG::AuxTypeRegistry::addFactory
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.
Definition: AuxTypeRegistry.cxx:1173
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:640
SG::AuxTypeRegistry::findAuxID
SG::auxid_t findAuxID(const std::string &name, const std::string &clsname="") const
Look up a name -> auxid_t mapping.
Definition: AuxTypeRegistry.cxx:757
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:568
xAOD::details::AuxStoreBase::EStructMode::kObjectStore
@ kObjectStore
The object describes a single object.
SG::IAuxTypeVectorFactory::tiAllocName
virtual std::string tiAllocName() const =0
Return the (demangled) name of the vector allocator.
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:571
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: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
ReadCalibFromCrest.typeName
typeName
Definition: ReadCalibFromCrest.py:439
convertTimingResiduals.offset
offset
Definition: convertTimingResiduals.py:71
xAOD::details::AuxStoreBase::EStructMode::kUndefinedStore
@ kUndefinedStore
The structure mode is not defined.
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:576
SG::AuxTypeRegistry::getAuxID
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.