imap-processing 0.7.0__py3-none-any.whl → 0.9.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.

Files changed (172) hide show
  1. imap_processing/__init__.py +1 -1
  2. imap_processing/_version.py +2 -2
  3. imap_processing/ccsds/excel_to_xtce.py +36 -2
  4. imap_processing/cdf/config/imap_codice_global_cdf_attrs.yaml +1 -1
  5. imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +145 -30
  6. imap_processing/cdf/config/imap_glows_l1b_variable_attrs.yaml +36 -36
  7. imap_processing/cdf/config/imap_hi_variable_attrs.yaml +136 -9
  8. imap_processing/cdf/config/imap_hit_global_cdf_attrs.yaml +14 -0
  9. imap_processing/cdf/config/imap_hit_l1a_variable_attrs.yaml +63 -1
  10. imap_processing/cdf/config/imap_hit_l1b_variable_attrs.yaml +9 -0
  11. imap_processing/cdf/config/imap_idex_global_cdf_attrs.yaml +14 -7
  12. imap_processing/cdf/config/imap_idex_l1a_variable_attrs.yaml +577 -235
  13. imap_processing/cdf/config/imap_idex_l1b_variable_attrs.yaml +326 -0
  14. imap_processing/cdf/config/imap_lo_l1a_variable_attrs.yaml +33 -23
  15. imap_processing/cdf/config/imap_mag_l1_variable_attrs.yaml +24 -28
  16. imap_processing/cdf/config/imap_ultra_l1a_variable_attrs.yaml +1 -0
  17. imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +137 -79
  18. imap_processing/cdf/config/imap_variable_schema.yaml +13 -0
  19. imap_processing/cdf/imap_cdf_manager.py +31 -27
  20. imap_processing/cdf/utils.py +3 -5
  21. imap_processing/cli.py +25 -14
  22. imap_processing/codice/codice_l1a.py +153 -63
  23. imap_processing/codice/constants.py +10 -10
  24. imap_processing/codice/decompress.py +10 -11
  25. imap_processing/codice/utils.py +1 -0
  26. imap_processing/glows/l1a/glows_l1a.py +1 -2
  27. imap_processing/glows/l1b/glows_l1b.py +3 -3
  28. imap_processing/glows/l1b/glows_l1b_data.py +59 -37
  29. imap_processing/glows/l2/glows_l2_data.py +123 -0
  30. imap_processing/hi/l1a/hi_l1a.py +4 -4
  31. imap_processing/hi/l1a/histogram.py +107 -109
  32. imap_processing/hi/l1a/science_direct_event.py +92 -225
  33. imap_processing/hi/l1b/hi_l1b.py +85 -11
  34. imap_processing/hi/l1c/hi_l1c.py +23 -1
  35. imap_processing/hi/packet_definitions/TLM_HI_COMBINED_SCI.xml +3994 -0
  36. imap_processing/hi/utils.py +1 -1
  37. imap_processing/hit/hit_utils.py +221 -0
  38. imap_processing/hit/l0/constants.py +118 -0
  39. imap_processing/hit/l0/decom_hit.py +100 -156
  40. imap_processing/hit/l1a/hit_l1a.py +170 -184
  41. imap_processing/hit/l1b/hit_l1b.py +33 -153
  42. imap_processing/ialirt/l0/process_codicelo.py +153 -0
  43. imap_processing/ialirt/l0/process_hit.py +5 -5
  44. imap_processing/ialirt/packet_definitions/ialirt_codicelo.xml +281 -0
  45. imap_processing/ialirt/process_ephemeris.py +212 -0
  46. imap_processing/idex/idex_l1a.py +65 -84
  47. imap_processing/idex/idex_l1b.py +192 -0
  48. imap_processing/idex/idex_variable_unpacking_and_eu_conversion.csv +33 -0
  49. imap_processing/idex/packet_definitions/idex_packet_definition.xml +97 -595
  50. imap_processing/lo/l0/decompression_tables/decompression_tables.py +17 -1
  51. imap_processing/lo/l0/lo_science.py +45 -13
  52. imap_processing/lo/l1a/lo_l1a.py +76 -8
  53. imap_processing/lo/packet_definitions/lo_xtce.xml +8344 -1849
  54. imap_processing/mag/l0/decom_mag.py +4 -3
  55. imap_processing/mag/l1a/mag_l1a.py +12 -13
  56. imap_processing/mag/l1a/mag_l1a_data.py +1 -2
  57. imap_processing/mag/l1b/mag_l1b.py +90 -7
  58. imap_processing/spice/geometry.py +156 -16
  59. imap_processing/spice/time.py +144 -2
  60. imap_processing/swapi/l1/swapi_l1.py +4 -4
  61. imap_processing/swapi/l2/swapi_l2.py +1 -1
  62. imap_processing/swapi/packet_definitions/swapi_packet_definition.xml +1535 -446
  63. imap_processing/swe/l1b/swe_l1b_science.py +8 -8
  64. imap_processing/swe/l2/swe_l2.py +134 -17
  65. imap_processing/tests/ccsds/test_data/expected_output.xml +2 -1
  66. imap_processing/tests/ccsds/test_excel_to_xtce.py +4 -4
  67. imap_processing/tests/cdf/test_imap_cdf_manager.py +0 -10
  68. imap_processing/tests/codice/conftest.py +1 -17
  69. imap_processing/tests/codice/data/imap_codice_l0_raw_20241110_v001.pkts +0 -0
  70. imap_processing/tests/codice/test_codice_l0.py +8 -2
  71. imap_processing/tests/codice/test_codice_l1a.py +127 -107
  72. imap_processing/tests/codice/test_codice_l1b.py +1 -0
  73. imap_processing/tests/codice/test_decompress.py +7 -7
  74. imap_processing/tests/conftest.py +100 -58
  75. imap_processing/tests/glows/conftest.py +6 -0
  76. imap_processing/tests/glows/test_glows_l1b.py +9 -9
  77. imap_processing/tests/glows/test_glows_l1b_data.py +9 -9
  78. imap_processing/tests/hi/test_data/l0/H90_NHK_20241104.bin +0 -0
  79. imap_processing/tests/hi/test_data/l0/H90_sci_cnt_20241104.bin +0 -0
  80. imap_processing/tests/hi/test_data/l0/H90_sci_de_20241104.bin +0 -0
  81. imap_processing/tests/hi/test_data/l1a/imap_hi_l1a_45sensor-de_20250415_v000.cdf +0 -0
  82. imap_processing/tests/hi/test_hi_l1b.py +73 -3
  83. imap_processing/tests/hi/test_hi_l1c.py +10 -2
  84. imap_processing/tests/hi/test_l1a.py +31 -58
  85. imap_processing/tests/hi/test_science_direct_event.py +58 -0
  86. imap_processing/tests/hi/test_utils.py +4 -3
  87. imap_processing/tests/hit/test_data/sci_sample1.ccsds +0 -0
  88. imap_processing/tests/hit/{test_hit_decom.py → test_decom_hit.py} +95 -36
  89. imap_processing/tests/hit/test_hit_l1a.py +299 -179
  90. imap_processing/tests/hit/test_hit_l1b.py +231 -24
  91. imap_processing/tests/hit/test_hit_utils.py +218 -0
  92. imap_processing/tests/hit/validation_data/hskp_sample_eu.csv +89 -0
  93. imap_processing/tests/hit/validation_data/sci_sample_raw1.csv +29 -0
  94. imap_processing/tests/ialirt/test_data/l0/apid01152.tlm +0 -0
  95. imap_processing/tests/ialirt/test_data/l0/imap_codice_l1a_lo-ialirt_20241110193700_v0.0.0.cdf +0 -0
  96. imap_processing/tests/ialirt/unit/test_process_codicelo.py +106 -0
  97. imap_processing/tests/ialirt/unit/test_process_ephemeris.py +109 -0
  98. imap_processing/tests/ialirt/unit/test_process_hit.py +9 -6
  99. imap_processing/tests/idex/conftest.py +2 -2
  100. imap_processing/tests/idex/imap_idex_l0_raw_20231214_v001.pkts +0 -0
  101. imap_processing/tests/idex/impact_14_tof_high_data.txt +4444 -4444
  102. imap_processing/tests/idex/test_idex_l0.py +4 -4
  103. imap_processing/tests/idex/test_idex_l1a.py +8 -2
  104. imap_processing/tests/idex/test_idex_l1b.py +126 -0
  105. imap_processing/tests/lo/test_lo_l1a.py +7 -16
  106. imap_processing/tests/lo/test_lo_science.py +69 -5
  107. imap_processing/tests/lo/test_pkts/imap_lo_l0_raw_20240803_v002.pkts +0 -0
  108. imap_processing/tests/lo/validation_data/Instrument_FM1_T104_R129_20240803_ILO_SCI_DE_dec_DN_with_fills.csv +1999 -0
  109. imap_processing/tests/mag/imap_mag_l1a_norm-magi_20251017_v001.cdf +0 -0
  110. imap_processing/tests/mag/test_mag_l1b.py +97 -7
  111. imap_processing/tests/spice/test_data/imap_ena_sim_metakernel.template +3 -1
  112. imap_processing/tests/spice/test_geometry.py +115 -9
  113. imap_processing/tests/spice/test_time.py +135 -6
  114. imap_processing/tests/swapi/test_swapi_decom.py +75 -69
  115. imap_processing/tests/swapi/test_swapi_l1.py +4 -4
  116. imap_processing/tests/swe/conftest.py +33 -0
  117. imap_processing/tests/swe/l1_validation/swe_l0_unpacked-data_20240510_v001_VALIDATION_L1B_v3.dat +4332 -0
  118. imap_processing/tests/swe/test_swe_l1b.py +29 -8
  119. imap_processing/tests/swe/test_swe_l2.py +64 -8
  120. imap_processing/tests/test_utils.py +2 -2
  121. imap_processing/tests/ultra/test_data/l0/ultra45_raw_sc_ultrarawimg_withFSWcalcs_FM45_40P_Phi28p5_BeamCal_LinearScan_phi2850_theta-000_20240207T102740.csv +3314 -3314
  122. imap_processing/tests/ultra/test_data/l1/dps_exposure_helio_45_E12.cdf +0 -0
  123. imap_processing/tests/ultra/test_data/l1/dps_exposure_helio_45_E24.cdf +0 -0
  124. imap_processing/tests/ultra/unit/test_de.py +113 -0
  125. imap_processing/tests/ultra/unit/test_spatial_utils.py +125 -0
  126. imap_processing/tests/ultra/unit/test_ultra_l1b.py +27 -3
  127. imap_processing/tests/ultra/unit/test_ultra_l1b_annotated.py +31 -10
  128. imap_processing/tests/ultra/unit/test_ultra_l1b_extended.py +55 -35
  129. imap_processing/tests/ultra/unit/test_ultra_l1c_pset_bins.py +10 -68
  130. imap_processing/ultra/constants.py +12 -3
  131. imap_processing/ultra/l1b/de.py +168 -30
  132. imap_processing/ultra/l1b/ultra_l1b_annotated.py +24 -10
  133. imap_processing/ultra/l1b/ultra_l1b_extended.py +46 -80
  134. imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +60 -144
  135. imap_processing/ultra/utils/spatial_utils.py +221 -0
  136. {imap_processing-0.7.0.dist-info → imap_processing-0.9.0.dist-info}/METADATA +15 -14
  137. {imap_processing-0.7.0.dist-info → imap_processing-0.9.0.dist-info}/RECORD +142 -139
  138. imap_processing/cdf/cdf_attribute_manager.py +0 -322
  139. imap_processing/cdf/config/shared/default_global_cdf_attrs_schema.yaml +0 -246
  140. imap_processing/cdf/config/shared/default_variable_cdf_attrs_schema.yaml +0 -466
  141. imap_processing/hi/l0/decom_hi.py +0 -24
  142. imap_processing/hi/packet_definitions/hi_packet_definition.xml +0 -482
  143. imap_processing/hit/l0/data_classes/housekeeping.py +0 -240
  144. imap_processing/hit/l0/data_classes/science_packet.py +0 -259
  145. imap_processing/hit/l0/utils/hit_base.py +0 -57
  146. imap_processing/tests/cdf/shared/default_global_cdf_attrs_schema.yaml +0 -246
  147. imap_processing/tests/cdf/shared/default_variable_cdf_attrs_schema.yaml +0 -466
  148. imap_processing/tests/cdf/test_cdf_attribute_manager.py +0 -353
  149. imap_processing/tests/codice/data/imap_codice_l0_hi-counters-aggregated_20240429_v001.pkts +0 -0
  150. imap_processing/tests/codice/data/imap_codice_l0_hi-counters-singles_20240429_v001.pkts +0 -0
  151. imap_processing/tests/codice/data/imap_codice_l0_hi-omni_20240429_v001.pkts +0 -0
  152. imap_processing/tests/codice/data/imap_codice_l0_hi-pha_20240429_v001.pkts +0 -0
  153. imap_processing/tests/codice/data/imap_codice_l0_hi-sectored_20240429_v001.pkts +0 -0
  154. imap_processing/tests/codice/data/imap_codice_l0_hskp_20100101_v001.pkts +0 -0
  155. imap_processing/tests/codice/data/imap_codice_l0_lo-counters-aggregated_20240429_v001.pkts +0 -0
  156. imap_processing/tests/codice/data/imap_codice_l0_lo-counters-singles_20240429_v001.pkts +0 -0
  157. imap_processing/tests/codice/data/imap_codice_l0_lo-nsw-angular_20240429_v001.pkts +0 -0
  158. imap_processing/tests/codice/data/imap_codice_l0_lo-nsw-priority_20240429_v001.pkts +0 -0
  159. imap_processing/tests/codice/data/imap_codice_l0_lo-nsw-species_20240429_v001.pkts +0 -0
  160. imap_processing/tests/codice/data/imap_codice_l0_lo-pha_20240429_v001.pkts +0 -0
  161. imap_processing/tests/codice/data/imap_codice_l0_lo-sw-angular_20240429_v001.pkts +0 -0
  162. imap_processing/tests/codice/data/imap_codice_l0_lo-sw-priority_20240429_v001.pkts +0 -0
  163. imap_processing/tests/codice/data/imap_codice_l0_lo-sw-species_20240429_v001.pkts +0 -0
  164. imap_processing/tests/hi/test_decom.py +0 -55
  165. imap_processing/tests/hi/test_l1a_sci_de.py +0 -72
  166. imap_processing/tests/idex/imap_idex_l0_raw_20230725_v001.pkts +0 -0
  167. imap_processing/tests/mag/imap_mag_l1a_burst-magi_20231025_v001.cdf +0 -0
  168. /imap_processing/{hi/l0/__init__.py → tests/glows/test_glows_l2_data.py} +0 -0
  169. /imap_processing/tests/hit/test_data/{imap_hit_l0_hk_20100105_v001.pkts → imap_hit_l0_raw_20100105_v001.pkts} +0 -0
  170. {imap_processing-0.7.0.dist-info → imap_processing-0.9.0.dist-info}/LICENSE +0 -0
  171. {imap_processing-0.7.0.dist-info → imap_processing-0.9.0.dist-info}/WHEEL +0 -0
  172. {imap_processing-0.7.0.dist-info → imap_processing-0.9.0.dist-info}/entry_points.txt +0 -0
