ATLAS Offline Software
Control/AthContainers/Root/debug.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
13 #include "AthContainers/debug.h"
19 #include "AthLinks/DataLinkBase.h"
20 #ifndef XAOD_STANDALONE
21 # include "SGTools/DataProxy.h"
22 #endif
23 #include "CxxUtils/StrFormat.h"
24 #include <format>
25 #include <vector>
26 #include <sstream>
27 #include <iostream>
28 
29 
30 namespace SGdebug {
31 
32 
37 std::string aux_var_name (SG::auxid_t id)
38 {
40  return reg.getClassName(id) + "::" + reg.getName(id);
41 }
42 
43 
49 {
50  std::cout << aux_var_name(id) << "\n";
51 }
52 
53 
54 /******************************************************************************
55  * Print the list of aux variables given some object.
56  */
57 
58 
63 void print_aux_vars (const SG::auxid_set_t& auxids,
64  const SG::auxid_set_t& decors /*= SG::auxid_set_t()*/)
65 {
67  std::vector<SG::auxid_t> ids (auxids.begin(), auxids.end());
68  std::sort (ids.begin(), ids.end());
69 
70  for (SG::auxid_t id : ids) {
71  std::cout << id << " "
72  << reg.getClassName(id) << "::" << reg.getName(id) << " "
73  << "[" << reg.getTypeName(id);
74 
75  SG::AuxVarFlags flags = reg.getFlags(id);
77  std::cout << " (atomic)";
78  }
80  std::cout << " (linked)";
81  }
82  if (decors.test (id)) {
83  std::cout << " (decor)";
84  }
85 
86  std::cout << "]\n";
87  }
88 }
89 
90 
96 {
97  print_aux_vars (store.getAuxIDs(), store.getDecorIDs());
98 }
99 
100 
106 {
108 }
109 
110 
116 {
117  print_aux_vars (vec.getAuxIDs(), vec.getDecorIDs());
118 }
119 
120 
126 {
127  print_aux_vars (*vec);
128 }
129 
130 
136 {
137  print_aux_vars (elt.getAuxIDs(), elt.getDecorIDs());
138 }
139 
140 
146 {
147  print_aux_vars (*elt);
148 }
149 
150 
151 /******************************************************************************
152  * Dump out aux variables.
153  */
154 
155 
156 namespace {
157 
158 
159 template <class T>
160 void convert (std::ostream& os, const T& x)
161 {
162  os << x;
163 }
164 
165 
166 void convert (std::ostream& os, const char x)
167 {
168  os << static_cast<int > (x);
169 }
170 
171 
172 void convert (std::ostream& os, const unsigned char x)
173 {
174  os << static_cast<unsigned > (x);
175 }
176 
177 
178 void convert (std::ostream& os, const float x)
179 {
180  os << CxxUtils::strformat ("%.3f", x);
181 }
182 
183 
184 void convert (std::ostream& os, const double x)
185 {
186  os << CxxUtils::strformat ("%.3f", x);
187 }
188 
189 
190 void convert (std::ostream& os, const SG::JaggedVecEltBase& x, size_t i)
191 {
192  os << std::format ("[{},{}]", x.begin(i), x.end());
193 }
194 
195 
196 void convert (std::ostream& os, const DataLinkBase& x)
197 {
198 #ifdef XAOD_STANDALONE
199  os << std::format ("DataLink[{}]", x.persKey());
200 #else
201  os << std::format ("DataLink[{}/{}]", x.proxy() ? x.proxy()->clID() : CLID_NULL, x.dataID());
202 #endif
203 }
204 
205 
206 void convert (std::ostream& os, const SG::PackedLinkBase& x)
207 {
208  os << std::format ("PackedLink[{}/{}]", x.collection(), x.index());
209 }
210 
211 
212 template <class T>
213 void convert (std::ostream& os, const std::vector<T>& x)
214 {
215  os << "[";
216  bool first = true;
217  // using `decltype(auto)` in case T=bool
218  // cppcheck-suppress internalAstError
219  for (decltype(auto) elt : x) {
220  if (first)
221  first = false;
222  else
223  os << ", ";
224  convert (os, elt);
225  }
226  os << "]";
227 }
228 
229 
230 struct AuxVarSort
231 {
232  AuxVarSort (SG::auxid_t the_id)
233  : id(the_id),
234  name(aux_var_name(the_id))
235  {}
236 
237  SG::auxid_t id;
238  std::string name;
239 };
240 
241 
242 bool operator< (const AuxVarSort& a, const AuxVarSort& b )
243 {
244  return a.name < b.name;
245 }
246 
247 
248 } // anonymous namespace
249 
250 
257 std::string aux_var_as_string (SG::auxid_t auxid, const void* p, size_t i)
258 {
259  if (!p) {
260  return "(null)";
261  }
262 
263  std::ostringstream os;
264 
266  const std::type_info* ti = r.getType(auxid);
267 #define CONVERT(T) if (ti == &typeid(T)) convert (os, *reinterpret_cast<const T*>(p)); else
268 #define CONVERT1(T) CONVERT(T) CONVERT(std::vector<T>)
269  CONVERT1 (int)
270  CONVERT1 (unsigned int)
271  CONVERT1 (short)
272  CONVERT1 (unsigned short)
273  CONVERT1 (char)
274  CONVERT1 (unsigned char)
275  CONVERT1 (long)
276  CONVERT1 (unsigned long)
277  CONVERT1 (long long)
278  CONVERT1 (unsigned long long)
279  CONVERT1 (float)
280  CONVERT1 (double)
281  CONVERT1 (bool)
282  CONVERT1 (std::string)
283  //else
284  {
285  std::string tiname = AthContainers_detail::typeinfoName(*ti);
286  if (tiname.starts_with ("SG::JaggedVecElt<")) {
287  convert (os, *reinterpret_cast<const SG::JaggedVecEltBase*>(p), i);
288  }
289  else if (tiname.starts_with ("DataLink<")) {
290  convert (os, *reinterpret_cast<const DataLinkBase*>(p));
291  }
292  else if (tiname.starts_with ("SG::PackedLink<")) {
293  convert (os, *reinterpret_cast<const SG::PackedLinkBase*>(p));
294  }
295  else if (tiname.starts_with ("std::vector<SG::PackedLink<")) {
296  convert (os, *reinterpret_cast<const std::vector<SG::PackedLinkBase>*>(p));
297  }
298  else {
299  os << "<??? " << tiname << ">";
300  }
301  }
302  return os.str();
303 }
304 
305 
312 void dump_aux_vars (std::ostream& os, const SG::IConstAuxStore& store, size_t i)
313 {
314  if (i >= store.size()) return;
316  const SG::auxid_set_t& ids = store.getAuxIDs();
317  std::vector<AuxVarSort> vars (ids.begin(), ids.end());
318  std::sort (vars.begin(), vars.end());
319  for (const AuxVarSort& v : vars) {
320  if (reg.isLinked (v.id)) continue;
321  const void* pbeg = store.getData (v.id);
322  size_t eltsz = reg.getEltSize (v.id);
323  const char* p = reinterpret_cast<const char*>(pbeg) + eltsz*i;
324  os << v.name << " " << aux_var_as_string (v.id, p, i) << "\n";
325  SG::auxid_t linked_id = reg.linkedVariable (v.id);
326  if (linked_id != SG::null_auxid) {
327  os << " linked: " << aux_var_name (linked_id) << " ";
328  const SG::IAuxTypeVector* lv = store.linkedVector (v.id);
329  if (!lv) {
330  os << "(missing linkedVector)\n";
331  continue;
332  }
333  size_t sz = lv->size();
334  const char* lbeg = reinterpret_cast<const char*>(lv->toPtr());
335  size_t leltsz = reg.getEltSize (linked_id);
336  os << "[";
337  bool first = true;
338  for (size_t j = 0; j < sz; j++) {
339  if (first)
340  first = false;
341  else
342  os << ", ";
343  const char* p = reinterpret_cast<const char*>(lbeg) + leltsz*j;
344  os << aux_var_as_string (linked_id, p, i);
345  }
346  os << "]\n";
347  }
348  }
349 }
350 
351 
358 {
359  dump_aux_vars (std::cout, store, i);
360 }
361 
362 
369 {
370  dump_aux_vars (*store, i);
371 }
372 
373 
379 {
380  size_t sz = store.size();
381  for (size_t i = 0; i < sz; i++) {
382  std::cout << "=== Element " << i << "\n";
383  dump_aux_vars (store, i);
384  }
385 }
386 
387 
393 {
394  dump_aux_vars (*store);
395 }
396 
397 
403 void dump_aux_vars (const SG::AuxVectorData& vec, size_t i)
404 {
405  const SG::IConstAuxStore* store = vec.getConstStore();
406  if (store)
407  dump_aux_vars (*store, i);
408 }
409 
410 
416 void dump_aux_vars (const SG::AuxVectorData* vec, size_t i)
417 {
418  dump_aux_vars (*vec, i);
419 }
420 
421 
427 {
428  const SG::IConstAuxStore* store = vec.getConstStore();
429  if (store)
430  dump_aux_vars (*store);
431 }
432 
433 
439 {
440  dump_aux_vars (*vec);
441 }
442 
443 
448 void dump_aux_vars (const SG::AuxElement& elt)
449 {
450  const SG::AuxVectorData* cont = elt.container();
451  if (cont)
452  dump_aux_vars (*cont, elt.index());
453 }
454 
455 
460 void dump_aux_vars (const SG::AuxElement* elt)
461 {
462  dump_aux_vars (*elt);
463 }
464 
465 
466 } // namespace SG
operator<
bool operator<(const DataVector< T > &a, const DataVector< T > &b)
Vector ordering relation.
SGTest::store
TestStore store
Definition: TestStore.cxx:23
beamspotman.r
def r
Definition: beamspotman.py:676
fitman.sz
sz
Definition: fitman.py:527
vtune_athena.format
format
Definition: vtune_athena.py:14
SG::AuxTypeRegistry::instance
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Definition: AuxTypeRegistry.cxx:639
AthenaPoolTestRead.flags
flags
Definition: AthenaPoolTestRead.py:8
SG::AuxElement
Base class for elements of a container that can have aux data.
Definition: AuxElement.h:483
SGdebug
Definition: Control/AthContainers/AthContainers/debug.h:22
SG::AuxTypeRegistry::getName
std::string getName(SG::auxid_t auxid) const
Return the name of an aux data item.
Definition: AuxTypeRegistry.cxx:881
CxxUtils::ConcurrentBitset::end
const_iterator end() const
Return an end iterator.
vec
std::vector< size_t > vec
Definition: CombinationsGeneratorTest.cxx:9
x
#define x
SG::AuxTypeRegistry
Handle mappings between names and auxid_t.
Definition: AuxTypeRegistry.h:61
SG::JaggedVecEltBase
Describe one element of a jagged vector (base class).
Definition: JaggedVecImpl.h:52
SG::Linked
@ Linked
Mark that this variable is linked to another one.
Definition: AuxTypes.h:77
SG::auxid_t
size_t auxid_t
Identifier for a particular aux data item.
Definition: AuxTypes.h:27
StrFormat.h
Provide helper functions to create formatted strings.
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
Athena::typeinfoName
std::string typeinfoName(const std::type_info &ti)
Convert a type_info to a demangled string.
Definition: AthenaKernel/src/ClassName.cxx:23
SG::AuxTypeRegistry::getTypeName
std::string getTypeName(SG::auxid_t auxid) const
Return the type name of an aux data item.
Definition: AuxTypeRegistry.cxx:923
lumiFormat.i
int i
Definition: lumiFormat.py:85
SG::AuxTypeRegistry::getFlags
Flags getFlags(SG::auxid_t auxid) const
Return flags associated with an auxiliary variable.
Definition: AuxTypeRegistry.cxx:990
PackedLinkImpl.h
Definition of PackedLink type.
SG::AuxTypeRegistry::linkedVariable
SG::auxid_t linkedVariable(SG::auxid_t auxid) const
Return the auxid if the linked variable, if there is one.
Definition: AuxTypeRegistry.cxx:1006
SG::AuxTypeRegistry::getEltSize
size_t getEltSize(SG::auxid_t auxid) const
Return size of an element in the STL vector.
Definition: AuxTypeRegistry.cxx:977
error.h
Helper for emitting error messages.
SG::AuxElement::getAuxIDs
const SG::auxid_set_t & getAuxIDs() const
Return a set of identifiers for existing data items for this object.
Definition: AuxElement.cxx:355
SG::AuxElement::index
size_t index() const
Return the index of this element within its container.
SG::AuxVarFlags
AuxVarFlags
Additional flags to qualify an auxiliary variable.
Definition: AuxTypes.h:58
ReadFromCoolCompare.os
os
Definition: ReadFromCoolCompare.py:231
SG::AuxTypeRegistry::getClassName
std::string getClassName(SG::auxid_t auxid) const
Return the class name associated with an aux data item (may be blank).
Definition: AuxTypeRegistry.cxx:895
CxxUtils::ConcurrentBitset::begin
const_iterator begin() const
Return a begin iterator.
SGdebug::dump_aux_vars
void dump_aux_vars(std::ostream &os, const SG::IConstAuxStore &store, size_t i)
Dump aux variables from a store for a single element.
Definition: Control/AthContainers/Root/debug.cxx:312
CxxUtils::strformat
std::string strformat(const char *fmt,...)
return a std::string according to a format fmt and varargs
Definition: StrFormat.cxx:49
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:239
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
python.subdetectors.mmg.ids
ids
Definition: mmg.py:8
SG::AuxTypeRegistry::isLinked
bool isLinked(SG::auxid_t auxid) const
Test whether this is a linked variable.
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
TMVAToMVAUtils::convert
std::unique_ptr< MVAUtils::BDT > convert(TMVA::MethodBDT *bdt, bool isRegression=true, bool useYesNoLeaf=false)
Definition: TMVAToMVAUtils.h:114
SG::Atomic
@ Atomic
Mark that this variable should only be accessed atomically.
Definition: AuxTypes.h:70
SG::AuxElement::getDecorIDs
const SG::auxid_set_t & getDecorIDs() const
Return a set of identifiers for decorations for this object.
Definition: AuxElement.cxx:378
JaggedVecImpl.h
Definition of JaggedVecElt.
python.PyAthena.v
v
Definition: PyAthena.py:154
a
TList * a
Definition: liststreamerinfos.cxx:10
SG::PackedLinkBase
A packed version of ElementLink.
Definition: PackedLinkImpl.h:47
CONVERT1
#define CONVERT1(T)
DeMoScan.first
bool first
Definition: DeMoScan.py:536
SG::IAuxTypeVector
Abstract interface for manipulating vectors of arbitrary types.
Definition: IAuxTypeVector.h:42
AuxTypeRegistry.h
Handle mappings between names and auxid_t.
SG::auxid_set_t
A set of aux data identifiers.
Definition: AuxTypes.h:47
SGdebug::print_aux_vars
void print_aux_vars(const SG::auxid_set_t &auxids, const SG::auxid_set_t &decors=SG::auxid_set_t())
Print the list of aux variables in a set.
Definition: Control/AthContainers/Root/debug.cxx:63
SGdebug::print_aux_var_name
void print_aux_var_name(SG::auxid_t id)
Print the name corresponding to a given aux id.
Definition: Control/AthContainers/Root/debug.cxx:48
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.
IConstAuxStore.h
Interface for const operations on an auxiliary store.
SG::IConstAuxStore
Interface for const operations on an auxiliary store.
Definition: IConstAuxStore.h:64
SG::IAuxTypeVector::size
virtual size_t size() const =0
Return the size of the vector.
SGdebug::aux_var_name
std::string aux_var_name(SG::auxid_t id)
Return the name corresponding to a given aux id.
Definition: Control/AthContainers/Root/debug.cxx:37
DataLinkBase
Type-independent part of DataLink; holds the persistent state.
Definition: AthLinks/DataLinkBase.h:39
SGdebug::aux_var_as_string
std::string aux_var_as_string(SG::auxid_t auxid, const void *p, size_t i)
Convert an aux variable to a string.
Definition: Control/AthContainers/Root/debug.cxx:257
SG::IAuxTypeVector::toPtr
virtual void * toPtr()=0
Return a pointer to the start of the vector's data.
debug.h
Helper functions intended to be called from the debugger.
CxxUtils::ConcurrentBitset::test
bool test(bit_t bit) const
Test to see if a bit is set.
DataProxy.h