reboost 0.6.2__py3-none-any.whl → 0.8.0__py3-none-any.whl

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/hpge/surface.py CHANGED
@@ -185,10 +185,38 @@ def _compute_diffusion_impl(
185
185
  return collected_charge
186
186
 
187
187
 
188
+ def get_surface_library(fccd: float, dist_step_in_um: float, **kwargs):
189
+ """Build the surface response library by calling `reboost.hpge.surface.get_surface_response`.
190
+
191
+ Parameters
192
+ ----------
193
+ fccd
194
+ The value of the FCCD
195
+ dist_step_in_um
196
+ The distance steps to use in building the library
197
+ **kwargs
198
+ Other keyword arguments to `reboost.hpge.surface.get_surface_response`.
199
+
200
+ Returns
201
+ -------
202
+ 2D array of the cumulative-charge arriving at the p-n junction as a function
203
+ of time, for each distance.
204
+ """
205
+ steps = int(fccd / dist_step_in_um)
206
+
207
+ out = np.zeros((10000, steps))
208
+
209
+ for step in range(steps):
210
+ out[:, step] = get_surface_response(fccd, init=step * dist_step_in_um, **kwargs)
211
+
212
+ return out
213
+
214
+
188
215
  def get_surface_response(
189
216
  fccd: float,
190
- recomb_depth: float,
191
217
  init: float = 0,
218
+ *,
219
+ recomb_depth: float = 500,
192
220
  recomb: float = 0.002,
193
221
  init_size: float = 0.0,
194
222
  factor: float = 0.29,
@@ -197,6 +225,11 @@ def get_surface_response(
197
225
  ):
198
226
  """Extract the surface response current pulse based on diffusion.
199
227
 
228
+ This extracts the amount of charge arrived (cumulative) at the p-n
229
+ junction as a function of time, based on diffusion. The final
230
+ induced waveform on the p-n contact is obtained from convolution
231
+ with the bulk pulse.
232
+
200
233
  Parameters
201
234
  ----------
202
235
  fccd
reboost/hpge/utils.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import Callable, NamedTuple
3
+ from collections.abc import Callable
4
+ from typing import NamedTuple
4
5
 
5
6
  import lgdo
6
7
  import numpy as np
reboost/iterator.py CHANGED
@@ -107,7 +107,10 @@ class GLMIterator:
107
107
  glm_n_rows = self.sto.read_n_rows(f"glm/{self.lh5_group}", self.glm_file)
108
108
 
109
109
  # get the number of stp rows
110
- stp_n_rows = self.sto.read_n_rows(f"{self.stp_field}/{self.lh5_group}", self.stp_file)
110
+ try:
111
+ stp_n_rows = self.sto.read_n_rows(f"{self.stp_field}/{self.lh5_group}", self.stp_file)
112
+ except Exception:
113
+ stp_n_rows = 0
111
114
 
112
115
  # heuristics for a good buffer length
113
116
  if self.use_glm:
reboost/math/stats.py CHANGED
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import logging
4
- from typing import Callable
4
+ from collections.abc import Callable
5
5
 
6
6
  import awkward as ak
7
7
  import numpy as np
@@ -111,7 +111,7 @@ def gaussian_sample(mu: ArrayLike, sigma: ArrayLike | float, *, seed: int | None
111
111
  sigma = sigma.view_as("np")
112
112
  elif isinstance(sigma, ak.Array):
113
113
  sigma = sigma.to_numpy()
114
- elif not isinstance(sigma, (float, int, np.ndarray)):
114
+ elif not isinstance(sigma, float | int | np.ndarray):
115
115
  sigma = np.array(sigma)
116
116
 
117
117
  rng = np.random.default_rng(seed=seed) # Create a random number generator
reboost/optmap/cli.py CHANGED
@@ -35,21 +35,7 @@ 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 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(
46
- "--detectors",
47
- help="file with detector ids of all optical channels.",
48
- )
49
- evt_parser.add_argument("input", help="input stp LH5 file", metavar="INPUT_STP")
50
- evt_parser.add_argument("output", help="output evt LH5 file", metavar="OUTPUT_EVT")
51
-
52
- # STEP 2a: build map file from evt tier
38
+ # STEP 1a: build map file from evt tier
53
39
  map_parser = subparsers.add_parser("createmap", help="build optical map from evt file(s)")
54
40
  map_parser.add_argument(
55
41
  "--settings",
@@ -91,42 +77,67 @@ def optical_cli() -> None:
91
77
  )
92
78
  map_parser.add_argument("output", help="output map LH5 file", metavar="OUTPUT_MAP")
93
79
 
94
- # STEP 2b: view maps
95
- mapview_parser = subparsers.add_parser("viewmap", help="view optical map")
80
+ # STEP 1b: view maps
81
+ mapview_parser = subparsers.add_parser(
82
+ "viewmap",
83
+ help="view optical map (arrows: navigate slices/axes, 'c': channel selector)",
84
+ formatter_class=argparse.RawTextHelpFormatter,
85
+ description=(
86
+ "Interactively view optical maps stored in LH5 files.\n\n"
87
+ "Keyboard controls:\n"
88
+ " left/right - previous/next slice along the current axis\n"
89
+ " up/down - switch slicing axis (x, y, z)\n"
90
+ " c - open channel selector overlay to switch detector map\n\n"
91
+ "Display notes:\n"
92
+ " - Cells where no primary photons were simulated are shown in white.\n"
93
+ " - Cells where no photons were detected are shown in grey.\n"
94
+ " - Cells with values above the colormap maximum are shown in red.\n"
95
+ " - Use --hist to choose which histogram to display. 'prob_unc_rel' shows the\n"
96
+ " relative uncertainty prob_unc / prob where defined.\n"
97
+ " - Use --divide to show the ratio of two map files (this/other)."
98
+ ),
99
+ epilog=(
100
+ "Examples:\n"
101
+ " reboost-optical viewmap mymap.lh5\n"
102
+ " reboost-optical viewmap mymap.lh5 --channel _1067205\n"
103
+ " reboost-optical viewmap mymap.lh5 --hist prob_unc_rel --min 0 --max 1\n"
104
+ " reboost-optical viewmap mymap.lh5 --divide other.lh5 --title 'Comparison'"
105
+ ),
106
+ )
96
107
  mapview_parser.add_argument("input", help="input map LH5 file", metavar="INPUT_MAP")
97
108
  mapview_parser.add_argument(
98
109
  "--channel",
99
110
  action="store",
100
111
  default="all",
101
- help="default: %(default)s",
112
+ help="channel to display ('all' or '_<detid>'). Press 'c' in the viewer to switch. default: %(default)s",
102
113
  )
103
114
  mapview_parser.add_argument(
104
115
  "--hist",
105
- choices=("nr_gen", "nr_det", "p_det", "p_det_err", "p_det_err_rel"),
116
+ choices=("_nr_gen", "_nr_det", "prob", "prob_unc", "prob_unc_rel"),
106
117
  action="store",
107
- default="p_det",
118
+ default="prob",
108
119
  help="select optical map histogram to show. default: %(default)s",
109
120
  )
110
121
  mapview_parser.add_argument(
111
122
  "--divide",
112
123
  action="store",
113
- help="default: none",
124
+ help="divide by another map file before display (ratio). default: none",
114
125
  )
115
126
  mapview_parser.add_argument(
116
127
  "--min",
117
128
  default=1e-4,
118
129
  type=(lambda s: s if s == "auto" else float(s)),
119
- help="colormap min value. default: %(default)e",
130
+ help="colormap min value; use 'auto' for automatic scaling. default: %(default)e",
120
131
  )
121
132
  mapview_parser.add_argument(
122
133
  "--max",
123
134
  default=1e-2,
124
135
  type=(lambda s: s if s == "auto" else float(s)),
125
- help="colormap max value. default: %(default)e",
136
+ help="colormap max value; use 'auto' for automatic scaling. default: %(default)e",
126
137
  )
127
138
  mapview_parser.add_argument("--title", help="title of figure. default: stem of filename")
128
139
 
129
- # STEP 2c: merge maps
140
+ # STEP 1c: merge maps
130
141
  mapmerge_parser = subparsers.add_parser("mergemap", help="merge optical maps")
131
142
  mapmerge_parser.add_argument(
132
143
  "input", help="input map LH5 files", metavar="INPUT_MAP", nargs="+"
@@ -151,49 +162,10 @@ def optical_cli() -> None:
151
162
  help="""Check map statistics after creation. default: %(default)s""",
152
163
  )
153
164
 
154
- # STEP 2d: check map
165
+ # STEP 1d: check map
155
166
  checkmap_parser = subparsers.add_parser("checkmap", help="check optical maps")
156
167
  checkmap_parser.add_argument("input", help="input map LH5 file", metavar="INPUT_MAP")
157
168
 
158
- # STEP 3: convolve with hits from non-optical simulations
159
- convolve_parser = subparsers.add_parser(
160
- "convolve", help="convolve non-optical hits with optical map"
161
- )
162
- convolve_parser.add_argument(
163
- "--material",
164
- action="store",
165
- choices=("lar", "pen", "fib"),
166
- default="lar",
167
- help="default: %(default)s",
168
- )
169
- convolve_parser.add_argument(
170
- "--map",
171
- action="store",
172
- required=True,
173
- metavar="INPUT_MAP",
174
- help="input map LH5 file",
175
- )
176
- convolve_parser.add_argument(
177
- "--edep",
178
- action="store",
179
- required=True,
180
- metavar="INPUT_EDEP",
181
- help="input non-optical LH5 hit file",
182
- )
183
- convolve_parser.add_argument(
184
- "--edep-lgdo",
185
- action="store",
186
- required=True,
187
- metavar="LGDO_PATH",
188
- help="path to LGDO inside non-optical LH5 hit file (e.g. /stp/detXX)",
189
- )
190
- convolve_parser.add_argument(
191
- "--dist-mode",
192
- action="store",
193
- default="poisson+no-fano",
194
- )
195
- convolve_parser.add_argument("--output", help="output hit LH5 file", metavar="OUTPUT_HIT")
196
-
197
169
  # STEP X: rebin maps
198
170
  rebin_parser = subparsers.add_parser("rebin", help="rebin optical maps")
199
171
  rebin_parser.add_argument("input", help="input map LH5 files", metavar="INPUT_MAP")
@@ -205,24 +177,7 @@ def optical_cli() -> None:
205
177
  log_level = (None, logging.INFO, logging.DEBUG)[min(args.verbose, 2)]
206
178
  setup_log(log_level)
207
179
 
208
- # STEP 1: build evt file from hit tier
209
- if args.command == "evt":
210
- from .evt import build_optmap_evt, get_optical_detectors_from_geom
211
-
212
- _check_input_file(parser, args.input)
213
- _check_output_file(parser, args.output)
214
-
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)
222
-
223
- build_optmap_evt(args.input, args.output, detectors, args.bufsize)
224
-
225
- # STEP 2a: build map file from evt tier
180
+ # STEP 1a: build map file from evt tier
226
181
  if args.command == "createmap":
227
182
  from .create import create_optical_maps
228
183
 
@@ -250,7 +205,7 @@ def optical_cli() -> None:
250
205
  geom_fn=args.geom,
251
206
  )
252
207
 
253
- # STEP 2b: view maps
208
+ # STEP 1b: view maps
254
209
  if args.command == "viewmap":
255
210
  from .mapview import view_optmap
256
211
 
@@ -267,7 +222,7 @@ def optical_cli() -> None:
267
222
  histogram_choice=args.hist,
268
223
  )
269
224
 
270
- # STEP 2c: merge maps
225
+ # STEP 1c: merge maps
271
226
  if args.command == "mergemap":
272
227
  from .create import merge_optical_maps
273
228
 
@@ -281,29 +236,13 @@ def optical_cli() -> None:
281
236
  args.input, args.output, settings, check_after_create=args.check, n_procs=args.n_procs
282
237
  )
283
238
 
284
- # STEP 2d: check maps
239
+ # STEP 1d: check maps
285
240
  if args.command == "checkmap":
286
241
  from .create import check_optical_map
287
242
 
288
243
  _check_input_file(parser, args.input)
289
244
  check_optical_map(args.input)
290
245
 
291
- # STEP 3: convolve with hits from non-optical simulations
292
- if args.command == "convolve":
293
- from .convolve import convolve
294
-
295
- _check_input_file(parser, [args.map, args.edep])
296
- _check_output_file(parser, args.output, optional=True)
297
- convolve(
298
- args.map,
299
- args.edep,
300
- args.edep_lgdo,
301
- args.material,
302
- args.output,
303
- args.bufsize,
304
- dist_mode=args.dist_mode,
305
- )
306
-
307
246
  # STEP X: rebin maps
308
247
  if args.command == "rebin":
309
248
  from .create import rebin_optical_maps