imap-processing 0.12.0__py3-none-any.whl → 0.13.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/__init__.py +1 -0
- imap_processing/_version.py +2 -2
- imap_processing/ccsds/ccsds_data.py +1 -2
- imap_processing/ccsds/excel_to_xtce.py +1 -2
- imap_processing/cdf/config/imap_codice_global_cdf_attrs.yaml +18 -12
- imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +569 -0
- imap_processing/cdf/config/imap_codice_l1b_variable_attrs.yaml +1846 -128
- imap_processing/cdf/config/imap_hit_global_cdf_attrs.yaml +5 -5
- imap_processing/cdf/config/imap_idex_global_cdf_attrs.yaml +20 -1
- imap_processing/cdf/config/imap_idex_l1a_variable_attrs.yaml +6 -4
- imap_processing/cdf/config/imap_idex_l1b_variable_attrs.yaml +3 -3
- imap_processing/cdf/config/imap_mag_global_cdf_attrs.yaml +15 -0
- imap_processing/cdf/config/imap_swapi_variable_attrs.yaml +22 -0
- imap_processing/cdf/config/imap_swe_l1b_variable_attrs.yaml +16 -0
- imap_processing/cdf/config/imap_ultra_global_cdf_attrs.yaml +178 -5
- imap_processing/cdf/config/imap_ultra_l1a_variable_attrs.yaml +5045 -41
- imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +33 -19
- imap_processing/cdf/config/imap_ultra_l1c_variable_attrs.yaml +8 -48
- imap_processing/cdf/utils.py +41 -33
- imap_processing/cli.py +463 -234
- imap_processing/codice/codice_l1a.py +260 -47
- imap_processing/codice/codice_l1b.py +51 -152
- imap_processing/codice/constants.py +38 -1
- imap_processing/ena_maps/ena_maps.py +658 -65
- imap_processing/ena_maps/utils/coordinates.py +1 -1
- imap_processing/ena_maps/utils/spatial_utils.py +10 -5
- imap_processing/glows/l1a/glows_l1a.py +28 -99
- imap_processing/glows/l1a/glows_l1a_data.py +2 -2
- imap_processing/glows/l1b/glows_l1b.py +1 -4
- imap_processing/glows/l1b/glows_l1b_data.py +1 -3
- imap_processing/glows/l2/glows_l2.py +2 -5
- imap_processing/hi/l1a/hi_l1a.py +31 -12
- imap_processing/hi/l1b/hi_l1b.py +80 -43
- imap_processing/hi/l1c/hi_l1c.py +12 -16
- imap_processing/hit/ancillary/imap_hit_l1b-to-l2-sector-dt0-factors_20250219_v002.csv +81 -0
- imap_processing/hit/hit_utils.py +93 -35
- imap_processing/hit/l0/decom_hit.py +3 -1
- imap_processing/hit/l1a/hit_l1a.py +30 -25
- imap_processing/hit/l1b/constants.py +6 -2
- imap_processing/hit/l1b/hit_l1b.py +279 -318
- imap_processing/hit/l2/constants.py +37 -0
- imap_processing/hit/l2/hit_l2.py +373 -264
- imap_processing/ialirt/l0/parse_mag.py +138 -10
- imap_processing/ialirt/l0/process_swapi.py +69 -0
- imap_processing/ialirt/l0/process_swe.py +318 -22
- imap_processing/ialirt/packet_definitions/ialirt.xml +216 -212
- imap_processing/ialirt/packet_definitions/ialirt_codicehi.xml +1 -1
- imap_processing/ialirt/packet_definitions/ialirt_codicelo.xml +1 -1
- imap_processing/ialirt/packet_definitions/ialirt_swapi.xml +14 -14
- imap_processing/ialirt/utils/grouping.py +1 -1
- imap_processing/idex/idex_constants.py +9 -1
- imap_processing/idex/idex_l0.py +22 -8
- imap_processing/idex/idex_l1a.py +75 -44
- imap_processing/idex/idex_l1b.py +9 -8
- imap_processing/idex/idex_l2a.py +79 -45
- imap_processing/idex/idex_l2b.py +120 -0
- imap_processing/idex/idex_variable_unpacking_and_eu_conversion.csv +33 -39
- imap_processing/idex/packet_definitions/idex_housekeeping_packet_definition.xml +9130 -0
- imap_processing/lo/l0/lo_science.py +1 -2
- imap_processing/lo/l1a/lo_l1a.py +1 -4
- imap_processing/lo/l1b/lo_l1b.py +527 -6
- imap_processing/lo/l1b/tof_conversions.py +11 -0
- imap_processing/lo/l1c/lo_l1c.py +1 -4
- imap_processing/mag/constants.py +43 -0
- imap_processing/mag/imap_mag_sdc_configuration_v001.py +8 -0
- imap_processing/mag/l1a/mag_l1a.py +2 -9
- imap_processing/mag/l1a/mag_l1a_data.py +10 -10
- imap_processing/mag/l1b/mag_l1b.py +84 -17
- imap_processing/mag/l1c/interpolation_methods.py +180 -3
- imap_processing/mag/l1c/mag_l1c.py +236 -70
- imap_processing/mag/l2/mag_l2.py +140 -0
- imap_processing/mag/l2/mag_l2_data.py +288 -0
- imap_processing/spacecraft/quaternions.py +1 -3
- imap_processing/spice/geometry.py +3 -3
- imap_processing/spice/kernels.py +0 -276
- imap_processing/spice/pointing_frame.py +257 -0
- imap_processing/spice/repoint.py +48 -19
- imap_processing/spice/spin.py +38 -33
- imap_processing/spice/time.py +24 -0
- imap_processing/swapi/l1/swapi_l1.py +16 -12
- imap_processing/swapi/l2/swapi_l2.py +116 -4
- imap_processing/swapi/swapi_utils.py +32 -0
- imap_processing/swe/l1a/swe_l1a.py +2 -9
- imap_processing/swe/l1a/swe_science.py +8 -11
- imap_processing/swe/l1b/swe_l1b.py +898 -23
- imap_processing/swe/l2/swe_l2.py +21 -77
- imap_processing/swe/utils/swe_constants.py +1 -0
- imap_processing/tests/ccsds/test_excel_to_xtce.py +1 -1
- imap_processing/tests/cdf/test_utils.py +14 -16
- imap_processing/tests/codice/conftest.py +44 -33
- imap_processing/tests/codice/data/validation/imap_codice_l1a_hi-pha_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-pha_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/test_codice_l1a.py +20 -11
- imap_processing/tests/codice/test_codice_l1b.py +6 -7
- imap_processing/tests/conftest.py +78 -22
- imap_processing/tests/ena_maps/test_ena_maps.py +462 -33
- imap_processing/tests/ena_maps/test_spatial_utils.py +1 -1
- imap_processing/tests/glows/conftest.py +10 -14
- imap_processing/tests/glows/test_glows_decom.py +4 -4
- imap_processing/tests/glows/test_glows_l1a_cdf.py +6 -27
- imap_processing/tests/glows/test_glows_l1a_data.py +6 -8
- imap_processing/tests/glows/test_glows_l1b.py +11 -11
- imap_processing/tests/glows/test_glows_l1b_data.py +5 -5
- imap_processing/tests/glows/test_glows_l2.py +2 -8
- imap_processing/tests/hi/conftest.py +1 -1
- imap_processing/tests/hi/test_hi_l1b.py +10 -12
- imap_processing/tests/hi/test_hi_l1c.py +27 -24
- imap_processing/tests/hi/test_l1a.py +7 -9
- imap_processing/tests/hi/test_science_direct_event.py +2 -2
- imap_processing/tests/hit/helpers/l1_validation.py +44 -43
- imap_processing/tests/hit/test_decom_hit.py +1 -1
- imap_processing/tests/hit/test_hit_l1a.py +9 -9
- imap_processing/tests/hit/test_hit_l1b.py +172 -217
- imap_processing/tests/hit/test_hit_l2.py +380 -118
- imap_processing/tests/hit/test_hit_utils.py +122 -55
- imap_processing/tests/hit/validation_data/hit_l1b_standard_sample2_nsrl_v4_3decimals.csv +62 -62
- imap_processing/tests/hit/validation_data/sci_sample_raw.csv +1 -1
- imap_processing/tests/ialirt/unit/test_decom_ialirt.py +16 -81
- imap_processing/tests/ialirt/unit/test_grouping.py +2 -2
- imap_processing/tests/ialirt/unit/test_parse_mag.py +71 -16
- imap_processing/tests/ialirt/unit/test_process_codicehi.py +3 -3
- imap_processing/tests/ialirt/unit/test_process_codicelo.py +3 -10
- imap_processing/tests/ialirt/unit/test_process_ephemeris.py +4 -4
- imap_processing/tests/ialirt/unit/test_process_hit.py +3 -3
- imap_processing/tests/ialirt/unit/test_process_swapi.py +24 -16
- imap_processing/tests/ialirt/unit/test_process_swe.py +115 -7
- imap_processing/tests/idex/conftest.py +72 -7
- imap_processing/tests/idex/test_data/imap_idex_l0_raw_20241206_v001.pkts +0 -0
- imap_processing/tests/idex/test_data/imap_idex_l0_raw_20250108_v001.pkts +0 -0
- imap_processing/tests/idex/test_idex_l0.py +33 -11
- imap_processing/tests/idex/test_idex_l1a.py +50 -23
- imap_processing/tests/idex/test_idex_l1b.py +104 -25
- imap_processing/tests/idex/test_idex_l2a.py +48 -32
- imap_processing/tests/idex/test_idex_l2b.py +93 -0
- imap_processing/tests/lo/test_lo_l1a.py +3 -3
- imap_processing/tests/lo/test_lo_l1b.py +371 -6
- imap_processing/tests/lo/test_lo_l1c.py +1 -1
- imap_processing/tests/lo/test_lo_science.py +6 -7
- imap_processing/tests/lo/test_star_sensor.py +1 -1
- imap_processing/tests/mag/conftest.py +58 -9
- imap_processing/tests/mag/test_mag_decom.py +4 -3
- imap_processing/tests/mag/test_mag_l1a.py +13 -7
- imap_processing/tests/mag/test_mag_l1b.py +9 -9
- imap_processing/tests/mag/test_mag_l1c.py +151 -47
- imap_processing/tests/mag/test_mag_l2.py +130 -0
- imap_processing/tests/mag/test_mag_validation.py +144 -7
- imap_processing/tests/mag/validation/L1c/T013/mag-l1b-l1c-t013-magi-normal-in.csv +1217 -0
- imap_processing/tests/mag/validation/L1c/T013/mag-l1b-l1c-t013-magi-normal-out.csv +1857 -0
- imap_processing/tests/mag/validation/L1c/T013/mag-l1b-l1c-t013-mago-normal-in.csv +1217 -0
- imap_processing/tests/mag/validation/L1c/T013/mag-l1b-l1c-t013-mago-normal-out.csv +1857 -0
- imap_processing/tests/mag/validation/L1c/T014/mag-l1b-l1c-t014-magi-normal-in.csv +1217 -0
- imap_processing/tests/mag/validation/L1c/T014/mag-l1b-l1c-t014-magi-normal-out.csv +1793 -0
- imap_processing/tests/mag/validation/L1c/T014/mag-l1b-l1c-t014-mago-normal-in.csv +1217 -0
- imap_processing/tests/mag/validation/L1c/T014/mag-l1b-l1c-t014-mago-normal-out.csv +1793 -0
- imap_processing/tests/mag/validation/L1c/T015/mag-l1b-l1c-t015-magi-burst-in.csv +2561 -0
- imap_processing/tests/mag/validation/L1c/T015/mag-l1b-l1c-t015-magi-normal-in.csv +961 -0
- imap_processing/tests/mag/validation/L1c/T015/mag-l1b-l1c-t015-magi-normal-out.csv +1539 -0
- imap_processing/tests/mag/validation/L1c/T015/mag-l1b-l1c-t015-mago-normal-in.csv +1921 -0
- imap_processing/tests/mag/validation/L1c/T015/mag-l1b-l1c-t015-mago-normal-out.csv +2499 -0
- imap_processing/tests/mag/validation/L1c/T016/mag-l1b-l1c-t016-magi-normal-in.csv +865 -0
- imap_processing/tests/mag/validation/L1c/T016/mag-l1b-l1c-t016-magi-normal-out.csv +1196 -0
- imap_processing/tests/mag/validation/L1c/T016/mag-l1b-l1c-t016-mago-normal-in.csv +1729 -0
- imap_processing/tests/mag/validation/L1c/T016/mag-l1b-l1c-t016-mago-normal-out.csv +3053 -0
- imap_processing/tests/mag/validation/L2/imap_mag_l1b_norm-mago_20251017_v002.cdf +0 -0
- imap_processing/tests/mag/validation/calibration/imap_mag_l2-calibration-matrices_20251017_v004.cdf +0 -0
- imap_processing/tests/mag/validation/calibration/imap_mag_l2-offsets-norm_20251017_20251017_v001.cdf +0 -0
- imap_processing/tests/spacecraft/test_quaternions.py +1 -1
- imap_processing/tests/spice/test_data/fake_repoint_data.csv +4 -4
- imap_processing/tests/spice/test_data/fake_spin_data.csv +11 -11
- imap_processing/tests/spice/test_geometry.py +3 -3
- imap_processing/tests/spice/test_kernels.py +1 -200
- imap_processing/tests/spice/test_pointing_frame.py +185 -0
- imap_processing/tests/spice/test_repoint.py +20 -10
- imap_processing/tests/spice/test_spin.py +50 -9
- imap_processing/tests/spice/test_time.py +14 -0
- imap_processing/tests/swapi/lut/imap_swapi_esa-unit-conversion_20250211_v000.csv +73 -0
- imap_processing/tests/swapi/lut/imap_swapi_lut-notes_20250211_v000.csv +1025 -0
- imap_processing/tests/swapi/test_swapi_l1.py +7 -9
- imap_processing/tests/swapi/test_swapi_l2.py +180 -8
- imap_processing/tests/swe/lut/checker-board-indices.csv +24 -0
- imap_processing/tests/swe/lut/imap_swe_esa-lut_20250301_v000.csv +385 -0
- imap_processing/tests/swe/lut/imap_swe_l1b-in-flight-cal_20240510_20260716_v000.csv +3 -0
- imap_processing/tests/swe/test_swe_l1a.py +6 -6
- imap_processing/tests/swe/test_swe_l1a_science.py +3 -3
- imap_processing/tests/swe/test_swe_l1b.py +162 -24
- imap_processing/tests/swe/test_swe_l2.py +82 -102
- imap_processing/tests/test_cli.py +171 -88
- imap_processing/tests/test_utils.py +2 -1
- imap_processing/tests/ultra/data/mock_data.py +49 -21
- imap_processing/tests/ultra/unit/conftest.py +53 -70
- imap_processing/tests/ultra/unit/test_badtimes.py +2 -4
- imap_processing/tests/ultra/unit/test_cullingmask.py +4 -6
- imap_processing/tests/ultra/unit/test_de.py +3 -10
- imap_processing/tests/ultra/unit/test_decom_apid_880.py +27 -76
- imap_processing/tests/ultra/unit/test_decom_apid_881.py +15 -16
- imap_processing/tests/ultra/unit/test_decom_apid_883.py +12 -10
- imap_processing/tests/ultra/unit/test_decom_apid_896.py +202 -55
- imap_processing/tests/ultra/unit/test_lookup_utils.py +23 -1
- imap_processing/tests/ultra/unit/test_spacecraft_pset.py +3 -4
- imap_processing/tests/ultra/unit/test_ultra_l1a.py +84 -307
- imap_processing/tests/ultra/unit/test_ultra_l1b.py +30 -12
- imap_processing/tests/ultra/unit/test_ultra_l1b_annotated.py +2 -2
- imap_processing/tests/ultra/unit/test_ultra_l1b_culling.py +4 -1
- imap_processing/tests/ultra/unit/test_ultra_l1b_extended.py +163 -29
- imap_processing/tests/ultra/unit/test_ultra_l1c.py +5 -5
- imap_processing/tests/ultra/unit/test_ultra_l1c_pset_bins.py +32 -43
- imap_processing/tests/ultra/unit/test_ultra_l2.py +230 -0
- imap_processing/ultra/constants.py +1 -1
- imap_processing/ultra/l0/decom_tools.py +21 -34
- imap_processing/ultra/l0/decom_ultra.py +168 -204
- imap_processing/ultra/l0/ultra_utils.py +152 -136
- imap_processing/ultra/l1a/ultra_l1a.py +55 -243
- imap_processing/ultra/l1b/badtimes.py +1 -4
- imap_processing/ultra/l1b/cullingmask.py +2 -6
- imap_processing/ultra/l1b/de.py +62 -47
- imap_processing/ultra/l1b/extendedspin.py +8 -4
- imap_processing/ultra/l1b/lookup_utils.py +72 -9
- imap_processing/ultra/l1b/ultra_l1b.py +3 -8
- imap_processing/ultra/l1b/ultra_l1b_culling.py +4 -4
- imap_processing/ultra/l1b/ultra_l1b_extended.py +236 -78
- imap_processing/ultra/l1c/histogram.py +2 -6
- imap_processing/ultra/l1c/spacecraft_pset.py +2 -4
- imap_processing/ultra/l1c/ultra_l1c.py +1 -5
- imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +107 -60
- imap_processing/ultra/l2/ultra_l2.py +299 -0
- imap_processing/ultra/lookup_tables/Angular_Profiles_FM45_LeftSlit.csv +526 -0
- imap_processing/ultra/lookup_tables/Angular_Profiles_FM45_RightSlit.csv +526 -0
- imap_processing/ultra/lookup_tables/Angular_Profiles_FM90_LeftSlit.csv +526 -0
- imap_processing/ultra/lookup_tables/Angular_Profiles_FM90_RightSlit.csv +526 -0
- imap_processing/ultra/lookup_tables/FM45_Startup1_ULTRA_IMGPARAMS_20240719.csv +2 -2
- imap_processing/ultra/lookup_tables/FM90_Startup1_ULTRA_IMGPARAMS_20240719.csv +2 -0
- imap_processing/ultra/packet_definitions/README.md +38 -0
- imap_processing/ultra/packet_definitions/ULTRA_SCI_COMBINED.xml +15302 -482
- imap_processing/ultra/utils/ultra_l1_utils.py +13 -12
- imap_processing/utils.py +1 -1
- {imap_processing-0.12.0.dist-info → imap_processing-0.13.0.dist-info}/METADATA +3 -2
- {imap_processing-0.12.0.dist-info → imap_processing-0.13.0.dist-info}/RECORD +264 -225
- imap_processing/hi/l1b/hi_eng_unit_convert_table.csv +0 -154
- imap_processing/mag/imap_mag_sdc-configuration_v001.yaml +0 -6
- imap_processing/mag/l1b/__init__.py +0 -0
- imap_processing/swe/l1b/swe_esa_lookup_table.csv +0 -1441
- imap_processing/swe/l1b/swe_l1b_science.py +0 -699
- imap_processing/tests/swe/test_swe_l1b_science.py +0 -103
- imap_processing/ultra/lookup_tables/dps_sensitivity45.cdf +0 -0
- imap_processing/ultra/lookup_tables/ultra_90_dps_exposure_compressed.cdf +0 -0
- /imap_processing/idex/packet_definitions/{idex_packet_definition.xml → idex_science_packet_definition.xml} +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/20240827095047_SWE_IALIRT_packet.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/461971383-404.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/461971384-405.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/461971385-406.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/461971386-407.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/461971387-408.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/461971388-409.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/461971389-410.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/461971390-411.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/461971391-412.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/BinLog CCSDS_FRAG_TLM_20240826_152323Z_IALIRT_data_for_SDC.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/IALiRT Raw Packet Telemetry.txt +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/apid01152.tlm +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/eu_SWP_IAL_20240826_152033.csv +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/hi_fsw_view_1_ccsds.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/hit_ialirt_sample.ccsds +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/hit_ialirt_sample.csv +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/idle_export_eu.SWE_IALIRT_20240827_093852.csv +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/imap_codice_l1a_hi-ialirt_20240523200000_v0.0.0.cdf +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/imap_codice_l1a_lo-ialirt_20241110193700_v0.0.0.cdf +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/sample_decoded_i-alirt_data.csv +0 -0
- /imap_processing/tests/mag/validation/{imap_calibration_mag_20240229_v01.cdf → calibration/imap_mag_l1b-calibration_20240229_v001.cdf} +0 -0
- /imap_processing/{swe/l1b/engineering_unit_convert_table.csv → tests/swe/lut/imap_swe_eu-conversion_20240510_v000.csv} +0 -0
- {imap_processing-0.12.0.dist-info → imap_processing-0.13.0.dist-info}/LICENSE +0 -0
- {imap_processing-0.12.0.dist-info → imap_processing-0.13.0.dist-info}/WHEEL +0 -0
- {imap_processing-0.12.0.dist-info → imap_processing-0.13.0.dist-info}/entry_points.txt +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from collections import namedtuple
|
|
2
|
+
from unittest.mock import patch
|
|
2
3
|
|
|
3
4
|
import numpy as np
|
|
4
5
|
import pytest
|
|
@@ -8,17 +9,29 @@ from imap_processing import imap_module_directory
|
|
|
8
9
|
from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
|
|
9
10
|
from imap_processing.cdf.utils import load_cdf
|
|
10
11
|
from imap_processing.lo.l1b.lo_l1b import (
|
|
12
|
+
calculate_tof1_for_golden_triples,
|
|
11
13
|
convert_start_end_acq_times,
|
|
14
|
+
convert_tofs_to_eu,
|
|
12
15
|
create_datasets,
|
|
13
16
|
get_avg_spin_durations,
|
|
14
17
|
get_spin_angle,
|
|
18
|
+
get_spin_start_times,
|
|
19
|
+
identify_species,
|
|
15
20
|
initialize_l1b_de,
|
|
16
21
|
lo_l1b,
|
|
22
|
+
set_bad_times,
|
|
23
|
+
set_coincidence_type,
|
|
24
|
+
set_each_event_epoch,
|
|
25
|
+
set_event_met,
|
|
26
|
+
set_pointing_bin,
|
|
27
|
+
set_pointing_direction,
|
|
17
28
|
set_spin_bin,
|
|
29
|
+
set_spin_cycle,
|
|
18
30
|
)
|
|
31
|
+
from imap_processing.spice.time import met_to_ttj2000ns
|
|
19
32
|
|
|
20
33
|
|
|
21
|
-
@pytest.fixture
|
|
34
|
+
@pytest.fixture
|
|
22
35
|
def dependencies():
|
|
23
36
|
return {
|
|
24
37
|
"imap_lo_l1a_de": load_cdf(
|
|
@@ -32,16 +45,24 @@ def dependencies():
|
|
|
32
45
|
}
|
|
33
46
|
|
|
34
47
|
|
|
35
|
-
@pytest.fixture
|
|
48
|
+
@pytest.fixture
|
|
36
49
|
def attr_mgr_l1b():
|
|
37
50
|
attr_mgr_l1b = ImapCdfAttributes()
|
|
38
51
|
attr_mgr_l1b.add_instrument_global_attrs(instrument="lo")
|
|
39
52
|
attr_mgr_l1b.add_instrument_variable_attrs(instrument="lo", level="l1b")
|
|
40
|
-
attr_mgr_l1b.add_global_attribute("Data_version", "000")
|
|
41
53
|
return attr_mgr_l1b
|
|
42
54
|
|
|
43
55
|
|
|
44
|
-
|
|
56
|
+
@pytest.fixture
|
|
57
|
+
def attr_mgr_l1a():
|
|
58
|
+
attr_mgr = ImapCdfAttributes()
|
|
59
|
+
attr_mgr.add_instrument_global_attrs(instrument="lo")
|
|
60
|
+
attr_mgr.add_instrument_variable_attrs(instrument="lo", level="l1a")
|
|
61
|
+
return attr_mgr
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@patch("imap_processing.lo.l1b.lo_l1b.instrument_pointing")
|
|
65
|
+
def test_lo_l1b(mock_instrument_pointing):
|
|
45
66
|
# Arrange
|
|
46
67
|
de_file = (
|
|
47
68
|
imap_module_directory / "tests/lo/test_cdfs/imap_lo_l1a_de_20241022_v002.cdf"
|
|
@@ -55,13 +76,16 @@ def test_lo_l1b():
|
|
|
55
76
|
data[dataset.attrs["Logical_source"]] = dataset
|
|
56
77
|
|
|
57
78
|
expected_logical_source = "imap_lo_l1b_de"
|
|
79
|
+
mock_instrument_pointing.return_value = np.zeros((2000, 2))
|
|
58
80
|
# Act
|
|
59
|
-
output_file = lo_l1b(data
|
|
81
|
+
output_file = lo_l1b(data)
|
|
60
82
|
|
|
61
83
|
# Assert
|
|
62
84
|
assert expected_logical_source == output_file[0].attrs["Logical_source"]
|
|
63
85
|
|
|
64
86
|
|
|
87
|
+
# @pytest.mark.external_kernel
|
|
88
|
+
# @pytest.mark.use_test_metakernel("imap_ena_sim_metakernel.template")
|
|
65
89
|
def test_create_datasets():
|
|
66
90
|
attr_mgr = ImapCdfAttributes()
|
|
67
91
|
attr_mgr.add_instrument_global_attrs(instrument="lo")
|
|
@@ -201,7 +225,6 @@ def test_get_spin_angle():
|
|
|
201
225
|
spin_angle,
|
|
202
226
|
spin_angle_expected,
|
|
203
227
|
atol=1e-2,
|
|
204
|
-
err_msg=f"Spin angle: {spin_angle} vs {spin_angle_expected}",
|
|
205
228
|
)
|
|
206
229
|
|
|
207
230
|
|
|
@@ -216,3 +239,345 @@ def test_spin_bin():
|
|
|
216
239
|
|
|
217
240
|
# Assert
|
|
218
241
|
np.testing.assert_array_equal(l1b_de["spin_bin"], expected_spin_bins)
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def test_spin_cycle():
|
|
245
|
+
# Arrange
|
|
246
|
+
de = xr.Dataset(
|
|
247
|
+
{
|
|
248
|
+
"de_count": ("epoch", [2, 3]),
|
|
249
|
+
"esa_step": ("direct_event", [1, 2, 3, 4, 5]),
|
|
250
|
+
},
|
|
251
|
+
coords={"epoch": [0, 1], "direct_event": [1, 2, 3, 4, 5]},
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
# spin_cycle = spin_start + 7 + (esa_step - 1) * 2
|
|
255
|
+
# where spin start is the spin number for the first spin
|
|
256
|
+
# in an Aggregated Science Cycle (first spin number of an epoch)
|
|
257
|
+
# and esa_step is the esa_step for a direct event
|
|
258
|
+
spin_cycle_expected = np.array([7, 9, 39, 41, 43])
|
|
259
|
+
spin_cycle_data = xr.Dataset()
|
|
260
|
+
|
|
261
|
+
# Act
|
|
262
|
+
spin_cycle_data = set_spin_cycle(de, spin_cycle_data)
|
|
263
|
+
|
|
264
|
+
# Assert
|
|
265
|
+
np.testing.assert_array_equal(spin_cycle_data["spin_cycle"], spin_cycle_expected)
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def test_get_spin_start_times():
|
|
269
|
+
# Arrange
|
|
270
|
+
l1b_de = xr.Dataset(
|
|
271
|
+
{
|
|
272
|
+
"spin_cycle": ("epoch", [0, 1, 2, 3, 4]),
|
|
273
|
+
},
|
|
274
|
+
coords={
|
|
275
|
+
"epoch": [
|
|
276
|
+
0,
|
|
277
|
+
1,
|
|
278
|
+
2,
|
|
279
|
+
3,
|
|
280
|
+
4,
|
|
281
|
+
]
|
|
282
|
+
},
|
|
283
|
+
)
|
|
284
|
+
l1a_de = xr.Dataset(
|
|
285
|
+
{
|
|
286
|
+
"de_count": ("epoch", [2, 3]),
|
|
287
|
+
"met": ("direct_event", [0, 1, 2, 3, 4]),
|
|
288
|
+
"de_time": ("direct_event", [0000, 1000, 2000, 3000, 4000]),
|
|
289
|
+
},
|
|
290
|
+
coords={"epoch": [0, 1], "direct_event": [0, 1, 2, 3, 4]},
|
|
291
|
+
)
|
|
292
|
+
spin = xr.Dataset(
|
|
293
|
+
{
|
|
294
|
+
"start_sec_spin": (
|
|
295
|
+
["epoch", "spin"],
|
|
296
|
+
[[20, 25, 30, 35, 40], [45, 50, 55, 60, 65]],
|
|
297
|
+
),
|
|
298
|
+
"start_subsec_spin": (
|
|
299
|
+
["epoch", "spin"],
|
|
300
|
+
[[2000, 3000, 4000, 5000, 6000], [1000, 1500, 2000, 3000, 4000]],
|
|
301
|
+
),
|
|
302
|
+
}
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
end_acq = xr.DataArray([0, 1], dims="epoch")
|
|
306
|
+
spin_start_times_expected = np.array([20.002, 50.0015, 55.002, 60.003, 65.004])
|
|
307
|
+
spin_start_times = get_spin_start_times(l1a_de, l1b_de, spin, end_acq)
|
|
308
|
+
|
|
309
|
+
np.testing.assert_allclose(
|
|
310
|
+
spin_start_times,
|
|
311
|
+
spin_start_times_expected,
|
|
312
|
+
atol=1e-4,
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def test_set_event_met():
|
|
317
|
+
# Arrange
|
|
318
|
+
l1b_de = xr.Dataset()
|
|
319
|
+
l1a_de = xr.Dataset(
|
|
320
|
+
{
|
|
321
|
+
"de_count": ("epoch", [2, 3]),
|
|
322
|
+
"de_time": ("direct_event", [0000, 1000, 2000, 3000, 4000]),
|
|
323
|
+
},
|
|
324
|
+
coords={
|
|
325
|
+
"epoch": [0, 1],
|
|
326
|
+
"direct_event": [
|
|
327
|
+
0,
|
|
328
|
+
1,
|
|
329
|
+
2,
|
|
330
|
+
3,
|
|
331
|
+
4,
|
|
332
|
+
],
|
|
333
|
+
},
|
|
334
|
+
)
|
|
335
|
+
avg_spin_durations = xr.DataArray([5, 10])
|
|
336
|
+
spin_start_times = xr.DataArray([10, 20, 30, 40, 50])
|
|
337
|
+
expected_event_met = np.array([10, 21.2207, 34.8828, 47.3242, 59.7656])
|
|
338
|
+
|
|
339
|
+
# Act
|
|
340
|
+
l1b_de = set_event_met(l1a_de, l1b_de, spin_start_times, avg_spin_durations)
|
|
341
|
+
|
|
342
|
+
# Assert
|
|
343
|
+
np.testing.assert_allclose(
|
|
344
|
+
l1b_de["event_met"].values,
|
|
345
|
+
expected_event_met,
|
|
346
|
+
atol=1e-4,
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
def test_set_each_event_epoch():
|
|
350
|
+
l1b_de = xr.Dataset(
|
|
351
|
+
{
|
|
352
|
+
"event_met": ("epoch", [10, 20, 30, 40, 50]),
|
|
353
|
+
},
|
|
354
|
+
coords={
|
|
355
|
+
"epoch": [0, 1, 2, 3, 4],
|
|
356
|
+
},
|
|
357
|
+
)
|
|
358
|
+
epoch_expected = met_to_ttj2000ns(np.array([10, 20, 30, 40, 50]))
|
|
359
|
+
|
|
360
|
+
l1b_de = set_each_event_epoch(l1b_de)
|
|
361
|
+
|
|
362
|
+
np.testing.assert_allclose(
|
|
363
|
+
l1b_de["epoch"].values,
|
|
364
|
+
epoch_expected,
|
|
365
|
+
atol=1e-4,
|
|
366
|
+
)
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
def test_calculate_tof1_for_golden_triples():
|
|
370
|
+
# Arrange
|
|
371
|
+
l1a_de = xr.Dataset(
|
|
372
|
+
{
|
|
373
|
+
"coincidence_type": ("epoch", [0, 0, 0]),
|
|
374
|
+
"mode": ("epoch", [0, 0, 1]),
|
|
375
|
+
"tof0": ("epoch", [2, 4, 2]),
|
|
376
|
+
"tof1": ("epoch", [0, 0, 0]),
|
|
377
|
+
"tof2": ("epoch", [2, 6, 2]),
|
|
378
|
+
"tof3": ("epoch", [2, 8, 2]),
|
|
379
|
+
"cksm": ("epoch", [2, 12, 2]),
|
|
380
|
+
}
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
l1a_de_expected = xr.Dataset(
|
|
384
|
+
{
|
|
385
|
+
"coincidence_type": ("epoch", [0, 0, 0]),
|
|
386
|
+
"mode": ("epoch", [0, 0, 1]),
|
|
387
|
+
"tof0": ("epoch", [2, 4, 2]),
|
|
388
|
+
"tof1": ("epoch", [42, 36, 0]),
|
|
389
|
+
"tof2": ("epoch", [2, 6, 2]),
|
|
390
|
+
"tof3": ("epoch", [2, 8, 2]),
|
|
391
|
+
"cksm": ("epoch", [2, 12, 2]),
|
|
392
|
+
}
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
# Act
|
|
396
|
+
l1a_de = calculate_tof1_for_golden_triples(l1a_de)
|
|
397
|
+
|
|
398
|
+
# Assert
|
|
399
|
+
assert l1a_de_expected.equals(l1a_de)
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
def test_set_coincidence_type(attr_mgr_l1a):
|
|
403
|
+
# Arrange
|
|
404
|
+
l1b_de = xr.Dataset()
|
|
405
|
+
tof_fill = attr_mgr_l1a.get_variable_attributes("tof0")["FILLVAL"]
|
|
406
|
+
ckm_fill = attr_mgr_l1a.get_variable_attributes("cksm")["FILLVAL"]
|
|
407
|
+
l1a_de = xr.Dataset(
|
|
408
|
+
{
|
|
409
|
+
"de_count": ("epoch", [3]),
|
|
410
|
+
"coincidence_type": ("direct_events", [0, 0, 4]),
|
|
411
|
+
"mode": ("direct_events", [1, 0, 1]),
|
|
412
|
+
"tof0": ("direct_events", [5, 2, 10]),
|
|
413
|
+
"tof1": ("direct_events", [10, 4, tof_fill]),
|
|
414
|
+
"tof2": ("direct_events", [15, 6, 20]),
|
|
415
|
+
"tof3": ("direct_events", [20, 8, 30]),
|
|
416
|
+
"cksm": ("direct_events", [25, ckm_fill, ckm_fill]),
|
|
417
|
+
},
|
|
418
|
+
coords={
|
|
419
|
+
"epoch": [0],
|
|
420
|
+
"direct_events": [0, 1, 2],
|
|
421
|
+
},
|
|
422
|
+
)
|
|
423
|
+
|
|
424
|
+
coincidence_type_expected = np.array(["111111", "111100", "101101"])
|
|
425
|
+
|
|
426
|
+
# Act
|
|
427
|
+
l1b_de = set_coincidence_type(l1a_de, l1b_de, attr_mgr_l1a)
|
|
428
|
+
|
|
429
|
+
# Assert
|
|
430
|
+
np.testing.assert_array_equal(
|
|
431
|
+
l1b_de["coincidence_type"].values,
|
|
432
|
+
coincidence_type_expected,
|
|
433
|
+
)
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
def test_convert_tofs_to_eu(attr_mgr_l1b, attr_mgr_l1a):
|
|
437
|
+
l1b_de = xr.Dataset()
|
|
438
|
+
tof_fill_l1a = attr_mgr_l1a.get_variable_attributes("tof0")["FILLVAL"]
|
|
439
|
+
tof_fill_l1b = attr_mgr_l1b.get_variable_attributes("tof1")["FILLVAL"]
|
|
440
|
+
l1a_de = xr.Dataset(
|
|
441
|
+
{
|
|
442
|
+
"de_count": ("epoch", [2]),
|
|
443
|
+
"coincidence_type": ("direct_events", [0, 4]),
|
|
444
|
+
"mode": ("direct_events", [1, 0]),
|
|
445
|
+
"tof0": ("direct_events", [5, 2]),
|
|
446
|
+
"tof1": ("direct_events", [10, tof_fill_l1a]),
|
|
447
|
+
"tof2": ("direct_events", [15, 6]),
|
|
448
|
+
"tof3": ("direct_events", [20, 8]),
|
|
449
|
+
},
|
|
450
|
+
coords={
|
|
451
|
+
"epoch": [0],
|
|
452
|
+
"direct_events": [0, 1],
|
|
453
|
+
},
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
tof0_expected = np.array([1.394394, 0.889272])
|
|
457
|
+
tof1_expected = np.array([0.931059, tof_fill_l1b])
|
|
458
|
+
tof2_expected = np.array([2.870557, 1.372876])
|
|
459
|
+
tof3_expected = np.array([3.88245, 1.818162])
|
|
460
|
+
|
|
461
|
+
# Act
|
|
462
|
+
l1b_de = convert_tofs_to_eu(l1a_de, l1b_de, attr_mgr_l1a, attr_mgr_l1b)
|
|
463
|
+
|
|
464
|
+
tof_checks = [
|
|
465
|
+
("tof0", tof0_expected),
|
|
466
|
+
("tof1", tof1_expected),
|
|
467
|
+
("tof2", tof2_expected),
|
|
468
|
+
("tof3", tof3_expected),
|
|
469
|
+
]
|
|
470
|
+
# Assert
|
|
471
|
+
for tof, expected_tof in tof_checks:
|
|
472
|
+
np.testing.assert_allclose(
|
|
473
|
+
l1b_de[tof].values,
|
|
474
|
+
expected_tof,
|
|
475
|
+
atol=1e-6,
|
|
476
|
+
)
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
def test_identify_species(attr_mgr_l1b):
|
|
480
|
+
# Arrange
|
|
481
|
+
fill_val = attr_mgr_l1b.get_variable_attributes("tof2")["FILLVAL"]
|
|
482
|
+
l1b_de = xr.Dataset(
|
|
483
|
+
{
|
|
484
|
+
"tof2": ("epoch", [1, 14, 50, 80, 500, fill_val]),
|
|
485
|
+
}
|
|
486
|
+
)
|
|
487
|
+
|
|
488
|
+
expected_species = np.array(["U", "H", "U", "O", "U", "U"])
|
|
489
|
+
|
|
490
|
+
# Act
|
|
491
|
+
l1b_de = identify_species(l1b_de)
|
|
492
|
+
|
|
493
|
+
# Assert
|
|
494
|
+
np.testing.assert_array_equal(l1b_de["species"], expected_species)
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
def test_set_bad_times():
|
|
498
|
+
# Arrange
|
|
499
|
+
l1b_de = xr.Dataset(
|
|
500
|
+
{},
|
|
501
|
+
coords={
|
|
502
|
+
"epoch": [0, 1, 2],
|
|
503
|
+
},
|
|
504
|
+
)
|
|
505
|
+
|
|
506
|
+
expected_bad_times = np.array([0, 0, 0])
|
|
507
|
+
|
|
508
|
+
# Act
|
|
509
|
+
l1b_de = set_bad_times(l1b_de)
|
|
510
|
+
|
|
511
|
+
# Assert
|
|
512
|
+
np.testing.assert_array_equal(l1b_de["badtimes"], expected_bad_times)
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
@pytest.mark.external_kernel
|
|
516
|
+
@pytest.mark.use_test_metakernel("imap_ena_sim_metakernel.template")
|
|
517
|
+
def test_set_direction():
|
|
518
|
+
# Arrange
|
|
519
|
+
l1b_de = xr.Dataset(
|
|
520
|
+
{},
|
|
521
|
+
coords={
|
|
522
|
+
"epoch": [
|
|
523
|
+
7.9794907254e17,
|
|
524
|
+
# + 1 second. Should be 24deg diff from
|
|
525
|
+
# previous epoch
|
|
526
|
+
7.9794907254e17 + 1e9,
|
|
527
|
+
# + 7.5 seconds. Should be 180deg diff from
|
|
528
|
+
# first epoch
|
|
529
|
+
7.9794907254e17 + 7.5e9,
|
|
530
|
+
# + 15 seconds. Should be 360deg diff from
|
|
531
|
+
# previous epoch
|
|
532
|
+
7.9794907254e17 + 15e9,
|
|
533
|
+
],
|
|
534
|
+
},
|
|
535
|
+
)
|
|
536
|
+
# latitudes are -90 to 90
|
|
537
|
+
expected_direction_lat = np.array([0, 0, 0, 0])
|
|
538
|
+
# longitude are -180 to 180
|
|
539
|
+
expected_direction_lon = np.array([140.5, 164.5, -39.5, 140.5])
|
|
540
|
+
|
|
541
|
+
# Act
|
|
542
|
+
l1b_de = set_pointing_direction(l1b_de)
|
|
543
|
+
|
|
544
|
+
# Assert
|
|
545
|
+
np.testing.assert_allclose(
|
|
546
|
+
l1b_de["direction_lat"].values,
|
|
547
|
+
expected_direction_lat,
|
|
548
|
+
atol=1e-1,
|
|
549
|
+
)
|
|
550
|
+
np.testing.assert_allclose(
|
|
551
|
+
l1b_de["direction_lon"].values,
|
|
552
|
+
expected_direction_lon,
|
|
553
|
+
atol=1e-1,
|
|
554
|
+
)
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
def test_pointing_bins():
|
|
558
|
+
# Arrange
|
|
559
|
+
l1b_de = xr.Dataset(
|
|
560
|
+
{
|
|
561
|
+
"direction_lat": ("epoch", [0, 0, 0, 0, 0]),
|
|
562
|
+
"direction_lon": ("epoch", [-180, 91.3, 116.3, 140.5, 180]),
|
|
563
|
+
},
|
|
564
|
+
coords={
|
|
565
|
+
"epoch": [
|
|
566
|
+
7.9794907049e17,
|
|
567
|
+
7.9794907153e17,
|
|
568
|
+
7.9794907254e17,
|
|
569
|
+
7.9794907354e17,
|
|
570
|
+
7.9794907454e17,
|
|
571
|
+
],
|
|
572
|
+
},
|
|
573
|
+
)
|
|
574
|
+
|
|
575
|
+
expected_pointing_lats = np.array([20, 20, 20, 20, 20])
|
|
576
|
+
expected_pointing_lons = np.array([0, 2712, 2962, 3205, 3600])
|
|
577
|
+
|
|
578
|
+
# Act
|
|
579
|
+
l1b_de = set_pointing_bin(l1b_de)
|
|
580
|
+
|
|
581
|
+
# Assert
|
|
582
|
+
np.testing.assert_array_equal(l1b_de["pointing_bin_lat"], expected_pointing_lats)
|
|
583
|
+
np.testing.assert_array_equal(l1b_de["pointing_bin_lon"], expected_pointing_lons)
|
|
@@ -17,7 +17,7 @@ from imap_processing.lo.l0.lo_science import (
|
|
|
17
17
|
from imap_processing.utils import convert_to_binary_string, packet_file_to_datasets
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
@pytest.fixture
|
|
20
|
+
@pytest.fixture
|
|
21
21
|
def fake_de_dataset():
|
|
22
22
|
# binary packet fields
|
|
23
23
|
count = "0000000000000010" # 2
|
|
@@ -72,7 +72,7 @@ def fake_de_dataset():
|
|
|
72
72
|
return dataset
|
|
73
73
|
|
|
74
74
|
|
|
75
|
-
@pytest.fixture
|
|
75
|
+
@pytest.fixture
|
|
76
76
|
def sample_data():
|
|
77
77
|
xtce_file = imap_module_directory / "lo/packet_definitions/lo_xtce.xml"
|
|
78
78
|
dependency = (
|
|
@@ -86,7 +86,7 @@ def sample_data():
|
|
|
86
86
|
return datasets_by_apid
|
|
87
87
|
|
|
88
88
|
|
|
89
|
-
@pytest.fixture
|
|
89
|
+
@pytest.fixture
|
|
90
90
|
def segmented_pkts_fake_data():
|
|
91
91
|
dataset = xr.Dataset(
|
|
92
92
|
data_vars=dict(
|
|
@@ -116,7 +116,7 @@ def segmented_pkts_fake_data():
|
|
|
116
116
|
return dataset
|
|
117
117
|
|
|
118
118
|
|
|
119
|
-
@pytest.fixture
|
|
119
|
+
@pytest.fixture
|
|
120
120
|
def fake_spin_data():
|
|
121
121
|
dataset = xr.Dataset(
|
|
122
122
|
data_vars=dict(
|
|
@@ -148,16 +148,15 @@ def fake_spin_data():
|
|
|
148
148
|
return dataset
|
|
149
149
|
|
|
150
150
|
|
|
151
|
-
@pytest.fixture
|
|
151
|
+
@pytest.fixture
|
|
152
152
|
def attr_mgr():
|
|
153
153
|
attr_mgr = ImapCdfAttributes()
|
|
154
154
|
attr_mgr.add_instrument_global_attrs(instrument="lo")
|
|
155
155
|
attr_mgr.add_instrument_variable_attrs(instrument="lo", level="l1a")
|
|
156
|
-
attr_mgr.add_global_attribute("Data_version", "v000")
|
|
157
156
|
return attr_mgr
|
|
158
157
|
|
|
159
158
|
|
|
160
|
-
@pytest.fixture
|
|
159
|
+
@pytest.fixture
|
|
161
160
|
def initialized_dataset(fake_de_dataset, attr_mgr):
|
|
162
161
|
fake_de_dataset.attrs["bit_pos"] = 0
|
|
163
162
|
de_fields = [
|
|
@@ -6,7 +6,7 @@ from imap_processing.ccsds.ccsds_data import CcsdsData
|
|
|
6
6
|
from imap_processing.lo.l0.data_classes.star_sensor import StarSensor
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
@pytest.fixture
|
|
9
|
+
@pytest.fixture
|
|
10
10
|
def star_sensor():
|
|
11
11
|
fake_data_field = namedtuple("fake_packet", ["raw_value", "derived_value"])
|
|
12
12
|
star_sensor = StarSensor.__new__(StarSensor)
|
|
@@ -7,15 +7,17 @@ import pytest
|
|
|
7
7
|
import xarray as xr
|
|
8
8
|
|
|
9
9
|
from imap_processing.cdf.utils import load_cdf
|
|
10
|
+
from imap_processing.mag.constants import VecSec
|
|
10
11
|
from imap_processing.mag.l1a.mag_l1a import mag_l1a
|
|
12
|
+
from imap_processing.spice.time import TTJ2000_EPOCH
|
|
11
13
|
|
|
12
14
|
|
|
13
|
-
@pytest.fixture
|
|
15
|
+
@pytest.fixture
|
|
14
16
|
def validation_l1a():
|
|
15
17
|
current_directory = Path(__file__).parent
|
|
16
18
|
test_file = current_directory / "validation" / "mag_l1_test_data.pkts"
|
|
17
19
|
# Test file contains only normal packets
|
|
18
|
-
l1a = mag_l1a(test_file
|
|
20
|
+
l1a = mag_l1a(test_file)
|
|
19
21
|
return l1a
|
|
20
22
|
|
|
21
23
|
|
|
@@ -57,27 +59,74 @@ def mag_l1a_dataset_generator(length):
|
|
|
57
59
|
return output_dataset
|
|
58
60
|
|
|
59
61
|
|
|
60
|
-
@pytest.fixture
|
|
61
|
-
def
|
|
62
|
+
@pytest.fixture
|
|
63
|
+
def mag_test_l1b_calibration_data():
|
|
62
64
|
imap_dir = Path(__file__).parent
|
|
63
|
-
cal_file =
|
|
65
|
+
cal_file = (
|
|
66
|
+
imap_dir
|
|
67
|
+
/ "validation"
|
|
68
|
+
/ "calibration"
|
|
69
|
+
/ "imap_mag_l1b-calibration_20240229_v001.cdf"
|
|
70
|
+
)
|
|
64
71
|
calibration_data = load_cdf(cal_file)
|
|
65
72
|
return calibration_data
|
|
66
73
|
|
|
67
74
|
|
|
68
|
-
|
|
69
|
-
|
|
75
|
+
@pytest.fixture
|
|
76
|
+
def mag_test_l2_data():
|
|
77
|
+
imap_dir = Path(__file__).parent
|
|
78
|
+
cal_file = (
|
|
79
|
+
imap_dir
|
|
80
|
+
/ "validation"
|
|
81
|
+
/ "calibration"
|
|
82
|
+
/ "imap_mag_l2-calibration-matrices_20251017_v004.cdf"
|
|
83
|
+
)
|
|
84
|
+
calibration_data = load_cdf(cal_file)
|
|
85
|
+
|
|
86
|
+
offsets_data = load_cdf(
|
|
87
|
+
imap_dir
|
|
88
|
+
/ "validation"
|
|
89
|
+
/ "calibration"
|
|
90
|
+
/ "imap_mag_l2-offsets-norm_20251017_20251017_v001.cdf"
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
return calibration_data, offsets_data
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def mag_generate_l1b_from_csv(df, logical_source):
|
|
97
|
+
length = len(df.index)
|
|
98
|
+
dataset = mag_l1a_dataset_generator(length)
|
|
99
|
+
|
|
100
|
+
dataset["vectors"].data = np.array(df[["x", "y", "z", "range"]])
|
|
101
|
+
dataset["compression_flags"].data = np.array(
|
|
102
|
+
df[["compression", "compression_width"]]
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
epoch = [np.datetime64(t) - np.datetime64(TTJ2000_EPOCH) for t in df["t"]]
|
|
106
|
+
epoch_ns = [(e / np.timedelta64(1, "ns")).astype(np.int64) for e in epoch]
|
|
107
|
+
dataset.coords["epoch"] = xr.DataArray(epoch_ns, name="epoch", dims=["epoch"])
|
|
108
|
+
|
|
109
|
+
dataset.attrs["Logical_source"] = logical_source
|
|
110
|
+
dataset.attrs["vectors_per_second"] = f"{epoch_ns[0]}:2"
|
|
111
|
+
|
|
112
|
+
return dataset
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def generate_test_epoch(
|
|
116
|
+
end, vectors_per_second: list[VecSec], starting_point=0, gaps=None
|
|
117
|
+
):
|
|
118
|
+
spacing = 1 / vectors_per_second[0].value
|
|
70
119
|
output = np.array([])
|
|
71
120
|
prev = starting_point
|
|
72
121
|
if gaps:
|
|
73
122
|
for index, gap in enumerate(gaps):
|
|
74
123
|
if len(vectors_per_second) != 1:
|
|
75
|
-
spacing = 1 / vectors_per_second[index]
|
|
124
|
+
spacing = 1 / vectors_per_second[index].value
|
|
76
125
|
output = np.concatenate(
|
|
77
126
|
(output, np.arange(prev, gap[0] + spacing, step=spacing) * 1e9)
|
|
78
127
|
)
|
|
79
128
|
prev = gap[1]
|
|
80
|
-
spacing = 1 / vectors_per_second[-1]
|
|
129
|
+
spacing = 1 / vectors_per_second[-1].value
|
|
81
130
|
output = np.concatenate(
|
|
82
131
|
(output, np.arange(prev, end + spacing, step=spacing) * 1e9)
|
|
83
132
|
)
|
|
@@ -9,11 +9,12 @@ from imap_processing.mag.constants import DataMode
|
|
|
9
9
|
from imap_processing.mag.l0.decom_mag import decom_packets, generate_dataset
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
@pytest.fixture
|
|
12
|
+
@pytest.fixture
|
|
13
13
|
def cdf_attrs():
|
|
14
14
|
test_attrs = ImapCdfAttributes()
|
|
15
15
|
test_attrs.add_instrument_global_attrs("mag")
|
|
16
16
|
test_attrs.add_instrument_variable_attrs("mag", "l1a")
|
|
17
|
+
# Default v001 expected when writing to file and re-loading
|
|
17
18
|
test_attrs.add_global_attribute("Data_version", "v001")
|
|
18
19
|
return test_attrs
|
|
19
20
|
|
|
@@ -75,7 +76,7 @@ def test_mag_raw_xarray(cdf_attrs):
|
|
|
75
76
|
[
|
|
76
77
|
item is not None
|
|
77
78
|
for key, item in norm_data.attrs.items()
|
|
78
|
-
if key
|
|
79
|
+
if key not in ("Logical_file_id", "Data_version")
|
|
79
80
|
]
|
|
80
81
|
)
|
|
81
82
|
|
|
@@ -83,7 +84,7 @@ def test_mag_raw_xarray(cdf_attrs):
|
|
|
83
84
|
[
|
|
84
85
|
item is not None
|
|
85
86
|
for key, item in burst_data.attrs.items()
|
|
86
|
-
if key
|
|
87
|
+
if key not in ("Logical_file_id", "Data_version")
|
|
87
88
|
]
|
|
88
89
|
)
|
|
89
90
|
|
|
@@ -15,7 +15,7 @@ from imap_processing.mag.l1a.mag_l1a_data import (
|
|
|
15
15
|
from imap_processing.spice.time import met_to_ttj2000ns
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
@pytest.fixture
|
|
18
|
+
@pytest.fixture
|
|
19
19
|
def uncompressed_vector_bytearray():
|
|
20
20
|
input_data = np.array(
|
|
21
21
|
[
|
|
@@ -225,7 +225,7 @@ def uncompressed_vector_bytearray():
|
|
|
225
225
|
return input_data
|
|
226
226
|
|
|
227
227
|
|
|
228
|
-
@pytest.fixture
|
|
228
|
+
@pytest.fixture
|
|
229
229
|
def expected_vectors():
|
|
230
230
|
primary_expected = np.array(
|
|
231
231
|
[
|
|
@@ -272,7 +272,7 @@ def expected_vectors():
|
|
|
272
272
|
return (primary_expected, secondary_expected)
|
|
273
273
|
|
|
274
274
|
|
|
275
|
-
@pytest.fixture
|
|
275
|
+
@pytest.fixture
|
|
276
276
|
def raw_compressed_vectors():
|
|
277
277
|
# compressed vectors, without the first starting uncompressed vector.
|
|
278
278
|
# 15 primary vectors and 15 secondary vectors, corresponding to most of
|
|
@@ -883,7 +883,7 @@ def test_mag_l1a():
|
|
|
883
883
|
current_directory = Path(__file__).parent
|
|
884
884
|
test_file = current_directory / "validation" / "mag_l1_test_data.pkts"
|
|
885
885
|
|
|
886
|
-
output_data = mag_l1a(test_file
|
|
886
|
+
output_data = mag_l1a(test_file)
|
|
887
887
|
|
|
888
888
|
# Test data is one day's worth of NORM data, so it should return one raw, one MAGO
|
|
889
889
|
# and one MAGI dataset
|
|
@@ -897,9 +897,6 @@ def test_mag_l1a():
|
|
|
897
897
|
for data_type in [data.attrs["Logical_source"] for data in output_data]:
|
|
898
898
|
assert data_type in expected_logical_source
|
|
899
899
|
|
|
900
|
-
for data in output_data:
|
|
901
|
-
assert data.attrs["Data_version"] == "v001"
|
|
902
|
-
|
|
903
900
|
assert "vectors" in output_data[-1].variables.keys()
|
|
904
901
|
assert "compression_flags" in output_data[-1].variables.keys()
|
|
905
902
|
|
|
@@ -910,6 +907,15 @@ def test_mag_l1a():
|
|
|
910
907
|
== output_data[-1]["compression_flags"].data.shape[0]
|
|
911
908
|
)
|
|
912
909
|
|
|
910
|
+
assert (
|
|
911
|
+
str(output_data[-1]["epoch"].data[0])
|
|
912
|
+
in output_data[-1].attrs["vectors_per_second"]
|
|
913
|
+
)
|
|
914
|
+
assert (
|
|
915
|
+
str(output_data[-2]["epoch"].data[0])
|
|
916
|
+
in output_data[-2].attrs["vectors_per_second"]
|
|
917
|
+
)
|
|
918
|
+
|
|
913
919
|
|
|
914
920
|
def test_mag_packet_properties():
|
|
915
921
|
# equal to 01001011
|