ATLAS Offline Software
Control/xAODRootAccess/Root/Utils.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // STL include(s):
6 #include <functional>
7 #include <regex>
8 
9 // ROOT include(s):
10 #include <TError.h>
11 
12 // EDM include(s):
14 
15 // Local include(s):
18 
19 
20 namespace {
21 
30  void removeDefaultTemplateParameters( std::string& name,
31  const std::string& vectorName ) {
32 
33  size_t vecPos = 0;
34  while( ( vecPos = name.find( vectorName + "<", vecPos ) ) !=
35  std::string::npos ) {
36 
37  // Update the position to point at the end of the search string:
38  vecPos += ( vectorName.size() + 1 );
39 
40  // Look for "the comma" that we should remove everything
41  // after:
42  int open = 0;
43  size_t commaPos = std::string::npos;
44  for( size_t pos = vecPos; pos < name.size(); ++pos ) {
45  switch( name[ pos ] ) {
46  case '<':
47  ++open;
48  break;
49  case '>':
50  --open;
51  break;
52  case ',':
53  if( ! open ) {
54  commaPos = pos;
55  }
56  break;
57  default:
58  break;
59  }
60  if( commaPos != std::string::npos ) {
61  break;
62  }
63  }
64 
65  // If we didn't find a comma, then let's give up:
66  if( commaPos == std::string::npos ) {
67  continue;
68  }
69 
70  // If we did, then let's look for the closing '>' of the vector:
71  open = 0;
72  size_t closingPos = std::string::npos;
73  for( size_t pos = commaPos; pos < name.size(); ++pos ) {
74  switch( name[ pos ] ) {
75  case '<':
76  ++open;
77  break;
78  case '>':
79  if( ! open ) {
80  closingPos = pos;
81  break;
82  }
83  --open;
84  break;
85  default:
86  break;
87  }
88  if( closingPos != std::string::npos ) {
89  break;
90  }
91  }
92 
93  // It's bad if we didn't find the closing '>'...
94  if( closingPos == std::string::npos ) {
95  ::Error( "removeDefaultTemplateParameters",
96  XAOD_MESSAGE( "Couldn't find closing '>' in name %s" ),
97  name.c_str() );
98  return;
99  }
100 
101  // Remove the identified part of the string:
102  name.erase( commaPos, closingPos - commaPos );
103  }
104 
105  return;
106  }
107 
108 } // private namespace
109 
110 namespace xAOD {
111 
112  namespace Utils {
113 
125  SG::sgkey_t hash( const std::string& name ) {
126 
127  static constexpr SG::sgkey_t MASK = (~static_cast<SG::sgkey_t>(0)) >> 2;
128 
129  // The helper object:
130  static const std::hash< std::string > helper;
131  // Let the helper do the work:
132  return ( static_cast< SG::sgkey_t >( helper( name ) ) & MASK );
133  }
134 
144  std::string dynBranchPrefix( const std::string& key ) {
145 
146  // Make a copy of the key that we can modify:
147  std::string result = key;
148 
149  // If it ends in a dot, then let's exchange that dot for
150  // "Dyn.":
151  if( result[ result.size() - 1 ] == '.' ) {
152  result.replace( result.size() - 1, 1, "Dyn." );
153  }
154  // If it doesn't end in a dot, then let's just add "Dyn." at
155  // the end, and be done with it:
156  else {
157  result += "Dyn.";
158  }
159 
160  return result;
161  }
162 
170  std::string dynFieldPrefix( const std::string& key ) {
171  // Make a copy of the key that we can modify:
172  std::string result = key;
173 
174  // If it ends in a colon, then let's exchange that colon for
175  // "Dyn:":
176  if( result[ result.size() - 1 ] == ':' ) {
177  result.replace( result.size() - 1, 1, "Dyn:" );
178  }
179  // If it doesn't end in a colon, then let's just add "Dyn:" at
180  // the end:
181  else {
182  result += "Dyn:";
183  }
184 
185  return result;
186  }
187 
194  const std::type_info& getTypeInfo( EDataType type ) {
195 
196  switch( type ) {
197 
198  case kChar_t:
199  case kchar:
200  return typeid( Char_t );
201  case kUChar_t:
202  return typeid( UChar_t );
203  case kShort_t:
204  return typeid( Short_t );
205  case kUShort_t:
206  return typeid( UShort_t );
207  case kInt_t:
208  case kCounter:
209  return typeid( Int_t );
210  case kUInt_t:
211  case kBits:
212  case kDataTypeAliasUnsigned_t:
213  return typeid( UInt_t );
214  case kLong_t:
215  return typeid( Long_t );
216  case kULong_t:
217  return typeid( ULong_t );
218  case kFloat_t:
219  return typeid( Float_t );
220  case kDouble_t:
221  return typeid( Double_t );
222  case kDouble32_t:
223  return typeid( Double32_t );
224  case kBool_t:
225  return typeid( Bool_t );
226  case kLong64_t:
227  return typeid( Long64_t );
228  case kULong64_t:
229  return typeid( ULong64_t );
230  case kFloat16_t:
231  return typeid( Float16_t );
232  case kCharStar:
233  return typeid( char* );
234  case kVoid_t:
235  return typeid( void );
236  default:
237  ::Error( "xAOD::Utils::getTypeInfo",
238  XAOD_MESSAGE( "Unknown data type (%i) received" ),
239  static_cast< int >( type ) );
240  return typeid( void );
241  }
242  }
243 
245 #define TYPE_CHECK_INSTANTIATE(MACRO) \
246  MACRO(std::int8_t) \
247  MACRO(std::uint8_t) \
248  MACRO(std::int16_t) \
249  MACRO(std::uint16_t) \
250  MACRO(std::int32_t) \
251  MACRO(std::uint32_t) \
252  MACRO(std::int64_t) \
253  MACRO(std::uint64_t) \
254  MACRO(char) \
255  MACRO(float) \
256  MACRO(double) \
257  MACRO(bool)
258 
260 #define GETTYPEINFO_SPECIALIZE(TYPE) \
261  if(typeName == #TYPE) { \
262  return typeid(TYPE); \
263  }
264 
265  const std::type_info& getTypeInfo(std::string_view typeName) {
267  ::Error("xAOD::Utils::getTypeInfo",
268  XAOD_MESSAGE("Unknown data type (%s) received"),
269  typeName.data());
270  return typeid(void);
271  }
272 
273 #undef GETTYPEINFO_SPECIALIZE
274 
275 #define ISPRIMITIVETYPE_SPECIALIZE(TYPE) \
276  if(typeName == #TYPE) { \
277  return true; \
278  }
279 
280  bool isPrimitiveType(std::string_view typeName) {
282  return false;
283  }
284 
285 #undef ISPRIMITIVETYPE_SPECIALIZE
286 #undef TYPE_CHECK_INSTANTIATE
287 
295  char rootType( char typeidType ) {
296 
297  // Do the hard-coded translation:
298  switch( typeidType ) {
299 
300  case 'c':
301  return 'B';
302  break;
303  case 'h':
304  return 'b';
305  break;
306  case 's':
307  return 'S';
308  break;
309  case 't':
310  return 's';
311  break;
312  case 'i':
313  return 'I';
314  break;
315  case 'j':
316  return 'i';
317  break;
318  case 'f':
319  return 'F';
320  break;
321  case 'd':
322  return 'D';
323  break;
324  case 'x':
325  return 'L';
326  break;
327  case 'y':
328  case 'm': // Not sure how platform-independent this one is...
329  return 'l';
330  break;
331  case 'b':
332  return 'O';
333  break;
334  }
335 
336  // If we didn't find this type:
337  Error( "xAOD::Utils::rootType",
338  XAOD_MESSAGE( "Received an unknown type: %c" ), typeidType );
339  return '\0';
340  }
341 
354  std::string getTypeName( const std::type_info& ti ) {
355 
356  // Get the "raw" type name:
357  std::string result = AthContainers_detail::typeinfoName( ti );
358 
359  // If there are no "tricky" classes in the name, then we're done
360  // already:
361  if( ( result.find( "DataVector<" ) == std::string::npos ) &&
362  ( result.find( "std::vector<" ) == std::string::npos ) &&
363  ( result.find( "std::__1::vector<") == std::string::npos ) ) {
364  return result;
365  }
366 
367  // Deal with the vector types:
368  removeDefaultTemplateParameters( result, "DataVector" );
369  removeDefaultTemplateParameters( result, "std::vector" );
370  removeDefaultTemplateParameters( result, "std::__1::vector" );
371 
372  // Make sure that no ">>" parts are left in the type name:
373  size_t pos = 0;
374  while( ( pos = result.find( ">>" ) ) != std::string::npos ) {
375  result.replace( pos, 2, "> >" );
376  }
377 
378  // Remove all "__1" namespaces from the type name:
379  while( ( pos = result.find( "__1::" ) ) != std::string::npos ) {
380  result.replace( pos, 5, "" );
381  }
382 
383  // Return the massaged name:
384  return result;
385  }
394  std::string getFirstBranchMatch( TTree * tree,
395  const std::string& pre ) {
396  const TObjArray * pBranches = tree->GetListOfBranches();
397  const std::regex pattern( ".*" + pre + ".*" );
398 
399  for( int i = 0, nLast = pBranches->GetLast(); i <= nLast; ++i ) {
400  const std::string name = pBranches->At(i)->GetName();
401 
402  if( std::regex_match( name, pattern ) )
403  return name;
404 
405  }
406 
407  return pre;
408  }
409 
410  } // namespace Utils
411 
412 } // namespace xAOD
mergePhysValFiles.pattern
pattern
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:25
xAOD::name
name
Definition: TriggerMenuJson_v1.cxx:29
GETTYPEINFO_SPECIALIZE
#define GETTYPEINFO_SPECIALIZE(TYPE)
Macro returning the type info for a given type name.
Definition: Control/xAODRootAccess/Root/Utils.cxx:260
get_generator_info.result
result
Definition: get_generator_info.py:21
tree
TChain * tree
Definition: tile_monitor.h:30
xAOD::Utils::dynFieldPrefix
std::string dynFieldPrefix(const std::string &key)
This function is used to figure out what to name dynamic auxiliary field coming from a container call...
Definition: Control/xAODRootAccess/Root/Utils.cxx:170
xAOD
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
Definition: ICaloAffectedTool.h:24
XAOD_MESSAGE
#define XAOD_MESSAGE(MESSAGE)
Simple macro for printing error/verbose messages.
Definition: Control/xAODRootAccess/xAODRootAccess/tools/Message.h:19
xAOD::Utils::isPrimitiveType
bool isPrimitiveType(std::string_view typeName)
Check if the type name describes a primitive type.
Definition: Control/xAODRootAccess/Root/Utils.cxx:280
Utils.h
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
xAOD::Utils::dynBranchPrefix
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...
Definition: Control/xAODRootAccess/Root/Utils.cxx:144
runBeamSpotCalibration.helper
helper
Definition: runBeamSpotCalibration.py:115
PrepareReferenceFile.regex
regex
Definition: PrepareReferenceFile.py:43
Athena::typeinfoName
std::string typeinfoName(const std::type_info &ti)
Convert a type_info to a demangled string.
Definition: AthenaKernel/src/ClassName.cxx:23
xAOD::Utils::getTypeName
std::string getTypeName(const std::type_info &ti)
This function is necessary in order to create type names that ROOT can understand.
Definition: Control/xAODRootAccess/Root/Utils.cxx:354
lumiFormat.i
int i
Definition: lumiFormat.py:85
Message.h
error.h
Helper for emitting error messages.
ISPRIMITIVETYPE_SPECIALIZE
#define ISPRIMITIVETYPE_SPECIALIZE(TYPE)
Definition: Control/xAODRootAccess/Root/Utils.cxx:275
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
SG::sgkey_t
uint32_t sgkey_t
Type used for hashed StoreGate key+CLID pairs.
Definition: CxxUtils/CxxUtils/sgkey_t.h:32
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:16
xAOD::Utils::getTypeInfo
const std::type_info & getTypeInfo(EDataType type)
This function is used when reading a primitive branch from an input file without the user explicitly ...
Definition: Control/xAODRootAccess/Root/Utils.cxx:194
Trk::open
@ open
Definition: BinningType.h:40
TYPE_CHECK_INSTANTIATE
#define TYPE_CHECK_INSTANTIATE(MACRO)
Macro instantiating another macro for all usual "primitive" types.
Definition: Control/xAODRootAccess/Root/Utils.cxx:245
xAOD::Utils::getFirstBranchMatch
std::string getFirstBranchMatch(TTree *tree, const std::string &pre)
This function is used to search for a branch in a TTree that contains a given substring.
Definition: Control/xAODRootAccess/Root/Utils.cxx:394
ReadCalibFromCool.typeName
typeName
Definition: ReadCalibFromCool.py:477
L1Topo::Error
Error
The different types of error that can be flagged in the L1TopoRDO.
Definition: Error.h:16
Utils
Definition: CaloCellSelectorUtils.cxx:10
xAOD::Utils::hash
SG::sgkey_t hash(const std::string &name)
This function provides a hashed version of the key (branch) names used in the xAOD file,...
Definition: Control/xAODRootAccess/Root/Utils.cxx:125
RoiUtil::MASK
MASK
Definition: RoiSerialise.cxx:35
xAOD::Utils::rootType
char rootType(char typeidType)
This function is used internally in the code when creating primitive dynamic auxiliary branches.
Definition: Control/xAODRootAccess/Root/Utils.cxx:295
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37