Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
tgeo-response2json.py
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file tgeo-response2json.py
1 #!/usr/bin/env python
2 # tgeo-response2json.py - convert TGeo response file options to ACTS v13.0.0 JSON format
3 
4 
5 from __future__ import print_function
6 
7 import sys, os, re, getopt, json, subprocess
8 from collections import OrderedDict
9 
10 
11 def usage():
12  print(
13  prog,
14  """- convert TGeo response file options to ACTS v13.0.0 JSON format
15 
16 USAGE:
17  """
18  + prog
19  + """ [OPTIONS] tgeo.response
20 
21 ACTS v13.0.0 (PR #884) changed the way the TGeo detector configuration is specified.
22 A JSON file is now used, instead of the previous method using Boost options,
23 which were often collected together in a response file (--response-file).
24 This script converts an old response file to the new JSON file.
25 
26 To include all the required settings, this script needs to know the defaults for
27 any options not specified in the response file. These defaults can be obtained
28 by running a TGeo example with the --geo-tgeo-dump-jsonconfig=def.json option.
29 This script includes a hardcoded copy of these defaults (produced with ACTS v13.0.0).
30 These are used by default, but the latest defaults can be regenerated and used by
31 specifying the -d (or -c) option.
32 
33 The JSON file is written to stdout.
34 
35 OPTIONS:
36  -h display this help and exit
37  -v verbose running
38  -d use ActsExampleGeometryTGeo --geo-tgeo-dump-jsonconfig to get list of default options
39  -c CMD run CMD --geo-tgeo-dump-jsonconfig instead
40  -f JSON read list of default options from JSON file
41  -n don't add any defaults
42 
43 If none of -dcfn options is specified, then use hardcoded default options.
44 
45 AUTHOR: Tim Adye <tim.adye@cern.ch>""",
46  )
47 
48 
49 prog = os.path.basename(sys.argv[0])
50 
51 
52 def main():
53  args = getopts()
54  for filename in args:
55  try:
56  with open(filename) as f:
57  process(f)
58  except IOError as e:
59  print(prog + ":", e, file=sys.stderr)
60 
61 
62 def getopts():
63  global opt, verbose
64  try:
65  optlist, args = getopt.getopt(sys.argv[1:], "hvdc:f:n")
66  except getopt.GetoptError as e:
67  print(prog + ":", e, file=sys.stderr)
68  exit(1)
69  opt = dict(optlist)
70  if "-h" in opt or len(sys.argv) <= 1:
71  usage()
72  sys.exit(0)
73  verbose = "-v" in opt
74  return args
75 
76 
77 def process(f):
78  vols = []
79  cfg = OrderedDict()
80  vol = None
81  iline = 0
82  for line in f:
83  iline += 1
84  if verbose:
85  print(str(iline) + ":" + line, end="", file=sys.stderr)
86  line = re.sub(r"#.*", "", line).strip()
87  if not line:
88  continue
89 
90  if re.match(r"--geo-[\w-]+-loglevel\s\d+$", line):
91  continue
92 
93  m = re.match(r"--(geo-tgeo-[\w-]+)\s+(.*)$", line)
94  if not m:
95  print(
96  "%s:%d: unrecognised type of option: %s" % (f.name, iline, line),
97  file=sys.stderr,
98  )
99  continue
100  o, v = m.groups()
101 
102  if o == "geo-tgeo-filename" or o == "geo-tgeo-worldvolume":
103  # cfg[o] = v
104  continue
105 
106  if o == "geo-tgeo-unit-scalor":
107  cfg[o] = float(v)
108  continue
109 
110  if o == "geo-tgeo-beampipe-parameters":
111  cfg["geo-tgeo-build-beampipe"] = True
112  cfg[o] = [float(x) for x in v.split(":")]
113  continue
114 
115  if o == "geo-tgeo-volume":
116  if vol is None:
117  cfg["Volumes"] = vols
118  vol = OrderedDict()
119  vol["geo-tgeo-volume-name"] = v
120  vols.append(vol)
121  continue
122 
123  if vol is None:
124  print(
125  "%s:%d: unrecognised global option: %s" % (f.name, iline, line),
126  file=sys.stderr,
127  )
128  continue
129 
130  if re.match("geo-tgeo-sfbin-(r|z|phi)-tolerance$", o):
131  vv = [float(x) for x in v.split(":")]
132  vol[o] = OrderedDict([("lower", vv[0]), ("upper", vv[1])])
133  continue
134 
135  m = re.match("geo-tgeo-([ncp])(.*)$", o)
136  if not m:
137  print(
138  "%s:%d: unrecognised option: %s" % (f.name, iline, line),
139  file=sys.stderr,
140  )
141  continue
142 
143  side, oo = m.groups()
144  side = {"n": "negative", "c": "central", "p": "positive"}[side]
145  oo = "geo-tgeo-" + oo
146  vv = v
147 
148  if oo == "geo-tgeo-layers":
149  oo = "geo-tgeo-volume-layers"
150  vv = bool(int(vv))
151 
152  elif oo == "geo-tgeo-volume-name":
153  oo = "geo-tgeo-subvolume-names"
154 
155  elif oo == "geo-tgeo-module-name":
156  oo = "geo-tgeo-sensitive-names"
157  vv = vv.split("|")
158 
159  elif oo == "geo-tgeo-module-axes":
160  oo = "geo-tgeo-sensitive-axes"
161 
162  elif re.match("geo-tgeo-layer-[rz]-split$", oo):
163  vv = float(vv)
164 
165  elif re.match("geo-tgeo-layer-[rz]-range$", oo):
166  oo += "s"
167  vv = [float(x) for x in vv.split(":")]
168  vv = OrderedDict([("lower", vv[0]), ("upper", vv[1])])
169 
170  else:
171  print(
172  "%s:%d: unrecognised option: %s" % (f.name, iline, line),
173  file=sys.stderr,
174  )
175  continue
176 
177  if oo not in vol:
178  vol[oo] = OrderedDict()
179  vol[oo][side] = vv
180 
181  if "-n" not in opt:
182 
183  if "-d" in opt:
184  empty = generate_empty_config("ActsExampleGeometryTGeo")
185  elif "-c" in opt:
186  empty = generate_empty_config(opt["-c"])
187  elif "-f" in opt:
188  with open(opt["-f"]) as ef:
189  ecfg = ef.read()
190  empty = json.loads(ecfg, object_pairs_hook=OrderedDict)
191  else:
192  empty = None
193 
194  if not empty:
195  empty = empty_config()
196 
197  for o, v in empty.items():
198  if o not in cfg:
199  cfg[o] = v
200  if len(empty.get("Volumes", [])):
201  for vol in vols:
202  for o, v in empty["Volumes"][0].items():
203  if o not in vol:
204  vol[o] = v
205 
206  print(json.dumps(cfg, indent=2))
207 
208 
210  cmd += " --geo-tgeo-dump-jsonconfig=/dev/stdout"
211  if verbose:
212  print("+", cmd, file=sys.stderr)
213  cfg = subprocess.check_output(cmd, shell=True)
214  if not cfg:
215  print(prog + ": command failed: " + cmd, file=sys.stderr)
216  return None
217  if verbose:
218  print(cfg, file=sys.stderr)
219  return json.loads(cfg, object_pairs_hook=OrderedDict)
220 
221 
223  return json.loads(
224  """
225 {
226  "geo-tgeo-unit-scalor": 1.0,
227  "geo-tgeo-build-beampipe": false,
228  "geo-tgeo-beampipe-parameters": [
229  0.0,
230  0.0,
231  0.0
232  ],
233  "Volumes": [
234  {
235  "geo-tgeo-volume-name": "",
236  "geo-tgeo-sfbin-r-tolerance": {
237  "lower": 0.0,
238  "upper": 0.0
239  },
240  "geo-tgeo-sfbin-z-tolerance": {
241  "lower": 0.0,
242  "upper": 0.0
243  },
244  "geo-tgeo-sfbin-phi-tolerance": {
245  "lower": 0.0,
246  "upper": 0.0
247  },
248  "geo-tgeo-volume-layers": {
249  "negative": false,
250  "central": false,
251  "positive": false
252  },
253  "geo-tgeo-subvolume-names": {
254  "negative": "",
255  "central": "",
256  "positive": ""
257  },
258  "geo-tgeo-sensitive-names": {
259  "negative": [],
260  "central": [],
261  "positive": []
262  },
263  "geo-tgeo-sensitive-axes": {
264  "negative": "",
265  "central": "",
266  "positive": ""
267  },
268  "geo-tgeo-layer-r-ranges": {
269  "negative": {
270  "lower": 0.0,
271  "upper": 0.0
272  },
273  "central": {
274  "lower": 0.0,
275  "upper": 0.0
276  },
277  "positive": {
278  "lower": 0.0,
279  "upper": 0.0
280  }
281  },
282  "geo-tgeo-layer-z-ranges": {
283  "negative": {
284  "lower": 0.0,
285  "upper": 0.0
286  },
287  "central": {
288  "lower": 0.0,
289  "upper": 0.0
290  },
291  "positive": {
292  "lower": 0.0,
293  "upper": 0.0
294  }
295  },
296  "geo-tgeo-layer-r-split": {
297  "negative": 0.0,
298  "central": 0.0,
299  "positive": 0.0
300  },
301  "geo-tgeo-layer-z-split": {
302  "negative": 0.0,
303  "central": 0.0,
304  "positive": 0.0
305  },
306  "geo-tgeo-cyl-disc-split": false,
307  "Splitters": {
308  "CylinderDisk": {
309  "geo-tgeo-cyl-nphi-segs": 0,
310  "geo-tgeo-cyl-nz-segs": 0,
311  "geo-tgeo-disc-nphi-segs": 0,
312  "geo-tgeo-disc-nr-segs": 0
313  }
314  }
315  }
316  ]
317 }
318 """,
319  object_pairs_hook=OrderedDict,
320  )
321 
322 
323 if __name__ == "__main__":
324  sys.exit(main())