imap-processing 0.9.0__py3-none-any.whl → 0.11.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 +749 -442
- imap_processing/cdf/config/imap_glows_global_cdf_attrs.yaml +7 -0
- imap_processing/cdf/config/imap_glows_l1a_variable_attrs.yaml +8 -2
- imap_processing/cdf/config/imap_glows_l1b_variable_attrs.yaml +0 -1
- imap_processing/cdf/config/imap_glows_l2_variable_attrs.yaml +358 -0
- imap_processing/cdf/config/imap_hi_variable_attrs.yaml +59 -25
- imap_processing/cdf/config/imap_hit_global_cdf_attrs.yaml +22 -0
- imap_processing/cdf/config/imap_idex_l1a_variable_attrs.yaml +32 -8
- imap_processing/cdf/config/imap_idex_l1b_variable_attrs.yaml +94 -5
- imap_processing/cdf/config/imap_lo_l1a_variable_attrs.yaml +65 -37
- imap_processing/cdf/config/imap_swapi_variable_attrs.yaml +16 -1
- imap_processing/cdf/config/imap_swe_global_cdf_attrs.yaml +7 -0
- imap_processing/cdf/config/imap_swe_l1a_variable_attrs.yaml +14 -14
- imap_processing/cdf/config/imap_swe_l1b_variable_attrs.yaml +25 -24
- imap_processing/cdf/config/imap_swe_l2_variable_attrs.yaml +238 -0
- imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +100 -92
- imap_processing/cdf/utils.py +2 -2
- imap_processing/cli.py +45 -9
- imap_processing/codice/codice_l1a.py +104 -58
- imap_processing/codice/constants.py +111 -155
- imap_processing/codice/data/esa_sweep_values.csv +256 -256
- imap_processing/codice/data/lo_stepping_values.csv +128 -128
- imap_processing/ena_maps/ena_maps.py +519 -0
- imap_processing/ena_maps/utils/map_utils.py +145 -0
- imap_processing/ena_maps/utils/spatial_utils.py +226 -0
- imap_processing/glows/__init__.py +3 -0
- imap_processing/glows/ancillary/imap_glows_pipeline_settings_v001.json +52 -0
- imap_processing/glows/l1a/glows_l1a.py +72 -14
- imap_processing/glows/l1b/glows_l1b.py +2 -1
- imap_processing/glows/l1b/glows_l1b_data.py +25 -1
- imap_processing/glows/l2/glows_l2.py +324 -0
- imap_processing/glows/l2/glows_l2_data.py +156 -51
- imap_processing/hi/l1a/science_direct_event.py +57 -51
- imap_processing/hi/l1b/hi_l1b.py +43 -28
- imap_processing/hi/l1c/hi_l1c.py +225 -42
- imap_processing/hi/utils.py +20 -3
- imap_processing/hit/l0/constants.py +2 -2
- imap_processing/hit/l0/decom_hit.py +1 -1
- imap_processing/hit/l1a/hit_l1a.py +94 -13
- imap_processing/hit/l1b/hit_l1b.py +158 -9
- imap_processing/ialirt/l0/process_codicehi.py +156 -0
- imap_processing/ialirt/l0/process_codicelo.py +5 -2
- imap_processing/ialirt/packet_definitions/ialirt.xml +28 -20
- imap_processing/ialirt/packet_definitions/ialirt_codicehi.xml +241 -0
- imap_processing/ialirt/packet_definitions/ialirt_swapi.xml +170 -0
- imap_processing/ialirt/packet_definitions/ialirt_swe.xml +258 -0
- imap_processing/ialirt/process_ephemeris.py +72 -40
- imap_processing/idex/decode.py +241 -0
- imap_processing/idex/idex_l1a.py +143 -81
- imap_processing/idex/idex_l1b.py +244 -10
- imap_processing/lo/l0/lo_science.py +61 -0
- imap_processing/lo/l1a/lo_l1a.py +98 -10
- imap_processing/lo/l1b/lo_l1b.py +2 -2
- imap_processing/lo/l1c/lo_l1c.py +2 -2
- imap_processing/lo/packet_definitions/lo_xtce.xml +1082 -9178
- imap_processing/mag/l0/decom_mag.py +2 -2
- imap_processing/mag/l1a/mag_l1a.py +7 -7
- imap_processing/mag/l1a/mag_l1a_data.py +62 -30
- imap_processing/mag/l1b/mag_l1b.py +11 -6
- imap_processing/quality_flags.py +18 -3
- imap_processing/spice/geometry.py +149 -177
- imap_processing/spice/kernels.py +26 -26
- imap_processing/spice/spin.py +233 -0
- imap_processing/spice/time.py +96 -31
- imap_processing/swapi/l1/swapi_l1.py +60 -31
- imap_processing/swapi/packet_definitions/swapi_packet_definition.xml +363 -384
- imap_processing/swe/l1a/swe_l1a.py +8 -3
- imap_processing/swe/l1a/swe_science.py +24 -24
- imap_processing/swe/l1b/swe_l1b.py +2 -1
- imap_processing/swe/l1b/swe_l1b_science.py +181 -122
- imap_processing/swe/l2/swe_l2.py +337 -70
- imap_processing/swe/utils/swe_utils.py +28 -0
- imap_processing/tests/cdf/test_utils.py +2 -2
- imap_processing/tests/codice/conftest.py +20 -17
- imap_processing/tests/codice/data/validation/imap_codice_l1a_hskp_20241110193622_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-counters-aggregated_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-counters-singles_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-nsw-angular_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-nsw-priority_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-nsw-species_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-sw-angular_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-sw-priority_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-sw-species_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/test_codice_l0.py +55 -121
- imap_processing/tests/codice/test_codice_l1a.py +147 -59
- imap_processing/tests/conftest.py +81 -22
- imap_processing/tests/ena_maps/test_ena_maps.py +309 -0
- imap_processing/tests/ena_maps/test_map_utils.py +286 -0
- imap_processing/tests/ena_maps/test_spatial_utils.py +161 -0
- imap_processing/tests/glows/conftest.py +7 -1
- imap_processing/tests/glows/test_glows_l1a_cdf.py +3 -7
- imap_processing/tests/glows/test_glows_l1a_data.py +34 -6
- imap_processing/tests/glows/test_glows_l1b_data.py +29 -17
- imap_processing/tests/glows/test_glows_l2.py +101 -0
- imap_processing/tests/hi/conftest.py +3 -3
- imap_processing/tests/hi/data/l1/imap_hi_l1b_45sensor-de_20250415_v999.cdf +0 -0
- imap_processing/tests/hi/data/l1/imap_his_pset-calibration-prod-config_20240101_v001.csv +31 -0
- imap_processing/tests/hi/test_hi_l1b.py +14 -9
- imap_processing/tests/hi/test_hi_l1c.py +136 -36
- imap_processing/tests/hi/test_l1a.py +0 -2
- imap_processing/tests/hi/test_science_direct_event.py +18 -14
- imap_processing/tests/hi/test_utils.py +16 -11
- imap_processing/tests/hit/helpers/__init__.py +0 -0
- imap_processing/tests/hit/helpers/l1_validation.py +405 -0
- imap_processing/tests/hit/test_data/sci_sample.ccsds +0 -0
- imap_processing/tests/hit/test_decom_hit.py +8 -10
- imap_processing/tests/hit/test_hit_l1a.py +117 -180
- imap_processing/tests/hit/test_hit_l1b.py +149 -55
- imap_processing/tests/hit/validation_data/hit_l1b_standard_sample2_nsrl_v4_3decimals.csv +62 -0
- imap_processing/tests/hit/validation_data/sci_sample_raw.csv +62 -0
- imap_processing/tests/ialirt/test_data/l0/20240827095047_SWE_IALIRT_packet.bin +0 -0
- imap_processing/tests/ialirt/test_data/l0/BinLog CCSDS_FRAG_TLM_20240826_152323Z_IALIRT_data_for_SDC.bin +0 -0
- imap_processing/tests/ialirt/test_data/l0/eu_SWP_IAL_20240826_152033.csv +644 -0
- imap_processing/tests/ialirt/test_data/l0/hi_fsw_view_1_ccsds.bin +0 -0
- imap_processing/tests/ialirt/test_data/l0/idle_export_eu.SWE_IALIRT_20240827_093852.csv +914 -0
- imap_processing/tests/ialirt/test_data/l0/imap_codice_l1a_hi-ialirt_20240523200000_v0.0.0.cdf +0 -0
- imap_processing/tests/ialirt/unit/test_process_codicehi.py +106 -0
- imap_processing/tests/ialirt/unit/test_process_ephemeris.py +33 -5
- imap_processing/tests/ialirt/unit/test_process_swapi.py +85 -0
- imap_processing/tests/ialirt/unit/test_process_swe.py +106 -0
- imap_processing/tests/idex/conftest.py +29 -1
- imap_processing/tests/idex/test_data/compressed_2023_102_14_24_55.pkts +0 -0
- imap_processing/tests/idex/test_data/non_compressed_2023_102_14_22_26.pkts +0 -0
- imap_processing/tests/idex/test_idex_l0.py +6 -3
- imap_processing/tests/idex/test_idex_l1a.py +151 -1
- imap_processing/tests/idex/test_idex_l1b.py +124 -2
- imap_processing/tests/lo/test_lo_l1a.py +62 -2
- imap_processing/tests/lo/test_lo_science.py +85 -0
- imap_processing/tests/lo/validation_data/Instrument_FM1_T104_R129_20240803_ILO_SPIN_EU.csv +2 -0
- imap_processing/tests/mag/conftest.py +16 -0
- imap_processing/tests/mag/test_mag_decom.py +6 -4
- imap_processing/tests/mag/test_mag_l1a.py +36 -7
- imap_processing/tests/mag/test_mag_l1b.py +55 -4
- imap_processing/tests/mag/test_mag_validation.py +148 -0
- imap_processing/tests/mag/validation/L1a/T001/all_p_ones.txt +19200 -0
- imap_processing/tests/mag/validation/L1a/T001/mag-l0-l1a-t001-in.bin +0 -0
- imap_processing/tests/mag/validation/L1a/T001/mag-l0-l1a-t001-out.csv +17 -0
- imap_processing/tests/mag/validation/L1a/T002/all_n_ones.txt +19200 -0
- imap_processing/tests/mag/validation/L1a/T002/mag-l0-l1a-t002-in.bin +0 -0
- imap_processing/tests/mag/validation/L1a/T002/mag-l0-l1a-t002-out.csv +17 -0
- imap_processing/tests/mag/validation/L1a/T003/field_like.txt +19200 -0
- imap_processing/tests/mag/validation/L1a/T003/mag-l0-l1a-t003-in.bin +0 -0
- imap_processing/tests/mag/validation/L1a/T003/mag-l0-l1a-t003-out.csv +17 -0
- imap_processing/tests/mag/validation/L1a/T004/field_like.txt +19200 -0
- imap_processing/tests/mag/validation/L1a/T004/mag-l0-l1a-t004-in.bin +0 -0
- imap_processing/tests/mag/validation/L1a/T004/mag-l0-l1a-t004-out.csv +17 -0
- imap_processing/tests/mag/validation/L1a/T005/field_like_range_change.txt +19200 -0
- imap_processing/tests/mag/validation/L1a/T005/mag-l0-l1a-t005-in.bin +0 -0
- imap_processing/tests/mag/validation/L1a/T005/mag-l0-l1a-t005-out.csv +17 -0
- imap_processing/tests/mag/validation/L1a/T006/hdr_field.txt +19200 -0
- imap_processing/tests/mag/validation/L1a/T006/mag-l0-l1a-t006-in.bin +0 -0
- imap_processing/tests/mag/validation/L1a/T006/mag-l0-l1a-t006-out.csv +17 -0
- imap_processing/tests/mag/validation/L1a/T007/hdr_field_and_range_change.txt +19200 -0
- imap_processing/tests/mag/validation/L1a/T007/mag-l0-l1a-t007-in.bin +0 -0
- imap_processing/tests/mag/validation/L1a/T007/mag-l0-l1a-t007-out.csv +17 -0
- imap_processing/tests/mag/validation/L1a/T008/field_like_range_change.txt +19200 -0
- imap_processing/tests/mag/validation/L1a/T008/mag-l0-l1a-t008-in.bin +0 -0
- imap_processing/tests/mag/validation/L1a/T008/mag-l0-l1a-t008-out.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T009/data.bin +0 -0
- imap_processing/tests/mag/validation/L1b/T009/field_like_all_ranges.txt +19200 -0
- imap_processing/tests/mag/validation/L1b/T009/mag-l1a-l1b-t009-in.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T009/mag-l1a-l1b-t009-magi-out.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T009/mag-l1a-l1b-t009-mago-out.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T010/data.bin +0 -0
- imap_processing/tests/mag/validation/L1b/T010/field_like_all_ranges.txt +19200 -0
- imap_processing/tests/mag/validation/L1b/T010/mag-l1a-l1b-t010-in.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T010/mag-l1a-l1b-t010-magi-out.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T010/mag-l1a-l1b-t010-mago-out.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T011/data.bin +0 -0
- imap_processing/tests/mag/validation/L1b/T011/field_like_all_ranges.txt +19200 -0
- imap_processing/tests/mag/validation/L1b/T011/mag-l1a-l1b-t011-in.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T011/mag-l1a-l1b-t011-magi-out.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T011/mag-l1a-l1b-t011-mago-out.csv +17 -0
- imap_processing/tests/spice/test_geometry.py +128 -133
- imap_processing/tests/spice/test_kernels.py +37 -37
- imap_processing/tests/spice/test_spin.py +184 -0
- imap_processing/tests/spice/test_time.py +43 -20
- imap_processing/tests/swapi/test_swapi_l1.py +11 -10
- imap_processing/tests/swapi/test_swapi_l2.py +13 -3
- imap_processing/tests/swe/test_swe_l1a.py +1 -1
- imap_processing/tests/swe/test_swe_l1b.py +20 -3
- imap_processing/tests/swe/test_swe_l1b_science.py +54 -35
- imap_processing/tests/swe/test_swe_l2.py +148 -5
- imap_processing/tests/test_cli.py +39 -7
- imap_processing/tests/test_quality_flags.py +19 -19
- imap_processing/tests/test_utils.py +3 -2
- imap_processing/tests/ultra/test_data/l0/ultra45_raw_sc_ultrarawimg_withFSWcalcs_FM45_40P_Phi28p5_BeamCal_LinearScan_phi2850_theta-000_20240207T102740.csv +3314 -3314
- imap_processing/tests/ultra/test_data/mock_data.py +161 -0
- imap_processing/tests/ultra/unit/conftest.py +73 -0
- imap_processing/tests/ultra/unit/test_badtimes.py +58 -0
- imap_processing/tests/ultra/unit/test_cullingmask.py +87 -0
- imap_processing/tests/ultra/unit/test_de.py +61 -60
- imap_processing/tests/ultra/unit/test_ultra_l1a.py +3 -3
- imap_processing/tests/ultra/unit/test_ultra_l1b.py +51 -77
- imap_processing/tests/ultra/unit/test_ultra_l1b_annotated.py +5 -5
- imap_processing/tests/ultra/unit/test_ultra_l1b_culling.py +114 -0
- imap_processing/tests/ultra/unit/test_ultra_l1b_extended.py +86 -26
- imap_processing/tests/ultra/unit/test_ultra_l1c.py +1 -1
- imap_processing/tests/ultra/unit/test_ultra_l1c_pset_bins.py +3 -3
- imap_processing/ultra/constants.py +11 -1
- imap_processing/ultra/l1a/ultra_l1a.py +2 -2
- imap_processing/ultra/l1b/badtimes.py +22 -5
- imap_processing/ultra/l1b/cullingmask.py +31 -5
- imap_processing/ultra/l1b/de.py +32 -37
- imap_processing/ultra/l1b/extendedspin.py +44 -20
- imap_processing/ultra/l1b/ultra_l1b.py +21 -22
- imap_processing/ultra/l1b/ultra_l1b_culling.py +190 -0
- imap_processing/ultra/l1b/ultra_l1b_extended.py +81 -30
- imap_processing/ultra/l1c/histogram.py +6 -2
- imap_processing/ultra/l1c/pset.py +6 -2
- imap_processing/ultra/l1c/ultra_l1c.py +2 -3
- imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +4 -3
- imap_processing/ultra/utils/ultra_l1_utils.py +70 -14
- imap_processing/utils.py +2 -2
- {imap_processing-0.9.0.dist-info → imap_processing-0.11.0.dist-info}/METADATA +7 -2
- {imap_processing-0.9.0.dist-info → imap_processing-0.11.0.dist-info}/RECORD +235 -152
- imap_processing/tests/codice/data/eu_unit_lookup_table.csv +0 -101
- imap_processing/tests/codice/data/idle_export_eu.COD_NHK_20230822_122700 2.csv +0 -100
- imap_processing/tests/codice/data/idle_export_raw.COD_NHK_20230822_122700.csv +0 -100
- imap_processing/tests/codice/data/imap_codice_l0_raw_20241110_v001.pkts +0 -0
- imap_processing/tests/hi/test_data/l1a/imap_hi_l1a_45sensor-de_20250415_v000.cdf +0 -0
- imap_processing/tests/hit/test_data/sci_sample1.ccsds +0 -0
- imap_processing/tests/ultra/unit/test_spatial_utils.py +0 -125
- imap_processing/ultra/utils/spatial_utils.py +0 -221
- /imap_processing/tests/hi/{test_data → data}/l0/20231030_H45_APP_NHK.bin +0 -0
- /imap_processing/tests/hi/{test_data → data}/l0/20231030_H45_APP_NHK.csv +0 -0
- /imap_processing/tests/hi/{test_data → data}/l0/20231030_H45_SCI_CNT.bin +0 -0
- /imap_processing/tests/hi/{test_data → data}/l0/20231030_H45_SCI_DE.bin +0 -0
- /imap_processing/tests/hi/{test_data → data}/l0/H90_NHK_20241104.bin +0 -0
- /imap_processing/tests/hi/{test_data → data}/l0/H90_sci_cnt_20241104.bin +0 -0
- /imap_processing/tests/hi/{test_data → data}/l0/H90_sci_de_20241104.bin +0 -0
- /imap_processing/tests/hi/{test_data → data}/l0/README.txt +0 -0
- /imap_processing/tests/idex/{imap_idex_l0_raw_20231214_v001.pkts → test_data/imap_idex_l0_raw_20231214_v001.pkts} +0 -0
- /imap_processing/tests/idex/{impact_14_tof_high_data.txt → test_data/impact_14_tof_high_data.txt} +0 -0
- /imap_processing/tests/mag/{imap_mag_l1a_norm-magi_20251017_v001.cdf → validation/imap_mag_l1a_norm-magi_20251017_v001.cdf} +0 -0
- /imap_processing/tests/mag/{mag_l0_test_data.pkts → validation/mag_l0_test_data.pkts} +0 -0
- /imap_processing/tests/mag/{mag_l0_test_output.csv → validation/mag_l0_test_output.csv} +0 -0
- /imap_processing/tests/mag/{mag_l1_test_data.pkts → validation/mag_l1_test_data.pkts} +0 -0
- /imap_processing/tests/mag/{mag_l1a_test_output.csv → validation/mag_l1a_test_output.csv} +0 -0
- {imap_processing-0.9.0.dist-info → imap_processing-0.11.0.dist-info}/LICENSE +0 -0
- {imap_processing-0.9.0.dist-info → imap_processing-0.11.0.dist-info}/WHEEL +0 -0
- {imap_processing-0.9.0.dist-info → imap_processing-0.11.0.dist-info}/entry_points.txt +0 -0
|
Binary file
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import pytest
|
|
3
|
+
|
|
4
|
+
from imap_processing import imap_module_directory
|
|
5
|
+
from imap_processing.cdf.utils import load_cdf
|
|
6
|
+
from imap_processing.ialirt.l0.process_codicehi import (
|
|
7
|
+
append_cod_hi_data,
|
|
8
|
+
find_groups,
|
|
9
|
+
process_codicehi,
|
|
10
|
+
)
|
|
11
|
+
from imap_processing.utils import packet_file_to_datasets
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@pytest.fixture(scope="session")
|
|
15
|
+
def xtce_codicehi_path():
|
|
16
|
+
"""Returns the xtce directory."""
|
|
17
|
+
return (
|
|
18
|
+
imap_module_directory / "ialirt" / "packet_definitions" / "ialirt_codicehi.xml"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@pytest.fixture(scope="session")
|
|
23
|
+
def binary_packet_path():
|
|
24
|
+
"""Returns the xtce directory."""
|
|
25
|
+
return (
|
|
26
|
+
imap_module_directory
|
|
27
|
+
/ "tests"
|
|
28
|
+
/ "ialirt"
|
|
29
|
+
/ "test_data"
|
|
30
|
+
/ "l0"
|
|
31
|
+
/ "hi_fsw_view_1_ccsds.bin"
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@pytest.fixture(scope="session")
|
|
36
|
+
def codicehi_validation_data():
|
|
37
|
+
"""Returns the test data directory."""
|
|
38
|
+
data_path = (
|
|
39
|
+
imap_module_directory
|
|
40
|
+
/ "tests"
|
|
41
|
+
/ "ialirt"
|
|
42
|
+
/ "test_data"
|
|
43
|
+
/ "l0"
|
|
44
|
+
/ "imap_codice_l1a_hi-ialirt_20240523200000_v0.0.0.cdf"
|
|
45
|
+
)
|
|
46
|
+
data = load_cdf(data_path)
|
|
47
|
+
|
|
48
|
+
return data
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@pytest.fixture()
|
|
52
|
+
def codicehi_test_data(binary_packet_path, xtce_codicehi_path):
|
|
53
|
+
"""Create xarray data"""
|
|
54
|
+
apid = 1168
|
|
55
|
+
codicehi_test_data = packet_file_to_datasets(
|
|
56
|
+
binary_packet_path, xtce_codicehi_path
|
|
57
|
+
)[apid]
|
|
58
|
+
|
|
59
|
+
return codicehi_test_data
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def test_find_groups(codicehi_test_data):
|
|
63
|
+
"""Tests find_groups"""
|
|
64
|
+
|
|
65
|
+
grouped_data = find_groups(codicehi_test_data)
|
|
66
|
+
unique_groups = np.unique(grouped_data["group"])
|
|
67
|
+
for group in unique_groups:
|
|
68
|
+
group_data = grouped_data["cod_hi_counter"].values[
|
|
69
|
+
grouped_data["group"] == group
|
|
70
|
+
]
|
|
71
|
+
np.testing.assert_array_equal(group_data, np.arange(234))
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def test_append_cod_hi_data(codicehi_test_data):
|
|
75
|
+
"""Tests append_cod_hi_data"""
|
|
76
|
+
|
|
77
|
+
grouped_data = find_groups(codicehi_test_data)
|
|
78
|
+
unique_groups = np.unique(grouped_data["group"])
|
|
79
|
+
for group in unique_groups:
|
|
80
|
+
mask = grouped_data["group"] == group
|
|
81
|
+
filtered_indices = np.where(mask)[0]
|
|
82
|
+
group_data = grouped_data.isel(epoch=filtered_indices)
|
|
83
|
+
expected_cod_hi_counter = np.repeat(group_data["cod_hi_counter"].values, 5)
|
|
84
|
+
appended_data = append_cod_hi_data(group_data)
|
|
85
|
+
assert np.array_equal(
|
|
86
|
+
appended_data["cod_hi_counter"].values, expected_cod_hi_counter.astype(int)
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_process_codicehi(codicehi_test_data, codicehi_validation_data, caplog):
|
|
91
|
+
"""Tests process_codicehi."""
|
|
92
|
+
codicehi_product = process_codicehi(codicehi_test_data)
|
|
93
|
+
assert codicehi_product == [{}]
|
|
94
|
+
|
|
95
|
+
indices = (codicehi_test_data["cod_hi_acq"] != 0).values.nonzero()[0]
|
|
96
|
+
codicehi_test_data["cod_hi_counter"].values[indices[0] : indices[0] + 234] = (
|
|
97
|
+
np.random.permutation(234)
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
with caplog.at_level("WARNING"):
|
|
101
|
+
process_codicehi(codicehi_test_data)
|
|
102
|
+
|
|
103
|
+
assert any(
|
|
104
|
+
"does not contain all values from 0 to 233 without duplicates" in message
|
|
105
|
+
for message in caplog.text.splitlines()
|
|
106
|
+
)
|
|
@@ -7,20 +7,46 @@ from imap_processing.ialirt import process_ephemeris
|
|
|
7
7
|
from imap_processing.spice.time import str_to_et
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
@pytest.mark.external_kernel()
|
|
11
|
+
def test_calculate_doppler(furnish_kernels):
|
|
11
12
|
"""
|
|
12
13
|
Test the calculate_doppler() function.
|
|
13
14
|
"""
|
|
14
|
-
|
|
15
|
+
longitude = -71.41 # longitude in degrees
|
|
16
|
+
latitude = -33.94 # latitude in degrees
|
|
17
|
+
altitude = 0.157 # altitude in kilometers
|
|
18
|
+
# test single observation time
|
|
19
|
+
observation_time = 843307269.1823885 # "2026-09-22T00:00:00.000"
|
|
20
|
+
|
|
21
|
+
kernels = [
|
|
22
|
+
"pck00011.tpc",
|
|
23
|
+
"imap_spk_demo.bsp",
|
|
24
|
+
"de440s.bsp",
|
|
25
|
+
"earth_1962_240827_2124_combined.bpc",
|
|
26
|
+
]
|
|
27
|
+
with furnish_kernels(kernels):
|
|
28
|
+
doppler_result = process_ephemeris.calculate_doppler(
|
|
29
|
+
longitude, latitude, altitude, observation_time
|
|
30
|
+
)
|
|
31
|
+
assert doppler_result is not None
|
|
32
|
+
|
|
33
|
+
# test array of observation times
|
|
34
|
+
time_endpoints = ("2026 SEP 22 00:00:00", "2026 SEP 22 23:59:59")
|
|
35
|
+
time_interval = int(1e3) # seconds between data points
|
|
36
|
+
observation_time = np.arange(
|
|
37
|
+
str_to_et(time_endpoints[0]), str_to_et(time_endpoints[1]), time_interval
|
|
38
|
+
)
|
|
39
|
+
with furnish_kernels(kernels):
|
|
40
|
+
doppler_result = process_ephemeris.calculate_doppler(
|
|
41
|
+
longitude, latitude, altitude, observation_time
|
|
42
|
+
)
|
|
43
|
+
assert doppler_result is not None
|
|
15
44
|
|
|
16
45
|
|
|
17
46
|
@pytest.mark.external_kernel()
|
|
18
47
|
def test_latitude_longitude_to_ecef(furnish_kernels):
|
|
19
48
|
"""
|
|
20
49
|
Test the latitude_longitude_to_ecef() function.
|
|
21
|
-
|
|
22
|
-
Test data is from https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/
|
|
23
|
-
georec_c.html.
|
|
24
50
|
"""
|
|
25
51
|
longitude = 118.0 # degrees
|
|
26
52
|
latitude = 30.0 # degrees
|
|
@@ -92,6 +118,8 @@ def test_build_output(furnish_kernels):
|
|
|
92
118
|
"naif0012.tls",
|
|
93
119
|
"pck00011.tpc",
|
|
94
120
|
"de440s.bsp",
|
|
121
|
+
"imap_spk_demo.bsp",
|
|
122
|
+
"earth_1962_240827_2124_combined.bpc",
|
|
95
123
|
]
|
|
96
124
|
with furnish_kernels(kernels):
|
|
97
125
|
output_dict = process_ephemeris.build_output(
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import pandas as pd
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from imap_processing import imap_module_directory
|
|
6
|
+
from imap_processing.utils import packet_file_to_datasets
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@pytest.fixture(scope="session")
|
|
10
|
+
def xtce_swapi_path():
|
|
11
|
+
"""Returns the xtce auxiliary directory."""
|
|
12
|
+
return imap_module_directory / "ialirt" / "packet_definitions" / "ialirt_swapi.xml"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@pytest.fixture(scope="session")
|
|
16
|
+
def binary_packet_path():
|
|
17
|
+
"""Returns the xtce directory."""
|
|
18
|
+
return (
|
|
19
|
+
imap_module_directory
|
|
20
|
+
/ "tests"
|
|
21
|
+
/ "ialirt"
|
|
22
|
+
/ "test_data"
|
|
23
|
+
/ "l0"
|
|
24
|
+
/ "BinLog CCSDS_FRAG_TLM_20240826_152323Z_IALIRT_data_for_SDC.bin"
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@pytest.fixture(scope="session")
|
|
29
|
+
def swapi_test_data():
|
|
30
|
+
"""Returns the test data directory."""
|
|
31
|
+
data_path = (
|
|
32
|
+
imap_module_directory
|
|
33
|
+
/ "tests"
|
|
34
|
+
/ "ialirt"
|
|
35
|
+
/ "test_data"
|
|
36
|
+
/ "l0"
|
|
37
|
+
/ "eu_SWP_IAL_20240826_152033.csv"
|
|
38
|
+
)
|
|
39
|
+
data = pd.read_csv(data_path)
|
|
40
|
+
|
|
41
|
+
return data
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@pytest.fixture()
|
|
45
|
+
def xarray_data(binary_packet_path, xtce_swapi_path):
|
|
46
|
+
"""Create xarray data"""
|
|
47
|
+
apid = 1187
|
|
48
|
+
|
|
49
|
+
xarray_data = packet_file_to_datasets(
|
|
50
|
+
binary_packet_path, xtce_swapi_path, use_derived_value=True
|
|
51
|
+
)[apid]
|
|
52
|
+
return xarray_data
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_decom_packets(xarray_data, swapi_test_data):
|
|
56
|
+
"""This function checks that all instrument parameters are accounted for."""
|
|
57
|
+
|
|
58
|
+
# TODO: confirm w/ SWAPI team validity_enum flag can be
|
|
59
|
+
# consistent with other instruments.
|
|
60
|
+
fields_to_test = {
|
|
61
|
+
"swapi_flag": "I_ALIRT_STATUS",
|
|
62
|
+
"swapi_reserved": "INST_RES_ST",
|
|
63
|
+
"swapi_seq": "SEQ_NUMBER",
|
|
64
|
+
"swapi_version": "SWEEP_TABLE",
|
|
65
|
+
"swapi_coin_1": "COIN_CNT0",
|
|
66
|
+
"swapi_coin_2": "COIN_CNT1",
|
|
67
|
+
"swapi_coin_3": "COIN_CNT2",
|
|
68
|
+
"swapi_coin_4": "COIN_CNT3",
|
|
69
|
+
"swapi_coin_5": "COIN_CNT4",
|
|
70
|
+
"swapi_coin_6": "COIN_CNT5",
|
|
71
|
+
"swapi_spare": "SPARE",
|
|
72
|
+
}
|
|
73
|
+
_, index, test_index = np.intersect1d(
|
|
74
|
+
xarray_data["swapi_acq"], swapi_test_data["ACQ_TIME"], return_indices=True
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
for xarray_field, test_field in fields_to_test.items():
|
|
78
|
+
actual_values = xarray_data[xarray_field].values[index]
|
|
79
|
+
expected_values = swapi_test_data[test_field].values[test_index]
|
|
80
|
+
|
|
81
|
+
# Assert that all values match
|
|
82
|
+
assert np.all(actual_values == expected_values), (
|
|
83
|
+
f"Mismatch found in {xarray_field}: "
|
|
84
|
+
f"actual {actual_values}, expected {expected_values}"
|
|
85
|
+
)
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import pandas as pd
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from imap_processing import imap_module_directory
|
|
6
|
+
from imap_processing.utils import packet_file_to_datasets
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@pytest.fixture(scope="session")
|
|
10
|
+
def xtce_swe_path():
|
|
11
|
+
"""Returns the xtce auxiliary directory."""
|
|
12
|
+
return imap_module_directory / "ialirt" / "packet_definitions" / "ialirt_swe.xml"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@pytest.fixture(scope="session")
|
|
16
|
+
def binary_packet_path():
|
|
17
|
+
"""Returns the xtce directory."""
|
|
18
|
+
return (
|
|
19
|
+
imap_module_directory
|
|
20
|
+
/ "tests"
|
|
21
|
+
/ "ialirt"
|
|
22
|
+
/ "test_data"
|
|
23
|
+
/ "l0"
|
|
24
|
+
/ "20240827095047_SWE_IALIRT_packet.bin"
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@pytest.fixture(scope="session")
|
|
29
|
+
def swe_test_data():
|
|
30
|
+
"""Returns the test data directory."""
|
|
31
|
+
data_path = (
|
|
32
|
+
imap_module_directory
|
|
33
|
+
/ "tests"
|
|
34
|
+
/ "ialirt"
|
|
35
|
+
/ "test_data"
|
|
36
|
+
/ "l0"
|
|
37
|
+
/ "idle_export_eu.SWE_IALIRT_20240827_093852.csv"
|
|
38
|
+
)
|
|
39
|
+
data = pd.read_csv(data_path)
|
|
40
|
+
|
|
41
|
+
return data
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@pytest.fixture()
|
|
45
|
+
def xarray_data(binary_packet_path, xtce_swe_path):
|
|
46
|
+
"""Create xarray data"""
|
|
47
|
+
apid = 1360
|
|
48
|
+
|
|
49
|
+
xarray_data = packet_file_to_datasets(
|
|
50
|
+
binary_packet_path, xtce_swe_path, use_derived_value=True
|
|
51
|
+
)[apid]
|
|
52
|
+
return xarray_data
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_decom_packets(xarray_data, swe_test_data):
|
|
56
|
+
"""This function checks that all instrument parameters are accounted for."""
|
|
57
|
+
|
|
58
|
+
fields_to_test = {
|
|
59
|
+
"swe_shcoarse": "SHCOARSE",
|
|
60
|
+
"swe_acq_sec": "ACQUISITION_TIME",
|
|
61
|
+
"swe_acq_sub": "ACQUISITION_TIME_SUBSECOND",
|
|
62
|
+
"swe_nom_flag": "INSTRUMENT_NOMINAL_FLAG",
|
|
63
|
+
"swe_ops_flag": "SCIENCE_OPERATION_FLAG",
|
|
64
|
+
"swe_seq": "SEQUENCE_NUMBER",
|
|
65
|
+
"swe_cem1_e1": "ELEC_COUNTS_SPIN_I_POL_0_E_0J",
|
|
66
|
+
"swe_cem1_e2": "ELEC_COUNTS_SPIN_I_POL_0_E_1J",
|
|
67
|
+
"swe_cem1_e3": "ELEC_COUNTS_SPIN_I_POL_0_E_2J",
|
|
68
|
+
"swe_cem1_e4": "ELEC_COUNTS_SPIN_I_POL_0_E_3J",
|
|
69
|
+
"swe_cem2_e1": "ELEC_COUNTS_SPIN_I_POL_1_E_0J",
|
|
70
|
+
"swe_cem2_e2": "ELEC_COUNTS_SPIN_I_POL_1_E_1J",
|
|
71
|
+
"swe_cem2_e3": "ELEC_COUNTS_SPIN_I_POL_1_E_2J",
|
|
72
|
+
"swe_cem2_e4": "ELEC_COUNTS_SPIN_I_POL_1_E_3J",
|
|
73
|
+
"swe_cem3_e1": "ELEC_COUNTS_SPIN_I_POL_2_E_0J",
|
|
74
|
+
"swe_cem3_e2": "ELEC_COUNTS_SPIN_I_POL_2_E_1J",
|
|
75
|
+
"swe_cem3_e3": "ELEC_COUNTS_SPIN_I_POL_2_E_2J",
|
|
76
|
+
"swe_cem3_e4": "ELEC_COUNTS_SPIN_I_POL_2_E_3J",
|
|
77
|
+
"swe_cem4_e1": "ELEC_COUNTS_SPIN_I_POL_3_E_0J",
|
|
78
|
+
"swe_cem4_e2": "ELEC_COUNTS_SPIN_I_POL_3_E_1J",
|
|
79
|
+
"swe_cem4_e3": "ELEC_COUNTS_SPIN_I_POL_3_E_2J",
|
|
80
|
+
"swe_cem4_e4": "ELEC_COUNTS_SPIN_I_POL_3_E_3J",
|
|
81
|
+
"swe_cem5_e1": "ELEC_COUNTS_SPIN_I_POL_4_E_0J",
|
|
82
|
+
"swe_cem5_e2": "ELEC_COUNTS_SPIN_I_POL_4_E_1J",
|
|
83
|
+
"swe_cem5_e3": "ELEC_COUNTS_SPIN_I_POL_4_E_2J",
|
|
84
|
+
"swe_cem5_e4": "ELEC_COUNTS_SPIN_I_POL_4_E_3J",
|
|
85
|
+
"swe_cem6_e1": "ELEC_COUNTS_SPIN_I_POL_5_E_0J",
|
|
86
|
+
"swe_cem6_e2": "ELEC_COUNTS_SPIN_I_POL_5_E_1J",
|
|
87
|
+
"swe_cem6_e3": "ELEC_COUNTS_SPIN_I_POL_5_E_2J",
|
|
88
|
+
"swe_cem6_e4": "ELEC_COUNTS_SPIN_I_POL_5_E_3J",
|
|
89
|
+
"swe_cem7_e1": "ELEC_COUNTS_SPIN_I_POL_6_E_0J",
|
|
90
|
+
"swe_cem7_e2": "ELEC_COUNTS_SPIN_I_POL_6_E_1J",
|
|
91
|
+
"swe_cem7_e3": "ELEC_COUNTS_SPIN_I_POL_6_E_2J",
|
|
92
|
+
"swe_cem7_e4": "ELEC_COUNTS_SPIN_I_POL_6_E_3J",
|
|
93
|
+
}
|
|
94
|
+
_, index, test_index = np.intersect1d(
|
|
95
|
+
xarray_data["swe_shcoarse"], swe_test_data["SHCOARSE"], return_indices=True
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
for xarray_field, test_field in fields_to_test.items():
|
|
99
|
+
actual_values = xarray_data[xarray_field].values[index]
|
|
100
|
+
expected_values = swe_test_data[test_field].values[test_index]
|
|
101
|
+
|
|
102
|
+
# Assert that all values match
|
|
103
|
+
assert np.all(actual_values == expected_values), (
|
|
104
|
+
f"Mismatch found in {xarray_field}: "
|
|
105
|
+
f"actual {actual_values}, expected {expected_values}"
|
|
106
|
+
)
|
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
|
|
3
|
+
import numpy as np
|
|
3
4
|
import pytest
|
|
4
5
|
import xarray as xr
|
|
5
6
|
|
|
6
7
|
from imap_processing import imap_module_directory
|
|
7
8
|
from imap_processing.idex.idex_l1a import PacketParser
|
|
8
9
|
|
|
10
|
+
SPICE_ARRAYS = [
|
|
11
|
+
"ephemeris_position_x",
|
|
12
|
+
"ephemeris_position_y",
|
|
13
|
+
"ephemeris_position_z",
|
|
14
|
+
"ephemeris_velocity_x",
|
|
15
|
+
"ephemeris_velocity_y",
|
|
16
|
+
"ephemeris_velocity_z",
|
|
17
|
+
"right_ascension",
|
|
18
|
+
"declination",
|
|
19
|
+
"solar_longitude",
|
|
20
|
+
"spin_phase",
|
|
21
|
+
]
|
|
22
|
+
|
|
9
23
|
|
|
10
24
|
@pytest.fixture(scope="module")
|
|
11
25
|
def decom_test_data() -> xr.Dataset:
|
|
@@ -17,6 +31,20 @@ def decom_test_data() -> xr.Dataset:
|
|
|
17
31
|
A ``xarray`` dataset containing the test data
|
|
18
32
|
"""
|
|
19
33
|
test_file = Path(
|
|
20
|
-
f"{imap_module_directory}/tests/idex/imap_idex_l0_raw_20231214_v001.pkts"
|
|
34
|
+
f"{imap_module_directory}/tests/idex/test_data/imap_idex_l0_raw_20231214_v001.pkts"
|
|
21
35
|
)
|
|
22
36
|
return PacketParser(test_file, "001").data
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_spice_data_side_effect_func(l1a_ds, idex_attrs):
|
|
40
|
+
# Create a mock dictionary of spice arrays
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
name: xr.DataArray(
|
|
44
|
+
name=name,
|
|
45
|
+
data=np.ones(len(l1a_ds["epoch"])),
|
|
46
|
+
dims="epoch",
|
|
47
|
+
attrs=idex_attrs.get_variable_attributes(name),
|
|
48
|
+
)
|
|
49
|
+
for name in SPICE_ARRAYS
|
|
50
|
+
}
|
|
Binary file
|
|
@@ -14,7 +14,7 @@ def test_idex_decom_length(decom_test_data: xr.Dataset):
|
|
|
14
14
|
decom_test_data : xarray.Dataset
|
|
15
15
|
The dataset to test with
|
|
16
16
|
"""
|
|
17
|
-
assert len(decom_test_data) ==
|
|
17
|
+
assert len(decom_test_data) == 110
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
def test_idex_decom_event_num(decom_test_data: xr.Dataset):
|
|
@@ -26,7 +26,8 @@ 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
|
-
|
|
29
|
+
if "epoch" in decom_test_data[var].dims:
|
|
30
|
+
assert len(decom_test_data[var]) == 14
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
def test_idex_tof_high_data(decom_test_data: xr.Dataset):
|
|
@@ -40,6 +41,8 @@ def test_idex_tof_high_data(decom_test_data: xr.Dataset):
|
|
|
40
41
|
The dataset to test with
|
|
41
42
|
"""
|
|
42
43
|
|
|
43
|
-
with open(
|
|
44
|
+
with open(
|
|
45
|
+
f"{imap_module_directory}/tests/idex/test_data/impact_14_tof_high_data.txt"
|
|
46
|
+
) as f:
|
|
44
47
|
data = np.array([int(line.rstrip("\n")) for line in f])
|
|
45
48
|
assert (decom_test_data["TOF_High"][13].data == data).all()
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
"""Tests the L1 processing for decommutated IDEX data"""
|
|
2
2
|
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from unittest import mock
|
|
5
|
+
|
|
3
6
|
import numpy as np
|
|
4
7
|
import pytest
|
|
5
8
|
import xarray as xr
|
|
@@ -7,6 +10,8 @@ from cdflib.xarray.xarray_to_cdf import ISTPError
|
|
|
7
10
|
|
|
8
11
|
from imap_processing import imap_module_directory
|
|
9
12
|
from imap_processing.cdf.utils import load_cdf, write_cdf
|
|
13
|
+
from imap_processing.idex.decode import _decode_sub_frame, read_bits, rice_decode
|
|
14
|
+
from imap_processing.idex.idex_l1a import PacketParser
|
|
10
15
|
|
|
11
16
|
|
|
12
17
|
def test_idex_cdf_file(decom_test_data: xr.Dataset):
|
|
@@ -89,9 +94,154 @@ def test_idex_tof_high_data_from_cdf(decom_test_data: xr.Dataset):
|
|
|
89
94
|
decom_test_data : xarray.Dataset
|
|
90
95
|
The dataset to test with
|
|
91
96
|
"""
|
|
92
|
-
with open(
|
|
97
|
+
with open(
|
|
98
|
+
f"{imap_module_directory}/tests/idex/test_data/impact_14_tof_high_data.txt"
|
|
99
|
+
) as f:
|
|
93
100
|
data = np.array([int(line.rstrip()) for line in f])
|
|
94
101
|
|
|
95
102
|
file_name = write_cdf(decom_test_data)
|
|
96
103
|
l1_data = load_cdf(file_name)
|
|
97
104
|
assert (l1_data["TOF_High"][13].data == data).all()
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def test_compressed_packet():
|
|
108
|
+
"""
|
|
109
|
+
Test compressed data decompression against known non-compressed data.
|
|
110
|
+
"""
|
|
111
|
+
test_data_dir = f"{imap_module_directory}/tests/idex/test_data"
|
|
112
|
+
|
|
113
|
+
compressed = Path(f"{test_data_dir}/compressed_2023_102_14_24_55.pkts")
|
|
114
|
+
non_compressed = Path(f"{test_data_dir}/non_compressed_2023_102_14_22_26.pkts")
|
|
115
|
+
|
|
116
|
+
decompressed = PacketParser(compressed, "001").data
|
|
117
|
+
expected = PacketParser(non_compressed, "001").data
|
|
118
|
+
|
|
119
|
+
waveforms = [
|
|
120
|
+
"TOF_High",
|
|
121
|
+
"TOF_Low",
|
|
122
|
+
"TOF_Mid",
|
|
123
|
+
"Ion_Grid",
|
|
124
|
+
"Target_High",
|
|
125
|
+
"Target_Low",
|
|
126
|
+
]
|
|
127
|
+
|
|
128
|
+
# Compare each decompressed waveform with known non-compressed waveform.
|
|
129
|
+
for var in waveforms:
|
|
130
|
+
assert np.allclose(decompressed[var], expected[var]), (
|
|
131
|
+
f"Variable: {var} is different for the decompressed and non compressed "
|
|
132
|
+
f"datasets."
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def test_read_bits():
|
|
137
|
+
"""
|
|
138
|
+
Test that read_bits() properly increments the pointer and reads the correct ints.
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
binary_str_6 = "110"
|
|
142
|
+
binary_str_neg_6 = "1010"
|
|
143
|
+
binary_str_1 = "0001"
|
|
144
|
+
|
|
145
|
+
full_string = binary_str_6 + binary_str_neg_6 + binary_str_1
|
|
146
|
+
|
|
147
|
+
pointer = 0
|
|
148
|
+
val, pointer = read_bits(full_string, pointer, 3)
|
|
149
|
+
assert val == 6
|
|
150
|
+
assert pointer == 3
|
|
151
|
+
# Test with a signed binary string
|
|
152
|
+
val, pointer = read_bits(full_string, pointer, 4, signed=True)
|
|
153
|
+
assert val == -6
|
|
154
|
+
assert pointer == 7
|
|
155
|
+
|
|
156
|
+
val, pointer = read_bits(full_string, pointer, 4)
|
|
157
|
+
assert val == 1
|
|
158
|
+
assert pointer == 11
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
@mock.patch("imap_processing.idex.decode._decode_sub_frame")
|
|
162
|
+
def test_rice_decode(mock_decode_sub_frame):
|
|
163
|
+
"""
|
|
164
|
+
Verify that rice_decode() returns the expected list of integers.
|
|
165
|
+
"""
|
|
166
|
+
|
|
167
|
+
mock_decode_sub_frame.return_value = [1 for _ in range(64)], 1
|
|
168
|
+
# mock binary string.
|
|
169
|
+
bstr = "0100000"
|
|
170
|
+
ints = rice_decode(bstr, True, 640)
|
|
171
|
+
# If there are 64 samples per block and the sample count is 640,
|
|
172
|
+
# There should be 10 calls to _decode_sub_frame()
|
|
173
|
+
assert mock_decode_sub_frame.call_count == 10
|
|
174
|
+
# There should be 640 samples
|
|
175
|
+
assert ints == [1 for _ in range(640)]
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def test_decode_sub_frame_psel_0():
|
|
179
|
+
"""Test constant predictor (psel=0) where all samples equal first sample."""
|
|
180
|
+
psel = 0
|
|
181
|
+
bstring = "0" * 9 + "1" # 1 in 10-bit binary
|
|
182
|
+
ints, bp = _decode_sub_frame(bstring, bp=0, psel=psel, k=0, n_bits=10)
|
|
183
|
+
assert ints == [1 for _ in range(64)]
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def test_decode_sub_frame_psel_1():
|
|
187
|
+
"""Test verbatim predictor (psel=1) where each sample stored directly."""
|
|
188
|
+
# Create a binary string that is equal to 1, 2, 3, 4 to 64. Each int is represented
|
|
189
|
+
# in 10 bits to mock the expected high sample waveform data.
|
|
190
|
+
psel = 1
|
|
191
|
+
bstring = "".join([bin(i)[2:].zfill(10) for i in range(64)])
|
|
192
|
+
ints, bp = _decode_sub_frame(bstring, bp=0, psel=psel, k=0, n_bits=10)
|
|
193
|
+
assert ints == [i for i in range(64)]
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def test_decode_sub_frame_psel_2():
|
|
197
|
+
"""Test linear predictor 1 (psel=2) with rice encoded residuals."""
|
|
198
|
+
psel = 2
|
|
199
|
+
k = 1
|
|
200
|
+
# This encoding takes the signed residual value (current value - last value)
|
|
201
|
+
# Example values 1, 2, 3, 8
|
|
202
|
+
# residual of 1
|
|
203
|
+
# quotient = 1 >> (k+1) = 0 (unary = "1")
|
|
204
|
+
# remainder = "01"
|
|
205
|
+
residual_1_and_2 = "101"
|
|
206
|
+
# residual of 5
|
|
207
|
+
# quotient = 4 >> (k+1) = 1 maps to 2 (unary = "001")
|
|
208
|
+
# remainder = "01"
|
|
209
|
+
residual_3 = "00101"
|
|
210
|
+
warmup = "0" * 9 + "1" # equal to 1
|
|
211
|
+
|
|
212
|
+
bstring = warmup + residual_1_and_2 + residual_1_and_2 + residual_3
|
|
213
|
+
ints, bp = _decode_sub_frame(bstring, bp=0, psel=psel, k=k, n_bits=10)
|
|
214
|
+
assert ints == [1, 2, 3, 8]
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def test_decode_sub_frame_psel_3():
|
|
218
|
+
"""Test linear predictor 2 (psel=3) with rice encoded residuals."""
|
|
219
|
+
# This predictor assumes that sample X(n) = 2X(n-1)-X(n-2). This predictor
|
|
220
|
+
# calculates the slope of the signal based on the two previous values
|
|
221
|
+
# (slope = X(n-1)-X(n-2)) and predicts the value of X(n) will follow on a straight
|
|
222
|
+
# line drawn between the two previous points.
|
|
223
|
+
# X(n) = X(n-1) + (X(n-1)-X(n-2)) = 2X(n-1)-X(n-2).
|
|
224
|
+
psel = 3
|
|
225
|
+
k = 1
|
|
226
|
+
# Example values: [1, 2, 4, 1, 5]
|
|
227
|
+
# For X(4)=1: predicted=3 (2*2-1), actual=4, residual=1
|
|
228
|
+
# For X(1)=-5: predicted=6 (2*4-2), actual=1, residual=-5
|
|
229
|
+
# For X(5)=7: predicted=-2 (2*1-4), actual=5, residual=7
|
|
230
|
+
# residual of 1
|
|
231
|
+
# quotient = 1 >> (K+1) = 0 (unary = "1")
|
|
232
|
+
# remainder = "01"
|
|
233
|
+
residual_1 = "101"
|
|
234
|
+
# residual of -5
|
|
235
|
+
# quotient = -5 >> (K+1) = -2 maps to 3 (unary = "0001")
|
|
236
|
+
# remainder = "11"
|
|
237
|
+
residual_2 = "000111"
|
|
238
|
+
# residual of 7
|
|
239
|
+
# quotient = 7 >> (K+1) = 1 maps to 2 (unary = "001")
|
|
240
|
+
# remainder = "11"
|
|
241
|
+
residual_3 = "00111"
|
|
242
|
+
warmup1 = "0" * 9 + "1" # 1
|
|
243
|
+
warmup2 = "0" * 8 + "10" # 2
|
|
244
|
+
|
|
245
|
+
bstring = warmup1 + warmup2 + residual_1 + residual_2 + residual_3
|
|
246
|
+
ints, bp = _decode_sub_frame(bstring, bp=0, psel=psel, k=k, n_bits=10)
|
|
247
|
+
assert ints == [1, 2, 4, 1, 5]
|