imap-processing 0.11.0__py3-none-any.whl → 0.13.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 (415) hide show
  1. imap_processing/__init__.py +11 -11
  2. imap_processing/_version.py +2 -2
  3. imap_processing/ccsds/ccsds_data.py +1 -2
  4. imap_processing/ccsds/excel_to_xtce.py +66 -18
  5. imap_processing/cdf/config/imap_codice_global_cdf_attrs.yaml +24 -40
  6. imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +934 -42
  7. imap_processing/cdf/config/imap_codice_l1b_variable_attrs.yaml +1846 -128
  8. imap_processing/cdf/config/imap_glows_global_cdf_attrs.yaml +0 -5
  9. imap_processing/cdf/config/imap_hi_global_cdf_attrs.yaml +10 -11
  10. imap_processing/cdf/config/imap_hi_variable_attrs.yaml +17 -19
  11. imap_processing/cdf/config/imap_hit_global_cdf_attrs.yaml +27 -14
  12. imap_processing/cdf/config/imap_hit_l1a_variable_attrs.yaml +106 -116
  13. imap_processing/cdf/config/imap_hit_l1b_variable_attrs.yaml +120 -145
  14. imap_processing/cdf/config/imap_hit_l2_variable_attrs.yaml +14 -0
  15. imap_processing/cdf/config/imap_idex_global_cdf_attrs.yaml +25 -9
  16. imap_processing/cdf/config/imap_idex_l1a_variable_attrs.yaml +6 -4
  17. imap_processing/cdf/config/imap_idex_l1b_variable_attrs.yaml +3 -3
  18. imap_processing/cdf/config/imap_lo_global_cdf_attrs.yaml +0 -12
  19. imap_processing/cdf/config/imap_lo_l1a_variable_attrs.yaml +1 -1
  20. imap_processing/cdf/config/imap_mag_global_cdf_attrs.yaml +23 -20
  21. imap_processing/cdf/config/imap_mag_l1a_variable_attrs.yaml +361 -0
  22. imap_processing/cdf/config/imap_mag_l1b_variable_attrs.yaml +160 -0
  23. imap_processing/cdf/config/imap_mag_l1c_variable_attrs.yaml +160 -0
  24. imap_processing/cdf/config/imap_spacecraft_global_cdf_attrs.yaml +18 -0
  25. imap_processing/cdf/config/imap_spacecraft_variable_attrs.yaml +40 -0
  26. imap_processing/cdf/config/imap_swapi_global_cdf_attrs.yaml +1 -5
  27. imap_processing/cdf/config/imap_swapi_variable_attrs.yaml +22 -0
  28. imap_processing/cdf/config/imap_swe_global_cdf_attrs.yaml +12 -4
  29. imap_processing/cdf/config/imap_swe_l1a_variable_attrs.yaml +16 -2
  30. imap_processing/cdf/config/imap_swe_l1b_variable_attrs.yaml +64 -52
  31. imap_processing/cdf/config/imap_swe_l2_variable_attrs.yaml +71 -47
  32. imap_processing/cdf/config/imap_ultra_global_cdf_attrs.yaml +180 -19
  33. imap_processing/cdf/config/imap_ultra_l1a_variable_attrs.yaml +5045 -41
  34. imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +80 -17
  35. imap_processing/cdf/config/imap_ultra_l1c_variable_attrs.yaml +32 -57
  36. imap_processing/cdf/utils.py +52 -38
  37. imap_processing/cli.py +477 -233
  38. imap_processing/codice/codice_l1a.py +466 -131
  39. imap_processing/codice/codice_l1b.py +51 -152
  40. imap_processing/codice/constants.py +1360 -569
  41. imap_processing/codice/decompress.py +2 -6
  42. imap_processing/ena_maps/ena_maps.py +1103 -146
  43. imap_processing/ena_maps/utils/coordinates.py +19 -0
  44. imap_processing/ena_maps/utils/map_utils.py +14 -17
  45. imap_processing/ena_maps/utils/spatial_utils.py +55 -52
  46. imap_processing/glows/l1a/glows_l1a.py +28 -99
  47. imap_processing/glows/l1a/glows_l1a_data.py +2 -2
  48. imap_processing/glows/l1b/glows_l1b.py +1 -4
  49. imap_processing/glows/l1b/glows_l1b_data.py +1 -3
  50. imap_processing/glows/l2/glows_l2.py +2 -5
  51. imap_processing/hi/l1a/hi_l1a.py +54 -29
  52. imap_processing/hi/l1a/histogram.py +0 -1
  53. imap_processing/hi/l1a/science_direct_event.py +6 -8
  54. imap_processing/hi/l1b/hi_l1b.py +111 -82
  55. imap_processing/hi/l1c/hi_l1c.py +416 -32
  56. imap_processing/hi/utils.py +58 -12
  57. imap_processing/hit/ancillary/imap_hit_l1b-to-l2-sector-dt0-factors_20250219_v002.csv +81 -0
  58. imap_processing/hit/ancillary/imap_hit_l1b-to-l2-standard-dt0-factors_20250219_v002.csv +205 -0
  59. imap_processing/hit/ancillary/imap_hit_l1b-to-l2-standard-dt1-factors_20250219_v002.csv +205 -0
  60. imap_processing/hit/ancillary/imap_hit_l1b-to-l2-standard-dt2-factors_20250219_v002.csv +205 -0
  61. imap_processing/hit/ancillary/imap_hit_l1b-to-l2-standard-dt3-factors_20250219_v002.csv +205 -0
  62. imap_processing/hit/ancillary/imap_hit_l1b-to-l2-summed-dt0-factors_20250219_v002.csv +68 -0
  63. imap_processing/hit/hit_utils.py +235 -5
  64. imap_processing/hit/l0/constants.py +20 -11
  65. imap_processing/hit/l0/decom_hit.py +21 -5
  66. imap_processing/hit/l1a/hit_l1a.py +71 -75
  67. imap_processing/hit/l1b/constants.py +321 -0
  68. imap_processing/hit/l1b/hit_l1b.py +377 -67
  69. imap_processing/hit/l2/constants.py +318 -0
  70. imap_processing/hit/l2/hit_l2.py +723 -0
  71. imap_processing/hit/packet_definitions/hit_packet_definitions.xml +1323 -71
  72. imap_processing/ialirt/l0/mag_l0_ialirt_data.py +155 -0
  73. imap_processing/ialirt/l0/parse_mag.py +374 -0
  74. imap_processing/ialirt/l0/process_swapi.py +69 -0
  75. imap_processing/ialirt/l0/process_swe.py +548 -0
  76. imap_processing/ialirt/packet_definitions/ialirt.xml +216 -208
  77. imap_processing/ialirt/packet_definitions/ialirt_codicehi.xml +1 -1
  78. imap_processing/ialirt/packet_definitions/ialirt_codicelo.xml +1 -1
  79. imap_processing/ialirt/packet_definitions/ialirt_mag.xml +115 -0
  80. imap_processing/ialirt/packet_definitions/ialirt_swapi.xml +14 -14
  81. imap_processing/ialirt/utils/grouping.py +114 -0
  82. imap_processing/ialirt/utils/time.py +29 -0
  83. imap_processing/idex/atomic_masses.csv +22 -0
  84. imap_processing/idex/decode.py +2 -2
  85. imap_processing/idex/idex_constants.py +33 -0
  86. imap_processing/idex/idex_l0.py +22 -8
  87. imap_processing/idex/idex_l1a.py +81 -51
  88. imap_processing/idex/idex_l1b.py +13 -39
  89. imap_processing/idex/idex_l2a.py +823 -0
  90. imap_processing/idex/idex_l2b.py +120 -0
  91. imap_processing/idex/idex_variable_unpacking_and_eu_conversion.csv +11 -11
  92. imap_processing/idex/packet_definitions/idex_housekeeping_packet_definition.xml +9130 -0
  93. imap_processing/lo/l0/lo_science.py +7 -2
  94. imap_processing/lo/l1a/lo_l1a.py +1 -5
  95. imap_processing/lo/l1b/lo_l1b.py +702 -29
  96. imap_processing/lo/l1b/tof_conversions.py +11 -0
  97. imap_processing/lo/l1c/lo_l1c.py +1 -4
  98. imap_processing/mag/constants.py +51 -0
  99. imap_processing/mag/imap_mag_sdc_configuration_v001.py +8 -0
  100. imap_processing/mag/l0/decom_mag.py +10 -3
  101. imap_processing/mag/l1a/mag_l1a.py +23 -19
  102. imap_processing/mag/l1a/mag_l1a_data.py +35 -10
  103. imap_processing/mag/l1b/mag_l1b.py +259 -50
  104. imap_processing/mag/l1c/interpolation_methods.py +388 -0
  105. imap_processing/mag/l1c/mag_l1c.py +621 -17
  106. imap_processing/mag/l2/mag_l2.py +140 -0
  107. imap_processing/mag/l2/mag_l2_data.py +288 -0
  108. imap_processing/quality_flags.py +1 -0
  109. imap_processing/spacecraft/packet_definitions/scid_x252.xml +538 -0
  110. imap_processing/spacecraft/quaternions.py +121 -0
  111. imap_processing/spice/geometry.py +19 -22
  112. imap_processing/spice/kernels.py +0 -276
  113. imap_processing/spice/pointing_frame.py +257 -0
  114. imap_processing/spice/repoint.py +149 -0
  115. imap_processing/spice/spin.py +38 -33
  116. imap_processing/spice/time.py +24 -0
  117. imap_processing/swapi/l1/swapi_l1.py +20 -12
  118. imap_processing/swapi/l2/swapi_l2.py +116 -5
  119. imap_processing/swapi/swapi_utils.py +32 -0
  120. imap_processing/swe/l1a/swe_l1a.py +44 -12
  121. imap_processing/swe/l1a/swe_science.py +13 -13
  122. imap_processing/swe/l1b/swe_l1b.py +898 -23
  123. imap_processing/swe/l2/swe_l2.py +75 -136
  124. imap_processing/swe/packet_definitions/swe_packet_definition.xml +1121 -1
  125. imap_processing/swe/utils/swe_constants.py +64 -0
  126. imap_processing/swe/utils/swe_utils.py +85 -28
  127. imap_processing/tests/ccsds/test_data/expected_output.xml +40 -1
  128. imap_processing/tests/ccsds/test_excel_to_xtce.py +24 -21
  129. imap_processing/tests/cdf/test_data/imap_instrument2_global_cdf_attrs.yaml +0 -2
  130. imap_processing/tests/cdf/test_utils.py +14 -16
  131. imap_processing/tests/codice/conftest.py +44 -33
  132. imap_processing/tests/codice/data/validation/imap_codice_l1a_hi-counters-aggregated_20241110193700_v0.0.0.cdf +0 -0
  133. imap_processing/tests/codice/data/validation/imap_codice_l1a_hi-counters-singles_20241110193700_v0.0.0.cdf +0 -0
  134. imap_processing/tests/codice/data/validation/imap_codice_l1a_hi-ialirt_20241110193700_v0.0.0.cdf +0 -0
  135. imap_processing/tests/codice/data/validation/imap_codice_l1a_hi-omni_20241110193700_v0.0.0.cdf +0 -0
  136. imap_processing/tests/codice/data/validation/imap_codice_l1a_hi-pha_20241110193700_v0.0.0.cdf +0 -0
  137. imap_processing/tests/codice/data/validation/imap_codice_l1a_hi-priorities_20241110193700_v0.0.0.cdf +0 -0
  138. imap_processing/tests/codice/data/validation/imap_codice_l1a_hi-sectored_20241110193700_v0.0.0.cdf +0 -0
  139. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-counters-aggregated_20241110193700_v0.0.0.cdf +0 -0
  140. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-counters-singles_20241110193700_v0.0.0.cdf +0 -0
  141. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-ialirt_20241110193700_v0.0.0.cdf +0 -0
  142. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-nsw-angular_20241110193700_v0.0.0.cdf +0 -0
  143. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-nsw-priority_20241110193700_v0.0.0.cdf +0 -0
  144. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-nsw-species_20241110193700_v0.0.0.cdf +0 -0
  145. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-pha_20241110193700_v0.0.0.cdf +0 -0
  146. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-sw-angular_20241110193700_v0.0.0.cdf +0 -0
  147. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-sw-priority_20241110193700_v0.0.0.cdf +0 -0
  148. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-sw-species_20241110193700_v0.0.0.cdf +0 -0
  149. imap_processing/tests/codice/test_codice_l1a.py +126 -53
  150. imap_processing/tests/codice/test_codice_l1b.py +6 -7
  151. imap_processing/tests/codice/test_decompress.py +4 -4
  152. imap_processing/tests/conftest.py +239 -27
  153. imap_processing/tests/ena_maps/conftest.py +51 -0
  154. imap_processing/tests/ena_maps/test_ena_maps.py +1068 -110
  155. imap_processing/tests/ena_maps/test_map_utils.py +66 -43
  156. imap_processing/tests/ena_maps/test_spatial_utils.py +17 -21
  157. imap_processing/tests/glows/conftest.py +10 -14
  158. imap_processing/tests/glows/test_glows_decom.py +4 -4
  159. imap_processing/tests/glows/test_glows_l1a_cdf.py +6 -27
  160. imap_processing/tests/glows/test_glows_l1a_data.py +6 -8
  161. imap_processing/tests/glows/test_glows_l1b.py +11 -11
  162. imap_processing/tests/glows/test_glows_l1b_data.py +5 -5
  163. imap_processing/tests/glows/test_glows_l2.py +2 -8
  164. imap_processing/tests/hi/conftest.py +1 -1
  165. imap_processing/tests/hi/data/l0/H45_diag_fee_20250208.bin +0 -0
  166. imap_processing/tests/hi/data/l0/H45_diag_fee_20250208_verify.csv +205 -0
  167. imap_processing/tests/hi/test_hi_l1b.py +22 -27
  168. imap_processing/tests/hi/test_hi_l1c.py +249 -18
  169. imap_processing/tests/hi/test_l1a.py +35 -7
  170. imap_processing/tests/hi/test_science_direct_event.py +3 -3
  171. imap_processing/tests/hi/test_utils.py +24 -2
  172. imap_processing/tests/hit/helpers/l1_validation.py +74 -73
  173. imap_processing/tests/hit/test_data/hskp_sample.ccsds +0 -0
  174. imap_processing/tests/hit/test_data/imap_hit_l0_raw_20100105_v001.pkts +0 -0
  175. imap_processing/tests/hit/test_decom_hit.py +5 -1
  176. imap_processing/tests/hit/test_hit_l1a.py +32 -36
  177. imap_processing/tests/hit/test_hit_l1b.py +300 -81
  178. imap_processing/tests/hit/test_hit_l2.py +716 -0
  179. imap_processing/tests/hit/test_hit_utils.py +184 -7
  180. imap_processing/tests/hit/validation_data/hit_l1b_standard_sample2_nsrl_v4_3decimals.csv +62 -62
  181. imap_processing/tests/hit/validation_data/hskp_sample_eu_3_6_2025.csv +89 -0
  182. imap_processing/tests/hit/validation_data/hskp_sample_raw.csv +89 -88
  183. imap_processing/tests/hit/validation_data/sci_sample_raw.csv +1 -1
  184. imap_processing/tests/ialirt/data/l0/461971383-404.bin +0 -0
  185. imap_processing/tests/ialirt/data/l0/461971384-405.bin +0 -0
  186. imap_processing/tests/ialirt/data/l0/461971385-406.bin +0 -0
  187. imap_processing/tests/ialirt/data/l0/461971386-407.bin +0 -0
  188. imap_processing/tests/ialirt/data/l0/461971387-408.bin +0 -0
  189. imap_processing/tests/ialirt/data/l0/461971388-409.bin +0 -0
  190. imap_processing/tests/ialirt/data/l0/461971389-410.bin +0 -0
  191. imap_processing/tests/ialirt/data/l0/461971390-411.bin +0 -0
  192. imap_processing/tests/ialirt/data/l0/461971391-412.bin +0 -0
  193. imap_processing/tests/ialirt/data/l0/sample_decoded_i-alirt_data.csv +383 -0
  194. imap_processing/tests/ialirt/unit/test_decom_ialirt.py +16 -81
  195. imap_processing/tests/ialirt/unit/test_grouping.py +81 -0
  196. imap_processing/tests/ialirt/unit/test_parse_mag.py +223 -0
  197. imap_processing/tests/ialirt/unit/test_process_codicehi.py +3 -3
  198. imap_processing/tests/ialirt/unit/test_process_codicelo.py +3 -10
  199. imap_processing/tests/ialirt/unit/test_process_ephemeris.py +4 -4
  200. imap_processing/tests/ialirt/unit/test_process_hit.py +3 -3
  201. imap_processing/tests/ialirt/unit/test_process_swapi.py +24 -16
  202. imap_processing/tests/ialirt/unit/test_process_swe.py +319 -6
  203. imap_processing/tests/ialirt/unit/test_time.py +16 -0
  204. imap_processing/tests/idex/conftest.py +127 -6
  205. imap_processing/tests/idex/test_data/imap_idex_l0_raw_20231218_v001.pkts +0 -0
  206. imap_processing/tests/idex/test_data/imap_idex_l0_raw_20241206_v001.pkts +0 -0
  207. imap_processing/tests/idex/test_data/imap_idex_l0_raw_20250108_v001.pkts +0 -0
  208. imap_processing/tests/idex/test_data/impact_14_tof_high_data.txt +4508 -4508
  209. imap_processing/tests/idex/test_idex_l0.py +33 -11
  210. imap_processing/tests/idex/test_idex_l1a.py +92 -21
  211. imap_processing/tests/idex/test_idex_l1b.py +106 -27
  212. imap_processing/tests/idex/test_idex_l2a.py +399 -0
  213. imap_processing/tests/idex/test_idex_l2b.py +93 -0
  214. imap_processing/tests/lo/test_cdfs/imap_lo_l1a_de_20241022_v002.cdf +0 -0
  215. imap_processing/tests/lo/test_cdfs/imap_lo_l1a_spin_20241022_v002.cdf +0 -0
  216. imap_processing/tests/lo/test_lo_l1a.py +3 -3
  217. imap_processing/tests/lo/test_lo_l1b.py +515 -6
  218. imap_processing/tests/lo/test_lo_l1c.py +1 -1
  219. imap_processing/tests/lo/test_lo_science.py +7 -7
  220. imap_processing/tests/lo/test_star_sensor.py +1 -1
  221. imap_processing/tests/mag/conftest.py +120 -2
  222. imap_processing/tests/mag/test_mag_decom.py +5 -4
  223. imap_processing/tests/mag/test_mag_l1a.py +51 -7
  224. imap_processing/tests/mag/test_mag_l1b.py +40 -59
  225. imap_processing/tests/mag/test_mag_l1c.py +354 -19
  226. imap_processing/tests/mag/test_mag_l2.py +130 -0
  227. imap_processing/tests/mag/test_mag_validation.py +247 -26
  228. imap_processing/tests/mag/validation/L1b/T009/MAGScience-normal-(2,2)-8s-20250204-16h39.csv +17 -0
  229. imap_processing/tests/mag/validation/L1b/T009/mag-l1a-l1b-t009-magi-out.csv +16 -16
  230. imap_processing/tests/mag/validation/L1b/T009/mag-l1a-l1b-t009-mago-out.csv +16 -16
  231. imap_processing/tests/mag/validation/L1b/T010/MAGScience-normal-(2,2)-8s-20250206-12h05.csv +17 -0
  232. imap_processing/tests/mag/validation/L1b/T011/MAGScience-normal-(2,2)-8s-20250204-16h08.csv +17 -0
  233. imap_processing/tests/mag/validation/L1b/T011/mag-l1a-l1b-t011-magi-out.csv +16 -16
  234. imap_processing/tests/mag/validation/L1b/T011/mag-l1a-l1b-t011-mago-out.csv +16 -16
  235. imap_processing/tests/mag/validation/L1b/T012/MAGScience-normal-(2,2)-8s-20250204-16h08.csv +17 -0
  236. imap_processing/tests/mag/validation/L1b/T012/data.bin +0 -0
  237. imap_processing/tests/mag/validation/L1b/T012/field_like_all_ranges.txt +19200 -0
  238. imap_processing/tests/mag/validation/L1b/T012/mag-l1a-l1b-t012-cal.cdf +0 -0
  239. imap_processing/tests/mag/validation/L1b/T012/mag-l1a-l1b-t012-in.csv +17 -0
  240. imap_processing/tests/mag/validation/L1b/T012/mag-l1a-l1b-t012-magi-out.csv +17 -0
  241. imap_processing/tests/mag/validation/L1b/T012/mag-l1a-l1b-t012-mago-out.csv +17 -0
  242. imap_processing/tests/mag/validation/L1c/T013/mag-l1b-l1c-t013-magi-normal-in.csv +1217 -0
  243. imap_processing/tests/mag/validation/L1c/T013/mag-l1b-l1c-t013-magi-normal-out.csv +1857 -0
  244. imap_processing/tests/mag/validation/L1c/T013/mag-l1b-l1c-t013-mago-normal-in.csv +1217 -0
  245. imap_processing/tests/mag/validation/L1c/T013/mag-l1b-l1c-t013-mago-normal-out.csv +1857 -0
  246. imap_processing/tests/mag/validation/L1c/T014/mag-l1b-l1c-t014-magi-normal-in.csv +1217 -0
  247. imap_processing/tests/mag/validation/L1c/T014/mag-l1b-l1c-t014-magi-normal-out.csv +1793 -0
  248. imap_processing/tests/mag/validation/L1c/T014/mag-l1b-l1c-t014-mago-normal-in.csv +1217 -0
  249. imap_processing/tests/mag/validation/L1c/T014/mag-l1b-l1c-t014-mago-normal-out.csv +1793 -0
  250. imap_processing/tests/mag/validation/L1c/T015/mag-l1b-l1c-t015-magi-burst-in.csv +2561 -0
  251. imap_processing/tests/mag/validation/L1c/T015/mag-l1b-l1c-t015-magi-normal-in.csv +961 -0
  252. imap_processing/tests/mag/validation/L1c/T015/mag-l1b-l1c-t015-magi-normal-out.csv +1539 -0
  253. imap_processing/tests/mag/validation/L1c/T015/mag-l1b-l1c-t015-mago-normal-in.csv +1921 -0
  254. imap_processing/tests/mag/validation/L1c/T015/mag-l1b-l1c-t015-mago-normal-out.csv +2499 -0
  255. imap_processing/tests/mag/validation/L1c/T016/mag-l1b-l1c-t016-magi-normal-in.csv +865 -0
  256. imap_processing/tests/mag/validation/L1c/T016/mag-l1b-l1c-t016-magi-normal-out.csv +1196 -0
  257. imap_processing/tests/mag/validation/L1c/T016/mag-l1b-l1c-t016-mago-normal-in.csv +1729 -0
  258. imap_processing/tests/mag/validation/L1c/T016/mag-l1b-l1c-t016-mago-normal-out.csv +3053 -0
  259. imap_processing/tests/mag/validation/L2/imap_mag_l1b_norm-mago_20251017_v002.cdf +0 -0
  260. imap_processing/tests/mag/validation/calibration/imap_mag_l1b-calibration_20240229_v001.cdf +0 -0
  261. imap_processing/tests/mag/validation/calibration/imap_mag_l2-calibration-matrices_20251017_v004.cdf +0 -0
  262. imap_processing/tests/mag/validation/calibration/imap_mag_l2-offsets-norm_20251017_20251017_v001.cdf +0 -0
  263. imap_processing/tests/spacecraft/data/SSR_2024_190_20_08_12_0483851794_2_DA_apid0594_1packet.pkts +0 -0
  264. imap_processing/tests/spacecraft/test_quaternions.py +71 -0
  265. imap_processing/tests/spice/test_data/fake_repoint_data.csv +5 -0
  266. imap_processing/tests/spice/test_data/fake_spin_data.csv +11 -11
  267. imap_processing/tests/spice/test_geometry.py +9 -12
  268. imap_processing/tests/spice/test_kernels.py +1 -200
  269. imap_processing/tests/spice/test_pointing_frame.py +185 -0
  270. imap_processing/tests/spice/test_repoint.py +121 -0
  271. imap_processing/tests/spice/test_spin.py +50 -9
  272. imap_processing/tests/spice/test_time.py +14 -0
  273. imap_processing/tests/swapi/lut/imap_swapi_esa-unit-conversion_20250211_v000.csv +73 -0
  274. imap_processing/tests/swapi/lut/imap_swapi_lut-notes_20250211_v000.csv +1025 -0
  275. imap_processing/tests/swapi/test_swapi_l1.py +13 -11
  276. imap_processing/tests/swapi/test_swapi_l2.py +180 -8
  277. imap_processing/tests/swe/l0_data/2024051010_SWE_HK_packet.bin +0 -0
  278. imap_processing/tests/swe/l0_data/2024051011_SWE_CEM_RAW_packet.bin +0 -0
  279. imap_processing/tests/swe/l0_validation_data/idle_export_eu.SWE_APP_HK_20240510_092742.csv +49 -0
  280. imap_processing/tests/swe/l0_validation_data/idle_export_eu.SWE_CEM_RAW_20240510_092742.csv +593 -0
  281. imap_processing/tests/swe/lut/checker-board-indices.csv +24 -0
  282. imap_processing/tests/swe/lut/imap_swe_esa-lut_20250301_v000.csv +385 -0
  283. imap_processing/tests/swe/lut/imap_swe_l1b-in-flight-cal_20240510_20260716_v000.csv +3 -0
  284. imap_processing/tests/swe/test_swe_l1a.py +20 -2
  285. imap_processing/tests/swe/test_swe_l1a_cem_raw.py +52 -0
  286. imap_processing/tests/swe/test_swe_l1a_hk.py +68 -0
  287. imap_processing/tests/swe/test_swe_l1a_science.py +3 -3
  288. imap_processing/tests/swe/test_swe_l1b.py +162 -24
  289. imap_processing/tests/swe/test_swe_l2.py +153 -91
  290. imap_processing/tests/test_cli.py +171 -88
  291. imap_processing/tests/test_utils.py +140 -17
  292. imap_processing/tests/ultra/data/l0/FM45_UltraFM45_Functional_2024-01-22T0105_20240122T010548.CCSDS +0 -0
  293. imap_processing/tests/ultra/data/l0/ultra45_raw_sc_ultraimgrates_20220530_00.csv +164 -0
  294. imap_processing/tests/ultra/{test_data → data}/l0/ultra45_raw_sc_ultrarawimg_withFSWcalcs_FM45_40P_Phi28p5_BeamCal_LinearScan_phi2850_theta-000_20240207T102740.csv +3243 -3243
  295. imap_processing/tests/ultra/data/mock_data.py +369 -0
  296. imap_processing/tests/ultra/unit/conftest.py +115 -89
  297. imap_processing/tests/ultra/unit/test_badtimes.py +4 -4
  298. imap_processing/tests/ultra/unit/test_cullingmask.py +8 -6
  299. imap_processing/tests/ultra/unit/test_de.py +14 -13
  300. imap_processing/tests/ultra/unit/test_decom_apid_880.py +27 -76
  301. imap_processing/tests/ultra/unit/test_decom_apid_881.py +54 -11
  302. imap_processing/tests/ultra/unit/test_decom_apid_883.py +12 -10
  303. imap_processing/tests/ultra/unit/test_decom_apid_896.py +202 -55
  304. imap_processing/tests/ultra/unit/test_lookup_utils.py +23 -1
  305. imap_processing/tests/ultra/unit/test_spacecraft_pset.py +77 -0
  306. imap_processing/tests/ultra/unit/test_ultra_l1a.py +98 -305
  307. imap_processing/tests/ultra/unit/test_ultra_l1b.py +60 -14
  308. imap_processing/tests/ultra/unit/test_ultra_l1b_annotated.py +2 -2
  309. imap_processing/tests/ultra/unit/test_ultra_l1b_culling.py +26 -27
  310. imap_processing/tests/ultra/unit/test_ultra_l1b_extended.py +239 -70
  311. imap_processing/tests/ultra/unit/test_ultra_l1c.py +5 -5
  312. imap_processing/tests/ultra/unit/test_ultra_l1c_pset_bins.py +114 -83
  313. imap_processing/tests/ultra/unit/test_ultra_l2.py +230 -0
  314. imap_processing/ultra/constants.py +1 -1
  315. imap_processing/ultra/l0/decom_tools.py +27 -39
  316. imap_processing/ultra/l0/decom_ultra.py +168 -204
  317. imap_processing/ultra/l0/ultra_utils.py +152 -136
  318. imap_processing/ultra/l1a/ultra_l1a.py +55 -271
  319. imap_processing/ultra/l1b/badtimes.py +1 -4
  320. imap_processing/ultra/l1b/cullingmask.py +2 -6
  321. imap_processing/ultra/l1b/de.py +116 -57
  322. imap_processing/ultra/l1b/extendedspin.py +20 -18
  323. imap_processing/ultra/l1b/lookup_utils.py +72 -9
  324. imap_processing/ultra/l1b/ultra_l1b.py +36 -16
  325. imap_processing/ultra/l1b/ultra_l1b_culling.py +66 -30
  326. imap_processing/ultra/l1b/ultra_l1b_extended.py +297 -94
  327. imap_processing/ultra/l1c/histogram.py +2 -6
  328. imap_processing/ultra/l1c/spacecraft_pset.py +84 -0
  329. imap_processing/ultra/l1c/ultra_l1c.py +8 -9
  330. imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +206 -108
  331. imap_processing/ultra/l2/ultra_l2.py +299 -0
  332. imap_processing/ultra/lookup_tables/Angular_Profiles_FM45_LeftSlit.csv +526 -0
  333. imap_processing/ultra/lookup_tables/Angular_Profiles_FM45_RightSlit.csv +526 -0
  334. imap_processing/ultra/lookup_tables/Angular_Profiles_FM90_LeftSlit.csv +526 -0
  335. imap_processing/ultra/lookup_tables/Angular_Profiles_FM90_RightSlit.csv +526 -0
  336. imap_processing/ultra/lookup_tables/FM45_Startup1_ULTRA_IMGPARAMS_20240719.csv +2 -2
  337. imap_processing/ultra/lookup_tables/FM90_Startup1_ULTRA_IMGPARAMS_20240719.csv +2 -0
  338. imap_processing/ultra/packet_definitions/README.md +38 -0
  339. imap_processing/ultra/packet_definitions/ULTRA_SCI_COMBINED.xml +15302 -482
  340. imap_processing/ultra/utils/ultra_l1_utils.py +31 -12
  341. imap_processing/utils.py +69 -29
  342. {imap_processing-0.11.0.dist-info → imap_processing-0.13.0.dist-info}/METADATA +10 -6
  343. imap_processing-0.13.0.dist-info/RECORD +578 -0
  344. imap_processing/cdf/config/imap_mag_l1_variable_attrs.yaml +0 -237
  345. imap_processing/hi/l1a/housekeeping.py +0 -27
  346. imap_processing/hi/l1b/hi_eng_unit_convert_table.csv +0 -154
  347. imap_processing/swe/l1b/swe_esa_lookup_table.csv +0 -1441
  348. imap_processing/swe/l1b/swe_l1b_science.py +0 -652
  349. imap_processing/tests/codice/data/imap_codice_l1a_hi-counters-aggregated_20240429_v001.cdf +0 -0
  350. imap_processing/tests/codice/data/imap_codice_l1a_hi-counters-singles_20240429_v001.cdf +0 -0
  351. imap_processing/tests/codice/data/imap_codice_l1a_hi-omni_20240429_v001.cdf +0 -0
  352. imap_processing/tests/codice/data/imap_codice_l1a_hi-sectored_20240429_v001.cdf +0 -0
  353. imap_processing/tests/codice/data/imap_codice_l1a_hskp_20100101_v001.cdf +0 -0
  354. imap_processing/tests/codice/data/imap_codice_l1a_lo-counters-aggregated_20240429_v001.cdf +0 -0
  355. imap_processing/tests/codice/data/imap_codice_l1a_lo-counters-singles_20240429_v001.cdf +0 -0
  356. imap_processing/tests/codice/data/imap_codice_l1a_lo-nsw-angular_20240429_v001.cdf +0 -0
  357. imap_processing/tests/codice/data/imap_codice_l1a_lo-nsw-priority_20240429_v001.cdf +0 -0
  358. imap_processing/tests/codice/data/imap_codice_l1a_lo-nsw-species_20240429_v001.cdf +0 -0
  359. imap_processing/tests/codice/data/imap_codice_l1a_lo-sw-angular_20240429_v001.cdf +0 -0
  360. imap_processing/tests/codice/data/imap_codice_l1a_lo-sw-priority_20240429_v001.cdf +0 -0
  361. imap_processing/tests/codice/data/imap_codice_l1a_lo-sw-species_20240429_v001.cdf +0 -0
  362. imap_processing/tests/codice/data/imap_codice_l1b_hi-counters-aggregated_20240429_v001.cdf +0 -0
  363. imap_processing/tests/codice/data/imap_codice_l1b_hi-counters-singles_20240429_v001.cdf +0 -0
  364. imap_processing/tests/codice/data/imap_codice_l1b_hi-omni_20240429_v001.cdf +0 -0
  365. imap_processing/tests/codice/data/imap_codice_l1b_hi-sectored_20240429_v001.cdf +0 -0
  366. imap_processing/tests/codice/data/imap_codice_l1b_hskp_20100101_v001.cdf +0 -0
  367. imap_processing/tests/codice/data/imap_codice_l1b_lo-counters-aggregated_20240429_v001.cdf +0 -0
  368. imap_processing/tests/codice/data/imap_codice_l1b_lo-counters-singles_20240429_v001.cdf +0 -0
  369. imap_processing/tests/codice/data/imap_codice_l1b_lo-nsw-angular_20240429_v001.cdf +0 -0
  370. imap_processing/tests/codice/data/imap_codice_l1b_lo-nsw-priority_20240429_v001.cdf +0 -0
  371. imap_processing/tests/codice/data/imap_codice_l1b_lo-nsw-species_20240429_v001.cdf +0 -0
  372. imap_processing/tests/codice/data/imap_codice_l1b_lo-sw-angular_20240429_v001.cdf +0 -0
  373. imap_processing/tests/codice/data/imap_codice_l1b_lo-sw-priority_20240429_v001.cdf +0 -0
  374. imap_processing/tests/codice/data/imap_codice_l1b_lo-sw-species_20240429_v001.cdf +0 -0
  375. imap_processing/tests/hi/data/l1/imap_hi_l1b_45sensor-de_20250415_v999.cdf +0 -0
  376. imap_processing/tests/hit/PREFLIGHT_raw_record_2023_256_15_59_04_apid1251.pkts +0 -0
  377. imap_processing/tests/hit/PREFLIGHT_raw_record_2023_256_15_59_04_apid1252.pkts +0 -0
  378. imap_processing/tests/hit/validation_data/hskp_sample_eu.csv +0 -89
  379. imap_processing/tests/hit/validation_data/sci_sample_raw1.csv +0 -29
  380. imap_processing/tests/idex/test_data/imap_idex_l0_raw_20231214_v001.pkts +0 -0
  381. imap_processing/tests/lo/test_cdfs/imap_lo_l1a_de_20100101_v001.cdf +0 -0
  382. imap_processing/tests/lo/test_cdfs/imap_lo_l1a_spin_20100101_v001.cdf +0 -0
  383. imap_processing/tests/swe/test_swe_l1b_science.py +0 -84
  384. imap_processing/tests/ultra/test_data/mock_data.py +0 -161
  385. imap_processing/ultra/l1c/pset.py +0 -40
  386. imap_processing/ultra/lookup_tables/dps_sensitivity45.cdf +0 -0
  387. imap_processing-0.11.0.dist-info/RECORD +0 -488
  388. /imap_processing/idex/packet_definitions/{idex_packet_definition.xml → idex_science_packet_definition.xml} +0 -0
  389. /imap_processing/tests/ialirt/{test_data → data}/l0/20240827095047_SWE_IALIRT_packet.bin +0 -0
  390. /imap_processing/tests/ialirt/{test_data → data}/l0/BinLog CCSDS_FRAG_TLM_20240826_152323Z_IALIRT_data_for_SDC.bin +0 -0
  391. /imap_processing/tests/ialirt/{test_data → data}/l0/IALiRT Raw Packet Telemetry.txt +0 -0
  392. /imap_processing/tests/ialirt/{test_data → data}/l0/apid01152.tlm +0 -0
  393. /imap_processing/tests/ialirt/{test_data → data}/l0/eu_SWP_IAL_20240826_152033.csv +0 -0
  394. /imap_processing/tests/ialirt/{test_data → data}/l0/hi_fsw_view_1_ccsds.bin +0 -0
  395. /imap_processing/tests/ialirt/{test_data → data}/l0/hit_ialirt_sample.ccsds +0 -0
  396. /imap_processing/tests/ialirt/{test_data → data}/l0/hit_ialirt_sample.csv +0 -0
  397. /imap_processing/tests/ialirt/{test_data → data}/l0/idle_export_eu.SWE_IALIRT_20240827_093852.csv +0 -0
  398. /imap_processing/tests/ialirt/{test_data → data}/l0/imap_codice_l1a_hi-ialirt_20240523200000_v0.0.0.cdf +0 -0
  399. /imap_processing/tests/ialirt/{test_data → data}/l0/imap_codice_l1a_lo-ialirt_20241110193700_v0.0.0.cdf +0 -0
  400. /imap_processing/{mag/l1b → tests/spacecraft}/__init__.py +0 -0
  401. /imap_processing/{swe/l1b/engineering_unit_convert_table.csv → tests/swe/lut/imap_swe_eu-conversion_20240510_v000.csv} +0 -0
  402. /imap_processing/tests/ultra/{test_data → data}/l0/FM45_40P_Phi28p5_BeamCal_LinearScan_phi28.50_theta-0.00_20240207T102740.CCSDS +0 -0
  403. /imap_processing/tests/ultra/{test_data → data}/l0/FM45_7P_Phi0.0_BeamCal_LinearScan_phi0.04_theta-0.01_20230821T121304.CCSDS +0 -0
  404. /imap_processing/tests/ultra/{test_data → data}/l0/FM45_TV_Cycle6_Hot_Ops_Front212_20240124T063837.CCSDS +0 -0
  405. /imap_processing/tests/ultra/{test_data → data}/l0/Ultra45_EM_SwRI_Cal_Run7_ThetaScan_20220530T225054.CCSDS +0 -0
  406. /imap_processing/tests/ultra/{test_data → data}/l0/ultra45_raw_sc_auxdata_Ultra45_EM_SwRI_Cal_Run7_ThetaScan_20220530T225054.csv +0 -0
  407. /imap_processing/tests/ultra/{test_data → data}/l0/ultra45_raw_sc_enaphxtofhangimg_FM45_TV_Cycle6_Hot_Ops_Front212_20240124T063837.csv +0 -0
  408. /imap_processing/tests/ultra/{test_data → data}/l0/ultra45_raw_sc_ultraimgrates_Ultra45_EM_SwRI_Cal_Run7_ThetaScan_20220530T225054.csv +0 -0
  409. /imap_processing/tests/ultra/{test_data → data}/l0/ultra45_raw_sc_ultrarawimgevent_FM45_7P_Phi00_BeamCal_LinearScan_phi004_theta-001_20230821T121304.csv +0 -0
  410. /imap_processing/tests/ultra/{test_data → data}/l1/dps_exposure_helio_45_E1.cdf +0 -0
  411. /imap_processing/tests/ultra/{test_data → data}/l1/dps_exposure_helio_45_E12.cdf +0 -0
  412. /imap_processing/tests/ultra/{test_data → data}/l1/dps_exposure_helio_45_E24.cdf +0 -0
  413. {imap_processing-0.11.0.dist-info → imap_processing-0.13.0.dist-info}/LICENSE +0 -0
  414. {imap_processing-0.11.0.dist-info → imap_processing-0.13.0.dist-info}/WHEEL +0 -0
  415. {imap_processing-0.11.0.dist-info → imap_processing-0.13.0.dist-info}/entry_points.txt +0 -0
