Skip to content

Commit 2b5e217

Browse files
authored
Lo L1A - Refactor combin_segemented_packets to handle MET (IMAP-Science-Operations-Center#2415)
* refactored combine segmented packets * added log per packet * removed check for unsegemented packets
1 parent edbc50a commit 2b5e217

3 files changed

Lines changed: 29 additions & 15 deletions

File tree

imap_processing/lo/l0/lo_science.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,10 @@ def parse_events(dataset: xr.Dataset, attr_mgr: ImapCdfAttributes) -> xr.Dataset
241241
pointing_de = 0
242242

243243
for pkt_idx, de_count in enumerate(de_count_values):
244+
logger.info(
245+
f"Parsing packet {pkt_idx} of {len(de_count_values)} "
246+
f"with {de_count} direct events"
247+
)
244248
raw_data = data_values[pkt_idx]
245249

246250
# Parse all direct events in this packet using bytewise operations
@@ -358,13 +362,16 @@ def extract_bits_from_bytes(
358362

359363
def combine_segmented_packets(dataset: xr.Dataset) -> xr.Dataset:
360364
"""
361-
Combine segmented packets.
365+
Combine segmented packets and set MET field.
362366
363367
If the number of bits needed to pack the direct events exceeds the
364368
maximum number of bits allowed in a packet, the direct events
365369
will be spread across multiple packets. This function will combine
366370
the segmented binary into a single binary string for each epoch.
367371
372+
This function also sets the MET field based on segment start times,
373+
even when no segmentation is present.
374+
368375
Parameters
369376
----------
370377
dataset : xr.Dataset
@@ -373,7 +380,7 @@ def combine_segmented_packets(dataset: xr.Dataset) -> xr.Dataset:
373380
Returns
374381
-------
375382
dataset : xr.Dataset
376-
Updated dataset with any segmented direct events combined.
383+
Updated dataset with any segmented direct events combined and MET field set.
377384
"""
378385
seq_flgs = dataset.seq_flgs.values
379386
seq_ctrs = dataset.src_seq_ctr.values
@@ -384,21 +391,19 @@ def combine_segmented_packets(dataset: xr.Dataset) -> xr.Dataset:
384391
# 3 = unsegmented packet
385392
seg_starts = np.nonzero((seq_flgs == 1) | (seq_flgs == 3))[0]
386393
seg_ends = np.nonzero((seq_flgs == 2) | (seq_flgs == 3))[0]
394+
387395
# Swap the epoch dimension for the shcoarse
388396
# the epoch dimension will be reduced to the
389397
# first epoch in each segment
390398
dataset.coords["shcoarse"] = dataset["shcoarse"]
391399
dataset = dataset.swap_dims({"epoch": "shcoarse"})
392400

393401
# Find the valid groups of segmented packets
394-
# returns a list of booleans for each group of segmented packets
395-
# where true means the group is valid
396402
valid_groups = find_valid_groups(seq_ctrs, seg_starts, seg_ends)
397403

398404
# Combine the segmented packets into raw bytes directly
399405
combined_data_list = []
400406
for start, end in zip(seg_starts, seg_ends, strict=False):
401-
# Concatenate raw bytes data directly
402407
combined_bytes = b"".join(dataset["data"].values[start : end + 1])
403408
combined_data_list.append(combined_bytes)
404409

@@ -414,11 +419,11 @@ def combine_segmented_packets(dataset: xr.Dataset) -> xr.Dataset:
414419

415420
# Create the data DataArray with combined raw bytes
416421
dataset["data"] = xr.DataArray(
417-
valid_combined_data, dims=["epoch"], coords={"epoch": dataset.coords["epoch"]}
422+
valid_combined_data,
423+
dims=["epoch"],
424+
coords={"epoch": dataset.coords["epoch"]},
418425
)
419-
# Set met to the first segment start times for the valid groups.
420-
# shcoarse will be retained as a per packet coordinate and met
421-
# is used as the mission elapsed time for each segment
426+
# Set met to the first segment start times for the valid groups
422427
dataset["met"] = xr.DataArray(
423428
dataset["shcoarse"].values[seg_starts][valid_groups], dims="epoch"
424429
)

imap_processing/lo/l1a/lo_l1a.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,9 @@ def lo_l1a(dependency: Path) -> list[xr.Dataset]:
8686
logical_source = "imap_lo_l1a_de"
8787
ds = datasets_by_apid[LoAPID.ILO_SCI_DE]
8888

89-
# Check if we need to combine segmented packets first
90-
needs_combine = not all(ds.seq_flgs.values == 3) # 3 = unsegmented
91-
92-
if needs_combine:
93-
# For segmented packets, combine raw bytes directly
94-
ds = combine_segmented_packets(ds)
89+
# For segmented packets, combine raw bytes directly
90+
# Always call combine_segmented_packets to set MET field
91+
ds = combine_segmented_packets(ds)
9592

9693
ds = parse_events(ds, attr_mgr)
9794
ds = add_dataset_attrs(ds, attr_mgr, logical_source)

imap_processing/tests/lo/test_lo_science.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,18 @@ def test_combine_segmented_packets(segmented_pkts_fake_data):
227227
np.testing.assert_array_equal(dataset["met"].values, np.array([0, 10, 30]))
228228

229229

230+
def test_combin_segmented_packets_only_met(segmented_pkts_fake_data):
231+
segmented_pkts_fake_data["seq_flgs"].values = np.full(10, 3)
232+
dataset = combine_segmented_packets(segmented_pkts_fake_data)
233+
234+
np.testing.assert_array_equal(
235+
dataset["epoch"].values, segmented_pkts_fake_data["epoch"].values
236+
)
237+
np.testing.assert_array_equal(
238+
dataset["met"].values, segmented_pkts_fake_data["shcoarse"].values
239+
)
240+
241+
230242
def test_validate_parse_events(sample_data, attr_mgr):
231243
de_data = sample_data[LoAPID.ILO_SCI_DE]
232244
validation_path = (

0 commit comments

Comments
 (0)