imap-processing 0.16.1__py3-none-any.whl → 0.17.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.
Potentially problematic release.
This version of imap-processing might be problematic. Click here for more details.
- imap_processing/_version.py +2 -2
- imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +24 -0
- imap_processing/cdf/config/imap_codice_l1b_variable_attrs.yaml +24 -0
- imap_processing/cdf/config/imap_hi_variable_attrs.yaml +8 -8
- imap_processing/cdf/config/imap_hit_global_cdf_attrs.yaml +1 -1
- imap_processing/cdf/config/imap_hit_l2_variable_attrs.yaml +394 -411
- imap_processing/cdf/config/imap_idex_global_cdf_attrs.yaml +9 -9
- imap_processing/cdf/config/imap_idex_l2b_variable_attrs.yaml +150 -57
- imap_processing/cdf/config/imap_swapi_variable_attrs.yaml +19 -0
- imap_processing/cdf/config/imap_swe_l1b_variable_attrs.yaml +20 -0
- imap_processing/cdf/config/imap_swe_l2_variable_attrs.yaml +39 -0
- imap_processing/cdf/config/imap_ultra_global_cdf_attrs.yaml +108 -0
- imap_processing/cdf/config/imap_ultra_l1a_variable_attrs.yaml +103 -2
- imap_processing/cdf/utils.py +7 -1
- imap_processing/cli.py +14 -8
- imap_processing/codice/codice_l1a.py +89 -30
- imap_processing/hi/hi_l1a.py +4 -4
- imap_processing/hi/hi_l1b.py +2 -2
- imap_processing/hi/packet_definitions/TLM_HI_COMBINED_SCI.xml +218 -38
- imap_processing/hit/hit_utils.py +2 -2
- imap_processing/hit/l0/decom_hit.py +2 -1
- imap_processing/hit/l2/hit_l2.py +2 -1
- imap_processing/ialirt/l0/process_codice.py +4 -34
- imap_processing/idex/idex_constants.py +7 -0
- imap_processing/idex/idex_l2b.py +372 -55
- imap_processing/lo/l0/lo_star_sensor.py +48 -0
- imap_processing/lo/l1a/lo_l1a.py +32 -32
- imap_processing/mag/l0/decom_mag.py +9 -6
- imap_processing/mag/l0/mag_l0_data.py +46 -0
- imap_processing/swapi/l1/swapi_l1.py +12 -2
- imap_processing/swapi/l2/swapi_l2.py +7 -6
- imap_processing/swe/l1b/swe_l1b.py +9 -0
- imap_processing/swe/l2/swe_l2.py +111 -17
- imap_processing/ultra/l0/decom_tools.py +13 -6
- imap_processing/ultra/l0/decom_ultra.py +190 -4
- imap_processing/ultra/l0/ultra_utils.py +184 -3
- imap_processing/ultra/l1a/ultra_l1a.py +52 -4
- imap_processing/ultra/packet_definitions/ULTRA_SCI_COMBINED.xml +3 -3
- imap_processing/utils.py +20 -42
- {imap_processing-0.16.1.dist-info → imap_processing-0.17.0.dist-info}/METADATA +1 -1
- {imap_processing-0.16.1.dist-info → imap_processing-0.17.0.dist-info}/RECORD +44 -45
- imap_processing/lo/l0/data_classes/star_sensor.py +0 -98
- imap_processing/lo/l0/utils/lo_base.py +0 -57
- {imap_processing-0.16.1.dist-info → imap_processing-0.17.0.dist-info}/LICENSE +0 -0
- {imap_processing-0.16.1.dist-info → imap_processing-0.17.0.dist-info}/WHEEL +0 -0
- {imap_processing-0.16.1.dist-info → imap_processing-0.17.0.dist-info}/entry_points.txt +0 -0
|
@@ -15,8 +15,19 @@ from imap_processing.ultra.l0.decom_tools import (
|
|
|
15
15
|
read_image_raw_events_binary,
|
|
16
16
|
)
|
|
17
17
|
from imap_processing.ultra.l0.ultra_utils import (
|
|
18
|
+
CMD_ECHO_MAP,
|
|
19
|
+
ENERGY_EVENT_FIELD_RANGES,
|
|
20
|
+
ENERGY_RATES_KEYS,
|
|
18
21
|
EVENT_FIELD_RANGES,
|
|
19
22
|
RATES_KEYS,
|
|
23
|
+
ULTRA_ENERGY_EVENTS,
|
|
24
|
+
ULTRA_ENERGY_RATES,
|
|
25
|
+
ULTRA_ENERGY_SPECTRA,
|
|
26
|
+
ULTRA_EVENTS,
|
|
27
|
+
ULTRA_PRI_1_EVENTS,
|
|
28
|
+
ULTRA_PRI_2_EVENTS,
|
|
29
|
+
ULTRA_PRI_3_EVENTS,
|
|
30
|
+
ULTRA_PRI_4_EVENTS,
|
|
20
31
|
ULTRA_RATES,
|
|
21
32
|
ULTRA_TOF,
|
|
22
33
|
)
|
|
@@ -136,7 +147,7 @@ def get_event_id(shcoarse: NDArray) -> NDArray:
|
|
|
136
147
|
return np.array(event_ids, dtype=np.int64)
|
|
137
148
|
|
|
138
149
|
|
|
139
|
-
def process_ultra_events(ds: xr.Dataset) -> xr.Dataset:
|
|
150
|
+
def process_ultra_events(ds: xr.Dataset, apid: int) -> xr.Dataset:
|
|
140
151
|
"""
|
|
141
152
|
Unpack and decode Ultra EVENTS packets.
|
|
142
153
|
|
|
@@ -144,12 +155,28 @@ def process_ultra_events(ds: xr.Dataset) -> xr.Dataset:
|
|
|
144
155
|
----------
|
|
145
156
|
ds : xarray.Dataset
|
|
146
157
|
Events dataset.
|
|
158
|
+
apid : int
|
|
159
|
+
APID of the events dataset.
|
|
147
160
|
|
|
148
161
|
Returns
|
|
149
162
|
-------
|
|
150
163
|
ds : xarray.Dataset
|
|
151
164
|
Dataset containing the decoded and decompressed data.
|
|
152
165
|
"""
|
|
166
|
+
all_event_apids = set(
|
|
167
|
+
ULTRA_EVENTS.apid
|
|
168
|
+
+ ULTRA_PRI_1_EVENTS.apid
|
|
169
|
+
+ ULTRA_PRI_2_EVENTS.apid
|
|
170
|
+
+ ULTRA_PRI_3_EVENTS.apid
|
|
171
|
+
+ ULTRA_PRI_4_EVENTS.apid
|
|
172
|
+
)
|
|
173
|
+
if apid in all_event_apids:
|
|
174
|
+
field_ranges = EVENT_FIELD_RANGES
|
|
175
|
+
elif apid in ULTRA_ENERGY_EVENTS.apid:
|
|
176
|
+
field_ranges = ENERGY_EVENT_FIELD_RANGES
|
|
177
|
+
else:
|
|
178
|
+
raise ValueError(f"APID {apid} not recognized for Ultra events processing.")
|
|
179
|
+
|
|
153
180
|
all_events = []
|
|
154
181
|
all_indices = []
|
|
155
182
|
|
|
@@ -160,7 +187,7 @@ def process_ultra_events(ds: xr.Dataset) -> xr.Dataset:
|
|
|
160
187
|
field: attrs.get_variable_attributes(field).get(
|
|
161
188
|
"FILLVAL", np.iinfo(np.int64).min
|
|
162
189
|
)
|
|
163
|
-
for field in
|
|
190
|
+
for field in field_ranges
|
|
164
191
|
}
|
|
165
192
|
|
|
166
193
|
counts = ds["count"].values
|
|
@@ -173,7 +200,9 @@ def process_ultra_events(ds: xr.Dataset) -> xr.Dataset:
|
|
|
173
200
|
else:
|
|
174
201
|
# Here there are multiple images in a single packet,
|
|
175
202
|
# so we need to loop through each image and decompress it.
|
|
176
|
-
event_data_list = read_image_raw_events_binary(
|
|
203
|
+
event_data_list = read_image_raw_events_binary(
|
|
204
|
+
eventdata_array[i], count, field_ranges
|
|
205
|
+
)
|
|
177
206
|
all_events.extend(event_data_list)
|
|
178
207
|
# Keep track of how many times does the event occurred at this epoch.
|
|
179
208
|
all_indices.extend([i] * count)
|
|
@@ -189,7 +218,7 @@ def process_ultra_events(ds: xr.Dataset) -> xr.Dataset:
|
|
|
189
218
|
}
|
|
190
219
|
|
|
191
220
|
# Add the event data to the expanded dataset.
|
|
192
|
-
for key in
|
|
221
|
+
for key in field_ranges:
|
|
193
222
|
expanded_data[key] = np.array([event[key] for event in all_events])
|
|
194
223
|
|
|
195
224
|
event_ids = get_event_id(expanded_data["shcoarse"])
|
|
@@ -242,3 +271,160 @@ def process_ultra_rates(ds: xr.Dataset) -> xr.Dataset:
|
|
|
242
271
|
ds[key] = xr.DataArray(np.array(values), dims=["epoch"])
|
|
243
272
|
|
|
244
273
|
return ds
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def process_ultra_energy_rates(ds: xr.Dataset) -> xr.Dataset:
|
|
277
|
+
"""
|
|
278
|
+
Unpack and decode Ultra ENERGY RATES packets.
|
|
279
|
+
|
|
280
|
+
Parameters
|
|
281
|
+
----------
|
|
282
|
+
ds : xarray.Dataset
|
|
283
|
+
Energy rates dataset.
|
|
284
|
+
|
|
285
|
+
Returns
|
|
286
|
+
-------
|
|
287
|
+
dataset : xarray.Dataset
|
|
288
|
+
Dataset containing the decoded and decompressed data.
|
|
289
|
+
"""
|
|
290
|
+
decom_data = defaultdict(list)
|
|
291
|
+
|
|
292
|
+
for rate in ds["ratedata"]:
|
|
293
|
+
raw_binary_string = convert_to_binary_string(rate.item())
|
|
294
|
+
decompressed_data = decompress_binary(
|
|
295
|
+
raw_binary_string,
|
|
296
|
+
cast(int, ULTRA_ENERGY_RATES.width),
|
|
297
|
+
cast(int, ULTRA_ENERGY_RATES.block),
|
|
298
|
+
cast(int, ULTRA_ENERGY_RATES.len_array),
|
|
299
|
+
cast(int, ULTRA_ENERGY_RATES.mantissa_bit_length),
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
for index in range(cast(int, ULTRA_ENERGY_RATES.len_array)):
|
|
303
|
+
decom_data[ENERGY_RATES_KEYS[index]].append(decompressed_data[index])
|
|
304
|
+
|
|
305
|
+
for key, values in decom_data.items():
|
|
306
|
+
ds[key] = xr.DataArray(np.array(values), dims=["epoch"])
|
|
307
|
+
|
|
308
|
+
return ds
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
def process_ultra_energy_spectra(ds: xr.Dataset) -> xr.Dataset:
|
|
312
|
+
"""
|
|
313
|
+
Unpack and decode Ultra ENERGY SPECTRA packets.
|
|
314
|
+
|
|
315
|
+
Parameters
|
|
316
|
+
----------
|
|
317
|
+
ds : xarray.Dataset
|
|
318
|
+
Energy rates dataset.
|
|
319
|
+
|
|
320
|
+
Returns
|
|
321
|
+
-------
|
|
322
|
+
dataset : xarray.Dataset
|
|
323
|
+
Dataset containing the decoded and decompressed data.
|
|
324
|
+
"""
|
|
325
|
+
energy_spectra = []
|
|
326
|
+
|
|
327
|
+
for rate in ds["compdata"]:
|
|
328
|
+
raw_binary_string = convert_to_binary_string(rate.item())
|
|
329
|
+
decompressed_data = decompress_binary(
|
|
330
|
+
raw_binary_string,
|
|
331
|
+
cast(int, ULTRA_ENERGY_SPECTRA.width),
|
|
332
|
+
cast(int, ULTRA_ENERGY_SPECTRA.block),
|
|
333
|
+
cast(int, ULTRA_ENERGY_SPECTRA.len_array),
|
|
334
|
+
cast(int, ULTRA_ENERGY_SPECTRA.mantissa_bit_length),
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
energy_spectra.append(decompressed_data)
|
|
338
|
+
|
|
339
|
+
energy_spectra = np.array(energy_spectra)
|
|
340
|
+
|
|
341
|
+
ds["ssd_sum"] = xr.DataArray(
|
|
342
|
+
energy_spectra,
|
|
343
|
+
dims=["epoch", "energyspectrastate"],
|
|
344
|
+
coords={"epoch": ds["epoch"], "energyspectrastate": np.arange(16)},
|
|
345
|
+
)
|
|
346
|
+
|
|
347
|
+
return ds
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
def process_ultra_cmd_echo(ds: xr.Dataset) -> xr.Dataset:
|
|
351
|
+
"""
|
|
352
|
+
Unpack and decode Ultra CMD ECHO packets.
|
|
353
|
+
|
|
354
|
+
Parameters
|
|
355
|
+
----------
|
|
356
|
+
ds : xarray.Dataset
|
|
357
|
+
Energy rates dataset.
|
|
358
|
+
|
|
359
|
+
Returns
|
|
360
|
+
-------
|
|
361
|
+
dataset : xarray.Dataset
|
|
362
|
+
Dataset containing the decoded and decompressed data.
|
|
363
|
+
"""
|
|
364
|
+
descriptions = []
|
|
365
|
+
|
|
366
|
+
fill = 0xFF
|
|
367
|
+
max_len = 10
|
|
368
|
+
arg_array = np.full((len(ds["epoch"]), max_len), fill, dtype=np.uint8)
|
|
369
|
+
|
|
370
|
+
for i, arg in enumerate(ds["args"].values):
|
|
371
|
+
# Converts to the numeric representations of each byte.
|
|
372
|
+
arg_array[i, : len(arg)] = np.frombuffer(arg, dtype=np.uint8)
|
|
373
|
+
|
|
374
|
+
# Default to "FILL" for unlisted values
|
|
375
|
+
for result in ds["result"].values:
|
|
376
|
+
descriptions.append(CMD_ECHO_MAP.get(result, "FILL"))
|
|
377
|
+
|
|
378
|
+
ds["arguments"] = xr.DataArray(
|
|
379
|
+
arg_array,
|
|
380
|
+
dims=["epoch", "arg_index"],
|
|
381
|
+
coords={
|
|
382
|
+
"epoch": ds["epoch"],
|
|
383
|
+
"arg_index": np.arange(10),
|
|
384
|
+
},
|
|
385
|
+
)
|
|
386
|
+
|
|
387
|
+
ds["result_description"] = xr.DataArray(
|
|
388
|
+
np.array(descriptions),
|
|
389
|
+
dims=["epoch"],
|
|
390
|
+
coords={"epoch": ds["epoch"]},
|
|
391
|
+
)
|
|
392
|
+
|
|
393
|
+
ds = ds.drop_vars(["args", "result"])
|
|
394
|
+
|
|
395
|
+
return ds
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
def process_ultra_macros_checksum(ds: xr.Dataset) -> xr.Dataset:
|
|
399
|
+
"""
|
|
400
|
+
Unpack and decode Ultra MACROS CHECKSUM packets.
|
|
401
|
+
|
|
402
|
+
Parameters
|
|
403
|
+
----------
|
|
404
|
+
ds : xarray.Dataset
|
|
405
|
+
Dataset containing macro checksums.
|
|
406
|
+
|
|
407
|
+
Returns
|
|
408
|
+
-------
|
|
409
|
+
dataset : xarray.Dataset
|
|
410
|
+
Dataset with unpacked and decoded checksum values.
|
|
411
|
+
"""
|
|
412
|
+
# big endian uint16
|
|
413
|
+
packed_dtype = np.dtype(">u2")
|
|
414
|
+
fill = np.iinfo(packed_dtype).max
|
|
415
|
+
n_epochs = ds.sizes["epoch"]
|
|
416
|
+
max_len = 256
|
|
417
|
+
|
|
418
|
+
checksum_array = np.full((n_epochs, max_len), fill)
|
|
419
|
+
|
|
420
|
+
for i, checksum in enumerate(ds["checksums"]):
|
|
421
|
+
checksum_array[i, :] = np.frombuffer(checksum.item(), dtype=packed_dtype)
|
|
422
|
+
|
|
423
|
+
ds["checksum"] = xr.DataArray(
|
|
424
|
+
checksum_array,
|
|
425
|
+
dims=["epoch", "checksum_index"],
|
|
426
|
+
coords={"epoch": ds["epoch"], "checksum_index": np.arange(max_len)},
|
|
427
|
+
)
|
|
428
|
+
ds = ds.drop_vars(["checksums"])
|
|
429
|
+
|
|
430
|
+
return ds
|
|
@@ -40,6 +40,30 @@ ULTRA_RATES = PacketProperties(
|
|
|
40
40
|
len_array=48,
|
|
41
41
|
mantissa_bit_length=12,
|
|
42
42
|
)
|
|
43
|
+
ULTRA_ENERGY_RATES = PacketProperties(
|
|
44
|
+
apid=[882, 946],
|
|
45
|
+
logical_source=[
|
|
46
|
+
"imap_ultra_l1a_45sensor-energy-rates",
|
|
47
|
+
"imap_ultra_l1a_90sensor-energy-rates",
|
|
48
|
+
],
|
|
49
|
+
addition_to_logical_desc="Energy Rates",
|
|
50
|
+
width=5,
|
|
51
|
+
block=16,
|
|
52
|
+
len_array=11,
|
|
53
|
+
mantissa_bit_length=12,
|
|
54
|
+
)
|
|
55
|
+
ULTRA_ENERGY_SPECTRA = PacketProperties(
|
|
56
|
+
apid=[889, 953],
|
|
57
|
+
logical_source=[
|
|
58
|
+
"imap_ultra_l1a_45sensor-energy-spectra",
|
|
59
|
+
"imap_ultra_l1a_90sensor-energy-spectra",
|
|
60
|
+
],
|
|
61
|
+
addition_to_logical_desc="Energy Spectra",
|
|
62
|
+
width=4,
|
|
63
|
+
block=16,
|
|
64
|
+
len_array=1,
|
|
65
|
+
mantissa_bit_length=5,
|
|
66
|
+
)
|
|
43
67
|
ULTRA_TOF = PacketProperties(
|
|
44
68
|
apid=[883, 947],
|
|
45
69
|
logical_source=[
|
|
@@ -61,20 +85,96 @@ ULTRA_EVENTS = PacketProperties(
|
|
|
61
85
|
len_array=None,
|
|
62
86
|
mantissa_bit_length=None,
|
|
63
87
|
)
|
|
88
|
+
ULTRA_ENERGY_EVENTS = PacketProperties(
|
|
89
|
+
apid=[897, 961],
|
|
90
|
+
logical_source=[
|
|
91
|
+
"imap_ultra_l1a_45sensor-energy-de",
|
|
92
|
+
"imap_ultra_l1a_90sensor-energy-de",
|
|
93
|
+
],
|
|
94
|
+
addition_to_logical_desc="Single Energy Events",
|
|
95
|
+
width=None,
|
|
96
|
+
block=None,
|
|
97
|
+
len_array=None,
|
|
98
|
+
mantissa_bit_length=None,
|
|
99
|
+
)
|
|
100
|
+
ULTRA_MACROS_CHECKSUM = PacketProperties(
|
|
101
|
+
apid=[872, 936],
|
|
102
|
+
logical_source=[
|
|
103
|
+
"imap_ultra_l1a_45sensor-macroschecksum",
|
|
104
|
+
"imap_ultra_l1a_90sensor-macroschecksum",
|
|
105
|
+
],
|
|
106
|
+
addition_to_logical_desc="Macros Checksum",
|
|
107
|
+
width=None,
|
|
108
|
+
block=None,
|
|
109
|
+
len_array=None,
|
|
110
|
+
mantissa_bit_length=None,
|
|
111
|
+
)
|
|
112
|
+
ULTRA_PRI_1_EVENTS = PacketProperties(
|
|
113
|
+
apid=[898, 962],
|
|
114
|
+
logical_source=[
|
|
115
|
+
"imap_ultra_l1a_45sensor-priority-1-de",
|
|
116
|
+
"imap_ultra_l1a_90sensor-priority-1-de",
|
|
117
|
+
],
|
|
118
|
+
addition_to_logical_desc="Primary 1 Events",
|
|
119
|
+
width=None,
|
|
120
|
+
block=None,
|
|
121
|
+
len_array=None,
|
|
122
|
+
mantissa_bit_length=None,
|
|
123
|
+
)
|
|
124
|
+
ULTRA_PRI_2_EVENTS = PacketProperties(
|
|
125
|
+
apid=[899, 963],
|
|
126
|
+
logical_source=[
|
|
127
|
+
"imap_ultra_l1a_45sensor-priority-2-de",
|
|
128
|
+
"imap_ultra_l1a_90sensor-priority-2-de",
|
|
129
|
+
],
|
|
130
|
+
addition_to_logical_desc="Primary 2 Events",
|
|
131
|
+
width=None,
|
|
132
|
+
block=None,
|
|
133
|
+
len_array=None,
|
|
134
|
+
mantissa_bit_length=None,
|
|
135
|
+
)
|
|
136
|
+
ULTRA_PRI_3_EVENTS = PacketProperties(
|
|
137
|
+
apid=[900, 964],
|
|
138
|
+
logical_source=[
|
|
139
|
+
"imap_ultra_l1a_45sensor-priority-3-de",
|
|
140
|
+
"imap_ultra_l1a_90sensor-priority-3-de",
|
|
141
|
+
],
|
|
142
|
+
addition_to_logical_desc="Primary 3 Events",
|
|
143
|
+
width=None,
|
|
144
|
+
block=None,
|
|
145
|
+
len_array=None,
|
|
146
|
+
mantissa_bit_length=None,
|
|
147
|
+
)
|
|
148
|
+
ULTRA_PRI_4_EVENTS = PacketProperties(
|
|
149
|
+
apid=[901, 965],
|
|
150
|
+
logical_source=[
|
|
151
|
+
"imap_ultra_l1a_45sensor-priority-4-de",
|
|
152
|
+
"imap_ultra_l1a_90sensor-priority-4-de",
|
|
153
|
+
],
|
|
154
|
+
addition_to_logical_desc="Primary 4 Events",
|
|
155
|
+
width=None,
|
|
156
|
+
block=None,
|
|
157
|
+
len_array=None,
|
|
158
|
+
mantissa_bit_length=None,
|
|
159
|
+
)
|
|
64
160
|
ULTRA_HK = PacketProperties(
|
|
65
161
|
apid=[
|
|
66
162
|
866,
|
|
67
163
|
867,
|
|
164
|
+
868,
|
|
68
165
|
869,
|
|
69
166
|
870,
|
|
167
|
+
871,
|
|
70
168
|
873,
|
|
71
169
|
874,
|
|
72
170
|
876,
|
|
73
171
|
877,
|
|
74
172
|
930,
|
|
75
173
|
931,
|
|
174
|
+
932,
|
|
76
175
|
933,
|
|
77
176
|
934,
|
|
177
|
+
935,
|
|
78
178
|
937,
|
|
79
179
|
938,
|
|
80
180
|
940,
|
|
@@ -83,16 +183,20 @@ ULTRA_HK = PacketProperties(
|
|
|
83
183
|
logical_source=[
|
|
84
184
|
"imap_ultra_l1a_45sensor-alarm",
|
|
85
185
|
"imap_ultra_l1a_45sensor-memchecksum",
|
|
186
|
+
"imap_ultra_l1a_45sensor-memdump",
|
|
86
187
|
"imap_ultra_l1a_45sensor-status",
|
|
87
188
|
"imap_ultra_l1a_45sensor-bootstatus",
|
|
189
|
+
"imap_ultra_l1a_45sensor-macrodump",
|
|
88
190
|
"imap_ultra_l1a_45sensor-monitorlimits",
|
|
89
191
|
"imap_ultra_l1a_45sensor-params",
|
|
90
192
|
"imap_ultra_l1a_45sensor-scauto",
|
|
91
193
|
"imap_ultra_l1a_45sensor-imgparams",
|
|
92
194
|
"imap_ultra_l1a_90sensor-alarm",
|
|
93
195
|
"imap_ultra_l1a_90sensor-memchecksum",
|
|
196
|
+
"imap_ultra_l1a_90sensor-memdump",
|
|
94
197
|
"imap_ultra_l1a_90sensor-status",
|
|
95
198
|
"imap_ultra_l1a_90sensor-bootstatus",
|
|
199
|
+
"imap_ultra_l1a_90sensor-macrodump",
|
|
96
200
|
"imap_ultra_l1a_90sensor-monitorlimits",
|
|
97
201
|
"imap_ultra_l1a_90sensor-params",
|
|
98
202
|
"imap_ultra_l1a_90sensor-scauto",
|
|
@@ -119,7 +223,21 @@ ULTRA_CMD_TEXT = PacketProperties(
|
|
|
119
223
|
len_array=None,
|
|
120
224
|
mantissa_bit_length=None,
|
|
121
225
|
)
|
|
122
|
-
|
|
226
|
+
ULTRA_CMD_ECHO = PacketProperties(
|
|
227
|
+
apid=[
|
|
228
|
+
865,
|
|
229
|
+
929,
|
|
230
|
+
],
|
|
231
|
+
logical_source=[
|
|
232
|
+
"imap_ultra_l1a_45sensor-cmdecho",
|
|
233
|
+
"imap_ultra_l1a_90sensor-cmdecho",
|
|
234
|
+
],
|
|
235
|
+
addition_to_logical_desc="Command echo",
|
|
236
|
+
width=None,
|
|
237
|
+
block=None,
|
|
238
|
+
len_array=None,
|
|
239
|
+
mantissa_bit_length=None,
|
|
240
|
+
)
|
|
123
241
|
|
|
124
242
|
# Module-level constant for event field ranges
|
|
125
243
|
EVENT_FIELD_RANGES = {
|
|
@@ -206,6 +324,20 @@ EVENT_FIELD_RANGES = {
|
|
|
206
324
|
"phase_angle": (156, 166),
|
|
207
325
|
}
|
|
208
326
|
|
|
327
|
+
# Module-level constant for event field ranges
|
|
328
|
+
ENERGY_EVENT_FIELD_RANGES = {
|
|
329
|
+
# Stop Type
|
|
330
|
+
"stop_type": (0, 4),
|
|
331
|
+
# Energy/Pulse Height
|
|
332
|
+
"energy_ph": (4, 16),
|
|
333
|
+
# Pulse Width
|
|
334
|
+
"pulse_width": (16, 27),
|
|
335
|
+
# Bin
|
|
336
|
+
"bin": (27, 31),
|
|
337
|
+
# Phase Angle
|
|
338
|
+
"phase_angle": (31, 41),
|
|
339
|
+
}
|
|
340
|
+
|
|
209
341
|
|
|
210
342
|
RATES_KEYS = [
|
|
211
343
|
# Start Right Full Constant Fraction Discriminator (CFD) Pulses
|
|
@@ -323,8 +455,55 @@ RATES_KEYS = [
|
|
|
323
455
|
# "discarded_events"
|
|
324
456
|
]
|
|
325
457
|
|
|
458
|
+
ENERGY_RATES_KEYS = [
|
|
459
|
+
# SSD0 Energy LED
|
|
460
|
+
"ssd0_energy_led",
|
|
461
|
+
# SSD1 Energy LED
|
|
462
|
+
"ssd1_energy_led",
|
|
463
|
+
# SSD2 Energy LED
|
|
464
|
+
"ssd2_energy_led",
|
|
465
|
+
# SSD3 Energy LED
|
|
466
|
+
"ssd3_energy_led",
|
|
467
|
+
# SSD4 Energy LED
|
|
468
|
+
"ssd4_energy_led",
|
|
469
|
+
# SSD5 Energy LED
|
|
470
|
+
"ssd5_energy_led",
|
|
471
|
+
# SSD6 Energy LED
|
|
472
|
+
"ssd6_energy_led",
|
|
473
|
+
# SSD7 Energy LED
|
|
474
|
+
"ssd7_energy_led",
|
|
475
|
+
# Event Active Time
|
|
476
|
+
"event_active_time",
|
|
477
|
+
# FIFO Valid Events
|
|
478
|
+
"fifo_valid_events",
|
|
479
|
+
# Processed Events
|
|
480
|
+
"processed_events",
|
|
481
|
+
]
|
|
482
|
+
|
|
483
|
+
ENERGY_SPECTRA_KEYS = [
|
|
484
|
+
# Sum of the 8 SSDs
|
|
485
|
+
"ssd_sum",
|
|
486
|
+
]
|
|
487
|
+
|
|
488
|
+
# Map of command echo fields
|
|
489
|
+
CMD_ECHO_MAP = {
|
|
490
|
+
0x00: "No error command executed",
|
|
491
|
+
0x01: "No error command appended to macro",
|
|
492
|
+
0x02: "Unknown opcode or insufficient arguments",
|
|
493
|
+
0x03: "Bad argument",
|
|
494
|
+
0x04: "Cannot run macro; no contexts",
|
|
495
|
+
0x05: "Cannot be used outside of a macro",
|
|
496
|
+
0x06: "Macro compilation error",
|
|
497
|
+
0x07: "Macro not killed (not running?)",
|
|
498
|
+
0x08: "Cannot boot program; bad checksum",
|
|
499
|
+
0x09: "Cannot restore macros; bad checksum",
|
|
500
|
+
0x0A: "Cannot load memory; write disabled",
|
|
501
|
+
0x10: "HV goal greater than limit",
|
|
502
|
+
0x11: "Shutter deployment disabled",
|
|
503
|
+
}
|
|
504
|
+
|
|
326
505
|
|
|
327
|
-
def parse_event(event_binary: str) -> dict:
|
|
506
|
+
def parse_event(event_binary: str, field_ranges: dict) -> dict:
|
|
328
507
|
"""
|
|
329
508
|
Parse a binary string representing a single event.
|
|
330
509
|
|
|
@@ -332,6 +511,8 @@ def parse_event(event_binary: str) -> dict:
|
|
|
332
511
|
----------
|
|
333
512
|
event_binary : str
|
|
334
513
|
Event binary string.
|
|
514
|
+
field_ranges : dict
|
|
515
|
+
The field ranges for the event data.
|
|
335
516
|
|
|
336
517
|
Returns
|
|
337
518
|
-------
|
|
@@ -339,7 +520,7 @@ def parse_event(event_binary: str) -> dict:
|
|
|
339
520
|
Dict of the fields for a single event.
|
|
340
521
|
"""
|
|
341
522
|
fields_dict = {}
|
|
342
|
-
for field, (start, end) in
|
|
523
|
+
for field, (start, end) in field_ranges.items():
|
|
343
524
|
field_value = int(event_binary[start:end], 2)
|
|
344
525
|
fields_dict[field] = field_value
|
|
345
526
|
return fields_dict
|
|
@@ -8,15 +8,28 @@ import xarray as xr
|
|
|
8
8
|
from imap_processing import imap_module_directory
|
|
9
9
|
from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
|
|
10
10
|
from imap_processing.ultra.l0.decom_ultra import (
|
|
11
|
+
process_ultra_cmd_echo,
|
|
12
|
+
process_ultra_energy_rates,
|
|
13
|
+
process_ultra_energy_spectra,
|
|
11
14
|
process_ultra_events,
|
|
15
|
+
process_ultra_macros_checksum,
|
|
12
16
|
process_ultra_rates,
|
|
13
17
|
process_ultra_tof,
|
|
14
18
|
)
|
|
15
19
|
from imap_processing.ultra.l0.ultra_utils import (
|
|
16
20
|
ULTRA_AUX,
|
|
21
|
+
ULTRA_CMD_ECHO,
|
|
17
22
|
ULTRA_CMD_TEXT,
|
|
23
|
+
ULTRA_ENERGY_EVENTS,
|
|
24
|
+
ULTRA_ENERGY_RATES,
|
|
25
|
+
ULTRA_ENERGY_SPECTRA,
|
|
18
26
|
ULTRA_EVENTS,
|
|
19
27
|
ULTRA_HK,
|
|
28
|
+
ULTRA_MACROS_CHECKSUM,
|
|
29
|
+
ULTRA_PRI_1_EVENTS,
|
|
30
|
+
ULTRA_PRI_2_EVENTS,
|
|
31
|
+
ULTRA_PRI_3_EVENTS,
|
|
32
|
+
ULTRA_PRI_4_EVENTS,
|
|
20
33
|
ULTRA_RATES,
|
|
21
34
|
ULTRA_TOF,
|
|
22
35
|
)
|
|
@@ -25,7 +38,9 @@ from imap_processing.utils import packet_file_to_datasets
|
|
|
25
38
|
logger = logging.getLogger(__name__)
|
|
26
39
|
|
|
27
40
|
|
|
28
|
-
def ultra_l1a(
|
|
41
|
+
def ultra_l1a( # noqa: PLR0912
|
|
42
|
+
packet_file: str, apid_input: Optional[int] = None
|
|
43
|
+
) -> list[xr.Dataset]:
|
|
29
44
|
"""
|
|
30
45
|
Will process ULTRA L0 data into L1A CDF files at output_filepath.
|
|
31
46
|
|
|
@@ -59,6 +74,19 @@ def ultra_l1a(packet_file: str, apid_input: Optional[int] = None) -> list[xr.Dat
|
|
|
59
74
|
else:
|
|
60
75
|
apids = list(datasets_by_apid.keys())
|
|
61
76
|
|
|
77
|
+
all_event_apids = {
|
|
78
|
+
apid: group.logical_source[i]
|
|
79
|
+
for group in [
|
|
80
|
+
ULTRA_EVENTS,
|
|
81
|
+
ULTRA_ENERGY_EVENTS,
|
|
82
|
+
ULTRA_PRI_1_EVENTS,
|
|
83
|
+
ULTRA_PRI_2_EVENTS,
|
|
84
|
+
ULTRA_PRI_3_EVENTS,
|
|
85
|
+
ULTRA_PRI_4_EVENTS,
|
|
86
|
+
]
|
|
87
|
+
for i, apid in enumerate(group.apid)
|
|
88
|
+
}
|
|
89
|
+
|
|
62
90
|
# Update dataset global attributes
|
|
63
91
|
attr_mgr = ImapCdfAttributes()
|
|
64
92
|
attr_mgr.add_instrument_global_attrs("ultra")
|
|
@@ -75,12 +103,29 @@ def ultra_l1a(packet_file: str, apid_input: Optional[int] = None) -> list[xr.Dat
|
|
|
75
103
|
decom_ultra_dataset = process_ultra_rates(datasets_by_apid[apid])
|
|
76
104
|
decom_ultra_dataset = decom_ultra_dataset.drop_vars("fastdata_00")
|
|
77
105
|
gattr_key = ULTRA_RATES.logical_source[ULTRA_RATES.apid.index(apid)]
|
|
78
|
-
elif apid in
|
|
79
|
-
decom_ultra_dataset =
|
|
80
|
-
|
|
106
|
+
elif apid in ULTRA_ENERGY_RATES.apid:
|
|
107
|
+
decom_ultra_dataset = process_ultra_energy_rates(datasets_by_apid[apid])
|
|
108
|
+
decom_ultra_dataset = decom_ultra_dataset.drop_vars("ratedata")
|
|
109
|
+
gattr_key = ULTRA_ENERGY_RATES.logical_source[
|
|
110
|
+
ULTRA_ENERGY_RATES.apid.index(apid)
|
|
111
|
+
]
|
|
112
|
+
elif apid in all_event_apids:
|
|
113
|
+
decom_ultra_dataset = process_ultra_events(datasets_by_apid[apid], apid)
|
|
114
|
+
gattr_key = all_event_apids[apid]
|
|
81
115
|
# Add coordinate attributes
|
|
82
116
|
attrs = attr_mgr.get_variable_attributes("event_id")
|
|
83
117
|
decom_ultra_dataset.coords["event_id"].attrs.update(attrs)
|
|
118
|
+
elif apid in ULTRA_ENERGY_SPECTRA.apid:
|
|
119
|
+
decom_ultra_dataset = process_ultra_energy_spectra(datasets_by_apid[apid])
|
|
120
|
+
decom_ultra_dataset = decom_ultra_dataset.drop_vars("compdata")
|
|
121
|
+
gattr_key = ULTRA_ENERGY_SPECTRA.logical_source[
|
|
122
|
+
ULTRA_ENERGY_SPECTRA.apid.index(apid)
|
|
123
|
+
]
|
|
124
|
+
elif apid in ULTRA_MACROS_CHECKSUM.apid:
|
|
125
|
+
decom_ultra_dataset = process_ultra_macros_checksum(datasets_by_apid[apid])
|
|
126
|
+
gattr_key = ULTRA_MACROS_CHECKSUM.logical_source[
|
|
127
|
+
ULTRA_MACROS_CHECKSUM.apid.index(apid)
|
|
128
|
+
]
|
|
84
129
|
elif apid in ULTRA_HK.apid:
|
|
85
130
|
decom_ultra_dataset = datasets_by_apid[apid]
|
|
86
131
|
gattr_key = ULTRA_HK.logical_source[ULTRA_HK.apid.index(apid)]
|
|
@@ -97,6 +142,9 @@ def ultra_l1a(packet_file: str, apid_input: Optional[int] = None) -> list[xr.Dat
|
|
|
97
142
|
coords={"epoch": decom_ultra_dataset["epoch"]},
|
|
98
143
|
)
|
|
99
144
|
gattr_key = ULTRA_CMD_TEXT.logical_source[ULTRA_CMD_TEXT.apid.index(apid)]
|
|
145
|
+
elif apid in ULTRA_CMD_ECHO.apid:
|
|
146
|
+
decom_ultra_dataset = process_ultra_cmd_echo(datasets_by_apid[apid])
|
|
147
|
+
gattr_key = ULTRA_CMD_ECHO.logical_source[ULTRA_CMD_ECHO.apid.index(apid)]
|
|
100
148
|
else:
|
|
101
149
|
logger.error(f"APID {apid} not recognized.")
|
|
102
150
|
continue
|
|
@@ -4726,15 +4726,15 @@
|
|
|
4726
4726
|
<xtce:IntegerParameterType name="U45_IMG_ENA_PHXTOF_HI_TIME.SPIN" signed="false">
|
|
4727
4727
|
<xtce:IntegerDataEncoding sizeInBits="8" encoding="unsigned" />
|
|
4728
4728
|
</xtce:IntegerParameterType>
|
|
4729
|
+
<xtce:IntegerParameterType name="U45_IMG_ENA_PHXTOF_HI_TIME.ABORTFLAG" signed="false">
|
|
4730
|
+
<xtce:IntegerDataEncoding sizeInBits="1" encoding="unsigned" />
|
|
4731
|
+
</xtce:IntegerParameterType>
|
|
4729
4732
|
<xtce:IntegerParameterType name="U45_IMG_ENA_PHXTOF_HI_TIME.STARTDELAY" signed="false">
|
|
4730
4733
|
<xtce:IntegerDataEncoding sizeInBits="15" encoding="unsigned" />
|
|
4731
4734
|
</xtce:IntegerParameterType>
|
|
4732
4735
|
<xtce:IntegerParameterType name="U45_IMG_ENA_PHXTOF_HI_TIME.P00" signed="false">
|
|
4733
4736
|
<xtce:IntegerDataEncoding sizeInBits="8" encoding="unsigned" />
|
|
4734
4737
|
</xtce:IntegerParameterType>
|
|
4735
|
-
<xtce:IntegerParameterType name="U45_IMG_ENA_PHXTOF_HI_TIME.ABORTFLAG" signed="false">
|
|
4736
|
-
<xtce:IntegerDataEncoding sizeInBits="8" encoding="unsigned" />
|
|
4737
|
-
</xtce:IntegerParameterType>
|
|
4738
4738
|
<xtce:BinaryParameterType name="U45_IMG_ENA_PHXTOF_HI_TIME.PACKETDATA">
|
|
4739
4739
|
<xtce:BinaryDataEncoding bitOrder="mostSignificantBitFirst">
|
|
4740
4740
|
<xtce:SizeInBits>
|
imap_processing/utils.py
CHANGED
|
@@ -15,48 +15,6 @@ from imap_processing.spice.time import met_to_ttj2000ns
|
|
|
15
15
|
logger = logging.getLogger(__name__)
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
def sort_by_time(packets: list, time_key: str) -> list:
|
|
19
|
-
"""
|
|
20
|
-
Sort packets by specified key.
|
|
21
|
-
|
|
22
|
-
Parameters
|
|
23
|
-
----------
|
|
24
|
-
packets : list
|
|
25
|
-
Decom data packets.
|
|
26
|
-
time_key : str
|
|
27
|
-
Key to sort by. Must be a key in the packets data dictionary.
|
|
28
|
-
e.g. "SHCOARSE" or "MET_TIME" or "ACQ_START_COARSE".
|
|
29
|
-
|
|
30
|
-
Returns
|
|
31
|
-
-------
|
|
32
|
-
sorted_packets : list
|
|
33
|
-
Sorted packets.
|
|
34
|
-
"""
|
|
35
|
-
sorted_packets = sorted(packets, key=lambda x: x[time_key])
|
|
36
|
-
return sorted_packets
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def group_by_apid(packets: list) -> dict:
|
|
40
|
-
"""
|
|
41
|
-
Group data by apid.
|
|
42
|
-
|
|
43
|
-
Parameters
|
|
44
|
-
----------
|
|
45
|
-
packets : list
|
|
46
|
-
Packet list.
|
|
47
|
-
|
|
48
|
-
Returns
|
|
49
|
-
-------
|
|
50
|
-
grouped_packets : dict
|
|
51
|
-
Grouped data by apid.
|
|
52
|
-
"""
|
|
53
|
-
grouped_packets: dict[list] = collections.defaultdict(list)
|
|
54
|
-
for packet in packets:
|
|
55
|
-
apid = packet["PKT_APID"]
|
|
56
|
-
grouped_packets.setdefault(apid, []).append(packet)
|
|
57
|
-
return grouped_packets
|
|
58
|
-
|
|
59
|
-
|
|
60
18
|
def convert_raw_to_eu(
|
|
61
19
|
dataset: xr.Dataset,
|
|
62
20
|
conversion_table_path: str,
|
|
@@ -347,6 +305,26 @@ def packet_file_to_datasets(
|
|
|
347
305
|
coords={"epoch": time_data},
|
|
348
306
|
)
|
|
349
307
|
ds = ds.sortby("epoch")
|
|
308
|
+
# We may get duplicate packets within the packet file if packets were
|
|
309
|
+
# ingested multiple times by the POC. We want to drop packets where
|
|
310
|
+
# apid, epoch, and src_seq_ctr are the same.
|
|
311
|
+
|
|
312
|
+
# xarray only supports dropping duplicates by index, so we instead go
|
|
313
|
+
# to pandas multi-index dataframe to identify the unique positions
|
|
314
|
+
unique_indices = (
|
|
315
|
+
ds[["src_seq_ctr"]]
|
|
316
|
+
.to_dataframe()
|
|
317
|
+
.reset_index()
|
|
318
|
+
.drop_duplicates()
|
|
319
|
+
.index.values
|
|
320
|
+
)
|
|
321
|
+
nduplicates = len(ds["epoch"]) - len(unique_indices)
|
|
322
|
+
if nduplicates != 0:
|
|
323
|
+
logger.warning(
|
|
324
|
+
f"Found [{nduplicates}] duplicate packets for APID {apid}. "
|
|
325
|
+
"Dropping duplicate packets and continuing processing."
|
|
326
|
+
)
|
|
327
|
+
ds = ds.isel(epoch=unique_indices)
|
|
350
328
|
|
|
351
329
|
# Strip any leading characters before "." from the field names which was due
|
|
352
330
|
# to the packet_name being a part of the variable name in the XTCE definition
|