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
@@ -99,28 +99,28 @@
99
99
  <xtce:Parameter name="SWAPI_RESERVED" parameterTypeRef="uint15">
100
100
  <xtce:LongDescription>SWAPI Instrument Reserved</xtce:LongDescription>
101
101
  </xtce:Parameter>
102
- <xtce:Parameter name="SWAPI_SEQ" parameterTypeRef="uint4">
102
+ <xtce:Parameter name="SWAPI_SEQ_NUMBER" parameterTypeRef="uint4">
103
103
  <xtce:LongDescription>Sequence Number in Table</xtce:LongDescription>
104
104
  </xtce:Parameter>
105
105
  <xtce:Parameter name="SWAPI_VERSION" parameterTypeRef="uint4">
106
106
  <xtce:LongDescription>Sweep Table Version Number</xtce:LongDescription>
107
107
  </xtce:Parameter>
108
- <xtce:Parameter name="SWAPI_COIN_1" parameterTypeRef="uint16">
108
+ <xtce:Parameter name="SWAPI_COIN_CNT0" parameterTypeRef="uint16">
109
109
  <xtce:LongDescription>Coincidence Counts During the First 1/6 Sec</xtce:LongDescription>
110
110
  </xtce:Parameter>
111
- <xtce:Parameter name="SWAPI_COIN_2" parameterTypeRef="uint16">
111
+ <xtce:Parameter name="SWAPI_COIN_CNT1" parameterTypeRef="uint16">
112
112
  <xtce:LongDescription>Coincidence Counts During the Second 1/6 Sec</xtce:LongDescription>
113
113
  </xtce:Parameter>
114
- <xtce:Parameter name="SWAPI_COIN_3" parameterTypeRef="uint16">
114
+ <xtce:Parameter name="SWAPI_COIN_CNT2" parameterTypeRef="uint16">
115
115
  <xtce:LongDescription>Coincidence Counts During the Third 1/6 Sec</xtce:LongDescription>
116
116
  </xtce:Parameter>
117
- <xtce:Parameter name="SWAPI_COIN_4" parameterTypeRef="uint16">
117
+ <xtce:Parameter name="SWAPI_COIN_CNT3" parameterTypeRef="uint16">
118
118
  <xtce:LongDescription>Coincidence Counts During the Fourth 1/6 Sec</xtce:LongDescription>
119
119
  </xtce:Parameter>
120
- <xtce:Parameter name="SWAPI_COIN_5" parameterTypeRef="uint16">
120
+ <xtce:Parameter name="SWAPI_COIN_CNT4" parameterTypeRef="uint16">
121
121
  <xtce:LongDescription>Coincidence Counts During the Fifth 1/6 Sec</xtce:LongDescription>
122
122
  </xtce:Parameter>
123
- <xtce:Parameter name="SWAPI_COIN_6" parameterTypeRef="uint16">
123
+ <xtce:Parameter name="SWAPI_COIN_CNT5" parameterTypeRef="uint16">
124
124
  <xtce:LongDescription>Coincidence Counts During the Sixth 1/6 Sec</xtce:LongDescription>
125
125
  </xtce:Parameter>
126
126
  <xtce:Parameter name="SWAPI_SPARE" parameterTypeRef="uint8">
@@ -153,14 +153,14 @@
153
153
  <xtce:ParameterRefEntry parameterRef="SWAPI_ACQ"/>
154
154
  <xtce:ParameterRefEntry parameterRef="SWAPI_FLAG"/>
155
155
  <xtce:ParameterRefEntry parameterRef="SWAPI_RESERVED"/>
156
- <xtce:ParameterRefEntry parameterRef="SWAPI_SEQ"/>
156
+ <xtce:ParameterRefEntry parameterRef="SWAPI_SEQ_NUMBER"/>
157
157
  <xtce:ParameterRefEntry parameterRef="SWAPI_VERSION"/>
