Skip to content

Commit 88244c9

Browse files
authored
IDEX l1a event messages (#2870)
* write out all event messages
1 parent 4e1b2d2 commit 88244c9

11 files changed

Lines changed: 1702 additions & 99 deletions

imap_processing/cdf/config/imap_idex_global_cdf_attrs.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ imap_idex_l1a_sci:
1515
Logical_source: imap_idex_l1a_sci-1week
1616
Logical_source_description: IMAP Mission IDEX Instrument Level-1A Weekly Data.
1717

18-
imap_idex_l1a_evt:
18+
imap_idex_l1a_msg:
1919
<<: *instrument_base
20-
Data_type: L1A_EVT>Level-1A Event Message Data
21-
Logical_source: imap_idex_l1a_evt
20+
Data_type: L1A_MSG>Level-1A Event Message Data
21+
Logical_source: imap_idex_l1a_msg
2222
Logical_source_description: IMAP Mission IDEX Instrument Level-1A Event Message Data.
2323

2424
imap_idex_l1a_catlst:
@@ -33,10 +33,10 @@ imap_idex_l1b_sci:
3333
Logical_source: imap_idex_l1b_sci-1week
3434
Logical_source_description: IMAP Mission IDEX Instrument Level-1B Weekly Data.
3535

36-
imap_idex_l1b_evt:
36+
imap_idex_l1b_msg:
3737
<<: *instrument_base
38-
Data_type: L1B_EVT>Level-1B Event Message Data
39-
Logical_source: imap_idex_l1b_evt
38+
Data_type: L1B_MSG>Level-1B Event Message Data
39+
Logical_source: imap_idex_l1b_msg
4040
Logical_source_description: IMAP Mission IDEX Instrument Level-1B Event Message Data.
4141

4242
imap_idex_l1b_catlst:

imap_processing/cdf/config/imap_idex_l1a_variable_attrs.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,12 @@ shfine:
208208
LABLAXIS: Packet Generation Time (Fine)
209209
UNITS: seconds
210210

211+
messages:
212+
<<: *string_base
213+
CATDESC: Rendered IDEX event message text
214+
FIELDNAM: Event message text
215+
FORMAT: A160
216+
211217
checksum:
212218
<<: *trigger_base
213219
CATDESC: CRC 16 Checksum

imap_processing/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1081,7 +1081,7 @@ def do_processing(
10811081
sci_dependencies = [load_cdf(f) for f in sci_files]
10821082
# sort science files by the first epoch value
10831083
sci_dependencies.sort(key=lambda ds: ds["epoch"].values[0])
1084-
hk_files = dependencies.get_file_paths(source="idex", descriptor="evt")
1084+
hk_files = dependencies.get_file_paths(source="idex", descriptor="msg")
10851085
# Remove duplicate housekeeping files
10861086
hk_dependencies = [load_cdf(dep) for dep in list(set(hk_files))]
10871087
# sort housekeeping files by the first epoch value
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
"""Helper functions for decoding event messages."""
2+
3+
import re
4+
5+
# Regex to match spaces where we need to embed params in the event message templates,
6+
# e.g. {p0}, {p1+2}, {p3:dict}, {p4+1|dict}
7+
EMBEDDED_PARAM_RE = re.compile(r"\{p(\d+)(?:\+(\d+))?(?::[\w]+)?(?:\|(\w+))?\}")
8+
9+
10+
def render_event_template(
11+
event_description_template: str, params_bytes: list, msg_json_data: dict
12+
) -> str:
13+
"""
14+
Produce an event message string by replacing placeholders with parameter values.
15+
16+
Example template:
17+
"Event {p0} occurred with value {p1+2:dictName}"
18+
19+
This would replace {p0} with the hex value of params[0], and replace {p1+2:dictName}
20+
with the combined hex value of params[1] and params[2] (treated as big-endian bytes)
21+
looked up in the dictionary named "dictName" for a human-readable string, or
22+
rendered as hex if not found in the dictionary.
23+
24+
Parameters
25+
----------
26+
event_description_template : str
27+
The event message template containing placeholders like {p0}, {p1+2},
28+
{p3:dict}, {p4+1|dict}.
29+
params_bytes : list
30+
The list of parameter values to substitute into the template.
31+
msg_json_data : dict
32+
Mapping of parameter values to human-readable strings for decoding event
33+
messages.
34+
35+
Returns
36+
-------
37+
str
38+
The rendered event message with placeholders replaced by parameter values.
39+
"""
40+
41+
def replace(m: re.Match[str]) -> str:
42+
"""
43+
Replace a single placeholder match with the corresponding parameter value.
44+
45+
Parameters
46+
----------
47+
m : re.Match[str]
48+
A regex match object for a placeholder in the template.
49+
50+
Returns
51+
-------
52+
str
53+
The string to replace the placeholder with.
54+
"""
55+
# We are parsing the placeholder value here to determine which parameter
56+
# to substitute and how to format them.
57+
# group one is the parameter index e.g. p0-3
58+
idx = int(m.group(1))
59+
# group two is the optional byte length e.g. +2 (so we know how many params
60+
# to combine)
61+
n_bytes = int(m.group(2)) if m.group(2) else 1
62+
# group three is an optional dictionary name to use for decoding this parameter
63+
dict_name = m.group(3)
64+
value = 0
65+
for i in range(n_bytes):
66+
# combine the next n_bytes params into a single integer value, treating
67+
# them as big-endian bytes
68+
value = (value << 8) | (
69+
params_bytes[idx + i] if idx + i < len(params_bytes) else 0
70+
)
71+
# If a dictionary name is provided use it to decode the value, otherwise just
72+
# render as hex.
73+
if dict_name:
74+
resolved = msg_json_data.get(dict_name, {}).get(
75+
value, f"0x{value:0{2 * n_bytes}X}"
76+
)
77+
return f"{dict_name}({resolved})" # wrap with dict name
78+
79+
return f"{value:02x}"
80+
81+
# Replace all placeholders in the template using the replace function defined above.
82+
return EMBEDDED_PARAM_RE.sub(replace, event_description_template)

0 commit comments

Comments
 (0)