imap-processing 0.6.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.
Files changed (398) hide show
  1. imap_processing/__init__.py +34 -0
  2. imap_processing/_version.py +3 -0
  3. imap_processing/ccsds/__init__.py +0 -0
  4. imap_processing/ccsds/ccsds_data.py +55 -0
  5. imap_processing/ccsds/excel_to_xtce.py +477 -0
  6. imap_processing/cdf/__init__.py +0 -0
  7. imap_processing/cdf/cdf_attribute_manager.py +322 -0
  8. imap_processing/cdf/config/imap_codice_global_cdf_attrs.yaml +212 -0
  9. imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +1358 -0
  10. imap_processing/cdf/config/imap_codice_l1b_variable_attrs.yaml +391 -0
  11. imap_processing/cdf/config/imap_constant_attrs.yaml +33 -0
  12. imap_processing/cdf/config/imap_default_global_cdf_attrs.yaml +17 -0
  13. imap_processing/cdf/config/imap_glows_global_cdf_attrs.yaml +41 -0
  14. imap_processing/cdf/config/imap_glows_l1a_variable_attrs.yaml +499 -0
  15. imap_processing/cdf/config/imap_glows_l1b_variable_attrs.yaml +334 -0
  16. imap_processing/cdf/config/imap_hi_global_cdf_attrs.yaml +51 -0
  17. imap_processing/cdf/config/imap_hi_variable_attrs.yaml +435 -0
  18. imap_processing/cdf/config/imap_hit_global_cdf_attrs.yaml +27 -0
  19. imap_processing/cdf/config/imap_hit_l1a_variable_attrs.yaml +493 -0
  20. imap_processing/cdf/config/imap_hit_l1b_variable_attrs.yaml +564 -0
  21. imap_processing/cdf/config/imap_idex_global_cdf_attrs.yaml +24 -0
  22. imap_processing/cdf/config/imap_idex_l1a_variable_attrs.yaml +426 -0
  23. imap_processing/cdf/config/imap_lo_global_cdf_attrs.yaml +90 -0
  24. imap_processing/cdf/config/imap_lo_l1a_variable_attrs.yaml +487 -0
  25. imap_processing/cdf/config/imap_lo_l1b_variable_attrs.yaml +121 -0
  26. imap_processing/cdf/config/imap_lo_l1c_variable_attrs.yaml +179 -0
  27. imap_processing/cdf/config/imap_mag_global_cdf_attrs.yaml +97 -0
  28. imap_processing/cdf/config/imap_mag_l1_variable_attrs.yaml +201 -0
  29. imap_processing/cdf/config/imap_swapi_global_cdf_attrs.yaml +33 -0
  30. imap_processing/cdf/config/imap_swapi_variable_attrs.yaml +137 -0
  31. imap_processing/cdf/config/imap_swe_global_cdf_attrs.yaml +24 -0
  32. imap_processing/cdf/config/imap_swe_l1a_variable_attrs.yaml +234 -0
  33. imap_processing/cdf/config/imap_swe_l1b_variable_attrs.yaml +273 -0
  34. imap_processing/cdf/config/imap_ultra_global_cdf_attrs.yaml +100 -0
  35. imap_processing/cdf/config/imap_ultra_l1a_variable_attrs.yaml +52 -0
  36. imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +297 -0
  37. imap_processing/cdf/config/imap_ultra_l1c_variable_attrs.yaml +121 -0
  38. imap_processing/cdf/config/shared/default_global_cdf_attrs_schema.yaml +246 -0
  39. imap_processing/cdf/config/shared/default_variable_cdf_attrs_schema.yaml +466 -0
  40. imap_processing/cdf/imap_cdf_manager.py +64 -0
  41. imap_processing/cdf/utils.py +147 -0
  42. imap_processing/cli.py +863 -0
  43. imap_processing/codice/__init__.py +1 -0
  44. imap_processing/codice/codice_l0.py +54 -0
  45. imap_processing/codice/codice_l1a.py +558 -0
  46. imap_processing/codice/codice_l1b.py +194 -0
  47. imap_processing/codice/constants.py +986 -0
  48. imap_processing/codice/data/esa_sweep_values.csv +257 -0
  49. imap_processing/codice/data/lo_stepping_values.csv +129 -0
  50. imap_processing/codice/decompress.py +142 -0
  51. imap_processing/codice/packet_definitions/P_COD_NHK.xml +618 -0
  52. imap_processing/codice/packet_definitions/codice_packet_definition.xml +5073 -0
  53. imap_processing/codice/utils.py +95 -0
  54. imap_processing/decom.py +40 -0
  55. imap_processing/glows/__init__.py +1 -0
  56. imap_processing/glows/ancillary/l1b_conversion_table_v001.json +42 -0
  57. imap_processing/glows/l0/__init__.py +0 -0
  58. imap_processing/glows/l0/decom_glows.py +91 -0
  59. imap_processing/glows/l0/glows_l0_data.py +194 -0
  60. imap_processing/glows/l1a/glows_l1a.py +424 -0
  61. imap_processing/glows/l1a/glows_l1a_data.py +555 -0
  62. imap_processing/glows/l1b/glows_l1b.py +270 -0
  63. imap_processing/glows/l1b/glows_l1b_data.py +583 -0
  64. imap_processing/glows/packet_definitions/GLX_COMBINED.xml +254 -0
  65. imap_processing/glows/packet_definitions/P_GLX_TMSCDE.xml +97 -0
  66. imap_processing/glows/packet_definitions/P_GLX_TMSCHIST.xml +215 -0
  67. imap_processing/glows/utils/__init__.py +0 -0
  68. imap_processing/glows/utils/constants.py +105 -0
  69. imap_processing/hi/__init__.py +1 -0
  70. imap_processing/hi/l0/__init__.py +0 -0
  71. imap_processing/hi/l0/decom_hi.py +24 -0
  72. imap_processing/hi/l1a/__init__.py +0 -0
  73. imap_processing/hi/l1a/hi_l1a.py +73 -0
  74. imap_processing/hi/l1a/histogram.py +142 -0
  75. imap_processing/hi/l1a/housekeeping.py +27 -0
  76. imap_processing/hi/l1a/science_direct_event.py +341 -0
  77. imap_processing/hi/l1b/__init__.py +0 -0
  78. imap_processing/hi/l1b/hi_eng_unit_convert_table.csv +154 -0
  79. imap_processing/hi/l1b/hi_l1b.py +127 -0
  80. imap_processing/hi/l1c/__init__.py +0 -0
  81. imap_processing/hi/l1c/hi_l1c.py +228 -0
  82. imap_processing/hi/packet_definitions/__init__.py +0 -0
  83. imap_processing/hi/packet_definitions/hi_packet_definition.xml +482 -0
  84. imap_processing/hi/utils.py +27 -0
  85. imap_processing/hit/__init__.py +1 -0
  86. imap_processing/hit/l0/__init__.py +0 -0
  87. imap_processing/hit/l0/data_classes/housekeeping.py +240 -0
  88. imap_processing/hit/l0/data_classes/science_packet.py +259 -0
  89. imap_processing/hit/l0/decom_hit.py +467 -0
  90. imap_processing/hit/l0/utils/hit_base.py +57 -0
  91. imap_processing/hit/l1a/__init__.py +0 -0
  92. imap_processing/hit/l1a/hit_l1a.py +254 -0
  93. imap_processing/hit/l1b/hit_l1b.py +179 -0
  94. imap_processing/hit/packet_definitions/hit_packet_definitions.xml +1276 -0
  95. imap_processing/ialirt/__init__.py +0 -0
  96. imap_processing/ialirt/l0/__init__.py +0 -0
  97. imap_processing/ialirt/l0/process_hit.py +220 -0
  98. imap_processing/ialirt/packet_definitions/__init__.py +0 -0
  99. imap_processing/ialirt/packet_definitions/ialirt.xml +778 -0
  100. imap_processing/ialirt/packet_definitions/ialirt_hit.xml +186 -0
  101. imap_processing/idex/__init__.py +2 -0
  102. imap_processing/idex/idex_constants.py +27 -0
  103. imap_processing/idex/idex_l0.py +31 -0
  104. imap_processing/idex/idex_l1a.py +631 -0
  105. imap_processing/idex/packet_definitions/idex_packet_definition.xml +3162 -0
  106. imap_processing/lo/__init__.py +1 -0
  107. imap_processing/lo/l0/__init__.py +0 -0
  108. imap_processing/lo/l0/data_classes/science_direct_events.py +215 -0
  109. imap_processing/lo/l0/data_classes/star_sensor.py +98 -0
  110. imap_processing/lo/l0/decompression_tables/12_to_16_bit.csv +4097 -0
  111. imap_processing/lo/l0/decompression_tables/8_to_12_bit.csv +257 -0
  112. imap_processing/lo/l0/decompression_tables/8_to_16_bit.csv +257 -0
  113. imap_processing/lo/l0/decompression_tables/decompression_tables.py +75 -0
  114. imap_processing/lo/l0/lo_apid.py +15 -0
  115. imap_processing/lo/l0/lo_science.py +150 -0
  116. imap_processing/lo/l0/utils/binary_string.py +59 -0
  117. imap_processing/lo/l0/utils/bit_decompression.py +62 -0
  118. imap_processing/lo/l0/utils/lo_base.py +57 -0
  119. imap_processing/lo/l1a/__init__.py +0 -0
  120. imap_processing/lo/l1a/lo_l1a.py +157 -0
  121. imap_processing/lo/l1b/lo_l1b.py +160 -0
  122. imap_processing/lo/l1c/lo_l1c.py +180 -0
  123. imap_processing/lo/packet_definitions/lo_xtce.xml +3541 -0
  124. imap_processing/mag/__init__.py +2 -0
  125. imap_processing/mag/constants.py +108 -0
  126. imap_processing/mag/l0/decom_mag.py +170 -0
  127. imap_processing/mag/l0/mag_l0_data.py +118 -0
  128. imap_processing/mag/l1a/mag_l1a.py +317 -0
  129. imap_processing/mag/l1a/mag_l1a_data.py +1007 -0
  130. imap_processing/mag/l1b/__init__.py +0 -0
  131. imap_processing/mag/l1b/imap_calibration_mag_20240229_v01.cdf +0 -0
  132. imap_processing/mag/l1b/mag_l1b.py +125 -0
  133. imap_processing/mag/l1c/mag_l1c.py +57 -0
  134. imap_processing/mag/packet_definitions/MAG_SCI_COMBINED.xml +235 -0
  135. imap_processing/quality_flags.py +91 -0
  136. imap_processing/spice/__init__.py +1 -0
  137. imap_processing/spice/geometry.py +322 -0
  138. imap_processing/spice/kernels.py +459 -0
  139. imap_processing/spice/time.py +72 -0
  140. imap_processing/swapi/__init__.py +1 -0
  141. imap_processing/swapi/l1/__init__.py +0 -0
  142. imap_processing/swapi/l1/swapi_l1.py +685 -0
  143. imap_processing/swapi/l2/__init__.py +0 -0
  144. imap_processing/swapi/l2/swapi_l2.py +107 -0
  145. imap_processing/swapi/packet_definitions/__init__.py +0 -0
  146. imap_processing/swapi/packet_definitions/swapi_packet_definition.xml +708 -0
  147. imap_processing/swapi/swapi_utils.py +25 -0
  148. imap_processing/swe/__init__.py +1 -0
  149. imap_processing/swe/l1a/__init__.py +0 -0
  150. imap_processing/swe/l1a/swe_l1a.py +48 -0
  151. imap_processing/swe/l1a/swe_science.py +223 -0
  152. imap_processing/swe/l1b/engineering_unit_convert_table.csv +65 -0
  153. imap_processing/swe/l1b/swe_esa_lookup_table.csv +1441 -0
  154. imap_processing/swe/l1b/swe_l1b.py +49 -0
  155. imap_processing/swe/l1b/swe_l1b_science.py +557 -0
  156. imap_processing/swe/packet_definitions/__init__.py +0 -0
  157. imap_processing/swe/packet_definitions/swe_packet_definition.xml +303 -0
  158. imap_processing/swe/utils/__init__.py +0 -0
  159. imap_processing/swe/utils/swe_utils.py +9 -0
  160. imap_processing/tests/__init__.py +0 -0
  161. imap_processing/tests/ccsds/test_data/expected_output.xml +171 -0
  162. imap_processing/tests/ccsds/test_excel_to_xtce.py +285 -0
  163. imap_processing/tests/cdf/__init__.py +0 -0
  164. imap_processing/tests/cdf/imap_default_global_cdf_attrs.yaml +8 -0
  165. imap_processing/tests/cdf/shared/default_global_cdf_attrs_schema.yaml +246 -0
  166. imap_processing/tests/cdf/shared/default_variable_cdf_attrs_schema.yaml +466 -0
  167. imap_processing/tests/cdf/test_cdf_attribute_manager.py +353 -0
  168. imap_processing/tests/cdf/test_data/imap_default_global_test_cdf_attrs.yaml +7 -0
  169. imap_processing/tests/cdf/test_data/imap_instrument1_global_cdf_attrs.yaml +14 -0
  170. imap_processing/tests/cdf/test_data/imap_instrument1_level1_variable_attrs.yaml +23 -0
  171. imap_processing/tests/cdf/test_data/imap_instrument2_global_cdf_attrs.yaml +23 -0
  172. imap_processing/tests/cdf/test_data/imap_instrument2_level2_variable_attrs.yaml +30 -0
  173. imap_processing/tests/cdf/test_data/imap_test_global.yaml +26 -0
  174. imap_processing/tests/cdf/test_data/imap_test_variable.yaml +41 -0
  175. imap_processing/tests/cdf/test_imap_cdf_manager.py +62 -0
  176. imap_processing/tests/cdf/test_utils.py +109 -0
  177. imap_processing/tests/codice/__init__.py +0 -0
  178. imap_processing/tests/codice/conftest.py +56 -0
  179. imap_processing/tests/codice/data/eu_unit_lookup_table.csv +101 -0
  180. imap_processing/tests/codice/data/idle_export_eu.COD_NHK_20230822_122700 2.csv +100 -0
  181. imap_processing/tests/codice/data/idle_export_raw.COD_NHK_20230822_122700.csv +100 -0
  182. imap_processing/tests/codice/data/imap_codice_l0_hi-counters-aggregated_20240429_v001.pkts +0 -0
  183. imap_processing/tests/codice/data/imap_codice_l0_hi-counters-singles_20240429_v001.pkts +0 -0
  184. imap_processing/tests/codice/data/imap_codice_l0_hi-omni_20240429_v001.pkts +0 -0
  185. imap_processing/tests/codice/data/imap_codice_l0_hi-pha_20240429_v001.pkts +0 -0
  186. imap_processing/tests/codice/data/imap_codice_l0_hi-sectored_20240429_v001.pkts +0 -0
  187. imap_processing/tests/codice/data/imap_codice_l0_hskp_20100101_v001.pkts +0 -0
  188. imap_processing/tests/codice/data/imap_codice_l0_lo-counters-aggregated_20240429_v001.pkts +0 -0
  189. imap_processing/tests/codice/data/imap_codice_l0_lo-counters-singles_20240429_v001.pkts +0 -0
  190. imap_processing/tests/codice/data/imap_codice_l0_lo-nsw-angular_20240429_v001.pkts +0 -0
  191. imap_processing/tests/codice/data/imap_codice_l0_lo-nsw-priority_20240429_v001.pkts +0 -0
  192. imap_processing/tests/codice/data/imap_codice_l0_lo-nsw-species_20240429_v001.pkts +0 -0
  193. imap_processing/tests/codice/data/imap_codice_l0_lo-pha_20240429_v001.pkts +0 -0
  194. imap_processing/tests/codice/data/imap_codice_l0_lo-sw-angular_20240429_v001.pkts +0 -0
  195. imap_processing/tests/codice/data/imap_codice_l0_lo-sw-priority_20240429_v001.pkts +0 -0
  196. imap_processing/tests/codice/data/imap_codice_l0_lo-sw-species_20240429_v001.pkts +0 -0
  197. imap_processing/tests/codice/data/imap_codice_l1a_hi-counters-aggregated_20240429_v001.cdf +0 -0
  198. imap_processing/tests/codice/data/imap_codice_l1a_hi-counters-singles_20240429_v001.cdf +0 -0
  199. imap_processing/tests/codice/data/imap_codice_l1a_hi-omni_20240429_v001.cdf +0 -0
  200. imap_processing/tests/codice/data/imap_codice_l1a_hi-sectored_20240429_v001.cdf +0 -0
  201. imap_processing/tests/codice/data/imap_codice_l1a_hskp_20100101_v001.cdf +0 -0
  202. imap_processing/tests/codice/data/imap_codice_l1a_lo-counters-aggregated_20240429_v001.cdf +0 -0
  203. imap_processing/tests/codice/data/imap_codice_l1a_lo-counters-singles_20240429_v001.cdf +0 -0
  204. imap_processing/tests/codice/data/imap_codice_l1a_lo-nsw-angular_20240429_v001.cdf +0 -0
  205. imap_processing/tests/codice/data/imap_codice_l1a_lo-nsw-priority_20240429_v001.cdf +0 -0
  206. imap_processing/tests/codice/data/imap_codice_l1a_lo-nsw-species_20240429_v001.cdf +0 -0
  207. imap_processing/tests/codice/data/imap_codice_l1a_lo-sw-angular_20240429_v001.cdf +0 -0
  208. imap_processing/tests/codice/data/imap_codice_l1a_lo-sw-priority_20240429_v001.cdf +0 -0
  209. imap_processing/tests/codice/data/imap_codice_l1a_lo-sw-species_20240429_v001.cdf +0 -0
  210. imap_processing/tests/codice/data/imap_codice_l1b_hi-counters-aggregated_20240429_v001.cdf +0 -0
  211. imap_processing/tests/codice/data/imap_codice_l1b_hi-counters-singles_20240429_v001.cdf +0 -0
  212. imap_processing/tests/codice/data/imap_codice_l1b_hi-omni_20240429_v001.cdf +0 -0
  213. imap_processing/tests/codice/data/imap_codice_l1b_hi-sectored_20240429_v001.cdf +0 -0
  214. imap_processing/tests/codice/data/imap_codice_l1b_hskp_20100101_v001.cdf +0 -0
  215. imap_processing/tests/codice/data/imap_codice_l1b_lo-counters-aggregated_20240429_v001.cdf +0 -0
  216. imap_processing/tests/codice/data/imap_codice_l1b_lo-counters-singles_20240429_v001.cdf +0 -0
  217. imap_processing/tests/codice/data/imap_codice_l1b_lo-nsw-angular_20240429_v001.cdf +0 -0
  218. imap_processing/tests/codice/data/imap_codice_l1b_lo-nsw-priority_20240429_v001.cdf +0 -0
  219. imap_processing/tests/codice/data/imap_codice_l1b_lo-nsw-species_20240429_v001.cdf +0 -0
  220. imap_processing/tests/codice/data/imap_codice_l1b_lo-sw-angular_20240429_v001.cdf +0 -0
  221. imap_processing/tests/codice/data/imap_codice_l1b_lo-sw-priority_20240429_v001.cdf +0 -0
  222. imap_processing/tests/codice/data/imap_codice_l1b_lo-sw-species_20240429_v001.cdf +0 -0
  223. imap_processing/tests/codice/test_codice_l0.py +144 -0
  224. imap_processing/tests/codice/test_codice_l1a.py +187 -0
  225. imap_processing/tests/codice/test_codice_l1b.py +60 -0
  226. imap_processing/tests/codice/test_decompress.py +50 -0
  227. imap_processing/tests/conftest.py +372 -0
  228. imap_processing/tests/glows/direct_events_validation_data_l1a.csv +5704 -0
  229. imap_processing/tests/glows/glows_test_packet_20110921_v01.pkts +0 -0
  230. imap_processing/tests/glows/test_glows_decom.py +133 -0
  231. imap_processing/tests/glows/test_glows_l1a_cdf.py +85 -0
  232. imap_processing/tests/glows/test_glows_l1a_data.py +510 -0
  233. imap_processing/tests/glows/test_glows_l1b.py +348 -0
  234. imap_processing/tests/glows/test_glows_l1b_data.py +70 -0
  235. imap_processing/tests/hi/__init__.py +0 -0
  236. imap_processing/tests/hi/conftest.py +133 -0
  237. imap_processing/tests/hi/test_data/l0/20231030_H45_APP_NHK.bin +0 -0
  238. imap_processing/tests/hi/test_data/l0/20231030_H45_APP_NHK.csv +201 -0
  239. imap_processing/tests/hi/test_data/l0/20231030_H45_SCI_CNT.bin +0 -0
  240. imap_processing/tests/hi/test_data/l0/20231030_H45_SCI_DE.bin +0 -0
  241. imap_processing/tests/hi/test_data/l0/README.txt +54 -0
  242. imap_processing/tests/hi/test_decom.py +55 -0
  243. imap_processing/tests/hi/test_hi_l1b.py +31 -0
  244. imap_processing/tests/hi/test_hi_l1c.py +69 -0
  245. imap_processing/tests/hi/test_l1a.py +96 -0
  246. imap_processing/tests/hi/test_l1a_sci_de.py +72 -0
  247. imap_processing/tests/hi/test_utils.py +15 -0
  248. imap_processing/tests/hit/PREFLIGHT_raw_record_2023_256_15_59_04_apid1251.pkts +0 -0
  249. imap_processing/tests/hit/PREFLIGHT_raw_record_2023_256_15_59_04_apid1252.pkts +0 -0
  250. imap_processing/tests/hit/__init__.py +0 -0
  251. imap_processing/tests/hit/test_data/imap_hit_l0_hk_20100105_v001.pkts +0 -0
  252. imap_processing/tests/hit/test_data/sci_sample.ccsds +0 -0
  253. imap_processing/tests/hit/test_hit_decom.py +230 -0
  254. imap_processing/tests/hit/test_hit_l1a.py +224 -0
  255. imap_processing/tests/hit/test_hit_l1b.py +52 -0
  256. imap_processing/tests/hit/validation_data/hskp_sample_raw.csv +88 -0
  257. imap_processing/tests/ialirt/__init__.py +0 -0
  258. imap_processing/tests/ialirt/test_data/l0/IALiRT Raw Packet Telemetry.txt +33 -0
  259. imap_processing/tests/ialirt/test_data/l0/hit_ialirt_sample.ccsds +0 -0
  260. imap_processing/tests/ialirt/test_data/l0/hit_ialirt_sample.csv +1001 -0
  261. imap_processing/tests/ialirt/unit/__init__.py +0 -0
  262. imap_processing/tests/ialirt/unit/test_decom_ialirt.py +94 -0
  263. imap_processing/tests/ialirt/unit/test_process_hit.py +226 -0
  264. imap_processing/tests/idex/__init__.py +0 -0
  265. imap_processing/tests/idex/conftest.py +22 -0
  266. imap_processing/tests/idex/imap_idex_l0_raw_20230725_v001.pkts +0 -0
  267. imap_processing/tests/idex/impact_14_tof_high_data.txt +8189 -0
  268. imap_processing/tests/idex/test_idex_l0.py +45 -0
  269. imap_processing/tests/idex/test_idex_l1a.py +91 -0
  270. imap_processing/tests/lo/__init__.py +0 -0
  271. imap_processing/tests/lo/test_binary_string.py +21 -0
  272. imap_processing/tests/lo/test_bit_decompression.py +39 -0
  273. imap_processing/tests/lo/test_cdfs/imap_lo_l0_raw_20240627_v001.pkts +0 -0
  274. imap_processing/tests/lo/test_cdfs/imap_lo_l1a_de_20100101_v001.cdf +0 -0
  275. imap_processing/tests/lo/test_cdfs/imap_lo_l1a_spin_20100101_v001.cdf +0 -0
  276. imap_processing/tests/lo/test_cdfs/imap_lo_l1b_de_20100101_v001.cdf +0 -0
  277. imap_processing/tests/lo/test_lo_l1a.py +66 -0
  278. imap_processing/tests/lo/test_lo_l1b.py +74 -0
  279. imap_processing/tests/lo/test_lo_l1c.py +66 -0
  280. imap_processing/tests/lo/test_science_counts.py +41 -0
  281. imap_processing/tests/lo/test_science_direct_events.py +209 -0
  282. imap_processing/tests/lo/test_star_sensor.py +35 -0
  283. imap_processing/tests/mag/imap_mag_l1a_burst-magi_20231025_v001.cdf +0 -0
  284. imap_processing/tests/mag/mag_l0_test_data.pkts +0 -0
  285. imap_processing/tests/mag/mag_l0_test_output.csv +37 -0
  286. imap_processing/tests/mag/mag_l1_test_data.pkts +0 -0
  287. imap_processing/tests/mag/mag_l1a_test_output.csv +97 -0
  288. imap_processing/tests/mag/test_mag_decom.py +117 -0
  289. imap_processing/tests/mag/test_mag_l1a.py +856 -0
  290. imap_processing/tests/mag/test_mag_l1b.py +77 -0
  291. imap_processing/tests/mag/test_mag_l1c.py +40 -0
  292. imap_processing/tests/spice/__init__.py +0 -0
  293. imap_processing/tests/spice/test_data/imap_ena_sim_metakernel.template +4 -0
  294. imap_processing/tests/spice/test_data/imap_science_0001.tf +171 -0
  295. imap_processing/tests/spice/test_data/imap_sclk_0000.tsc +156 -0
  296. imap_processing/tests/spice/test_data/imap_sim_ck_2hr_2secsampling_with_nutation.bc +0 -0
  297. imap_processing/tests/spice/test_data/imap_simple_metakernel.template +3 -0
  298. imap_processing/tests/spice/test_data/imap_spk_demo.bsp +0 -0
  299. imap_processing/tests/spice/test_data/imap_wkcp.tf +1806 -0
  300. imap_processing/tests/spice/test_data/naif0012.tls +150 -0
  301. imap_processing/tests/spice/test_data/sim_1yr_imap_attitude.bc +0 -0
  302. imap_processing/tests/spice/test_data/sim_1yr_imap_pointing_frame.bc +0 -0
  303. imap_processing/tests/spice/test_geometry.py +214 -0
  304. imap_processing/tests/spice/test_kernels.py +272 -0
  305. imap_processing/tests/spice/test_time.py +35 -0
  306. imap_processing/tests/swapi/__init__.py +0 -0
  307. imap_processing/tests/swapi/conftest.py +16 -0
  308. imap_processing/tests/swapi/l0_data/__init__.py +0 -0
  309. imap_processing/tests/swapi/l0_data/imap_swapi_l0_raw_20231012_v001.pkts +0 -0
  310. imap_processing/tests/swapi/l0_validation_data/__init__.py +0 -0
  311. imap_processing/tests/swapi/l0_validation_data/idle_export_eu.SWP_AUT_20231012_125245.csv +124 -0
  312. imap_processing/tests/swapi/l0_validation_data/idle_export_eu.SWP_HK_20231012_125245.csv +98 -0
  313. imap_processing/tests/swapi/l0_validation_data/idle_export_eu.SWP_MG_20231012_125245.csv +9 -0
  314. imap_processing/tests/swapi/l0_validation_data/idle_export_eu.SWP_SCI_20231012_125245.csv +72 -0
  315. imap_processing/tests/swapi/l0_validation_data/idle_export_raw.SWP_AUT_20231012_125245.csv +124 -0
  316. imap_processing/tests/swapi/l0_validation_data/idle_export_raw.SWP_HK_20231012_125245.csv +98 -0
  317. imap_processing/tests/swapi/l0_validation_data/idle_export_raw.SWP_MG_20231012_125245.csv +9 -0
  318. imap_processing/tests/swapi/l0_validation_data/idle_export_raw.SWP_SCI_20231012_125245.csv +72 -0
  319. imap_processing/tests/swapi/test_swapi_decom.py +135 -0
  320. imap_processing/tests/swapi/test_swapi_l1.py +354 -0
  321. imap_processing/tests/swapi/test_swapi_l2.py +21 -0
  322. imap_processing/tests/swe/__init__.py +0 -0
  323. imap_processing/tests/swe/conftest.py +35 -0
  324. imap_processing/tests/swe/decompressed/20230927173238_4th_quarter_decompressed.csv +181 -0
  325. imap_processing/tests/swe/decompressed/20230927173253_1st_quarter_decompressed.csv +181 -0
  326. imap_processing/tests/swe/decompressed/20230927173308_2nd_quarter_decompressed.csv +181 -0
  327. imap_processing/tests/swe/decompressed/20230927173323_3rd_quarter_decompressed.csv +181 -0
  328. imap_processing/tests/swe/l0_data/2024051010_SWE_SCIENCE_packet.bin +0 -0
  329. imap_processing/tests/swe/l0_validation_data/idle_export_eu.SWE_SCIENCE_20240510_092742.csv +544 -0
  330. imap_processing/tests/swe/l0_validation_data/idle_export_raw.SWE_SCIENCE_20240510_092742.csv +363 -0
  331. imap_processing/tests/swe/test_swe_l1a.py +12 -0
  332. imap_processing/tests/swe/test_swe_l1a_science.py +129 -0
  333. imap_processing/tests/swe/test_swe_l1b.py +61 -0
  334. imap_processing/tests/swe/test_swe_l1b_science.py +65 -0
  335. imap_processing/tests/test_cli.py +229 -0
  336. imap_processing/tests/test_decom.py +66 -0
  337. imap_processing/tests/test_quality_flags.py +71 -0
  338. imap_processing/tests/test_utils.py +107 -0
  339. imap_processing/tests/ultra/__init__.py +0 -0
  340. imap_processing/tests/ultra/test_data/l0/FM45_40P_Phi28p5_BeamCal_LinearScan_phi28.50_theta-0.00_20240207T102740.CCSDS +0 -0
  341. imap_processing/tests/ultra/test_data/l0/FM45_7P_Phi0.0_BeamCal_LinearScan_phi0.04_theta-0.01_20230821T121304.CCSDS +0 -0
  342. imap_processing/tests/ultra/test_data/l0/FM45_TV_Cycle6_Hot_Ops_Front212_20240124T063837.CCSDS +0 -0
  343. imap_processing/tests/ultra/test_data/l0/Ultra45_EM_SwRI_Cal_Run7_ThetaScan_20220530T225054.CCSDS +0 -0
  344. imap_processing/tests/ultra/test_data/l0/ultra45_raw_sc_auxdata_Ultra45_EM_SwRI_Cal_Run7_ThetaScan_20220530T225054.csv +24 -0
  345. imap_processing/tests/ultra/test_data/l0/ultra45_raw_sc_enaphxtofhangimg_FM45_TV_Cycle6_Hot_Ops_Front212_20240124T063837.csv +105 -0
  346. imap_processing/tests/ultra/test_data/l0/ultra45_raw_sc_ultraimgrates_Ultra45_EM_SwRI_Cal_Run7_ThetaScan_20220530T225054.csv +24 -0
  347. imap_processing/tests/ultra/test_data/l0/ultra45_raw_sc_ultrarawimg_withFSWcalcs_FM45_40P_Phi28p5_BeamCal_LinearScan_phi2850_theta-000_20240207T102740.csv +3314 -0
  348. imap_processing/tests/ultra/test_data/l0/ultra45_raw_sc_ultrarawimgevent_FM45_7P_Phi00_BeamCal_LinearScan_phi004_theta-001_20230821T121304.csv +702 -0
  349. imap_processing/tests/ultra/unit/__init__.py +0 -0
  350. imap_processing/tests/ultra/unit/conftest.py +210 -0
  351. imap_processing/tests/ultra/unit/test_decom_apid_880.py +98 -0
  352. imap_processing/tests/ultra/unit/test_decom_apid_881.py +50 -0
  353. imap_processing/tests/ultra/unit/test_decom_apid_883.py +44 -0
  354. imap_processing/tests/ultra/unit/test_decom_apid_896.py +104 -0
  355. imap_processing/tests/ultra/unit/test_lookup_utils.py +68 -0
  356. imap_processing/tests/ultra/unit/test_ultra_l1a.py +338 -0
  357. imap_processing/tests/ultra/unit/test_ultra_l1b.py +122 -0
  358. imap_processing/tests/ultra/unit/test_ultra_l1b_annotated.py +57 -0
  359. imap_processing/tests/ultra/unit/test_ultra_l1b_extended.py +342 -0
  360. imap_processing/tests/ultra/unit/test_ultra_l1c.py +104 -0
  361. imap_processing/tests/ultra/unit/test_ultra_l1c_pset_bins.py +35 -0
  362. imap_processing/ultra/__init__.py +1 -0
  363. imap_processing/ultra/constants.py +60 -0
  364. imap_processing/ultra/l0/__init__.py +0 -0
  365. imap_processing/ultra/l0/decom_tools.py +281 -0
  366. imap_processing/ultra/l0/decom_ultra.py +278 -0
  367. imap_processing/ultra/l0/ultra_utils.py +326 -0
  368. imap_processing/ultra/l1a/__init__.py +0 -0
  369. imap_processing/ultra/l1a/ultra_l1a.py +319 -0
  370. imap_processing/ultra/l1b/badtimes.py +26 -0
  371. imap_processing/ultra/l1b/cullingmask.py +26 -0
  372. imap_processing/ultra/l1b/de.py +59 -0
  373. imap_processing/ultra/l1b/extendedspin.py +45 -0
  374. imap_processing/ultra/l1b/lookup_utils.py +165 -0
  375. imap_processing/ultra/l1b/ultra_l1b.py +65 -0
  376. imap_processing/ultra/l1b/ultra_l1b_annotated.py +54 -0
  377. imap_processing/ultra/l1b/ultra_l1b_extended.py +764 -0
  378. imap_processing/ultra/l1c/histogram.py +36 -0
  379. imap_processing/ultra/l1c/pset.py +36 -0
  380. imap_processing/ultra/l1c/ultra_l1c.py +52 -0
  381. imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +54 -0
  382. imap_processing/ultra/lookup_tables/EgyNorm.mem.csv +32769 -0
  383. imap_processing/ultra/lookup_tables/FM45_Startup1_ULTRA_IMGPARAMS_20240719.csv +2 -0
  384. imap_processing/ultra/lookup_tables/ultra45_back-pos-luts.csv +4097 -0
  385. imap_processing/ultra/lookup_tables/ultra45_tdc_norm.csv +2050 -0
  386. imap_processing/ultra/lookup_tables/ultra90_back-pos-luts.csv +4097 -0
  387. imap_processing/ultra/lookup_tables/ultra90_tdc_norm.csv +2050 -0
  388. imap_processing/ultra/lookup_tables/yadjust.csv +257 -0
  389. imap_processing/ultra/packet_definitions/ULTRA_SCI_COMBINED.xml +547 -0
  390. imap_processing/ultra/packet_definitions/__init__.py +0 -0
  391. imap_processing/ultra/utils/__init__.py +0 -0
  392. imap_processing/ultra/utils/ultra_l1_utils.py +50 -0
  393. imap_processing/utils.py +413 -0
  394. imap_processing-0.6.0.dist-info/LICENSE +21 -0
  395. imap_processing-0.6.0.dist-info/METADATA +107 -0
  396. imap_processing-0.6.0.dist-info/RECORD +398 -0
  397. imap_processing-0.6.0.dist-info/WHEEL +4 -0
  398. imap_processing-0.6.0.dist-info/entry_points.txt +4 -0
