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,467 @@
|
|
|
1
|
+
"""Decommutate HIT CCSDS science data."""
|
|
2
|
+
|
|
3
|
+
from collections import namedtuple
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
import xarray as xr
|
|
7
|
+
|
|
8
|
+
# TODO: Consider moving global values into a config file
|
|
9
|
+
|
|
10
|
+
# Structure to hold binary details for a
|
|
11
|
+
# section of science data. Used to unpack
|
|
12
|
+
# binary data.
|
|
13
|
+
HITPacking = namedtuple(
|
|
14
|
+
"HITPacking",
|
|
15
|
+
[
|
|
16
|
+
"bit_length",
|
|
17
|
+
"section_length",
|
|
18
|
+
"shape",
|
|
19
|
+
],
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
# Define data structure for counts rates data
|
|
23
|
+
COUNTS_DATA_STRUCTURE = {
|
|
24
|
+
# field: bit_length, section_length, shape
|
|
25
|
+
# ------------------------------------------
|
|
26
|
+
# science frame header
|
|
27
|
+
"hdr_unit_num": HITPacking(2, 2, (1,)),
|
|
28
|
+
"hdr_frame_version": HITPacking(6, 6, (1,)),
|
|
29
|
+
"hdr_status_bits": HITPacking(8, 8, (1,)),
|
|
30
|
+
"hdr_minute_cnt": HITPacking(8, 8, (1,)),
|
|
31
|
+
# ------------------------------------------
|
|
32
|
+
# spare bits. Contains no data
|
|
33
|
+
"spare": HITPacking(24, 24, (1,)),
|
|
34
|
+
# ------------------------------------------
|
|
35
|
+
# erates - contains livetime counters
|
|
36
|
+
"livetime": HITPacking(16, 16, (1,)), # livetime counter
|
|
37
|
+
"num_trig": HITPacking(16, 16, (1,)), # number of triggers
|
|
38
|
+
"num_reject": HITPacking(16, 16, (1,)), # number of rejected events
|
|
39
|
+
"num_acc_w_pha": HITPacking(
|
|
40
|
+
16, 16, (1,)
|
|
41
|
+
), # number of accepted events with PHA data
|
|
42
|
+
"num_acc_no_pha": HITPacking(16, 16, (1,)), # number of events without PHA data
|
|
43
|
+
"num_haz_trig": HITPacking(16, 16, (1,)), # number of triggers with hazard flag
|
|
44
|
+
"num_haz_reject": HITPacking(
|
|
45
|
+
16, 16, (1,)
|
|
46
|
+
), # number of rejected events with hazard flag
|
|
47
|
+
"num_haz_acc_w_pha": HITPacking(
|
|
48
|
+
16, 16, (1,)
|
|
49
|
+
), # number of accepted hazard events with PHA data
|
|
50
|
+
"num_haz_acc_no_pha": HITPacking(
|
|
51
|
+
16, 16, (1,)
|
|
52
|
+
), # number of hazard events without PHA data
|
|
53
|
+
# -------------------------------------------
|
|
54
|
+
"sngrates": HITPacking(16, 1856, (2, 58)), # single rates
|
|
55
|
+
# -------------------------------------------
|
|
56
|
+
# evprates - contains event processing rates
|
|
57
|
+
"nread": HITPacking(16, 16, (1,)), # events read from event fifo
|
|
58
|
+
"nhazard": HITPacking(16, 16, (1,)), # events tagged with hazard flag
|
|
59
|
+
"nadcstim": HITPacking(16, 16, (1,)), # adc-stim events
|
|
60
|
+
"nodd": HITPacking(16, 16, (1,)), # odd events
|
|
61
|
+
"noddfix": HITPacking(16, 16, (1,)), # odd events that were fixed in sw
|
|
62
|
+
"nmulti": HITPacking(
|
|
63
|
+
16, 16, (1,)
|
|
64
|
+
), # events with multiple hits in a single detector
|
|
65
|
+
"nmultifix": HITPacking(16, 16, (1,)), # multi events that were fixed in sw
|
|
66
|
+
"nbadtraj": HITPacking(16, 16, (1,)), # bad trajectory
|
|
67
|
+
"nl2": HITPacking(16, 16, (1,)), # events sorted into L12 event category
|
|
68
|
+
"nl3": HITPacking(16, 16, (1,)), # events sorted into L123 event category
|
|
69
|
+
"nl4": HITPacking(16, 16, (1,)), # events sorted into L1423 event category
|
|
70
|
+
"npen": HITPacking(16, 16, (1,)), # events sorted into penetrating event category
|
|
71
|
+
"nformat": HITPacking(16, 16, (1,)), # nothing currently goes in this slot
|
|
72
|
+
"naside": HITPacking(16, 16, (1,)), # A-side events
|
|
73
|
+
"nbside": HITPacking(16, 16, (1,)), # B-side events
|
|
74
|
+
"nerror": HITPacking(16, 16, (1,)), # events that caused a processing error
|
|
75
|
+
"nbadtags": HITPacking(
|
|
76
|
+
16, 16, (1,)
|
|
77
|
+
), # events with inconsistent tags vs pulse heights
|
|
78
|
+
# -------------------------------------------
|
|
79
|
+
# other count rates
|
|
80
|
+
"coinrates": HITPacking(16, 416, (26,)), # coincidence rates
|
|
81
|
+
"bufrates": HITPacking(16, 512, (32,)), # priority buffer rates
|
|
82
|
+
"l2fgrates": HITPacking(16, 2112, (132,)), # range 2 foreground rates
|
|
83
|
+
"l2bgrates": HITPacking(16, 192, (12,)), # range 2 background rates
|
|
84
|
+
"l3fgrates": HITPacking(16, 2672, (167,)), # range 3 foreground rates
|
|
85
|
+
"l3bgrates": HITPacking(16, 192, (12,)), # range 3 background rates
|
|
86
|
+
"penfgrates": HITPacking(16, 528, (33,)), # range 4 foreground rates
|
|
87
|
+
"penbgrates": HITPacking(16, 240, (15,)), # range 4 background rates
|
|
88
|
+
"ialirtrates": HITPacking(16, 320, (20,)), # ialirt rates
|
|
89
|
+
"sectorates": HITPacking(16, 1920, (120,)), # sectored rates
|
|
90
|
+
"l4fgrates": HITPacking(16, 768, (48,)), # all range foreground rates
|
|
91
|
+
"l4bgrates": HITPacking(16, 384, (24,)), # all range foreground rates
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
# Define data structure for pulse height event data
|
|
95
|
+
PHA_DATA_STRUCTURE = {
|
|
96
|
+
# field: bit_length, section_length, shape
|
|
97
|
+
"pha_records": HITPacking(2, 29344, (917,)),
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
# Define the pattern of grouping flags in a complete science frame.
|
|
101
|
+
FLAG_PATTERN = np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2])
|
|
102
|
+
|
|
103
|
+
# Define size of science frame (num of packets)
|
|
104
|
+
FRAME_SIZE = len(FLAG_PATTERN)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def parse_data(bin_str: str, bits_per_index: int, start: int, end: int) -> list:
|
|
108
|
+
"""
|
|
109
|
+
Parse binary data.
|
|
110
|
+
|
|
111
|
+
Parameters
|
|
112
|
+
----------
|
|
113
|
+
bin_str : str
|
|
114
|
+
Binary string to be unpacked.
|
|
115
|
+
bits_per_index : int
|
|
116
|
+
Number of bits per index of the data section.
|
|
117
|
+
start : int
|
|
118
|
+
Starting index for slicing the binary string.
|
|
119
|
+
end : int
|
|
120
|
+
Ending index for slicing the binary string.
|
|
121
|
+
|
|
122
|
+
Returns
|
|
123
|
+
-------
|
|
124
|
+
parsed_data : list
|
|
125
|
+
Integers parsed from the binary string.
|
|
126
|
+
"""
|
|
127
|
+
parsed_data = [
|
|
128
|
+
int(bin_str[i : i + bits_per_index], 2)
|
|
129
|
+
for i in range(start, end, bits_per_index)
|
|
130
|
+
]
|
|
131
|
+
return parsed_data
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def parse_count_rates(sci_dataset: xr.Dataset) -> None:
|
|
135
|
+
"""
|
|
136
|
+
Parse binary count rates data and update dataset.
|
|
137
|
+
|
|
138
|
+
This function parses the binary count rates data,
|
|
139
|
+
stored as count_rates_binary in the dataset,
|
|
140
|
+
according to data structure details provided in
|
|
141
|
+
COUNTS_DATA_STRUCTURE. The parsed data, representing
|
|
142
|
+
integers, is added to the dataset as new data
|
|
143
|
+
fields.
|
|
144
|
+
|
|
145
|
+
Note: count_rates_binary is added to the dataset by
|
|
146
|
+
the assemble_science_frames function, which organizes
|
|
147
|
+
the binary science data packets by science frames.
|
|
148
|
+
|
|
149
|
+
Parameters
|
|
150
|
+
----------
|
|
151
|
+
sci_dataset : xr.Dataset
|
|
152
|
+
Xarray dataset containing HIT science packets
|
|
153
|
+
from a CCSDS file.
|
|
154
|
+
"""
|
|
155
|
+
counts_binary = sci_dataset.count_rates_binary
|
|
156
|
+
# initialize the starting bit for the sections of data
|
|
157
|
+
section_start = 0
|
|
158
|
+
# Decommutate binary data for each counts data field
|
|
159
|
+
for field, field_meta in COUNTS_DATA_STRUCTURE.items():
|
|
160
|
+
section_end = section_start + field_meta.section_length
|
|
161
|
+
bits_per_index = field_meta.bit_length
|
|
162
|
+
parsed_data = [
|
|
163
|
+
parse_data(bin_str, bits_per_index, section_start, section_end)
|
|
164
|
+
for bin_str in counts_binary.values
|
|
165
|
+
]
|
|
166
|
+
if field_meta.shape[0] == 1:
|
|
167
|
+
# flatten data into a 1D array
|
|
168
|
+
parsed_data = list(np.array(parsed_data).flat)
|
|
169
|
+
|
|
170
|
+
if field == "sngrates":
|
|
171
|
+
# Split into high and low gain arrays
|
|
172
|
+
for i, data in enumerate(parsed_data):
|
|
173
|
+
high_gain = data[::2] # Items at even indices 0, 2, 4, etc.
|
|
174
|
+
low_gain = data[1::2] # Items at odd indices 1, 3, 5, etc.
|
|
175
|
+
parsed_data[i] = [high_gain, low_gain]
|
|
176
|
+
|
|
177
|
+
# TODO
|
|
178
|
+
# - status bits needs to be further parsed (table 10 in algorithm doc)
|
|
179
|
+
# - subcommutate sectorates
|
|
180
|
+
# - decompress data
|
|
181
|
+
# - Follow up with HIT team about erates and evrates.
|
|
182
|
+
# (i.e.Should these be arrays containing all the sub fields
|
|
183
|
+
# or should each subfield be it's own data field/array)
|
|
184
|
+
|
|
185
|
+
# Get dims for data variables (yaml file not created yet)
|
|
186
|
+
if len(field_meta.shape) > 1:
|
|
187
|
+
dims = ["epoch", "gain", f"{field}_index"]
|
|
188
|
+
elif field_meta.shape[0] > 1:
|
|
189
|
+
dims = ["epoch", f"{field}_index"]
|
|
190
|
+
else:
|
|
191
|
+
dims = ["epoch"]
|
|
192
|
+
|
|
193
|
+
sci_dataset[field] = xr.DataArray(parsed_data, dims=dims, name=field)
|
|
194
|
+
# increment the start of the next section of data to parse
|
|
195
|
+
section_start += field_meta.section_length
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def is_sequential(counters: np.ndarray) -> np.bool_:
|
|
199
|
+
"""
|
|
200
|
+
Check if an array of packet sequence counters is sequential.
|
|
201
|
+
|
|
202
|
+
Parameters
|
|
203
|
+
----------
|
|
204
|
+
counters : np.ndarray
|
|
205
|
+
Array of packet sequence counters.
|
|
206
|
+
|
|
207
|
+
Returns
|
|
208
|
+
-------
|
|
209
|
+
bool
|
|
210
|
+
True if the sequence counters are sequential, False otherwise.
|
|
211
|
+
"""
|
|
212
|
+
return np.all(np.diff(counters) == 1)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def find_valid_starting_indices(flags: np.ndarray, counters: np.ndarray) -> np.ndarray:
|
|
216
|
+
"""
|
|
217
|
+
Find valid starting indices for science frames.
|
|
218
|
+
|
|
219
|
+
This function finds the starting indices of valid science frames.
|
|
220
|
+
A valid science frame has the following packet grouping flags:
|
|
221
|
+
|
|
222
|
+
First packet: 1
|
|
223
|
+
Next 18 packets: 0
|
|
224
|
+
Last packet: 2
|
|
225
|
+
|
|
226
|
+
The packet sequence counters for the identified science frames must
|
|
227
|
+
be sequential. Only the starting indices of valid science frames are
|
|
228
|
+
returned.
|
|
229
|
+
|
|
230
|
+
Parameters
|
|
231
|
+
----------
|
|
232
|
+
flags : np.ndarray
|
|
233
|
+
Array of packet grouping flags.
|
|
234
|
+
counters : np.ndarray
|
|
235
|
+
Array of packet sequence counters.
|
|
236
|
+
|
|
237
|
+
Returns
|
|
238
|
+
-------
|
|
239
|
+
valid_indices : np.ndarray
|
|
240
|
+
Array of valid indices for science frames.
|
|
241
|
+
"""
|
|
242
|
+
# TODO: consider combining functions to get valid indices to reduce
|
|
243
|
+
# code tracing
|
|
244
|
+
|
|
245
|
+
# Use sliding windows to compare segments of the array (20 packets) with the
|
|
246
|
+
# pattern. This generates an array of overlapping sub-arrays, each of length
|
|
247
|
+
# 20, from the flags array and is used to slide the "window" across the array
|
|
248
|
+
# and compare the sub-arrays with the predefined pattern.
|
|
249
|
+
windows = np.lib.stride_tricks.sliding_window_view(flags, FRAME_SIZE)
|
|
250
|
+
# Find where the windows match the pattern
|
|
251
|
+
matches = np.all(windows == FLAG_PATTERN, axis=1)
|
|
252
|
+
# Get the starting indices of matches
|
|
253
|
+
match_indices = np.where(matches)[0]
|
|
254
|
+
# Filter for only indices from valid science frames with sequential counters
|
|
255
|
+
valid_indices = get_valid_indices(match_indices, counters, FRAME_SIZE)
|
|
256
|
+
return valid_indices
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def get_valid_indices(
|
|
260
|
+
indices: np.ndarray, counters: np.ndarray, size: int
|
|
261
|
+
) -> np.ndarray:
|
|
262
|
+
"""
|
|
263
|
+
Get valid indices for science frames.
|
|
264
|
+
|
|
265
|
+
Check if the packet sequence counters for the science frames
|
|
266
|
+
are sequential. If they are, the science frame is valid and
|
|
267
|
+
an updated array of valid indices is returned.
|
|
268
|
+
|
|
269
|
+
Parameters
|
|
270
|
+
----------
|
|
271
|
+
indices : np.ndarray
|
|
272
|
+
Array of indices where the packet grouping flags match the pattern.
|
|
273
|
+
counters : np.ndarray
|
|
274
|
+
Array of packet sequence counters.
|
|
275
|
+
size : int
|
|
276
|
+
Size of science frame. 20 packets per science frame.
|
|
277
|
+
|
|
278
|
+
Returns
|
|
279
|
+
-------
|
|
280
|
+
valid_indices : np.ndarray
|
|
281
|
+
Array of valid indices for science frames.
|
|
282
|
+
"""
|
|
283
|
+
# Check if the packet sequence counters are sequential by getting an array
|
|
284
|
+
# of boolean values where True indicates the counters are sequential.
|
|
285
|
+
sequential_check = [is_sequential(counters[idx : idx + size]) for idx in indices]
|
|
286
|
+
return indices[sequential_check]
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
def update_ccsds_header_dims(sci_dataset: xr.Dataset) -> xr.Dataset:
|
|
290
|
+
"""
|
|
291
|
+
Update dimensions of CCSDS header fields.
|
|
292
|
+
|
|
293
|
+
The CCSDS header fields contain 1D arrays with
|
|
294
|
+
values from all the packets in the file.
|
|
295
|
+
While the epoch dimension contains time per packet,
|
|
296
|
+
it will be updated later in the process to represent
|
|
297
|
+
time per science frame, so another time dimension is
|
|
298
|
+
needed for the ccsds header fields.This function
|
|
299
|
+
updates the dimension for these fields to use sc_tick
|
|
300
|
+
instead of epoch. sc_tick is the time the packet was
|
|
301
|
+
created.
|
|
302
|
+
|
|
303
|
+
Parameters
|
|
304
|
+
----------
|
|
305
|
+
sci_dataset : xr.Dataset
|
|
306
|
+
Xarray dataset containing HIT science packets
|
|
307
|
+
from a CCSDS file.
|
|
308
|
+
|
|
309
|
+
Returns
|
|
310
|
+
-------
|
|
311
|
+
sci_dataset : xr.Dataset
|
|
312
|
+
Updated xarray dataset.
|
|
313
|
+
"""
|
|
314
|
+
# sc_tick contains spacecraft time per packet
|
|
315
|
+
sci_dataset.coords["sc_tick"] = sci_dataset["sc_tick"]
|
|
316
|
+
sci_dataset = sci_dataset.swap_dims({"epoch": "sc_tick"})
|
|
317
|
+
return sci_dataset
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
def assemble_science_frames(sci_dataset: xr.Dataset) -> xr.Dataset:
|
|
321
|
+
"""
|
|
322
|
+
Group packets into science frames.
|
|
323
|
+
|
|
324
|
+
HIT science frames (data from 1 minute) consist of 20 packets.
|
|
325
|
+
These are assembled from the binary science_data field in the
|
|
326
|
+
xarray dataset, which is a 1D array of science data from all
|
|
327
|
+
packets in the file, by using packet grouping flags.
|
|
328
|
+
|
|
329
|
+
The science frame is further categorized into
|
|
330
|
+
L1A data products -> count rates and event data.
|
|
331
|
+
|
|
332
|
+
The first six packets contain count rates data
|
|
333
|
+
The last 14 packets contain pulse height event data
|
|
334
|
+
|
|
335
|
+
These groups are added to the dataset as count_rates_binary
|
|
336
|
+
and pha_binary.
|
|
337
|
+
|
|
338
|
+
Parameters
|
|
339
|
+
----------
|
|
340
|
+
sci_dataset : xr.Dataset
|
|
341
|
+
Xarray Dataset for science data (APID 1252).
|
|
342
|
+
|
|
343
|
+
Returns
|
|
344
|
+
-------
|
|
345
|
+
sci_dataset : xr.Dataset
|
|
346
|
+
Updated xarray dataset with binary count rates and pulse
|
|
347
|
+
height event data per valid science frame added as new
|
|
348
|
+
data variables.
|
|
349
|
+
"""
|
|
350
|
+
# TODO: Figure out how to handle partial science frames at the
|
|
351
|
+
# beginning and end of CCSDS files. These science frames are split
|
|
352
|
+
# across CCSDS files and still need to be processed with packets
|
|
353
|
+
# from the previous file. Only discard incomplete science frames
|
|
354
|
+
# in the middle of the CCSDS file. The code currently skips all
|
|
355
|
+
# incomplete science frames.
|
|
356
|
+
|
|
357
|
+
# Convert sequence flags and counters to NumPy arrays for vectorized operations
|
|
358
|
+
seq_flgs = sci_dataset.seq_flgs.values
|
|
359
|
+
seq_ctrs = sci_dataset.src_seq_ctr.values
|
|
360
|
+
science_data = sci_dataset.science_data.values
|
|
361
|
+
epoch_data = sci_dataset.epoch.values
|
|
362
|
+
|
|
363
|
+
# Number of packets in the file
|
|
364
|
+
total_packets = len(epoch_data)
|
|
365
|
+
|
|
366
|
+
# Find starting indices for valid science frames
|
|
367
|
+
starting_indices = find_valid_starting_indices(seq_flgs, seq_ctrs)
|
|
368
|
+
|
|
369
|
+
# Check for extra packets at start and end of file
|
|
370
|
+
# TODO: Will need to handle these extra packets when processing multiple files
|
|
371
|
+
if starting_indices[0] != 0:
|
|
372
|
+
# The first science frame start index is not at the beginning of the file.
|
|
373
|
+
print(
|
|
374
|
+
f"{starting_indices[0]} packets at start of file belong to science frame "
|
|
375
|
+
f"from previous day's ccsds file"
|
|
376
|
+
)
|
|
377
|
+
last_index_of_last_frame = starting_indices[-1] + FRAME_SIZE
|
|
378
|
+
if last_index_of_last_frame:
|
|
379
|
+
remaining_packets = total_packets - last_index_of_last_frame
|
|
380
|
+
if 0 < remaining_packets < FRAME_SIZE:
|
|
381
|
+
print(
|
|
382
|
+
f"{remaining_packets} packets at end of file belong to science frame "
|
|
383
|
+
f"from next day's ccsds file"
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
# Extract data per science frame and organize by L1A data products
|
|
387
|
+
count_rates = []
|
|
388
|
+
pha = []
|
|
389
|
+
epoch_per_science_frame = np.array([])
|
|
390
|
+
for idx in starting_indices:
|
|
391
|
+
# Data from 20 packets in a science frame
|
|
392
|
+
science_data_frame = science_data[idx : idx + FRAME_SIZE]
|
|
393
|
+
# First 6 packets contain count rates data in binary
|
|
394
|
+
count_rates.append("".join(science_data_frame[:6]))
|
|
395
|
+
# Last 14 packets contain pulse height event data in binary
|
|
396
|
+
pha.append("".join(science_data_frame[6:]))
|
|
397
|
+
# Get first packet's epoch for the science frame
|
|
398
|
+
epoch_per_science_frame = np.append(epoch_per_science_frame, epoch_data[idx])
|
|
399
|
+
# TODO: Filter ccsds header fields to only include packets from the
|
|
400
|
+
# valid science frames. Doesn't need to be grouped by frames though
|
|
401
|
+
|
|
402
|
+
# Add new data variables to the dataset
|
|
403
|
+
sci_dataset = sci_dataset.drop_vars("epoch")
|
|
404
|
+
sci_dataset.coords["epoch"] = epoch_per_science_frame
|
|
405
|
+
sci_dataset["count_rates_binary"] = xr.DataArray(
|
|
406
|
+
count_rates, dims=["epoch"], name="count_rates_binary"
|
|
407
|
+
)
|
|
408
|
+
sci_dataset["pha_binary"] = xr.DataArray(pha, dims=["epoch"], name="pha_binary")
|
|
409
|
+
return sci_dataset
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
def decom_hit(sci_dataset: xr.Dataset) -> xr.Dataset:
|
|
413
|
+
"""
|
|
414
|
+
Group and decode HIT science data packets.
|
|
415
|
+
|
|
416
|
+
This function updates the science dataset with
|
|
417
|
+
organized, decommutated, and decompressed data.
|
|
418
|
+
|
|
419
|
+
The dataset that is passed in contains the unpacked
|
|
420
|
+
CCSDS header and the science data as bytes as follows:
|
|
421
|
+
|
|
422
|
+
<xarray.Dataset>
|
|
423
|
+
Dimensions: epoch
|
|
424
|
+
Coordinates:
|
|
425
|
+
* epoch (epoch) int64
|
|
426
|
+
Data variables:
|
|
427
|
+
sc_tick (epoch) uint32
|
|
428
|
+
science_data (epoch) <U2096
|
|
429
|
+
version (epoch) uint8
|
|
430
|
+
type (epoch) uint8
|
|
431
|
+
sec_hdr_flg (epoch) uint8
|
|
432
|
+
pkt_apid (epoch) uint16
|
|
433
|
+
seq_flgs (epoch) uint8
|
|
434
|
+
src_seq_ctr (epoch) uint16
|
|
435
|
+
pkt_len (epoch) uint16
|
|
436
|
+
|
|
437
|
+
The science data for a science frame (i.e. 1 minute of data)
|
|
438
|
+
is spread across 20 packets. This function groups the
|
|
439
|
+
data into science frames and decommutates and decompresses
|
|
440
|
+
binary into integers.
|
|
441
|
+
|
|
442
|
+
Parameters
|
|
443
|
+
----------
|
|
444
|
+
sci_dataset : xr.Dataset
|
|
445
|
+
Xarray dataset containing HIT science packets
|
|
446
|
+
from a CCSDS file.
|
|
447
|
+
|
|
448
|
+
Returns
|
|
449
|
+
-------
|
|
450
|
+
sci_dataset : xr.Dataset
|
|
451
|
+
Updated xarray dataset with new fields for all count
|
|
452
|
+
rates and pulse height event data per valid science frame
|
|
453
|
+
needed for creating an L1A product.
|
|
454
|
+
"""
|
|
455
|
+
# Update ccsds header fields to use sc_tick as dimension
|
|
456
|
+
sci_dataset = update_ccsds_header_dims(sci_dataset)
|
|
457
|
+
|
|
458
|
+
# Group science packets into groups of 20
|
|
459
|
+
sci_dataset = assemble_science_frames(sci_dataset)
|
|
460
|
+
|
|
461
|
+
# Parse count rates data from binary and add to dataset
|
|
462
|
+
parse_count_rates(sci_dataset)
|
|
463
|
+
|
|
464
|
+
# TODO:
|
|
465
|
+
# Parse binary PHA data and add to dataset (function call)
|
|
466
|
+
|
|
467
|
+
return sci_dataset
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""General HIT L0 data class used for parsing data and setting attributes."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, fields
|
|
4
|
+
|
|
5
|
+
import space_packet_parser
|
|
6
|
+
|
|
7
|
+
from imap_processing.ccsds.ccsds_data import CcsdsData
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class HITBase:
|
|
12
|
+
"""
|
|
13
|
+
Data structure for common values across HIT.
|
|
14
|
+
|
|
15
|
+
Attributes
|
|
16
|
+
----------
|
|
17
|
+
ground_sw_version : str
|
|
18
|
+
Ground software version.
|
|
19
|
+
packet_file_name : str
|
|
20
|
+
File name of the source packet.
|
|
21
|
+
ccsds_header : CcsdsData
|
|
22
|
+
CCSDS header data.
|
|
23
|
+
|
|
24
|
+
Methods
|
|
25
|
+
-------
|
|
26
|
+
parse_data(packet):
|
|
27
|
+
Parse the packet and assign to class variable using the xtce defined named.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
ground_sw_version: str
|
|
31
|
+
packet_file_name: str
|
|
32
|
+
ccsds_header: CcsdsData
|
|
33
|
+
|
|
34
|
+
def parse_data(self, packet: space_packet_parser.parser.Packet) -> None:
|
|
35
|
+
"""
|
|
36
|
+
Parse Lo L0 packet data.
|
|
37
|
+
|
|
38
|
+
Parameters
|
|
39
|
+
----------
|
|
40
|
+
packet : space_packet_parser.parser.Packet
|
|
41
|
+
A single Lo L0 packet from space packet parser.
|
|
42
|
+
"""
|
|
43
|
+
attributes = [field.name for field in fields(self)]
|
|
44
|
+
|
|
45
|
+
# For each item in packet, assign it to the matching attribute in the class.
|
|
46
|
+
for key, item in packet.data.items():
|
|
47
|
+
value = (
|
|
48
|
+
item.derived_value if item.derived_value is not None else item.raw_value
|
|
49
|
+
)
|
|
50
|
+
if "SPARE" in key:
|
|
51
|
+
continue
|
|
52
|
+
if key not in attributes:
|
|
53
|
+
raise KeyError(
|
|
54
|
+
f"Did not find matching attribute in {self.__class__} data class"
|
|
55
|
+
f"for {key}"
|
|
56
|
+
)
|
|
57
|
+
setattr(self, key, value)
|
|
File without changes
|