ATLAS Offline Software
Loading...
Searching...
No Matches
xAODVariableProxyLoaders.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
8
9#include "TClass.h"
10
11#include <memory>
12
13namespace ExpressionParsing {
14
15 TMethodWrapper::TMethodWrapper(const std::type_info &elementTypeinfo,
16 const std::string &methodName)
17 : m_valid(false)
18 {
19 TClass *cls = TClass::GetClass(elementTypeinfo);
20 if (!cls) {
21 cls = TClass::GetClass(SG::normalizedTypeinfoName(elementTypeinfo).c_str());
22 if (!cls) return;
23 }
24
25 m_methodCall.setProto (cls, methodName, "");
26
27 m_valid = m_methodCall.call() != nullptr;
28 }
29
33
35 {
36 TMethodCall* mc = m_methodCall.call();
37 if (!mc) return IProxyLoader::VT_UNK;
38 switch (mc->ReturnType()) {
39 case TMethodCall::kLong:
41 case TMethodCall::kDouble:
43 case TMethodCall::kString:
44 case TMethodCall::kOther:
45 case TMethodCall::kNone:
46 default: return IProxyLoader::VT_UNK;
47 }
48 }
49
51 {
52 return m_valid;
53 }
54
56 {
57 return m_valid;
58 }
59
60 int TMethodWrapper::getIntValue(const SG::AuxElement *auxElement) const
61 {
62 long retLong;
63 auto aux_nc ATLAS_THREAD_SAFE = const_cast<SG::AuxElement*>(auxElement); // required by TMethodCall
64 m_methodCall.call()->Execute(aux_nc, retLong);
65 return (int) retLong;
66 }
67
68 double TMethodWrapper::getDoubleValue(const SG::AuxElement *auxElement) const
69 {
70 double retDouble;
71 auto aux_nc ATLAS_THREAD_SAFE = const_cast<SG::AuxElement*>(auxElement); // required by TMethodCall
72 m_methodCall.call()->Execute(aux_nc, retDouble);
73 return retDouble;
74 }
75
77 {
78 throw std::runtime_error("TMethodWrapper doesn't deal with containers");
79 }
80
82 {
83 throw std::runtime_error("TMethodWrapper doesn't deal with containers");
84 }
85
86
87
88 // ********************************************************************************
89 TMethodCollectionWrapper::TMethodCollectionWrapper(const std::type_info &containerTypeinfo,
90 const std::string &methodName)
91 : m_collectionProxy(nullptr),
92 m_valid(false)
93 {
94 TClass *containerClass = TClass::GetClass(containerTypeinfo);
95 if (!containerClass) {
96 containerClass = TClass::GetClass(SG::normalizedTypeinfoName(containerTypeinfo).c_str());
97 if (!containerClass) return;
98 }
99
100 m_collectionProxy = containerClass->GetCollectionProxy();
101 if (!m_collectionProxy) return;
102
103 TClass *elementClass = m_collectionProxy->GetValueClass();
104 if (!elementClass) return;
105
106 m_methodCall.setProto (elementClass, methodName, "");
107
108 m_valid = m_methodCall.call() != nullptr;
109 }
110
114
116 {
117 TMethodCall* mc = m_methodCall.call();
118 if (!mc) return IProxyLoader::VT_UNK;
119 switch (mc->ReturnType()) {
120 case TMethodCall::kLong:
122 case TMethodCall::kDouble:
124 case TMethodCall::kString:
125 case TMethodCall::kOther:
126 case TMethodCall::kNone:
127 default: return IProxyLoader::VT_UNK;
128 }
129 }
130
132 {
133 return m_valid;
134 }
135
137 {
138 return m_valid;
139 }
140
142 {
143 throw std::runtime_error("TMethodCollectionWrapper doesn't deal with scalars");
144 }
145
147 {
148 throw std::runtime_error("TMethodCollectionWrapper doesn't deal with scalars");
149 }
150
151 std::vector<int> TMethodCollectionWrapper::getVecIntValue(const SG::AuxVectorData *auxVectorData)
152 {
153 long retLong;
154 auto data_nc ATLAS_THREAD_SAFE = const_cast<SG::AuxVectorData*>(auxVectorData); // required by TVirtualCollectionProxy
155 m_collectionProxy->PushProxy(data_nc);
156 const UInt_t N = m_collectionProxy->Size();
157 std::vector<int> result(N);
158 for (UInt_t i = 0; i < N; ++i) {
159 void *element = (*m_collectionProxy)[i];
160 m_methodCall.call()->Execute(element, retLong);
161 result[i] = (int) retLong;
162 }
163 m_collectionProxy->PopProxy();
164 return result;
165 }
166
167 std::vector<double> TMethodCollectionWrapper::getVecDoubleValue(const SG::AuxVectorData *auxVectorData)
168 {
169 double retDouble;
170 auto data_nc ATLAS_THREAD_SAFE = const_cast<SG::AuxVectorData*>(auxVectorData); // required by TVirtualCollectionProxy
171 m_collectionProxy->PushProxy(data_nc);
172 const UInt_t N = m_collectionProxy->Size();
173 std::vector<double> result(N);
174 for (UInt_t i = 0; i < N; ++i) {
175 void *element = (*m_collectionProxy)[i];
176 m_methodCall.call()->Execute(element, retDouble);
177 result[i] = (double) retDouble;
178 }
179 m_collectionProxy->PopProxy();
180 return result;
181 }
182
183
184
185 // ********************************************************************************
187 m_accessorCache(accessorCache_t::Updater_t())
188 {
189 }
190
195
197 {
198 for (auto x : m_accessorCache) delete x.second;
199 // m_accessorCache.clear(); // not supported by ConcurrentStrMap
200 }
201
202 template <class TYPE, class AUX>
203 bool xAODProxyLoader::try_type(const std::string& varname, const std::type_info* ti, const AUX* data) const
204 {
205 if (*ti == typeid(TYPE)) {
206 auto accWrap = std::make_unique<AccessorWrapper<TYPE>>(varname);
207 if (accWrap && accWrap->isValid(data)) {
208 m_accessorCache.insert_or_assign(varname, accWrap.release());
209 return true;
210 } else if (accWrap) {
212 const SG::auxid_t auxid = r.findAuxID(varname);
213 throw std::runtime_error("Unsupported aux element type '"+r.getTypeName(auxid)+"' for '"+varname+"'");
214 }
215 }
216 return false;
217 }
218
219 template <class AUX>
221 const AUX* data, bool isVector) const
222 {
224 const SG::auxid_t auxid = r.findAuxID(varname);
225 if (auxid != SG::null_auxid) {
226 const std::type_info *ti = r.getType(auxid);
227 // Try integer types:
228 if ( try_type<int>(varname, ti, data) ||
229 try_type<bool>(varname, ti, data) ||
230 try_type<unsigned int>(varname, ti, data) ||
231 try_type<char>(varname, ti, data) ||
232 try_type<uint8_t>(varname, ti, data) ||
233 try_type<unsigned short>(varname, ti, data) ||
234 try_type<short>(varname, ti, data) ) {
236 }
237 // Try floating point types:
238 if ( try_type<float>(varname, ti, data) ||
239 try_type<double>(varname, ti, data) ) {
241 }
242 }
243 return VT_UNK;
244 }
245
246
247
248 // ********************************************************************************
250 : m_auxElement(auxElement)
251 {
252 }
253
255 {
256 m_auxElement = auxElement;
257 }
258
260 {
261 // Try TMethodWrapper
262 auto container = m_auxElement->container();
263 const std::type_info &containerTypeinfo = typeid(*container);
264 TClass *containerClass = TClass::GetClass(containerTypeinfo);
265 if (!containerClass) {
266 containerClass = TClass::GetClass(SG::normalizedTypeinfoName(containerTypeinfo).c_str());
267 }
268 if (containerClass) {
269 std::unique_ptr<TMethodWrapper> accWrap;
270 if( !strcmp(containerClass->GetName(),"SG::AuxElementStandaloneData") ) { /* special case where the element type is the aux element */
271 accWrap = std::make_unique<TMethodWrapper>( typeid(*m_auxElement) , varname );
272 } else {
273 TVirtualCollectionProxy* collProxy = containerClass->GetCollectionProxy();
274 if(collProxy) {
275 const std::type_info &elementTypeinfo = *(collProxy->GetValueClass()->GetTypeInfo());
276 accWrap = std::make_unique<TMethodWrapper>(elementTypeinfo, varname);
277 }
278 }
279 if (accWrap && accWrap->isValid(m_auxElement)) {
280 const IProxyLoader::VariableType vtype = accWrap->variableType();
281 m_accessorCache.insert_or_assign(varname, accWrap.release());
282 return vtype;
283 }
284 }
285
286 return try_all_known_types(varname, m_auxElement, false);
287 }
288
289 int xAODElementProxyLoader::loadIntVariableFromString(const std::string &varname) const
290 {
291 return m_accessorCache.at(varname)->getIntValue(m_auxElement);
292 }
293
294 double xAODElementProxyLoader::loadDoubleVariableFromString(const std::string &varname) const
295 {
296 return m_accessorCache.at(varname)->getDoubleValue(m_auxElement);
297 }
298
299 std::vector<int> xAODElementProxyLoader::loadVecIntVariableFromString(const std::string &) const
300 {
301 throw std::runtime_error("xAODElementProxyLoader can't load vector types");
302 }
303
304 std::vector<double> xAODElementProxyLoader::loadVecDoubleVariableFromString(const std::string &) const
305 {
306 throw std::runtime_error("xAODElementProxyLoader can't load vector types");
307 }
308
309
310
311 // ********************************************************************************
313 : m_auxVectorData(auxVectorData)
314 {
315 }
316
318 {
319 m_auxVectorData = auxVectorData;
320 }
321
323 {
324 auto accWrap = std::make_unique<TMethodCollectionWrapper>(typeid(*m_auxVectorData), varname);
325 if (accWrap && accWrap->isValid(m_auxVectorData)) {
326 const IProxyLoader::VariableType vtype = accWrap->variableType();
327 m_accessorCache.insert_or_assign(varname, accWrap.release());
328 return vtype;
329 }
330
332
333 // Before giving up completely, check the size of the vector. If it's
334 // 0, it may be that it's empty on *all* events of the current input
335 // file. Meaning that dynamic variables will be missing from each event.
336 if( vtype==VT_UNK && m_auxVectorData->size_v() == 0 ) {
337 // Let's claim a vector<double> type, that seems to be the safest bet.
338 // Even if the variable should actually be vector<int>, this is a
339 // simple conversion at least.
340 vtype = VT_VECDOUBLE;
341 }
342
343 return vtype;
344 }
345
347 {
348 throw std::runtime_error("xAODVectorProxyLoader can't load scalar types");
349 }
350
352 {
353 throw std::runtime_error("xAODVectorProxyLoader can't load scalar types");
354 }
355
356 std::vector<int> xAODVectorProxyLoader::loadVecIntVariableFromString(const std::string &varname) const
357 {
358 return m_accessorCache.at(varname)->getVecIntValue(m_auxVectorData);
359 }
360
361 std::vector<double> xAODVectorProxyLoader::loadVecDoubleVariableFromString(const std::string &varname) const
362 {/*
363 // Check whether we have an accessor already:
364 std::map< std::string, BaseAccessorWrapper* >::const_iterator itr;
365 if( ( itr = m_accessorCache.find( varname ) ) == m_accessorCache.end() ) {
366 // For an empty container let's not bother too much:
367 if( m_auxVectorData->size_v() == 0 ) {
368 return std::vector< double >();
369 }
370 // If it's not empty, then let the variableTypeFromString function
371 // figure out the variable type, and create the accessor:
372 if( variableTypeFromString( varname ) == VT_UNK ) {
373 throw std::runtime_error( "Couldn't find variable type for " +
374 varname );
375 }
376 // Update the iterator:
377 itr = m_accessorCache.find( varname );
378 }
379 // Now do the "regular thing". Note that even if the type turns out
380 // to be an integer type, the accessor wrapper does the conversion
381 // reasonably anyway, behind the scenes.
382 return itr->second->getVecDoubleValue(m_auxVectorData);*/
383 return m_accessorCache.at(varname)->getVecDoubleValue(m_auxVectorData);
384 }
385
386}
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
#define TYPE(CODE, TYP, IOTYP)
#define x
Define macros for attributes used to control the static checker.
RootUtils::TSMethodCall m_methodCall ATLAS_THREAD_SAFE
virtual bool isValid(const SG::AuxElement *auxElement) const
virtual int getIntValue(const SG::AuxElement *auxElement) const
virtual std::vector< int > getVecIntValue(const SG::AuxVectorData *auxVectorData)
virtual double getDoubleValue(const SG::AuxElement *auxElement) const
TMethodCollectionWrapper(const std::type_info &containerTypeinfo, const std::string &methodName)
virtual std::vector< double > getVecDoubleValue(const SG::AuxVectorData *auxVectorData)
virtual std::vector< int > getVecIntValue(const SG::AuxVectorData *auxVectorData)
TMethodWrapper(const std::type_info &elementTypeinfo, const std::string &methodName)
virtual std::vector< double > getVecDoubleValue(const SG::AuxVectorData *auxVectorData)
RootUtils::TSMethodCall m_methodCall ATLAS_THREAD_SAFE
virtual bool isValid(const SG::AuxElement *auxElement) const
virtual double getDoubleValue(const SG::AuxElement *auxElement) const
IProxyLoader::VariableType variableType()
virtual int getIntValue(const SG::AuxElement *auxElement) const
void setData(const SG::AuxElement *auxElement)
virtual double loadDoubleVariableFromString(const std::string &varname) const
virtual std::vector< double > loadVecDoubleVariableFromString(const std::string &varname) const
virtual int loadIntVariableFromString(const std::string &varname) const
virtual std::vector< int > loadVecIntVariableFromString(const std::string &varname) const
virtual IProxyLoader::VariableType variableTypeFromString(const std::string &varname) const
bool try_type(const std::string &varname, const std::type_info *ti, const AUX *data) const
IProxyLoader::VariableType try_all_known_types(const std::string &varname, const AUX *data, bool isVector) const
CxxUtils::ConcurrentStrMap< BaseAccessorWrapper *, CxxUtils::SimpleUpdater > accessorCache_t
virtual std::vector< int > loadVecIntVariableFromString(const std::string &varname) const
virtual IProxyLoader::VariableType variableTypeFromString(const std::string &varname) const
virtual int loadIntVariableFromString(const std::string &varname) const
virtual double loadDoubleVariableFromString(const std::string &varname) const
void setData(const SG::AuxVectorData *auxElement)
virtual std::vector< double > loadVecDoubleVariableFromString(const std::string &varname) const
Base class for elements of a container that can have aux data.
Definition AuxElement.h:483
Handle mappings between names and auxid_t.
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Manage lookup of vectors of auxiliary data.
int r
Definition globals.cxx:22
Namespace holding all the expression evaluation code.
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...
static const auxid_t null_auxid
To signal no aux data item.
Definition AuxTypes.h:30
size_t auxid_t
Identifier for a particular aux data item.
Definition AuxTypes.h:27
Convert a type_info to a normalized string representation (matching the names used in the root dictio...