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
@@ -7,8 +7,8 @@ from typing import Union
7
7
  import xarray as xr
8
8
 
9
9
  from imap_processing import imap_module_directory
10
+ from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
10
11
  from imap_processing.hi.l1a.histogram import create_dataset as hist_create_dataset
11
- from imap_processing.hi.l1a.housekeeping import process_housekeeping
12
12
  from imap_processing.hi.l1a.science_direct_event import science_direct_event
13
13
  from imap_processing.hi.utils import HIAPID
14
14
  from imap_processing.utils import packet_file_to_datasets
@@ -16,7 +16,7 @@ from imap_processing.utils import packet_file_to_datasets
16
16
  logger = logging.getLogger(__name__)
17
17
 
18
18
 
19
- def hi_l1a(packet_file_path: Union[str, Path], data_version: str) -> list[xr.Dataset]:
19
+ def hi_l1a(packet_file_path: Union[str, Path]) -> list[xr.Dataset]:
20
20
  """
21
21
  Will process IMAP raw data to l1a.
22
22
 
@@ -24,50 +24,75 @@ def hi_l1a(packet_file_path: Union[str, Path], data_version: str) -> list[xr.Dat
24
24
  ----------
25
25
  packet_file_path : str
26
26
  Data packet file path.
27
- data_version : str
28
- Version of the data product being created.
29
27
 
30
28
  Returns
31
29
  -------
32
30
  processed_data : list[xarray.Dataset]
33
31
  List of processed xarray dataset.
34
32
  """
35
- packet_def_file = (
36
- imap_module_directory / "hi/packet_definitions/TLM_HI_COMBINED_SCI.xml"
37
- )
38
- datasets_by_apid = packet_file_to_datasets(
39
- packet_file=packet_file_path, xtce_packet_definition=packet_def_file
40
- )
33
+ datasets_by_apid = hi_packet_file_to_datasets(packet_file_path)
41
34
 
42
35
  # Process science to l1a.
43
36
  processed_data = []
44
37
  for apid in datasets_by_apid:
45
- if apid in [HIAPID.H45_SCI_CNT, HIAPID.H90_SCI_CNT]:
46
- logger.info(
47
- "Processing histogram data for [%s] packets", HIAPID.H45_SCI_CNT.name
48
- )
49
- data = hist_create_dataset(datasets_by_apid[apid])
50
- elif apid in [HIAPID.H45_SCI_DE, HIAPID.H90_SCI_DE]:
51
- logger.info(
52
- "Processing direct event data for [%s] packets", HIAPID.H45_SCI_DE.name
53
- )
38
+ try:
39
+ apid_enum = HIAPID(apid)
40
+ except ValueError as err:
41
+ raise RuntimeError(f"Encountered unexpected APID [{apid}]") from err
54
42
 
43
+ logger.info(f"Processing IMAP-Hi data for {apid_enum.name} packets")
44
+
45
+ if apid_enum in [HIAPID.H45_SCI_CNT, HIAPID.H90_SCI_CNT]:
46
+ data = hist_create_dataset(datasets_by_apid[apid])
47
+ gattr_key = "imap_hi_l1a_hist_attrs"
48
+ elif apid_enum in [HIAPID.H45_SCI_DE, HIAPID.H90_SCI_DE]:
55
49
  data = science_direct_event(datasets_by_apid[apid])
56
- elif apid in [HIAPID.H45_APP_NHK, HIAPID.H90_APP_NHK]:
57
- logger.info(
58
- "Processing housekeeping data for [%s] packets", HIAPID.H45_APP_NHK.name
59
- )
60
- data = process_housekeeping(datasets_by_apid[apid])
61
- else:
62
- raise RuntimeError(f"Encountered unexpected APID [{apid}]")
50
+ gattr_key = "imap_hi_l1a_de_attrs"
51
+ elif apid_enum in [HIAPID.H45_APP_NHK, HIAPID.H90_APP_NHK]:
52
+ data = datasets_by_apid[apid]
53
+ gattr_key = "imap_hi_l1a_hk_attrs"
54
+ elif apid_enum in [HIAPID.H45_DIAG_FEE, HIAPID.H90_DIAG_FEE]:
55
+ data = datasets_by_apid[apid]
56
+ gattr_key = "imap_hi_l1a_diagfee_attrs"
63
57
 
