ATLAS Offline Software
Loading...
Searching...
No Matches
xAOD::TAuxStore Class Referenceabstract

"ROOT @c TTree implementation" of IAuxStore More...

#include <TAuxStore.h>

Inheritance diagram for xAOD::TAuxStore:
Collaboration diagram for xAOD::TAuxStore:

Classes

struct  impl

Public Types

enum class  EStructMode { kUndefinedStore = 0 , kContainerStore = 1 , kObjectStore = 2 }
 "Structural" modes of the object More...

Public Member Functions

 TAuxStore (const EventContext &ctx, std::string_view prefix="", bool topStore=true, EStructMode mode=EStructMode::kUndefinedStore, int basketSize=2048, int splitLevel=0)
 Constructor.
virtual ~TAuxStore ()
 Destructor.
virtual void setPrefix (std::string_view prefix) override
 Set the object name prefix.
int basketSize () const
 Get the size of the baskets created for the output branches.
void setBasketSize (int value)
 Set the size of the baskets created for the output branches.
int splitLevel () const
 Get the split level of the output branches.
void setSplitLevel (int value)
 Set the split level of the output branches.
StatusCode readFrom (::TTree &tree, bool printWarnings=true)
 Connect the object to an input TTree.
StatusCode writeTo (::TTree &tree)
 Connect the object to an output TTree.
int getEntry (int getall=0)
 Read the values from the TTree entry that was loaded with TTree::LoadTree().
EStructMode structMode () const
 Get what structure mode the object was constructed with.
void setStructMode (EStructMode mode)
 Set the structure mode of the object to a new value.
const std::string & prefix () const
 Get the currently configured object name prefix.
bool isTopStore () const
 Check if the object is a "top store", or not.
void setTopStore (bool value=true)
 Set whether the object should behave as a "top store" or not.
virtual void * getData (auxid_t auxid, size_t size, size_t capacity)=0
 Return the data vector for one aux data item.
virtual bool resize (size_t sz)=0
 Change the size of all aux data vectors.
virtual void reserve (size_t sz)=0
 Change the capacity of all aux data vectors.
virtual void shift (size_t pos, ptrdiff_t offs)=0
 Shift the elements of the container.
virtual bool insertMove (size_t pos, IAuxStore &other, const SG::auxid_set_t &ignore=SG::auxid_set_t())=0
 Move all elements from other to this store.
virtual bool setOption (auxid_t, const AuxDataOption &)
 Set an option for a given auxiliary variable.
Functions implementing the @c SG::IConstAuxStore interface
virtual const void * getData (SG::auxid_t auxid) const override
 Get a pointer to a given array.
virtual const SG::IAuxTypeVectorgetVector (SG::auxid_t auxid) const override
 Return vector interface for one aux data item.
virtual const SG::auxid_set_tgetAuxIDs () const override
 Get the types(names) of variables handled by this container.
virtual const SG::auxid_set_tgetDecorIDs () const override
 Get the types(names) of decorations handled by this container.
virtual void * getDecoration (SG::auxid_t auxid, std::size_t size, std::size_t capacity) override
 Get a pointer to a given array, creating the array if necessary.
virtual SG::auxid_set_t getCopyIDs (bool warnUnlocked=false) const override
 Get the set of variables that we should deep copy.
virtual bool isDecoration (SG::auxid_t auxid) const override
 Test if a variable is a decoration.
virtual void lock () override
 Lock the object, and don't let decorations be added.
virtual bool clearDecorations () override
 Remove the decorations added so far.
virtual void lockDecoration (SG::auxid_t auxid) override
 Lock a decoration.
virtual std::size_t size () const override
 Return the number of elements in the store.
virtual const SG::IAuxTypeVectorlinkedVector (SG::auxid_t auxid) const override
 Return (const) interface for a linked variable.
virtual SG::IAuxTypeVectorlinkedVector (SG::auxid_t auxid) override
 Return (non-const) interface for a linked variable.
virtual void toTransient (const EventContext &ctx) override
 Call toTransient on contained variables.
Functions implementing the @c SG::IAuxStore interface
virtual void * getData (SG::auxid_t auxid, std::size_t size, std::size_t capacity) override
 Get a pointer to a given array, creating the array if necessary.
virtual const SG::auxid_set_tgetWritableAuxIDs () const override
 Return a set of writable data identifiers.
virtual bool resize (std::size_t size) override
 Resize the arrays to a given size.
virtual void reserve (std::size_t size) override
 Reserve a given size for the arrays.
virtual void shift (std::size_t pos, std::ptrdiff_t offs) override
 Shift the contents of the stored arrays.
virtual bool insertMove (std::size_t pos, SG::IAuxStore &other, const SG::auxid_set_t &ignore) override
 Insert contents of another store via move.
Functions implementing the SG::IAuxStoreIO interface
virtual const void * getIOData (SG::auxid_t auxid) const override
 Get a pointer to the data being stored for one aux data item.
virtual const std::type_info * getIOType (SG::auxid_t auxid) const override
 Return the type of the data to be stored for one aux data item.
virtual const SG::auxid_set_tgetDynamicAuxIDs () const override
 Get the types(names) of variables created dynamically.
virtual void selectAux (const std::set< std::string > &attributes)
 Select dynamic auxiliary attributes for writing.
virtual SG::auxid_set_t getSelectedAuxIDs () const override
 Get the IDs of the selected aux variables.

Static Public Attributes

static constexpr bool supportsThinning = true
 Mark that this type supports thinning operations.

Protected Types

using mutex_t = AthContainers_detail::mutex
 Mutex type for multithread synchronization.
using guard_t = AthContainers_detail::lock_guard<mutex_t>
 Guard type for multithreaded synchronisation.

Protected Member Functions

bool isAuxIDSelected (SG::auxid_t auxid) const
 Check if an auxiliary variable is selected for ouput writing.

Protected Attributes

Members m_data
 Member variables of the base class.

Private Attributes

std::unique_ptr< implm_impl
 Pointer to the internal object.
AuxSelection m_selection
 Object helping to select which auxiliary variables to write.
bool m_locked = false
 Is this container locked?
mutex_t m_mutex1
 Mutex objects used for multithreaded synchronisation.
mutex_t m_mutex2

Functions implementing functionality for @c AuxStoreBase

virtual void reset () override
 Tell the object that all branches will need to be re-read.
virtual bool hasEntryFor (SG::auxid_t auxid) const override
 Check if a given variable is available from the input.
virtual StatusCode getEntryFor (SG::auxid_t auxid) override
 Load a single variable from the input.
virtual bool hasOutput () const override
 Check if an output is being written by the object.
virtual StatusCode setupInputData (SG::auxid_t auxid) override
 Connect a variable to the input.
virtual StatusCode setupOutputData (SG::auxid_t auxid) override
 Connect a variable to the output.
virtual const void * getInputObject (SG::auxid_t auxid) const override
 Get a pointer to an input object, as it is in memory, for getIOData().
virtual const std::type_info * getInputType (SG::auxid_t auxid) const override
 Get the type of an input object, for getIOType().

Detailed Description

"ROOT @c TTree implementation" of IAuxStore

This is a "D3PDReader-like" implementation for the auxiliary store interface. It is meant to provide very efficient access to a relatively small number of auxiliary variables.

Author
Attila Krasznahorkay Attil.nosp@m.a.Kr.nosp@m.aszna.nosp@m.hork.nosp@m.ay@ce.nosp@m.rn.c.nosp@m.h

Definition at line 31 of file TAuxStore.h.

Member Typedef Documentation

◆ guard_t

Guard type for multithreaded synchronisation.

Definition at line 212 of file AuxStoreBase.h.

◆ mutex_t

Mutex type for multithread synchronization.

Definition at line 210 of file AuxStoreBase.h.

Member Enumeration Documentation

◆ EStructMode

enum class xAOD::details::AuxStoreBase::EStructMode
stronginherited

"Structural" modes of the object

Enumerator
kUndefinedStore 

The structure mode is not defined.

kContainerStore 

The object describes an entire container.

kObjectStore 

The object describes a single object.

Definition at line 30 of file AuxStoreBase.h.

30 {
31 kUndefinedStore = 0,
32 kContainerStore = 1,
33 kObjectStore = 2
34 };

Constructor & Destructor Documentation

◆ TAuxStore()

xAOD::TAuxStore::TAuxStore ( const EventContext & ctx,
std::string_view prefix = "",
bool topStore = true,
EStructMode mode = EStructMode::kUndefinedStore,
int basketSize = 2048,
int splitLevel = 0 )

Constructor.

Definition at line 831 of file TAuxStore.cxx.

834 : details::AuxStoreBase(topStore, mode),
835 m_impl{std::make_unique<impl>(ctx, m_data, basketSize, splitLevel)} {
836
838}
int splitLevel() const
Get the split level of the output branches.
virtual void setPrefix(std::string_view prefix) override
Set the object name prefix.
std::unique_ptr< impl > m_impl
Pointer to the internal object.
Definition TAuxStore.h:93
int basketSize() const
Get the size of the baskets created for the output branches.
const std::string & prefix() const
Get the currently configured object name prefix.
Members m_data
Member variables of the base class.

◆ ~TAuxStore()

xAOD::TAuxStore::~TAuxStore ( )
virtualdefault

Destructor.

Member Function Documentation

◆ basketSize()

int xAOD::TAuxStore::basketSize ( ) const

Get the size of the baskets created for the output branches.

Definition at line 849 of file TAuxStore.cxx.

849 {
850
851 assert(m_impl);
852 return m_impl->m_basketSize;
853}

◆ clearDecorations()

bool xAOD::details::AuxStoreBase::clearDecorations ( )
overridevirtualinherited

Remove the decorations added so far.

Only works for transient decorations.

Definition at line 222 of file AuxStoreBase.cxx.

