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
|
@@ -6,9 +6,7 @@ import xarray as xr
|
|
|
6
6
|
from imap_processing.ultra.utils.ultra_l1_utils import create_dataset
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
def calculate_histogram(
|
|
10
|
-
histogram_dataset: xr.Dataset, name: str, data_version: str
|
|
11
|
-
) -> xr.Dataset:
|
|
9
|
+
def calculate_histogram(histogram_dataset: xr.Dataset, name: str) -> xr.Dataset:
|
|
12
10
|
"""
|
|
13
11
|
Create dictionary with defined datatype for Histogram Data.
|
|
14
12
|
|
|
@@ -18,8 +16,6 @@ def calculate_histogram(
|
|
|
18
16
|
Dataset containing histogram data.
|
|
19
17
|
name : str
|
|
20
18
|
Name of dataset.
|
|
21
|
-
data_version : str
|
|
22
|
-
Version of the data.
|
|
23
19
|
|
|
24
20
|
Returns
|
|
25
21
|
-------
|
|
@@ -35,6 +31,6 @@ def calculate_histogram(
|
|
|
35
31
|
histogram_dict["epoch"] = epoch
|
|
36
32
|
histogram_dict["sid"] = np.zeros(len(epoch), dtype=np.uint8)
|
|
37
33
|
|
|
38
|
-
dataset = create_dataset(histogram_dict, name, "l1c"
|
|
34
|
+
dataset = create_dataset(histogram_dict, name, "l1c")
|
|
39
35
|
|
|
40
36
|
return dataset
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"""Calculate Pointing Set Grids."""
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import pandas as pd
|
|
5
|
+
import xarray as xr
|
|
6
|
+
|
|
7
|
+
from imap_processing import imap_module_directory
|
|
8
|
+
from imap_processing.ultra.l1c.ultra_l1c_pset_bins import (
|
|
9
|
+
build_energy_bins,
|
|
10
|
+
get_background_rates,
|
|
11
|
+
get_spacecraft_exposure_times,
|
|
12
|
+
get_spacecraft_histogram,
|
|
13
|
+
)
|
|
14
|
+
from imap_processing.ultra.utils.ultra_l1_utils import create_dataset
|
|
15
|
+
|
|
16
|
+
# TODO: This is a placeholder for the API lookup table directory.
|
|
17
|
+
TEST_PATH = imap_module_directory / "tests" / "ultra" / "data" / "l1"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def calculate_spacecraft_pset(
|
|
21
|
+
de_dataset: xr.Dataset,
|
|
22
|
+
extendedspin_dataset: xr.Dataset,
|
|
23
|
+
cullingmask_dataset: xr.Dataset,
|
|
24
|
+
name: str,
|
|
25
|
+
) -> xr.Dataset:
|
|
26
|
+
"""
|
|
27
|
+
Create dictionary with defined datatype for Pointing Set Grid Data.
|
|
28
|
+
|
|
29
|
+
Parameters
|
|
30
|
+
----------
|
|
31
|
+
de_dataset : xarray.Dataset
|
|
32
|
+
Dataset containing de data.
|
|
33
|
+
extendedspin_dataset : xarray.Dataset
|
|
34
|
+
Dataset containing extendedspin data.
|
|
35
|
+
cullingmask_dataset : xarray.Dataset
|
|
36
|
+
Dataset containing cullingmask data.
|
|
37
|
+
name : str
|
|
38
|
+
Name of the dataset.
|
|
39
|
+
|
|
40
|
+
Returns
|
|
41
|
+
-------
|
|
42
|
+
dataset : xarray.Dataset
|
|
43
|
+
Dataset containing the data.
|
|
44
|
+
"""
|
|
45
|
+
pset_dict: dict[str, np.ndarray] = {}
|
|
46
|
+
|
|
47
|
+
v_mag_dps_spacecraft = np.linalg.norm(de_dataset["velocity_dps_sc"].values, axis=1)
|
|
48
|
+
vhat_dps_spacecraft = (
|
|
49
|
+
de_dataset["velocity_dps_sc"].values / v_mag_dps_spacecraft[:, np.newaxis]
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
intervals, _, energy_bin_geometric_means = build_energy_bins()
|
|
53
|
+
counts, latitude, longitude, n_pix = get_spacecraft_histogram(
|
|
54
|
+
vhat_dps_spacecraft,
|
|
55
|
+
de_dataset["energy_spacecraft"].values,
|
|
56
|
+
intervals,
|
|
57
|
+
nside=128,
|
|
58
|
+
)
|
|
59
|
+
healpix = np.arange(n_pix)
|
|
60
|
+
|
|
61
|
+
# calculate background rates
|
|
62
|
+
background_rates = get_background_rates()
|
|
63
|
+
|
|
64
|
+
# TODO: calculate sensitivity and interpolate based on energy.
|
|
65
|
+
|
|
66
|
+
# Calculate exposure
|
|
67
|
+
constant_exposure = TEST_PATH / "ultra_90_dps_exposure.csv"
|
|
68
|
+
df_exposure = pd.read_csv(constant_exposure)
|
|
69
|
+
exposure_pointing = get_spacecraft_exposure_times(df_exposure)
|
|
70
|
+
|
|
71
|
+
# For ISTP, epoch should be the center of the time bin.
|
|
72
|
+
pset_dict["epoch"] = de_dataset.epoch.data[0].astype(np.int64)
|
|
73
|
+
pset_dict["counts"] = counts
|
|
74
|
+
pset_dict["latitude"] = latitude
|
|
75
|
+
pset_dict["longitude"] = longitude
|
|
76
|
+
pset_dict["energy_bin_geometric_mean"] = energy_bin_geometric_means
|
|
77
|
+
pset_dict["background_rates"] = background_rates
|
|
78
|
+
pset_dict["exposure_factor"] = exposure_pointing
|
|
79
|
+
pset_dict["healpix"] = healpix
|
|
80
|
+
pset_dict["energy_bin_delta"] = np.diff(intervals, axis=1).squeeze()
|
|
81
|
+
|
|
82
|
+
dataset = create_dataset(pset_dict, name, "l1c")
|
|
83
|
+
|
|
84
|
+
return dataset
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
import xarray as xr
|
|
4
4
|
|
|
5
5
|
from imap_processing.ultra.l1c.histogram import calculate_histogram
|
|
6
|
-
from imap_processing.ultra.l1c.
|
|
6
|
+
from imap_processing.ultra.l1c.spacecraft_pset import calculate_spacecraft_pset
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
def ultra_l1c(data_dict: dict
|
|
9
|
+
def ultra_l1c(data_dict: dict) -> list[xr.Dataset]:
|
|
10
10
|
"""
|
|
11
11
|
Will process ULTRA L1A and L1B data into L1C CDF files at output_filepath.
|
|
12
12
|
|
|
@@ -14,8 +14,6 @@ def ultra_l1c(data_dict: dict, data_version: str) -> list[xr.Dataset]:
|
|
|
14
14
|
----------
|
|
15
15
|
data_dict : dict
|
|
16
16
|
The data itself and its dependent data.
|
|
17
|
-
data_version : str
|
|
18
|
-
Version of the data product being created.
|
|
19
17
|
|
|
20
18
|
Returns
|
|
21
19
|
-------
|
|
@@ -31,7 +29,6 @@ def ultra_l1c(data_dict: dict, data_version: str) -> list[xr.Dataset]:
|
|
|
31
29
|
histogram_dataset = calculate_histogram(
|
|
32
30
|
data_dict[f"imap_ultra_l1a_{instrument_id}sensor-histogram"],
|
|
33
31
|
f"imap_ultra_l1c_{instrument_id}sensor-histogram",
|
|
34
|
-
data_version,
|
|
35
32
|
)
|
|
36
33
|
output_datasets = [histogram_dataset]
|
|
37
34
|
elif (
|
|
@@ -39,12 +36,14 @@ def ultra_l1c(data_dict: dict, data_version: str) -> list[xr.Dataset]:
|
|
|
39
36
|
and f"imap_ultra_l1b_{instrument_id}sensor-de" in data_dict
|
|
40
37
|
and f"imap_ultra_l1b_{instrument_id}sensor-extendedspin" in data_dict
|
|
41
38
|
):
|
|
42
|
-
|
|
39
|
+
spacecraft_pset = calculate_spacecraft_pset(
|
|
43
40
|
data_dict[f"imap_ultra_l1b_{instrument_id}sensor-de"],
|
|
44
|
-
f"
|
|
45
|
-
|
|
41
|
+
data_dict[f"imap_ultra_l1b_{instrument_id}sensor-extendedspin"],
|
|
42
|
+
data_dict[f"imap_ultra_l1b_{instrument_id}sensor-cullingmask"],
|
|
43
|
+
f"imap_ultra_l1c_{instrument_id}sensor-spacecraftpset",
|
|
46
44
|
)
|
|
47
|
-
|
|
45
|
+
# TODO: add calculate_helio_pset here
|
|
46
|
+
output_datasets = [spacecraft_pset]
|
|
48
47
|
else:
|
|
49
48
|
raise ValueError("Data dictionary does not contain the expected keys.")
|
|
50
49
|
|
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
"""Module to create pointing sets."""
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import cdflib
|
|
3
|
+
import astropy_healpix.healpy as hp
|
|
6
4
|
import numpy as np
|
|
5
|
+
import pandas
|
|
6
|
+
import pandas as pd
|
|
7
7
|
from numpy.typing import NDArray
|
|
8
|
+
from scipy.interpolate import interp1d
|
|
8
9
|
|
|
9
|
-
from imap_processing.ena_maps.utils.spatial_utils import build_spatial_bins
|
|
10
10
|
from imap_processing.spice.geometry import (
|
|
11
11
|
SpiceFrame,
|
|
12
12
|
cartesian_to_spherical,
|
|
13
13
|
imap_state,
|
|
14
|
-
spherical_to_cartesian,
|
|
15
14
|
)
|
|
16
15
|
from imap_processing.ultra.constants import UltraConstants
|
|
17
16
|
|
|
18
17
|
# TODO: add species binning.
|
|
19
18
|
|
|
20
19
|
|
|
21
|
-
def build_energy_bins() -> tuple[list[tuple[float, float]], np.ndarray]:
|
|
20
|
+
def build_energy_bins() -> tuple[list[tuple[float, float]], np.ndarray, np.ndarray]:
|
|
22
21
|
"""
|
|
23
22
|
Build energy bin boundaries.
|
|
24
23
|
|
|
@@ -28,6 +27,8 @@ def build_energy_bins() -> tuple[list[tuple[float, float]], np.ndarray]:
|
|
|
28
27
|
Energy bins.
|
|
29
28
|
energy_midpoints : np.ndarray
|
|
30
29
|
Array of energy bin midpoints.
|
|
30
|
+
energy_bin_geometric_means : np.ndarray
|
|
31
|
+
Array of geometric means of energy bins.
|
|
31
32
|
"""
|
|
32
33
|
# Calculate energy step
|
|
33
34
|
energy_step = (1 + UltraConstants.ALPHA / 2) / (1 - UltraConstants.ALPHA / 2)
|
|
@@ -44,19 +45,20 @@ def build_energy_bins() -> tuple[list[tuple[float, float]], np.ndarray]:
|
|
|
44
45
|
(float(energy_bin_edges[i]), float(energy_bin_edges[i + 1]))
|
|
45
46
|
for i in range(len(energy_bin_edges) - 1)
|
|
46
47
|
]
|
|
48
|
+
energy_bin_geometric_means = np.sqrt(energy_bin_edges[:-1] * energy_bin_edges[1:])
|
|
47
49
|
|
|
48
|
-
return intervals, energy_midpoints
|
|
50
|
+
return intervals, energy_midpoints, energy_bin_geometric_means
|
|
49
51
|
|
|
50
52
|
|
|
51
|
-
def
|
|
53
|
+
def get_spacecraft_histogram(
|
|
52
54
|
vhat: tuple[np.ndarray, np.ndarray, np.ndarray],
|
|
53
55
|
energy: np.ndarray,
|
|
54
|
-
az_bin_edges: np.ndarray,
|
|
55
|
-
el_bin_edges: np.ndarray,
|
|
56
56
|
energy_bin_edges: list[tuple[float, float]],
|
|
57
|
-
|
|
57
|
+
nside: int = 128,
|
|
58
|
+
nested: bool = False,
|
|
59
|
+
) -> tuple[NDArray, NDArray, NDArray, NDArray]:
|
|
58
60
|
"""
|
|
59
|
-
Compute a 3D histogram of the particle data.
|
|
61
|
+
Compute a 3D histogram of the particle data using HEALPix binning.
|
|
60
62
|
|
|
61
63
|
Parameters
|
|
62
64
|
----------
|
|
@@ -64,123 +66,165 @@ def get_histogram(
|
|
|
64
66
|
The x,y,z-components of the unit velocity vector.
|
|
65
67
|
energy : np.ndarray
|
|
66
68
|
The particle energy.
|
|
67
|
-
az_bin_edges : np.ndarray
|
|
68
|
-
Array of azimuth bin boundary values.
|
|
69
|
-
el_bin_edges : np.ndarray
|
|
70
|
-
Array of elevation bin boundary values.
|
|
71
69
|
energy_bin_edges : list[tuple[float, float]]
|
|
72
70
|
Array of energy bin edges.
|
|
71
|
+
nside : int, optional
|
|
72
|
+
The nside parameter of the Healpix tessellation.
|
|
73
|
+
Default is 128.
|
|
74
|
+
nested : bool, optional
|
|
75
|
+
Whether the Healpix tessellation is nested. Default is False.
|
|
73
76
|
|
|
74
77
|
Returns
|
|
75
78
|
-------
|
|
76
79
|
hist : np.ndarray
|
|
77
|
-
A 3D histogram array.
|
|
80
|
+
A 3D histogram array with shape (n_pix, n_energy_bins).
|
|
81
|
+
latitude : np.ndarray
|
|
82
|
+
Array of latitude values.
|
|
83
|
+
longitude : np.ndarray
|
|
84
|
+
Array of longitude values.
|
|
85
|
+
n_pix : int
|
|
86
|
+
Number of healpix pixels.
|
|
78
87
|
|
|
79
88
|
Notes
|
|
80
89
|
-----
|
|
81
|
-
The histogram will
|
|
90
|
+
The histogram will work properly for overlapping energy bins, i.e.
|
|
82
91
|
the same energy value can fall into multiple bins if the intervals overlap.
|
|
92
|
+
|
|
93
|
+
azimuthal angle [0, 360], elevation angle [-90, 90]
|
|
83
94
|
"""
|
|
84
|
-
|
|
95
|
+
# vhat = direction in which particle is traveling
|
|
96
|
+
# Make negative to see where it came from
|
|
97
|
+
spherical_coords = cartesian_to_spherical(-np.array(vhat), degrees=True)
|
|
85
98
|
az, el = (
|
|
86
99
|
spherical_coords[..., 1],
|
|
87
100
|
spherical_coords[..., 2],
|
|
88
101
|
)
|
|
89
102
|
|
|
90
|
-
#
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
)
|
|
103
|
+
# Compute number of HEALPix pixels that cover the sphere
|
|
104
|
+
n_pix = hp.nside2npix(nside)
|
|
105
|
+
|
|
106
|
+
# Calculate the corresponding longitude (az) latitude (el)
|
|
107
|
+
# center coordinates
|
|
108
|
+
longitude, latitude = hp.pix2ang(nside, np.arange(n_pix), lonlat=True)
|
|
109
|
+
|
|
110
|
+
# Get HEALPix pixel indices for each event
|
|
111
|
+
# HEALPix expects latitude in [-90, 90] so we don't need to change elevation
|
|
112
|
+
hpix_idx = hp.ang2pix(nside, az, el, nest=nested, lonlat=True)
|
|
113
|
+
|
|
114
|
+
# Initialize histogram: (n_energy_bins, n_HEALPix pixels)
|
|
115
|
+
hist = np.zeros((len(energy_bin_edges), n_pix))
|
|
94
116
|
|
|
117
|
+
# Bin data in energy & HEALPix space
|
|
95
118
|
for i, (e_min, e_max) in enumerate(energy_bin_edges):
|
|
96
|
-
# Filter data for current energy bin.
|
|
97
119
|
mask = (energy >= e_min) & (energy < e_max)
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
bins=[az_bin_edges, el_bin_edges, [e_min, e_max]],
|
|
101
|
-
)
|
|
102
|
-
# Assign 2D histogram to current energy bin.
|
|
103
|
-
hist_total[:, :, i] = hist[:, :, 0]
|
|
120
|
+
# Only count the events that fall within the energy bin
|
|
121
|
+
hist[i, :] += np.bincount(hpix_idx[mask], minlength=n_pix).astype(np.float64)
|
|
104
122
|
|
|
105
|
-
return
|
|
123
|
+
return hist, latitude, longitude, n_pix
|
|
106
124
|
|
|
107
125
|
|
|
108
|
-
def
|
|
109
|
-
|
|
126
|
+
def get_background_rates(
|
|
127
|
+
nside: int = 128,
|
|
110
128
|
) -> NDArray:
|
|
111
129
|
"""
|
|
112
|
-
|
|
130
|
+
Calculate background rates.
|
|
113
131
|
|
|
114
132
|
Parameters
|
|
115
133
|
----------
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
n_spins : int
|
|
119
|
-
Number of spins per pointing.
|
|
120
|
-
sensor : str
|
|
121
|
-
Sensor (45 or 90).
|
|
134
|
+
nside : int, optional
|
|
135
|
+
The nside parameter of the Healpix tessellation (default is 128).
|
|
122
136
|
|
|
123
137
|
Returns
|
|
124
138
|
-------
|
|
125
|
-
|
|
126
|
-
|
|
139
|
+
background_rates : np.ndarray
|
|
140
|
+
Array of background rates.
|
|
141
|
+
|
|
142
|
+
Notes
|
|
143
|
+
-----
|
|
144
|
+
This is a placeholder.
|
|
127
145
|
"""
|
|
128
|
-
|
|
129
|
-
|
|
146
|
+
n_pix = hp.nside2npix(nside)
|
|
147
|
+
return np.zeros(n_pix)
|
|
130
148
|
|
|
131
|
-
|
|
149
|
+
|
|
150
|
+
def get_spacecraft_exposure_times(constant_exposure: pandas.DataFrame) -> NDArray:
|
|
151
|
+
"""
|
|
152
|
+
Compute exposure times for HEALPix pixels.
|
|
153
|
+
|
|
154
|
+
Parameters
|
|
155
|
+
----------
|
|
156
|
+
constant_exposure : pandas.DataFrame
|
|
157
|
+
Exposure data.
|
|
158
|
+
|
|
159
|
+
Returns
|
|
160
|
+
-------
|
|
161
|
+
exposure_pointing : np.ndarray
|
|
162
|
+
Total exposure times of pixels in a
|
|
163
|
+
Healpix tessellation of the sky
|
|
164
|
+
in the pointing (dps) frame.
|
|
165
|
+
"""
|
|
166
|
+
# TODO: use the universal spin table and
|
|
167
|
+
# universal pointing table here to determine actual number of spins
|
|
168
|
+
exposure_pointing = (
|
|
169
|
+
constant_exposure["Exposure Time"] * 5760
|
|
170
|
+
) # 5760 spins per pointing (for now)
|
|
171
|
+
|
|
172
|
+
return exposure_pointing
|
|
132
173
|
|
|
133
174
|
|
|
134
175
|
def get_helio_exposure_times(
|
|
135
176
|
time: np.ndarray,
|
|
136
|
-
|
|
177
|
+
df_exposure: pd.DataFrame,
|
|
178
|
+
nside: int = 128,
|
|
179
|
+
nested: bool = False,
|
|
137
180
|
) -> NDArray:
|
|
138
181
|
"""
|
|
139
|
-
Compute a
|
|
182
|
+
Compute a 2D (Healpix index, energy) array of exposure in the helio frame.
|
|
140
183
|
|
|
141
184
|
Parameters
|
|
142
185
|
----------
|
|
143
186
|
time : np.ndarray
|
|
144
|
-
Median time of pointing in
|
|
145
|
-
|
|
146
|
-
Spacecraft exposure.
|
|
187
|
+
Median time of pointing in et.
|
|
188
|
+
df_exposure : pd.DataFrame
|
|
189
|
+
Spacecraft exposure in healpix coordinates.
|
|
190
|
+
nside : int, optional
|
|
191
|
+
The nside parameter of the Healpix tessellation (default is 128).
|
|
192
|
+
nested : bool, optional
|
|
193
|
+
Whether the Healpix tessellation is nested (default is False).
|
|
147
194
|
|
|
148
195
|
Returns
|
|
149
196
|
-------
|
|
150
|
-
|
|
151
|
-
A
|
|
197
|
+
helio_exposure : np.ndarray
|
|
198
|
+
A 2D array of shape (npix, n_energy_bins).
|
|
152
199
|
|
|
153
200
|
Notes
|
|
154
201
|
-----
|
|
155
202
|
These calculations are performed once per pointing.
|
|
156
203
|
"""
|
|
157
|
-
# Get
|
|
158
|
-
_, energy_midpoints = build_energy_bins()
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
)
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
)
|
|
167
|
-
|
|
168
|
-
# Create a 3D Cartesian grid from spherical coordinates
|
|
169
|
-
# using azimuth and elevation midpoints.
|
|
170
|
-
az_grid, el_grid = np.meshgrid(az_bin_midpoints, el_bin_midpoints[::-1])
|
|
171
|
-
|
|
172
|
-
# Radial distance.
|
|
173
|
-
r = np.ones(el_grid.shape)
|
|
174
|
-
spherical_coords = np.stack((r, np.radians(az_grid), np.radians(el_grid)), axis=-1)
|
|
175
|
-
cartesian_coords = spherical_to_cartesian(spherical_coords)
|
|
176
|
-
cartesian = cartesian_coords.reshape(-1, 3, order="F").T
|
|
177
|
-
|
|
178
|
-
# Spacecraft velocity in the pointing (DPS) frame wrt heliosphere.
|
|
204
|
+
# Get energy midpoints.
|
|
205
|
+
_, energy_midpoints, _ = build_energy_bins()
|
|
206
|
+
# Extract (RA/Dec) and exposure from the spacecraft frame.
|
|
207
|
+
ra = df_exposure["Right Ascension (deg)"].values
|
|
208
|
+
dec = df_exposure["Declination (deg)"].values
|
|
209
|
+
exposure_flat = df_exposure["Exposure Time"].values
|
|
210
|
+
|
|
211
|
+
# The Cartesian state vector representing the position and velocity of the
|
|
212
|
+
# IMAP spacecraft.
|
|
179
213
|
state = imap_state(time, ref_frame=SpiceFrame.IMAP_DPS)
|
|
180
214
|
|
|
181
215
|
# Extract the velocity part of the state vector
|
|
182
216
|
spacecraft_velocity = state[3:6]
|
|
217
|
+
# Convert (RA, Dec) angles into 3D unit vectors.
|
|
218
|
+
# Each unit vector represents a direction in the sky where the spacecraft observed
|
|
219
|
+
# and accumulated exposure time.
|
|
220
|
+
unit_dirs = hp.ang2vec(ra, dec, lonlat=True).T # Shape (N, 3)
|
|
221
|
+
|
|
222
|
+
# Initialize output array.
|
|
223
|
+
# Each row corresponds to a HEALPix pixel, and each column to an energy bin.
|
|
224
|
+
npix = hp.nside2npix(nside)
|
|
225
|
+
helio_exposure = np.zeros((npix, len(energy_midpoints)))
|
|
183
226
|
|
|
227
|
+
# Loop through energy bins and compute transformed exposure.
|
|
184
228
|
for i, energy_midpoint in enumerate(energy_midpoints):
|
|
185
229
|
# Convert the midpoint energy to a velocity (km/s).
|
|
186
230
|
# Based on kinetic energy equation: E = 1/2 * m * v^2.
|
|
@@ -193,56 +237,110 @@ def get_helio_exposure_times(
|
|
|
193
237
|
# to the velocity wrt heliosphere.
|
|
194
238
|
# energy_velocity * cartesian -> apply the magnitude of the velocity
|
|
195
239
|
# to every position on the grid in the despun grid.
|
|
196
|
-
helio_velocity = spacecraft_velocity.reshape(
|
|
240
|
+
helio_velocity = spacecraft_velocity.reshape(1, 3) + energy_velocity * unit_dirs
|
|
197
241
|
|
|
198
242
|
# Normalized vectors representing the direction of the heliocentric velocity.
|
|
199
|
-
helio_normalized = helio_velocity
|
|
200
|
-
helio_velocity
|
|
243
|
+
helio_normalized = helio_velocity / np.linalg.norm(
|
|
244
|
+
helio_velocity, axis=1, keepdims=True
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
# Convert Cartesian heliocentric vectors into spherical coordinates.
|
|
248
|
+
# Result: azimuth (longitude) and elevation (latitude) in degrees.
|
|
249
|
+
helio_spherical = cartesian_to_spherical(helio_normalized)
|
|
250
|
+
az, el = helio_spherical[:, 1], helio_spherical[:, 2]
|
|
251
|
+
|
|
252
|
+
# Convert azimuth/elevation directions to HEALPix pixel indices.
|
|
253
|
+
hpix_idx = hp.ang2pix(nside, az, el, nest=nested, lonlat=True)
|
|
254
|
+
|
|
255
|
+
# Accumulate exposure values into HEALPix pixels for this energy bin.
|
|
256
|
+
helio_exposure[:, i] = np.bincount(
|
|
257
|
+
hpix_idx, weights=exposure_flat, minlength=npix
|
|
201
258
|
)
|
|
202
|
-
# Converts vectors from Cartesian coordinates (x, y, z)
|
|
203
|
-
# into spherical coordinates.
|
|
204
|
-
spherical_coords = cartesian_to_spherical(helio_normalized)
|
|
205
|
-
az, el = spherical_coords[..., 1], spherical_coords[..., 2]
|
|
206
259
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
260
|
+
return helio_exposure
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def get_spacecraft_sensitivity(
|
|
264
|
+
efficiencies: pandas.DataFrame,
|
|
265
|
+
geometric_function: pandas.DataFrame,
|
|
266
|
+
) -> tuple[pandas.DataFrame, NDArray, NDArray, NDArray]:
|
|
267
|
+
"""
|
|
268
|
+
Compute sensitivity as efficiency * geometric factor.
|
|
269
|
+
|
|
270
|
+
Parameters
|
|
271
|
+
----------
|
|
272
|
+
efficiencies : pandas.DataFrame
|
|
273
|
+
Efficiencies at different energy levels.
|
|
274
|
+
geometric_function : pandas.DataFrame
|
|
275
|
+
Geometric function.
|
|
276
|
+
|
|
277
|
+
Returns
|
|
278
|
+
-------
|
|
279
|
+
pointing_sensitivity : pandas.DataFrame
|
|
280
|
+
Sensitivity with dimensions (HEALPIX pixel_number, energy).
|
|
281
|
+
energy_vals : NDArray
|
|
282
|
+
Energy values of dataframe.
|
|
283
|
+
right_ascension : NDArray
|
|
284
|
+
Right ascension (longitude/azimuth) values of dataframe (0 - 360 degrees).
|
|
285
|
+
declination : NDArray
|
|
286
|
+
Declination (latitude/elevation) values of dataframe (-90 to 90 degrees).
|
|
287
|
+
"""
|
|
288
|
+
# Exclude "Right Ascension (deg)" and "Declination (deg)" from the multiplication
|
|
289
|
+
energy_columns = [
|
|
290
|
+
col
|
|
291
|
+
for col in efficiencies.columns
|
|
292
|
+
if col not in ["Right Ascension (deg)", "Declination (deg)"]
|
|
293
|
+
]
|
|
294
|
+
sensitivity = efficiencies[energy_columns].mul(
|
|
295
|
+
geometric_function["Response (cm2-sr)"].values, axis=0
|
|
296
|
+
)
|
|
210
297
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
el_idx = np.clip(el_idx, 0, len(el_bin_edges) - 2)
|
|
298
|
+
right_ascension = efficiencies["Right Ascension (deg)"]
|
|
299
|
+
declination = efficiencies["Declination (deg)"]
|
|
214
300
|
|
|
215
|
-
|
|
216
|
-
idx = el_idx + az_idx * az_grid.shape[0]
|
|
217
|
-
# Bins the transposed sc_exposure array.
|
|
218
|
-
binned_exposure = sc_exposure.T.flatten(order="F")[idx]
|
|
219
|
-
# Reshape the binned exposure.
|
|
220
|
-
exposure_3d[:, :, i] = binned_exposure.reshape(az_grid.shape, order="F")
|
|
301
|
+
energy_vals = np.array([float(col.replace("keV", "")) for col in energy_columns])
|
|
221
302
|
|
|
222
|
-
return
|
|
303
|
+
return sensitivity, energy_vals, right_ascension, declination
|
|
223
304
|
|
|
224
305
|
|
|
225
|
-
def
|
|
226
|
-
|
|
306
|
+
def grid_sensitivity(
|
|
307
|
+
efficiencies: pandas.DataFrame,
|
|
308
|
+
geometric_function: pandas.DataFrame,
|
|
309
|
+
energy: float,
|
|
227
310
|
) -> NDArray:
|
|
228
311
|
"""
|
|
229
|
-
|
|
312
|
+
Grid the sensitivity.
|
|
230
313
|
|
|
231
314
|
Parameters
|
|
232
315
|
----------
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
316
|
+
efficiencies : pandas.DataFrame
|
|
317
|
+
Efficiencies at different energy levels.
|
|
318
|
+
geometric_function : pandas.DataFrame
|
|
319
|
+
Geometric function.
|
|
320
|
+
energy : np.ndarray
|
|
321
|
+
The particle energy.
|
|
322
|
+
energy : float
|
|
323
|
+
Energy to which we are interpolating.
|
|
239
324
|
|
|
240
325
|
Returns
|
|
241
326
|
-------
|
|
242
|
-
|
|
243
|
-
|
|
327
|
+
interpolated_sensitivity : np.ndarray
|
|
328
|
+
Sensitivity with dimensions (HEALPIX pixel_number, 1).
|
|
244
329
|
"""
|
|
245
|
-
|
|
246
|
-
|
|
330
|
+
sensitivity, energy_vals, right_ascension, declination = get_spacecraft_sensitivity(
|
|
331
|
+
efficiencies, geometric_function
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
# Create interpolator over energy dimension for each pixel (axis=1)
|
|
335
|
+
interp_func = interp1d(
|
|
336
|
+
energy_vals,
|
|
337
|
+
sensitivity.values,
|
|
338
|
+
axis=1,
|
|
339
|
+
bounds_error=False,
|
|
340
|
+
fill_value=np.nan,
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
# Interpolate to energy
|
|
344
|
+
interpolated = interp_func(energy)
|
|
247
345
|
|
|
248
|
-
return
|
|
346
|
+
return interpolated
|