ATLAS Offline Software
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 
13 namespace 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 
31  {
32  }
33 
35  {
36  TMethodCall* mc = m_methodCall.call();
37  if (!mc) return IProxyLoader::VT_UNK;
38  switch (mc->ReturnType()) {
39  case TMethodCall::kLong:
40  return IProxyLoader::VT_INT;
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 
112  {
113  }
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 
192  {
194  }
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 
290  {
291  return m_accessorCache.at(varname)->getIntValue(m_auxElement);
292  }
293 
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 
351  double xAODVectorProxyLoader::loadDoubleVariableFromString(const std::string &) const
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 }
ExpressionParsing::TMethodCollectionWrapper::~TMethodCollectionWrapper
virtual ~TMethodCollectionWrapper()
Definition: xAODVariableProxyLoaders.cxx:111
beamspotman.r
def r
Definition: beamspotman.py:676
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
ExpressionParsing::TMethodCollectionWrapper::getDoubleValue
virtual double getDoubleValue(const SG::AuxElement *auxElement) const
Definition: xAODVariableProxyLoaders.cxx:146
get_generator_info.result
result
Definition: get_generator_info.py:21
ExpressionParsing::xAODElementProxyLoader::loadVecIntVariableFromString
virtual std::vector< int > loadVecIntVariableFromString(const std::string &varname) const
Definition: xAODVariableProxyLoaders.cxx:299
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
SG::AuxTypeRegistry::instance
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Definition: AuxTypeRegistry.cxx:639
ExpressionParsing::TMethodCollectionWrapper::m_valid
bool m_valid
Definition: xAODVariableProxyLoaders.h:142
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
ExpressionParsing::TMethodCollectionWrapper::ATLAS_THREAD_SAFE
RootUtils::TSMethodCall m_methodCall ATLAS_THREAD_SAFE
Definition: xAODVariableProxyLoaders.h:141
SG::AuxElement
Base class for elements of a container that can have aux data.
Definition: AuxElement.h:483
ExpressionParsing::TMethodCollectionWrapper::TMethodCollectionWrapper
TMethodCollectionWrapper(const std::type_info &containerTypeinfo, const std::string &methodName)
Definition: xAODVariableProxyLoaders.cxx:89
ExpressionParsing::IProxyLoader::VT_VECDOUBLE
@ VT_VECDOUBLE
Definition: IProxyLoader.h:21
xAODVariableProxyLoaders.h
ExpressionParsing::xAODProxyLoader::try_type
bool try_type(const std::string &varname, const std::type_info *ti, const AUX *data) const
Definition: xAODVariableProxyLoaders.cxx:203
ExpressionParsing::TMethodWrapper::variableType
IProxyLoader::VariableType variableType()
Definition: xAODVariableProxyLoaders.cxx:34
ExpressionParsing::TMethodCollectionWrapper::getVecIntValue
virtual std::vector< int > getVecIntValue(const SG::AuxVectorData *auxVectorData)
Definition: xAODVariableProxyLoaders.cxx:151
CaloClusterListBadChannel.cls
cls
Definition: CaloClusterListBadChannel.py:8
ExpressionParsing::TMethodCollectionWrapper::getVecDoubleValue
virtual std::vector< double > getVecDoubleValue(const SG::AuxVectorData *auxVectorData)
Definition: xAODVariableProxyLoaders.cxx:167
ExpressionParsing::xAODVectorProxyLoader::variableTypeFromString
virtual IProxyLoader::VariableType variableTypeFromString(const std::string &varname) const
Definition: xAODVariableProxyLoaders.cxx:322
ExpressionParsing::xAODElementProxyLoader::setData
void setData(const SG::AuxElement *auxElement)
Definition: xAODVariableProxyLoaders.cxx:254
JetTiledMap::N
@ N
Definition: TiledEtaPhiMap.h:44
ExpressionParsing::xAODVectorProxyLoader::m_auxVectorData
const SG::AuxVectorData * m_auxVectorData
Definition: xAODVariableProxyLoaders.h:201
ExpressionParsing::TMethodCollectionWrapper::variableType
IProxyLoader::VariableType variableType()
Definition: xAODVariableProxyLoaders.cxx:115
x
#define x
ExpressionParsing::TMethodWrapper::isValid
virtual bool isValid(const SG::AuxElement *auxElement) const
Definition: xAODVariableProxyLoaders.cxx:50
ExpressionParsing::xAODVectorProxyLoader::xAODVectorProxyLoader
xAODVectorProxyLoader()=default
ExpressionParsing::TMethodWrapper::getVecDoubleValue
virtual std::vector< double > getVecDoubleValue(const SG::AuxVectorData *auxVectorData)
Definition: xAODVariableProxyLoaders.cxx:81
ExpressionParsing::TMethodWrapper::ATLAS_THREAD_SAFE
RootUtils::TSMethodCall m_methodCall ATLAS_THREAD_SAFE
Definition: xAODVariableProxyLoaders.h:119
SG::AuxTypeRegistry
Handle mappings between names and auxid_t.
Definition: AuxTypeRegistry.h:61
ExpressionParsing::IProxyLoader::VariableType
VariableType
Definition: IProxyLoader.h:21
SG::auxid_t
size_t auxid_t
Identifier for a particular aux data item.
Definition: AuxTypes.h:27
ExpressionParsing::IProxyLoader::VT_DOUBLE
@ VT_DOUBLE
Definition: IProxyLoader.h:21
ExpressionParsing::IProxyLoader::VT_UNK
@ VT_UNK
Definition: IProxyLoader.h:21
mc
Definition: mc.PG_single_nu_valid.py:1
ExpressionParsing::TMethodCollectionWrapper::isValid
virtual bool isValid(const SG::AuxElement *auxElement) const
Definition: xAODVariableProxyLoaders.cxx:131
lumiFormat.i
int i
Definition: lumiFormat.py:85
ExpressionParsing::xAODElementProxyLoader::m_auxElement
const SG::AuxElement * m_auxElement
Definition: xAODVariableProxyLoaders.h:183
ExpressionParsing::TMethodWrapper::~TMethodWrapper
virtual ~TMethodWrapper()
Definition: xAODVariableProxyLoaders.cxx:30
ExpressionParsing::xAODProxyLoader::try_all_known_types
IProxyLoader::VariableType try_all_known_types(const std::string &varname, const AUX *data, bool isVector) const
Definition: xAODVariableProxyLoaders.cxx:220
ExpressionParsing::xAODVectorProxyLoader::loadVecIntVariableFromString
virtual std::vector< int > loadVecIntVariableFromString(const std::string &varname) const
Definition: xAODVariableProxyLoaders.cxx:356
ExpressionParsing
Namespace holding all the expression evaluation code.
Definition: ExpressionParser.h:26
ExpressionParsing::IProxyLoader::VT_VECINT
@ VT_VECINT
Definition: IProxyLoader.h:21
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
ExpressionParsing::xAODVectorProxyLoader::loadDoubleVariableFromString
virtual double loadDoubleVariableFromString(const std::string &varname) const
Definition: xAODVariableProxyLoaders.cxx:351
normalizedTypeinfoName.h
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
ExpressionParsing::xAODElementProxyLoader::loadIntVariableFromString
virtual int loadIntVariableFromString(const std::string &varname) const
Definition: xAODVariableProxyLoaders.cxx:289
ExpressionParsing::xAODVectorProxyLoader::loadIntVariableFromString
virtual int loadIntVariableFromString(const std::string &varname) const
Definition: xAODVariableProxyLoaders.cxx:346
ExpressionParsing::IProxyLoader::VT_INT
@ VT_INT
Definition: IProxyLoader.h:21
TYPE
#define TYPE(CODE, TYP, IOTYP)
ExpressionParsing::xAODProxyLoader::accessorCache_t
CxxUtils::ConcurrentStrMap< BaseAccessorWrapper *, CxxUtils::SimpleUpdater > accessorCache_t
Definition: xAODVariableProxyLoaders.h:164
ExpressionParsing::TMethodCollectionWrapper::m_collectionProxy
TVirtualCollectionProxy * m_collectionProxy
Definition: xAODVariableProxyLoaders.h:140
ExpressionParsing::xAODProxyLoader::xAODProxyLoader
xAODProxyLoader()
Definition: xAODVariableProxyLoaders.cxx:186
ExpressionParsing::xAODElementProxyLoader::xAODElementProxyLoader
xAODElementProxyLoader()=default
ExpressionParsing::TMethodWrapper::m_valid
bool m_valid
Definition: xAODVariableProxyLoaders.h:120
ExpressionParsing::TMethodWrapper::getVecIntValue
virtual std::vector< int > getVecIntValue(const SG::AuxVectorData *auxVectorData)
Definition: xAODVariableProxyLoaders.cxx:76
LArG4AODNtuplePlotter.varname
def varname(hname)
Definition: LArG4AODNtuplePlotter.py:37
ExpressionParsing::xAODElementProxyLoader::loadDoubleVariableFromString
virtual double loadDoubleVariableFromString(const std::string &varname) const
Definition: xAODVariableProxyLoaders.cxx:294
ExpressionParsing::xAODElementProxyLoader::loadVecDoubleVariableFromString
virtual std::vector< double > loadVecDoubleVariableFromString(const std::string &varname) const
Definition: xAODVariableProxyLoaders.cxx:304
ExpressionParsing::TMethodWrapper::getIntValue
virtual int getIntValue(const SG::AuxElement *auxElement) const
Definition: xAODVariableProxyLoaders.cxx:60
ExpressionParsing::xAODVectorProxyLoader::setData
void setData(const SG::AuxVectorData *auxElement)
Definition: xAODVariableProxyLoaders.cxx:317
ExpressionParsing::xAODElementProxyLoader::variableTypeFromString
virtual IProxyLoader::VariableType variableTypeFromString(const std::string &varname) const
Definition: xAODVariableProxyLoaders.cxx:259
ExpressionParsing::TMethodWrapper::getDoubleValue
virtual double getDoubleValue(const SG::AuxElement *auxElement) const
Definition: xAODVariableProxyLoaders.cxx:68
runLayerRecalibration.isVector
string isVector
Definition: runLayerRecalibration.py:125
SG::AuxVectorData
Manage lookup of vectors of auxiliary data.
Definition: AuxVectorData.h:168
SG::AuxElement::container
const SG::AuxVectorData * container() const
Return the container holding this element.
checker_macros.h
Define macros for attributes used to control the static checker.
ExpressionParsing::xAODProxyLoader::reset
virtual void reset()
Definition: xAODVariableProxyLoaders.cxx:196
ExpressionParsing::xAODVectorProxyLoader::loadVecDoubleVariableFromString
virtual std::vector< double > loadVecDoubleVariableFromString(const std::string &varname) const
Definition: xAODVariableProxyLoaders.cxx:361
ExpressionParsing::TMethodWrapper::TMethodWrapper
TMethodWrapper(const std::type_info &elementTypeinfo, const std::string &methodName)
Definition: xAODVariableProxyLoaders.cxx:15
ExpressionParsing::xAODProxyLoader::~xAODProxyLoader
virtual ~xAODProxyLoader()
Definition: xAODVariableProxyLoaders.cxx:191
ExpressionParsing::TMethodCollectionWrapper::getIntValue
virtual int getIntValue(const SG::AuxElement *auxElement) const
Definition: xAODVariableProxyLoaders.cxx:141
SG::AuxVectorData::size_v
virtual size_t size_v() const =0
Return the size of the container.