legend-daq2lh5 1.3.0__py3-none-any.whl → 1.4.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
daq2lh5/_version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '1.3.0'
16
- __version_tuple__ = version_tuple = (1, 3, 0)
15
+ __version__ = version = '1.4.0'
16
+ __version_tuple__ = version_tuple = (1, 4, 0)
@@ -1,6 +1,5 @@
1
1
  from __future__ import annotations
2
2
 
3
- import json
4
3
  import logging
5
4
  import os
6
5
 
@@ -8,6 +7,7 @@ import h5py
8
7
  import lgdo
9
8
  from lgdo import lh5
10
9
 
10
+ from .. import utils
11
11
  from ..buffer_processor.buffer_processor import buffer_processor
12
12
  from ..raw_buffer import RawBuffer, RawBufferLibrary
13
13
 
@@ -104,11 +104,13 @@ def lh5_buffer_processor(
104
104
  raw_store.gimme_file(proc_file_name, "a")
105
105
 
106
106
  # Do key expansion on the out_spec
107
- if isinstance(out_spec, str) and out_spec.endswith(".json"):
108
- with open(out_spec) as json_file:
109
- out_spec = json.load(json_file)
107
+ allowed_exts = [ext for exts in utils.__file_extensions__.values() for ext in exts]
108
+ if isinstance(out_spec, str) and any(
109
+ [out_spec.endswith(ext) for ext in allowed_exts]
110
+ ):
111
+ out_spec = utils.load_dict(out_spec)
110
112
  if isinstance(out_spec, dict):
111
- RawBufferLibrary(json_dict=out_spec)
113
+ RawBufferLibrary(config=out_spec)
112
114
 
113
115
  # Write everything in the raw file to the new file, check for proc_spec under either the group name, out_name, or the name
114
116
  for tb in lh5_tables:
daq2lh5/build_raw.py CHANGED
@@ -1,7 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import glob
4
- import json
5
4
  import logging
6
5
  import os
7
6
  import time
@@ -10,6 +9,7 @@ import numpy as np
10
9
  from lgdo import lh5
11
10
  from tqdm.auto import tqdm
12
11
 
12
+ from . import utils
13
13
  from .compass.compass_streamer import CompassStreamer
14
14
  from .fc.fc_streamer import FCStreamer
15
15
  from .llama.llama_streamer import LLAMAStreamer
@@ -49,12 +49,14 @@ def build_raw(
49
49
  Specification for the output stream.
50
50
 
51
51
  - if None, uses ``{in_stream}.lh5`` as the output filename.
52
- - if a str not ending in ``.json``, interpreted as the output filename.
53
- - if a str ending in ``.json``, interpreted as a filename containing
54
- json-shorthand for the output specification (see :mod:`.raw_buffer`).
55
- - if a JSON dict, should be a dict loaded from the json shorthand
56
- notation for RawBufferLibraries (see :mod:`.raw_buffer`), which is
57
- then used to build a :class:`.RawBufferLibrary`.
52
+ - if a str not ending with a config file extension, interpreted as the
53
+ output filename.
54
+ - if a str ending with a config file extension, interpreted as a
55
+ filename containing shorthand for the output specification (see
56
+ :mod:`.raw_buffer`).
57
+ - if a dict, should be a dict loaded from the shorthand notation for
58
+ RawBufferLibraries (see :mod:`.raw_buffer`), which is then used to
59
+ build a :class:`.RawBufferLibrary`.
58
60
  - if a :class:`.RawBufferLibrary`, the mapping of data to output file /
59
61
  group is taken from that.
60
62
 
@@ -72,8 +74,8 @@ def build_raw(
72
74
 
73
75
  - if None, CompassDecoder will sacrifice the first packet to determine
74
76
  waveform length
75
- - if a str ending in ``.json``, interpreted as a filename containing
76
- json-shorthand for the output specification (see
77
+ - if a str ending with a config file extension, interpreted as a
78
+ filename containing shorthand for the output specification (see
77
79
  :mod:`.compass.compass_event_decoder`).
78
80
 
79
81
  hdf5_settings
@@ -120,11 +122,13 @@ def build_raw(
120
122
 
121
123
  # process out_spec and setup rb_lib if specified
122
124
  rb_lib = None
123
- if isinstance(out_spec, str) and out_spec.endswith(".json"):
124
- with open(out_spec) as json_file:
125
- out_spec = json.load(json_file)
125
+ allowed_exts = [ext for exts in utils.__file_extensions__.values() for ext in exts]
126
+ if isinstance(out_spec, str) and any(
127
+ [out_spec.endswith(ext) for ext in allowed_exts]
128
+ ):
129
+ out_spec = utils.load_dict(out_spec)
126
130
  if isinstance(out_spec, dict):
127
- out_spec = RawBufferLibrary(json_dict=out_spec, kw_dict=kwargs)
131
+ out_spec = RawBufferLibrary(config=out_spec, kw_dict=kwargs)
128
132
  if isinstance(out_spec, RawBufferLibrary):
129
133
  rb_lib = out_spec
130
134
  # if no rb_lib, write all data to file
daq2lh5/raw_buffer.py CHANGED
@@ -19,48 +19,49 @@ output to a :class:`.RawBufferList`.
19
19
  :class:`.RawBufferLibrary`: a dictionary of :class:`RawBufferList`\ s, e.g. one
20
20
  for each :class:`~.data_decoder.DataDecoder`. Keyed by the decoder name.
21
21
 
22
- :class:`.RawBuffer` supports a JSON short-hand notation, see
23
- :meth:`.RawBufferLibrary.set_from_json_dict` for full specification.
24
-
25
- Example JSON yielding a valid :class:`.RawBufferLibrary` is below. In the
26
- example, the user would call ``RawBufferLibrary.set_from_json_dict(json_dict,
27
- kw_dict)`` with ``kw_dict`` containing an entry for ``'file_key'``. The other
28
- keywords ``{key}`` and ``{name}`` are understood by and filled in during
29
- :meth:`.RawBufferLibrary.set_from_json_dict` unless overloaded in ``kw_dict``.
22
+ :class:`.RawBuffer` supports a config file short-hand notation, see
23
+ :meth:`.RawBufferLibrary.set_from_dict` for full specification.
24
+
25
+ Example YAML yielding a valid :class:`.RawBufferLibrary` is below (other
26
+ formats like JSON are also supported). In the example, the user would call
27
+ ``RawBufferLibrary.set_from_dict(config, kw_dict)`` with ``kw_dict``
28
+ containing an entry for ``'file_key'``. The other keywords ``{key}`` and
29
+ ``{name}`` are understood by and filled in during
30
+ :meth:`.RawBufferLibrary.set_from_dict` unless overloaded in ``kw_dict``.
30
31
  Note the use of the wildcard ``*``: this will match all other decoder names /
31
32
  keys.
32
33
 
33
- .. code-block :: json
34
-
35
- {
36
- "FCEventDecoder" : {
37
- "g{key:0>3d}" : {
38
- "key_list" : [ [24,64] ],
39
- "out_stream" : "$DATADIR/{file_key}_geds.lh5:/geds",
40
- "proc_spec": {
41
- "window": {"waveform", 10, 100, "windowed_waveform"}
42
- }
43
- },
44
- "spms" : {
45
- "key_list" : [ [6,23] ],
46
- "out_stream" : "$DATADIR/{file_key}_spms.lh5:/spms"
47
- },
48
- "puls" : {
49
- "key_list" : [ 0 ],
50
- "out_stream" : "$DATADIR/{file_key}_auxs.lh5:/auxs"
51
- },
52
- "muvt" : {
53
- "key_list" : [ 1, 5 ],
54
- "out_stream" : "$DATADIR/{file_key}_auxs.lh5:/auxs"
55
- }
56
- },
57
- "*" : {
58
- "{name}" : {
59
- "key_list" : [ "*" ],
60
- "out_stream" : "$DATADIR/{file_key}_{name}.lh5"
61
- }
62
- }
63
- }
34
+ .. code-block :: yaml
35
+
36
+ FCEventDecoder:
37
+ "g{key:0>3d}":
38
+ key_list:
39
+ - [24, 64]
40
+ out_stream: "$DATADIR/{file_key}_geds.lh5:/geds"
41
+ proc_spec:
42
+ window:
43
+ - waveform
44
+ - 10
45
+ - 100
46
+ - windowed_waveform
47
+ spms:
48
+ key_list:
49
+ - [6, 23]
50
+ out_stream: "$DATADIR/{file_key}_spms.lh5:/spms"
51
+ puls:
52
+ key_list:
53
+ - 0
54
+ out_stream: "$DATADIR/{file_key}_auxs.lh5:/auxs"
55
+ muvt:
56
+ key_list:
57
+ - 1
58
+ - 5
59
+ out_stream: "$DATADIR/{file_key}_auxs.lh5:/auxs"
60
+
61
+ "*":
62
+ "{name}":
63
+ key_list: ["*"]
64
+ out_stream: "$DATADIR/{file_key}_{name}.lh5"
64
65
  """
65
66
 
66
67
  from __future__ import annotations
@@ -105,7 +106,7 @@ class RawBuffer:
105
106
  the name or identifier of the object in the output stream.
106
107
  proc_spec
107
108
  a dictionary containing the following:
108
- - a DSP config file, passed as a dictionary, or as a path to a JSON file
109
+ - a DSP config file, passed as a dictionary, or as a path to a config file
109
110
  - an array containing: the name of an LGDO object stored in the :class:`.RawBuffer` to be sliced,
110
111
  the start and end indices of the slice, and the new name for the sliced object
111
112
  - a dictionary of fields to drop
@@ -185,29 +186,27 @@ class RawBufferList(list):
185
186
  self.keyed_dict[key] = rb
186
187
  return self.keyed_dict
187
188
 
188
- def set_from_json_dict(
189
- self, json_dict: dict, kw_dict: dict[str, str] = None
190
- ) -> None:
191
- """Set up a :class:`.RawBufferList` from a dictionary written in JSON
192
- shorthand. See :meth:`.RawBufferLibrary.set_from_json_dict` for details.
189
+ def set_from_dict(self, config: dict, kw_dict: dict[str, str] = None) -> None:
190
+ """Set up a :class:`.RawBufferList` from a dictionary. See
191
+ :meth:`.RawBufferLibrary.set_from_dict` for details.
193
192
 
194
193
  Notes
195
194
  -----
196
- `json_dict` is changed by this function.
195
+ `config` is changed by this function.
197
196
  """
198
- expand_rblist_json_dict(json_dict, {} if kw_dict is None else kw_dict)
199
- for name in json_dict:
197
+ expand_rblist_dict(config, {} if kw_dict is None else kw_dict)
198
+ for name in config:
200
199
  rb = RawBuffer()
201
- if "key_list" in json_dict[name]:
202
- rb.key_list = json_dict[name]["key_list"]
203
- if "out_stream" in json_dict[name]:
204
- rb.out_stream = json_dict[name]["out_stream"]
205
- if "proc_spec" in json_dict[name]:
206
- rb.proc_spec = json_dict[name][
200
+ if "key_list" in config[name]:
201
+ rb.key_list = config[name]["key_list"]
202
+ if "out_stream" in config[name]:
203
+ rb.out_stream = config[name]["out_stream"]
204
+ if "proc_spec" in config[name]:
205
+ rb.proc_spec = config[name][
207
206
  "proc_spec"
208
207
  ] # If you swap this with the next line, then key expansion doesn't work
209
- if "out_name" in json_dict[name]:
210
- rb.out_name = json_dict[name]["out_name"]
208
+ if "out_name" in config[name]:
209
+ rb.out_name = config[name]["out_name"]
211
210
  else:
212
211
  rb.out_name = name
213
212
  self.append(rb)
@@ -250,15 +249,12 @@ class RawBufferLibrary(dict):
250
249
  write to them.
251
250
  """
252
251
 
253
- def __init__(self, json_dict: dict = None, kw_dict: dict[str, str] = None) -> None:
254
- if json_dict is not None:
255
- self.set_from_json_dict(json_dict, kw_dict)
252
+ def __init__(self, config: dict = None, kw_dict: dict[str, str] = None) -> None:
253
+ if config is not None:
254
+ self.set_from_dict(config, kw_dict)
256
255
 
257
- def set_from_json_dict(
258
- self, json_dict: dict, kw_dict: dict[str, str] = None
259
- ) -> None:
260
- r"""Set up a :class:`.RawBufferLibrary` from a dictionary written in
261
- JSON shorthand.
256
+ def set_from_dict(self, config: dict, kw_dict: dict[str, str] = None) -> None:
257
+ r"""Set up a :class:`.RawBufferLibrary` from a dictionary.
262
258
 
263
259
  Basic structure:
264
260
 
@@ -288,7 +284,7 @@ class RawBufferLibrary(dict):
288
284
  to the first and last integer keys in a contiguous range (e.g. of
289
285
  channels) that get stored to the same buffer. These simply get
290
286
  replaced with the explicit list of integers in the range. We use
291
- lists not tuples for JSON compliance.
287
+ lists not tuples for config file format compliance.
292
288
  * The ``name`` can include ``{key:xxx}`` format specifiers, indicating
293
289
  that each key in ``key_list`` should be given its own buffer with the
294
290
  corresponding name. The same specifier can appear in ``out_path`` to
@@ -307,18 +303,18 @@ class RawBufferLibrary(dict):
307
303
 
308
304
  Parameters
309
305
  ----------
310
- json_dict
311
- loaded from a JSON file written in the allowed shorthand.
312
- `json_dict` is changed by this function.
306
+ config
307
+ loaded from a config file written in the allowed shorthand.
308
+ `config` is changed by this function.
313
309
  kw_dict
314
310
  dictionary of keyword-value pairs for substitutions into the
315
311
  ``out_stream`` and ``out_name`` fields.
316
312
  """
317
- for list_name in json_dict:
313
+ for list_name in config:
318
314
  if list_name not in self:
319
315
  self[list_name] = RawBufferList()
320
- self[list_name].set_from_json_dict(
321
- json_dict[list_name], {} if kw_dict is None else kw_dict
316
+ self[list_name].set_from_dict(
317
+ config[list_name], {} if kw_dict is None else kw_dict
322
318
  )
323
319
 
324
320
  def get_list_of(self, attribute: str, unique: bool = True) -> list:
@@ -352,26 +348,26 @@ class RawBufferLibrary(dict):
352
348
  rb_list.clear_full()
353
349
 
354
350
 
355
- def expand_rblist_json_dict(json_dict: dict, kw_dict: dict[str, str]) -> None:
356
- """Expand shorthands in a JSON dictionary representing a
351
+ def expand_rblist_dict(config: dict, kw_dict: dict[str, str]) -> None:
352
+ """Expand shorthands in a dictionary representing a
357
353
  :class:`.RawBufferList`.
358
354
 
359
- See :meth:`.RawBufferLibrary.set_from_json_dict` for details.
355
+ See :meth:`.RawBufferLibrary.set_from_dict` for details.
360
356
 
361
357
  Notes
362
358
  -----
363
- The input JSON dictionary is changed by this function.
359
+ The input dictionary is changed by this function.
364
360
  """
365
361
  # get the original list of groups because we are going to change the
366
- # dict.keys() of json_dict inside the next list. Note: we have to convert
362
+ # dict.keys() of config inside the next list. Note: we have to convert
367
363
  # from dict_keys to list here otherwise the loop complains about changing
368
364
  # the dictionary during iteration
369
- buffer_names = list(json_dict.keys())
365
+ buffer_names = list(config.keys())
370
366
  for name in buffer_names:
371
367
  if name == "":
372
368
  raise ValueError("buffer name can't be empty")
373
369
 
374
- info = json_dict[name] # changes to info will change json_dict[name]
370
+ info = config[name] # changes to info will change config[name]
375
371
  # make sure we have a key list
376
372
  if "key_list" not in info:
377
373
  raise ValueError(f"'{name}' is missing key_list")
@@ -399,12 +395,12 @@ def expand_rblist_json_dict(json_dict: dict, kw_dict: dict[str, str]) -> None:
399
395
  continue # will be handled later, once the key_list is known
400
396
  for key in info["key_list"]:
401
397
  expanded_name = name.format(key=key)
402
- json_dict[expanded_name] = info.copy()
403
- json_dict[expanded_name]["key_list"] = [key]
404
- json_dict.pop(name)
398
+ config[expanded_name] = info.copy()
399
+ config[expanded_name]["key_list"] = [key]
400
+ config.pop(name)
405
401
 
406
402
  # now re-iterate and expand out_paths
407
- for name, info in json_dict.items():
403
+ for name, info in config.items():
408
404
  if len(info["key_list"]) == 1 and not (
409
405
  isinstance(info["key_list"][0], str) and "*" in info["key_list"][0]
410
406
  ):
daq2lh5/utils.py ADDED
@@ -0,0 +1,35 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import logging
5
+ from pathlib import Path
6
+
7
+ import yaml
8
+
9
+ log = logging.getLogger(__name__)
10
+
11
+
12
+ __file_extensions__ = {"json": [".json"], "yaml": [".yaml", ".yml"]}
13
+
14
+
15
+ def load_dict(fname: str, ftype: str | None = None) -> dict:
16
+ """Load a text file as a Python dict."""
17
+ fname = Path(fname)
18
+
19
+ # determine file type from extension
20
+ if ftype is None:
21
+ for _ftype, exts in __file_extensions__.items():
22
+ if fname.suffix in exts:
23
+ ftype = _ftype
24
+
25
+ msg = f"loading {ftype} dict from: {fname}"
26
+ log.debug(msg)
27
+
28
+ with fname.open() as f:
29
+ if ftype == "json":
30
+ return json.load(f)
31
+ if ftype == "yaml":
32
+ return yaml.safe_load(f)
33
+
34
+ msg = f"unsupported file format {ftype}"
35
+ raise NotImplementedError(msg)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: legend_daq2lh5
3
- Version: 1.3.0
3
+ Version: 1.4.0
4
4
  Summary: Convert digitizer data to LH5
5
5
  Home-page: https://github.com/legend-exp/legend-daq2lh5
6
6
  Author: Jason Detwiler
@@ -1,14 +1,15 @@
1
1
  daq2lh5/__init__.py,sha256=VPmwKuZSA0icpce05ojhnsKWhR4_QUgD0oVXUoN9wks,975
2
- daq2lh5/_version.py,sha256=HGwtpza1HCPtlyqElUvIyH97K44TO13CYiYVZNezQ1M,411
3
- daq2lh5/build_raw.py,sha256=w0sS8MEN-UhAHSjlPbqDlMBfzjeznIIrKxNxuRxPFqA,10531
2
+ daq2lh5/_version.py,sha256=R8-T9fmURjcuoxYpHTAjyNAhgJPDtI2jogCjqYYkfCU,411
3
+ daq2lh5/build_raw.py,sha256=SDpdOU8qpfzMtx8gtFu-RZYqxutQo1smJSkv-LrH9YE,10672
4
4
  daq2lh5/cli.py,sha256=7bPfH1XbyAS48wZn_0unj4Y5MD5kF7V34Q5srn4jKVM,2913
5
5
  daq2lh5/data_decoder.py,sha256=Cn40fodfKs7pKa2odzG1j806iw9IyQVfbbWObNGmof8,10677
6
6
  daq2lh5/data_streamer.py,sha256=WuyqneVg8Kf7V072aUWYT5q3vmPZoobjAZ7oSw0sC9k,14187
7
7
  daq2lh5/logging.py,sha256=rYNeToaZBTCaIiC42a4CUroAo1PCOreTXbpEZyMO8Fo,987
8
- daq2lh5/raw_buffer.py,sha256=2jJvH7BbVkJCzF5A2nOIdcgwUs68eLnpvc0FvTjckaI,17688
8
+ daq2lh5/raw_buffer.py,sha256=LfkVAOZa4cWz227Ef22rKi57Shk7GbENoxUEkxC6IgU,17403
9
+ daq2lh5/utils.py,sha256=Pc8Oh0ZVBqwwVehyhSJttHnX5tWbOyEZPk-rVg8mb0c,839
9
10
  daq2lh5/buffer_processor/__init__.py,sha256=7k6v_KPximtv7805QnX4-xp_S3vqvqwDfdV3q95oZJo,84
10
11
  daq2lh5/buffer_processor/buffer_processor.py,sha256=GUxpNDbqGLuUEZmXjeratipbzmki12RFNYZkxgMtesg,14483
11
- daq2lh5/buffer_processor/lh5_buffer_processor.py,sha256=yL1ru0_GTsZx099oi45sXL-FxPfdChtStd_IFtZNI_Q,8222
12
+ daq2lh5/buffer_processor/lh5_buffer_processor.py,sha256=einRDLI6EVR-U_TT2GdCZPctFnosJ774eMiUj-ahn6c,8316
12
13
  daq2lh5/compass/__init__.py,sha256=mOXHWp7kRDgNTPQty3E8k2KPSy_vAzjneKfAcCVaPyE,132
13
14
  daq2lh5/compass/compass_config_parser.py,sha256=zeAsOo1dOJPGLL8-zkAcdYRkqt8BodtOPi96n7fWsl4,12300
14
15
  daq2lh5/compass/compass_event_decoder.py,sha256=kiPOaEu8SgLD2wbSPbBahcbTBBRAIw35wtVLBcwPcXY,7386
@@ -32,9 +33,9 @@ daq2lh5/orca/orca_header_decoder.py,sha256=ORIIyfx22ybyKc-uyWy5ER49-dl3BGpHdfV8O
32
33
  daq2lh5/orca/orca_packet.py,sha256=nOHuBXsTI1SzTjHZtff0txSQYvkwo4XGx3fpk7XfYj8,2489
33
34
  daq2lh5/orca/orca_run_decoder.py,sha256=3atKXC6mDi8_PK6ICUBBJ-LyaTM8OU31kKWIpmttRr4,2065
34
35
  daq2lh5/orca/orca_streamer.py,sha256=VbD9PF-rx_Rk-rEy7XECPmgxr6kZSUf0tC7Qbol3Qeg,15693
35
- legend_daq2lh5-1.3.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
36
- legend_daq2lh5-1.3.0.dist-info/METADATA,sha256=3fR5Z-61fjaRaAEObVk9k8HpTGxiDF0wL4f6djIX8aQ,3956
37
- legend_daq2lh5-1.3.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
38
- legend_daq2lh5-1.3.0.dist-info/entry_points.txt,sha256=R08R4NrHi0ab5MJN_qKqzePVzrLSsw5WpmbiwwduYjw,59
39
- legend_daq2lh5-1.3.0.dist-info/top_level.txt,sha256=MJQVLyLqMgMKBdVfNXFaCKCjHKakAs19VLbC9ctXZ7A,8
40
- legend_daq2lh5-1.3.0.dist-info/RECORD,,
36
+ legend_daq2lh5-1.4.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
37
+ legend_daq2lh5-1.4.0.dist-info/METADATA,sha256=SKEW8u7wRrCK5zTY01iMGDYGPmrmg1ED5g9fsbwLVVA,3956
38
+ legend_daq2lh5-1.4.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
39
+ legend_daq2lh5-1.4.0.dist-info/entry_points.txt,sha256=R08R4NrHi0ab5MJN_qKqzePVzrLSsw5WpmbiwwduYjw,59
40
+ legend_daq2lh5-1.4.0.dist-info/top_level.txt,sha256=MJQVLyLqMgMKBdVfNXFaCKCjHKakAs19VLbC9ctXZ7A,8
41
+ legend_daq2lh5-1.4.0.dist-info/RECORD,,