imap-processing 0.9.0__py3-none-any.whl → 0.11.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of imap-processing might be problematic. Click here for more details.

Files changed (243) hide show
  1. imap_processing/_version.py +2 -2
  2. imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +749 -442
  3. imap_processing/cdf/config/imap_glows_global_cdf_attrs.yaml +7 -0
  4. imap_processing/cdf/config/imap_glows_l1a_variable_attrs.yaml +8 -2
  5. imap_processing/cdf/config/imap_glows_l1b_variable_attrs.yaml +0 -1
  6. imap_processing/cdf/config/imap_glows_l2_variable_attrs.yaml +358 -0
  7. imap_processing/cdf/config/imap_hi_variable_attrs.yaml +59 -25
  8. imap_processing/cdf/config/imap_hit_global_cdf_attrs.yaml +22 -0
  9. imap_processing/cdf/config/imap_idex_l1a_variable_attrs.yaml +32 -8
  10. imap_processing/cdf/config/imap_idex_l1b_variable_attrs.yaml +94 -5
  11. imap_processing/cdf/config/imap_lo_l1a_variable_attrs.yaml +65 -37
  12. imap_processing/cdf/config/imap_swapi_variable_attrs.yaml +16 -1
  13. imap_processing/cdf/config/imap_swe_global_cdf_attrs.yaml +7 -0
  14. imap_processing/cdf/config/imap_swe_l1a_variable_attrs.yaml +14 -14
  15. imap_processing/cdf/config/imap_swe_l1b_variable_attrs.yaml +25 -24
  16. imap_processing/cdf/config/imap_swe_l2_variable_attrs.yaml +238 -0
  17. imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +100 -92
  18. imap_processing/cdf/utils.py +2 -2
  19. imap_processing/cli.py +45 -9
  20. imap_processing/codice/codice_l1a.py +104 -58
  21. imap_processing/codice/constants.py +111 -155
  22. imap_processing/codice/data/esa_sweep_values.csv +256 -256
  23. imap_processing/codice/data/lo_stepping_values.csv +128 -128
  24. imap_processing/ena_maps/ena_maps.py +519 -0
  25. imap_processing/ena_maps/utils/map_utils.py +145 -0
  26. imap_processing/ena_maps/utils/spatial_utils.py +226 -0
  27. imap_processing/glows/__init__.py +3 -0
  28. imap_processing/glows/ancillary/imap_glows_pipeline_settings_v001.json +52 -0
  29. imap_processing/glows/l1a/glows_l1a.py +72 -14
  30. imap_processing/glows/l1b/glows_l1b.py +2 -1
  31. imap_processing/glows/l1b/glows_l1b_data.py +25 -1
  32. imap_processing/glows/l2/glows_l2.py +324 -0
  33. imap_processing/glows/l2/glows_l2_data.py +156 -51
  34. imap_processing/hi/l1a/science_direct_event.py +57 -51
  35. imap_processing/hi/l1b/hi_l1b.py +43 -28
  36. imap_processing/hi/l1c/hi_l1c.py +225 -42
  37. imap_processing/hi/utils.py +20 -3
  38. imap_processing/hit/l0/constants.py +2 -2
  39. imap_processing/hit/l0/decom_hit.py +1 -1
  40. imap_processing/hit/l1a/hit_l1a.py +94 -13
  41. imap_processing/hit/l1b/hit_l1b.py +158 -9
  42. imap_processing/ialirt/l0/process_codicehi.py +156 -0
  43. imap_processing/ialirt/l0/process_codicelo.py +5 -2
  44. imap_processing/ialirt/packet_definitions/ialirt.xml +28 -20
  45. imap_processing/ialirt/packet_definitions/ialirt_codicehi.xml +241 -0
  46. imap_processing/ialirt/packet_definitions/ialirt_swapi.xml +170 -0
  47. imap_processing/ialirt/packet_definitions/ialirt_swe.xml +258 -0
  48. imap_processing/ialirt/process_ephemeris.py +72 -40
  49. imap_processing/idex/decode.py +241 -0
  50. imap_processing/idex/idex_l1a.py +143 -81
  51. imap_processing/idex/idex_l1b.py +244 -10
  52. imap_processing/lo/l0/lo_science.py +61 -0
  53. imap_processing/lo/l1a/lo_l1a.py +98 -10
  54. imap_processing/lo/l1b/lo_l1b.py +2 -2
  55. imap_processing/lo/l1c/lo_l1c.py +2 -2
  56. imap_processing/lo/packet_definitions/lo_xtce.xml +1082 -9178
  57. imap_processing/mag/l0/decom_mag.py +2 -2
  58. imap_processing/mag/l1a/mag_l1a.py +7 -7
  59. imap_processing/mag/l1a/mag_l1a_data.py +62 -30
  60. imap_processing/mag/l1b/mag_l1b.py +11 -6
  61. imap_processing/quality_flags.py +18 -3
  62. imap_processing/spice/geometry.py +149 -177
  63. imap_processing/spice/kernels.py +26 -26
  64. imap_processing/spice/spin.py +233 -0
  65. imap_processing/spice/time.py +96 -31
  66. imap_processing/swapi/l1/swapi_l1.py +60 -31
  67. imap_processing/swapi/packet_definitions/swapi_packet_definition.xml +363 -384
  68. imap_processing/swe/l1a/swe_l1a.py +8 -3
  69. imap_processing/swe/l1a/swe_science.py +24 -24
  70. imap_processing/swe/l1b/swe_l1b.py +2 -1
  71. imap_processing/swe/l1b/swe_l1b_science.py +181 -122
  72. imap_processing/swe/l2/swe_l2.py +337 -70
  73. imap_processing/swe/utils/swe_utils.py +28 -0
  74. imap_processing/tests/cdf/test_utils.py +2 -2
  75. imap_processing/tests/codice/conftest.py +20 -17
  76. imap_processing/tests/codice/data/validation/imap_codice_l1a_hskp_20241110193622_v0.0.0.cdf +0 -0
  77. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-counters-aggregated_20241110193700_v0.0.0.cdf +0 -0
  78. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-counters-singles_20241110193700_v0.0.0.cdf +0 -0
  79. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-nsw-angular_20241110193700_v0.0.0.cdf +0 -0
  80. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-nsw-priority_20241110193700_v0.0.0.cdf +0 -0
  81. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-nsw-species_20241110193700_v0.0.0.cdf +0 -0
  82. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-sw-angular_20241110193700_v0.0.0.cdf +0 -0
  83. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-sw-priority_20241110193700_v0.0.0.cdf +0 -0
  84. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-sw-species_20241110193700_v0.0.0.cdf +0 -0
  85. imap_processing/tests/codice/test_codice_l0.py +55 -121
  86. imap_processing/tests/codice/test_codice_l1a.py +147 -59
  87. imap_processing/tests/conftest.py +81 -22
  88. imap_processing/tests/ena_maps/test_ena_maps.py +309 -0
  89. imap_processing/tests/ena_maps/test_map_utils.py +286 -0
  90. imap_processing/tests/ena_maps/test_spatial_utils.py +161 -0
  91. imap_processing/tests/glows/conftest.py +7 -1
  92. imap_processing/tests/glows/test_glows_l1a_cdf.py +3 -7
  93. imap_processing/tests/glows/test_glows_l1a_data.py +34 -6
  94. imap_processing/tests/glows/test_glows_l1b_data.py +29 -17
  95. imap_processing/tests/glows/test_glows_l2.py +101 -0
  96. imap_processing/tests/hi/conftest.py +3 -3
  97. imap_processing/tests/hi/data/l1/imap_hi_l1b_45sensor-de_20250415_v999.cdf +0 -0
  98. imap_processing/tests/hi/data/l1/imap_his_pset-calibration-prod-config_20240101_v001.csv +31 -0
  99. imap_processing/tests/hi/test_hi_l1b.py +14 -9
  100. imap_processing/tests/hi/test_hi_l1c.py +136 -36
  101. imap_processing/tests/hi/test_l1a.py +0 -2
  102. imap_processing/tests/hi/test_science_direct_event.py +18 -14
  103. imap_processing/tests/hi/test_utils.py +16 -11
  104. imap_processing/tests/hit/helpers/__init__.py +0 -0
  105. imap_processing/tests/hit/helpers/l1_validation.py +405 -0
  106. imap_processing/tests/hit/test_data/sci_sample.ccsds +0 -0
  107. imap_processing/tests/hit/test_decom_hit.py +8 -10
  108. imap_processing/tests/hit/test_hit_l1a.py +117 -180
  109. imap_processing/tests/hit/test_hit_l1b.py +149 -55
  110. imap_processing/tests/hit/validation_data/hit_l1b_standard_sample2_nsrl_v4_3decimals.csv +62 -0
  111. imap_processing/tests/hit/validation_data/sci_sample_raw.csv +62 -0
  112. imap_processing/tests/ialirt/test_data/l0/20240827095047_SWE_IALIRT_packet.bin +0 -0
  113. imap_processing/tests/ialirt/test_data/l0/BinLog CCSDS_FRAG_TLM_20240826_152323Z_IALIRT_data_for_SDC.bin +0 -0
  114. imap_processing/tests/ialirt/test_data/l0/eu_SWP_IAL_20240826_152033.csv +644 -0
  115. imap_processing/tests/ialirt/test_data/l0/hi_fsw_view_1_ccsds.bin +0 -0
  116. imap_processing/tests/ialirt/test_data/l0/idle_export_eu.SWE_IALIRT_20240827_093852.csv +914 -0
  117. imap_processing/tests/ialirt/test_data/l0/imap_codice_l1a_hi-ialirt_20240523200000_v0.0.0.cdf +0 -0
  118. imap_processing/tests/ialirt/unit/test_process_codicehi.py +106 -0
  119. imap_processing/tests/ialirt/unit/test_process_ephemeris.py +33 -5
  120. imap_processing/tests/ialirt/unit/test_process_swapi.py +85 -0
  121. imap_processing/tests/ialirt/unit/test_process_swe.py +106 -0
  122. imap_processing/tests/idex/conftest.py +29 -1
  123. imap_processing/tests/idex/test_data/compressed_2023_102_14_24_55.pkts +0 -0
  124. imap_processing/tests/idex/test_data/non_compressed_2023_102_14_22_26.pkts +0 -0
  125. imap_processing/tests/idex/test_idex_l0.py +6 -3
  126. imap_processing/tests/idex/test_idex_l1a.py +151 -1
  127. imap_processing/tests/idex/test_idex_l1b.py +124 -2
  128. imap_processing/tests/lo/test_lo_l1a.py +62 -2
  129. imap_processing/tests/lo/test_lo_science.py +85 -0
  130. imap_processing/tests/lo/validation_data/Instrument_FM1_T104_R129_20240803_ILO_SPIN_EU.csv +2 -0
  131. imap_processing/tests/mag/conftest.py +16 -0
  132. imap_processing/tests/mag/test_mag_decom.py +6 -4
  133. imap_processing/tests/mag/test_mag_l1a.py +36 -7
  134. imap_processing/tests/mag/test_mag_l1b.py +55 -4
  135. imap_processing/tests/mag/test_mag_validation.py +148 -0
  136. imap_processing/tests/mag/validation/L1a/T001/all_p_ones.txt +19200 -0
  137. imap_processing/tests/mag/validation/L1a/T001/mag-l0-l1a-t001-in.bin +0 -0
  138. imap_processing/tests/mag/validation/L1a/T001/mag-l0-l1a-t001-out.csv +17 -0
  139. imap_processing/tests/mag/validation/L1a/T002/all_n_ones.txt +19200 -0
  140. imap_processing/tests/mag/validation/L1a/T002/mag-l0-l1a-t002-in.bin +0 -0
  141. imap_processing/tests/mag/validation/L1a/T002/mag-l0-l1a-t002-out.csv +17 -0
  142. imap_processing/tests/mag/validation/L1a/T003/field_like.txt +19200 -0
  143. imap_processing/tests/mag/validation/L1a/T003/mag-l0-l1a-t003-in.bin +0 -0
  144. imap_processing/tests/mag/validation/L1a/T003/mag-l0-l1a-t003-out.csv +17 -0
  145. imap_processing/tests/mag/validation/L1a/T004/field_like.txt +19200 -0
  146. imap_processing/tests/mag/validation/L1a/T004/mag-l0-l1a-t004-in.bin +0 -0
  147. imap_processing/tests/mag/validation/L1a/T004/mag-l0-l1a-t004-out.csv +17 -0
  148. imap_processing/tests/mag/validation/L1a/T005/field_like_range_change.txt +19200 -0
  149. imap_processing/tests/mag/validation/L1a/T005/mag-l0-l1a-t005-in.bin +0 -0
  150. imap_processing/tests/mag/validation/L1a/T005/mag-l0-l1a-t005-out.csv +17 -0
  151. imap_processing/tests/mag/validation/L1a/T006/hdr_field.txt +19200 -0
  152. imap_processing/tests/mag/validation/L1a/T006/mag-l0-l1a-t006-in.bin +0 -0
  153. imap_processing/tests/mag/validation/L1a/T006/mag-l0-l1a-t006-out.csv +17 -0
  154. imap_processing/tests/mag/validation/L1a/T007/hdr_field_and_range_change.txt +19200 -0
  155. imap_processing/tests/mag/validation/L1a/T007/mag-l0-l1a-t007-in.bin +0 -0
  156. imap_processing/tests/mag/validation/L1a/T007/mag-l0-l1a-t007-out.csv +17 -0
  157. imap_processing/tests/mag/validation/L1a/T008/field_like_range_change.txt +19200 -0
  158. imap_processing/tests/mag/validation/L1a/T008/mag-l0-l1a-t008-in.bin +0 -0
  159. imap_processing/tests/mag/validation/L1a/T008/mag-l0-l1a-t008-out.csv +17 -0
  160. imap_processing/tests/mag/validation/L1b/T009/data.bin +0 -0
  161. imap_processing/tests/mag/validation/L1b/T009/field_like_all_ranges.txt +19200 -0
  162. imap_processing/tests/mag/validation/L1b/T009/mag-l1a-l1b-t009-in.csv +17 -0
  163. imap_processing/tests/mag/validation/L1b/T009/mag-l1a-l1b-t009-magi-out.csv +17 -0
  164. imap_processing/tests/mag/validation/L1b/T009/mag-l1a-l1b-t009-mago-out.csv +17 -0
  165. imap_processing/tests/mag/validation/L1b/T010/data.bin +0 -0
  166. imap_processing/tests/mag/validation/L1b/T010/field_like_all_ranges.txt +19200 -0
  167. imap_processing/tests/mag/validation/L1b/T010/mag-l1a-l1b-t010-in.csv +17 -0
  168. imap_processing/tests/mag/validation/L1b/T010/mag-l1a-l1b-t010-magi-out.csv +17 -0
  169. imap_processing/tests/mag/validation/L1b/T010/mag-l1a-l1b-t010-mago-out.csv +17 -0
  170. imap_processing/tests/mag/validation/L1b/T011/data.bin +0 -0
  171. imap_processing/tests/mag/validation/L1b/T011/field_like_all_ranges.txt +19200 -0
  172. imap_processing/tests/mag/validation/L1b/T011/mag-l1a-l1b-t011-in.csv +17 -0
  173. imap_processing/tests/mag/validation/L1b/T011/mag-l1a-l1b-t011-magi-out.csv +17 -0
  174. imap_processing/tests/mag/validation/L1b/T011/mag-l1a-l1b-t011-mago-out.csv +17 -0
  175. imap_processing/tests/spice/test_geometry.py +128 -133
  176. imap_processing/tests/spice/test_kernels.py +37 -37
  177. imap_processing/tests/spice/test_spin.py +184 -0
  178. imap_processing/tests/spice/test_time.py +43 -20
  179. imap_processing/tests/swapi/test_swapi_l1.py +11 -10
  180. imap_processing/tests/swapi/test_swapi_l2.py +13 -3
  181. imap_processing/tests/swe/test_swe_l1a.py +1 -1
  182. imap_processing/tests/swe/test_swe_l1b.py +20 -3
  183. imap_processing/tests/swe/test_swe_l1b_science.py +54 -35
  184. imap_processing/tests/swe/test_swe_l2.py +148 -5
  185. imap_processing/tests/test_cli.py +39 -7
  186. imap_processing/tests/test_quality_flags.py +19 -19
  187. imap_processing/tests/test_utils.py +3 -2
  188. imap_processing/tests/ultra/test_data/l0/ultra45_raw_sc_ultrarawimg_withFSWcalcs_FM45_40P_Phi28p5_BeamCal_LinearScan_phi2850_theta-000_20240207T102740.csv +3314 -3314
  189. imap_processing/tests/ultra/test_data/mock_data.py +161 -0
  190. imap_processing/tests/ultra/unit/conftest.py +73 -0
  191. imap_processing/tests/ultra/unit/test_badtimes.py +58 -0
  192. imap_processing/tests/ultra/unit/test_cullingmask.py +87 -0
  193. imap_processing/tests/ultra/unit/test_de.py +61 -60
  194. imap_processing/tests/ultra/unit/test_ultra_l1a.py +3 -3
  195. imap_processing/tests/ultra/unit/test_ultra_l1b.py +51 -77
  196. imap_processing/tests/ultra/unit/test_ultra_l1b_annotated.py +5 -5
  197. imap_processing/tests/ultra/unit/test_ultra_l1b_culling.py +114 -0
  198. imap_processing/tests/ultra/unit/test_ultra_l1b_extended.py +86 -26
  199. imap_processing/tests/ultra/unit/test_ultra_l1c.py +1 -1
  200. imap_processing/tests/ultra/unit/test_ultra_l1c_pset_bins.py +3 -3
  201. imap_processing/ultra/constants.py +11 -1
  202. imap_processing/ultra/l1a/ultra_l1a.py +2 -2
  203. imap_processing/ultra/l1b/badtimes.py +22 -5
  204. imap_processing/ultra/l1b/cullingmask.py +31 -5
  205. imap_processing/ultra/l1b/de.py +32 -37
  206. imap_processing/ultra/l1b/extendedspin.py +44 -20
  207. imap_processing/ultra/l1b/ultra_l1b.py +21 -22
  208. imap_processing/ultra/l1b/ultra_l1b_culling.py +190 -0
  209. imap_processing/ultra/l1b/ultra_l1b_extended.py +81 -30
  210. imap_processing/ultra/l1c/histogram.py +6 -2
  211. imap_processing/ultra/l1c/pset.py +6 -2
  212. imap_processing/ultra/l1c/ultra_l1c.py +2 -3
  213. imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +4 -3
  214. imap_processing/ultra/utils/ultra_l1_utils.py +70 -14
  215. imap_processing/utils.py +2 -2
  216. {imap_processing-0.9.0.dist-info → imap_processing-0.11.0.dist-info}/METADATA +7 -2
  217. {imap_processing-0.9.0.dist-info → imap_processing-0.11.0.dist-info}/RECORD +235 -152
  218. imap_processing/tests/codice/data/eu_unit_lookup_table.csv +0 -101
  219. imap_processing/tests/codice/data/idle_export_eu.COD_NHK_20230822_122700 2.csv +0 -100
  220. imap_processing/tests/codice/data/idle_export_raw.COD_NHK_20230822_122700.csv +0 -100
  221. imap_processing/tests/codice/data/imap_codice_l0_raw_20241110_v001.pkts +0 -0
  222. imap_processing/tests/hi/test_data/l1a/imap_hi_l1a_45sensor-de_20250415_v000.cdf +0 -0
  223. imap_processing/tests/hit/test_data/sci_sample1.ccsds +0 -0
  224. imap_processing/tests/ultra/unit/test_spatial_utils.py +0 -125
  225. imap_processing/ultra/utils/spatial_utils.py +0 -221
  226. /imap_processing/tests/hi/{test_data → data}/l0/20231030_H45_APP_NHK.bin +0 -0
  227. /imap_processing/tests/hi/{test_data → data}/l0/20231030_H45_APP_NHK.csv +0 -0
  228. /imap_processing/tests/hi/{test_data → data}/l0/20231030_H45_SCI_CNT.bin +0 -0
  229. /imap_processing/tests/hi/{test_data → data}/l0/20231030_H45_SCI_DE.bin +0 -0
  230. /imap_processing/tests/hi/{test_data → data}/l0/H90_NHK_20241104.bin +0 -0
  231. /imap_processing/tests/hi/{test_data → data}/l0/H90_sci_cnt_20241104.bin +0 -0
  232. /imap_processing/tests/hi/{test_data → data}/l0/H90_sci_de_20241104.bin +0 -0
  233. /imap_processing/tests/hi/{test_data → data}/l0/README.txt +0 -0
  234. /imap_processing/tests/idex/{imap_idex_l0_raw_20231214_v001.pkts → test_data/imap_idex_l0_raw_20231214_v001.pkts} +0 -0
  235. /imap_processing/tests/idex/{impact_14_tof_high_data.txt → test_data/impact_14_tof_high_data.txt} +0 -0
  236. /imap_processing/tests/mag/{imap_mag_l1a_norm-magi_20251017_v001.cdf → validation/imap_mag_l1a_norm-magi_20251017_v001.cdf} +0 -0
  237. /imap_processing/tests/mag/{mag_l0_test_data.pkts → validation/mag_l0_test_data.pkts} +0 -0
  238. /imap_processing/tests/mag/{mag_l0_test_output.csv → validation/mag_l0_test_output.csv} +0 -0
  239. /imap_processing/tests/mag/{mag_l1_test_data.pkts → validation/mag_l1_test_data.pkts} +0 -0
  240. /imap_processing/tests/mag/{mag_l1a_test_output.csv → validation/mag_l1a_test_output.csv} +0 -0
  241. {imap_processing-0.9.0.dist-info → imap_processing-0.11.0.dist-info}/LICENSE +0 -0
  242. {imap_processing-0.9.0.dist-info → imap_processing-0.11.0.dist-info}/WHEEL +0 -0
  243. {imap_processing-0.9.0.dist-info → imap_processing-0.11.0.dist-info}/entry_points.txt +0 -0