158
- <xtce:ParameterRefEntry parameterRef="SWAPI_COIN_1"/>
159
- <xtce:ParameterRefEntry parameterRef="SWAPI_COIN_2"/>
160
- <xtce:ParameterRefEntry parameterRef="SWAPI_COIN_3"/>
161
- <xtce:ParameterRefEntry parameterRef="SWAPI_COIN_4"/>
162
- <xtce:ParameterRefEntry parameterRef="SWAPI_COIN_5"/>
163
- <xtce:ParameterRefEntry parameterRef="SWAPI_COIN_6"/>
158
+ <xtce:ParameterRefEntry parameterRef="SWAPI_COIN_CNT0"/>
159
+ <xtce:ParameterRefEntry parameterRef="SWAPI_COIN_CNT1"/>
160
+ <xtce:ParameterRefEntry parameterRef="SWAPI_COIN_CNT2"/>
161
+ <xtce:ParameterRefEntry parameterRef="SWAPI_COIN_CNT3"/>
162
+ <xtce:ParameterRefEntry parameterRef="SWAPI_COIN_CNT4"/>
163
+ <xtce:ParameterRefEntry parameterRef="SWAPI_COIN_CNT5"/>
164
164
  <xtce:ParameterRefEntry parameterRef="SWAPI_SPARE"/>
165
165
  <!-- SWAPI -->
166
166
  </xtce:EntryList>
