ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
RAuxStore.cxx
Go to the documentation of this file.
1 // Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2 
3 // Local include(s).
5 
6 #include "isRegisteredType.h"
7 #include "lookupVectorType.h"
12 
13 // Athena include(s).
18 #include "CxxUtils/as_const_ptr.h"
19 #include "xAODCore/tools/IOStats.h"
21 
22 // ROOT include(s).
23 #include <TClass.h>
24 #include <TROOT.h>
25 
26 #include <ROOT/RNTupleInspector.hxx>
27 #include <ROOT/RNTupleReader.hxx>
28 #include <ROOT/RNTupleView.hxx>
29 #include <ROOT/RNTupleWriter.hxx>
30 
31 // System include(s).
32 #include <cassert>
33 #include <functional>
34 #include <memory>
35 #include <string>
36 
37 // Make the RNTuple types available in the ROOT namespace
38 // with all versions of ROOT.
39 #if ROOT_VERSION_CODE < ROOT_VERSION(6, 36, 0)
40 namespace ROOT {
41 using Experimental::DescriptorId_t;
43 using Experimental::RFieldDescriptor;
44 using Experimental::RNTupleInspector;
47 using Experimental::RNTupleView;
49 #if ROOT_VERSION_CODE < ROOT_VERSION(6, 35, 1)
50 using Experimental::RException;
52 #endif // ROOT_VERSION_CODE < ROOT_VERSION(6, 35, 1)
53 } // namespace ROOT
54 #endif // ROOT_VERSION_CODE < ROOT_VERSION(6, 36, 0)
55 
56 namespace {
57 
67 bool isContainerField(const ROOT::RFieldDescriptor& fieldDesc,
68  SG::auxid_t auxid) {
69 
70  // For unknown types it doesn't matter if the field describes a
71  // container or a single element.
72  if (!xAOD::details::isRegisteredType(auxid)) {
73  return true;
74  }
75 
76  // If it's a primitive field, then it's not a container.
77  if (xAOD::Utils::isPrimitiveType(fieldDesc.GetTypeName())) {
78  return false;
79  }
80 
81  // For non-primitive types, get the dictionary of the type.
82  TClass* cl = TClass::GetClass(fieldDesc.GetTypeName().c_str());
83 
84  // If there is no class associated with the field then it should be
85  // a field describing a standalone object. (As it should be a
86  // "primitive" field in this case.)
87  if (!cl) {
88  ::Warning("::isPContainerField",
89  XAOD_MESSAGE("Couldn't get a dictionary for type \"%s\""),
90  fieldDesc.GetTypeName().c_str());
91  return false;
92  }
93 
94  // If there is a class, ask for the type_info of its type:
95  const std::type_info* root_ti = cl->GetTypeInfo();
96  if (!root_ti) {
97  // This may be an emulated class. One known case is when the type name
98  // is saved as "basic_string<char>" rather than "string" by Athena I/O.
99  // (It's not fully understood why this happens for dynamic branches...)
100  // So, let's see if we can get a functional TClass by massaging the
101  // type name a bit.
102  ::TString typeName(cl->GetName());
103  typeName.ReplaceAll("basic_string<char>", "string");
104  ::TClass* newCl = ::TClass::GetClass(typeName);
105  if (newCl) {
106  root_ti = newCl->GetTypeInfo();
107  }
108  }
109  if (!root_ti) {
110  ::Error("::isContainerField",
111  XAOD_MESSAGE("Couldn't get an std::type_info object out of "
112  "type \"%s\""),
113  cl->GetName());
114  return false;
115  }
116 
117  // Ask for the auxiliary type infos:
118  const std::type_info* aux_obj_ti =
120  if (!aux_obj_ti) {
121  ::Error("::isContainerField",
122  XAOD_MESSAGE("Couldn't get std::type_info object for "
123  "auxiliary id: %i"),
124  static_cast<int>(auxid));
125  return false;
126  }
127  const std::type_info* aux_vec_ti =
129  if (!aux_vec_ti) {
130  ::Error("::isContainerField",
131  XAOD_MESSAGE("Couldn't get std::type_info object for "
132  "auxiliary id: %i"),
133  static_cast<int>(auxid));
134  return false;
135  }
136 
137  // Check which one the ROOT type info agrees with:
138  if (*root_ti == *aux_obj_ti) {
139  // This branch describes a single object:
140  return false;
141  } else if (*root_ti == *aux_vec_ti) {
142  // This branch describes a container of objects:
143  return true;
144  }
145 
146  // For enum and vector<enum> types (PFO...) the type given by
147  // the aux type registry is vector<int>. We have to take it into account
148  // here...
149  if (cl->GetCollectionProxy() && (*aux_vec_ti == typeid(std::vector<int>))) {
150  return true;
151  }
152 
153  TClass* cl2 = xAOD::details::lookupVectorType(*cl);
154  if (cl2) {
155  if (*cl2->GetTypeInfo() == *aux_vec_ti) {
156  return true;
157  }
158  }
159 
160  // If we got this far, the branch may have undergone schema evolution. If
161  // it's one that ROOT can deal with itself, then we should still be able
162  // to read the branch with this code.
163  //
164  // Note that even after looking at the ROOT source code, I'm still not
165  // 100% sure whether we would need to delete the objects returned by
166  // TClass::GetConversionStreamerInfo(...) in this code. :-( But based on
167  // general experience with the ROOT code, I'm going to say no...
168  TClass* aux_vec_cl =
169  TClass::GetClass(xAOD::Utils::getTypeName(*aux_vec_ti).c_str());
170  if (aux_vec_cl &&
171  aux_vec_cl->GetConversionStreamerInfo(cl, cl->GetClassVersion())) {
172  return true;
173  }
174  TClass* aux_obj_cl =
175  TClass::GetClass(xAOD::Utils::getTypeName(*aux_obj_ti).c_str());
176  if (aux_obj_cl &&
177  aux_obj_cl->GetConversionStreamerInfo(cl, cl->GetClassVersion())) {
178  return false;
179  }
180 
181  // If neither, then something went wrong...
182  ::Error("::isContainerField",
183  XAOD_MESSAGE("Couldn't determine if field describes a single "
184  "object or a container"));
185  ::Error("::isContainerField", XAOD_MESSAGE("ROOT type : %s"),
186  xAOD::Utils::getTypeName(*root_ti).c_str());
187  ::Error("::isContainerField", XAOD_MESSAGE("Object type: %s"),
188  xAOD::Utils::getTypeName(*aux_obj_ti).c_str());
189  ::Error("::isContainerField", XAOD_MESSAGE("Vector type: %s"),
190  xAOD::Utils::getTypeName(*aux_vec_ti).c_str());
191  return kFALSE;
192 }
193 
195 class RFieldHandle {
196 
197  public:
199  RFieldHandle(ROOT::RNTupleView<void> field, SG::auxid_t auxid,
200  std::string_view prefix, void* object, const std::type_info* ti)
201  : m_field(std::move(field)),
202  m_auxid(auxid),
203  m_prefix(prefix),
204  m_object(object),
205  m_typeInfo(ti) {}
206 
208  StatusCode getEntry(::Long64_t entry) {
209 
210  // Check if anything needs to be done:
211  if ((m_entry == entry) && (!m_needsRead)) {
212  return StatusCode::SUCCESS;
213  }
214 
215  try {
216  // Load the entry
217  m_field(entry);
218  } catch (const ROOT::RException& e) {
219  ::Error("::RFieldInfo::getEntry",
220  "Failed to load entry %lld for field %s.%s: %s", entry,
221  m_prefix.data(),
222  SG::AuxTypeRegistry::instance().getName(m_auxid).c_str(),
223  e.what());
224  return StatusCode::FAILURE;
225  }
226 
227  // Remember what entry was loaded for this field.
228  m_entry = entry;
229  m_needsRead = false;
230  return StatusCode::SUCCESS;
231  }
232 
239  void* objectPtr() { return m_object; }
240 
242  const std::type_info* typeInfo() const { return m_typeInfo; }
243 
245  void reset() { m_needsRead = true; }
246 
247  private:
249  ROOT::RNTupleView<void> m_field;
251  SG::auxid_t m_auxid;
253  std::string_view m_prefix;
255  void* m_object = nullptr;
257  const std::type_info* m_typeInfo = nullptr;
259  ::Long64_t m_entry = -1;
261  bool m_needsRead = true;
262 
263 }; // class RFieldInfo
264 
265 bool fieldExists(std::string_view fieldName,
266  ROOT::RNTupleReader& ntupleReader) {
267  // If it cannot find a field id it will give the maximum value of
268  // unsigned long
269  return (ntupleReader.GetDescriptor().FindFieldId(fieldName) !=
271 }
272 
273 } // namespace
274 
275 namespace xAOD {
276 
278 
287 
288  // Check if an input ntuple is even available.
289  if (!m_inTuple) {
290  // It's not an error if it isn't.
291  return StatusCode::SUCCESS;
292  }
293 
294  // Check if the input was already scanned.
295  if (m_inputScanned) {
296  return StatusCode::SUCCESS;
297  }
298 
299  // Iterate over all fields of the input ntuple.
300  for (const ROOT::RFieldBase* field :
301 #if ROOT_VERSION_CODE >= ROOT_VERSION(6, 35, 0)
302  m_inTuple->GetModel().GetConstFieldZero().GetConstSubfields()
303 #else
304  m_inTuple->GetModel().GetConstFieldZero().GetSubFields()
305 #endif // ROOT_VERSION_CODE >= ROOT_VERSION(6, 35, 0)
306  ) {
307 
308  // Get the name of the current field.
309  const std::string fieldName = field->GetQualifiedFieldName();
310 
311  // Look for static fields.
312  if (m_data.m_topStore && (fieldName == m_data.m_prefix)) {
313 
314  // Loop over the sub-fields of this field.
315  for (const ROOT::RFieldBase* subField :
316 #if ROOT_VERSION_CODE >= ROOT_VERSION(6, 35, 0)
317  field->GetConstSubFields()
318 #else
319  field->GetSubFields()
320 #endif // ROOT_VERSION_CODE >= ROOT_VERSION(6, 35, 0)
321  ) {
322 
323  // Get the name of this sub-field.
324  const std::string subFieldName = subField->GetQualifiedFieldName();
325  const std::string subAuxName =
326  subFieldName.substr(subFieldName.find(".") + 1);
327 
328  // Skip this entry if it refers to a base class.
329  if (subAuxName.starts_with("xAOD::") ||
330  subAuxName.starts_with("SG::") ||
331  subAuxName.starts_with("ILockable")) {
332  continue;
333  }
334 
335  // Set up this field.
336  RETURN_CHECK("xAOD::RAuxStore::impl::scanInputNtuple",
337  setupAuxField(*subField, subAuxName));
338  }
339  // Don't check the rest of the loop's body:
340  continue;
341  }
342 
343  // if fieldname doesnt start with the value of m_dynPrefix, skip
344  if (fieldName.starts_with(m_data.m_dynPrefix) == false) {
345  continue;
346  }
347  if (fieldName == m_data.m_dynPrefix) {
348  ::Error("xAOD::RAuxStore::impl::scanInputNtuple",
349  "Dynamic field with empty name found on container: %s",
350  m_data.m_prefix.c_str());
351  continue;
352  }
353  // The auxiliary property name:
354  const std::string auxName = fieldName.substr(fieldName.find(":") + 1);
355  // Leave the rest up to the function that is shared with the
356  // dynamic fields:
357  RETURN_CHECK("xAOD::RAuxStore::scanInputNtuple",
358  setupAuxField(*field, auxName));
359  }
360 
361  // the input was successfully scanned:
362  m_inputScanned = true;
363  return StatusCode::SUCCESS;
364  }
365 
375  const std::type_info* auxFieldType(const ROOT::RFieldBase& field,
376  std::string* expectedClassName = nullptr) {
377 
378  // Get the type name of the field. Not worrying about automatic schema
379  // evolution for now.
380  const std::string typeName = field.GetTypeName();
381  ::TClass* expectedClass = ::TClass::GetClass(typeName.c_str());
382  if (expectedClassName) {
383  if (expectedClass) {
384  *expectedClassName = expectedClass->GetName();
385  } else {
386  *expectedClassName = typeName;
387  }
388  }
389 
390  // If this is a primitive variable, and we're still not sure whether this
391  // is a store for an object or a container, the answer is given...
395  }
396 
397  // Get the type_info of the branch.
398  const std::type_info* ti = nullptr;
400  if (expectedClass) {
401  ti = expectedClass->GetTypeInfo();
402  } else {
403  ti = &(Utils::getTypeInfo(typeName));
404  }
405  } else {
406  if (!expectedClass) {
407  ::Warning("xAOD::RAuxStore::impl::auxFieldType",
408  "Couldn't get the type of field \"%s\"",
409  field.GetFieldName().c_str());
410  } else {
411  ::TVirtualCollectionProxy* prox = expectedClass->GetCollectionProxy();
412 
413  if (!prox) {
414  TClass* cl2 = details::lookupVectorType(*expectedClass);
415  if (cl2) {
416  prox = cl2->GetCollectionProxy();
417  }
418  }
419 
420  if (!prox) {
421  ::Warning("xAOD::RAuxStore::impl::auxFieldType",
422  "Couldn't get the type of field \"%s\"",
423  field.GetFieldName().c_str());
424  } else {
425  if (prox->GetValueClass()) {
426  ti = prox->GetValueClass()->GetTypeInfo();
427  } else {
428  ti = &(Utils::getTypeInfo(prox->GetType()));
429  }
430  }
431  }
432  }
433 
434  return ti;
435  }
436 
450  std::string_view auxName) {
451 
452  // Get the (on disk) type of the field.
453  std::string expectedClassName;
454  const std::type_info* ti = auxFieldType(field, &expectedClassName);
455  if (ti == nullptr) {
456  // If we didn't find a type_info for the field, give up now...
457  return StatusCode::SUCCESS;
458  }
459 
460  // Get the registry:
462 
463  // Check if the registry already knows this variable name. If yes, let's
464  // use the type known by the registry. To be able to deal with simple
465  // schema evolution in dynamic fields.
466  if (const SG::auxid_t regAuxid = registry.findAuxID(std::string{auxName});
467  regAuxid != SG::null_auxid) {
468  m_data.m_auxIDs.insert(regAuxid);
469  return StatusCode::SUCCESS;
470  }
471 
473  SG::auxid_t linkedAuxId = SG::null_auxid;
474 
475  if (SG::AuxTypeRegistry::isLinkedName(std::string{auxName})) {
477  } else if (SG::AuxTypeRegistry::classNameHasLink(expectedClassName)) {
478  const std::string linkedAttr =
479  SG::AuxTypeRegistry::linkedName(std::string{auxName});
480  const std::string linkedFieldName =
481  SG::AuxTypeRegistry::linkedName(field.GetFieldName());
482  const std::type_info* linkedTi = nullptr;
483  if (::fieldExists(linkedFieldName, *m_inTuple)) {
484  linkedTi =
485  auxFieldType(m_inTuple->GetModel().GetConstField(linkedFieldName));
486  }
487  if (linkedTi) {
488  linkedAuxId = registry.getAuxID(
489  *linkedTi, linkedAttr, "",
491  }
492  if (linkedAuxId == SG::null_auxid) {
493  ::Error("xAOD::RAuxStore::setupAuxField",
494  "Could not find linked variable for %s type %s", auxName.data(),
495  expectedClassName.c_str());
496  }
497  }
498 
499  // Check for an auxiliary ID for this field:
500  SG::auxid_t auxid =
501  registry.getAuxID(*ti, std::string{auxName}, "", flags, linkedAuxId);
502 
503  // First try to find a compiled factory for the vector type:
504  if (auxid == SG::null_auxid) {
505 
506  // Construct the name of the factory's class:
507  // But be careful --- if we don't exactly match the name
508  // in TClassTable, then we may trigger autoparsing. Besides the
509  // resource usage that implies, that can lead to crashes in dbg
510  // builds due to cling bugs.
511  std::string typeName = Utils::getTypeName(*ti);
512  if (typeName.starts_with("std::vector<"))
513  typeName.erase(0, 5);
514  std::string factoryClassName =
515  "SG::AuxTypeVectorFactory<" + typeName + ",allocator<" + typeName;
516  if (factoryClassName[factoryClassName.size() - 1] == '>') {
517  factoryClassName += ' ';
518  }
519  factoryClassName += "> >";
520 
521  // Look for the dictionary of this type:
522  ::TClass* factoryClass = TClass::GetClass(factoryClassName.c_str());
523  if (factoryClass && factoryClass->IsLoaded()) {
524  ::TClass* baseClass = ::TClass::GetClass("SG::IAuxTypeVectorFactory");
525  if (baseClass && baseClass->IsLoaded()) {
526  const Int_t offset = factoryClass->GetBaseClassOffset(baseClass);
527  if (offset >= 0) {
528  void* factoryVoidPointer = factoryClass->New();
529  if (factoryVoidPointer) {
530  unsigned long tmp =
531  reinterpret_cast<unsigned long>(factoryVoidPointer) + offset;
532  SG::IAuxTypeVectorFactory* factory =
533  reinterpret_cast<SG::IAuxTypeVectorFactory*>(tmp);
534  registry.addFactory(
535  *ti, *factory->tiAlloc(),
536  std::unique_ptr<SG::IAuxTypeVectorFactory>(factory));
537  auxid = registry.getAuxID(*ti, std::string{auxName}, "", flags,
538  linkedAuxId);
539  }
540  }
541  }
542  }
543  }
544 
545  // If that didn't succeed, let's assign a generic factory to this type:
546  if (auxid == SG::null_auxid && linkedAuxId == SG::null_auxid) {
547  // Construct the name of the vector type:
548  std::string vectorClassName = "std::vector<" + Utils::getTypeName(*ti);
549  if (vectorClassName[vectorClassName.size() - 1] == '>') {
550  vectorClassName += ' ';
551  }
552  vectorClassName += '>';
553 
554  // Get the dictionary for the type:
555  ::TClass* vectorClass = ::TClass::GetClass(vectorClassName.c_str());
556  if (vectorClass && vectorClass->IsLoaded()) {
557  auto factory = std::make_unique<TAuxVectorFactory>(vectorClass);
558  if (factory->tiAlloc()) {
559  const std::type_info* tiAlloc = factory->tiAlloc();
560  registry.addFactory(*ti, *tiAlloc, std::move(factory));
561  } else {
562  std::string tiAllocName = factory->tiAllocName();
563  registry.addFactory(*ti, tiAllocName, std::move(factory));
564  }
565  auxid = registry.getAuxID(*ti, std::string{auxName}, "",
567  } else {
568  ::Warning("xAOD::RAuxStore::setupAuxField",
569  "Couldn't find dictionary for type: %s",
570  vectorClassName.c_str());
571  }
572  }
573 
574  // Check if we succeeded:
575  if (auxid == SG::null_auxid) {
576  if (linkedAuxId != SG::null_auxid) {
577  ::Error("xAOD::RAuxStore::setupAuxField",
578  XAOD_MESSAGE("Dynamic ROOT vector factory not implemented for "
579  "linked types; field \"%s\""),
580  field.GetFieldName().c_str());
581  } else {
582  ::Error("xAOD::RAuxStore::setupAuxField",
583  XAOD_MESSAGE("Couldn't assign auxiliary ID to field \"%s\""),
584  field.GetFieldName().c_str());
585  }
586  return StatusCode::FAILURE;
587  }
588 
589  // Remember the auxiliary ID:
590  m_data.m_auxIDs.insert(auxid);
591  return StatusCode::SUCCESS;
592  }
593 
596 
601 
603  bool m_inputScanned = false;
604 
606  ::Long64_t m_entry;
607 
609  std::vector<std::unique_ptr<RFieldHandle> > m_fields;
611  std::vector<bool> m_fieldsWritten;
613  std::vector<bool> m_missingFields;
614 
616  mutable mutex_t m_mutex;
617 
618 }; // struct RAuxStore::impl
619 
620 RAuxStore::RAuxStore(std::string_view prefix, bool topStore, EStructMode mode)
621  : details::AuxStoreBase(topStore, mode),
622  m_impl{std::make_unique<impl>(m_data)} {
623 
624  setPrefix(prefix);
625 }
626 
627 RAuxStore::~RAuxStore() = default;
628 
629 void RAuxStore::setPrefix(std::string_view prefix) {
630 
633  reset();
634 }
635 
644 
645  assert(m_impl);
646 
647  // Make sure that everything will be re-read after this:
648  reset();
649 
650  // We will need to check again which branches are available:
651  m_impl->m_missingFields.clear();
652 
653  // Remember the tree:
654  m_impl->m_inTuple = &reader;
655 
656  // Catalogue all the branches:
657  RETURN_CHECK("xAOD::RAuxStore::readFrom", m_impl->scanInputTuple());
658 
659  // Return gracefully.
660  return StatusCode::SUCCESS;
661 }
662 
670 
671  assert(m_impl);
672 
673  // Look for any auxiliary fields that have not been connected to yet.
674  RETURN_CHECK("xAOD::RAuxStore::writeTo", m_impl->scanInputTuple());
675 
676  // Put the object into "output writing" mode.
677  m_impl->m_outTuple = &writer;
678 
679  // Create all the variables that we already know about. Notice that the
680  // code makes a copy of the auxid set on purpose. Because the underlying
681  // AuxSelection object gets modified while doing the for loop.
682  const SG::auxid_set_t selAuxIDs = getSelectedAuxIDs();
683  for (SG::auxid_t id : selAuxIDs) {
684  RETURN_CHECK("xAOD::RAuxStore::writeTo", setupOutputData(id));
685  }
686 
687  // Return gracefully.
688  return StatusCode::SUCCESS;
689 }
690 
691 StatusCode RAuxStore::getEntry(std::int64_t entry, int getall) {
692 
693  assert(m_impl);
694 
695  // Guard against multi-threaded execution:
696  guard_t guard(m_impl->m_mutex);
697 
698  m_impl->m_entry = entry;
699 
700  // Reset the transient store. TEvent::fill() calls this function with
701  // getall==99. When that is happening, we need to keep the transient
702  // store still around. Since the user may want to interact with the
703  // object after it was written out. (And since TEvent::fill() asks for
704  // the transient decorations after calling getEntry(...).)
705  if (m_data.m_transientStore && (getall != 99)) {
706  // Remove the transient auxiliary IDs from the internal list:
707  m_data.m_auxIDs -= m_data.m_transientStore->getAuxIDs();
708  m_data.m_decorIDs -= m_data.m_transientStore->getDecorIDs();
709  // Delete the object:
710  m_data.m_transientStore.reset();
711  }
712 
713  // Now remove the IDs of the decorations that are getting persistified:
714  if (getall != 99) {
715  for (SG::auxid_t auxid = 0; auxid < m_data.m_isDecoration.size(); ++auxid) {
716  if (!m_data.m_isDecoration[auxid]) {
717  continue;
718  }
719  m_data.m_auxIDs.erase(auxid);
720  m_data.m_decorIDs.erase(auxid);
721  }
722  }
723 
724  // If we don't need everything loaded, return now:
725  if (!getall) {
726  return StatusCode::SUCCESS;
727  }
728 
729  // Get all the variables at once:
730  for (auto& field : m_impl->m_fields) {
731  if (field) {
732  RETURN_CHECK("xAOD::RAuxStore::getEntry", field->getEntry(entry));
733  }
734  }
735 
736  // Return gracefully.
737  return StatusCode::SUCCESS;
738 }
739 
741 
742  assert(m_impl);
743 
744  // Loop through all of the output variables.
745  for (SG::auxid_t id : getSelectedAuxIDs()) {
746  // Now connect the output entry to the variable.
747  const std::string fieldName =
750  void* fieldPtr = const_cast<void*>(getIOData(id));
751  if (fieldPtr) {
752  entry.BindRawPtr(fieldName, fieldPtr);
753  } else {
754  entry.EmplaceNewValue(fieldName);
755  }
756  }
757 
758  // Return gracefully.
759  return StatusCode::SUCCESS;
760 }
761 
763 
764  assert(m_impl);
765 
766  for (auto& field : m_impl->m_fields) {
767  if (field) {
768  field->reset();
769  }
770  }
771  m_impl->m_inputScanned = false;
772 }
773 
775 
776  assert(m_impl);
777  return ((m_impl->m_fields.size() > auxid) && m_impl->m_fields[auxid]);
778 }
779 
781 
782  assert(m_impl);
783  assert(m_impl->m_fields.size() > auxid);
784  assert(m_impl->m_fields[auxid]);
785  RETURN_CHECK("xAOD::RAuxStore::getEntryFor",
786  m_impl->m_fields[auxid]->getEntry(m_impl->m_entry));
787  return StatusCode::SUCCESS;
788 }
789 
790 bool RAuxStore::hasOutput() const {
791 
792  assert(m_impl);
793  return (m_impl->m_outTuple != nullptr);
794 }
795 
804 
805  // Return right away if we already know that the field is missing.
806  if ((auxid < m_impl->m_missingFields.size()) &&
807  m_impl->m_missingFields[auxid]) {
808  return StatusCode::RECOVERABLE;
809  }
810 
811  // We may call this function without an input being used. That's not an
812  // error either.
813  if (m_impl->m_inTuple == nullptr) {
814  return StatusCode::RECOVERABLE;
815  }
816 
817  // Make sure the internal storage is large enough:
818  if (m_data.m_vecs.size() <= auxid) {
819  m_data.m_vecs.resize(auxid + 1);
820  }
821  if (m_impl->m_fields.size() <= auxid) {
822  m_impl->m_fields.resize(auxid + 1);
823  }
824 
825  // Check if we need to do anything. Remember, output-only variables don't
826  // have an associated RFieldHandle. To tell the caller that no input is
827  // actually available for the variable (only an output), use a different
828  // return value.
829  if (m_data.m_vecs[auxid]) {
830  return (m_impl->m_fields[auxid] ? StatusCode::SUCCESS
831  : StatusCode::RECOVERABLE);
832  }
833 
834  // Convenience access to the registry.
836 
837  // Get the property name:
838  const std::string statFieldName =
839  std::format("{}{}", m_data.m_prefix, r.getName(auxid));
840  const std::string dynFieldName =
841  std::format("{}{}", m_data.m_dynPrefix, r.getName(auxid));
842 
843  // Check if the field exists:
844  std::string fieldName = statFieldName;
845  ROOT::DescriptorId_t fieldId;
846  if ((fieldId = m_impl->m_inTuple->GetDescriptor().FindFieldId(
847  statFieldName)) == std::numeric_limits<unsigned long>::max()) {
848  if ((fieldId = m_impl->m_inTuple->GetDescriptor().FindFieldId(
849  dynFieldName)) == std::numeric_limits<unsigned long>::max()) {
850  // Remember that the field is missing.
851  if (m_impl->m_missingFields.size() <= auxid) {
852  m_impl->m_missingFields.resize(auxid + 1);
853  }
854  m_impl->m_missingFields[auxid] = true;
855  // The field doesn't exist, but this is not an error per se.
856  // The user may just be calling isAvailable(...) on the variable.
857  return StatusCode::RECOVERABLE;
858  }
859  // We have a dynamic field:
860  fieldName = dynFieldName;
861  }
862 
863  // Get the object describing this field.
864  const ROOT::RFieldDescriptor& fieldDesc =
865  m_impl->m_inTuple->GetDescriptor().GetFieldDescriptor(fieldId);
866 
867  // Check if it's a "primitive field":
868  const bool primitiveField = Utils::isPrimitiveType(fieldDesc.GetTypeName());
869  // Check if it's a "container field":
870  const bool containerField =
871  (primitiveField ? false : isContainerField(fieldDesc, auxid));
872 
873  // Set the structure mode if it has not been defined externally:
877  }
878 
879  // Check that the branch type makes sense:
880  if ((containerField &&
882  !r.isLinked(auxid)) ||
883  ((!containerField) &&
885  ::Error("xAOD::RAuxStore::setupInputData",
886  XAOD_MESSAGE("Field type and requested structure mode "
887  "differ for field: %s"),
888  fieldName.c_str());
889  return StatusCode::FAILURE;
890  }
891 
892  // Get the property type:
893  const std::type_info* fieldType = nullptr;
894  if (details::isRegisteredType(auxid)) {
895  // Get the type from the auxiliary type registry:
896  fieldType = (containerField ? r.getVecType(auxid) : r.getType(auxid));
897  } else {
898  // Get the type from the input field itself:
899  TClass* clDummy = ::TClass::GetClass(fieldDesc.GetTypeName().c_str());
900  fieldType = (clDummy ? clDummy->GetTypeInfo()
901  : &(Utils::getTypeInfo(fieldDesc.GetTypeName())));
902  }
903  if (!fieldType) {
904  ::Error("xAOD::RAuxStore::setupInputData",
905  XAOD_MESSAGE("Can't read/copy variable %s (%s)"), fieldName.c_str(),
906  fieldDesc.GetTypeName().c_str());
907  return StatusCode::RECOVERABLE;
908  }
909  const TString fieldTypeName = Utils::getTypeName(*fieldType).c_str();
910 
911  // Check if we have the needed dictionary for an object field:
912  ::TClass* fieldClass = nullptr;
913  if (!primitiveField) {
914  // Get the property's class:
915  fieldClass = ::TClass::GetClass(*fieldType, true, true);
916  if (!fieldClass) {
917  fieldClass = ::TClass::GetClass(fieldTypeName);
918  }
919  if (!fieldClass) {
920  ::Error("xAOD::RAuxStore::setupInputData",
921  XAOD_MESSAGE("No dictionary available for class \"%s\""),
922  fieldTypeName.Data());
923  return StatusCode::FAILURE;
924  }
925  }
926 
927  // Create the smart object holding this vector:
928  if (details::isRegisteredType(auxid)) {
929  m_data.m_vecs[auxid] = r.makeVector(auxid, (size_t)0, (size_t)0);
930  if (!containerField) {
931  m_data.m_vecs[auxid]->resize(1);
932  }
933  if (fieldClass &&
934  strncmp(fieldClass->GetName(), "SG::PackedContainer<", 20) == 0) {
935  std::unique_ptr<SG::IAuxTypeVector> packed =
936  m_data.m_vecs[auxid]->toPacked();
937  std::swap(m_data.m_vecs[auxid], packed);
938  }
939  } else {
940  ::Error("xAOD::RAuxStore::setupInputData",
941  XAOD_MESSAGE("Couldn't create in-memory vector for "
942  "variable %s (%i)"),
943  fieldName.c_str(), static_cast<int>(auxid));
944  return StatusCode::FAILURE;
945  }
946 
947  // Access/create the field, and create a field handle object.
948  void* objectPtr = (containerField ? m_data.m_vecs[auxid]->toVector()
949  : m_data.m_vecs[auxid]->toPtr());
950  m_impl->m_fields[auxid] = std::make_unique<RFieldHandle>(
951  m_impl->m_inTuple->GetView<void>(fieldName.c_str(), objectPtr), auxid,
952  m_data.m_prefix, objectPtr, fieldType);
953 
954  // Get the current entry.
955  RETURN_CHECK("xAOD::RAuxStore::setupInputData",
956  m_impl->m_fields[auxid]->getEntry(m_impl->m_entry));
957 
958  // Remember which variable got created:
959  m_data.m_auxIDs.insert(auxid);
960 
961  // Check if we just replaced a generic object:
962  if (details::isRegisteredType(auxid)) {
963  // The name of the variable we just created:
964  const std::string auxname = r.getName(auxid);
965  // Check if there's another variable with this name already:
966  for (SG::auxid_t i = 0; i < m_data.m_vecs.size(); ++i) {
967  // Check if we have this aux ID:
968  if (!m_data.m_vecs[i]) {
969  continue;
970  }
971  // Ingore the object that we *just* created:
972  if (i == auxid) {
973  continue;
974  }
975  // The name of the variable:
976  const std::string testname = r.getName(i);
977  // Check if it has the same name:
978  if (testname != auxname) {
979  continue;
980  }
981  // Check that the other one is a non-registered type:
983  ::Error("xAOD::RAuxStore::setupInputData",
984  XAOD_MESSAGE("Internal logic error!"));
985  continue;
986  }
987  // Okay, we do need to remove this object:
988  m_data.m_vecs[i].reset();
989  m_impl->m_fields[i].reset();
991  }
992  }
993 
994  SG::auxid_t linked_auxid = r.linkedVariable(auxid);
995  if (linked_auxid != SG::null_auxid) {
996  return setupInputData(linked_auxid);
997  }
998 
999  // Return gracefully:
1000  return StatusCode::SUCCESS;
1001 }
1002 
1011 
1012  assert(m_impl);
1013 
1014  // Check whether we need to do anything.
1015  if (!m_impl->m_outTuple) {
1016  return StatusCode::SUCCESS;
1017  }
1018 
1019  // Check if the variable needs to be written out.
1020  if (!isAuxIDSelected(auxid)) {
1021  return StatusCode::SUCCESS;
1022  }
1023 
1024  // Make sure that containers are large enough:
1025  if (m_data.m_vecs.size() <= auxid) {
1026  m_data.m_vecs.resize(auxid + 1);
1027  }
1028  if (m_impl->m_fieldsWritten.size() <= auxid) {
1029  m_impl->m_fieldsWritten.resize(auxid + 1);
1030  }
1031 
1032  // Check if this auxiliary variable is already in the output:
1033  if (m_impl->m_fieldsWritten[auxid]) {
1034  return StatusCode::SUCCESS;
1035  }
1036 
1037  // After this point, we either succeed with setting up the writing of this
1038  // variable, or the code fails completely. So let's set this flag already,
1039  // as unfortunately we can recursively end up here using the code below.
1040  m_impl->m_fieldsWritten[auxid] = true;
1041 
1042  // The registry:
1044 
1045  // Check if the variable was put into the transient store as a
1046  // decoration, and now needs to be put into the output file:
1047  if ((!m_data.m_vecs[auxid]) && m_data.m_transientStore &&
1048  (m_data.m_transientStore->getAuxIDs().test(auxid))) {
1049 
1050  // Get the variable from the transient store:
1051  const void* pptr = m_data.m_transientStore->getData(auxid);
1052  if (!pptr) {
1053  ::Fatal("xAOD::RAuxStore::setupOutputData",
1054  XAOD_MESSAGE("Internal logic error detected"));
1055  return StatusCode::FAILURE;
1056  }
1057 
1058  // Create the new object:
1059  m_data.m_vecs[auxid] = reg.makeVector(auxid, m_data.m_size, m_data.m_size);
1060  void* ptr = m_data.m_vecs[auxid]->toPtr();
1061  if (!ptr) {
1062  ::Error("xAOD::RAuxStore::setupOutputData",
1063  XAOD_MESSAGE("Couldn't create decoration in memory "
1064  "for writing"));
1065  return StatusCode::FAILURE;
1066  }
1067 
1068  // Get the type of this variable:
1069  const std::type_info* type = reg.getType(auxid);
1070  if (!type) {
1071  ::Error("xAOD::RAuxStore::setupOutputData",
1072  XAOD_MESSAGE("Couldn't get the type of transient "
1073  "variable %i"),
1074  static_cast<int>(auxid));
1075  return StatusCode::FAILURE;
1076  }
1077  // Now get the factory for this variable:
1078  const SG::IAuxTypeVectorFactory* factory = reg.getFactory(auxid);
1079  if (!factory) {
1080  ::Error("xAOD::RAuxStore::setupOutputData",
1081  XAOD_MESSAGE("No factory found for transient variable "
1082  "%i"),
1083  static_cast<int>(auxid));
1084  return StatusCode::FAILURE;
1085  }
1086 
1087  // Mark it as a decoration already, otherwise the copy may fail.
1088  if (m_data.m_isDecoration.size() <= auxid) {
1089  m_data.m_isDecoration.resize(auxid + 1);
1090  }
1091  m_data.m_isDecoration[auxid] = true;
1092 
1093  // Finally, do the copy, and remove the variable from the transient store.
1094  factory->copy(auxid, SG::AuxVectorInterface(*this), 0,
1096  m_data.m_size);
1097  }
1098 
1099  // Check if we know about this variable to be on the input,
1100  // but haven't connected to it yet:
1101  if ((m_data.m_auxIDs.test(auxid)) && (!m_data.m_vecs[auxid]) &&
1102  (!m_impl->m_fields[auxid])) {
1103  RETURN_CHECK("xAOD::RAuxStore::setupOutputData", setupInputData(auxid));
1104  }
1105 
1106  // Check that we know the store's type:
1109  ::Error("xAOD::RAuxStore::setupOutputData",
1110  XAOD_MESSAGE("Structure mode unknown for variable %s"),
1111  reg.getName(auxid).c_str());
1112  return StatusCode::FAILURE;
1113  }
1114 
1115  // Check if the variable exists already in memory:
1116  if (!m_data.m_vecs[auxid]) {
1117  m_data.m_vecs[auxid] = reg.makeVector(auxid, (size_t)0, (size_t)0);
1119  m_data.m_vecs[auxid]->resize(1);
1120  }
1121  }
1122 
1123  // Figure out the type and name of the output field.
1124  const std::string fieldName =
1125  std::format("{}{}", m_data.m_dynPrefix, reg.getName(auxid));
1126  const std::string typeName = SG::normalizedTypeinfoName(
1128  ? reg.getVecType(auxid)
1129  : reg.getType(auxid)));
1130 
1131  // Update the output ntuple's model.
1132  {
1133  auto field = ROOT::RFieldBase::Create(fieldName, typeName).Unwrap();
1134  auto updater = m_impl->m_outTuple->CreateModelUpdater();
1135  updater->BeginUpdate();
1136  updater->AddField(std::move(field));
1137  updater->CommitUpdate();
1138  }
1139 
1140  // Remember that we now handle this variable.
1141  m_data.m_auxIDs.insert(auxid);
1142 
1143  // We were successful:
1144  return StatusCode::SUCCESS;
1145 }
1146 
1147 const void* RAuxStore::getInputObject(SG::auxid_t auxid) const {
1148 
1149  assert(m_impl);
1150  assert(m_impl->m_fields.size() > auxid);
1151  assert(m_impl->m_fields[auxid]);
1152  return m_impl->m_fields[auxid]->objectPtr();
1153 }
1154 
1155 const std::type_info* RAuxStore::getInputType(SG::auxid_t auxid) const {
1156 
1157  assert(m_impl);
1158  assert(m_impl->m_fields.size() > auxid);
1159  assert(m_impl->m_fields[auxid]);
1160  return m_impl->m_fields[auxid]->typeInfo();
1161 }
1162 
1163 } // namespace xAOD
SG::AuxTypeRegistry::getFactory
const IAuxTypeVectorFactory * getFactory(const std::type_info &ti, const std::type_info &ti_alloc)
Return the vector factory for a given vector element type.
Definition: AuxTypeRegistry.cxx:1110
xAOD::RAuxStore::hasOutput
virtual bool hasOutput() const override
Check if an output is being written by the object.
Definition: RAuxStore.cxx:790
python.Dso.registry
registry
Definition: Control/AthenaServices/python/Dso.py:159
xAOD::details::AuxStoreBase::prefix
const std::string & prefix() const
Get the currently configured object name prefix.
Definition: AuxStoreBase.cxx:38
xAOD::RAuxStore::impl::m_fieldsWritten
std::vector< bool > m_fieldsWritten
"Write status" of the different variables
Definition: RAuxStore.cxx:611
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
beamspotman.r
def r
Definition: beamspotman.py:676
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::m_entry
::Long64_t m_entry
The entry to load from the ntuple.
Definition: RAuxStore.cxx:606
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:449
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
lookupVectorType.h
vtune_athena.format
format
Definition: vtune_athena.py:14
xAOD::details::AuxStoreBase::Members::m_vecs
std::vector< std::unique_ptr< SG::IAuxTypeVector > > m_vecs
Variables handled currently by the object (indexed by auxiliary ID)
Definition: AuxStoreBase.h:191
xAOD::RAuxStore::setPrefix
virtual void setPrefix(std::string_view prefix) override
Set the object name prefix.
Definition: RAuxStore.cxx:629
xAOD::RAuxStore::impl::m_missingFields
std::vector< bool > m_missingFields
Mark fields we've found to be missing.
Definition: RAuxStore.cxx:613
SG::AuxTypeRegistry::instance
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Definition: AuxTypeRegistry.cxx:639
AuxVectorInterface.h
Make an AuxVectorData object from either a raw vector or an aux store.
SG::normalizedTypeinfoName
std::string normalizedTypeinfoName(const std::type_info &info)
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
Definition: normalizedTypeinfoName.cxx:120
RAuxStore.h
RootStorageSvc::RFieldBase
ROOT::RFieldBase RFieldBase
Definition: RNTupleWriterHelper.h:27
AthenaPoolTestRead.flags
flags
Definition: AthenaPoolTestRead.py:8
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
SG::AuxTypeRegistry::getName
std::string getName(SG::auxid_t auxid) const
Return the name of an aux data item.
Definition: AuxTypeRegistry.cxx:881
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
exceptions.h
Exceptions that can be thrown from AthContainers.
xAOD::details::AuxStoreBase::EStructMode
EStructMode
"Structural" modes of the object
Definition: AuxStoreBase.h:30
xAOD::RAuxStore::~RAuxStore
virtual ~RAuxStore()
Destructor.
xAOD::RAuxStore::getInputObject
virtual const void * getInputObject(SG::auxid_t auxid) const override
Get a pointer to an input object, as it is in memory, for getIOData()
Definition: RAuxStore.cxx:1147
as_const_ptr.h
Helper for getting a const version of a pointer.
isRegisteredType.h
xAOD::details::AuxStoreBase::guard_t
AthContainers_detail::lock_guard< mutex_t > guard_t
Guard type for multithreaded synchronisation.
Definition: AuxStoreBase.h:206
xAOD::details::AuxStoreBase::Members::m_transientStore
std::unique_ptr< SG::AuxStoreInternal > m_transientStore
Store for the in-memory-only variables.
Definition: AuxStoreBase.h:183
xAOD::RAuxStore::impl::m_outTuple
ROOT::RNTupleWriter * m_outTuple
The ntuple being written to.
Definition: RAuxStore.cxx:600
xAOD::Utils::dynFieldPrefix
std::string dynFieldPrefix(const std::string &key)
This function is used to figure out what to name dynamic auxiliary field coming from a container call...
Definition: Control/xAODRootAccess/Root/Utils.cxx:170
xAOD::RAuxStore::impl::m_mutex
mutex_t m_mutex
Mutex object used for multithreaded synchronisation.
Definition: RAuxStore.cxx:616
xAOD::RAuxStore::RNTupleReader
ROOT::Experimental::RNTupleReader RNTupleReader
The RNTuple reader type.
Definition: RAuxStore.h:35
xAOD::details::AuxStoreBase::Members::m_size
std::size_t m_size
The current size of the container being described.
Definition: AuxStoreBase.h:193
xAOD
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
Definition: ICaloAffectedTool.h:24
xAOD::RAuxStore::impl::m_fields
std::vector< std::unique_ptr< RFieldHandle > > m_fields
Fields containing the various auxiliary variables.
Definition: RAuxStore.cxx:609
xAOD::details::isRegisteredType
bool isRegisteredType(SG::auxid_t auxid)
Check if the auxiliary variable has a registered type.
Definition: isRegisteredType.cxx:11
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
xAOD::RAuxStore::getEntryFor
virtual StatusCode getEntryFor(SG::auxid_t auxid) override
Load a single variable from the input.
Definition: RAuxStore.cxx:780
ReadOfcFromCool.field
field
Definition: ReadOfcFromCool.py:48
Utils.h
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
IOStats.h
xAOD::RAuxStore::getEntry
StatusCode getEntry(std::int64_t entry, int getall=0)
Get entry from the input RNTuple.
Definition: RAuxStore.cxx:691
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:595
xAOD::details::AuxStoreBase::EStructMode::kObjectStore
@ kObjectStore
The object describes a single object.
ReturnCheck.h
xAOD::RAuxStore::setupOutputData
virtual StatusCode setupOutputData(SG::auxid_t auxid) override
Connect a variable to the output.
Definition: RAuxStore.cxx:1010
xAOD::details::AuxStoreBase::EStructMode::kContainerStore
@ kContainerStore
The object describes an entire container.
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
xAOD::RAuxStore::impl::scanInputTuple
StatusCode scanInputTuple()
Scans the input ntuple for auxiliary data fields and sets up the necessary structures to access them.
Definition: RAuxStore.cxx:286
xAOD::RAuxStore::commitTo
StatusCode commitTo(REntry &entry)
Commit a new entry to the output RNTuple.
Definition: RAuxStore.cxx:740
xAOD::details::AuxStoreBase::Members::m_decorIDs
SG::auxid_set_t m_decorIDs
Internal list of auxiliary decoration IDs handled currently by the object.
Definition: AuxStoreBase.h:189
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:598
SG::auxid_t
size_t auxid_t
Identifier for a particular aux data item.
Definition: AuxTypes.h:27
SG::AuxTypeRegistry::getType
const std::type_info * getType(SG::auxid_t auxid) const
Return the type of an aux data item.
Definition: AuxTypeRegistry.cxx:908
H5Utils::internal::packed
H5::CompType packed(H5::CompType in)
Definition: common.cxx:16
xAOD::details::AuxStoreBase::m_data
Members m_data
Member variables of the base class.
Definition: AuxStoreBase.h:201
ReadStats.h
xAOD::RAuxStore::hasEntryFor
virtual bool hasEntryFor(SG::auxid_t auxid) const override
Check if a given variable is available from the input.
Definition: RAuxStore.cxx:774
details
Definition: IParticleWriter.h:21
xAOD::details::AuxStoreBase::mutex_t
AthContainers_detail::mutex mutex_t
Mutex type for multithread synchronization.
Definition: AuxStoreBase.h:204
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
xAOD::RAuxStore::writeTo
StatusCode writeTo(RNTupleWriter &writer)
Add the variables of the store to an output RNTuple.
Definition: RAuxStore.cxx:669
CxxUtils::ConcurrentBitset::insert
ConcurrentBitset & insert(bit_t bit, bit_t new_nbits=0)
Set a bit to 1.
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
Message.h
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
pool::RootCollection::RNTupleWriter
ROOT::Experimental::RNTupleWriter RNTupleWriter
Definition: RNTCollection.h:39
checkCorrelInHIST.prefix
dictionary prefix
Definition: checkCorrelInHIST.py:391
Preparation.mode
mode
Definition: Preparation.py:107
SG::AuxTypeRegistry::isLinkedName
static bool isLinkedName(const std::string &name)
Test if a variable name corresponds to a linked variable.
Definition: AuxTypeRegistry.cxx:1292
SG::IAuxTypeVectorFactory::copy
virtual void copy(SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, const AuxVectorData &src, size_t src_index, size_t n) const =0
Copy elements between vectors.
SG::AuxTypeRegistry::getVecType
const std::type_info * getVecType(SG::auxid_t auxid) const
Return the type of the STL vector used to hold an aux data item.
Definition: AuxTypeRegistry.cxx:936
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
xAOD::RAuxStore::getInputType
virtual const std::type_info * getInputType(SG::auxid_t auxid) const override
Get the type of an input object, for getIOType()
Definition: RAuxStore.cxx:1155
SG::AuxVarFlags
AuxVarFlags
Additional flags to qualify an auxiliary variable.
Definition: AuxTypes.h:58
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
xAOD::details::AuxStoreBase::getSelectedAuxIDs
virtual SG::auxid_set_t getSelectedAuxIDs() const override
Get the IDs of the selected aux variables.
Definition: AuxStoreBase.cxx:623
xAOD::details::AuxStoreBase::isAuxIDSelected
bool isAuxIDSelected(SG::auxid_t auxid) const
Check if an auxiliary variable is selected for ouput writing.
Definition: AuxStoreBase.cxx:639
GetAllXsec.entry
list entry
Definition: GetAllXsec.py:132
SG::AuxTypeRegistry::makeVector
std::unique_ptr< IAuxTypeVector > makeVector(SG::auxid_t auxid, size_t size, size_t capacity) const
Construct a new vector to hold an aux item.
Definition: AuxTypeRegistry.cxx:817
xAOD::details::AuxStoreBase::Members::m_structMode
EStructMode m_structMode
The "structural" mode of the object.
Definition: AuxStoreBase.h:174
xAOD::RAuxStore::setupInputData
virtual StatusCode setupInputData(SG::auxid_t auxid) override
Connect a variable to the input.
Definition: RAuxStore.cxx:803
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:375
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
SG::AuxVectorInterface
Make an AuxVectorData object from either a raw array or an aux store.
Definition: AuxVectorInterface.h:33
xAOD::RAuxStore::impl
Definition: RAuxStore.cxx:277
pool::RootCollection::RNTupleModel
ROOT::Experimental::RNTupleModel RNTupleModel
Definition: RNTCollection.h:40
xAOD::RAuxStore::readFrom
StatusCode readFrom(RNTupleReader &reader)
Connect the object to an input RNTuple.
Definition: RAuxStore.cxx:643
CxxUtils::reset
constexpr std::enable_if_t< is_bitmask_v< E >, E & > reset(E &lhs, E rhs)
Convenience function to clear bits in a class enum bitmask.
Definition: bitmask.h:251
AuxTypeRegistry.h
Handle mappings between names and auxid_t.
convertTimingResiduals.offset
offset
Definition: convertTimingResiduals.py:71
RNTupleReader
ROOT::Experimental::RNTupleReader RNTupleReader
Definition: RNTupleAuxDynStore.h:19
RootStorageSvc::REntry
ROOT::Experimental::REntry REntry
Definition: RNTupleWriterHelper.h:24
xAOD::details::AuxStoreBase::getIOData
virtual const void * getIOData(SG::auxid_t auxid) const override
Get a pointer to the data being stored for one aux data item.
Definition: AuxStoreBase.cxx:510
xAOD::RAuxStore::reset
virtual void reset() override
Tell the object that all branches will need to be re-read.
Definition: RAuxStore.cxx:762
xAOD::RAuxStore::RAuxStore
RAuxStore(std::string_view prefix="", bool topStore=true, EStructMode mode=EStructMode::kUndefinedStore)
Constructor.
Definition: RAuxStore.cxx:620
xAOD::details::AuxStoreBase::EStructMode::kUndefinedStore
@ kUndefinedStore
The structure mode is not defined.
ReadCalibFromCool.typeName
typeName
Definition: ReadCalibFromCool.py:477
SG::auxid_set_t
A set of aux data identifiers.
Definition: AuxTypes.h:47
pickleTool.object
object
Definition: pickleTool.py:30
L1Topo::Error
Error
The different types of error that can be flagged in the L1TopoRDO.
Definition: Error.h:16
xAOD::RAuxStore::m_impl
std::unique_ptr< impl > m_impl
Pointer to the internal object.
Definition: RAuxStore.h:87
collisions.reader
reader
read the goodrunslist xml file(s)
Definition: collisions.py:22
CxxUtils::ConcurrentBitset::erase
ConcurrentBitset & erase(bit_t bit)
Turn off one bit.
xAOD::details::AuxStoreBase::Members::m_isDecoration
std::vector< bool > m_isDecoration
Per variable lock status (indexed by auxiliary ID)
Definition: AuxStoreBase.h:196
example.writer
writer
show summary of content
Definition: example.py:36
AuxStoreInternal.h
An auxiliary data store that holds data internally.
xAOD::details::AuxStoreBase::Members::m_dynPrefix
std::string m_dynPrefix
Dynamic prefix for the branch names.
Definition: AuxStoreBase.h:180
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:26
xAOD::details::AuxStoreBase::Members::m_topStore
bool m_topStore
Flag stating whether this is a "top store".
Definition: AuxStoreBase.h:176
ROOT
Selection rules: declare transient members.
Definition: DataVector.h:580
TAuxVectorFactory.h
xAOD::RAuxStore::impl::m_inputScanned
bool m_inputScanned
"Scan status" of the input RNTuple
Definition: RAuxStore.cxx:603
xAOD::details::AuxStoreBase::Members
Struct collecting all member variables of this base class.
Definition: AuxStoreBase.h:171
CxxUtils::ConcurrentBitset::test
bool test(bit_t bit) const
Test to see if a bit is set.