Skip to content

Commit 82d376c

Browse files
committed
MNT: Upgrade space_packet_parser to next release
This gets rid of some warnings in the code base and simplifies some instantiation logic.
1 parent 4dea6b5 commit 82d376c

File tree

7 files changed

+167
-57
lines changed

7 files changed

+167
-57
lines changed

imap_processing/decom.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@
55
to decommutate CCSDS packet data using a given XTCE packet definition.
66
"""
77

8+
import logging
89
from pathlib import Path
910

10-
from space_packet_parser import definitions
11+
import space_packet_parser as spp
12+
from space_packet_parser.exceptions import UnrecognizedPacketTypeError
13+
14+
logger = logging.getLogger(__name__)
1115

1216

1317
def decom_packets(packet_file: str | Path, xtce_packet_definition: str | Path) -> list:
@@ -29,8 +33,15 @@ def decom_packets(packet_file: str | Path, xtce_packet_definition: str | Path) -
2933
list
3034
List of all the unpacked data.
3135
"""
32-
packet_definition = definitions.XtcePacketDefinition(xtce_packet_definition)
36+
packet_definition = spp.load_xtce(xtce_packet_definition)
3337

3438
with open(packet_file, "rb") as binary_data:
35-
packet_generator = packet_definition.packet_generator(binary_data)
36-
return list(packet_generator)
39+
packets = []
40+
for binary_packet in spp.ccsds_generator(binary_data):
41+
try:
42+
packets.append(packet_definition.parse_bytes(binary_packet))
43+
except UnrecognizedPacketTypeError as e:
44+
# Log the error and continue processing other packets
45+
logger.debug(e)
46+
continue
47+
return packets

imap_processing/glows/l0/decom_glows.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from enum import Enum
44
from pathlib import Path
55

6-
from space_packet_parser import definitions
6+
import space_packet_parser as spp
77

88
from imap_processing import imap_module_directory
99
from imap_processing.ccsds.ccsds_data import CcsdsData
@@ -49,32 +49,40 @@ def decom_packets(
4949
f"{imap_module_directory}/glows/packet_definitions/GLX_COMBINED.xml"
5050
)
5151

52-
packet_definition = definitions.XtcePacketDefinition(xtce_document)
52+
packet_definition = spp.load_xtce(xtce_document)
5353

5454
histdata = []
5555
dedata = []
5656

5757
filename = packet_file_path.name
5858

5959
with open(packet_file_path, "rb") as binary_data:
60-
glows_packets = packet_definition.packet_generator(binary_data)
61-
62-
for packet in glows_packets:
60+
for binary_packet in spp.ccsds_generator(binary_data):
61+
packet = packet_definition.parse_bytes(binary_packet)
6362
apid = packet["PKT_APID"]
6463
# Do something with the packet data
6564
if apid == GlowsParams.HIST_APID.value:
66-
values = [item.raw_value for item in packet.user_data.values()]
67-
hist_l0 = HistogramL0(
68-
__version__, filename, CcsdsData(packet.header), *values
69-
)
65+
values = [
66+
item.raw_value for i, item in enumerate(packet.values()) if i > 6
67+
]
68+
header = {
69+
key: value
70+
for i, (key, value) in enumerate(packet.items())
71+
if i <= 6
72+
}
73+
hist_l0 = HistogramL0(__version__, filename, CcsdsData(header), *values)
7074
histdata.append(hist_l0)
7175

7276
if apid == GlowsParams.DE_APID.value:
73-
values = [item.raw_value for item in packet.user_data.values()]
74-
75-
de_l0 = DirectEventL0(
76-
__version__, filename, CcsdsData(packet.header), *values
77-
)
77+
values = [
78+
item.raw_value for i, item in enumerate(packet.values()) if i > 6
79+
]
80+
header = {
81+
key: value
82+
for i, (key, value) in enumerate(packet.items())
83+
if i <= 6
84+
}
85+
de_l0 = DirectEventL0(__version__, filename, CcsdsData(header), *values)
7886
dedata.append(de_l0)
7987

8088
return histdata, dedata