222 {
223
224 // Guard against multi-threaded execution:
225 guard_t guard(m_mutex1);
226
227 // Clear the transient decorations:
228 bool anycleared = false;
229 if (m_data.m_transientStore) {
230 SG::auxid_set_t old_id_set = m_data.m_transientStore->getAuxIDs();
231
232 // Clear the decorations from the transient store:
233 anycleared = m_data.m_transientStore->clearDecorations();
234
235 // Now remove ids that were cleared.
236 if (anycleared) {
237 old_id_set -= m_data.m_transientStore->getAuxIDs();
238 // old_id_set is now the set of ids that were cleared.
239 m_data.m_auxIDs -= old_id_set;
240 m_data.m_decorIDs.clear();
241 }
242 }
243
244 // The decorations which are going into the output file, are here to stay.
245 // Removing their IDs from the internal set would just cause more problems
246 // in my mind than just leaving them be.
247
248 return anycleared;
249}
mutex_t m_mutex1
Mutex objects used for multithreaded synchronisation.
AthContainers_detail::lock_guard< mutex_t > guard_t
Guard type for multithreaded synchronisation.

◆ getAuxIDs()

const SG::auxid_set_t & xAOD::details::AuxStoreBase::getAuxIDs ( ) const
overridevirtualinherited

Get the types(names) of variables handled by this container.

Definition at line 106 of file AuxStoreBase.cxx.

106 {
107
108 return m_data.m_auxIDs;
109}

◆ getCopyIDs()

SG::auxid_set_t xAOD::details::AuxStoreBase::getCopyIDs ( bool warnUnlocked = false) const
overridevirtualinherited

Get the set of variables that we should deep copy.

Definition at line 193 of file AuxStoreBase.cxx.

194{
195 return SG::getCopyIDs (getAuxIDs(), getDecorIDs(), warnUnlocked, {});
196}
virtual const SG::auxid_set_t & getDecorIDs() const override
Get the types(names) of decorations handled by this container.
virtual const SG::auxid_set_t & getAuxIDs() const override
Get the types(names) of variables handled by this container.
virtual SG::auxid_set_t getCopyIDs(bool warnUnlocked=false) const override
Return the set of variables to copy in a deep copy.

◆ getData() [1/3]

virtual void * SG::IAuxStore::getData ( auxid_t auxid,
size_t size,
size_t capacity )
pure virtualinherited

Return the data vector for one aux data item.

Parameters
auxidThe identifier of the desired aux data item.
sizeThe current size of the container (in case the data item does not already exist).
capacityThe current capacity of the container (in case the data item does not already exist).

Each aux data item is stored as a vector, with one entry per entry in the owning container. This returns a pointer to the start of the vector.

If the data item does not exist, it should be created and initialized to default values. size and capacity give the size for the new aux data item vector.

If the container is locked, throw an exception.

Implemented in xAOD::AuxContainerBase, xAOD::AuxInfoBase, xAOD::ByteStreamAuxContainer_v1, and xAOD::ShallowAuxContainer.

◆ getData() [2/3]

const void * xAOD::details::AuxStoreBase::getData ( SG::auxid_t auxid) const
overridevirtualinherited

Get a pointer to a given array.

Definition at line 56 of file AuxStoreBase.cxx.

56 {
57
58 const SG::IAuxTypeVector* v = getVector(auxid);
59 if (v) {
60 return v->toPtr();
61 }
62 return nullptr;
63}
virtual const SG::IAuxTypeVector * getVector(SG::auxid_t auxid) const override
Return vector interface for one aux data item.

◆ getData() [3/3]

void * xAOD::details::AuxStoreBase::getData ( SG::auxid_t auxid,
std::size_t size,
std::size_t capacity )
overridevirtualinherited

Get a pointer to a given array, creating the array if necessary.

Definition at line 328 of file AuxStoreBase.cxx.

329 {
330
331 // Guard against multi-threaded execution:
332 guard_t guard(m_mutex2);
333
334 // Remember the size:
335 m_data.m_size = size;
336
337 // Check if we want to write this variable to the output:
338 if (!(isAuxIDSelected(auxid) && hasOutput())) {
339 // Create the store only when necessary:
340 if (!m_data.m_transientStore) {
341 m_data.m_transientStore = std::make_unique<SG::AuxStoreInternal>(
342 m_data.m_structMode == EStructMode::kObjectStore);
343 if (m_locked) {
344 m_data.m_transientStore->lock();
345 }
346 }
347 // Let the transient store create the variable:
348 std::size_t nids = m_data.m_transientStore->getAuxIDs().size();
349 void* result = m_data.m_transientStore->getData(auxid, size, capacity);
350 if (result && (nids != m_data.m_transientStore->getAuxIDs().size())) {
351 m_data.m_auxIDs.insert(auxid);
352 }
353 // Return the address in the transient memory:
354 return result;
355 }
356
357 // If the variable exists already, and this is a locked store, then
358 // we are in trouble.
359 if (m_locked && (auxid < m_data.m_vecs.size()) && m_data.m_vecs[auxid]) {
360 if (!((auxid < m_data.m_isDecoration.size()) &&
361 m_data.m_isDecoration[auxid])) {
362 throw SG::ExcStoreLocked(auxid);
363 }
364 }
365
366 // Connect this auxiliary variable just to the output:
367 if (setupOutputData(auxid).isFailure()) {
368 ::Error("xAOD::AuxStoreBase::getData",
369 XAOD_MESSAGE("Failed to set up variable %s"),
370 SG::AuxTypeRegistry::instance().getName(auxid).c_str());
371 return nullptr;
372 }
373
374 // Check whether things make sense:
375 if ((m_data.m_structMode == EStructMode::kObjectStore) && (size != 1)) {
376 ::Error("xAOD::AuxStoreBase::getData",
377 XAOD_MESSAGE("Branch creation requested with:"));
378 ::Error("xAOD::AuxStoreBase::getData", XAOD_MESSAGE(" name = %s"),
379 SG::AuxTypeRegistry::instance().getName(auxid).c_str());
380 ::Error("xAOD::AuxStoreBase::getData", XAOD_MESSAGE(" size = %i"),
381 static_cast<int>(size));
382 ::Error("xAOD::AuxStoreBase::getData",
383 XAOD_MESSAGE(" m_structMode = EStructMode::kObjectStore"));
384 return nullptr;
385 }
386
387 // Make sure the variable is of the right size:
388 m_data.m_vecs[auxid]->reserve(capacity);
389 m_data.m_vecs[auxid]->resize(size);
390
391 // Return the object:
392 return m_data.m_vecs[auxid]->toPtr();
393}
#define XAOD_MESSAGE(MESSAGE)
Simple macro for printing error/verbose messages.
static AuxTypeRegistry & instance()
Return the singleton registry instance.
virtual StatusCode setupOutputData(SG::auxid_t auxid)=0
Connect a variable to the output.
virtual bool hasOutput() const =0
Check if an output is being written by the object.
bool isAuxIDSelected(SG::auxid_t auxid) const
Check if an auxiliary variable is selected for ouput writing.
@ kObjectStore
The object describes a single object.
bool m_locked
Is this container locked?
virtual std::size_t size() const override
Return the number of elements in the store.
SG::auxid_t auxid() const
Return the aux id for this variable.

◆ getDecoration()

void * xAOD::details::AuxStoreBase::getDecoration ( SG::auxid_t auxid,
std::size_t size,
std::size_t capacity )
overridevirtualinherited

Get a pointer to a given array, creating the array if necessary.

Definition at line 116 of file AuxStoreBase.cxx.

117 {
118
119 // Guard against multi-threaded execution:
120 guard_t guard(m_mutex1);
121
122 // Remember the requested size:
123 m_data.m_size = size;
124
125 // If this is a locked object, deal with it correctly:
126 if (m_locked) {
127 // If the variable exists already and it's a decoration, then let's
128 // give it back.
129 if ((auxid < m_data.m_vecs.size()) && m_data.m_vecs[auxid] &&
130 (auxid < m_data.m_isDecoration.size() &&
131 m_data.m_isDecoration[auxid])) {
132 // Things look okay...
133 m_data.m_vecs[auxid]->reserve(capacity);
134 m_data.m_vecs[auxid]->resize(size);
135 return m_data.m_vecs[auxid]->toPtr();
136 }
137 // If it's in the transient store already, return it from there.
138 // Since in a locked store *everything* is a decoration in the
139 // transient store.
140 if (m_data.m_transientStore &&
141 m_data.m_transientStore->getAuxIDs().test(auxid)) {
142 return m_data.m_transientStore->getDecoration(auxid, size, capacity);
143 }
144 // If we know this auxiliary ID, but it was not found as a decoration
145 // by the previous checks, then we're in trouble.
146 if (m_data.m_auxIDs.test(auxid)) {
147 throw SG::ExcStoreLocked(auxid);
148 }
149 }
150
151 // Check if we want to write this variable to the output:
152 if (!(isAuxIDSelected(auxid) && hasOutput())) {
153
154 // Create the store only when necessary:
155 if (!m_data.m_transientStore) {
156 m_data.m_transientStore = std::make_unique<SG::AuxStoreInternal>(
157 m_data.m_structMode == EStructMode::kObjectStore);
158 if (m_locked) {
159 m_data.m_transientStore->lock();
160 }
161 }
162 // Let the transient store create the decoration:
163 const std::size_t nids = m_data.m_transientStore->getAuxIDs().size();
164 void* result =
165 m_data.m_transientStore->getDecoration(auxid, size, capacity);
166 if (result && (nids != m_data.m_transientStore->getAuxIDs().size())) {
167 if (m_data.m_transientStore->isDecoration(auxid)) {
168 m_data.m_decorIDs.insert(auxid);
169 }
170 std::atomic_thread_fence( std::memory_order_seq_cst );
171 m_data.m_auxIDs.insert(auxid);
172 }
173 // Return the memory address from the transient store:
174 return result;
175 }
176
177 // Doesn't exist yet. So let's make it:
178 if (m_locked) {
179 // If the container is locked, remember that this is a decoration:
180 if (m_data.m_isDecoration.size() <= auxid) {
181 m_data.m_isDecoration.resize(auxid + 1);
182 }
183 m_data.m_isDecoration[auxid] = true;
184 m_data.m_decorIDs.insert(auxid);
185 std::atomic_thread_fence( std::memory_order_seq_cst );
186 }
187 void* result = getData(auxid, size, capacity);
188
189 // Return the pointer made by getData(...):
190 return result;
191}
virtual const void * getData(SG::auxid_t auxid) const override
Get a pointer to a given array.