@@ -1,18 +1,74 @@
1
1
  from collections import namedtuple
2
+ from unittest.mock import patch
3
+
4
+ import numpy as np
5
+ import pytest
6
+ import xarray as xr
2
7
 
3
8
  from imap_processing import imap_module_directory
4
9
  from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
5
10
  from imap_processing.cdf.utils import load_cdf
6
- from imap_processing.lo.l1b.lo_l1b import create_datasets, lo_l1b
11
+ from imap_processing.lo.l1b.lo_l1b import (
12
+ calculate_tof1_for_golden_triples,
13
+ convert_start_end_acq_times,
14
+ convert_tofs_to_eu,
15
+ create_datasets,
16
+ get_avg_spin_durations,
17
+ get_spin_angle,
18
+ get_spin_start_times,
19
+ identify_species,
20
+ initialize_l1b_de,
21
+ lo_l1b,
22
+ set_bad_times,
23
+ set_coincidence_type,
24
+ set_each_event_epoch,
25
+ set_event_met,
26
+ set_pointing_bin,
27
+ set_pointing_direction,
28
+ set_spin_bin,
29
+ set_spin_cycle,
30
+ )
31
+ from imap_processing.spice.time import met_to_ttj2000ns
32
+
33
+
34
+ @pytest.fixture
35
+ def dependencies():
36
+ return {
37
+ "imap_lo_l1a_de": load_cdf(
38
+ imap_module_directory
39
+ / "tests/lo/test_cdfs/imap_lo_l1a_de_20241022_v002.cdf"
40
+ ),
41
+ "imap_lo_l1a_spin": load_cdf(
42
+ imap_module_directory
43
+ / "tests/lo/test_cdfs/imap_lo_l1a_spin_20241022_v002.cdf"
44
+ ),
45
+ }
46
+
47
+
48
+ @pytest.fixture
49
+ def attr_mgr_l1b():
50
+ attr_mgr_l1b = ImapCdfAttributes()
51
+ attr_mgr_l1b.add_instrument_global_attrs(instrument="lo")
52
+ attr_mgr_l1b.add_instrument_variable_attrs(instrument="lo", level="l1b")
53
+ return attr_mgr_l1b
7
54
 