64
- # TODO: revisit this
65
- data.attrs["Data_version"] = data_version
58
+ # Update dataset global attributes
59
+ attr_mgr = ImapCdfAttributes()
60
+ attr_mgr.add_instrument_global_attrs("hi")
61
+ data.attrs.update(attr_mgr.get_global_attributes(gattr_key))
66
62
 
67
63
  # set the sensor string in Logical_source
68
- sensor_str = HIAPID(apid).sensor
64
+ sensor_str = apid_enum.sensor
69
65
  data.attrs["Logical_source"] = data.attrs["Logical_source"].format(
70
66
  sensor=sensor_str
71
67
  )
72
68
  processed_data.append(data)
73
69
  return processed_data
70
+
71
+
72
+ def hi_packet_file_to_datasets(
73
+ packet_file_path: Union[str, Path], use_derived_value: bool = False
74
+ ) -> dict[int, xr.Dataset]:
75
+ """
76
+ Extract hi datasets from packet file.
77
+
78
+ Parameters
79
+ ----------
80
+ packet_file_path : str
81
+ L0 packet file path.
82
+ use_derived_value : bool
83
+ Whether to use the derived value from the XTCE definition. Default is False.
84
+
85
+ Returns
86
+ -------
87
+ datasets : dict[int, xarray.Dataset]
88
+ Dictionary of xarray datasets keyed by APID.
89
+ """
90
+ packet_def_file = (
91
+ imap_module_directory / "hi/packet_definitions/TLM_HI_COMBINED_SCI.xml"
92
+ )
93
+ datasets_by_apid = packet_file_to_datasets(
94
+ packet_file=packet_file_path,
95
+ xtce_packet_definition=packet_def_file,
96
+ use_derived_value=use_derived_value,
97
+ )
98
+ return datasets_by_apid
@@ -116,7 +116,6 @@ def create_dataset(input_ds: xr.Dataset) -> xr.Dataset:
116
116
  )
117
117
 
118
118
  dataset.update(new_vars)
119
- dataset.attrs.update(attr_mgr.get_global_attributes("imap_hi_l1a_hist_attrs"))
120
119
 
121
120
  return dataset
122
121
 
@@ -31,11 +31,11 @@ def parse_direct_events(de_data: bytes) -> dict[str, npt.ArrayLike]:
31
31
  IMAP-Hi direct event data information is stored in
32
32
  48-bits as follows:
33
33
 
34
- | Read 48-bits into 2, 16, 10, 10, 10, bits. Each of these breaks
34
+ | Read 48-bits into 16, 2, 10, 10, 10, bits. Each of these breaks
35
35
  | down as:
36
36
  |
37
- | start_bitmask_data - 2 bits (tA=1, tB=2, tC1=3, META=0)
38
37
  | de_tag - 16 bits
38
+ | start_bitmask_data - 2 bits (tA=1, tB=2, tC1=3)
39
39
  | tof_1 - 10 bit counter
40
40
  | tof_2 - 10 bit counter
41
41
  | tof_3 - 10 bit counter
@@ -70,16 +70,16 @@ def parse_direct_events(de_data: bytes) -> dict[str, npt.ArrayLike]:
70
70
  # direct events.
71
71
  # Considering the 6-bytes of data for each DE as 3 2-byte words,
72
72
  # each word contains the following:
73
- # word_0: 2-bits of Trigger ID, upper 14-bits of de_tag
74
- # word_1: lower 2-bits of de_tag, 10-bits tof_1, upper 4-bits of tof_2
73
+ # word_0: full 16-bits is the de_tag
74
+ # word_1: 2-bits of Trigger ID, 10-bits tof_1, upper 4-bits of tof_2
75
75
  # word_2: lower 6-bits of tof_2, 10-bits of tof_3
76
76
  data_uint16 = np.reshape(
77
77
  np.frombuffer(de_data, dtype=">u2"), (3, -1), order="F"
78
78
  ).astype(np.uint16)
79
79
 
80
80
  de_dict = dict()
81
- de_dict["trigger_id"] = (data_uint16[0] >> 14).astype(np.uint8)
82
- de_dict["de_tag"] = (data_uint16[0] << 2) + (data_uint16[1] >> 14)
81
+ de_dict["de_tag"] = data_uint16[0]
82
+ de_dict["trigger_id"] = (data_uint16[1] >> 14).astype(np.uint8)
83
83
  de_dict["tof_1"] = (data_uint16[1] & int(b"00111111_11110000", 2)) >> 4