◆ getDecorIDs()

const SG::auxid_set_t & xAOD::details::AuxStoreBase::getDecorIDs ( ) const
overridevirtualinherited

Get the types(names) of decorations handled by this container.

Definition at line 111 of file AuxStoreBase.cxx.

111 {
112
113 return m_data.m_decorIDs;
114}

◆ getDynamicAuxIDs()

const SG::auxid_set_t & xAOD::details::AuxStoreBase::getDynamicAuxIDs ( ) const
overridevirtualinherited

Get the types(names) of variables created dynamically.

Implements SG::IAuxStoreIO.

Definition at line 637 of file AuxStoreBase.cxx.

637 {
638
639 // All the auxiliary decorations handled by this object are considered
640 // dynamic:
641 return getAuxIDs();
642}

◆ getEntry()

int xAOD::TAuxStore::getEntry ( int getall = 0)

Read the values from the TTree entry that was loaded with TTree::LoadTree().

Definition at line 945 of file TAuxStore.cxx.

945 {
946
947 assert(m_impl);
948
949 // Guard against multi-threaded execution:
950 guard_t guard(m_impl->m_mutex);
951
952 // Reset the transient store. TEvent::fill() calls this function with
953 // getall==99. When that is happening, we need to keep the transient
954 // store still around. Since the user may want to interact with the
955 // object after it was written out. (And since TEvent::fill() asks for
956 // the transient decorations after calling getEntry(...).)
957 if (m_data.m_transientStore && (getall != 99)) {
958 // Remove the transient auxiliary IDs from the internal list:
959 m_data.m_auxIDs -= m_data.m_transientStore->getAuxIDs();
960 m_data.m_decorIDs -= m_data.m_transientStore->getDecorIDs();
961 // Delete the object:
962 m_data.m_transientStore.reset();
963 }
964
965 // Now remove the IDs of the decorations that are getting persistified:
966 if (getall != 99) {
967 for (SG::auxid_t auxid = 0; auxid < m_data.m_isDecoration.size(); ++auxid) {
968 if (!m_data.m_isDecoration[auxid]) {
969 continue;
970 }
971 m_data.m_auxIDs.erase(auxid);
972 m_data.m_decorIDs.erase(auxid);
973 }
974 }
975
976 // If we don't need everything loaded, return now:
977 if (!getall) {
978 return 0;
979 }
980
981 // Get all the variables at once:
982 int bytesRead = 0;
983 for (auto& branchHandle : m_impl->m_branches) {
984 if (branchHandle) {
985 bytesRead += branchHandle->getEntry();
986#ifndef XAOD_STANDALONE
987 m_data.m_vecs[branchHandle->auxid()]->toTransient( m_impl->m_ctx );
988#endif
989 }
990 }
991 return bytesRead;
992}
size_t auxid_t
Identifier for a particular aux data item.
Definition AuxTypes.h:27

◆ getEntryFor()

StatusCode xAOD::TAuxStore::getEntryFor ( SG::auxid_t auxid)
overrideprivatevirtual

Load a single variable from the input.

Implements xAOD::details::AuxStoreBase.

Definition at line 1012 of file TAuxStore.cxx.

1012 {
1013
1014 assert(m_impl);
1015 assert(m_impl->m_branches.size() > auxid);
1016 assert(m_impl->m_branches[auxid]);
1017 const ::Int_t readBytes = m_impl->m_branches[auxid]->getEntry();
1018 if (readBytes < 0) {
1019 ::Error("xAOD::TAuxStore::getEntryFor",
1020 XAOD_MESSAGE("Couldn't read in variable %s"),
1021 SG::AuxTypeRegistry::instance().getName(auxid).c_str());
1022 return StatusCode::FAILURE;
1023 }
1024#ifndef XAOD_STANDALONE
1025 m_data.m_vecs[auxid]->toTransient( m_impl->m_ctx );
1026#endif
1027 return StatusCode::SUCCESS;
1028}

◆ getInputObject()

const void * xAOD::TAuxStore::getInputObject ( SG::auxid_t auxid) const
overrideprivatevirtual

Get a pointer to an input object, as it is in memory, for getIOData().

Implements xAOD::details::AuxStoreBase.

Definition at line 1546 of file TAuxStore.cxx.

1546 {
1547
1548 assert(m_impl);
1549 assert(m_impl->m_branches.size() > auxid);
1550 assert(m_impl->m_branches[auxid]);
1551 return m_impl->m_branches[auxid]->objectPtr();
1552}

◆ getInputType()

const std::type_info * xAOD::TAuxStore::getInputType ( SG::auxid_t auxid) const
overrideprivatevirtual

Get the type of an input object, for getIOType().

Implements xAOD::details::AuxStoreBase.

Definition at line 1554 of file TAuxStore.cxx.

1554 {
1555
1556 assert(m_impl);
1557 assert(m_impl->m_branches.size() > auxid);
1558 assert(m_impl->m_branches[auxid]);
1559 return m_impl->m_branches[auxid]->typeInfo();
1560}

◆ getIOData()

const void * xAOD::details::AuxStoreBase::getIOData ( SG::auxid_t auxid) const
overridevirtualinherited

Get a pointer to the data being stored for one aux data item.

Implements SG::IAuxStoreIO.

Definition at line 539 of file AuxStoreBase.cxx.

539 {
540
541 // Guard against multi-threaded execution:
542 guard_t guard(m_mutex1);
543
544 auto this_nc ATLAS_THREAD_SAFE =
545 const_cast<AuxStoreBase*>(this); // locked above
546
547 // If the variable is coming from the input, and is connected to already.
548 if (hasEntryFor(auxid)) {
549 if (!this_nc->getEntryFor(auxid).isSuccess()) {
550 ::Error("xAOD::AuxStoreBase::getIOData",
551 XAOD_MESSAGE("Couldn't read in variable %s"),
552 SG::AuxTypeRegistry::instance().getName(auxid).c_str());
553 return nullptr;
554 }
555 return getInputObject(auxid);
556 }
557
558 // Check if it's in the transient store:
559 if (m_data.m_transientStore &&
560 m_data.m_transientStore->getAuxIDs().test(auxid)) {
561 return m_data.m_transientStore->getIOData(auxid);
562 }
563
564 // If not, try connecting to it now:
565 if (!this_nc->setupInputData(auxid).isSuccess()) {
566 // This is not actually an error condition anymore. We can end up here
567 // when we decorate constant objects coming from the input file, but
568 // on one event we can't set any decorations. For instance when the
569 // input container is empty. In that case the object will still list
570 // the auxiliary ID belonging to that decoration as being available,
571 // but it really isn't.
572 //
573 // Later on it might be needed to tweak the logic of all of this, but
574 // for now just silently returning 0 seems to do the right thing.
575 return nullptr;
576 }
577
578 // Now we should know this variable:
579 if (!hasEntryFor(auxid)) {
580 ::Fatal("xAOD::AuxStoreBase::getIOData",
581 XAOD_MESSAGE("Internal logic error detected"));
582 return nullptr;
583 }
584
585 // Make sure that the right payload is in memory:
586 if (!this_nc->getEntryFor(auxid).isSuccess()) {
587 ::Error("xAOD::AuxStoreBase::getIOData",
588 XAOD_MESSAGE("Couldn't read in variable %s"),
589 SG::AuxTypeRegistry::instance().getName(auxid).c_str());
590 return nullptr;
591 }
592
593 // Return the pointer.
594 return getInputObject(auxid);
595}
#define ATLAS_THREAD_SAFE
virtual bool hasEntryFor(SG::auxid_t auxid) const =0
Check if a given variable is available from the input.
AuxStoreBase(bool topStore=true, EStructMode mode=EStructMode::kUndefinedStore)
Constructor.
virtual const void * getInputObject(SG::auxid_t auxid) const =0
Get a pointer to an input object, as it is in memory, for getIOData().

◆ getIOType()

const std::type_info * xAOD::details::AuxStoreBase::getIOType ( SG::auxid_t auxid) const
overridevirtualinherited

Return the type of the data to be stored for one aux data item.

Implements SG::IAuxStoreIO.

Definition at line 598 of file AuxStoreBase.cxx.

598 {
599
600 // Guard against multi-threaded execution:
601 guard_t guard(m_mutex1);
602
603 // If the variable is connected to already:
604 if (hasEntryFor(auxid)) {
605 return getInputType(auxid);
606 }
607
608 // Check if it's in the transient store:
609 if (m_data.m_transientStore &&
610 m_data.m_transientStore->getAuxIDs().test(auxid)) {
611 return m_data.m_transientStore->getIOType(auxid);
612 }
613
614 // If not, try connecting to it now:
615 auto this_nc ATLAS_THREAD_SAFE =
616 const_cast<AuxStoreBase*>(this); // locked above
617 if (!this_nc->setupInputData(auxid).isSuccess()) {
618 ::Error("xAOD::AuxStoreBase::getIOType",
619 XAOD_MESSAGE("Couldn't connect to auxiliary variable "
620 "%i %s"),
621 static_cast<int>(auxid),
622 SG::AuxTypeRegistry::instance().getName(auxid).c_str());
623 return nullptr;
624 }
625
626 // Now we should know this variable:
627 if (!hasEntryFor(auxid)) {
628 ::Fatal("xAOD::AuxStoreBase::getIOType",
629 XAOD_MESSAGE("Internal logic error detected"));
630 return nullptr;
631 }
632
633 // Return the type info:
634 return getInputType(auxid);
635}
virtual const std::type_info * getInputType(SG::auxid_t auxid) const =0
Get the type of an input object, for getIOType().

