Loading [MathJax]/jax/output/SVG/config.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::TAuxStore::impl Struct Reference
Collaboration diagram for xAOD::TAuxStore::impl:

Public Member Functions

StatusCode scanInputTree ()
 Scan the input TTree for auxiliary branches. More...
 
const std::type_info * auxBranchType (::TBranch &br, std::string_view auxName, bool staticBranch, std::string *expectedClassName=nullptr)
 Find the type_info to use as the aux type for a given branch. More...
 
StatusCode setupAuxBranch (::TBranch &br, std::string_view auxName, bool staticBranch)
 Register one input branch as an available auxiliary variable. More...
 

Public Attributes

Membersm_data
 Variables coming from AuxStoreBase. More...
 
int m_basketSize = 2048
 The basket size for the output branches. More...
 
int m_splitLevel = 0
 The split level for the output branches. More...
 
::TTree * m_inTree = nullptr
 The TTree being read from. More...
 
::TTree * m_outTree = nullptr
 The TTree being written to. More...
 
bool m_inputScanned = false
 "Scan status" of the input TTree More...
 
std::vector< std::unique_ptr< TBranchHandle > > m_branches
 Branches reading the various auxiliary variables. More...
 
std::vector< boolm_branchesWritten
 "Write status" of the different variables More...
 
std::vector< boolm_missingBranches
 Mark branches we've found to be missing. More...
 
mutex_t m_mutex
 Mutex object used for multithreaded synchronisation. More...
 

Detailed Description

Definition at line 423 of file TAuxStore.cxx.

Member Function Documentation

◆ auxBranchType()

const std::type_info* xAOD::TAuxStore::impl::auxBranchType ( ::TBranch &  br,
std::string_view  auxName,
bool  staticBranch,
std::string *  expectedClassName = nullptr 
)
inline

Find the type_info to use as the aux type for a given branch.

Definition at line 545 of file TAuxStore.cxx.

547  {
548 
549  // Get the branch's type:
550  ::TClass* expectedClass = nullptr;
551  ::EDataType expectedType = kOther_t;
552  if (br.GetExpectedType(expectedClass, expectedType) &&
553  ((!staticBranch) || (!auxName.starts_with("m_")))) {
554  ::Warning("xAOD::TAuxStore::impl::auxBranchType",
555  "Couldn't get the type of branch \"%s\"", br.GetName());
556  }
557 
558  // Check for schema evolution:
559  // If a branch has automatic schema evolution from one class to another,
560  // then what we get from GetExpectedType will be the on-disk class.
561  // What we have in memory is given by GetCurrentClass.
562  if (expectedClass) {
563  if (TBranchElement* bre = dynamic_cast<TBranchElement*>(&br)) {
564  TClass* newClass = bre->GetCurrentClass();
565  if (newClass && newClass != expectedClass) {
566  expectedClass = newClass;
567  }
568  }
569  if (expectedClassName) {
570  *expectedClassName = expectedClass->GetName();
571  }
572  }
573 
574  // If this is a primitive variable, and we're still not sure whether this
575  // is a store for an object or a container, the answer is given...
576  if ((!expectedClass) &&
579  }
580 
581  // Get the type_info of the branch.
582  const std::type_info* ti = nullptr;
584  if (expectedClass) {
585  ti = expectedClass->GetTypeInfo();
586  } else {
587  ti = &(Utils::getTypeInfo(expectedType));
588  }
589  } else {
590  if (!expectedClass) {
591  if ((!staticBranch) || (!auxName.starts_with("m_"))) {
592  ::Warning("xAOD::TAuxStore::impl::auxBranchType",
593  "Couldn't get the type of branch \"%s\"", br.GetName());
594  }
595  } else {
596  ::TVirtualCollectionProxy* prox = expectedClass->GetCollectionProxy();
597 
598  if (!prox) {
599  TClass* cl2 = details::lookupVectorType(*expectedClass);
600  if (cl2) {
601  prox = cl2->GetCollectionProxy();
602  }
603  }
604 
605  if (!prox) {
606  if ((!staticBranch) || (!auxName.starts_with("m_"))) {
607  ::Warning("xAOD::TAuxStore::impl::auxBranchType",
608  "Couldn't get the type of branch \"%s\"", br.GetName());
609  }
610  } else {
611  if (prox->GetValueClass()) {
612  ti = prox->GetValueClass()->GetTypeInfo();
613  } else {
614  ti = &(Utils::getTypeInfo(prox->GetType()));
615  }
616  }
617  }
618  }
619 
620  return ti;
621  }

