Skip to content

Commit 1714ad7

Browse files
committed
added apid 897
1 parent 9365939 commit 1714ad7

8 files changed

Lines changed: 65 additions & 88 deletions

File tree

imap_processing/cdf/config/imap_ultra_global_cdf_attrs.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,18 @@ imap_ultra_l1a_90sensor-de:
6868
Logical_source: imap_ultra_l1a_90sensor-de
6969
Logical_source_description: IMAP-Ultra Instrument Level-1A Direct Event Data.
7070

71+
imap_ultra_l1a_45sensor-energy-de:
72+
<<: *instrument_base
73+
Data_type: L1A_ENERGY_DE>Level-1A Energy Direct Event
74+
Logical_source: imap_ultra_l1a_45sensor-energy-de
75+
Logical_source_description: IMAP-Ultra Instrument Level-1A Energy Direct Event Data.
76+
77+
imap_ultra_l1a_90sensor-energy-de:
78+
<<: *instrument_base
79+
Data_type: L1A_ENERGY_DE>Level-1A EnergyDirect Event
80+
Logical_source: imap_ultra_l1a_90sensor-energy-de
81+
Logical_source_description: IMAP-Ultra Instrument Level-1A Energy Direct Event Data.
82+
7183
imap_ultra_l1b_45sensor-de:
7284
<<: *instrument_base
7385
Data_type: L1B_45Sensor-DE>Level-1B Direct Events for Ultra45

imap_processing/tests/external_test_data_config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@
6363
("IMAP-Ultra45_r1_L1_V0_shortened.csv", "ultra/data/l1/"),
6464

6565
# Ultra
66+
("ultra45_raw_sc_rawnrgevnt_FM45_UltraFM45_Functional_2024-01-22T0105_20240122T010548.csv", "ultra/data/l0/"),
67+
("ultra45_raw_sc_imgpriority1evnt_FM45_UltraFM45Extra_TV_Tests_2024-01-22T0930_20240122T093008.csv", "ultra/data/l0/"),
6668
("ultra45_raw_sc_ultranrgrates_FM45_UltraFM45_Functional_"
6769
"2024-01-22T0105_20240122T010548.csv", "ultra/data/l0/"),
6870
("imap_ultra_l0_raw_20260924_v001.pkts", "ultra/data/l0/"),