◆ getSelectedAuxIDs()

SG::auxid_set_t xAOD::details::AuxStoreBase::getSelectedAuxIDs ( ) const
overridevirtualinherited

Get the IDs of the selected aux variables.

Reimplemented from SG::IAuxStoreIO.

Definition at line 652 of file AuxStoreBase.cxx.

652 {
653
654 // Guard against multi-threaded execution:
655 guard_t guard(m_mutex1);
656 // Leave the calculation up to the internal object:
657 return m_selection.getSelectedAuxIDs(m_data.m_auxIDs);
658}
AuxSelection m_selection
Object helping to select which auxiliary variables to write.

◆ getVector()

const SG::IAuxTypeVector * xAOD::details::AuxStoreBase::getVector ( SG::auxid_t auxid) const
overridevirtualinherited

Return vector interface for one aux data item.

Definition at line 65 of file AuxStoreBase.cxx.

65 {
66
67 // Guard against multi-threaded execution:
68 guard_t guard(m_mutex1);
69
70 // Check if the transient store already handles this variable:
71 if (m_data.m_transientStore &&
72 (m_data.m_transientStore->getAuxIDs().test(auxid))) {
73 return m_data.m_transientStore->getVector(auxid);
74 }
75
76 // Access the object through a non-const pointer. This is "safe" because
77 // of the mutex lock above.
78 auto this_nc ATLAS_THREAD_SAFE = const_cast<AuxStoreBase*>(this);
79
80 // Connect this auxiliary variable both to the input and output
81 // if needed:
82 if ((auxid >= m_data.m_vecs.size()) || (!m_data.m_vecs[auxid])) {
83 if ((!this_nc->setupInputData(auxid).isSuccess()) ||
84 (!this_nc->setupOutputData(auxid).isSuccess())) {
85 return nullptr;
86 }
87 }
88
89 // Make sure the variable is up to date:
90 if (this_nc->getEntryFor(auxid).isSuccess() == false) {
91 ::Error("xAOD::AuxStoreBase::getVector",
92 XAOD_MESSAGE("Couldn't read in variable %s"),
93 SG::AuxTypeRegistry::instance().getName(auxid).c_str());
94 return nullptr;
95 }
96
97 // Let the AuxTypeVector object know that the std::vector that it manages
98 // has changed. (This updates the cached span.)
99 SG::IAuxTypeVector* vec = m_data.m_vecs[auxid].get();
100 vec->resize (vec->size());
101
102 // Return the pointer to the object:
103 return vec;
104}
std::vector< size_t > vec

◆ getWritableAuxIDs()

const SG::auxid_set_t & xAOD::details::AuxStoreBase::getWritableAuxIDs ( ) const
overridevirtualinherited

Return a set of writable data identifiers.

Implements SG::IAuxStore.

Definition at line 395 of file AuxStoreBase.cxx.

395 {
396
397 return getAuxIDs();
398}

◆ hasEntryFor()

bool xAOD::TAuxStore::hasEntryFor ( SG::auxid_t auxid) const
overrideprivatevirtual

Check if a given variable is available from the input.

Implements xAOD::details::AuxStoreBase.

Definition at line 1006 of file TAuxStore.cxx.

1006 {
1007
1008 assert(m_impl);
1009 return ((m_impl->m_branches.size() > auxid) && m_impl->m_branches[auxid]);
1010}

◆ hasOutput()

bool xAOD::TAuxStore::hasOutput ( ) const
overrideprivatevirtual

Check if an output is being written by the object.

Implements xAOD::details::AuxStoreBase.

Definition at line 1030 of file TAuxStore.cxx.

1030 {
1031
1032 assert(m_impl);
1033 return (m_impl->m_outTree != nullptr);
1034}

◆ insertMove() [1/2]

virtual bool SG::IAuxStore::insertMove ( size_t pos,
IAuxStore & other,
const SG::auxid_set_t & ignore = SG::auxid_set_t() )
pure virtualinherited

Move all elements from other to this store.

Parameters
posThe starting index of the insertion.
otherStore from which to do the move.
ignoreSet of variables that should not be added to the store.

Let len be the size of other. The store will be increased in size by len elements, with the elements at pos being copied to pos+len. Then, for each auxiliary variable, the entire contents of that variable for other will be moved to this store at index pos. This will be done via move semantics if possible; otherwise, it will be done with a copy. Variables present in this store but not in other will have the corresponding elements default-initialized. Variables in other but not in this store will be added unless they are in ignore.

Returns true if it is known that none of the vectors' memory moved, false otherwise.

◆ insertMove() [2/2]

bool xAOD::details::AuxStoreBase::insertMove ( std::size_t pos,
SG::IAuxStore & other,
const SG::auxid_set_t & ignore )
overridevirtualinherited

Insert contents of another store via move.

Definition at line 489 of file AuxStoreBase.cxx.

490 {
491 // Guard against multi-threaded execution:
492 guard_t guard(m_mutex1);
493
494 // A sanity check:
495 if (m_data.m_structMode == EStructMode::kObjectStore) {
496 ::Error("xAOD::AuxStoreBase::insertMove",
497 XAOD_MESSAGE("Should not have been called for single-object "
498 "store"));
499 return false;
500 }
501
502 bool nomove = true;
503 std::size_t other_size = other.size();
504
505 SG::auxid_set_t ignore = ignore_in;
506
507 for (SG::auxid_t id : m_data.m_auxIDs) {
508 SG::IAuxTypeVector* v_dst = nullptr;
509 if (id < m_data.m_vecs.size()) {
510 v_dst = m_data.m_vecs[id].get();
511 }
512 if (v_dst && !v_dst->isLinked()) {
513 ignore.insert(id);
514 if (other.getData(id)) {
515 void* src_ptr = other.getData(id, other_size, other_size);
516 if (src_ptr) {
517 if (!v_dst->insertMove(pos, src_ptr, 0, other_size, other)) {
518 nomove = false;
519 }
520 }
521 } else {
522 const void* orig = v_dst->toPtr();
523 v_dst->shift(pos, other_size);
524 if (orig != v_dst->toPtr()) {
525 nomove = false;
526 }
527 }
528 }
529 }
530
531 if (m_data.m_transientStore) {
532 if (!m_data.m_transientStore->insertMove(pos, other, ignore))
533 nomove = false;
534 }
535
536 return nomove;
537}
bool isLinked() const
Return true if this variable is linked from another one.
virtual void * toPtr()=0
Return a pointer to the start of the vector's data.
virtual bool insertMove(size_t pos, void *src, size_t src_pos, size_t src_n, IAuxStore &srcStore)=0
Insert elements into the vector via move semantics.
virtual bool shift(size_t pos, ptrdiff_t offs)=0
Shift the elements of the vector.

◆ isAuxIDSelected()

bool xAOD::details::AuxStoreBase::isAuxIDSelected ( SG::auxid_t auxid) const
protectedinherited

Check if an auxiliary variable is selected for ouput writing.

This is a tricky one.

The function can't just rely on getSelectedAuxIDs, as the aux ID received here may be a new ID that the object doesn't yet know about. So we have no other choice but to check this ID explicitly.

@apram auxid The auxiliary ID that should be checked

Returns
true if the variable needs to be written out, false if not

Definition at line 668 of file AuxStoreBase.cxx.

668 {
669
670 // A temporary object:
671 SG::auxid_set_t auxids;
672 auxids.insert(auxid);
673
674 // Check if the auxid is returned as a selected ID:
675 return m_selection.getSelectedAuxIDs(auxids).size();
676}

◆ isDecoration()

bool xAOD::details::AuxStoreBase::isDecoration ( SG::auxid_t auxid) const
overridevirtualinherited

Test if a variable is a decoration.

Definition at line 199 of file AuxStoreBase.cxx.

199 {
200 if (m_locked) {
201 if (auxid < m_data.m_isDecoration.size() && m_data.m_isDecoration[auxid]) {
202 return true;
203 }
204 if (m_data.m_transientStore) {
205 return m_data.m_transientStore->isDecoration(auxid);
206 }
207 }
208 return false;
209}

◆ isTopStore()

bool xAOD::details::AuxStoreBase::isTopStore ( ) const
inherited

Check if the object is a "top store", or not.

Definition at line 45 of file AuxStoreBase.cxx.

45 {
46
47 return m_data.m_topStore;
48}

◆ linkedVector() [1/2]

const SG::IAuxTypeVector * xAOD::details::AuxStoreBase::linkedVector ( SG::auxid_t auxid) const
overridevirtualinherited

Return (const) interface for a linked variable.

Definition at line 287 of file AuxStoreBase.cxx.

287 {
288 const SG::AuxTypeRegistry& r = SG::AuxTypeRegistry::instance();
289 SG::auxid_t linked_id = r.linkedVariable(auxid);
290 guard_t guard(m_mutex1);
291 if (linked_id < m_data.m_vecs.size()) {
292 return m_data.m_vecs[linked_id].get();
293 }
294 if (m_data.m_transientStore) {
295 return CxxUtils::as_const_ptr(m_data.m_transientStore.get())
296 ->linkedVector(auxid);
297 }
298 return nullptr;
299}
int r
Definition globals.cxx:22
const T * as_const_ptr(const T *p)
Helper for getting a const version of a pointer.

◆ linkedVector() [2/2]

SG::IAuxTypeVector * xAOD::details::AuxStoreBase::linkedVector ( SG::auxid_t auxid)
overridevirtualinherited

Return (non-const) interface for a linked variable.

Reimplemented from SG::IAuxStore.

Definition at line 301 of file AuxStoreBase.cxx.