@@ -7,18 +7,18 @@ from imap_processing import imap_module_directory
7
7
 
8
8
 
9
9
  def test_idex_decom_length(decom_test_data: xr.Dataset):
10
- """Verify that there are 6 data variables in the output.
10
+ """Verify that the output data has the expected number of data variables.
11
11
 
12
12
  Parameters
13
13
  ----------
14
14
  decom_test_data : xarray.Dataset
15
15
  The dataset to test with
16
16
  """
17
- assert len(decom_test_data) == 42
17
+ assert len(decom_test_data) == 106
18
18
 
19
19
 
20
20
  def test_idex_decom_event_num(decom_test_data: xr.Dataset):
21
- """Verify that 19 impacts were gathered by the test data.
21
+ """Verify that 14 impacts were gathered by the test data.
22
22
 
23
23
  Parameters
24
24
  ----------
@@ -26,7 +26,7 @@ def test_idex_decom_event_num(decom_test_data: xr.Dataset):
26
26
  The dataset to test with
27
27
  """
28
28
  for var in decom_test_data:
29
- assert len(decom_test_data[var]) == 19
29
+ assert len(decom_test_data[var]) == 14
30
30
 
31
31
 
32
32
  def test_idex_tof_high_data(decom_test_data: xr.Dataset):
