ATLAS Offline Software
Control/xAODRootAccess/Root/Utils.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 
6 // STL include(s):
7 #include <functional>
8 #include <regex>
9 
10 // ROOT include(s):
11 #include <TError.h>
12 
13 // EDM include(s):
15 
16 // Local include(s):
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 
169  const std::type_info& getTypeInfo( EDataType type ) {
170 
171  switch( type ) {
172 
173  case kChar_t:
174  case kchar:
175  return typeid( Char_t );
176  case kUChar_t:
177  return typeid( UChar_t );
178  case kShort_t:
179  return typeid( Short_t );
180  case kUShort_t:
181  return typeid( UShort_t );
182  case kInt_t:
183  case kCounter:
184  return typeid( Int_t );
185  case kUInt_t:
186  case kBits:
187  case kDataTypeAliasUnsigned_t:
188  return typeid( UInt_t );
189  case kLong_t:
190  return typeid( Long_t );
191  case kULong_t:
192  return typeid( ULong_t );
193  case kFloat_t:
194  return typeid( Float_t );
195  case kDouble_t:
196  return typeid( Double_t );
197  case kDouble32_t:
198  return typeid( Double32_t );
199  case kBool_t:
200  return typeid( Bool_t );
201  case kLong64_t:
202  return typeid( Long64_t );
203  case kULong64_t:
204  return typeid( ULong64_t );
205  case kFloat16_t:
206  return typeid( Float16_t );
207  case kCharStar:
208  return typeid( char* );
209  case kVoid_t:
210  return typeid( void );
211  default:
212  ::Error( "xAOD::Utils::getTypeInfo",
213  XAOD_MESSAGE( "Unknown data type (%i) received" ),
214  static_cast< int >( type ) );
215  return typeid( void );
216  }
217  }
218 
226  char rootType( char typeidType ) {
227 
228  // Do the hard-coded translation:
229  switch( typeidType ) {
230 
231  case 'c':
232  return 'B';
233  break;
234  case 'h':
235  return 'b';
236  break;
237  case 's':
238  return 'S';
239  break;
240  case 't':
241  return 's';
242  break;
243  case 'i':
244  return 'I';
245  break;
246  case 'j':
247  return 'i';
248  break;
249  case 'f':
250  return 'F';
251  break;
252  case 'd':
253  return 'D';
254  break;
255  case 'x':
256  return 'L';
257  break;
258  case 'y':
259  case 'm': // Not sure how platform-independent this one is...
260  return 'l';
261  break;
262  case 'b':
263  return 'O';
264  break;
265  }
266 
267  // If we didn't find this type:
268  Error( "xAOD::Utils::rootType",
269  XAOD_MESSAGE( "Received an unknown type: %c" ), typeidType );
270  return '\0';
271  }
272 
285  std::string getTypeName( const std::type_info& ti ) {
286 
287  // Get the "raw" type name:
288  std::string result = AthContainers_detail::typeinfoName( ti );
289 
290  // If there are no "tricky" classes in the name, then we're done
291  // already:
292  if( ( result.find( "DataVector<" ) == std::string::npos ) &&
293  ( result.find( "std::vector<" ) == std::string::npos ) &&
294  ( result.find( "std::__1::vector<") == std::string::npos ) ) {
295  return result;
296  }
297 
298  // Deal with the vector types:
299  removeDefaultTemplateParameters( result, "DataVector" );
300  removeDefaultTemplateParameters( result, "std::vector" );
301  removeDefaultTemplateParameters( result, "std::__1::vector" );
302 
303  // Make sure that no ">>" parts are left in the type name:
304  size_t pos = 0;
305  while( ( pos = result.find( ">>" ) ) != std::string::npos ) {
306  result.replace( pos, 2, "> >" );
307  }
308 
309  // Remove all "__1" namespaces from the type name:
310  while( ( pos = result.find( "__1::" ) ) != std::string::npos ) {
311  result.replace( pos, 5, "" );
312  }
313 
314  // Return the massaged name:
315  return result;
316  }
317 
318  std::string getFirstBranchMatch( TTree * tree,
319  const std::string& pre ) {
320  const TObjArray * pBranches = tree->GetListOfBranches();
321  const std::regex pattern( ".*" + pre + ".*" );
322 
323  for( int i = 0, nLast = pBranches->GetLast(); i <= nLast; ++i ) {
324  const std::string name = pBranches->At(i)->GetName();
325 
326  if( std::regex_match( name, pattern ) )
327  return name;
328 
329  }
330 
331  return pre;
332  }
333 
334  } // namespace Utils
335 
336 } // namespace xAOD
mergePhysValFiles.pattern
pattern
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:26
xAOD::name
name
Definition: TriggerMenuJson_v1.cxx:29
get_generator_info.result
result
Definition: get_generator_info.py:21
tree
TChain * tree
Definition: tile_monitor.h:30
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
Utils.h
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:112
PrepareReferenceFile.regex
regex
Definition: PrepareReferenceFile.py:43
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:285
lumiFormat.i
int i
Definition: lumiFormat.py:92
Message.h
error.h
Helper for emitting error messages.
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
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:18
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:169
Trk::open
@ open
Definition: BinningType.h:40
xAOD::Utils::getFirstBranchMatch
std::string getFirstBranchMatch(TTree *tree, const std::string &pre)
Search for branches, returns search term on no result.
Definition: Control/xAODRootAccess/Root/Utils.cxx:318
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
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:226
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37