301 {
302 const SG::AuxTypeRegistry& r = SG::AuxTypeRegistry::instance();
303 SG::auxid_t linked_id = r.linkedVariable(auxid);
304 guard_t guard(m_mutex1);
305 if (linked_id < m_data.m_vecs.size()) {
306 return m_data.m_vecs[linked_id].get();
307 }
308 if (m_data.m_transientStore) {
309 return m_data.m_transientStore->linkedVector(auxid);
310 }
311 return nullptr;
312}

◆ lock()

void xAOD::details::AuxStoreBase::lock ( )
overridevirtualinherited

Lock the object, and don't let decorations be added.

Definition at line 211 of file AuxStoreBase.cxx.

211 {
212
213 // Guard against multi-threaded execution:
214 guard_t guard(m_mutex1);
215
216 m_locked = true;
217 if (m_data.m_transientStore) {
218 m_data.m_transientStore->lock();
219 }
220}

◆ lockDecoration()

void xAOD::details::AuxStoreBase::lockDecoration ( SG::auxid_t auxid)
overridevirtualinherited

Lock a decoration.

Definition at line 252 of file AuxStoreBase.cxx.

252 {
253 if (m_data.m_transientStore) {
254 m_data.m_transientStore->lockDecoration(auxid);
255 }
256 m_data.m_decorIDs.erase(auxid);
257}

◆ prefix()

const std::string & xAOD::details::AuxStoreBase::prefix ( ) const
inherited

Get the currently configured object name prefix.

Definition at line 40 of file AuxStoreBase.cxx.

40 {
41
42 return m_data.m_prefix;
43}

◆ readFrom()

StatusCode xAOD::TAuxStore::readFrom ( ::TTree & tree,
bool printWarnings = true )

Connect the object to an input TTree.

This function is called by the infrastructure to connect the object to an input TTree whenever a new input file is opened.

Parameters
treePointer to the TTree that is being read from

Definition at line 878 of file TAuxStore.cxx.

878 {
879
880 assert(m_impl);
881
882 // Make sure that everything will be re-read after this:
883 reset();
884
885 // We will need to check again which branches are available:
886 m_impl->m_missingBranches.clear();
887
888 // Remember the tree:
889 m_impl->m_inTree = &tree;
890
891 // Catalogue all the branches:
892 RETURN_CHECK("xAOD::TAuxStore::readFrom", m_impl->scanInputTree());
893
894 // Check if we'll be likely to be able to read the "static"
895 // variables:
896 assert(m_impl->m_inTree != nullptr);
897 TBranch* br = m_impl->m_inTree->GetBranch(m_data.m_prefix.data());
898 if (br == nullptr) {
899 // We might not even have static branches, so this is not an error
900 // by itself...
901 return StatusCode::SUCCESS;
902 }
903 // In order to read complex objects, like smart pointers from an
904 // auxiliary container variable-by-variable, the split level of the
905 // branch must be exactly 1.
906 if ((br->GetSplitLevel() != 1) && m_data.m_topStore && printWarnings) {
907 ::Warning("xAOD::TAuxStore::readFrom",
908 "Static branch (%s) with split level %i discovered",
909 m_data.m_prefix.data(), br->GetSplitLevel());
910 ::Warning("xAOD::TAuxStore::readFrom",
911 "The reading of complex variables from it may/will fail!");
912 }
913
914 // Return gracefully.
915 return StatusCode::SUCCESS;
916}
#define RETURN_CHECK(CONTEXT, EXP)
Helper macro for checking return codes in a compact form in the code.
Definition ReturnCheck.h:26
virtual void reset() override
Tell the object that all branches will need to be re-read.
TChain * tree

◆ reserve() [1/2]

virtual void SG::IAuxStore::reserve ( size_t sz)
pure virtualinherited

Change the capacity of all aux data vectors.

Parameters
szThe new capacity.

This should be called when the capacity of the container changes (by reserve). This should change the capacity for the vectors for all aux data items.

Implemented in xAOD::AuxContainerBase, xAOD::AuxInfoBase, xAOD::ByteStreamAuxContainer_v1, and xAOD::ShallowAuxContainer.

◆ reserve() [2/2]

void xAOD::details::AuxStoreBase::reserve ( std::size_t size)
overridevirtualinherited

Reserve a given size for the arrays.

Definition at line 433 of file AuxStoreBase.cxx.

433 {
434
435 // Guard against multi-threaded execution:
436 guard_t guard(m_mutex1);
437
438 // A sanity check:
439 if ((m_data.m_structMode == EStructMode::kObjectStore) && (size != 1)) {
440 ::Error("xAOD::AuxStoreBase::reserve",
441 XAOD_MESSAGE("size = %i for single-object store"),
442 static_cast<int>(size));
443 return;
444 }
445
446 for (auto& v : m_data.m_vecs) {
447 if (v && !v->isLinked()) {
448 v->reserve(size);
449 }
450 }
451
452 if (m_data.m_transientStore) {
453 m_data.m_transientStore->reserve(size);
454 }
455}

◆ reset()

void xAOD::TAuxStore::reset ( )
overridevirtual

Tell the object that all branches will need to be re-read.

Implements xAOD::details::AuxStoreBase.

Definition at line 994 of file TAuxStore.cxx.

994 {
995
996 assert(m_impl);
997
998 for (auto& branchHandle : m_impl->m_branches) {
999 if (branchHandle) {
1000 branchHandle->reset();
1001 }
1002 }
1003 m_impl->m_inputScanned = false;
1004}

◆ resize() [1/2]

virtual bool SG::IAuxStore::resize ( size_t sz)
pure virtualinherited

Change the size of all aux data vectors.

Parameters
szThe new size.

This should be called when the size of the container changes. This should resize the vectors for all aux data items.

If the size of the container grows, the new elements should be default-initialized; if it shrinks, destructors should be run as appropriate.

Should return true if it is known that none of the data pointers changed (and thus the cache does not need to be cleared), false otherwise.

Implemented in xAOD::AuxContainerBase, xAOD::AuxInfoBase, xAOD::ByteStreamAuxContainer_v1, and xAOD::ShallowAuxContainer.

◆ resize() [2/2]

bool xAOD::details::AuxStoreBase::resize ( std::size_t size)
overridevirtualinherited

Resize the arrays to a given size.

Definition at line 400 of file AuxStoreBase.cxx.

400 {
401
402 // Guard against multi-threaded execution:
403 guard_t guard(m_mutex1);
404
405 // A sanity check:
406 if ((m_data.m_structMode == EStructMode::kObjectStore) && (size != 1)) {
407 ::Error("xAOD::AuxStoreBase::resize",
408 XAOD_MESSAGE("size = %i for single-object store"),
409 static_cast<int>(size));
410 return false;
411 }
412
413 // Remember the new size:
414 m_data.m_size = size;
415
416 bool nomoves = true;
417 for (auto& v : m_data.m_vecs) {
418 if (v && !v->isLinked()) {
419 if (!v->resize(size)) {
420 nomoves = false;
421 }
422 }
423 }
424 if (m_data.m_transientStore) {
425 if (!m_data.m_transientStore->resize(size)) {
426 nomoves = false;
427 }
428 }
429
430 return nomoves;
431}

◆ selectAux()

void xAOD::details::AuxStoreBase::selectAux ( const std::set< std::string > & attributes)
virtualinherited

Select dynamic auxiliary attributes for writing.

Definition at line 645 of file AuxStoreBase.cxx.

645 {
646
647 guard_t guard(m_mutex1);
648 m_selection.selectAux(attributes);
649}

◆ setBasketSize()

void xAOD::TAuxStore::setBasketSize ( int value)

Set the size of the baskets created for the output branches.

Definition at line 855 of file TAuxStore.cxx.

855 {
856
857 assert(m_impl);
858 m_impl->m_basketSize = value;
859}

◆ setOption()

virtual bool SG::IAuxStore::setOption ( auxid_t ,
const AuxDataOption &  )
inlinevirtualinherited

Set an option for a given auxiliary variable.

Parameters
auxidThe identifier of the desired aux data item.
optionThe option to set.

The interpretation of the option depends on the particular representation of the variable.

Returns true if the option setting was successful; false otherwise.

Reimplemented in xAOD::AuxContainerBase, and xAOD::AuxInfoBase.

Definition at line 189 of file IAuxStore.h.

190 { return false; }

◆ setPrefix()

void xAOD::TAuxStore::setPrefix ( std::string_view prefix)
overridevirtual

Set the object name prefix.

Implements xAOD::details::AuxStoreBase.

Definition at line 842 of file TAuxStore.cxx.

842 {
843
844 m_data.m_prefix = prefix;
845 m_data.m_dynPrefix = Utils::dynBranchPrefix(m_data.m_prefix);
846 reset();
847}
std::string dynBranchPrefix(const std::string &key)
This function is used to figure out what to name dynamic auxiliary branches coming from a container c...

◆ setSplitLevel()

void xAOD::TAuxStore::setSplitLevel ( int value)

Set the split level of the output branches.

Definition at line 867 of file TAuxStore.cxx.

867 {
868
869 assert(m_impl);
870 m_impl->m_splitLevel = value;
871}

◆ setStructMode()

void xAOD::details::AuxStoreBase::setStructMode ( EStructMode mode)
inherited

Set the structure mode of the object to a new value.

Definition at line 34 of file AuxStoreBase.cxx.

34 {
35
36 m_data.m_structMode = mode;
37 reset();
38}
virtual void reset()=0
Reset all (transient) information in the object.

◆ setTopStore()

void xAOD::details::AuxStoreBase::setTopStore ( bool value = true)
inherited

Set whether the object should behave as a "top store" or not.

Definition at line 50 of file AuxStoreBase.cxx.

50 {
51
52 m_data.m_topStore = value;
53 reset();
54}

◆ setupInputData()

StatusCode xAOD::TAuxStore::setupInputData ( SG::auxid_t auxid)
overrideprivatevirtual

Connect a variable to the input.

Connect a variable to the input tree.

This internal function takes care of connecting to an individual (sub-)branch in the input file for a given auxiliary variable. It needs to handle a number of different use cases, so it's a bit long.