imap_processing/idex/idex_l1a.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ class RawDustEvent:
288288
289289
Parameters
290290
----------
291-
header_packet : space_packet_parser.packets.CCSDSPacket
291+
header_packet : space_packet_parser.SpacePacket
292292
The FPGA metadata event header.
293293
294294
Attributes
@@ -340,7 +340,7 @@ class RawDustEvent:
340340
MAX_HIGH_BLOCKS = 16
341341
MAX_LOW_BLOCKS = 64
342342

343-
def __init__(self, header_packet: space_packet_parser.packets.CCSDSPacket) -> None:
343+
def __init__(self, header_packet: space_packet_parser.SpacePacket) -> None:
344344
"""
345345
Initialize a raw dust event, with an FPGA Header Packet from IDEX.
346346
@@ -352,7 +352,7 @@ def __init__(self, header_packet: space_packet_parser.packets.CCSDSPacket) -> No
352352
353353
Parameters
354354
----------
355-
header_packet : space_packet_parser.packets.CCSDSPacket
355+
header_packet : space_packet_parser.SpacePacket
356356
The FPGA metadata event header.
357357
"""
358358
# Calculate the impact time in seconds since epoch
@@ -371,8 +371,8 @@ def __init__(self, header_packet: space_packet_parser.packets.CCSDSPacket) -> No
371371
# Iterate through every telemetry item not in the header and pull out the values
372372
self.telemetry_items = {
373373
key.lower(): val
374-
for key, val in header_packet.items()
375-
if key not in header_packet.header.keys()
374+
for i, (key, val) in enumerate(header_packet.items())
375+
if i > 6 # Skip first 7 header items
376376
}
377377

