ATLAS Offline Software
MenuXML2JSONConverter.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2 import sys
3 import os
4 
6  def __init__(self, tabsize = 4, **args):
7  self.tabsize = tabsize
8 
9  self.__doc = None
10  self.__root = None
11  self.__rules = {}
12  self.xmlfilename = None
13 
14 
15  def convertFile(self, inputfilename, jsonfilename = None ):
16  if not inputfilename.endswith(".xml"):
17  print("judging by the suffix, %s is not an xml file" % inputfilename)
18  return 1
19  self.parseXMLFile( inputfilename )
20  self.writeJsonFile( jsonfilename )
21 
22  def parseXMLFile(self,filename):
23  self.xmlfilename = filename
24  import xml.etree.ElementTree as ET
25  self.doc = ET.parse(filename)
26  self.root = self.doc.getroot()
27  print("Parsed file %s" % filename)
28  return self.doc
29 
30  def loadRules(self,docname):
31  self.rules = { 'asInt' : {},
32  'asArray' : [],
33  'asMultiArray' : [],
34  'ignoreElement' : [],
35  'ignoreAttrib' : [],
36  'promote' : {},
37  'rename' : {} # renaming will be applied last
38  }
39 
40  if docname == "LVL1Config":
41  self.rules['asInt'] = {
42  "TriggerItem" : ["partition", "complex_deadtime", "ctpid"],
43  "TriggerThreshold" : ["bitnum", "mapping", "version", "active", "id"],
44  "TriggerThresholdValue" : [ "thresholdval", "etamin", "etamax", "phimin", "phimax",
45  "em_isolation", "window", "priority", "had_veto", "had_isolation"],
46  "Signal" : [ "range_end", "range_begin" ],
47  "Random" : ["cut0", "cut1", "cut2", "cut3"],
48  "PrescaleSet" : ["menuPartition"],
49  "Prescale" : ["ctpid"],
50  "TriggerCondition" : ["multi"],
51  "METSignificance" : ["xeMax", "teSqrtMax", "xsSigmaOffset", "teSqrtMin", "xsSigmaScale", "xeMin"],
52  "MinimumTOBPt" : [ "priority", "etamin", "ptmin", "etamax", "window" ],
53  "Parametrization" : [ "slope", "isobit", "priority", "etamin", "offset", "mincut", "etamax", "upperlimit"],
54  "CaloInfo" : [ "global_em_scale", "global_jet_scale"],
55  "BunchGroupSet" : [ "menuPartition" ],
56  "BunchGroup" : [ "internalNumber" ],
57  "MuctpiInfo" : [ "high_pt", "max_cand", "low_pt" ],
58  "PrescaledClock" : [ "clock1", "clock2" ],
59  "LVL1Config" : [ "l1Version", "ctpVersion" ]
60  }
61  self.rules['asArray'] = [ 'AND', 'OR' ]
62  self.rules['asMultiArray'] = [ ('PrescaleSet', 'Prescale'),
63  ('TriggerThreshold', 'TriggerThresholdValue'),
64  ('TriggerCounterList', 'TriggerCounter'),
65  ('Isolation', 'Parametrization'),
66  ('TriggerMenu', 'TriggerItem'),
67  ('CaloInfo', 'MinimumTOBPt'),
68  ('CaloInfo', 'Isolation'),
69  ('BunchGroupSet', 'BunchGroup'),
70  ('OR', 'TriggerCondition'),
71  ('TriggerThresholdList', 'TriggerThreshold'),
72  ('AND', 'TriggerCondition'),
73  ('AND', 'OR'),
74  ('AND', 'InternalTrigger')
75  ]
76  self.rules['ignoreElement'] = []
77  self.rules['promote'] = {"TriggerThresholdList" : "TriggerThreshold"}
78  self.rules['rename'] = { "TriggerItem" : "items", "TriggerMenu" : "menu", "l1Version" : "version", "ctpid" : "ctpId",
79  "complex_deadtime" : "complexDeadtime", "trigger_type" : "triggerType", "TriggerThreshold" : "thresholds",
80  "triggerthreshold" : "triggerThreshold", "TriggerCondition" : "triggerCondition", "InternalTrigger" : "internalTrigger",
81  "Cable" : "cable", "Signal" : "signal", "range_begin" : "rangeBegin", "range_end" : "rangeEnd",
82  "TriggerThresholdValue" : "thresholdValues" }
83 
84  elif docname == "HLT_MENU":
85 
86  self.rules['asInt'] = {
87  "CHAIN": ["EBstep", "chain_counter"],
88  "SIGNATURE": ["signature_counter"]
89  }
90  self.rules['asMultiArray'] = [ ('SEQUENCE_LIST', 'SEQUENCE'),
91  ('GROUP_LIST', 'GROUP'),
92  ('SIGNATURE_LIST', 'SIGNATURE'),
93  ('CHAIN_LIST', 'CHAIN'),
94  ('STREAMTAG_LIST', 'STREAMTAG'),
95  ('SIGNATURE', 'TRIGGERELEMENT')
96  ]
97  self.rules['ignoreElement'] = [ "SEQUENCE_LIST", "SIGNATURE_LIST", "TRIGGERTYPE_LIST" ]
98  self.rules['ignoreAttrib'] = [ ("CHAIN", "level"),
99  ("CHAIN", "EBstep"),
100  ("CHAIN", "pass_through"),
101  ("CHAIN", "prescale"),
102  ("CHAIN", "rerun_prescale"),
103  ("HLT_MENU", "prescale_set_name")]
104  self.rules['promote'] = {"GROUP_LIST" : "GROUP", "STREAMTAG_LIST" : "STREAMTAG", "CHAIN_LIST" : "CHAIN"}
105  self.rules['rename'] = { "GROUP" : "groups", "STREAMTAG" : "streams", "CHAIN" : "chains",
106  "menu_name" : "name",
107  "chain_name" : "name", "chain_counter" : "counter", "lower_chain_name" : "l1item",
108  "stream" : "name"}
109 
110  elif docname == "TOPO_MENU":
111 
112  self.rules['asInt'] = {
113  "Parameter": ["pos", "value"],
114  "Bit": ["selection"],
115  "Input": ["position"],
116  "Output": ["bits", "fpga", "clock", "algoId", "module", "firstbit"],
117  "SortAlgo": ["algoId"],
118  "DecisionAlgo": ["algoId"],
119  }
120  self.rules['asMultiArray'] = [ ('OutputList', 'Output'),
121  ('Fixed', 'Generic'),
122  ('Fixed', 'Input'),
123  ('TOPO_MENU', 'SortAlgo'),
124  ('TOPO_MENU', 'DecisionAlgo'),
125  ('Variable', 'Parameter'),
126  ('Output', 'Bit'),
127  ('SIGNATURE', 'TRIGGERELEMENT')
128  ]
129  self.rules['promote'] = { "OutputList" : "Output" }
130  self.rules['rename'] = { "menu_name" : "name", "menu_version" : "version",
131  "algname" : "algName", "algoId" : "algId", "firstbit" : "firstBit", "module" : "board", "triggerline" : "triggerLines",
132  "SortAlgo" : "sortingAlgorithms", "DecisionAlgo" : "decisionAlgorithms",
133  "Fixed" : "fixedParameters", "Input" : "inputs", "Output" : "outputs", "Generic" : "generics",
134  "Variable" : "variableParameters", "Parameter" : "parameters"}
135  else:
136  print("Unknown document with root element %s" % docname)
137  return 1
138  return 0
139 
140 
141  def renameKey(self,key):
142  return self.rules['rename'][key] if key in self.rules['rename'] else key
143 
144 
145  def createJsonStruct(self, node):
146  if node.tag in self.rules['asArray']:
147  return [ {element.tag : self.createJsonStruct(element)} for element in node ]
148 
149  else:
150  d = {}
151  # writing attributs of the element to json structure in alphabetical order
152  # turn values into int according to the asInt rule
153  for attr in sorted(node.attrib.keys()):
154  if (node.tag, attr) in self.rules['ignoreAttrib']: # attributes to ignore
155  continue
156  if node.tag in self.rules['asInt'] and attr in self.rules['asInt'][node.tag]:
157  d[self.renameKey(attr)] = int(node.attrib[attr])
158  else:
159  d[self.renameKey(attr)] = node.attrib[attr]
160  # looping over children
161  for element in node:
162  if element.tag in self.rules['ignoreElement']:
163  continue
164  if (node.tag, element.tag) in self.rules['asMultiArray']:
165  # list of multiple identical elements (e.g. CHAINs)
166  key = self.renameKey(element.tag)
167  if key not in d: d[key] = list()
168  d[key] += [ self.createJsonStruct(element) ]
169  else:
170  # single element (e.g. CHAIN_LIST)
171  if element.tag in d:
172  raise RuntimeError("element %s already attached to node %s and not declared as MultiArray" % (element.tag, node.tag))
173 
174  if element.tag in self.rules['promote']:
175  obj = self.createJsonStruct(element)
176  promoted = self.renameKey( self.rules['promote'][element.tag]) #e.g. Chains
177  d[promoted] = obj[promoted]
178  else:
179  d[self.renameKey(element.tag)] = self.createJsonStruct(element)
180 
181  return d
182 
183 
184 
185  def writeJsonFile(self, filename = None):
186  import json
187  if not filename:
188  # use xml filename base
189  filename = self.xmlfilename.rstrip(".xml")+".json"
190  elif os.path.isdir(filename):
191  filename = filename.rstrip("/") + "/" + self.xmlfilename.split("/")[-1].rstrip(".xml")+".json"
192  self.loadRules(self.root.tag)
193  d = self.createJsonStruct(self.root)
194  FH = open(filename, "w")
195  json.dump(d, FH, indent=self.tabsize, separators=(',', ': '))
196  FH.close()
197  print("Wrote file %s" % filename)
198 
199 
200 
201  def checkJsonConformity(self, filename):
202  print("Checking json conformity", end=' ')
203  import json
204  FH = open(filename, "rb")
205  try:
206  json.load(FH)
207  print(" ... OK")
208  except ValueError as e:
209  print(" ... FAILED")
210  print(e)
211  FH.close()
212 
213 
214 
215 def test():
216  if len(sys.argv)<=1:
217  print("please specify xml file for conversion")
218  return 1
219 
220  converter = XML2JsonConverter()
221  converter.convertFile( sys.argv[1] )
222  return 0
223 
224 
225 if __name__=="__main__":
226  sys.exit(test())
227 
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename R::value_type > sorted(const R &r, PROJ proj={})
Helper function to create a sorted vector from an unsorted range.
python.MenuXML2JSONConverter.XML2JsonConverter.tabsize
tabsize
Definition: MenuXML2JSONConverter.py:7
python.MenuXML2JSONConverter.XML2JsonConverter.__root
__root
Definition: MenuXML2JSONConverter.py:10
python.MenuXML2JSONConverter.XML2JsonConverter.__rules
__rules
Definition: MenuXML2JSONConverter.py:11
python.MenuXML2JSONConverter.XML2JsonConverter.createJsonStruct
def createJsonStruct(self, node)
Definition: MenuXML2JSONConverter.py:145
python.MenuXML2JSONConverter.XML2JsonConverter.renameKey
def renameKey(self, key)
Definition: MenuXML2JSONConverter.py:141
python.MenuXML2JSONConverter.XML2JsonConverter.checkJsonConformity
def checkJsonConformity(self, filename)
Definition: MenuXML2JSONConverter.py:201
python.MenuXML2JSONConverter.XML2JsonConverter.doc
doc
Definition: MenuXML2JSONConverter.py:25
python.MenuXML2JSONConverter.XML2JsonConverter.writeJsonFile
def writeJsonFile(self, filename=None)
Definition: MenuXML2JSONConverter.py:185
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
python.MenuXML2JSONConverter.XML2JsonConverter.loadRules
def loadRules(self, docname)
Definition: MenuXML2JSONConverter.py:30
print
void print(char *figname, TCanvas *c1)
Definition: TRTCalib_StrawStatusPlots.cxx:26
python.MenuXML2JSONConverter.XML2JsonConverter.__init__
def __init__(self, tabsize=4, **args)
Definition: MenuXML2JSONConverter.py:6
python.MenuXML2JSONConverter.XML2JsonConverter.convertFile
def convertFile(self, inputfilename, jsonfilename=None)
Definition: MenuXML2JSONConverter.py:15
Trk::open
@ open
Definition: BinningType.h:40
python.MenuXML2JSONConverter.XML2JsonConverter.rules
rules
Definition: MenuXML2JSONConverter.py:31
python.MenuXML2JSONConverter.XML2JsonConverter.__doc
__doc
Definition: MenuXML2JSONConverter.py:9
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
python.MenuXML2JSONConverter.XML2JsonConverter.parseXMLFile
def parseXMLFile(self, filename)
Definition: MenuXML2JSONConverter.py:22
python.MenuXML2JSONConverter.test
def test()
Definition: MenuXML2JSONConverter.py:215
pickleTool.object
object
Definition: pickleTool.py:29
python.MenuXML2JSONConverter.XML2JsonConverter.xmlfilename
xmlfilename
Definition: MenuXML2JSONConverter.py:12
python.MenuXML2JSONConverter.XML2JsonConverter
Definition: MenuXML2JSONConverter.py:5
python.MenuXML2JSONConverter.XML2JsonConverter.root
root
Definition: MenuXML2JSONConverter.py:26
Trk::split
@ split
Definition: LayerMaterialProperties.h:38