imap-processing 0.11.0__py3-none-any.whl → 0.12.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 +10 -11
- imap_processing/_version.py +2 -2
- imap_processing/ccsds/excel_to_xtce.py +65 -16
- imap_processing/cdf/config/imap_codice_global_cdf_attrs.yaml +6 -28
- imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +365 -42
- 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 +26 -13
- 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 +6 -9
- imap_processing/cdf/config/imap_idex_l1a_variable_attrs.yaml +1 -1
- 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 +9 -21
- 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_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 +48 -52
- imap_processing/cdf/config/imap_swe_l2_variable_attrs.yaml +71 -47
- imap_processing/cdf/config/imap_ultra_global_cdf_attrs.yaml +2 -14
- imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +51 -2
- imap_processing/cdf/config/imap_ultra_l1c_variable_attrs.yaml +29 -14
- imap_processing/cdf/utils.py +13 -7
- imap_processing/cli.py +23 -8
- imap_processing/codice/codice_l1a.py +207 -85
- imap_processing/codice/constants.py +1322 -568
- imap_processing/codice/decompress.py +2 -6
- imap_processing/ena_maps/ena_maps.py +480 -116
- 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 +45 -47
- imap_processing/hi/l1a/hi_l1a.py +24 -18
- 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 +31 -39
- imap_processing/hi/l1c/hi_l1c.py +405 -17
- imap_processing/hi/utils.py +58 -12
- 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 +173 -1
- imap_processing/hit/l0/constants.py +20 -11
- imap_processing/hit/l0/decom_hit.py +18 -4
- imap_processing/hit/l1a/hit_l1a.py +45 -54
- imap_processing/hit/l1b/constants.py +317 -0
- imap_processing/hit/l1b/hit_l1b.py +367 -18
- imap_processing/hit/l2/constants.py +281 -0
- imap_processing/hit/l2/hit_l2.py +614 -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 +246 -0
- imap_processing/ialirt/l0/process_swe.py +252 -0
- imap_processing/ialirt/packet_definitions/ialirt.xml +7 -3
- imap_processing/ialirt/packet_definitions/ialirt_mag.xml +115 -0
- 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 +25 -0
- imap_processing/idex/idex_l1a.py +6 -7
- imap_processing/idex/idex_l1b.py +4 -31
- imap_processing/idex/idex_l2a.py +789 -0
- imap_processing/idex/idex_variable_unpacking_and_eu_conversion.csv +39 -33
- imap_processing/lo/l0/lo_science.py +6 -0
- imap_processing/lo/l1a/lo_l1a.py +0 -1
- imap_processing/lo/l1b/lo_l1b.py +177 -25
- imap_processing/mag/constants.py +8 -0
- imap_processing/mag/imap_mag_sdc-configuration_v001.yaml +6 -0
- imap_processing/mag/l0/decom_mag.py +10 -3
- imap_processing/mag/l1a/mag_l1a.py +22 -11
- imap_processing/mag/l1a/mag_l1a_data.py +28 -3
- imap_processing/mag/l1b/mag_l1b.py +190 -48
- imap_processing/mag/l1c/interpolation_methods.py +211 -0
- imap_processing/mag/l1c/mag_l1c.py +447 -9
- imap_processing/quality_flags.py +1 -0
- imap_processing/spacecraft/packet_definitions/scid_x252.xml +538 -0
- imap_processing/spacecraft/quaternions.py +123 -0
- imap_processing/spice/geometry.py +16 -19
- imap_processing/spice/repoint.py +120 -0
- imap_processing/swapi/l1/swapi_l1.py +4 -0
- imap_processing/swapi/l2/swapi_l2.py +0 -1
- imap_processing/swe/l1a/swe_l1a.py +47 -8
- imap_processing/swe/l1a/swe_science.py +5 -2
- imap_processing/swe/l1b/swe_l1b_science.py +103 -56
- imap_processing/swe/l2/swe_l2.py +60 -65
- imap_processing/swe/packet_definitions/swe_packet_definition.xml +1121 -1
- imap_processing/swe/utils/swe_constants.py +63 -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 +23 -20
- imap_processing/tests/cdf/test_data/imap_instrument2_global_cdf_attrs.yaml +0 -2
- imap_processing/tests/codice/conftest.py +1 -1
- 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 +110 -46
- imap_processing/tests/codice/test_decompress.py +4 -4
- imap_processing/tests/conftest.py +166 -10
- imap_processing/tests/ena_maps/conftest.py +51 -0
- imap_processing/tests/ena_maps/test_ena_maps.py +638 -109
- imap_processing/tests/ena_maps/test_map_utils.py +66 -43
- imap_processing/tests/ena_maps/test_spatial_utils.py +16 -20
- 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 +12 -15
- imap_processing/tests/hi/test_hi_l1c.py +234 -6
- imap_processing/tests/hi/test_l1a.py +30 -0
- imap_processing/tests/hi/test_science_direct_event.py +1 -1
- imap_processing/tests/hi/test_utils.py +24 -2
- imap_processing/tests/hit/helpers/l1_validation.py +39 -39
- 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 +4 -0
- imap_processing/tests/hit/test_hit_l1a.py +24 -28
- imap_processing/tests/hit/test_hit_l1b.py +304 -40
- imap_processing/tests/hit/test_hit_l2.py +454 -0
- imap_processing/tests/hit/test_hit_utils.py +112 -2
- 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/ialirt/test_data/l0/461971383-404.bin +0 -0
- imap_processing/tests/ialirt/test_data/l0/461971384-405.bin +0 -0
- imap_processing/tests/ialirt/test_data/l0/461971385-406.bin +0 -0
- imap_processing/tests/ialirt/test_data/l0/461971386-407.bin +0 -0
- imap_processing/tests/ialirt/test_data/l0/461971387-408.bin +0 -0
- imap_processing/tests/ialirt/test_data/l0/461971388-409.bin +0 -0
- imap_processing/tests/ialirt/test_data/l0/461971389-410.bin +0 -0
- imap_processing/tests/ialirt/test_data/l0/461971390-411.bin +0 -0
- imap_processing/tests/ialirt/test_data/l0/461971391-412.bin +0 -0
- imap_processing/tests/ialirt/test_data/l0/sample_decoded_i-alirt_data.csv +383 -0
- imap_processing/tests/ialirt/unit/test_grouping.py +81 -0
- imap_processing/tests/ialirt/unit/test_parse_mag.py +168 -0
- imap_processing/tests/ialirt/unit/test_process_swe.py +208 -3
- imap_processing/tests/ialirt/unit/test_time.py +16 -0
- imap_processing/tests/idex/conftest.py +62 -6
- imap_processing/tests/idex/test_data/imap_idex_l0_raw_20231218_v001.pkts +0 -0
- imap_processing/tests/idex/test_data/impact_14_tof_high_data.txt +4508 -4508
- imap_processing/tests/idex/test_idex_l1a.py +48 -4
- imap_processing/tests/idex/test_idex_l1b.py +3 -3
- imap_processing/tests/idex/test_idex_l2a.py +383 -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_l1b.py +148 -4
- imap_processing/tests/lo/test_lo_science.py +1 -0
- imap_processing/tests/mag/conftest.py +69 -0
- imap_processing/tests/mag/test_mag_decom.py +1 -1
- imap_processing/tests/mag/test_mag_l1a.py +38 -0
- imap_processing/tests/mag/test_mag_l1b.py +34 -53
- imap_processing/tests/mag/test_mag_l1c.py +251 -20
- imap_processing/tests/mag/test_mag_validation.py +109 -25
- 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/imap_calibration_mag_20240229_v01.cdf +0 -0
- imap_processing/tests/spacecraft/__init__.py +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_geometry.py +6 -9
- imap_processing/tests/spice/test_repoint.py +111 -0
- imap_processing/tests/swapi/test_swapi_l1.py +7 -3
- 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/test_swe_l1a.py +18 -0
- 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_l1b_science.py +23 -4
- imap_processing/tests/swe/test_swe_l2.py +112 -30
- imap_processing/tests/test_cli.py +2 -2
- imap_processing/tests/test_utils.py +138 -16
- 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 +341 -0
- imap_processing/tests/ultra/unit/conftest.py +69 -26
- imap_processing/tests/ultra/unit/test_badtimes.py +2 -0
- imap_processing/tests/ultra/unit/test_cullingmask.py +4 -0
- imap_processing/tests/ultra/unit/test_de.py +12 -4
- imap_processing/tests/ultra/unit/test_decom_apid_881.py +44 -0
- imap_processing/tests/ultra/unit/test_spacecraft_pset.py +78 -0
- imap_processing/tests/ultra/unit/test_ultra_l1a.py +28 -12
- imap_processing/tests/ultra/unit/test_ultra_l1b.py +34 -6
- imap_processing/tests/ultra/unit/test_ultra_l1b_culling.py +22 -26
- imap_processing/tests/ultra/unit/test_ultra_l1b_extended.py +86 -51
- imap_processing/tests/ultra/unit/test_ultra_l1c_pset_bins.py +94 -52
- imap_processing/ultra/l0/decom_tools.py +6 -5
- imap_processing/ultra/l1a/ultra_l1a.py +28 -56
- imap_processing/ultra/l1b/de.py +72 -28
- imap_processing/ultra/l1b/extendedspin.py +12 -14
- imap_processing/ultra/l1b/ultra_l1b.py +34 -9
- imap_processing/ultra/l1b/ultra_l1b_culling.py +65 -29
- imap_processing/ultra/l1b/ultra_l1b_extended.py +64 -19
- imap_processing/ultra/l1c/spacecraft_pset.py +86 -0
- imap_processing/ultra/l1c/ultra_l1c.py +7 -4
- imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +112 -61
- imap_processing/ultra/lookup_tables/ultra_90_dps_exposure_compressed.cdf +0 -0
- imap_processing/ultra/utils/ultra_l1_utils.py +20 -2
- imap_processing/utils.py +68 -28
- {imap_processing-0.11.0.dist-info → imap_processing-0.12.0.dist-info}/METADATA +8 -5
- {imap_processing-0.11.0.dist-info → imap_processing-0.12.0.dist-info}/RECORD +250 -199
- imap_processing/cdf/config/imap_mag_l1_variable_attrs.yaml +0 -237
- imap_processing/hi/l1a/housekeeping.py +0 -27
- 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/ultra/test_data/mock_data.py +0 -161
- imap_processing/ultra/l1c/pset.py +0 -40
- /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.12.0.dist-info}/LICENSE +0 -0
- {imap_processing-0.11.0.dist-info → imap_processing-0.12.0.dist-info}/WHEEL +0 -0
- {imap_processing-0.11.0.dist-info → imap_processing-0.12.0.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Define utils and classes related to coordinates of the ENA maps."""
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class CoordNames(Enum):
|
|
7
|
+
"""Enumeration of the names of the coordinates in the L1C and L2 ENA datasets."""
|
|
8
|
+
|
|
9
|
+
GENERIC_PIXEL = "pixel"
|
|
10
|
+
|
|
11
|
+
TIME = "epoch"
|
|
12
|
+
ENERGY = "energy"
|
|
13
|
+
HEALPIX_INDEX = "healpix_index"
|
|
14
|
+
|
|
15
|
+
# The names of the az/el angular coordinates may differ between L1C and L2 data
|
|
16
|
+
AZIMUTH_L1C = "longitude"
|
|
17
|
+
ELEVATION_L1C = "latitude"
|
|
18
|
+
AZIMUTH_L2 = "longitude"
|
|
19
|
+
ELEVATION_L2 = "latitude"
|
|
@@ -12,20 +12,22 @@ logger = logging.getLogger(__name__)
|
|
|
12
12
|
|
|
13
13
|
def bin_single_array_at_indices(
|
|
14
14
|
value_array: NDArray,
|
|
15
|
-
projection_grid_shape: tuple[int,
|
|
15
|
+
projection_grid_shape: tuple[int, ...],
|
|
16
16
|
projection_indices: NDArray,
|
|
17
17
|
input_indices: NDArray | None = None,
|
|
18
18
|
) -> NDArray:
|
|
19
19
|
"""
|
|
20
20
|
Bin an array of values at the given indices.
|
|
21
21
|
|
|
22
|
+
NOTE: The output array's spatial axis is always the final (-1) axis.
|
|
23
|
+
|
|
22
24
|
Parameters
|
|
23
25
|
----------
|
|
24
26
|
value_array : NDArray
|
|
25
|
-
Array of values to bin. The
|
|
27
|
+
Array of values to bin. The final axis be the one and only spatial axis.
|
|
26
28
|
If other axes are present, they will be binned independently
|
|
27
|
-
along the
|
|
28
|
-
projection_grid_shape : tuple[int]
|
|
29
|
+
along the spatial axis.
|
|
30
|
+
projection_grid_shape : tuple[int, ...]
|
|
29
31
|
The shape of the grid onto which values are projected
|
|
30
32
|
(rows, columns) if the grid is rectangular,
|
|
31
33
|
or just (number of bins,) if the grid is 1D.
|
|
@@ -36,7 +38,7 @@ def bin_single_array_at_indices(
|
|
|
36
38
|
Ordered indices for input grid, corresponding to indices in projection grid.
|
|
37
39
|
1 dimensional. May be non-unique, depending on the projection method.
|
|
38
40
|
If None (default), an arange of the same length as the
|
|
39
|
-
|
|
41
|
+
final axis of value_array is used.
|
|
40
42
|
|
|
41
43
|
Returns
|
|
42
44
|
-------
|
|
@@ -52,7 +54,7 @@ def bin_single_array_at_indices(
|
|
|
52
54
|
If the input value_array has dimensionality less than 1.
|
|
53
55
|
"""
|
|
54
56
|
if input_indices is None:
|
|
55
|
-
input_indices = np.arange(value_array.shape[
|
|
57
|
+
input_indices = np.arange(value_array.shape[-1])
|
|
56
58
|
|
|
57
59
|
# Both sets of indices must be 1D with the same number of elements
|
|
58
60
|
if input_indices.ndim != 1 or projection_indices.ndim != 1:
|
|
@@ -80,23 +82,18 @@ def bin_single_array_at_indices(
|
|
|
80
82
|
binned_values = np.apply_along_axis(
|
|
81
83
|
lambda x: np.bincount(
|
|
82
84
|
projection_indices,
|
|
83
|
-
weights=x[input_indices
|
|
85
|
+
weights=x[..., input_indices],
|
|
84
86
|
minlength=num_projection_indices,
|
|
85
87
|
),
|
|
86
|
-
axis
|
|
88
|
+
axis=-1,
|
|
87
89
|
arr=value_array,
|
|
88
90
|
)
|
|
89
|
-
else:
|
|
90
|
-
raise NotImplementedError(
|
|
91
|
-
"Only 1+ Dimensional arrays are supported for binning. "
|
|
92
|
-
f"Received array with shape {value_array.shape}."
|
|
93
|
-
)
|
|
94
91
|
return binned_values
|
|
95
92
|
|
|
96
93
|
|
|
97
94
|
def bin_values_at_indices(
|
|
98
95
|
input_values_to_bin: dict[str, NDArray],
|
|
99
|
-
projection_grid_shape: tuple[int,
|
|
96
|
+
projection_grid_shape: tuple[int, ...],
|
|
100
97
|
projection_indices: NDArray,
|
|
101
98
|
input_indices: NDArray | None = None,
|
|
102
99
|
) -> dict[str, NDArray]:
|
|
@@ -107,10 +104,10 @@ def bin_values_at_indices(
|
|
|
107
104
|
----------
|
|
108
105
|
input_values_to_bin : dict[str, NDArray]
|
|
109
106
|
Dict matching variable names to arrays of values to bin.
|
|
110
|
-
The
|
|
107
|
+
The final (-1) axis of each array must be the one and only spatial axis,
|
|
111
108
|
which the indices correspond to and on which the values will be binned.
|
|
112
|
-
The other axes will be binned independently along this
|
|
113
|
-
projection_grid_shape : tuple[int,
|
|
109
|
+
The other axes will be binned independently along this final spatial axis.
|
|
110
|
+
projection_grid_shape : tuple[int, ...]
|
|
114
111
|
The shape of the grid onto which values are projected (rows, columns).
|
|
115
112
|
This size of the resulting grid (rows * columns) will be the size of the
|
|
116
113
|
projected values contained in the output dictionary.
|
|
@@ -15,8 +15,7 @@ def build_spatial_bins(
|
|
|
15
15
|
"""
|
|
16
16
|
Build spatial bin boundaries for azimuth and elevation.
|
|
17
17
|
|
|
18
|
-
Input angles in degrees
|
|
19
|
-
output angles in radians for internal use.
|
|
18
|
+
Input/output angles in degrees.
|
|
20
19
|
|
|
21
20
|
Parameters
|
|
22
21
|
----------
|
|
@@ -28,13 +27,13 @@ def build_spatial_bins(
|
|
|
28
27
|
Returns
|
|
29
28
|
-------
|
|
30
29
|
az_bin_edges : np.ndarray
|
|
31
|
-
Array of azimuth bin boundary values in
|
|
30
|
+
Array of azimuth bin boundary values in degrees.
|
|
32
31
|
el_bin_edges : np.ndarray
|
|
33
|
-
Array of elevation bin boundary values in
|
|
32
|
+
Array of elevation bin boundary values in degrees.
|
|
34
33
|
az_bin_midpoints : np.ndarray
|
|
35
|
-
Array of azimuth bin midpoint values in
|
|
34
|
+
Array of azimuth bin midpoint values in degrees.
|
|
36
35
|
el_bin_midpoints : np.ndarray
|
|
37
|
-
Array of elevation bin midpoint values in
|
|
36
|
+
Array of elevation bin midpoint values in degrees.
|
|
38
37
|
"""
|
|
39
38
|
# Azimuth bins from 0 to 360 degrees.
|
|
40
39
|
az_bin_edges = np.arange(0, 360 + az_spacing_deg, az_spacing_deg)
|
|
@@ -44,12 +43,11 @@ def build_spatial_bins(
|
|
|
44
43
|
el_bin_edges = np.arange(-90, 90 + el_spacing_deg, el_spacing_deg)
|
|
45
44
|
el_bin_midpoints = el_bin_edges[:-1] + el_spacing_deg / 2 # Midpoints between edges
|
|
46
45
|
|
|
47
|
-
# Convert all angles to radians and return them
|
|
48
46
|
return (
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
az_bin_edges,
|
|
48
|
+
el_bin_edges,
|
|
49
|
+
az_bin_midpoints,
|
|
50
|
+
el_bin_midpoints,
|
|
53
51
|
)
|
|
54
52
|
|
|
55
53
|
|
|
@@ -59,6 +57,10 @@ def build_solid_angle_map(
|
|
|
59
57
|
"""
|
|
60
58
|
Build a solid angle map in steradians for a given spacing in degrees.
|
|
61
59
|
|
|
60
|
+
NOTE: This function works in radians internally and returns steradians, while other
|
|
61
|
+
functions in this module work in degrees. Expressing solid angles in steradians
|
|
62
|
+
is the preferred unit for ENA Maps.
|
|
63
|
+
|
|
62
64
|
Parameters
|
|
63
65
|
----------
|
|
64
66
|
spacing_deg : float
|
|
@@ -96,23 +98,26 @@ def build_solid_angle_map(
|
|
|
96
98
|
@typing.no_type_check
|
|
97
99
|
def rewrap_even_spaced_az_el_grid(
|
|
98
100
|
raveled_values: NDArray,
|
|
99
|
-
|
|
101
|
+
grid_shape: tuple[int] | None = None,
|
|
100
102
|
order: typing.Literal["C"] | typing.Literal["F"] = "C",
|
|
101
103
|
) -> NDArray:
|
|
102
104
|
"""
|
|
103
105
|
Take an unwrapped (raveled) 1D array and reshapes it into a 2D az/el grid.
|
|
104
106
|
|
|
107
|
+
In the input, unwrapped grid, the spatial axis is the final (-1) axis.
|
|
108
|
+
In the output, the spatial axes are the -2 (azimuth) and -1 (elevation) axes.
|
|
109
|
+
|
|
105
110
|
Assumes the following must be true of the original grid:
|
|
106
111
|
1. Grid was evenly spaced in angular space,
|
|
107
112
|
2. Grid had the same spacing in both azimuth and elevation.
|
|
108
|
-
3. Azimuth is axis
|
|
109
|
-
4. Elevation is axis
|
|
113
|
+
3. Azimuth is the first spatial axis (and extends a total of 360 degrees).
|
|
114
|
+
4. Elevation is the second spatial axis (and extends a total of 180 degrees).
|
|
110
115
|
|
|
111
116
|
Parameters
|
|
112
117
|
----------
|
|
113
118
|
raveled_values : NDArray
|
|
114
119
|
1D array of values to be reshaped into a 2D grid.
|
|
115
|
-
|
|
120
|
+
grid_shape : tuple[int], optional
|
|
116
121
|
The shape of the original grid, if known, by default None.
|
|
117
122
|
If None, the shape will be inferred from the size of the input array.
|
|
118
123
|
order : {'C', 'F'}, optional
|
|
@@ -121,35 +126,27 @@ def rewrap_even_spaced_az_el_grid(
|
|
|
121
126
|
Returns
|
|
122
127
|
-------
|
|
123
128
|
NDArray
|
|
124
|
-
The reshaped 2D grid of values.
|
|
125
|
-
|
|
126
|
-
Raises
|
|
127
|
-
------
|
|
128
|
-
ValueError
|
|
129
|
-
If the input is not a 1D array or 2D array with an 'extra' non-spatial axis.
|
|
129
|
+
The reshaped 2D grid of values with (azimuth, elevation) as the final 2 axes.
|
|
130
130
|
"""
|
|
131
|
-
if raveled_values.ndim > 2:
|
|
132
|
-
raise ValueError(
|
|
133
|
-
"Input must be a 1D array or 2D array with only one spatial axis as axis 0."
|
|
134
|
-
)
|
|
135
|
-
|
|
136
131
|
# We can infer the shape if its evenly spaced and 2D
|
|
137
|
-
if not
|
|
138
|
-
spacing_deg = 1 / np.sqrt(raveled_values.shape[
|
|
139
|
-
|
|
132
|
+
if not grid_shape:
|
|
133
|
+
spacing_deg = 1 / np.sqrt(raveled_values.shape[-1] / (360 * 180))
|
|
134
|
+
grid_shape = (int(360 // spacing_deg), int(180 // spacing_deg))
|
|
140
135
|
|
|
141
|
-
if raveled_values.ndim ==
|
|
142
|
-
|
|
143
|
-
|
|
136
|
+
if raveled_values.ndim == 1:
|
|
137
|
+
array_shape = grid_shape
|
|
138
|
+
else:
|
|
139
|
+
array_shape = (*raveled_values.shape[:-1], *grid_shape)
|
|
140
|
+
return raveled_values.reshape(array_shape, order=order)
|
|
144
141
|
|
|
145
142
|
|
|
146
143
|
class AzElSkyGrid:
|
|
147
144
|
"""
|
|
148
145
|
Representation of a 2D grid of azimuth and elevation angles covering the sky.
|
|
149
146
|
|
|
150
|
-
All angles are stored internally in
|
|
151
|
-
Azimuth is within the range [0,
|
|
152
|
-
elevation is within the range [-
|
|
147
|
+
All angles are stored internally in degrees.
|
|
148
|
+
Azimuth is within the range [0, 360) degrees,
|
|
149
|
+
elevation is within the range [-90, 90) degrees.
|
|
153
150
|
|
|
154
151
|
Parameters
|
|
155
152
|
----------
|
|
@@ -157,13 +154,13 @@ class AzElSkyGrid:
|
|
|
157
154
|
Spacing of the grid in degrees, by default 0.5.
|
|
158
155
|
reversed_elevation : bool, optional
|
|
159
156
|
Whether the elevation grid should be reversed, by default False.
|
|
160
|
-
If False, the elevation grid will be from -
|
|
161
|
-
If True, the elevation grid will be from
|
|
157
|
+
If False, the elevation grid will be from -90 to 90 deg.
|
|
158
|
+
If True, the elevation grid will be from 90 to -90 deg.
|
|
162
159
|
|
|
163
160
|
Raises
|
|
164
161
|
------
|
|
165
162
|
ValueError
|
|
166
|
-
If the spacing is not positive or does not divide evenly into
|
|
163
|
+
If the spacing is not positive or does not divide evenly into 180 degrees.
|
|
167
164
|
"""
|
|
168
165
|
|
|
169
166
|
def __init__(
|
|
@@ -174,25 +171,26 @@ class AzElSkyGrid:
|
|
|
174
171
|
# Store grid properties
|
|
175
172
|
self.reversed_elevation = reversed_elevation
|
|
176
173
|
|
|
177
|
-
# Internally, work in
|
|
178
|
-
self.
|
|
174
|
+
# Internally, work in degrees
|
|
175
|
+
self.spacing_deg = spacing_deg
|
|
179
176
|
|
|
180
|
-
# Ensure valid grid spacing (positive, divides evenly into
|
|
181
|
-
if self.
|
|
177
|
+
# Ensure valid grid spacing (positive, divides evenly into 180 degrees)
|
|
178
|
+
if self.spacing_deg <= 0:
|
|
182
179
|
raise ValueError("Spacing must be positive valued, non-zero.")
|
|
183
180
|
|
|
184
|
-
if not np.isclose((
|
|
185
|
-
raise ValueError("Spacing must divide evenly into
|
|
181
|
+
if not np.isclose((180 / self.spacing_deg) % 1, 0):
|
|
182
|
+
raise ValueError("Spacing must divide evenly into 180 degrees.")
|
|
186
183
|
|
|
187
184
|
# build_spacial_bins creates the bin edges and centers for azimuth and elevation
|
|
188
185
|
# E.g. for spacing=1, az_bin_edges = [0, 1, 2, ..., 359, 360] deg.
|
|
189
|
-
# However returned values are in radians.
|
|
190
186
|
(
|
|
191
187
|
self.az_bin_edges,
|
|
192
188
|
self.el_bin_edges,
|
|
193
189
|
self.az_bin_midpoints,
|
|
194
190
|
self.el_bin_midpoints,
|
|
195
|
-
) = build_spatial_bins(
|
|
191
|
+
) = build_spatial_bins(
|
|
192
|
+
az_spacing_deg=self.spacing_deg, el_spacing_deg=self.spacing_deg
|
|
193
|
+
)
|
|
196
194
|
|
|
197
195
|
# If desired, reverse the elevation range so that the grid is in the order
|
|
198
196
|
# defined by the Ultra prototype code (`build_dps_grid.m`).
|
|
@@ -221,6 +219,6 @@ class AzElSkyGrid:
|
|
|
221
219
|
A string representation of the AzElSkyGrid.
|
|
222
220
|
"""
|
|
223
221
|
return (
|
|
224
|
-
f"AzElSkyGrid with a spacing of {self.
|
|
222
|
+
f"AzElSkyGrid with a spacing of {self.spacing_deg:.4e} degrees. "
|
|
225
223
|
f"{self.grid_shape} Grid."
|
|
226
224
|
)
|
imap_processing/hi/l1a/hi_l1a.py
CHANGED
|
@@ -7,8 +7,8 @@ from typing import Union
|
|
|
7
7
|
import xarray as xr
|
|
8
8
|
|
|
9
9
|
from imap_processing import imap_module_directory
|
|
10
|
+
from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
|
|
10
11
|
from imap_processing.hi.l1a.histogram import create_dataset as hist_create_dataset
|
|
11
|
-
from imap_processing.hi.l1a.housekeeping import process_housekeeping
|
|
12
12
|
from imap_processing.hi.l1a.science_direct_event import science_direct_event
|
|
13
13
|
from imap_processing.hi.utils import HIAPID
|
|
14
14
|
from imap_processing.utils import packet_file_to_datasets
|
|
@@ -42,30 +42,36 @@ def hi_l1a(packet_file_path: Union[str, Path], data_version: str) -> list[xr.Dat
|
|
|
42
42
|
# Process science to l1a.
|
|
43
43
|
processed_data = []
|
|
44
44
|
for apid in datasets_by_apid:
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
logger.info(
|
|
52
|
-
"Processing direct event data for [%s] packets", HIAPID.H45_SCI_DE.name
|
|
53
|
-
)
|
|
45
|
+
try:
|
|
46
|
+
apid_enum = HIAPID(apid)
|
|
47
|
+
except ValueError as err:
|
|
48
|
+
raise RuntimeError(f"Encountered unexpected APID [{apid}]") from err
|
|
49
|
+
|
|
50
|
+
logger.info(f"Processing IMAP-Hi data for {apid_enum.name} packets")
|
|
54
51
|
|
|
52
|
+
if apid_enum in [HIAPID.H45_SCI_CNT, HIAPID.H90_SCI_CNT]:
|
|
53
|
+
data = hist_create_dataset(datasets_by_apid[apid])
|
|
54
|
+
gattr_key = "imap_hi_l1a_hist_attrs"
|
|
55
|
+
elif apid_enum in [HIAPID.H45_SCI_DE, HIAPID.H90_SCI_DE]:
|
|
55
56
|
data = science_direct_event(datasets_by_apid[apid])
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
57
|
+
gattr_key = "imap_hi_l1a_de_attrs"
|
|
58
|
+
elif apid_enum in [HIAPID.H45_APP_NHK, HIAPID.H90_APP_NHK]:
|
|
59
|
+
data = datasets_by_apid[apid]
|
|
60
|
+
gattr_key = "imap_hi_l1a_hk_attrs"
|
|
61
|
+
elif apid_enum in [HIAPID.H45_DIAG_FEE, HIAPID.H90_DIAG_FEE]:
|
|
62
|
+
data = datasets_by_apid[apid]
|
|
63
|
+
gattr_key = "imap_hi_l1a_diagfee_attrs"
|
|
64
|
+
|
|
65
|
+
# Update dataset global attributes
|
|
66
|
+
attr_mgr = ImapCdfAttributes()
|
|
67
|
+
attr_mgr.add_instrument_global_attrs("hi")
|
|
68
|
+
data.attrs.update(attr_mgr.get_global_attributes(gattr_key))
|
|
63
69
|
|
|
64
70
|
# TODO: revisit this
|
|
65
71
|
data.attrs["Data_version"] = data_version
|
|
66
72
|
|
|
67
73
|
# set the sensor string in Logical_source
|
|
68
|
-
sensor_str =
|
|
74
|
+
sensor_str = apid_enum.sensor
|
|
69
75
|
data.attrs["Logical_source"] = data.attrs["Logical_source"].format(
|
|
70
76
|
sensor=sensor_str
|
|
71
77
|
)
|
|
@@ -31,11 +31,11 @@ def parse_direct_events(de_data: bytes) -> dict[str, npt.ArrayLike]:
|
|
|
31
31
|
IMAP-Hi direct event data information is stored in
|
|
32
32
|
48-bits as follows:
|
|
33
33
|
|
|
34
|
-
| Read 48-bits into
|
|
34
|
+
| Read 48-bits into 16, 2, 10, 10, 10, bits. Each of these breaks
|
|
35
35
|
| down as:
|
|
36
36
|
|
|
|
37
|
-
| start_bitmask_data - 2 bits (tA=1, tB=2, tC1=3, META=0)
|
|
38
37
|
| de_tag - 16 bits
|
|
38
|
+
| start_bitmask_data - 2 bits (tA=1, tB=2, tC1=3)
|
|
39
39
|
| tof_1 - 10 bit counter
|
|
40
40
|
| tof_2 - 10 bit counter
|
|
41
41
|
| tof_3 - 10 bit counter
|
|
@@ -70,16 +70,16 @@ def parse_direct_events(de_data: bytes) -> dict[str, npt.ArrayLike]:
|
|
|
70
70
|
# direct events.
|
|
71
71
|
# Considering the 6-bytes of data for each DE as 3 2-byte words,
|
|
72
72
|
# each word contains the following:
|
|
73
|
-
# word_0:
|
|
74
|
-
# word_1:
|
|
73
|
+
# word_0: full 16-bits is the de_tag
|
|
74
|
+
# word_1: 2-bits of Trigger ID, 10-bits tof_1, upper 4-bits of tof_2
|
|
75
75
|
# word_2: lower 6-bits of tof_2, 10-bits of tof_3
|
|
76
76
|
data_uint16 = np.reshape(
|
|
77
77
|
np.frombuffer(de_data, dtype=">u2"), (3, -1), order="F"
|
|
78
78
|
).astype(np.uint16)
|
|
79
79
|
|
|
80
80
|
de_dict = dict()
|
|
81
|
-
de_dict["
|
|
82
|
-
de_dict["
|
|
81
|
+
de_dict["de_tag"] = data_uint16[0]
|
|
82
|
+
de_dict["trigger_id"] = (data_uint16[1] >> 14).astype(np.uint8)
|
|
83
83
|
de_dict["tof_1"] = (data_uint16[1] & int(b"00111111_11110000", 2)) >> 4
|
|
84
84
|
de_dict["tof_2"] = ((data_uint16[1] & int(b"00000000_00001111", 2)) << 6) + (
|
|
85
85
|
data_uint16[2] >> 10
|
|
@@ -147,10 +147,8 @@ def create_dataset(de_data_dict: dict[str, npt.ArrayLike]) -> xr.Dataset:
|
|
|
147
147
|
attrs=event_met_attrs,
|
|
148
148
|
)
|
|
149
149
|
|
|
150
|
-
de_global_attrs = attr_mgr.get_global_attributes("imap_hi_l1a_de_attrs")
|
|
151
150
|
dataset = xr.Dataset(
|
|
152
151
|
coords={"epoch": epoch, "event_met": event_met},
|
|
153
|
-
attrs=de_global_attrs,
|
|
154
152
|
)
|
|
155
153
|
|
|
156
154
|
for var_name, data in de_data_dict.items():
|
imap_processing/hi/l1b/hi_l1b.py
CHANGED
|
@@ -12,6 +12,7 @@ from imap_processing.cdf.utils import parse_filename_like
|
|
|
12
12
|
from imap_processing.hi.l1a.science_direct_event import HALF_CLOCK_TICK_S
|
|
13
13
|
from imap_processing.hi.utils import (
|
|
14
14
|
HIAPID,
|
|
15
|
+
CoincidenceBitmap,
|
|
15
16
|
HiConstants,
|
|
16
17
|
create_dataset_variables,
|
|
17
18
|
parse_sensor_number,
|
|
@@ -36,15 +37,6 @@ class TriggerId(IntEnum):
|
|
|
36
37
|
C = 3
|
|
37
38
|
|
|
38
39
|
|
|
39
|
-
class CoincidenceBitmap(IntEnum):
|
|
40
|
-
"""IntEnum class for coincidence type bitmap values."""
|
|
41
|
-
|
|
42
|
-
A = 2**3
|
|
43
|
-
B = 2**2
|
|
44
|
-
C1 = 2**1
|
|
45
|
-
C2 = 2**0
|
|
46
|
-
|
|
47
|
-
|
|
48
40
|
logger = logging.getLogger(__name__)
|
|
49
41
|
ATTR_MGR = ImapCdfAttributes()
|
|
50
42
|
ATTR_MGR.add_instrument_global_attrs("hi")
|
|
@@ -124,7 +116,7 @@ def annotate_direct_events(l1a_dataset: xr.Dataset) -> xr.Dataset:
|
|
|
124
116
|
"""
|
|
125
117
|
l1b_dataset = l1a_dataset.copy()
|
|
126
118
|
l1b_dataset.update(de_esa_energy_step(l1b_dataset))
|
|
127
|
-
l1b_dataset.update(
|
|
119
|
+
l1b_dataset.update(compute_coincidence_type_and_tofs(l1b_dataset))
|
|
128
120
|
l1b_dataset.update(de_nominal_bin_and_spin_phase(l1b_dataset))
|
|
129
121
|
l1b_dataset.update(compute_hae_coordinates(l1b_dataset))
|
|
130
122
|
l1b_dataset.update(
|
|
@@ -154,14 +146,14 @@ def annotate_direct_events(l1a_dataset: xr.Dataset) -> xr.Dataset:
|
|
|
154
146
|
return l1b_dataset
|
|
155
147
|
|
|
156
148
|
|
|
157
|
-
def
|
|
149
|
+
def compute_coincidence_type_and_tofs(
|
|
158
150
|
dataset: xr.Dataset,
|
|
159
151
|
) -> dict[str, xr.DataArray]:
|
|
160
152
|
"""
|
|
161
|
-
Compute coincidence type and time
|
|
153
|
+
Compute coincidence type and time of flights.
|
|
162
154
|
|
|
163
|
-
Generates the new variables "coincidence_type", "
|
|
164
|
-
"
|
|
155
|
+
Generates the new variables "coincidence_type", "tof_ab", "tof_ac1",
|
|
156
|
+
"tof_bc1", and "tof_c1c2" and returns a dictionary with the new
|
|
165
157
|
variables that can be added to the input dataset by calling the
|
|
166
158
|
xarray.Dataset.update method.
|
|
167
159
|
|
|
@@ -178,16 +170,16 @@ def compute_coincidence_type_and_time_deltas(
|
|
|
178
170
|
new_vars = create_dataset_variables(
|
|
179
171
|
[
|
|
180
172
|
"coincidence_type",
|
|
181
|
-
"
|
|
182
|
-
"
|
|
183
|
-
"
|
|
184
|
-
"
|
|
173
|
+
"tof_ab",
|
|
174
|
+
"tof_ac1",
|
|
175
|
+
"tof_bc1",
|
|
176
|
+
"tof_c1c2",
|
|
185
177
|
],
|
|
186
178
|
len(dataset.event_met),
|
|
187
179
|
att_manager_lookup_str="hi_de_{0}",
|
|
188
180
|
)
|
|
189
181
|
|
|
190
|
-
# compute masks needed for coincidence type and
|
|
182
|
+
# compute masks needed for coincidence type and ToF calculations
|
|
191
183
|
a_first = dataset.trigger_id.values == TriggerId.A
|
|
192
184
|
b_first = dataset.trigger_id.values == TriggerId.B
|
|
193
185
|
c_first = dataset.trigger_id.values == TriggerId.C
|
|
@@ -221,56 +213,56 @@ def compute_coincidence_type_and_time_deltas(
|
|
|
221
213
|
# | 2 | B | t_a - t_b | t_c1 - t_b | t_c2 - t_c1 |
|
|
222
214
|
# | 3 | C | t_a - t_c1 | t_b - t_c1 | t_c2 - t_c1 |
|
|
223
215
|
|
|
224
|
-
# Prepare for
|
|
216
|
+
# Prepare for L1B ToF calculations by converting L1A TOF values to nanoseconds
|
|
225
217
|
tof_1_ns = (dataset.tof_1.values * HiConstants.TOF1_TICK_DUR).astype(np.int32)
|
|
226
218
|
tof_2_ns = (dataset.tof_2.values * HiConstants.TOF2_TICK_DUR).astype(np.int32)
|
|
227
219
|
tof_3_ns = (dataset.tof_3.values * HiConstants.TOF3_TICK_DUR).astype(np.int32)
|
|
228
220
|
|
|
229
|
-
# # **********
|
|
221
|
+
# # ********** tof_ab = (t_b - t_a) **********
|
|
230
222
|
# Table: row 1, column 1
|
|
231
223
|
a_and_tof1 = a_first & tof1_valid
|
|
232
|
-
new_vars["
|
|
224
|
+
new_vars["tof_ab"].values[a_and_tof1] = tof_1_ns[a_and_tof1]
|
|
233
225
|
# Table: row 2, column 1
|
|
234
226
|
b_and_tof1 = b_first & tof1_valid
|
|
235
|
-
new_vars["
|
|
227
|
+
new_vars["tof_ab"].values[b_and_tof1] = -1 * tof_1_ns[b_and_tof1]
|
|
236
228
|
# Table: row 3, column 1 and 2
|
|
237
|
-
#
|
|
229
|
+
# tof_ab = (t_b - t_c1) - (t_a - t_c1) = (t_b - t_a)
|
|
238
230
|
c_and_tof1and2 = c_first & tof1and2_valid
|
|
239
|
-
new_vars["
|
|
231
|
+
new_vars["tof_ab"].values[c_and_tof1and2] = (
|
|
240
232
|
tof_2_ns[c_and_tof1and2] - tof_1_ns[c_and_tof1and2]
|
|
241
233
|
)
|
|
242
234
|
|
|
243
|
-
# **********
|
|
235
|
+
# ********** tof_ac1 = (t_c1 - t_a) **********
|
|
244
236
|
# Table: row 1, column 2
|
|
245
237
|
a_and_tof2 = a_first & tof2_valid
|
|
246
|
-
new_vars["
|
|
238
|
+
new_vars["tof_ac1"].values[a_and_tof2] = tof_2_ns[a_and_tof2]
|
|
247
239
|
# Table: row 2, column 1 and 2
|
|
248
|
-
#
|
|
240
|
+
# tof_ac1 = (t_c1 - t_b) - (t_a - t_b) = (t_c1 - t_a)
|
|
249
241
|
b_and_tof1and2 = b_first & tof1and2_valid
|
|
250
|
-
new_vars["
|
|
242
|
+
new_vars["tof_ac1"].values[b_and_tof1and2] = (
|
|
251
243
|
tof_2_ns[b_and_tof1and2] - tof_1_ns[b_and_tof1and2]
|
|
252
244
|
)
|
|
253
245
|
# Table: row 3, column 1
|
|
254
246
|
c_and_tof1 = c_first & tof1_valid
|
|
255
|
-
new_vars["
|
|
247
|
+
new_vars["tof_ac1"].values[c_and_tof1] = -1 * tof_1_ns[c_and_tof1]
|
|
256
248
|
|
|
257
|
-
# **********
|
|
249
|
+
# ********** tof_bc1 = (t_c1 - t_b) **********
|
|
258
250
|
# Table: row 1, column 1 and 2
|
|
259
|
-
#
|
|
251
|
+
# tof_bc1 = (t_c1 - t_a) - (t_b - t_a) => (t_c1 - t_b)
|
|
260
252
|
a_and_tof1and2 = a_first & tof1and2_valid
|
|
261
|
-
new_vars["
|
|
253
|
+
new_vars["tof_bc1"].values[a_and_tof1and2] = (
|
|
262
254
|
tof_2_ns[a_and_tof1and2] - tof_1_ns[a_and_tof1and2]
|
|
263
255
|
)
|
|
264
256
|
# Table: row 2, column 2
|
|
265
257
|
b_and_tof2 = b_first & tof2_valid
|
|
266
|
-
new_vars["
|
|
258
|
+
new_vars["tof_bc1"].values[b_and_tof2] = tof_2_ns[b_and_tof2]
|
|
267
259
|
# Table: row 3, column 2
|
|
268
260
|
c_and_tof2 = c_first & tof2_valid
|
|
269
|
-
new_vars["
|
|
261
|
+
new_vars["tof_bc1"].values[c_and_tof2] = -1 * tof_2_ns[c_and_tof2]
|
|
270
262
|
|
|
271
|
-
# **********
|
|
263
|
+
# ********** tof_c1c2 = (t_c2 - t_c1) **********
|
|
272
264
|
# Table: all rows, column 3
|
|
273
|
-
new_vars["
|
|
265
|
+
new_vars["tof_c1c2"].values[tof3_valid] = tof_3_ns[tof3_valid]
|
|
274
266
|
|
|
275
267
|
return new_vars
|
|
276
268
|
|
|
@@ -325,8 +317,8 @@ def compute_hae_coordinates(dataset: xr.Dataset) -> dict[str, xr.DataArray]:
|
|
|
325
317
|
Parameters
|
|
326
318
|
----------
|
|
327
319
|
dataset : xarray.Dataset
|
|
328
|
-
The partial L1B dataset that has had coincidence type,
|
|
329
|
-
spin phase computed and added to the L1A data.
|
|
320
|
+
The partial L1B dataset that has had coincidence type, times of flight,
|
|
321
|
+
and spin phase computed and added to the L1A data.
|
|
330
322
|
|
|
331
323
|
Returns
|
|
332
324
|
-------
|