imap_processing/tests/ultra/unit/conftest.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
)
1414
from imap_processing.ultra.l0.ultra_utils import (
1515
ULTRA_AUX,
16+
ULTRA_ENERGY_EVENTS,
1617
ULTRA_ENERGY_RATES,
1718
ULTRA_EVENTS,
1819
ULTRA_RATES,
@@ -172,17 +173,19 @@ def decom_test_data(request, xtce_path):
172173

173174
strategy_dict = {
174175
ULTRA_TOF.apid[0]: process_ultra_tof,
176+
ULTRA_ENERGY_EVENTS.apid[0]: process_ultra_events,
175177
ULTRA_EVENTS.apid[0]: process_ultra_events,
176178
ULTRA_RATES.apid[0]: process_ultra_rates,
177179
ULTRA_ENERGY_RATES.apid[0]: process_ultra_energy_rates,
178180
ULTRA_TOF.apid[1]: process_ultra_tof,
181+
ULTRA_ENERGY_EVENTS.apid[1]: process_ultra_events,
179182
ULTRA_EVENTS.apid[1]: process_ultra_events,
180183
ULTRA_RATES.apid[1]: process_ultra_rates,
181184
ULTRA_ENERGY_RATES.apid[1]: process_ultra_energy_rates,
182185
}
183186

184187
process_function = strategy_dict.get(apid, lambda *args: False)
185-
data_packet_xarray = process_function(datasets_by_apid[apid])
188+
data_packet_xarray = process_function(datasets_by_apid[apid], apid)
186189

187190
return data_packet_xarray
188191

imap_processing/tests/ultra/unit/test_ultra_l1a.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from imap_processing.ultra.l0.decom_ultra import get_event_id
99
from imap_processing.ultra.l0.ultra_utils import (
1010
ULTRA_AUX,
11+
ULTRA_ENERGY_EVENTS,
1112
ULTRA_ENERGY_RATES,
1213
ULTRA_EVENTS,
1314
ULTRA_RATES,
@@ -138,6 +139,20 @@ def test_cdf_events(ccsds_path_theta_0):
138139
)
139140

140141

142+
def test_cdf_energy_events(ccsds_path_functional):
143+
"""Tests that CDF file can be created."""
144+
test_data = ultra_l1a(ccsds_path_functional, apid_input=ULTRA_ENERGY_EVENTS.apid[0])
145+
test_data[0].attrs["Data_version"] = "999"
146+
test_data[0].attrs["Repointing"] = "repoint99999"
147+
test_data_path = write_cdf(test_data[0], istp=True)
148+
149+
assert test_data_path.exists()
150+
assert (
151+
test_data_path.name
152+
== "imap_ultra_l1a_45sensor-energy-de_20240122-repoint99999_v999.cdf"
153+
)
154+
155+
141156
def test_cdf_hk(ccsds_path_theta_0):
142157
"""Tests that CDF file can be created."""
143158
test_data = ultra_l1a(ccsds_path_theta_0, apid_input=869)

imap_processing/ultra/l0/decom_tools.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ def decompress_image(
239239
def read_image_raw_events_binary(
240240
event_data: bytes,
241241
count: int,
242+
field_ranges: dict,
242243
) -> NDArray:
243244
"""
244245
Convert contents of binary string 'EVENTDATA' into values.
@@ -249,22 +250,25 @@ def read_image_raw_events_binary(
249250
Event data.
250251
count : int
251252
Number of events.
253+
field_ranges : dict
254+
Field ranges for the event data.
252255
253256
Returns
254257
-------
255258
event_data : NDArray
256259
Event data.
257260
"""
258261
binary = convert_to_binary_string(event_data)
259-
# 166 bits per event
260-
event_length = 166 if count else 0
262+
length = max(end for _, (_, end) in field_ranges.items())
263+
# bits per event
264+
event_length = length if count else 0
261265
event_data_list = []
262266

263267
# For all packets with event data, parses the binary string
264268
for i in range(count):
265269
start_index = i * event_length
266270
event_binary = binary[start_index : start_index + event_length]
267-
parsed_event = parse_event(event_binary)
271+
parsed_event = parse_event(event_binary, field_ranges)
268272
event_data_list.append(parsed_event)
269273

270274
return np.array(event_data_list)

imap_processing/ultra/l0/decom_ultra.py

Lines changed: 16 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
EVENT_FIELD_RANGES,
2121
RATES_KEYS,
2222
ULTRA_ENERGY_RATES,
23+
ULTRA_ENERGY_EVENTS,
24+
ULTRA_EVENTS,
2325
ULTRA_RATES,
2426
ULTRA_TOF,
2527
)
@@ -139,93 +141,29 @@ def get_event_id(shcoarse: NDArray) -> NDArray:
139141
return np.array(event_ids, dtype=np.int64)
140142

141143

142-
def process_ultra_events(ds: xr.Dataset) -> xr.Dataset:
144+
def process_ultra_events(ds: xr.Dataset, apid: int) -> xr.Dataset:
143145
"""
144146
Unpack and decode Ultra EVENTS packets.
145147
146148
Parameters
147149
----------
148150
ds : xarray.Dataset
149151
Events dataset.
152+
apid : int
153+
APID of the events dataset.
150154
151155
Returns
152156
-------
153157
ds : xarray.Dataset
154158
Dataset containing the decoded and decompressed data.
155159
"""
156-
all_events = []
157-
all_indices = []
158-
159-
attrs = ImapCdfAttributes()
160-
attrs.add_instrument_variable_attrs("ultra", level="l1a")
161-
162-
empty_event = {
163-
field: attrs.get_variable_attributes(field).get(
164-
"FILLVAL", np.iinfo(np.int64).min
165-
)
166-
for field in EVENT_FIELD_RANGES
167-
}
168-
169-
counts = ds["count"].values
170-
eventdata_array = ds["eventdata"].values
171-
172-
for i, count in enumerate(counts):
173-
if count == 0:
174-
all_events.append(empty_event)
175-
all_indices.append(i)
176-
else:
177-
# Here there are multiple images in a single packet,
178-
# so we need to loop through each image and decompress it.
179-
event_data_list = read_image_raw_events_binary(eventdata_array[i], count)
180-
all_events.extend(event_data_list)
181-
# Keep track of how many times does the event occurred at this epoch.
182-
all_indices.extend([i] * count)
160+
if apid in ULTRA_EVENTS.apid:
161+
field_ranges = EVENT_FIELD_RANGES
162+
elif apid in ULTRA_ENERGY_EVENTS.apid:
163+
field_ranges = ENERGY_EVENT_FIELD_RANGES
164+
else:
165+
logger.error(f"APID {apid} not recognized for Ultra events processing.")
183166

184-
# Now we have the event data, we need to create the xarray dataset.
185-
# We cannot append to the existing dataset (sorted_packets)
186-
# because there are multiple events for each epoch.
187-
idx = np.array(all_indices)
188-
189-
# Expand the existing dataset so that it is the same length as the event data.
190-
expanded_data = {
191-
var: ds[var].values[idx] for var in ds.data_vars if var != "eventdata"
192-
}
193-
194-
# Add the event data to the expanded dataset.
195-
for key in EVENT_FIELD_RANGES:
196-
expanded_data[key] = np.array([event[key] for event in all_events])
197-
198-
event_ids = get_event_id(expanded_data["shcoarse"])
199-
200-
coords = {
201-
"epoch": ds["epoch"].values[idx],
202-
"event_id": ("epoch", event_ids),
203-
}
204-
205-
dataset = xr.Dataset(coords=coords)
206-
for key, data in expanded_data.items():
207-
dataset[key] = xr.DataArray(
208-
data,
209-
dims=["epoch"],
210-
)
211-
212-
return dataset
213-
214-
215-
def process_ultra_energy_events(ds: xr.Dataset) -> xr.Dataset:
216-
"""
217-
Unpack and decode Ultra ENERGY EVENTS packets.
218-
219-
Parameters
220-
----------
221-
ds : xarray.Dataset
222-
Events dataset.
223-
224-
Returns
225-
-------
226-
ds : xarray.Dataset
227-
Dataset containing the decoded and decompressed data.
228-
"""
229167
all_events = []
230168
all_indices = []
231169

@@ -236,7 +174,7 @@ def process_ultra_energy_events(ds: xr.Dataset) -> xr.Dataset:
236174
field: attrs.get_variable_attributes(field).get(
237175
"FILLVAL", np.iinfo(np.int64).min
238176
)
239-
for field in ENERGY_EVENT_FIELD_RANGES
177+
for field in field_ranges
240178
}
241179