@@ -1,5 +1,5 @@
1
1
  """
2
- Functions for computing geometry, many of which use SPICE.
2
+ Functions for computing geometry, many of which use SPICEYPY.
3
3
 
4
4
  Paradigms for developing this module:
5
5
 
@@ -9,16 +9,13 @@ Paradigms for developing this module:
9
9
  * Always return numpy arrays for vectorized calls.
10
10
  """
11
11
 
12
- import os
13
12
  import typing
14
13
  from enum import IntEnum
15
- from pathlib import Path
16
14
  from typing import Union
17
15
 
18
16
  import numpy as np
19
17
  import numpy.typing as npt
20
- import pandas as pd
21
- import spiceypy as spice
18
+ import spiceypy
22
19
  from numpy.typing import NDArray
23
20
 
24
21
  from imap_processing.spice.kernels import ensure_spice
@@ -33,17 +30,18 @@ class SpiceBody(IntEnum):
33
30
  # IMAP Pointing Frame (Despun) as defined in imap_science_0001.tf
34
31
  IMAP_DPS = -43901
35
32
  # Standard NAIF bodies
36
- SOLAR_SYSTEM_BARYCENTER = spice.bodn2c("SOLAR_SYSTEM_BARYCENTER")
37
- SUN = spice.bodn2c("SUN")
38
- EARTH = spice.bodn2c("EARTH")
33
+ SOLAR_SYSTEM_BARYCENTER = spiceypy.bodn2c("SOLAR_SYSTEM_BARYCENTER")
34
+ SUN = spiceypy.bodn2c("SUN")
35
+ EARTH = spiceypy.bodn2c("EARTH")
39
36
 
