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
@@ -0,0 +1,17 @@
1
+ sequence,x_pri,y_pri,z_pri,rng_pri,x_sec,y_sec,z_sec,rng_sec,pri_coarse,pri_fine,sec_coarse,sec_fine,compression,compression_width_bits
2
+ 14,13,-27,-1,1,2,-5,7,0,476381218,64355,476381218,64357,0,16
3
+ 14,26,-30,-13,1,7,-10,-5,0,476381218,64355,476381218,64357,0,16
4
+ 14,38,-51,-24,1,0,-14,0,0,476381218,64355,476381218,64357,0,16
5
+ 14,44,-53,-39,2,-1,-20,5,0,476381218,64355,476381218,64357,0,16
6
+ 14,50,-48,-50,2,12,-27,8,1,476381218,64355,476381218,64357,0,16
7
+ 14,52,-59,-48,2,9,-32,4,1,476381218,64355,476381218,64357,0,16
8
+ 14,53,-78,-44,2,17,-26,-4,1,476381218,64355,476381218,64357,0,16
9
+ 14,58,-87,-51,2,29,-36,-16,1,476381218,64355,476381218,64357,0,16
10
+ 14,51,-100,-68,3,41,-54,-29,1,476381218,64355,476381218,64357,0,16
11
+ 14,26,-114,-70,3,47,-51,-43,2,476381218,64355,476381218,64357,0,16
12
+ 14,34,-125,-67,3,50,-49,-49,2,476381218,64355,476381218,64357,0,16
13
+ 14,39,-121,-70,3,53,-66,-48,2,476381218,64355,476381218,64357,0,16
14
+ 14,29,-96,-54,3,54,-80,-44,2,476381218,64355,476381218,64357,0,16
15
+ 14,3,-9,-2,0,59,-91,-56,2,476381218,64355,476381218,64357,0,16
16
+ 14,0,-1,8,0,43,-103,-71,3,476381218,64355,476381218,64357,0,16
17
+ 14,5,-10,-2,0,23,-119,-67,3,476381218,64355,476381218,64357,0,16
@@ -0,0 +1,17 @@
1
+ t,coarse,fine,sequence,x,y,z,range,compression,compression_width
2
+ 2025-02-04T16:06:58.982024,476381218,64357,14,4.55075124996,-11.19786196854,15.77425592322,0,0,16
3
+ 2025-02-04T16:06:59.482024,476381218,64357,14,15.92762937486,-22.40731698594,-11.07018889848,0,0,16
4
+ 2025-02-04T16:06:59.982024,476381218,64357,14,0,-31.33237315404,0.16302044052,0,0,16
5
+ 2025-02-04T16:07:00.482024,476381218,64357,14,-2.27537562498,-44.75666872758,11.44735711164,0,0,16
6
+ 2025-02-04T16:07:00.982024,476381218,64357,14,0.885096288,-1.952868096,0.590544504,1,0,16
7
+ 2025-02-04T16:07:01.482024,476381218,64357,14,0.663822216,-2.313845568,0.302605344,1,0,16
8
+ 2025-02-04T16:07:01.982024,476381218,64357,14,1.253886408,-1.881232704,-0.277225488,1,0,16
9
+ 2025-02-04T16:07:02.482024,476381218,64357,14,2.138982696,-2.605478976,-1.139884128,1,0,16
10
+ 2025-02-04T16:07:02.982024,476381218,64357,14,3.024078984,-3.907900224,-2.071901592,1,0,16
11
+ 2025-02-04T16:07:03.482024,476381218,64357,14,0.88482713616,-0.9431913528,-0.78778074834,2,0,16
12
+ 2025-02-04T16:07:03.982024,476381218,64357,14,0.941305464,-0.90634074822,-0.89873597394,2,0,16
13
+ 2025-02-04T16:07:04.482024,476381218,64357,14,0.99778379184,-1.22037879546,-0.87847855812,2,0,16
14
+ 2025-02-04T16:07:04.982024,476381218,64357,14,1.01660990112,-1.47895667604,-0.80315324496,2,0,16
15
+ 2025-02-04T16:07:05.482024,476381218,64357,14,1.11074044752,-1.68224447592,-1.02364442208,2,0,16
16
+ 2025-02-04T16:07:05.982024,476381218,64357,14,0.19710391041,-0.46535117637,-0.31706811786,3,0,16
17
+ 2025-02-04T16:07:06.482024,476381218,64357,14,0.10542767301,-0.53738602233,-0.29896071126,3,0,16
@@ -0,0 +1,17 @@
1
+ t,coarse,fine,sequence,x,y,z,range,compression,compression_width
2
+ 2025-02-04T16:06:58.981994,476381218,64355,14,0.959660208,-1.952789976,-0.065792592,1,0,16
3
+ 2025-02-04T16:06:59.481994,476381218,64355,14,1.919320416,-2.168504496,-0.934627104,1,0,16
4
+ 2025-02-04T16:06:59.981994,476381218,64355,14,2.805160608,-3.687134832,-1.725878016,1,0,16
5
+ 2025-02-04T16:07:00.481994,476381218,64355,14,0.82931140512,-0.97823230506,-0.71816753502,2,0,16
6
+ 2025-02-04T16:07:00.981994,476381218,64355,14,0.942399324,-0.8856151974,-0.922033134,2,0,16
7
+ 2025-02-04T16:07:01.481994,476381218,64355,14,0.98009529696,-1.08887713398,-0.88430215752,2,0,16
8
+ 2025-02-04T16:07:01.981994,476381218,64355,14,0.99894328344,-1.44004598082,-0.8089813125,2,0,16
9
+ 2025-02-04T16:07:02.481994,476381218,64355,14,1.09318321584,-1.60624150722,-0.93784261842,2,0,16
10
+ 2025-02-04T16:07:02.981994,476381218,64355,14,0.23448643983,-0.4504876167,-0.30422097897,3,0,16
11
+ 2025-02-04T16:07:03.481994,476381218,64355,14,0.11954210658,-0.5137174926,-0.31298135118,3,0,16
12
+ 2025-02-04T16:07:03.981994,476381218,64355,14,0.15632429322,-0.5632591128,-0.29918061558,3,0,16
13
+ 2025-02-04T16:07:04.481994,476381218,64355,14,0.17931315987,-0.5452042089,-0.31278820557,3,0,16
14
+ 2025-02-04T16:07:04.981994,476381218,64355,14,0.13333542657,-0.4325684769,-0.24123552375,3,0,16
15
+ 2025-02-04T16:07:05.481994,476381218,64355,14,6.89166060498,-20.13180037308,-4.42656442566,0,0,16
16
+ 2025-02-04T16:07:05.981994,476381218,64355,14,0,-2.23802879004,18.00488498574,0,0,16
17
+ 2025-02-04T16:07:06.481994,476381218,64355,14,11.4861010083,-22.3628566716,-4.42269580368,0,0,16
@@ -1,23 +1,24 @@
1
1
  """Tests coverage for imap_processing/spice/geometry.py"""