@@ -21,7 +21,7 @@ def test_idex_cdf_file(decom_test_data: xr.Dataset):
21
21
  file_name = write_cdf(decom_test_data)
22
22
 
23
23
  assert file_name.exists()
24
- assert file_name.name == "imap_idex_l1_sci_20230725_v001.cdf"
24
+ assert file_name.name == "imap_idex_l1a_sci_20231214_v001.cdf"
25
25
 
26
26
 
27
27
  def test_bad_cdf_attributes(decom_test_data: xr.Dataset):
@@ -32,11 +32,15 @@ def test_bad_cdf_attributes(decom_test_data: xr.Dataset):
32
32
  decom_test_data : xarray.Dataset
33
33
  The dataset to test with
34
34
  """
35
- del decom_test_data["TOF_High"].attrs["DEPEND_1"]
35
+ tof_catdesc = decom_test_data["TOF_High"].attrs["CATDESC"]
36
+ del decom_test_data["TOF_High"].attrs["CATDESC"]
36
37
 
37
38
  with pytest.raises(ISTPError):
38
39
  write_cdf(decom_test_data)
39
40
 
41
+ # Add attributes back so future tests do not fail
42
+ decom_test_data["TOF_High"].attrs["CATDESC"] = tof_catdesc
43
+
40
44
 
41
45
  def test_bad_cdf_file_data(decom_test_data: xr.Dataset):
42
46
  """Ensure an ``ISTPError`` is raised when using bad data.
