ATLAS Offline Software
Loading...
Searching...
No Matches
PhysicsAnalysis/D3PDMaker/D3PDMakerReader/python/Helpers.py
Go to the documentation of this file.
1# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
2
3#
4# This module collects some functions used by the helper scripts of
5# the package.
6#
7# @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
8
9
17def separateSources( filenames ):
18
19 # Loop over the file names, and create the header and source lists:
20 header_files = []
21 source_files = []
22 for file in filenames:
23 # Skip the lingering linkdef and dictionary files:
24 if file.lower().find( "linkdef" ) != -1 or file.lower().find( "dict" ) != -1:
25 continue
26 # Find the header files:
27 if file.endswith( ".h" ) or file.endswith( ".icc" ):
28 header_files += [ file ]
29 pass
30 # Find the source files:
31 if file.endswith( ".cxx" ) or file.endswith( ".cpp" ) or file.endswith( ".C" ):
32 source_files += [ file ]
33 pass
34 pass
35
36 # Return the result:
37 return ( header_files, source_files )
38
39
48def dictionaryHeaders( filenames ):
49
50 # Loop over the file names, and collect the "dictionary headers":
51 header_files = []
52 for file in filenames:
53 # Skip the lingering linkdef and dictionary files:
54 if file.lower().find( "linkdef" ) != -1 or file.lower().find( "dict" ) != -1:
55 continue
56 # Skip the D3PDReader template classes:
57 if ( file.find( "VarHandle.h" ) != -1 or
58 file.find( "VarHandle.icc" ) != -1 or
59 file.find( "VarProxy.h" ) != -1 or
60 file.find( "VarProxy.icc" ) != -1 ):
61 continue
62 # Find the header files:
63 if file.endswith( ".h" ):
64 header_files += [ file ]
65 pass
66 pass
67
68 # Return the final list:
69 return header_files
70
71
80def dictionaryClasses( filenames ):
81
82 # Create a logger object first of all:
83 from AthenaCommon.Logging import logging
84 logger = logging.getLogger( "dictionaryClasses" )
85
86 # Extract the class names from the header files:
87 classnames = [ "D3PDReader::VarHandleBase",
88 "D3PDReader::VarProxyBase",
89 "D3PDReader::VariableStats",
90 "D3PDReader::D3PDReadStats",
91 "map<TString,D3PDReader::VariableStats>",
92 "pair<TString,D3PDReader::VariableStats>",
93 "map<TString,D3PDReader::VarHandleBase*>",
94 "pair<TString,D3PDReader::VarHandleBase*>",
95 "D3PDReader::UserD3PDObjectElement",
96 "D3PDReader::UserD3PDObject" ]
97 for header in filenames:
98 # Open the header file:
99 hfile = open( header, "rU" )
100 if not hfile:
101 logger.error( "Couldn't open header file: %s", hfile )
102 return 255
103 for line in hfile:
104 import re
105 m1 = re.match( r".*ClassDef\‍( (\w+), 0 \‍)", line )
106 m2 = re.match( ".*(VarHandle< .* >).*", line )
107 m3 = re.match( ".*(VarProxy< .* >).*", line )
108 if m1:
109 if not ( "D3PDReader::" + m1.group( 1 ) ) in classnames:
110 logger.verbose( "Found class: " + m1.group( 1 ) )
111 classnames += [ "D3PDReader::" + m1.group( 1 ) ]
112 pass
113 continue
114 if m2:
115 if m2.group( 1 ) == "VarHandle< T >": continue
116 if not ( "D3PDReader::" + m2.group( 1 ) ) in classnames:
117 logger.verbose( "Found class: " + m2.group( 1 ) )
118 classnames += [ "D3PDReader::" + m2.group( 1 ) ]
119 pass
120 continue
121 if m3:
122 if m3.group( 1 ) == "VarProxy< T >": continue
123 if not ( "D3PDReader::" + m3.group( 1 ) ) in classnames:
124 logger.verbose( "Found class: " + m3.group( 1 ) )
125 classnames += [ "D3PDReader::" + m3.group( 1 ) ]
126 pass
127 continue
128 pass
129 pass
130
131 # Now "clean up" these class names a little, so that ROOT would
132 # like them better:
133 import re
134 finalnames = []
135 for cname in classnames:
136 # First, let's remove all mentions of the std namespace:
137 cname = re.sub( r"std::", "", cname )
138 # Now remove all the whitespaces:
139 cname = re.sub( r"\s", "", cname )
140 # Remove the allocator class names:
141 cname = re.sub( r",allocator<\w*>", "", cname )
142 cname = re.sub( r",allocator<\w*<\w*>>", "", cname )
143 cname = re.sub( r",allocator<\w*<\w*<\w*>>>", "", cname )
144 # Make sure whitespaces are re-inserted into the unsigned primitive
145 # names:
146 cname = re.sub( r"unsigned", "unsigned ", cname )
147 # Also take care of adding back the needed whitespace before the
148 # "long" modifier. But don't add a whitespace after the last long in
149 # the name. For instance, "longlong" should become "long long" and not
150 # "long long ".
151 cname = re.sub( r"long(?!>)", "long ", cname )
152 # Finally, make sure that there is a space between the > operators:
153 while cname != re.sub( r">>", "> >", cname ):
154 cname = re.sub( r">>", "> >", cname )
155 pass
156 finalnames += [ cname ]
157 pass
158
159 return finalnames
160
161
172def writeLinkDefFile( filename, classnames, headers = [] ):
173
174 # Create a logger object first of all:
175 from AthenaCommon.Logging import logging
176 logger = logging.getLogger( "writeLinkDefFile" )
177
178 # Open the linkdef file:
179 linkdef = open( filename, "w" )
180 if not linkdef:
181 logger.error( "Couldn't open %s for writing!", filename )
182 return 255
183 else:
184 logger.info( "Writing linkdef file to: %s", filename )
185 pass
186
187 # Write the file's header:
188 linkdef.write( "// Dear emacs, this is -*- c++ -*-\n" )
189 linkdef.write( "// $Id: Helpers.py 600807 2014-06-08 15:26:51Z krasznaa $\n" )
190 linkdef.write( "#ifndef D3PDREADER_LINKDEF_H\n" )
191 linkdef.write( "#define D3PDREADER_LINKDEF_H\n\n" )
192
193 # Write the required includes:
194 for header in headers:
195 linkdef.write( "#include \"%s\"\n" % header )
196 pass
197
198 # Write the rest of the constant part:
199 linkdef.write( "\n#ifdef __CINT__\n\n" )
200 linkdef.write( "#pragma link off all globals;\n" )
201 linkdef.write( "#pragma link off all classes;\n" )
202 linkdef.write( "#pragma link off all functions;\n\n" )
203 linkdef.write( "#pragma link C++ nestedclass;\n\n" )
204
205 # Write which files to generate a dictionary for:
206 for classname in classnames:
207 linkdef.write( "#pragma link C++ class %s+;\n" % classname )
208 pass
209
210 # Write which template functions to generate a dictionary for:
211 linkdef.write( "\n" )
212 linkdef.write( "// You can disable the remaining lines if you don't\n" )
213 linkdef.write( "// plan to use the library in CINT or PyROOT.\n" )
214 functions = [ "D3PDReader::UserD3PDObject::DeclareVariable<bool>",
215 "D3PDReader::UserD3PDObject::DeclareVariable<short>",
216 "D3PDReader::UserD3PDObject::DeclareVariable<unsigned short>",
217 "D3PDReader::UserD3PDObject::DeclareVariable<int>",
218 "D3PDReader::UserD3PDObject::DeclareVariable<unsigned int>",
219 "D3PDReader::UserD3PDObject::DeclareVariable<long long>",
220 "D3PDReader::UserD3PDObject::DeclareVariable<unsigned long long>",
221 "D3PDReader::UserD3PDObject::DeclareVariable<float>",
222 "D3PDReader::UserD3PDObject::DeclareVariable<double>",
223# "D3PDReader::UserD3PDObject::DeclareVariable<vector<short>* >",
224# "D3PDReader::UserD3PDObject::DeclareVariable<vector<unsigned short>* >",
225# "D3PDReader::UserD3PDObject::DeclareVariable<vector<int>* >",
226# "D3PDReader::UserD3PDObject::DeclareVariable<vector<unsigned int>* >",
227# "D3PDReader::UserD3PDObject::DeclareVariable<vector<long long>* >",
228# "D3PDReader::UserD3PDObject::DeclareVariable<vector<unsigned long long>* >",
229# "D3PDReader::UserD3PDObject::DeclareVariable<vector<float>* >",
230# "D3PDReader::UserD3PDObject::DeclareVariable<vector<double>* >",
231 "D3PDReader::UserD3PDObject::Variable<bool>",
232 "D3PDReader::UserD3PDObject::Variable<short>",
233 "D3PDReader::UserD3PDObject::Variable<unsigned short>",
234 "D3PDReader::UserD3PDObject::Variable<int>",
235 "D3PDReader::UserD3PDObject::Variable<unsigned int>",
236 "D3PDReader::UserD3PDObject::Variable<long long>",
237 "D3PDReader::UserD3PDObject::Variable<unsigned long long>",
238 "D3PDReader::UserD3PDObject::Variable<float>",
239 "D3PDReader::UserD3PDObject::Variable<double>",
240# "D3PDReader::UserD3PDObject::Variable<vector<short>* >",
241# "D3PDReader::UserD3PDObject::Variable<vector<unsigned short>* >",
242# "D3PDReader::UserD3PDObject::Variable<vector<int>* >",
243# "D3PDReader::UserD3PDObject::Variable<vector<unsigned int>* >",
244# "D3PDReader::UserD3PDObject::Variable<vector<long long>* >",
245# "D3PDReader::UserD3PDObject::Variable<vector<unsigned long long>* >",
246# "D3PDReader::UserD3PDObject::Variable<vector<float>* >",
247# "D3PDReader::UserD3PDObject::Variable<vector<double>* >",
248 "D3PDReader::UserD3PDObjectElement::Variable<short>",
249 "D3PDReader::UserD3PDObjectElement::Variable<unsigned short>",
250 "D3PDReader::UserD3PDObjectElement::Variable<int>",
251 "D3PDReader::UserD3PDObjectElement::Variable<unsigned int>",
252 "D3PDReader::UserD3PDObjectElement::Variable<long long>",
253 "D3PDReader::UserD3PDObjectElement::Variable<unsigned long long>",
254 "D3PDReader::UserD3PDObjectElement::Variable<float>",
255 "D3PDReader::UserD3PDObjectElement::Variable<double>" ]
256 for function in functions:
257 linkdef.write( "#pragma link C++ function %s;\n" % function )
258 pass
259
260 # Close the file:
261 linkdef.write( "\n" )
262 linkdef.write( "#endif // __CINT__\n" )
263 linkdef.write( "#endif // D3PDREADER_LINKDEF_H\n" )
264 linkdef.close()
265
266 # Signal that the function was successful:
267 return 0
268
269
279def makeRootCorePackageSkeleton( directory, name ):
280
281 # Create a logger object first of all:
282 from AthenaCommon.Logging import logging
283 logger = logging.getLogger( "makeRootCorePackageSkeleton" )
284
285 # Check whether the output directory exists:
286 import os.path
287 if not os.path.exists( directory ):
288 logger.error( "The output directory (%s) doesn't exist!", directory )
289 return 255
290
291 # Check that the package's directory doesn't exist yet:
292 if os.path.exists( directory + "/" + name ):
293 logger.error( "The directory for the package (%s/%s) already exists!", directory, name )
294 return 255
295
296 # Create the directory structure:
297 import os
298 os.mkdir( directory + "/" + name, 0o755 )
299 os.mkdir( directory + "/" + name + "/" + name, 0o755 )
300 os.mkdir( directory + "/" + name + "/Root", 0o755 )
301 os.mkdir( directory + "/" + name + "/cmt", 0o755 )
302
303 # Create the RootCore Makefile:
304 makefile = open( directory + "/" + name + "/cmt/Makefile.RootCore", "w" )
305 makefile.write( "# $Id: Helpers.py 600807 2014-06-08 15:26:51Z krasznaa $\n\n" )
306 makefile.write( "PACKAGE = %s\n" % name )
307 makefile.write( "PACKAGE_PRELOAD = Tree\n" )
308 makefile.write( "# Add the option -DACTIVATE_BRANCHES if your analysis framework\n" )
309 makefile.write( "# disables all branches by default.\n" )
310 makefile.write( "# Remove the COLLECT_D3PD_READING_STATISTICS option to gain a bit\n" )
311 makefile.write( "# of performance...\n" )
312 makefile.write( "PACKAGE_CXXFLAGS = -DCOLLECT_D3PD_READING_STATISTICS\n" )
313 makefile.write( "PACKAGE_LDFLAGS =\n" )
314 makefile.write( "PACKAGE_DEP =\n" )
315 makefile.write( "PACKAGE_PEDANTIC = 1\n" )
316 makefile.write( "PACKAGE_NOOPT = dict\n\n" )
317 makefile.write( "include $(ROOTCOREDIR)/Makefile-common\n" )
318 makefile.close()
319
320 # Create the RootCore requirements file:
321 requirements = open( directory + "/" + name + "/cmt/requirements", "w" )
322 requirements.write( "package %s\n\n" % name )
323 requirements.write( "use AtlasPolicy AtlasPolicy-*\n" )
324 requirements.write( "use AtlasROOT AtlasROOT-* External\n\n" )
325 requirements.write( "library %s ../Root/*.cxx\n" % name )
326 requirements.write( "apply_pattern installed_library\n\n" )
327 requirements.write( "apply_pattern have_root_headers root_headers=\"*.h " \
328 "../Root/LinkDef.h\" headers_lib=%s\n" % name )
329 requirements.close()
330
331 # Signal that the function was successful:
332 return 0
333
334
345def makeSFramePackageSkeleton( directory, name ):
346
347 # Create a logger object first of all:
348 from AthenaCommon.Logging import logging
349 logger = logging.getLogger( "makeSFramePackageSkeleton" )
350
351 # Check whether the output directory exists:
352 import os.path
353 if not os.path.exists( directory ):
354 logger.error( "The output directory (%s) doesn't exist!", directory )
355 return 255
356
357 # Check that the package's directory doesn't exist yet:
358 if os.path.exists( directory + "/" + name ):
359 logger.error( "The directory for the package (%s/%s) already exists!", directory, name )
360 return 255
361
362 # Create the directory structure:
363 import os
364 os.mkdir( directory + "/" + name, 0o755 )
365 os.mkdir( directory + "/" + name + "/include", 0o755 )
366 os.mkdir( directory + "/" + name + "/src", 0o755 )
367 os.mkdir( directory + "/" + name + "/proof", 0o755 )
368
369 # Create the SFrame Makefile:
370 makefile = open( directory + "/" + name + "/Makefile", "w" )
371 makefile.write( "# $Id: Helpers.py 600807 2014-06-08 15:26:51Z krasznaa $\n\n" )
372 makefile.write( "# Package information\n" )
373 makefile.write( "LIBRARY = %s\n" % name )
374 makefile.write( "OBJDIR = obj\n" )
375 makefile.write( "DEPDIR = $(OBJDIR)/dep\n" )
376 makefile.write( "SRCDIR = src\n" )
377 makefile.write( "INCDIR = include\n\n" )
378 makefile.write( "# Enable collecting D3PD reading statistics\n" )
379 makefile.write( "INCLUDES += -DCOLLECT_D3PD_READING_STATISTICS\n\n" )
380 makefile.write( "# Include the generic compilation rules\n" )
381 makefile.write( "include $(SFRAME_DIR)/Makefile.common\n" )
382 makefile.close()
383
384 # Create the PROOF related files:
385 setup = open( directory + "/" + name + "/proof/SETUP.C", "w" )
386 setup.write( "// $Id: Helpers.py 600807 2014-06-08 15:26:51Z krasznaa $\n\n" )
387 setup.write( "int SETUP() {\n\n" )
388 setup.write( " if( gSystem->Load( \"libTree\" ) == -1 ) return -1;\n" )
389 setup.write( " if( gSystem->Load( \"lib%s\" ) == -1 ) return -1;\n\n" % name )
390 setup.write( " return 0;\n" )
391 setup.write( "}\n" )
392 setup.close()
393 # Notice that BUILD.sh has to be executable:
394 build = open( directory + "/" + name + "/proof/BUILD.sh", "w" )
395 build.write( "# $Id: Helpers.py 600807 2014-06-08 15:26:51Z krasznaa $\n\n" )
396 build.write( "if [ \"$1\" = \"clean\" ]; then\n" )
397 build.write( " make distclean\n" )
398 build.write( " exit 0\n" )
399 build.write( "fi\n\n" )
400 build.write( "make default\n" )
401 build.close()
402 os.chmod( directory + "/" + name + "/proof/BUILD.sh", 0o755 )
403
404 # Signal that the function was successful:
405 return 0
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138
makeSFramePackageSkeleton(directory, name)
Create an SFrame package skeleton.
dictionaryHeaders(filenames)
Find the headers needed for dictionary generation.
dictionaryClasses(filenames)
Function collecting the class names to create a dictionary for.
writeLinkDefFile(filename, classnames, headers=[])
Function writing a LinkDef file.
makeRootCorePackageSkeleton(directory, name)
Create the directory structure for a RootCore package.
separateSources(filenames)
Separate the source and header files based on their names.