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
|
@@ -8,8 +8,11 @@ import pandas as pd
|
|
|
8
8
|
import xarray as xr
|
|
9
9
|
|
|
10
10
|
from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
|
|
11
|
+
from imap_processing.spice.time import met_to_ttj2000ns
|
|
12
|
+
from imap_processing.swe.utils import swe_constants
|
|
11
13
|
from imap_processing.swe.utils.swe_utils import (
|
|
12
|
-
|
|
14
|
+
calculate_data_acquisition_time,
|
|
15
|
+
combine_acquisition_time,
|
|
13
16
|
read_lookup_table,
|
|
14
17
|
)
|
|
15
18
|
|
|
@@ -157,18 +160,19 @@ def calculate_calibration_factor(
|
|
|
157
160
|
Parameters
|
|
158
161
|
----------
|
|
159
162
|
acquisition_times : numpy.ndarray
|
|
160
|
-
Data points to interpolate. Shape is (
|
|
163
|
+
Data points to interpolate. Shape is (N_ESA_STEPS, N_ANGLE_SECTORS).
|
|
161
164
|
cal_times : numpy.ndarray
|
|
162
165
|
X-coordinates data points. Calibration times. Shape is (n,).
|
|
163
166
|
cal_data : numpy.ndarray
|
|
164
167
|
Y-coordinates data points. Calibration data of corresponding cal_times.
|
|
165
|
-
Shape is (n,
|
|
168
|
+
Shape is (n, N_CEMS).
|
|
166
169
|
|
|
167
170
|
Returns
|
|
168
171
|
-------
|
|
169
172
|
calibration_factor : numpy.ndarray
|
|
170
|
-
Calibration factor for each CEM detector. Shape is
|
|
171
|
-
where last 7 dimension
|
|
173
|
+
Calibration factor for each CEM detector. Shape is
|
|
174
|
+
(N_ESA_STEPS, N_ANGLE_SECTORS, N_CEMS) where last 7 dimension
|
|
175
|
+
contains calibration factor for each CEM detector.
|
|
172
176
|
"""
|
|
173
177
|
# Raise error if there is no pre or post time in cal_times. SWE does not
|
|
174
178
|
# want to extrapolate calibration data.
|
|
@@ -220,20 +224,23 @@ def apply_in_flight_calibration(
|
|
|
220
224
|
Parameters
|
|
221
225
|
----------
|
|
222
226
|
corrected_counts : numpy.ndarray
|
|
223
|
-
Corrected count of full cycle data. Data shape is
|
|
227
|
+
Corrected count of full cycle data. Data shape is
|
|
228
|
+
(N_ESA_STEPS, N_ANGLE_SECTORS, N_CEMS).
|
|
224
229
|
acquisition_time : numpy.ndarray
|
|
225
|
-
Acquisition time of full cycle data. Data shape is
|
|
230
|
+
Acquisition time of full cycle data. Data shape is
|
|
231
|
+
(N_ESA_STEPS, N_ANGLE_SECTORS).
|
|
226
232
|
|
|
227
233
|
Returns
|
|
228
234
|
-------
|
|
229
235
|
corrected_counts : numpy.ndarray
|
|
230
236
|
Corrected count of full cycle data after applying in-flight calibration.
|
|
231
|
-
Array shape is (
|
|
237
|
+
Array shape is (N_ESA_STEPS, N_ANGLE_SECTORS, N_CEMS).
|
|
232
238
|
"""
|
|
233
239
|
# Read in in-flight calibration data
|
|
234
240
|
in_flight_cal_df = read_in_flight_cal_data()
|
|
235
241
|
# calculate calibration factor.
|
|
236
|
-
# return shape of calculate_calibration_factor is
|
|
242
|
+
# return shape of calculate_calibration_factor is
|
|
243
|
+
# (N_ESA_STEPS, N_ANGLE_SECTORS, N_CEMS) where
|
|
237
244
|
# last 7 dimension contains calibration factor for each CEM detector.
|
|
238
245
|
cal_factor = calculate_calibration_factor(
|
|
239
246
|
acquisition_time,
|
|
@@ -270,31 +277,38 @@ def populate_full_cycle_data(
|
|
|
270
277
|
# with information that esa step ramps up in even column and ramps down
|
|
271
278
|
# in odd column every six steps.
|
|
272
279
|
if esa_table_num == 0:
|
|
273
|
-
energy_steps = 24
|
|
274
|
-
angle = 30
|
|
275
|
-
cem_detectors = 7
|
|
276
280
|
# create new full cycle data array
|
|
277
|
-
full_cycle_data = np.zeros(
|
|
281
|
+
full_cycle_data = np.zeros(
|
|
282
|
+
(
|
|
283
|
+
swe_constants.N_ESA_STEPS,
|
|
284
|
+
swe_constants.N_ANGLE_SECTORS,
|
|
285
|
+
swe_constants.N_CEMS,
|
|
286
|
+
)
|
|
287
|
+
)
|
|
278
288
|
# SWE needs to store acquisition time of each count data point
|
|
279
289
|
# to use in level 2 processing to calculate
|
|
280
290
|
# spin phase. This is done below by using information from
|
|
281
291
|
# science packet.
|
|
282
|
-
acquisition_times = np.zeros(
|
|
292
|
+
acquisition_times = np.zeros(
|
|
293
|
+
(swe_constants.N_ESA_STEPS, swe_constants.N_ANGLE_SECTORS)
|
|
294
|
+
)
|
|
283
295
|
|
|
284
296
|
# Store acquisition duration for later calculation in this function
|
|
285
|
-
acq_duration_arr = np.zeros(
|
|
297
|
+
acq_duration_arr = np.zeros(
|
|
298
|
+
(swe_constants.N_ESA_STEPS, swe_constants.N_ANGLE_SECTORS)
|
|
299
|
+
)
|
|
286
300
|
|
|
287
301
|
# Initialize esa_step_number and column_index.
|
|
288
302
|
# esa_step_number goes from 0 to 719 range where
|
|
289
|
-
# 720 came from 24 x 30. full_cycle_data array has
|
|
290
|
-
# dimension.
|
|
303
|
+
# 720 came from 24 x 30. full_cycle_data array has
|
|
304
|
+
# (N_ESA_STEPS, N_ANGLE_SECTORS) dimension.
|
|
291
305
|
esa_step_number = 0
|
|
292
306
|
# column_index goes from 0 to 29 range where
|
|
293
307
|
# 30 came from 30 column in full_cycle_data array
|
|
294
308
|
column_index = -1
|
|
295
309
|
|
|
296
310
|
# Go through four quarter cycle data packets
|
|
297
|
-
for index in range(
|
|
311
|
+
for index in range(swe_constants.N_QUARTER_CYCLES):
|
|
298
312
|
decompressed_counts = l1a_data["science_data"].data[packet_index + index]
|
|
299
313
|
# Do deadtime correction
|
|
300
314
|
acq_duration = l1a_data["acq_duration"].data[packet_index + index]
|
|
@@ -304,11 +318,9 @@ def populate_full_cycle_data(
|
|
|
304
318
|
# Each quarter cycle data should have same acquisition start time coarse
|
|
305
319
|
# and fine value. We will use that as base time to calculate each
|
|
306
320
|
# acquisition time for each count data.
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
l1a_data["acq_start_coarse"].data[packet_index + index]
|
|
311
|
-
+ l1a_data["acq_start_fine"].data[packet_index + index] / 1000000
|
|
321
|
+
base_quarter_cycle_acq_time = combine_acquisition_time(
|
|
322
|
+
l1a_data["acq_start_coarse"].data[packet_index + index],
|
|
323
|
+
l1a_data["acq_start_fine"].data[packet_index + index],
|
|
312
324
|
)
|
|
313
325
|
|
|
314
326
|
# Go through each quarter cycle's 180 ESA measurements
|
|
@@ -317,7 +329,9 @@ def populate_full_cycle_data(
|
|
|
317
329
|
# Get esa voltage value from esa lookup table and
|
|
318
330
|
# use that to get row index in full data array
|
|
319
331
|
esa_voltage_value = esa_lookup_table.loc[esa_step_number]["esa_v"]
|
|
320
|
-
esa_voltage_row_index = ESA_VOLTAGE_ROW_INDEX_DICT[
|
|
332
|
+
esa_voltage_row_index = swe_constants.ESA_VOLTAGE_ROW_INDEX_DICT[
|
|
333
|
+
esa_voltage_value
|
|
334
|
+
]
|
|
321
335
|
|
|
322
336
|
# every six steps, increment column index
|
|
323
337
|
if esa_step_number % 6 == 0:
|
|
@@ -326,15 +340,14 @@ def populate_full_cycle_data(
|
|
|
326
340
|
full_cycle_data[esa_voltage_row_index][column_index] = corrected_counts[
|
|
327
341
|
step
|
|
328
342
|
]
|
|
329
|
-
# Acquisition time (in seconds) of each count data point
|
|
330
|
-
# using this formula:
|
|
331
|
-
# each_count_acq_time = base_quarter_cycle_acq_time +
|
|
332
|
-
# (step * ( acq_duration + settle_duration) / 1000000 )
|
|
333
|
-
# where step goes from 0 to 179, acq_start_coarse is in seconds and
|
|
334
|
-
# acq_start_fine is in microseconds and acq_duration is in microseconds.
|
|
343
|
+
# Acquisition time (in seconds) of each count data point
|
|
335
344
|
acquisition_times[esa_voltage_row_index][column_index] = (
|
|
336
|
-
|
|
337
|
-
|
|
345
|
+
calculate_data_acquisition_time(
|
|
346
|
+
base_quarter_cycle_acq_time,
|
|
347
|
+
esa_step_number,
|
|
348
|
+
acq_duration,
|
|
349
|
+
settle_duration,
|
|
350
|
+
)
|
|
338
351
|
)
|
|
339
352
|
# Store acquisition duration for later calculation
|
|
340
353
|
acq_duration_arr[esa_voltage_row_index][column_index] = acq_duration
|
|
@@ -352,13 +365,16 @@ def populate_full_cycle_data(
|
|
|
352
365
|
calibrated_counts = apply_in_flight_calibration(full_cycle_data, acquisition_times)
|
|
353
366
|
|
|
354
367
|
# Convert counts to rate
|
|
355
|
-
counts_rate = convert_counts_to_rate(
|
|
368
|
+
counts_rate = convert_counts_to_rate(
|
|
369
|
+
calibrated_counts, acq_duration_arr[:, :, np.newaxis]
|
|
370
|
+
)
|
|
356
371
|
|
|
357
|
-
# Store
|
|
372
|
+
# Store full cycle data in xr.Dataset for later use.
|
|
358
373
|
full_cycle_ds = xr.Dataset(
|
|
359
374
|
{
|
|
360
375
|
"full_cycle_data": (["esa_step", "spin_sector", "cem_id"], counts_rate),
|
|
361
376
|
"acquisition_time": (["esa_step", "spin_sector"], acquisition_times),
|
|
377
|
+
"acq_duration": (["esa_step", "spin_sector"], acq_duration_arr),
|
|
362
378
|
}
|
|
363
379
|
)
|
|
364
380
|
|
|
@@ -381,7 +397,7 @@ def find_cycle_starts(cycles: np.ndarray) -> npt.NDArray:
|
|
|
381
397
|
first_quarter_indices : numpy.ndarray
|
|
382
398
|
Array of indices of start cycle.
|
|
383
399
|
"""
|
|
384
|
-
if cycles.size <
|
|
400
|
+
if cycles.size < swe_constants.N_QUARTER_CYCLES:
|
|
385
401
|
return np.array([], np.int64)
|
|
386
402
|
|
|
387
403
|
# calculate difference between consecutive cycles
|
|
@@ -422,7 +438,10 @@ def get_indices_of_full_cycles(quarter_cycle: np.ndarray) -> npt.NDArray:
|
|
|
422
438
|
# Eg. [[0, 1, 2, 3]]
|
|
423
439
|
# then we add both of them together to get an array of shape(n, 4)
|
|
424
440
|
# Eg. [[3, 4, 5, 6], [8, 9, 10, 11]]
|
|
425
|
-
full_cycles_indices =
|
|
441
|
+
full_cycles_indices = (
|
|
442
|
+
indices_of_start[..., None]
|
|
443
|
+
+ np.arange(swe_constants.N_QUARTER_CYCLES)[None, ...]
|
|
444
|
+
)
|
|
426
445
|
return full_cycles_indices.reshape(-1)
|
|
427
446
|
|
|
428
447
|
|
|
@@ -470,7 +489,9 @@ def swe_l1b_science(l1a_data: xr.Dataset, data_version: str) -> xr.Dataset:
|
|
|
470
489
|
# Array to store list of table populated with data
|
|
471
490
|
# of full cycles
|
|
472
491
|
full_cycle_science_data = []
|
|
492
|
+
# These two are carried in l1b for level 2 and 3 processing
|
|
473
493
|
full_cycle_acq_times = []
|
|
494
|
+
full_cycle_acq_duration = []
|
|
474
495
|
packet_index = 0
|
|
475
496
|
l1a_data_copy = l1a_data.copy(deep=True)
|
|
476
497
|
|
|
@@ -505,7 +526,7 @@ def swe_l1b_science(l1a_data: xr.Dataset, data_version: str) -> xr.Dataset:
|
|
|
505
526
|
)
|
|
506
527
|
|
|
507
528
|
# Go through each cycle and populate full cycle data
|
|
508
|
-
for packet_index in range(0, total_packets,
|
|
529
|
+
for packet_index in range(0, total_packets, swe_constants.N_QUARTER_CYCLES):
|
|
509
530
|
# get ESA lookup table information
|
|
510
531
|
esa_table_num = l1a_data["esa_table_num"].data[packet_index]
|
|
511
532
|
|
|
@@ -524,6 +545,7 @@ def swe_l1b_science(l1a_data: xr.Dataset, data_version: str) -> xr.Dataset:
|
|
|
524
545
|
# save full data array to file
|
|
525
546
|
full_cycle_science_data.append(full_cycle_ds["full_cycle_data"].data)
|
|
526
547
|
full_cycle_acq_times.append(full_cycle_ds["acquisition_time"].data)
|
|
548
|
+
full_cycle_acq_duration.append(full_cycle_ds["acq_duration"].data)
|
|
527
549
|
|
|
528
550
|
# ------------------------------------------------------------------
|
|
529
551
|
# Save data to dataset.
|
|
@@ -534,22 +556,32 @@ def swe_l1b_science(l1a_data: xr.Dataset, data_version: str) -> xr.Dataset:
|
|
|
534
556
|
cdf_attrs.add_instrument_variable_attrs("swe", "l1b")
|
|
535
557
|
cdf_attrs.add_global_attribute("Data_version", data_version)
|
|
536
558
|
|
|
537
|
-
#
|
|
538
|
-
#
|
|
539
|
-
#
|
|
540
|
-
# of
|
|
559
|
+
# One full cycle data combines four quarter cycles data.
|
|
560
|
+
# Epoch will store center of each science meansurement using
|
|
561
|
+
# third acquisition start time coarse and fine value
|
|
562
|
+
# of four quarter cycle data packets. For example, we want to
|
|
563
|
+
# get indices of 3rd quarter cycle data packet in each full cycle
|
|
564
|
+
# and use that to calculate center time of data acquisition time.
|
|
565
|
+
# Quarter cycle indices: 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, ...
|
|
566
|
+
indices_of_center_time = np.arange(2, total_packets, swe_constants.N_QUARTER_CYCLES)
|
|
567
|
+
|
|
568
|
+
center_time = combine_acquisition_time(
|
|
569
|
+
full_cycle_l1a_data["acq_start_coarse"].data[indices_of_center_time],
|
|
570
|
+
full_cycle_l1a_data["acq_start_fine"].data[indices_of_center_time],
|
|
571
|
+
)
|
|
572
|
+
|
|
541
573
|
epoch_time = xr.DataArray(
|
|
542
|
-
|
|
574
|
+
met_to_ttj2000ns(center_time),
|
|
543
575
|
name="epoch",
|
|
544
576
|
dims=["epoch"],
|
|
545
|
-
attrs=cdf_attrs.get_variable_attributes("epoch"),
|
|
577
|
+
attrs=cdf_attrs.get_variable_attributes("epoch", check_schema=False),
|
|
546
578
|
)
|
|
547
579
|
|
|
548
580
|
esa_step = xr.DataArray(
|
|
549
|
-
np.arange(
|
|
581
|
+
np.arange(swe_constants.N_ESA_STEPS),
|
|
550
582
|
name="esa_step",
|
|
551
583
|
dims=["esa_step"],
|
|
552
|
-
attrs=cdf_attrs.get_variable_attributes("esa_step"),
|
|
584
|
+
attrs=cdf_attrs.get_variable_attributes("esa_step", check_schema=False),
|
|
553
585
|
)
|
|
554
586
|
|
|
555
587
|
# NOTE: LABL_PTR_1 should be CDF_CHAR.
|
|
@@ -557,14 +589,14 @@ def swe_l1b_science(l1a_data: xr.Dataset, data_version: str) -> xr.Dataset:
|
|
|
557
589
|
esa_step.values.astype(str),
|
|
558
590
|
name="esa_step_label",
|
|
559
591
|
dims=["esa_step"],
|
|
560
|
-
attrs=cdf_attrs.get_variable_attributes("esa_step_label"),
|
|
592
|
+
attrs=cdf_attrs.get_variable_attributes("esa_step_label", check_schema=False),
|
|
561
593
|
)
|
|
562
594
|
|
|
563
595
|
spin_sector = xr.DataArray(
|
|
564
|
-
np.arange(
|
|
596
|
+
np.arange(swe_constants.N_ANGLE_SECTORS),
|
|
565
597
|
name="spin_sector",
|
|
566
598
|
dims=["spin_sector"],
|
|
567
|
-
attrs=cdf_attrs.get_variable_attributes("spin_sector"),
|
|
599
|
+
attrs=cdf_attrs.get_variable_attributes("spin_sector", check_schema=False),
|
|
568
600
|
)
|
|
569
601
|
|
|
570
602
|
# NOTE: LABL_PTR_2 should be CDF_CHAR.
|
|
@@ -572,21 +604,30 @@ def swe_l1b_science(l1a_data: xr.Dataset, data_version: str) -> xr.Dataset:
|
|
|
572
604
|
spin_sector.values.astype(str),
|
|
573
605
|
name="spin_sector_label",
|
|
574
606
|
dims=["spin_sector"],
|
|
575
|
-
attrs=cdf_attrs.get_variable_attributes(
|
|
607
|
+
attrs=cdf_attrs.get_variable_attributes(
|
|
608
|
+
"spin_sector_label", check_schema=False
|
|
609
|
+
),
|
|
576
610
|
)
|
|
577
611
|
|
|
578
612
|
cycle = xr.DataArray(
|
|
579
|
-
np.arange(
|
|
613
|
+
np.arange(swe_constants.N_QUARTER_CYCLES),
|
|
580
614
|
name="cycle",
|
|
581
615
|
dims=["cycle"],
|
|
582
|
-
attrs=cdf_attrs.get_variable_attributes("cycle"),
|
|
616
|
+
attrs=cdf_attrs.get_variable_attributes("cycle", check_schema=False),
|
|
617
|
+
)
|
|
618
|
+
|
|
619
|
+
cycle_label = xr.DataArray(
|
|
620
|
+
cycle.values.astype(str),
|
|
621
|
+
name="cycle_label",
|
|
622
|
+
dims=["cycle"],
|
|
623
|
+
attrs=cdf_attrs.get_variable_attributes("cycle_label", check_schema=False),
|
|
583
624
|
)
|
|
584
625
|
|
|
585
626
|
cem_id = xr.DataArray(
|
|
586
|
-
np.arange(
|
|
627
|
+
np.arange(swe_constants.N_CEMS, dtype=np.int8),
|
|
587
628
|
name="cem_id",
|
|
588
629
|
dims=["cem_id"],
|
|
589
|
-
attrs=cdf_attrs.get_variable_attributes("cem_id"),
|
|
630
|
+
attrs=cdf_attrs.get_variable_attributes("cem_id", check_schema=False),
|
|
590
631
|
)
|
|
591
632
|
|
|
592
633
|
# NOTE: LABL_PTR_3 should be CDF_CHAR.
|
|
@@ -594,7 +635,7 @@ def swe_l1b_science(l1a_data: xr.Dataset, data_version: str) -> xr.Dataset:
|
|
|
594
635
|
cem_id.values.astype(str),
|
|
595
636
|
name="cem_id_label",
|
|
596
637
|
dims=["cem_id"],
|
|
597
|
-
attrs=cdf_attrs.get_variable_attributes("cem_id_label"),
|
|
638
|
+
attrs=cdf_attrs.get_variable_attributes("cem_id_label", check_schema=False),
|
|
598
639
|
)
|
|
599
640
|
|
|
600
641
|
# Add science data and it's associated metadata into dataset.
|
|
@@ -622,6 +663,7 @@ def swe_l1b_science(l1a_data: xr.Dataset, data_version: str) -> xr.Dataset:
|
|
|
622
663
|
"esa_step_label": esa_step_label,
|
|
623
664
|
"spin_sector_label": spin_sector_label,
|
|
624
665
|
"cem_id_label": cem_id_label,
|
|
666
|
+
"cycle_label": cycle_label,
|
|
625
667
|
},
|
|
626
668
|
attrs=cdf_attrs.get_global_attributes("imap_swe_l1b_sci"),
|
|
627
669
|
)
|
|
@@ -636,14 +678,19 @@ def swe_l1b_science(l1a_data: xr.Dataset, data_version: str) -> xr.Dataset:
|
|
|
636
678
|
dims=["epoch", "esa_step", "spin_sector"],
|
|
637
679
|
attrs=cdf_attrs.get_variable_attributes("acquisition_time"),
|
|
638
680
|
)
|
|
681
|
+
dataset["acq_duration"] = xr.DataArray(
|
|
682
|
+
full_cycle_acq_duration,
|
|
683
|
+
dims=["epoch", "esa_step", "spin_sector"],
|
|
684
|
+
attrs=cdf_attrs.get_variable_attributes("acq_duration"),
|
|
685
|
+
)
|
|
639
686
|
|
|
640
687
|
# create xarray dataset for each metadata field
|
|
641
688
|
for key, value in full_cycle_l1a_data.items():
|
|
642
|
-
if key
|
|
689
|
+
if key in ["science_data", "acq_duration"]:
|
|
643
690
|
continue
|
|
644
691
|
metadata_field = key.lower()
|
|
645
692
|
dataset[metadata_field] = xr.DataArray(
|
|
646
|
-
value.data.reshape(-1,
|
|
693
|
+
value.data.reshape(-1, swe_constants.N_QUARTER_CYCLES),
|
|
647
694
|
dims=["epoch", "cycle"],
|
|
648
695
|
attrs=cdf_attrs.get_variable_attributes(metadata_field),
|
|
649
696
|
)
|
imap_processing/swe/l2/swe_l2.py
CHANGED
|
@@ -11,34 +11,11 @@ import xarray as xr
|
|
|
11
11
|
from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
|
|
12
12
|
from imap_processing.spice.geometry import SpiceFrame
|
|
13
13
|
from imap_processing.spice.spin import get_instrument_spin_phase, get_spin_angle
|
|
14
|
+
from imap_processing.swe.utils import swe_constants
|
|
14
15
|
from imap_processing.swe.utils.swe_utils import (
|
|
15
|
-
ESA_VOLTAGE_ROW_INDEX_DICT,
|
|
16
16
|
read_lookup_table,
|
|
17
17
|
)
|
|
18
18
|
|
|
19
|
-
# TODO: add these to instrument status summary
|
|
20
|
-
ENERGY_CONVERSION_FACTOR = 4.75
|
|
21
|
-
# 7 CEMs geometric factors in cm^2 sr eV/eV units.
|
|
22
|
-
GEOMETRIC_FACTORS = np.array(
|
|
23
|
-
[
|
|
24
|
-
435e-6,
|
|
25
|
-
599e-6,
|
|
26
|
-
808e-6,
|
|
27
|
-
781e-6,
|
|
28
|
-
876e-6,
|
|
29
|
-
548e-6,
|
|
30
|
-
432e-6,
|
|
31
|
-
]
|
|
32
|
-
)
|
|
33
|
-
ELECTRON_MASS = 9.10938356e-31 # kg
|
|
34
|
-
|
|
35
|
-
# See doc string of calculate_phase_space_density() for more details.
|
|
36
|
-
VELOCITY_CONVERSION_FACTOR = 1.237e31
|
|
37
|
-
# See doc string of calculate_flux() for more details.
|
|
38
|
-
FLUX_CONVERSION_FACTOR = 6.187e30
|
|
39
|
-
|
|
40
|
-
CEM_DETECTORS_ANGLE = np.array([-63, -42, -21, 0, 21, 42, 63])
|
|
41
|
-
|
|
42
19
|
|
|
43
20
|
def get_particle_energy() -> npt.NDArray:
|
|
44
21
|
"""
|
|
@@ -57,7 +34,9 @@ def get_particle_energy() -> npt.NDArray:
|
|
|
57
34
|
lookup_table = read_lookup_table()
|
|
58
35
|
|
|
59
36
|
# Convert voltage to electron energy in eV by apply conversion factor.
|
|
60
|
-
lookup_table["energy"] =
|
|
37
|
+
lookup_table["energy"] = (
|
|
38
|
+
lookup_table["esa_v"].values * swe_constants.ENERGY_CONVERSION_FACTOR
|
|
39
|
+
)
|
|
61
40
|
return lookup_table
|
|
62
41
|
|
|
63
42
|
|
|
@@ -117,14 +96,16 @@ def calculate_phase_space_density(l1b_dataset: xr.Dataset) -> xr.Dataset:
|
|
|
117
96
|
for val in esa_table_nums
|
|
118
97
|
]
|
|
119
98
|
)
|
|
120
|
-
particle_energy_data = particle_energy_data.reshape(
|
|
99
|
+
particle_energy_data = particle_energy_data.reshape(
|
|
100
|
+
-1, swe_constants.N_ESA_STEPS, swe_constants.N_ANGLE_SECTORS
|
|
101
|
+
)
|
|
121
102
|
|
|
122
103
|
# Calculate phase space density using formula:
|
|
123
104
|
# 2 * (C/tau) / (G * 1.237e31 * eV^2)
|
|
124
105
|
# See doc string for more details.
|
|
125
106
|
density = (2 * l1b_dataset["science_data"]) / (
|
|
126
|
-
GEOMETRIC_FACTORS[np.newaxis, np.newaxis, np.newaxis, :]
|
|
127
|
-
* VELOCITY_CONVERSION_FACTOR
|
|
107
|
+
swe_constants.GEOMETRIC_FACTORS[np.newaxis, np.newaxis, np.newaxis, :]
|
|
108
|
+
* swe_constants.VELOCITY_CONVERSION_FACTOR
|
|
128
109
|
* particle_energy_data[:, :, :, np.newaxis] ** 2
|
|
129
110
|
)
|
|
130
111
|
|
|
@@ -194,7 +175,7 @@ def calculate_flux(l1b_dataset: xr.Dataset) -> npt.NDArray:
|
|
|
194
175
|
"""
|
|
195
176
|
phase_space_density_ds = calculate_phase_space_density(l1b_dataset)
|
|
196
177
|
flux = (
|
|
197
|
-
FLUX_CONVERSION_FACTOR
|
|
178
|
+
swe_constants.FLUX_CONVERSION_FACTOR
|
|
198
179
|
* phase_space_density_ds["energy_in_eV"].data[:, :, :, np.newaxis]
|
|
199
180
|
* phase_space_density_ds["phase_space_density"].data
|
|
200
181
|
)
|
|
@@ -220,22 +201,32 @@ def put_data_into_angle_bins(
|
|
|
220
201
|
Parameters
|
|
221
202
|
----------
|
|
222
203
|
data : numpy.ndarray
|
|
223
|
-
Data to put in bins. Shape:
|
|
204
|
+
Data to put in bins. Shape:
|
|
205
|
+
(full_cycle_data, N_ESA_STEPS, N_ANGLE_BINS, N_CEMS).
|
|
224
206
|
angle_bin_indices : numpy.ndarray
|
|
225
207
|
Indices of angle bins to put data in. Shape:
|
|
226
|
-
(full_cycle_data,
|
|
208
|
+
(full_cycle_data, N_ESA_STEPS, N_ANGLE_BINS).
|
|
227
209
|
|
|
228
210
|
Returns
|
|
229
211
|
-------
|
|
230
212
|
numpy.ndarray
|
|
231
|
-
Data in bins. Shape:
|
|
213
|
+
Data in bins. Shape:
|
|
214
|
+
(full_cycle_data, N_ESA_STEPS, N_ANGLE_BINS, N_CEMS).
|
|
232
215
|
"""
|
|
233
216
|
# Initialize with zeros instead of NaN because np.add.at() does not
|
|
234
217
|
# work with nan values. It results in nan + value = nan
|
|
235
|
-
binned_data = np.zeros(
|
|
218
|
+
binned_data = np.zeros(
|
|
219
|
+
(
|
|
220
|
+
data.shape[0],
|
|
221
|
+
swe_constants.N_ESA_STEPS,
|
|
222
|
+
swe_constants.N_ANGLE_BINS,
|
|
223
|
+
swe_constants.N_CEMS,
|
|
224
|
+
),
|
|
225
|
+
dtype=np.float64,
|
|
226
|
+
)
|
|
236
227
|
|
|
237
228
|
time_indices = np.arange(data.shape[0])[:, None, None]
|
|
238
|
-
energy_indices = np.arange(
|
|
229
|
+
energy_indices = np.arange(swe_constants.N_ESA_STEPS)[None, :, None]
|
|
239
230
|
|
|
240
231
|
# Use np.add.at() to accumulate values into bins
|
|
241
232
|
np.add.at(binned_data, (time_indices, energy_indices, angle_bin_indices), data)
|
|
@@ -335,45 +326,52 @@ def swe_l2(l1b_dataset: xr.Dataset, data_version: str) -> xr.Dataset:
|
|
|
335
326
|
|
|
336
327
|
# Energy values in eV.
|
|
337
328
|
energy_xr = xr.DataArray(
|
|
338
|
-
np.array(list(ESA_VOLTAGE_ROW_INDEX_DICT.keys()))
|
|
329
|
+
np.array(list(swe_constants.ESA_VOLTAGE_ROW_INDEX_DICT.keys()))
|
|
330
|
+
* swe_constants.ENERGY_CONVERSION_FACTOR,
|
|
339
331
|
name="energy",
|
|
340
332
|
dims=["energy"],
|
|
341
|
-
attrs=cdf_attributes.get_variable_attributes("energy"),
|
|
333
|
+
attrs=cdf_attributes.get_variable_attributes("energy", check_schema=False),
|
|
342
334
|
)
|
|
343
335
|
|
|
344
336
|
energy_label = xr.DataArray(
|
|
345
|
-
np.array(list(ESA_VOLTAGE_ROW_INDEX_DICT.keys())).astype(str),
|
|
337
|
+
np.array(list(swe_constants.ESA_VOLTAGE_ROW_INDEX_DICT.keys())).astype(str),
|
|
346
338
|
name="energy_label",
|
|
347
339
|
dims=["energy"],
|
|
348
|
-
attrs=cdf_attributes.get_variable_attributes(
|
|
340
|
+
attrs=cdf_attributes.get_variable_attributes(
|
|
341
|
+
"energy_label", check_schema=False
|
|
342
|
+
),
|
|
349
343
|
)
|
|
350
344
|
|
|
351
345
|
# Angle of each CEM detectors.
|
|
352
346
|
inst_el_xr = xr.DataArray(
|
|
353
|
-
CEM_DETECTORS_ANGLE,
|
|
347
|
+
swe_constants.CEM_DETECTORS_ANGLE,
|
|
354
348
|
name="inst_el",
|
|
355
349
|
dims=["inst_el"],
|
|
356
|
-
attrs=cdf_attributes.get_variable_attributes("inst_el"),
|
|
350
|
+
attrs=cdf_attributes.get_variable_attributes("inst_el", check_schema=False),
|
|
357
351
|
)
|
|
358
352
|
inst_el_label = xr.DataArray(
|
|
359
|
-
CEM_DETECTORS_ANGLE.astype(str),
|
|
353
|
+
swe_constants.CEM_DETECTORS_ANGLE.astype(str),
|
|
360
354
|
name="inst_el_label",
|
|
361
355
|
dims=["inst_el"],
|
|
362
|
-
attrs=cdf_attributes.get_variable_attributes(
|
|
356
|
+
attrs=cdf_attributes.get_variable_attributes(
|
|
357
|
+
"inst_el_label", check_schema=False
|
|
358
|
+
),
|
|
363
359
|
)
|
|
364
360
|
|
|
365
361
|
# Spin Angle bins storing bin center values.
|
|
366
362
|
inst_az_xr = xr.DataArray(
|
|
367
|
-
np.arange(0, 360, 12) + 6,
|
|
363
|
+
np.arange(0, 360, 12, dtype=np.float32) + 6,
|
|
368
364
|
name="inst_az",
|
|
369
365
|
dims=["inst_az"],
|
|
370
|
-
attrs=cdf_attributes.get_variable_attributes("inst_az"),
|
|
366
|
+
attrs=cdf_attributes.get_variable_attributes("inst_az", check_schema=False),
|
|
371
367
|
)
|
|
372
368
|
inst_az_label = xr.DataArray(
|
|
373
369
|
inst_az_xr.values.astype(str),
|
|
374
370
|
name="inst_az_label",
|
|
375
371
|
dims=["inst_az"],
|
|
376
|
-
attrs=cdf_attributes.get_variable_attributes(
|
|
372
|
+
attrs=cdf_attributes.get_variable_attributes(
|
|
373
|
+
"inst_az_label", check_schema=False
|
|
374
|
+
),
|
|
377
375
|
)
|
|
378
376
|
|
|
379
377
|
dataset = xr.Dataset(
|
|
@@ -419,36 +417,33 @@ def swe_l2(l1b_dataset: xr.Dataset, data_version: str) -> xr.Dataset:
|
|
|
419
417
|
|
|
420
418
|
# Carry over acquisition times for L3 purposes.
|
|
421
419
|
dataset["acquisition_time"] = l1b_dataset["acquisition_time"]
|
|
420
|
+
# Update the acquisition_time variable attributes.
|
|
421
|
+
dataset["acquisition_time"].attrs = cdf_attributes.get_variable_attributes(
|
|
422
|
+
"acquisition_time"
|
|
423
|
+
)
|
|
424
|
+
# Carry over acq_duration for L3 purposes.
|
|
425
|
+
dataset["acq_duration"] = l1b_dataset["acq_duration"]
|
|
426
|
+
# Update the acq_duration variable attributes.
|
|
427
|
+
dataset["acq_duration"].attrs = cdf_attributes.get_variable_attributes(
|
|
428
|
+
"acq_duration"
|
|
429
|
+
)
|
|
422
430
|
|
|
423
431
|
# Calculate spin phase using SWE acquisition_time from the
|
|
424
432
|
# L1B dataset. The L1B dataset stores acquisition_time with
|
|
425
|
-
# dimensions (epoch, esa_step, spin_sector).
|
|
426
|
-
#
|
|
427
|
-
# necessary to accurately determine the center angle of the data.
|
|
428
|
-
#
|
|
429
|
-
# To determine the center acquisition time, we adjust the
|
|
430
|
-
# recorded acquisition_time as follows:
|
|
431
|
-
# acquisition_time + (acq_duration / 1000000) / 2
|
|
432
|
-
#
|
|
433
|
-
# Here, acq_duration is given in microseconds and is stored
|
|
434
|
-
# in the L1B dataset with dimensions (epoch, cycle). Since acq_duration
|
|
435
|
-
# remains the same for all quarter cycles within a full sweep,
|
|
436
|
-
# we use the first acq_duration value for each full sweep to perform
|
|
437
|
-
# this adjustment.
|
|
438
|
-
|
|
439
|
-
acq_duration = l1b_dataset["acq_duration"].data[:, 0] / 2000000
|
|
440
|
-
data_acq_time = (
|
|
441
|
-
l1b_dataset["acquisition_time"].data + acq_duration[:, np.newaxis, np.newaxis]
|
|
442
|
-
)
|
|
433
|
+
# dimensions (epoch, esa_step, spin_sector). acquisition_time is
|
|
434
|
+
# center time of acquisition time of each science measurement which
|
|
435
|
+
# is necessary to accurately determine the center angle of the data.
|
|
443
436
|
|
|
444
437
|
# Calculate spin phase
|
|
445
438
|
inst_spin_phase = get_instrument_spin_phase(
|
|
446
|
-
query_met_times=
|
|
439
|
+
query_met_times=l1b_dataset["acquisition_time"].data.ravel(),
|
|
447
440
|
instrument=SpiceFrame.IMAP_SWE,
|
|
448
441
|
)
|
|
449
442
|
|
|
450
443
|
# Convert spin phase to spin angle in degrees.
|
|
451
|
-
inst_spin_angle = get_spin_angle(inst_spin_phase, degrees=True).reshape(
|
|
444
|
+
inst_spin_angle = get_spin_angle(inst_spin_phase, degrees=True).reshape(
|
|
445
|
+
-1, swe_constants.N_ESA_STEPS, swe_constants.N_ANGLE_SECTORS
|
|
446
|
+
)
|
|
452
447
|
|
|
453
448
|
# Save spin angle in dataset per SWE request.
|
|
454
449
|
dataset["inst_az_spin_sector"] = xr.DataArray(
|