◆ scanInputTree()

StatusCode xAOD::TAuxStore::impl::scanInputTree ( )
inline

Scan the input TTree for auxiliary branches.

When writing an output tree, while reading information from an input tree, it can often happen that we want to copy the contents of some variables that we don't actually need during the event processing of this particular job. Since the user doesn't ask for all the possible input variables, this function needs to look at the input TTree, and try to figure out which of the branches in the tree belong to this object.

The function creates a "proper" or "virtual" auxiliary ID for each of the branches found, so they can be referenced in the "usual way" in the other parts of the code later on.

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

Definition at line 442 of file TAuxStore.cxx.

442  {
443 
444  // Check if an input tree is even available:
445  if (!m_inTree) {
446  // It's not an error if it isn't.
447  return StatusCode::SUCCESS;
448  }
449 
450  // Check if the input was already scanned:
451  if (m_inputScanned) {
452  return StatusCode::SUCCESS;
453  }
454 
455  // Get a list of all branches in the tree:
456  TObjArray* branches = m_inTree->GetListOfBranches();
457 
458  // Check each of them:
459  for (Int_t i = 0; i < branches->GetEntriesFast(); ++i) {
460 
461  // The name of this top-level branch:
462  const TString brName = branches->At(i)->GetName();
463 
464  // Access the branch pointer:
465  TBranch* br = dynamic_cast<TBranch*>(branches->At(i));
466  if (!br) {
467  ::Fatal("xAOD::TAuxStore::impl::scanInputTree",
468  XAOD_MESSAGE("Logic error detected"));
469  }
470 
471  // For top-level stores let's scan the static branches as well:
472  if (m_data.m_topStore && (brName == m_data.m_prefix)) {
473 
474  // Make sure the object has been instantiated so that aux data
475  // registrations will have been done.
476  br->SetAddress(0);
477 
478  // Get a list of its sub-branches:
479  TObjArray* sbranches = br->GetListOfBranches();
480 
481  // ...and then loop over them:
482  for (Int_t j = 0; j < sbranches->GetEntriesFast(); ++j) {
483 
484  // The name of the sub-branch:
485  const TString brName = sbranches->At(j)->GetName();
486 
487  // Try to make a variable name out of the branch name:
488  const TString auxName =
489  brName(brName.Index(".") + 1, brName.Length());
490 
491  // Skip this entry if it refers to a base class:
492  if (auxName.BeginsWith("xAOD::") || auxName.BeginsWith("SG::") ||
493  (auxName == "ILockable")) {
494  continue;
495  }
496 
497  // The sub-branch:
498  ::TBranch* sbr = dynamic_cast< ::TBranch*>(sbranches->At(j));
499  if (!sbr) {
500  ::Fatal("xAOD::TAuxStore::impl::scanInputTree",
501  XAOD_MESSAGE("Logic error detected"));
502  }
503 
504  // Leave the rest up to the function that is shared with the
505  // dynamic branches:
506  RETURN_CHECK("xAOD::TAuxStore::impl::scanInputTree",
507  setupAuxBranch(*sbr, auxName, true));
508  }
509 
510  // Don't check the rest of the loop's body:
511  continue;
512  }
513 
514  // Check if it has the right prefix to be a dynamic variable:
515  if (!brName.BeginsWith(m_data.m_dynPrefix.data())) {
516  continue;
517  }
518  // It's possible to create dynamic variables with an empty name
519  // as well. Which is a bug. Such variables are just ignored
520  // for now.
521  if (brName == m_data.m_dynPrefix) {
522  ::Warning("xAOD::TAuxStore::impl::scanInputTree",
523  "Dynamic branch with empty name found on container: %s",
524  m_data.m_prefix.data());
525  continue;
526  }
527 
528  // The auxiliary property name:
529  const TString auxName = brName(brName.Index(".") + 1, brName.Length());
530 
531  // Leave the rest up to the function that is shared with the
532  // dynamic branches:
533  RETURN_CHECK("xAOD::TAuxStore::impl::scanInputTree",
534  setupAuxBranch(*br, auxName, false));
535  }
536 
537  // Okay, the input was successfully scanned:
538  m_inputScanned = true;
539 
540  // Return gracefully:
541  return StatusCode::SUCCESS;
542  }