378378
logger.debug(
@@ -420,7 +420,7 @@ def _append_raw_data(self, scitype: Scitype, bits: str) -> None:
420420
logger.warning("Unknown science type received: [%s]", scitype)
421421

422422
def _set_sample_trigger_times(
423-
self, packet: space_packet_parser.packets.CCSDSPacket
423+
self, packet: space_packet_parser.SpacePacket
424424
) -> None:
425425
"""
426426
Calculate the actual sample trigger time.
@@ -430,7 +430,7 @@ def _set_sample_trigger_times(
430430
431431
Parameters
432432
----------
433-
packet : space_packet_parser.packets.CCSDSPacket
433+
packet : space_packet_parser.SpacePacket
434434
The IDEX FPGA header packet info.
435435
436436
Notes
@@ -590,15 +590,13 @@ def _calc_high_sample_resolution(self, num_samples: int) -> npt.NDArray:
590590
)
591591
return time_high_sample_rate_data
592592

593-
def _populate_bit_strings(
594-
self, packet: space_packet_parser.packets.CCSDSPacket
595-
) -> None:
593+
def _populate_bit_strings(self, packet: space_packet_parser.SpacePacket) -> None:
596594
"""
597595
Parse IDEX data packets to populate bit strings.
598596
599597
Parameters
600598
----------
601-
packet : space_packet_parser.packets.CCSDSPacket
599+
packet : space_packet_parser.SpacePacket
602600
A single science data packet for one of the 6.
603601
IDEX observables.
604602
"""

imap_processing/mag/l0/decom_mag.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
from pathlib import Path
99

1010
import numpy as np
11+
import space_packet_parser as spp
1112
import xarray as xr
12-
from space_packet_parser import definitions
1313

1414
from imap_processing import imap_module_directory
1515
from imap_processing.ccsds.ccsds_data import CcsdsData
@@ -41,20 +41,26 @@ def decom_packets(packet_file_path: str | Path) -> dict[str, list[MagL0]]:
4141
f"{imap_module_directory}/mag/packet_definitions/MAG_SCI_COMBINED.xml"
4242
)
4343

44-
packet_definition = definitions.XtcePacketDefinition(xtce_document)
44+
packet_definition = spp.load_xtce(xtce_document)
4545

4646
# Store in a dict for de-duplication. Only the keys are returned as a list.
4747
norm_dict: dict[MagL0, None] = {}
4848
burst_dict: dict[MagL0, None] = {}
4949

5050
with open(packet_file_path, "rb") as binary_data:
51-
mag_packets = packet_definition.packet_generator(binary_data)
52-
53-
for packet in mag_packets:
51+
for binary_packet in spp.ccsds_generator(binary_data):
52+
packet = packet_definition.parse_bytes(binary_packet)
5453
apid = packet["PKT_APID"]
5554
if apid in (Mode.BURST, Mode.NORMAL):
56-
values = [item.raw_value for item in packet.user_data.values()]
57-
mag_l0 = MagL0(CcsdsData(packet.header), *values)
55+
values = [
56+
item.raw_value for i, item in enumerate(packet.values()) if i > 6
57+
]
58+
header = {
59+
key: value
60+
for i, (key, value) in enumerate(packet.items())
61+
if i <= 6
62+
}
63+
mag_l0 = MagL0(CcsdsData(header), *values)
5864
if apid == Mode.NORMAL:
5965
if mag_l0 not in norm_dict:
6066
norm_dict[mag_l0] = None

imap_processing/utils.py

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66

77
import numpy as np
88
import pandas as pd
9+
import space_packet_parser as spp
910
import xarray as xr
10-
from space_packet_parser import definitions, encodings, parameters
11+
from space_packet_parser.exceptions import UnrecognizedPacketTypeError
12+
from space_packet_parser.xtce import definitions, encodings, parameter_types
1113

1214
from imap_processing.spice.time import met_to_ttj2000ns
1315

@@ -158,11 +160,11 @@ def _get_minimum_numpy_datatype( # noqa: PLR0912 - Too many branches
158160
datatype : str
159161
The minimum datatype.
160162
"""
161-
data_encoding = definition.named_parameters[name].parameter_type.encoding
163+
data_encoding = definition.parameters[name].parameter_type.encoding
162164

163165
if use_derived_value and isinstance(
164-
definition.named_parameters[name].parameter_type,
165-
parameters.EnumeratedParameterType,
166+
definition.parameters[name].parameter_type,
167+
parameter_types.EnumeratedParameterType,
166168
):
167169
# We don't have a way of knowing what is enumerated,
168170
# let numpy infer the datatype
@@ -254,11 +256,18 @@ def packet_file_to_datasets(
254256
variable_mapping: dict[int, set] = dict()
255257

256258
# Set up the parser from the input packet definition
257-
packet_definition = definitions.XtcePacketDefinition(xtce_packet_definition)
259+
packet_definition = spp.load_xtce(xtce_packet_definition)
258260

259261
with open(packet_file, "rb") as binary_data:
260-
packet_generator = packet_definition.packet_generator(binary_data)
261-
for packet in packet_generator:
262+
for binary_packet in spp.ccsds_generator(binary_data):
263+
try:
264+
packet = packet_definition.parse_bytes(binary_packet)
265+
except UnrecognizedPacketTypeError as e:
266+
# NOTE: Not all of our definitions have all of the APIDs
267+
# we may encounter, so we only want to process ones
268+
# we can actual parse.
269+
logger.debug(e)
270+
continue
262271
apid = packet["PKT_APID"]
263272
if apid not in data_dict:
264273
# This is the first packet for this APID
@@ -274,10 +283,7 @@ def packet_file_to_datasets(
274283
f"got: {packet.keys()}"
275284
)
276285

277-
# TODO: Do we want to give an option to remove the header content?
278-
packet_content = packet.user_data | packet.header
279-
280-
for key, value in packet_content.items():
286+
for key, value in packet.items():
281287
val = value if use_derived_value else value.raw_value
282288
data_dict[apid][key].append(val)
283289
if key not in datatype_mapping[apid]:
@@ -289,8 +295,15 @@ def packet_file_to_datasets(
289295
dataset_by_apid = {}
290296

291297
for apid, data in data_dict.items():
292-
# The time key is always the first key in the data dictionary on IMAP
293-
time_key = next(iter(data.keys()))
298+
# The time key is the secondary header, right after the primary header
299+
# in the data dictionary on IMAP (8th key overall)
300+
try:
301+
time_key = list(data.keys())[7]
302+
except IndexError:
303+
logger.debug(
304+
f"Could not determine time key for APID {apid}, skipping dataset."
305+
)
306+
continue
294307
# Convert to J2000 time and use that as our primary dimension
295308
time_data = met_to_ttj2000ns(data[time_key])
296309
ds = xr.Dataset(

0 commit comments

Comments
 (0)