8
55
 
9
- def test_lo_l1b():
56
+ @pytest.fixture
57
+ def attr_mgr_l1a():
58
+ attr_mgr = ImapCdfAttributes()
59
+ attr_mgr.add_instrument_global_attrs(instrument="lo")
60
+ attr_mgr.add_instrument_variable_attrs(instrument="lo", level="l1a")
61
+ return attr_mgr
62
+
63
+
64
+ @patch("imap_processing.lo.l1b.lo_l1b.instrument_pointing")
65
+ def test_lo_l1b(mock_instrument_pointing):
10
66
  # Arrange
11
67
  de_file = (
12
- imap_module_directory / "tests/lo/test_cdfs/imap_lo_l1a_de_20100101_v001.cdf"
68
+ imap_module_directory / "tests/lo/test_cdfs/imap_lo_l1a_de_20241022_v002.cdf"
13
69
  )
14
70
  spin_file = (
15
- imap_module_directory / "tests/lo/test_cdfs/imap_lo_l1a_spin_20100101_v001.cdf"
71
+ imap_module_directory / "tests/lo/test_cdfs/imap_lo_l1a_spin_20241022_v002.cdf"
16
72
  )
17
73
  data = {}
18
74
  for file in [de_file, spin_file]:
@@ -20,13 +76,16 @@ def test_lo_l1b():
20
76
  data[dataset.attrs["Logical_source"]] = dataset
