imap-processing 0.6.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.
- imap_processing/__init__.py +34 -0
- imap_processing/_version.py +3 -0
- imap_processing/ccsds/__init__.py +0 -0
- imap_processing/ccsds/ccsds_data.py +55 -0
- imap_processing/ccsds/excel_to_xtce.py +477 -0
- imap_processing/cdf/__init__.py +0 -0
- imap_processing/cdf/cdf_attribute_manager.py +322 -0
- imap_processing/cdf/config/imap_codice_global_cdf_attrs.yaml +212 -0
- imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +1358 -0
- imap_processing/cdf/config/imap_codice_l1b_variable_attrs.yaml +391 -0
- imap_processing/cdf/config/imap_constant_attrs.yaml +33 -0
- imap_processing/cdf/config/imap_default_global_cdf_attrs.yaml +17 -0
- imap_processing/cdf/config/imap_glows_global_cdf_attrs.yaml +41 -0
- imap_processing/cdf/config/imap_glows_l1a_variable_attrs.yaml +499 -0
- imap_processing/cdf/config/imap_glows_l1b_variable_attrs.yaml +334 -0
- imap_processing/cdf/config/imap_hi_global_cdf_attrs.yaml +51 -0
- imap_processing/cdf/config/imap_hi_variable_attrs.yaml +435 -0
- imap_processing/cdf/config/imap_hit_global_cdf_attrs.yaml +27 -0
- imap_processing/cdf/config/imap_hit_l1a_variable_attrs.yaml +493 -0
- imap_processing/cdf/config/imap_hit_l1b_variable_attrs.yaml +564 -0
- imap_processing/cdf/config/imap_idex_global_cdf_attrs.yaml +24 -0
- imap_processing/cdf/config/imap_idex_l1a_variable_attrs.yaml +426 -0
- imap_processing/cdf/config/imap_lo_global_cdf_attrs.yaml +90 -0
- imap_processing/cdf/config/imap_lo_l1a_variable_attrs.yaml +487 -0
- imap_processing/cdf/config/imap_lo_l1b_variable_attrs.yaml +121 -0
- imap_processing/cdf/config/imap_lo_l1c_variable_attrs.yaml +179 -0
- imap_processing/cdf/config/imap_mag_global_cdf_attrs.yaml +97 -0
- imap_processing/cdf/config/imap_mag_l1_variable_attrs.yaml +201 -0
- imap_processing/cdf/config/imap_swapi_global_cdf_attrs.yaml +33 -0
- imap_processing/cdf/config/imap_swapi_variable_attrs.yaml +137 -0
- imap_processing/cdf/config/imap_swe_global_cdf_attrs.yaml +24 -0
- imap_processing/cdf/config/imap_swe_l1a_variable_attrs.yaml +234 -0
- imap_processing/cdf/config/imap_swe_l1b_variable_attrs.yaml +273 -0
- imap_processing/cdf/config/imap_ultra_global_cdf_attrs.yaml +100 -0
- imap_processing/cdf/config/imap_ultra_l1a_variable_attrs.yaml +52 -0
- imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +297 -0
- imap_processing/cdf/config/imap_ultra_l1c_variable_attrs.yaml +121 -0
- imap_processing/cdf/config/shared/default_global_cdf_attrs_schema.yaml +246 -0
- imap_processing/cdf/config/shared/default_variable_cdf_attrs_schema.yaml +466 -0
- imap_processing/cdf/imap_cdf_manager.py +64 -0
- imap_processing/cdf/utils.py +147 -0
- imap_processing/cli.py +863 -0
- imap_processing/codice/__init__.py +1 -0
- imap_processing/codice/codice_l0.py +54 -0
- imap_processing/codice/codice_l1a.py +558 -0
- imap_processing/codice/codice_l1b.py +194 -0
- imap_processing/codice/constants.py +986 -0
- imap_processing/codice/data/esa_sweep_values.csv +257 -0
- imap_processing/codice/data/lo_stepping_values.csv +129 -0
- imap_processing/codice/decompress.py +142 -0
- imap_processing/codice/packet_definitions/P_COD_NHK.xml +618 -0
- imap_processing/codice/packet_definitions/codice_packet_definition.xml +5073 -0
- imap_processing/codice/utils.py +95 -0
- imap_processing/decom.py +40 -0
- imap_processing/glows/__init__.py +1 -0
- imap_processing/glows/ancillary/l1b_conversion_table_v001.json +42 -0
- imap_processing/glows/l0/__init__.py +0 -0
- imap_processing/glows/l0/decom_glows.py +91 -0
- imap_processing/glows/l0/glows_l0_data.py +194 -0
- imap_processing/glows/l1a/glows_l1a.py +424 -0
- imap_processing/glows/l1a/glows_l1a_data.py +555 -0
- imap_processing/glows/l1b/glows_l1b.py +270 -0
- imap_processing/glows/l1b/glows_l1b_data.py +583 -0
- imap_processing/glows/packet_definitions/GLX_COMBINED.xml +254 -0
- imap_processing/glows/packet_definitions/P_GLX_TMSCDE.xml +97 -0
- imap_processing/glows/packet_definitions/P_GLX_TMSCHIST.xml +215 -0
- imap_processing/glows/utils/__init__.py +0 -0
- imap_processing/glows/utils/constants.py +105 -0
- imap_processing/hi/__init__.py +1 -0
- imap_processing/hi/l0/__init__.py +0 -0
- imap_processing/hi/l0/decom_hi.py +24 -0
- imap_processing/hi/l1a/__init__.py +0 -0
- imap_processing/hi/l1a/hi_l1a.py +73 -0
- imap_processing/hi/l1a/histogram.py +142 -0
- imap_processing/hi/l1a/housekeeping.py +27 -0
- imap_processing/hi/l1a/science_direct_event.py +341 -0
- imap_processing/hi/l1b/__init__.py +0 -0
- imap_processing/hi/l1b/hi_eng_unit_convert_table.csv +154 -0
- imap_processing/hi/l1b/hi_l1b.py +127 -0
- imap_processing/hi/l1c/__init__.py +0 -0
- imap_processing/hi/l1c/hi_l1c.py +228 -0
- imap_processing/hi/packet_definitions/__init__.py +0 -0
- imap_processing/hi/packet_definitions/hi_packet_definition.xml +482 -0
- imap_processing/hi/utils.py +27 -0
- imap_processing/hit/__init__.py +1 -0
- imap_processing/hit/l0/__init__.py +0 -0
- imap_processing/hit/l0/data_classes/housekeeping.py +240 -0
- imap_processing/hit/l0/data_classes/science_packet.py +259 -0
- imap_processing/hit/l0/decom_hit.py +467 -0
- imap_processing/hit/l0/utils/hit_base.py +57 -0
- imap_processing/hit/l1a/__init__.py +0 -0
- imap_processing/hit/l1a/hit_l1a.py +254 -0
- imap_processing/hit/l1b/hit_l1b.py +179 -0
- imap_processing/hit/packet_definitions/hit_packet_definitions.xml +1276 -0
- imap_processing/ialirt/__init__.py +0 -0
- imap_processing/ialirt/l0/__init__.py +0 -0
- imap_processing/ialirt/l0/process_hit.py +220 -0
- imap_processing/ialirt/packet_definitions/__init__.py +0 -0
- imap_processing/ialirt/packet_definitions/ialirt.xml +778 -0
- imap_processing/ialirt/packet_definitions/ialirt_hit.xml +186 -0
- imap_processing/idex/__init__.py +2 -0
- imap_processing/idex/idex_constants.py +27 -0
- imap_processing/idex/idex_l0.py +31 -0
- imap_processing/idex/idex_l1a.py +631 -0
- imap_processing/idex/packet_definitions/idex_packet_definition.xml +3162 -0
- imap_processing/lo/__init__.py +1 -0
- imap_processing/lo/l0/__init__.py +0 -0
- imap_processing/lo/l0/data_classes/science_direct_events.py +215 -0
- imap_processing/lo/l0/data_classes/star_sensor.py +98 -0
- imap_processing/lo/l0/decompression_tables/12_to_16_bit.csv +4097 -0
- imap_processing/lo/l0/decompression_tables/8_to_12_bit.csv +257 -0
- imap_processing/lo/l0/decompression_tables/8_to_16_bit.csv +257 -0
- imap_processing/lo/l0/decompression_tables/decompression_tables.py +75 -0
- imap_processing/lo/l0/lo_apid.py +15 -0
- imap_processing/lo/l0/lo_science.py +150 -0
- imap_processing/lo/l0/utils/binary_string.py +59 -0
- imap_processing/lo/l0/utils/bit_decompression.py +62 -0
- imap_processing/lo/l0/utils/lo_base.py +57 -0
- imap_processing/lo/l1a/__init__.py +0 -0
- imap_processing/lo/l1a/lo_l1a.py +157 -0
- imap_processing/lo/l1b/lo_l1b.py +160 -0
- imap_processing/lo/l1c/lo_l1c.py +180 -0
- imap_processing/lo/packet_definitions/lo_xtce.xml +3541 -0
- imap_processing/mag/__init__.py +2 -0
- imap_processing/mag/constants.py +108 -0
- imap_processing/mag/l0/decom_mag.py +170 -0
- imap_processing/mag/l0/mag_l0_data.py +118 -0
- imap_processing/mag/l1a/mag_l1a.py +317 -0
- imap_processing/mag/l1a/mag_l1a_data.py +1007 -0
- imap_processing/mag/l1b/__init__.py +0 -0
- imap_processing/mag/l1b/imap_calibration_mag_20240229_v01.cdf +0 -0
- imap_processing/mag/l1b/mag_l1b.py +125 -0
- imap_processing/mag/l1c/mag_l1c.py +57 -0
- imap_processing/mag/packet_definitions/MAG_SCI_COMBINED.xml +235 -0
- imap_processing/quality_flags.py +91 -0
- imap_processing/spice/__init__.py +1 -0
- imap_processing/spice/geometry.py +322 -0
- imap_processing/spice/kernels.py +459 -0
- imap_processing/spice/time.py +72 -0
- imap_processing/swapi/__init__.py +1 -0
- imap_processing/swapi/l1/__init__.py +0 -0
- imap_processing/swapi/l1/swapi_l1.py +685 -0
- imap_processing/swapi/l2/__init__.py +0 -0
- imap_processing/swapi/l2/swapi_l2.py +107 -0
- imap_processing/swapi/packet_definitions/__init__.py +0 -0
- imap_processing/swapi/packet_definitions/swapi_packet_definition.xml +708 -0
- imap_processing/swapi/swapi_utils.py +25 -0
- imap_processing/swe/__init__.py +1 -0
- imap_processing/swe/l1a/__init__.py +0 -0
- imap_processing/swe/l1a/swe_l1a.py +48 -0
- imap_processing/swe/l1a/swe_science.py +223 -0
- imap_processing/swe/l1b/engineering_unit_convert_table.csv +65 -0
- imap_processing/swe/l1b/swe_esa_lookup_table.csv +1441 -0
- imap_processing/swe/l1b/swe_l1b.py +49 -0
- imap_processing/swe/l1b/swe_l1b_science.py +557 -0
- imap_processing/swe/packet_definitions/__init__.py +0 -0
- imap_processing/swe/packet_definitions/swe_packet_definition.xml +303 -0
- imap_processing/swe/utils/__init__.py +0 -0
- imap_processing/swe/utils/swe_utils.py +9 -0
- imap_processing/tests/__init__.py +0 -0
- imap_processing/tests/ccsds/test_data/expected_output.xml +171 -0
- imap_processing/tests/ccsds/test_excel_to_xtce.py +285 -0
- imap_processing/tests/cdf/__init__.py +0 -0
- imap_processing/tests/cdf/imap_default_global_cdf_attrs.yaml +8 -0
- imap_processing/tests/cdf/shared/default_global_cdf_attrs_schema.yaml +246 -0
- imap_processing/tests/cdf/shared/default_variable_cdf_attrs_schema.yaml +466 -0
- imap_processing/tests/cdf/test_cdf_attribute_manager.py +353 -0
- imap_processing/tests/cdf/test_data/imap_default_global_test_cdf_attrs.yaml +7 -0
- imap_processing/tests/cdf/test_data/imap_instrument1_global_cdf_attrs.yaml +14 -0
- imap_processing/tests/cdf/test_data/imap_instrument1_level1_variable_attrs.yaml +23 -0
- imap_processing/tests/cdf/test_data/imap_instrument2_global_cdf_attrs.yaml +23 -0
- imap_processing/tests/cdf/test_data/imap_instrument2_level2_variable_attrs.yaml +30 -0
- imap_processing/tests/cdf/test_data/imap_test_global.yaml +26 -0
- imap_processing/tests/cdf/test_data/imap_test_variable.yaml +41 -0
- imap_processing/tests/cdf/test_imap_cdf_manager.py +62 -0
- imap_processing/tests/cdf/test_utils.py +109 -0
- imap_processing/tests/codice/__init__.py +0 -0
- imap_processing/tests/codice/conftest.py +56 -0
- imap_processing/tests/codice/data/eu_unit_lookup_table.csv +101 -0
- imap_processing/tests/codice/data/idle_export_eu.COD_NHK_20230822_122700 2.csv +100 -0
- imap_processing/tests/codice/data/idle_export_raw.COD_NHK_20230822_122700.csv +100 -0
- imap_processing/tests/codice/data/imap_codice_l0_hi-counters-aggregated_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_hi-counters-singles_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_hi-omni_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_hi-pha_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_hi-sectored_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_hskp_20100101_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_lo-counters-aggregated_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_lo-counters-singles_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_lo-nsw-angular_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_lo-nsw-priority_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_lo-nsw-species_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_lo-pha_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_lo-sw-angular_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_lo-sw-priority_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_lo-sw-species_20240429_v001.pkts +0 -0
- 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/codice/test_codice_l0.py +144 -0
- imap_processing/tests/codice/test_codice_l1a.py +187 -0
- imap_processing/tests/codice/test_codice_l1b.py +60 -0
- imap_processing/tests/codice/test_decompress.py +50 -0
- imap_processing/tests/conftest.py +372 -0
- imap_processing/tests/glows/direct_events_validation_data_l1a.csv +5704 -0
- imap_processing/tests/glows/glows_test_packet_20110921_v01.pkts +0 -0
- imap_processing/tests/glows/test_glows_decom.py +133 -0
- imap_processing/tests/glows/test_glows_l1a_cdf.py +85 -0
- imap_processing/tests/glows/test_glows_l1a_data.py +510 -0
- imap_processing/tests/glows/test_glows_l1b.py +348 -0
- imap_processing/tests/glows/test_glows_l1b_data.py +70 -0
- imap_processing/tests/hi/__init__.py +0 -0
- imap_processing/tests/hi/conftest.py +133 -0
- imap_processing/tests/hi/test_data/l0/20231030_H45_APP_NHK.bin +0 -0
- imap_processing/tests/hi/test_data/l0/20231030_H45_APP_NHK.csv +201 -0
- imap_processing/tests/hi/test_data/l0/20231030_H45_SCI_CNT.bin +0 -0
- imap_processing/tests/hi/test_data/l0/20231030_H45_SCI_DE.bin +0 -0
- imap_processing/tests/hi/test_data/l0/README.txt +54 -0
- imap_processing/tests/hi/test_decom.py +55 -0
- imap_processing/tests/hi/test_hi_l1b.py +31 -0
- imap_processing/tests/hi/test_hi_l1c.py +69 -0
- imap_processing/tests/hi/test_l1a.py +96 -0
- imap_processing/tests/hi/test_l1a_sci_de.py +72 -0
- imap_processing/tests/hi/test_utils.py +15 -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/__init__.py +0 -0
- imap_processing/tests/hit/test_data/imap_hit_l0_hk_20100105_v001.pkts +0 -0
- imap_processing/tests/hit/test_data/sci_sample.ccsds +0 -0
- imap_processing/tests/hit/test_hit_decom.py +230 -0
- imap_processing/tests/hit/test_hit_l1a.py +224 -0
- imap_processing/tests/hit/test_hit_l1b.py +52 -0
- imap_processing/tests/hit/validation_data/hskp_sample_raw.csv +88 -0
- imap_processing/tests/ialirt/__init__.py +0 -0
- imap_processing/tests/ialirt/test_data/l0/IALiRT Raw Packet Telemetry.txt +33 -0
- imap_processing/tests/ialirt/test_data/l0/hit_ialirt_sample.ccsds +0 -0
- imap_processing/tests/ialirt/test_data/l0/hit_ialirt_sample.csv +1001 -0
- imap_processing/tests/ialirt/unit/__init__.py +0 -0
- imap_processing/tests/ialirt/unit/test_decom_ialirt.py +94 -0
- imap_processing/tests/ialirt/unit/test_process_hit.py +226 -0
- imap_processing/tests/idex/__init__.py +0 -0
- imap_processing/tests/idex/conftest.py +22 -0
- imap_processing/tests/idex/imap_idex_l0_raw_20230725_v001.pkts +0 -0
- imap_processing/tests/idex/impact_14_tof_high_data.txt +8189 -0
- imap_processing/tests/idex/test_idex_l0.py +45 -0
- imap_processing/tests/idex/test_idex_l1a.py +91 -0
- imap_processing/tests/lo/__init__.py +0 -0
- imap_processing/tests/lo/test_binary_string.py +21 -0
- imap_processing/tests/lo/test_bit_decompression.py +39 -0
- imap_processing/tests/lo/test_cdfs/imap_lo_l0_raw_20240627_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/lo/test_cdfs/imap_lo_l1b_de_20100101_v001.cdf +0 -0
- imap_processing/tests/lo/test_lo_l1a.py +66 -0
- imap_processing/tests/lo/test_lo_l1b.py +74 -0
- imap_processing/tests/lo/test_lo_l1c.py +66 -0
- imap_processing/tests/lo/test_science_counts.py +41 -0
- imap_processing/tests/lo/test_science_direct_events.py +209 -0
- imap_processing/tests/lo/test_star_sensor.py +35 -0
- imap_processing/tests/mag/imap_mag_l1a_burst-magi_20231025_v001.cdf +0 -0
- imap_processing/tests/mag/mag_l0_test_data.pkts +0 -0
- imap_processing/tests/mag/mag_l0_test_output.csv +37 -0
- imap_processing/tests/mag/mag_l1_test_data.pkts +0 -0
- imap_processing/tests/mag/mag_l1a_test_output.csv +97 -0
- imap_processing/tests/mag/test_mag_decom.py +117 -0
- imap_processing/tests/mag/test_mag_l1a.py +856 -0
- imap_processing/tests/mag/test_mag_l1b.py +77 -0
- imap_processing/tests/mag/test_mag_l1c.py +40 -0
- imap_processing/tests/spice/__init__.py +0 -0
- imap_processing/tests/spice/test_data/imap_ena_sim_metakernel.template +4 -0
- imap_processing/tests/spice/test_data/imap_science_0001.tf +171 -0
- imap_processing/tests/spice/test_data/imap_sclk_0000.tsc +156 -0
- imap_processing/tests/spice/test_data/imap_sim_ck_2hr_2secsampling_with_nutation.bc +0 -0
- imap_processing/tests/spice/test_data/imap_simple_metakernel.template +3 -0
- imap_processing/tests/spice/test_data/imap_spk_demo.bsp +0 -0
- imap_processing/tests/spice/test_data/imap_wkcp.tf +1806 -0
- imap_processing/tests/spice/test_data/naif0012.tls +150 -0
- imap_processing/tests/spice/test_data/sim_1yr_imap_attitude.bc +0 -0
- imap_processing/tests/spice/test_data/sim_1yr_imap_pointing_frame.bc +0 -0
- imap_processing/tests/spice/test_geometry.py +214 -0
- imap_processing/tests/spice/test_kernels.py +272 -0
- imap_processing/tests/spice/test_time.py +35 -0
- imap_processing/tests/swapi/__init__.py +0 -0
- imap_processing/tests/swapi/conftest.py +16 -0
- imap_processing/tests/swapi/l0_data/__init__.py +0 -0
- imap_processing/tests/swapi/l0_data/imap_swapi_l0_raw_20231012_v001.pkts +0 -0
- imap_processing/tests/swapi/l0_validation_data/__init__.py +0 -0
- imap_processing/tests/swapi/l0_validation_data/idle_export_eu.SWP_AUT_20231012_125245.csv +124 -0
- imap_processing/tests/swapi/l0_validation_data/idle_export_eu.SWP_HK_20231012_125245.csv +98 -0
- imap_processing/tests/swapi/l0_validation_data/idle_export_eu.SWP_MG_20231012_125245.csv +9 -0
- imap_processing/tests/swapi/l0_validation_data/idle_export_eu.SWP_SCI_20231012_125245.csv +72 -0
- imap_processing/tests/swapi/l0_validation_data/idle_export_raw.SWP_AUT_20231012_125245.csv +124 -0
- imap_processing/tests/swapi/l0_validation_data/idle_export_raw.SWP_HK_20231012_125245.csv +98 -0
- imap_processing/tests/swapi/l0_validation_data/idle_export_raw.SWP_MG_20231012_125245.csv +9 -0
- imap_processing/tests/swapi/l0_validation_data/idle_export_raw.SWP_SCI_20231012_125245.csv +72 -0
- imap_processing/tests/swapi/test_swapi_decom.py +135 -0
- imap_processing/tests/swapi/test_swapi_l1.py +354 -0
- imap_processing/tests/swapi/test_swapi_l2.py +21 -0
- imap_processing/tests/swe/__init__.py +0 -0
- imap_processing/tests/swe/conftest.py +35 -0
- imap_processing/tests/swe/decompressed/20230927173238_4th_quarter_decompressed.csv +181 -0
- imap_processing/tests/swe/decompressed/20230927173253_1st_quarter_decompressed.csv +181 -0
- imap_processing/tests/swe/decompressed/20230927173308_2nd_quarter_decompressed.csv +181 -0
- imap_processing/tests/swe/decompressed/20230927173323_3rd_quarter_decompressed.csv +181 -0
- imap_processing/tests/swe/l0_data/2024051010_SWE_SCIENCE_packet.bin +0 -0
- imap_processing/tests/swe/l0_validation_data/idle_export_eu.SWE_SCIENCE_20240510_092742.csv +544 -0
- imap_processing/tests/swe/l0_validation_data/idle_export_raw.SWE_SCIENCE_20240510_092742.csv +363 -0
- imap_processing/tests/swe/test_swe_l1a.py +12 -0
- imap_processing/tests/swe/test_swe_l1a_science.py +129 -0
- imap_processing/tests/swe/test_swe_l1b.py +61 -0
- imap_processing/tests/swe/test_swe_l1b_science.py +65 -0
- imap_processing/tests/test_cli.py +229 -0
- imap_processing/tests/test_decom.py +66 -0
- imap_processing/tests/test_quality_flags.py +71 -0
- imap_processing/tests/test_utils.py +107 -0
- imap_processing/tests/ultra/__init__.py +0 -0
- imap_processing/tests/ultra/test_data/l0/FM45_40P_Phi28p5_BeamCal_LinearScan_phi28.50_theta-0.00_20240207T102740.CCSDS +0 -0
- imap_processing/tests/ultra/test_data/l0/FM45_7P_Phi0.0_BeamCal_LinearScan_phi0.04_theta-0.01_20230821T121304.CCSDS +0 -0
- imap_processing/tests/ultra/test_data/l0/FM45_TV_Cycle6_Hot_Ops_Front212_20240124T063837.CCSDS +0 -0
- imap_processing/tests/ultra/test_data/l0/Ultra45_EM_SwRI_Cal_Run7_ThetaScan_20220530T225054.CCSDS +0 -0
- imap_processing/tests/ultra/test_data/l0/ultra45_raw_sc_auxdata_Ultra45_EM_SwRI_Cal_Run7_ThetaScan_20220530T225054.csv +24 -0
- imap_processing/tests/ultra/test_data/l0/ultra45_raw_sc_enaphxtofhangimg_FM45_TV_Cycle6_Hot_Ops_Front212_20240124T063837.csv +105 -0
- imap_processing/tests/ultra/test_data/l0/ultra45_raw_sc_ultraimgrates_Ultra45_EM_SwRI_Cal_Run7_ThetaScan_20220530T225054.csv +24 -0
- imap_processing/tests/ultra/test_data/l0/ultra45_raw_sc_ultrarawimg_withFSWcalcs_FM45_40P_Phi28p5_BeamCal_LinearScan_phi2850_theta-000_20240207T102740.csv +3314 -0
- imap_processing/tests/ultra/test_data/l0/ultra45_raw_sc_ultrarawimgevent_FM45_7P_Phi00_BeamCal_LinearScan_phi004_theta-001_20230821T121304.csv +702 -0
- imap_processing/tests/ultra/unit/__init__.py +0 -0
- imap_processing/tests/ultra/unit/conftest.py +210 -0
- imap_processing/tests/ultra/unit/test_decom_apid_880.py +98 -0
- imap_processing/tests/ultra/unit/test_decom_apid_881.py +50 -0
- imap_processing/tests/ultra/unit/test_decom_apid_883.py +44 -0
- imap_processing/tests/ultra/unit/test_decom_apid_896.py +104 -0
- imap_processing/tests/ultra/unit/test_lookup_utils.py +68 -0
- imap_processing/tests/ultra/unit/test_ultra_l1a.py +338 -0
- imap_processing/tests/ultra/unit/test_ultra_l1b.py +122 -0
- imap_processing/tests/ultra/unit/test_ultra_l1b_annotated.py +57 -0
- imap_processing/tests/ultra/unit/test_ultra_l1b_extended.py +342 -0
- imap_processing/tests/ultra/unit/test_ultra_l1c.py +104 -0
- imap_processing/tests/ultra/unit/test_ultra_l1c_pset_bins.py +35 -0
- imap_processing/ultra/__init__.py +1 -0
- imap_processing/ultra/constants.py +60 -0
- imap_processing/ultra/l0/__init__.py +0 -0
- imap_processing/ultra/l0/decom_tools.py +281 -0
- imap_processing/ultra/l0/decom_ultra.py +278 -0
- imap_processing/ultra/l0/ultra_utils.py +326 -0
- imap_processing/ultra/l1a/__init__.py +0 -0
- imap_processing/ultra/l1a/ultra_l1a.py +319 -0
- imap_processing/ultra/l1b/badtimes.py +26 -0
- imap_processing/ultra/l1b/cullingmask.py +26 -0
- imap_processing/ultra/l1b/de.py +59 -0
- imap_processing/ultra/l1b/extendedspin.py +45 -0
- imap_processing/ultra/l1b/lookup_utils.py +165 -0
- imap_processing/ultra/l1b/ultra_l1b.py +65 -0
- imap_processing/ultra/l1b/ultra_l1b_annotated.py +54 -0
- imap_processing/ultra/l1b/ultra_l1b_extended.py +764 -0
- imap_processing/ultra/l1c/histogram.py +36 -0
- imap_processing/ultra/l1c/pset.py +36 -0
- imap_processing/ultra/l1c/ultra_l1c.py +52 -0
- imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +54 -0
- imap_processing/ultra/lookup_tables/EgyNorm.mem.csv +32769 -0
- imap_processing/ultra/lookup_tables/FM45_Startup1_ULTRA_IMGPARAMS_20240719.csv +2 -0
- imap_processing/ultra/lookup_tables/ultra45_back-pos-luts.csv +4097 -0
- imap_processing/ultra/lookup_tables/ultra45_tdc_norm.csv +2050 -0
- imap_processing/ultra/lookup_tables/ultra90_back-pos-luts.csv +4097 -0
- imap_processing/ultra/lookup_tables/ultra90_tdc_norm.csv +2050 -0
- imap_processing/ultra/lookup_tables/yadjust.csv +257 -0
- imap_processing/ultra/packet_definitions/ULTRA_SCI_COMBINED.xml +547 -0
- imap_processing/ultra/packet_definitions/__init__.py +0 -0
- imap_processing/ultra/utils/__init__.py +0 -0
- imap_processing/ultra/utils/ultra_l1_utils.py +50 -0
- imap_processing/utils.py +413 -0
- imap_processing-0.6.0.dist-info/LICENSE +21 -0
- imap_processing-0.6.0.dist-info/METADATA +107 -0
- imap_processing-0.6.0.dist-info/RECORD +398 -0
- imap_processing-0.6.0.dist-info/WHEEL +4 -0
- imap_processing-0.6.0.dist-info/entry_points.txt +4 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
"""Ultra Decompression Tools."""
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import numpy.typing as npt
|
|
5
|
+
import space_packet_parser
|
|
6
|
+
|
|
7
|
+
from imap_processing.ultra.l0.ultra_utils import (
|
|
8
|
+
EVENT_FIELD_RANGES,
|
|
9
|
+
append_fillval,
|
|
10
|
+
parse_event,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def read_and_advance(
|
|
15
|
+
binary_data: str, n: int, current_position: int
|
|
16
|
+
) -> tuple[int, int]:
|
|
17
|
+
"""
|
|
18
|
+
Extract the specified number of bits from a binary string.
|
|
19
|
+
|
|
20
|
+
Starting from the current position, it reads n bits. This is used twice.
|
|
21
|
+
The first time it reads the first 5 bits to determine the width.
|
|
22
|
+
The second time it uses the width to determine the value of the bitstring.
|
|
23
|
+
|
|
24
|
+
Parameters
|
|
25
|
+
----------
|
|
26
|
+
binary_data : str
|
|
27
|
+
The string of binary data from which bits will be read.
|
|
28
|
+
This is a string of 0's and 1's.
|
|
29
|
+
n : int
|
|
30
|
+
Number of bits to read from the binary string.
|
|
31
|
+
current_position : int
|
|
32
|
+
The starting position in the binary string from which bits will be read.
|
|
33
|
+
|
|
34
|
+
Returns
|
|
35
|
+
-------
|
|
36
|
+
value : int
|
|
37
|
+
The integer representation of the read bits or None if the end of the
|
|
38
|
+
string is reached before reading 'n' bits.
|
|
39
|
+
current_position + n
|
|
40
|
+
- The updated position in the binary string after reading the bits.
|
|
41
|
+
"""
|
|
42
|
+
# Ensure we don't read past the end
|
|
43
|
+
if current_position + n > len(binary_data):
|
|
44
|
+
raise IndexError(
|
|
45
|
+
f"Attempted to read past the end of binary string. "
|
|
46
|
+
f"Current position: {current_position}, "
|
|
47
|
+
f"Requested bits: {n}, String length: {len(binary_data)}"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
value = int(binary_data[current_position : current_position + n], 2)
|
|
51
|
+
return value, current_position + n
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def log_decompression(value: int, mantissa_bit_length: int) -> int:
|
|
55
|
+
"""
|
|
56
|
+
Perform logarithmic decompression on an integer.
|
|
57
|
+
|
|
58
|
+
Supports both 16-bit and 8-bit formats based on the specified
|
|
59
|
+
mantissa bit length.
|
|
60
|
+
|
|
61
|
+
Parameters
|
|
62
|
+
----------
|
|
63
|
+
value : int
|
|
64
|
+
An integer comprised of a 4-bit exponent followed by a variable-length mantissa.
|
|
65
|
+
mantissa_bit_length : int
|
|
66
|
+
The bit length of the mantissa (default is 12 for 16-bit format).
|
|
67
|
+
|
|
68
|
+
Returns
|
|
69
|
+
-------
|
|
70
|
+
int
|
|
71
|
+
The decompressed integer value.
|
|
72
|
+
"""
|
|
73
|
+
# Determine the base value and mask based on mantissa bit length
|
|
74
|
+
if mantissa_bit_length == 12:
|
|
75
|
+
base_value = 4096
|
|
76
|
+
mantissa_mask = 0xFFF
|
|
77
|
+
elif mantissa_bit_length == 4:
|
|
78
|
+
base_value = 16
|
|
79
|
+
mantissa_mask = 0x0F
|
|
80
|
+
else:
|
|
81
|
+
raise ValueError("Unsupported mantissa bit length")
|
|
82
|
+
|
|
83
|
+
# Extract the exponent and mantissa
|
|
84
|
+
e = value >> mantissa_bit_length # Extract the exponent
|
|
85
|
+
m = value & mantissa_mask # Extract the mantissa
|
|
86
|
+
|
|
87
|
+
if e == 0:
|
|
88
|
+
return m
|
|
89
|
+
else:
|
|
90
|
+
return (base_value + m) << (e - 1)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def decompress_binary(
|
|
94
|
+
binary: str, width_bit: int, block: int, array_length: int, mantissa_bit_length: int
|
|
95
|
+
) -> list:
|
|
96
|
+
"""
|
|
97
|
+
Will decompress a binary string.
|
|
98
|
+
|
|
99
|
+
Decompress a binary string based on block-width encoding and
|
|
100
|
+
logarithmic compression.
|
|
101
|
+
|
|
102
|
+
This function interprets a binary string where the value of 'width_bits'
|
|
103
|
+
specifies the width of the following bits. Each value is then extracted and
|
|
104
|
+
subjected to logarithmic decompression.
|
|
105
|
+
|
|
106
|
+
Parameters
|
|
107
|
+
----------
|
|
108
|
+
binary : str
|
|
109
|
+
A binary string containing the compressed data.
|
|
110
|
+
width_bit : int
|
|
111
|
+
The bit width that describes the width of data in the block.
|
|
112
|
+
block : int
|
|
113
|
+
Number of values in each block.
|
|
114
|
+
array_length : int
|
|
115
|
+
The length of the array to be decompressed.
|
|
116
|
+
mantissa_bit_length : int
|
|
117
|
+
The bit length of the mantissa.
|
|
118
|
+
|
|
119
|
+
Returns
|
|
120
|
+
-------
|
|
121
|
+
list
|
|
122
|
+
A list of decompressed values.
|
|
123
|
+
|
|
124
|
+
Notes
|
|
125
|
+
-----
|
|
126
|
+
Equations from Section 1.2.1.1 Data Compression and Decompression Algorithms
|
|
127
|
+
in Ultra_algorithm_doc_rev2.pdf.
|
|
128
|
+
"""
|
|
129
|
+
current_position = 0
|
|
130
|
+
decompressed_values: list = []
|
|
131
|
+
|
|
132
|
+
while current_position < len(binary):
|
|
133
|
+
# Read the width of the block
|
|
134
|
+
width, current_position = read_and_advance(binary, width_bit, current_position)
|
|
135
|
+
# If width is 0 or None, we don't have enough bits left
|
|
136
|
+
if width is None or len(decompressed_values) >= array_length:
|
|
137
|
+
break
|
|
138
|
+
|
|
139
|
+
# For each block, read 16 values of the given width
|
|
140
|
+
for _ in range(block):
|
|
141
|
+
# Ensure there are enough bits left to read the width
|
|
142
|
+
if len(binary) - current_position < width:
|
|
143
|
+
break
|
|
144
|
+
|
|
145
|
+
value, current_position = read_and_advance(binary, width, current_position)
|
|
146
|
+
|
|
147
|
+
# Log decompression
|
|
148
|
+
decompressed_values.append(log_decompression(value, mantissa_bit_length))
|
|
149
|
+
|
|
150
|
+
return decompressed_values
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def decompress_image(
|
|
154
|
+
pixel0: int,
|
|
155
|
+
binary_data: str,
|
|
156
|
+
width_bit: int,
|
|
157
|
+
mantissa_bit_length: int,
|
|
158
|
+
) -> npt.NDArray:
|
|
159
|
+
"""
|
|
160
|
+
Will decompress a binary string representing an image into a matrix of pixel values.
|
|
161
|
+
|
|
162
|
+
It starts with an initial pixel value and decompresses the rest of the image using
|
|
163
|
+
block-wise decompression and logarithmic decompression based on provided bit widths
|
|
164
|
+
and lengths.
|
|
165
|
+
|
|
166
|
+
Parameters
|
|
167
|
+
----------
|
|
168
|
+
pixel0 : int
|
|
169
|
+
The first, unmodified pixel p0,0.
|
|
170
|
+
binary_data : str
|
|
171
|
+
Binary string.
|
|
172
|
+
width_bit : int
|
|
173
|
+
The bit width that describes the width of data in the block.
|
|
174
|
+
mantissa_bit_length : int
|
|
175
|
+
The bit length of the mantissa.
|
|
176
|
+
|
|
177
|
+
Returns
|
|
178
|
+
-------
|
|
179
|
+
p_decom : numpy.ndarray
|
|
180
|
+
A 2D numpy array representing pixel values.
|
|
181
|
+
Each pixel is stored as an unsigned 16-bit integer (uint16).
|
|
182
|
+
|
|
183
|
+
Notes
|
|
184
|
+
-----
|
|
185
|
+
This process is described starting on page 168 in IMAP-Ultra Flight
|
|
186
|
+
Software Specification document (7523-9009_Rev_-.pdf).
|
|
187
|
+
"""
|
|
188
|
+
rows = 54
|
|
189
|
+
cols = 180
|
|
190
|
+
pixels_per_block = 15
|
|
191
|
+
|
|
192
|
+
blocks_per_row = cols // pixels_per_block
|
|
193
|
+
|
|
194
|
+
# Compressed pixel matrix
|
|
195
|
+
p = np.zeros((rows, cols), dtype=np.uint16)
|
|
196
|
+
# Decompressed pixel matrix
|
|
197
|
+
p_decom = np.zeros((rows, cols), dtype=np.int16)
|
|
198
|
+
|
|
199
|
+
pos = 0 # Starting position in the binary string
|
|
200
|
+
|
|
201
|
+
for i in range(rows):
|
|
202
|
+
for j in range(blocks_per_row):
|
|
203
|
+
# Read the width for the block.
|
|
204
|
+
w, pos = read_and_advance(binary_data, width_bit, pos)
|
|
205
|
+
for k in range(pixels_per_block):
|
|
206
|
+
# Handle the special case in which the width is 0
|
|
207
|
+
if w == 0:
|
|
208
|
+
value = 0
|
|
209
|
+
else:
|
|
210
|
+
# Find the value of each pixel in the block
|
|
211
|
+
value, pos = read_and_advance(binary_data, w, pos)
|
|
212
|
+
|
|
213
|
+
# if the least significant bit of value is set (odd)
|
|
214
|
+
if value & 0x01:
|
|
215
|
+
# value >> 1: shifts bits of value one place to the right
|
|
216
|
+
# ~: bitwise NOT operator (flips bits)
|
|
217
|
+
delta_f = ~(value >> 1)
|
|
218
|
+
else:
|
|
219
|
+
delta_f = value >> 1
|
|
220
|
+
|
|
221
|
+
# Calculate the new pixel value and update pixel0
|
|
222
|
+
column_index = j * pixels_per_block + k
|
|
223
|
+
# 0xff is the hexadecimal representation of the number 255,
|
|
224
|
+
# Keeps only the last 8 bits of the result of pixel0 - delta_f
|
|
225
|
+
# This operation ensures that the result is within the range
|
|
226
|
+
# of an 8-bit byte (0-255)
|
|
227
|
+
# Use np.int16 for the arithmetic operation to avoid overflow
|
|
228
|
+
# Then implicitly cast back to the p's uint16 dtype for storage
|
|
229
|
+
p[i][column_index] = np.int16(pixel0) - delta_f
|
|
230
|
+
# Perform logarithmic decompression on the pixel value
|
|
231
|
+
p_decom[i][column_index] = log_decompression(
|
|
232
|
+
p[i][column_index], mantissa_bit_length
|
|
233
|
+
)
|
|
234
|
+
pixel0 = p[i][column_index]
|
|
235
|
+
pixel0 = p[i][0]
|
|
236
|
+
|
|
237
|
+
return p_decom
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def read_image_raw_events_binary(
|
|
241
|
+
packet: space_packet_parser.parser.Packet, decom_data: dict
|
|
242
|
+
) -> dict:
|
|
243
|
+
"""
|
|
244
|
+
Convert contents of binary string 'EVENTDATA' into values.
|
|
245
|
+
|
|
246
|
+
Parameters
|
|
247
|
+
----------
|
|
248
|
+
packet : space_packet_parser.parser.Packet
|
|
249
|
+
Packet.
|
|
250
|
+
decom_data : dict
|
|
251
|
+
Parsed data.
|
|
252
|
+
|
|
253
|
+
Returns
|
|
254
|
+
-------
|
|
255
|
+
decom_data : dict
|
|
256
|
+
Each for loop appends to the existing dictionary.
|
|
257
|
+
"""
|
|
258
|
+
binary = packet.data["EVENTDATA"].raw_value
|
|
259
|
+
count = packet.data["COUNT"].derived_value
|
|
260
|
+
# 166 bits per event
|
|
261
|
+
event_length = 166 if count else 0
|
|
262
|
+
|
|
263
|
+
# Uses fill value for all packets that do not contain event data.
|
|
264
|
+
if count == 0:
|
|
265
|
+
# if decom_data is empty, append fill values to all fields
|
|
266
|
+
if not decom_data:
|
|
267
|
+
for field in EVENT_FIELD_RANGES.keys():
|
|
268
|
+
decom_data[field] = []
|
|
269
|
+
append_fillval(decom_data, packet)
|
|
270
|
+
|
|
271
|
+
# For all packets with event data, parses the binary string
|
|
272
|
+
else:
|
|
273
|
+
for i in range(count):
|
|
274
|
+
start_index = i * event_length
|
|
275
|
+
event_binary = binary[start_index : start_index + event_length]
|
|
276
|
+
event_data = parse_event(event_binary)
|
|
277
|
+
|
|
278
|
+
for key, value in event_data.items():
|
|
279
|
+
decom_data[key].append(value)
|
|
280
|
+
|
|
281
|
+
return decom_data
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"""Decommutates Ultra CCSDS packets."""
|
|
2
|
+
|
|
3
|
+
import collections
|
|
4
|
+
import logging
|
|
5
|
+
from collections import defaultdict
|
|
6
|
+
from typing import Any, Union
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
from space_packet_parser.parser import Packet
|
|
10
|
+
|
|
11
|
+
from imap_processing.ccsds.ccsds_data import CcsdsData
|
|
12
|
+
from imap_processing.ultra.l0.decom_tools import (
|
|
13
|
+
decompress_binary,
|
|
14
|
+
decompress_image,
|
|
15
|
+
read_image_raw_events_binary,
|
|
16
|
+
)
|
|
17
|
+
from imap_processing.ultra.l0.ultra_utils import (
|
|
18
|
+
RATES_KEYS,
|
|
19
|
+
ULTRA_AUX,
|
|
20
|
+
ULTRA_EVENTS,
|
|
21
|
+
ULTRA_RATES,
|
|
22
|
+
ULTRA_TOF,
|
|
23
|
+
append_ccsds_fields,
|
|
24
|
+
)
|
|
25
|
+
from imap_processing.utils import sort_by_time
|
|
26
|
+
|
|
27
|
+
logging.basicConfig(level=logging.INFO)
|
|
28
|
+
logger = logging.getLogger(__name__)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def append_tof_params(
|
|
32
|
+
decom_data: dict,
|
|
33
|
+
packet: Packet,
|
|
34
|
+
decompressed_data: np.ndarray,
|
|
35
|
+
data_dict: dict,
|
|
36
|
+
stacked_dict: dict,
|
|
37
|
+
) -> None:
|
|
38
|
+
"""
|
|
39
|
+
Append parsed items to a dictionary, including decompressed data if available.
|
|
40
|
+
|
|
41
|
+
Parameters
|
|
42
|
+
----------
|
|
43
|
+
decom_data : dict
|
|
44
|
+
Dictionary to which the data is appended.
|
|
45
|
+
packet : space_packet_parser.parser.Packet
|
|
46
|
+
Individual packet.
|
|
47
|
+
decompressed_data : list
|
|
48
|
+
Data that has been decompressed.
|
|
49
|
+
data_dict : dict
|
|
50
|
+
Dictionary used for stacking in SID dimension.
|
|
51
|
+
stacked_dict : dict
|
|
52
|
+
Dictionary used for stacking in time dimension.
|
|
53
|
+
"""
|
|
54
|
+
# TODO: add error handling to make certain every timestamp has 8 SID values
|
|
55
|
+
|
|
56
|
+
for key in packet.data.keys():
|
|
57
|
+
# Keep appending packet data until SID = 7
|
|
58
|
+
if key == "PACKETDATA":
|
|
59
|
+
data_dict[key].append(decompressed_data)
|
|
60
|
+
# Keep appending all other data until SID = 7
|
|
61
|
+
else:
|
|
62
|
+
data_dict[key].append(packet.data[key].derived_value)
|
|
63
|
+
|
|
64
|
+
# Append CCSDS fields to the dictionary
|
|
65
|
+
ccsds_data = CcsdsData(packet.header)
|
|
66
|
+
append_ccsds_fields(data_dict, ccsds_data)
|
|
67
|
+
|
|
68
|
+
# Once "SID" reaches 7, we have all the images and data for the single timestamp
|
|
69
|
+
if packet.data["SID"].derived_value == 7:
|
|
70
|
+
decom_data["SHCOARSE"].extend(list(set(data_dict["SHCOARSE"])))
|
|
71
|
+
data_dict["SHCOARSE"].clear()
|
|
72
|
+
|
|
73
|
+
for key in packet.data.keys():
|
|
74
|
+
if key != "SHCOARSE":
|
|
75
|
+
stacked_dict[key].append(np.stack(data_dict[key]))
|
|
76
|
+
data_dict[key].clear()
|
|
77
|
+
for key in packet.header.keys():
|
|
78
|
+
stacked_dict[key].append(np.stack(data_dict[key]))
|
|
79
|
+
data_dict[key].clear()
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def append_params(decom_data: dict, packet: Packet) -> None:
|
|
83
|
+
# Todo Update what packet type is.
|
|
84
|
+
"""
|
|
85
|
+
Append parsed items to a dictionary, including decompressed data if available.
|
|
86
|
+
|
|
87
|
+
Parameters
|
|
88
|
+
----------
|
|
89
|
+
decom_data : dict
|
|
90
|
+
Dictionary to which the data is appended.
|
|
91
|
+
packet : space_packet_parser.parser.Packet
|
|
92
|
+
Individual packet.
|
|
93
|
+
"""
|
|
94
|
+
for key, item in packet.data.items():
|
|
95
|
+
decom_data[key].append(item.derived_value)
|
|
96
|
+
|
|
97
|
+
ccsds_data = CcsdsData(packet.header)
|
|
98
|
+
append_ccsds_fields(decom_data, ccsds_data)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def process_ultra_apids(data: list, apid: int) -> Union[dict[Any, Any], bool]:
|
|
102
|
+
"""
|
|
103
|
+
Unpack and decode Ultra packets using CCSDS format and XTCE packet definitions.
|
|
104
|
+
|
|
105
|
+
Parameters
|
|
106
|
+
----------
|
|
107
|
+
data : list
|
|
108
|
+
Grouped data.
|
|
109
|
+
apid : int
|
|
110
|
+
The APID to process.
|
|
111
|
+
|
|
112
|
+
Returns
|
|
113
|
+
-------
|
|
114
|
+
decom_data : dict
|
|
115
|
+
A dictionary containing the decoded data.
|
|
116
|
+
"""
|
|
117
|
+
# Strategy dict maps APIDs to their respective processing functions
|
|
118
|
+
strategy_dict = {
|
|
119
|
+
ULTRA_TOF.apid[0]: process_ultra_tof,
|
|
120
|
+
ULTRA_EVENTS.apid[0]: process_ultra_events,
|
|
121
|
+
ULTRA_AUX.apid[0]: process_ultra_aux,
|
|
122
|
+
ULTRA_RATES.apid[0]: process_ultra_rates,
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
sorted_packets = sort_by_time(data, "SHCOARSE")
|
|
126
|
+
|
|
127
|
+
process_function = strategy_dict.get(apid, lambda *args: False)
|
|
128
|
+
decom_data = process_function(sorted_packets, defaultdict(list))
|
|
129
|
+
|
|
130
|
+
return decom_data
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def process_ultra_tof(
|
|
134
|
+
sorted_packets: list, decom_data: collections.defaultdict
|
|
135
|
+
) -> dict:
|
|
136
|
+
"""
|
|
137
|
+
Unpack and decode Ultra TOF packets.
|
|
138
|
+
|
|
139
|
+
Parameters
|
|
140
|
+
----------
|
|
141
|
+
sorted_packets : list
|
|
142
|
+
TOF packets sorted by time.
|
|
143
|
+
decom_data : collections.defaultdict
|
|
144
|
+
Empty dictionary.
|
|
145
|
+
|
|
146
|
+
Returns
|
|
147
|
+
-------
|
|
148
|
+
decom_data : dict
|
|
149
|
+
A dictionary containing the decoded data.
|
|
150
|
+
"""
|
|
151
|
+
stacked_dict: dict = defaultdict(list)
|
|
152
|
+
data_dict: dict = defaultdict(list)
|
|
153
|
+
|
|
154
|
+
# For TOF we need to sort by time and then SID
|
|
155
|
+
sorted_packets = sorted(
|
|
156
|
+
sorted_packets,
|
|
157
|
+
key=lambda x: (x.data["SHCOARSE"].raw_value, x.data["SID"].raw_value),
|
|
158
|
+
)
|
|
159
|
+
if isinstance(ULTRA_TOF.mantissa_bit_length, int) and isinstance(
|
|
160
|
+
ULTRA_TOF.width, int
|
|
161
|
+
):
|
|
162
|
+
for packet in sorted_packets:
|
|
163
|
+
# Decompress the image data
|
|
164
|
+
decompressed_data = decompress_image(
|
|
165
|
+
packet.data["P00"].derived_value,
|
|
166
|
+
packet.data["PACKETDATA"].raw_value,
|
|
167
|
+
ULTRA_TOF.width,
|
|
168
|
+
ULTRA_TOF.mantissa_bit_length,
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
# Append the decompressed data and other derived data
|
|
172
|
+
# to the dictionary
|
|
173
|
+
append_tof_params(
|
|
174
|
+
decom_data,
|
|
175
|
+
packet,
|
|
176
|
+
decompressed_data=decompressed_data,
|
|
177
|
+
data_dict=data_dict,
|
|
178
|
+
stacked_dict=stacked_dict,
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
# Stack the data to create required dimensions
|
|
182
|
+
for key in stacked_dict.keys():
|
|
183
|
+
decom_data[key] = np.stack(stacked_dict[key])
|
|
184
|
+
|
|
185
|
+
return decom_data
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def process_ultra_events(sorted_packets: list, decom_data: dict) -> dict:
|
|
189
|
+
"""
|
|
190
|
+
Unpack and decode Ultra EVENTS packets.
|
|
191
|
+
|
|
192
|
+
Parameters
|
|
193
|
+
----------
|
|
194
|
+
sorted_packets : list
|
|
195
|
+
EVENTS packets sorted by time.
|
|
196
|
+
decom_data : collections.defaultdict
|
|
197
|
+
Empty dictionary.
|
|
198
|
+
|
|
199
|
+
Returns
|
|
200
|
+
-------
|
|
201
|
+
decom_data : dict
|
|
202
|
+
A dictionary containing the decoded data.
|
|
203
|
+
"""
|
|
204
|
+
for packet in sorted_packets:
|
|
205
|
+
# Here there are multiple images in a single packet,
|
|
206
|
+
# so we need to loop through each image and decompress it.
|
|
207
|
+
decom_data = read_image_raw_events_binary(packet, decom_data)
|
|
208
|
+
count = packet.data["COUNT"].derived_value
|
|
209
|
+
|
|
210
|
+
if count == 0:
|
|
211
|
+
append_params(decom_data, packet)
|
|
212
|
+
else:
|
|
213
|
+
for i in range(count):
|
|
214
|
+
logging.info(f"Appending image #{i}")
|
|
215
|
+
append_params(decom_data, packet)
|
|
216
|
+
|
|
217
|
+
return decom_data
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def process_ultra_aux(sorted_packets: list, decom_data: dict) -> dict:
|
|
221
|
+
"""
|
|
222
|
+
Unpack and decode Ultra AUX packets.
|
|
223
|
+
|
|
224
|
+
Parameters
|
|
225
|
+
----------
|
|
226
|
+
sorted_packets : list
|
|
227
|
+
AUX packets sorted by time.
|
|
228
|
+
decom_data : collections.defaultdict
|
|
229
|
+
Empty dictionary.
|
|
230
|
+
|
|
231
|
+
Returns
|
|
232
|
+
-------
|
|
233
|
+
decom_data : dict
|
|
234
|
+
A dictionary containing the decoded data.
|
|
235
|
+
"""
|
|
236
|
+
for packet in sorted_packets:
|
|
237
|
+
append_params(decom_data, packet)
|
|
238
|
+
|
|
239
|
+
return decom_data
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def process_ultra_rates(sorted_packets: list, decom_data: dict) -> dict:
|
|
243
|
+
"""
|
|
244
|
+
Unpack and decode Ultra RATES packets.
|
|
245
|
+
|
|
246
|
+
Parameters
|
|
247
|
+
----------
|
|
248
|
+
sorted_packets : list
|
|
249
|
+
RATES packets sorted by time.
|
|
250
|
+
decom_data : collections.defaultdict
|
|
251
|
+
Empty dictionary.
|
|
252
|
+
|
|
253
|
+
Returns
|
|
254
|
+
-------
|
|
255
|
+
decom_data : dict
|
|
256
|
+
A dictionary containing the decoded data.
|
|
257
|
+
"""
|
|
258
|
+
if (
|
|
259
|
+
isinstance(ULTRA_RATES.mantissa_bit_length, int)
|
|
260
|
+
and isinstance(ULTRA_RATES.len_array, int)
|
|
261
|
+
and isinstance(ULTRA_RATES.block, int)
|
|
262
|
+
and isinstance(ULTRA_RATES.width, int)
|
|
263
|
+
):
|
|
264
|
+
for packet in sorted_packets:
|
|
265
|
+
decompressed_data = decompress_binary(
|
|
266
|
+
packet.data["FASTDATA_00"].raw_value,
|
|
267
|
+
ULTRA_RATES.width,
|
|
268
|
+
ULTRA_RATES.block,
|
|
269
|
+
ULTRA_RATES.len_array,
|
|
270
|
+
ULTRA_RATES.mantissa_bit_length,
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
for index in range(ULTRA_RATES.len_array):
|
|
274
|
+
decom_data[RATES_KEYS[index]].append(decompressed_data[index])
|
|
275
|
+
|
|
276
|
+
append_params(decom_data, packet)
|
|
277
|
+
|
|
278
|
+
return decom_data
|