Parameters
auxidThe ID of the variable to connect to
Returns
StatusCode::SUCCESS if the function was successful, something else otherwise

Implements xAOD::details::AuxStoreBase.

Definition at line 1046 of file TAuxStore.cxx.

1046 {
1047
1048 assert(m_impl);
1049
1050 // Return right away if we already know that the branch is missing.
1051 if ((auxid < m_impl->m_missingBranches.size()) &&
1052 m_impl->m_missingBranches[auxid]) {
1053 return StatusCode::RECOVERABLE;
1054 }
1055
1056 // Make sure the internal storage is large enough:
1057 if (m_data.m_vecs.size() <= auxid) {
1058 m_data.m_vecs.resize(auxid + 1);
1059 }
1060 if (m_impl->m_branches.size() <= auxid) {
1061 m_impl->m_branches.resize(auxid + 1);
1062 }
1063
1064 // Check if we need to do anything:
1065 if (m_data.m_vecs[auxid] && m_impl->m_branches[auxid]) {
1066 return StatusCode::SUCCESS;
1067 }
1068
1069 // A little sanity check.
1070 if (m_impl->m_inTree == nullptr) {
1071 ::Error("xAOD::TAuxStore::setupInputData",
1072 XAOD_MESSAGE("No input TTree set up!"));
1073 return StatusCode::FAILURE;
1074 }
1075
1076 // Another sanity check.
1077 if (m_data.m_vecs[auxid] || m_impl->m_branches[auxid]) {
1078 ::Error("xAOD::TAuxStore::setupInputData",
1079 XAOD_MESSAGE("Internal logic error!"));
1080 return StatusCode::FAILURE;
1081 }
1082
1083 // Convenience access to the registry.
1084 const SG::AuxTypeRegistry& r = SG::AuxTypeRegistry::instance();
1085
1086 // Get the property name:
1087 const TString statBrName =
1088 std::format("{}{}", m_data.m_prefix, r.getName(auxid));
1089 const TString dynBrName =
1090 std::format("{}{}", m_data.m_dynPrefix, r.getName(auxid));
1091
1092 // Check if the branch exists:
1093 Bool_t staticBranch = true;
1094 TString brName = statBrName;
1095
1096 TBranch* br = m_impl->m_inTree->GetBranch(statBrName);
1097 if (!br) {
1098 br = m_impl->m_inTree->GetBranch(dynBrName);
1099 if (!br) {
1100 // Since TTree::GetBranch / TTObjArray::FindObject is expensive,
1101 // remember that we didn't find this branch in this file.
1102 if (m_impl->m_missingBranches.size() <= auxid) {
1103 m_impl->m_missingBranches.resize(auxid + 1);
1104 }
1105 m_impl->m_missingBranches[auxid] = true;
1106 // The branch doesn't exist, but this is not an error per se.
1107 // The user may just be calling isAvailable(...) on the variable.
1108 return StatusCode::RECOVERABLE;
1109 }
1110 // We have a dynamic branch:
1111 staticBranch = false;
1112 brName = dynBrName;
1113 }
1114
1115 // Check if it's a "primitive branch":
1116 const Bool_t primitiveBranch = isPrimitiveBranch(*br);
1117 // Check if it's a "container branch":
1118 const Bool_t containerBranch =
1119 (primitiveBranch ? false : isContainerBranch(*br, auxid));
1120
1121 // Set the structure mode if it has not been defined externally:
1122 if (m_data.m_structMode == EStructMode::kUndefinedStore) {
1123 m_data.m_structMode = (containerBranch ? EStructMode::kContainerStore
1125 }
1126
1127 // Check that the branch type makes sense:
1128 if ((containerBranch &&
1129 (m_data.m_structMode != EStructMode::kContainerStore) &&
1130 !r.isLinked(auxid)) ||
1131 ((!containerBranch) &&
1132 (m_data.m_structMode != EStructMode::kObjectStore))) {
1133 ::Error("xAOD::TAuxStore::setupInputData",
1134 XAOD_MESSAGE("Branch type and requested structure mode "
1135 "differ for branch: %s"),
1136 brName.Data());
1137 return StatusCode::FAILURE;
1138 }
1139
1140 // Check what variable it is:
1141 ::TClass* clDummy = 0;
1142 ::EDataType dType = kOther_t;
1143 if (br->GetExpectedType(clDummy, dType)) {
1144 ::Error("xAOD::TAuxStore::setupInputData",
1145 XAOD_MESSAGE("Couldn't determine the type of branch \"%s\""),
1146 brName.Data());
1147 return StatusCode::FAILURE;
1148 }
1149
1150 // Get the property type:
1151 const std::type_info* brType = 0;
1152 if (details::isRegisteredType(auxid)) {
1153 // Get the type from the auxiliary type registry:
1154 brType = (containerBranch ? r.getVecType(auxid) : r.getType(auxid));
1155 } else {
1156 // Get the type from the input branch itself:
1157 brType = (clDummy ? clDummy->GetTypeInfo() : &(Utils::getTypeInfo(dType)));
1158 }
1159 if (!brType) {
1160 ::Error("xAOD::TAuxStore::setupInputData",
1161 XAOD_MESSAGE("Can't read/copy variable %s (%s)"), brName.Data(),
1162 clDummy->GetName());
1163 return StatusCode::RECOVERABLE;
1164 }
1165 const TString brTypeName = Utils::getTypeName(*brType).c_str();
1166
1167 // Check if we have the needed dictionary for an object branch:
1168 ::TClass* brClass = 0;
1169 if (!primitiveBranch) {
1170 // Get the property's class:
1171 brClass = ::TClass::GetClass(*brType, true, true);
1172 if (!brClass) {
1173 brClass = ::TClass::GetClass(brTypeName);
1174 }
1175 if (!brClass) {
1176 ::Error("xAOD::TAuxStore::setupInputData",
1177 XAOD_MESSAGE("No dictionary available for class \"%s\""),
1178 brTypeName.Data());
1179 return StatusCode::FAILURE;
1180 }
1181 }
1182
1183 // Create the smart object holding this vector:
1184 if (details::isRegisteredType(auxid)) {
1185 m_data.m_vecs[auxid] = r.makeVector(auxid, (size_t)0, (size_t)0);
1186 if (!containerBranch) {
1187 m_data.m_vecs[auxid]->resize(1);
1188 }
1189 if (clDummy &&
1190 strncmp(clDummy->GetName(), "SG::PackedContainer<", 20) == 0) {
1191 std::unique_ptr<SG::IAuxTypeVector> packed =
1192 m_data.m_vecs[auxid]->toPacked();
1193 std::swap(m_data.m_vecs[auxid], packed);
1194 }
1195 } else {
1196 ::Error("xAOD::TAuxStore::setupInputData",
1197 XAOD_MESSAGE("Couldn't create in-memory vector for "
1198 "variable %s (%i)"),
1199 brName.Data(), static_cast<int>(auxid));
1200 return StatusCode::FAILURE;
1201 }
1202
1203 // Create a new branch handle:
1204 const std::type_info* objType = brType;
1205 if (containerBranch) {
1206 objType = m_data.m_vecs[auxid]->objType();
1207 if (!objType)
1208 objType = r.getType(auxid);
1209 }
1210 m_impl->m_branches[auxid] = std::make_unique<TBranchHandle>(
1211 staticBranch, primitiveBranch, objType,
1212 (containerBranch ? m_data.m_vecs[auxid]->toVector()
1213 : m_data.m_vecs[auxid]->toPtr()),
1214 auxid, m_data.m_prefix);
1215
1216 // Set the tree/branch in the "right mode":
1217 if (staticBranch) {
1218 br->SetMakeClass();
1219 }
1220
1221 // Connect to the branch:
1222 ::Int_t status = 0;
1223 if (clDummy && ::TString(clDummy->GetName()).Contains("basic_string<char>")) {
1224 // This is pretty much just a hack. As it happens, Athena I/O can
1225 // create dynamic branches that consider themselves to be of type
1226 // "vector<basic_string<char> >" and similar. (Instead of the
1227 // canonical "vector<string>" name.) When we encounter such a branch,
1228 // we just connect to it without performing any compatibility checks.
1229 // Since we don't need to apply any read rules in this case anyway.
1230 status = m_impl->m_inTree->SetBranchAddress(
1231 brName, m_impl->m_branches[auxid]->inputObjectPtr(),
1232 m_impl->m_branches[auxid]->branchPtr());
1233 } else {
1234 status = m_impl->m_inTree->SetBranchAddress(
1235 brName, m_impl->m_branches[auxid]->inputObjectPtr(),
1236 m_impl->m_branches[auxid]->branchPtr(), brClass, dType,
1237 ((!staticBranch) && (!primitiveBranch)));
1238 }
1239 if (status < 0) {
1240 ::Error("xAOD::TAuxStore::setupInputData",
1241 XAOD_MESSAGE("Coulnd't connect to branch \"%s\""), brName.Data());
1242 ::Error("xAOD::TAuxStore::setupInputData", XAOD_MESSAGE("Return code: %i"),
1243 status);
1244 m_data.m_vecs[auxid].reset();
1245 m_impl->m_branches[auxid].reset();
1246 return StatusCode::FAILURE;
1247 }
1248
1249 // Get the current entry:
1250 m_impl->m_branches[auxid]->getEntry();
1251#ifndef XAOD_STANDALONE
1252 m_data.m_vecs[auxid]->toTransient( m_impl->m_ctx );
1253#endif
1254
1255 // Remember which variable got created:
1256 m_data.m_auxIDs.insert(auxid);
1257
1258 // Check if we just replaced a generic object:
1259 if (details::isRegisteredType(auxid)) {
1260 // The name of the variable we just created:
1261 const std::string auxname = r.getName(auxid);
1262 // Check if there's another variable with this name already:
1263 for (SG::auxid_t i = 0; i < m_data.m_vecs.size(); ++i) {
1264 // Check if we have this aux ID:
1265 if (!m_data.m_vecs[i]) {
1266 continue;
1267 }
1268 // Ingore the object that we *just* created:
1269 if (i == auxid) {
1270 continue;
1271 }
1272 // The name of the variable:
1273 const std::string testname = r.getName(i);
1274 // Check if it has the same name:
1275 if (testname != auxname) {
1276 continue;
1277 }
1278 // Check that the other one is a non-registered type:
1280 ::Error("xAOD::TAuxStore::setupInputData",
1281 XAOD_MESSAGE("Internal logic error!"));
1282 continue;
1283 }
1284 // Okay, we do need to remove this object:
1285 m_data.m_vecs[i].reset();
1286 m_impl->m_branches[i].reset();
1287 m_data.m_auxIDs.erase(i);
1288 }
1289 }
1290
1291 SG::auxid_t linked_auxid = r.linkedVariable(auxid);
1292 if (linked_auxid != SG::null_auxid) {
1293 return setupInputData(linked_auxid);
1294 }
1295
1296 // Return gracefully.
1297 return StatusCode::SUCCESS;
1298}
virtual StatusCode setupInputData(SG::auxid_t auxid) override
Connect a variable to the input.
@ kUndefinedStore
The structure mode is not defined.
@ kContainerStore
The object describes an entire container.
H5::CompType packed(H5::CompType in)
static const auxid_t null_auxid
To signal no aux data item.
Definition AuxTypes.h:30
status
Definition merge.py:16
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)
const std::type_info & getTypeInfo(EDataType type)
This function is used when reading a primitive branch from an input file without the user explicitly ...
std::string getTypeName(const std::type_info &ti)
This function is necessary in order to create type names that ROOT can understand.
bool isRegisteredType(SG::auxid_t auxid)
Check if the auxiliary variable has a registered type.

