imap-processing 0.11.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 +11 -11
- imap_processing/_version.py +2 -2
- imap_processing/ccsds/ccsds_data.py +1 -2
- imap_processing/ccsds/excel_to_xtce.py +66 -18
- imap_processing/cdf/config/imap_codice_global_cdf_attrs.yaml +24 -40
- imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +934 -42
- imap_processing/cdf/config/imap_codice_l1b_variable_attrs.yaml +1846 -128
- imap_processing/cdf/config/imap_glows_global_cdf_attrs.yaml +0 -5
- imap_processing/cdf/config/imap_hi_global_cdf_attrs.yaml +10 -11
- imap_processing/cdf/config/imap_hi_variable_attrs.yaml +17 -19
- imap_processing/cdf/config/imap_hit_global_cdf_attrs.yaml +27 -14
- imap_processing/cdf/config/imap_hit_l1a_variable_attrs.yaml +106 -116
- imap_processing/cdf/config/imap_hit_l1b_variable_attrs.yaml +120 -145
- imap_processing/cdf/config/imap_hit_l2_variable_attrs.yaml +14 -0
- imap_processing/cdf/config/imap_idex_global_cdf_attrs.yaml +25 -9
- 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_lo_global_cdf_attrs.yaml +0 -12
- imap_processing/cdf/config/imap_lo_l1a_variable_attrs.yaml +1 -1
- imap_processing/cdf/config/imap_mag_global_cdf_attrs.yaml +23 -20
- imap_processing/cdf/config/imap_mag_l1a_variable_attrs.yaml +361 -0
- imap_processing/cdf/config/imap_mag_l1b_variable_attrs.yaml +160 -0
- imap_processing/cdf/config/imap_mag_l1c_variable_attrs.yaml +160 -0
- imap_processing/cdf/config/imap_spacecraft_global_cdf_attrs.yaml +18 -0
- imap_processing/cdf/config/imap_spacecraft_variable_attrs.yaml +40 -0
- imap_processing/cdf/config/imap_swapi_global_cdf_attrs.yaml +1 -5
- imap_processing/cdf/config/imap_swapi_variable_attrs.yaml +22 -0
- imap_processing/cdf/config/imap_swe_global_cdf_attrs.yaml +12 -4
- imap_processing/cdf/config/imap_swe_l1a_variable_attrs.yaml +16 -2
- imap_processing/cdf/config/imap_swe_l1b_variable_attrs.yaml +64 -52
- imap_processing/cdf/config/imap_swe_l2_variable_attrs.yaml +71 -47
- imap_processing/cdf/config/imap_ultra_global_cdf_attrs.yaml +180 -19
- imap_processing/cdf/config/imap_ultra_l1a_variable_attrs.yaml +5045 -41
- imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +80 -17
- imap_processing/cdf/config/imap_ultra_l1c_variable_attrs.yaml +32 -57
- imap_processing/cdf/utils.py +52 -38
- imap_processing/cli.py +477 -233
- imap_processing/codice/codice_l1a.py +466 -131
- imap_processing/codice/codice_l1b.py +51 -152
- imap_processing/codice/constants.py +1360 -569
- imap_processing/codice/decompress.py +2 -6
- imap_processing/ena_maps/ena_maps.py +1103 -146
- imap_processing/ena_maps/utils/coordinates.py +19 -0
- imap_processing/ena_maps/utils/map_utils.py +14 -17
- imap_processing/ena_maps/utils/spatial_utils.py +55 -52
- 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 +54 -29
- imap_processing/hi/l1a/histogram.py +0 -1
- imap_processing/hi/l1a/science_direct_event.py +6 -8
- imap_processing/hi/l1b/hi_l1b.py +111 -82
- imap_processing/hi/l1c/hi_l1c.py +416 -32
- imap_processing/hi/utils.py +58 -12
- imap_processing/hit/ancillary/imap_hit_l1b-to-l2-sector-dt0-factors_20250219_v002.csv +81 -0
- imap_processing/hit/ancillary/imap_hit_l1b-to-l2-standard-dt0-factors_20250219_v002.csv +205 -0
- imap_processing/hit/ancillary/imap_hit_l1b-to-l2-standard-dt1-factors_20250219_v002.csv +205 -0
- imap_processing/hit/ancillary/imap_hit_l1b-to-l2-standard-dt2-factors_20250219_v002.csv +205 -0
- imap_processing/hit/ancillary/imap_hit_l1b-to-l2-standard-dt3-factors_20250219_v002.csv +205 -0
- imap_processing/hit/ancillary/imap_hit_l1b-to-l2-summed-dt0-factors_20250219_v002.csv +68 -0
- imap_processing/hit/hit_utils.py +235 -5
- imap_processing/hit/l0/constants.py +20 -11
- imap_processing/hit/l0/decom_hit.py +21 -5
- imap_processing/hit/l1a/hit_l1a.py +71 -75
- imap_processing/hit/l1b/constants.py +321 -0
- imap_processing/hit/l1b/hit_l1b.py +377 -67
- imap_processing/hit/l2/constants.py +318 -0
- imap_processing/hit/l2/hit_l2.py +723 -0
- imap_processing/hit/packet_definitions/hit_packet_definitions.xml +1323 -71
- imap_processing/ialirt/l0/mag_l0_ialirt_data.py +155 -0
- imap_processing/ialirt/l0/parse_mag.py +374 -0
- imap_processing/ialirt/l0/process_swapi.py +69 -0
- imap_processing/ialirt/l0/process_swe.py +548 -0
- imap_processing/ialirt/packet_definitions/ialirt.xml +216 -208
- 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_mag.xml +115 -0
- imap_processing/ialirt/packet_definitions/ialirt_swapi.xml +14 -14
- imap_processing/ialirt/utils/grouping.py +114 -0
- imap_processing/ialirt/utils/time.py +29 -0
- imap_processing/idex/atomic_masses.csv +22 -0
- imap_processing/idex/decode.py +2 -2
- imap_processing/idex/idex_constants.py +33 -0
- imap_processing/idex/idex_l0.py +22 -8
- imap_processing/idex/idex_l1a.py +81 -51
- imap_processing/idex/idex_l1b.py +13 -39
- imap_processing/idex/idex_l2a.py +823 -0
- imap_processing/idex/idex_l2b.py +120 -0
- imap_processing/idex/idex_variable_unpacking_and_eu_conversion.csv +11 -11
- imap_processing/idex/packet_definitions/idex_housekeeping_packet_definition.xml +9130 -0
- imap_processing/lo/l0/lo_science.py +7 -2
- imap_processing/lo/l1a/lo_l1a.py +1 -5
- imap_processing/lo/l1b/lo_l1b.py +702 -29
- imap_processing/lo/l1b/tof_conversions.py +11 -0
- imap_processing/lo/l1c/lo_l1c.py +1 -4
- imap_processing/mag/constants.py +51 -0
- imap_processing/mag/imap_mag_sdc_configuration_v001.py +8 -0
- imap_processing/mag/l0/decom_mag.py +10 -3
- imap_processing/mag/l1a/mag_l1a.py +23 -19
- imap_processing/mag/l1a/mag_l1a_data.py +35 -10
- imap_processing/mag/l1b/mag_l1b.py +259 -50
- imap_processing/mag/l1c/interpolation_methods.py +388 -0
- imap_processing/mag/l1c/mag_l1c.py +621 -17
- imap_processing/mag/l2/mag_l2.py +140 -0
- imap_processing/mag/l2/mag_l2_data.py +288 -0
- imap_processing/quality_flags.py +1 -0
- imap_processing/spacecraft/packet_definitions/scid_x252.xml +538 -0
- imap_processing/spacecraft/quaternions.py +121 -0
- imap_processing/spice/geometry.py +19 -22
- imap_processing/spice/kernels.py +0 -276
- imap_processing/spice/pointing_frame.py +257 -0
- imap_processing/spice/repoint.py +149 -0
- imap_processing/spice/spin.py +38 -33
- imap_processing/spice/time.py +24 -0
- imap_processing/swapi/l1/swapi_l1.py +20 -12
- imap_processing/swapi/l2/swapi_l2.py +116 -5
- imap_processing/swapi/swapi_utils.py +32 -0
- imap_processing/swe/l1a/swe_l1a.py +44 -12
- imap_processing/swe/l1a/swe_science.py +13 -13
- imap_processing/swe/l1b/swe_l1b.py +898 -23
- imap_processing/swe/l2/swe_l2.py +75 -136
- imap_processing/swe/packet_definitions/swe_packet_definition.xml +1121 -1
- imap_processing/swe/utils/swe_constants.py +64 -0
- imap_processing/swe/utils/swe_utils.py +85 -28
- imap_processing/tests/ccsds/test_data/expected_output.xml +40 -1
- imap_processing/tests/ccsds/test_excel_to_xtce.py +24 -21
- imap_processing/tests/cdf/test_data/imap_instrument2_global_cdf_attrs.yaml +0 -2
- 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-counters-aggregated_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_hi-counters-singles_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_hi-ialirt_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_hi-omni_20241110193700_v0.0.0.cdf +0 -0
- 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_hi-priorities_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_hi-sectored_20241110193700_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-ialirt_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-pha_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_l1a.py +126 -53
- imap_processing/tests/codice/test_codice_l1b.py +6 -7
- imap_processing/tests/codice/test_decompress.py +4 -4
- imap_processing/tests/conftest.py +239 -27
- imap_processing/tests/ena_maps/conftest.py +51 -0
- imap_processing/tests/ena_maps/test_ena_maps.py +1068 -110
- imap_processing/tests/ena_maps/test_map_utils.py +66 -43
- imap_processing/tests/ena_maps/test_spatial_utils.py +17 -21
- 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/data/l0/H45_diag_fee_20250208.bin +0 -0
- imap_processing/tests/hi/data/l0/H45_diag_fee_20250208_verify.csv +205 -0
- imap_processing/tests/hi/test_hi_l1b.py +22 -27
- imap_processing/tests/hi/test_hi_l1c.py +249 -18
- imap_processing/tests/hi/test_l1a.py +35 -7
- imap_processing/tests/hi/test_science_direct_event.py +3 -3
- imap_processing/tests/hi/test_utils.py +24 -2
- imap_processing/tests/hit/helpers/l1_validation.py +74 -73
- imap_processing/tests/hit/test_data/hskp_sample.ccsds +0 -0
- imap_processing/tests/hit/test_data/imap_hit_l0_raw_20100105_v001.pkts +0 -0
- imap_processing/tests/hit/test_decom_hit.py +5 -1
- imap_processing/tests/hit/test_hit_l1a.py +32 -36
- imap_processing/tests/hit/test_hit_l1b.py +300 -81
- imap_processing/tests/hit/test_hit_l2.py +716 -0
- imap_processing/tests/hit/test_hit_utils.py +184 -7
- imap_processing/tests/hit/validation_data/hit_l1b_standard_sample2_nsrl_v4_3decimals.csv +62 -62
- imap_processing/tests/hit/validation_data/hskp_sample_eu_3_6_2025.csv +89 -0
- imap_processing/tests/hit/validation_data/hskp_sample_raw.csv +89 -88
- imap_processing/tests/hit/validation_data/sci_sample_raw.csv +1 -1
- imap_processing/tests/ialirt/data/l0/461971383-404.bin +0 -0
- imap_processing/tests/ialirt/data/l0/461971384-405.bin +0 -0
- imap_processing/tests/ialirt/data/l0/461971385-406.bin +0 -0
- imap_processing/tests/ialirt/data/l0/461971386-407.bin +0 -0
- imap_processing/tests/ialirt/data/l0/461971387-408.bin +0 -0
- imap_processing/tests/ialirt/data/l0/461971388-409.bin +0 -0
- imap_processing/tests/ialirt/data/l0/461971389-410.bin +0 -0
- imap_processing/tests/ialirt/data/l0/461971390-411.bin +0 -0
- imap_processing/tests/ialirt/data/l0/461971391-412.bin +0 -0
- imap_processing/tests/ialirt/data/l0/sample_decoded_i-alirt_data.csv +383 -0
- imap_processing/tests/ialirt/unit/test_decom_ialirt.py +16 -81
- imap_processing/tests/ialirt/unit/test_grouping.py +81 -0
- imap_processing/tests/ialirt/unit/test_parse_mag.py +223 -0
- 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 +319 -6
- imap_processing/tests/ialirt/unit/test_time.py +16 -0
- imap_processing/tests/idex/conftest.py +127 -6
- imap_processing/tests/idex/test_data/imap_idex_l0_raw_20231218_v001.pkts +0 -0
- 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_data/impact_14_tof_high_data.txt +4508 -4508
- imap_processing/tests/idex/test_idex_l0.py +33 -11
- imap_processing/tests/idex/test_idex_l1a.py +92 -21
- imap_processing/tests/idex/test_idex_l1b.py +106 -27
- imap_processing/tests/idex/test_idex_l2a.py +399 -0
- imap_processing/tests/idex/test_idex_l2b.py +93 -0
- imap_processing/tests/lo/test_cdfs/imap_lo_l1a_de_20241022_v002.cdf +0 -0
- imap_processing/tests/lo/test_cdfs/imap_lo_l1a_spin_20241022_v002.cdf +0 -0
- imap_processing/tests/lo/test_lo_l1a.py +3 -3
- imap_processing/tests/lo/test_lo_l1b.py +515 -6
- imap_processing/tests/lo/test_lo_l1c.py +1 -1
- imap_processing/tests/lo/test_lo_science.py +7 -7
- imap_processing/tests/lo/test_star_sensor.py +1 -1
- imap_processing/tests/mag/conftest.py +120 -2
- imap_processing/tests/mag/test_mag_decom.py +5 -4
- imap_processing/tests/mag/test_mag_l1a.py +51 -7
- imap_processing/tests/mag/test_mag_l1b.py +40 -59
- imap_processing/tests/mag/test_mag_l1c.py +354 -19
- imap_processing/tests/mag/test_mag_l2.py +130 -0
- imap_processing/tests/mag/test_mag_validation.py +247 -26
- imap_processing/tests/mag/validation/L1b/T009/MAGScience-normal-(2,2)-8s-20250204-16h39.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T009/mag-l1a-l1b-t009-magi-out.csv +16 -16
- imap_processing/tests/mag/validation/L1b/T009/mag-l1a-l1b-t009-mago-out.csv +16 -16
- imap_processing/tests/mag/validation/L1b/T010/MAGScience-normal-(2,2)-8s-20250206-12h05.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T011/MAGScience-normal-(2,2)-8s-20250204-16h08.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T011/mag-l1a-l1b-t011-magi-out.csv +16 -16
- imap_processing/tests/mag/validation/L1b/T011/mag-l1a-l1b-t011-mago-out.csv +16 -16
- imap_processing/tests/mag/validation/L1b/T012/MAGScience-normal-(2,2)-8s-20250204-16h08.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T012/data.bin +0 -0
- imap_processing/tests/mag/validation/L1b/T012/field_like_all_ranges.txt +19200 -0
- imap_processing/tests/mag/validation/L1b/T012/mag-l1a-l1b-t012-cal.cdf +0 -0
- imap_processing/tests/mag/validation/L1b/T012/mag-l1a-l1b-t012-in.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T012/mag-l1a-l1b-t012-magi-out.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T012/mag-l1a-l1b-t012-mago-out.csv +17 -0
- 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_l1b-calibration_20240229_v001.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/data/SSR_2024_190_20_08_12_0483851794_2_DA_apid0594_1packet.pkts +0 -0
- imap_processing/tests/spacecraft/test_quaternions.py +71 -0
- imap_processing/tests/spice/test_data/fake_repoint_data.csv +5 -0
- imap_processing/tests/spice/test_data/fake_spin_data.csv +11 -11
- imap_processing/tests/spice/test_geometry.py +9 -12
- 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 +121 -0
- 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 +13 -11
- imap_processing/tests/swapi/test_swapi_l2.py +180 -8
- imap_processing/tests/swe/l0_data/2024051010_SWE_HK_packet.bin +0 -0
- imap_processing/tests/swe/l0_data/2024051011_SWE_CEM_RAW_packet.bin +0 -0
- imap_processing/tests/swe/l0_validation_data/idle_export_eu.SWE_APP_HK_20240510_092742.csv +49 -0
- imap_processing/tests/swe/l0_validation_data/idle_export_eu.SWE_CEM_RAW_20240510_092742.csv +593 -0
- 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 +20 -2
- imap_processing/tests/swe/test_swe_l1a_cem_raw.py +52 -0
- imap_processing/tests/swe/test_swe_l1a_hk.py +68 -0
- 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 +153 -91
- imap_processing/tests/test_cli.py +171 -88
- imap_processing/tests/test_utils.py +140 -17
- imap_processing/tests/ultra/data/l0/FM45_UltraFM45_Functional_2024-01-22T0105_20240122T010548.CCSDS +0 -0
- imap_processing/tests/ultra/data/l0/ultra45_raw_sc_ultraimgrates_20220530_00.csv +164 -0
- imap_processing/tests/ultra/{test_data → data}/l0/ultra45_raw_sc_ultrarawimg_withFSWcalcs_FM45_40P_Phi28p5_BeamCal_LinearScan_phi2850_theta-000_20240207T102740.csv +3243 -3243
- imap_processing/tests/ultra/data/mock_data.py +369 -0
- imap_processing/tests/ultra/unit/conftest.py +115 -89
- imap_processing/tests/ultra/unit/test_badtimes.py +4 -4
- imap_processing/tests/ultra/unit/test_cullingmask.py +8 -6
- imap_processing/tests/ultra/unit/test_de.py +14 -13
- imap_processing/tests/ultra/unit/test_decom_apid_880.py +27 -76
- imap_processing/tests/ultra/unit/test_decom_apid_881.py +54 -11
- 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 +77 -0
- imap_processing/tests/ultra/unit/test_ultra_l1a.py +98 -305
- imap_processing/tests/ultra/unit/test_ultra_l1b.py +60 -14
- imap_processing/tests/ultra/unit/test_ultra_l1b_annotated.py +2 -2
- imap_processing/tests/ultra/unit/test_ultra_l1b_culling.py +26 -27
- imap_processing/tests/ultra/unit/test_ultra_l1b_extended.py +239 -70
- imap_processing/tests/ultra/unit/test_ultra_l1c.py +5 -5
- imap_processing/tests/ultra/unit/test_ultra_l1c_pset_bins.py +114 -83
- 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 +27 -39
- 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 -271
- imap_processing/ultra/l1b/badtimes.py +1 -4
- imap_processing/ultra/l1b/cullingmask.py +2 -6
- imap_processing/ultra/l1b/de.py +116 -57
- imap_processing/ultra/l1b/extendedspin.py +20 -18
- imap_processing/ultra/l1b/lookup_utils.py +72 -9
- imap_processing/ultra/l1b/ultra_l1b.py +36 -16
- imap_processing/ultra/l1b/ultra_l1b_culling.py +66 -30
- imap_processing/ultra/l1b/ultra_l1b_extended.py +297 -94
- imap_processing/ultra/l1c/histogram.py +2 -6
- imap_processing/ultra/l1c/spacecraft_pset.py +84 -0
- imap_processing/ultra/l1c/ultra_l1c.py +8 -9
- imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +206 -108
- 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 +31 -12
- imap_processing/utils.py +69 -29
- {imap_processing-0.11.0.dist-info → imap_processing-0.13.0.dist-info}/METADATA +10 -6
- imap_processing-0.13.0.dist-info/RECORD +578 -0
- imap_processing/cdf/config/imap_mag_l1_variable_attrs.yaml +0 -237
- imap_processing/hi/l1a/housekeeping.py +0 -27
- imap_processing/hi/l1b/hi_eng_unit_convert_table.csv +0 -154
- imap_processing/swe/l1b/swe_esa_lookup_table.csv +0 -1441
- imap_processing/swe/l1b/swe_l1b_science.py +0 -652
- imap_processing/tests/codice/data/imap_codice_l1a_hi-counters-aggregated_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1a_hi-counters-singles_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1a_hi-omni_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1a_hi-sectored_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1a_hskp_20100101_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1a_lo-counters-aggregated_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1a_lo-counters-singles_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1a_lo-nsw-angular_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1a_lo-nsw-priority_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1a_lo-nsw-species_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1a_lo-sw-angular_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1a_lo-sw-priority_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1a_lo-sw-species_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1b_hi-counters-aggregated_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1b_hi-counters-singles_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1b_hi-omni_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1b_hi-sectored_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1b_hskp_20100101_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1b_lo-counters-aggregated_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1b_lo-counters-singles_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1b_lo-nsw-angular_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1b_lo-nsw-priority_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1b_lo-nsw-species_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1b_lo-sw-angular_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1b_lo-sw-priority_20240429_v001.cdf +0 -0
- imap_processing/tests/codice/data/imap_codice_l1b_lo-sw-species_20240429_v001.cdf +0 -0
- imap_processing/tests/hi/data/l1/imap_hi_l1b_45sensor-de_20250415_v999.cdf +0 -0
- imap_processing/tests/hit/PREFLIGHT_raw_record_2023_256_15_59_04_apid1251.pkts +0 -0
- imap_processing/tests/hit/PREFLIGHT_raw_record_2023_256_15_59_04_apid1252.pkts +0 -0
- imap_processing/tests/hit/validation_data/hskp_sample_eu.csv +0 -89
- imap_processing/tests/hit/validation_data/sci_sample_raw1.csv +0 -29
- imap_processing/tests/idex/test_data/imap_idex_l0_raw_20231214_v001.pkts +0 -0
- imap_processing/tests/lo/test_cdfs/imap_lo_l1a_de_20100101_v001.cdf +0 -0
- imap_processing/tests/lo/test_cdfs/imap_lo_l1a_spin_20100101_v001.cdf +0 -0
- imap_processing/tests/swe/test_swe_l1b_science.py +0 -84
- imap_processing/tests/ultra/test_data/mock_data.py +0 -161
- imap_processing/ultra/l1c/pset.py +0 -40
- imap_processing/ultra/lookup_tables/dps_sensitivity45.cdf +0 -0
- imap_processing-0.11.0.dist-info/RECORD +0 -488
- /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/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/{mag/l1b → tests/spacecraft}/__init__.py +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/tests/ultra/{test_data → data}/l0/FM45_40P_Phi28p5_BeamCal_LinearScan_phi28.50_theta-0.00_20240207T102740.CCSDS +0 -0
- /imap_processing/tests/ultra/{test_data → data}/l0/FM45_7P_Phi0.0_BeamCal_LinearScan_phi0.04_theta-0.01_20230821T121304.CCSDS +0 -0
- /imap_processing/tests/ultra/{test_data → data}/l0/FM45_TV_Cycle6_Hot_Ops_Front212_20240124T063837.CCSDS +0 -0
- /imap_processing/tests/ultra/{test_data → data}/l0/Ultra45_EM_SwRI_Cal_Run7_ThetaScan_20220530T225054.CCSDS +0 -0
- /imap_processing/tests/ultra/{test_data → data}/l0/ultra45_raw_sc_auxdata_Ultra45_EM_SwRI_Cal_Run7_ThetaScan_20220530T225054.csv +0 -0
- /imap_processing/tests/ultra/{test_data → data}/l0/ultra45_raw_sc_enaphxtofhangimg_FM45_TV_Cycle6_Hot_Ops_Front212_20240124T063837.csv +0 -0
- /imap_processing/tests/ultra/{test_data → data}/l0/ultra45_raw_sc_ultraimgrates_Ultra45_EM_SwRI_Cal_Run7_ThetaScan_20220530T225054.csv +0 -0
- /imap_processing/tests/ultra/{test_data → data}/l0/ultra45_raw_sc_ultrarawimgevent_FM45_7P_Phi00_BeamCal_LinearScan_phi004_theta-001_20230821T121304.csv +0 -0
- /imap_processing/tests/ultra/{test_data → data}/l1/dps_exposure_helio_45_E1.cdf +0 -0
- /imap_processing/tests/ultra/{test_data → data}/l1/dps_exposure_helio_45_E12.cdf +0 -0
- /imap_processing/tests/ultra/{test_data → data}/l1/dps_exposure_helio_45_E24.cdf +0 -0
- {imap_processing-0.11.0.dist-info → imap_processing-0.13.0.dist-info}/LICENSE +0 -0
- {imap_processing-0.11.0.dist-info → imap_processing-0.13.0.dist-info}/WHEEL +0 -0
- {imap_processing-0.11.0.dist-info → imap_processing-0.13.0.dist-info}/entry_points.txt +0 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"""Test coverage for imap_processing.hi.l1c.hi_l1c.py"""
|
|
2
2
|
|
|
3
|
+
from collections import namedtuple
|
|
3
4
|
from unittest import mock
|
|
5
|
+
from unittest.mock import MagicMock
|
|
4
6
|
|
|
5
7
|
import numpy as np
|
|
6
8
|
import pandas as pd
|
|
@@ -9,9 +11,10 @@ import xarray as xr
|
|
|
9
11
|
|
|
10
12
|
from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
|
|
11
13
|
from imap_processing.cdf.utils import load_cdf, write_cdf
|
|
14
|
+
from imap_processing.hi.l1a.science_direct_event import DE_CLOCK_TICK_S
|
|
12
15
|
from imap_processing.hi.l1c import hi_l1c
|
|
13
16
|
from imap_processing.hi.l1c.hi_l1c import CalibrationProductConfig
|
|
14
|
-
from imap_processing.hi.utils import HIAPID
|
|
17
|
+
from imap_processing.hi.utils import HIAPID, CoincidenceBitmap
|
|
15
18
|
|
|
16
19
|
|
|
17
20
|
@pytest.fixture(scope="module")
|
|
@@ -24,46 +27,46 @@ def hi_test_cal_prod_config_path(hi_l1_test_data_path):
|
|
|
24
27
|
@mock.patch("imap_processing.hi.l1c.hi_l1c.generate_pset_dataset")
|
|
25
28
|
def test_hi_l1c(mock_generate_pset_dataset, hi_test_cal_prod_config_path):
|
|
26
29
|
"""Test coverage for hi_l1c function"""
|
|
27
|
-
mock_generate_pset_dataset.return_value = xr.Dataset(
|
|
28
|
-
pset = hi_l1c.hi_l1c(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
assert pset.attrs["Data_version"] == "99"
|
|
30
|
+
mock_generate_pset_dataset.return_value = xr.Dataset()
|
|
31
|
+
pset = hi_l1c.hi_l1c([xr.Dataset(), hi_test_cal_prod_config_path])[0]
|
|
32
|
+
# Empty attributes, global values get added in post-processing
|
|
33
|
+
assert pset.attrs == {}
|
|
32
34
|
|
|
33
35
|
|
|
34
36
|
def test_hi_l1c_not_implemented():
|
|
35
37
|
"""Test coverage for hi_l1c function with unrecognized dependencies"""
|
|
36
38
|
with pytest.raises(NotImplementedError):
|
|
37
|
-
hi_l1c.hi_l1c([None, None]
|
|
39
|
+
hi_l1c.hi_l1c([None, None])
|
|
38
40
|
|
|
39
41
|
|
|
40
|
-
@pytest.mark.
|
|
42
|
+
@pytest.mark.external_test_data
|
|
43
|
+
@pytest.mark.external_kernel
|
|
41
44
|
@pytest.mark.use_test_metakernel("imap_ena_sim_metakernel.template")
|
|
42
|
-
def test_generate_pset_dataset(
|
|
45
|
+
def test_generate_pset_dataset(
|
|
46
|
+
hi_l1_test_data_path, hi_test_cal_prod_config_path, use_fake_spin_data_for_time
|
|
47
|
+
):
|
|
43
48
|
"""Test coverage for generate_pset_dataset function"""
|
|
49
|
+
use_fake_spin_data_for_time(482372987.999)
|
|
44
50
|
l1b_de_path = hi_l1_test_data_path / "imap_hi_l1b_45sensor-de_20250415_v999.cdf"
|
|
45
51
|
l1b_dataset = load_cdf(l1b_de_path)
|
|
46
52
|
l1c_dataset = hi_l1c.generate_pset_dataset(
|
|
47
53
|
l1b_dataset, hi_test_cal_prod_config_path
|
|
48
54
|
)
|
|
49
55
|
|
|
50
|
-
assert l1c_dataset.epoch.data[0] ==
|
|
51
|
-
np.int64
|
|
52
|
-
)
|
|
56
|
+
assert l1c_dataset.epoch.data[0] == l1b_dataset.epoch.data[0].astype(np.int64)
|
|
53
57
|
|
|
54
58
|
np.testing.assert_array_equal(l1c_dataset.despun_z.data.shape, (1, 3))
|
|
55
59
|
np.testing.assert_array_equal(l1c_dataset.hae_latitude.data.shape, (1, 3600))
|
|
56
60
|
np.testing.assert_array_equal(l1c_dataset.hae_longitude.data.shape, (1, 3600))
|
|
61
|
+
np.testing.assert_array_equal(l1c_dataset.exposure_times.data.shape, (1, 9, 3600))
|
|
57
62
|
for var in [
|
|
58
63
|
"counts",
|
|
59
|
-
"exposure_times",
|
|
60
64
|
"background_rates",
|
|
61
65
|
"background_rates_uncertainty",
|
|
62
66
|
]:
|
|
63
67
|
np.testing.assert_array_equal(l1c_dataset[var].data.shape, (1, 9, 2, 3600))
|
|
64
68
|
|
|
65
69
|
# Test ISTP compliance by writing CDF
|
|
66
|
-
l1c_dataset.attrs["Data_version"] = 1
|
|
67
70
|
write_cdf(l1c_dataset)
|
|
68
71
|
|
|
69
72
|
|
|
@@ -74,7 +77,7 @@ def test_empty_pset_dataset():
|
|
|
74
77
|
n_calibration_prods = 5
|
|
75
78
|
sensor_str = HIAPID.H90_SCI_DE.sensor
|
|
76
79
|
dataset = hi_l1c.empty_pset_dataset(
|
|
77
|
-
l1b_esa_energy_steps, n_calibration_prods, sensor_str
|
|
80
|
+
100, l1b_esa_energy_steps, n_calibration_prods, sensor_str
|
|
78
81
|
)
|
|
79
82
|
|
|
80
83
|
assert dataset.epoch.size == 1
|
|
@@ -131,6 +134,225 @@ def test_pset_geometry(mock_frame_transform, mock_geom_frame_transform, sensor_s
|
|
|
131
134
|
)
|
|
132
135
|
|
|
133
136
|
|
|
137
|
+
@pytest.mark.external_test_data
|
|
138
|
+
def test_pset_counts(hi_l1_test_data_path, hi_test_cal_prod_config_path):
|
|
139
|
+
"""Test coverage for pset_counts function."""
|
|
140
|
+
l1b_de_path = hi_l1_test_data_path / "imap_hi_l1b_45sensor-de_20250415_v999.cdf"
|
|
141
|
+
l1b_dataset = load_cdf(l1b_de_path)
|
|
142
|
+
cal_config_df = hi_l1c.CalibrationProductConfig.from_csv(
|
|
143
|
+
hi_test_cal_prod_config_path
|
|
144
|
+
)
|
|
145
|
+
empty_pset = hi_l1c.empty_pset_dataset(
|
|
146
|
+
100,
|
|
147
|
+
l1b_dataset.esa_energy_step.data,
|
|
148
|
+
cal_config_df.cal_prod_config.number_of_products,
|
|
149
|
+
HIAPID.H90_SCI_DE.sensor,
|
|
150
|
+
)
|
|
151
|
+
counts_var = hi_l1c.pset_counts(empty_pset.coords, cal_config_df, l1b_dataset)
|
|
152
|
+
assert "counts" in counts_var
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def test_get_tof_window_mask():
|
|
156
|
+
"""Test coverage for get_tof_window_mask function."""
|
|
157
|
+
# Create a synthetic dataframe with required columns containing data
|
|
158
|
+
# intended to test all aspects of the function.
|
|
159
|
+
fill_vals = {
|
|
160
|
+
"tof_ab": -11,
|
|
161
|
+
"tof_ac1": -12,
|
|
162
|
+
"tof_bc1": -13,
|
|
163
|
+
"tof_c1c2": -14,
|
|
164
|
+
}
|
|
165
|
+
Row = namedtuple(
|
|
166
|
+
"Row",
|
|
167
|
+
[
|
|
168
|
+
"Index",
|
|
169
|
+
"tof_ab_low",
|
|
170
|
+
"tof_ab_high",
|
|
171
|
+
"tof_ac1_low",
|
|
172
|
+
"tof_ac1_high",
|
|
173
|
+
"tof_bc1_low",
|
|
174
|
+
"tof_bc1_high",
|
|
175
|
+
"tof_c1c2_low",
|
|
176
|
+
"tof_c1c2_high",
|
|
177
|
+
],
|
|
178
|
+
)
|
|
179
|
+
prod_config_row = Row((1, 0), 0, 1, -1, 2, 1, 5, 4, 6)
|
|
180
|
+
synth_df = pd.DataFrame(
|
|
181
|
+
{
|
|
182
|
+
"tof_ab": np.array(
|
|
183
|
+
[0, 2, 1, 0, -1, -5, -11], dtype=np.int32
|
|
184
|
+
), # T, F, T, T, F, F, FILL
|
|
185
|
+
"tof_ac1": np.array(
|
|
186
|
+
[-1, 2, -2, 0, 3, 0, -12], dtype=np.int32
|
|
187
|
+
), # T, T, F, T, F, T, FILL
|
|
188
|
+
"tof_bc1": np.array(
|
|
189
|
+
[1, 5, 3, 0, 6, 2, -13], dtype=np.int32
|
|
190
|
+
), # T, T, T, F, F, T, FILL
|
|
191
|
+
"tof_c1c2": np.array(
|
|
192
|
+
[4, 6, 5, 3, 7, -9, -14], dtype=np.int32
|
|
193
|
+
), # T, T, T, F, F, F, FILL
|
|
194
|
+
},
|
|
195
|
+
)
|
|
196
|
+
expected_mask = np.array([True, False, False, False, False, False, True])
|
|
197
|
+
window_mask = hi_l1c.get_tof_window_mask(synth_df, prod_config_row, fill_vals)
|
|
198
|
+
np.testing.assert_array_equal(expected_mask, window_mask)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
@mock.patch("imap_processing.hi.l1c.hi_l1c.get_spin_data", return_value=None)
|
|
202
|
+
@mock.patch("imap_processing.hi.l1c.hi_l1c.get_instrument_spin_phase")
|
|
203
|
+
@mock.patch("imap_processing.hi.l1c.hi_l1c.get_de_clock_ticks_for_esa_step")
|
|
204
|
+
@mock.patch("imap_processing.hi.l1c.hi_l1c.find_second_de_packet_data")
|
|
205
|
+
def test_pset_exposure(
|
|
206
|
+
mock_find_second_de_packet_data,
|
|
207
|
+
mock_de_clock_ticks,
|
|
208
|
+
mock_spin_phase,
|
|
209
|
+
mock_spin_data,
|
|
210
|
+
):
|
|
211
|
+
"""Test coverage for pset_exposure function"""
|
|
212
|
+
empty_pset = hi_l1c.empty_pset_dataset(
|
|
213
|
+
100, np.arange(2) + 1, 2, HIAPID.H90_SCI_DE.sensor
|
|
214
|
+
)
|
|
215
|
+
# Set the mock of find_second_de_packet_data to return a xr.Dataset
|
|
216
|
+
# with some dummy data. ESA 1 will get binned data once, ESA 2 will get
|
|
217
|
+
# binned data twice.
|
|
218
|
+
mock_find_second_de_packet_data.return_value = xr.Dataset(
|
|
219
|
+
coords={"epoch": xr.DataArray(np.arange(3), dims=["epoch"])},
|
|
220
|
+
data_vars={
|
|
221
|
+
"ccsds_met": xr.DataArray(np.arange(3), dims=["epoch"]),
|
|
222
|
+
"esa_energy_step": xr.DataArray(np.array([1, 2, 2]), dims=["epoch"]),
|
|
223
|
+
},
|
|
224
|
+
)
|
|
225
|
+
# Set mock of get_de_clock_ticks_for_esa_step and spin phase to generate
|
|
226
|
+
# deterministic histogram values.
|
|
227
|
+
# ESA step 1 should have repeating values of 3, 1.
|
|
228
|
+
# ESA step 2 should have repeating values of 6, 2
|
|
229
|
+
mock_spin_phase.return_value = np.concat(
|
|
230
|
+
[hi_l1c.SPIN_PHASE_BIN_CENTERS, hi_l1c.SPIN_PHASE_BIN_CENTERS[::2]]
|
|
231
|
+
)
|
|
232
|
+
mock_de_clock_ticks.return_value = (
|
|
233
|
+
np.zeros(hi_l1c.N_SPIN_BINS + hi_l1c.N_SPIN_BINS // 2),
|
|
234
|
+
np.concat([np.ones(hi_l1c.N_SPIN_BINS), np.ones(hi_l1c.N_SPIN_BINS // 2) * 2]),
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
# The above mocks mean no data needs to be in the l1b_dataset. It
|
|
238
|
+
# only needs to provide a logical source that contains "90sensor".
|
|
239
|
+
l1b_dataset = MagicMock()
|
|
240
|
+
l1b_dataset.attrs = {"Logical_source": "90sensor"}
|
|
241
|
+
|
|
242
|
+
# All the setup is done, call the pset_exposure function
|
|
243
|
+
exposure_dict = hi_l1c.pset_exposure(empty_pset.coords, l1b_dataset)
|
|
244
|
+
|
|
245
|
+
# Based on the spin phase and clock_tick mocks, the expected clock ticks are:
|
|
246
|
+
# - Repeated values of 3, 1 for the first half of the spin bins
|
|
247
|
+
# - Repeated values of 3, 2 for the second half of the spin bins
|
|
248
|
+
expected_values = np.stack(
|
|
249
|
+
[
|
|
250
|
+
np.tile([3, 1], hi_l1c.N_SPIN_BINS // 2),
|
|
251
|
+
np.tile([6, 2], hi_l1c.N_SPIN_BINS // 2),
|
|
252
|
+
]
|
|
253
|
+
).astype(float)[None, :, :]
|
|
254
|
+
# Convert expected clock ticks to seconds
|
|
255
|
+
expected_values *= DE_CLOCK_TICK_S
|
|
256
|
+
np.testing.assert_allclose(
|
|
257
|
+
exposure_dict["exposure_times"].data,
|
|
258
|
+
expected_values,
|
|
259
|
+
atol=DE_CLOCK_TICK_S / 100,
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def test_find_second_de_packet_data():
|
|
264
|
+
"""Test coverage for find_second_de_packet_data function"""
|
|
265
|
+
# Create a test l1b_dataset
|
|
266
|
+
# Expect to remove index 0 and 5 due to missing esa_step pair
|
|
267
|
+
# Expect to remove index 11 due to 0 being a calibration step
|
|
268
|
+
# Expect to return indices 2, 4, 7, 9, 13
|
|
269
|
+
esa_steps = np.array([1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 0, 0, 7, 7])
|
|
270
|
+
l1b_dataset = xr.Dataset(
|
|
271
|
+
coords={
|
|
272
|
+
"epoch": xr.DataArray(
|
|
273
|
+
np.arange(esa_steps.size),
|
|
274
|
+
dims=["epoch"],
|
|
275
|
+
),
|
|
276
|
+
"event_met": xr.DataArray(
|
|
277
|
+
np.arange(10),
|
|
278
|
+
dims=["event_met"],
|
|
279
|
+
),
|
|
280
|
+
},
|
|
281
|
+
data_vars={
|
|
282
|
+
"esa_step": xr.DataArray(
|
|
283
|
+
esa_steps,
|
|
284
|
+
dims=["epoch"],
|
|
285
|
+
),
|
|
286
|
+
"coincidence_type": xr.DataArray(
|
|
287
|
+
np.ones(10),
|
|
288
|
+
dims=["event_met"],
|
|
289
|
+
),
|
|
290
|
+
},
|
|
291
|
+
)
|
|
292
|
+
subset = hi_l1c.find_second_de_packet_data(l1b_dataset)
|
|
293
|
+
np.testing.assert_array_equal(subset.epoch.data, np.array([2, 4, 7, 9, 13]))
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
@pytest.fixture(scope="module")
|
|
297
|
+
def fake_spin_df():
|
|
298
|
+
"""Generate a synthetic spin dataframe"""
|
|
299
|
+
# Generate some spin periods that vary by a random fraction of a second
|
|
300
|
+
spin_period = np.full(10, 15) + np.random.randn(10) / 10
|
|
301
|
+
d = {
|
|
302
|
+
"spin_start_met": np.add.accumulate(spin_period),
|
|
303
|
+
"spin_period_sec": spin_period,
|
|
304
|
+
}
|
|
305
|
+
spin_df = pd.DataFrame.from_dict(d)
|
|
306
|
+
return spin_df
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def test_get_de_clock_ticks_for_esa_step(fake_spin_df):
|
|
310
|
+
"""Test coverage for get_de_clock_ticks_for_esa_step function."""
|
|
311
|
+
|
|
312
|
+
# Test nominal cases where CCSDS met falls after 8th spin start and before
|
|
313
|
+
# the end spin in the table + 1/2 spin period
|
|
314
|
+
for _, spin_row in fake_spin_df.iloc[8:].iterrows():
|
|
315
|
+
for ccsds_met in np.linspace(
|
|
316
|
+
spin_row.spin_start_met,
|
|
317
|
+
spin_row.spin_start_met + np.floor(spin_row.spin_period_sec / 2),
|
|
318
|
+
10,
|
|
319
|
+
):
|
|
320
|
+
clock_tick_mets, clock_tick_weights = (
|
|
321
|
+
hi_l1c.get_de_clock_ticks_for_esa_step(ccsds_met, fake_spin_df)
|
|
322
|
+
)
|
|
323
|
+
np.testing.assert_array_equal(clock_tick_mets.shape, clock_tick_mets.shape)
|
|
324
|
+
# Verify last weight entry
|
|
325
|
+
exp_final_weight = (
|
|
326
|
+
np.absolute(
|
|
327
|
+
fake_spin_df.spin_start_met.to_numpy() - clock_tick_mets[-1]
|
|
328
|
+
).min()
|
|
329
|
+
/ DE_CLOCK_TICK_S
|
|
330
|
+
)
|
|
331
|
+
assert clock_tick_weights[-1] == exp_final_weight
|
|
332
|
+
assert np.all(clock_tick_weights[:-1] == 1)
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def test_get_de_clock_ticks_for_esa_step_exceptions(fake_spin_df):
|
|
336
|
+
"""Test the exception logic in the get_de_clock_ticks_for_esa_step function."""
|
|
337
|
+
# Test the ccsds_met being > 1/2 spin period past the spin start
|
|
338
|
+
bad_ccsds_met = (
|
|
339
|
+
fake_spin_df.iloc[8].spin_start_met
|
|
340
|
+
+ fake_spin_df.iloc[8].spin_period_sec / 2
|
|
341
|
+
+ 0.1
|
|
342
|
+
)
|
|
343
|
+
with pytest.raises(
|
|
344
|
+
ValueError, match="The difference between ccsds_met and spin_start_met"
|
|
345
|
+
):
|
|
346
|
+
hi_l1c.get_de_clock_ticks_for_esa_step(bad_ccsds_met, fake_spin_df)
|
|
347
|
+
|
|
348
|
+
# Test the ccsds_met being too close to the start of the spin table
|
|
349
|
+
bad_ccsds_met = fake_spin_df.iloc[7].spin_start_met
|
|
350
|
+
with pytest.raises(
|
|
351
|
+
ValueError, match="Error determining start/end time for exposure time"
|
|
352
|
+
):
|
|
353
|
+
hi_l1c.get_de_clock_ticks_for_esa_step(bad_ccsds_met, fake_spin_df)
|
|
354
|
+
|
|
355
|
+
|
|
134
356
|
class TestCalibrationProductConfig:
|
|
135
357
|
"""
|
|
136
358
|
All test coverage for the pd.DataFrame accessor extension "cal_prod_config".
|
|
@@ -138,7 +360,7 @@ class TestCalibrationProductConfig:
|
|
|
138
360
|
|
|
139
361
|
def test_wrong_columns(self):
|
|
140
362
|
"""Test coverage for a dataframe with the wrong columns."""
|
|
141
|
-
required_columns = CalibrationProductConfig.required_columns
|
|
363
|
+
required_columns = hi_l1c.CalibrationProductConfig.required_columns
|
|
142
364
|
for exclude_column_name in required_columns:
|
|
143
365
|
include_columns = set(required_columns) - {exclude_column_name}
|
|
144
366
|
df = pd.DataFrame({col: [1, 2, 3] for col in include_columns})
|
|
@@ -147,10 +369,19 @@ class TestCalibrationProductConfig:
|
|
|
147
369
|
|
|
148
370
|
def test_from_csv(self, hi_test_cal_prod_config_path):
|
|
149
371
|
"""Test coverage for read_csv function."""
|
|
372
|
+
df = hi_l1c.CalibrationProductConfig.from_csv(hi_test_cal_prod_config_path)
|
|
373
|
+
assert isinstance(df["coincidence_type_list"][0, 1], tuple)
|
|
374
|
+
|
|
375
|
+
def test_added_coincidence_type_values_column(self, hi_test_cal_prod_config_path):
|
|
150
376
|
df = CalibrationProductConfig.from_csv(hi_test_cal_prod_config_path)
|
|
151
|
-
assert
|
|
377
|
+
assert "coincidence_type_values" in df.columns
|
|
378
|
+
for _, row in df.iterrows():
|
|
379
|
+
for detect_string, val in zip(
|
|
380
|
+
row["coincidence_type_list"], row["coincidence_type_values"]
|
|
381
|
+
):
|
|
382
|
+
assert val == CoincidenceBitmap.detector_hit_str_to_int(detect_string)
|
|
152
383
|
|
|
153
384
|
def test_number_of_products(self, hi_test_cal_prod_config_path):
|
|
154
385
|
"""Test coverage for number of products accessor."""
|
|
155
|
-
df = CalibrationProductConfig.from_csv(hi_test_cal_prod_config_path)
|
|
386
|
+
df = hi_l1c.CalibrationProductConfig.from_csv(hi_test_cal_prod_config_path)
|
|
156
387
|
assert df.cal_prod_config.number_of_products == 2
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import numpy as np
|
|
2
|
+
import pandas as pd
|
|
2
3
|
|
|
3
4
|
from imap_processing.cdf.utils import write_cdf
|
|
4
5
|
from imap_processing.hi.l1a.hi_l1a import hi_l1a
|
|
@@ -10,29 +11,56 @@ def test_sci_de_decom(hi_l0_test_data_path):
|
|
|
10
11
|
"""Test science direct event data"""
|
|
11
12
|
|
|
12
13
|
bin_data_path = hi_l0_test_data_path / "H90_sci_de_20241104.bin"
|
|
13
|
-
processed_data = hi_l1a(bin_data_path
|
|
14
|
+
processed_data = hi_l1a(bin_data_path)
|
|
14
15
|
|
|
15
16
|
assert processed_data[0].attrs["Logical_source"] == "imap_hi_l1a_90sensor-de"
|
|
16
|
-
assert processed_data[0].attrs["Data_version"] == "001"
|
|
17
17
|
|
|
18
18
|
# TODO: Verify correct unpacking of sample data. Issue: #1186
|
|
19
19
|
|
|
20
20
|
# Write to CDF
|
|
21
|
-
cdf_filename = "imap_hi_l1a_90sensor-
|
|
21
|
+
cdf_filename = "imap_hi_l1a_90sensor-de_20241105_v999.cdf"
|
|
22
22
|
cdf_filepath = write_cdf(processed_data[0])
|
|
23
23
|
assert cdf_filepath.name == cdf_filename
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
def test_diag_fee_decom(hi_l0_test_data_path):
|
|
27
|
+
"""Test diag_fee data"""
|
|
28
|
+
bin_data_path = hi_l0_test_data_path / "H45_diag_fee_20250208.bin"
|
|
29
|
+
processed_data = hi_l1a(packet_file_path=bin_data_path)
|
|
30
|
+
dataset = processed_data[0]
|
|
31
|
+
cdf_filepath = write_cdf(processed_data[0], istp=False)
|
|
32
|
+
assert cdf_filepath.name == "imap_hi_l1a_45sensor-diagfee_20250208_v999.cdf"
|
|
33
|
+
|
|
34
|
+
assert np.unique(processed_data[0]["pkt_apid"].values) == HIAPID.H45_DIAG_FEE.value
|
|
35
|
+
|
|
36
|
+
validation_df = pd.read_csv(
|
|
37
|
+
hi_l0_test_data_path / "H45_diag_fee_20250208_verify.csv"
|
|
38
|
+
)
|
|
39
|
+
val_to_test_map = {
|
|
40
|
+
"PHVERNO": "version",
|
|
41
|
+
"PHTYPE": "type",
|
|
42
|
+
"PHSHF": "sec_hdr_flg",
|
|
43
|
+
"PHAPID": "pkt_apid",
|
|
44
|
+
"PHGROUPF": "seq_flgs",
|
|
45
|
+
"PHSEQCNT": "src_seq_ctr",
|
|
46
|
+
"PHDLEN": "pkt_len",
|
|
47
|
+
}
|
|
48
|
+
for col_name, series in validation_df.items():
|
|
49
|
+
if col_name == "timestamp":
|
|
50
|
+
continue
|
|
51
|
+
ds_var_name = val_to_test_map.get(col_name, col_name.lower())
|
|
52
|
+
np.testing.assert_array_equal(series.values, dataset[ds_var_name].data)
|
|
53
|
+
|
|
54
|
+
|
|
26
55
|
def test_app_nhk_decom(hi_l0_test_data_path):
|
|
27
56
|
"""Test housekeeping data"""
|
|
28
57
|
|
|
29
58
|
# Unpack housekeeping data
|
|
30
59
|
bin_data_path = hi_l0_test_data_path / "H90_NHK_20241104.bin"
|
|
31
|
-
processed_data = hi_l1a(packet_file_path=bin_data_path
|
|
60
|
+
processed_data = hi_l1a(packet_file_path=bin_data_path)
|
|
32
61
|
|
|
33
62
|
assert np.unique(processed_data[0]["pkt_apid"].values) == HIAPID.H90_APP_NHK.value
|
|
34
63
|
assert processed_data[0].attrs["Logical_source"] == "imap_hi_l1a_90sensor-hk"
|
|
35
|
-
assert processed_data[0].attrs["Data_version"] == "001"
|
|
36
64
|
# TODO: compare with validation data once we have it. Issue: #1184
|
|
37
65
|
|
|
38
66
|
# Write CDF
|
|
@@ -40,13 +68,13 @@ def test_app_nhk_decom(hi_l0_test_data_path):
|
|
|
40
68
|
|
|
41
69
|
# TODO: ask Vivek about this date mismatch between the file name
|
|
42
70
|
# and the data. May get resolved when we have good sample data.
|
|
43
|
-
assert cem_raw_cdf_filepath.name == "imap_hi_l1a_90sensor-
|
|
71
|
+
assert cem_raw_cdf_filepath.name == "imap_hi_l1a_90sensor-hk_20241105_v999.cdf"
|
|
44
72
|
|
|
45
73
|
|
|
46
74
|
def test_app_hist_decom(hi_l0_test_data_path):
|
|
47
75
|
"""Test histogram (SCI_CNT) data"""
|
|
48
76
|
bin_data_path = hi_l0_test_data_path / "H90_sci_cnt_20241104.bin"
|
|
49
|
-
processed_data = hi_l1a(packet_file_path=bin_data_path
|
|
77
|
+
processed_data = hi_l1a(packet_file_path=bin_data_path)
|
|
50
78
|
|
|
51
79
|
assert processed_data[0].attrs["Logical_source"] == "imap_hi_l1a_90sensor-hist"
|
|
52
80
|
# TODO: compare with validation data once we have it. Issue: #1185
|
|
@@ -21,8 +21,8 @@ def test_parse_direct_events():
|
|
|
21
21
|
# Encode the random events data into a bit-string
|
|
22
22
|
bin_str = ""
|
|
23
23
|
for i in range(n_events):
|
|
24
|
-
bin_str += f"{exp_dict['trigger_id'][i]:02b}" # 2-bits for trigger_id
|
|
25
24
|
bin_str += f"{exp_dict['de_tag'][i]:016b}" # 16-bits for de_tag
|
|
25
|
+
bin_str += f"{exp_dict['trigger_id'][i]:02b}" # 2-bits for trigger_id
|
|
26
26
|
bin_str += f"{exp_dict['tof_1'][i]:010b}" # 10-bits for tof_1
|
|
27
27
|
bin_str += f"{exp_dict['tof_2'][i]:010b}" # 10-bits for tof_2
|
|
28
28
|
bin_str += f"{exp_dict['tof_3'][i]:010b}" # 10-bits for tof_3
|
|
@@ -30,8 +30,8 @@ def test_parse_direct_events():
|
|
|
30
30
|
bytes_obj = bytes([int(bin_str[i : i + 8], 2) for i in range(0, len(bin_str), 8)])
|
|
31
31
|
# Parse the fake events and check values
|
|
32
32
|
de_dict = parse_direct_events(bytes_obj)
|
|
33
|
-
for key in exp_dict.
|
|
34
|
-
np.testing.assert_array_equal(de_dict[key],
|
|
33
|
+
for key, expected_val in exp_dict.items():
|
|
34
|
+
np.testing.assert_array_equal(de_dict[key], expected_val)
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
def test_create_dataset():
|
|
@@ -7,6 +7,7 @@ import xarray as xr
|
|
|
7
7
|
from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
|
|
8
8
|
from imap_processing.hi.utils import (
|
|
9
9
|
HIAPID,
|
|
10
|
+
CoincidenceBitmap,
|
|
10
11
|
create_dataset_variables,
|
|
11
12
|
full_dataarray,
|
|
12
13
|
parse_sensor_number,
|
|
@@ -74,13 +75,13 @@ def test_full_dataarray(name, shape, fill_value, expected_shape):
|
|
|
74
75
|
@pytest.mark.parametrize(
|
|
75
76
|
"var_names, shape, fill_value, lookup_str",
|
|
76
77
|
[
|
|
77
|
-
(["
|
|
78
|
+
(["tof_ab", "tof_ac1"], 5, None, "hi_de_{0}"),
|
|
78
79
|
(["hae_latitude"], (3, 5), 0, "hi_pset_{0}"),
|
|
79
80
|
],
|
|
80
81
|
)
|
|
81
82
|
def test_create_dataset_variables(var_names, shape, fill_value, lookup_str):
|
|
82
83
|
"""Test coverage for `imap_processing.hi.utils.create_dataset_variables`"""
|
|
83
|
-
var_names = ["
|
|
84
|
+
var_names = ["tof_ab", "tof_ac1", "tof_bc1"]
|
|
84
85
|
l1b_de_vars = create_dataset_variables(
|
|
85
86
|
var_names, shape, fill_value=fill_value, att_manager_lookup_str="hi_de_{0}"
|
|
86
87
|
)
|
|
@@ -100,3 +101,24 @@ def test_create_dataset_variables(var_names, shape, fill_value, lookup_str):
|
|
|
100
101
|
assert data_array.shape == shape
|
|
101
102
|
expected_fill_value = fill_value if fill_value is not None else attrs["FILLVAL"]
|
|
102
103
|
np.testing.assert_array_equal(data_array, expected_fill_value)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@pytest.mark.parametrize(
|
|
107
|
+
"sensor_hit_str, expected_val",
|
|
108
|
+
[
|
|
109
|
+
("ABC1C2", 15),
|
|
110
|
+
("ABC1", 14),
|
|
111
|
+
("AB", 12),
|
|
112
|
+
("AC1C2", 11),
|
|
113
|
+
("AC1", 10),
|
|
114
|
+
("A", 8),
|
|
115
|
+
("BC1C2", 7),
|
|
116
|
+
("BC1", 6),
|
|
117
|
+
("B", 4),
|
|
118
|
+
("C1C2", 3),
|
|
119
|
+
("C1", 2),
|
|
120
|
+
],
|
|
121
|
+
)
|
|
122
|
+
def test_coincidence_type_string_to_int(sensor_hit_str, expected_val):
|
|
123
|
+
"""Test coverage for coincidence_type_string_to_int function"""
|
|
124
|
+
assert CoincidenceBitmap.detector_hit_str_to_int(sensor_hit_str) == expected_val
|