2
2
 
3
+ from unittest import mock
4
+
3
5
  import numpy as np
4
- import pandas as pd
5
6
  import pytest
6
- import spiceypy as spice
7
+ import spiceypy
7
8
 
8
9
  from imap_processing.spice.geometry import (
9
10
  SpiceBody,
10
11
  SpiceFrame,
11
12
  basis_vectors,
13
+ cartesian_to_latitudinal,
12
14
  cartesian_to_spherical,
13
15
  frame_transform,
14
- get_instrument_spin_phase,
16
+ frame_transform_az_el,
15
17
  get_rotation_matrix,
16
- get_spacecraft_spin_phase,
17
18
  get_spacecraft_to_instrument_spin_phase_offset,
18
- get_spin_data,
19
19
  imap_state,
20
20
  instrument_pointing,
21
+ solar_longitude,
21
22
  spherical_to_cartesian,
22
23
  )
23
24
  from imap_processing.spice.kernels import ensure_spice
@@ -47,116 +48,6 @@ def test_imap_state_ecliptic():
47
48
  assert state.shape == (6,)
48
49
 
49
50
 
50
- @pytest.fixture()
51
- def fake_spin_data(monkeypatch, spice_test_data_path):
52
- """Generate fake spin dataframe for testing"""
53
- fake_spin_path = spice_test_data_path / "fake_spin_data.csv"
54
- monkeypatch.setenv("SPIN_DATA_FILEPATH", str(fake_spin_path))
55
- return fake_spin_path
56
-
57
-
58
- @pytest.mark.parametrize(
59
- "query_met_times, expected",
60
- [
61
- (15, 0.0), # Scalar test
62
- (np.array([15.1, 30.1]), np.array([0.1 / 15, 0.1 / 15])), # Array test
63
- (np.array([]), None), # Empty array test
64
- (np.array([50]), np.array([5 / 15])), # Single element array test
65
- # The first spin has thruster firing set, but should return valid value
66
- (5.0, 5 / 15),
67
- # Test invalid spin period flag causes nan
68
- (106.0, np.nan),
69
- # Test invalid spin phase flag causes nans
70
- (np.array([121, 122, 123]), np.full(3, np.nan)),
71
- # Test that invalid spin period causes nans
72
- (np.array([110, 111]), np.full(2, np.nan)),
73
- # Test for time in missing spin
74
- (65, np.nan),
75
- (np.array([65.1, 66]), np.full(2, np.nan)),
76
- # Combined test
77
- (
78
- np.array([7.5, 30, 61, 75, 106, 121, 136]),
79
- np.array([0.5, 0, np.nan, 0, np.nan, np.nan, 1 / 15]),
80
- ),
81
- ],
82
- )
83
- def test_get_spacecraft_spin_phase(query_met_times, expected, fake_spin_data):
84
- """Test get_spacecraft_spin_phase() with generated spin data."""
85
- # Call the function
86
- spin_phases = get_spacecraft_spin_phase(query_met_times=query_met_times)
87
-
88
- # Test the returned type
89
- if isinstance(expected, float):
90
- assert isinstance(spin_phases, float), "Spin phase must be a float."
91
- elif expected is None:
92
- assert len(spin_phases) == 0, "Spin phase must be empty."
93
- else:
94
- assert spin_phases.shape == expected.shape
95
- # Test the value
96
- np.testing.assert_array_almost_equal(spin_phases, expected)
97
-
98
-
99
- @pytest.mark.parametrize("query_met_times", [-1, 165])
100
- def test_get_spacecraft_spin_phase_value_error(query_met_times, fake_spin_data):
101
- """Test get_spacecraft_spin_phase() for raising ValueError."""
102
- with pytest.raises(ValueError, match="Query times"):
103
- _ = get_spacecraft_spin_phase(query_met_times)
104
-
105
-
106
- @pytest.mark.usefixtures("use_fake_spin_data_for_time")
107
- def test_get_spin_data(use_fake_spin_data_for_time):
108
- """Test get_spin_data() with generated spin data."""
109
- use_fake_spin_data_for_time(453051323.0 - 56120)
110
- spin_data = get_spin_data()
111
-
112
- (
113
- np.testing.assert_array_equal(spin_data["spin_number"], np.arange(5761)),
114
- "One day should have 5,761 records of 15 seconds when including end_met.",
115
- )
116
- assert isinstance(spin_data, pd.DataFrame), "Return type must be pandas.DataFrame."
117
-
118
- assert set(spin_data.columns) == {
119
- "spin_number",
120
- "spin_start_sec",
121
- "spin_start_subsec",
122
- "spin_period_sec",
123
- "spin_period_valid",
124
- "spin_phase_valid",
125
- "spin_period_source",
126
- "thruster_firing",
127
- "spin_start_time",
128
- }, "Spin data must have the specified fields."
129
-
130
-
131
- @pytest.mark.parametrize(
132
- "instrument",
133
- [
134
- SpiceFrame.IMAP_LO,
135
- SpiceFrame.IMAP_HI_45,
136
- SpiceFrame.IMAP_HI_90,
137
- SpiceFrame.IMAP_ULTRA_45,
138
- SpiceFrame.IMAP_ULTRA_90,
139
- SpiceFrame.IMAP_SWAPI,
140
- SpiceFrame.IMAP_IDEX,
141
- SpiceFrame.IMAP_CODICE,
142
- SpiceFrame.IMAP_HIT,
143
- SpiceFrame.IMAP_SWE,
144
- SpiceFrame.IMAP_GLOWS,
145
- SpiceFrame.IMAP_MAG,
146
- ],
147
- )
148
- def test_get_instrument_spin_phase(instrument, fake_spin_data):
149
- """Test coverage for get_instrument_spin_phase()"""
150
- met_times = np.array([7.5, 30, 61, 75, 106, 121, 136])
151
- expected_nan_mask = np.array([False, False, True, False, True, True, False])
152
- inst_phase = get_instrument_spin_phase(met_times, instrument)
153
- assert inst_phase.shape == met_times.shape
154
- np.testing.assert_array_equal(np.isnan(inst_phase), expected_nan_mask)
155
- assert np.logical_and(
156
- 0 <= inst_phase[~expected_nan_mask], inst_phase[~expected_nan_mask] < 1
157
- ).all()
158
-
159
-
160
51
  @pytest.mark.parametrize(
161
52
  "instrument, expected_offset",
162
53
  [
@@ -233,7 +124,7 @@ def test_frame_transform(et_strings, position, from_frame, to_frame, furnish_ker
233
124
  ]
234
125
  with furnish_kernels(kernels):
235
126
  # Test single et and position calculation
236
- et = np.array([spice.utc2et(et_str) for et_str in et_strings])
127
+ et = np.array([spiceypy.utc2et(et_str) for et_str in et_strings])
237
128
  et_arg = et[0] if len(et) == 1 else et
238
129
  result = frame_transform(et_arg, position, from_frame, to_frame)
239
130
  # check the result shape before modifying for value checking.
@@ -255,11 +146,33 @@ def test_frame_transform(et_strings, position, from_frame, to_frame, furnish_ker
255
146
  position = np.broadcast_to(position, (len(et), 3))
256
147
  result = np.broadcast_to(result, (len(et), 3))
257
148
  for spice_et, spice_position, test_result in zip(et, position, result):
258
- rotation_matrix = spice.pxform(from_frame.name, to_frame.name, spice_et)
259
- spice_result = spice.mxv(rotation_matrix, spice_position)
149
+ rotation_matrix = spiceypy.pxform(from_frame.name, to_frame.name, spice_et)
150
+ spice_result = spiceypy.mxv(rotation_matrix, spice_position)
260
151
  np.testing.assert_allclose(test_result, spice_result, atol=1e-12)
261
152
 
262
153
 
154
+ @pytest.mark.parametrize(
155
+ "spice_frame",
156
+ [
157
+ SpiceFrame.IMAP_DPS,
158
+ SpiceFrame.IMAP_SPACECRAFT,
159
+ SpiceFrame.ECLIPJ2000,
160
+ ],
161
+ )
162
+ @pytest.mark.parametrize(
163
+ "position",
164
+ [
165
+ np.array([1, 0, 0]),
166
+ np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]),
167
+ np.random.rand(10, 3),
168
+ ],
169
+ )
170
+ def test_frame_transform_same_frame(position, spice_frame):
171
+ """Test that frame_transform returns position when input/output frames are same."""
172
+ result = frame_transform(0, position, spice_frame, spice_frame)
173
+ assert result is position
174
+
175
+
263
176
  def test_frame_transform_exceptions():
264
177
  """Test that the proper exceptions get raised when input arguments are invalid."""
265
178
  with pytest.raises(
@@ -287,6 +200,45 @@ def test_frame_transform_exceptions():
287
200
  )
288
201
 
289
202
 
203
+ @pytest.mark.parametrize(
204
+ "spice_frame",
205
+ [
206
+ SpiceFrame.IMAP_DPS,
207
+ SpiceFrame.IMAP_SPACECRAFT,
208
+ SpiceFrame.ECLIPJ2000,
209
+ ],
210
+ )
211
+ @pytest.mark.parametrize("degrees_bool", [True, False])
212
+ def test_frame_transform_az_el_same_frame(spice_frame, degrees_bool):
213
+ """Test that frame_transform returns az/el when input/output frames are same."""
214
+ az_el_points = np.array(
215
+ [
216
+ [0, -90],
217
+ [0, 0],
218
+ [0, 89.999999],
219
+ [90, -90],
220
+ [90, 0],
221
+ [90, 89.999999],
222
+ [180, -90],
223
+ [180, 0],
224
+ [180, 89.999999],
225
+ [270, -90],
226
+ [270, 0],
227
+ [270, 89.999999],
228
+ [359.999999, -90],
229
+ [359.999999, 0],
230
+ [359.999999, 89.999999],
231
+ [360, 90],
232
+ ]
233
+ )
234
+ if not degrees_bool:
235
+ az_el_points = np.deg2rad(az_el_points)
236
+ result = frame_transform_az_el(
237
+ 0, az_el_points, spice_frame, spice_frame, degrees=degrees_bool
238
+ )
239
+ np.testing.assert_allclose(result, az_el_points)
240
+
241
+
290
242
  def test_get_rotation_matrix(furnish_kernels):
291
243
  """Test coverage for get_rotation_matrix()."""
292
244
  kernels = [
@@ -297,7 +249,7 @@ def test_get_rotation_matrix(furnish_kernels):
297
249
  "sim_1yr_imap_pointing_frame.bc",
298
250
  ]
299
251
  with furnish_kernels(kernels):
300
- et = spice.utc2et("2025-09-30T12:00:00.000")
252
+ et = spiceypy.utc2et("2025-09-30T12:00:00.000")
301
253
  # test input of float
302
254
  rotation = get_rotation_matrix(
303
255
  et, SpiceFrame.IMAP_IDEX, SpiceFrame.IMAP_SPACECRAFT
@@ -319,7 +271,7 @@ def test_instrument_pointing(furnish_kernels):
319
271
  "sim_1yr_imap_pointing_frame.bc",
320
272
  ]
321
273
  with furnish_kernels(kernels):
322
- et = spice.utc2et("2025-06-12T12:00:00.000")
274
+ et = spiceypy.utc2et("2025-06-12T12:00:00.000")
323
275
  # Single et input
324
276
  ins_pointing = instrument_pointing(
325
277
  et, SpiceFrame.IMAP_HI_90, SpiceFrame.ECLIPJ2000
@@ -344,7 +296,7 @@ def test_basis_vectors():
344
296
  """Test coverage for basis_vectors()."""
345
297
  # This call to SPICE needs to be wrapped with `ensure_spice` so that kernels
346
298
  # get furnished automatically
347
- et = ensure_spice(spice.utc2et)("2025-09-30T12:00:00.000")
299
+ et = ensure_spice(spiceypy.utc2et)("2025-09-30T12:00:00.000")
348
300
  # test input of float
349
301
  sc_axes = basis_vectors(et, SpiceFrame.IMAP_SPACECRAFT, SpiceFrame.IMAP_SPACECRAFT)
350
302
  np.testing.assert_array_equal(sc_axes, np.eye(3))
@@ -378,18 +330,11 @@ def test_cartesian_to_spherical():
378
330
 
379
331
  for point in cartesian_points:
380
332
  r, az, el = cartesian_to_spherical(point)
381
- r_spice, colat_spice, slong_spice = spice.recsph(point)
382
-
383
- # Convert SPICE co-latitude to elevation
384
- el_spice = 90 - np.degrees(colat_spice)
385
- az_spice = np.degrees(slong_spice)
386
-
387
- # Normalize azimuth to [0, 360]
388
- az_spice = az_spice % 360
333
+ range, ra, dec = spiceypy.recrad(point)
389
334
 
390
- np.testing.assert_allclose(r, r_spice, atol=1e-5)
391
- np.testing.assert_allclose(az, az_spice, atol=1e-5)
392
- np.testing.assert_allclose(el, el_spice, atol=1e-5)
335
+ np.testing.assert_allclose(r, range, atol=1e-5)
336
+ np.testing.assert_allclose(az, np.degrees(ra), atol=1e-5)
337
+ np.testing.assert_allclose(el, np.degrees(dec), atol=1e-5)
393
338
 
394
339
 
395
340
  def test_spherical_to_cartesian():
@@ -403,12 +348,62 @@ def test_spherical_to_cartesian():
403
348
  spherical_points = np.stack(
404
349
  (r * np.ones_like(theta).ravel(), theta.ravel(), elev.ravel()), axis=-1
405
350
  )
351
+ spherical_points_degrees = np.stack(
352
+ (
353
+ r * np.ones_like(theta).ravel(),
354
+ np.degrees(theta.ravel()),
355
+ np.degrees(elev.ravel()),
356
+ ),
357
+ axis=-1,
358
+ )
406
359
 
407
360
  # Convert elevation to colatitude for SPICE
408
361
  colat = np.pi / 2 - spherical_points[:, 2]
409
362
 
363
+ cartesian_from_degrees = spherical_to_cartesian(
364
+ spherical_points_degrees, degrees=True
365
+ )
366
+
410
367
  for i in range(len(colat)):
411
368
  cartesian_coords = spherical_to_cartesian(np.array([spherical_points[i]]))
412
- spice_coords = spice.sphrec(r, colat[i], spherical_points[i, 1])
369
+ spice_coords = spiceypy.sphrec(r, colat[i], spherical_points[i, 1])
413
370
 
414
371
  np.testing.assert_allclose(cartesian_coords[0], spice_coords, atol=1e-5)
372
+ np.testing.assert_allclose(cartesian_from_degrees[i], spice_coords, atol=1e-5)
373
+
374
+
375
+ def test_cartesian_to_latitudinal():
376
+ """Test cartesian_to_latitudinal()."""
377
+ # example cartesian coords
378
+ coords = np.ones(3)
379
+
380
+ # test with one coord vector
381
+ lat_coords = cartesian_to_latitudinal(coords, degrees=True)
382
+ assert lat_coords.shape == (3,)
383
+ assert lat_coords[1] == 45
384
+ assert lat_coords[2] == 35.264389682754654
385
+
386
+ # Test with multiple coord vectors
387
+ coords = np.tile(coords, (10, 1))
388
+ lat_coords = cartesian_to_latitudinal(coords, degrees=True)
389
+ assert lat_coords.shape == (10, 3)
390
+
391
+
392
+ @mock.patch("imap_processing.spice.geometry.imap_state")
393
+ def test_solar_longitude(mock_state):
394
+ """Test solar_longitude()."""
395
+
396
+ mock_state.side_effect = lambda t, observer: (
397
+ np.ones(6) if (isinstance(t, int)) else np.ones((len(t), 6))
398
+ )
399
+ # example et time
400
+ et = 798033670
401
+
402
+ # test for one time interval
403
+ lon = solar_longitude(et, degrees=True)
404
+ assert lon == 45
405
+
406
+ # Test with multiple time intervals
407
+ et = np.tile(et, (10, 1))
408
+ lon = solar_longitude(et, degrees=True)
409
+ assert lon.shape == (10,)
@@ -2,7 +2,7 @@
2
2
 
3
3
  import numpy as np
4
4
  import pytest
5
- import spiceypy as spice
5
+ import spiceypy
6
6
  from spiceypy.utils.exceptions import SpiceyError
7
7
 
8
8
  from imap_processing.spice.kernels import (
@@ -45,11 +45,11 @@ def multiple_pointing_kernels(spice_test_data_path):
45
45
  @pytest.fixture()
46
46
  def et_times(pointing_frame_kernels):
47
47
  """Tests get_et_times function."""
48
- spice.furnsh(pointing_frame_kernels)
48
+ spiceypy.furnsh(pointing_frame_kernels)
49
49
 
50
- ck_kernel, _, _, _ = spice.kdata(0, "ck")
51
- ck_cover = spice.ckcov(ck_kernel, -43000, True, "INTERVAL", 0, "TDB")
52
- et_start, et_end = spice.wnfetd(ck_cover, 0)
50
+ ck_kernel, _, _, _ = spiceypy.kdata(0, "ck")
51
+ ck_cover = spiceypy.ckcov(ck_kernel, -43000, True, "INTERVAL", 0, "TDB")
52
+ et_start, et_end = spiceypy.wnfetd(ck_cover, 0)
53
53
  et_times = _get_et_times(et_start, et_end)
54
54
 
55
55
  return et_times
@@ -58,7 +58,7 @@ def et_times(pointing_frame_kernels):
58
58
  @ensure_spice
59
59
  def single_wrap_et2utc(et, fmt, prec):
60
60
  """Directly decorate a spice function with ensure_spice for use in tests"""
61
- return spice.et2utc(et, fmt, prec)
61
+ return spiceypy.et2utc(et, fmt, prec)
62
62
 
63
63
 
64
64
  @ensure_spice
@@ -72,7 +72,7 @@ def double_wrap_et2utc(et, fmt, prec):
72
72
  @ensure_spice(time_kernels_only=True)
73
73
  def single_wrap_et2utc_tk_only(et, fmt, prec):
74
74
  """Directly wrap a spice function with optional time_kernels_only set True"""
75
- return spice.et2utc(et, fmt, prec)
75
+ return spiceypy.et2utc(et, fmt, prec)
76
76
 
77
77
 
78
78
  @ensure_spice(time_kernels_only=True)
@@ -101,7 +101,7 @@ def test_ensure_spice_emus_mk_path(func, use_test_metakernel):
101
101
  @pytest.mark.usefixtures("_unset_metakernel_path")
102
102
  def test_ensure_spice_time_kernels():
103
103
  """Test functionality of ensure spice with timekernels set"""
104
- wrapped = ensure_spice(spice.et2utc, time_kernels_only=True)
104
+ wrapped = ensure_spice(spiceypy.et2utc, time_kernels_only=True)
105
105
  # TODO: Update/remove this test when a decision has been made about
106
106
  # whether IMAP will use the time_kernels_only functionality and the
107
107
  # ensure_spice decorator has been update.
@@ -113,7 +113,7 @@ def test_ensure_spice_time_kernels():
113
113
  @pytest.mark.usefixtures("_unset_metakernel_path")
114
114
  def test_ensure_spice_key_error():
115
115
  """Test functionality of ensure spice when all branches fail"""
116
- wrapped = ensure_spice(spice.et2utc)
116
+ wrapped = ensure_spice(spiceypy.et2utc)
117
117
  # The ensure_spice decorator should raise a SpiceyError when all attempts to
118
118
  # furnish a set of kernels with sufficient coverage for the spiceypy
119
119
  # functions that it decorates.
@@ -123,7 +123,7 @@ def test_ensure_spice_key_error():
123
123
 
124
124
  def test_average_quaternions(et_times, pointing_frame_kernels):
125
125
  """Tests average_quaternions function."""
126
- spice.furnsh(pointing_frame_kernels)
126
+ spiceypy.furnsh(pointing_frame_kernels)
127
127
  q_avg = _average_quaternions(et_times)
128
128
 
129
129
  # Generated from MATLAB code results
@@ -133,10 +133,10 @@ def test_average_quaternions(et_times, pointing_frame_kernels):
133
133
 
134
134
  def test_create_rotation_matrix(et_times, pointing_frame_kernels):
135
135
  """Tests create_rotation_matrix function."""
136
- spice.furnsh(pointing_frame_kernels)
136
+ spiceypy.furnsh(pointing_frame_kernels)
137
137
  rotation_matrix = _create_rotation_matrix(et_times)
138
138
  q_avg = _average_quaternions(et_times)
139
- z_avg = spice.q2m(list(q_avg))[:, 2]
139
+ z_avg = spiceypy.q2m(list(q_avg))[:, 2]
140
140
 
141
141
  rotation_matrix_expected = np.array(
142
142
  [[0.0000, 0.0000, 1.0000], [0.9104, -0.4136, 0.0000], [0.4136, 0.9104, 0.0000]]
@@ -151,8 +151,8 @@ def test_create_pointing_frame(
151
151
  spice_test_data_path, pointing_frame_kernels, tmp_path, et_times
152
152
  ):
153
153
  """Tests create_pointing_frame function."""
154
- spice.kclear()
155
- spice.furnsh(pointing_frame_kernels)
154
+ spiceypy.kclear()
155
+ spiceypy.furnsh(pointing_frame_kernels)
156
156
  create_pointing_frame(
157
157
  pointing_frame_path=tmp_path / "imap_dps.bc",
158
158
  ck_path=spice_test_data_path / "imap_sim_ck_2hr_2secsampling_with_nutation.bc",
@@ -161,9 +161,9 @@ def test_create_pointing_frame(
161
161
  # After imap_dps.bc has been created.
162
162
  dps_kernel = str(tmp_path / "imap_dps.bc")
163
163
 
164
- spice.furnsh(dps_kernel)
165
- rotation_matrix_1 = spice.pxform("ECLIPJ2000", "IMAP_DPS", et_times[0] + 100)
166
- rotation_matrix_2 = spice.pxform("ECLIPJ2000", "IMAP_DPS", et_times[0] + 1000)
164
+ spiceypy.furnsh(dps_kernel)
165
+ rotation_matrix_1 = spiceypy.pxform("ECLIPJ2000", "IMAP_DPS", et_times[0] + 100)
166
+ rotation_matrix_2 = spiceypy.pxform("ECLIPJ2000", "IMAP_DPS", et_times[0] + 1000)
167
167
 
168
168
  # All the rotation matrices should be the same.
169
169
  assert np.array_equal(rotation_matrix_1, rotation_matrix_2)
@@ -178,7 +178,7 @@ def test_create_pointing_frame(
178
178
  assert (tmp_path / "imap_dps.bc").exists()
179
179
 
180
180
  # Tests error handling when incorrect kernel is loaded.
181
- spice.furnsh(pointing_frame_kernels)
181
+ spiceypy.furnsh(pointing_frame_kernels)
182
182
  with pytest.raises(
183
183
  ValueError, match="Error: Expected CK kernel badname_kernel.bc"
184
184
  ): # Replace match string with expected error message
@@ -189,11 +189,11 @@ def test_create_pointing_frame(
189
189
 
190
190
  def test_et_times(pointing_frame_kernels):
191
191
  """Tests get_et_times function."""
192
- spice.furnsh(pointing_frame_kernels)
192
+ spiceypy.furnsh(pointing_frame_kernels)
193
193
 
194
- ck_kernel, _, _, _ = spice.kdata(0, "ck")
195
- ck_cover = spice.ckcov(ck_kernel, -43000, True, "INTERVAL", 0, "TDB")
196
- et_start, et_end = spice.wnfetd(ck_cover, 0)
194
+ ck_kernel, _, _, _ = spiceypy.kdata(0, "ck")
195
+ ck_cover = spiceypy.ckcov(ck_kernel, -43000, True, "INTERVAL", 0, "TDB")
196
+ et_start, et_end = spiceypy.wnfetd(ck_cover, 0)
197
197
  et_times = _get_et_times(et_start, et_end)
198
198
 
199
199
  assert et_times[0] == et_start
@@ -204,7 +204,7 @@ def test_et_times(pointing_frame_kernels):
204
204
 
205
205
  def test_multiple_attempts(pointing_frame_kernels, tmp_path, spice_test_data_path):
206
206
  """Tests create_pointing_frame function with multiple pointing kernels."""
207
- spice.furnsh(pointing_frame_kernels)
207
+ spiceypy.furnsh(pointing_frame_kernels)
208
208
 
209
209
  # Check that a single segment is added regardless of how many times
210
210
  # create_pointing_frame is called.
@@ -212,32 +212,32 @@ def test_multiple_attempts(pointing_frame_kernels, tmp_path, spice_test_data_pat
212
212
  pointing_frame_path=tmp_path / "imap_dps.bc",
213
213
  ck_path=spice_test_data_path / "imap_sim_ck_2hr_2secsampling_with_nutation.bc",
214
214
  )
215
- ck_cover = spice.ckcov(
215
+ ck_cover = spiceypy.ckcov(
216
216
  str(tmp_path / "imap_dps.bc"), -43901, True, "INTERVAL", 0, "TDB"
217
217
  )
218
- num_intervals = spice.wncard(ck_cover)
218
+ num_intervals = spiceypy.wncard(ck_cover)
219
219
  assert num_intervals == 1
220
220
 
221
221
  create_pointing_frame(
222
222
  pointing_frame_path=tmp_path / "imap_dps.bc",
223
223
  ck_path=spice_test_data_path / "imap_sim_ck_2hr_2secsampling_with_nutation.bc",
224
224
  )
225
- ck_cover = spice.ckcov(
225
+ ck_cover = spiceypy.ckcov(
226
226
  str(tmp_path / "imap_dps.bc"), -43901, True, "INTERVAL", 0, "TDB"
227
227
  )
228
- num_intervals = spice.wncard(ck_cover)
228
+ num_intervals = spiceypy.wncard(ck_cover)
229
229
  assert num_intervals == 1
230
230
 
231
231
 
232
232
  def test_multiple_pointings(pointing_frame_kernels, spice_test_data_path, tmp_path):
233
233
  """Tests create_pointing_frame function with multiple pointing kernels."""
234
- spice.furnsh(pointing_frame_kernels)
234
+ spiceypy.furnsh(pointing_frame_kernels)
235
235
 
236
236
  create_pointing_frame(
237
237
  pointing_frame_path=tmp_path / "imap_pointing_frame.bc",
238
238
  ck_path=spice_test_data_path / "imap_sim_ck_2hr_2secsampling_with_nutation.bc",
239
239
  )
240
- ck_cover_pointing = spice.ckcov(
240
+ ck_cover_pointing = spiceypy.ckcov(
241
241
  str(tmp_path / "imap_pointing_frame.bc"),
242
242
  -43901,
243
243
  True,
@@ -245,10 +245,10 @@ def test_multiple_pointings(pointing_frame_kernels, spice_test_data_path, tmp_pa
245
245
  0,
246
246
  "TDB",
247
247
  )
248
- num_intervals = spice.wncard(ck_cover_pointing)
249
- et_start_pointing, et_end_pointing = spice.wnfetd(ck_cover_pointing, 0)
248
+ num_intervals = spiceypy.wncard(ck_cover_pointing)
249
+ et_start_pointing, et_end_pointing = spiceypy.wnfetd(ck_cover_pointing, 0)
250
250
 
251
- ck_cover = spice.ckcov(
251
+ ck_cover = spiceypy.ckcov(
252
252
  str(spice_test_data_path / "imap_sim_ck_2hr_2secsampling_with_nutation.bc"),
253
253
  -43000,
254
254
  True,
@@ -256,8 +256,8 @@ def test_multiple_pointings(pointing_frame_kernels, spice_test_data_path, tmp_pa
256
256
  0,
257
257
  "TDB",
258
258
  )
259
- num_intervals_expected = spice.wncard(ck_cover)
260
- et_start_expected, et_end_expected = spice.wnfetd(ck_cover, 0)
259
+ num_intervals_expected = spiceypy.wncard(ck_cover)
260
+ et_start_expected, et_end_expected = spiceypy.wnfetd(ck_cover, 0)
261
261
 
262
262
  assert num_intervals == num_intervals_expected
263
263
  assert et_start_pointing == et_start_expected
@@ -265,8 +265,8 @@ def test_multiple_pointings(pointing_frame_kernels, spice_test_data_path, tmp_pa
265
265
 
266
266
  et_times = _get_et_times(et_start_pointing, et_end_pointing)
267
267
 
268
- spice.furnsh(str(tmp_path / "imap_pointing_frame.bc"))
269
- rotation_matrix_1 = spice.pxform("ECLIPJ2000", "IMAP_DPS", et_times[100])
270
- rotation_matrix_2 = spice.pxform("ECLIPJ2000", "IMAP_DPS", et_times[1000])
268
+ spiceypy.furnsh(str(tmp_path / "imap_pointing_frame.bc"))
269
+ rotation_matrix_1 = spiceypy.pxform("ECLIPJ2000", "IMAP_DPS", et_times[100])
270
+ rotation_matrix_2 = spiceypy.pxform("ECLIPJ2000", "IMAP_DPS", et_times[1000])
271
271
 
272
272
  assert np.array_equal(rotation_matrix_1, rotation_matrix_2)