diff --git a/imap_processing/cdf/config/imap_ultra_global_cdf_attrs.yaml b/imap_processing/cdf/config/imap_ultra_global_cdf_attrs.yaml
index 22778fb357..2c264edf95 100644
--- a/imap_processing/cdf/config/imap_ultra_global_cdf_attrs.yaml
+++ b/imap_processing/cdf/config/imap_ultra_global_cdf_attrs.yaml
@@ -80,6 +80,54 @@ imap_ultra_l1a_90sensor-energy-de:
Logical_source: imap_ultra_l1a_90sensor-energy-de
Logical_source_description: IMAP-Ultra Instrument Level-1A Energy Direct Event Data.
+imap_ultra_l1a_45sensor-priority-1-de:
+ <<: *instrument_base
+ Data_type: L1A_PRIORITY_1_DE>Level-1A Priority 1 Direct Event
+ Logical_source: imap_ultra_l1a_45sensor-priority-1-de
+ Logical_source_description: IMAP-Ultra Instrument Level-1A Priority 1 Direct Event Data.
+
+imap_ultra_l1a_90sensor-priority-1-de:
+ <<: *instrument_base
+ Data_type: L1A_PRIORITY_1_DE>Level-1A Priority 1 Direct Event
+ Logical_source: imap_ultra_l1a_90sensor-priority-1-de
+ Logical_source_description: IMAP-Ultra Instrument Level-1A Priority 1 Direct Event Data.
+
+imap_ultra_l1a_45sensor-priority-2-de:
+ <<: *instrument_base
+ Data_type: L1A_PRIORITY_2_DE>Level-1A Priority 2 Direct Event
+ Logical_source: imap_ultra_l1a_45sensor-priority-2-de
+ Logical_source_description: IMAP-Ultra Instrument Level-1A Priority 2 Direct Event Data.
+
+imap_ultra_l1a_90sensor-priority-2-de:
+ <<: *instrument_base
+ Data_type: L1A_PRIORITY_2_DE>Level-1A Priority 2 Direct Event
+ Logical_source: imap_ultra_l1a_90sensor-priority-2-de
+ Logical_source_description: IMAP-Ultra Instrument Level-1A Priority 2 Direct Event Data.
+
+imap_ultra_l1a_45sensor-priority-3-de:
+ <<: *instrument_base
+ Data_type: L1A_PRIORITY_3_DE>Level-1A Priority 3 Direct Event
+ Logical_source: imap_ultra_l1a_45sensor-priority-3-de
+ Logical_source_description: IMAP-Ultra Instrument Level-1A Priority 3 Direct Event Data.
+
+imap_ultra_l1a_90sensor-priority-3-de:
+ <<: *instrument_base
+ Data_type: L1A_PRIORITY_3_DE>Level-1A Priority 3 Direct Event
+ Logical_source: imap_ultra_l1a_90sensor-priority-3-de
+ Logical_source_description: IMAP-Ultra Instrument Level-1A Priority 3 Direct Event Data.
+
+imap_ultra_l1a_45sensor-priority-4-de:
+ <<: *instrument_base
+ Data_type: L1A_PRIORITY_4_DE>Level-1A Priority 4 Direct Event
+ Logical_source: imap_ultra_l1a_45sensor-priority-4-de
+ Logical_source_description: IMAP-Ultra Instrument Level-1A Priority 4 Direct Event Data.
+
+imap_ultra_l1a_90sensor-priority-4-de:
+ <<: *instrument_base
+ Data_type: L1A_PRIORITY_4_DE>Level-1A Priority 4 Direct Event
+ Logical_source: imap_ultra_l1a_90sensor-priority-4-de
+ Logical_source_description: IMAP-Ultra Instrument Level-1A Priority 4 Direct Event Data.
+
imap_ultra_l1b_45sensor-de:
<<: *instrument_base
Data_type: L1B_45Sensor-DE>Level-1B Direct Events for Ultra45
diff --git a/imap_processing/tests/external_test_data_config.py b/imap_processing/tests/external_test_data_config.py
index 2073f5ace0..5bdb0eac06 100644
--- a/imap_processing/tests/external_test_data_config.py
+++ b/imap_processing/tests/external_test_data_config.py
@@ -63,8 +63,12 @@
("IMAP-Ultra45_r1_L1_V0_shortened.csv", "ultra/data/l1/"),
# Ultra
+ ("FM45_UltraFM45Extra_TV_Tests_2024-01-22T0930_20240122T093008.CCSDS", "ultra/data/l0/"),
("ultra45_raw_sc_rawnrgevnt_19840122_00.csv", "ultra/data/l0/"),
("ultra45_raw_sc_imgpriority1evnt_FM45_UltraFM45Extra_TV_Tests_2024-01-22T0930_20240122T093008.csv", "ultra/data/l0/"),
+ ("ultra45_raw_sc_imgpriority2evnt_FM45_UltraFM45Extra_TV_Tests_2024-01-22T0930_20240122T093008.csv", "ultra/data/l0/"),
+ ("ultra45_raw_sc_imgpriority3evnt_FM45_UltraFM45Extra_TV_Tests_2024-01-22T0930_20240122T093008.csv", "ultra/data/l0/"),
+ ("ultra45_raw_sc_imgpriority4evnt_FM45_UltraFM45Extra_TV_Tests_2024-01-22T0930_20240122T093008.csv", "ultra/data/l0/"),
("ultra45_raw_sc_ultranrgrates_FM45_UltraFM45_Functional_"
"2024-01-22T0105_20240122T010548.csv", "ultra/data/l0/"),
("imap_ultra_l0_raw_20260924_v001.pkts", "ultra/data/l0/"),
diff --git a/imap_processing/tests/ultra/unit/conftest.py b/imap_processing/tests/ultra/unit/conftest.py
index 9875579be6..f6903e26e0 100644
--- a/imap_processing/tests/ultra/unit/conftest.py
+++ b/imap_processing/tests/ultra/unit/conftest.py
@@ -16,6 +16,10 @@
ULTRA_ENERGY_EVENTS,
ULTRA_ENERGY_RATES,
ULTRA_EVENTS,
+ ULTRA_PRI_1_EVENTS,
+ ULTRA_PRI_2_EVENTS,
+ ULTRA_PRI_3_EVENTS,
+ ULTRA_PRI_4_EVENTS,
ULTRA_RATES,
ULTRA_TOF,
)
@@ -102,6 +106,19 @@ def ccsds_path_functional():
)
+@pytest.fixture
+def ccsds_path_extra():
+ """Returns the ccsds directory."""
+ return (
+ imap_module_directory
+ / "tests"
+ / "ultra"
+ / "data"
+ / "l0"
+ / "FM45_UltraFM45Extra_TV_Tests_2024-01-22T0930_20240122T093008.CCSDS"
+ )
+
+
@pytest.fixture
def xtce_path():
"""Returns the xtce image rates directory."""
@@ -178,6 +195,14 @@ def decom_test_data(request, xtce_path):
ULTRA_ENERGY_EVENTS.apid[1]: lambda ds, apid: process_ultra_events(ds, apid),
ULTRA_EVENTS.apid[0]: lambda ds, apid: process_ultra_events(ds, apid),
ULTRA_EVENTS.apid[1]: lambda ds, apid: process_ultra_events(ds, apid),
+ ULTRA_PRI_1_EVENTS.apid[0]: lambda ds, apid: process_ultra_events(ds, apid),
+ ULTRA_PRI_1_EVENTS.apid[1]: lambda ds, apid: process_ultra_events(ds, apid),
+ ULTRA_PRI_2_EVENTS.apid[0]: lambda ds, apid: process_ultra_events(ds, apid),
+ ULTRA_PRI_2_EVENTS.apid[1]: lambda ds, apid: process_ultra_events(ds, apid),
+ ULTRA_PRI_3_EVENTS.apid[0]: lambda ds, apid: process_ultra_events(ds, apid),
+ ULTRA_PRI_3_EVENTS.apid[1]: lambda ds, apid: process_ultra_events(ds, apid),
+ ULTRA_PRI_4_EVENTS.apid[0]: lambda ds, apid: process_ultra_events(ds, apid),
+ ULTRA_PRI_4_EVENTS.apid[1]: lambda ds, apid: process_ultra_events(ds, apid),
ULTRA_RATES.apid[0]: lambda ds, apid: process_ultra_rates(ds),
ULTRA_RATES.apid[1]: lambda ds, apid: process_ultra_rates(ds),
ULTRA_ENERGY_RATES.apid[0]: lambda ds, apid: process_ultra_energy_rates(ds),
diff --git a/imap_processing/tests/ultra/unit/test_decom_apid_898.py b/imap_processing/tests/ultra/unit/test_decom_apid_898.py
new file mode 100644
index 0000000000..df13d6903d
--- /dev/null
+++ b/imap_processing/tests/ultra/unit/test_decom_apid_898.py
@@ -0,0 +1,63 @@
+import numpy as np
+import pandas as pd
+import pytest
+
+from imap_processing import imap_module_directory
+
+
+@pytest.mark.parametrize(
+ "decom_test_data",
+ [
+ pytest.param(
+ {
+ "apid": 898,
+ "filename": "FM45_UltraFM45Extra_TV_Tests_"
+ "2024-01-22T0930_20240122T093008.CCSDS",
+ }
+ )
+ ],
+ indirect=True,
+)
+@pytest.mark.external_test_data
+def test_image_raw_events_decom(decom_test_data, xtce_path):
+ """This function reads validation data and checks that decom data
+ matches validation data for image rate packet"""
+ filename = (
+ "ultra45_raw_sc_imgpriority1evnt_FM45_UltraFM45Extra_TV_Tests_"
+ "2024-01-22T0930_20240122T093008.csv"
+ )
+ priority_1_events_test_path = (
+ imap_module_directory / "tests" / "ultra" / "data" / "l0" / filename
+ )
+
+ decom_ultra = decom_test_data
+ df = pd.read_csv(priority_1_events_test_path, index_col="MET")
+
+ vars_to_compare = {
+ "SID": "sid",
+ "Spin": "spin",
+ "AbortFlag": "abortflag",
+ "StartDelay": "startdelay",
+ "Count": "count",
+ "CoinType": "coin_type",
+ "StartType": "start_type",
+ "StopType": "stop_type",
+ "StartPosTDC": "start_pos_tdc",
+ "StopNorthTDC": "stop_north_tdc",
+ "StopEastTDC": "stop_east_tdc",
+ "StopSouthTDC": "stop_south_tdc",
+ "StopWestTDC": "stop_west_tdc",
+ "CoinNorthTDC": "coin_north_tdc",
+ "CoinSouthTDC": "coin_south_tdc",
+ "CoinDiscreteTDC": "coin_discrete_tdc",
+ "EnergyOrPH": "energy_ph",
+ "PulseWidth": "pulse_width",
+ "PhaseAngle": "phase_angle",
+ "Bin": "bin",
+ }
+
+ for df_var, xr_var in vars_to_compare.items():
+ good_values = df[df_var].values != -1
+ np.testing.assert_array_equal(
+ df[df_var].values[good_values], decom_ultra[xr_var].values[good_values]
+ )
diff --git a/imap_processing/tests/ultra/unit/test_decom_apid_899.py b/imap_processing/tests/ultra/unit/test_decom_apid_899.py
new file mode 100644
index 0000000000..1de44fe60e
--- /dev/null
+++ b/imap_processing/tests/ultra/unit/test_decom_apid_899.py
@@ -0,0 +1,64 @@
+import numpy as np
+import pandas as pd
+import pytest
+
+from imap_processing import imap_module_directory
+
+
+@pytest.mark.parametrize(
+ "decom_test_data",
+ [
+ pytest.param(
+ {
+ "apid": 899,
+ "filename": "FM45_UltraFM45Extra_TV_Tests_"
+ "2024-01-22T0930_20240122T093008.CCSDS",
+ }
+ )
+ ],
+ indirect=True,
+)
+@pytest.mark.external_test_data
+def test_image_raw_events_decom(decom_test_data, xtce_path):
+ """This function reads validation data and checks that decom data
+ matches validation data for image rate packet"""
+ filename = (
+ "ultra45_raw_sc_imgpriority2evnt_FM45_UltraFM45Extra_TV_Tests_"
+ "2024-01-22T0930_20240122T093008.csv"
+ )
+ priority_2_events_test_path = (
+ imap_module_directory / "tests" / "ultra" / "data" / "l0" / filename
+ )
+
+ decom_ultra = decom_test_data
+ df = pd.read_csv(priority_2_events_test_path, index_col="MET")
+
+ vars_to_compare = {
+ "SID": "sid",
+ "Spin": "spin",
+ "AbortFlag": "abortflag",
+ "StartDelay": "startdelay",
+ "Count": "count",
+ "CoinType": "coin_type",
+ "StartType": "start_type",
+ "StopType": "stop_type",
+ "StartPosTDC": "start_pos_tdc",
+ "StopNorthTDC": "stop_north_tdc",
+ "StopEastTDC": "stop_east_tdc",
+ "StopSouthTDC": "stop_south_tdc",
+ "StopWestTDC": "stop_west_tdc",
+ "CoinNorthTDC": "coin_north_tdc",
+ "CoinSouthTDC": "coin_south_tdc",
+ "CoinDiscreteTDC": "coin_discrete_tdc",
+ "EnergyOrPH": "energy_ph",
+ "PulseWidth": "pulse_width",
+ "PhaseAngle": "phase_angle",
+ "Bin": "bin",
+ }
+
+ for df_var, xr_var in vars_to_compare.items():
+ good_values = df[df_var].values != -1
+ np.testing.assert_array_equal(
+ df[df_var].values[good_values],
+ decom_ultra[xr_var].values[good_values],
+ )
diff --git a/imap_processing/tests/ultra/unit/test_decom_apid_900.py b/imap_processing/tests/ultra/unit/test_decom_apid_900.py
new file mode 100644
index 0000000000..7c103be62c
--- /dev/null
+++ b/imap_processing/tests/ultra/unit/test_decom_apid_900.py
@@ -0,0 +1,64 @@
+import numpy as np
+import pandas as pd
+import pytest
+
+from imap_processing import imap_module_directory
+
+
+@pytest.mark.parametrize(
+ "decom_test_data",
+ [
+ pytest.param(
+ {
+ "apid": 900,
+ "filename": "FM45_UltraFM45Extra_TV_Tests_"
+ "2024-01-22T0930_20240122T093008.CCSDS",
+ }
+ )
+ ],
+ indirect=True,
+)
+@pytest.mark.external_test_data
+def test_image_raw_events_decom(decom_test_data, xtce_path):
+ """This function reads validation data and checks that decom data
+ matches validation data for image rate packet"""
+ filename = (
+ "ultra45_raw_sc_imgpriority3evnt_FM45_UltraFM45Extra_TV_Tests_"
+ "2024-01-22T0930_20240122T093008.csv"
+ )
+ priority_3_events_test_path = (
+ imap_module_directory / "tests" / "ultra" / "data" / "l0" / filename
+ )
+
+ decom_ultra = decom_test_data
+ df = pd.read_csv(priority_3_events_test_path, index_col="MET")
+
+ vars_to_compare = {
+ "SID": "sid",
+ "Spin": "spin",
+ "AbortFlag": "abortflag",
+ "StartDelay": "startdelay",
+ "Count": "count",
+ "CoinType": "coin_type",
+ "StartType": "start_type",
+ "StopType": "stop_type",
+ "StartPosTDC": "start_pos_tdc",
+ "StopNorthTDC": "stop_north_tdc",
+ "StopEastTDC": "stop_east_tdc",
+ "StopSouthTDC": "stop_south_tdc",
+ "StopWestTDC": "stop_west_tdc",
+ "CoinNorthTDC": "coin_north_tdc",
+ "CoinSouthTDC": "coin_south_tdc",
+ "CoinDiscreteTDC": "coin_discrete_tdc",
+ "EnergyOrPH": "energy_ph",
+ "PulseWidth": "pulse_width",
+ "PhaseAngle": "phase_angle",
+ "Bin": "bin",
+ }
+
+ for df_var, xr_var in vars_to_compare.items():
+ good_values = df[df_var].values != -1
+ np.testing.assert_array_equal(
+ df[df_var].values[good_values],
+ decom_ultra[xr_var].values[good_values],
+ )
diff --git a/imap_processing/tests/ultra/unit/test_decom_apid_901.py b/imap_processing/tests/ultra/unit/test_decom_apid_901.py
new file mode 100644
index 0000000000..4e2353d6eb
--- /dev/null
+++ b/imap_processing/tests/ultra/unit/test_decom_apid_901.py
@@ -0,0 +1,64 @@
+import numpy as np
+import pandas as pd
+import pytest
+
+from imap_processing import imap_module_directory
+
+
+@pytest.mark.parametrize(
+ "decom_test_data",
+ [
+ pytest.param(
+ {
+ "apid": 901,
+ "filename": "FM45_UltraFM45Extra_TV_Tests_"
+ "2024-01-22T0930_20240122T093008.CCSDS",
+ }
+ )
+ ],
+ indirect=True,
+)
+@pytest.mark.external_test_data
+def test_image_raw_events_decom(decom_test_data, xtce_path):
+ """This function reads validation data and checks that decom data
+ matches validation data for image rate packet"""
+ filename = (
+ "ultra45_raw_sc_imgpriority4evnt_FM45_UltraFM45Extra_TV_Tests_"
+ "2024-01-22T0930_20240122T093008.csv"
+ )
+ priority_4_events_test_path = (
+ imap_module_directory / "tests" / "ultra" / "data" / "l0" / filename
+ )
+
+ decom_ultra = decom_test_data
+ df = pd.read_csv(priority_4_events_test_path, index_col="MET")
+
+ vars_to_compare = {
+ "SID": "sid",
+ "Spin": "spin",
+ "AbortFlag": "abortflag",
+ "StartDelay": "startdelay",
+ "Count": "count",
+ "CoinType": "coin_type",
+ "StartType": "start_type",
+ "StopType": "stop_type",
+ "StartPosTDC": "start_pos_tdc",
+ "StopNorthTDC": "stop_north_tdc",
+ "StopEastTDC": "stop_east_tdc",
+ "StopSouthTDC": "stop_south_tdc",
+ "StopWestTDC": "stop_west_tdc",
+ "CoinNorthTDC": "coin_north_tdc",
+ "CoinSouthTDC": "coin_south_tdc",
+ "CoinDiscreteTDC": "coin_discrete_tdc",
+ "EnergyOrPH": "energy_ph",
+ "PulseWidth": "pulse_width",
+ "PhaseAngle": "phase_angle",
+ "Bin": "bin",
+ }
+
+ for df_var, xr_var in vars_to_compare.items():
+ good_values = df[df_var].values != -1
+ np.testing.assert_array_equal(
+ df[df_var].values[good_values],
+ decom_ultra[xr_var].values[good_values],
+ )
diff --git a/imap_processing/tests/ultra/unit/test_ultra_l1a.py b/imap_processing/tests/ultra/unit/test_ultra_l1a.py
index d2be3ab23f..9ed5735d02 100644
--- a/imap_processing/tests/ultra/unit/test_ultra_l1a.py
+++ b/imap_processing/tests/ultra/unit/test_ultra_l1a.py
@@ -11,6 +11,10 @@
ULTRA_ENERGY_EVENTS,
ULTRA_ENERGY_RATES,
ULTRA_EVENTS,
+ ULTRA_PRI_1_EVENTS,
+ ULTRA_PRI_2_EVENTS,
+ ULTRA_PRI_3_EVENTS,
+ ULTRA_PRI_4_EVENTS,
ULTRA_RATES,
ULTRA_TOF,
)
@@ -153,6 +157,70 @@ def test_cdf_energy_events(ccsds_path_functional):
)
+@pytest.mark.external_test_data
+def test_cdf_pri_1_events(ccsds_path_extra):
+ """Tests that CDF file can be created."""
+ test_data = ultra_l1a(ccsds_path_extra, apid_input=ULTRA_PRI_1_EVENTS.apid[0])
+
+ test_data[0].attrs["Data_version"] = "999"
+ test_data[0].attrs["Repointing"] = "repoint99999"
+ test_data_path = write_cdf(test_data[0], istp=True)
+
+ assert test_data_path.exists()
+ assert (
+ test_data_path.name
+ == "imap_ultra_l1a_45sensor-priority-1-de_20240122-repoint99999_v999.cdf"
+ )
+
+
+@pytest.mark.external_test_data
+def test_cdf_pri_2_events(ccsds_path_extra):
+ """Tests that CDF file can be created."""
+ test_data = ultra_l1a(ccsds_path_extra, apid_input=ULTRA_PRI_2_EVENTS.apid[0])
+
+ test_data[0].attrs["Data_version"] = "999"
+ test_data[0].attrs["Repointing"] = "repoint99999"
+ test_data_path = write_cdf(test_data[0], istp=True)
+
+ assert test_data_path.exists()
+ assert (
+ test_data_path.name
+ == "imap_ultra_l1a_45sensor-priority-2-de_20240122-repoint99999_v999.cdf"
+ )
+
+
+@pytest.mark.external_test_data
+def test_cdf_pri_3_events(ccsds_path_extra):
+ """Tests that CDF file can be created."""
+ test_data = ultra_l1a(ccsds_path_extra, apid_input=ULTRA_PRI_3_EVENTS.apid[0])
+
+ test_data[0].attrs["Data_version"] = "999"
+ test_data[0].attrs["Repointing"] = "repoint99999"
+ test_data_path = write_cdf(test_data[0], istp=True)
+
+ assert test_data_path.exists()
+ assert (
+ test_data_path.name
+ == "imap_ultra_l1a_45sensor-priority-3-de_20240122-repoint99999_v999.cdf"
+ )
+
+
+@pytest.mark.external_test_data
+def test_cdf_pri_4_events(ccsds_path_extra):
+ """Tests that CDF file can be created."""
+ test_data = ultra_l1a(ccsds_path_extra, apid_input=ULTRA_PRI_4_EVENTS.apid[0])
+
+ test_data[0].attrs["Data_version"] = "999"
+ test_data[0].attrs["Repointing"] = "repoint99999"
+ test_data_path = write_cdf(test_data[0], istp=True)
+
+ assert test_data_path.exists()
+ assert (
+ test_data_path.name
+ == "imap_ultra_l1a_45sensor-priority-4-de_20240122-repoint99999_v999.cdf"
+ )
+
+
def test_cdf_hk(ccsds_path_theta_0):
"""Tests that CDF file can be created."""
test_data = ultra_l1a(ccsds_path_theta_0, apid_input=869)
diff --git a/imap_processing/ultra/l0/decom_ultra.py b/imap_processing/ultra/l0/decom_ultra.py
index 8719a922ee..b3f2711940 100644
--- a/imap_processing/ultra/l0/decom_ultra.py
+++ b/imap_processing/ultra/l0/decom_ultra.py
@@ -22,6 +22,10 @@
ULTRA_ENERGY_EVENTS,
ULTRA_ENERGY_RATES,
ULTRA_EVENTS,
+ ULTRA_PRI_1_EVENTS,
+ ULTRA_PRI_2_EVENTS,
+ ULTRA_PRI_3_EVENTS,
+ ULTRA_PRI_4_EVENTS,
ULTRA_RATES,
ULTRA_TOF,
)
@@ -157,7 +161,14 @@ def process_ultra_events(ds: xr.Dataset, apid: int) -> xr.Dataset:
ds : xarray.Dataset
Dataset containing the decoded and decompressed data.
"""
- if apid in ULTRA_EVENTS.apid:
+ all_event_apids = set(
+ ULTRA_EVENTS.apid
+ + ULTRA_PRI_1_EVENTS.apid
+ + ULTRA_PRI_2_EVENTS.apid
+ + ULTRA_PRI_3_EVENTS.apid
+ + ULTRA_PRI_4_EVENTS.apid
+ )
+ if apid in all_event_apids:
field_ranges = EVENT_FIELD_RANGES
elif apid in ULTRA_ENERGY_EVENTS.apid:
field_ranges = ENERGY_EVENT_FIELD_RANGES
diff --git a/imap_processing/ultra/l0/ultra_utils.py b/imap_processing/ultra/l0/ultra_utils.py
index 017d579c42..f72dc1c918 100644
--- a/imap_processing/ultra/l0/ultra_utils.py
+++ b/imap_processing/ultra/l0/ultra_utils.py
@@ -85,6 +85,54 @@ class PacketProperties(NamedTuple):
len_array=None,
mantissa_bit_length=None,
)
+ULTRA_PRI_1_EVENTS = PacketProperties(
+ apid=[898, 962],
+ logical_source=[
+ "imap_ultra_l1a_45sensor-priority-1-de",
+ "imap_ultra_l1a_90sensor-priority-1-de",
+ ],
+ addition_to_logical_desc="Primary 1 Events",
+ width=None,
+ block=None,
+ len_array=None,
+ mantissa_bit_length=None,
+)
+ULTRA_PRI_2_EVENTS = PacketProperties(
+ apid=[899, 963],
+ logical_source=[
+ "imap_ultra_l1a_45sensor-priority-2-de",
+ "imap_ultra_l1a_90sensor-priority-2-de",
+ ],
+ addition_to_logical_desc="Primary 2 Events",
+ width=None,
+ block=None,
+ len_array=None,
+ mantissa_bit_length=None,
+)
+ULTRA_PRI_3_EVENTS = PacketProperties(
+ apid=[900, 964],
+ logical_source=[
+ "imap_ultra_l1a_45sensor-priority-3-de",
+ "imap_ultra_l1a_90sensor-priority-3-de",
+ ],
+ addition_to_logical_desc="Primary 3 Events",
+ width=None,
+ block=None,
+ len_array=None,
+ mantissa_bit_length=None,
+)
+ULTRA_PRI_4_EVENTS = PacketProperties(
+ apid=[901, 965],
+ logical_source=[
+ "imap_ultra_l1a_45sensor-priority-4-de",
+ "imap_ultra_l1a_90sensor-priority-4-de",
+ ],
+ addition_to_logical_desc="Primary 4 Events",
+ width=None,
+ block=None,
+ len_array=None,
+ mantissa_bit_length=None,
+)
ULTRA_HK = PacketProperties(
apid=[
866,
diff --git a/imap_processing/ultra/l1a/ultra_l1a.py b/imap_processing/ultra/l1a/ultra_l1a.py
index 3c26a67188..5e1b969b49 100644
--- a/imap_processing/ultra/l1a/ultra_l1a.py
+++ b/imap_processing/ultra/l1a/ultra_l1a.py
@@ -20,6 +20,10 @@
ULTRA_ENERGY_RATES,
ULTRA_EVENTS,
ULTRA_HK,
+ ULTRA_PRI_1_EVENTS,
+ ULTRA_PRI_2_EVENTS,
+ ULTRA_PRI_3_EVENTS,
+ ULTRA_PRI_4_EVENTS,
ULTRA_RATES,
ULTRA_TOF,
)
@@ -28,7 +32,7 @@
logger = logging.getLogger(__name__)
-def ultra_l1a(packet_file: str, apid_input: Optional[int] = None) -> list[xr.Dataset]: # noqa: PLR0912
+def ultra_l1a(packet_file: str, apid_input: Optional[int] = None) -> list[xr.Dataset]:
"""
Will process ULTRA L0 data into L1A CDF files at output_filepath.
@@ -62,6 +66,19 @@ def ultra_l1a(packet_file: str, apid_input: Optional[int] = None) -> list[xr.Dat
else:
apids = list(datasets_by_apid.keys())
+ all_event_apids = {
+ apid: group.logical_source[i]
+ for group in [
+ ULTRA_EVENTS,
+ ULTRA_ENERGY_EVENTS,
+ ULTRA_PRI_1_EVENTS,
+ ULTRA_PRI_2_EVENTS,
+ ULTRA_PRI_3_EVENTS,
+ ULTRA_PRI_4_EVENTS,
+ ]
+ for i, apid in enumerate(group.apid)
+ }
+
# Update dataset global attributes
attr_mgr = ImapCdfAttributes()
attr_mgr.add_instrument_global_attrs("ultra")
@@ -84,17 +101,9 @@ def ultra_l1a(packet_file: str, apid_input: Optional[int] = None) -> list[xr.Dat
gattr_key = ULTRA_ENERGY_RATES.logical_source[
ULTRA_ENERGY_RATES.apid.index(apid)
]
- elif apid in ULTRA_EVENTS.apid:
- decom_ultra_dataset = process_ultra_events(datasets_by_apid[apid], apid)
- gattr_key = ULTRA_EVENTS.logical_source[ULTRA_EVENTS.apid.index(apid)]
- # Add coordinate attributes
- attrs = attr_mgr.get_variable_attributes("event_id")
- decom_ultra_dataset.coords["event_id"].attrs.update(attrs)
- elif apid in ULTRA_ENERGY_EVENTS.apid:
+ elif apid in all_event_apids:
decom_ultra_dataset = process_ultra_events(datasets_by_apid[apid], apid)
- gattr_key = ULTRA_ENERGY_EVENTS.logical_source[
- ULTRA_ENERGY_EVENTS.apid.index(apid)
- ]
+ gattr_key = all_event_apids[apid]
# Add coordinate attributes
attrs = attr_mgr.get_variable_attributes("event_id")
decom_ultra_dataset.coords["event_id"].attrs.update(attrs)
diff --git a/imap_processing/ultra/packet_definitions/ULTRA_SCI_COMBINED.xml b/imap_processing/ultra/packet_definitions/ULTRA_SCI_COMBINED.xml
index 4a887bb0d7..df36118015 100644
--- a/imap_processing/ultra/packet_definitions/ULTRA_SCI_COMBINED.xml
+++ b/imap_processing/ultra/packet_definitions/ULTRA_SCI_COMBINED.xml
@@ -4726,15 +4726,15 @@
+
+
+
-
-
-