@@ -72,6 +76,8 @@ def test_bad_cdf_file_data(decom_test_data: xr.Dataset):
72
76
  with pytest.raises(ISTPError):
73
77
  write_cdf(decom_test_data)
74
78
 
79
+ del decom_test_data["Bad_data"]
80
+
75
81
 
76
82
  def test_idex_tof_high_data_from_cdf(decom_test_data: xr.Dataset):
77
83
  """Verify that a sample of the data is correct inside the CDF file.
@@ -0,0 +1,126 @@
1
+ """Tests the L1b processing for IDEX data"""
2
+
3
+ from unittest import mock
4
+
5
+ import numpy as np
6
+ import pandas as pd
7
+ import pytest
8
+ import xarray as xr
9
+
10
+ from imap_processing import imap_module_directory
11
+ from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
12
+ from imap_processing.cdf.utils import write_cdf
13
+ from imap_processing.idex.idex_l1b import idex_l1b, unpack_instrument_settings
14
+
15
+
16
+ @pytest.fixture(scope="module")
17
+ def l1b_dataset(decom_test_data: xr.Dataset) -> xr.Dataset:
18
+ """Return a ``xarray`` dataset containing test data.
19
+
20
+ Returns
21
+ -------
22
+ dataset : xr.Dataset
23
+ A ``xarray`` dataset containing the test data
24
+ """
25
+ dataset = idex_l1b(decom_test_data, data_version="001")
26
+ return dataset
27
+
28
+
29
+ def test_l1b_cdf_filenames(l1b_dataset: xr.Dataset):
30
+ """Tests that the ``idex_l1b`` function generates datasets
31
+ with the expected logical source.
32
+
33
+ Parameters
34
+ ----------
35
+ l1b_dataset : xr.Dataset
36
+ A ``xarray`` dataset containing the test data
37
+ """
38
+ expected_src = "imap_idex_l1b_sci"
39
+ assert l1b_dataset.attrs["Logical_source"] == expected_src
40
+
41
+
42
+ def test_idex_cdf_file(l1b_dataset: xr.Dataset):
43
+ """Verify the CDF file can be created with no errors.
44
+
45
+ Parameters
46
+ ----------
47
+ l1b_dataset : xarray.Dataset
48
+ The dataset to test with
49
+ """
50
+
51
+ file_name = write_cdf(l1b_dataset)
52
+
53
+ assert file_name.exists()
54
+ assert file_name.name == "imap_idex_l1b_sci_20231214_v001.cdf"
55
+
56
+
57
+ def test_idex_waveform_units(l1b_dataset: xr.Dataset):
58
+ """Verify the CDF instrument settings and waveforms have the correct units.
59
+
60
+ Parameters
61
+ ----------
62
+ l1b_dataset : xarray.Dataset
63
+ The dataset to test with
64
+ """
65
+ cdf_var_defs_path = (
66
+ f"{imap_module_directory}/idex/idex_variable_unpacking_and_eu_conversion.csv"
67
+ )
68
+ cdf_var_defs = pd.read_csv(cdf_var_defs_path)
69
+
70
+ # Check instrument setting units
71
+ for _, row in cdf_var_defs.iterrows():
72
+ var_name = row["mnemonic"]
73
+ assert l1b_dataset[var_name].attrs["units"] == row["unit"]
74
+
75
+ # Check waveform units
76
+ waveform_var_names = [
77
+ "TOF_High",
78
+ "TOF_Low",
79
+ "TOF_Mid",
80
+ "Ion_Grid",
81
+ "Target_Low",
82
+ "Target_High",
83
+ ]
84
+
85
+ for var_name in waveform_var_names:
86
+ assert l1b_dataset[var_name].attrs["UNITS"] == "pC"
87
+
88
+
89
+ def test_unpack_instrument_settings():
90
+ """
91
+ Check that the instrument setting variables are being unpacked correctly
92
+
93
+ Example
94
+ -------
95
+ In this example, we are using a test variable that has five bits
96
+ Idx__test_var01 = 0b10010
97
+
98
+ Int(0b10010) = 18
99
+
100
+ This should unpack into test_var0, and test_var1
101
+ - test_var0 is two bits long and starts at 0, and the unpacked value should be 2
102
+ - test_var1 is three bits long and starts at 3, and the unpacked value should be 4
103
+ """
104
+ # Create test dataset with an array shape = 5 all values = 18
105
+ test_ds = xr.Dataset({"idx__test_var01": xr.DataArray(np.full(5, 18))})
106
+
107
+ test_cdf_defs_df = pd.DataFrame(
108
+ {
109
+ "mnemonic": ["test_var0", "test_var1"],
110
+ "var_name": ["idx__test_var01", "idx__test_var01"],
111
+ "starting_bit": [0, 2],
112
+ "nbits_padding_before": [0, 0],
113
+ "unsigned_nbits": [2, 3],
114
+ }
115
+ )
116
+ idex_attrs = ImapCdfAttributes()
117
+ # Mock attribute manager variable attrs
118
+ with mock.patch.object(
119
+ idex_attrs, "get_variable_attributes", return_value={"CATDESC": "Test var"}
120
+ ):
121
+ unpacked_dict = unpack_instrument_settings(
122
+ test_ds, test_cdf_defs_df, idex_attrs
123
+ )
124
+
125
+ assert np.all(unpacked_dict["test_var0"] == 2)
126
+ assert np.all(unpacked_dict["test_var1"] == 4)
@@ -1,29 +1,20 @@
1
- from pathlib import Path
2
-
3
1
  import numpy as np
4
- import pytest
5
2
 
6
3
  from imap_processing import imap_module_directory
7
4
  from imap_processing.lo.l1a.lo_l1a import lo_l1a
8
5
 
9
6
 
10
- @pytest.mark.skip(reason="not implemented")
11
- @pytest.mark.parametrize(
12
- ("dependency", "expected_logical_source"),
13
- [
14
- (Path("imap_lo_l0_de_20100101_v001.pkts"), "imap_lo_l1a_de"),
15
- (
16
- Path("imap_lo_l0_spin_20100101_v001.pkt"),
17
- "imap_lo_l1a_spin",
18
- ),
19
- ],
20
- )
21
- def test_lo_l1a(dependency, expected_logical_source):
7
+ def test_lo_l1a():
22
8
  # Act
9
+ dependency = (
10
+ imap_module_directory / "tests/lo/test_pkts/imap_lo_l0_raw_20240803_v002.pkts"
11
+ )
12
+ expected_logical_source = ["imap_lo_l1a_histogram", "imap_lo_l1a_de"]
23
13
  output_dataset = lo_l1a(dependency, "001")
24
14
 
25
15
  # Assert
26
- assert expected_logical_source == output_dataset.attrs["Logical_source"]
16
+ for dataset, logical_source in zip(output_dataset, expected_logical_source):
17
+ assert logical_source == dataset.attrs["Logical_source"]
27
18
 
28
19
 
29
20
  def test_lo_l1a_dataset():
@@ -1,8 +1,11 @@
1
1
  import numpy as np
2
+ import pandas as pd
2
3
  import pytest
3
4
  import xarray as xr
4
5
 
6
+ from imap_processing import imap_module_directory
5
7
  from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
8
+ from imap_processing.lo.l0.lo_apid import LoAPID
6
9
  from imap_processing.lo.l0.lo_science import (
7
10
  combine_segmented_packets,
8
11
  parse_de_bin,
@@ -10,10 +13,14 @@ from imap_processing.lo.l0.lo_science import (
10
13
  parse_fixed_fields,
11
14
  parse_variable_fields,
12
15
  )
16
+ from imap_processing.utils import convert_to_binary_string, packet_file_to_datasets
13
17
 
14
18
 
15
19
  @pytest.fixture()
16
20
  def fake_de_dataset():
21
+ # binary packet fields
22
+ count = "0000000000000010" # 2
23
+ passes = "00000000000000000000000000000001" # 1
17
24
  # DE One
18
25
  absent_1 = "0000" # case 0
19
26
  time_1 = "000001100100" # 100
@@ -37,7 +44,9 @@ def fake_de_dataset():
37
44
  pos_2 = "00" # 0
38
45
 
39
46
  de_data = (
40
- absent_1
47
+ count
48
+ + passes
49
+ + absent_1
41
50
  + time_1
42
51
  + energy_1
43
52
  + mode_1
@@ -55,13 +64,27 @@ def fake_de_dataset():
55
64
  dataset = xr.Dataset(
56
65
  data_vars=dict(
57
66
  count=(["time"], np.array([2])),
58
- data=(["time"], np.array([de_data])),
67
+ events=(["time"], np.array([de_data])),
59
68
  )
60
69
  )
61
70
 
62
71
  return dataset
63
72
 
64
73
 
74
+ @pytest.fixture()
75
+ def sample_data():
76
+ xtce_file = imap_module_directory / "lo/packet_definitions/lo_xtce.xml"
77
+ dependency = (
78
+ imap_module_directory / "tests/lo/test_pkts/imap_lo_l0_raw_20240803_v002.pkts"
79
+ )
80
+ datasets_by_apid = packet_file_to_datasets(
81
+ packet_file=dependency.resolve(),
82
+ xtce_packet_definition=xtce_file.resolve(),
83
+ use_derived_value=False,
84
+ )
85
+ return datasets_by_apid
86
+
87
+
65
88
  @pytest.fixture()
66
89
  def segmented_pkts_fake_data():
67
90
  dataset = xr.Dataset(
@@ -142,6 +165,9 @@ def test_parse_events(fake_de_dataset, attr_mgr):
142
165
 
143
166
 
144
167
  def test_parse_fixed_fields(initialized_dataset):
168
+ # Arrange
169
+ initialized_dataset.attrs["bit_pos"] = 48
170
+
145
171
  # Act
146
172
  dataset = parse_fixed_fields(initialized_dataset, 0, 0)
147
173
 
@@ -158,7 +184,7 @@ def test_parse_variable_fields(initialized_dataset):
158
184
  # Arrange
159
185
  initialized_dataset["coincidence_type"].values = np.array([0, 255])
160
186
  initialized_dataset["mode"].values = np.array([1, 255])
161
- initialized_dataset.attrs["bit_pos"] = 20
187
+ initialized_dataset.attrs["bit_pos"] = 68
162
188
 
163
189
  # Act
164
190
  dataset = parse_variable_fields(initialized_dataset, 0, 0)
@@ -195,10 +221,48 @@ def test_combine_segmented_packets(segmented_pkts_fake_data):
195
221
  dataset["events"].values,
196
222
  np.array(
197
223
  [
198
- "0000000001,0000000010,0000000100,0000001000",
224
+ "0000000001000000001000000001000000001000",
199
225
  "0000010000",
200
- "0100000000,1000000000",
226
+ "01000000001000000000",
201
227
  ]
202
228
  ),
203
229
  )
204
230
  np.testing.assert_array_equal(dataset["epoch"].values, np.array([0, 10, 30]))
231
+
232
+
233
+ def test_validate_parse_events(sample_data, attr_mgr):
234
+ de_data = sample_data[LoAPID.ILO_SCI_DE]
235
+ validation_path = (
236
+ imap_module_directory / "tests/lo/validation_data/"
237
+ "Instrument_FM1_T104_R129_20240803_ILO_SCI_DE_dec_DN_with_fills.csv"
238
+ )
239
+
240
+ validation_data = pd.read_csv(validation_path)
241
+ de_fields = [
242
+ "coincidence_type",
243
+ "de_time",
244
+ "esa_step",
245
+ "mode",
246
+ "tof0",
247
+ "tof1",
248
+ "tof2",
249
+ "tof3",
250
+ "cksm",
251
+ "pos",
252
+ ]
253
+
254
+ de_data["data"] = xr.DataArray(
255
+ [convert_to_binary_string(data) for data in de_data["data"].values],
256
+ dims=de_data["data"].dims,
257
+ attrs=de_data["data"].attrs,
258
+ )
259
+ de_data = combine_segmented_packets(de_data)
260
+ dataset = parse_events(de_data, attr_mgr)
261
+
262
+ for field in de_fields:
263
+ np.testing.assert_array_equal(
264
+ dataset[field].values, validation_data[field.upper()].values
265
+ )
266
+
267
+ assert dataset["de_count"].values == 1998
268
+ assert dataset["passes"].values == 8