21
77
 
22
78
  expected_logical_source = "imap_lo_l1b_de"
79
+ mock_instrument_pointing.return_value = np.zeros((2000, 2))
23
80
  # Act
24
- output_file = lo_l1b(data, "001")
81
+ output_file = lo_l1b(data)
25
82
 
26
83
  # Assert
27
- assert expected_logical_source == output_file.attrs["Logical_source"]
84
+ assert expected_logical_source == output_file[0].attrs["Logical_source"]
28
85
 
29
86
 
87
+ # @pytest.mark.external_kernel
88
+ # @pytest.mark.use_test_metakernel("imap_ena_sim_metakernel.template")
30
89
  def test_create_datasets():
31
90
  attr_mgr = ImapCdfAttributes()
32
91
  attr_mgr.add_instrument_global_attrs(instrument="lo")
@@ -72,3 +131,453 @@ def test_create_datasets():
72
131
  assert dataset.badtime.shape[0] == 3
73
132
  assert len(dataset.esa_step.shape) == 1
74
133
  assert dataset.esa_step.shape[0] == 3
134
+
135
+
136
+ def test_initialize_dataset(dependencies, attr_mgr_l1b):
137
+ # Arrange
138
+ l1a_de = dependencies["imap_lo_l1a_de"]
139
+ logical_source = "imap_lo_l1b_de"
140
+
141
+ # Act
142
+ l1b_de = initialize_l1b_de(l1a_de, attr_mgr_l1b, logical_source)
143
+
144
+ # Assert
145
+ assert l1b_de.attrs["Logical_source"] == logical_source
146
+ assert list(l1b_de.coords.keys()) == []
147
+ assert len(l1b_de.data_vars) == 4
148
+ assert len(l1b_de.coords) == 0
149
+ for l1b_name, l1a_name in {
150
+ "pos": "pos",
151
+ "mode": "mode",
152
+ "absent": "coincidence_type",
153
+ "esa_step": "esa_step",
154
+ }.items():
155
+ assert l1b_name in l1b_de.data_vars
156
+ np.testing.assert_array_equal(l1b_de[l1b_name], l1a_de[l1a_name])
157
+
158
+
159
+ def test_convert_start_end_acq_times():
160
+ # Arrange
161
+ spin = xr.Dataset(
162
+ {
163
+ "acq_start_sec": ("epoch", [1, 2, 3]),
164
+ "acq_start_subsec": ("epoch", [4, 5, 6]),
165
+ "acq_end_sec": ("epoch", [7, 8, 9]),
166
+ "acq_end_subsec": ("epoch", [10, 11, 12]),
167
+ },
168
+ coords={"epoch": [0, 1, 2]},
169
+ )
170
+
171
+ acq_start_expected = xr.DataArray(
172
+ [
173
+ spin["acq_start_sec"][0] + spin["acq_start_subsec"][0] * 1e-6,
174
+ spin["acq_start_sec"][1] + spin["acq_start_subsec"][1] * 1e-6,
175
+ spin["acq_start_sec"][2] + spin["acq_start_subsec"][2] * 1e-6,
176
+ ],
177
+ dims="epoch",
178
+ )
179
+ acq_end_expected = xr.DataArray(
180
+ [
181
+ spin["acq_end_sec"][0] + spin["acq_end_subsec"][0] * 1e-6,
182
+ spin["acq_end_sec"][1] + spin["acq_end_subsec"][1] * 1e-6,
183
+ spin["acq_end_sec"][2] + spin["acq_end_subsec"][2] * 1e-6,
184
+ ],
185
+ dims="epoch",
186
+ )
187
+
188
+ # Act
189
+ acq_start, acq_end = convert_start_end_acq_times(spin)
190
+
191
+ # Assert
192
+ np.testing.assert_array_equal(acq_start.values, acq_start_expected.values)
193
+ np.testing.assert_array_equal(acq_end.values, acq_end_expected.values)
194
+
195
+
196
+ def test_get_avg_spin_durations():
197
+ # Arrange
198
+ acq_start = xr.DataArray([0, 423, 846.2], dims="epoch")
199
+ acq_end = xr.DataArray([422.8, 846, 1269.7], dims="epoch")
200
+ expected_avg_spin_durations = np.array([422.8, 423, 423.5]) / 28
201
+
202
+ # Act
203
+ avg_spin_durations = get_avg_spin_durations(acq_start, acq_end)
204
+
205
+ # Assert
206
+ np.testing.assert_array_equal(avg_spin_durations, expected_avg_spin_durations)
207
+
208
+
209
+ def test_get_spin_angle():
210
+ # Arrange
211
+ de = xr.Dataset(
212
+ {
213
+ "de_count": ("epoch", [2, 3]),
214
+ "de_time": ("direct_event", [0000, 1000, 2000, 3000, 4000]),
215
+ },
216
+ coords={"epoch": [0, 1], "direct_event": [0, 1, 2, 3, 4]},
217
+ )
218
+ spin_angle_expected = np.array([0, 87.89, 175.78, 263.67, 351.56])
219
+
220
+ # Act
221
+ spin_angle = get_spin_angle(de)
222
+
223
+ # Assert
224
+ np.testing.assert_allclose(
225
+ spin_angle,
226
+ spin_angle_expected,
227
+ atol=1e-2,
228
+ )
229
+
230
+
231
+ def test_spin_bin():
232
+ # Arrange
233
+ l1b_de = xr.Dataset()
234
+ spin_angle = np.array([0, 50, 150, 250, 365])
235
+ expected_spin_bins = np.array([0, 8, 25, 41, 60])
236
+
237
+ # Act
238
+ l1b_de = set_spin_bin(l1b_de, spin_angle)
239
+
240
+ # Assert
241
+ np.testing.assert_array_equal(l1b_de["spin_bin"], expected_spin_bins)
242
+
243
+
244
+ def test_spin_cycle():
245
+ # Arrange
246
+ de = xr.Dataset(
247
+ {
248
+ "de_count": ("epoch", [2, 3]),
249
+ "esa_step": ("direct_event", [1, 2, 3, 4, 5]),
250
+ },
251
+ coords={"epoch": [0, 1], "direct_event": [1, 2, 3, 4, 5]},
252
+ )
253
+
254
+ # spin_cycle = spin_start + 7 + (esa_step - 1) * 2
255
+ # where spin start is the spin number for the first spin
256
+ # in an Aggregated Science Cycle (first spin number of an epoch)
257
+ # and esa_step is the esa_step for a direct event
258
+ spin_cycle_expected = np.array([7, 9, 39, 41, 43])
259
+ spin_cycle_data = xr.Dataset()
260
+
261
+ # Act
262
+ spin_cycle_data = set_spin_cycle(de, spin_cycle_data)
263
+
264
+ # Assert
265
+ np.testing.assert_array_equal(spin_cycle_data["spin_cycle"], spin_cycle_expected)
266
+
267
+
268
+ def test_get_spin_start_times():
269
+ # Arrange
270
+ l1b_de = xr.Dataset(
271
+ {
272
+ "spin_cycle": ("epoch", [0, 1, 2, 3, 4]),
273
+ },
274
+ coords={
275
+ "epoch": [
276
+ 0,
277
+ 1,
278
+ 2,
279
+ 3,
280
+ 4,
281
+ ]
282
+ },
283
+ )
284
+ l1a_de = xr.Dataset(
285
+ {
286
+ "de_count": ("epoch", [2, 3]),
287
+ "met": ("direct_event", [0, 1, 2, 3, 4]),
288
+ "de_time": ("direct_event", [0000, 1000, 2000, 3000, 4000]),
289
+ },
290
+ coords={"epoch": [0, 1], "direct_event": [0, 1, 2, 3, 4]},
291
+ )
292
+ spin = xr.Dataset(
293
+ {
294
+ "start_sec_spin": (
295
+ ["epoch", "spin"],
296
+ [[20, 25, 30, 35, 40], [45, 50, 55, 60, 65]],
297
+ ),
298
+ "start_subsec_spin": (
299
+ ["epoch", "spin"],
300
+ [[2000, 3000, 4000, 5000, 6000], [1000, 1500, 2000, 3000, 4000]],
301
+ ),
302
+ }
303
+ )
304
+
305
+ end_acq = xr.DataArray([0, 1], dims="epoch")
306
+ spin_start_times_expected = np.array([20.002, 50.0015, 55.002, 60.003, 65.004])
307
+ spin_start_times = get_spin_start_times(l1a_de, l1b_de, spin, end_acq)
308
+
309
+ np.testing.assert_allclose(
310
+ spin_start_times,
311
+ spin_start_times_expected,
312
+ atol=1e-4,
313
+ )
314
+
315
+
316
+ def test_set_event_met():
317
+ # Arrange
318
+ l1b_de = xr.Dataset()
319
+ l1a_de = xr.Dataset(
320
+ {
321
+ "de_count": ("epoch", [2, 3]),
322
+ "de_time": ("direct_event", [0000, 1000, 2000, 3000, 4000]),
323
+ },
324
+ coords={
325
+ "epoch": [0, 1],
326
+ "direct_event": [
327
+ 0,
328
+ 1,
329
+ 2,
330
+ 3,
331
+ 4,
332
+ ],
333
+ },
334
+ )
335
+ avg_spin_durations = xr.DataArray([5, 10])
336
+ spin_start_times = xr.DataArray([10, 20, 30, 40, 50])
337
+ expected_event_met = np.array([10, 21.2207, 34.8828, 47.3242, 59.7656])
338
+
339
+ # Act
340
+ l1b_de = set_event_met(l1a_de, l1b_de, spin_start_times, avg_spin_durations)
341
+
342
+ # Assert
343
+ np.testing.assert_allclose(
344
+ l1b_de["event_met"].values,
345
+ expected_event_met,
346
+ atol=1e-4,
347
+ )
348
+
349
+ def test_set_each_event_epoch():
350
+ l1b_de = xr.Dataset(
351
+ {
352
+ "event_met": ("epoch", [10, 20, 30, 40, 50]),
353
+ },
354
+ coords={
355
+ "epoch": [0, 1, 2, 3, 4],
356
+ },
357
+ )
358
+ epoch_expected = met_to_ttj2000ns(np.array([10, 20, 30, 40, 50]))
359
+
360
+ l1b_de = set_each_event_epoch(l1b_de)
361
+
362
+ np.testing.assert_allclose(
363
+ l1b_de["epoch"].values,
364
+ epoch_expected,
365
+ atol=1e-4,
366
+ )
367
+
368
+
369
+ def test_calculate_tof1_for_golden_triples():
370
+ # Arrange
371
+ l1a_de = xr.Dataset(
372
+ {
373
+ "coincidence_type": ("epoch", [0, 0, 0]),
374
+ "mode": ("epoch", [0, 0, 1]),
375
+ "tof0": ("epoch", [2, 4, 2]),
376
+ "tof1": ("epoch", [0, 0, 0]),
377
+ "tof2": ("epoch", [2, 6, 2]),
378
+ "tof3": ("epoch", [2, 8, 2]),
379
+ "cksm": ("epoch", [2, 12, 2]),
380
+ }
381
+ )
382
+
383
+ l1a_de_expected = xr.Dataset(
384
+ {
385
+ "coincidence_type": ("epoch", [0, 0, 0]),
386
+ "mode": ("epoch", [0, 0, 1]),
387
+ "tof0": ("epoch", [2, 4, 2]),
388
+ "tof1": ("epoch", [42, 36, 0]),
389
+ "tof2": ("epoch", [2, 6, 2]),
390
+ "tof3": ("epoch", [2, 8, 2]),
391
+ "cksm": ("epoch", [2, 12, 2]),
392
+ }
393
+ )
394
+
395
+ # Act
396
+ l1a_de = calculate_tof1_for_golden_triples(l1a_de)
397
+
398
+ # Assert
399
+ assert l1a_de_expected.equals(l1a_de)
400
+
401
+
402
+ def test_set_coincidence_type(attr_mgr_l1a):
403
+ # Arrange
404
+ l1b_de = xr.Dataset()
405
+ tof_fill = attr_mgr_l1a.get_variable_attributes("tof0")["FILLVAL"]
406
+ ckm_fill = attr_mgr_l1a.get_variable_attributes("cksm")["FILLVAL"]
407
+ l1a_de = xr.Dataset(
408
+ {
409
+ "de_count": ("epoch", [3]),
410
+ "coincidence_type": ("direct_events", [0, 0, 4]),
411
+ "mode": ("direct_events", [1, 0, 1]),
412
+ "tof0": ("direct_events", [5, 2, 10]),
413
+ "tof1": ("direct_events", [10, 4, tof_fill]),
414
+ "tof2": ("direct_events", [15, 6, 20]),
415
+ "tof3": ("direct_events", [20, 8, 30]),
416
+ "cksm": ("direct_events", [25, ckm_fill, ckm_fill]),
417
+ },
418
+ coords={
419
+ "epoch": [0],
420
+ "direct_events": [0, 1, 2],
421
+ },
422
+ )
423
+
424
+ coincidence_type_expected = np.array(["111111", "111100", "101101"])
425
+
426
+ # Act
427
+ l1b_de = set_coincidence_type(l1a_de, l1b_de, attr_mgr_l1a)
428
+
429
+ # Assert
430
+ np.testing.assert_array_equal(
431
+ l1b_de["coincidence_type"].values,
432
+ coincidence_type_expected,
433
+ )
434
+
435
+
436
+ def test_convert_tofs_to_eu(attr_mgr_l1b, attr_mgr_l1a):
437
+ l1b_de = xr.Dataset()
438
+ tof_fill_l1a = attr_mgr_l1a.get_variable_attributes("tof0")["FILLVAL"]
439
+ tof_fill_l1b = attr_mgr_l1b.get_variable_attributes("tof1")["FILLVAL"]
440
+ l1a_de = xr.Dataset(
441
+ {
442
+ "de_count": ("epoch", [2]),
443
+ "coincidence_type": ("direct_events", [0, 4]),
444
+ "mode": ("direct_events", [1, 0]),
445
+ "tof0": ("direct_events", [5, 2]),
446
+ "tof1": ("direct_events", [10, tof_fill_l1a]),
447
+ "tof2": ("direct_events", [15, 6]),
448
+ "tof3": ("direct_events", [20, 8]),
449
+ },
450
+ coords={
451
+ "epoch": [0],
452
+ "direct_events": [0, 1],
453
+ },
454
+ )
455
+
456
+ tof0_expected = np.array([1.394394, 0.889272])
457
+ tof1_expected = np.array([0.931059, tof_fill_l1b])
458
+ tof2_expected = np.array([2.870557, 1.372876])
459
+ tof3_expected = np.array([3.88245, 1.818162])
460
+
461
+ # Act
462
+ l1b_de = convert_tofs_to_eu(l1a_de, l1b_de, attr_mgr_l1a, attr_mgr_l1b)
463
+
464
+ tof_checks = [
465
+ ("tof0", tof0_expected),
466
+ ("tof1", tof1_expected),
467
+ ("tof2", tof2_expected),
468
+ ("tof3", tof3_expected),
469
+ ]
470
+ # Assert
471
+ for tof, expected_tof in tof_checks:
472
+ np.testing.assert_allclose(
473
+ l1b_de[tof].values,
474
+ expected_tof,
475
+ atol=1e-6,
476
+ )
477
+
478
+
479
+ def test_identify_species(attr_mgr_l1b):
480
+ # Arrange
481
+ fill_val = attr_mgr_l1b.get_variable_attributes("tof2")["FILLVAL"]
482
+ l1b_de = xr.Dataset(
483
+ {
484
+ "tof2": ("epoch", [1, 14, 50, 80, 500, fill_val]),
485
+ }
486
+ )
487
+
488
+ expected_species = np.array(["U", "H", "U", "O", "U", "U"])
489
+
490
+ # Act
491
+ l1b_de = identify_species(l1b_de)
492
+
493
+ # Assert
494
+ np.testing.assert_array_equal(l1b_de["species"], expected_species)
495
+
496
+
497
+ def test_set_bad_times():
498
+ # Arrange
499
+ l1b_de = xr.Dataset(
500
+ {},
501
+ coords={
502
+ "epoch": [0, 1, 2],
503
+ },
504
+ )
505
+
506
+ expected_bad_times = np.array([0, 0, 0])
507
+
508
+ # Act
509
+ l1b_de = set_bad_times(l1b_de)
510
+
511
+ # Assert
512
+ np.testing.assert_array_equal(l1b_de["badtimes"], expected_bad_times)
513
+
514
+
515
+ @pytest.mark.external_kernel
516
+ @pytest.mark.use_test_metakernel("imap_ena_sim_metakernel.template")
517
+ def test_set_direction():
518
+ # Arrange
519
+ l1b_de = xr.Dataset(
520
+ {},
521
+ coords={
522
+ "epoch": [
523
+ 7.9794907254e17,
524
+ # + 1 second. Should be 24deg diff from
525
+ # previous epoch
526
+ 7.9794907254e17 + 1e9,
527
+ # + 7.5 seconds. Should be 180deg diff from
528
+ # first epoch
529
+ 7.9794907254e17 + 7.5e9,
530
+ # + 15 seconds. Should be 360deg diff from
531
+ # previous epoch
532
+ 7.9794907254e17 + 15e9,
533
+ ],
534
+ },
535
+ )
536
+ # latitudes are -90 to 90
537
+ expected_direction_lat = np.array([0, 0, 0, 0])
538
+ # longitude are -180 to 180
539
+ expected_direction_lon = np.array([140.5, 164.5, -39.5, 140.5])
540
+
541
+ # Act
542
+ l1b_de = set_pointing_direction(l1b_de)
543
+
544
+ # Assert
545
+ np.testing.assert_allclose(
546
+ l1b_de["direction_lat"].values,
547
+ expected_direction_lat,
548
+ atol=1e-1,
549
+ )
550
+ np.testing.assert_allclose(
551
+ l1b_de["direction_lon"].values,
552
+ expected_direction_lon,
553
+ atol=1e-1,
554
+ )
555
+
556
+
557
+ def test_pointing_bins():
558
+ # Arrange
559
+ l1b_de = xr.Dataset(
560
+ {
561
+ "direction_lat": ("epoch", [0, 0, 0, 0, 0]),
562
+ "direction_lon": ("epoch", [-180, 91.3, 116.3, 140.5, 180]),
563
+ },
564
+ coords={
565
+ "epoch": [
566
+ 7.9794907049e17,
567
+ 7.9794907153e17,
568
+ 7.9794907254e17,
569
+ 7.9794907354e17,
570
+ 7.9794907454e17,
571
+ ],
572
+ },
573
+ )
574
+
575
+ expected_pointing_lats = np.array([20, 20, 20, 20, 20])
576
+ expected_pointing_lons = np.array([0, 2712, 2962, 3205, 3600])
577
+
578
+ # Act
579
+ l1b_de = set_pointing_bin(l1b_de)
580
+
581
+ # Assert
582
+ np.testing.assert_array_equal(l1b_de["pointing_bin_lat"], expected_pointing_lats)
583
+ np.testing.assert_array_equal(l1b_de["pointing_bin_lon"], expected_pointing_lons)
@@ -19,7 +19,7 @@ def test_lo_l1c():
19
19
 
