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,764 @@
|
|
|
1
|
+
"""Calculates Extended Raw Events for ULTRA L1b."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from enum import Enum
|
|
5
|
+
from typing import ClassVar
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
import xarray
|
|
9
|
+
from numpy import ndarray
|
|
10
|
+
from numpy.typing import NDArray
|
|
11
|
+
|
|
12
|
+
from imap_processing.ultra.constants import UltraConstants
|
|
13
|
+
from imap_processing.ultra.l1b.lookup_utils import (
|
|
14
|
+
get_back_position,
|
|
15
|
+
get_energy_norm,
|
|
16
|
+
get_image_params,
|
|
17
|
+
get_norm,
|
|
18
|
+
get_y_adjust,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
logger = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class StartType(Enum):
|
|
25
|
+
"""Start Type: 1=Left, 2=Right."""
|
|
26
|
+
|
|
27
|
+
Left = 1
|
|
28
|
+
Right = 2
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class StopType(Enum):
|
|
32
|
+
"""Stop Type: 1=Top, 2=Bottom, SSD: 8-15."""
|
|
33
|
+
|
|
34
|
+
Top = 1
|
|
35
|
+
Bottom = 2
|
|
36
|
+
PH: ClassVar[list[int]] = [1, 2]
|
|
37
|
+
SSD: ClassVar[list[int]] = [8, 9, 10, 11, 12, 13, 14, 15]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class CoinType(Enum):
|
|
41
|
+
"""Coin Type: 1=Top, 2=Bottom."""
|
|
42
|
+
|
|
43
|
+
Top = 1
|
|
44
|
+
Bottom = 2
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def get_front_x_position(start_type: ndarray, start_position_tdc: ndarray) -> ndarray:
|
|
48
|
+
"""
|
|
49
|
+
Calculate the front xf position.
|
|
50
|
+
|
|
51
|
+
Converts Start Position Time to Digital Converter (TDC)
|
|
52
|
+
values into units of hundredths of a millimeter using a scale factor and offsets.
|
|
53
|
+
Further description is available on pages 30 of
|
|
54
|
+
IMAP-Ultra Flight Software Specification document (7523-9009_Rev_-.pdf).
|
|
55
|
+
|
|
56
|
+
Parameters
|
|
57
|
+
----------
|
|
58
|
+
start_type : ndarray
|
|
59
|
+
Start Type: 1=Left, 2=Right.
|
|
60
|
+
start_position_tdc : ndarray
|
|
61
|
+
Start Position Time to Digital Converter (TDC).
|
|
62
|
+
|
|
63
|
+
Returns
|
|
64
|
+
-------
|
|
65
|
+
xf : ndarray
|
|
66
|
+
X front position (hundredths of a millimeter).
|
|
67
|
+
"""
|
|
68
|
+
# Left and right start types.
|
|
69
|
+
indices = np.nonzero((start_type == 1) | (start_type == 2))
|
|
70
|
+
|
|
71
|
+
xftsc = get_image_params("XFTSC")
|
|
72
|
+
xft_lt_off = get_image_params("XFTLTOFF")
|
|
73
|
+
xft_rt_off = get_image_params("XFTRTOFF")
|
|
74
|
+
xft_off = np.where(start_type[indices] == 1, xft_lt_off, xft_rt_off)
|
|
75
|
+
|
|
76
|
+
# Calculate xf and convert to hundredths of a millimeter
|
|
77
|
+
xf: ndarray = (xftsc * -start_position_tdc[indices] + xft_off) * 100
|
|
78
|
+
|
|
79
|
+
return xf
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def get_front_y_position(start_type: ndarray, yb: ndarray) -> tuple[ndarray, ndarray]:
|
|
83
|
+
"""
|
|
84
|
+
Compute the adjustments for the front y position and distance front to back.
|
|
85
|
+
|
|
86
|
+
This function utilizes lookup tables and trigonometry based on
|
|
87
|
+
the angle of the foil. Further description is available in the
|
|
88
|
+
IMAP-Ultra Flight Software Specification document pg 30.
|
|
89
|
+
|
|
90
|
+
Parameters
|
|
91
|
+
----------
|
|
92
|
+
start_type : np.array
|
|
93
|
+
Start Type: 1=Left, 2=Right.
|
|
94
|
+
yb : np.array
|
|
95
|
+
Y back position in hundredths of a millimeter.
|
|
96
|
+
|
|
97
|
+
Returns
|
|
98
|
+
-------
|
|
99
|
+
d : np.array
|
|
100
|
+
Distance front to back in hundredths of a millimeter.
|
|
101
|
+
yf : np.array
|
|
102
|
+
Front y position in hundredths of a millimeter.
|
|
103
|
+
"""
|
|
104
|
+
# Determine start types
|
|
105
|
+
index_left = np.nonzero(start_type == 1)
|
|
106
|
+
index_right = np.nonzero(start_type == 2)
|
|
107
|
+
|
|
108
|
+
yf = np.zeros(len(start_type))
|
|
109
|
+
d = np.zeros(len(start_type))
|
|
110
|
+
|
|
111
|
+
# Compute adjustments for left start type
|
|
112
|
+
dy_lut_left = np.floor(
|
|
113
|
+
(UltraConstants.YF_ESTIMATE_LEFT - yb[index_left] / 100)
|
|
114
|
+
* UltraConstants.N_ELEMENTS
|
|
115
|
+
/ UltraConstants.TRIG_CONSTANT
|
|
116
|
+
+ 0.5
|
|
117
|
+
)
|
|
118
|
+
# y adjustment in mm
|
|
119
|
+
y_adjust_left = get_y_adjust(dy_lut_left) / 100
|
|
120
|
+
# hundredths of a millimeter
|
|
121
|
+
yf[index_left] = (UltraConstants.YF_ESTIMATE_LEFT - y_adjust_left) * 100
|
|
122
|
+
# distance adjustment in mm
|
|
123
|
+
distance_adjust_left = np.sqrt(2) * UltraConstants.D_SLIT_FOIL - y_adjust_left
|
|
124
|
+
# hundredths of a millimeter
|
|
125
|
+
d[index_left] = (UltraConstants.SLIT_Z - distance_adjust_left) * 100
|
|
126
|
+
|
|
127
|
+
# Compute adjustments for right start type
|
|
128
|
+
dy_lut_right = np.floor(
|
|
129
|
+
(yb[index_right] / 100 - UltraConstants.YF_ESTIMATE_RIGHT)
|
|
130
|
+
* UltraConstants.N_ELEMENTS
|
|
131
|
+
/ UltraConstants.TRIG_CONSTANT
|
|
132
|
+
+ 0.5
|
|
133
|
+
)
|
|
134
|
+
# y adjustment in mm
|
|
135
|
+
y_adjust_right = get_y_adjust(dy_lut_right) / 100
|
|
136
|
+
# hundredths of a millimeter
|
|
137
|
+
yf[index_right] = (UltraConstants.YF_ESTIMATE_RIGHT + y_adjust_right) * 100
|
|
138
|
+
# distance adjustment in mm
|
|
139
|
+
distance_adjust_right = np.sqrt(2) * UltraConstants.D_SLIT_FOIL - y_adjust_right
|
|
140
|
+
# hundredths of a millimeter
|
|
141
|
+
d[index_right] = (UltraConstants.SLIT_Z - distance_adjust_right) * 100
|
|
142
|
+
|
|
143
|
+
return np.array(d), np.array(yf)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def get_ph_tof_and_back_positions(
|
|
147
|
+
de_dataset: xarray.Dataset, xf: np.ndarray, sensor: str
|
|
148
|
+
) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
|
|
149
|
+
"""
|
|
150
|
+
Calculate back xb, yb position and tof.
|
|
151
|
+
|
|
152
|
+
An incoming particle may trigger pulses from one of the stop anodes.
|
|
153
|
+
If so, four pulses are produced, one each from the north, south,
|
|
154
|
+
east, and west sides.
|
|
155
|
+
|
|
156
|
+
The Time Of Flight (tof) and the position of the particle at the
|
|
157
|
+
back of the sensor are measured using the timing of the pulses.
|
|
158
|
+
Further description is available on pages 32-33 of
|
|
159
|
+
IMAP-Ultra Flight Software Specification document
|
|
160
|
+
(7523-9009_Rev_-.pdf).
|
|
161
|
+
|
|
162
|
+
Parameters
|
|
163
|
+
----------
|
|
164
|
+
de_dataset : xarray.Dataset
|
|
165
|
+
Data in xarray format.
|
|
166
|
+
xf : np.array
|
|
167
|
+
X front position in (hundredths of a millimeter).
|
|
168
|
+
Has same length as de_dataset.
|
|
169
|
+
sensor : str
|
|
170
|
+
Sensor name.
|
|
171
|
+
|
|
172
|
+
Returns
|
|
173
|
+
-------
|
|
174
|
+
tof : np.array
|
|
175
|
+
Time of flight (nanoseconds).
|
|
176
|
+
t2 : np.array
|
|
177
|
+
Particle time of flight from start to stop (tenths of a nanosecond).
|
|
178
|
+
xb : np.array
|
|
179
|
+
Back positions in x direction (hundredths of a millimeter).
|
|
180
|
+
yb : np.array
|
|
181
|
+
Back positions in y direction (hundredths of a millimeter).
|
|
182
|
+
"""
|
|
183
|
+
indices = np.nonzero(
|
|
184
|
+
np.isin(de_dataset["STOP_TYPE"], [StopType.Top.value, StopType.Bottom.value])
|
|
185
|
+
)[0]
|
|
186
|
+
de_filtered = de_dataset.isel(epoch=indices)
|
|
187
|
+
|
|
188
|
+
xf_ph = xf[indices]
|
|
189
|
+
|
|
190
|
+
# There are mismatches between the stop TDCs, i.e., SpN, SpS, SpE, and SpW.
|
|
191
|
+
# This normalizes the TDCs
|
|
192
|
+
sp_n_norm = get_norm(de_filtered["STOP_NORTH_TDC"].data, "SpN", sensor)
|
|
193
|
+
sp_s_norm = get_norm(de_filtered["STOP_SOUTH_TDC"].data, "SpS", sensor)
|
|
194
|
+
sp_e_norm = get_norm(de_filtered["STOP_EAST_TDC"].data, "SpE", sensor)
|
|
195
|
+
sp_w_norm = get_norm(de_filtered["STOP_WEST_TDC"].data, "SpW", sensor)
|
|
196
|
+
|
|
197
|
+
# Convert normalized TDC values into units of hundredths of a
|
|
198
|
+
# millimeter using lookup tables.
|
|
199
|
+
xb_index = sp_s_norm - sp_n_norm + 2047
|
|
200
|
+
yb_index = sp_e_norm - sp_w_norm + 2047
|
|
201
|
+
|
|
202
|
+
# Convert xf to a tof offset
|
|
203
|
+
tofx = sp_n_norm + sp_s_norm
|
|
204
|
+
tofy = sp_e_norm + sp_w_norm
|
|
205
|
+
|
|
206
|
+
# tof is the average of the two tofs measured in the X and Y directions,
|
|
207
|
+
# tofx and tofy
|
|
208
|
+
# Units in tenths of a nanosecond
|
|
209
|
+
t1 = tofx + tofy # /2 incorporated into scale
|
|
210
|
+
|
|
211
|
+
xb = np.zeros(len(indices))
|
|
212
|
+
yb = np.zeros(len(indices))
|
|
213
|
+
|
|
214
|
+
# particle_tof (t2) used later to compute etof
|
|
215
|
+
t2 = np.zeros(len(indices))
|
|
216
|
+
tof = np.zeros(len(indices))
|
|
217
|
+
|
|
218
|
+
# Stop Type: 1=Top, 2=Bottom
|
|
219
|
+
# Convert converts normalized TDC values into units of
|
|
220
|
+
# hundredths of a millimeter using lookup tables.
|
|
221
|
+
stop_type_top = de_filtered["STOP_TYPE"].data == StopType.Top.value
|
|
222
|
+
xb[stop_type_top] = get_back_position(xb_index[stop_type_top], "XBkTp", sensor)
|
|
223
|
+
yb[stop_type_top] = get_back_position(yb_index[stop_type_top], "YBkTp", sensor)
|
|
224
|
+
|
|
225
|
+
# Correction for the propagation delay of the start anode and other effects.
|
|
226
|
+
t2[stop_type_top] = get_image_params("TOFSC") * t1[
|
|
227
|
+
stop_type_top
|
|
228
|
+
] + get_image_params("TOFTPOFF")
|
|
229
|
+
# Variable xf_ph divided by 10 to convert to mm.
|
|
230
|
+
tof[stop_type_top] = t2[stop_type_top] + xf_ph[
|
|
231
|
+
stop_type_top
|
|
232
|
+
] / 10 * get_image_params("XFTTOF")
|
|
233
|
+
|
|
234
|
+
stop_type_bottom = de_filtered["STOP_TYPE"].data == StopType.Bottom.value
|
|
235
|
+
xb[stop_type_bottom] = get_back_position(
|
|
236
|
+
xb_index[stop_type_bottom], "XBkBt", sensor
|
|
237
|
+
)
|
|
238
|
+
yb[stop_type_bottom] = get_back_position(
|
|
239
|
+
yb_index[stop_type_bottom], "YBkBt", sensor
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
# Correction for the propagation delay of the start anode and other effects.
|
|
243
|
+
t2[stop_type_bottom] = get_image_params("TOFSC") * t1[
|
|
244
|
+
stop_type_bottom
|
|
245
|
+
] + get_image_params("TOFBTOFF") # 10*ns
|
|
246
|
+
|
|
247
|
+
# Variable xf_ph divided by 10 to convert to mm.
|
|
248
|
+
tof[stop_type_bottom] = t2[stop_type_bottom] + xf_ph[
|
|
249
|
+
stop_type_bottom
|
|
250
|
+
] / 10 * get_image_params("XFTTOF")
|
|
251
|
+
|
|
252
|
+
return tof, t2, xb, yb
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def get_path_length(front_position: tuple, back_position: tuple, d: float) -> float:
|
|
256
|
+
"""
|
|
257
|
+
Calculate the path length.
|
|
258
|
+
|
|
259
|
+
Parameters
|
|
260
|
+
----------
|
|
261
|
+
front_position : tuple of floats
|
|
262
|
+
Front position (xf,yf) (hundredths of a millimeter).
|
|
263
|
+
back_position : tuple of floats
|
|
264
|
+
Back position (xb,yb) (hundredths of a millimeter).
|
|
265
|
+
d : float
|
|
266
|
+
Distance from slit to foil (hundredths of a millimeter).
|
|
267
|
+
|
|
268
|
+
Returns
|
|
269
|
+
-------
|
|
270
|
+
path_length : float
|
|
271
|
+
Path length (r) (hundredths of a millimeter).
|
|
272
|
+
"""
|
|
273
|
+
path_length: float = np.sqrt(
|
|
274
|
+
(front_position[0] - back_position[0]) ** 2
|
|
275
|
+
+ (front_position[1] - back_position[1]) ** 2
|
|
276
|
+
+ (d) ** 2
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
return path_length
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
def get_ssd_back_position_and_tof_offset(
|
|
283
|
+
de_dataset: xarray.Dataset,
|
|
284
|
+
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
285
|
+
"""
|
|
286
|
+
Lookup the Y SSD positions (yb), TOF Offset, and SSD number.
|
|
287
|
+
|
|
288
|
+
Parameters
|
|
289
|
+
----------
|
|
290
|
+
de_dataset : xarray.Dataset
|
|
291
|
+
The input dataset containing STOP_TYPE and SSD_FLAG data.
|
|
292
|
+
|
|
293
|
+
Returns
|
|
294
|
+
-------
|
|
295
|
+
yb : np.ndarray
|
|
296
|
+
Y SSD positions in hundredths of a millimeter.
|
|
297
|
+
tof_offset : np.ndarray
|
|
298
|
+
TOF offset.
|
|
299
|
+
ssd_number : np.ndarray
|
|
300
|
+
SSD number.
|
|
301
|
+
|
|
302
|
+
Notes
|
|
303
|
+
-----
|
|
304
|
+
The X back position (xb) is assumed to be 0 for SSD.
|
|
305
|
+
"""
|
|
306
|
+
indices = np.nonzero(np.isin(de_dataset["STOP_TYPE"], StopType.SSD.value))[0]
|
|
307
|
+
de_filtered = de_dataset.isel(epoch=indices)
|
|
308
|
+
|
|
309
|
+
yb = np.zeros(len(indices), dtype=np.float64)
|
|
310
|
+
ssd_number = np.zeros(len(indices), dtype=int)
|
|
311
|
+
tof_offset = np.zeros(len(indices), dtype=np.float64)
|
|
312
|
+
|
|
313
|
+
for i in range(8):
|
|
314
|
+
ssd_flag_mask = de_filtered[f"SSD_FLAG_{i}"].data == 1
|
|
315
|
+
|
|
316
|
+
# Multiply ybs times 100 to convert to hundredths of a millimeter.
|
|
317
|
+
yb[ssd_flag_mask] = get_image_params(f"YBKSSD{i}") * 100
|
|
318
|
+
ssd_number[ssd_flag_mask] = i
|
|
319
|
+
|
|
320
|
+
tof_offset[
|
|
321
|
+
(de_filtered["START_TYPE"] == StartType.Left.value) & ssd_flag_mask
|
|
322
|
+
] = get_image_params(f"TOFSSDLTOFF{i}")
|
|
323
|
+
tof_offset[
|
|
324
|
+
(de_filtered["START_TYPE"] == StartType.Right.value) & ssd_flag_mask
|
|
325
|
+
] = get_image_params(f"TOFSSDRTOFF{i}")
|
|
326
|
+
|
|
327
|
+
return yb, tof_offset, ssd_number
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
def calculate_etof_xc(
|
|
331
|
+
de_subset: xarray.Dataset, particle_tof: np.ndarray, sensor: str, location: str
|
|
332
|
+
) -> tuple[np.ndarray, np.ndarray]:
|
|
333
|
+
"""
|
|
334
|
+
Calculate the etof and xc values for the given subset.
|
|
335
|
+
|
|
336
|
+
Parameters
|
|
337
|
+
----------
|
|
338
|
+
de_subset : xarray.Dataset
|
|
339
|
+
Subset of the dataset for a specific COIN_TYPE.
|
|
340
|
+
particle_tof : np.ndarray
|
|
341
|
+
Particle time of flight (i.e. from start to stop).
|
|
342
|
+
sensor : str
|
|
343
|
+
Sensor name.
|
|
344
|
+
location : str
|
|
345
|
+
Location indicator, either 'TP' (Top) or 'BT' (Bottom).
|
|
346
|
+
|
|
347
|
+
Returns
|
|
348
|
+
-------
|
|
349
|
+
etof : np.ndarray
|
|
350
|
+
Time for the electrons to travel back to the coincidence
|
|
351
|
+
anode (tenths of a nanosecond).
|
|
352
|
+
xc : np.ndarray
|
|
353
|
+
X coincidence position (millimeters).
|
|
354
|
+
"""
|
|
355
|
+
# CoinNNorm
|
|
356
|
+
coin_n_norm = get_norm(de_subset["COIN_NORTH_TDC"], "CoinN", sensor)
|
|
357
|
+
# CoinSNorm
|
|
358
|
+
coin_s_norm = get_norm(de_subset["COIN_SOUTH_TDC"], "CoinS", sensor)
|
|
359
|
+
xc = get_image_params(f"XCOIN{location}SC") * (
|
|
360
|
+
coin_s_norm - coin_n_norm
|
|
361
|
+
) + get_image_params(f"XCOIN{location}OFF") # millimeter
|
|
362
|
+
|
|
363
|
+
# Time for the electrons to travel back to coincidence anode.
|
|
364
|
+
t2 = get_image_params("ETOFSC") * (coin_n_norm + coin_s_norm) + get_image_params(
|
|
365
|
+
f"ETOF{location}OFF"
|
|
366
|
+
)
|
|
367
|
+
|
|
368
|
+
# Multiply by 10 to convert to tenths of a nanosecond.
|
|
369
|
+
etof = t2 * 10 - particle_tof
|
|
370
|
+
|
|
371
|
+
return etof, xc
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
def get_coincidence_positions(
|
|
375
|
+
de_dataset: xarray.Dataset, particle_tof: np.ndarray, sensor: str
|
|
376
|
+
) -> tuple[np.ndarray, np.ndarray]:
|
|
377
|
+
"""
|
|
378
|
+
Calculate coincidence positions.
|
|
379
|
+
|
|
380
|
+
Calculate time for electrons to travel back to
|
|
381
|
+
the coincidence anode (etof) and the x coincidence position (xc).
|
|
382
|
+
|
|
383
|
+
The tof measured by the coincidence anode consists of the particle
|
|
384
|
+
tof from start to stop, plus the time for the electrons to travel
|
|
385
|
+
back to the coincidence anode.
|
|
386
|
+
|
|
387
|
+
Further description is available on pages 34-35 of
|
|
388
|
+
IMAP-Ultra Flight Software Specification document
|
|
389
|
+
(7523-9009_Rev_-.pdf).
|
|
390
|
+
|
|
391
|
+
Parameters
|
|
392
|
+
----------
|
|
393
|
+
de_dataset : xarray.Dataset
|
|
394
|
+
Data in xarray format.
|
|
395
|
+
particle_tof : np.ndarray
|
|
396
|
+
Particle time of flight (i.e. from start to stop)
|
|
397
|
+
(tenths of a nanosecond).
|
|
398
|
+
sensor : str
|
|
399
|
+
Sensor name.
|
|
400
|
+
|
|
401
|
+
Returns
|
|
402
|
+
-------
|
|
403
|
+
etof : np.ndarray
|
|
404
|
+
Time for the electrons to travel back to
|
|
405
|
+
coincidence anode (tenths of a nanosecond).
|
|
406
|
+
xc : np.ndarray
|
|
407
|
+
X coincidence position (hundredths of a millimeter).
|
|
408
|
+
"""
|
|
409
|
+
index_top = np.nonzero(np.isin(de_dataset["COIN_TYPE"], CoinType.Top.value))[0]
|
|
410
|
+
de_top = de_dataset.isel(epoch=index_top)
|
|
411
|
+
|
|
412
|
+
index_bottom = np.nonzero(np.isin(de_dataset["COIN_TYPE"], CoinType.Bottom.value))[
|
|
413
|
+
0
|
|
414
|
+
]
|
|
415
|
+
de_bottom = de_dataset.isel(epoch=index_bottom)
|
|
416
|
+
|
|
417
|
+
etof = np.zeros(len(de_dataset["COIN_TYPE"]), dtype=np.float64)
|
|
418
|
+
xc_array = np.zeros(len(de_dataset["COIN_TYPE"]), dtype=np.float64)
|
|
419
|
+
|
|
420
|
+
# Normalized TDCs
|
|
421
|
+
# For the stop anode, there are mismatches between the coincidence TDCs,
|
|
422
|
+
# i.e., CoinN and CoinS. They must be normalized via lookup tables.
|
|
423
|
+
etof_top, xc_top = calculate_etof_xc(de_top, particle_tof[index_top], sensor, "TP")
|
|
424
|
+
etof[index_top] = etof_top
|
|
425
|
+
xc_array[index_top] = xc_top
|
|
426
|
+
|
|
427
|
+
etof_bottom, xc_bottom = calculate_etof_xc(
|
|
428
|
+
de_bottom, particle_tof[index_bottom], sensor, "BT"
|
|
429
|
+
)
|
|
430
|
+
etof[index_bottom] = etof_bottom
|
|
431
|
+
xc_array[index_bottom] = xc_bottom
|
|
432
|
+
|
|
433
|
+
# Convert to hundredths of a millimeter by multiplying times 100
|
|
434
|
+
return etof, xc_array * 100
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
def get_particle_velocity(
|
|
438
|
+
front_position: tuple[float, float],
|
|
439
|
+
back_position: tuple[float, float],
|
|
440
|
+
d: np.ndarray,
|
|
441
|
+
tof: np.ndarray,
|
|
442
|
+
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
443
|
+
"""
|
|
444
|
+
Determine the particle velocity.
|
|
445
|
+
|
|
446
|
+
The equation is: velocity = ((xf - xb), (yf - yb), d).
|
|
447
|
+
|
|
448
|
+
Further description is available on pages 39 of
|
|
449
|
+
IMAP-Ultra Flight Software Specification document
|
|
450
|
+
(7523-9009_Rev_-.pdf).
|
|
451
|
+
|
|
452
|
+
Parameters
|
|
453
|
+
----------
|
|
454
|
+
front_position : tuple
|
|
455
|
+
Front position (xf,yf) (hundredths of a millimeter).
|
|
456
|
+
back_position : tuple
|
|
457
|
+
Back position (xb,yb) (hundredths of a millimeter).
|
|
458
|
+
d : np.array
|
|
459
|
+
Distance from slit to foil (hundredths of a millimeter).
|
|
460
|
+
tof : np.array
|
|
461
|
+
Time of flight (tenths of a nanosecond).
|
|
462
|
+
|
|
463
|
+
Returns
|
|
464
|
+
-------
|
|
465
|
+
vhat_x : np.array
|
|
466
|
+
Normalized component of the velocity vector in x direction.
|
|
467
|
+
vhat_y : np.array
|
|
468
|
+
Normalized component of the velocity vector in y direction.
|
|
469
|
+
vhat_z : np.array
|
|
470
|
+
Normalized component of the velocity vector in z direction.
|
|
471
|
+
"""
|
|
472
|
+
if tof[tof < 0].any():
|
|
473
|
+
logger.info("Negative tof values found.")
|
|
474
|
+
|
|
475
|
+
delta_x = front_position[0] - back_position[0]
|
|
476
|
+
delta_y = front_position[1] - back_position[1]
|
|
477
|
+
|
|
478
|
+
v_x = delta_x / tof
|
|
479
|
+
v_y = delta_y / tof
|
|
480
|
+
v_z = d / tof
|
|
481
|
+
|
|
482
|
+
# Magnitude of the velocity vector
|
|
483
|
+
magnitude_v = np.sqrt(v_x**2 + v_y**2 + v_z**2)
|
|
484
|
+
|
|
485
|
+
vhat_x = -v_x / magnitude_v
|
|
486
|
+
vhat_y = -v_y / magnitude_v
|
|
487
|
+
vhat_z = -v_z / magnitude_v
|
|
488
|
+
|
|
489
|
+
vhat_x[tof < 0] = np.iinfo(np.int64).min # used as fillvals
|
|
490
|
+
vhat_y[tof < 0] = np.iinfo(np.int64).min
|
|
491
|
+
vhat_z[tof < 0] = np.iinfo(np.int64).min
|
|
492
|
+
|
|
493
|
+
return vhat_x, vhat_y, vhat_z
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
def get_ssd_tof(de_dataset: xarray.Dataset, xf: np.ndarray) -> NDArray[np.float64]:
|
|
497
|
+
"""
|
|
498
|
+
Calculate back xb, yb position for the SSDs.
|
|
499
|
+
|
|
500
|
+
An incoming particle could miss the stop anodes and instead
|
|
501
|
+
hit one of the SSDs between the anodes. Which SSD is hit
|
|
502
|
+
gives a coarse measurement of the y back position;
|
|
503
|
+
the x back position will be fixed.
|
|
504
|
+
|
|
505
|
+
Before hitting the SSD, particles pass through the stop foil;
|
|
506
|
+
dislodged electrons are accelerated back towards the coincidence anode.
|
|
507
|
+
The Coincidence Discrete provides a measure of the TOF.
|
|
508
|
+
A scale factor and offsets, and a multiplier convert xf to a tof offset.
|
|
509
|
+
|
|
510
|
+
Further description is available on pages 36 of
|
|
511
|
+
IMAP-Ultra Flight Software Specification document
|
|
512
|
+
(7523-9009_Rev_-.pdf).
|
|
513
|
+
|
|
514
|
+
Parameters
|
|
515
|
+
----------
|
|
516
|
+
de_dataset : xarray.Dataset
|
|
517
|
+
Data in xarray format.
|
|
518
|
+
xf : np.array
|
|
519
|
+
Front x position (hundredths of a millimeter).
|
|
520
|
+
|
|
521
|
+
Returns
|
|
522
|
+
-------
|
|
523
|
+
tof : np.ndarray
|
|
524
|
+
Time of flight (tenths of a nanosecond).
|
|
525
|
+
"""
|
|
526
|
+
_, tof_offset, ssd_number = get_ssd_back_position_and_tof_offset(de_dataset)
|
|
527
|
+
indices = np.nonzero(np.isin(de_dataset["STOP_TYPE"], [StopType.SSD.value]))[0]
|
|
528
|
+
|
|
529
|
+
de_discrete = de_dataset.isel(epoch=indices)["COIN_DISCRETE_TDC"]
|
|
530
|
+
|
|
531
|
+
time = get_image_params("TOFSSDSC") * de_discrete.values + tof_offset
|
|
532
|
+
|
|
533
|
+
# The scale factor and offsets, and a multiplier to convert xf to a tof offset.
|
|
534
|
+
# Convert xf to mm by dividing by 100.
|
|
535
|
+
tof = (
|
|
536
|
+
time
|
|
537
|
+
+ get_image_params("TOFSSDTOTOFF")
|
|
538
|
+
+ xf[indices] / 100 * get_image_params("XFTTOF")
|
|
539
|
+
) * 10
|
|
540
|
+
|
|
541
|
+
# Convert TOF to tenths of a nanosecond.
|
|
542
|
+
return np.asarray(tof, dtype=np.float64)
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
def get_energy_pulse_height(
|
|
546
|
+
stop_type: np.ndarray, energy: np.ndarray, xb: np.ndarray, yb: np.ndarray
|
|
547
|
+
) -> NDArray[np.float64]:
|
|
548
|
+
"""
|
|
549
|
+
Calculate the pulse-height energy.
|
|
550
|
+
|
|
551
|
+
Calculate energy measured using the
|
|
552
|
+
pulse height from the stop anode.
|
|
553
|
+
Lookup tables (lut) are used for corrections.
|
|
554
|
+
Further description is available on pages 40-41 of
|
|
555
|
+
IMAP-Ultra Flight Software Specification document
|
|
556
|
+
(7523-9009_Rev_-.pdf).
|
|
557
|
+
|
|
558
|
+
Parameters
|
|
559
|
+
----------
|
|
560
|
+
stop_type : np.ndarray
|
|
561
|
+
Stop type: 1=Top, 2=Bottom.
|
|
562
|
+
energy : np.ndarray
|
|
563
|
+
Energy measured using the pulse height.
|
|
564
|
+
xb : np.ndarray
|
|
565
|
+
X back position (hundredths of a millimeter).
|
|
566
|
+
yb : np.ndarray
|
|
567
|
+
Y back position (hundredths of a millimeter).
|
|
568
|
+
|
|
569
|
+
Returns
|
|
570
|
+
-------
|
|
571
|
+
energy_ph : np.ndarray
|
|
572
|
+
Energy measured using the pulse height
|
|
573
|
+
from the stop anode (DN).
|
|
574
|
+
"""
|
|
575
|
+
indices_top = np.where(stop_type == 1)[0]
|
|
576
|
+
indices_bottom = np.where(stop_type == 2)[0]
|
|
577
|
+
|
|
578
|
+
xlut = np.zeros(len(stop_type), dtype=np.float64)
|
|
579
|
+
ylut = np.zeros(len(stop_type), dtype=np.float64)
|
|
580
|
+
energy_ph = np.zeros(len(stop_type), dtype=np.float64)
|
|
581
|
+
|
|
582
|
+
# Stop type 1
|
|
583
|
+
xlut[indices_top] = (xb[indices_top] / 100 - 25 / 2) * 20 / 50 # mm
|
|
584
|
+
ylut[indices_top] = (yb[indices_top] / 100 + 82 / 2) * 32 / 82 # mm
|
|
585
|
+
# Stop type 2
|
|
586
|
+
xlut[indices_bottom] = (xb[indices_bottom] / 100 + 50 + 25 / 2) * 20 / 50 # mm
|
|
587
|
+
ylut[indices_bottom] = (yb[indices_bottom] / 100 + 82 / 2) * 32 / 82 # mm
|
|
588
|
+
|
|
589
|
+
# TODO: waiting on these lookup tables: SpTpPHCorr, SpBtPHCorr
|
|
590
|
+
energy_ph[indices_top] = energy[indices_top] - get_image_params(
|
|
591
|
+
"SPTPPHOFF"
|
|
592
|
+
) # * SpTpPHCorr[
|
|
593
|
+
# xlut[indices_top], ylut[indices_top]] / 1024
|
|
594
|
+
|
|
595
|
+
energy_ph[indices_bottom] = energy[indices_bottom] - get_image_params(
|
|
596
|
+
"SPBTPHOFF"
|
|
597
|
+
) # * SpBtPHCorr[
|
|
598
|
+
# xlut[indices_bottom], ylut[indices_bottom]] / 1024
|
|
599
|
+
|
|
600
|
+
return energy_ph
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
def get_energy_ssd(de_dataset: xarray.Dataset, ssd: np.ndarray) -> NDArray[np.float64]:
|
|
604
|
+
"""
|
|
605
|
+
Get SSD energy.
|
|
606
|
+
|
|
607
|
+
For SSD events, the SSD itself provides a direct
|
|
608
|
+
measurement of the energy. To cover higher energies,
|
|
609
|
+
a so-called composite energy is calculated using the
|
|
610
|
+
SSD energy and SSD energy pulse width.
|
|
611
|
+
The result is then normalized per SSD via a lookup table.
|
|
612
|
+
Further description is available on pages 41 of
|
|
613
|
+
IMAP-Ultra Flight Software Specification document
|
|
614
|
+
(7523-9009_Rev_-.pdf).
|
|
615
|
+
|
|
616
|
+
Parameters
|
|
617
|
+
----------
|
|
618
|
+
de_dataset : xarray.Dataset
|
|
619
|
+
Events dataset.
|
|
620
|
+
ssd : np.ndarray
|
|
621
|
+
SSD number.
|
|
622
|
+
|
|
623
|
+
Returns
|
|
624
|
+
-------
|
|
625
|
+
energy_norm : np.ndarray
|
|
626
|
+
Energy measured using the SSD.
|
|
627
|
+
"""
|
|
628
|
+
ssd_indices = np.where(de_dataset["STOP_TYPE"].data >= 8)[0]
|
|
629
|
+
energy = de_dataset["ENERGY_PH"].data[ssd_indices]
|
|
630
|
+
|
|
631
|
+
composite_energy = np.empty(len(energy), dtype=np.float64)
|
|
632
|
+
|
|
633
|
+
composite_energy[energy >= UltraConstants.COMPOSITE_ENERGY_THRESHOLD] = (
|
|
634
|
+
UltraConstants.COMPOSITE_ENERGY_THRESHOLD
|
|
635
|
+
+ de_dataset["PULSE_WIDTH"].data[ssd_indices][
|
|
636
|
+
energy >= UltraConstants.COMPOSITE_ENERGY_THRESHOLD
|
|
637
|
+
]
|
|
638
|
+
)
|
|
639
|
+
composite_energy[energy < UltraConstants.COMPOSITE_ENERGY_THRESHOLD] = energy[
|
|
640
|
+
energy < UltraConstants.COMPOSITE_ENERGY_THRESHOLD
|
|
641
|
+
]
|
|
642
|
+
|
|
643
|
+
energy_norm = get_energy_norm(ssd, composite_energy)
|
|
644
|
+
|
|
645
|
+
return energy_norm
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
def get_ctof(tof: np.ndarray, path_length: np.ndarray) -> NDArray:
|
|
649
|
+
"""
|
|
650
|
+
Calculate the corrected TOF.
|
|
651
|
+
|
|
652
|
+
The corrected TOF (ctof) is the TOF normalized with respect
|
|
653
|
+
to a fixed distance dmin between the front and back detectors.
|
|
654
|
+
The normalized TOF is termed the corrected TOF (ctof).
|
|
655
|
+
Further description is available on pages 42-44 of
|
|
656
|
+
IMAP-Ultra Flight Software Specification document
|
|
657
|
+
(7523-9009_Rev_-.pdf).
|
|
658
|
+
|
|
659
|
+
Parameters
|
|
660
|
+
----------
|
|
661
|
+
tof : np.ndarray
|
|
662
|
+
Time of flight (tenths of a nanosecond).
|
|
663
|
+
path_length : np.ndarray
|
|
664
|
+
Path length (r) (hundredths of a millimeter).
|
|
665
|
+
|
|
666
|
+
Returns
|
|
667
|
+
-------
|
|
668
|
+
ctof : np.ndarray
|
|
669
|
+
Corrected TOF (tenths of a ns).
|
|
670
|
+
"""
|
|
671
|
+
# Multiply times 100 to convert to hundredths of a millimeter.
|
|
672
|
+
ctof = tof * UltraConstants.DMIN * 100 / path_length
|
|
673
|
+
|
|
674
|
+
return ctof
|
|
675
|
+
|
|
676
|
+
|
|
677
|
+
def determine_species_pulse_height(
|
|
678
|
+
energy: np.ndarray, tof: np.ndarray, path_length: np.ndarray
|
|
679
|
+
) -> NDArray:
|
|
680
|
+
"""
|
|
681
|
+
Determine the species for pulse-height events.
|
|
682
|
+
|
|
683
|
+
Species is determined from the particle energy and velocity.
|
|
684
|
+
For velocity, the particle TOF is normalized with respect
|
|
685
|
+
to a fixed distance dmin between the front and back detectors.
|
|
686
|
+
The normalized TOF is termed the corrected TOF (ctof).
|
|
687
|
+
Particle species are determined from
|
|
688
|
+
the energy and ctof using a lookup table.
|
|
689
|
+
|
|
690
|
+
Further description is available on pages 42-44 of
|
|
691
|
+
IMAP-Ultra Flight Software Specification document
|
|
692
|
+
(7523-9009_Rev_-.pdf).
|
|
693
|
+
|
|
694
|
+
Parameters
|
|
695
|
+
----------
|
|
696
|
+
energy : np.ndarray
|
|
697
|
+
Energy from the SSD event (keV).
|
|
698
|
+
tof : np.ndarray
|
|
699
|
+
Time of flight of the SSD event (tenths of a nanosecond).
|
|
700
|
+
path_length : np.ndarray
|
|
701
|
+
Path length (r) (hundredths of a millimeter).
|
|
702
|
+
|
|
703
|
+
Returns
|
|
704
|
+
-------
|
|
705
|
+
bin : np.array
|
|
706
|
+
Species bin.
|
|
707
|
+
"""
|
|
708
|
+
# PH event TOF normalization to Z axis
|
|
709
|
+
ctof = get_ctof(tof, path_length)
|
|
710
|
+
# TODO: need lookup tables
|
|
711
|
+
# placeholder
|
|
712
|
+
bin = np.zeros(len(ctof))
|
|
713
|
+
# bin = PHxTOFSpecies[ctof, energy]
|
|
714
|
+
|
|
715
|
+
return bin
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
def determine_species_ssd(
|
|
719
|
+
energy: np.ndarray, tof: np.ndarray, path_length: np.ndarray
|
|
720
|
+
) -> NDArray:
|
|
721
|
+
"""
|
|
722
|
+
Determine the species for SSD events.
|
|
723
|
+
|
|
724
|
+
Species is determined from the particle's energy and velocity.
|
|
725
|
+
For velocity, the particle's TOF is normalized with respect
|
|
726
|
+
to a fixed distance dmin between the front and back detectors.
|
|
727
|
+
For SSD events, an adjustment is also made to the path length
|
|
728
|
+
to account for the shorter distances that such events
|
|
729
|
+
travel to reach the detector. The normalized TOF is termed
|
|
730
|
+
the corrected tof (ctof). Particle species are determined from
|
|
731
|
+
the energy and cTOF using a lookup table.
|
|
732
|
+
|
|
733
|
+
Further description is available on pages 42-44 of
|
|
734
|
+
IMAP-Ultra Flight Software Specification document
|
|
735
|
+
(7523-9009_Rev_-.pdf).
|
|
736
|
+
|
|
737
|
+
Parameters
|
|
738
|
+
----------
|
|
739
|
+
energy : np.ndarray
|
|
740
|
+
Energy from the SSD event (keV).
|
|
741
|
+
tof : np.ndarray
|
|
742
|
+
Time of flight of the SSD event (tenths of a nanosecond).
|
|
743
|
+
path_length : np.ndarray
|
|
744
|
+
Path length (r) (hundredths of a millimeter).
|
|
745
|
+
|
|
746
|
+
Returns
|
|
747
|
+
-------
|
|
748
|
+
bin : np.ndarray
|
|
749
|
+
Species bin.
|
|
750
|
+
"""
|
|
751
|
+
# SSD event TOF normalization to Z axis
|
|
752
|
+
ctof = get_ctof(tof, path_length)
|
|
753
|
+
|
|
754
|
+
bin = np.zeros(len(ctof)) # placeholder
|
|
755
|
+
|
|
756
|
+
# TODO: get these lookup tables
|
|
757
|
+
# if r < get_image_params("PathSteepThresh"):
|
|
758
|
+
# # bin = ExTOFSpeciesSteep[energy, ctof]
|
|
759
|
+
# elif r < get_image_params("PathMediumThresh"):
|
|
760
|
+
# # bin = ExTOFSpeciesMedium[energy, ctof]
|
|
761
|
+
# else:
|
|
762
|
+
# # bin = ExTOFSpeciesFlat[energy, ctof]
|
|
763
|
+
|
|
764
|
+
return bin
|