ATLAS Offline Software
Loading...
Searching...
No Matches
DynVarFixerAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Local include(s):
6#include "DynVarFixerAlg.h"
7
8// EDM include(s):
11
12// ROOT include(s):
13#include <TClass.h>
14#include <TVirtualCollectionProxy.h>
15#include <TGenCollectionProxy.h>
16
17// System include(s).
18#include <algorithm>
19#include <cassert>
20#include <string>
21
22namespace xAODMaker {
23
25
26 // Greet the user.
27 ATH_MSG_INFO( "Initialising" );
28 ATH_MSG_DEBUG( "Will be fixing dynamic variables in container(s):" );
29 ATH_MSG_DEBUG( " " << m_constKeys );
30
31 // Initialise the read handle keys.
32 ATH_CHECK( m_constKeys.initialize() );
33 std::vector< std::string > keys( m_constKeys.size() );
34 std::transform( m_constKeys.begin(), m_constKeys.end(), keys.begin(),
36 return key.key(); } );
37 ATH_CHECK( m_ioKeys.assign( keys ) );
38 ATH_CHECK( m_ioKeys.initialize() );
39
40 // Reset the cache variable.
41 m_dicts.clear();
42
43 // Return gracefully.
44 return StatusCode::SUCCESS;
45 }
46
48
49 // Construct the SG::IConstAuxStore and SG::IAuxStoreIO read handles.
50 auto constHandles = m_constKeys.makeHandles();
51 auto ioHandles = m_ioKeys.makeHandles();
52 assert( constHandles.size() == ioHandles.size() );
53
54 // Loop over the specified containers:
55 for( std::size_t i = 0; i < constHandles.size(); ++i ) {
56
57 // Access the appropriate handles.
59 constHandles.at( i );
61 ioHandles.at( i );
62
63 // If the store is empty, stop here.
64 if( constHandle->size() == 0 ) {
65 continue;
66 }
67
68 // Remember the store's name and size.
69 const std::string& cname = constHandle.key();
70 const size_t size = constHandle->size();
71 ATH_MSG_VERBOSE( "Size of container \"" << cname << "\": " << size );
72
73 // Loop over all dynamic variables of the container:
74 for( SG::auxid_t auxid : ioHandle->getDynamicAuxIDs() ) {
75
76 // Access the registry:
77 static const auto& reg = SG::AuxTypeRegistry::instance();
78
79 // Tell the user what's happening.
80 ATH_MSG_VERBOSE( "Checking variable \"" << cname
81 << reg.getName( auxid ) << "\"" );
82
83 // Access the std::vector variable:
84 const void* vecPtr = ioHandle->getIOData( auxid );
85
86 // Get a dictionary for the variable:
87 ::TClass* cl = getClass( auxid );
88 if( ! cl ) {
89 continue;
90 }
91
92 // Get the collection proxy for the class:
93 ::TVirtualCollectionProxy* proxy = cl->GetCollectionProxy();
94 if( ! proxy ) {
95 ATH_MSG_FATAL( "Couldn't get collection proxy for variable \""
96 << reg.getName( auxid ) << "\"" );
97 return StatusCode::FAILURE;
98 }
99
100 // Attach the proxy to the auxiliary variable:
101 ::TVirtualCollectionProxy::TPushPop helper( proxy,
102 ( void* ) vecPtr );
103
104 // Check if the variable is of the right size. If it is, don't
105 // bother the variable any longer.
106 if( proxy->Size() == size ) {
107 continue;
108 }
109 ATH_MSG_VERBOSE( "Size of variable \"" << cname
110 << reg.getName( auxid ) << "\": "
111 << proxy->Size() );
112
113 // If it's not, then try to resize it using the TGenCollectionProxy
114 // interface:
115 ::TGenCollectionProxy* genProxy =
116 dynamic_cast< ::TGenCollectionProxy* >( proxy );
117 if( ! genProxy ) {
118 ATH_MSG_WARNING( "Variable \"" << reg.getName( auxid )
119 << "\" doesn't have a TGenCollectionProxy. "
120 << "Variable not fixed!" );
121 continue;
122 }
123
124 // Resize the variable to the right size:
125 static const ::Bool_t FORCE_DELETE = kFALSE;
126 genProxy->Resize( size, FORCE_DELETE );
127 ATH_MSG_VERBOSE( "Size of variable \"" << cname
128 << reg.getName( auxid ) << "\" after resize: "
129 << proxy->Size() );
130 ATH_MSG_DEBUG( "Fixed variable: \"" << cname << reg.getName( auxid )
131 << "\"" );
132 }
133 }
134
135 // Return gracefully.
136 return StatusCode::SUCCESS;
137 }
138
140
141 // Check if we already checked, and there's no dictionary available for
142 // this type:
143 if( ( m_noDict.size() > auxid ) && m_noDict[ auxid ] ) {
144 return nullptr;
145 }
146
147 // Check if the cache already has this variable:
148 if( ( m_dicts.size() > auxid ) && m_dicts[ auxid ] ) {
149 return m_dicts[ auxid ];
150 }
151
152 // Make sure that the cache variables are large enough:
153 if( m_dicts.size() <= auxid ) {
154 m_dicts.resize( auxid + 1, nullptr );
155 }
156 if( m_noDict.size() <= auxid ) {
157 m_noDict.resize( auxid + 1, false );
158 }
159
160 // If not, then look for a dictionary for this type:
161 static const auto& reg = SG::AuxTypeRegistry::instance();
162 static const ::Bool_t LOAD = kTRUE;
163 static const ::Bool_t SILENT = kTRUE;
164 ::TClass* cl = ::TClass::GetClass( reg.getVecTypeName( auxid ).c_str(),
165 LOAD, SILENT );
166
167 // Cache the result:
168 if( cl ) {
169 m_dicts[ auxid ] = cl;
170 } else {
171 ATH_MSG_INFO( "No dictionary available for variable \""
172 << reg.getName( auxid ) << "\"" );
173 m_noDict[ auxid ] = true;
174 }
175
176 // Return what we found:
177 return cl;
178 }
179
180} // namespace xAODMaker
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Handle mappings between names and auxid_t.
Handle class for reading from StoreGate.
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Property holding a SG store/key/clid from which a ReadHandle is made.
virtual const std::string & key() const override final
Return the StoreGate ID for the referenced object.
std::vector< bool > m_noDict
Flag showing which variables don't have a dictionary for them.
SG::ReadHandleKeyArray< SG::IConstAuxStore > m_constKeys
Containers to access with the SG::IConstAuxStore interface.
StatusCode execute() override
Function executing the algorithm.
::TClass * getClass(SG::auxid_t auxid)
Get the dictionary describing an auxiliary vector variable.
StatusCode initialize() override
Function initialising the algorithm.
SG::ReadHandleKeyArray< SG::IAuxStoreIO > m_ioKeys
Containers to access with the SG::IAuxStoreIO interface.
std::vector< ::TClass * > m_dicts
Cache of the dictionaries used.
size_t auxid_t
Identifier for a particular aux data item.
Definition AuxTypes.h:27