20
20
  expected_logical_source = "imap_lo_l1c_pset"
21
21
  # Act
22
- output_dataset = lo_l1c(data, "001")
22
+ output_dataset = lo_l1c(data)
23
23
 
24
24
  # Assert
25
25
  assert expected_logical_source == output_dataset.attrs["Logical_source"]
@@ -17,7 +17,7 @@ from imap_processing.lo.l0.lo_science import (
17
17
  from imap_processing.utils import convert_to_binary_string, packet_file_to_datasets
18
18
 
19
19
 
20
- @pytest.fixture()
20
+ @pytest.fixture
21
21
  def fake_de_dataset():
22
22
  # binary packet fields
23
23
  count = "0000000000000010" # 2
@@ -72,7 +72,7 @@ def fake_de_dataset():
72
72
  return dataset
73
73
 
74
74
 
75
- @pytest.fixture()
75
+ @pytest.fixture
76
76
  def sample_data():
77
77
  xtce_file = imap_module_directory / "lo/packet_definitions/lo_xtce.xml"
78
78
  dependency = (
@@ -86,7 +86,7 @@ def sample_data():
86
86
  return datasets_by_apid
87
87
 
88
88
 
89
- @pytest.fixture()
89
+ @pytest.fixture
90
90
  def segmented_pkts_fake_data():
91
91
  dataset = xr.Dataset(
92
92
  data_vars=dict(
@@ -116,7 +116,7 @@ def segmented_pkts_fake_data():
116
116
  return dataset
117
117
 
118
118
 
119
- @pytest.fixture()
119
+ @pytest.fixture
120
120
  def fake_spin_data():
121
121
  dataset = xr.Dataset(
122
122
  data_vars=dict(
@@ -148,16 +148,15 @@ def fake_spin_data():
148
148
  return dataset
149
149
 
150
150
 
151
- @pytest.fixture()
151
+ @pytest.fixture
152
152
  def attr_mgr():
153
153
  attr_mgr = ImapCdfAttributes()
154
154
  attr_mgr.add_instrument_global_attrs(instrument="lo")
155
155
  attr_mgr.add_instrument_variable_attrs(instrument="lo", level="l1a")
156
- attr_mgr.add_global_attribute("Data_version", "v000")
157
156
  return attr_mgr
158
157
 
159
158
 
160
- @pytest.fixture()
159
+ @pytest.fixture
161
160
  def initialized_dataset(fake_de_dataset, attr_mgr):
162
161
  fake_de_dataset.attrs["bit_pos"] = 0
163
162
  de_fields = [
@@ -261,6 +260,7 @@ def test_combine_segmented_packets(segmented_pkts_fake_data):
261
260
  ),
262
261
  )
263
262
  np.testing.assert_array_equal(dataset["epoch"].values, np.array([0, 10, 30]))
263
+ np.testing.assert_array_equal(dataset["met"].values, np.array([0, 10, 30]))
264
264
 
265
265
 
266
266
  def test_validate_parse_events(sample_data, attr_mgr):
@@ -6,7 +6,7 @@ from imap_processing.ccsds.ccsds_data import CcsdsData
6
6
  from imap_processing.lo.l0.data_classes.star_sensor import StarSensor
7
7
 
8
8
 
9
- @pytest.fixture()
9
+ @pytest.fixture
10
10
  def star_sensor():
11
11
  fake_data_field = namedtuple("fake_packet", ["raw_value", "derived_value"])
12
12
  star_sensor = StarSensor.__new__(StarSensor)