Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:12:06

0001 #!/usr/bin/env python
0002 # tgeo-response2json.py - convert TGeo response file options to ACTS v13.0.0 JSON format
0003 
0004 import sys
0005 import os
0006 import re
0007 import getopt
0008 import json
0009 import subprocess
0010 from collections import OrderedDict
0011 
0012 
0013 def usage():
0014     print(
0015         prog,
0016         """- convert TGeo response file options to ACTS v13.0.0 JSON format
0017 
0018 USAGE:
0019   """
0020         + prog
0021         + """ [OPTIONS] tgeo.response
0022 
0023 ACTS v13.0.0 (PR #884) changed the way the TGeo detector configuration is specified.
0024 A JSON file is now used, instead of the previous method using Boost options,
0025 which were often collected together in a response file (--response-file).
0026 This script converts an old response file to the new JSON file.
0027 
0028 To include all the required settings, this script needs to know the defaults for
0029 any options not specified in the response file. These defaults can be obtained
0030 by running a TGeo example with the --geo-tgeo-dump-jsonconfig=def.json option.
0031 This script includes a hardcoded copy of these defaults (produced with ACTS v13.0.0).
0032 These are used by default, but the latest defaults can be regenerated and used by
0033 specifying the -d (or -c) option.
0034 
0035 The JSON file is written to stdout.
0036 
0037 OPTIONS:
0038   -h      display this help and exit
0039   -v      verbose running
0040   -d      use ActsExampleGeometryTGeo --geo-tgeo-dump-jsonconfig to get list of default options
0041   -c CMD  run CMD --geo-tgeo-dump-jsonconfig instead
0042   -f JSON read list of default options from JSON file
0043   -n      don't add any defaults
0044 
0045 If none of -dcfn options is specified, then use hardcoded default options.
0046 
0047 AUTHOR: Tim Adye <tim.adye@cern.ch>""",
0048     )
0049 
0050 
0051 prog = os.path.basename(sys.argv[0])
0052 
0053 
0054 def main():
0055     args = getopts()
0056     for filename in args:
0057         try:
0058             with open(filename) as f:
0059                 process(f)
0060         except IOError as e:
0061             print(prog + ":", e, file=sys.stderr)
0062 
0063 
0064 def getopts():
0065     global opt, verbose
0066     try:
0067         optlist, args = getopt.getopt(sys.argv[1:], "hvdc:f:n")
0068     except getopt.GetoptError as e:
0069         print(prog + ":", e, file=sys.stderr)
0070         exit(1)
0071     opt = dict(optlist)
0072     if "-h" in opt or len(sys.argv) <= 1:
0073         usage()
0074         sys.exit(0)
0075     verbose = "-v" in opt
0076     return args
0077 
0078 
0079 def process(f):
0080     vols = []
0081     cfg = OrderedDict()
0082     vol = None
0083     iline = 0
0084     for line in f:
0085         iline += 1
0086         if verbose:
0087             print(str(iline) + ":" + line, end="", file=sys.stderr)
0088         line = re.sub(r"#.*", "", line).strip()
0089         if not line:
0090             continue
0091 
0092         if re.match(r"--geo-[\w-]+-loglevel\s\d+$", line):
0093             continue
0094 
0095         m = re.match(r"--(geo-tgeo-[\w-]+)\s+(.*)$", line)
0096         if not m:
0097             print(
0098                 "%s:%d: unrecognised type of option: %s" % (f.name, iline, line),
0099                 file=sys.stderr,
0100             )
0101             continue
0102         o, v = m.groups()
0103 
0104         if o == "geo-tgeo-filename" or o == "geo-tgeo-worldvolume":
0105             #      cfg[o] = v
0106             continue
0107 
0108         if o == "geo-tgeo-unit-scalor":
0109             cfg[o] = float(v)
0110             continue
0111 
0112         if o == "geo-tgeo-beampipe-parameters":
0113             cfg["geo-tgeo-build-beampipe"] = True
0114             cfg[o] = [float(x) for x in v.split(":")]
0115             continue
0116 
0117         if o == "geo-tgeo-volume":
0118             if vol is None:
0119                 cfg["Volumes"] = vols
0120             vol = OrderedDict()
0121             vol["geo-tgeo-volume-name"] = v
0122             vols.append(vol)
0123             continue
0124 
0125         if vol is None:
0126             print(
0127                 "%s:%d: unrecognised global option: %s" % (f.name, iline, line),
0128                 file=sys.stderr,
0129             )
0130             continue
0131 
0132         if re.match("geo-tgeo-sfbin-(r|z|phi)-tolerance$", o):
0133             vv = [float(x) for x in v.split(":")]
0134             vol[o] = OrderedDict([("lower", vv[0]), ("upper", vv[1])])
0135             continue
0136 
0137         m = re.match("geo-tgeo-([ncp])(.*)$", o)
0138         if not m:
0139             print(
0140                 "%s:%d: unrecognised option: %s" % (f.name, iline, line),
0141                 file=sys.stderr,
0142             )
0143             continue
0144 
0145         side, oo = m.groups()
0146         side = {"n": "negative", "c": "central", "p": "positive"}[side]
0147         oo = "geo-tgeo-" + oo
0148         vv = v
0149 
0150         if oo == "geo-tgeo-layers":
0151             oo = "geo-tgeo-volume-layers"
0152             vv = bool(int(vv))
0153 
0154         elif oo == "geo-tgeo-volume-name":
0155             oo = "geo-tgeo-subvolume-names"
0156 
0157         elif oo == "geo-tgeo-module-name":
0158             oo = "geo-tgeo-sensitive-names"
0159             vv = vv.split("|")
0160 
0161         elif oo == "geo-tgeo-module-axes":
0162             oo = "geo-tgeo-sensitive-axes"
0163 
0164         elif re.match("geo-tgeo-layer-[rz]-split$", oo):
0165             vv = float(vv)
0166 
0167         elif re.match("geo-tgeo-layer-[rz]-range$", oo):
0168             oo += "s"
0169             vv = [float(x) for x in vv.split(":")]
0170             vv = OrderedDict([("lower", vv[0]), ("upper", vv[1])])
0171 
0172         else:
0173             print(
0174                 "%s:%d: unrecognised option: %s" % (f.name, iline, line),
0175                 file=sys.stderr,
0176             )
0177             continue
0178 
0179         if oo not in vol:
0180             vol[oo] = OrderedDict()
0181         vol[oo][side] = vv
0182 
0183     if "-n" not in opt:
0184         if "-d" in opt:
0185             empty = generate_empty_config("ActsExampleGeometryTGeo")
0186         elif "-c" in opt:
0187             empty = generate_empty_config(opt["-c"])
0188         elif "-f" in opt:
0189             with open(opt["-f"]) as ef:
0190                 ecfg = ef.read()
0191             empty = json.loads(ecfg, object_pairs_hook=OrderedDict)
0192         else:
0193             empty = None
0194 
0195         if not empty:
0196             empty = empty_config()
0197 
0198         for o, v in empty.items():
0199             if o not in cfg:
0200                 cfg[o] = v
0201         if len(empty.get("Volumes", [])):
0202             for vol in vols:
0203                 for o, v in empty["Volumes"][0].items():
0204                     if o not in vol:
0205                         vol[o] = v
0206 
0207     print(json.dumps(cfg, indent=2))
0208 
0209 
0210 def generate_empty_config(cmd):
0211     cmd += " --geo-tgeo-dump-jsonconfig=/dev/stdout"
0212     if verbose:
0213         print("+", cmd, file=sys.stderr)
0214     cfg = subprocess.check_output(cmd, shell=True)
0215     if not cfg:
0216         print(prog + ": command failed: " + cmd, file=sys.stderr)
0217         return None
0218     if verbose:
0219         print(cfg, file=sys.stderr)
0220     return json.loads(cfg, object_pairs_hook=OrderedDict)
0221 
0222 
0223 def empty_config():
0224     return json.loads(
0225         """
0226 {
0227   "geo-tgeo-unit-scalor": 1.0,
0228   "geo-tgeo-build-beampipe": false,
0229   "geo-tgeo-beampipe-parameters": [
0230     0.0,
0231     0.0,
0232     0.0
0233   ],
0234   "Volumes": [
0235     {
0236       "geo-tgeo-volume-name": "",
0237       "geo-tgeo-sfbin-r-tolerance": {
0238         "lower": 0.0,
0239         "upper": 0.0
0240       },
0241       "geo-tgeo-sfbin-z-tolerance": {
0242         "lower": 0.0,
0243         "upper": 0.0
0244       },
0245       "geo-tgeo-sfbin-phi-tolerance": {
0246         "lower": 0.0,
0247         "upper": 0.0
0248       },
0249       "geo-tgeo-volume-layers": {
0250         "negative": false,
0251         "central": false,
0252         "positive": false
0253       },
0254       "geo-tgeo-subvolume-names": {
0255         "negative": "",
0256         "central": "",
0257         "positive": ""
0258       },
0259       "geo-tgeo-sensitive-names": {
0260         "negative": [],
0261         "central": [],
0262         "positive": []
0263       },
0264       "geo-tgeo-sensitive-axes": {
0265         "negative": "",
0266         "central": "",
0267         "positive": ""
0268       },
0269       "geo-tgeo-layer-r-ranges": {
0270         "negative": {
0271           "lower": 0.0,
0272           "upper": 0.0
0273         },
0274         "central": {
0275           "lower": 0.0,
0276           "upper": 0.0
0277         },
0278         "positive": {
0279           "lower": 0.0,
0280           "upper": 0.0
0281         }
0282       },
0283       "geo-tgeo-layer-z-ranges": {
0284         "negative": {
0285           "lower": 0.0,
0286           "upper": 0.0
0287         },
0288         "central": {
0289           "lower": 0.0,
0290           "upper": 0.0
0291         },
0292         "positive": {
0293           "lower": 0.0,
0294           "upper": 0.0
0295         }
0296       },
0297       "geo-tgeo-layer-r-split": {
0298         "negative": 0.0,
0299         "central": 0.0,
0300         "positive": 0.0
0301       },
0302       "geo-tgeo-layer-z-split": {
0303         "negative": 0.0,
0304         "central": 0.0,
0305         "positive": 0.0
0306       },
0307       "geo-tgeo-cyl-disc-split": false,
0308       "Splitters": {
0309         "CylinderDisk": {
0310           "geo-tgeo-cyl-nphi-segs": 0,
0311           "geo-tgeo-cyl-nz-segs": 0,
0312           "geo-tgeo-disc-nphi-segs": 0,
0313           "geo-tgeo-disc-nr-segs": 0
0314         }
0315       }
0316     }
0317   ]
0318 }
0319 """,
0320         object_pairs_hook=OrderedDict,
0321     )
0322 
0323 
0324 if __name__ == "__main__":
0325     sys.exit(main())