@@ -0,0 +1,114 @@
1
+ """Common grouping functions for I-ALiRT instruments."""
2
+
3
+ import logging
4
+
5
+ import numpy as np
6
+ import xarray as xr
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+
11
+ def filter_valid_groups(grouped_data: xr.Dataset) -> xr.Dataset:
12
+ """
13
+ Filter out groups where `src_seq_ctr` diff are not 1.
14
+
15
+ Parameters
16
+ ----------
17
+ grouped_data : xr.Dataset
18
+ Dataset with a "group" coordinate.
19
+
20
+ Returns
21
+ -------
22
+ filtered_data : xr.Dataset
23
+ Filtered dataset with only valid groups remaining.
24
+ """
25
+ valid_groups = []
26
+ unique_groups = np.unique(grouped_data["group"].values)
27
+
28
+ for group in unique_groups:
29
+ src_seq_ctr = grouped_data["src_seq_ctr"][
30
+ (grouped_data["group"] == group).values
31
+ ]
32
+ src_seq_ctr_diff = np.diff(src_seq_ctr) % 16384
33
+
34
+ # Accept group only if all diffs are 1.
35
+ if np.all(src_seq_ctr_diff == 1):
36
+ valid_groups.append(group)
37
+ else:
38
+ logger.info(f"src_seq_ctr_diff != 1 for group {group}.")
39
+
40
+ filtered_data = grouped_data.where(
41
+ xr.DataArray(np.isin(grouped_data["group"], valid_groups), dims="epoch"),
42
+ drop=True,
43
+ )
44
+
45
+ return filtered_data
46
+
47
+
48
+ def find_groups(
49
+ accumulated_data: xr.Dataset,
50
+ sequence_range: tuple,
51
+ sequence_name: str,
52
+ time_name: str,
53
+ ) -> xr.Dataset:
54
+ """
55
+ Group data based on time and sequence number values.
56
+
57
+ Parameters
58
+ ----------
59
+ accumulated_data : xr.Dataset
60
+ Packets dataset accumulated over 1 min.
61
+ sequence_range : tuple
62
+ Tuple of two integers defining the range of group values (inclusive endpoints).
63
+ sequence_name : str
64
+ Name of the sequence variable.
65
+ time_name : str
66
+ Name of the time variable.
67
+
68
+ Returns
69
+ -------
70
+ grouped_data : xr.Dataset
71
+ Filtered data with "group" coordinate.
72
+
73
+ Notes
74
+ -----
75
+ Filters data based on:
76
+ 1. Time values between the first and last sequence_range values.
77
+ Take out time values before sequence_range[0] and after sequence_range[-1].
78
+ 2. Sequence values src_seq_ctr between the first and
79
+ last sequence_range. These must be consecutive.
80
+ """
81
+ sorted_data = accumulated_data.sortby(time_name, ascending=True)
82
+
83
+ # Use sequence_range == 0 to define the beginning of the group.
84
+ # Find time at this index and use it as the beginning time for the group.
85
+ start_times = sorted_data[time_name][
86
+ (sorted_data[sequence_name] == sequence_range[0])
87
+ ]
88
+ start_time = start_times.min()
89
+ # Use max sequence_range to define the end of the group.
90
+ end_times = sorted_data[time_name][
91
+ ([sorted_data[sequence_name] == sequence_range[-1]][-1])
92
+ ]
93
+ end_time = end_times.max()
94
+
95
+ # Filter data before the sequence_range=0
96
+ # and after the last value of sequence_range.
97
+ grouped_data = sorted_data.where(
98
+ (sorted_data[time_name] >= start_time) & (sorted_data[time_name] <= end_time),
99
+ drop=True,
100
+ )
101
+
102
+ # Assign labels based on the start_times.
103
+ group_labels = np.searchsorted(start_times, grouped_data[time_name], side="right")
104
+ # Example:
105
+ # grouped_data.coords
106
+ # Coordinates:
107
+ # * epoch (epoch) int64 7kB 315922822184000000 ... 315923721184000000
108
+ # group (epoch) int64 7kB 1 1 1 1 1 1 1 1 1 ... 15 15 15 15 15 15 15 15 15
109
+ grouped_data = grouped_data.assign_coords(group=("epoch", group_labels))
110
+
111
+ # Filter out groups with non-sequential src_seq_ctr values.
112
+ filtered_data = filter_valid_groups(grouped_data)
113
+
114
+ return filtered_data
@@ -0,0 +1,29 @@
1
+ """Common time functions for I-ALiRT instruments."""
2
+
3
+ import xarray as xr
4
+
5
+
6
+ def calculate_time(
7
+ coarse_time: xr.DataArray, fine_time: xr.DataArray, conversion: int
8
+ ) -> xr.DataArray:
9
+ """
10
+ Calculate the time.
11
+
12
+ Parameters
13
+ ----------
14
+ coarse_time : xr.DataArray
15
+ Coarse time.
16
+ fine_time : xr.DataArray
17
+ Fine time.
18
+ conversion : int
19
+ Fine time units = 1 second.
20
+
21
+ Returns
22
+ -------
23
+ time_seconds: xr.DataArray
24
+ Calculated time.
25
+ """
26
+ fine_time_fraction = fine_time / conversion
27
+ time_seconds = coarse_time + fine_time_fraction
28
+
29
+ return time_seconds
@@ -0,0 +1,22 @@
1
+ Mass,Name
2
+ 1,H
3
+ 2,H2
4
+ 12,C
5
+ 16,O
6
+ 22,Na
7
+ 23,Mg24
8
+ 24,Mg25
9
+ 25,Mg26
10
+ 27,Si28
11
+ 28,Si29
12
+ 29,Si30
13
+ 39,K39
14
+ 39,Ca40
15
+ 40,K41
16
+ 41,Ca42
17
+ 43,Ca44
18
+ 53,Fe54
19
+ 55,Fe56
20
+ 56,Fe57
21
+ 57,Fe58
22
+ 196,Au197
@@ -174,7 +174,7 @@ def rice_decode(compressed_data: str, nbit10: bool, sample_count: int) -> list[i
174
174
 
175
175
  Returns
176
176
  -------
177
- list
177
+ list[int]
178
178
  Decompressed data as a list of integers.
179
179
  """
180
180
  # Constants:
@@ -186,7 +186,7 @@ def rice_decode(compressed_data: str, nbit10: bool, sample_count: int) -> list[i
186
186
  sub_frame_per_frame = frame_size / SUB_FRAME_SIZE
187
187
 
188
188
  bits = compressed_data
189
- out_data = []
189
+ out_data: list[int] = []
190
190
  sub_frame_count = 0
191
191
  bp = 0
192
192
  # Decode all subframes
@@ -1,6 +1,15 @@
1
1
  """Contains dataclasses to support IDEX processing."""
2
2
 
3
3
  from dataclasses import dataclass
4
+ from enum import Enum, IntEnum
5
+
6
+
7
+ class IDEXAPID(IntEnum):
8
+ """Create ENUM for apid."""
9
+
10
+ IDEX_SCIENCE = 1424
11
+ IDEX_CATLST = 1419
12
+ IDEX_EVT = 1418
4
13
 
5
14
 
6
15
  @dataclass
@@ -25,3 +34,27 @@ class IdexConstants:
25
34
  DATA_MAX: int = 4096
26
35
  SAMPLE_RATE_MIN: int = -130
27
36
  SAMPLE_RATE_MAX: int = 130
37
+
38
+
39
+ # FM sampling rate (quartz oscillator)
40
+ # Seconds per sample.
41
+ FM_SAMPLING_RATE = 0.0038466235767167234e-6
42
+ # Nanoseconds to seconds conversion
43
+ NS_TO_S = 1e-9
44
+ # Microseconds to seconds conversion
45
+ US_TO_S = 1e-6
46
+
47
+ TARGET_HIGH_FREQUENCY_CUTOFF = 100
48
+
49
+ TARGET_NOISE_FREQUENCY = 7000
50
+
51
+
52
+ class ConversionFactors(float, Enum):
53
+ """Conversion factor values (DN to picocoulombs) for each of the six waveforms."""
54
+
55
+ TOF_High = 2.89e-4
56
+ TOF_Low = 5.14e-4
57
+ TOF_Mid = 1.13e-2
58
+ Target_Low = 1.58e1
59
+ Target_High = 1.63e-1
60
+ Ion_Grid = 7.46e-4
@@ -2,14 +2,19 @@
2
2
 
3
3
  import logging
4
4
  from pathlib import Path
5
- from typing import Union
5
+ from typing import Any, Union
6
+
7
+ from xarray import Dataset
6
8
 
7
9
  from imap_processing import decom, imap_module_directory
10
+ from imap_processing.utils import packet_file_to_datasets
8
11
 
9
12
  logger = logging.getLogger(__name__)
10
13
 
11
14
 
12
- def decom_packets(packet_file: Union[str, Path]) -> list:
15
+ def decom_packets(
16
+ packet_file: Union[str, Path],
17
+ ) -> tuple[list[Any], dict[int, Dataset]]:
13
18
  """
14
19
  Decom IDEX data packets using IDEX packet definition.
15
20
 
@@ -20,12 +25,21 @@ def decom_packets(packet_file: Union[str, Path]) -> list:
20
25
 
21
26
  Returns
22
27
  -------
23
- list
24
- All the unpacked data.
28
+ Tuple[list, dict]
29
+ Returns a list of all unpacked science data and a dictionary of datasets
30
+ indexed by their APIDs.
31
+
32
+ Notes
33
+ -----
34
+ The function 'packet_file_to_dataset' does not work with IDEX science packets due to
35
+ branching logic within the science xml file. The science data and housekeeping data
36
+ will be decommed separately and both returned from this function.
25
37
  """
26
- xtce_filename = "idex_packet_definition.xml"
27
- xtce_file = f"{imap_module_directory}/idex/packet_definitions/{xtce_filename}"
38
+ xtce_base_path = f"{imap_module_directory}/idex/packet_definitions"
39
+ science_xtce_file = f"{xtce_base_path}/idex_science_packet_definition.xml"
40
+ hk_xtce_file = f"{xtce_base_path}/idex_housekeeping_packet_definition.xml"
28
41
 
29
- decom_packet_list = decom.decom_packets(packet_file, xtce_file)
42
+ science_decom_packet_list = decom.decom_packets(packet_file, science_xtce_file)
43
+ datasets_by_apid = packet_file_to_datasets(packet_file, hk_xtce_file)
30
44
 
31
- return list(decom_packet_list)
45
+ return list(science_decom_packet_list), datasets_by_apid
@@ -10,7 +10,7 @@ Examples
10
10
  from imap_processing.idex.idex_l1a import PacketParser
11
11
 
12
12
  l0_file = "imap_processing/tests/idex/imap_idex_l0_sci_20231214_v001.pkts"
13
- l1a_data = PacketParser(l0_file, data_version)
13
+ l1a_data = PacketParser(l0_file)
14
14
  l1a_data.write_l1a_cdf()
15
15
  """
16
16
 
@@ -26,6 +26,7 @@ import xarray as xr
26
26
 
27
27
  from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
28
28
  from imap_processing.idex.decode import rice_decode
29
+ from imap_processing.idex.idex_constants import IDEXAPID
29
30
  from imap_processing.idex.idex_l0 import decom_packets
30
31
  from imap_processing.spice.time import met_to_ttj2000ns
31
32
  from imap_processing.utils import convert_to_binary_string
@@ -57,11 +58,9 @@ class PacketParser:
57
58
  ----------
58
59
  packet_file : str
59
60
  The path and filename to the L0 file to read.
60
- data_version : str
61
- The version of the data product being created.
62
61
  """
63
62
 
64
- def __init__(self, packet_file: Union[str, Path], data_version: str) -> None:
63
+ def __init__(self, packet_file: Union[str, Path]) -> None:
65
64
  """
66
65
  Read a L0 pkts file and perform all of the decom work.
67
66
 
@@ -69,23 +68,62 @@ class PacketParser:
69
68
  ----------
70
69
  packet_file : pathlib.Path | str
71
70
  The path and filename to the L0 file to read.
72
- data_version : str
73
- The version of the data product being created.
74
71
 
75
72
  Notes
76
73
  -----
77
74
  Currently assumes one L0 file will generate exactly one L1a file.
78
75
  """
79
- decom_packet_list = decom_packets(packet_file)
76
+ self.data = []
77
+ self.idex_attrs = get_idex_attrs()
78
+ epoch_attrs = self.idex_attrs.get_variable_attributes(
79
+ "epoch", check_schema=False
80
+ )
81
+
82
+ science_packets, datset_by_apid = decom_packets(packet_file)
83
+
84
+ if science_packets:
85
+ logger.info("Processing IDEX L1A Science data.")
86
+ self.data.append(self._create_science_dataset(science_packets))
87
+
88
+ if IDEXAPID.IDEX_EVT in datset_by_apid:
89
+ logger.info("Processing IDEX L1A Event Message data.")
90
+ data = datset_by_apid[IDEXAPID.IDEX_EVT]
91
+ data.attrs = self.idex_attrs.get_global_attributes("imap_idex_l1a_evt")
92
+ data["epoch"].attrs = epoch_attrs
93
+ self.data.append(data)
94
+
95
+ if IDEXAPID.IDEX_CATLST in datset_by_apid:
96
+ logger.info("Processing IDEX L1A Catalog List Summary data.")
97
+ data = datset_by_apid[IDEXAPID.IDEX_CATLST]
98
+ data.attrs = self.idex_attrs.get_global_attributes("imap_idex_l1a_catlst")
99
+ data["epoch"].attrs = epoch_attrs
100
+ self.data.append(data)
101
+
102
+ logger.info("IDEX L1A data processing completed.")
103
+
104
+ def _create_science_dataset(self, science_decom_packet_list: list) -> xr.Dataset:
105
+ """
106
+ Process IDEX science packets into an xarray Dataset.
107
+
108
+ Parameters
109
+ ----------
110
+ science_decom_packet_list : list
111
+ List of decommutated science packets.
112
+
113
+ Returns
114
+ -------
115
+ xarray.Dataset
116
+ Dataset containing processed dust events.
117
+ """
80
118
  dust_events = {}
81
- for packet in decom_packet_list:
119
+ for packet in science_decom_packet_list:
82
120
  if "IDX__SCI0TYPE" in packet:
83
121
  scitype = packet["IDX__SCI0TYPE"]
84
122
  event_number = packet["IDX__SCI0EVTNUM"]
85
123
  if scitype == Scitype.FIRST_PACKET:
86
124
  # Initial packet for new dust event
87
125
  # Further packets will fill in data
88
- dust_events[event_number] = RawDustEvent(packet, data_version)
126
+ dust_events[event_number] = RawDustEvent(packet)
89
127
  elif event_number not in dust_events:
90
128
  raise KeyError(
91
129
  f"Have not receive header information from event number\
@@ -101,40 +139,43 @@ class PacketParser:
101
139
  dust_event.process() for dust_event in dust_events.values()
102
140
  ]
103
141
 
104
- self.data = xr.concat(processed_dust_impact_list, dim="epoch")
105
- idex_attrs = get_idex_attrs(data_version)
106
- self.data.attrs = idex_attrs.get_global_attributes("imap_idex_l1a_sci")
142
+ data = xr.concat(processed_dust_impact_list, dim="epoch")
143
+ data.attrs = self.idex_attrs.get_global_attributes("imap_idex_l1a_sci")
107
144
 
108
145
  # Add high and low sample rate coords
109
- self.data["time_low_sample_rate_index"] = xr.DataArray(
110
- np.arange(len(self.data["time_low_sample_rate"][0])),
146
+ data["time_low_sample_rate_index"] = xr.DataArray(
147
+ np.arange(len(data["time_low_sample_rate"][0])),
111
148
  name="time_low_sample_rate_index",
112
149
  dims=["time_low_sample_rate_index"],
113
- attrs=idex_attrs.get_variable_attributes("time_low_sample_rate_index"),
150
+ attrs=self.idex_attrs.get_variable_attributes("time_low_sample_rate_index"),
114
151
  )
115
152
 
116
- self.data["time_high_sample_rate_index"] = xr.DataArray(
117
- np.arange(len(self.data["time_high_sample_rate"][0])),
153
+ data["time_high_sample_rate_index"] = xr.DataArray(
154
+ np.arange(len(data["time_high_sample_rate"][0])),
118
155
  name="time_high_sample_rate_index",
119
156
  dims=["time_high_sample_rate_index"],
120
- attrs=idex_attrs.get_variable_attributes("time_high_sample_rate_index"),
157
+ attrs=self.idex_attrs.get_variable_attributes(
158
+ "time_high_sample_rate_index"
159
+ ),
121
160
  )
122
161
  # NOTE: LABL_PTR_1 should be CDF_CHAR.
123
- self.data["time_low_sample_rate_label"] = xr.DataArray(
124
- self.data.time_low_sample_rate_index.values.astype(str),
162
+ data["time_low_sample_rate_label"] = xr.DataArray(
163
+ data.time_low_sample_rate_index.values.astype(str),
125
164
  name="time_low_sample_rate_label",
126
165
  dims=["time_low_sample_rate_index"],
127
- attrs=idex_attrs.get_variable_attributes("time_low_sample_rate_label"),
166
+ attrs=self.idex_attrs.get_variable_attributes("time_low_sample_rate_label"),
128
167
  )
129
168
 
130
- self.data["time_high_sample_rate_label"] = xr.DataArray(
131
- self.data.time_high_sample_rate_index.values.astype(str),
169
+ data["time_high_sample_rate_label"] = xr.DataArray(
170
+ data.time_high_sample_rate_index.values.astype(str),
132
171
  name="time_high_sample_rate_label",
133
172
  dims=["time_high_sample_rate_index"],
134
- attrs=idex_attrs.get_variable_attributes("time_high_sample_rate_label"),
173
+ attrs=self.idex_attrs.get_variable_attributes(
174
+ "time_high_sample_rate_label"
175
+ ),
135
176
  )
136
177
 
137
- logger.info("IDEX L1A science data processing completed.")
178
+ return data
138
179
 
139
180
 
140
181
  def _read_waveform_bits(waveform_raw: str, high_sample: bool = True) -> list[int]:
@@ -162,10 +203,10 @@ def _read_waveform_bits(waveform_raw: str, high_sample: bool = True) -> list[int
162
203
 
163
204
  Returns
164
205
  -------
165
- ints : list
206
+ ints : list[int]
166
207
  List of the waveform.
167
208
  """
168
- ints = []
209
+ ints: list[int] = []
169
210
  if high_sample:
170
211
  for i in range(0, len(waveform_raw), 32):
171
212
  # 32-bit chunks, divided up into 2, 10, 10, 10
@@ -198,8 +239,6 @@ class RawDustEvent:
198
239
  ----------
199
240
  header_packet : space_packet_parser.packets.CCSDSPacket
200
241
  The FPGA metadata event header.
201
- data_version : str
202
- The version of the data product being created.
203
242
 
204
243
  Attributes
205
244
  ----------
@@ -252,9 +291,7 @@ class RawDustEvent:
252
291
  MAX_HIGH_BLOCKS = 16
253
292
  MAX_LOW_BLOCKS = 64
254
293
 
255
- def __init__(
256
- self, header_packet: space_packet_parser.packets.CCSDSPacket, data_version: str
257
- ) -> None:
294
+ def __init__(self, header_packet: space_packet_parser.packets.CCSDSPacket) -> None:
258
295
  """
259
296
  Initialize a raw dust event, with an FPGA Header Packet from IDEX.
260
297
 
@@ -268,8 +305,6 @@ class RawDustEvent:
268
305
  ----------
269
306
  header_packet : space_packet_parser.packets.CCSDSPacket
270
307
  The FPGA metadata event header.
271
- data_version : str
272
- Data version for CDF filename, in the format ``vXXX``.
273
308
  """
274
309
  # Calculate the impact time in seconds since epoch
275
310
  self.impact_time = 0
@@ -301,7 +336,7 @@ class RawDustEvent:
301
336
  self.Ion_Grid_bits = ""
302
337
 
303
338
  self.compressed = self.telemetry_items["idx__sci0comp"]
304
- self.cdf_attrs = get_idex_attrs(data_version)
339
+ self.cdf_attrs = get_idex_attrs()
305
340
 
306
341
  def _append_raw_data(self, scitype: Scitype, bits: str) -> None:
307
342
  """
@@ -398,6 +433,7 @@ class RawDustEvent:
398
433
  # To extract the high gain bits, the bitwise right shift (>> 20) moves the bits
399
434
  # 20 positions to the right, and the mask (0b1111111111) keeps only the least
400
435
  # significant 10 bits.
436
+ # TODO use the delay corresponding to the trigger
401
437
  high_gain_delay = (packet["IDX__TXHDRSAMPDELAY"] >> 22) & 0b1111111111
402
438
  n_blocks = packet["IDX__TXHDRBLOCKS"]
403
439
 
@@ -410,22 +446,20 @@ class RawDustEvent:
410
446
  # Bits 13-16 represent the number of high sampling pre-trigger blocks.
411
447
  # We can extract this by shifting right by 16 bits and applying a mask to keep
412
448
  # the last 4 bits.
413
-
414
449
  num_low_sample_pretrigger_blocks = (n_blocks >> 6) & 0b111111
415
450
  num_high_sample_pretrigger_blocks = (n_blocks >> 16) & 0b1111
416
-
417
451
  # Calculate the low and high sample trigger times based on the high gain delay
418
452
  # and the number of high sample/low sample pretrigger blocks
419
453
  self.low_sample_trigger_time = (
420
454
  self.LOW_SAMPLE_RATE
421
455
  * (num_low_sample_pretrigger_blocks + 1)
422
456
  * self.NUMBER_SAMPLES_PER_LOW_SAMPLE_BLOCK
423
- - self.HIGH_SAMPLE_RATE * high_gain_delay
424
457
  )
425
458
  self.high_sample_trigger_time = (
426
459
  self.HIGH_SAMPLE_RATE
427
460
  * (num_high_sample_pretrigger_blocks + 1)
428
461
  * self.NUMBER_SAMPLES_PER_HIGH_SAMPLE_BLOCK
462
+ - self.HIGH_SAMPLE_RATE * high_gain_delay
429
463
  )
430
464
 
431
465
  def _parse_high_sample_waveform(self, waveform_raw: str) -> list[int]:
@@ -442,15 +476,16 @@ class RawDustEvent:
442
476
 
443
477
  Returns
444
478
  -------
445
- ints : list
479
+ ints : list[int]
446
480
  List of the high sample waveform.
447
481
  """
448
482
  samples = self.MAX_HIGH_BLOCKS * self.NUMBER_SAMPLES_PER_HIGH_SAMPLE_BLOCK
483
+ ints: list[int] = []
449
484
  if self.compressed.raw_value == 1:
450
- ints = rice_decode(waveform_raw, nbit10=True, sample_count=samples)
485
+ ints.extend(rice_decode(waveform_raw, nbit10=True, sample_count=samples))
451
486
  ints = ints[:-3]
452
487
  else:
453
- ints = _read_waveform_bits(waveform_raw, high_sample=True)
488
+ ints.extend(_read_waveform_bits(waveform_raw, high_sample=True))
454
489
  return ints
455
490
 
456
491
  def _parse_low_sample_waveform(self, waveform_raw: str) -> list[int]:
@@ -467,14 +502,15 @@ class RawDustEvent:
467
502
 
468
503
  Returns
469
504
  -------
470
- ints : list
505
+ ints : list[int]
471
506
  List of processed low sample waveform.
472
507
  """
473
508
  samples = self.MAX_LOW_BLOCKS * self.NUMBER_SAMPLES_PER_LOW_SAMPLE_BLOCK
509
+ ints: list[int] = []
474
510
  if self.compressed.raw_value == 1:
475
- ints = rice_decode(waveform_raw, nbit10=False, sample_count=samples)
511
+ ints.extend(rice_decode(waveform_raw, nbit10=False, sample_count=samples))
476
512
  else:
477
- ints = _read_waveform_bits(waveform_raw, high_sample=False)
513
+ ints.extend(_read_waveform_bits(waveform_raw, high_sample=False))
478
514
  return ints
479
515
 
480
516
  def _calc_low_sample_resolution(self, num_samples: int) -> npt.NDArray:
@@ -652,15 +688,10 @@ class RawDustEvent:
652
688
  return dataset
653
689
 
654
690
 
655
- def get_idex_attrs(data_version: str) -> ImapCdfAttributes:
691
+ def get_idex_attrs() -> ImapCdfAttributes:
656
692
  """
657
693
  Load in CDF attributes for IDEX instrument.
658
694
 
659
- Parameters
660
- ----------
661
- data_version : str
662
- Data version for CDF filename, in the format "vXXX".
663
-
664
695
  Returns
665
696
  -------
666
697
  idex_attrs : ImapCdfAttributes
@@ -669,5 +700,4 @@ def get_idex_attrs(data_version: str) -> ImapCdfAttributes:
669
700
  idex_attrs = ImapCdfAttributes()
670
701
  idex_attrs.add_instrument_global_attrs("idex")
671
702
  idex_attrs.add_instrument_variable_attrs("idex", "l1a")
672
- idex_attrs.add_global_attribute("Data_version", data_version)
673
703
  return idex_attrs