legend-daq2lh5 1.4.2__py3-none-any.whl → 1.5.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.
daq2lh5/_version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '1.4.2'
21
- __version_tuple__ = version_tuple = (1, 4, 2)
20
+ __version__ = version = '1.5.0'
21
+ __version_tuple__ = version_tuple = (1, 5, 0)
@@ -74,7 +74,7 @@ def lh5_buffer_processor(
74
74
  # Look one layer deeper for a :meth:`lgdo.Table` if necessary
75
75
  elif lh5.ls(lh5_file, f"{tb}"):
76
76
  # Check to make sure that this isn't a table itself
77
- maybe_table, _ = raw_store.read(f"{tb}", lh5_file)
77
+ maybe_table = raw_store.read(f"{tb}", lh5_file)
78
78
  if isinstance(maybe_table, lgdo.Table):
79
79
  lh5_tables.append(f"{tb}")
80
80
  del maybe_table
@@ -114,7 +114,7 @@ def lh5_buffer_processor(
114
114
 
115
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
116
116
  for tb in lh5_tables:
117
- lgdo_obj, _ = raw_store.read(f"{tb}", lh5_file)
117
+ lgdo_obj = raw_store.read(f"{tb}", lh5_file)
118
118
 
119
119
  # Find the out_name.
120
120
  # If the top level group has an lgdo table in it, then the out_name is group
@@ -80,7 +80,7 @@ fc_decoded_values = {
80
80
  }
81
81
  """Default FlashCam Event decoded values.
82
82
 
83
- Re-used by :class:`~.orca.orca_flashcam.ORFlashCamWaveformDecoder`.
83
+ Reused by :class:`~.orca.orca_flashcam.ORFlashCamWaveformDecoder`.
84
84
 
85
85
  Warning
86
86
  -------
@@ -20,6 +20,8 @@ llama_decoded_values_template = {
20
20
  "fadc_channel_id": {"dtype": "uint32"},
21
21
  # time since epoch
22
22
  "time_since_run_start": {"dtype": "float64", "units": "s"},
23
+ "unixtime": {"dtype": "float64", "units": "s"},
24
+ "unixtime_accuracy": {"dtype": "float64", "units": "s"},
23
25
  "fadc_status_bits": {"dtype": "uint32"},
24
26
  # waveform data --> not always present
25
27
  # "waveform": {
@@ -109,6 +111,9 @@ class LLAMAEventDecoder(DataDecoder):
109
111
  if format_bits & 0x08:
110
112
  self.__add_energy(self.decoded_values[fch])
111
113
 
114
+ def set_global_configs(self, global_configs: dict[str, Any]):
115
+ self.global_configs = global_configs
116
+
112
117
  def get_key_lists(self) -> list[list[int | str]]:
113
118
  """Get list of keys.
114
119
 
@@ -196,6 +201,11 @@ class LLAMAEventDecoder(DataDecoder):
196
201
  tbl["fadc_channel_id"].nda[ii] = fadc_channel_id
197
202
  tbl["packet_id"].nda[ii] = packet_id
198
203
  tbl["time_since_run_start"].nda[ii] = timestamp
204
+ tbl["unixtime"].nda[ii] = timestamp + self.global_configs["initial_timestamp"]
205
+ # accuracy when comparing timestamps of different files:
206
+ tbl["unixtime_accuracy"].nda[ii] = self.global_configs[
207
+ "initial_timestamp_accuracy"
208
+ ]
199
209
 
200
210
  offset = 2
201
211
  if format_bits & 0x1:
@@ -1,7 +1,10 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import datetime
3
4
  import io
4
5
  import logging
6
+ import os
7
+ import re
5
8
  from typing import Any, Dict
6
9
 
7
10
  import lgdo
@@ -15,6 +18,25 @@ log = logging.getLogger(__name__)
15
18
  LLAMA_Channel_Configs_t = Dict[int, Dict[str, Any]]
16
19
 
17
20
 
21
+ def parse_filename_for_timestamp(f_in_name: str) -> float:
22
+ """take a filename; return the unixtime parsed from the filename; 0 if impossible."""
23
+ filename = os.path.basename(f_in_name)
24
+ if match := re.fullmatch(r".*(\d{8})[-T](\d{6})(Z?).*", filename):
25
+ tsymd = match.group(1)
26
+ tshms = match.group(2)
27
+ utc: bool = True if match.group(3) == "Z" else False
28
+ when_file: datetime.datetime = datetime.datetime.strptime(
29
+ tsymd + tshms, "%Y%m%d%H%M%S"
30
+ ) # naive datetime object
31
+ if utc:
32
+ when_file = when_file.replace(
33
+ tzinfo=datetime.timezone.utc
34
+ ) # make it aware; UTC. Naive is treated as local
35
+ return when_file.timestamp()
36
+ else:
37
+ return 0
38
+
39
+
18
40
  class LLAMAHeaderDecoder(DataDecoder): # DataDecoder currently unused
19
41
  """Decode llamaDAQ header data.
20
42
 
@@ -31,7 +53,7 @@ class LLAMAHeaderDecoder(DataDecoder): # DataDecoder currently unused
31
53
  self.config = lgdo.Struct()
32
54
  self.channel_configs = None
33
55
 
34
- def decode_header(self, f_in: io.BufferedReader) -> lgdo.Struct:
56
+ def decode_header(self, f_in: io.BufferedReader, f_in_name: str) -> lgdo.Struct:
35
57
  n_bytes_read = 0
36
58
 
37
59
  f_in.seek(0) # should be there anyhow, but re-set if not
@@ -55,6 +77,15 @@ class LLAMAHeaderDecoder(DataDecoder): # DataDecoder currently unused
55
77
  self.length_econf = evt_data_16[5]
56
78
  self.number_chOpen = evt_data_32[3]
57
79
 
80
+ self.global_configs = {}
81
+
82
+ # currently pulled from filename with 1s precision.
83
+ # change if we have it in the llamaDAQ file's header
84
+ self.global_configs["initial_timestamp"] = parse_filename_for_timestamp(
85
+ f_in_name
86
+ )
87
+ self.global_configs["initial_timestamp_accuracy"] = 1.0 # in seconds
88
+
58
89
  log.debug(
59
90
  f"File version: {self.version_major}.{self.version_minor}.{self.version_patch}"
60
91
  )
@@ -72,6 +103,13 @@ class LLAMAHeaderDecoder(DataDecoder): # DataDecoder currently unused
72
103
  self.config.add_field("version_patch", lgdo.Scalar(self.version_patch))
73
104
  self.config.add_field("length_econf", lgdo.Scalar(self.length_econf))
74
105
  self.config.add_field("number_chOpen", lgdo.Scalar(self.number_chOpen))
106
+ self.config.add_field(
107
+ "initial_timestamp", lgdo.Scalar(self.global_configs["initial_timestamp"])
108
+ )
109
+ self.config.add_field(
110
+ "initial_timestamp_accuracy",
111
+ lgdo.Scalar(self.global_configs["initial_timestamp_accuracy"]),
112
+ )
75
113
 
76
114
  for fch_id, fch_content in self.channel_configs.items():
77
115
  fch_lgdo = lgdo.Struct()
@@ -88,6 +126,9 @@ class LLAMAHeaderDecoder(DataDecoder): # DataDecoder currently unused
88
126
  def get_channel_configs(self) -> LLAMA_Channel_Configs_t:
89
127
  return self.channel_configs
90
128
 
129
+ def get_global_configs(self) -> dict[str, Any]:
130
+ return self.global_configs
131
+
91
132
  def __decode_channel_configs(self, f_in: io.BufferedReader) -> int:
92
133
  """Reads the metadata.
93
134
 
@@ -53,12 +53,15 @@ class LLAMAStreamer(DataStreamer):
53
53
  self.packet_id = 0
54
54
 
55
55
  # read header info here
56
- header, n_bytes_hdr = self.header_decoder.decode_header(self.in_stream)
56
+ header, n_bytes_hdr = self.header_decoder.decode_header(
57
+ self.in_stream, llama_filename
58
+ )
57
59
  self.n_bytes_read += n_bytes_hdr
58
60
 
59
61
  self.event_decoder.set_channel_configs(
60
62
  self.header_decoder.get_channel_configs()
61
63
  )
64
+ self.event_decoder.set_global_configs(self.header_decoder.get_global_configs())
62
65
 
63
66
  # as far as I can tell, this happens if a user does not specify output.
64
67
  # Then I can still get a rb_lib, but that misses keys entirely, which I need since channels can have different setups.
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import bz2
3
4
  import gzip
4
5
  import json
5
6
  import logging
@@ -201,6 +202,8 @@ class OrcaStreamer(DataStreamer):
201
202
  self.close_in_stream()
202
203
  if stream_name.endswith(".gz"):
203
204
  self.in_stream = gzip.open(stream_name.encode("utf-8"), "rb")
205
+ elif stream_name.endswith(".bz2"):
206
+ self.in_stream = bz2.open(stream_name.encode("utf-8"), "rb")
204
207
  else:
205
208
  self.in_stream = open(stream_name.encode("utf-8"), "rb")
206
209
  self.n_bytes_read = 0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: legend_daq2lh5
3
- Version: 1.4.2
3
+ Version: 1.5.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
@@ -11,7 +11,6 @@ Classifier: Development Status :: 4 - Beta
11
11
  Classifier: Intended Audience :: Developers
12
12
  Classifier: Intended Audience :: Information Technology
13
13
  Classifier: Intended Audience :: Science/Research
14
- Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
15
14
  Classifier: Operating System :: MacOS
16
15
  Classifier: Operating System :: POSIX
17
16
  Classifier: Operating System :: Unix
@@ -48,6 +47,7 @@ Requires-Dist: pre-commit; extra == "test"
48
47
  Requires-Dist: pylegendtestdata; extra == "test"
49
48
  Requires-Dist: pytest>=6.0; extra == "test"
50
49
  Requires-Dist: pytest-cov; extra == "test"
50
+ Dynamic: license-file
51
51
 
52
52
  # legend-daq2lh5
53
53
 
@@ -1,5 +1,5 @@
1
1
  daq2lh5/__init__.py,sha256=VPmwKuZSA0icpce05ojhnsKWhR4_QUgD0oVXUoN9wks,975
2
- daq2lh5/_version.py,sha256=Ls_J-pNiuTKX1KU6pZ6tPQXAMcmLAzW_HHHgGVQNEd0,511
2
+ daq2lh5/_version.py,sha256=qEW4HoWHYDkBguijNs9nZzHd38qlKSeRTDG2QQbYrGY,511
3
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
@@ -9,7 +9,7 @@ daq2lh5/raw_buffer.py,sha256=LfkVAOZa4cWz227Ef22rKi57Shk7GbENoxUEkxC6IgU,17403
9
9
  daq2lh5/utils.py,sha256=Pc8Oh0ZVBqwwVehyhSJttHnX5tWbOyEZPk-rVg8mb0c,839
10
10
  daq2lh5/buffer_processor/__init__.py,sha256=7k6v_KPximtv7805QnX4-xp_S3vqvqwDfdV3q95oZJo,84
11
11
  daq2lh5/buffer_processor/buffer_processor.py,sha256=GUxpNDbqGLuUEZmXjeratipbzmki12RFNYZkxgMtesg,14483
12
- daq2lh5/buffer_processor/lh5_buffer_processor.py,sha256=einRDLI6EVR-U_TT2GdCZPctFnosJ774eMiUj-ahn6c,8316
12
+ daq2lh5/buffer_processor/lh5_buffer_processor.py,sha256=BEWC0fFg7YU-COcp6Z0W51DLBq5NeGNwSI_97H4TrnQ,8310
13
13
  daq2lh5/compass/__init__.py,sha256=mOXHWp7kRDgNTPQty3E8k2KPSy_vAzjneKfAcCVaPyE,132
14
14
  daq2lh5/compass/compass_config_parser.py,sha256=zeAsOo1dOJPGLL8-zkAcdYRkqt8BodtOPi96n7fWsl4,12300
15
15
  daq2lh5/compass/compass_event_decoder.py,sha256=kiPOaEu8SgLD2wbSPbBahcbTBBRAIw35wtVLBcwPcXY,7386
@@ -17,14 +17,14 @@ daq2lh5/compass/compass_header_decoder.py,sha256=AA-Md2FIT3nD4mXX9CrWvbbfmKiA436
17
17
  daq2lh5/compass/compass_streamer.py,sha256=zSl7IqO0ID0wcixkLE9QVEG3bF9hfGVITVPomCeOFTM,8841
18
18
  daq2lh5/fc/__init__.py,sha256=bB1j6r-bDmylNi0iutQeAJGjsDSjLSoXMqFfXWwfb8I,141
19
19
  daq2lh5/fc/fc_config_decoder.py,sha256=RLRfUOZN0vYbAprqTymP7TGg641IiP9rgCGIOwWVKzU,1996
20
- daq2lh5/fc/fc_event_decoder.py,sha256=JIRsySnxeuY3wmxjJOrTXo6wpelVup8WIvxU-fkPL-A,8131
20
+ daq2lh5/fc/fc_event_decoder.py,sha256=J1kKkd3Qz7SP3y0MGMxbsmWlL9SdVATdYX26bivS_Ho,8130
21
21
  daq2lh5/fc/fc_status_decoder.py,sha256=o_3vTAgYXelZxIsreCYioVYid2mY-wqloYKlxoCqX5Q,3390
22
22
  daq2lh5/fc/fc_streamer.py,sha256=S0imXdVsiyolPvxI1uiBngpC58DporSNZPqx1HeVi5o,5737
23
23
  daq2lh5/llama/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
24
  daq2lh5/llama/llama_base.py,sha256=B-NCBjE_FQE1WxijWi4Z1XBy4rqLHm2XhkC40s7Sdms,290
25
- daq2lh5/llama/llama_event_decoder.py,sha256=D7MRPmE-ucNCjeLJzY3RepmijjkvGHzu3vNV0zkcLho,14489
26
- daq2lh5/llama/llama_header_decoder.py,sha256=xi_BMw4HLQc-PQ5wIZWSHSsBZvrCpS9_G03X7Mr6tGA,6175
27
- daq2lh5/llama/llama_streamer.py,sha256=Bmcj5Bs28KSV4y08TeJcntzUAkqz6HqlSNm7Kffgloc,5203
25
+ daq2lh5/llama/llama_event_decoder.py,sha256=DVULTX7JzlRe23HZYXn79VkoU2_z03o7nxWc33bGK8U,14981
26
+ daq2lh5/llama/llama_header_decoder.py,sha256=r57sn_3eh21xpKfsAOPDmhPW4ULzt_0b7M8HZgmwU_4,7712
27
+ daq2lh5/llama/llama_streamer.py,sha256=lrK73JIXjpogPrkP_tpFQQGSyWxFhivSpU1YEfRMHhQ,5329
28
28
  daq2lh5/orca/__init__.py,sha256=Xf6uOIOzk_QkKH_7VizGlCo3iuiAgLtUE3A07x_HXC0,175
29
29
  daq2lh5/orca/orca_base.py,sha256=-XIolXsHj-1EdewaGxyvJTZvRGZsDyZe-5PzVOd-LFY,1333
30
30
  daq2lh5/orca/orca_digitizers.py,sha256=BsAA3OgQ13YIirDM8pd_xDY3F5FqEY4YjSHviflmov8,20867
@@ -33,10 +33,10 @@ daq2lh5/orca/orca_header.py,sha256=1tDRG8l9Gqu4c0K4BjXBSC5eiLTzY_HaCsgNBiv5EgI,4
33
33
  daq2lh5/orca/orca_header_decoder.py,sha256=ORIIyfx22ybyKc-uyWy5ER49-dl3BGpHdfV8OCDmjIw,1632
34
34
  daq2lh5/orca/orca_packet.py,sha256=nOHuBXsTI1SzTjHZtff0txSQYvkwo4XGx3fpk7XfYj8,2489
35
35
  daq2lh5/orca/orca_run_decoder.py,sha256=3atKXC6mDi8_PK6ICUBBJ-LyaTM8OU31kKWIpmttRr4,2065
36
- daq2lh5/orca/orca_streamer.py,sha256=VbD9PF-rx_Rk-rEy7XECPmgxr6kZSUf0tC7Qbol3Qeg,15693
37
- legend_daq2lh5-1.4.2.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
38
- legend_daq2lh5-1.4.2.dist-info/METADATA,sha256=a7rqLL0JYeSoxoD9lopkQN55eyrSC0Ten8M__syVX9A,3956
39
- legend_daq2lh5-1.4.2.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
40
- legend_daq2lh5-1.4.2.dist-info/entry_points.txt,sha256=R08R4NrHi0ab5MJN_qKqzePVzrLSsw5WpmbiwwduYjw,59
41
- legend_daq2lh5-1.4.2.dist-info/top_level.txt,sha256=MJQVLyLqMgMKBdVfNXFaCKCjHKakAs19VLbC9ctXZ7A,8
42
- legend_daq2lh5-1.4.2.dist-info/RECORD,,
36
+ daq2lh5/orca/orca_streamer.py,sha256=-NxH0oR9ZSd9ljbR-z_GiPx0Bv7aiLdef6nX2vBYJ3k,15820
37
+ legend_daq2lh5-1.5.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
38
+ legend_daq2lh5-1.5.0.dist-info/METADATA,sha256=sf5hY5retNd3CuhkpUmMpxEo4OkOJ1XVDsCi-9qyRG4,3901
39
+ legend_daq2lh5-1.5.0.dist-info/WHEEL,sha256=ck4Vq1_RXyvS4Jt6SI0Vz6fyVs4GWg7AINwpsaGEgPE,91
40
+ legend_daq2lh5-1.5.0.dist-info/entry_points.txt,sha256=R08R4NrHi0ab5MJN_qKqzePVzrLSsw5WpmbiwwduYjw,59
41
+ legend_daq2lh5-1.5.0.dist-info/top_level.txt,sha256=MJQVLyLqMgMKBdVfNXFaCKCjHKakAs19VLbC9ctXZ7A,8
42
+ legend_daq2lh5-1.5.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.2)
2
+ Generator: setuptools (80.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5