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,583 @@
|
|
|
1
|
+
# ruff: noqa: PLR0913
|
|
2
|
+
"""Module for GLOWS L1B data products."""
|
|
3
|
+
|
|
4
|
+
import dataclasses
|
|
5
|
+
import json
|
|
6
|
+
from dataclasses import InitVar, dataclass, field
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Optional
|
|
9
|
+
|
|
10
|
+
import numpy as np
|
|
11
|
+
|
|
12
|
+
from imap_processing.glows.utils.constants import TimeTuple
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class AncillaryParameters:
|
|
16
|
+
"""
|
|
17
|
+
GLOWS L1B Ancillary Parameters for decoding ancillary histogram data points.
|
|
18
|
+
|
|
19
|
+
This class reads from a JSON file input which defines ancillary parameters.
|
|
20
|
+
It validates to ensure the input file has all the required parameters.
|
|
21
|
+
|
|
22
|
+
Parameters
|
|
23
|
+
----------
|
|
24
|
+
input_table : dict
|
|
25
|
+
Dictionary generated from input JSON file.
|
|
26
|
+
|
|
27
|
+
Attributes
|
|
28
|
+
----------
|
|
29
|
+
version: str
|
|
30
|
+
version of the ancillary file
|
|
31
|
+
filter_temperature: dict
|
|
32
|
+
dictionary of filter temperature parameters, with keys ["min", "max", "n_bits",
|
|
33
|
+
"p01", "p02", "p03", "p04"]
|
|
34
|
+
hv_voltage: dict
|
|
35
|
+
dictionary of CEM voltage parameters, with keys ["min", "max", "n_bits",
|
|
36
|
+
"p01", "p02", "p03", "p04"]
|
|
37
|
+
spin_period: dict
|
|
38
|
+
dictionary of spin period parameters, with keys ["min", "max", "n_bits"]
|
|
39
|
+
spin_phase: dict
|
|
40
|
+
dictionary of spin phase parameters, with keys ["min", "max", "n_bits"]
|
|
41
|
+
pulse_length: dict
|
|
42
|
+
dictionary of pulse length parameters, with keys ["min", "max", "n_bits",
|
|
43
|
+
"p01", "p02", "p03", "p04"]
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __init__(self, input_table: dict):
|
|
47
|
+
"""
|
|
48
|
+
Generate ancillary parameters from the given input.
|
|
49
|
+
|
|
50
|
+
Validates parameters and will throw a KeyError if input data is incorrect.
|
|
51
|
+
"""
|
|
52
|
+
full_keys = ["min", "max", "n_bits", "p01", "p02", "p03", "p04"]
|
|
53
|
+
spin_keys = ["min", "max", "n_bits"]
|
|
54
|
+
|
|
55
|
+
try:
|
|
56
|
+
self.version = input_table["version"]
|
|
57
|
+
self.filter_temperature = input_table["filter_temperature"]
|
|
58
|
+
if any([key not in full_keys for key in self.filter_temperature.keys()]):
|
|
59
|
+
raise KeyError("Filter temperature parameters are incorrect.")
|
|
60
|
+
self.hv_voltage = input_table["hv_voltage"]
|
|
61
|
+
if any([key not in full_keys for key in self.hv_voltage.keys()]):
|
|
62
|
+
raise KeyError("HV voltage parameters are incorrect.")
|
|
63
|
+
self.spin_period = input_table["spin_period"]
|
|
64
|
+
if any([key not in spin_keys for key in self.spin_period.keys()]):
|
|
65
|
+
raise KeyError("Spin period parameters are incorrect.")
|
|
66
|
+
self.spin_phase = input_table["spin_phase"]
|
|
67
|
+
if any([key not in spin_keys for key in self.spin_phase.keys()]):
|
|
68
|
+
raise KeyError("Spin phase parameters are incorrect.")
|
|
69
|
+
self.pulse_length = input_table["pulse_length"]
|
|
70
|
+
if any([key not in full_keys for key in self.pulse_length.keys()]):
|
|
71
|
+
raise KeyError("Pulse length parameters are incorrect.")
|
|
72
|
+
|
|
73
|
+
except KeyError as e:
|
|
74
|
+
raise KeyError(
|
|
75
|
+
"GLOWS L1B Ancillary input_table does not conform to "
|
|
76
|
+
"expected format."
|
|
77
|
+
) from e
|
|
78
|
+
|
|
79
|
+
def decode(self, param_key: str, encoded_value: np.double) -> np.double:
|
|
80
|
+
"""
|
|
81
|
+
Decode parameters using the algorithm defined in section -.
|
|
82
|
+
|
|
83
|
+
The output parameter T_d is defined as:
|
|
84
|
+
T_d = (T_e - B) / A
|
|
85
|
+
|
|
86
|
+
where T_e is the encoded value and A and B are:
|
|
87
|
+
A = (2^n - 1) / (max - min)
|
|
88
|
+
B = -min * A
|
|
89
|
+
|
|
90
|
+
Max, min, and n are defined in an ancillary data file defined by
|
|
91
|
+
AncillaryParameters.
|
|
92
|
+
|
|
93
|
+
Parameters
|
|
94
|
+
----------
|
|
95
|
+
param_key : str
|
|
96
|
+
The parameter to use for decoding. Should be one of "filter_temperature",
|
|
97
|
+
"hv_voltage", "spin_period", "spin_phase", or "pulse_length".
|
|
98
|
+
encoded_value : np.double
|
|
99
|
+
The encoded value to decode.
|
|
100
|
+
|
|
101
|
+
Returns
|
|
102
|
+
-------
|
|
103
|
+
decoded_value : np.double
|
|
104
|
+
The decoded value.
|
|
105
|
+
"""
|
|
106
|
+
params = getattr(self, param_key)
|
|
107
|
+
# compute parameters a and b:
|
|
108
|
+
param_a = (2 ** params["n_bits"] - 1) / (params["max"] - params["min"])
|
|
109
|
+
param_b = -params["min"] * param_a
|
|
110
|
+
|
|
111
|
+
return np.double((encoded_value - param_b) / param_a)
|
|
112
|
+
|
|
113
|
+
def decode_std_dev(self, param_key: str, encoded_value: np.double) -> np.double:
|
|
114
|
+
"""
|
|
115
|
+
Decode an encoded variance variable and compute the standard deviation.
|
|
116
|
+
|
|
117
|
+
The decoded value of encoded_value is given by:
|
|
118
|
+
variance = encoded_value / (param_a**2)
|
|
119
|
+
|
|
120
|
+
where param_a is defined as:
|
|
121
|
+
param_a = (2^n - 1) / (max - min)
|
|
122
|
+
|
|
123
|
+
The standard deviation is then the square root of the variance.
|
|
124
|
+
|
|
125
|
+
Parameters
|
|
126
|
+
----------
|
|
127
|
+
param_key : str
|
|
128
|
+
The parameter to use for decoding. Should be one of "filter_temperature",
|
|
129
|
+
"hv_voltage", "spin_period", "spin_phase", or "pulse_length".
|
|
130
|
+
encoded_value : np.double
|
|
131
|
+
The encoded variance to decode.
|
|
132
|
+
|
|
133
|
+
Returns
|
|
134
|
+
-------
|
|
135
|
+
std_dev : np.double
|
|
136
|
+
The standard deviation of the encoded value.
|
|
137
|
+
"""
|
|
138
|
+
params = getattr(self, param_key)
|
|
139
|
+
# compute parameters a and b:
|
|
140
|
+
param_a = (2 ** params["n_bits"] - 1) / (params["max"] - params["min"])
|
|
141
|
+
|
|
142
|
+
variance = encoded_value / (param_a**2)
|
|
143
|
+
|
|
144
|
+
return np.double(np.sqrt(variance))
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
@dataclass
|
|
148
|
+
class DirectEventL1B:
|
|
149
|
+
"""
|
|
150
|
+
GLOWS L1B direct event data product.
|
|
151
|
+
|
|
152
|
+
This class uses dataclass "InitVar" types which are only used to create the
|
|
153
|
+
output dataclass and not used beyond the __post_init__ function. These attributes
|
|
154
|
+
represent data variables that are present in L1A but not passed on in the same form
|
|
155
|
+
to L1B.
|
|
156
|
+
|
|
157
|
+
Attributes
|
|
158
|
+
----------
|
|
159
|
+
direct_events: np.ndarray
|
|
160
|
+
4d array consisting of [seconds, subseconds, pulse_length, is_multi_event],
|
|
161
|
+
which is the DirectEvent structure from L1A. This is used to generate
|
|
162
|
+
direct_event_glows_times and direct_event_pulse_lengths.
|
|
163
|
+
seq_count_in_pkts_file: int
|
|
164
|
+
Sequence count in the input file, passed from L1A
|
|
165
|
+
unique_identifier: str
|
|
166
|
+
YYYY-MM-DDThh:mm:ss based on IMAP UTC time
|
|
167
|
+
number_of_de_packets: InitVar[np.double]
|
|
168
|
+
Number of DE packets in the block, passed in from L1A.
|
|
169
|
+
TODO: Missing from algorithm document, double check that this should be in L1B
|
|
170
|
+
imap_time_last_pps: np.double
|
|
171
|
+
Last PPS in IMAP clock format. Copied from imap_sclk_last_pps in L1A,
|
|
172
|
+
In seconds.
|
|
173
|
+
glows_time_last_pps: np.double
|
|
174
|
+
Last PPS in GLOWS clock format. Creaded from glows_sclk_last_pps and
|
|
175
|
+
glows_ssclk_last_pps in L1A. In seconds, with subseconds as decimal.
|
|
176
|
+
glows_ssclk_last_pps: InitVar[np.double]
|
|
177
|
+
Subseconds of the last PPS in GLOWS clock format. Used to update
|
|
178
|
+
glows_time_last_pps.
|
|
179
|
+
imap_time_next_pps: np.double
|
|
180
|
+
Next PPS in IMAP clock format. Copied from imap_slck_next_pps in L1A.
|
|
181
|
+
In seconds.
|
|
182
|
+
catbed_heater_active: InitVar[np.double]
|
|
183
|
+
Flag for catbed heater
|
|
184
|
+
spin_period_valid: InitVar[np.double]
|
|
185
|
+
Flag for valid spin period
|
|
186
|
+
spin_phase_at_next_pps_valid: InitVar[np.double]
|
|
187
|
+
Flag for valid spin phase at next PPS
|
|
188
|
+
spin_period_source: InitVar[np.double]
|
|
189
|
+
Source of spin period flag
|
|
190
|
+
spin_period: np.double
|
|
191
|
+
Spin period in seconds, decoded from ancillary data
|
|
192
|
+
spin_phase_at_next_pps: np.double
|
|
193
|
+
Spin phase at the next PPS in degrees, decoded from ancillary data
|
|
194
|
+
number_of_completed_spins: int
|
|
195
|
+
Number of completed spins in the block, passed from L1A
|
|
196
|
+
filter_temperature: np.double
|
|
197
|
+
Filter temperature in Celsius degrees, decoded from ancillary data
|
|
198
|
+
hv_voltage: np.double
|
|
199
|
+
CEM voltage in volts, decoded from ancillary data
|
|
200
|
+
glows_time_on_pps_valid: InitVar[np.double]
|
|
201
|
+
Flag for valid GLOWS time on PPS, ends up in flags array
|
|
202
|
+
time_status_valid: InitVar[np.double]
|
|
203
|
+
Flag for valid time status, ends up in flags array
|
|
204
|
+
housekeeping_valid: InitVar[np.double]
|
|
205
|
+
Flag for valid housekeeping, ends up in flags array
|
|
206
|
+
is_pps_autogenerated: InitVar[np.double]
|
|
207
|
+
Flag for autogenerated PPS, ends up in flags array
|
|
208
|
+
hv_test_in_progress: InitVar[np.double]
|
|
209
|
+
Flag for HV test in progress, ends up in flags array
|
|
210
|
+
pulse_test_in_progress: InitVar[np.double]
|
|
211
|
+
Flag for pulse test in progress, ends up in flags array
|
|
212
|
+
memory_error_detected: InitVar[np.double]
|
|
213
|
+
Flag for memory error detected, ends up in flags array
|
|
214
|
+
flags: ndarray
|
|
215
|
+
array of flags for extra information, per histogram. This is assembled from
|
|
216
|
+
L1A variables.
|
|
217
|
+
direct_event_glows_times: ndarray
|
|
218
|
+
array of times for direct events, GLOWS clock, subseconds as decimal part of
|
|
219
|
+
float. From direct_events.
|
|
220
|
+
direct_event_pulse_lengths: ndarray
|
|
221
|
+
array of pulse lengths [μs] for direct events. From direct_events
|
|
222
|
+
"""
|
|
223
|
+
|
|
224
|
+
direct_events: InitVar[np.ndarray]
|
|
225
|
+
seq_count_in_pkts_file: np.double # Passed from L1A
|
|
226
|
+
# unique_identifier: str = field(init=False)
|
|
227
|
+
number_of_de_packets: np.double # TODO Is this required in L1B?
|
|
228
|
+
imap_time_last_pps: np.double
|
|
229
|
+
glows_time_last_pps: np.double
|
|
230
|
+
# Added to the end of glows_time_last_pps as subseconds
|
|
231
|
+
glows_ssclk_last_pps: InitVar[int]
|
|
232
|
+
imap_time_next_pps: np.double
|
|
233
|
+
catbed_heater_active: InitVar[np.double]
|
|
234
|
+
spin_period_valid: InitVar[np.double]
|
|
235
|
+
spin_phase_at_next_pps_valid: InitVar[np.double]
|
|
236
|
+
spin_period_source: InitVar[np.double]
|
|
237
|
+
spin_period: np.double
|
|
238
|
+
spin_phase_at_next_pps: np.double
|
|
239
|
+
number_of_completed_spins: np.double
|
|
240
|
+
filter_temperature: np.double
|
|
241
|
+
hv_voltage: np.double
|
|
242
|
+
glows_time_on_pps_valid: InitVar[np.double]
|
|
243
|
+
time_status_valid: InitVar[np.double]
|
|
244
|
+
housekeeping_valid: InitVar[np.double]
|
|
245
|
+
is_pps_autogenerated: InitVar[np.double]
|
|
246
|
+
hv_test_in_progress: InitVar[np.double]
|
|
247
|
+
pulse_test_in_progress: InitVar[np.double]
|
|
248
|
+
memory_error_detected: InitVar[np.double]
|
|
249
|
+
|
|
250
|
+
# pkts_file_name: str # TODO: Add once L1A questions are answered
|
|
251
|
+
# l1a_file_name: str # TODO: Add once L1A questions are answered
|
|
252
|
+
# ancillary_data_files: np.ndarray # TODO: Add once L1A questions are answered
|
|
253
|
+
# The following variables are created from the InitVar data
|
|
254
|
+
de_flags: Optional[np.ndarray] = field(init=False, default=None)
|
|
255
|
+
# TODO: First two values of DE are sec/subsec
|
|
256
|
+
direct_event_glows_times: Optional[np.ndarray] = field(init=False, default=None)
|
|
257
|
+
# 3rd value is pulse length
|
|
258
|
+
direct_event_pulse_lengths: Optional[np.ndarray] = field(init=False, default=None)
|
|
259
|
+
# TODO: where does the multi-event flag go?
|
|
260
|
+
|
|
261
|
+
def __post_init__(
|
|
262
|
+
self,
|
|
263
|
+
direct_events: np.ndarray,
|
|
264
|
+
glows_ssclk_last_pps: int,
|
|
265
|
+
catbed_heater_active: np.double,
|
|
266
|
+
spin_period_valid: np.double,
|
|
267
|
+
spin_phase_at_next_pps_valid: np.double,
|
|
268
|
+
spin_period_source: np.double,
|
|
269
|
+
glows_time_on_pps_valid: np.double,
|
|
270
|
+
time_status_valid: np.double,
|
|
271
|
+
housekeeping_valid: np.double,
|
|
272
|
+
is_pps_autogenerated: np.double,
|
|
273
|
+
hv_test_in_progress: np.double,
|
|
274
|
+
pulse_test_in_progress: np.double,
|
|
275
|
+
memory_error_detected: np.double,
|
|
276
|
+
) -> None:
|
|
277
|
+
"""
|
|
278
|
+
Generate the L1B data for direct events using the inputs from InitVar.
|
|
279
|
+
|
|
280
|
+
Parameters
|
|
281
|
+
----------
|
|
282
|
+
direct_events : np.ndarray
|
|
283
|
+
Direct events.
|
|
284
|
+
glows_ssclk_last_pps : int
|
|
285
|
+
Glows subsecond clock for the last PPS.
|
|
286
|
+
catbed_heater_active : np.double
|
|
287
|
+
Flag if the catbed heater is active.
|
|
288
|
+
spin_period_valid : np.double
|
|
289
|
+
Valid spin period.
|
|
290
|
+
spin_phase_at_next_pps_valid : np.double
|
|
291
|
+
Flag indicating if the next spin phase is valid.
|
|
292
|
+
spin_period_source : np.double
|
|
293
|
+
Spin period source.
|
|
294
|
+
glows_time_on_pps_valid : np.double
|
|
295
|
+
Flag indicating if the glows time is valid.
|
|
296
|
+
time_status_valid : np.double
|
|
297
|
+
Flag indicating if time status is valid.
|
|
298
|
+
housekeeping_valid : np.double
|
|
299
|
+
Flag indicating if housekeeping is valid.
|
|
300
|
+
is_pps_autogenerated : np.double
|
|
301
|
+
Flag indicating if the PPS is autogenerated.
|
|
302
|
+
hv_test_in_progress : np.double
|
|
303
|
+
Flag indicating if a HV (high voltage) test is in progress.
|
|
304
|
+
pulse_test_in_progress : np.double
|
|
305
|
+
Flag indicating if a pulse test is in progress.
|
|
306
|
+
memory_error_detected : np.double
|
|
307
|
+
Flag indicating if a memory error is detected.
|
|
308
|
+
"""
|
|
309
|
+
self.direct_event_glows_times, self.direct_event_pulse_lengths = (
|
|
310
|
+
self.process_direct_events(direct_events)
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
# TODO: double check that this time is in unix time and is the correct variable
|
|
314
|
+
# TODO: This cannot be in the data because it's a string, put it in the
|
|
315
|
+
# attributes
|
|
316
|
+
# self.unique_identifier = np.datetime_as_string(
|
|
317
|
+
# np.datetime64(int(self.imap_time_last_pps), "ns"), "s"
|
|
318
|
+
# )
|
|
319
|
+
self.glows_time_last_pps = TimeTuple(
|
|
320
|
+
int(self.glows_time_last_pps), glows_ssclk_last_pps
|
|
321
|
+
).to_seconds()
|
|
322
|
+
|
|
323
|
+
with open(
|
|
324
|
+
Path(__file__).parents[1] / "ancillary" / "l1b_conversion_table_v001.json"
|
|
325
|
+
) as f:
|
|
326
|
+
self.ancillary_parameters = AncillaryParameters(json.loads(f.read()))
|
|
327
|
+
|
|
328
|
+
self.filter_temperature = self.ancillary_parameters.decode(
|
|
329
|
+
"filter_temperature", self.filter_temperature
|
|
330
|
+
)
|
|
331
|
+
self.hv_voltage = self.ancillary_parameters.decode(
|
|
332
|
+
"hv_voltage", self.hv_voltage
|
|
333
|
+
)
|
|
334
|
+
self.spin_period = self.ancillary_parameters.decode(
|
|
335
|
+
"spin_period", self.spin_period
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
self.de_flags = np.array(
|
|
339
|
+
[
|
|
340
|
+
catbed_heater_active,
|
|
341
|
+
spin_period_valid,
|
|
342
|
+
spin_phase_at_next_pps_valid,
|
|
343
|
+
spin_period_source,
|
|
344
|
+
glows_time_on_pps_valid,
|
|
345
|
+
time_status_valid,
|
|
346
|
+
housekeeping_valid,
|
|
347
|
+
is_pps_autogenerated,
|
|
348
|
+
hv_test_in_progress,
|
|
349
|
+
pulse_test_in_progress,
|
|
350
|
+
memory_error_detected,
|
|
351
|
+
]
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
@staticmethod
|
|
355
|
+
def process_direct_events(direct_events: np.ndarray) -> tuple:
|
|
356
|
+
"""
|
|
357
|
+
Will process direct events data, separating out the time flags and pulse length.
|
|
358
|
+
|
|
359
|
+
Parameters
|
|
360
|
+
----------
|
|
361
|
+
direct_events : np.ndarray
|
|
362
|
+
Direct event data from L1A, with shape (n, 4) where n is the number of
|
|
363
|
+
direct events.
|
|
364
|
+
|
|
365
|
+
Returns
|
|
366
|
+
-------
|
|
367
|
+
(times, pulse_lengths) : tuple
|
|
368
|
+
Tuple of two np.ndarrays, the first being the times of the direct events
|
|
369
|
+
and the second being the pulse lengths. Both of shape (n,).
|
|
370
|
+
"""
|
|
371
|
+
times = np.zeros((direct_events.shape[0],))
|
|
372
|
+
pulse_lengths = np.zeros((direct_events.shape[0],))
|
|
373
|
+
for index, de in enumerate(direct_events):
|
|
374
|
+
times[index] = TimeTuple(de[0], de[1]).to_seconds()
|
|
375
|
+
pulse_lengths[index] = de[2]
|
|
376
|
+
|
|
377
|
+
return times, pulse_lengths
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
@dataclass
|
|
381
|
+
class HistogramL1B:
|
|
382
|
+
"""
|
|
383
|
+
GLOWS L1B histogram data product, generated from GLOWS L1A histogram data product.
|
|
384
|
+
|
|
385
|
+
All the spice attributes come from the SPICE kernels and are not initialized.
|
|
386
|
+
Other variables are initialized as their encoded or unprocessed values, and then
|
|
387
|
+
decoded or processed in the __post_init__ method.
|
|
388
|
+
|
|
389
|
+
IMPORTANT: The order of the fields inherited from L1A must match the order of the
|
|
390
|
+
fields in the DataSet created in decom_glows.py.
|
|
391
|
+
|
|
392
|
+
Attributes
|
|
393
|
+
----------
|
|
394
|
+
histograms
|
|
395
|
+
array of block-accumulated count numbers
|
|
396
|
+
flight_software_version: str
|
|
397
|
+
seq_count_in_pkts_file: int
|
|
398
|
+
last_spin_id: int
|
|
399
|
+
The ID of the previous spin
|
|
400
|
+
flags_set_onboard: int
|
|
401
|
+
is_generated_on_ground: int
|
|
402
|
+
number_of_spins_per_block
|
|
403
|
+
nblock
|
|
404
|
+
unique_block_identifier
|
|
405
|
+
YYYY-MM-DDThh:mm:ss based on IMAP UTC time
|
|
406
|
+
number_of_bins_per_histogram
|
|
407
|
+
nbin
|
|
408
|
+
number_of_events
|
|
409
|
+
total number of events/counts in histogram
|
|
410
|
+
imap_spin_angle_bin_cntr
|
|
411
|
+
IMAP spin angle ψ for bin centers, see Sec. -
|
|
412
|
+
filter_temperature_average
|
|
413
|
+
block-averaged value, decoded to Celsius degrees using Eq. (47)
|
|
414
|
+
filter_temperature_std_dev
|
|
415
|
+
standard deviation (1 sigma), decoded to Celsius degrees using Eq. (51)
|
|
416
|
+
hv_voltage_average
|
|
417
|
+
block-averaged value, decoded to volts using Eq. (47)
|
|
418
|
+
hv_voltage_std_dev
|
|
419
|
+
standard deviation (1 sigma), decoded to volts using Eq. (51)
|
|
420
|
+
spin_period_average
|
|
421
|
+
block-averaged onboard value, decoded to seconds using Eq. (47)
|
|
422
|
+
spin_period_std_dev
|
|
423
|
+
standard deviation (1 sigma), decoded to seconds using Eq. (51)
|
|
424
|
+
pulse_length_average
|
|
425
|
+
block-averaged value, decoded to μs using Eq. (47)
|
|
426
|
+
pulse_length_std_dev
|
|
427
|
+
standard deviation (1 sigma), decoded to μs using Eq. (51)
|
|
428
|
+
glows_start_time
|
|
429
|
+
GLOWS clock, subseconds as decimal part of float, see Sec. -.1
|
|
430
|
+
glows_end_time_offset
|
|
431
|
+
GLOWS clock, subseconds as decimal part of float, see Sec. -.1
|
|
432
|
+
imap_start_time
|
|
433
|
+
IMAP clock, subseconds as decimal part of float, see Sec. -.1
|
|
434
|
+
imap_end_time_offset
|
|
435
|
+
IMAP clock, subseconds as decimal part of float, see Sec. -.1
|
|
436
|
+
histogram_flag_array
|
|
437
|
+
flags for bad-time information per bin, consisting of [is_close_to_uv_source,
|
|
438
|
+
is_inside_excluded_region, is_excluded_by_instr_team, is_suspected_transient]
|
|
439
|
+
spin_period_ground_average
|
|
440
|
+
block-averaged value computed on ground, see Sec. -.1
|
|
441
|
+
spin_period_ground_std_dev
|
|
442
|
+
standard deviation (1 sigma), see Sec. -.1
|
|
443
|
+
position_angle_offset_average
|
|
444
|
+
block-averaged value in degrees, see Sec. - and -.1
|
|
445
|
+
position_angle_offset_std_dev
|
|
446
|
+
standard deviation (1 sigma), see Sec. - and -.1
|
|
447
|
+
spin_axis_orientation_std_dev
|
|
448
|
+
standard deviation( 1 sigma): ∆λ, ∆φ for ⟨λ⟩, ⟨φ⟩
|
|
449
|
+
spin_axis_orientation_average
|
|
450
|
+
block-averaged spin-axis ecliptic longitude ⟨λ⟩ and latitude ⟨φ⟩ in degrees
|
|
451
|
+
spacecraft_location_average
|
|
452
|
+
block-averaged Cartesian ecliptic coordinates ⟨X⟩, ⟨Y ⟩, ⟨Z⟩ [km] of IMAP
|
|
453
|
+
spacecraft_location_std_dev
|
|
454
|
+
standard deviations (1 sigma) ∆X, ∆Y , ∆Z for ⟨X⟩, ⟨Y ⟩, ⟨Z⟩
|
|
455
|
+
spacecraft_velocity_average
|
|
456
|
+
block-averaged values ⟨VX⟩, ⟨VY⟩, ⟨VZ⟩ [km/s] of IMAP velocity components
|
|
457
|
+
(Cartesian ecliptic frame)
|
|
458
|
+
spacecraft_velocity_std_dev
|
|
459
|
+
standard deviations (1 sigma) ∆VX , ∆VY , ∆VZ for ⟨VX ⟩, ⟨VY ⟩, ⟨VZ ⟩
|
|
460
|
+
flags
|
|
461
|
+
flags for extra information, per histogram. This should be a human-readable
|
|
462
|
+
structure.
|
|
463
|
+
"""
|
|
464
|
+
|
|
465
|
+
histograms: np.ndarray
|
|
466
|
+
flight_software_version: str
|
|
467
|
+
# pkts_file_name: str TODO: add this in L0
|
|
468
|
+
seq_count_in_pkts_file: int
|
|
469
|
+
# l1a_file_name: str TODO: add this
|
|
470
|
+
# ancillary_data_files: np.ndarray TODO Add this
|
|
471
|
+
last_spin_id: int
|
|
472
|
+
flags_set_onboard: int # TODO: this should be renamed in L1B
|
|
473
|
+
is_generated_on_ground: int
|
|
474
|
+
number_of_spins_per_block: int
|
|
475
|
+
number_of_bins_per_histogram: int
|
|
476
|
+
number_of_events: int
|
|
477
|
+
filter_temperature_average: np.double
|
|
478
|
+
filter_temperature_std_dev: np.double
|
|
479
|
+
hv_voltage_average: np.double
|
|
480
|
+
hv_voltage_std_dev: np.double
|
|
481
|
+
spin_period_average: np.double
|
|
482
|
+
spin_period_std_dev: np.double
|
|
483
|
+
pulse_length_average: np.double
|
|
484
|
+
pulse_length_std_dev: np.double
|
|
485
|
+
imap_start_time: np.double # No conversion needed from l1a->l1b
|
|
486
|
+
imap_end_time_offset: np.double # No conversion needed from l1a->l1b
|
|
487
|
+
glows_start_time: np.double # No conversion needed from l1a->l1b
|
|
488
|
+
glows_end_time_offset: np.double # No conversion needed from l1a->l1b
|
|
489
|
+
# unique_block_identifier: str = field(
|
|
490
|
+
# init=False
|
|
491
|
+
# ) # Could be datetime TODO: Can't put a string in data
|
|
492
|
+
imap_spin_angle_bin_cntr: np.ndarray = field(init=False) # Same size as bins
|
|
493
|
+
histogram_flag_array: np.ndarray = field(init=False)
|
|
494
|
+
spin_period_ground_average: np.double = field(init=False) # retrieved from SPICE?
|
|
495
|
+
spin_period_ground_std_dev: np.double = field(init=False) # retrieved from SPICE?
|
|
496
|
+
position_angle_offset_average: np.double = field(init=False) # retrieved from SPICE
|
|
497
|
+
position_angle_offset_std_dev: np.double = field(init=False) # retrieved from SPICE
|
|
498
|
+
spin_axis_orientation_std_dev: np.double = field(init=False) # retrieved from SPICE
|
|
499
|
+
spin_axis_orientation_average: np.double = field(init=False) # retrieved from SPICE
|
|
500
|
+
spacecraft_location_average: np.ndarray = field(init=False) # retrieved from SPIC
|
|
501
|
+
spacecraft_location_std_dev: np.ndarray = field(init=False) # retrieved from SPIC
|
|
502
|
+
spacecraft_velocity_average: np.ndarray = field(init=False) # retrieved from SPIC
|
|
503
|
+
spacecraft_velocity_std_dev: np.ndarray = field(init=False) # retrieved from SPIC
|
|
504
|
+
flags: np.ndarray = field(init=False)
|
|
505
|
+
# TODO:
|
|
506
|
+
# - Determine a good way to output flags as "human readable"
|
|
507
|
+
# - Add spice pieces
|
|
508
|
+
# - add in the filenames for the input files - should they be global attributes?
|
|
509
|
+
# - also unique identifiers
|
|
510
|
+
# - Bad angle algorithm using SPICE locations
|
|
511
|
+
# - Move ancillary file to AWS
|
|
512
|
+
|
|
513
|
+
def __post_init__(self) -> None:
|
|
514
|
+
"""Will process data."""
|
|
515
|
+
# self.histogram_flag_array = np.zeros((2,))
|
|
516
|
+
|
|
517
|
+
# TODO: These pieces will need to be filled in from SPICE kernels. For now,
|
|
518
|
+
# they are placeholders. GLOWS example code has better placeholders if needed.
|
|
519
|
+
self.spin_period_ground_average = np.double(-999.9)
|
|
520
|
+
self.spin_period_ground_std_dev = np.double(-999.9)
|
|
521
|
+
self.position_angle_offset_average = np.double(-999.9)
|
|
522
|
+
self.position_angle_offset_std_dev = np.double(-999.9)
|
|
523
|
+
self.spin_axis_orientation_std_dev = np.double(-999.9)
|
|
524
|
+
self.spin_axis_orientation_average = np.double(-999.9)
|
|
525
|
+
self.spacecraft_location_average = np.array([-999.9, -999.9, -999.9])
|
|
526
|
+
self.spacecraft_location_std_dev = np.array([-999.9, -999.9, -999.9])
|
|
527
|
+
self.spacecraft_velocity_average = np.array([-999.9, -999.9, -999.9])
|
|
528
|
+
self.spacecraft_velocity_std_dev = np.array([-999.9, -999.9, -999.9])
|
|
529
|
+
# Will require some additional inputs
|
|
530
|
+
self.imap_spin_angle_bin_cntr = np.zeros((3600,))
|
|
531
|
+
|
|
532
|
+
# TODO: This should probably be an AWS file
|
|
533
|
+
# TODO Pass in AncillaryParameters object instead of reading here.
|
|
534
|
+
with open(
|
|
535
|
+
Path(__file__).parents[1] / "ancillary" / "l1b_conversion_table_v001.json"
|
|
536
|
+
) as f:
|
|
537
|
+
self.ancillary_parameters = AncillaryParameters(json.loads(f.read()))
|
|
538
|
+
|
|
539
|
+
self.filter_temperature_average = self.ancillary_parameters.decode(
|
|
540
|
+
"filter_temperature", self.filter_temperature_average
|
|
541
|
+
)
|
|
542
|
+
self.filter_temperature_std_dev = self.ancillary_parameters.decode_std_dev(
|
|
543
|
+
"filter_temperature", self.filter_temperature_std_dev
|
|
544
|
+
)
|
|
545
|
+
|
|
546
|
+
self.hv_voltage_average = self.ancillary_parameters.decode(
|
|
547
|
+
"hv_voltage", self.hv_voltage_average
|
|
548
|
+
)
|
|
549
|
+
self.hv_voltage_std_dev = self.ancillary_parameters.decode_std_dev(
|
|
550
|
+
"hv_voltage", self.hv_voltage_std_dev
|
|
551
|
+
)
|
|
552
|
+
self.spin_period_average = self.ancillary_parameters.decode(
|
|
553
|
+
"spin_period", self.spin_period_average
|
|
554
|
+
)
|
|
555
|
+
self.spin_period_std_dev = self.ancillary_parameters.decode_std_dev(
|
|
556
|
+
"spin_period", self.spin_period_std_dev
|
|
557
|
+
)
|
|
558
|
+
self.pulse_length_average = self.ancillary_parameters.decode(
|
|
559
|
+
"pulse_length", self.pulse_length_average
|
|
560
|
+
)
|
|
561
|
+
self.pulse_length_std_dev = self.ancillary_parameters.decode_std_dev(
|
|
562
|
+
"pulse_length", self.pulse_length_std_dev
|
|
563
|
+
)
|
|
564
|
+
|
|
565
|
+
self.histogram_flag_array = np.zeros((4, 3600))
|
|
566
|
+
# self.unique_block_identifier = np.datetime_as_string(
|
|
567
|
+
# np.datetime64(int(self.imap_start_time), "ns"), "s"
|
|
568
|
+
# )
|
|
569
|
+
self.flags = np.zeros((17, 3600))
|
|
570
|
+
|
|
571
|
+
def output_data(self) -> tuple:
|
|
572
|
+
"""
|
|
573
|
+
Output the L1B DataArrays as a tuple.
|
|
574
|
+
|
|
575
|
+
It is faster to return the values like this than to use to_dict() from
|
|
576
|
+
dataclasses.
|
|
577
|
+
|
|
578
|
+
Returns
|
|
579
|
+
-------
|
|
580
|
+
tuple
|
|
581
|
+
A tuple containing each attribute value in the class.
|
|
582
|
+
"""
|
|
583
|
+
return tuple(getattr(self, out.name) for out in dataclasses.fields(self))
|