40
37
 
41
38
  class SpiceFrame(IntEnum):
42
39
  """Enum containing SPICE IDs for reference frames, defined in imap_wkcp.tf."""
43
40
 
44
41
  # Standard SPICE Frames
45
- J2000 = spice.irfnum("J2000")
46
- ECLIPJ2000 = spice.irfnum("ECLIPJ2000")
42
+ J2000 = spiceypy.irfnum("J2000")
43
+ ECLIPJ2000 = spiceypy.irfnum("ECLIPJ2000")
44
+ ITRF93 = 13000
47
45
  # IMAP Pointing Frame (Despun) as defined in imap_science_0001.tf
48
46
  IMAP_DPS = -43901
49
47
  # IMAP specific as defined in imap_wkcp.tf
@@ -85,6 +83,7 @@ BORESIGHT_LOOKUP = {
85
83
  def imap_state(
86
84
  et: Union[np.ndarray, float],
87
85
  ref_frame: SpiceFrame = SpiceFrame.ECLIPJ2000,
86
+ abcorr: str = "NONE",
88
87
  observer: SpiceBody = SpiceBody.SUN,
89
88
  ) -> np.ndarray:
90
89
  """
@@ -96,10 +95,12 @@ def imap_state(
96
95
  ----------
97
96
  et : np.ndarray or float
98
97
  Epoch time(s) [J2000 seconds] to get the IMAP state for.
99
- ref_frame : SpiceFrame
98
+ ref_frame : SpiceFrame (Optional)
100
99
  Reference frame which the IMAP state is expressed in. Default is
101
100
  SpiceFrame.ECLIPJ2000.
102
- observer : SpiceBody
101
+ abcorr : str (Optional)
102
+ Aberration correction flag. Default is "NONE".
103
+ observer : SpiceBody (Optional)
103
104
  Observing body. Default is SpiceBody.SUN.
104
105
 
105
106
  Returns
@@ -108,163 +109,12 @@ def imap_state(
108
109
  The Cartesian state vector representing the position and velocity of the
109
110
  IMAP spacecraft.
110
111
  """
111
- state, _ = spice.spkezr(
112
- SpiceBody.IMAP.name, et, ref_frame.name, "NONE", observer.name
112
+ state, _ = spiceypy.spkezr(
113
+ SpiceBody.IMAP.name, et, ref_frame.name, abcorr, observer.name
113
114
  )
114
115
  return np.asarray(state)
115
116
 
116
117
 
117
- def get_spin_data() -> pd.DataFrame:
118
- """
119
- Read spin file using environment variable and return spin data.
120
-
121
- SPIN_DATA_FILEPATH environment variable would be a fixed value.
122
- It could be s3 filepath that can be used to download the data
123
- through API or it could be path EFS or Batch volume mount path.
124
-
125
- Spin data should contain the following fields:
126
- * spin_number
127
- * spin_start_sec
128
- * spin_start_subsec
129
- * spin_period_sec
130
- * spin_period_valid
131
- * spin_phase_valid
132
- * spin_period_source
133
- * thruster_firing
134
-
135
- Returns
136
- -------
137
- spin_data : pandas.DataFrame
138
- Spin data.
139
- """
140
- spin_data_filepath = os.getenv("SPIN_DATA_FILEPATH")
141
- if spin_data_filepath is not None:
142
- path_to_spin_file = Path(spin_data_filepath)
143
- else:
144
- # Handle the case where the environment variable is not set
145
- raise ValueError("SPIN_DATA_FILEPATH environment variable is not set.")
146
-
147
- spin_df = pd.read_csv(path_to_spin_file, comment="#")
148
- # Combine spin_start_sec and spin_start_subsec to get the spin start
149
- # time in seconds. The spin start subseconds are in milliseconds.
150
- spin_df["spin_start_time"] = (
151
- spin_df["spin_start_sec"] + spin_df["spin_start_subsec"] / 1e3
152
- )
153
-
154
- return spin_df
155
-
156
-
157
- def get_spacecraft_spin_phase(
158
- query_met_times: Union[float, npt.NDArray],
159
- ) -> Union[float, npt.NDArray]:
160
- """
161
- Get the spacecraft spin phase for the input query times.
162
-
163
- Formula to calculate spin phase:
164
- spin_phase = (query_met_times - spin_start_time) / spin_period_sec
165
-
166
- Parameters
167
- ----------
168
- query_met_times : float or np.ndarray
169
- Query times in Mission Elapsed Time (MET).
170
-
171
- Returns
172
- -------
173
- spin_phase : float or np.ndarray
174
- Spin phase for the input query times.
175
- """
176
- spin_df = get_spin_data()
177
-
178
- # Ensure query_met_times is an array
179
- query_met_times = np.asarray(query_met_times)
180
- is_scalar = query_met_times.ndim == 0
181
- if is_scalar:
182
- # Force scalar to array because np.asarray() will not
183
- # convert scalar to array
184
- query_met_times = np.atleast_1d(query_met_times)
185
- # Empty array check
186
- if query_met_times.size == 0:
187
- return query_met_times
188
-
189
- # Create an empty array to store spin phase results
190
- spin_phases = np.zeros_like(query_met_times)
191
-
192
- # Find all spin time that are less or equal to query_met_times.
193
- # To do that, use side right, a[i-1] <= v < a[i], in the searchsorted.
194
- # Eg.
195
- # >>> df['a']
196
- # array([0, 15, 30, 45, 60])
197
- # >>> np.searchsorted(df['a'], [0, 13, 15, 32, 70], side='right')
198
- # array([1, 1, 2, 3, 5])
199
- last_spin_indices = (
200
- np.searchsorted(spin_df["spin_start_time"], query_met_times, side="right") - 1
201
- )
202
- # Make sure input times are within the bounds of spin data
203
- spin_df_start_time = spin_df["spin_start_time"].values[0]
204
- spin_df_end_time = (
205
- spin_df["spin_start_time"].values[-1] + spin_df["spin_period_sec"].values[-1]
206
- )
207
- input_start_time = query_met_times.min()
208
- input_end_time = query_met_times.max()
209
- if input_start_time < spin_df_start_time or input_end_time >= spin_df_end_time:
210
- raise ValueError(
211
- f"Query times, {query_met_times} are outside of the spin data range, "
212
- f"{spin_df_start_time, spin_df_end_time}."
213
- )
214
-
215
- # Calculate spin phase
216
- spin_phases = (
217
- query_met_times - spin_df["spin_start_time"].values[last_spin_indices]
218
- ) / spin_df["spin_period_sec"].values[last_spin_indices]
219
-
220
- # Check for invalid spin phase using below checks:
221
- # 1. Check that the spin phase is in valid range, [0, 1).
222
- # 2. Check invalid spin phase using spin_phase_valid,
223
- # spin_period_valid columns.
224
- invalid_spin_phase_range = (spin_phases < 0) | (spin_phases >= 1)
225
-
226
- invalid_spins = (spin_df["spin_phase_valid"].values[last_spin_indices] == 0) | (
227
- spin_df["spin_period_valid"].values[last_spin_indices] == 0
228
- )
229
- bad_spin_phases = invalid_spin_phase_range | invalid_spins
230
- spin_phases[bad_spin_phases] = np.nan
231
-
232
- if is_scalar:
233
- return spin_phases[0]
234
- return spin_phases
235
-
236
-
237
- def get_instrument_spin_phase(
238
- query_met_times: Union[float, npt.NDArray],
239
- instrument: SpiceFrame,
240
- ) -> Union[float, npt.NDArray]:
241
- """
242
- Get the instrument spin phase for the input query times.
243
-
244
- Formula to calculate spin phase:
245
- instrument_spin_phase = (spacecraft_spin_phase + instrument_spin_offset) % 1
246
-
247
- Parameters
248
- ----------
249
- query_met_times : float or np.ndarray
250
- Query times in Mission Elapsed Time (MET).
251
- instrument : SpiceFrame
252
- Instrument frame to calculate spin phase for.
253
-
254
- Returns
255
- -------
256
- spin_phase : float or np.ndarray
257
- Instrument spin phase for the input query times. Spin phase is a
258
- floating point number in the range [0, 1) corresponding to the
259
- spin angle / 360.
260
- """
261
- spacecraft_spin_phase = get_spacecraft_spin_phase(query_met_times)
262
- instrument_spin_phase_offset = get_spacecraft_to_instrument_spin_phase_offset(
263
- instrument
264
- )
265
- return (spacecraft_spin_phase + instrument_spin_phase_offset) % 1
266
-
267
-
268
118
  def get_spacecraft_to_instrument_spin_phase_offset(instrument: SpiceFrame) -> float:
269
119
  """
270
120
  Get the spin phase offset from the spacecraft to the instrument.
@@ -314,9 +164,9 @@ def frame_transform(
314
164
  This function is a vectorized equivalent to performing the following SPICE
315
165
  calls for each input time and position vector to perform the transform.
316
166
  The matrix multiplication step is done using `numpy.matmul` rather than
317
- `spice.mxv`.
318
- >>> rotation_matrix = spice.pxform(from_frame, to_frame, et)
319
- ... result = spice.mxv(rotation_matrix, position)
167
+ `spiceypy.mxv`.
168
+ >>> rotation_matrix = spiceypy.pxform(from_frame, to_frame, et)
169
+ ... result = spiceypy.mxv(rotation_matrix, position)
320
170
 
321
171
  Parameters
322
172
  ----------
@@ -339,6 +189,10 @@ def frame_transform(
339
189
  result : np.ndarray
340
190
  3d Cartesian position vector(s) in reference frame `to_frame`.
341
191
  """
192
+ # If from_frame and to_frame are the same, no rotation needed
193
+ if from_frame == to_frame:
194
+ return position
195
+
342
196
  if position.ndim == 1:
343
197
  if not len(position) == 3:
344
198
  raise ValueError(
@@ -372,6 +226,56 @@ def frame_transform(
372
226
  return result
373
227
 
374
228
 
229
+ def frame_transform_az_el(
230
+ et: Union[float, npt.NDArray],
231
+ az_el: npt.NDArray,
232
+ from_frame: SpiceFrame,
233
+ to_frame: SpiceFrame,
234
+ degrees: bool = True,
235
+ ) -> npt.NDArray:
236
+ """
237
+ Transform azimuth and elevation coordinates between reference frames.
238
+
239
+ Parameters
240
+ ----------
241
+ et : float or np.ndarray
242
+ Ephemeris time(s) corresponding to position(s).
243
+ az_el : np.ndarray
244
+ <azimuth, elevation> vector or array of vectors in reference frame `from_frame`.
245
+ There are several possible shapes for the input az_el and et:
246
+ 1. A single az_el vector may be provided for multiple `et` query times
247
+ 2. A single `et` may be provided for multiple az_el vectors,
248
+ 3. The same number of `et` and az_el vectors may be provided.
249
+ It is not allowed to have n az_el vectors and m `et`, where n != m.
250
+ from_frame : SpiceFrame
251
+ Reference frame of input coordinates.
252
+ to_frame : SpiceFrame
253
+ Reference frame of output coordinates.
254
+ degrees : bool
255
+ If True, azimuth and elevation input and output will be in degrees.
256
+
257
+ Returns
258
+ -------
259
+ to_frame_az_el : np.ndarray
260
+ Azimuth/elevation coordinates in reference frame `to_frame`. This
261
+ output coordinate vector will have shape (2,) if a single `az_el` position
262
+ vector and single `et` time are input. Otherwise, it will have shape (n, 2)
263
+ where n is the number of input position vector or ephemeris times. The last
264
+ axis of the output vector contains azimuth in the 0th position and elevation
265
+ in the 1st position.
266
+ """
267
+ # Convert input az/el to Cartesian vectors
268
+ spherical_coords_in = np.array(
269
+ [np.ones_like(az_el[..., 0]), az_el[..., 0], az_el[..., 1]]
270
+ ).T
271
+ from_frame_cartesian = spherical_to_cartesian(spherical_coords_in, degrees=degrees)
272
+ # Transform to to_frame
273
+ to_frame_cartesian = frame_transform(et, from_frame_cartesian, from_frame, to_frame)
274
+ # Convert to spherical and extract azimuth/elevation
275
+ to_frame_az_el = cartesian_to_spherical(to_frame_cartesian, degrees=degrees)
276
+ return to_frame_az_el[..., 1:3]
277
+
278
+
375
279
  @typing.no_type_check
376
280
  @ensure_spice
377
281
  def get_rotation_matrix(
@@ -404,7 +308,7 @@ def get_rotation_matrix(
404
308
  where `n` matches the number of elements in et.
405
309
  """
406
310
  vec_pxform = np.vectorize(
407
- spice.pxform,
311
+ spiceypy.pxform,
408
312
  excluded=["fromstr", "tostr"],
409
313
  signature="(),(),()->(3,3)",
410
314
  otypes=[np.float64],
@@ -446,8 +350,8 @@ def instrument_pointing(
446
350
  if cartesian:
447
351
  return pointing
448
352
  if isinstance(et, typing.Collection):
449
- return np.rad2deg([spice.reclat(vec)[1:] for vec in pointing])
450
- return np.rad2deg(spice.reclat(pointing)[1:])
353
+ return np.rad2deg([spiceypy.reclat(vec)[1:] for vec in pointing])
354
+ return np.rad2deg(spiceypy.reclat(pointing)[1:])
451
355
 
452
356
 
453
357
  def basis_vectors(
@@ -483,8 +387,8 @@ def basis_vectors(
483
387
  Examples
484
388
  --------
485
389
  >>> from imap_processing.spice.geometry import basis_vectors
486
- ... from imap_processing.spice.time import j2000ns_to_j2000s
487
- ... et = j2000ns_to_j2000s(dataset.epoch.values)
390
+ ... from imap_processing.spice.time import ttj2000ns_to_et
391
+ ... et = ttj2000ns_to_et(dataset.epoch.values)
488
392
  ... basis_vectors = basis_vectors(
489
393
  ... et, SpiceFrame.IMAP_SPACECRAFT, SpiceFrame.ECLIPJ2000
490
394
  ... )
@@ -524,7 +428,7 @@ def cartesian_to_spherical(
524
428
  output range=[0, 360],
525
429
  otherwise in radians if degrees parameter is False:
526
430
  output range=[0, 2*pi].
527
- - elevation : angle from the z-axis
431
+ - elevation : angle from the xy-plane
528
432
  In degrees if degrees parameter is True (by default):
529
433
  output range=[0, 180],
530
434
  otherwise in radians if degrees parameter is False:
@@ -535,7 +439,7 @@ def cartesian_to_spherical(
535
439
 
536
440
  vhat = v / magnitude_v
537
441
 
538
- # Elevation angle (angle from the z-axis, range: [-pi/2, pi/2])
442
+ # Elevation angle (angle from the xy-plane, range: [-pi/2, pi/2])
539
443
  el = np.arcsin(vhat[..., 2])
540
444
 
541
445
  # Azimuth angle (angle in the xy-plane, range: [0, 2*pi])
@@ -553,7 +457,7 @@ def cartesian_to_spherical(
553
457
  return spherical_coords
554
458
 
555
459
 
556
- def spherical_to_cartesian(spherical_coords: NDArray) -> NDArray:
460
+ def spherical_to_cartesian(spherical_coords: NDArray, degrees: bool = False) -> NDArray:
557
461
  """
558
462
  Convert spherical coordinates to Cartesian coordinates.
559
463
 
@@ -565,7 +469,10 @@ def spherical_to_cartesian(spherical_coords: NDArray) -> NDArray:
565
469
 
566
470
  - r : Distance of the point from the origin.
567
471
  - azimuth : angle in the xy-plane in radians [0, 2*pi].
568
- - elevation : angle from the z-axis in radians [-pi/2, pi/2].
472
+ - elevation : angle from the xy-plane in radians [-pi/2, pi/2].
473
+ degrees : bool
474
+ Set to True if input azimuth and elevation angles are in degrees.
475
+ Defaults to False.
569
476
 
570
477
  Returns
571
478
  -------
@@ -576,6 +483,10 @@ def spherical_to_cartesian(spherical_coords: NDArray) -> NDArray:
576
483
  azimuth = spherical_coords[..., 1]
577
484
  elevation = spherical_coords[..., 2]
578
485
 
486
+ if degrees:
487
+ azimuth = np.radians(azimuth)
488
+ elevation = np.radians(elevation)
489
+
579
490
  x = r * np.cos(elevation) * np.cos(azimuth)
580
491
  y = r * np.cos(elevation) * np.sin(azimuth)
581
492
  z = r * np.sin(elevation)
@@ -583,3 +494,64 @@ def spherical_to_cartesian(spherical_coords: NDArray) -> NDArray:
583
494
  cartesian_coords = np.stack((x, y, z), axis=-1)
584
495
 
585
496
  return cartesian_coords
497
+
498
+
499
+ def cartesian_to_latitudinal(coords: NDArray, degrees: bool = False) -> NDArray:
500
+ """
501
+ Convert cartesian coordinates to latitudinal coordinates in radians.
502
+
503
+ This is a vectorized wrapper around `spiceypy.reclat`
504
+ "Convert from rectangular coordinates to latitudinal coordinates."
505
+ https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/reclat_c.html
506
+
507
+ Parameters
508
+ ----------
509
+ coords : np.ndarray
510
+ Either shape (n, 3) or (3) where the last dimension represents a vector
511
+ with x, y, z-components.
512
+ degrees : bool
513
+ If True, the longitude and latitude coords are returned in degrees.
514
+ Defaults to False.
515
+
516
+ Returns
517
+ -------
518
+ np.ndarray
519
+ A NumPy array with shape (n, 3) or (3), where the last dimension contains
520
+ the latitudinal coordinates (radius, longitude, latitude).
521
+ """
522
+ # If coords is 1d, add another dimension
523
+ while coords.ndim < 2:
524
+ coords = np.expand_dims(coords, axis=0)
525
+ latitudinal_coords = np.array([spiceypy.reclat(vec) for vec in coords])
526
+
527
+ if degrees:
528
+ latitudinal_coords[..., 1:] = np.degrees(latitudinal_coords[..., 1:])
529
+ # Return array of latitudinal and remove the first dimension if it is 1.
530
+ return np.squeeze(latitudinal_coords)
531
+
532
+
533
+ def solar_longitude(
534
+ et: Union[np.ndarray, float],
535
+ degrees: bool = False,
536
+ ) -> Union[float, npt.NDArray]:
537
+ """
538
+ Compute the solar longitude of the Imap Spacecraft.
539
+
540
+ Parameters
541
+ ----------
542
+ et : float or np.ndarray
543
+ Ephemeris time(s) to at which to compute solar longitude.
544
+ degrees : bool
545
+ If True, the longitude is returned in degrees.
546
+ Defaults to False.
547
+
548
+ Returns
549
+ -------
550
+ float or np.ndarray
551
+ The solar longitude at the specified times.
552
+ """
553
+ # Get position of IMAP in ecliptic frame
554
+ imap_pos = imap_state(et, observer=SpiceBody.SUN)[..., 0:3]
555
+ lat_coords = cartesian_to_latitudinal(imap_pos, degrees=degrees)[..., 1]
556
+
557
+ return float(lat_coords) if lat_coords.size == 1 else lat_coords
@@ -9,7 +9,7 @@ from pathlib import Path
9
9
  from typing import Any, Callable, Optional, Union, overload
10
10
 
11
11
  import numpy as np
12
- import spiceypy as spice
12
+ import spiceypy
13
13
  from numpy.typing import NDArray
14
14
  from spiceypy.utils.exceptions import SpiceyError
15
15
 
@@ -145,7 +145,7 @@ def ensure_spice(
145
145
  # Step 2.
146
146
  if os.getenv("SPICE_METAKERNEL"):
147
147
  metakernel_path = os.getenv("SPICE_METAKERNEL")
148
- spice.furnsh(metakernel_path)
148
+ spiceypy.furnsh(metakernel_path)
149
149
  else:
150
150
  furnish_time_kernel()
151
151
  except KeyError:
@@ -200,13 +200,13 @@ def open_spice_ck_file(pointing_frame_path: Path) -> Generator[int, None, None]:
200
200
  # and how that will affect appending to the pointing
201
201
  # frame kernel.
202
202
  if pointing_frame_path.exists():
203
- handle = spice.dafopw(str(pointing_frame_path))
203
+ handle = spiceypy.dafopw(str(pointing_frame_path))
204
204
  else:
205
- handle = spice.ckopn(str(pointing_frame_path), "CK", 0)
205
+ handle = spiceypy.ckopn(str(pointing_frame_path), "CK", 0)
206
206
  try:
207
207
  yield handle
208
208
  finally:
209
- spice.ckcls(handle)
209
+ spiceypy.ckcls(handle)
210
210
 
211
211
 
212
212
  @ensure_spice
@@ -245,12 +245,12 @@ def create_pointing_frame(pointing_frame_path: Path, ck_path: Path) -> None:
245
245
  """
246
246
  # Get IDs.
247
247
  # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool
248
- id_imap_dps = spice.gipool("FRAME_IMAP_DPS", 0, 1)
249
- id_imap_sclk = spice.gipool("CK_-43000_SCLK", 0, 1)
248
+ id_imap_dps = spiceypy.gipool("FRAME_IMAP_DPS", 0, 1)
249
+ id_imap_sclk = spiceypy.gipool("CK_-43000_SCLK", 0, 1)
250
250
 
251
251
  # Verify that only ck_path kernel is loaded.
252
- count = spice.ktotal("ck")
253
- loaded_ck_kernel, _, _, _ = spice.kdata(count - 1, "ck")
252
+ count = spiceypy.ktotal("ck")
253
+ loaded_ck_kernel, _, _, _ = spiceypy.kdata(count - 1, "ck")
254
254
 
255
255
  if count != 1 or str(ck_path) != loaded_ck_kernel:
256
256
  raise ValueError(f"Error: Expected CK kernel {ck_path}")
@@ -258,28 +258,28 @@ def create_pointing_frame(pointing_frame_path: Path, ck_path: Path) -> None:
258
258
  # If the pointing frame kernel already exists, find the last time.
259
259
  if pointing_frame_path.exists():
260
260
  # Get the last time in the pointing frame kernel.
261
- pointing_cover = spice.ckcov(
261
+ pointing_cover = spiceypy.ckcov(
262
262
  str(pointing_frame_path), int(id_imap_dps), True, "SEGMENT", 0, "TDB"
263
263
  )
264
- num_segments = spice.wncard(pointing_cover)
265
- _, et_end_pointing_frame = spice.wnfetd(pointing_cover, num_segments - 1)
264
+ num_segments = spiceypy.wncard(pointing_cover)
265
+ _, et_end_pointing_frame = spiceypy.wnfetd(pointing_cover, num_segments - 1)
266
266
  else:
267
267
  et_end_pointing_frame = None
268
268
 
269
269
  # TODO: Query for .csv file to get the pointing start and end times.
270
270
  # TODO: Remove next four lines once query is added.
271
- id_imap_spacecraft = spice.gipool("FRAME_IMAP_SPACECRAFT", 0, 1)
272
- ck_cover = spice.ckcov(
271
+ id_imap_spacecraft = spiceypy.gipool("FRAME_IMAP_SPACECRAFT", 0, 1)
272
+ ck_cover = spiceypy.ckcov(
273
273
  str(ck_path), int(id_imap_spacecraft), True, "INTERVAL", 0, "TDB"
274
274
  )
275
- num_intervals = spice.wncard(ck_cover)
275
+ num_intervals = spiceypy.wncard(ck_cover)
276
276
 
277
277
  with open_spice_ck_file(pointing_frame_path) as handle:
278
278
  # TODO: this will change to the number of pointings.
279
279
  for i in range(num_intervals):
280
280
  # Get the coverage window
281
281
  # TODO: this will change to pointing start and end time.
282
- et_start, et_end = spice.wnfetd(ck_cover, i)
282
+ et_start, et_end = spiceypy.wnfetd(ck_cover, i)
283
283
  et_times = _get_et_times(et_start, et_end)
284
284
 
285
285
  # TODO: remove after query is added.
@@ -294,16 +294,16 @@ def create_pointing_frame(pointing_frame_path: Path, ck_path: Path) -> None:
294
294
 
295
295
  # Convert the rotation matrix to a quaternion.
296
296
  # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.m2q
297
- q_avg = spice.m2q(rotation_matrix)
297
+ q_avg = spiceypy.m2q(rotation_matrix)
298
298
 
299
299
  # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.sce2c
300
300
  # Convert start and end times to SCLK.
301
- sclk_begtim = spice.sce2c(int(id_imap_sclk), et_times[0])
302
- sclk_endtim = spice.sce2c(int(id_imap_sclk), et_times[-1])
301
+ sclk_begtim = spiceypy.sce2c(int(id_imap_sclk), et_times[0])
302
+ sclk_endtim = spiceypy.sce2c(int(id_imap_sclk), et_times[-1])
303
303
 
304
304
  # Create the pointing frame kernel.
305
305
  # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckw02
306
- spice.ckw02(
306
+ spiceypy.ckw02(
307
307
  # Handle of an open CK file.
308
308
  handle,
309
309
  # Start time of the segment.
@@ -355,7 +355,7 @@ def _get_et_times(et_start: float, et_end: float) -> NDArray[np.float64]:
355
355
 
356
356
  # 1 spin/15 seconds; 10 quaternions / spin.
357
357
  num_samples = (et_end - et_start) / 15 * 10
358
- # There were rounding errors when using spice.pxform so np.ceil and np.floor
358
+ # There were rounding errors when using spiceypy.pxform so np.ceil and np.floor
359
359
  # were used to ensure the start and end times were included in the array.
360
360
  et_times = np.linspace(
361
361
  np.ceil(et_start * 1e6) / 1e6, np.floor(et_end * 1e6) / 1e6, int(num_samples)
@@ -390,10 +390,10 @@ def _average_quaternions(et_times: np.ndarray) -> NDArray:
390
390
 
391
391
  # Rotation matrix from IMAP spacecraft frame to ECLIPJ2000.
392
392
  # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.pxform
393
- body_rots = spice.pxform("IMAP_SPACECRAFT", "ECLIPJ2000", tdb)
393
+ body_rots = spiceypy.pxform("IMAP_SPACECRAFT", "ECLIPJ2000", tdb)
394
394
  # Convert rotation matrix to quaternion.
395
395
  # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.m2q
396
- body_quat = spice.m2q(body_rots)
396
+ body_quat = spiceypy.m2q(body_rots)
397
397
 
398
398
  # Standardize the quaternion so that they may be compared.
399
399
  body_quat = body_quat * np.sign(body_quat[0])
@@ -440,7 +440,7 @@ def _create_rotation_matrix(et_times: np.ndarray) -> NDArray:
440
440
  # Converts the averaged quaternion (q_avg) into a rotation matrix
441
441
  # and get inertial z axis.
442
442
  # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.q2m
443
- z_avg = spice.q2m(list(q_avg))[:, 2]
443
+ z_avg = spiceypy.q2m(list(q_avg))[:, 2]
444
444
  # y_avg is perpendicular to both z_avg and the standard Z-axis.
445
445
  y_avg = np.cross(z_avg, [0, 0, 1])
446
446
  # x_avg is perpendicular to y_avg and z_avg.
@@ -459,5 +459,5 @@ def furnish_time_kernel() -> None:
459
459
  # TODO: we need to load these kernels from EFS volumen that is
460
460
  # mounted to batch volume and extend this to generate metakernell
461
461
  # which is TBD.
462
- spice.furnsh(str(spice_test_data_path / "imap_sclk_0000.tsc"))
463
- spice.furnsh(str(spice_test_data_path / "naif0012.tls"))
462
+ spiceypy.furnsh(str(spice_test_data_path / "imap_sclk_0000.tsc"))
463
+ spiceypy.furnsh(str(spice_test_data_path / "naif0012.tls"))