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 @@
|
|
|
1
|
+
__version__ = "001"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Perform CoDICE L0 processing.
|
|
3
|
+
|
|
4
|
+
This module contains a function to decommutate CoDICE CCSDS packets using
|
|
5
|
+
XTCE packet definitions.
|
|
6
|
+
|
|
7
|
+
For more information on this process and the latest versions of the packet
|
|
8
|
+
definitions, see https://lasp.colorado.edu/galaxy/display/IMAP/CoDICE.
|
|
9
|
+
|
|
10
|
+
Notes
|
|
11
|
+
-----
|
|
12
|
+
from imap_processing.codice.codice_l0 import decom_packets
|
|
13
|
+
packet_file = '/path/to/raw_ccsds_20230822_122700Z_idle.bin'
|
|
14
|
+
packet_list = decom_packets(packet_file)
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
import xarray as xr
|
|
20
|
+
|
|
21
|
+
from imap_processing import imap_module_directory
|
|
22
|
+
from imap_processing.utils import packet_file_to_datasets
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def decom_packets(packet_file: Path) -> dict[int, xr.Dataset]:
|
|
26
|
+
"""
|
|
27
|
+
Decom CoDICE data packets using CoDICE packet definition.
|
|
28
|
+
|
|
29
|
+
Parameters
|
|
30
|
+
----------
|
|
31
|
+
packet_file : pathlib.Path
|
|
32
|
+
Path to data packet path with filename.
|
|
33
|
+
|
|
34
|
+
Returns
|
|
35
|
+
-------
|
|
36
|
+
datasets : dict[int, xarray.Dataset]
|
|
37
|
+
Mapping from apid to ``xarray`` dataset, one dataset per apid.
|
|
38
|
+
"""
|
|
39
|
+
# TODO: Currently need to use the 'old' packet definition for housekeeping
|
|
40
|
+
# because the simulated housekeeping data being used has various
|
|
41
|
+
# mis-matches from the telemetry definition. This may be updated
|
|
42
|
+
# once new simulated housekeeping data are acquired.
|
|
43
|
+
if "hskp" in str(packet_file):
|
|
44
|
+
xtce_filename = "P_COD_NHK.xml"
|
|
45
|
+
else:
|
|
46
|
+
xtce_filename = "codice_packet_definition.xml"
|
|
47
|
+
xtce_packet_definition = Path(
|
|
48
|
+
f"{imap_module_directory}/codice/packet_definitions/{xtce_filename}"
|
|
49
|
+
)
|
|
50
|
+
datasets: dict[int, xr.Dataset] = packet_file_to_datasets(
|
|
51
|
+
packet_file, xtce_packet_definition
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
return datasets
|
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Perform CoDICE l1a processing.
|
|
3
|
+
|
|
4
|
+
This module processes decommutated CoDICE packets and creates L1a data products.
|
|
5
|
+
|
|
6
|
+
Notes
|
|
7
|
+
-----
|
|
8
|
+
from imap_processing.codice.codice_l0 import decom_packets
|
|
9
|
+
from imap_processing.codice.codice_l1a import process_codice_l1a
|
|
10
|
+
packets = decom_packets(packet_file)
|
|
11
|
+
dataset = process_codice_l1a(packets)
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import logging
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from typing import Any
|
|
19
|
+
|
|
20
|
+
import numpy as np
|
|
21
|
+
import pandas as pd
|
|
22
|
+
import xarray as xr
|
|
23
|
+
from numpy.typing import NDArray
|
|
24
|
+
|
|
25
|
+
from imap_processing import imap_module_directory
|
|
26
|
+
from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
|
|
27
|
+
from imap_processing.codice import constants
|
|
28
|
+
from imap_processing.codice.codice_l0 import decom_packets
|
|
29
|
+
from imap_processing.codice.decompress import decompress
|
|
30
|
+
from imap_processing.codice.utils import CODICEAPID
|
|
31
|
+
|
|
32
|
+
logger = logging.getLogger(__name__)
|
|
33
|
+
logger.setLevel(logging.INFO)
|
|
34
|
+
|
|
35
|
+
# TODO: Add support for decomming multiple APIDs from a single file
|
|
36
|
+
# TODO: Determine what should go in event data CDF and how it should be
|
|
37
|
+
# structured.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class CoDICEL1aPipeline:
|
|
41
|
+
"""
|
|
42
|
+
Contains methods for processing L0 data and creating L1a data products.
|
|
43
|
+
|
|
44
|
+
Parameters
|
|
45
|
+
----------
|
|
46
|
+
table_id : int
|
|
47
|
+
A unique ID assigned to a specific table configuration. This field is
|
|
48
|
+
used to link the overall acquisition and processing settings to a
|
|
49
|
+
specific table configuration.
|
|
50
|
+
plan_id : int
|
|
51
|
+
The plan table that was in use. In conjunction with ``plan_step``,
|
|
52
|
+
describes which counters are included in the data packet.
|
|
53
|
+
plan_step : int
|
|
54
|
+
Plan step that was active when the data was acquired and processed. In
|
|
55
|
+
conjunction with ``plan_id``, describes which counters are included
|
|
56
|
+
in the data packet.
|
|
57
|
+
view_id : int
|
|
58
|
+
Provides information about how data was collapsed and/or compressed.
|
|
59
|
+
|
|
60
|
+
Methods
|
|
61
|
+
-------
|
|
62
|
+
decompress_data(science_values)
|
|
63
|
+
Perform decompression on the data.
|
|
64
|
+
define_coordinates()
|
|
65
|
+
Create ``xr.DataArrays`` for the coords needed in the final dataset.
|
|
66
|
+
define_data_variables()
|
|
67
|
+
Define and add the appropriate data variables to the dataset.
|
|
68
|
+
define_dimensions()
|
|
69
|
+
Define the dimensions of the data arrays for the final dataset.
|
|
70
|
+
define_support_variables()
|
|
71
|
+
Define and add 'support' CDF data variables to the dataset.
|
|
72
|
+
get_acquisition_times()
|
|
73
|
+
Retrieve the acquisition times via the Lo stepping table.
|
|
74
|
+
get_energy_table()
|
|
75
|
+
Retrieve the ESA sweep values.
|
|
76
|
+
reshape_data()
|
|
77
|
+
Reshape the data arrays based on the data product being made.
|
|
78
|
+
set_data_product_config()
|
|
79
|
+
Set the various settings for defining the data products.
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
def __init__(self, table_id: int, plan_id: int, plan_step: int, view_id: int):
|
|
83
|
+
"""Initialize a ``CoDICEL1aPipeline`` class instance."""
|
|
84
|
+
self.table_id = table_id
|
|
85
|
+
self.plan_id = plan_id
|
|
86
|
+
self.plan_step = plan_step
|
|
87
|
+
self.view_id = view_id
|
|
88
|
+
|
|
89
|
+
def decompress_data(self, science_values: str) -> None:
|
|
90
|
+
"""
|
|
91
|
+
Perform decompression on the data.
|
|
92
|
+
|
|
93
|
+
The science data within the packet is a compressed, binary string of
|
|
94
|
+
values. Apply the appropriate decompression algorithm to get an array
|
|
95
|
+
of decompressed values.
|
|
96
|
+
|
|
97
|
+
Parameters
|
|
98
|
+
----------
|
|
99
|
+
science_values : str
|
|
100
|
+
A string of binary data representing the science values of the data.
|
|
101
|
+
"""
|
|
102
|
+
compression_algorithm = constants.LO_COMPRESSION_ID_LOOKUP[self.view_id]
|
|
103
|
+
|
|
104
|
+
# Decompress the binary string into a list of integers
|
|
105
|
+
self.data = decompress(science_values, compression_algorithm)
|
|
106
|
+
|
|
107
|
+
def define_coordinates(self) -> None:
|
|
108
|
+
"""
|
|
109
|
+
Create ``xr.DataArrays`` for the coords needed in the final dataset.
|
|
110
|
+
|
|
111
|
+
The coordinates for the dataset depend on the data product being made.
|
|
112
|
+
"""
|
|
113
|
+
self.coords = {}
|
|
114
|
+
|
|
115
|
+
for name in self.config["coords"]:
|
|
116
|
+
if name == "epoch":
|
|
117
|
+
values = self.packet_dataset.epoch
|
|
118
|
+
elif name == "inst_az":
|
|
119
|
+
values = np.arange(self.config["num_positions"])
|
|
120
|
+
elif name == "spin_sector":
|
|
121
|
+
values = np.arange(self.config["num_spin_sectors"])
|
|
122
|
+
elif name == "esa_step":
|
|
123
|
+
values = np.arange(self.config["num_energy_steps"])
|
|
124
|
+
else:
|
|
125
|
+
# TODO: Need to implement other types of coords
|
|
126
|
+
continue
|
|
127
|
+
|
|
128
|
+
coord = xr.DataArray(
|
|
129
|
+
values,
|
|
130
|
+
name=name,
|
|
131
|
+
dims=[name],
|
|
132
|
+
attrs=self.cdf_attrs.get_variable_attributes(name),
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
self.coords[name] = coord
|
|
136
|
+
|
|
137
|
+
def define_data_variables(self) -> xr.Dataset:
|
|
138
|
+
"""
|
|
139
|
+
Define and add the appropriate data variables to the dataset.
|
|
140
|
+
|
|
141
|
+
The data variables included in the dataset depend on the data product
|
|
142
|
+
being made. The method returns the ``xarray.Dataset`` object that can
|
|
143
|
+
then be written to a CDF file.
|
|
144
|
+
|
|
145
|
+
Returns
|
|
146
|
+
-------
|
|
147
|
+
dataset : xarray.Dataset
|
|
148
|
+
The 'final' ``xarray`` dataset.
|
|
149
|
+
"""
|
|
150
|
+
# Create the main dataset to hold all the variables
|
|
151
|
+
dataset = xr.Dataset(
|
|
152
|
+
coords=self.coords,
|
|
153
|
+
attrs=self.cdf_attrs.get_global_attributes(self.config["dataset_name"]),
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
# Create a data variable for each counter
|
|
157
|
+
for variable_data, variable_name in zip(
|
|
158
|
+
self.data, self.config["variable_names"]
|
|
159
|
+
):
|
|
160
|
+
# Reshape to 4 dimensions to allow for epoch dimension
|
|
161
|
+
reshaped_variable_data = np.expand_dims(variable_data, axis=0)
|
|
162
|
+
|
|
163
|
+
# Get the CDF attributes
|
|
164
|
+
descriptor = self.config["dataset_name"].split("imap_codice_l1a_")[-1]
|
|
165
|
+
cdf_attrs_key = f"{descriptor}-{variable_name}"
|
|
166
|
+
attrs = self.cdf_attrs.get_variable_attributes(cdf_attrs_key)
|
|
167
|
+
|
|
168
|
+
# Create the CDF data variable
|
|
169
|
+
dataset[variable_name] = xr.DataArray(
|
|
170
|
+
reshaped_variable_data,
|
|
171
|
+
name=variable_name,
|
|
172
|
+
dims=self.config["dims"],
|
|
173
|
+
attrs=attrs,
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
# Add support data variables based on data product
|
|
177
|
+
dataset = self.define_support_variables(dataset)
|
|
178
|
+
|
|
179
|
+
return dataset
|
|
180
|
+
|
|
181
|
+
def define_support_variables(self, dataset: xr.Dataset) -> xr.Dataset:
|
|
182
|
+
"""
|
|
183
|
+
Define and add 'support' CDF data variables to the dataset.
|
|
184
|
+
|
|
185
|
+
These variables include instrument metadata, energies, times, etc. that
|
|
186
|
+
help further define the L1a CDF data product. The variables included
|
|
187
|
+
depend on the data product being made.
|
|
188
|
+
|
|
189
|
+
Parameters
|
|
190
|
+
----------
|
|
191
|
+
dataset : xarray.Dataset
|
|
192
|
+
``xarray`` dataset for the data product.
|
|
193
|
+
|
|
194
|
+
Returns
|
|
195
|
+
-------
|
|
196
|
+
dataset : xarray.Dataset
|
|
197
|
+
``xarray`` dataset for the data product, with added support variables.
|
|
198
|
+
"""
|
|
199
|
+
for variable_name in self.config["support_variables"]:
|
|
200
|
+
if variable_name == "energy_table":
|
|
201
|
+
variable_data = self.get_energy_table()
|
|
202
|
+
dims = ["esa_step"]
|
|
203
|
+
attrs = self.cdf_attrs.get_variable_attributes("esa_step")
|
|
204
|
+
|
|
205
|
+
elif variable_name == "acquisition_time_per_step":
|
|
206
|
+
variable_data = self.get_acquisition_times()
|
|
207
|
+
dims = ["esa_step"]
|
|
208
|
+
attrs = self.cdf_attrs.get_variable_attributes(
|
|
209
|
+
"acquisition_time_per_step"
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
else:
|
|
213
|
+
# TODO: Need to implement methods to gather and set other
|
|
214
|
+
# support attributes
|
|
215
|
+
continue
|
|
216
|
+
|
|
217
|
+
# Add variable to the dataset
|
|
218
|
+
dataset[variable_name] = xr.DataArray(
|
|
219
|
+
variable_data,
|
|
220
|
+
dims=dims,
|
|
221
|
+
attrs=attrs,
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
return dataset
|
|
225
|
+
|
|
226
|
+
def get_acquisition_times(self) -> list[float]:
|
|
227
|
+
"""
|
|
228
|
+
Retrieve the acquisition times via the Lo stepping table.
|
|
229
|
+
|
|
230
|
+
Get the acquisition times from the data file based on the values of
|
|
231
|
+
``plan_id`` and ``plan_step``
|
|
232
|
+
|
|
233
|
+
The Lo stepping table defines how many voltage steps and which steps are
|
|
234
|
+
used during each spacecraft spin. A full cycle takes 16 spins. The table
|
|
235
|
+
provides the timing for a given energy step, and most importantly
|
|
236
|
+
provides the "acquisition time", which is the acquisition time, in
|
|
237
|
+
milliseconds, for the energy step.
|
|
238
|
+
|
|
239
|
+
Returns
|
|
240
|
+
-------
|
|
241
|
+
acquisition_times : list[float]
|
|
242
|
+
The list of acquisition times from the Lo stepping table.
|
|
243
|
+
"""
|
|
244
|
+
# Read in the Lo stepping data table
|
|
245
|
+
lo_stepping_data_file = Path(
|
|
246
|
+
f"{imap_module_directory}/codice/data/lo_stepping_values.csv"
|
|
247
|
+
)
|
|
248
|
+
lo_stepping_data = pd.read_csv(lo_stepping_data_file)
|
|
249
|
+
|
|
250
|
+
# Determine which Lo stepping table is needed
|
|
251
|
+
lo_stepping_table_id = constants.LO_STEPPING_TABLE_ID_LOOKUP[
|
|
252
|
+
(self.plan_id, self.plan_step)
|
|
253
|
+
]
|
|
254
|
+
|
|
255
|
+
# Get the appropriate values
|
|
256
|
+
lo_stepping_values = lo_stepping_data[
|
|
257
|
+
lo_stepping_data["table_num"] == lo_stepping_table_id
|
|
258
|
+
]
|
|
259
|
+
|
|
260
|
+
# Create a list for the acquisition times
|
|
261
|
+
acquisition_times = []
|
|
262
|
+
|
|
263
|
+
# Only need the energy columns from the table
|
|
264
|
+
energy_steps = lo_stepping_values[
|
|
265
|
+
["e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8"]
|
|
266
|
+
].astype(str) # convert to string to avoid confusion with table index value
|
|
267
|
+
|
|
268
|
+
# For each energy step (0-127), scan the energy columns and find the row
|
|
269
|
+
# number, which corresponds to a specific acquisition time, then append
|
|
270
|
+
# it to the list
|
|
271
|
+
for step_number in range(128):
|
|
272
|
+
row_number = np.argmax(energy_steps == str(step_number), axis=1).argmax()
|
|
273
|
+
acquisition_times.append(lo_stepping_values.acq_time[row_number])
|
|
274
|
+
|
|
275
|
+
return acquisition_times
|
|
276
|
+
|
|
277
|
+
def get_energy_table(self) -> NDArray[float]:
|
|
278
|
+
"""
|
|
279
|
+
Retrieve the ESA sweep values.
|
|
280
|
+
|
|
281
|
+
Get the ElectroStatic Analyzer (ESA) sweep values from the data file
|
|
282
|
+
based on the values of ``plan_id`` and ``plan_step``
|
|
283
|
+
|
|
284
|
+
CoDICE-Lo measures ions between ~0.5 and 80 keV/q that enter the
|
|
285
|
+
aperture and are selected and focused according to their E/q into the
|
|
286
|
+
Time of Flight (TOF) assembly. The E/q sweeping steps up to the max
|
|
287
|
+
voltage for the next stepping cycle when solar wind count rate exceed a
|
|
288
|
+
predefined threshold rate.
|
|
289
|
+
|
|
290
|
+
The ESA sweep table defines the voltage steps that are used to cover the
|
|
291
|
+
full energy per charge range.
|
|
292
|
+
|
|
293
|
+
Returns
|
|
294
|
+
-------
|
|
295
|
+
energy_table : NDArray[float]
|
|
296
|
+
The list of ESA sweep values (i.e. voltage steps).
|
|
297
|
+
"""
|
|
298
|
+
# Read in the ESA sweep data table
|
|
299
|
+
esa_sweep_data_file = Path(
|
|
300
|
+
f"{imap_module_directory}/codice/data/esa_sweep_values.csv"
|
|
301
|
+
)
|
|
302
|
+
sweep_data = pd.read_csv(esa_sweep_data_file)
|
|
303
|
+
|
|
304
|
+
# Determine which ESA sweep table is needed
|
|
305
|
+
sweep_table_id = constants.ESA_SWEEP_TABLE_ID_LOOKUP[
|
|
306
|
+
(self.plan_id, self.plan_step)
|
|
307
|
+
]
|
|
308
|
+
|
|
309
|
+
# Get the appropriate values
|
|
310
|
+
sweep_table = sweep_data[sweep_data["table_idx"] == sweep_table_id]
|
|
311
|
+
energy_table: NDArray[float] = sweep_table["esa_v"].values
|
|
312
|
+
|
|
313
|
+
return energy_table
|
|
314
|
+
|
|
315
|
+
def reshape_data(self) -> None:
|
|
316
|
+
"""
|
|
317
|
+
Reshape the data arrays based on the data product being made.
|
|
318
|
+
|
|
319
|
+
These data need to be divided up by species or priorities (or
|
|
320
|
+
what I am calling "counters" as a general term), and re-arranged into
|
|
321
|
+
3D arrays representing dimensions such as spin sectors, positions, and
|
|
322
|
+
energies (depending on the data product).
|
|
323
|
+
"""
|
|
324
|
+
# For CoDICE-lo, data are a 3D arrays with a shape representing
|
|
325
|
+
# [<num_positions>,<num_spin_sectors>,<num_energy_steps>]
|
|
326
|
+
if self.config["instrument"] == "lo":
|
|
327
|
+
self.data = np.array(self.data, dtype=np.uint32).reshape(
|
|
328
|
+
(
|
|
329
|
+
self.config["num_counters"],
|
|
330
|
+
self.config["num_positions"],
|
|
331
|
+
self.config["num_spin_sectors"],
|
|
332
|
+
self.config["num_energy_steps"],
|
|
333
|
+
)
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
# For CoDICE-hi, data are a 3D array with a shape representing
|
|
337
|
+
# [<num_energy_steps>,<num_positions>,<num_spin_sectors>]
|
|
338
|
+
elif self.config["instrument"] == "hi":
|
|
339
|
+
self.data = np.array(self.data, dtype=np.uint32).reshape(
|
|
340
|
+
(
|
|
341
|
+
self.config["num_counters"],
|
|
342
|
+
self.config["num_energy_steps"],
|
|
343
|
+
self.config["num_positions"],
|
|
344
|
+
self.config["num_spin_sectors"],
|
|
345
|
+
)
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
def set_data_product_config(
|
|
349
|
+
self, apid: int, packet: xr.Dataset, data_version: str
|
|
350
|
+
) -> None:
|
|
351
|
+
"""
|
|
352
|
+
Set the various settings for defining the data products.
|
|
353
|
+
|
|
354
|
+
Parameters
|
|
355
|
+
----------
|
|
356
|
+
apid : int
|
|
357
|
+
The APID of interest.
|
|
358
|
+
packet : xarray.Dataset
|
|
359
|
+
A packet for the APID of interest.
|
|
360
|
+
data_version : str
|
|
361
|
+
Version of the data product being created.
|
|
362
|
+
"""
|
|
363
|
+
# Set the packet dataset so that it can be easily called from various
|
|
364
|
+
# methods
|
|
365
|
+
self.packet_dataset = packet
|
|
366
|
+
|
|
367
|
+
# Set various configurations of the data product
|
|
368
|
+
self.config: dict[str, Any] = constants.DATA_PRODUCT_CONFIGURATIONS.get(apid) # type: ignore
|
|
369
|
+
|
|
370
|
+
# Gather and set the CDF attributes
|
|
371
|
+
self.cdf_attrs = ImapCdfAttributes()
|
|
372
|
+
self.cdf_attrs.add_instrument_global_attrs("codice")
|
|
373
|
+
self.cdf_attrs.add_instrument_variable_attrs("codice", "l1a")
|
|
374
|
+
self.cdf_attrs.add_global_attribute("Data_version", data_version)
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
def create_event_dataset(
|
|
378
|
+
apid: int, packet: xr.Dataset, data_version: str
|
|
379
|
+
) -> xr.Dataset:
|
|
380
|
+
"""
|
|
381
|
+
Create dataset for event data.
|
|
382
|
+
|
|
383
|
+
Parameters
|
|
384
|
+
----------
|
|
385
|
+
apid : int
|
|
386
|
+
The APID of the packet.
|
|
387
|
+
packet : xarray.Dataset
|
|
388
|
+
The packet to process.
|
|
389
|
+
data_version : str
|
|
390
|
+
Version of the data product being created.
|
|
391
|
+
|
|
392
|
+
Returns
|
|
393
|
+
-------
|
|
394
|
+
dataset : xarray.Dataset
|
|
395
|
+
Xarray dataset containing the event data.
|
|
396
|
+
"""
|
|
397
|
+
if apid == CODICEAPID.COD_LO_PHA:
|
|
398
|
+
dataset_name = "imap_codice_l1a_lo-pha"
|
|
399
|
+
elif apid == CODICEAPID.COD_HI_PHA:
|
|
400
|
+
dataset_name = "imap_codice_l1a_hi-pha"
|
|
401
|
+
|
|
402
|
+
# Extract the data
|
|
403
|
+
# event_data = packet.event_data.data (Currently turned off, see TODO)
|
|
404
|
+
|
|
405
|
+
cdf_attrs = ImapCdfAttributes()
|
|
406
|
+
cdf_attrs.add_instrument_global_attrs("codice")
|
|
407
|
+
cdf_attrs.add_instrument_variable_attrs("codice", "l1a")
|
|
408
|
+
cdf_attrs.add_global_attribute("Data_version", data_version)
|
|
409
|
+
|
|
410
|
+
# Define coordinates
|
|
411
|
+
epoch = xr.DataArray(
|
|
412
|
+
packet.epoch,
|
|
413
|
+
name="epoch",
|
|
414
|
+
dims=["epoch"],
|
|
415
|
+
attrs=cdf_attrs.get_variable_attributes("epoch"),
|
|
416
|
+
)
|
|
417
|
+
|
|
418
|
+
# Create the dataset to hold the data variables
|
|
419
|
+
dataset = xr.Dataset(
|
|
420
|
+
coords={
|
|
421
|
+
"epoch": epoch,
|
|
422
|
+
},
|
|
423
|
+
attrs=cdf_attrs.get_global_attributes(dataset_name),
|
|
424
|
+
)
|
|
425
|
+
|
|
426
|
+
return dataset
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
def create_hskp_dataset(
|
|
430
|
+
packet: xr.Dataset,
|
|
431
|
+
data_version: str,
|
|
432
|
+
) -> xr.Dataset:
|
|
433
|
+
"""
|
|
434
|
+
Create dataset for each metadata field for housekeeping data.
|
|
435
|
+
|
|
436
|
+
Parameters
|
|
437
|
+
----------
|
|
438
|
+
packet : xarray.Dataset
|
|
439
|
+
The packet to process.
|
|
440
|
+
data_version : str
|
|
441
|
+
Version of the data product being created.
|
|
442
|
+
|
|
443
|
+
Returns
|
|
444
|
+
-------
|
|
445
|
+
dataset : xarray.Dataset
|
|
446
|
+
Xarray dataset containing the metadata.
|
|
447
|
+
"""
|
|
448
|
+
cdf_attrs = ImapCdfAttributes()
|
|
449
|
+
cdf_attrs.add_instrument_global_attrs("codice")
|
|
450
|
+
cdf_attrs.add_instrument_variable_attrs("codice", "l1a")
|
|
451
|
+
cdf_attrs.add_global_attribute("Data_version", data_version)
|
|
452
|
+
|
|
453
|
+
epoch = xr.DataArray(
|
|
454
|
+
packet.epoch,
|
|
455
|
+
name="epoch",
|
|
456
|
+
dims=["epoch"],
|
|
457
|
+
attrs=cdf_attrs.get_variable_attributes("epoch"),
|
|
458
|
+
)
|
|
459
|
+
|
|
460
|
+
dataset = xr.Dataset(
|
|
461
|
+
coords={"epoch": epoch},
|
|
462
|
+
attrs=cdf_attrs.get_global_attributes("imap_codice_l1a_hskp"),
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
for variable in packet:
|
|
466
|
+
attrs = cdf_attrs.get_variable_attributes(variable)
|
|
467
|
+
|
|
468
|
+
dataset[variable] = xr.DataArray(
|
|
469
|
+
packet[variable].data, dims=["epoch"], attrs=attrs
|
|
470
|
+
)
|
|
471
|
+
|
|
472
|
+
return dataset
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
def get_params(packet: xr.Dataset) -> tuple[int, int, int, int]:
|
|
476
|
+
"""
|
|
477
|
+
Return the four 'main' parameters used for l1a processing.
|
|
478
|
+
|
|
479
|
+
The combination of these parameters largely determines what steps/values
|
|
480
|
+
are used to create CoDICE L1a data products and what steps are needed in
|
|
481
|
+
the pipeline algorithm.
|
|
482
|
+
|
|
483
|
+
Parameters
|
|
484
|
+
----------
|
|
485
|
+
packet : xarray.Dataset
|
|
486
|
+
A packet for the APID of interest.
|
|
487
|
+
|
|
488
|
+
Returns
|
|
489
|
+
-------
|
|
490
|
+
table_id : int
|
|
491
|
+
A unique ID assigned to a specific table configuration. This field is
|
|
492
|
+
used to link the overall acquisition and processing settings to a
|
|
493
|
+
specific table configuration.
|
|
494
|
+
plan_id : int
|
|
495
|
+
The plan table that was in use. In conjunction with ``plan_step``,
|
|
496
|
+
describes which counters are included in the data packet.
|
|
497
|
+
plan_step : int
|
|
498
|
+
Plan step that was active when the data was acquired and processed. In
|
|
499
|
+
conjunction with ``plan_id``, describes which counters are included
|
|
500
|
+
in the data packet.
|
|
501
|
+
view_id : int
|
|
502
|
+
Provides information about how data was collapsed and/or compressed.
|
|
503
|
+
"""
|
|
504
|
+
table_id = int(packet.table_id.data)
|
|
505
|
+
plan_id = int(packet.plan_id.data)
|
|
506
|
+
plan_step = int(packet.plan_step.data)
|
|
507
|
+
view_id = int(packet.view_id.data)
|
|
508
|
+
|
|
509
|
+
return table_id, plan_id, plan_step, view_id
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
def process_codice_l1a(file_path: Path, data_version: str) -> xr.Dataset:
|
|
513
|
+
"""
|
|
514
|
+
Will process CoDICE l0 data to create l1a data products.
|
|
515
|
+
|
|
516
|
+
Parameters
|
|
517
|
+
----------
|
|
518
|
+
file_path : pathlib.Path | str
|
|
519
|
+
Path to the CoDICE L0 file to process.
|
|
520
|
+
data_version : str
|
|
521
|
+
Version of the data product being created.
|
|
522
|
+
|
|
523
|
+
Returns
|
|
524
|
+
-------
|
|
525
|
+
dataset : xarray.Dataset
|
|
526
|
+
The ``xarray`` dataset containing the science data and supporting metadata.
|
|
527
|
+
"""
|
|
528
|
+
# Decom the packets, group data by APID, and sort by time
|
|
529
|
+
datasets = decom_packets(file_path)
|
|
530
|
+
|
|
531
|
+
for apid in datasets:
|
|
532
|
+
packet_dataset = datasets[apid]
|
|
533
|
+
logger.info(f"\nProcessing {CODICEAPID(apid).name} packet")
|
|
534
|
+
|
|
535
|
+
if apid == CODICEAPID.COD_NHK:
|
|
536
|
+
dataset = create_hskp_dataset(packet_dataset, data_version)
|
|
537
|
+
|
|
538
|
+
elif apid in [CODICEAPID.COD_LO_PHA, CODICEAPID.COD_HI_PHA]:
|
|
539
|
+
dataset = create_event_dataset(apid, packet_dataset, data_version)
|
|
540
|
+
|
|
541
|
+
elif apid in constants.APIDS_FOR_SCIENCE_PROCESSING:
|
|
542
|
+
# Extract the data
|
|
543
|
+
science_values = packet_dataset.data.data[0]
|
|
544
|
+
|
|
545
|
+
# Get the four "main" parameters for processing
|
|
546
|
+
table_id, plan_id, plan_step, view_id = get_params(packet_dataset)
|
|
547
|
+
|
|
548
|
+
# Run the pipeline to create a dataset for the product
|
|
549
|
+
pipeline = CoDICEL1aPipeline(table_id, plan_id, plan_step, view_id)
|
|
550
|
+
pipeline.set_data_product_config(apid, packet_dataset, data_version)
|
|
551
|
+
pipeline.decompress_data(science_values)
|
|
552
|
+
pipeline.reshape_data()
|
|
553
|
+
pipeline.define_coordinates()
|
|
554
|
+
dataset = pipeline.define_data_variables()
|
|
555
|
+
|
|
556
|
+
logger.info(f"\nFinal data product:\n{dataset}\n")
|
|
557
|
+
|
|
558
|
+
return dataset
|