ATLAS Offline Software
Loading...
Searching...
No Matches
XMLtoHeader.py
Go to the documentation of this file.
1#!/usr/bin/python
2
3
4# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
5import os.path
6import sys
7import getopt
8import xml.etree.ElementTree as ET
9from datetime import date
10
11#--------------------------------------
12#get command line arguments
13#--------------------------------------
14argv = sys.argv
15
16inputXMLname = '../schema/L1CTSpecifications.xml'
17outputNames = 'L1Common'
18
19opts, remainder = getopt.getopt( argv[1:], 'i:o:', ['inputXML=','outputNames='])
20#print ("OPTIONS: ", opts)
21#print ("REMAINDER: ", remainder)
22
23for opt,arg in opts:
24 if opt in ['-i','--inputXML']:
25 inputXMLname = arg
26 elif opt in ['-o','--outputNames']:
27 outputNames = arg
28 else:
29 print("option %s not known.." % opt)
30
31
32
33#-----------------------------------
34# some definitions
35#-----------------------------------
36
37typeDictCpp = {'u32' :'uint32_t','u16':'uint16_t','s32' :'int32_t','s16':'int16_t','string':'string', 'bool':'bool','float':'float','double':'double'}
38typeDictJava = {'u32' :'long','u16':'long','s32' :'int','s16':'int','string':'String', 'bool':'Boolean','float':'Single','double':'Double'}
39
40versionDict = {}
41
42if 'dataformat' in os.path.basename(outputNames):
43 versionDict = {'v0':'Before moving the L1A position to the eformat-version field', 'v1': 'After moving the L1A position to the eformat-version field to free bits for the HLT counter', 'v2':'First version of CTP data with programmable extra words (up to 50), and time difference in BC to previous L1A', 'v3':'Including also the turn counter in the payload','v4':'Version with increased number of inputs/items for run-2 (->beginning 2015)'}#,'vZ': 'dummy for testing'}
44
45if 'L1Common' in os.path.basename(outputNames):
46 #versionDict = {'v0':'Before long shutdown I (before 2015)', 'v1': 'Version after long shutdown I','v2':'dummy','v3':'dummy','v4':'dummy'}
47 versionDict = {'v0':'Before long shutdown I (before 2015)', 'v1': 'Version after long shutdown I'}
48
49
50#print versionDict.keys()
51message_missingElement = 'Concerning child #{number}: Sorry, no {element} specified. This is a necessary element. Please make sure to specify it in the config file.'
52
53
54
55#----------------------
56#Read the XML tree
57#----------------------
58tree = ET.parse(inputXMLname)
59root = tree.getroot()
60
61#---------------------------------------------
62#Get all versions that exist for an element
63#---------------------------------------------
64
65nameVersionsDict={}
66childIndex = 0
67for child in root:
68 childIndex +=1
69 if child.find('name') is None:
70 #print (message_missingElement.format(number=childIndex, element='name'))
71 exit(1)
72 elif child.find('name').text[1:-1] in nameVersionsDict:
73 nameVersionsDict[child.find('name').text[1:-1]].append(child.attrib['ns'])
74 else:
75 versionList = [child.attrib['ns']]
76 nameVersionsDict[child.find('name').text[1:-1]] = versionList
77
78#print (nameVersionsDict)
79staticList = [] #parameters that didn't change so far
80for name in nameVersionsDict:
81 if len(nameVersionsDict[name])==1:
82 staticList.append(name)
83 for vers in nameVersionsDict[name]:
84 count = nameVersionsDict[name].count(vers)
85 if count>1:
86 #print ('ERROR: Element "',name,'" occurs several times with same version (' , vers, '). Please fix config file.')
87 exit(1)
88
89
90#------------------------------------------------------------------
91#Get number of changed parameters compared to v0 for each version
92#------------------------------------------------------------------
93numChangeVersionDict = {}
94numChangeVersionDict['v0'] = 0
95changedParameterNames = []
96for v in list(versionDict)[1:]:
97 childIndex = 0
98 for child in root:
99 childIndex +=1
100 if child.attrib['ns'] is None:
101 #print (message_missingElement.format(number=childIndex, element='ns'))
102 exit(1)
103 else:
104 if child.attrib['ns']==v:
105 if child.find('name').text[1:-1] not in changedParameterNames:
106 changedParameterNames.append(child.find('name').text[1:-1])
107
108 numChangeVersionDict[v] = len(changedParameterNames)
109
110
111
112
113def CreateFiles(time):
114#=====================================
115# actually create the output files
116#=====================================
117
118 #--------- the definition of CTP version class--------------------------------
119 cppBaseStartstring = "/*\n*This file was automatically created by XMLtoHeader.py\n* Created on: {creationTime}\n* Created with config: {xmlFile}\n*\n* Author: Ruth Poettgen\n* Contact: ruth.poettgen@cern.ch\n**Brief: Defines class for different CTP versions.\n*/\n\n\n#include <inttypes.h>\n#include <assert.h>\n#include <iostream>\n#include <stdlib.h>\n#include <map>\n#include <iomanip>\n#include <sstream>\n\n"
120 start = cppBaseStartstring.format(creationTime = time, xmlFile = inputXMLname)
121
122 baseNameRoot = os.path.basename(outputNames)
123 baseName = baseNameRoot + 'Version'
124 fileName = outputNames + 'Version'
125 baseHeader = open(fileName+'.h','w')
126 baseHeader.write(start)
127
128
129 baseHeader.write('#ifndef '+baseName.upper() + '_H\n')
130 baseHeader.write('#define '+baseName.upper() + '_H\n')
131 baseHeader.write('\nclass '+baseName + '{\n\n')
132
133 protectedString = "\nprotected:\n"
134 protectedString += " //---------------------------------------------------------------------------------------------------\n"
135 protectedString += " // For explanation of the variables and there values in different versions see config XML file.\n"
136 protectedString += " //---------------------------------------------------------------------------------------------------\n"
137
138 functionString = ''
139
140 publicString = "\npublic: \n"
141 publicString += '\n ' + baseName + '(unsigned int version) {\n'
142
143 dumpString = '\n std::string dump() const {\n';
144 dumpString += '\n std::ostringstream s;\n';
145 dumpString += '\n std::ostringstream tmp;\n\n';
146 dumpString += ' s << \"For a description of the parameters for different CTP version, see schema/L1CoreSpecifications.xml in L1CommonCore.\" << std::endl;\n\n';
147 dumpString += ' s << \"|-------------------------------------------------------------|\" << std::endl;\n';
148 dumpString += ' s << \"| Name | Value |\" << std::endl;\n';
149 dumpString += ' s << \"|-------------------------------------------------------------|\" << std::endl;\n';
150
151 #dumpString += ' s << \"|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\" << std::endl;\n';
152 #dumpString += ' s << \"| Name | Value | Comment |\" << std::endl;\n';
153 #dumpString += ' s << \"|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\" << std::endl;\n';
154
155 changedValuesDict = {}
156 numberOfChanges = 0
157 #--------------------------------------------
158 #get start strings for the other files
159 #--------------------------------------------
160
161 pyStartstring = "#!/usr/bin/env python\n\n#This file was automatically created by XMLtoHeader.py\n# Created on: {creationTime}\n# Created with config: {xmlFile}\n# \n# Author: Ruth Poettgen\n# Contact: ruth.poettgen@cern.ch\n\n\n\nimport sys\n\nclass {classname}(object):\n def __init__(self):\n"
162
163 #javaStartstring = "/*\n*This file was automatically created by XMLtoHeader.py\n* Created on: {creationTime}\n* Created with config: {xmlFile}\n*\n* Author: Ruth Poettgen\n* Contact: ruth.poettgen@cern.ch\n**Brief: Defines some CTP parameters. {version}.\n*/\n\n\npackage {pack};\n\npublic class {classname} "
164
165
166 #-------------------------------------------------------
167 # write one file/one constructor part for each version
168 #-------------------------------------------------------
169 for v in versionDict:
170
171 if (v!='v0'):
172 changedValuesDict[v] = []
173
174 pyStartstring = pyStartstring.format(creationTime = time,version = versionDict[v], xmlFile = inputXMLname, classname=baseNameRoot)
175 headerName = outputNames + "_" + v + ".py"
176 pyHeader = open(headerName,'w')
177 pyHeader.write(pyStartstring)
178
179 #javaStartstring = javaStartstring.format(creationTime = time, xmlFile = inputXMLname,version = versionDict[v],pack='L1Common.'+ outputNames,classname=outputNames+'_'+v)
180 #headerName = outputNames + "_" + v + ".java"
181 #javaHeader = open(headerName,'w')
182 #javaHeader.write(javaStartstring + '{\n\n')
183
184
185 childIndex=0
186 nameList=[]
187
188 for child in root:
189 hasChanged = False
190 childIndex=childIndex+1
191 #print ('looking at child #', childIndex)
192
193 if child.attrib['ns'] not in versionDict:
194 #print 'Version ID ', child.attrib['ns'], ' not recognised. Should be one of ', versionDict.keys()
195 exit(1)
196
197 #check if all the attributes necessary are set
198 if child.find('name') is None:
199 #print (message_missingElement.format(number=childIndex, element='name'))
200 exit(1)
201 if child.find('type') is None:
202 #print (message_missingElement.format(number=childIndex, element='type'))
203 exit(1)
204 if child.find('value') is None:
205 #print (message_missingElement.format(number=childIndex, element='value'))
206 exit(1)
207
208
209 #check wether parameter has already been written, don't write again
210 if child.find('name').text[1:-1] in nameList:
211 #print (child.find('name').text[1:-1], ' already written. Skipping.')
212 continue
213 #else:
214 #print ('Found new parameter: ', child.find('name').text[1:-1])
215
216
217 #-------------------------------------------------------------
218 #get latest version of parameter for the required CTP version
219 #-------------------------------------------------------------
220
221 if list(versionDict).index( child.attrib['ns'] )>list(versionDict).index(v):
222 #print 'Version (' , child.attrib['ns'] , ') is beyond what we are looking for right now (' , v, ') . Skipping.'
223 continue
224
225 tmp_v=v
226 while tmp_v not in nameVersionsDict[child.find('name').text[1:-1]]:
227 #print tmp_v, 'is not contained in ', nameVersionsDict[child.find('name').text[1:-1]]
228 index = list(versionDict).index(tmp_v)
229 tmp_v = list(versionDict)[index-1]
230 #print '--> Going to write ' , tmp_v , ' instead'
231
232 if tmp_v!='v0':
233 hasChanged=True
234
235 if child.attrib['ns']!=tmp_v:
236 #print ('Version (' , child.attrib['ns'] , ') is not what we are looking for right now. Skipping.')
237 continue
238
239
240 #-------------------------------------------------------------
241 # write the files
242 #-------------------------------------------------------------
243
244 typeText = child.find('type').text
245 nameText = child.find('name').text[1:-1]
246 valueText = child.find('value').text
247
248
249 pyHeader.write(' self.'+nameText.ljust(30)+'= ')
250
251 if 'mult' in typeText: #arrays need special treatment
252
253 #javaHeader.write(' '+'public static ' + typeDictJava[ typeText[0:-5] ] +'[] ')
254 #javaHeader.write(nameText.ljust(30)+'= ')
255 #javaHeader.write(' { ' + valueText +' };')
256
257 pyHeader.write( ('[ ' + valueText + ' ]').ljust(50) )
258
259
260 listOfElements = valueText.split(',')
261 numberOfElements = len(listOfElements)
262
263 if v=='v0':
264
265 protectedString += ' '
266 protectedString += typeDictCpp[typeText[0:-5]] + ' '
267 protectedString += (nameText+ '['+ str(numberOfElements) + ']').ljust(20)+ '='
268 protectedString += '{ ' + valueText + '};'
269
270
271 functionString += '\n const '+typeDictCpp[typeText[0:-5]] + '* get'
272 functionString += nameText + '() const { return ' + nameText + '; }'
273
274
275 dumpString += '\n s << \"|\" << std::left << std::setw(40) << \" ' + nameText + '\" << \" | \";\n'
276 dumpString += ' tmp.clear(); tmp.str(\"\");\n tmp<< \"[\";\n'
277 dumpString += ' for (int i=0; i <' + str(numberOfElements) + '; i++) {\n'
278 dumpString += ' if (i) tmp<<\",\";\n'
279 dumpString += ' tmp << this->' + nameText + '[i];\n }\n tmp<<\"]\";\n'
280 dumpString += ' s << std::right << std::setw(17) << tmp.str() << \" | \" << std::endl;\n\n'
281 #dumpString += ' s << std::right << std::setw(35) << tmp.str() << \" | \";\n'
282 #if child.find('comment') is None:
283 # dumpString += ' s << std::left << std::setw(120) << ' + '\"--\"' + ' << \" | \" << std::endl;\n\n'
284 #else:
285 # dumpString += ' s << std::left << std::setw(120) << ' + child.find('comment').text + ' << \" | \" << std::endl;\n\n'
286
287
288
289 if hasChanged:
290 changedValuesDict[v].append([nameText,valueText])
291
292 else:
293 #javaHeader.write(' public static ' + typeDictJava[typeText] +' ')
294 #javaHeader.write(nameText.ljust(30)+'= ')
295 #javaHeader.write(valueText +';')
296
297 if (valueText)[0] not in ['0','1','2','3','4','5','6','7','8','9']:
298 val = valueText
299 pyHeader.write( ('self.' + val.replace('+',' + self.')).ljust(10))
300 else:
301 pyHeader.write(valueText.ljust(10))
302
303
304 if v=='v0':
305 functionString += '\n '+typeDictCpp[typeText] + ' get'
306 functionString += nameText + '() const { return ' + nameText + '; }'
307
308 protectedString += ' ' + typeDictCpp[typeText] + ' '
309 protectedString += nameText
310 protectedString += ' = ' + valueText + ';'
311
312 dumpString += ' s << \"|\" << std::left << std::setw(40) << \" ' + nameText + '\" << \" | \";\n'
313 dumpString += ' s << std::right << std::setw(17) << this->' + nameText + ' << \" | \" << std::endl;\n\n'
314 #dumpString += ' s << std::right << std::setw(35) << this->' + nameText + ' << \" | \";\n'
315 #if child.find('comment') is None:
316 #dumpString += ' s << std::left << std::setw(120) << ' + '\"--\"' + ' << \" | \" << std::endl;\n\n'
317 #else:
318 #dumpString += ' s << std::left << std::setw(120) << ' + child.find('comment').text + ' << \" | \" << std::endl;\n\n'
319
320
321 if hasChanged:
322 changedValuesDict[v].append([nameText,valueText])
323
324
325
326 #--- comment -------------------------
327 if child.find('comment') is None:
328 pyHeader.write('\n')
329 #javaHeader.write('\n')
330 else:
331 pyHeader.write( ' # ' + child.find('comment').text[1:-1] + '\n')
332 if v =='v0':
333 protectedString += '\n'
334
335 nameList.append(nameText)
336
337
338
339
340 #------------------------------
341 # finalise the file writing
342 #------------------------------
343
344 pyHeader.write('\n\n' + baseNameRoot + '_' + v + ' = ' + baseNameRoot + '()'+'\n\n' + 'del ' + baseNameRoot)
345 #javaHeader.write('\n}')
346
347 dumpString += ' s << \"|-------------------------------------------------------------|\" << std::endl;\n\n';
348 #dumpString += ' s << \"|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\" << std::endl;\n\n';
349 dumpString += ' return s.str();\n\n }'
350
351 nVersions = len(versionDict)
352
353 #access function
354 selection= ' if (version>=' + str(nVersions)+') {\n';
355 selection+= ' std::cerr << \"ERROR: invalid CTP version requested (\" << version << \"). Should be in [0,'+ str(nVersions-1)+ '].Setting it to the latest version ('+str(nVersions-1)+'). \" << std::endl;\n'
356 selection += ' version='+str(nVersions-1)+';\n'
357 selection+= ' }\n\n'
358
359
360 versionInt = 1
361 for v in changedValuesDict:
362 selection += ' if (version==' + str(versionInt) + ' ) {\n'
363 for pair in changedValuesDict[v]:
364 if ',' in pair[1]:
365 listOfValues = pair[1].split(',')
366 numValues = len(listOfElements)
367 selection+='\n'
368 valIndex = 0
369 for val in listOfValues:
370 selection+= ' ' + pair[0] + '[' + str(valIndex) + '] = ' + val + ';\n'
371 valIndex+=1
372 else:
373 selection+=' ' + pair[0] + ' = ' + pair[1] + ';\n'
374
375 selection += ' }\n\n'
376 versionInt+=1
377 numberOfChanges = len(changedValuesDict)
378
379
380 baseHeader.write(protectedString+'\n\n')
381 baseHeader.write(publicString +'\n\n')
382 baseHeader.write(selection)
383 baseHeader.write(' };\n\n')
384 baseHeader.write(functionString+'\n\n')
385 baseHeader.write(dumpString+'\n\n')
386 baseHeader.write('\n};\n\n')
387 baseHeader.write('#endif //' + baseName.upper() + '_H')
388
389
390now = date.today().strftime("%d/%m/%y")
391
392if __name__ == "__main__":
393 CreateFiles(now)
394
395
void print(char *figname, TCanvas *c1)
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177
CreateFiles(time)
Definition index.py:1