@@ -0,0 +1 @@
1
+ __version__ = "001"
@@ -0,0 +1,54 @@
1
+ """
2
+ Perform CoDICE L0 processing.
3
+
4
+ This module contains a function to decommutate CoDICE CCSDS packets using
5
+ XTCE packet definitions.
6
+
7
+ For more information on this process and the latest versions of the packet
8
+ definitions, see https://lasp.colorado.edu/galaxy/display/IMAP/CoDICE.
9
+
10
+ Notes
11
+ -----
12
+ from imap_processing.codice.codice_l0 import decom_packets
13
+ packet_file = '/path/to/raw_ccsds_20230822_122700Z_idle.bin'
14
+ packet_list = decom_packets(packet_file)
15
+ """
16
+
17
+ from pathlib import Path
18
+
19
+ import xarray as xr
20
+
21
+ from imap_processing import imap_module_directory
22
+ from imap_processing.utils import packet_file_to_datasets
23
+
24
+
25
+ def decom_packets(packet_file: Path) -> dict[int, xr.Dataset]:
26
+ """
27
+ Decom CoDICE data packets using CoDICE packet definition.
28
+
29
+ Parameters
30
+ ----------
31
+ packet_file : pathlib.Path
32
+ Path to data packet path with filename.
33
+
34
+ Returns
35
+ -------
36
+ datasets : dict[int, xarray.Dataset]
37
+ Mapping from apid to ``xarray`` dataset, one dataset per apid.
38
+ """
39
+ # TODO: Currently need to use the 'old' packet definition for housekeeping
40
+ # because the simulated housekeeping data being used has various
41
+ # mis-matches from the telemetry definition. This may be updated
42
+ # once new simulated housekeeping data are acquired.
43
+ if "hskp" in str(packet_file):
44
+ xtce_filename = "P_COD_NHK.xml"
45
+ else:
46
+ xtce_filename = "codice_packet_definition.xml"
47
+ xtce_packet_definition = Path(
48
+ f"{imap_module_directory}/codice/packet_definitions/{xtce_filename}"
49
+ )
50
+ datasets: dict[int, xr.Dataset] = packet_file_to_datasets(
51
+ packet_file, xtce_packet_definition
52
+ )
53
+
54
+ return datasets
@@ -0,0 +1,558 @@
1
+ """
2
+ Perform CoDICE l1a processing.
3
+
4
+ This module processes decommutated CoDICE packets and creates L1a data products.
5
+
6
+ Notes
7
+ -----
8
+ from imap_processing.codice.codice_l0 import decom_packets
9
+ from imap_processing.codice.codice_l1a import process_codice_l1a
10
+ packets = decom_packets(packet_file)
11
+ dataset = process_codice_l1a(packets)
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import logging
17
+ from pathlib import Path
18
+ from typing import Any
19
+
20
+ import numpy as np
21
+ import pandas as pd
22
+ import xarray as xr
23
+ from numpy.typing import NDArray
24
+
25
+ from imap_processing import imap_module_directory
26
+ from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
27
+ from imap_processing.codice import constants
28
+ from imap_processing.codice.codice_l0 import decom_packets
29
+ from imap_processing.codice.decompress import decompress
30
+ from imap_processing.codice.utils import CODICEAPID
31
+
32
+ logger = logging.getLogger(__name__)
33
+ logger.setLevel(logging.INFO)
34
+
35
+ # TODO: Add support for decomming multiple APIDs from a single file
36
+ # TODO: Determine what should go in event data CDF and how it should be
37
+ # structured.
38
+
39
+
40
+ class CoDICEL1aPipeline:
41
+ """
42
+ Contains methods for processing L0 data and creating L1a data products.
43
+
44
+ Parameters
45
+ ----------
46
+ table_id : int
47
+ A unique ID assigned to a specific table configuration. This field is
48
+ used to link the overall acquisition and processing settings to a
49
+ specific table configuration.
50
+ plan_id : int
51
+ The plan table that was in use. In conjunction with ``plan_step``,
52
+ describes which counters are included in the data packet.
53
+ plan_step : int
54
+ Plan step that was active when the data was acquired and processed. In
55
+ conjunction with ``plan_id``, describes which counters are included
56
+ in the data packet.
57
+ view_id : int
58
+ Provides information about how data was collapsed and/or compressed.
59
+
60
+ Methods
61
+ -------
62
+ decompress_data(science_values)
63
+ Perform decompression on the data.
64
+ define_coordinates()
65
+ Create ``xr.DataArrays`` for the coords needed in the final dataset.
66
+ define_data_variables()
67
+ Define and add the appropriate data variables to the dataset.
68
+ define_dimensions()
69
+ Define the dimensions of the data arrays for the final dataset.
70
+ define_support_variables()
71
+ Define and add 'support' CDF data variables to the dataset.
72
+ get_acquisition_times()
73
+ Retrieve the acquisition times via the Lo stepping table.
74
+ get_energy_table()
75
+ Retrieve the ESA sweep values.
76
+ reshape_data()
77
+ Reshape the data arrays based on the data product being made.
78
+ set_data_product_config()
79
+ Set the various settings for defining the data products.
80
+ """
81
+
82
+ def __init__(self, table_id: int, plan_id: int, plan_step: int, view_id: int):
83
+ """Initialize a ``CoDICEL1aPipeline`` class instance."""
84
+ self.table_id = table_id
85
+ self.plan_id = plan_id
86
+ self.plan_step = plan_step
87
+ self.view_id = view_id
88
+
89
+ def decompress_data(self, science_values: str) -> None:
90
+ """
91
+ Perform decompression on the data.
92
+
93
+ The science data within the packet is a compressed, binary string of
94
+ values. Apply the appropriate decompression algorithm to get an array
95
+ of decompressed values.
96
+
97
+ Parameters
98
+ ----------
99
+ science_values : str
100
+ A string of binary data representing the science values of the data.
101
+ """
102
+ compression_algorithm = constants.LO_COMPRESSION_ID_LOOKUP[self.view_id]
103
+
104
+ # Decompress the binary string into a list of integers
105
+ self.data = decompress(science_values, compression_algorithm)
106
+
107
+ def define_coordinates(self) -> None:
108
+ """
109
+ Create ``xr.DataArrays`` for the coords needed in the final dataset.
110
+
111
+ The coordinates for the dataset depend on the data product being made.
112
+ """
113
+ self.coords = {}
114
+
115
+ for name in self.config["coords"]:
116
+ if name == "epoch":
117
+ values = self.packet_dataset.epoch
118
+ elif name == "inst_az":
119
+ values = np.arange(self.config["num_positions"])
120
+ elif name == "spin_sector":
121
+ values = np.arange(self.config["num_spin_sectors"])
122
+ elif name == "esa_step":
123
+ values = np.arange(self.config["num_energy_steps"])
124
+ else:
125
+ # TODO: Need to implement other types of coords
126
+ continue
127
+
128
+ coord = xr.DataArray(
129
+ values,
130
+ name=name,
131
+ dims=[name],
132
+ attrs=self.cdf_attrs.get_variable_attributes(name),
133
+ )
134
+
135
+ self.coords[name] = coord
136
+
137
+ def define_data_variables(self) -> xr.Dataset:
138
+ """
139
+ Define and add the appropriate data variables to the dataset.
140
+
141
+ The data variables included in the dataset depend on the data product
142
+ being made. The method returns the ``xarray.Dataset`` object that can
143
+ then be written to a CDF file.
144
+
145
+ Returns
146
+ -------
147
+ dataset : xarray.Dataset
148
+ The 'final' ``xarray`` dataset.
149
+ """
150
+ # Create the main dataset to hold all the variables
151
+ dataset = xr.Dataset(
152
+ coords=self.coords,
153
+ attrs=self.cdf_attrs.get_global_attributes(self.config["dataset_name"]),
154
+ )
155
+
156
+ # Create a data variable for each counter
157
+ for variable_data, variable_name in zip(
158
+ self.data, self.config["variable_names"]
159
+ ):
160
+ # Reshape to 4 dimensions to allow for epoch dimension
161
+ reshaped_variable_data = np.expand_dims(variable_data, axis=0)
162
+
163
+ # Get the CDF attributes
164
+ descriptor = self.config["dataset_name"].split("imap_codice_l1a_")[-1]
165
+ cdf_attrs_key = f"{descriptor}-{variable_name}"
166
+ attrs = self.cdf_attrs.get_variable_attributes(cdf_attrs_key)
167
+
168
+ # Create the CDF data variable
169
+ dataset[variable_name] = xr.DataArray(
170
+ reshaped_variable_data,
171
+ name=variable_name,
172
+ dims=self.config["dims"],
173
+ attrs=attrs,
174
+ )
175
+
176
+ # Add support data variables based on data product
177
+ dataset = self.define_support_variables(dataset)
178
+
179
+ return dataset
180
+
181
+ def define_support_variables(self, dataset: xr.Dataset) -> xr.Dataset:
182
+ """
183
+ Define and add 'support' CDF data variables to the dataset.
184
+
185
+ These variables include instrument metadata, energies, times, etc. that
186
+ help further define the L1a CDF data product. The variables included
187
+ depend on the data product being made.
188
+
189
+ Parameters
190
+ ----------
191
+ dataset : xarray.Dataset
192
+ ``xarray`` dataset for the data product.
193
+
194
+ Returns
195
+ -------
196
+ dataset : xarray.Dataset
197
+ ``xarray`` dataset for the data product, with added support variables.
198
+ """
199
+ for variable_name in self.config["support_variables"]:
200
+ if variable_name == "energy_table":
201
+ variable_data = self.get_energy_table()
202
+ dims = ["esa_step"]
203
+ attrs = self.cdf_attrs.get_variable_attributes("esa_step")
204
+
205
+ elif variable_name == "acquisition_time_per_step":
206
+ variable_data = self.get_acquisition_times()
207
+ dims = ["esa_step"]
208
+ attrs = self.cdf_attrs.get_variable_attributes(
209
+ "acquisition_time_per_step"
210
+ )
211
+
212
+ else:
213
+ # TODO: Need to implement methods to gather and set other
214
+ # support attributes
215
+ continue
216
+
217
+ # Add variable to the dataset
218
+ dataset[variable_name] = xr.DataArray(
219
+ variable_data,
220
+ dims=dims,
221
+ attrs=attrs,
222
+ )
223
+
224
+ return dataset
225
+
226
+ def get_acquisition_times(self) -> list[float]:
227
+ """
228
+ Retrieve the acquisition times via the Lo stepping table.
229
+
230
+ Get the acquisition times from the data file based on the values of
231
+ ``plan_id`` and ``plan_step``
232
+
233
+ The Lo stepping table defines how many voltage steps and which steps are
234
+ used during each spacecraft spin. A full cycle takes 16 spins. The table
235
+ provides the timing for a given energy step, and most importantly
236
+ provides the "acquisition time", which is the acquisition time, in
237
+ milliseconds, for the energy step.
238
+
239
+ Returns
240
+ -------
241
+ acquisition_times : list[float]
242
+ The list of acquisition times from the Lo stepping table.
243
+ """
244
+ # Read in the Lo stepping data table
245
+ lo_stepping_data_file = Path(
246
+ f"{imap_module_directory}/codice/data/lo_stepping_values.csv"
247
+ )
248
+ lo_stepping_data = pd.read_csv(lo_stepping_data_file)
249
+
250
+ # Determine which Lo stepping table is needed
251
+ lo_stepping_table_id = constants.LO_STEPPING_TABLE_ID_LOOKUP[
252
+ (self.plan_id, self.plan_step)
253
+ ]
254
+
255
+ # Get the appropriate values
256
+ lo_stepping_values = lo_stepping_data[
257
+ lo_stepping_data["table_num"] == lo_stepping_table_id
258
+ ]
259
+
260
+ # Create a list for the acquisition times
261
+ acquisition_times = []
262
+
263
+ # Only need the energy columns from the table
264
+ energy_steps = lo_stepping_values[
265
+ ["e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8"]
266
+ ].astype(str) # convert to string to avoid confusion with table index value
267
+
268
+ # For each energy step (0-127), scan the energy columns and find the row
269
+ # number, which corresponds to a specific acquisition time, then append
270
+ # it to the list
271
+ for step_number in range(128):
272
+ row_number = np.argmax(energy_steps == str(step_number), axis=1).argmax()
273
+ acquisition_times.append(lo_stepping_values.acq_time[row_number])
274
+
275
+ return acquisition_times
276
+
277
+ def get_energy_table(self) -> NDArray[float]:
278
+ """
279
+ Retrieve the ESA sweep values.
280
+
281
+ Get the ElectroStatic Analyzer (ESA) sweep values from the data file
282
+ based on the values of ``plan_id`` and ``plan_step``
283
+
284
+ CoDICE-Lo measures ions between ~0.5 and 80 keV/q that enter the
285
+ aperture and are selected and focused according to their E/q into the
286
+ Time of Flight (TOF) assembly. The E/q sweeping steps up to the max
287
+ voltage for the next stepping cycle when solar wind count rate exceed a
288
+ predefined threshold rate.
289
+
290
+ The ESA sweep table defines the voltage steps that are used to cover the
291
+ full energy per charge range.
292
+
293
+ Returns
294
+ -------
295
+ energy_table : NDArray[float]
296
+ The list of ESA sweep values (i.e. voltage steps).
297
+ """
298
+ # Read in the ESA sweep data table
299
+ esa_sweep_data_file = Path(
300
+ f"{imap_module_directory}/codice/data/esa_sweep_values.csv"
301
+ )
302
+ sweep_data = pd.read_csv(esa_sweep_data_file)
303
+
304
+ # Determine which ESA sweep table is needed
305
+ sweep_table_id = constants.ESA_SWEEP_TABLE_ID_LOOKUP[
306
+ (self.plan_id, self.plan_step)
307
+ ]
308
+
309
+ # Get the appropriate values
310
+ sweep_table = sweep_data[sweep_data["table_idx"] == sweep_table_id]
311
+ energy_table: NDArray[float] = sweep_table["esa_v"].values
312
+
313
+ return energy_table
314
+
315
+ def reshape_data(self) -> None:
316
+ """
317
+ Reshape the data arrays based on the data product being made.
318
+
319
+ These data need to be divided up by species or priorities (or
320
+ what I am calling "counters" as a general term), and re-arranged into
321
+ 3D arrays representing dimensions such as spin sectors, positions, and
322
+ energies (depending on the data product).
323
+ """
324
+ # For CoDICE-lo, data are a 3D arrays with a shape representing
325
+ # [<num_positions>,<num_spin_sectors>,<num_energy_steps>]
326
+ if self.config["instrument"] == "lo":
327
+ self.data = np.array(self.data, dtype=np.uint32).reshape(
328
+ (
329
+ self.config["num_counters"],
330
+ self.config["num_positions"],
331
+ self.config["num_spin_sectors"],
332
+ self.config["num_energy_steps"],
333
+ )
334
+ )
335
+
336
+ # For CoDICE-hi, data are a 3D array with a shape representing
337
+ # [<num_energy_steps>,<num_positions>,<num_spin_sectors>]
338
+ elif self.config["instrument"] == "hi":
339
+ self.data = np.array(self.data, dtype=np.uint32).reshape(
340
+ (
341
+ self.config["num_counters"],
342
+ self.config["num_energy_steps"],
343
+ self.config["num_positions"],
344
+ self.config["num_spin_sectors"],
345
+ )
346
+ )
347
+
348
+ def set_data_product_config(
349
+ self, apid: int, packet: xr.Dataset, data_version: str
350
+ ) -> None:
351
+ """
352
+ Set the various settings for defining the data products.
353
+
354
+ Parameters
355
+ ----------
356
+ apid : int
357
+ The APID of interest.
358
+ packet : xarray.Dataset
359
+ A packet for the APID of interest.
360
+ data_version : str
361
+ Version of the data product being created.
362
+ """
363
+ # Set the packet dataset so that it can be easily called from various
364
+ # methods
365
+ self.packet_dataset = packet
366
+
367
+ # Set various configurations of the data product
368
+ self.config: dict[str, Any] = constants.DATA_PRODUCT_CONFIGURATIONS.get(apid) # type: ignore
369
+
370
+ # Gather and set the CDF attributes
371
+ self.cdf_attrs = ImapCdfAttributes()
372
+ self.cdf_attrs.add_instrument_global_attrs("codice")
373
+ self.cdf_attrs.add_instrument_variable_attrs("codice", "l1a")
374
+ self.cdf_attrs.add_global_attribute("Data_version", data_version)
375
+
376
+
377
+ def create_event_dataset(
378
+ apid: int, packet: xr.Dataset, data_version: str
379
+ ) -> xr.Dataset:
380
+ """
381
+ Create dataset for event data.
382
+
383
+ Parameters
384
+ ----------
385
+ apid : int
386
+ The APID of the packet.
387
+ packet : xarray.Dataset
388
+ The packet to process.
389
+ data_version : str
390
+ Version of the data product being created.
391
+
392
+ Returns
393
+ -------
394
+ dataset : xarray.Dataset
395
+ Xarray dataset containing the event data.
396
+ """
397
+ if apid == CODICEAPID.COD_LO_PHA:
398
+ dataset_name = "imap_codice_l1a_lo-pha"
399
+ elif apid == CODICEAPID.COD_HI_PHA:
400
+ dataset_name = "imap_codice_l1a_hi-pha"
401
+
402
+ # Extract the data
403
+ # event_data = packet.event_data.data (Currently turned off, see TODO)
404
+
405
+ cdf_attrs = ImapCdfAttributes()
406
+ cdf_attrs.add_instrument_global_attrs("codice")
407
+ cdf_attrs.add_instrument_variable_attrs("codice", "l1a")
408
+ cdf_attrs.add_global_attribute("Data_version", data_version)
409
+
410
+ # Define coordinates
411
+ epoch = xr.DataArray(
412
+ packet.epoch,
413
+ name="epoch",
414
+ dims=["epoch"],
415
+ attrs=cdf_attrs.get_variable_attributes("epoch"),
416
+ )
417
+
418
+ # Create the dataset to hold the data variables
419
+ dataset = xr.Dataset(
420
+ coords={
421
+ "epoch": epoch,
422
+ },
423
+ attrs=cdf_attrs.get_global_attributes(dataset_name),
424
+ )
425
+
426
+ return dataset
427
+
428
+
429
+ def create_hskp_dataset(
430
+ packet: xr.Dataset,
431
+ data_version: str,
432
+ ) -> xr.Dataset:
433
+ """
434
+ Create dataset for each metadata field for housekeeping data.
435
+
436
+ Parameters
437
+ ----------
438
+ packet : xarray.Dataset
439
+ The packet to process.
440
+ data_version : str
441
+ Version of the data product being created.
442
+
443
+ Returns
444
+ -------
445
+ dataset : xarray.Dataset
446
+ Xarray dataset containing the metadata.
447
+ """
448
+ cdf_attrs = ImapCdfAttributes()
449
+ cdf_attrs.add_instrument_global_attrs("codice")
450
+ cdf_attrs.add_instrument_variable_attrs("codice", "l1a")
451
+ cdf_attrs.add_global_attribute("Data_version", data_version)
452
+
453
+ epoch = xr.DataArray(
454
+ packet.epoch,
455
+ name="epoch",
456
+ dims=["epoch"],
457
+ attrs=cdf_attrs.get_variable_attributes("epoch"),
458
+ )
459
+
460
+ dataset = xr.Dataset(
461
+ coords={"epoch": epoch},
462
+ attrs=cdf_attrs.get_global_attributes("imap_codice_l1a_hskp"),
463
+ )
464
+
465
+ for variable in packet:
466
+ attrs = cdf_attrs.get_variable_attributes(variable)
467
+
468
+ dataset[variable] = xr.DataArray(
469
+ packet[variable].data, dims=["epoch"], attrs=attrs
470
+ )
471
+
472
+ return dataset
473
+
474
+
475
+ def get_params(packet: xr.Dataset) -> tuple[int, int, int, int]:
476
+ """
477
+ Return the four 'main' parameters used for l1a processing.
478
+
479
+ The combination of these parameters largely determines what steps/values
480
+ are used to create CoDICE L1a data products and what steps are needed in
481
+ the pipeline algorithm.
482
+
483
+ Parameters
484
+ ----------
485
+ packet : xarray.Dataset
486
+ A packet for the APID of interest.
487
+
488
+ Returns
489
+ -------
490
+ table_id : int
491
+ A unique ID assigned to a specific table configuration. This field is
492
+ used to link the overall acquisition and processing settings to a
493
+ specific table configuration.
494
+ plan_id : int
495
+ The plan table that was in use. In conjunction with ``plan_step``,
496
+ describes which counters are included in the data packet.
497
+ plan_step : int
498
+ Plan step that was active when the data was acquired and processed. In
499
+ conjunction with ``plan_id``, describes which counters are included
500
+ in the data packet.
501
+ view_id : int
502
+ Provides information about how data was collapsed and/or compressed.
503
+ """
504
+ table_id = int(packet.table_id.data)
505
+ plan_id = int(packet.plan_id.data)
506
+ plan_step = int(packet.plan_step.data)
507
+ view_id = int(packet.view_id.data)
508
+
509
+ return table_id, plan_id, plan_step, view_id
510
+
511
+
512
+ def process_codice_l1a(file_path: Path, data_version: str) -> xr.Dataset:
513
+ """
514
+ Will process CoDICE l0 data to create l1a data products.
515
+
516
+ Parameters
517
+ ----------
518
+ file_path : pathlib.Path | str
519
+ Path to the CoDICE L0 file to process.
520
+ data_version : str
521
+ Version of the data product being created.
522
+
523
+ Returns
524
+ -------
525
+ dataset : xarray.Dataset
526
+ The ``xarray`` dataset containing the science data and supporting metadata.
527
+ """
528
+ # Decom the packets, group data by APID, and sort by time
529
+ datasets = decom_packets(file_path)
530
+
531
+ for apid in datasets:
532
+ packet_dataset = datasets[apid]
533
+ logger.info(f"\nProcessing {CODICEAPID(apid).name} packet")
534
+
535
+ if apid == CODICEAPID.COD_NHK:
536
+ dataset = create_hskp_dataset(packet_dataset, data_version)
537
+
538
+ elif apid in [CODICEAPID.COD_LO_PHA, CODICEAPID.COD_HI_PHA]:
539
+ dataset = create_event_dataset(apid, packet_dataset, data_version)
540
+
541
+ elif apid in constants.APIDS_FOR_SCIENCE_PROCESSING:
542
+ # Extract the data
543
+ science_values = packet_dataset.data.data[0]
544
+
545
+ # Get the four "main" parameters for processing
546
+ table_id, plan_id, plan_step, view_id = get_params(packet_dataset)
547
+
548
+ # Run the pipeline to create a dataset for the product
549
+ pipeline = CoDICEL1aPipeline(table_id, plan_id, plan_step, view_id)
550
+ pipeline.set_data_product_config(apid, packet_dataset, data_version)
551
+ pipeline.decompress_data(science_values)
552
+ pipeline.reshape_data()
553
+ pipeline.define_coordinates()
554
+ dataset = pipeline.define_data_variables()
555
+
556
+ logger.info(f"\nFinal data product:\n{dataset}\n")
557
+
558
+ return dataset