reboost 0.6.0__tar.gz → 0.6.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {reboost-0.6.0 → reboost-0.6.1}/PKG-INFO +2 -3
- {reboost-0.6.0 → reboost-0.6.1}/pyproject.toml +3 -5
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/_version.py +2 -2
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/optmap/cli.py +45 -24
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/optmap/convolve.py +29 -18
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/optmap/create.py +46 -17
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/optmap/evt.py +43 -20
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost.egg-info/PKG-INFO +2 -3
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost.egg-info/SOURCES.txt +1 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost.egg-info/requires.txt +1 -2
- {reboost-0.6.0 → reboost-0.6.1}/tests/test_optmap.py +32 -11
- reboost-0.6.1/tests/test_optmap_dets.gdml +24 -0
- {reboost-0.6.0 → reboost-0.6.1}/LICENSE +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/README.md +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/setup.cfg +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/__init__.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/build_evt.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/build_glm.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/build_hit.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/cli.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/core.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/hpge/__init__.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/hpge/psd.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/hpge/surface.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/hpge/utils.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/iterator.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/log_utils.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/math/__init__.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/math/functions.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/math/stats.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/optmap/__init__.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/optmap/mapview.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/optmap/numba_pdg.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/optmap/optmap.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/profile.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/shape/__init__.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/shape/cluster.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/shape/group.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/shape/reduction.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/units.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost/utils.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost.egg-info/dependency_links.txt +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost.egg-info/entry_points.txt +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost.egg-info/not-zip-safe +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/src/reboost.egg-info/top_level.txt +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/conftest.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/evt/test_evt.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/glm/test_build_glm.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/hit/configs/args.yaml +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/hit/configs/basic.yaml +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/hit/configs/geom.gdml +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/hit/configs/hit_config.yaml +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/hit/configs/pars.yaml +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/hit/configs/reshape.yaml +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/hit/test_build_hit.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/hpge/simulation/gammas.mac +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/hpge/simulation/geometry.gdml +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/hpge/simulation/make_dt_map.jl +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/hpge/simulation/make_geom.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/hpge/test_current.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/hpge/test_dt_heuristic.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/hpge/test_files/drift_time_maps.lh5 +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/hpge/test_files/internal_electron.lh5 +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/hpge/test_hpge_map.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/hpge/test_r90.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/hpge/test_surface.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/test_cli.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/test_core.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/test_math.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/test_profile.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/test_shape.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/test_units.py +0 -0
- {reboost-0.6.0 → reboost-0.6.1}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: reboost
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.1
|
|
4
4
|
Summary: New LEGEND Monte-Carlo simulation post-processing
|
|
5
5
|
Author-email: Manuel Huber <info@manuelhu.de>, Toby Dixon <toby.dixon.23@ucl.ac.uk>, Luigi Pertoldi <gipert@pm.me>
|
|
6
6
|
Maintainer: The LEGEND Collaboration
|
|
@@ -703,6 +703,7 @@ Requires-Dist: scipy
|
|
|
703
703
|
Requires-Dist: numba
|
|
704
704
|
Requires-Dist: legend-pydataobj>=1.14
|
|
705
705
|
Requires-Dist: legend-pygeom-optics>=0.9.2
|
|
706
|
+
Requires-Dist: legend-pygeom-tools>=0.0.11
|
|
706
707
|
Requires-Dist: hist
|
|
707
708
|
Requires-Dist: dbetto
|
|
708
709
|
Requires-Dist: particle
|
|
@@ -722,8 +723,6 @@ Requires-Dist: pre-commit; extra == "test"
|
|
|
722
723
|
Requires-Dist: pytest>=6.0; extra == "test"
|
|
723
724
|
Requires-Dist: pytest-cov; extra == "test"
|
|
724
725
|
Requires-Dist: legend-pygeom-hpges; extra == "test"
|
|
725
|
-
Requires-Dist: legend-pygeom-tools; extra == "test"
|
|
726
|
-
Requires-Dist: pyg4ometry; extra == "test"
|
|
727
726
|
Requires-Dist: pylegendtestdata>=0.6; extra == "test"
|
|
728
727
|
Dynamic: license-file
|
|
729
728
|
|
|
@@ -37,8 +37,9 @@ dependencies = [
|
|
|
37
37
|
"numpy",
|
|
38
38
|
"scipy",
|
|
39
39
|
"numba",
|
|
40
|
-
"legend-pydataobj>=1.14",
|
|
41
|
-
"legend-pygeom-optics>=0.9.2",
|
|
40
|
+
"legend-pydataobj >=1.14",
|
|
41
|
+
"legend-pygeom-optics >=0.9.2",
|
|
42
|
+
"legend-pygeom-tools >=0.0.11",
|
|
42
43
|
"hist",
|
|
43
44
|
"dbetto",
|
|
44
45
|
"particle",
|
|
@@ -75,10 +76,7 @@ test = [
|
|
|
75
76
|
"pytest>=6.0",
|
|
76
77
|
"pytest-cov",
|
|
77
78
|
"legend-pygeom-hpges",
|
|
78
|
-
"legend-pygeom-tools",
|
|
79
|
-
"pyg4ometry",
|
|
80
79
|
"pylegendtestdata>=0.6",
|
|
81
|
-
|
|
82
80
|
]
|
|
83
81
|
|
|
84
82
|
[project.scripts]
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import argparse
|
|
4
|
-
import json
|
|
5
4
|
import logging
|
|
6
|
-
|
|
5
|
+
|
|
6
|
+
import dbetto
|
|
7
7
|
|
|
8
8
|
from ..log_utils import setup_log
|
|
9
9
|
from ..utils import _check_input_file, _check_output_file
|
|
@@ -35,14 +35,18 @@ def optical_cli() -> None:
|
|
|
35
35
|
|
|
36
36
|
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
37
37
|
|
|
38
|
-
# STEP 1: build evt file from
|
|
39
|
-
evt_parser = subparsers.add_parser("evt", help="build evt file from remage
|
|
40
|
-
evt_parser.
|
|
38
|
+
# STEP 1: build evt file from stp tier
|
|
39
|
+
evt_parser = subparsers.add_parser("evt", help="build optmap-evt file from remage stp file")
|
|
40
|
+
evt_parser_det_group = evt_parser.add_mutually_exclusive_group(required=True)
|
|
41
|
+
evt_parser_det_group.add_argument(
|
|
42
|
+
"--geom",
|
|
43
|
+
help="GDML geometry file",
|
|
44
|
+
)
|
|
45
|
+
evt_parser_det_group.add_argument(
|
|
41
46
|
"--detectors",
|
|
42
|
-
help="file
|
|
43
|
-
required=True,
|
|
47
|
+
help="file with detector ids of all optical channels.",
|
|
44
48
|
)
|
|
45
|
-
evt_parser.add_argument("input", help="input
|
|
49
|
+
evt_parser.add_argument("input", help="input stp LH5 file", metavar="INPUT_STP")
|
|
46
50
|
evt_parser.add_argument("output", help="output evt LH5 file", metavar="OUTPUT_EVT")
|
|
47
51
|
|
|
48
52
|
# STEP 2a: build map file from evt tier
|
|
@@ -55,7 +59,20 @@ def optical_cli() -> None:
|
|
|
55
59
|
)
|
|
56
60
|
map_parser.add_argument(
|
|
57
61
|
"--detectors",
|
|
58
|
-
help=
|
|
62
|
+
help=(
|
|
63
|
+
"file that contains a list of detector ids that will be produced as additional output maps."
|
|
64
|
+
+ "By default, all channels will be included."
|
|
65
|
+
),
|
|
66
|
+
)
|
|
67
|
+
map_parser_det_group = map_parser.add_mutually_exclusive_group(required=True)
|
|
68
|
+
map_parser_det_group.add_argument(
|
|
69
|
+
"--geom",
|
|
70
|
+
help="GDML geometry file",
|
|
71
|
+
)
|
|
72
|
+
map_parser_det_group.add_argument(
|
|
73
|
+
"--evt",
|
|
74
|
+
action="store_true",
|
|
75
|
+
help="the input file is already an optmap-evt file.",
|
|
59
76
|
)
|
|
60
77
|
map_parser.add_argument(
|
|
61
78
|
"--n-procs",
|
|
@@ -69,7 +86,9 @@ def optical_cli() -> None:
|
|
|
69
86
|
action="store_true",
|
|
70
87
|
help="""Check map statistics after creation. default: %(default)s""",
|
|
71
88
|
)
|
|
72
|
-
map_parser.add_argument(
|
|
89
|
+
map_parser.add_argument(
|
|
90
|
+
"input", help="input stp or optmap-evt LH5 file", metavar="INPUT_EVT", nargs="+"
|
|
91
|
+
)
|
|
73
92
|
map_parser.add_argument("output", help="output map LH5 file", metavar="OUTPUT_MAP")
|
|
74
93
|
|
|
75
94
|
# STEP 2b: view maps
|
|
@@ -171,7 +190,7 @@ def optical_cli() -> None:
|
|
|
171
190
|
convolve_parser.add_argument(
|
|
172
191
|
"--dist-mode",
|
|
173
192
|
action="store",
|
|
174
|
-
default="
|
|
193
|
+
default="poisson+no-fano",
|
|
175
194
|
)
|
|
176
195
|
convolve_parser.add_argument("--output", help="output hit LH5 file", metavar="OUTPUT_HIT")
|
|
177
196
|
|
|
@@ -188,15 +207,18 @@ def optical_cli() -> None:
|
|
|
188
207
|
|
|
189
208
|
# STEP 1: build evt file from hit tier
|
|
190
209
|
if args.command == "evt":
|
|
191
|
-
from .evt import build_optmap_evt
|
|
210
|
+
from .evt import build_optmap_evt, get_optical_detectors_from_geom
|
|
192
211
|
|
|
193
|
-
_check_input_file(parser, args.detectors)
|
|
194
212
|
_check_input_file(parser, args.input)
|
|
195
213
|
_check_output_file(parser, args.output)
|
|
196
214
|
|
|
197
|
-
# load detector ids from
|
|
198
|
-
|
|
199
|
-
|
|
215
|
+
# load detector ids from the geometry.
|
|
216
|
+
if args.geom is not None:
|
|
217
|
+
_check_input_file(parser, args.geom, "geometry")
|
|
218
|
+
detectors = get_optical_detectors_from_geom(args.geom)
|
|
219
|
+
else:
|
|
220
|
+
_check_input_file(parser, args.detectors, "detectors")
|
|
221
|
+
detectors = dbetto.utils.load_dict(args.detectors)
|
|
200
222
|
|
|
201
223
|
build_optmap_evt(args.input, args.output, detectors, args.bufsize)
|
|
202
224
|
|
|
@@ -209,23 +231,23 @@ def optical_cli() -> None:
|
|
|
209
231
|
|
|
210
232
|
# load settings for binning from config file.
|
|
211
233
|
_check_input_file(parser, args.input, "settings")
|
|
212
|
-
|
|
213
|
-
settings = json.load(settings_f)
|
|
234
|
+
settings = dbetto.utils.load_dict(args.settings)
|
|
214
235
|
|
|
215
|
-
chfilter =
|
|
236
|
+
chfilter = "*"
|
|
216
237
|
if args.detectors is not None:
|
|
217
|
-
# load detector ids from a JSON array
|
|
218
|
-
|
|
219
|
-
chfilter = json.load(detectors_f)
|
|
238
|
+
# load detector ids from a JSON/YAML array
|
|
239
|
+
chfilter = dbetto.utils.load_dict(args.detectors)
|
|
220
240
|
|
|
221
241
|
create_optical_maps(
|
|
222
242
|
args.input,
|
|
223
243
|
settings,
|
|
224
244
|
args.bufsize,
|
|
245
|
+
is_stp_file=(not args.evt),
|
|
225
246
|
chfilter=chfilter,
|
|
226
247
|
output_lh5_fn=args.output,
|
|
227
248
|
check_after_create=args.check,
|
|
228
249
|
n_procs=args.n_procs,
|
|
250
|
+
geom_fn=args.geom,
|
|
229
251
|
)
|
|
230
252
|
|
|
231
253
|
# STEP 2b: view maps
|
|
@@ -251,8 +273,7 @@ def optical_cli() -> None:
|
|
|
251
273
|
|
|
252
274
|
# load settings for binning from config file.
|
|
253
275
|
_check_input_file(parser, args.input, "settings")
|
|
254
|
-
|
|
255
|
-
settings = json.load(settings_f)
|
|
276
|
+
settings = dbetto.utils.load_dict(args.settings)
|
|
256
277
|
|
|
257
278
|
_check_input_file(parser, args.input)
|
|
258
279
|
_check_output_file(parser, args.output)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
+
import re
|
|
4
5
|
|
|
5
6
|
import legendoptics.scintillate as sc
|
|
6
7
|
import numba
|
|
@@ -24,8 +25,8 @@ OPTMAP_SUM_CH = -2
|
|
|
24
25
|
|
|
25
26
|
def open_optmap(optmap_fn: str):
|
|
26
27
|
maps = lh5.ls(optmap_fn)
|
|
27
|
-
#
|
|
28
|
-
det_ntuples = [m for m in maps if
|
|
28
|
+
# only accept _<number> (/all is read separately)
|
|
29
|
+
det_ntuples = [m for m in maps if re.match(r"_\d+$", m)]
|
|
29
30
|
detids = np.array([int(m.lstrip("_")) for m in det_ntuples])
|
|
30
31
|
detidx = np.arange(0, detids.shape[0])
|
|
31
32
|
|
|
@@ -53,17 +54,25 @@ def open_optmap(optmap_fn: str):
|
|
|
53
54
|
|
|
54
55
|
# give this check some numerical slack.
|
|
55
56
|
if np.any(
|
|
56
|
-
|
|
57
|
+
np.abs(
|
|
58
|
+
ow[OPTMAP_SUM_CH][ow[OPTMAP_ANY_CH] >= 0] - ow[OPTMAP_ANY_CH][ow[OPTMAP_ANY_CH] >= 0]
|
|
59
|
+
)
|
|
57
60
|
< -1e-15
|
|
58
61
|
):
|
|
59
62
|
msg = "optical map does not fulfill relation sum(p_i) >= p_any"
|
|
60
63
|
raise ValueError(msg)
|
|
61
64
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
try:
|
|
66
|
+
# check the exponent from the optical map file
|
|
67
|
+
optmap_multi_det_exp = lh5.read("/_hitcounts_exp", optmap_fn).value
|
|
68
|
+
assert isinstance(optmap_multi_det_exp, float)
|
|
69
|
+
if np.isfinite(optmap_multi_det_exp):
|
|
70
|
+
msg = f"found finite _hitcounts_exp {optmap_multi_det_exp} which is not supported any more"
|
|
71
|
+
raise RuntimeError(msg)
|
|
72
|
+
except KeyError: # the _hitcounts_exp might not be always present.
|
|
73
|
+
pass
|
|
65
74
|
|
|
66
|
-
return detids, detidx, optmap_edges, ow
|
|
75
|
+
return detids, detidx, optmap_edges, ow
|
|
67
76
|
|
|
68
77
|
|
|
69
78
|
def iterate_stepwise_depositions(
|
|
@@ -71,7 +80,7 @@ def iterate_stepwise_depositions(
|
|
|
71
80
|
optmap_for_convolve,
|
|
72
81
|
scint_mat_params: sc.ComputedScintParams,
|
|
73
82
|
rng: np.random.Generator = None,
|
|
74
|
-
dist: str = "
|
|
83
|
+
dist: str = "poisson",
|
|
75
84
|
mode: str = "no-fano",
|
|
76
85
|
):
|
|
77
86
|
# those np functions are not supported by numba, but needed for efficient array access below.
|
|
@@ -144,7 +153,6 @@ def _iterate_stepwise_depositions(
|
|
|
144
153
|
detidx,
|
|
145
154
|
optmap_edges,
|
|
146
155
|
optmap_weights,
|
|
147
|
-
optmap_multi_det_exp,
|
|
148
156
|
scint_mat_params: sc.ComputedScintParams,
|
|
149
157
|
dist: str,
|
|
150
158
|
mode: str,
|
|
@@ -223,8 +231,6 @@ def _iterate_stepwise_depositions(
|
|
|
223
231
|
# we detect this energy deposition; we should at least get one photon out here!
|
|
224
232
|
|
|
225
233
|
detsel_size = 1
|
|
226
|
-
if np.isfinite(optmap_multi_det_exp):
|
|
227
|
-
detsel_size = rng.geometric(1 - np.exp(-optmap_multi_det_exp))
|
|
228
234
|
|
|
229
235
|
px_sum = optmap_weights[OPTMAP_SUM_CH, cur_bins[0], cur_bins[1], cur_bins[2]]
|
|
230
236
|
assert px_sum >= 0.0 # should not be negative.
|
|
@@ -238,7 +244,7 @@ def _iterate_stepwise_depositions(
|
|
|
238
244
|
detp[d] = 0.0
|
|
239
245
|
det_no_stats += had_det_no_stats
|
|
240
246
|
|
|
241
|
-
# should be equivalent to rng.choice(detidx, size=
|
|
247
|
+
# should be equivalent to rng.choice(detidx, size=detsel_size, p=detp)
|
|
242
248
|
detsel = detidx[
|
|
243
249
|
np.searchsorted(np.cumsum(detp), rng.random(size=(detsel_size,)), side="right")
|
|
244
250
|
]
|
|
@@ -339,7 +345,7 @@ def convolve(
|
|
|
339
345
|
material: str,
|
|
340
346
|
output_file: str | None = None,
|
|
341
347
|
buffer_len: int = int(1e6),
|
|
342
|
-
dist_mode: str = "
|
|
348
|
+
dist_mode: str = "poisson+no-fano",
|
|
343
349
|
):
|
|
344
350
|
if material not in ["lar", "pen"]:
|
|
345
351
|
msg = f"unknown material {material} for scintillation"
|
|
@@ -356,13 +362,18 @@ def convolve(
|
|
|
356
362
|
(1 * pint.get_application_registry().ns), # dummy!
|
|
357
363
|
)
|
|
358
364
|
|
|
359
|
-
log.info("opening map %s", map_file)
|
|
360
|
-
optmap_for_convolve = open_optmap(map_file)
|
|
361
|
-
|
|
362
365
|
# special handling of distributions and flags.
|
|
363
366
|
dist, mode = dist_mode.split("+")
|
|
364
|
-
|
|
365
|
-
|
|
367
|
+
if (
|
|
368
|
+
dist not in ("multinomial", "poisson")
|
|
369
|
+
or mode not in ("", "no-fano")
|
|
370
|
+
or (dist == "poisson" and mode != "no-fano")
|
|
371
|
+
):
|
|
372
|
+
msg = f"unsupported statistical distribution {dist_mode} for scintillation emission"
|
|
373
|
+
raise ValueError(msg)
|
|
374
|
+
|
|
375
|
+
log.info("opening map %s", map_file)
|
|
376
|
+
optmap_for_convolve = open_optmap(map_file)
|
|
366
377
|
|
|
367
378
|
log.info("opening energy deposition hit output %s", edep_file)
|
|
368
379
|
it = LH5Iterator(edep_file, edep_path, buffer_len=buffer_len)
|
|
@@ -14,7 +14,12 @@ from numba import njit
|
|
|
14
14
|
from numpy.typing import NDArray
|
|
15
15
|
|
|
16
16
|
from ..log_utils import setup_log
|
|
17
|
-
from .evt import
|
|
17
|
+
from .evt import (
|
|
18
|
+
EVT_TABLE_NAME,
|
|
19
|
+
generate_optmap_evt,
|
|
20
|
+
get_optical_detectors_from_geom,
|
|
21
|
+
read_optmap_evt,
|
|
22
|
+
)
|
|
18
23
|
from .optmap import OpticalMap
|
|
19
24
|
|
|
20
25
|
log = logging.getLogger(__name__)
|
|
@@ -109,12 +114,13 @@ def _create_optical_maps_process_init(optmaps, log_level) -> None:
|
|
|
109
114
|
|
|
110
115
|
|
|
111
116
|
def _create_optical_maps_process(
|
|
112
|
-
optmap_events_fn, buffer_len, all_det_ids, ch_idx_to_map_idx
|
|
117
|
+
optmap_events_fn, buffer_len, is_stp_file, all_det_ids, ch_idx_to_map_idx
|
|
113
118
|
) -> None:
|
|
114
119
|
log.info("started worker task for %s", optmap_events_fn)
|
|
115
120
|
x = _create_optical_maps_chunk(
|
|
116
121
|
optmap_events_fn,
|
|
117
122
|
buffer_len,
|
|
123
|
+
is_stp_file,
|
|
118
124
|
all_det_ids,
|
|
119
125
|
_shared_optmaps,
|
|
120
126
|
ch_idx_to_map_idx,
|
|
@@ -124,9 +130,12 @@ def _create_optical_maps_process(
|
|
|
124
130
|
|
|
125
131
|
|
|
126
132
|
def _create_optical_maps_chunk(
|
|
127
|
-
optmap_events_fn, buffer_len, all_det_ids, optmaps, ch_idx_to_map_idx
|
|
133
|
+
optmap_events_fn, buffer_len, is_stp_file, all_det_ids, optmaps, ch_idx_to_map_idx
|
|
128
134
|
) -> None:
|
|
129
|
-
|
|
135
|
+
if not is_stp_file:
|
|
136
|
+
optmap_events_it = read_optmap_evt(optmap_events_fn, buffer_len)
|
|
137
|
+
else:
|
|
138
|
+
optmap_events_it = generate_optmap_evt(optmap_events_fn, all_det_ids, buffer_len)
|
|
130
139
|
|
|
131
140
|
hits_per_primary = np.zeros(10, dtype=np.int64)
|
|
132
141
|
hits_per_primary_len = 0
|
|
@@ -156,19 +165,24 @@ def create_optical_maps(
|
|
|
156
165
|
optmap_events_fn: list[str],
|
|
157
166
|
settings,
|
|
158
167
|
buffer_len: int = int(5e6),
|
|
168
|
+
is_stp_file: bool = True,
|
|
159
169
|
chfilter: tuple[str | int] | Literal["*"] = (),
|
|
160
170
|
output_lh5_fn: str | None = None,
|
|
161
171
|
after_save: Callable[[int, str, OpticalMap]] | None = None,
|
|
162
172
|
check_after_create: bool = False,
|
|
163
173
|
n_procs: int | None = 1,
|
|
174
|
+
geom_fn: str | None = None,
|
|
164
175
|
) -> None:
|
|
165
176
|
"""Create optical maps.
|
|
166
177
|
|
|
167
178
|
Parameters
|
|
168
179
|
----------
|
|
169
180
|
optmap_events_fn
|
|
170
|
-
list of filenames to lh5 files
|
|
171
|
-
and one column (with numeric
|
|
181
|
+
list of filenames to lh5 files, that can either be stp files from remage or "optmap-evt"
|
|
182
|
+
files with a table ``/optmap_evt`` with columns ``{x,y,z}loc`` and one column (with numeric
|
|
183
|
+
header) for each SiPM channel.
|
|
184
|
+
is_stp_file
|
|
185
|
+
if true, do convert a remage output file (stp file) on-the-fly to an optmap-evt file.
|
|
172
186
|
chfilter
|
|
173
187
|
tuple of detector ids that will be included in the resulting optmap. Those have to match
|
|
174
188
|
the column names in ``optmap_events_fn``.
|
|
@@ -181,9 +195,13 @@ def create_optical_maps(
|
|
|
181
195
|
|
|
182
196
|
use_shmem = n_procs is None or n_procs > 1
|
|
183
197
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
198
|
+
if not is_stp_file:
|
|
199
|
+
optmap_evt_columns = list(
|
|
200
|
+
lh5.read(EVT_TABLE_NAME, optmap_events_fn[0], start_row=0, n_rows=1).keys()
|
|
201
|
+
) # peek into the (first) file to find column names.
|
|
202
|
+
else:
|
|
203
|
+
optmap_evt_columns = [str(i) for i in get_optical_detectors_from_geom(geom_fn)]
|
|
204
|
+
|
|
187
205
|
all_det_ids, optmaps, optmap_det_ids = _optmaps_for_channels(
|
|
188
206
|
optmap_evt_columns, settings, chfilter=chfilter, use_shmem=use_shmem
|
|
189
207
|
)
|
|
@@ -202,7 +220,9 @@ def create_optical_maps(
|
|
|
202
220
|
if not use_shmem:
|
|
203
221
|
for fn in optmap_events_fn:
|
|
204
222
|
q.append(
|
|
205
|
-
_create_optical_maps_chunk(
|
|
223
|
+
_create_optical_maps_chunk(
|
|
224
|
+
fn, buffer_len, is_stp_file, all_det_ids, optmaps, ch_idx_to_map_idx
|
|
225
|
+
)
|
|
206
226
|
)
|
|
207
227
|
else:
|
|
208
228
|
ctx = mp.get_context("forkserver")
|
|
@@ -222,7 +242,7 @@ def create_optical_maps(
|
|
|
222
242
|
for fn in optmap_events_fn:
|
|
223
243
|
r = pool.apply_async(
|
|
224
244
|
_create_optical_maps_process,
|
|
225
|
-
args=(fn, buffer_len, all_det_ids, ch_idx_to_map_idx),
|
|
245
|
+
args=(fn, buffer_len, is_stp_file, all_det_ids, ch_idx_to_map_idx),
|
|
226
246
|
)
|
|
227
247
|
pool_results.append((r, fn))
|
|
228
248
|
|
|
@@ -401,6 +421,9 @@ def merge_optical_maps(
|
|
|
401
421
|
hits_per_primary = np.zeros(10, dtype=np.int64)
|
|
402
422
|
hits_per_primary_len = 0
|
|
403
423
|
for optmap_fn in map_l5_files:
|
|
424
|
+
if "_hitcounts" not in lh5.ls(optmap_fn):
|
|
425
|
+
log.warning("skipping _hitcounts calculations, missing in file %s", optmap_fn)
|
|
426
|
+
return
|
|
404
427
|
hitcounts = lh5.read("/_hitcounts", optmap_fn)
|
|
405
428
|
assert isinstance(hitcounts, Array)
|
|
406
429
|
hits_per_primary[0 : len(hitcounts)] += hitcounts
|
|
@@ -417,13 +440,18 @@ def merge_optical_maps(
|
|
|
417
440
|
def check_optical_map(map_l5_file: str):
|
|
418
441
|
"""Run a health check on the map file.
|
|
419
442
|
|
|
420
|
-
This checks for consistency, and
|
|
443
|
+
This checks for consistency, and outputs details on map statistics.
|
|
421
444
|
"""
|
|
422
|
-
if
|
|
423
|
-
log.
|
|
445
|
+
if "_hitcounts_exp" not in lh5.ls(map_l5_file):
|
|
446
|
+
log.info("no _hitcounts_exp found")
|
|
447
|
+
elif lh5.read("_hitcounts_exp", lh5_file=map_l5_file).value != np.inf:
|
|
448
|
+
log.error("unexpected _hitcounts_exp not equal to positive infinity")
|
|
424
449
|
return
|
|
425
|
-
|
|
426
|
-
|
|
450
|
+
|
|
451
|
+
if "_hitcounts" not in lh5.ls(map_l5_file):
|
|
452
|
+
log.info("no _hitcounts found")
|
|
453
|
+
elif lh5.read("_hitcounts", lh5_file=map_l5_file).nda.shape != (2,):
|
|
454
|
+
log.error("unexpected _hitcounts shape")
|
|
427
455
|
return
|
|
428
456
|
|
|
429
457
|
all_binning = None
|
|
@@ -477,4 +505,5 @@ def rebin_optical_maps(map_l5_file: str, output_lh5_file: str, factor: int):
|
|
|
477
505
|
|
|
478
506
|
# just copy hitcounts exponent.
|
|
479
507
|
for dset in ("_hitcounts_exp", "_hitcounts"):
|
|
480
|
-
lh5.
|
|
508
|
+
if dset in lh5.ls(map_l5_file):
|
|
509
|
+
lh5.write(lh5.read(dset, lh5_file=map_l5_file), dset, lh5_file=output_lh5_file)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from collections.abc import Iterable
|
|
4
|
+
from collections.abc import Generator, Iterable
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
7
|
import numpy as np
|
|
@@ -14,20 +14,18 @@ log = logging.getLogger(__name__)
|
|
|
14
14
|
EVT_TABLE_NAME = "optmap_evt"
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
def
|
|
18
|
-
lh5_in_file: str,
|
|
19
|
-
) -> None:
|
|
17
|
+
def generate_optmap_evt(
|
|
18
|
+
lh5_in_file: str, detectors: Iterable[str | int], buffer_len: int = int(5e6)
|
|
19
|
+
) -> Generator[Table, None, None]:
|
|
20
20
|
"""Create a faster map for lookup of the hits in each detector, for each primary event."""
|
|
21
21
|
log.info("reading file %s", lh5_in_file)
|
|
22
22
|
|
|
23
|
-
lh5_out_file = Path(lh5_out_file)
|
|
24
|
-
lh5_out_file_tmp = lh5_out_file.with_stem(".evt-tmp." + lh5_out_file.stem)
|
|
25
|
-
if lh5_out_file_tmp.exists():
|
|
26
|
-
msg = f"temporary output file {lh5_out_file_tmp} already exists"
|
|
27
|
-
raise RuntimeError(msg)
|
|
28
23
|
vert_it = LH5Iterator(lh5_in_file, "vtx", buffer_len=buffer_len)
|
|
29
24
|
opti_it = LH5Iterator(lh5_in_file, "stp/optical", buffer_len=buffer_len)
|
|
30
25
|
|
|
26
|
+
if len(detectors) == 0:
|
|
27
|
+
msg = "detector array cannot be empty for optmap-evt building"
|
|
28
|
+
raise ValueError(msg)
|
|
31
29
|
detectors = [str(d) for d in detectors]
|
|
32
30
|
for d in detectors:
|
|
33
31
|
if not d.isnumeric():
|
|
@@ -35,11 +33,11 @@ def build_optmap_evt(
|
|
|
35
33
|
|
|
36
34
|
vert_df = None
|
|
37
35
|
vert_df_bounds = None
|
|
38
|
-
vert_it_count = 0
|
|
39
36
|
hits_expected = 0
|
|
37
|
+
had_last_chunk = False
|
|
40
38
|
|
|
41
|
-
def _store_vert_df():
|
|
42
|
-
nonlocal vert_df
|
|
39
|
+
def _store_vert_df(last_chunk: bool) -> Generator[Table, None, None]:
|
|
40
|
+
nonlocal vert_df, had_last_chunk
|
|
43
41
|
if vert_df is None:
|
|
44
42
|
return
|
|
45
43
|
|
|
@@ -49,8 +47,8 @@ def build_optmap_evt(
|
|
|
49
47
|
hits_sum += np.sum(vert_df[d])
|
|
50
48
|
assert hits_sum == hits_expected
|
|
51
49
|
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
yield Table(vert_df)
|
|
51
|
+
had_last_chunk = last_chunk
|
|
54
52
|
vert_df = None
|
|
55
53
|
|
|
56
54
|
# helper function for "windowed join". while iterating the optical hits, we have to
|
|
@@ -59,8 +57,8 @@ def build_optmap_evt(
|
|
|
59
57
|
# This function follows the assumption, that the output event ids are at least "somewhat"
|
|
60
58
|
# monotonic, i.e. later chunks do not contain lower evtids than the previous chunk(s).
|
|
61
59
|
# Going back is not implemented.
|
|
62
|
-
def _ensure_vert_df(vert_it: LH5Iterator, evtid: int) -> None:
|
|
63
|
-
nonlocal vert_df, vert_df_bounds,
|
|
60
|
+
def _ensure_vert_df(vert_it: LH5Iterator, evtid: int) -> Generator[Table, None, None]:
|
|
61
|
+
nonlocal vert_df, vert_df_bounds, hits_expected
|
|
64
62
|
|
|
65
63
|
# skipping multiple chunks is possible in sparsely populated simulations.
|
|
66
64
|
while vert_df_bounds is None or evtid > vert_df_bounds[1] or evtid < vert_df_bounds[0]:
|
|
@@ -74,9 +72,8 @@ def build_optmap_evt(
|
|
|
74
72
|
# here, evtid > vert_df_bounds[1] (or vert_df_bounds is still None). We need to fetch
|
|
75
73
|
# the next event table chunk.
|
|
76
74
|
|
|
77
|
-
vert_it_count += 1
|
|
78
75
|
# we might have filled a dataframe, save it to disk.
|
|
79
|
-
_store_vert_df()
|
|
76
|
+
yield from _store_vert_df(last_chunk=False)
|
|
80
77
|
|
|
81
78
|
# read the next vertex chunk into memory.
|
|
82
79
|
vert_df = next(vert_it).view_as("pd")
|
|
@@ -98,11 +95,28 @@ def build_optmap_evt(
|
|
|
98
95
|
log.info("build evt table (%d)", opti_it_count)
|
|
99
96
|
|
|
100
97
|
for t in opti_df[["evtid", "det_uid"]].itertuples(name=None, index=False):
|
|
101
|
-
_ensure_vert_df(vert_it, t[0])
|
|
98
|
+
yield from _ensure_vert_df(vert_it, t[0])
|
|
102
99
|
vert_df.loc[t[0], str(t[1])] += 1
|
|
103
100
|
hits_expected += 1
|
|
104
101
|
|
|
105
|
-
_store_vert_df() # store the last chunk.
|
|
102
|
+
yield from _store_vert_df(last_chunk=True) # store the last chunk.
|
|
103
|
+
|
|
104
|
+
assert had_last_chunk, "did not reach last chunk in optmap-evt building"
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def build_optmap_evt(
|
|
108
|
+
lh5_in_file: str, lh5_out_file: str, detectors: Iterable[str | int], buffer_len: int = int(5e6)
|
|
109
|
+
) -> None:
|
|
110
|
+
"""Create a faster map for lookup of the hits in each detector, for each primary event."""
|
|
111
|
+
lh5_out_file = Path(lh5_out_file)
|
|
112
|
+
lh5_out_file_tmp = lh5_out_file.with_stem(".evt-tmp." + lh5_out_file.stem)
|
|
113
|
+
if lh5_out_file_tmp.exists():
|
|
114
|
+
msg = f"temporary output file {lh5_out_file_tmp} already exists"
|
|
115
|
+
raise RuntimeError(msg)
|
|
116
|
+
|
|
117
|
+
for vert_it_count, chunk in enumerate(generate_optmap_evt(lh5_in_file, detectors, buffer_len)):
|
|
118
|
+
log.info("store evt file %s (%d)", lh5_out_file_tmp, vert_it_count - 1)
|
|
119
|
+
lh5.write(Table(chunk), name=EVT_TABLE_NAME, lh5_file=lh5_out_file_tmp, wo_mode="append")
|
|
106
120
|
|
|
107
121
|
# after finishing the output file, rename to the actual output file name.
|
|
108
122
|
if lh5_out_file.exists():
|
|
@@ -111,5 +125,14 @@ def build_optmap_evt(
|
|
|
111
125
|
lh5_out_file_tmp.rename(lh5_out_file)
|
|
112
126
|
|
|
113
127
|
|
|
128
|
+
def get_optical_detectors_from_geom(geom_fn) -> list[int]:
|
|
129
|
+
import pyg4ometry
|
|
130
|
+
import pygeomtools
|
|
131
|
+
|
|
132
|
+
geom_registry = pyg4ometry.gdml.Reader(geom_fn).getRegistry()
|
|
133
|
+
detectors = pygeomtools.get_all_sensvols(geom_registry)
|
|
134
|
+
return [d.uid for d in detectors.values() if d.detector_type == "optical"]
|
|
135
|
+
|
|
136
|
+
|
|
114
137
|
def read_optmap_evt(lh5_file: str, buffer_len: int = int(5e6)) -> LH5Iterator:
|
|
115
138
|
return LH5Iterator(lh5_file, EVT_TABLE_NAME, buffer_len=buffer_len)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: reboost
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.1
|
|
4
4
|
Summary: New LEGEND Monte-Carlo simulation post-processing
|
|
5
5
|
Author-email: Manuel Huber <info@manuelhu.de>, Toby Dixon <toby.dixon.23@ucl.ac.uk>, Luigi Pertoldi <gipert@pm.me>
|
|
6
6
|
Maintainer: The LEGEND Collaboration
|
|
@@ -703,6 +703,7 @@ Requires-Dist: scipy
|
|
|
703
703
|
Requires-Dist: numba
|
|
704
704
|
Requires-Dist: legend-pydataobj>=1.14
|
|
705
705
|
Requires-Dist: legend-pygeom-optics>=0.9.2
|
|
706
|
+
Requires-Dist: legend-pygeom-tools>=0.0.11
|
|
706
707
|
Requires-Dist: hist
|
|
707
708
|
Requires-Dist: dbetto
|
|
708
709
|
Requires-Dist: particle
|
|
@@ -722,8 +723,6 @@ Requires-Dist: pre-commit; extra == "test"
|
|
|
722
723
|
Requires-Dist: pytest>=6.0; extra == "test"
|
|
723
724
|
Requires-Dist: pytest-cov; extra == "test"
|
|
724
725
|
Requires-Dist: legend-pygeom-hpges; extra == "test"
|
|
725
|
-
Requires-Dist: legend-pygeom-tools; extra == "test"
|
|
726
|
-
Requires-Dist: pyg4ometry; extra == "test"
|
|
727
726
|
Requires-Dist: pylegendtestdata>=0.6; extra == "test"
|
|
728
727
|
Dynamic: license-file
|
|
729
728
|
|
|
@@ -5,6 +5,7 @@ scipy
|
|
|
5
5
|
numba
|
|
6
6
|
legend-pydataobj>=1.14
|
|
7
7
|
legend-pygeom-optics>=0.9.2
|
|
8
|
+
legend-pygeom-tools>=0.0.11
|
|
8
9
|
hist
|
|
9
10
|
dbetto
|
|
10
11
|
particle
|
|
@@ -27,6 +28,4 @@ pre-commit
|
|
|
27
28
|
pytest>=6.0
|
|
28
29
|
pytest-cov
|
|
29
30
|
legend-pygeom-hpges
|
|
30
|
-
legend-pygeom-tools
|
|
31
|
-
pyg4ometry
|
|
32
31
|
pylegendtestdata>=0.6
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
3
5
|
import numpy as np
|
|
4
6
|
import pytest
|
|
5
7
|
from lgdo import Array, Table, lh5
|
|
@@ -49,13 +51,13 @@ def tbl_hits(tmptestdir):
|
|
|
49
51
|
hit_file = tmptestdir / "hit.lh5"
|
|
50
52
|
lh5.write(tbl_vertices, name="vtx", lh5_file=hit_file, wo_mode="overwrite_file")
|
|
51
53
|
lh5.write(tbl_optical, name="stp/optical", lh5_file=hit_file, wo_mode="overwrite")
|
|
52
|
-
return hit_file
|
|
54
|
+
return (str(hit_file),)
|
|
53
55
|
|
|
54
56
|
|
|
55
57
|
def test_optmap_evt(tbl_hits, tmptestdir):
|
|
56
58
|
evt_out_file = tmptestdir / "evt-out.lh5"
|
|
57
59
|
build_optmap_evt(
|
|
58
|
-
|
|
60
|
+
tbl_hits[0],
|
|
59
61
|
str(evt_out_file),
|
|
60
62
|
detectors=("1", "002", "003"),
|
|
61
63
|
buffer_len=20, # note: shorter window sizes (e.g. 10) do not work.
|
|
@@ -67,16 +69,17 @@ def tbl_evt_fns(tmptestdir) -> tuple[str]:
|
|
|
67
69
|
evt_count = 100
|
|
68
70
|
rng = np.random.default_rng(1234)
|
|
69
71
|
loc = rng.uniform(size=(evt_count, 3))
|
|
70
|
-
hits = rng.geometric(p=0.9, size=(evt_count, 3)) - 1
|
|
72
|
+
# hits = rng.geometric(p=0.9, size=(evt_count, 3)) - 1
|
|
73
|
+
hits = rng.choice([1, 2, 3], size=evt_count)
|
|
71
74
|
|
|
72
75
|
tbl_evt = Table(
|
|
73
76
|
{
|
|
74
77
|
"xloc": Array(loc[:, 0]),
|
|
75
78
|
"yloc": Array(loc[:, 1]),
|
|
76
79
|
"zloc": Array(loc[:, 2]),
|
|
77
|
-
"001": Array(hits
|
|
78
|
-
"002": Array(hits
|
|
79
|
-
"003": Array(hits
|
|
80
|
+
"001": Array((hits == 1).astype(int)),
|
|
81
|
+
"002": Array((hits == 2).astype(int)),
|
|
82
|
+
"003": Array((hits == 3).astype(int)),
|
|
80
83
|
}
|
|
81
84
|
)
|
|
82
85
|
|
|
@@ -86,43 +89,56 @@ def tbl_evt_fns(tmptestdir) -> tuple[str]:
|
|
|
86
89
|
|
|
87
90
|
|
|
88
91
|
@pytest.mark.filterwarnings("ignore::scipy.optimize._optimize.OptimizeWarning")
|
|
89
|
-
|
|
92
|
+
@pytest.mark.parametrize("input_fixture", ["tbl_evt_fns", "tbl_hits"])
|
|
93
|
+
def test_optmap_create(input_fixture, request):
|
|
90
94
|
settings = {
|
|
91
95
|
"range_in_m": [[0, 1], [0, 1], [0, 1]],
|
|
92
96
|
"bins": [10, 10, 10],
|
|
93
97
|
}
|
|
94
98
|
|
|
99
|
+
extra_params = {
|
|
100
|
+
"is_stp_file": input_fixture == "tbl_hits",
|
|
101
|
+
"geom_fn": (
|
|
102
|
+
f"{Path(__file__).parent}/test_optmap_dets.gdml" if input_fixture == "tbl_hits" else ""
|
|
103
|
+
),
|
|
104
|
+
}
|
|
105
|
+
input_fixture = request.getfixturevalue(input_fixture)
|
|
106
|
+
|
|
95
107
|
# test creation only with the summary map.
|
|
96
108
|
create_optical_maps(
|
|
97
|
-
|
|
109
|
+
input_fixture,
|
|
98
110
|
settings,
|
|
99
111
|
chfilter=(),
|
|
100
112
|
output_lh5_fn=None,
|
|
113
|
+
**extra_params,
|
|
101
114
|
)
|
|
102
115
|
|
|
103
116
|
# test creation with all detectors.
|
|
104
117
|
create_optical_maps(
|
|
105
|
-
|
|
118
|
+
input_fixture,
|
|
106
119
|
settings,
|
|
107
120
|
chfilter=("001", "002", "003"),
|
|
108
121
|
output_lh5_fn=None,
|
|
122
|
+
**extra_params,
|
|
109
123
|
)
|
|
110
124
|
|
|
111
125
|
# test creation with some detectors.
|
|
112
126
|
create_optical_maps(
|
|
113
|
-
|
|
127
|
+
input_fixture,
|
|
114
128
|
settings,
|
|
115
129
|
chfilter=("001"),
|
|
116
130
|
output_lh5_fn=None,
|
|
131
|
+
**extra_params,
|
|
117
132
|
)
|
|
118
133
|
|
|
119
134
|
# test creation on multiple cores.
|
|
120
135
|
create_optical_maps(
|
|
121
|
-
|
|
136
|
+
input_fixture,
|
|
122
137
|
settings,
|
|
123
138
|
chfilter=("001", "002", "003"),
|
|
124
139
|
output_lh5_fn=None,
|
|
125
140
|
n_procs=2,
|
|
141
|
+
**extra_params,
|
|
126
142
|
)
|
|
127
143
|
|
|
128
144
|
|
|
@@ -139,6 +155,7 @@ def test_optmap_merge(tbl_evt_fns, tmptestdir):
|
|
|
139
155
|
settings,
|
|
140
156
|
chfilter=("001", "002", "003"),
|
|
141
157
|
output_lh5_fn=map1_fn,
|
|
158
|
+
is_stp_file=False,
|
|
142
159
|
)
|
|
143
160
|
map2_fn = str(tmptestdir / "map2.lh5")
|
|
144
161
|
create_optical_maps(
|
|
@@ -146,6 +163,7 @@ def test_optmap_merge(tbl_evt_fns, tmptestdir):
|
|
|
146
163
|
settings,
|
|
147
164
|
chfilter=("001", "002", "003"),
|
|
148
165
|
output_lh5_fn=map2_fn,
|
|
166
|
+
is_stp_file=False,
|
|
149
167
|
)
|
|
150
168
|
|
|
151
169
|
# test in sequential mode.
|
|
@@ -170,6 +188,7 @@ def test_optmap_rebin(tbl_evt_fns, tmptestdir):
|
|
|
170
188
|
settings,
|
|
171
189
|
chfilter=("001", "002", "003"),
|
|
172
190
|
output_lh5_fn=map1_fn,
|
|
191
|
+
is_stp_file=False,
|
|
173
192
|
)
|
|
174
193
|
|
|
175
194
|
map_rebinned_fn = str(tmptestdir / "map-rebinned.lh5")
|
|
@@ -219,6 +238,7 @@ def test_optmap_convolve(tbl_evt_fns, tbl_edep, tmptestdir):
|
|
|
219
238
|
settings,
|
|
220
239
|
chfilter=("001"),
|
|
221
240
|
output_lh5_fn=map_fn,
|
|
241
|
+
is_stp_file=False,
|
|
222
242
|
)
|
|
223
243
|
|
|
224
244
|
out_fn = str(tmptestdir / "convolved.lh5")
|
|
@@ -245,6 +265,7 @@ def test_optmap_save_and_load(tmptestdir, tbl_evt_fns):
|
|
|
245
265
|
settings,
|
|
246
266
|
chfilter=("001", "002", "003"),
|
|
247
267
|
output_lh5_fn=map_fn,
|
|
268
|
+
is_stp_file=False,
|
|
248
269
|
)
|
|
249
270
|
|
|
250
271
|
assert list_optical_maps(map_fn) == ["_001", "_002", "_003", "all"]
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<?xml version="1.0" ?>
|
|
2
|
+
<gdml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://cern.ch/service-spi/app/releases/GDML/schema/gdml.xsd">
|
|
3
|
+
<materials></materials>
|
|
4
|
+
<solids>
|
|
5
|
+
<box name="world" x="20" y="20" z="20" lunit="m"/>
|
|
6
|
+
</solids>
|
|
7
|
+
<structure>
|
|
8
|
+
<volume name="world">
|
|
9
|
+
<materialref ref="G4_Galactic"/>
|
|
10
|
+
<solidref ref="world"/>
|
|
11
|
+
</volume>
|
|
12
|
+
</structure>
|
|
13
|
+
<userinfo>
|
|
14
|
+
<auxiliary auxtype="RMG_detector_meta" auxvalue=""/>
|
|
15
|
+
<auxiliary auxtype="RMG_detector" auxvalue="optical">
|
|
16
|
+
<auxiliary auxtype="S01" auxvalue="001"/>
|
|
17
|
+
<auxiliary auxtype="S02" auxvalue="002"/>
|
|
18
|
+
<auxiliary auxtype="S03" auxvalue="003"/>
|
|
19
|
+
</auxiliary>
|
|
20
|
+
</userinfo>
|
|
21
|
+
<setup>
|
|
22
|
+
<world ref="world" />
|
|
23
|
+
</setup>
|
|
24
|
+
</gdml>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|