ATLAS Offline Software
Loading...
Searching...
No Matches
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
20namespace {
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
110namespace 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 }
386
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
#define TYPE_CHECK_INSTANTIATE(MACRO)
Macro instantiating another macro for all usual "primitive" types.
#define ISPRIMITIVETYPE_SPECIALIZE(TYPE)
#define GETTYPEINFO_SPECIALIZE(TYPE)
Macro returning the type info for a given type name.
#define XAOD_MESSAGE(MESSAGE)
Simple macro for printing error/verbose messages.
Helper for emitting error messages.
uint32_t sgkey_t
Type used for hashed StoreGate key+CLID pairs.
Definition sgkey_t.h:32
@ open
Definition BinningType.h:40
const std::type_info & getTypeInfo(EDataType type)
This function is used when reading a primitive branch from an input file without the user explicitly ...
SG::sgkey_t hash(const std::string &name)
This function provides a hashed version of the key (branch) names used in the xAOD file,...
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...
char rootType(char typeidType)
This function is used internally in the code when creating primitive dynamic auxiliary branches.
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.
bool isPrimitiveType(std::string_view typeName)
Check if the type name describes a primitive type.
std::string getTypeName(const std::type_info &ti)
This function is necessary in order to create type names that ROOT can understand.
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...
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
TChain * tree