◆ setupAuxBranch()

StatusCode xAOD::TAuxStore::impl::setupAuxBranch ( ::TBranch &  br,
std::string_view  auxName,
bool  staticBranch 
)
inline

Register one input branch as an available auxiliary variable.

This function takes care of assigning an auxiliary ID to a given branch. It tries its best to find an auxiliary vector factory for the branch's type, but if it fails, it still falls back to using SG::AuxTypePlaceholder as the type. In which case of course only dumb copying will be possible for the given branch. (And no vector operations on the branch's payload until the variable of the branch is accessed explicitly.)

Parameters
brPointer to the branch under investigation
auxNameThe name of the auxiliary property, extracted from the branch's name
staticBranchkTRUE if this is a "static branch", and kFALSE if it's a dynamic one
Returns
StatusCode::SUCCESS if the function was successful, something else otherwise

Definition at line 641 of file TAuxStore.cxx.

642  {
643 
644  // Get the (on disk) type of the branch.
645  std::string expectedClassName;
646  const std::type_info* ti =
647  auxBranchType(br, auxName, staticBranch, &expectedClassName);
648  if (ti == nullptr) {
649  // If we didn't find a type_info for the branch, give up now...
650  return StatusCode::SUCCESS;
651  }
652 
653  // Get the registry:
655 
656  // Check if the registry already knows this variable name. If yes, let's
657  // use the type known by the registry. To be able to deal with simple
658  // schema evolution in dynamic branches.
659  if (const SG::auxid_t regAuxid = registry.findAuxID(std::string{auxName});
660  regAuxid != SG::null_auxid) {
661  m_data.m_auxIDs.insert(regAuxid);
662  return StatusCode::SUCCESS;
663  }
664 
666  SG::auxid_t linked_auxid = SG::null_auxid;
667 
668  if (SG::AuxTypeRegistry::isLinkedName(std::string{auxName})) {
670  } else if (SG::AuxTypeRegistry::classNameHasLink(expectedClassName)) {
671  std::string linkedAttr =
672  SG::AuxTypeRegistry::linkedName(std::string{auxName});
673  std::string linkedBranch = SG::AuxTypeRegistry::linkedName(br.GetName());
674  ::TBranch* lbr = m_inTree->GetBranch(linkedBranch.c_str());
675  const std::type_info* lti = nullptr;
676  if (lbr) {
677  lti = auxBranchType(*lbr, linkedAttr, staticBranch);
678  }
679  if (lti) {
680  linked_auxid = registry.getAuxID(
681  *lti, linkedAttr, "",
683  }
684  if (linked_auxid == SG::null_auxid) {
685  ::Error("xAOD::TAuxStore::impl::setupAuxBranch",
686  "Could not find linked variable for %s type %s", auxName.data(),
687  expectedClassName.c_str());
688  }
689  }
690 
691  // Check for an auxiliary ID for this branch:
692  SG::auxid_t auxid =
693  registry.getAuxID(*ti, std::string{auxName}, "", flags, linked_auxid);
694 
695  // First try to find a compiled factory for the vector type:
696  if (auxid == SG::null_auxid) {
697 
698  // Construct the name of the factory's class:
699  // But be careful --- if we don't exactly match the name
700  // in TClassTable, then we may trigger autoparsing. Besides the
701  // resource usage that implies, that can lead to crashes in dbg
702  // builds due to cling bugs.
703  std::string tn = Utils::getTypeName(*ti);
704  if (tn.starts_with("std::vector<")) {
705  tn.erase(0, 5);
706  }
707  std::string fac_class_name =
708  "SG::AuxTypeVectorFactory<" + tn + ",allocator<" + tn;
709  if (fac_class_name[fac_class_name.size() - 1] == '>') {
710  fac_class_name += ' ';
711  }
712  fac_class_name += "> >";
713 
714  // Look for the dictionary of this type:
715  ::TClass* fac_class = TClass::GetClass(fac_class_name.c_str());
716  if (fac_class && fac_class->IsLoaded()) {
717  ::TClass* base_class = ::TClass::GetClass("SG::IAuxTypeVectorFactory");
718  if (base_class && base_class->IsLoaded()) {
719  const Int_t offs = fac_class->GetBaseClassOffset(base_class);
720  if (offs >= 0) {
721  void* fac_vp = fac_class->New();
722  if (fac_vp) {
723  unsigned long tmp =
724  reinterpret_cast<unsigned long>(fac_vp) + offs;
726  reinterpret_cast<SG::IAuxTypeVectorFactory*>(tmp);
727  registry.addFactory(
728  *ti, *fac->tiAlloc(),
729  std::unique_ptr<SG::IAuxTypeVectorFactory>(fac));
730  auxid = registry.getAuxID(*ti, std::string{auxName}, "", flags,
731  linked_auxid);
732  }
733  }
734  }
735  }
736  }
737 
738  // If that didn't succeed, let's assign a generic factory to this type:
739  if (auxid == SG::null_auxid && linked_auxid == SG::null_auxid) {
740 
741  // Construct the name of the vector type:
742  std::string vec_class_name = "std::vector<" + Utils::getTypeName(*ti);
743  if (vec_class_name[vec_class_name.size() - 1] == '>') {
744  vec_class_name += ' ';
745  }
746  vec_class_name += '>';
747 
748  // Get the dictionary for the type:
749  ::TClass* vec_class = ::TClass::GetClass(vec_class_name.c_str());
750  if (vec_class && vec_class->IsLoaded()) {
751  auto fac = std::make_unique<TAuxVectorFactory>(vec_class);
752  if (fac->tiAlloc()) {
753  const std::type_info* tiAlloc = fac->tiAlloc();
754  registry.addFactory(*ti, *tiAlloc, std::move(fac));
755  } else {
756  std::string tiAllocName = fac->tiAllocName();
757  registry.addFactory(*ti, tiAllocName, std::move(fac));
758  }
759  auxid = registry.getAuxID(*ti, std::string{auxName}, "",
761  } else {
762  ::Warning("xAOD::TAuxStore::impl::setupAuxBranch",
763  "Couldn't find dictionary for type: %s",
764  vec_class_name.c_str());
765  }
766  }
767 
768  // Check if we succeeded:
769  if (auxid == SG::null_auxid) {
770  if (linked_auxid != SG::null_auxid) {
771  ::Error("xAOD::TAuxStore::impl::setupAuxBranch",
772  XAOD_MESSAGE("Dynamic ROOT vector factory not implemented for "
773  "linked types; branch "
774  "\"%s\""),
775  br.GetName());
776  } else {
777  ::Error("xAOD::TAuxStore::impl::setupAuxBranch",
778  XAOD_MESSAGE("Couldn't assign auxiliary ID to branch "
779  "\"%s\""),
780  br.GetName());
781  }
782  return StatusCode::FAILURE;
783  }
784 
785  // Remember the auxiliary ID:
786  m_data.m_auxIDs.insert(auxid);
787  return StatusCode::SUCCESS;
788  }

Member Data Documentation

◆ m_basketSize

int xAOD::TAuxStore::impl::m_basketSize = 2048

The basket size for the output branches.

Definition at line 794 of file TAuxStore.cxx.

◆ m_branches

std::vector<std::unique_ptr<TBranchHandle> > xAOD::TAuxStore::impl::m_branches

Branches reading the various auxiliary variables.

Definition at line 807 of file TAuxStore.cxx.

◆ m_branchesWritten

std::vector<bool> xAOD::TAuxStore::impl::m_branchesWritten

"Write status" of the different variables

Definition at line 809 of file TAuxStore.cxx.

◆ m_data

Members& xAOD::TAuxStore::impl::m_data

Variables coming from AuxStoreBase.

Definition at line 791 of file TAuxStore.cxx.

◆ m_inputScanned

bool xAOD::TAuxStore::impl::m_inputScanned = false

"Scan status" of the input TTree

Definition at line 804 of file TAuxStore.cxx.

◆ m_inTree

::TTree* xAOD::TAuxStore::impl::m_inTree = nullptr

The TTree being read from.

Definition at line 799 of file TAuxStore.cxx.

◆ m_missingBranches

std::vector<bool> xAOD::TAuxStore::impl::m_missingBranches

Mark branches we've found to be missing.

(Because TTree::GetBranch is very expensive.)

Definition at line 812 of file TAuxStore.cxx.

◆ m_mutex

mutex_t xAOD::TAuxStore::impl::m_mutex
mutable

Mutex object used for multithreaded synchronisation.

Definition at line 815 of file TAuxStore.cxx.

◆ m_outTree

::TTree* xAOD::TAuxStore::impl::m_outTree = nullptr

The TTree being written to.

Definition at line 801 of file TAuxStore.cxx.

◆ m_splitLevel

int xAOD::TAuxStore::impl::m_splitLevel = 0

The split level for the output branches.

Definition at line 796 of file TAuxStore.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
checkxAOD.brName
brName
Definition: Tools/PyUtils/bin/checkxAOD.py:125
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
xAOD::TAuxStore::impl::auxBranchType
const std::type_info * auxBranchType(::TBranch &br, std::string_view auxName, bool staticBranch, std::string *expectedClassName=nullptr)
Find the type_info to use as the aux type for a given branch.
Definition: TAuxStore.cxx:545
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
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::details::AuxStoreBase::EStructMode::kObjectStore
@ kObjectStore
The object describes a single object.
SG::AuxTypeRegistry
Handle mappings between names and auxid_t.
Definition: AuxTypeRegistry.h:61
xAOD::TAuxStore::impl::m_inTree
::TTree * m_inTree
The TTree being read from.
Definition: TAuxStore.cxx:799
runLayerRecalibration.branches
list branches
Definition: runLayerRecalibration.py:98
SG::Linked
@ Linked
Mark that this variable is linked to another one.
Definition: AuxTypes.h:77
SG::auxid_t
size_t auxid_t
Identifier for a particular aux data item.
Definition: AuxTypes.h:27
xAOD::TAuxStore::impl::setupAuxBranch
StatusCode setupAuxBranch(::TBranch &br, std::string_view auxName, bool staticBranch)
Register one input branch as an available auxiliary variable.
Definition: TAuxStore.cxx:641
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
lumiFormat.i
int i
Definition: lumiFormat.py:85
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.
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::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
xAOD::details::AuxStoreBase::EStructMode::kUndefinedStore
@ kUndefinedStore
The structure mode is not defined.
xAOD::TAuxStore::impl::m_data
Members & m_data
Variables coming from AuxStoreBase.
Definition: TAuxStore.cxx:791
xAOD::TAuxStore::impl::m_inputScanned
bool m_inputScanned
"Scan status" of the input TTree
Definition: TAuxStore.cxx:804
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
PlotCalibFromCool.br
br
Definition: PlotCalibFromCool.py:355