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,123 @@
|
|
|
1
|
+
"""Spacecraft quaternion processing."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
import xarray as xr
|
|
7
|
+
|
|
8
|
+
from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
|
|
9
|
+
from imap_processing.spice.time import met_to_ttj2000ns
|
|
10
|
+
from imap_processing.utils import packet_file_to_datasets
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def load_quaternion_packets(packet_file: Path | str) -> xr.Dataset:
|
|
14
|
+
"""
|
|
15
|
+
Load the raw quaternion packets from the packet file.
|
|
16
|
+
|
|
17
|
+
Parameters
|
|
18
|
+
----------
|
|
19
|
+
packet_file : Path
|
|
20
|
+
Path to the packet file containing the quaternions in apid 594.
|
|
21
|
+
|
|
22
|
+
Returns
|
|
23
|
+
-------
|
|
24
|
+
xarray.Dataset
|
|
25
|
+
Dataset containing the raw quaternion packets.
|
|
26
|
+
"""
|
|
27
|
+
xtce_packet_definition = Path(__file__).parent / "packet_definitions/scid_x252.xml"
|
|
28
|
+
datasets_by_apid = packet_file_to_datasets(
|
|
29
|
+
packet_file=packet_file, xtce_packet_definition=xtce_packet_definition
|
|
30
|
+
)
|
|
31
|
+
return datasets_by_apid[0x252]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def assemble_quaternions(ds: xr.Dataset) -> xr.Dataset:
|
|
35
|
+
"""
|
|
36
|
+
Assemble quaternions from the l1a dataset.
|
|
37
|
+
|
|
38
|
+
The quaternions are stored in separate variables for each component (x, y, z, s)
|
|
39
|
+
and for each 10 Hz sample of the 1s packet. i.e. there are 4 * 10 = 40 variables
|
|
40
|
+
in the initial dataset that we want to turn into 4 variables with a continuous
|
|
41
|
+
10 Hz sampling period.
|
|
42
|
+
|
|
43
|
+
The output dataset will have a single dimension "epoch" that will be the time
|
|
44
|
+
associated with each of the 10 Hz samples. There are 4 data variables: "quat_x",
|
|
45
|
+
"quat_y", "quat_z", "quat_s".
|
|
46
|
+
|
|
47
|
+
Parameters
|
|
48
|
+
----------
|
|
49
|
+
ds : xarray.Dataset
|
|
50
|
+
Input dataset containing the 10Hz quaternions from packet 0x252 (APID 594).
|
|
51
|
+
|
|
52
|
+
Returns
|
|
53
|
+
-------
|
|
54
|
+
xarray.Dataset
|
|
55
|
+
Output dataset with the quaternions assembled into 4 variables with a
|
|
56
|
+
continuous 10 Hz sampling period.
|
|
57
|
+
"""
|
|
58
|
+
# Our time is only given for the first timestamp
|
|
59
|
+
# We then add to it 0.1 increments and ravel the array to associate a specific time
|
|
60
|
+
# with each of the 10 samples
|
|
61
|
+
time = (
|
|
62
|
+
ds["SCIENCEDATA1HZ_QUAT_10_HZ_TIME".lower()].values[:, np.newaxis]
|
|
63
|
+
+ np.arange(0, 1, 0.1)
|
|
64
|
+
).ravel()
|
|
65
|
+
output_ds = xr.Dataset(coords={"epoch": time})
|
|
66
|
+
base_name = "FSW_ACS_QUAT_10_HZ_BUFFERED".lower()
|
|
67
|
+
for quat_i, label in enumerate(["x", "y", "z", "s"]):
|
|
68
|
+
# 0, 1, 2, .. 9 // 10, 11, 12, .. 19 // 20, 21, 22, .. 29 // 30, 31, 32, .. 39
|
|
69
|
+
names = [f"{base_name}_{i + quat_i*10}" for i in range(10)]
|
|
70
|
+
quat = np.stack([ds[name] for name in names], axis=1).ravel()
|
|
71
|
+
output_ds[f"quat_{label}"] = ("epoch", quat)
|
|
72
|
+
return output_ds
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def process_quaternions(packet_file: Path | str) -> tuple[xr.Dataset, xr.Dataset]:
|
|
76
|
+
"""
|
|
77
|
+
Generate l1a and l1b datasets from a packet file containing the raw quaternions.
|
|
78
|
+
|
|
79
|
+
This produces two CDF files: one for the l1a quaternions and one for the l1b
|
|
80
|
+
quaternions. The l1b quaternions are assembled into 4 variables: "quat_x",
|
|
81
|
+
"quat_y", "quat_z", "quat_s".
|
|
82
|
+
|
|
83
|
+
Parameters
|
|
84
|
+
----------
|
|
85
|
+
packet_file : Path
|
|
86
|
+
Path to the packet file containing the quaternions in apid 594.
|
|
87
|
+
|
|
88
|
+
Returns
|
|
89
|
+
-------
|
|
90
|
+
xarray.Dataset
|
|
91
|
+
Dataset containing the l1a quaternions.
|
|
92
|
+
xarray.Dataset
|
|
93
|
+
Dataset containing the l1b quaternions.
|
|
94
|
+
"""
|
|
95
|
+
l1a_ds = load_quaternion_packets(packet_file)
|
|
96
|
+
|
|
97
|
+
# Assemble the quaternions into the correct components
|
|
98
|
+
l1b_ds = assemble_quaternions(l1a_ds)
|
|
99
|
+
|
|
100
|
+
# Update dataset global attributes
|
|
101
|
+
attr_mgr = ImapCdfAttributes()
|
|
102
|
+
attr_mgr.add_instrument_global_attrs("spacecraft")
|
|
103
|
+
# TODO: Allow version to be passed in
|
|
104
|
+
attr_mgr.add_global_attribute("Data_version", 1)
|
|
105
|
+
attr_mgr.add_instrument_variable_attrs(instrument="spacecraft", level=None)
|
|
106
|
+
|
|
107
|
+
l1a_ds.attrs.update(
|
|
108
|
+
attr_mgr.get_global_attributes("imap_spacecraft_l1a_quaternions")
|
|
109
|
+
)
|
|
110
|
+
l1b_ds.attrs.update(
|
|
111
|
+
attr_mgr.get_global_attributes("imap_spacecraft_l1b_quaternions")
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
# Update the epoch attribute
|
|
115
|
+
l1b_ds["epoch"] = met_to_ttj2000ns(l1b_ds["epoch"])
|
|
116
|
+
# check_schema=False keeps DEPEND_0 = '' from being auto added
|
|
117
|
+
epoch_attrs = attr_mgr.get_variable_attributes("epoch", check_schema=False)
|
|
118
|
+
l1b_ds["epoch"].attrs.update(epoch_attrs)
|
|
119
|
+
|
|
120
|
+
for var in ["quat_x", "quat_y", "quat_z", "quat_s"]:
|
|
121
|
+
l1b_ds[var].attrs.update(attr_mgr.get_variable_attributes(var))
|
|
122
|
+
|
|
123
|
+
return l1a_ds, l1b_ds
|
|
@@ -268,7 +268,7 @@ def frame_transform_az_el(
|
|
|
268
268
|
spherical_coords_in = np.array(
|
|
269
269
|
[np.ones_like(az_el[..., 0]), az_el[..., 0], az_el[..., 1]]
|
|
270
270
|
).T
|
|
271
|
-
from_frame_cartesian = spherical_to_cartesian(spherical_coords_in
|
|
271
|
+
from_frame_cartesian = spherical_to_cartesian(spherical_coords_in)
|
|
272
272
|
# Transform to to_frame
|
|
273
273
|
to_frame_cartesian = frame_transform(et, from_frame_cartesian, from_frame, to_frame)
|
|
274
274
|
# Convert to spherical and extract azimuth/elevation
|
|
@@ -425,14 +425,14 @@ def cartesian_to_spherical(
|
|
|
425
425
|
- r : Distance of the point from the origin.
|
|
426
426
|
- azimuth : angle in the xy-plane
|
|
427
427
|
In degrees if degrees parameter is True (by default):
|
|
428
|
-
output range=[0, 360
|
|
428
|
+
output range=[0, 360) degrees,
|
|
429
429
|
otherwise in radians if degrees parameter is False:
|
|
430
|
-
output range=[0, 2*pi
|
|
430
|
+
output range=[0, 2*pi) radians.
|
|
431
431
|
- elevation : angle from the xy-plane
|
|
432
432
|
In degrees if degrees parameter is True (by default):
|
|
433
|
-
output range=[
|
|
433
|
+
output range=[-90, 90) degrees,
|
|
434
434
|
otherwise in radians if degrees parameter is False:
|
|
435
|
-
output range=[-pi/2, pi/2
|
|
435
|
+
output range=[-pi/2, pi/2) radians.
|
|
436
436
|
"""
|
|
437
437
|
# Magnitude of the velocity vector
|
|
438
438
|
magnitude_v = np.linalg.norm(v, axis=-1, keepdims=True)
|
|
@@ -457,9 +457,9 @@ def cartesian_to_spherical(
|
|
|
457
457
|
return spherical_coords
|
|
458
458
|
|
|
459
459
|
|
|
460
|
-
def spherical_to_cartesian(spherical_coords: NDArray
|
|
460
|
+
def spherical_to_cartesian(spherical_coords: NDArray) -> NDArray:
|
|
461
461
|
"""
|
|
462
|
-
Convert spherical coordinates to Cartesian coordinates.
|
|
462
|
+
Convert spherical coordinates (angles in degrees) to Cartesian coordinates.
|
|
463
463
|
|
|
464
464
|
Parameters
|
|
465
465
|
----------
|
|
@@ -468,11 +468,8 @@ def spherical_to_cartesian(spherical_coords: NDArray, degrees: bool = False) ->
|
|
|
468
468
|
the spherical coordinates (r, azimuth, elevation):
|
|
469
469
|
|
|
470
470
|
- r : Distance of the point from the origin.
|
|
471
|
-
- azimuth : angle in the xy-plane in
|
|
472
|
-
- elevation : angle from the xy-plane in
|
|
473
|
-
degrees : bool
|
|
474
|
-
Set to True if input azimuth and elevation angles are in degrees.
|
|
475
|
-
Defaults to False.
|
|
471
|
+
- azimuth : angle in the xy-plane in degrees. Range is [0, 360) degrees.
|
|
472
|
+
- elevation : angle from the xy-plane in degrees. Range is [-90, 90) degrees.
|
|
476
473
|
|
|
477
474
|
Returns
|
|
478
475
|
-------
|
|
@@ -483,9 +480,9 @@ def spherical_to_cartesian(spherical_coords: NDArray, degrees: bool = False) ->
|
|
|
483
480
|
azimuth = spherical_coords[..., 1]
|
|
484
481
|
elevation = spherical_coords[..., 2]
|
|
485
482
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
483
|
+
# Convert to radians for numpy trigonometric operations
|
|
484
|
+
azimuth = np.deg2rad(azimuth)
|
|
485
|
+
elevation = np.deg2rad(elevation)
|
|
489
486
|
|
|
490
487
|
x = r * np.cos(elevation) * np.cos(azimuth)
|
|
491
488
|
y = r * np.cos(elevation) * np.sin(azimuth)
|
|
@@ -496,7 +493,7 @@ def spherical_to_cartesian(spherical_coords: NDArray, degrees: bool = False) ->
|
|
|
496
493
|
return cartesian_coords
|
|
497
494
|
|
|
498
495
|
|
|
499
|
-
def cartesian_to_latitudinal(coords: NDArray, degrees: bool =
|
|
496
|
+
def cartesian_to_latitudinal(coords: NDArray, degrees: bool = True) -> NDArray:
|
|
500
497
|
"""
|
|
501
498
|
Convert cartesian coordinates to latitudinal coordinates in radians.
|
|
502
499
|
|
|
@@ -511,7 +508,7 @@ def cartesian_to_latitudinal(coords: NDArray, degrees: bool = False) -> NDArray:
|
|
|
511
508
|
with x, y, z-components.
|
|
512
509
|
degrees : bool
|
|
513
510
|
If True, the longitude and latitude coords are returned in degrees.
|
|
514
|
-
Defaults to
|
|
511
|
+
Defaults to True.
|
|
515
512
|
|
|
516
513
|
Returns
|
|
517
514
|
-------
|
|
@@ -532,7 +529,7 @@ def cartesian_to_latitudinal(coords: NDArray, degrees: bool = False) -> NDArray:
|
|
|
532
529
|
|
|
533
530
|
def solar_longitude(
|
|
534
531
|
et: Union[np.ndarray, float],
|
|
535
|
-
degrees: bool =
|
|
532
|
+
degrees: bool = True,
|
|
536
533
|
) -> Union[float, npt.NDArray]:
|
|
537
534
|
"""
|
|
538
535
|
Compute the solar longitude of the Imap Spacecraft.
|
|
@@ -543,7 +540,7 @@ def solar_longitude(
|
|
|
543
540
|
Ephemeris time(s) to at which to compute solar longitude.
|
|
544
541
|
degrees : bool
|
|
545
542
|
If True, the longitude is returned in degrees.
|
|
546
|
-
Defaults to
|
|
543
|
+
Defaults to True.
|
|
547
544
|
|
|
548
545
|
Returns
|
|
549
546
|
-------
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"""Functions for retrieving repointing table data."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import os
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Union
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
import pandas as pd
|
|
10
|
+
from numpy import typing as npt
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_repoint_data() -> pd.DataFrame:
|
|
16
|
+
"""
|
|
17
|
+
Read repointing file using environment variable and return as dataframe.
|
|
18
|
+
|
|
19
|
+
REPOINT_DATA_FILEPATH environment variable should point to a local
|
|
20
|
+
file where the repointing csv file is located.
|
|
21
|
+
|
|
22
|
+
Returns
|
|
23
|
+
-------
|
|
24
|
+
repoint_df : pd.DataFrame
|
|
25
|
+
The repointing csv loaded into a pandas dataframe. The dataframe will
|
|
26
|
+
contain the following columns:
|
|
27
|
+
- `repoint_start_time`: Starting MET time of each repoint maneuver.
|
|
28
|
+
- `repoint_end_time`: Ending MET time of each repoint maneuver.
|
|
29
|
+
- `repoint_id`: Unique ID number of each repoint maneuver.
|
|
30
|
+
"""
|
|
31
|
+
repoint_data_filepath = os.getenv("REPOINT_DATA_FILEPATH")
|
|
32
|
+
if repoint_data_filepath is not None:
|
|
33
|
+
path_to_spin_file = Path(repoint_data_filepath)
|
|
34
|
+
else:
|
|
35
|
+
# Handle the case where the environment variable is not set
|
|
36
|
+
raise ValueError("REPOINT_DATA_FILEPATH environment variable is not set.")
|
|
37
|
+
|
|
38
|
+
logger.info(f"Reading repointing data from {path_to_spin_file}")
|
|
39
|
+
repoint_df = pd.read_csv(path_to_spin_file, comment="#")
|
|
40
|
+
|
|
41
|
+
return repoint_df
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def interpolate_repoint_data(
|
|
45
|
+
query_met_times: Union[float, npt.NDArray],
|
|
46
|
+
) -> pd.DataFrame:
|
|
47
|
+
"""
|
|
48
|
+
Interpolate repointing data to the queried MET times.
|
|
49
|
+
|
|
50
|
+
In addition to the repoint start, end, and id values that come directly from
|
|
51
|
+
the universal repointing table, a column is added to the output dataframe
|
|
52
|
+
which indicates whether each query met time occurs during a repoint maneuver
|
|
53
|
+
i.e. between the repoint start and end times of a row in the repointing
|
|
54
|
+
table.
|
|
55
|
+
|
|
56
|
+
Query times that are more than 24-hours after that last repoint start time
|
|
57
|
+
in the repoint table will cause an error to be raised. The assumption here
|
|
58
|
+
is that we shouldn't be processing data that occurs that close to the next
|
|
59
|
+
expected repoint start time before getting an updated repoint table.
|
|
60
|
+
|
|
61
|
+
Parameters
|
|
62
|
+
----------
|
|
63
|
+
query_met_times : float or np.ndarray
|
|
64
|
+
Query times in Mission Elapsed Time (MET).
|
|
65
|
+
|
|
66
|
+
Returns
|
|
67
|
+
-------
|
|
68
|
+
repoint_df : pandas.DataFrame
|
|
69
|
+
Repoint table data interpolated such that there is one row
|
|
70
|
+
for each of the queried MET times. Output columns are:
|
|
71
|
+
- `repoint_start_time`
|
|
72
|
+
- `repoint_end_time`
|
|
73
|
+
- `repoint_id`
|
|
74
|
+
- `repoint_in_progress`
|
|
75
|
+
|
|
76
|
+
Raises
|
|
77
|
+
------
|
|
78
|
+
ValueError : If any of the query_met_times are before the first repoint
|
|
79
|
+
start time or after the last repoint start time plus 24-hours.
|
|
80
|
+
"""
|
|
81
|
+
repoint_df = get_repoint_data()
|
|
82
|
+
|
|
83
|
+
# Ensure query_met_times is an array
|
|
84
|
+
query_met_times = np.atleast_1d(query_met_times)
|
|
85
|
+
|
|
86
|
+
# Make sure no query times are before the first repoint in the dataframe.
|
|
87
|
+
repoint_df_start_time = repoint_df["repoint_start_time"].values[0]
|
|
88
|
+
if np.any(query_met_times < repoint_df_start_time):
|
|
89
|
+
bad_times = query_met_times[query_met_times < repoint_df_start_time]
|
|
90
|
+
raise ValueError(
|
|
91
|
+
f"{bad_times.size} query times are before the first repoint start "
|
|
92
|
+
f" time in the repoint table. {bad_times=}, {repoint_df_start_time=}"
|
|
93
|
+
)
|
|
94
|
+
# Make sure that no query times are after the valid range of the dataframe.
|
|
95
|
+
# We approximate the end time of the table by adding 24 hours to the last
|
|
96
|
+
# known repoint start time.
|
|
97
|
+
repoint_df_end_time = repoint_df["repoint_start_time"].values[-1] + 24 * 60 * 60
|
|
98
|
+
if np.any(query_met_times >= repoint_df_end_time):
|
|
99
|
+
bad_times = query_met_times[query_met_times >= repoint_df_end_time]
|
|
100
|
+
raise ValueError(
|
|
101
|
+
f"{bad_times.size} query times are after the valid time of the "
|
|
102
|
+
f"pointing table. The valid end time is 24-hours after the last "
|
|
103
|
+
f"repoint_start_time. {bad_times=}, {repoint_df_end_time=}"
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# Find the row index for each queried MET time such that:
|
|
107
|
+
# repoint_start_time[i] <= MET < repoint_start_time[i+1]
|
|
108
|
+
row_indices = (
|
|
109
|
+
np.searchsorted(repoint_df["repoint_start_time"], query_met_times, side="right")
|
|
110
|
+
- 1
|
|
111
|
+
)
|
|
112
|
+
out_df = repoint_df.iloc[row_indices]
|
|
113
|
+
|
|
114
|
+
# Add a column indicating if the query time is during a repoint or not.
|
|
115
|
+
# The table already has the correct row for each query time, so we
|
|
116
|
+
# only need to check if the query time is less than the repoint end time to
|
|
117
|
+
# get the same result as `repoint_start_time <= query_met_times < repoint_end_time`.
|
|
118
|
+
out_df["repoint_in_progress"] = query_met_times < out_df["repoint_end_time"].values
|
|
119
|
+
|
|
120
|
+
return out_df
|
|
@@ -509,6 +509,10 @@ def process_swapi_science(
|
|
|
509
509
|
# since we are not processing in real-time, the ground processing
|
|
510
510
|
# algorithm should use the closest timestamp HK packet to fill in
|
|
511
511
|
# the data quality for the SCI data per SWAPI team.
|
|
512
|
+
|
|
513
|
+
# Drop duplicate epoch values in HK data. Otherwise, the nearest
|
|
514
|
+
# method will not work as expected because .sel requires unique values.
|
|
515
|
+
hk_dataset = hk_dataset.drop_duplicates("epoch")
|
|
512
516
|
good_sweep_times = good_sweep_sci["epoch"].data
|
|
513
517
|
good_sweep_hk_data = hk_dataset.sel({"epoch": good_sweep_times}, method="nearest")
|
|
514
518
|
|
|
@@ -62,7 +62,6 @@ def swapi_l2(l1_dataset: xr.Dataset, data_version: str) -> xr.Dataset:
|
|
|
62
62
|
# Update L2 specific attributes
|
|
63
63
|
l2_dataset.attrs["Data_version"] = data_version
|
|
64
64
|
l2_global_attrs = cdf_manager.get_global_attributes("imap_swapi_l2_sci")
|
|
65
|
-
l2_dataset.attrs["Data_level"] = l2_global_attrs["Data_level"]
|
|
66
65
|
l2_dataset.attrs["Data_type"] = l2_global_attrs["Data_type"]
|
|
67
66
|
l2_dataset.attrs["Logical_source"] = l2_global_attrs["Logical_source"]
|
|
68
67
|
l2_dataset.attrs["Logical_source_description"] = l2_global_attrs[
|
|
@@ -5,6 +5,7 @@ import logging
|
|
|
5
5
|
import xarray as xr
|
|
6
6
|
|
|
7
7
|
from imap_processing import imap_module_directory
|
|
8
|
+
from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
|
|
8
9
|
from imap_processing.swe.l1a.swe_science import swe_science
|
|
9
10
|
from imap_processing.swe.utils.swe_utils import (
|
|
10
11
|
SWEAPID,
|
|
@@ -42,12 +43,50 @@ def swe_l1a(packet_file: str, data_version: str) -> xr.Dataset:
|
|
|
42
43
|
packet_file, xtce_document, use_derived_value=False
|
|
43
44
|
)
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
46
|
+
processed_data = []
|
|
47
|
+
|
|
48
|
+
if SWEAPID.SWE_SCIENCE in datasets_by_apid:
|
|
49
|
+
logger.info("Processing SWE science data.")
|
|
50
|
+
processed_data.append(
|
|
51
|
+
swe_science(
|
|
52
|
+
l0_dataset=datasets_by_apid[SWEAPID.SWE_SCIENCE],
|
|
53
|
+
data_version=data_version,
|
|
54
|
+
)
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# Process non-science data
|
|
58
|
+
# Define minimal CDF attrs for the non science dataset
|
|
59
|
+
imap_attrs = ImapCdfAttributes()
|
|
60
|
+
imap_attrs.add_instrument_global_attrs("swe")
|
|
61
|
+
imap_attrs.add_global_attribute("Data_version", data_version)
|
|
62
|
+
imap_attrs.add_instrument_variable_attrs("swe", "l1a")
|
|
63
|
+
non_science_attrs = imap_attrs.get_variable_attributes("non_science_attrs")
|
|
64
|
+
epoch_attrs = imap_attrs.get_variable_attributes("epoch", check_schema=False)
|
|
65
|
+
|
|
66
|
+
if SWEAPID.SWE_APP_HK in datasets_by_apid:
|
|
67
|
+
logger.info("Processing SWE housekeeping data.")
|
|
68
|
+
hk_ds = datasets_by_apid[SWEAPID.SWE_APP_HK]
|
|
69
|
+
hk_ds.attrs.update(imap_attrs.get_global_attributes("imap_swe_l1a_hk"))
|
|
70
|
+
hk_ds["epoch"].attrs.update(epoch_attrs)
|
|
71
|
+
# Add attrs to HK data variables
|
|
72
|
+
for var_name in hk_ds.data_vars:
|
|
73
|
+
hk_ds[var_name].attrs.update(non_science_attrs)
|
|
74
|
+
processed_data.append(hk_ds)
|
|
75
|
+
|
|
76
|
+
if SWEAPID.SWE_CEM_RAW in datasets_by_apid:
|
|
77
|
+
logger.info("Processing SWE CEM raw data.")
|
|
78
|
+
cem_raw_ds = datasets_by_apid[SWEAPID.SWE_CEM_RAW]
|
|
79
|
+
cem_raw_ds.attrs.update(
|
|
80
|
+
imap_attrs.get_global_attributes("imap_swe_l1a_cem-raw")
|
|
52
81
|
)
|
|
53
|
-
|
|
82
|
+
cem_raw_ds["epoch"].attrs.update(epoch_attrs)
|
|
83
|
+
|
|
84
|
+
# Add attrs to CEM raw data variables
|
|
85
|
+
for var_name in cem_raw_ds.data_vars:
|
|
86
|
+
cem_raw_ds[var_name].attrs.update(non_science_attrs)
|
|
87
|
+
processed_data.append(cem_raw_ds)
|
|
88
|
+
|
|
89
|
+
if len(processed_data) == 0:
|
|
90
|
+
logger.info("Data contains unknown APID.")
|
|
91
|
+
|
|
92
|
+
return processed_data
|
|
@@ -6,6 +6,7 @@ import numpy as np
|
|
|
6
6
|
import xarray as xr
|
|
7
7
|
|
|
8
8
|
from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
|
|
9
|
+
from imap_processing.swe.utils import swe_constants
|
|
9
10
|
from imap_processing.swe.utils.swe_utils import SWEAPID
|
|
10
11
|
|
|
11
12
|
logger = logging.getLogger(__name__)
|
|
@@ -119,7 +120,9 @@ def swe_science(l0_dataset: xr.Dataset, data_version: str) -> xr.Dataset:
|
|
|
119
120
|
# 4. Reshape the data to 180 x 7
|
|
120
121
|
raw_science_array = np.array(
|
|
121
122
|
[
|
|
122
|
-
np.frombuffer(binary_string, dtype=np.uint8).reshape(
|
|
123
|
+
np.frombuffer(binary_string, dtype=np.uint8).reshape(
|
|
124
|
+
180, swe_constants.N_CEMS
|
|
125
|
+
)
|
|
123
126
|
for binary_string in l0_dataset["science_data"].values
|
|
124
127
|
]
|
|
125
128
|
)
|
|
@@ -157,7 +160,7 @@ def swe_science(l0_dataset: xr.Dataset, data_version: str) -> xr.Dataset:
|
|
|
157
160
|
)
|
|
158
161
|
|
|
159
162
|
cem_id = xr.DataArray(
|
|
160
|
-
np.arange(
|
|
163
|
+
np.arange(swe_constants.N_CEMS),
|
|
161
164
|
name="cem_id",
|
|
162
165
|
dims=["cem_id"],
|
|
163
166
|
attrs=cdf_attrs.get_variable_attributes("cem_id"),
|