84
84
  de_dict["tof_2"] = ((data_uint16[1] & int(b"00000000_00001111", 2)) << 6) + (
85
85
  data_uint16[2] >> 10
@@ -147,10 +147,8 @@ def create_dataset(de_data_dict: dict[str, npt.ArrayLike]) -> xr.Dataset:
147
147
  attrs=event_met_attrs,
148
148
  )
149
149
 
150
- de_global_attrs = attr_mgr.get_global_attributes("imap_hi_l1a_de_attrs")
151
150
  dataset = xr.Dataset(
152
151
  coords={"epoch": epoch, "event_met": event_met},
153
- attrs=de_global_attrs,
154
152
  )
155
153
 
156
154
  for var_name, data in de_data_dict.items():
@@ -2,6 +2,8 @@
2
2
 
3
3
  import logging
4
4
  from enum import IntEnum
5
+ from pathlib import Path
6
+ from typing import Union
5
7
 
6
8
  import numpy as np
7
9
  import xarray as xr
@@ -12,6 +14,7 @@ from imap_processing.cdf.utils import parse_filename_like
12
14
  from imap_processing.hi.l1a.science_direct_event import HALF_CLOCK_TICK_S
13
15
  from imap_processing.hi.utils import (
14
16
  HIAPID,
17
+ CoincidenceBitmap,
15
18
  HiConstants,
16
19
  create_dataset_variables,
17
20
  parse_sensor_number,
@@ -25,7 +28,7 @@ from imap_processing.spice.spin import (
25
28
  get_spacecraft_spin_phase,
26
29
  )
27
30
  from imap_processing.spice.time import met_to_sclkticks, sct_to_et
28
- from imap_processing.utils import convert_raw_to_eu
31
+ from imap_processing.utils import packet_file_to_datasets
29
32
 
30
33
 
31
34
  class TriggerId(IntEnum):
@@ -36,76 +39,102 @@ class TriggerId(IntEnum):
36
39
  C = 3
37
40
 
38
41
 
39
- class CoincidenceBitmap(IntEnum):
40
- """IntEnum class for coincidence type bitmap values."""
41
-
42
- A = 2**3
43
- B = 2**2
44
- C1 = 2**1
45
- C2 = 2**0
46
-
47
-
48
42
  logger = logging.getLogger(__name__)
49
43
  ATTR_MGR = ImapCdfAttributes()
50
44
  ATTR_MGR.add_instrument_global_attrs("hi")
51
45
  ATTR_MGR.add_instrument_variable_attrs(instrument="hi", level=None)
52
46
 
53
47
 
54
- def hi_l1b(l1a_dataset: xr.Dataset, data_version: str) -> xr.Dataset:
48
+ def hi_l1b(dependency: Union[str, Path, xr.Dataset]) -> list[xr.Dataset]:
55
49
  """
56
50
  High level IMAP-HI L1B processing function.
57
51
 
58
52
  Parameters
59
53
  ----------
60
- l1a_dataset : xarray.Dataset
61
- L1A dataset to process.
62
- data_version : str
63
- Version of the data product being created.
54
+ dependency : str or xarray.Dataset
55
+ Path to L0 file or L1A dataset to process.
64
56
 
65
57
  Returns
66
58
  -------
67
- l1b_dataset : xarray.Dataset
68
- Processed xarray dataset.
59
+ l1b_dataset : list[xarray.Dataset]
60
+ Processed xarray datasets.
69
61
  """
70
- logger.info(
71
- f"Running Hi L1B processing on dataset: {l1a_dataset.attrs['Logical_source']}"
72
- )
73
- logical_source_parts = parse_filename_like(l1a_dataset.attrs["Logical_source"])
74
- # TODO: apid is not currently stored in all L1A data but should be.
75
- # Use apid to determine what L1B processing function to call
76
-
77
62
  # Housekeeping processing
78
- if logical_source_parts["descriptor"].endswith("hk"):
79
- # if packet_enum in (HIAPID.H45_APP_NHK, HIAPID.H90_APP_NHK):
80
- packet_enum = HIAPID(l1a_dataset["pkt_apid"].data[0])
81
- conversion_table_path = str(
82
- imap_module_directory / "hi" / "l1b" / "hi_eng_unit_convert_table.csv"
83
- )
84
- l1b_dataset = convert_raw_to_eu(
85
- l1a_dataset,
86
- conversion_table_path=conversion_table_path,
87
- packet_name=packet_enum.name,
88
- comment="#", # type: ignore[arg-type]
89
- # Todo error, Argument "comment" to "convert_raw_to_eu" has incompatible
90
- # type "str"; expected "dict[Any, Any]"
91
- converters={"mnemonic": str.lower},
92
- )
93
-
94
- l1b_dataset.attrs.update(ATTR_MGR.get_global_attributes("imap_hi_l1b_hk_attrs"))
95
- elif logical_source_parts["descriptor"].endswith("de"):
96
- l1b_dataset = annotate_direct_events(l1a_dataset)
97
- else:
98
- raise NotImplementedError(
99
- f"No Hi L1B processing defined for file type: "
63
+ if isinstance(dependency, (Path, str)):
64
+ logger.info(f"Running Hi L1B processing on file: {dependency}")
65
+ l1b_datasets = housekeeping(dependency)
66
+ elif isinstance(dependency, xr.Dataset):
67
+ l1a_dataset = dependency
68
+ logger.info(
69
+ f"Running Hi L1B processing on dataset: "
100
70
  f"{l1a_dataset.attrs['Logical_source']}"
101
71
  )
102
- # Update global attributes
103
- l1b_dataset.attrs["Logical_source"] = l1b_dataset.attrs["Logical_source"].format(
104
- sensor=logical_source_parts["sensor"]
72
+ logical_source_parts = parse_filename_like(l1a_dataset.attrs["Logical_source"])
73
+ # TODO: apid is not currently stored in all L1A data but should be.
74
+ # Use apid to determine what L1B processing function to call
75
+
76
+ # DE processing
77
+ if logical_source_parts["descriptor"].endswith("de"):
78
+ l1b_datasets = [annotate_direct_events(l1a_dataset)]
79
+ l1b_datasets[0].attrs["Logical_source"] = (
80
+ l1b_datasets[0]
81
+ .attrs["Logical_source"]
82
+ .format(sensor=logical_source_parts["sensor"])
83
+ )
84
+ else:
85
+ raise NotImplementedError(
86
+ f"No Hi L1B processing defined for file type: "
87
+ f"{l1a_dataset.attrs['Logical_source']}"
88
+ )
89
+
90
+ return l1b_datasets
91
+
92
+
93
+ def housekeeping(packet_file_path: Union[str, Path]) -> list[xr.Dataset]:
94
+ """
95
+ Will process IMAP raw data to l1b housekeeping dataset.
96
+
97
+ In order to use `space_packet_parser` and the xtce which contains the
98
+ DN to EU conversion factors, the L0 packet file is used to go straight to
99
+ L1B.
100
+
101
+ Parameters
102
+ ----------
103
+ packet_file_path : str
104
+ Packet file path.
105
+
106
+ Returns
107
+ -------
108
+ processed_data : list[xarray.Dataset]
109
+ Housekeeping datasets with engineering units.
110
+ """
111
+ packet_def_file = (
112
+ imap_module_directory / "hi/packet_definitions/TLM_HI_COMBINED_SCI.xml"
105
113
  )
106
- # TODO: revisit this
107
- l1b_dataset.attrs["Data_version"] = data_version
108
- return l1b_dataset
114
+ # TODO: If raw and derived values can be gotten from one call to
115
+ # packet_file_to_datasets, the L1A and L1B could be generated
116
+ # in a single L1A/B function.
117
+ datasets_by_apid = packet_file_to_datasets(
118
+ packet_file=packet_file_path,
119
+ xtce_packet_definition=packet_def_file,
120
+ use_derived_value=True,
121
+ )
122
+
123
+ # Extract only the HK datasets
124
+ attr_mgr = ImapCdfAttributes()
125
+ attr_mgr.add_instrument_global_attrs("hi")
126
+ datasets = list()
127
+ for apid in [HIAPID.H45_APP_NHK, HIAPID.H90_APP_NHK]:
128
+ if apid in datasets_by_apid:
129
+ datasets.append(datasets_by_apid[apid])
130
+ # Update the dataset global attributes
131
+ datasets[-1].attrs.update(
132
+ ATTR_MGR.get_global_attributes("imap_hi_l1b_hk_attrs")
133
+ )
134
+ datasets[-1].attrs["Logical_source"] = (
135
+ datasets[-1].attrs["Logical_source"].format(sensor=apid.sensor)
136
+ )
137
+ return datasets
109
138
 
110
139
 
111
140
  def annotate_direct_events(l1a_dataset: xr.Dataset) -> xr.Dataset:
@@ -124,7 +153,7 @@ def annotate_direct_events(l1a_dataset: xr.Dataset) -> xr.Dataset:
124
153
  """
125
154
  l1b_dataset = l1a_dataset.copy()
126
155
  l1b_dataset.update(de_esa_energy_step(l1b_dataset))
127
- l1b_dataset.update(compute_coincidence_type_and_time_deltas(l1b_dataset))
156
+ l1b_dataset.update(compute_coincidence_type_and_tofs(l1b_dataset))
128
157
  l1b_dataset.update(de_nominal_bin_and_spin_phase(l1b_dataset))
129
158
  l1b_dataset.update(compute_hae_coordinates(l1b_dataset))
130
159
  l1b_dataset.update(
@@ -154,14 +183,14 @@ def annotate_direct_events(l1a_dataset: xr.Dataset) -> xr.Dataset:
154
183
  return l1b_dataset
155
184
 
156
185
 
157
- def compute_coincidence_type_and_time_deltas(
186
+ def compute_coincidence_type_and_tofs(
158
187
  dataset: xr.Dataset,
159
188
  ) -> dict[str, xr.DataArray]:
160
189
  """
161
- Compute coincidence type and time deltas.
190
+ Compute coincidence type and time of flights.
162
191
 
163
- Generates the new variables "coincidence_type", "delta_t_ab", "delta_t_ac1",
164
- "delta_t_bc1", and "delta_t_c1c2" and returns a dictionary with the new
192
+ Generates the new variables "coincidence_type", "tof_ab", "tof_ac1",
193
+ "tof_bc1", and "tof_c1c2" and returns a dictionary with the new
165
194
  variables that can be added to the input dataset by calling the
166
195
  xarray.Dataset.update method.
167
196
 
@@ -178,16 +207,16 @@ def compute_coincidence_type_and_time_deltas(
178
207
  new_vars = create_dataset_variables(
179
208
  [
180
209
  "coincidence_type",
181
- "delta_t_ab",
182
- "delta_t_ac1",
183
- "delta_t_bc1",
184
- "delta_t_c1c2",
210
+ "tof_ab",
211
+ "tof_ac1",
212
+ "tof_bc1",
213
+ "tof_c1c2",
185
214
  ],
186
215
  len(dataset.event_met),
187
216
  att_manager_lookup_str="hi_de_{0}",
188
217
  )
189
218
 
190
- # compute masks needed for coincidence type and delta t calculations
219
+ # compute masks needed for coincidence type and ToF calculations
191
220
  a_first = dataset.trigger_id.values == TriggerId.A
192
221
  b_first = dataset.trigger_id.values == TriggerId.B
193
222
  c_first = dataset.trigger_id.values == TriggerId.C
@@ -221,56 +250,56 @@ def compute_coincidence_type_and_time_deltas(
221
250
  # | 2 | B | t_a - t_b | t_c1 - t_b | t_c2 - t_c1 |
222
251
  # | 3 | C | t_a - t_c1 | t_b - t_c1 | t_c2 - t_c1 |
223
252
 
224
- # Prepare for delta_t calculations by converting TOF values to nanoseconds
253
+ # Prepare for L1B ToF calculations by converting L1A TOF values to nanoseconds
225
254
  tof_1_ns = (dataset.tof_1.values * HiConstants.TOF1_TICK_DUR).astype(np.int32)
226
255
  tof_2_ns = (dataset.tof_2.values * HiConstants.TOF2_TICK_DUR).astype(np.int32)
227
256
  tof_3_ns = (dataset.tof_3.values * HiConstants.TOF3_TICK_DUR).astype(np.int32)
228
257
 
229
- # # ********** delta_t_ab = (t_b - t_a) **********
258
+ # # ********** tof_ab = (t_b - t_a) **********
230
259
  # Table: row 1, column 1
231
260
  a_and_tof1 = a_first & tof1_valid
232
- new_vars["delta_t_ab"].values[a_and_tof1] = tof_1_ns[a_and_tof1]
261
+ new_vars["tof_ab"].values[a_and_tof1] = tof_1_ns[a_and_tof1]
233
262
  # Table: row 2, column 1
234
263
  b_and_tof1 = b_first & tof1_valid
235
- new_vars["delta_t_ab"].values[b_and_tof1] = -1 * tof_1_ns[b_and_tof1]
264
+ new_vars["tof_ab"].values[b_and_tof1] = -1 * tof_1_ns[b_and_tof1]
236
265
  # Table: row 3, column 1 and 2
237
- # delta_t_ab = (t_b - t_c1) - (t_a - t_c1) = (t_b - t_a)
266
+ # tof_ab = (t_b - t_c1) - (t_a - t_c1) = (t_b - t_a)
238
267
  c_and_tof1and2 = c_first & tof1and2_valid
239
- new_vars["delta_t_ab"].values[c_and_tof1and2] = (
268
+ new_vars["tof_ab"].values[c_and_tof1and2] = (
240
269
  tof_2_ns[c_and_tof1and2] - tof_1_ns[c_and_tof1and2]
241
270
  )
242
271
 
243
- # ********** delta_t_ac1 = (t_c1 - t_a) **********
272
+ # ********** tof_ac1 = (t_c1 - t_a) **********
244
273
  # Table: row 1, column 2
245
274
  a_and_tof2 = a_first & tof2_valid
246
- new_vars["delta_t_ac1"].values[a_and_tof2] = tof_2_ns[a_and_tof2]
275
+ new_vars["tof_ac1"].values[a_and_tof2] = tof_2_ns[a_and_tof2]
247
276
  # Table: row 2, column 1 and 2
248
- # delta_t_ac1 = (t_c1 - t_b) - (t_a - t_b) = (t_c1 - t_a)
277
+ # tof_ac1 = (t_c1 - t_b) - (t_a - t_b) = (t_c1 - t_a)
249
278
  b_and_tof1and2 = b_first & tof1and2_valid
250
- new_vars["delta_t_ac1"].values[b_and_tof1and2] = (
279
+ new_vars["tof_ac1"].values[b_and_tof1and2] = (
251
280
  tof_2_ns[b_and_tof1and2] - tof_1_ns[b_and_tof1and2]
252
281
  )
253
282
  # Table: row 3, column 1
254
283
  c_and_tof1 = c_first & tof1_valid
255
- new_vars["delta_t_ac1"].values[c_and_tof1] = -1 * tof_1_ns[c_and_tof1]
284
+ new_vars["tof_ac1"].values[c_and_tof1] = -1 * tof_1_ns[c_and_tof1]
256
285
 
257
- # ********** delta_t_bc1 = (t_c1 - t_b) **********
286
+ # ********** tof_bc1 = (t_c1 - t_b) **********
258
287
  # Table: row 1, column 1 and 2
259
- # delta_t_bc1 = (t_c1 - t_a) - (t_b - t_a) => (t_c1 - t_b)
288
+ # tof_bc1 = (t_c1 - t_a) - (t_b - t_a) => (t_c1 - t_b)
260
289
  a_and_tof1and2 = a_first & tof1and2_valid
261
- new_vars["delta_t_bc1"].values[a_and_tof1and2] = (
290
+ new_vars["tof_bc1"].values[a_and_tof1and2] = (
262
291
  tof_2_ns[a_and_tof1and2] - tof_1_ns[a_and_tof1and2]
263
292
  )
264
293
  # Table: row 2, column 2
265
294
  b_and_tof2 = b_first & tof2_valid
266
- new_vars["delta_t_bc1"].values[b_and_tof2] = tof_2_ns[b_and_tof2]
295
+ new_vars["tof_bc1"].values[b_and_tof2] = tof_2_ns[b_and_tof2]
267
296
  # Table: row 3, column 2
268
297
  c_and_tof2 = c_first & tof2_valid
269
- new_vars["delta_t_bc1"].values[c_and_tof2] = -1 * tof_2_ns[c_and_tof2]
298
+ new_vars["tof_bc1"].values[c_and_tof2] = -1 * tof_2_ns[c_and_tof2]
270
299
 
271
- # ********** delta_t_c1c2 = (t_c2 - t_c1) **********
300
+ # ********** tof_c1c2 = (t_c2 - t_c1) **********
272
301
  # Table: all rows, column 3
273
- new_vars["delta_t_c1c2"].values[tof3_valid] = tof_3_ns[tof3_valid]
302
+ new_vars["tof_c1c2"].values[tof3_valid] = tof_3_ns[tof3_valid]
274
303
 
275
304
  return new_vars
276
305
 
@@ -325,8 +354,8 @@ def compute_hae_coordinates(dataset: xr.Dataset) -> dict[str, xr.DataArray]:
325
354
  Parameters
326
355
  ----------
327
356
  dataset : xarray.Dataset
328
- The partial L1B dataset that has had coincidence type, time deltas, and
329
- spin phase computed and added to the L1A data.
357
+ The partial L1B dataset that has had coincidence type, times of flight,
358
+ and spin phase computed and added to the L1A data.
330
359
 
331
360
  Returns
332
361
  -------