◆ setupOutputData()

StatusCode xAOD::TAuxStore::setupOutputData ( SG::auxid_t auxid)
overrideprivatevirtual

Connect a variable to the output.

Connect a variable to the output tree.

This function is used internally to create a "simple" output branch with the contents of a single auxiliary variable.

Parameters
auxidThe ID of the variable to create an output branch for
Returns
StatusCode::SUCCESS if the function was successful, something else otherwise

Implements xAOD::details::AuxStoreBase.

Definition at line 1309 of file TAuxStore.cxx.

1309 {
1310
1311 assert(m_impl);
1312
1313 // Check whether we need to do anything:
1314 if (!m_impl->m_outTree) {
1315 return StatusCode::SUCCESS;
1316 }
1317
1318 // Check if the variable needs to be written out:
1319 if (!isAuxIDSelected(auxid)) {
1320 return StatusCode::SUCCESS;
1321 }
1322
1323 // Make sure that containers are large enough:
1324 if (m_data.m_vecs.size() <= auxid) {
1325 m_data.m_vecs.resize(auxid + 1);
1326 }
1327 if (m_impl->m_branches.size() <= auxid) {
1328 m_impl->m_branches.resize(auxid + 1);
1329 }
1330 if (m_impl->m_branchesWritten.size() <= auxid) {
1331 m_impl->m_branchesWritten.resize(auxid + 1);
1332 }
1333
1334 // Check if this auxiliary variable is already in the output:
1335 if (m_impl->m_branchesWritten[auxid]) {
1336 return StatusCode::SUCCESS;
1337 }
1338
1339 // The registry:
1340 SG::AuxTypeRegistry& reg = SG::AuxTypeRegistry::instance();
1341
1342 // Check if the variable was put into the transient store as a
1343 // decoration, and now needs to be put into the output file:
1344 if ((!m_data.m_vecs[auxid]) && m_data.m_transientStore &&
1345 (m_data.m_transientStore->getAuxIDs().test(auxid))) {
1346
1347 // Get the variable from the transient store:
1348 const void* pptr = m_data.m_transientStore->getData(auxid);
1349 if (!pptr) {
1350 ::Fatal("xAOD::TAuxStore::setupOutputData",
1351 XAOD_MESSAGE("Internal logic error detected"));
1352 return StatusCode::FAILURE;
1353 }
1354
1355 // Create the new object:
1356 m_data.m_vecs[auxid] = reg.makeVector(auxid, m_data.m_size, m_data.m_size);
1357 void* ptr = m_data.m_vecs[auxid]->toPtr();
1358 if (!ptr) {
1359 ::Error("xAOD::TAuxStore::setupOutputData",
1360 XAOD_MESSAGE("Couldn't create decoration in memory "
1361 "for writing"));
1362 return StatusCode::FAILURE;
1363 }
1364
1365 // Get the type of this variable:
1366 const std::type_info* type = reg.getType(auxid);
1367 if (!type) {
1368 ::Error("xAOD::TAuxStore::setupOutputData",
1369 XAOD_MESSAGE("Couldn't get the type of transient "
1370 "variable %i"),
1371 static_cast<int>(auxid));
1372 return StatusCode::FAILURE;
1373 }
1374 // Now get the factory for this variable:
1375 const SG::IAuxTypeVectorFactory* factory = reg.getFactory(auxid);
1376 if (!factory) {
1377 ::Error("xAOD::TAuxStore::setupOutputData",
1378 XAOD_MESSAGE("No factory found for transient variable "
1379 "%i"),
1380 static_cast<int>(auxid));
1381 return StatusCode::FAILURE;
1382 }
1383
1384 // Mark it as a decoration already, otherwise the copy may fail.
1385 if (m_data.m_isDecoration.size() <= auxid) {
1386 m_data.m_isDecoration.resize(auxid + 1);
1387 }
1388 m_data.m_isDecoration[auxid] = true;
1389
1390 // Finally, do the copy:
1391 factory->copy(auxid, SG::AuxVectorInterface(*this), 0,
1392 SG::AuxVectorInterface(*m_data.m_transientStore), 0,
1393 m_data.m_size);
1394 }
1395
1396 // Check if we know about this variable to be on the input,
1397 // but haven't connected to it yet:
1398 if ((m_data.m_auxIDs.test(auxid)) && (!m_data.m_vecs[auxid]) &&
1399 (!m_impl->m_branches[auxid])) {
1400 RETURN_CHECK("xAOD::TAuxStore::setupOutputData", setupInputData(auxid));
1401 }
1402
1403 // Check that we know the store's type:
1404 if ((m_data.m_structMode != EStructMode::kContainerStore) &&
1405 (m_data.m_structMode != EStructMode::kObjectStore)) {
1406 ::Error("xAOD::TAuxStore::setupOutputData",
1407 XAOD_MESSAGE("Structure mode unknown for variable %s"),
1408 SG::AuxTypeRegistry::instance().getName(auxid).c_str());
1409 return StatusCode::FAILURE;
1410 }
1411
1412 // Check if the variable exists already in memory:
1413 if (!m_data.m_vecs[auxid]) {
1414 m_data.m_vecs[auxid] =
1415 SG::AuxTypeRegistry::instance().makeVector(auxid, (size_t)0, (size_t)0);
1416 if (m_data.m_structMode == EStructMode::kObjectStore) {
1417 m_data.m_vecs[auxid]->resize(1);
1418 }
1419 }
1420
1421 // Check if the branch handle exists already:
1422 if (!m_impl->m_branches[auxid]) {
1423 // Get the property type:
1424 const std::type_info* brType =
1425 (m_data.m_structMode == EStructMode::kContainerStore
1428 // Create the handle object:
1429 bool primitiveBranch = (strlen(brType->name()) == 1);
1430 m_impl->m_branches[auxid] = std::make_unique<TBranchHandle>(
1431 false, (strlen(brType->name()) == 1),
1432 (primitiveBranch ? brType : m_data.m_vecs[auxid]->objType()),
1433 (m_data.m_structMode == EStructMode::kObjectStore
1434 ? m_data.m_vecs[auxid]->toPtr()
1435 : m_data.m_vecs[auxid]->toVector()),
1436 auxid, m_data.m_prefix);
1437 }
1438
1439 // Construct a name for the branch:
1440 const TString brName =
1441 std::format("{}{}", m_data.m_dynPrefix,
1443
1444 // If the output branch exists already, assume that it was us making
1445 // it:
1446 ::TBranch* br = m_impl->m_outTree->GetBranch(brName);
1447 if (br) {
1448 // Apparently a branch that was already set up for copying as a basic
1449 // variable, now got accessed explicitly. So let's update the output
1450 // branch to point to this new location now.
1451 br->SetAddress(m_impl->m_branches[auxid]->outputObjectPtr());
1452 // Update the cache. Notice that the "write status" of the typeless
1453 // auxiliary ID is not turned off. But it shouldn't matter, as the
1454 // variable will not be accessed in a typeless way anymore.
1455 m_impl->m_branchesWritten[auxid] = true;
1456 // Return gracefully:
1457 return StatusCode::SUCCESS;
1458 }
1459
1460 // Check that we know the type of the branch:
1461 const std::type_info* brType = m_impl->m_branches[auxid]->typeInfo();
1462 if (!brType) {
1463 ::Error("xAOD::TAuxStore::setupOutputData",
1464 XAOD_MESSAGE("There's an internal logic error in the "
1465 "code"));
1466 return StatusCode::FAILURE;
1467 }
1468 const std::string brTypeName = Utils::getTypeName(*brType);
1469
1470 // Decide if this is a primitive branch:
1471 const Bool_t primitiveBranch = (strlen(brType->name()) == 1);
1472
1473 // Let's create the branch now:
1474 if (primitiveBranch) {
1475
1476 // Get the "ROOT type" belonging to this primitive:
1477 const char rootType = Utils::rootType(brType->name()[0]);
1478 if (rootType == '\0') {
1479 ::Error("xAOD::TAuxStore::setupOutputData",
1480 XAOD_MESSAGE("Type not known for variable \"%s\" "
1481 "of type \"%s\""),
1482 brName.Data(), brTypeName.c_str());
1483 return StatusCode::FAILURE;
1484 }
1485
1486 // Construct the type description:
1487 std::ostringstream typeDesc;
1488 typeDesc << brName << "/" << rootType;
1489
1490 // Create the branch:
1491 br = m_impl->m_outTree->Branch(
1492 brName, m_impl->m_branches[auxid]->outputObjectPtr(),
1493 typeDesc.str().c_str(), m_impl->m_basketSize);
1494
1495 } else {
1496
1497 // Access the dictionary for the type:
1498 TClass* cl = TClass::GetClass(*brType);
1499 if (!cl) {
1500 cl = TClass::GetClass(brTypeName.c_str());
1501 }
1502 if (!cl) {
1503 ::Error("xAOD::TAuxStore::setupOutputData",
1504 XAOD_MESSAGE("Couldn't find dictionary for type: %s"),
1505 brTypeName.c_str());
1506 return StatusCode::FAILURE;
1507 }
1508 if (!cl->GetStreamerInfo()) {
1509 ::Error("xAOD::TAuxStore::setupOutputData",
1510 XAOD_MESSAGE("No streamer info available for type %s"),
1511 cl->GetName());
1512 return StatusCode::FAILURE;
1513 }
1514
1515 // Create the branch:
1516 br = m_impl->m_outTree->Branch(brName, cl->GetName(),
1517 m_impl->m_branches[auxid]->outputObjectPtr(),
1518 m_impl->m_basketSize, m_impl->m_splitLevel);
1519 }
1520
1521 // Check if we succeeded:
1522 if (!br) {
1523 ::Error("xAOD::TAuxStore::setupOutputData",
1524 XAOD_MESSAGE("Failed creating branch \"%s\" of type "
1525 "\"%s\""),
1526 brName.Data(), brTypeName.c_str());
1527 return StatusCode::FAILURE;
1528 }
1529
1530 // If this is not the first event, fill up the branch with dummy
1531 // info:
1532 for (Long64_t i = 0; i < m_impl->m_outTree->GetEntries(); ++i) {
1533 br->Fill();
1534 }
1535
1536 // Update the cache:
1537 m_impl->m_branchesWritten[auxid] = true;
1538
1539 // Also, remember that we now handle this variable:
1540 m_data.m_auxIDs.insert(auxid);
1541
1542 // We were successful:
1543 return StatusCode::SUCCESS;
1544}
const std::type_info * getType(SG::auxid_t auxid) const
Return the type of an aux data item.
std::string getName(SG::auxid_t auxid) const
Return the name of an aux data item.
const std::type_info * getVecType(SG::auxid_t auxid) const
Return the type of the STL vector used to hold an aux data item.
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.
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.
void * ptr(T *p)
Definition SGImplSvc.cxx:74
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
char rootType(char typeidType)
This function is used internally in the code when creating primitive dynamic auxiliary branches.

◆ shift() [1/2]

virtual void SG::IAuxStore::shift ( size_t pos,
ptrdiff_t offs )
pure virtualinherited

Shift the elements of the container.

Parameters
posThe starting index for the shift.
offsThe (signed) amount of the shift.

This operation shifts the elements in the vectors for all aux data items, to implement an insertion or deletion. offs may be either positive or negative.

If offs is positive, then the container is growing. The container size should be increased by offs, the element at pos moved to pos + offs, and similarly for following elements. The elements between pos and pos + offs should be default-initialized.

If offs is negative, then the container is shrinking. The element at pos should be moved to pos + offs, and similarly for following elements. The container should then be shrunk by -offs elements (running destructors as appropriate).

Implemented in xAOD::AuxContainerBase, xAOD::AuxInfoBase, xAOD::ByteStreamAuxContainer_v1, and xAOD::ShallowAuxContainer.

◆ shift() [2/2]

void xAOD::details::AuxStoreBase::shift ( std::size_t pos,
std::ptrdiff_t offs )
overridevirtualinherited

Shift the contents of the stored arrays.

Definition at line 457 of file AuxStoreBase.cxx.

457 {
458
459 // Guard against multi-threaded execution:
460 guard_t guard(m_mutex1);
461
462 // A sanity check:
463 if (m_data.m_structMode == EStructMode::kObjectStore) {
464 ::Error("xAOD::AuxStoreBase::shift",
465 XAOD_MESSAGE("Should not have been called for single-object "
466 "store"));
467 return;
468 }
469
470 // Adjust the size of the container:
471 if ((static_cast<std::size_t>(std::abs(offs)) > m_data.m_size) &&
472 (offs < 0)) {
473 m_data.m_size = 0;
474 } else {
475 m_data.m_size += offs;
476 }
477
478 for (auto& v : m_data.m_vecs) {
479 if (v && !v->isLinked()) {
480 v->shift(pos, offs);
481 }
482 }
483
484 if (m_data.m_transientStore) {
485 m_data.m_transientStore->shift(pos, offs);
486 }
487}

◆ size()

std::size_t xAOD::details::AuxStoreBase::size ( ) const
overridevirtualinherited

Return the number of elements in the store.

Definition at line 259 of file AuxStoreBase.cxx.

259 {
260
261 // First, try to find a managed vector in the store:
262 for (SG::auxid_t id : m_data.m_auxIDs) {
263 // Make sure that we are still within the bounds of our vector:
264 if (id >= m_data.m_vecs.size())
265 break;
266 // Skip non-existent or linked objects:
267 if (!m_data.m_vecs[id] || m_data.m_vecs[id]->isLinked()) {
268 continue;
269 }
270 // Ask the vector for its size:
271 const std::size_t size = m_data.m_vecs[id]->size();
272 // Only accept a non-zero size. Not sure why...
273 if (size > 0) {
274 return size;
275 }
276 }
277
278 // Check if we have a transient store, and get the size from that:
279 if (m_data.m_transientStore) {
280 return m_data.m_transientStore->size();
281 }
282
283 // Apparently the store is empty:
284 return 0;
285}

◆ splitLevel()

int xAOD::TAuxStore::splitLevel ( ) const

Get the split level of the output branches.

Definition at line 861 of file TAuxStore.cxx.

861 {
862
863 assert(m_impl);
864 return m_impl->m_splitLevel;
865}

◆ structMode()

auto xAOD::details::AuxStoreBase::structMode ( ) const
inherited

Get what structure mode the object was constructed with.

Definition at line 29 of file AuxStoreBase.cxx.

29 {
30
31 return m_data.m_structMode;
32}

◆ toTransient()

void xAOD::details::AuxStoreBase::toTransient ( const EventContext & ctx)
overridevirtualinherited

Call toTransient on contained variables.

Implements SG::IAuxStore.

Definition at line 314 of file AuxStoreBase.cxx.

314 {
315 // Guard against multi-threaded execution:
316 guard_t guard(m_mutex1);
317
318 for (auto& v : m_data.m_vecs) {
319 if (v) {
320 v->toTransient( ctx );
321 }
322 }
323 if (m_data.m_transientStore) {
324 m_data.m_transientStore->toTransient(ctx);
325 }
326}

◆ writeTo()

StatusCode xAOD::TAuxStore::writeTo ( ::TTree & tree)

Connect the object to an output TTree.

This function is called by the infrastructure to connect the object to an output TTree.

Parameters
treePointer to the TTree that is being written to

Definition at line 923 of file TAuxStore.cxx.

923 {
924
925 assert(m_impl);
926
927 // Look for any auxiliary branches that have not been connected to yet:
928 RETURN_CHECK("xAOD::TAuxStore::writeTo", m_impl->scanInputTree());
929
930 // Store the TTree pointer:
931 m_impl->m_outTree = &tree;
932
933 // Create all the variables that we already know about. Notice that the
934 // code makes a copy of the auxid set on purpose. Because the underlying
935 // AuxSelection object gets modified while doing the for loop.
936 const SG::auxid_set_t selAuxIDs = getSelectedAuxIDs();
937 for (SG::auxid_t id : selAuxIDs) {
938 RETURN_CHECK("xAOD::TAuxStore::writeTo", setupOutputData(id));
939 }
940
941 // Return gracefully.
942 return StatusCode::SUCCESS;
943}
virtual StatusCode setupOutputData(SG::auxid_t auxid) override
Connect a variable to the output.
virtual SG::auxid_set_t getSelectedAuxIDs() const override
Get the IDs of the selected aux variables.

Member Data Documentation

◆ m_data

Members xAOD::details::AuxStoreBase::m_data
protectedinherited

Member variables of the base class.

Definition at line 207 of file AuxStoreBase.h.

◆ m_impl

std::unique_ptr<impl> xAOD::TAuxStore::m_impl
private

Pointer to the internal object.

Definition at line 93 of file TAuxStore.h.

◆ m_locked

bool xAOD::details::AuxStoreBase::m_locked = false
privateinherited

Is this container locked?

Definition at line 218 of file AuxStoreBase.h.

◆ m_mutex1

mutex_t xAOD::details::AuxStoreBase::m_mutex1
mutableprivateinherited

Mutex objects used for multithreaded synchronisation.

Definition at line 220 of file AuxStoreBase.h.

◆ m_mutex2

mutex_t xAOD::details::AuxStoreBase::m_mutex2
privateinherited

Definition at line 220 of file AuxStoreBase.h.

◆ m_selection

AuxSelection xAOD::details::AuxStoreBase::m_selection
privateinherited

Object helping to select which auxiliary variables to write.

Definition at line 216 of file AuxStoreBase.h.

◆ supportsThinning

bool SG::IAuxStore::supportsThinning = true
staticconstexprinherited

Mark that this type supports thinning operations.

See AthContainers/supportsThinning.h and AthenaPoolCnvSvc/T_AthenaPoolCnv.h. Helps guide which pool converter template will be used. If false, the default pool converter will be used rather than the aux store-specific one. Ordinary xAOD type should not touch this, but may be overridden in a derived class to handle certain special cases.

Definition at line 216 of file IAuxStore.h.


The documentation for this class was generated from the following files: