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.
Files changed (304) hide show
  1. {imap_processing-1.0.37 → imap_processing-1.0.38}/PKG-INFO +2 -2
  2. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_mag_l2_variable_attrs.yaml +2 -0
  3. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cli.py +76 -17
  4. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/l0/process_swe.py +4 -2
  5. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l1b/lo_l1b.py +39 -12
  6. imap_processing-1.0.38/imap_processing/lo/lo_pivot_kernel.py +227 -0
  7. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l2/mag_l2_data.py +1 -1
  8. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/quality_flags.py +1 -0
  9. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/spice/pointing_frame.py +99 -24
  10. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/constants.py +8 -12
  11. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1b/badtimes.py +21 -19
  12. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1b/de.py +52 -37
  13. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1b/extendedspin.py +44 -24
  14. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1b/goodtimes.py +33 -25
  15. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1b/lookup_utils.py +5 -1
  16. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1b/quality_flag_filters.py +1 -0
  17. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1b/ultra_l1b_culling.py +26 -23
  18. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1b/ultra_l1b_extended.py +72 -49
  19. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +0 -1
  20. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l2/ultra_l2.py +5 -5
  21. {imap_processing-1.0.37 → imap_processing-1.0.38}/pyproject.toml +2 -2
  22. {imap_processing-1.0.37 → imap_processing-1.0.38}/LICENSE +0 -0
  23. {imap_processing-1.0.37 → imap_processing-1.0.38}/README.md +0 -0
  24. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/__init__.py +0 -0
  25. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ancillary/__init__.py +0 -0
  26. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ancillary/ancillary_dataset_combiner.py +0 -0
  27. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ccsds/__init__.py +0 -0
  28. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ccsds/ccsds_data.py +0 -0
  29. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ccsds/excel_to_xtce.py +0 -0
  30. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/__init__.py +0 -0
  31. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_codice_global_cdf_attrs.yaml +0 -0
  32. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +0 -0
  33. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_codice_l1b_variable_attrs.yaml +0 -0
  34. {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
  35. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_codice_l2-hi-omni_variable_attrs.yaml +0 -0
  36. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_codice_l2-hi-sectored_variable_attrs.yaml +0 -0
  37. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_codice_l2-lo-angular_variable_attrs.yaml +0 -0
  38. {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
  39. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_codice_l2-lo-species_variable_attrs.yaml +0 -0
  40. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_constant_attrs.yaml +0 -0
  41. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_default_global_cdf_attrs.yaml +0 -0
  42. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_enamaps_l2-common_variable_attrs.yaml +0 -0
  43. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_enamaps_l2-healpix_variable_attrs.yaml +0 -0
  44. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_enamaps_l2-rectangular_variable_attrs.yaml +0 -0
  45. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_glows_global_cdf_attrs.yaml +0 -0
  46. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_glows_l1a_variable_attrs.yaml +0 -0
  47. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_glows_l1b_variable_attrs.yaml +0 -0
  48. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_glows_l2_variable_attrs.yaml +0 -0
  49. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_hi_global_cdf_attrs.yaml +0 -0
  50. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_hi_variable_attrs.yaml +0 -0
  51. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_hit_global_cdf_attrs.yaml +0 -0
  52. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_hit_l1a_variable_attrs.yaml +0 -0
  53. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_hit_l1b_variable_attrs.yaml +0 -0
  54. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_hit_l2_variable_attrs.yaml +0 -0
  55. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_ialirt_global_cdf_attrs.yaml +0 -0
  56. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_ialirt_l1_variable_attrs.yaml +0 -0
  57. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_idex_global_cdf_attrs.yaml +0 -0
  58. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_idex_l1a_variable_attrs.yaml +0 -0
  59. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_idex_l1b_variable_attrs.yaml +0 -0
  60. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_idex_l2a_variable_attrs.yaml +0 -0
  61. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_idex_l2b_variable_attrs.yaml +0 -0
  62. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_idex_l2c_variable_attrs.yaml +0 -0
  63. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_lo_global_cdf_attrs.yaml +0 -0
  64. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_lo_l1a_variable_attrs.yaml +0 -0
  65. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_lo_l1b_variable_attrs.yaml +0 -0
  66. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_lo_l1c_variable_attrs.yaml +0 -0
  67. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_mag_global_cdf_attrs.yaml +0 -0
  68. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_mag_l1a_variable_attrs.yaml +0 -0
  69. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_mag_l1b_variable_attrs.yaml +0 -0
  70. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_mag_l1c_variable_attrs.yaml +0 -0
  71. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_spacecraft_global_cdf_attrs.yaml +0 -0
  72. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_spacecraft_variable_attrs.yaml +0 -0
  73. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_swapi_global_cdf_attrs.yaml +0 -0
  74. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_swapi_variable_attrs.yaml +0 -0
  75. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_swe_global_cdf_attrs.yaml +0 -0
  76. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_swe_l1a_variable_attrs.yaml +0 -0
  77. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_swe_l1b_variable_attrs.yaml +0 -0
  78. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_swe_l2_variable_attrs.yaml +0 -0
  79. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_ultra_global_cdf_attrs.yaml +0 -0
  80. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_ultra_l1a_variable_attrs.yaml +0 -0
  81. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +0 -0
  82. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_ultra_l1c_variable_attrs.yaml +0 -0
  83. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/config/imap_variable_schema.yaml +0 -0
  84. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/imap_cdf_manager.py +0 -0
  85. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/cdf/utils.py +0 -0
  86. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/__init__.py +0 -0
  87. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a.py +0 -0
  88. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_de.py +0 -0
  89. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_hi_counters_aggregated.py +0 -0
  90. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_hi_counters_singles.py +0 -0
  91. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_hi_omni.py +0 -0
  92. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_hi_priority.py +0 -0
  93. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_hi_sectored.py +0 -0
  94. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_ialirt_hi.py +0 -0
  95. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_lo_counters_aggregated.py +0 -0
  96. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_lo_counters_singles.py +0 -0
  97. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_lo_priority.py +0 -0
  98. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1a_lo_species.py +0 -0
  99. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l1b.py +0 -0
  100. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/codice_l2.py +0 -0
  101. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/constants.py +0 -0
  102. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/data/esa_sweep_values.csv +0 -0
  103. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/data/lo_stepping_values.csv +0 -0
  104. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/decompress.py +0 -0
  105. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/packet_definitions/P_COD_NHK.xml +0 -0
  106. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/packet_definitions/imap_codice_packet-definition_20250101_v001.xml +0 -0
  107. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/packet_definitions/imap_codice_packet-definition_20260129_v001.xml +0 -0
  108. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/codice/utils.py +0 -0
  109. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ena_maps/__init__.py +0 -0
  110. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ena_maps/ena_maps.py +0 -0
  111. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ena_maps/utils/__init__.py +0 -0
  112. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ena_maps/utils/coordinates.py +0 -0
  113. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ena_maps/utils/corrections.py +0 -0
  114. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ena_maps/utils/map_utils.py +0 -0
  115. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ena_maps/utils/naming.py +0 -0
  116. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ena_maps/utils/spatial_utils.py +0 -0
  117. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/__init__.py +0 -0
  118. {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
  119. {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
  120. {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
  121. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/ancillary/imap_glows_pipeline-settings_20250923_v002.json +0 -0
  122. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/ancillary/imap_glows_pipeline_settings_v001.json +0 -0
  123. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/ancillary/imap_glows_suspected-transients_20250923_v002.dat +0 -0
  124. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/ancillary/l1b_conversion_table_v001.json +0 -0
  125. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/l0/__init__.py +0 -0
  126. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/l0/decom_glows.py +0 -0
  127. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/l0/glows_l0_data.py +0 -0
  128. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/l1a/glows_l1a.py +0 -0
  129. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/l1a/glows_l1a_data.py +0 -0
  130. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/l1b/glows_l1b.py +0 -0
  131. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/l1b/glows_l1b_data.py +0 -0
  132. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/l2/glows_l2.py +0 -0
  133. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/l2/glows_l2_data.py +0 -0
  134. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/packet_definitions/GLX_COMBINED.xml +0 -0
  135. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/packet_definitions/P_GLX_TMSCDE.xml +0 -0
  136. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/packet_definitions/P_GLX_TMSCHIST.xml +0 -0
  137. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/utils/__init__.py +0 -0
  138. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/glows/utils/constants.py +0 -0
  139. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hi/__init__.py +0 -0
  140. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hi/hi_goodtimes.py +0 -0
  141. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hi/hi_l1a.py +0 -0
  142. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hi/hi_l1b.py +0 -0
  143. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hi/hi_l1c.py +0 -0
  144. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hi/hi_l2.py +0 -0
  145. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hi/packet_definitions/TLM_HI_COMBINED_SCI.xml +0 -0
  146. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hi/packet_definitions/__init__.py +0 -0
  147. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hi/utils.py +0 -0
  148. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/__init__.py +0 -0
  149. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/hit_utils.py +0 -0
  150. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/l0/__init__.py +0 -0
  151. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/l0/constants.py +0 -0
  152. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/l0/decom_hit.py +0 -0
  153. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/l1a/__init__.py +0 -0
  154. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/l1a/hit_l1a.py +0 -0
  155. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/l1b/constants.py +0 -0
  156. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/l1b/hit_l1b.py +0 -0
  157. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/l2/constants.py +0 -0
  158. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/l2/hit_l2.py +0 -0
  159. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/hit/packet_definitions/hit_packet_definitions.xml +0 -0
  160. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/__init__.py +0 -0
  161. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/calculate_ingest.py +0 -0
  162. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/constants.py +0 -0
  163. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/generate_coverage.py +0 -0
  164. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/l0/__init__.py +0 -0
  165. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/l0/ialirt_spice.py +0 -0
  166. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/l0/mag_l0_ialirt_data.py +0 -0
  167. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/l0/parse_mag.py +0 -0
  168. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/l0/process_codice.py +0 -0
  169. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/l0/process_hit.py +0 -0
  170. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/l0/process_status.py +0 -0
  171. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/l0/process_swapi.py +0 -0
  172. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/packet_definitions/__init__.py +0 -0
  173. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/packet_definitions/ialirt.xml +0 -0
  174. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/packet_definitions/ialirt_codicehi.xml +0 -0
  175. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/packet_definitions/ialirt_codicelo.xml +0 -0
  176. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/packet_definitions/ialirt_hit.xml +0 -0
  177. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/packet_definitions/ialirt_mag.xml +0 -0
  178. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/packet_definitions/ialirt_swapi.xml +0 -0
  179. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/packet_definitions/ialirt_swe.xml +0 -0
  180. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/process_ephemeris.py +0 -0
  181. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/utils/constants.py +0 -0
  182. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/utils/create_xarray.py +0 -0
  183. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/utils/grouping.py +0 -0
  184. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ialirt/utils/time.py +0 -0
  185. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/__init__.py +0 -0
  186. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/atomic_masses.csv +0 -0
  187. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/decode.py +0 -0
  188. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/evt_msg_decode_utils.py +0 -0
  189. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_10_day_CDF_names.csv +0 -0
  190. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_constants.py +0 -0
  191. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_event_flags.py +0 -0
  192. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_evt_msg_parsing_dictionaries.json +0 -0
  193. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_l0.py +0 -0
  194. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_l1a.py +0 -0
  195. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_l1b.py +0 -0
  196. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_l2a.py +0 -0
  197. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_l2b.py +0 -0
  198. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_utils.py +0 -0
  199. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/idex_variable_unpacking_and_eu_conversion.csv +0 -0
  200. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/packet_definitions/idex_housekeeping_packet_definition.xml +0 -0
  201. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/idex/packet_definitions/idex_science_packet_definition.xml +0 -0
  202. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/__init__.py +0 -0
  203. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/ancillary_data/imap_lo_bootstrap-correction-factors_v001.csv +0 -0
  204. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/ancillary_data/imap_lo_hydrogen-geometric-factor_v001.csv +0 -0
  205. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/ancillary_data/imap_lo_hydrogen-geometric-factor_v004.csv +0 -0
  206. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/ancillary_data/imap_lo_isn-mask-parameters_v001.csv +0 -0
  207. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/ancillary_data/imap_lo_oxygen-geometric-factor_v001.csv +0 -0
  208. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/ancillary_data/imap_lo_oxygen-geometric-factor_v004.csv +0 -0
  209. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/ancillary_data/imap_lo_sputter-correction-factors_v001.csv +0 -0
  210. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/ancillary_data/imap_lo_sputter-correction-factors_v002.csv +0 -0
  211. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/constants.py +0 -0
  212. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l0/__init__.py +0 -0
  213. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l0/decompression_tables/decompression_tables.py +0 -0
  214. {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
  215. {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
  216. {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
  217. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l0/lo_apid.py +0 -0
  218. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l0/lo_science.py +0 -0
  219. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l0/lo_star_sensor.py +0 -0
  220. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l0/utils/binary_string.py +0 -0
  221. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l0/utils/bit_decompression.py +0 -0
  222. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l1a/__init__.py +0 -0
  223. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l1a/lo_l1a.py +0 -0
  224. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l1b/tof_conversions.py +0 -0
  225. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l1c/lo_l1c.py +0 -0
  226. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/l2/lo_l2.py +0 -0
  227. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/lo_ancillary.py +0 -0
  228. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/lo/packet_definitions/lo_xtce.xml +0 -0
  229. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/__init__.py +0 -0
  230. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/constants.py +0 -0
  231. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/imap_mag_sdc_configuration_v001.py +0 -0
  232. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l0/decom_mag.py +0 -0
  233. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l0/mag_l0_data.py +0 -0
  234. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l1a/mag_l1a.py +0 -0
  235. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l1a/mag_l1a_data.py +0 -0
  236. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l1b/imap_mag_l1b-calibration_20240229_v002.cdf +0 -0
  237. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l1b/mag_l1b.py +0 -0
  238. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l1c/interpolation_methods.py +0 -0
  239. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l1c/mag_l1c.py +0 -0
  240. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l1d/__init__.py +0 -0
  241. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l1d/mag_l1d.py +0 -0
  242. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l1d/mag_l1d_data.py +0 -0
  243. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l2/__init__.py +0 -0
  244. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/l2/mag_l2.py +0 -0
  245. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/mag/packet_definitions/MAG_SCI_COMBINED.xml +0 -0
  246. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/spacecraft/packet_definitions/scid_x252.xml +0 -0
  247. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/spacecraft/quaternions.py +0 -0
  248. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/spice/__init__.py +0 -0
  249. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/spice/config.py +0 -0
  250. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/spice/geometry.py +0 -0
  251. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/spice/repoint.py +0 -0
  252. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/spice/spin.py +0 -0
  253. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/spice/time.py +0 -0
  254. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swapi/__init__.py +0 -0
  255. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swapi/constants.py +0 -0
  256. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swapi/l1/__init__.py +0 -0
  257. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swapi/l1/swapi_l1.py +0 -0
  258. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swapi/l2/__init__.py +0 -0
  259. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swapi/l2/swapi_l2.py +0 -0
  260. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swapi/packet_definitions/__init__.py +0 -0
  261. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swapi/packet_definitions/swapi_packet_definition.xml +0 -0
  262. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swapi/swapi_utils.py +0 -0
  263. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/__init__.py +0 -0
  264. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/l1a/__init__.py +0 -0
  265. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/l1a/swe_l1a.py +0 -0
  266. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/l1a/swe_science.py +0 -0
  267. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/l1b/swe_l1b.py +0 -0
  268. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/l2/swe_l2.py +0 -0
  269. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/packet_definitions/__init__.py +0 -0
  270. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/packet_definitions/swe_packet_definition.xml +0 -0
  271. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/utils/__init__.py +0 -0
  272. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/utils/swe_constants.py +0 -0
  273. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/swe/utils/swe_utils.py +0 -0
  274. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/__init__.py +0 -0
  275. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l0/__init__.py +0 -0
  276. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l0/decom_tools.py +0 -0
  277. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l0/decom_ultra.py +0 -0
  278. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l0/ultra_utils.py +0 -0
  279. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1a/__init__.py +0 -0
  280. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1a/ultra_l1a.py +0 -0
  281. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1b/ultra_l1b.py +0 -0
  282. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1b/ultra_l1b_annotated.py +0 -0
  283. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/helio_pset.py +0 -0
  284. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/l1c_lookup_utils.py +0 -0
  285. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/make_helio_index_maps.py +0 -0
  286. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/sim_spice_kernels/imap_001.tf +0 -0
  287. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/sim_spice_kernels/imap_science_100.tf +0 -0
  288. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/sim_spice_kernels/imap_science_130.tf +0 -0
  289. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/sim_spice_kernels/imap_sclk_0000.tsc +0 -0
  290. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/sim_spice_kernels/imap_spk_demo.bsp +0 -0
  291. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/sim_spice_kernels/naif0012.tls +0 -0
  292. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/sim_spice_kernels/sim_1yr_imap_attitude.bc +0 -0
  293. {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
  294. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/spacecraft_pset.py +0 -0
  295. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/ultra_l1c.py +0 -0
  296. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l1c/ultra_l1c_culling.py +0 -0
  297. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l2/__init__.py +0 -0
  298. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/l2/ultra_l2_systematic_uncertainties.csv +0 -0
  299. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/packet_definitions/README.md +0 -0
  300. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/packet_definitions/ULTRA_SCI_COMBINED.xml +0 -0
  301. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/packet_definitions/__init__.py +0 -0
  302. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/utils/__init__.py +0 -0
  303. {imap_processing-1.0.37 → imap_processing-1.0.38}/imap_processing/ultra/utils/ultra_l1_utils.py +0 -0
  304. {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.37
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 (>=0.42.0)
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)
@@ -52,6 +52,8 @@ vector_attrs: &vectors_default
52
52
  FILLVAL: -1.0e31
53
53
  FORMAT: F13.5
54
54
  LABL_PTR_1: direction_label
55
+ SCALEMAX: 100.0
56
+ SCALEMIN: -100.0
55
57
  UNITS: nT
56
58
  VALIDMAX: 1.0e+5
57
59
  VALIDMIN: -1.0e+5
@@ -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
- dataset : xr.Dataset
1447
- Xr.Dataset of output files.
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 == "l1a":
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
- resolved_version = self._resolve_version(self.descriptor)
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 * grouped["swe_seq"].values) % 360, # Energy steps 0 and 1
116
- (24 + 24 * grouped["swe_seq"].values) % 360, # Energy steps 2 and 3
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
- hk_epoch_ets = ttj2000ns_to_et(cdf_hk["epoch"])
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}")
@@ -243,7 +243,7 @@ class MagL2L1dBase:
243
243
  )
244
244
 
245
245
  quality_flags = xr.DataArray(
246
- self.quality_flags,
246
+ self.quality_flags.astype(np.uint8),
247
247
  name="quality_flags",
248
248
  dims=["epoch"],
249
249
  attrs=attribute_manager.get_variable_attributes("qf"),
@@ -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
- version_str = str(Version(None, minor_version)).lstrip("v")
78
- pointing_kernel_path = (
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
- spiceypy.ckcls(handle)
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(pointing_kernel_path) as handle:
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
- # Pointing frame ID.
161
- SpiceFrame.IMAP_DPS.value,
237
+ # Frame ID.
238
+ frame.value,
162
239
  # Reference frame.
163
- SpiceFrame.ECLIPJ2000.name, # Reference frame
240
+ reference_frame.name,
164
241
  # Identifier.
165
- SpiceFrame.IMAP_DPS.name,
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
- # Average quaternion.
251
+ # Constant quaternion for the segment.
175
252
  segment["quaternion"],
176
- # Angular velocity vectors. The IMAP_DPS frame is quasi-inertial
177
- # for each pointing so each segment has zeros here.
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],