Loading [MathJax]/extensions/tex2jax.js
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 "ROOTTypes.h"
7 #include "isRegisteredType.h"
8 #include "lookupVectorType.h"
13 
14 // Athena include(s).
18 
19 // ROOT include(s).
20 #include <TClass.h>
21 #include <TROOT.h>
22 
23 // System include(s).
24 #include <cassert>
25 #include <memory>
26 #include <string>
27 
28 namespace {
29 
39 bool isContainerField(const ROOT::RFieldDescriptor& fieldDesc,
40  SG::auxid_t auxid) {
41 
42  // For unknown types it doesn't matter if the field describes a
43  // container or a single element.
44  if (!xAOD::details::isRegisteredType(auxid)) {
45  return true;
46  }
47 
48  // If it's a primitive field, then it's not a container.
49  if (xAOD::Utils::isPrimitiveType(fieldDesc.GetTypeName())) {
50  return false;
51  }
52 
53  // For non-primitive types, get the dictionary of the type.
54  TClass* cl = TClass::GetClass(fieldDesc.GetTypeName().c_str());
55 
56  // If there is no class associated with the field then it should be
57  // a field describing a standalone object. (As it should be a
58  // "primitive" field in this case.)
59  if (!cl) {
60  ::Warning("::isPContainerField",
61  XAOD_MESSAGE("Couldn't get a dictionary for type \"%s\""),
62  fieldDesc.GetTypeName().c_str());
63  return false;
64  }
65 
66  // If there is a class, ask for the type_info of its type:
67  const std::type_info* root_ti = cl->GetTypeInfo();
68  if (!root_ti) {
69  // This may be an emulated class. One known case is when the type name
70  // is saved as "basic_string<char>" rather than "string" by Athena I/O.
71  // (It's not fully understood why this happens for dynamic branches...)
72  // So, let's see if we can get a functional TClass by massaging the
73  // type name a bit.
74  ::TString typeName(cl->GetName());
75  typeName.ReplaceAll("basic_string<char>", "string");
76  ::TClass* newCl = ::TClass::GetClass(typeName);
77  if (newCl) {
78  root_ti = newCl->GetTypeInfo();
79  }
80  }
81  if (!root_ti) {
82  ::Error("::isContainerField",
83  XAOD_MESSAGE("Couldn't get an std::type_info object out of "
84  "type \"%s\""),
85  cl->GetName());
86  return false;
87  }
88 
89  // Ask for the auxiliary type infos:
90  const std::type_info* aux_obj_ti =
92  if (!aux_obj_ti) {
93  ::Error("::isContainerField",
94  XAOD_MESSAGE("Couldn't get std::type_info object for "
95  "auxiliary id: %i"),
96  static_cast<int>(auxid));
97  return false;
98  }
99  const std::type_info* aux_vec_ti =
101  if (!aux_vec_ti) {
102  ::Error("::isContainerField",
103  XAOD_MESSAGE("Couldn't get std::type_info object for "
104  "auxiliary id: %i"),
105  static_cast<int>(auxid));
106  return false;
107  }
108 
109  // Check which one the ROOT type info agrees with:
110  if (*root_ti == *aux_obj_ti) {
111  // This branch describes a single object:
112  return false;
113  } else if (*root_ti == *aux_vec_ti) {
114  // This branch describes a container of objects:
115  return true;
116  }
117 
118  // For enum and vector<enum> types (PFO...) the type given by
119  // the aux type registry is vector<int>. We have to take it into account
120  // here...
121  if (cl->GetCollectionProxy() && (*aux_vec_ti == typeid(std::vector<int>))) {
122  return true;
123  }
124 
125  TClass* cl2 = xAOD::details::lookupVectorType(*cl);
126  if (cl2) {
127  if (*cl2->GetTypeInfo() == *aux_vec_ti) {
128  return true;
129  }
130  }
131 
132  // If we got this far, the branch may have undergone schema evolution. If
133  // it's one that ROOT can deal with itself, then we should still be able
134  // to read the branch with this code.
135  //
136  // Note that even after looking at the ROOT source code, I'm still not
137  // 100% sure whether we would need to delete the objects returned by
138  // TClass::GetConversionStreamerInfo(...) in this code. :-( But based on
139  // general experience with the ROOT code, I'm going to say no...
140  TClass* aux_vec_cl =
141  TClass::GetClass(xAOD::Utils::getTypeName(*aux_vec_ti).c_str());
142  if (aux_vec_cl &&
143  aux_vec_cl->GetConversionStreamerInfo(cl, cl->GetClassVersion())) {
144  return true;
145  }
146  TClass* aux_obj_cl =
147  TClass::GetClass(xAOD::Utils::getTypeName(*aux_obj_ti).c_str());
148  if (aux_obj_cl &&
149  aux_obj_cl->GetConversionStreamerInfo(cl, cl->GetClassVersion())) {
150  return false;
151  }
152 
153  // If neither, then something went wrong...
154  ::Error("::isContainerField",
155  XAOD_MESSAGE("Couldn't determine if field describes a single "
156  "object or a container"));
157  ::Error("::isContainerField", XAOD_MESSAGE("ROOT type : %s"),
158  xAOD::Utils::getTypeName(*root_ti).c_str());
159  ::Error("::isContainerField", XAOD_MESSAGE("Object type: %s"),
160  xAOD::Utils::getTypeName(*aux_obj_ti).c_str());
161  ::Error("::isContainerField", XAOD_MESSAGE("Vector type: %s"),
162  xAOD::Utils::getTypeName(*aux_vec_ti).c_str());
163  return kFALSE;
164 }
165 
167 class RFieldHandle {
168 
169  public:
171  RFieldHandle(ROOT::RNTupleView<void> field, SG::auxid_t auxid,
172  std::string_view prefix, void* object, const std::type_info* ti)
173  : m_field(std::move(field)),
174  m_auxid(auxid),
175  m_prefix(prefix),
176  m_object(object),
177  m_typeInfo(ti) {}
178 
180  StatusCode getEntry(::Long64_t entry) {
181 
182  // Check if anything needs to be done:
183  if ((m_entry == entry) && (!m_needsRead)) {
184  return StatusCode::SUCCESS;
185  }
186 
187  try {
188  // Load the entry
189  m_field(entry);
190  } catch (const ROOT::RException& e) {
191  ::Error("::RFieldInfo::getEntry",
192  "Failed to load entry %lld for field %s.%s: %s", entry,
193  m_prefix.data(),
194  SG::AuxTypeRegistry::instance().getName(m_auxid).c_str(),
195  e.what());
196  return StatusCode::FAILURE;
197  }
198 
199  // Remember what entry was loaded for this field.
200  m_entry = entry;
201  m_needsRead = false;
202  return StatusCode::SUCCESS;
203  }
204 
211  void* objectPtr() { return m_object; }
212 
214  const std::type_info* typeInfo() const { return m_typeInfo; }
215 
217  void reset() { m_needsRead = true; }
218 
219  private:
221  ROOT::RNTupleView<void> m_field;
223  SG::auxid_t m_auxid;
225  std::string_view m_prefix;
227  void* m_object = nullptr;
229  const std::type_info* m_typeInfo = nullptr;
231  ::Long64_t m_entry = -1;
233  bool m_needsRead = true;
234 
235 }; // class RFieldInfo
236 
237 bool fieldExists(std::string_view fieldName,
238  ROOT::RNTupleReader& ntupleReader) {
239  // If it cannot find a field id it will give the maximum value of
240  // unsigned long
241  return (ntupleReader.GetDescriptor().FindFieldId(fieldName) !=
243 }
244 
245 } // namespace
246 
247 namespace xAOD {
248 
250 
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 name of this sub-field.
296  const std::string subFieldName = subField->GetQualifiedFieldName();
297  const std::string subAuxName =
298  subFieldName.substr(subFieldName.find(".") + 1);
299 
300  // Skip this entry if it refers to a base class.
301  if (subAuxName.starts_with("xAOD::") ||
302  subAuxName.starts_with("SG::") ||
303  subAuxName.starts_with("ILockable")) {
304  continue;
305  }
306 
307  // Set up this field.
308  RETURN_CHECK("xAOD::RAuxStore::impl::scanInputNtuple",
309  setupAuxField(*subField, subAuxName));
310  }
311  // Don't check the rest of the loop's body:
312  continue;
313  }
314 
315  // if fieldname doesnt start with the value of m_dynPrefix, skip
316  if (fieldName.starts_with(m_data.m_dynPrefix) == false) {
317  continue;
318  }
319  if (fieldName == m_data.m_dynPrefix) {
320  ::Error("xAOD::RAuxStore::impl::scanInputNtuple",
321  "Dynamic field with empty name found on container: %s",
322  m_data.m_prefix.c_str());
323  continue;
324  }
325  // The auxiliary property name:
326  const std::string auxName = fieldName.substr(fieldName.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  }
337 
347  const std::type_info* auxFieldType(const ROOT::RFieldBase& field,
348  std::string* expectedClassName = nullptr) {
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  }
408 
421  StatusCode setupAuxField(const ROOT::RFieldBase& field,
422  std::string_view auxName) {
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  if (const SG::auxid_t regAuxid = registry.findAuxID(std::string{auxName});
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(std::string{auxName})) {
449  } else if (SG::AuxTypeRegistry::classNameHasLink(expectedClassName)) {
450  const std::string linkedAttr =
451  SG::AuxTypeRegistry::linkedName(std::string{auxName});
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, std::string{auxName}, "", 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, std::string{auxName}, "", 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, std::string{auxName}, "",
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  }
565 
568 
570  ROOT::RNTupleReader* m_inTuple = nullptr;
572  ROOT::RNTupleWriter* m_outTuple = nullptr;
573 
575  bool m_inputScanned = false;
576 
578  ::Long64_t m_entry;
579 
581  std::vector<std::unique_ptr<RFieldHandle> > m_fields;
583  std::vector<bool> m_fieldsWritten;
585  std::vector<bool> m_missingFields;
586 
588  mutable mutex_t m_mutex;
589 
590 }; // struct RAuxStore::impl
591 
592 RAuxStore::RAuxStore(std::string_view prefix, bool topStore, EStructMode mode)
593  : details::AuxStoreBase(topStore, mode),
594  m_impl{std::make_unique<impl>(m_data)} {
595 
596  setPrefix(prefix);
597 }
598 
599 RAuxStore::~RAuxStore() = default;
600 
601 void RAuxStore::setPrefix(std::string_view prefix) {
602 
605  reset();
606 }
607 
615 StatusCode RAuxStore::readFrom(ROOT::RNTupleReader& reader) {
616 
617  assert(m_impl);
618 
619  // Make sure that everything will be re-read after this:
620  reset();
621 
622  // We will need to check again which branches are available:
623  m_impl->m_missingFields.clear();
624 
625  // Remember the tree:
626  m_impl->m_inTuple = &reader;
627 
628  // Catalogue all the branches:
629  RETURN_CHECK("xAOD::RAuxStore::readFrom", m_impl->scanInputTuple());
630 
631  // Return gracefully.
632  return StatusCode::SUCCESS;
633 }
634 
641 StatusCode RAuxStore::writeTo(ROOT::RNTupleWriter& writer) {
642 
643  assert(m_impl);
644 
645  // Look for any auxiliary fields that have not been connected to yet.
646  RETURN_CHECK("xAOD::RAuxStore::writeTo", m_impl->scanInputTuple());
647 
648  // Put the object into "output writing" mode.
649  m_impl->m_outTuple = &writer;
650 
651  // Create all the variables that we already know about. Notice that the
652  // code makes a copy of the auxid set on purpose. Because the underlying
653  // AuxSelection object gets modified while doing the for loop.
654  const SG::auxid_set_t selAuxIDs = getSelectedAuxIDs();
655  for (SG::auxid_t id : selAuxIDs) {
656  RETURN_CHECK("xAOD::RAuxStore::writeTo", setupOutputData(id));
657  }
658 
659  // Return gracefully.
660  return StatusCode::SUCCESS;
661 }
662 
663 StatusCode RAuxStore::getEntry(std::int64_t entry, int getall) {
664 
665  assert(m_impl);
666 
667  // Guard against multi-threaded execution:
668  guard_t guard(m_impl->m_mutex);
669 
670  m_impl->m_entry = entry;
671 
672  // Reset the transient store. TEvent::fill() calls this function with
673  // getall==99. When that is happening, we need to keep the transient
674  // store still around. Since the user may want to interact with the
675  // object after it was written out. (And since TEvent::fill() asks for
676  // the transient decorations after calling getEntry(...).)
677  if (m_data.m_transientStore && (getall != 99)) {
678  // Remove the transient auxiliary IDs from the internal list:
679  m_data.m_auxIDs -= m_data.m_transientStore->getAuxIDs();
680  m_data.m_decorIDs -= m_data.m_transientStore->getDecorIDs();
681  // Delete the object:
682  m_data.m_transientStore.reset();
683  }
684 
685  // Now remove the IDs of the decorations that are getting persistified:
686  if (getall != 99) {
687  for (SG::auxid_t auxid = 0; auxid < m_data.m_isDecoration.size(); ++auxid) {
688  if (!m_data.m_isDecoration[auxid]) {
689  continue;
690  }
691  m_data.m_auxIDs.erase(auxid);
692  m_data.m_decorIDs.erase(auxid);
693  }
694  }
695 
696  // If we don't need everything loaded, return now:
697  if (!getall) {
698  return StatusCode::SUCCESS;
699  }
700 
701  // Get all the variables at once:
702  for (auto& field : m_impl->m_fields) {
703  if (field) {
704  RETURN_CHECK("xAOD::RAuxStore::getEntry", field->getEntry(entry));
705  }
706  }
707 
708  // Return gracefully.
709  return StatusCode::SUCCESS;
710 }
711 
713 
714  assert(m_impl);
715 
716  // Loop through all of the output variables.
717  for (SG::auxid_t id : getSelectedAuxIDs()) {
718  // Now connect the output entry to the variable.
719  const std::string fieldName =
722  void* fieldPtr = const_cast<void*>(getIOData(id));
723  if (fieldPtr) {
724  entry.BindRawPtr(fieldName, fieldPtr);
725  } else {
726  entry.EmplaceNewValue(fieldName);
727  }
728  }
729 
730  // Return gracefully.
731  return StatusCode::SUCCESS;
732 }
733 
735 
736  assert(m_impl);
737 
738  for (auto& field : m_impl->m_fields) {
739  if (field) {
740  field->reset();
741  }
742  }
743  m_impl->m_inputScanned = false;
744 }
745 
747 
748  assert(m_impl);
749  return ((m_impl->m_fields.size() > auxid) && m_impl->m_fields[auxid]);
750 }
751 
753 
754  assert(m_impl);
755  assert(m_impl->m_fields.size() > auxid);
756  assert(m_impl->m_fields[auxid]);
757  RETURN_CHECK("xAOD::RAuxStore::getEntryFor",
758  m_impl->m_fields[auxid]->getEntry(m_impl->m_entry));
759  return StatusCode::SUCCESS;
760 }
761 
762 bool RAuxStore::hasOutput() const {
763 
764  assert(m_impl);
765  return (m_impl->m_outTuple != nullptr);
766 }
767 
776 
777  // Return right away if we already know that the field is missing.
778  if ((auxid < m_impl->m_missingFields.size()) &&
779  m_impl->m_missingFields[auxid]) {
780  return StatusCode::RECOVERABLE;
781  }
782 
783  // We may call this function without an input being used. That's not an
784  // error either.
785  if (m_impl->m_inTuple == nullptr) {
786  return StatusCode::RECOVERABLE;
787  }
788 
789  // Make sure the internal storage is large enough:
790  if (m_data.m_vecs.size() <= auxid) {
791  m_data.m_vecs.resize(auxid + 1);
792  }
793  if (m_impl->m_fields.size() <= auxid) {
794  m_impl->m_fields.resize(auxid + 1);
795  }
796 
797  // Check if we need to do anything. Remember, output-only variables don't
798  // have an associated RFieldHandle. To tell the caller that no input is
799  // actually available for the variable (only an output), use a different
800  // return value.
801  if (m_data.m_vecs[auxid]) {
802  return (m_impl->m_fields[auxid] ? StatusCode::SUCCESS
803  : StatusCode::RECOVERABLE);
804  }
805 
806  // Convenience access to the registry.
808 
809  // Get the property name:
810  const std::string statFieldName =
811  std::format("{}{}", m_data.m_prefix, r.getName(auxid));
812  const std::string dynFieldName =
813  std::format("{}{}", m_data.m_dynPrefix, r.getName(auxid));
814 
815  // Check if the field exists:
816  std::string fieldName = statFieldName;
817  ROOT::DescriptorId_t fieldId;
818  if ((fieldId = m_impl->m_inTuple->GetDescriptor().FindFieldId(
819  statFieldName)) == std::numeric_limits<unsigned long>::max()) {
820  if ((fieldId = m_impl->m_inTuple->GetDescriptor().FindFieldId(
821  dynFieldName)) == std::numeric_limits<unsigned long>::max()) {
822  // Remember that the field is missing.
823  if (m_impl->m_missingFields.size() <= auxid) {
824  m_impl->m_missingFields.resize(auxid + 1);
825  }
826  m_impl->m_missingFields[auxid] = true;
827  // The field doesn't exist, but this is not an error per se.
828  // The user may just be calling isAvailable(...) on the variable.
829  return StatusCode::RECOVERABLE;
830  }
831  // We have a dynamic field:
832  fieldName = dynFieldName;
833  }
834 
835  // Get the object describing this field.
836  const ROOT::RFieldDescriptor& fieldDesc =
837  m_impl->m_inTuple->GetDescriptor().GetFieldDescriptor(fieldId);
838 
839  // Check if it's a "primitive field":
840  const bool primitiveField = Utils::isPrimitiveType(fieldDesc.GetTypeName());
841  // Check if it's a "container field":
842  const bool containerField =
843  (primitiveField ? false : isContainerField(fieldDesc, auxid));
844 
845  // Set the structure mode if it has not been defined externally:
849  }
850 
851  // Check that the branch type makes sense:
852  if ((containerField &&
854  !r.isLinked(auxid)) ||
855  ((!containerField) &&
857  ::Error("xAOD::RAuxStore::setupInputData",
858  XAOD_MESSAGE("Field type and requested structure mode "
859  "differ for field: %s"),
860  fieldName.c_str());
861  return StatusCode::FAILURE;
862  }
863 
864  // Get the property type:
865  const std::type_info* fieldType = nullptr;
866  if (details::isRegisteredType(auxid)) {
867  // Get the type from the auxiliary type registry:
868  fieldType = (containerField ? r.getVecType(auxid) : r.getType(auxid));
869  } else {
870  // Get the type from the input field itself:
871  TClass* clDummy = ::TClass::GetClass(fieldDesc.GetTypeName().c_str());
872  fieldType = (clDummy ? clDummy->GetTypeInfo()
873  : &(Utils::getTypeInfo(fieldDesc.GetTypeName())));
874  }
875  if (!fieldType) {
876  ::Error("xAOD::RAuxStore::setupInputData",
877  XAOD_MESSAGE("Can't read/copy variable %s (%s)"), fieldName.c_str(),
878  fieldDesc.GetTypeName().c_str());
879  return StatusCode::RECOVERABLE;
880  }
881  const TString fieldTypeName = Utils::getTypeName(*fieldType).c_str();
882 
883  // Check if we have the needed dictionary for an object field:
884  ::TClass* fieldClass = nullptr;
885  if (!primitiveField) {
886  // Get the property's class:
887  fieldClass = ::TClass::GetClass(*fieldType, true, true);
888  if (!fieldClass) {
889  fieldClass = ::TClass::GetClass(fieldTypeName);
890  }
891  if (!fieldClass) {
892  ::Error("xAOD::RAuxStore::setupInputData",
893  XAOD_MESSAGE("No dictionary available for class \"%s\""),
894  fieldTypeName.Data());
895  return StatusCode::FAILURE;
896  }
897  }
898 
899  // Create the smart object holding this vector:
900  if (details::isRegisteredType(auxid)) {
901  m_data.m_vecs[auxid] = r.makeVector(auxid, (size_t)0, (size_t)0);
902  if (!containerField) {
903  m_data.m_vecs[auxid]->resize(1);
904  }
905  if (fieldClass &&
906  strncmp(fieldClass->GetName(), "SG::PackedContainer<", 20) == 0) {
907  std::unique_ptr<SG::IAuxTypeVector> packed =
908  m_data.m_vecs[auxid]->toPacked();
909  std::swap(m_data.m_vecs[auxid], packed);
910  }
911  } else {
912  ::Error("xAOD::RAuxStore::setupInputData",
913  XAOD_MESSAGE("Couldn't create in-memory vector for "
914  "variable %s (%i)"),
915  fieldName.c_str(), static_cast<int>(auxid));
916  return StatusCode::FAILURE;
917  }
918 
919  // Access/create the field, and create a field handle object.
920  void* objectPtr = (containerField ? m_data.m_vecs[auxid]->toVector()
921  : m_data.m_vecs[auxid]->toPtr());
922  m_impl->m_fields[auxid] = std::make_unique<RFieldHandle>(
923  m_impl->m_inTuple->GetView<void>(fieldName.c_str(), objectPtr), auxid,
924  m_data.m_prefix, objectPtr, fieldType);
925 
926  // Get the current entry.
927  RETURN_CHECK("xAOD::RAuxStore::setupInputData",
928  m_impl->m_fields[auxid]->getEntry(m_impl->m_entry));
929 
930  // Remember which variable got created:
931  m_data.m_auxIDs.insert(auxid);
932 
933  // Check if we just replaced a generic object:
934  if (details::isRegisteredType(auxid)) {
935  // The name of the variable we just created:
936  const std::string auxname = r.getName(auxid);
937  // Check if there's another variable with this name already:
938  for (SG::auxid_t i = 0; i < m_data.m_vecs.size(); ++i) {
939  // Check if we have this aux ID:
940  if (!m_data.m_vecs[i]) {
941  continue;
942  }
943  // Ingore the object that we *just* created:
944  if (i == auxid) {
945  continue;
946  }
947  // The name of the variable:
948  const std::string testname = r.getName(i);
949  // Check if it has the same name:
950  if (testname != auxname) {
951  continue;
952  }
953  // Check that the other one is a non-registered type:
955  ::Error("xAOD::RAuxStore::setupInputData",
956  XAOD_MESSAGE("Internal logic error!"));
957  continue;
958  }
959  // Okay, we do need to remove this object:
960  m_data.m_vecs[i].reset();
961  m_impl->m_fields[i].reset();
963  }
964  }
965 
966  SG::auxid_t linked_auxid = r.linkedVariable(auxid);
967  if (linked_auxid != SG::null_auxid) {
968  return setupInputData(linked_auxid);
969  }
970 
971  // Return gracefully:
972  return StatusCode::SUCCESS;
973 }
974 
983 
984  assert(m_impl);
985 
986  // Check whether we need to do anything.
987  if (!m_impl->m_outTuple) {
988  return StatusCode::SUCCESS;
989  }
990 
991  // Check if the variable needs to be written out.
992  if (!isAuxIDSelected(auxid)) {
993  return StatusCode::SUCCESS;
994  }
995 
996  // Make sure that containers are large enough:
997  if (m_data.m_vecs.size() <= auxid) {
998  m_data.m_vecs.resize(auxid + 1);
999  }
1000  if (m_impl->m_fieldsWritten.size() <= auxid) {
1001  m_impl->m_fieldsWritten.resize(auxid + 1);
1002  }
1003 
1004  // Check if this auxiliary variable is already in the output:
1005  if (m_impl->m_fieldsWritten[auxid]) {
1006  return StatusCode::SUCCESS;
1007  }
1008 
1009  // After this point, we either succeed with setting up the writing of this
1010  // variable, or the code fails completely. So let's set this flag already,
1011  // as unfortunately we can recursively end up here using the code below.
1012  m_impl->m_fieldsWritten[auxid] = true;
1013 
1014  // The registry:
1016 
1017  // Check if the variable was put into the transient store as a
1018  // decoration, and now needs to be put into the output file:
1019  if ((!m_data.m_vecs[auxid]) && m_data.m_transientStore &&
1020  (m_data.m_transientStore->getAuxIDs().test(auxid))) {
1021 
1022  // Get the variable from the transient store:
1023  const void* pptr = m_data.m_transientStore->getData(auxid);
1024  if (!pptr) {
1025  ::Fatal("xAOD::RAuxStore::setupOutputData",
1026  XAOD_MESSAGE("Internal logic error detected"));
1027  return StatusCode::FAILURE;
1028  }
1029 
1030  // Create the new object:
1031  m_data.m_vecs[auxid] = reg.makeVector(auxid, m_data.m_size, m_data.m_size);
1032  void* ptr = m_data.m_vecs[auxid]->toPtr();
1033  if (!ptr) {
1034  ::Error("xAOD::RAuxStore::setupOutputData",
1035  XAOD_MESSAGE("Couldn't create decoration in memory "
1036  "for writing"));
1037  return StatusCode::FAILURE;
1038  }
1039 
1040  // Get the type of this variable:
1041  const std::type_info* type = reg.getType(auxid);
1042  if (!type) {
1043  ::Error("xAOD::RAuxStore::setupOutputData",
1044  XAOD_MESSAGE("Couldn't get the type of transient "
1045  "variable %i"),
1046  static_cast<int>(auxid));
1047  return StatusCode::FAILURE;
1048  }
1049  // Now get the factory for this variable:
1050  const SG::IAuxTypeVectorFactory* factory = reg.getFactory(auxid);
1051  if (!factory) {
1052  ::Error("xAOD::RAuxStore::setupOutputData",
1053  XAOD_MESSAGE("No factory found for transient variable "
1054  "%i"),
1055  static_cast<int>(auxid));
1056  return StatusCode::FAILURE;
1057  }
1058 
1059  // Mark it as a decoration already, otherwise the copy may fail.
1060  if (m_data.m_isDecoration.size() <= auxid) {
1061  m_data.m_isDecoration.resize(auxid + 1);
1062  }
1063  m_data.m_isDecoration[auxid] = true;
1064 
1065  // Finally, do the copy, and remove the variable from the transient store.
1066  factory->copy(auxid, SG::AuxVectorInterface(*this), 0,
1068  m_data.m_size);
1069  }
1070 
1071  // Check if we know about this variable to be on the input,
1072  // but haven't connected to it yet:
1073  if ((m_data.m_auxIDs.test(auxid)) && (!m_data.m_vecs[auxid]) &&
1074  (!m_impl->m_fields[auxid])) {
1075  RETURN_CHECK("xAOD::RAuxStore::setupOutputData", setupInputData(auxid));
1076  }
1077 
1078  // Check that we know the store's type:
1081  ::Error("xAOD::RAuxStore::setupOutputData",
1082  XAOD_MESSAGE("Structure mode unknown for variable %s"),
1083  reg.getName(auxid).c_str());
1084  return StatusCode::FAILURE;
1085  }
1086 
1087  // Check if the variable exists already in memory:
1088  if (!m_data.m_vecs[auxid]) {
1089  m_data.m_vecs[auxid] = reg.makeVector(auxid, (size_t)0, (size_t)0);
1091  m_data.m_vecs[auxid]->resize(1);
1092  }
1093  }
1094 
1095  // Figure out the type and name of the output field.
1096  const std::string fieldName =
1097  std::format("{}{}", m_data.m_dynPrefix, reg.getName(auxid));
1098  const std::string typeName = SG::normalizedTypeinfoName(
1100  ? reg.getVecType(auxid)
1101  : reg.getType(auxid)));
1102 
1103  // Update the output ntuple's model.
1104  {
1105  auto field = ROOT::RFieldBase::Create(fieldName, typeName).Unwrap();
1106  auto updater = m_impl->m_outTuple->CreateModelUpdater();
1107  updater->BeginUpdate();
1108  updater->AddField(std::move(field));
1109  updater->CommitUpdate();
1110  }
1111 
1112  // Remember that we now handle this variable.
1113  m_data.m_auxIDs.insert(auxid);
1114 
1115  // We were successful:
1116  return StatusCode::SUCCESS;
1117 }
1118 
1119 const void* RAuxStore::getInputObject(SG::auxid_t auxid) const {
1120 
1121  assert(m_impl);
1122  assert(m_impl->m_fields.size() > auxid);
1123  assert(m_impl->m_fields[auxid]);
1124  return m_impl->m_fields[auxid]->objectPtr();
1125 }
1126 
1127 const std::type_info* RAuxStore::getInputType(SG::auxid_t auxid) const {
1128 
1129  assert(m_impl);
1130  assert(m_impl->m_fields.size() > auxid);
1131  assert(m_impl->m_fields[auxid]);
1132  return m_impl->m_fields[auxid]->typeInfo();
1133 }
1134 
1135 } // 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:762
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:583
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:578
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
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:601
xAOD::RAuxStore::impl::m_missingFields
std::vector< bool > m_missingFields
Mark fields we've found to be missing.
Definition: RAuxStore.cxx:585
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
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
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:1119
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:572
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:588
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:581
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:752
ReadOfcFromCool.field
field
Definition: ReadOfcFromCool.py:48
Utils.h
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
xAOD::RAuxStore::getEntry
StatusCode getEntry(std::int64_t entry, int getall=0)
Get entry from the input RNTuple.
Definition: RAuxStore.cxx:663
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:567
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:982
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:258
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:570
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
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:746
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
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
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:1127
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
xAOD::RAuxStore::readFrom
StatusCode readFrom(ROOT::RNTupleReader &reader)
Connect the object to an input RNTuple.
Definition: RAuxStore.cxx:615
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
ROOTTypes.h
xAOD::RAuxStore::setupInputData
virtual StatusCode setupInputData(SG::auxid_t auxid) override
Connect a variable to the input.
Definition: RAuxStore.cxx:775
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
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:249
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
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:734
xAOD::RAuxStore::RAuxStore
RAuxStore(std::string_view prefix="", bool topStore=true, EStructMode mode=EStructMode::kUndefinedStore)
Constructor.
Definition: RAuxStore.cxx:592
xAOD::details::AuxStoreBase::EStructMode::kUndefinedStore
@ kUndefinedStore
The structure mode is not defined.
ReadCalibFromCool.typeName
typeName
Definition: ReadCalibFromCool.py:477
xAOD::RAuxStore::writeTo
StatusCode writeTo(ROOT::RNTupleWriter &writer)
Add the variables of the store to an output RNTuple.
Definition: RAuxStore.cxx:641
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
TAuxVectorFactory.h
xAOD::RAuxStore::commitTo
StatusCode commitTo(ROOT::REntry &entry)
Commit a new entry to the output RNTuple.
Definition: RAuxStore.cxx:712
xAOD::RAuxStore::impl::m_inputScanned
bool m_inputScanned
"Scan status" of the input RNTuple
Definition: RAuxStore.cxx:575
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.