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,150 @@
|
|
|
1
|
+
"""Processing function for Lo Science Data."""
|
|
2
|
+
|
|
3
|
+
from collections import namedtuple
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
import xarray as xr
|
|
7
|
+
|
|
8
|
+
from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
|
|
9
|
+
from imap_processing.lo.l0.utils.bit_decompression import (
|
|
10
|
+
DECOMPRESSION_TABLES,
|
|
11
|
+
Decompress,
|
|
12
|
+
decompress_int,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
HistPacking = namedtuple(
|
|
16
|
+
"HistPacking",
|
|
17
|
+
[
|
|
18
|
+
"bit_length",
|
|
19
|
+
"section_length",
|
|
20
|
+
"shape", # (azimuth, esa_step)
|
|
21
|
+
],
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
HIST_DATA_META = {
|
|
25
|
+
# field: bit_length, section_length, shape
|
|
26
|
+
"start_a": HistPacking(12, 504, (6, 7)),
|
|
27
|
+
"start_c": HistPacking(12, 504, (6, 7)),
|
|
28
|
+
"stop_b0": HistPacking(12, 504, (6, 7)),
|
|
29
|
+
"stop_b3": HistPacking(12, 504, (6, 7)),
|
|
30
|
+
"tof0_count": HistPacking(8, 336, (6, 7)),
|
|
31
|
+
"tof1_count": HistPacking(8, 336, (6, 7)),
|
|
32
|
+
"tof2_count": HistPacking(8, 336, (6, 7)),
|
|
33
|
+
"tof3_count": HistPacking(8, 336, (6, 7)),
|
|
34
|
+
"tof0_tof1": HistPacking(8, 3360, (60, 7)),
|
|
35
|
+
"tof0_tof2": HistPacking(8, 3360, (60, 7)),
|
|
36
|
+
"tof1_tof2": HistPacking(8, 3360, (60, 7)),
|
|
37
|
+
"silver": HistPacking(8, 3360, (60, 7)),
|
|
38
|
+
"disc_tof0": HistPacking(8, 336, (6, 7)),
|
|
39
|
+
"disc_tof1": HistPacking(8, 336, (6, 7)),
|
|
40
|
+
"disc_tof2": HistPacking(8, 336, (6, 7)),
|
|
41
|
+
"disc_tof3": HistPacking(8, 336, (6, 7)),
|
|
42
|
+
"pos0": HistPacking(12, 504, (6, 7)),
|
|
43
|
+
"pos1": HistPacking(12, 504, (6, 7)),
|
|
44
|
+
"pos2": HistPacking(12, 504, (6, 7)),
|
|
45
|
+
"pos3": HistPacking(12, 504, (6, 7)),
|
|
46
|
+
"hydrogen": HistPacking(8, 3360, (60, 7)),
|
|
47
|
+
"oxygen": HistPacking(8, 3360, (60, 7)),
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def parse_histogram(dataset: xr.Dataset, attr_mgr: ImapCdfAttributes) -> xr.Dataset:
|
|
52
|
+
"""
|
|
53
|
+
Parse and decompress binary histogram data for Lo.
|
|
54
|
+
|
|
55
|
+
Parameters
|
|
56
|
+
----------
|
|
57
|
+
dataset : xr.Dataset
|
|
58
|
+
Lo science counts from packets_to_dataset function.
|
|
59
|
+
attr_mgr : ImapCdfAttributes
|
|
60
|
+
CDF attribute manager for Lo L1A.
|
|
61
|
+
|
|
62
|
+
Returns
|
|
63
|
+
-------
|
|
64
|
+
dataset : xr.Dataset
|
|
65
|
+
Parsed and decompressed histogram data.
|
|
66
|
+
"""
|
|
67
|
+
hist_bin = dataset.sci_cnt
|
|
68
|
+
|
|
69
|
+
# initialize the starting bit for the sections of data
|
|
70
|
+
section_start = 0
|
|
71
|
+
# for each field type in the histogram data
|
|
72
|
+
for field in HIST_DATA_META:
|
|
73
|
+
data_meta = HIST_DATA_META[field]
|
|
74
|
+
# for each histogram binary string decompress
|
|
75
|
+
# the data
|
|
76
|
+
decompressed_data = [
|
|
77
|
+
decompress(
|
|
78
|
+
bin_str, data_meta.bit_length, section_start, data_meta.section_length
|
|
79
|
+
)
|
|
80
|
+
for bin_str in hist_bin.values
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
# add on the epoch length (equal to number of packets) to the
|
|
84
|
+
# field shape
|
|
85
|
+
data_shape = (len(hist_bin), data_meta.shape[0], data_meta.shape[1])
|
|
86
|
+
|
|
87
|
+
# get the dimension names from the CDF attr manager
|
|
88
|
+
dims = [
|
|
89
|
+
value
|
|
90
|
+
for key, value in attr_mgr.get_variable_attributes(field).items()
|
|
91
|
+
if "DEPEND" in key
|
|
92
|
+
]
|
|
93
|
+
# reshape the decompressed data
|
|
94
|
+
shaped_data = np.array(decompressed_data, dtype=np.uint32).reshape(data_shape)
|
|
95
|
+
# add the data to the dataset
|
|
96
|
+
dataset[field] = xr.DataArray(
|
|
97
|
+
shaped_data, dims=dims, attrs=attr_mgr.get_variable_attributes(field)
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
# increment for the start of the next section
|
|
101
|
+
section_start += data_meta.section_length
|
|
102
|
+
|
|
103
|
+
return dataset
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def decompress(
|
|
107
|
+
bin_str: str, bits_per_index: int, section_start: int, section_length: int
|
|
108
|
+
) -> list[int]:
|
|
109
|
+
"""
|
|
110
|
+
Parse and decompress binary histogram data for Lo.
|
|
111
|
+
|
|
112
|
+
Parameters
|
|
113
|
+
----------
|
|
114
|
+
bin_str : str
|
|
115
|
+
Binary string to decompress.
|
|
116
|
+
bits_per_index : int
|
|
117
|
+
Number of bits per index of the data section.
|
|
118
|
+
section_start : int
|
|
119
|
+
The start bit for the section of data.
|
|
120
|
+
section_length : int
|
|
121
|
+
The length of the section of data.
|
|
122
|
+
|
|
123
|
+
Returns
|
|
124
|
+
-------
|
|
125
|
+
decompressed_ints : list[int]
|
|
126
|
+
Decompressed integers for the data section.
|
|
127
|
+
"""
|
|
128
|
+
# select the decompression method based on the bit length
|
|
129
|
+
# of the compressed data
|
|
130
|
+
if bits_per_index == 8:
|
|
131
|
+
decompress = Decompress.DECOMPRESS8TO16
|
|
132
|
+
elif bits_per_index == 12:
|
|
133
|
+
decompress = Decompress.DECOMPRESS12TO16
|
|
134
|
+
else:
|
|
135
|
+
raise ValueError(f"Invalid bits_per_index: {bits_per_index}")
|
|
136
|
+
|
|
137
|
+
# parse the binary and convert to integers
|
|
138
|
+
raw_ints = [
|
|
139
|
+
int(bin_str[i : i + bits_per_index], 2)
|
|
140
|
+
for i in range(section_start, section_start + section_length, bits_per_index)
|
|
141
|
+
]
|
|
142
|
+
|
|
143
|
+
# decompress raw integers
|
|
144
|
+
decompressed_ints: list[int] = decompress_int(
|
|
145
|
+
raw_ints,
|
|
146
|
+
decompress,
|
|
147
|
+
DECOMPRESSION_TABLES,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
return decompressed_ints
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""Class for binary data strings."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class BinaryString:
|
|
5
|
+
"""
|
|
6
|
+
Iterate through a binary string.
|
|
7
|
+
|
|
8
|
+
The binary string class retains the current
|
|
9
|
+
binary string bit position and updates it
|
|
10
|
+
each time the string is accessed.
|
|
11
|
+
|
|
12
|
+
Parameters
|
|
13
|
+
----------
|
|
14
|
+
bin : str
|
|
15
|
+
Binary string.
|
|
16
|
+
|
|
17
|
+
Attributes
|
|
18
|
+
----------
|
|
19
|
+
bin : str
|
|
20
|
+
Binary string.
|
|
21
|
+
bit_pos : int
|
|
22
|
+
Current position in the binary string.
|
|
23
|
+
|
|
24
|
+
Methods
|
|
25
|
+
-------
|
|
26
|
+
next_bits(num_bits)
|
|
27
|
+
Returns the next x bits in the binary string
|
|
28
|
+
using the current bit position as the reference point.
|
|
29
|
+
The bit position is updated to be the bit immediately
|
|
30
|
+
following the last returned bit.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
bin: str
|
|
34
|
+
bit_pos: int
|
|
35
|
+
|
|
36
|
+
def __init__(self, bin: str) -> None:
|
|
37
|
+
self.bin = bin
|
|
38
|
+
self.bit_pos = 0
|
|
39
|
+
|
|
40
|
+
def next_bits(self, num_bits: int) -> str:
|
|
41
|
+
"""
|
|
42
|
+
Return the next x bits in the binary string.
|
|
43
|
+
|
|
44
|
+
The bit position updated to be the bit immediately
|
|
45
|
+
following the last returned bit.
|
|
46
|
+
|
|
47
|
+
Parameters
|
|
48
|
+
----------
|
|
49
|
+
num_bits : int
|
|
50
|
+
The number of bits you want to read off the binary string.
|
|
51
|
+
|
|
52
|
+
Returns
|
|
53
|
+
-------
|
|
54
|
+
bits : str
|
|
55
|
+
A binary string containing the next x bits that were requested.
|
|
56
|
+
"""
|
|
57
|
+
bits = self.bin[self.bit_pos : self.bit_pos + num_bits]
|
|
58
|
+
self.bit_pos += num_bits
|
|
59
|
+
return bits
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Decompression for 8 to 12, 8 to 16, and 12 to 16 bits."""
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Decompress(Enum):
|
|
10
|
+
"""The decompression options."""
|
|
11
|
+
|
|
12
|
+
DECOMPRESS8TO12 = "8_to_12"
|
|
13
|
+
DECOMPRESS8TO16 = "8_to_16"
|
|
14
|
+
DECOMPRESS12TO16 = "12_to_16"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# Load all decompression tables into a dictionary.
|
|
18
|
+
DECOMPRESSION_TABLES = {
|
|
19
|
+
enum: np.loadtxt(
|
|
20
|
+
Path(__file__).parent.parent / f"decompression_tables/{enum.value}_bit.csv",
|
|
21
|
+
delimiter=",",
|
|
22
|
+
skiprows=1,
|
|
23
|
+
)
|
|
24
|
+
for enum in Decompress
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def decompress_int(
|
|
29
|
+
compressed_values: list, decompression: Decompress, decompression_lookup: dict
|
|
30
|
+
) -> list[int]:
|
|
31
|
+
# No idea what the correct type is for the return. Mypy says it is Any
|
|
32
|
+
"""
|
|
33
|
+
Will decompress a data field using a specified bit conversion.
|
|
34
|
+
|
|
35
|
+
Parameters
|
|
36
|
+
----------
|
|
37
|
+
compressed_values : list
|
|
38
|
+
Compressed integers.
|
|
39
|
+
decompression : Decompress
|
|
40
|
+
The decompression to use.
|
|
41
|
+
decompression_lookup : dict
|
|
42
|
+
Dictionary containing all the decompression tables.
|
|
43
|
+
|
|
44
|
+
Returns
|
|
45
|
+
-------
|
|
46
|
+
decompressed : list[int]
|
|
47
|
+
The decompressed integer.
|
|
48
|
+
"""
|
|
49
|
+
valid_decompression = [
|
|
50
|
+
Decompress.DECOMPRESS8TO12,
|
|
51
|
+
Decompress.DECOMPRESS8TO16,
|
|
52
|
+
Decompress.DECOMPRESS12TO16,
|
|
53
|
+
]
|
|
54
|
+
if decompression not in valid_decompression:
|
|
55
|
+
raise ValueError(
|
|
56
|
+
"Invalid decompression method. Must be one of the following Enums: "
|
|
57
|
+
+ "Decompress.DECOMPRESS8TO12, Decompress.DECOMPRESS8TO12, "
|
|
58
|
+
+ "Decompress.DECOMPRESS8TO12"
|
|
59
|
+
)
|
|
60
|
+
data = decompression_lookup[decompression]
|
|
61
|
+
decompressed: list[int] = data[compressed_values, 1]
|
|
62
|
+
return decompressed
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""General Lo L0 data class used for parsing data and setting attributes."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, fields
|
|
4
|
+
|
|
5
|
+
from space_packet_parser.parser import Packet
|
|
6
|
+
|
|
7
|
+
from imap_processing.ccsds.ccsds_data import CcsdsData
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class LoBase:
|
|
12
|
+
"""
|
|
13
|
+
Data structure for common values across histogram and direct events data.
|
|
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 set_attributes(self, packet: Packet) -> None:
|
|
35
|
+
"""
|
|
36
|
+
Set dataclass attributes with 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 or "CHKSUM" 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
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"""IMAP-Lo L1A Data Processing."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
import xarray as xr
|
|
8
|
+
|
|
9
|
+
from imap_processing import imap_module_directory
|
|
10
|
+
from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
|
|
11
|
+
from imap_processing.lo.l0.lo_apid import LoAPID
|
|
12
|
+
from imap_processing.lo.l0.lo_science import parse_histogram
|
|
13
|
+
from imap_processing.utils import packet_file_to_datasets
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
logger.setLevel(logging.INFO)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def lo_l1a(dependency: Path, data_version: str) -> list[xr.Dataset]:
|
|
20
|
+
"""
|
|
21
|
+
Will process IMAP-Lo L0 data into L1A CDF data products.
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
dependency : Path
|
|
26
|
+
Dependency file needed for data product creation.
|
|
27
|
+
Should always be only one for L1A.
|
|
28
|
+
data_version : str
|
|
29
|
+
Version of the data product being created.
|
|
30
|
+
|
|
31
|
+
Returns
|
|
32
|
+
-------
|
|
33
|
+
created_file_paths : list[Path]
|
|
34
|
+
Location of created CDF files.
|
|
35
|
+
"""
|
|
36
|
+
xtce_file = imap_module_directory / "lo/packet_definitions/lo_xtce.xml"
|
|
37
|
+
|
|
38
|
+
logger.info("\nDecommutating packets and converting to dataset")
|
|
39
|
+
datasets_by_apid = packet_file_to_datasets(
|
|
40
|
+
packet_file=dependency.resolve(),
|
|
41
|
+
xtce_packet_definition=xtce_file.resolve(),
|
|
42
|
+
use_derived_value=False,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# create the attribute manager for this data level
|
|
46
|
+
attr_mgr = ImapCdfAttributes()
|
|
47
|
+
attr_mgr.add_instrument_global_attrs(instrument="lo")
|
|
48
|
+
attr_mgr.add_instrument_variable_attrs(instrument="lo", level="l1a")
|
|
49
|
+
attr_mgr.add_global_attribute("Data_version", data_version)
|
|
50
|
+
|
|
51
|
+
logger.info(
|
|
52
|
+
f"\nProcessing {LoAPID(LoAPID.ILO_SCI_CNT).name} "
|
|
53
|
+
f"packet (APID: {LoAPID.ILO_SCI_CNT.value})"
|
|
54
|
+
)
|
|
55
|
+
if LoAPID.ILO_SCI_CNT in datasets_by_apid:
|
|
56
|
+
logical_source = "imap_lo_l1a_histogram"
|
|
57
|
+
datasets_by_apid[LoAPID.ILO_SCI_CNT] = parse_histogram(
|
|
58
|
+
datasets_by_apid[LoAPID.ILO_SCI_CNT], attr_mgr
|
|
59
|
+
)
|
|
60
|
+
datasets_by_apid[LoAPID.ILO_SCI_CNT] = add_dataset_attrs(
|
|
61
|
+
datasets_by_apid[LoAPID.ILO_SCI_CNT], attr_mgr, logical_source
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
good_apids = [LoAPID.ILO_SCI_CNT]
|
|
65
|
+
logger.info(f"\nReturning datasets: {[LoAPID(apid) for apid in good_apids]}")
|
|
66
|
+
return [datasets_by_apid[good_apid] for good_apid in good_apids]
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def add_dataset_attrs(
|
|
70
|
+
dataset: xr.Dataset, attr_mgr: ImapCdfAttributes, logical_source: str
|
|
71
|
+
) -> xr.Dataset:
|
|
72
|
+
"""
|
|
73
|
+
Add Attributes to the dataset.
|
|
74
|
+
|
|
75
|
+
Parameters
|
|
76
|
+
----------
|
|
77
|
+
dataset : xr.Dataset
|
|
78
|
+
Lo dataset from packets_to_dataset function.
|
|
79
|
+
attr_mgr : ImapCdfAttributes
|
|
80
|
+
CDF attribute manager for Lo L1A.
|
|
81
|
+
logical_source : str
|
|
82
|
+
Logical source for the data.
|
|
83
|
+
|
|
84
|
+
Returns
|
|
85
|
+
-------
|
|
86
|
+
dataset : xr.Dataset
|
|
87
|
+
Data with attributes added.
|
|
88
|
+
"""
|
|
89
|
+
# TODO: may want up split up these if statements into their
|
|
90
|
+
# own functions
|
|
91
|
+
if logical_source == "imap_lo_l1a_histogram":
|
|
92
|
+
azimuth_60 = xr.DataArray(
|
|
93
|
+
data=np.arange(0, 6, dtype=np.uint8),
|
|
94
|
+
name="azimuth_60",
|
|
95
|
+
dims=["azimuth_60"],
|
|
96
|
+
attrs=attr_mgr.get_variable_attributes("azimuth_60"),
|
|
97
|
+
)
|
|
98
|
+
azimuth_60_label = xr.DataArray(
|
|
99
|
+
data=azimuth_60.values.astype(str),
|
|
100
|
+
name="azimuth_60_label",
|
|
101
|
+
dims=["azimuth_60_label"],
|
|
102
|
+
attrs=attr_mgr.get_variable_attributes("azimuth_60_label"),
|
|
103
|
+
)
|
|
104
|
+
azimuth_6 = xr.DataArray(
|
|
105
|
+
data=np.arange(0, 60, dtype=np.uint8),
|
|
106
|
+
name="azimuth_6",
|
|
107
|
+
dims=["azimuth_6"],
|
|
108
|
+
attrs=attr_mgr.get_variable_attributes("azimuth_6"),
|
|
109
|
+
)
|
|
110
|
+
azimuth_6_label = xr.DataArray(
|
|
111
|
+
data=azimuth_6.values.astype(str),
|
|
112
|
+
name="azimuth_6_label",
|
|
113
|
+
dims=["azimuth_6_label"],
|
|
114
|
+
attrs=attr_mgr.get_variable_attributes("azimuth_6_label"),
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
esa_step = xr.DataArray(
|
|
118
|
+
data=np.arange(1, 8, dtype=np.uint8),
|
|
119
|
+
name="esa_step",
|
|
120
|
+
dims=["esa_step"],
|
|
121
|
+
attrs=attr_mgr.get_variable_attributes("esa_step"),
|
|
122
|
+
)
|
|
123
|
+
esa_step_label = xr.DataArray(
|
|
124
|
+
esa_step.values.astype(str),
|
|
125
|
+
name="esa_step_label",
|
|
126
|
+
dims=["esa_step_label"],
|
|
127
|
+
attrs=attr_mgr.get_variable_attributes("esa_step_label"),
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
dataset.shcoarse.attrs.update(attr_mgr.get_variable_attributes("shcoarse"))
|
|
131
|
+
dataset.epoch.attrs.update(attr_mgr.get_variable_attributes("epoch"))
|
|
132
|
+
|
|
133
|
+
dataset = dataset.assign_coords(
|
|
134
|
+
azimuth_60=azimuth_60,
|
|
135
|
+
azimuth_60_label=azimuth_60_label,
|
|
136
|
+
azimuth_6=azimuth_6,
|
|
137
|
+
azimuth_6_label=azimuth_6_label,
|
|
138
|
+
esa_step=esa_step,
|
|
139
|
+
esa_step_label=esa_step_label,
|
|
140
|
+
)
|
|
141
|
+
dataset.attrs.update(attr_mgr.get_global_attributes(logical_source))
|
|
142
|
+
# remove the binary field and CCSDS header from the dataset
|
|
143
|
+
dataset = dataset.drop_vars(
|
|
144
|
+
[
|
|
145
|
+
"sci_cnt",
|
|
146
|
+
"chksum",
|
|
147
|
+
"version",
|
|
148
|
+
"type",
|
|
149
|
+
"sec_hdr_flg",
|
|
150
|
+
"pkt_apid",
|
|
151
|
+
"seq_flgs",
|
|
152
|
+
"src_seq_ctr",
|
|
153
|
+
"pkt_len",
|
|
154
|
+
]
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
return dataset
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"""IMAP-Lo L1B Data Processing."""
|
|
2
|
+
|
|
3
|
+
from collections import namedtuple
|
|
4
|
+
from dataclasses import Field
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
import xarray as xr
|
|
9
|
+
|
|
10
|
+
from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
|
|
11
|
+
from imap_processing.spice.time import met_to_j2000ns
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def lo_l1b(dependencies: dict, data_version: str) -> list[Path]:
|
|
15
|
+
"""
|
|
16
|
+
Will process IMAP-Lo L1A data into L1B CDF data products.
|
|
17
|
+
|
|
18
|
+
Parameters
|
|
19
|
+
----------
|
|
20
|
+
dependencies : dict
|
|
21
|
+
Dictionary of datasets needed for L1B data product creation in xarray Datasets.
|
|
22
|
+
data_version : str
|
|
23
|
+
Version of the data product being created.
|
|
24
|
+
|
|
25
|
+
Returns
|
|
26
|
+
-------
|
|
27
|
+
created_file_paths : list[pathlib.Path]
|
|
28
|
+
Location of created CDF files.
|
|
29
|
+
"""
|
|
30
|
+
# create the attribute manager for this data level
|
|
31
|
+
attr_mgr = ImapCdfAttributes()
|
|
32
|
+
attr_mgr.add_instrument_global_attrs(instrument="lo")
|
|
33
|
+
attr_mgr.add_instrument_variable_attrs(instrument="lo", level="l1b")
|
|
34
|
+
attr_mgr.add_global_attribute("Data_version", data_version)
|
|
35
|
+
|
|
36
|
+
# if the dependencies are used to create Annotated Direct Events
|
|
37
|
+
|
|
38
|
+
if "imap_lo_l1a_de" in dependencies and "imap_lo_l1a_spin" in dependencies:
|
|
39
|
+
logical_source = "imap_lo_l1b_de"
|
|
40
|
+
# TODO: TEMPORARY. Need to update to use the L1B data class once that exists
|
|
41
|
+
# and I have sample data.
|
|
42
|
+
data_field_tup = namedtuple("data_field_tup", ["name"])
|
|
43
|
+
data_fields = [
|
|
44
|
+
data_field_tup("ESA_STEP"),
|
|
45
|
+
data_field_tup("MODE"),
|
|
46
|
+
data_field_tup("TOF0"),
|
|
47
|
+
data_field_tup("TOF1"),
|
|
48
|
+
data_field_tup("TOF2"),
|
|
49
|
+
data_field_tup("TOF3"),
|
|
50
|
+
data_field_tup("COINCIDENCE_TYPE"),
|
|
51
|
+
data_field_tup("POS"),
|
|
52
|
+
data_field_tup("COINCIDENCE"),
|
|
53
|
+
data_field_tup("BADTIME"),
|
|
54
|
+
data_field_tup("DIRECTION"),
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
dataset: list[Path] = create_datasets(attr_mgr, logical_source, data_fields) # type: ignore[arg-type]
|
|
58
|
+
# TODO Remove once data_fields is removed from create_datasets
|
|
59
|
+
return dataset
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# TODO: This is going to work differently when I sample data.
|
|
63
|
+
# The data_fields input is temporary.
|
|
64
|
+
def create_datasets(
|
|
65
|
+
attr_mgr: ImapCdfAttributes,
|
|
66
|
+
logical_source: str,
|
|
67
|
+
data_fields: list[Field],
|
|
68
|
+
) -> xr.Dataset:
|
|
69
|
+
"""
|
|
70
|
+
Create a dataset using the populated data classes.
|
|
71
|
+
|
|
72
|
+
Parameters
|
|
73
|
+
----------
|
|
74
|
+
attr_mgr : ImapCdfAttributes
|
|
75
|
+
Attribute manager used to get the data product field's attributes.
|
|
76
|
+
logical_source : str
|
|
77
|
+
The logical source of the data product that's being created.
|
|
78
|
+
data_fields : list[dataclasses.Field]
|
|
79
|
+
List of Fields for data classes.
|
|
80
|
+
|
|
81
|
+
Returns
|
|
82
|
+
-------
|
|
83
|
+
dataset : xarray.Dataset
|
|
84
|
+
Dataset with all data product fields in xr.DataArray.
|
|
85
|
+
"""
|
|
86
|
+
# TODO: Once L1B DE processing is implemented using the spin packet
|
|
87
|
+
# and relative L1A DE time to calculate the absolute DE time,
|
|
88
|
+
# this epoch conversion will go away and the time in the DE dataclass
|
|
89
|
+
# can be used direction
|
|
90
|
+
epoch_converted_time = met_to_j2000ns([0, 1, 2])
|
|
91
|
+
|
|
92
|
+
# Create a data array for the epoch time
|
|
93
|
+
# TODO: might need to update the attrs to use new YAML file
|
|
94
|
+
epoch_time = xr.DataArray(
|
|
95
|
+
data=epoch_converted_time,
|
|
96
|
+
name="epoch",
|
|
97
|
+
dims=["epoch"],
|
|
98
|
+
attrs=attr_mgr.get_variable_attributes("epoch"),
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
if logical_source == "imap_lo_l1b_de":
|
|
102
|
+
direction_vec = xr.DataArray(
|
|
103
|
+
data=[0, 1, 2],
|
|
104
|
+
name="direction_vec",
|
|
105
|
+
dims=["direction_vec"],
|
|
106
|
+
attrs=attr_mgr.get_variable_attributes("direction_vec"),
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
direction_vec_label = xr.DataArray(
|
|
110
|
+
data=direction_vec.values.astype(str),
|
|
111
|
+
name="direction_vec_label",
|
|
112
|
+
dims=["direction_vec_label"],
|
|
113
|
+
attrs=attr_mgr.get_variable_attributes("direction_vec_label"),
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
dataset = xr.Dataset(
|
|
117
|
+
coords={
|
|
118
|
+
"epoch": epoch_time,
|
|
119
|
+
"direction_vec": direction_vec,
|
|
120
|
+
"direction_vec_label": direction_vec_label,
|
|
121
|
+
},
|
|
122
|
+
attrs=attr_mgr.get_global_attributes(logical_source),
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
# Loop through the data fields that were pulled from the
|
|
126
|
+
# data class. These should match the field names given
|
|
127
|
+
# to each field in the YAML attribute file
|
|
128
|
+
for data_field in data_fields:
|
|
129
|
+
field = data_field.name.lower()
|
|
130
|
+
# Create a list of all the dimensions using the DEPEND_I keys in the
|
|
131
|
+
# YAML attributes
|
|
132
|
+
dims = [
|
|
133
|
+
value
|
|
134
|
+
for key, value in attr_mgr.get_variable_attributes(field).items()
|
|
135
|
+
if "DEPEND" in key
|
|
136
|
+
]
|
|
137
|
+
|
|
138
|
+
# Create a data array for the current field and add it to the dataset
|
|
139
|
+
# TODO: TEMPORARY. need to update to use l1a data once that's available.
|
|
140
|
+
# Won't need to check for the direction field when I have sample data either.
|
|
141
|
+
if field == "direction":
|
|
142
|
+
dataset[field] = xr.DataArray(
|
|
143
|
+
[[0, 0, 1], [0, 1, 0], [0, 0, 1]],
|
|
144
|
+
dims=dims,
|
|
145
|
+
attrs=attr_mgr.get_variable_attributes(field),
|
|
146
|
+
)
|
|
147
|
+
# TODO: This is temporary.
|
|
148
|
+
# The data type will be set in the data class when that's created
|
|
149
|
+
elif field in ["tof0", "tof1", "tof2", "tof3"]:
|
|
150
|
+
dataset[field] = xr.DataArray(
|
|
151
|
+
[np.float16(1), np.float16(1), np.float16(1)],
|
|
152
|
+
dims=dims,
|
|
153
|
+
attrs=attr_mgr.get_variable_attributes(field),
|
|
154
|
+
)
|
|
155
|
+
else:
|
|
156
|
+
dataset[field] = xr.DataArray(
|
|
157
|
+
[1, 1, 1], dims=dims, attrs=attr_mgr.get_variable_attributes(field)
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
return dataset
|