Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
smearing-config.py
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file smearing-config.py
1 # This file is part of the Acts project.
2 #
3 # Copyright (C) 2021 CERN for the benefit of the Acts project
4 #
5 # This Source Code Form is subject to the terms of the Mozilla Public
6 # License, v. 2.0. If a copy of the MPL was not distributed with this
7 # file, You can obtain one at http:#mozilla.org/MPL/2.0/.
8 
9 
10 # each volume configuration is one logical block
11 #
12 # --digi-smear-volume=8
13 # --digi-smear-indices=0:1:5 # loc0, loc1, and time
14 # --digi-smear-types=0:0:3 # loc{0,1} uses gaussian, time uses uniform
15 # # parameter 0: loc0 gaussian width
16 # # parameter 1: loc1 gaussian width
17 # # parameter 2-4: time pitch,min,max
18 # --digi-smear-parameters=10:20:2.5:-25:25
19 #
20 # which can be repeated as often as needed
21 #
22 # --digi-smear-volume=11
23 # --digi-smear-indices=1 # loc1
24 # --digi-smear-types=0 # loc1 uses gaussian
25 # --digi-smear-parameters=12.5 # loc1 gaussian width
26 #
27 
28 
29 import argparse
30 import json
31 import sys
32 
33 
34 def add_switch(i, argv, current):
35 
36  fields = argv[i].split("=")
37 
38  if len(fields) == 1:
39  # --foo bar
40  current.append(argv[i])
41  current.append(argv[i + 1])
42  i += 2
43 
44  elif len(fields) == 2:
45  # --foo=bar
46  current.append(argv[i])
47  i += 1
48 
49  else:
50  raise RuntimeError(f"Invalid argument: {argv[i]}")
51 
52  return i
53 
54 
56  argv = sys.argv[1:]
57  blocks = []
58  current = []
59 
60  i = 0
61  while i < len(argv):
62  if argv[i].startswith("--digi-smear-volume"):
63  if current:
64  blocks.append(current)
65  current = []
66  i = add_switch(i, argv, current)
67  if current:
68  blocks.append(current)
69  current = []
70 
71  return blocks
72 
73 
74 def arg_parser():
75  argp = argparse.ArgumentParser()
76  argp.add_argument(
77  "--digi-smear-volume", help="Sensitive volume identifiers", required=True
78  )
79  argp.add_argument(
80  "--digi-smear-indices",
81  help="Smear parameter indices for this volume",
82  required=True,
83  )
84  argp.add_argument(
85  "--digi-smear-types",
86  help="Smear function types as 0 (gauss), 1 (truncated gauss), 2 (clipped gauss), 3 (uniform), 4 (digital)",
87  required=True,
88  )
89  argp.add_argument(
90  "--digi-smear-parameters",
91  help="Smear parameters depending on the smearing type, 1 parameter for simple gauss, 3 for all others (1 parameter, 2 range values)",
92  required=True,
93  )
94  return argp
95 
96 
97 def get_args():
98  return [arg_parser().parse_args(block) for block in get_args_blocks()]
99 
100 
101 def get_n_params(type_id):
102  if type_id == 0:
103  return 1
104  return 3
105 
106 
107 def get_param_blocks(types_ids, params):
108  blocks = []
109  icur = 0
110  for x in types_ids:
111  n = get_n_params(x)
112  blocks.append(params[icur : icur + n])
113  icur += n
114  return blocks
115 
116 
117 def block_to_json(args):
118  top_data = {"volume": int(args.digi_smear_volume), "value": {"smearing": []}}
119 
120  indices = [int(x) for x in args.digi_smear_indices.split(":")]
121  types = [int(x) for x in args.digi_smear_types.split(":")]
122  params = [float(x) for x in args.digi_smear_parameters.split(":")]
123  param_blocks = get_param_blocks(types, params)
124 
125  for i, t, ps in zip(indices, types, param_blocks):
126  data = {"index": i}
127  if t == 0:
128  data["mean"] = 0.0
129  data["stddev"] = ps[0]
130  data["type"] = "Gauss"
131  elif t == 1:
132  data["mean"] = 0.0
133  data["stddev"] = ps[0]
134  data["range"] = ps[1:]
135  data["type"] = "GaussTrunc"
136  elif t == 2:
137  data["mean"] = 0.0
138  data["stddev"] = ps[0]
139  data["range"] = ps[1:]
140  data["type"] = "GaussClipped"
141  elif t in [3, 4]:
142  data["type"] = "Uniform" if t == 3 else "Digitial"
143 
144  pitch = ps[0]
145  low = ps[1]
146  high = ps[2]
147 
148  data["bindata"] = [
149  0, # Acts::Open,
150  0, # Acts::binX,
151  (high - low) / pitch,
152  low,
153  high,
154  ]
155  else:
156  raise RuntimeError(f"Unrecognized type: {t}")
157 
158  top_data["value"]["smearing"].append(data)
159 
160  return top_data
161 
162 
164  return {
165  "acts-geometry-hierarchy-map": {
166  "format-version": 0,
167  "value-identifier": "digitization-configuration",
168  },
169  "entries": [block_to_json(x) for x in get_args()],
170  }
171 
172 
173 def main():
174  print(json.dumps(get_json_data(), indent=4))
175 
176 
177 if __name__ == "__main__":
178  main()