242180
counts = ds["count"].values
@@ -249,7 +187,9 @@ def process_ultra_energy_events(ds: xr.Dataset) -> xr.Dataset:
249187
else:
250188
# Here there are multiple images in a single packet,
251189
# so we need to loop through each image and decompress it.
252-
event_data_list = read_image_raw_events_binary(eventdata_array[i], count)
190+
event_data_list = read_image_raw_events_binary(
191+
eventdata_array[i], count, field_ranges
192+
)
253193
all_events.extend(event_data_list)
254194
# Keep track of how many times does the event occurred at this epoch.
255195
all_indices.extend([i] * count)
@@ -265,7 +205,7 @@ def process_ultra_energy_events(ds: xr.Dataset) -> xr.Dataset:
265205
}
266206

267207
# Add the event data to the expanded dataset.
268-
for key in EVENT_FIELD_RANGES:
208+
for key in field_ranges:
269209
expanded_data[key] = np.array([event[key] for event in all_events])
270210

271211
event_ids = get_event_id(expanded_data["shcoarse"])

imap_processing/ultra/l0/ultra_utils.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -235,11 +235,11 @@ class PacketProperties(NamedTuple):
235235
# Stop Type
236236
"stop_type": (0, 4),
237237
# Energy/Pulse Height
238-
"energy_ph": (5, 17),
238+
"energy_ph": (4, 16),
239239
# Pulse Width
240-
"pulse_width": (18, 29),
240+
"pulse_width": (16, 27),
241241
# Bin
242-
"bin": (30, 34),
242+
"bin": (27, 33),
243243
}
244244

245245

@@ -359,7 +359,6 @@ class PacketProperties(NamedTuple):
359359
# "discarded_events"
360360
]
361361

362-
363362
ENERGY_RATES_KEYS = [
364363
# SSD0 Energy LED
365364
"ssd0_energy_led",
@@ -386,22 +385,24 @@ class PacketProperties(NamedTuple):
386385
]
387386

388387

389-
def parse_event(event_binary: str) -> dict:
388+
def parse_event(event_binary: str, field_ranges: dict) -> dict:
390389
"""
391390
Parse a binary string representing a single event.
392391
393392
Parameters
394393
----------
395394
event_binary : str
396395
Event binary string.
396+
field_ranges : dict
397+
The field ranges for the event data.
397398
398399
Returns
399400
-------
400401
fields_dict : dict
401402
Dict of the fields for a single event.
402403
"""
403404
fields_dict = {}
404-
for field, (start, end) in EVENT_FIELD_RANGES.items():
405+
for field, (start, end) in field_ranges.items():
405406
field_value = int(event_binary[start:end], 2)
406407
fields_dict[field] = field_value
407408
return fields_dict

imap_processing/ultra/l1a/ultra_l1a.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,13 @@ def ultra_l1a(packet_file: str, apid_input: Optional[int] = None) -> list[xr.Dat
8686
ULTRA_ENERGY_RATES.apid.index(apid)
8787
]
8888
elif apid in ULTRA_EVENTS.apid:
89-
decom_ultra_dataset = process_ultra_events(datasets_by_apid[apid])
89+
decom_ultra_dataset = process_ultra_events(datasets_by_apid[apid], apid)
9090
gattr_key = ULTRA_EVENTS.logical_source[ULTRA_EVENTS.apid.index(apid)]
9191
# Add coordinate attributes
9292
attrs = attr_mgr.get_variable_attributes("event_id")
9393
decom_ultra_dataset.coords["event_id"].attrs.update(attrs)
9494
elif apid in ULTRA_ENERGY_EVENTS.apid:
95-
decom_ultra_dataset = process_ultra_energy_events(datasets_by_apid[apid])
95+
decom_ultra_dataset = process_ultra_events(datasets_by_apid[apid], apid)
9696
gattr_key = ULTRA_ENERGY_EVENTS.logical_source[
9797
ULTRA_ENERGY_EVENTS.apid.index(apid)
9898
]

0 commit comments

Comments
 (0)