imap-processing 1.0.37__tar.gz → 1.0.38__tar.gz
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-1.0.37 → imap_processing-1.0.38}/PKG-INFO +2 -2
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_mag_l2_variable_attrs.yaml +2 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cli.py +76 -17
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/l0/process_swe.py +4 -2
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l1b/lo_l1b.py +39 -12
- imap_processing-1.0.38/imap_processing/lo/lo_pivot_kernel.py +227 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l2/mag_l2_data.py +1 -1
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/quality_flags.py +1 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/spice/pointing_frame.py +99 -24
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/constants.py +8 -12
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1b/badtimes.py +21 -19
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1b/de.py +52 -37
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1b/extendedspin.py +44 -24
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1b/goodtimes.py +33 -25
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1b/lookup_utils.py +5 -1
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1b/quality_flag_filters.py +1 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1b/ultra_l1b_culling.py +26 -23
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1b/ultra_l1b_extended.py +72 -49
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +0 -1
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l2/ultra_l2.py +5 -5
- {imap_processing-1.0.37 → imap_processing-1.0.38}/pyproject.toml +2 -2
- {imap_processing-1.0.37 → imap_processing-1.0.38}/LICENSE +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/README.md +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ancillary/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ancillary/ancillary_dataset_combiner.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ccsds/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ccsds/ccsds_data.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ccsds/excel_to_xtce.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_codice_global_cdf_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_codice_l1b_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_codice_l2-hi-direct-events_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_codice_l2-hi-omni_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_codice_l2-hi-sectored_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_codice_l2-lo-angular_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_codice_l2-lo-direct-events_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_codice_l2-lo-species_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_constant_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_default_global_cdf_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_enamaps_l2-common_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_enamaps_l2-healpix_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_enamaps_l2-rectangular_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_glows_global_cdf_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_glows_l1a_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_glows_l1b_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_glows_l2_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_hi_global_cdf_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_hi_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_hit_global_cdf_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_hit_l1a_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_hit_l1b_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_hit_l2_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_ialirt_global_cdf_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_ialirt_l1_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_idex_global_cdf_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_idex_l1a_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_idex_l1b_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_idex_l2a_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_idex_l2b_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_idex_l2c_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_lo_global_cdf_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_lo_l1a_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_lo_l1b_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_lo_l1c_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_mag_global_cdf_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_mag_l1a_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_mag_l1b_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_mag_l1c_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_spacecraft_global_cdf_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_spacecraft_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_swapi_global_cdf_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_swapi_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_swe_global_cdf_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_swe_l1a_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_swe_l1b_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_swe_l2_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_ultra_global_cdf_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_ultra_l1a_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_ultra_l1c_variable_attrs.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_variable_schema.yaml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/imap_cdf_manager.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/utils.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_de.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_hi_counters_aggregated.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_hi_counters_singles.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_hi_omni.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_hi_priority.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_hi_sectored.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_ialirt_hi.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_lo_counters_aggregated.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_lo_counters_singles.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_lo_priority.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_lo_species.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1b.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l2.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/constants.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/data/esa_sweep_values.csv +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/data/lo_stepping_values.csv +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/decompress.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/packet_definitions/P_COD_NHK.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/packet_definitions/imap_codice_packet-definition_20250101_v001.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/packet_definitions/imap_codice_packet-definition_20260129_v001.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/utils.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ena_maps/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ena_maps/ena_maps.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ena_maps/utils/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ena_maps/utils/coordinates.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ena_maps/utils/corrections.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ena_maps/utils/map_utils.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ena_maps/utils/naming.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ena_maps/utils/spatial_utils.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/ancillary/imap_glows_exclusions-by-instr-team_20250923_v002.dat +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/ancillary/imap_glows_map-of-excluded-regions_20250923_v002.dat +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/ancillary/imap_glows_map-of-uv-sources_20250923_v002.dat +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/ancillary/imap_glows_pipeline-settings_20250923_v002.json +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/ancillary/imap_glows_pipeline_settings_v001.json +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/ancillary/imap_glows_suspected-transients_20250923_v002.dat +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/ancillary/l1b_conversion_table_v001.json +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/l0/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/l0/decom_glows.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/l0/glows_l0_data.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/l1a/glows_l1a.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/l1a/glows_l1a_data.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/l1b/glows_l1b.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/l1b/glows_l1b_data.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/l2/glows_l2.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/l2/glows_l2_data.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/packet_definitions/GLX_COMBINED.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/packet_definitions/P_GLX_TMSCDE.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/packet_definitions/P_GLX_TMSCHIST.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/utils/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/utils/constants.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hi/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hi/hi_goodtimes.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hi/hi_l1a.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hi/hi_l1b.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hi/hi_l1c.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hi/hi_l2.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hi/packet_definitions/TLM_HI_COMBINED_SCI.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hi/packet_definitions/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hi/utils.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/hit_utils.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/l0/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/l0/constants.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/l0/decom_hit.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/l1a/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/l1a/hit_l1a.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/l1b/constants.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/l1b/hit_l1b.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/l2/constants.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/l2/hit_l2.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/packet_definitions/hit_packet_definitions.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/calculate_ingest.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/constants.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/generate_coverage.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/l0/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/l0/ialirt_spice.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/l0/mag_l0_ialirt_data.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/l0/parse_mag.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/l0/process_codice.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/l0/process_hit.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/l0/process_status.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/l0/process_swapi.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/packet_definitions/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/packet_definitions/ialirt.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/packet_definitions/ialirt_codicehi.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/packet_definitions/ialirt_codicelo.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/packet_definitions/ialirt_hit.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/packet_definitions/ialirt_mag.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/packet_definitions/ialirt_swapi.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/packet_definitions/ialirt_swe.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/process_ephemeris.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/utils/constants.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/utils/create_xarray.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/utils/grouping.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/utils/time.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/atomic_masses.csv +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/decode.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/evt_msg_decode_utils.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_10_day_CDF_names.csv +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_constants.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_event_flags.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_evt_msg_parsing_dictionaries.json +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_l0.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_l1a.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_l1b.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_l2a.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_l2b.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_utils.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_variable_unpacking_and_eu_conversion.csv +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/packet_definitions/idex_housekeeping_packet_definition.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/packet_definitions/idex_science_packet_definition.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/ancillary_data/imap_lo_bootstrap-correction-factors_v001.csv +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/ancillary_data/imap_lo_hydrogen-geometric-factor_v001.csv +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/ancillary_data/imap_lo_hydrogen-geometric-factor_v004.csv +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/ancillary_data/imap_lo_isn-mask-parameters_v001.csv +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/ancillary_data/imap_lo_oxygen-geometric-factor_v001.csv +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/ancillary_data/imap_lo_oxygen-geometric-factor_v004.csv +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/ancillary_data/imap_lo_sputter-correction-factors_v001.csv +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/ancillary_data/imap_lo_sputter-correction-factors_v002.csv +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/constants.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l0/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l0/decompression_tables/decompression_tables.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l0/decompression_tables/log10_12_to_16_bit_uncompress.csv +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l0/decompression_tables/log10_8_to_12_bit_uncompress.csv +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l0/decompression_tables/log10_8_to_16_bit_uncompress.csv +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l0/lo_apid.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l0/lo_science.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l0/lo_star_sensor.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l0/utils/binary_string.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l0/utils/bit_decompression.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l1a/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l1a/lo_l1a.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l1b/tof_conversions.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l1c/lo_l1c.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l2/lo_l2.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/lo_ancillary.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/packet_definitions/lo_xtce.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/constants.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/imap_mag_sdc_configuration_v001.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l0/decom_mag.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l0/mag_l0_data.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l1a/mag_l1a.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l1a/mag_l1a_data.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l1b/imap_mag_l1b-calibration_20240229_v002.cdf +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l1b/mag_l1b.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l1c/interpolation_methods.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l1c/mag_l1c.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l1d/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l1d/mag_l1d.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l1d/mag_l1d_data.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l2/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l2/mag_l2.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/packet_definitions/MAG_SCI_COMBINED.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/spacecraft/packet_definitions/scid_x252.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/spacecraft/quaternions.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/spice/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/spice/config.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/spice/geometry.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/spice/repoint.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/spice/spin.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/spice/time.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swapi/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swapi/constants.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swapi/l1/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swapi/l1/swapi_l1.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swapi/l2/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swapi/l2/swapi_l2.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swapi/packet_definitions/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swapi/packet_definitions/swapi_packet_definition.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swapi/swapi_utils.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/l1a/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/l1a/swe_l1a.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/l1a/swe_science.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/l1b/swe_l1b.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/l2/swe_l2.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/packet_definitions/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/packet_definitions/swe_packet_definition.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/utils/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/utils/swe_constants.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/utils/swe_utils.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l0/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l0/decom_tools.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l0/decom_ultra.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l0/ultra_utils.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1a/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1a/ultra_l1a.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1b/ultra_l1b.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1b/ultra_l1b_annotated.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/helio_pset.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/l1c_lookup_utils.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/make_helio_index_maps.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/sim_spice_kernels/imap_001.tf +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/sim_spice_kernels/imap_science_100.tf +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/sim_spice_kernels/imap_science_130.tf +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/sim_spice_kernels/imap_sclk_0000.tsc +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/sim_spice_kernels/imap_spk_demo.bsp +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/sim_spice_kernels/naif0012.tls +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/sim_spice_kernels/sim_1yr_imap_attitude.bc +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/sim_spice_kernels/sim_1yr_imap_pointing_frame.bc +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/spacecraft_pset.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/ultra_l1c.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/ultra_l1c_culling.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l2/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l2/ultra_l2_systematic_uncertainties.csv +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/packet_definitions/README.md +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/packet_definitions/ULTRA_SCI_COMBINED.xml +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/packet_definitions/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/utils/__init__.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/utils/ultra_l1_utils.py +0 -0
- {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: imap-processing
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.38
|
|
4
4
|
Summary: IMAP Science Operations Center Processing
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -31,7 +31,7 @@ Provides-Extra: tools
|
|
|
31
31
|
Requires-Dist: astropy-healpix (>=1.0)
|
|
32
32
|
Requires-Dist: cdflib (>=1.3.11)
|
|
33
33
|
Requires-Dist: healpy (>=1.18.0,<2) ; extra == "map-visualization"
|
|
34
|
-
Requires-Dist: imap-data-access (>=
|
|
34
|
+
Requires-Dist: imap-data-access (>=1.3.0)
|
|
35
35
|
Requires-Dist: mypy (==1.10.1) ; extra == "dev"
|
|
36
36
|
Requires-Dist: netcdf4 (>=1.7.2,<2) ; extra == "test"
|
|
37
37
|
Requires-Dist: numpy (>=2,<3)
|
|
@@ -66,6 +66,7 @@ from imap_processing.idex.idex_l1a import idex_l1a
|
|
|
66
66
|
from imap_processing.idex.idex_l1b import idex_l1b
|
|
67
67
|
from imap_processing.idex.idex_l2a import idex_l2a
|
|
68
68
|
from imap_processing.idex.idex_l2b import idex_l2b
|
|
69
|
+
from imap_processing.lo import lo_pivot_kernel
|
|
69
70
|
from imap_processing.lo.constants import LoConstants
|
|
70
71
|
from imap_processing.lo.l1a import lo_l1a
|
|
71
72
|
from imap_processing.lo.l1b import lo_l1b
|
|
@@ -473,6 +474,33 @@ class ProcessInstrument(ABC):
|
|
|
473
474
|
logger.warning(msg)
|
|
474
475
|
return self.version_map.get(descriptor, self._fallback_version)
|
|
475
476
|
|
|
477
|
+
def _resolve_kernel_minor_version(self, descriptor: str) -> int:
|
|
478
|
+
"""
|
|
479
|
+
Return the minor version to use in the filename of a generated kernel.
|
|
480
|
+
|
|
481
|
+
Parameters
|
|
482
|
+
----------
|
|
483
|
+
descriptor : str
|
|
484
|
+
The descriptor of the kernel job, e.g. "pointing-attitude".
|
|
485
|
+
|
|
486
|
+
Returns
|
|
487
|
+
-------
|
|
488
|
+
int
|
|
489
|
+
The minor version for the kernel filename.
|
|
490
|
+
"""
|
|
491
|
+
resolved_version = self._resolve_version(descriptor)
|
|
492
|
+
if resolved_version is None:
|
|
493
|
+
raise ValueError(
|
|
494
|
+
f"No version provided for {descriptor} processing. "
|
|
495
|
+
f"Provide a version for the '{descriptor}' descriptor in "
|
|
496
|
+
"the dependency JSON's version block, or a fallback --version."
|
|
497
|
+
)
|
|
498
|
+
return (
|
|
499
|
+
resolved_version.minor
|
|
500
|
+
if isinstance(resolved_version, Version)
|
|
501
|
+
else int(resolved_version.lstrip("v"))
|
|
502
|
+
)
|
|
503
|
+
|
|
476
504
|
def upload_products(self, products: list[Path]) -> None:
|
|
477
505
|
"""
|
|
478
506
|
Upload data products to the IMAP SDC.
|
|
@@ -1430,9 +1458,48 @@ class Lo(ProcessInstrument):
|
|
|
1430
1458
|
|
|
1431
1459
|
return filtered_dependencies
|
|
1432
1460
|
|
|
1461
|
+
def _generate_pivot_kernel(
|
|
1462
|
+
self, dependencies: ProcessingInputCollection
|
|
1463
|
+
) -> list[Path]:
|
|
1464
|
+
"""
|
|
1465
|
+
Generate the Lo pivot platform CK for the pointing given by repointing.
|
|
1466
|
+
|
|
1467
|
+
Parameters
|
|
1468
|
+
----------
|
|
1469
|
+
dependencies : ProcessingInputCollection
|
|
1470
|
+
Object containing dependencies to process.
|
|
1471
|
+
|
|
1472
|
+
Returns
|
|
1473
|
+
-------
|
|
1474
|
+
list[Path]
|
|
1475
|
+
The generated Lo pivot kernel.
|
|
1476
|
+
"""
|
|
1477
|
+
if self.repointing is None:
|
|
1478
|
+
raise ValueError(
|
|
1479
|
+
"repointing must be provided for pivot-ckernel processing."
|
|
1480
|
+
)
|
|
1481
|
+
nhk_files = dependencies.get_file_paths(
|
|
1482
|
+
source="lo", data_type="l1b", descriptor="nhk"
|
|
1483
|
+
)
|
|
1484
|
+
if len(nhk_files) != 1:
|
|
1485
|
+
raise ValueError(
|
|
1486
|
+
f"Unexpected dependencies found for IMAP-Lo pivot-ckernel: "
|
|
1487
|
+
f"{nhk_files}. Expected exactly one L1B NHK file."
|
|
1488
|
+
)
|
|
1489
|
+
# The repoint table provides the pointing start and end times.
|
|
1490
|
+
if not dependencies.get_file_paths(data_type=RepointInput.data_type):
|
|
1491
|
+
raise ValueError(
|
|
1492
|
+
"A repoint table dependency is required for IMAP-Lo pivot-ckernel "
|
|
1493
|
+
"processing."
|
|
1494
|
+
)
|
|
1495
|
+
minor_version = self._resolve_kernel_minor_version(self.descriptor)
|
|
1496
|
+
return lo_pivot_kernel.generate_lo_pivot_kernel(
|
|
1497
|
+
nhk_files[0], self.repointing, minor_version
|
|
1498
|
+
)
|
|
1499
|
+
|
|
1433
1500
|
def do_processing(
|
|
1434
1501
|
self, dependencies: ProcessingInputCollection
|
|
1435
|
-
) -> list[xr.Dataset]:
|
|
1502
|
+
) -> list[xr.Dataset | Path]:
|
|
1436
1503
|
"""
|
|
1437
1504
|
Perform IMAP-Lo specific processing.
|
|
1438
1505
|
|
|
@@ -1443,12 +1510,15 @@ class Lo(ProcessInstrument):
|
|
|
1443
1510
|
|
|
1444
1511
|
Returns
|
|
1445
1512
|
-------
|
|
1446
|
-
|
|
1447
|
-
|
|
1513
|
+
datasets : list[xarray.Dataset | Path]
|
|
1514
|
+
The list of processed products.
|
|
1448
1515
|
"""
|
|
1449
1516
|
print(f"Processing IMAP-Lo {self.data_level}")
|
|
1450
|
-
datasets: list[xr.Dataset] = []
|
|
1451
|
-
if self.data_level == "
|
|
1517
|
+
datasets: list[xr.Dataset | Path] = []
|
|
1518
|
+
if self.data_level == "l1b" and self.descriptor == "pivot-ckernel":
|
|
1519
|
+
datasets.extend(self._generate_pivot_kernel(dependencies))
|
|
1520
|
+
|
|
1521
|
+
elif self.data_level == "l1a":
|
|
1452
1522
|
# L1A packet / products are 1 to 1. Should only have
|
|
1453
1523
|
# one dependency file
|
|
1454
1524
|
science_files = dependencies.get_file_paths(source="lo", data_type="l0")
|
|
@@ -1859,18 +1929,7 @@ class Spacecraft(ProcessInstrument):
|
|
|
1859
1929
|
data_type=SPICESource.SPICE.value
|
|
1860
1930
|
)
|
|
1861
1931
|
ah_paths = [path for path in spice_inputs if ".ah" in path.suffixes]
|
|
1862
|
-
|
|
1863
|
-
if resolved_version is None:
|
|
1864
|
-
raise ValueError(
|
|
1865
|
-
"No version provided for pointing-attitude processing. "
|
|
1866
|
-
"Provide a version for the 'pointing-attitude' descriptor in "
|
|
1867
|
-
"the dependency JSON's version block, or a fallback --version."
|
|
1868
|
-
)
|
|
1869
|
-
minor_version = (
|
|
1870
|
-
resolved_version.minor
|
|
1871
|
-
if isinstance(resolved_version, Version)
|
|
1872
|
-
else int(resolved_version.lstrip("v"))
|
|
1873
|
-
)
|
|
1932
|
+
minor_version = self._resolve_kernel_minor_version(self.descriptor)
|
|
1874
1933
|
pointing_kernel_paths = pointing_frame.generate_pointing_attitude_kernel(
|
|
1875
1934
|
ah_paths, self.start_date, minor_version
|
|
1876
1935
|
)
|
|
@@ -110,10 +110,12 @@ def prepare_raw_counts(grouped: xr.Dataset, cem_number: int = N_CEMS) -> NDArray
|
|
|
110
110
|
# Example: energy steps 0-1 have the same phi;
|
|
111
111
|
# energy steps 2-3 have the same phi, etc.
|
|
112
112
|
# A depiction of this is shown in Figure 7 of the SWE Algorithm Document.
|
|
113
|
+
# Cast to int64 so the phi calculation does not overflow uint8.
|
|
114
|
+
swe_seq = grouped["swe_seq"].values.astype(np.int64)
|
|
113
115
|
phi_values = np.array(
|
|
114
116
|
[
|
|
115
|
-
(12 + 24 *
|
|
116
|
-
(24 + 24 *
|
|
117
|
+
(12 + 24 * swe_seq) % 360, # Energy steps 0 and 1
|
|
118
|
+
(24 + 24 * swe_seq) % 360, # Energy steps 2 and 3
|
|
117
119
|
]
|
|
118
120
|
)
|
|
119
121
|
phi_bins = phi_to_bin(phi_values).astype(int) # Get phi bin indices
|
|
@@ -1862,6 +1862,44 @@ def get_pivot_angle_from_nhk(ds_nhk: xr.Dataset) -> float:
|
|
|
1862
1862
|
return ds_nhk["pcc_cumulative_cnt_pri"].isel(epoch=nitems // 2).item()
|
|
1863
1863
|
|
|
1864
1864
|
|
|
1865
|
+
def get_median_pivot_angle(ds_nhk: xr.Dataset) -> float:
|
|
1866
|
+
"""
|
|
1867
|
+
Get the median pivot angle from the NHK dataset.
|
|
1868
|
+
|
|
1869
|
+
The median of ``pcc_coarse_pot_pri`` is taken over the samples between
|
|
1870
|
+
``PIVOT_HK_HOUR_RANGE`` hours after the first NHK sample, which avoids the
|
|
1871
|
+
pivot platform motion at the start of a pointing.
|
|
1872
|
+
|
|
1873
|
+
Parameters
|
|
1874
|
+
----------
|
|
1875
|
+
ds_nhk : xr.Dataset
|
|
1876
|
+
The NHK dataset containing pivot angle information.
|
|
1877
|
+
|
|
1878
|
+
Returns
|
|
1879
|
+
-------
|
|
1880
|
+
pivot_angle : float
|
|
1881
|
+
The median pivot angle [degrees], or NaN if the dataset has no records
|
|
1882
|
+
or there are no valid samples within the time range.
|
|
1883
|
+
"""
|
|
1884
|
+
if ds_nhk.sizes.get("epoch", 0) == 0:
|
|
1885
|
+
return np.nan
|
|
1886
|
+
|
|
1887
|
+
hk_epoch_ets = ttj2000ns_to_et(ds_nhk["epoch"])
|
|
1888
|
+
start_et_hk = (
|
|
1889
|
+
hk_epoch_ets[0] + timedelta(hours=c.PIVOT_HK_HOUR_RANGE[0]).total_seconds()
|
|
1890
|
+
)
|
|
1891
|
+
end_et_hk = (
|
|
1892
|
+
hk_epoch_ets[0] + timedelta(hours=c.PIVOT_HK_HOUR_RANGE[1]).total_seconds()
|
|
1893
|
+
)
|
|
1894
|
+
|
|
1895
|
+
coarse_pot_pri = ds_nhk["pcc_coarse_pot_pri"].values
|
|
1896
|
+
return float(
|
|
1897
|
+
np.nanmedian(
|
|
1898
|
+
coarse_pot_pri[(hk_epoch_ets >= start_et_hk) & (hk_epoch_ets <= end_et_hk)]
|
|
1899
|
+
)
|
|
1900
|
+
)
|
|
1901
|
+
|
|
1902
|
+
|
|
1865
1903
|
def _get_esa_level_indices(epochs: np.ndarray, anc_dependencies: list) -> np.ndarray:
|
|
1866
1904
|
"""
|
|
1867
1905
|
Get the ESA level indices (reswept indices) for the given epochs.
|
|
@@ -2485,18 +2523,7 @@ def l1b_bgrates_and_goodtimes( # noqa: PLR0912
|
|
|
2485
2523
|
pivot: float = 90.0
|
|
2486
2524
|
cdf_hk = sci_dependencies.get("imap_lo_l1b_nhk")
|
|
2487
2525
|
if cdf_hk is not None and "pcc_coarse_pot_pri" in cdf_hk:
|
|
2488
|
-
|
|
2489
|
-
start_et_hk = (
|
|
2490
|
-
hk_epoch_ets[0] + timedelta(hours=c.PIVOT_HK_HOUR_RANGE[0]).total_seconds()
|
|
2491
|
-
)
|
|
2492
|
-
end_et_hk = (
|
|
2493
|
-
hk_epoch_ets[0] + timedelta(hours=c.PIVOT_HK_HOUR_RANGE[1]).total_seconds()
|
|
2494
|
-
)
|
|
2495
|
-
|
|
2496
|
-
coarse_pot_pri = cdf_hk["pcc_coarse_pot_pri"].values
|
|
2497
|
-
pivot = np.nanmedian( # type: ignore
|
|
2498
|
-
coarse_pot_pri[(hk_epoch_ets >= start_et_hk) & (hk_epoch_ets <= end_et_hk)]
|
|
2499
|
-
)
|
|
2526
|
+
pivot = get_median_pivot_angle(cdf_hk)
|
|
2500
2527
|
if np.isnan(pivot):
|
|
2501
2528
|
pivot = 90.0
|
|
2502
2529
|
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"""Generate the IMAP-Lo pivot platform attitude kernel (CK)."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import os
|
|
5
|
+
import tempfile
|
|
6
|
+
from datetime import datetime, timezone
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
import imap_data_access
|
|
10
|
+
import numpy as np
|
|
11
|
+
import spiceypy
|
|
12
|
+
|
|
13
|
+
from imap_processing.cdf.utils import load_cdf
|
|
14
|
+
from imap_processing.lo.l1b.lo_l1b import get_median_pivot_angle
|
|
15
|
+
from imap_processing.spice.geometry import SpiceFrame
|
|
16
|
+
from imap_processing.spice.pointing_frame import (
|
|
17
|
+
POINTING_SEGMENT_DTYPE,
|
|
18
|
+
segment_ck_filename,
|
|
19
|
+
write_constant_attitude_ck,
|
|
20
|
+
)
|
|
21
|
+
from imap_processing.spice.repoint import get_pointing_times_from_id
|
|
22
|
+
from imap_processing.spice.time import (
|
|
23
|
+
et_to_utc,
|
|
24
|
+
met_to_sclkticks,
|
|
25
|
+
met_to_utc,
|
|
26
|
+
sct_to_et,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
logger = logging.getLogger(__name__)
|
|
30
|
+
|
|
31
|
+
LO_PIVOT_KERNEL_PREFIX = "imap_lopivot"
|
|
32
|
+
LO_PIVOT_KERNEL_EXTENSION = "bc"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def generate_lo_pivot_kernel(
|
|
36
|
+
l1b_nhk_path: Path, repointing: str, minor_version: int
|
|
37
|
+
) -> list[Path]:
|
|
38
|
+
"""
|
|
39
|
+
Generate the IMAP-Lo pivot platform CK for a single pointing.
|
|
40
|
+
|
|
41
|
+
The kernel contains one constant-attitude segment covering the pointing,
|
|
42
|
+
from the end of its repoint maneuver to the start of the next repoint
|
|
43
|
+
maneuver. There is no coverage during repoint maneuvers, which is when
|
|
44
|
+
the pivot platform is moved.
|
|
45
|
+
|
|
46
|
+
Parameters
|
|
47
|
+
----------
|
|
48
|
+
l1b_nhk_path : Path
|
|
49
|
+
Lo L1B NHK file for the pointing.
|
|
50
|
+
repointing : str
|
|
51
|
+
The pointing to generate the kernel for, in the format 'repoint#####'.
|
|
52
|
+
minor_version : int
|
|
53
|
+
Minor version, from the batch command, to use for the output
|
|
54
|
+
kernel filename.
|
|
55
|
+
|
|
56
|
+
Returns
|
|
57
|
+
-------
|
|
58
|
+
kernel_paths : list[Path]
|
|
59
|
+
Location of the new Lo pivot kernel.
|
|
60
|
+
|
|
61
|
+
Raises
|
|
62
|
+
------
|
|
63
|
+
ValueError
|
|
64
|
+
If `l1b_nhk_path` is not an NHK file for `repointing`.
|
|
65
|
+
FileExistsError
|
|
66
|
+
If the output kernel already exists.
|
|
67
|
+
|
|
68
|
+
Notes
|
|
69
|
+
-----
|
|
70
|
+
Kernels required to be furnished:
|
|
71
|
+
|
|
72
|
+
- Latest NAIF leapseconds kernel (naif0012.tls)
|
|
73
|
+
- The latest IMAP sclk (imap_sclk_NNNN.tsc)
|
|
74
|
+
- The latest IMAP frame kernel (imap_###.tf), which defines IMAP_LO_BASE
|
|
75
|
+
|
|
76
|
+
The repoint table must also be set (`imap_processing.spice.repoint`), as it
|
|
77
|
+
gives the pointing start and end times.
|
|
78
|
+
"""
|
|
79
|
+
repoint_id = imap_data_access.ScienceFilePath(l1b_nhk_path.name).repointing
|
|
80
|
+
if repoint_id is None or f"repoint{repoint_id:05d}" != repointing:
|
|
81
|
+
raise ValueError(f"{l1b_nhk_path.name} is not an NHK file for {repointing}.")
|
|
82
|
+
|
|
83
|
+
segment, pivot_angle = calculate_pivot_segment(l1b_nhk_path, repoint_id)
|
|
84
|
+
|
|
85
|
+
kernel_filename = segment_ck_filename(
|
|
86
|
+
f"{LO_PIVOT_KERNEL_PREFIX}-{repointing}",
|
|
87
|
+
segment,
|
|
88
|
+
minor_version,
|
|
89
|
+
LO_PIVOT_KERNEL_EXTENSION,
|
|
90
|
+
)
|
|
91
|
+
kernel_path = imap_data_access.SPICEFilePath(kernel_filename).construct_path()
|
|
92
|
+
# open_spice_ck_file would append a duplicate segment to an existing file.
|
|
93
|
+
if kernel_path.exists():
|
|
94
|
+
raise FileExistsError(f"Lo pivot kernel already exists: {kernel_path}")
|
|
95
|
+
kernel_path.parent.mkdir(parents=True, exist_ok=True)
|
|
96
|
+
|
|
97
|
+
# Write the kernel in a temporary directory and only publish it once it is
|
|
98
|
+
# complete, so a failed write never leaves a partial kernel at the output
|
|
99
|
+
# path. os.link does not replace an existing file, preserving the
|
|
100
|
+
# no-overwrite behavior even if the kernel appeared during the write.
|
|
101
|
+
with tempfile.TemporaryDirectory(dir=kernel_path.parent) as tmp_dir:
|
|
102
|
+
tmp_kernel_path = Path(tmp_dir) / kernel_path.name
|
|
103
|
+
write_lo_pivot_ck(tmp_kernel_path, segment, pivot_angle, l1b_nhk_path.name)
|
|
104
|
+
os.link(tmp_kernel_path, kernel_path)
|
|
105
|
+
return [kernel_path]
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def calculate_pivot_segment(
|
|
109
|
+
l1b_nhk_path: Path, repoint_id: int
|
|
110
|
+
) -> tuple[np.ndarray, float]:
|
|
111
|
+
"""
|
|
112
|
+
Calculate the data for the single segment of a Lo pivot kernel.
|
|
113
|
+
|
|
114
|
+
Parameters
|
|
115
|
+
----------
|
|
116
|
+
l1b_nhk_path : Path
|
|
117
|
+
Lo L1B NHK file for the pointing.
|
|
118
|
+
repoint_id : int
|
|
119
|
+
Repoint ID of the pointing.
|
|
120
|
+
|
|
121
|
+
Returns
|
|
122
|
+
-------
|
|
123
|
+
segment : numpy.ndarray
|
|
124
|
+
Structured array of POINTING_SEGMENT_DTYPE with one element. The
|
|
125
|
+
quaternion rotates vectors from the IMAP_LO_BASE frame into the
|
|
126
|
+
IMAP_LO frame.
|
|
127
|
+
pivot_angle : float
|
|
128
|
+
Pivot angle [degrees] of the pointing.
|
|
129
|
+
|
|
130
|
+
Raises
|
|
131
|
+
------
|
|
132
|
+
ValueError
|
|
133
|
+
If the NHK file has no valid pivot angle samples.
|
|
134
|
+
"""
|
|
135
|
+
pointing_start_met, pointing_end_met = get_pointing_times_from_id(repoint_id)
|
|
136
|
+
# Use the same pivot angle as the goodtimes product.
|
|
137
|
+
pivot_angle = get_median_pivot_angle(load_cdf(l1b_nhk_path))
|
|
138
|
+
if np.isnan(pivot_angle):
|
|
139
|
+
raise ValueError(f"No valid pivot angle samples in {l1b_nhk_path.name}.")
|
|
140
|
+
logger.info(
|
|
141
|
+
f"repoint{repoint_id:05d} ({met_to_utc(pointing_start_met)}, "
|
|
142
|
+
f"{met_to_utc(pointing_end_met)}): pivot angle {pivot_angle:.4f} deg"
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
segment = np.zeros(1, dtype=POINTING_SEGMENT_DTYPE)
|
|
146
|
+
segment[0]["pointing_id"] = repoint_id
|
|
147
|
+
segment[0]["start_sclk_ticks"] = met_to_sclkticks(pointing_start_met)
|
|
148
|
+
segment[0]["end_sclk_ticks"] = met_to_sclkticks(pointing_end_met)
|
|
149
|
+
segment[0]["quaternion"] = pivot_angle_to_quaternion(pivot_angle)
|
|
150
|
+
return segment, pivot_angle
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def pivot_angle_to_quaternion(pivot_angle: float) -> np.ndarray:
|
|
154
|
+
"""
|
|
155
|
+
Get the SPICE quaternion rotating IMAP_LO_BASE vectors into IMAP_LO.
|
|
156
|
+
|
|
157
|
+
The IMAP_LO frame is the IMAP_LO_BASE frame rotated about its +X axis by
|
|
158
|
+
the pivot angle. The rotation is consistent with
|
|
159
|
+
`imap_processing.spice.geometry.get_lo_pivot_boresight`: the IMAP_LO
|
|
160
|
+
boresight, -Y, expressed in IMAP_LO_BASE is the pivot boresight.
|
|
161
|
+
|
|
162
|
+
Parameters
|
|
163
|
+
----------
|
|
164
|
+
pivot_angle : float
|
|
165
|
+
The pivot angle [degrees].
|
|
166
|
+
|
|
167
|
+
Returns
|
|
168
|
+
-------
|
|
169
|
+
quaternion : numpy.ndarray
|
|
170
|
+
SPICE-style quaternion, shape (4,).
|
|
171
|
+
"""
|
|
172
|
+
# spiceypy.rotate returns the matrix that rotates the coordinate frame by
|
|
173
|
+
# the angle about the axis, i.e. it maps IMAP_LO_BASE vectors into IMAP_LO.
|
|
174
|
+
rotation_matrix = spiceypy.rotate(np.deg2rad(pivot_angle), 1)
|
|
175
|
+
return np.asarray(spiceypy.m2q(rotation_matrix))
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def write_lo_pivot_ck(
|
|
179
|
+
kernel_path: Path,
|
|
180
|
+
segment_data: np.ndarray,
|
|
181
|
+
pivot_angle: float,
|
|
182
|
+
parent_file: str,
|
|
183
|
+
) -> None:
|
|
184
|
+
"""
|
|
185
|
+
Write the Lo pivot CK, recording the pivot angle in the comments.
|
|
186
|
+
|
|
187
|
+
Parameters
|
|
188
|
+
----------
|
|
189
|
+
kernel_path : pathlib.Path
|
|
190
|
+
Location to write the CK kernel.
|
|
191
|
+
segment_data : numpy.ndarray
|
|
192
|
+
Structured array of POINTING_SEGMENT_DTYPE with one element.
|
|
193
|
+
pivot_angle : float
|
|
194
|
+
Pivot angle [degrees] of the pointing.
|
|
195
|
+
parent_file : str
|
|
196
|
+
Filename of the NHK file the pivot angle was derived from.
|
|
197
|
+
"""
|
|
198
|
+
segment = segment_data[0]
|
|
199
|
+
start_utc = et_to_utc(sct_to_et(segment["start_sclk_ticks"]))
|
|
200
|
+
end_utc = et_to_utc(sct_to_et(segment["end_sclk_ticks"]))
|
|
201
|
+
comments = [
|
|
202
|
+
"CK FOR IMAP_LO FRAME (IMAP-LO PIVOT PLATFORM)",
|
|
203
|
+
"==================================================================",
|
|
204
|
+
"",
|
|
205
|
+
f"Original file name: {kernel_path.name}",
|
|
206
|
+
f"Creation date: {datetime.now(timezone.utc).strftime('%Y-%m-%d')}",
|
|
207
|
+
f"Parent files: {[parent_file]}",
|
|
208
|
+
"",
|
|
209
|
+
"The IMAP_LO frame is the IMAP_LO_BASE frame rotated about +X by the",
|
|
210
|
+
"pivot angle, constant over the pointing.",
|
|
211
|
+
"",
|
|
212
|
+
f"Repoint ID: repoint{segment['pointing_id']:05d}",
|
|
213
|
+
f"Pointing start (UTC): {start_utc}",
|
|
214
|
+
f"Pointing end (UTC): {end_utc}",
|
|
215
|
+
f"Pivot angle (deg): {pivot_angle:.4f}",
|
|
216
|
+
"",
|
|
217
|
+
]
|
|
218
|
+
|
|
219
|
+
logger.debug(f"Writing Lo pivot kernel: {kernel_path}")
|
|
220
|
+
write_constant_attitude_ck(
|
|
221
|
+
kernel_path,
|
|
222
|
+
segment_data,
|
|
223
|
+
SpiceFrame.IMAP_LO,
|
|
224
|
+
SpiceFrame.IMAP_LO_BASE,
|
|
225
|
+
comments,
|
|
226
|
+
)
|
|
227
|
+
logger.debug(f"Finished writing Lo pivot kernel: {kernel_path}")
|
|
@@ -47,6 +47,7 @@ class ImapDEOutliersUltraFlags(FlagNameMixin):
|
|
|
47
47
|
INVALID_ENERGY = 2**3 # bit 3
|
|
48
48
|
DURINGREPOINT = 2**4 # bit 4 # event during a repointing
|
|
49
49
|
BACKTOF = 2**5 # bit 5 # Back TOF outlier
|
|
50
|
+
AUXOUTLIER = 2**6 # bit 6 # Event time is outside of aux dataset range.
|
|
50
51
|
|
|
51
52
|
|
|
52
53
|
class ImapHkUltraFlags(FlagNameMixin):
|
|
@@ -66,20 +66,9 @@ def generate_pointing_attitude_kernel(
|
|
|
66
66
|
if len(pointing_segments) == 0:
|
|
67
67
|
raise ValueError("No Pointings covered by input dependencies.")
|
|
68
68
|
|
|
69
|
-
# get the start and end yyyy_doy strings
|
|
70
|
-
start_datetime = spiceypy.et2datetime(
|
|
71
|
-
sct_to_et(pointing_segments[0]["start_sclk_ticks"])
|
|
72
|
-
)
|
|
73
|
-
end_datetime = spiceypy.et2datetime(
|
|
74
|
-
sct_to_et(pointing_segments[-1]["end_sclk_ticks"])
|
|
75
|
-
)
|
|
76
69
|
sorted_ck_paths = list(sorted(imap_attitude_cks, key=lambda x: x.name))
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
sorted_ck_paths[-1].parent / f"imap_dps_"
|
|
80
|
-
f"{start_datetime.strftime('%Y_%j')}_"
|
|
81
|
-
f"{end_datetime.strftime('%Y_%j')}_"
|
|
82
|
-
f"{version_str}.ah.bc"
|
|
70
|
+
pointing_kernel_path = sorted_ck_paths[-1].parent / segment_ck_filename(
|
|
71
|
+
"imap_dps", pointing_segments, minor_version, "ah.bc"
|
|
83
72
|
)
|
|
84
73
|
write_pointing_frame_ck(
|
|
85
74
|
pointing_kernel_path, pointing_segments, [p.name for p in imap_attitude_cks]
|
|
@@ -87,6 +76,45 @@ def generate_pointing_attitude_kernel(
|
|
|
87
76
|
return [pointing_kernel_path]
|
|
88
77
|
|
|
89
78
|
|
|
79
|
+
def segment_ck_filename(
|
|
80
|
+
prefix: str, segment_data: np.ndarray, minor_version: int, extension: str
|
|
81
|
+
) -> str:
|
|
82
|
+
"""
|
|
83
|
+
Build a CK filename from the time coverage of its segments.
|
|
84
|
+
|
|
85
|
+
The filename has the form ``<prefix>_<YYYY_DOY>_<YYYY_DOY>_<NNN>.<extension>``
|
|
86
|
+
where the dates are the start of the first segment and the end of the
|
|
87
|
+
last segment.
|
|
88
|
+
|
|
89
|
+
Parameters
|
|
90
|
+
----------
|
|
91
|
+
prefix : str
|
|
92
|
+
Leading portion of the filename, e.g. "imap_dps".
|
|
93
|
+
segment_data : np.ndarray
|
|
94
|
+
Numpy structured array of POINTING_SEGMENT_DTYPE, sorted by time.
|
|
95
|
+
minor_version : int
|
|
96
|
+
Minor version to use in the filename.
|
|
97
|
+
extension : str
|
|
98
|
+
Filename extension without the leading ".", e.g. "ah.bc".
|
|
99
|
+
|
|
100
|
+
Returns
|
|
101
|
+
-------
|
|
102
|
+
filename : str
|
|
103
|
+
The CK filename.
|
|
104
|
+
"""
|
|
105
|
+
start_datetime = spiceypy.et2datetime(
|
|
106
|
+
sct_to_et(segment_data[0]["start_sclk_ticks"])
|
|
107
|
+
)
|
|
108
|
+
end_datetime = spiceypy.et2datetime(sct_to_et(segment_data[-1]["end_sclk_ticks"]))
|
|
109
|
+
version_str = str(Version(None, minor_version)).lstrip("v")
|
|
110
|
+
return (
|
|
111
|
+
f"{prefix}_"
|
|
112
|
+
f"{start_datetime.strftime('%Y_%j')}_"
|
|
113
|
+
f"{end_datetime.strftime('%Y_%j')}_"
|
|
114
|
+
f"{version_str}.{extension}"
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
|
|
90
118
|
@contextmanager
|
|
91
119
|
def open_spice_ck_file(pointing_frame_path: Path) -> Generator[int, None, None]:
|
|
92
120
|
"""
|
|
@@ -109,7 +137,10 @@ def open_spice_ck_file(pointing_frame_path: Path) -> Generator[int, None, None]:
|
|
|
109
137
|
try:
|
|
110
138
|
yield handle
|
|
111
139
|
finally:
|
|
112
|
-
|
|
140
|
+
# dafcls rather than ckcls: ckcls also raises SPICE(NOSEGMENTSFOUND)
|
|
141
|
+
# when no segment was written, which would leave the file open and
|
|
142
|
+
# replace the original error.
|
|
143
|
+
spiceypy.dafcls(handle)
|
|
113
144
|
|
|
114
145
|
|
|
115
146
|
def write_pointing_frame_ck(
|
|
@@ -142,8 +173,54 @@ def write_pointing_frame_ck(
|
|
|
142
173
|
]
|
|
143
174
|
|
|
144
175
|
logger.debug(f"Writing pointing attitude kernel: {pointing_kernel_path}")
|
|
176
|
+
write_constant_attitude_ck(
|
|
177
|
+
pointing_kernel_path,
|
|
178
|
+
segment_data,
|
|
179
|
+
SpiceFrame.IMAP_DPS,
|
|
180
|
+
SpiceFrame.ECLIPJ2000,
|
|
181
|
+
comments,
|
|
182
|
+
)
|
|
183
|
+
logger.debug(f"Finished writing pointing attitude kernel: {pointing_kernel_path}")
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def write_constant_attitude_ck(
|
|
187
|
+
kernel_path: Path,
|
|
188
|
+
segment_data: np.ndarray,
|
|
189
|
+
frame: SpiceFrame,
|
|
190
|
+
reference_frame: SpiceFrame,
|
|
191
|
+
comments: list[str],
|
|
192
|
+
) -> None:
|
|
193
|
+
"""
|
|
194
|
+
Write a CK with a single constant attitude record per segment.
|
|
195
|
+
|
|
196
|
+
Parameters
|
|
197
|
+
----------
|
|
198
|
+
kernel_path : pathlib.Path
|
|
199
|
+
Location to write the CK kernel.
|
|
200
|
+
segment_data : np.ndarray
|
|
201
|
+
Numpy structured array with the following dtypes:
|
|
202
|
+
("start_sclk_ticks", np.float64),
|
|
203
|
+
("end_sclk_ticks", np.float64),
|
|
204
|
+
("quaternion", np.float64, (4,)),
|
|
205
|
+
("pointing_id", np.uint32),
|
|
206
|
+
frame : SpiceFrame
|
|
207
|
+
Frame whose orientation the CK defines. Also used as the segment
|
|
208
|
+
identifier.
|
|
209
|
+
reference_frame : SpiceFrame
|
|
210
|
+
Frame the orientation is relative to. The quaternion in each segment
|
|
211
|
+
rotates vectors from this frame into `frame`.
|
|
212
|
+
comments : list[str]
|
|
213
|
+
Lines to write to the comment area of the CK.
|
|
214
|
+
|
|
215
|
+
Raises
|
|
216
|
+
------
|
|
217
|
+
ValueError
|
|
218
|
+
If `segment_data` is empty.
|
|
219
|
+
"""
|
|
220
|
+
if len(segment_data) == 0:
|
|
221
|
+
raise ValueError(f"No segments to write to {kernel_path.name}.")
|
|
145
222
|
|
|
146
|
-
with open_spice_ck_file(
|
|
223
|
+
with open_spice_ck_file(kernel_path) as handle:
|
|
147
224
|
# Write the comments to the file
|
|
148
225
|
spiceypy.dafac(handle, comments)
|
|
149
226
|
|
|
@@ -157,12 +234,12 @@ def write_pointing_frame_ck(
|
|
|
157
234
|
segment["start_sclk_ticks"],
|
|
158
235
|
# End time of the segment.
|
|
159
236
|
segment["end_sclk_ticks"],
|
|
160
|
-
#
|
|
161
|
-
|
|
237
|
+
# Frame ID.
|
|
238
|
+
frame.value,
|
|
162
239
|
# Reference frame.
|
|
163
|
-
|
|
240
|
+
reference_frame.name,
|
|
164
241
|
# Identifier.
|
|
165
|
-
|
|
242
|
+
frame.name,
|
|
166
243
|
# Number of pointing intervals.
|
|
167
244
|
1,
|
|
168
245
|
# Start times of individual pointing records within segment.
|
|
@@ -171,18 +248,16 @@ def write_pointing_frame_ck(
|
|
|
171
248
|
# End times of individual pointing records within segment.
|
|
172
249
|
# Since there is only a single record this is equal to sclk_endtim.
|
|
173
250
|
np.array([segment["end_sclk_ticks"]]), # Single stop time
|
|
174
|
-
#
|
|
251
|
+
# Constant quaternion for the segment.
|
|
175
252
|
segment["quaternion"],
|
|
176
|
-
# Angular velocity vectors. The
|
|
177
|
-
#
|
|
253
|
+
# Angular velocity vectors. The attitude is constant over each
|
|
254
|
+
# segment so each segment has zeros here.
|
|
178
255
|
np.array([0.0, 0.0, 0.0]),
|
|
179
256
|
# The number of seconds per encoded spacecraft clock
|
|
180
257
|
# tick for each interval.
|
|
181
258
|
np.array([TICK_DURATION]),
|
|
182
259
|
)
|
|
183
260
|
|
|
184
|
-
logger.debug(f"Finished writing pointing attitude kernel: {pointing_kernel_path}")
|
|
185
|
-
|
|
186
261
|
|
|
187
262
|
def calculate_pointing_attitude_segments(
|
|
188
263
|
ck_paths: list[Path],
|