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,150 @@
1
+ """Processing function for Lo Science Data."""
2
+
3
+ from collections import namedtuple
4
+
5
+ import numpy as np
6
+ import xarray as xr
7
+
8
+ from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
9
+ from imap_processing.lo.l0.utils.bit_decompression import (
10
+ DECOMPRESSION_TABLES,
11
+ Decompress,
12
+ decompress_int,
13
+ )
14
+
15
+ HistPacking = namedtuple(
16
+ "HistPacking",
17
+ [
18
+ "bit_length",
19
+ "section_length",
20
+ "shape", # (azimuth, esa_step)
21
+ ],
22
+ )
23
+
24
+ HIST_DATA_META = {
25
+ # field: bit_length, section_length, shape
26
+ "start_a": HistPacking(12, 504, (6, 7)),
27
+ "start_c": HistPacking(12, 504, (6, 7)),
28
+ "stop_b0": HistPacking(12, 504, (6, 7)),
29
+ "stop_b3": HistPacking(12, 504, (6, 7)),
30
+ "tof0_count": HistPacking(8, 336, (6, 7)),
31
+ "tof1_count": HistPacking(8, 336, (6, 7)),
32
+ "tof2_count": HistPacking(8, 336, (6, 7)),
33
+ "tof3_count": HistPacking(8, 336, (6, 7)),
34
+ "tof0_tof1": HistPacking(8, 3360, (60, 7)),
35
+ "tof0_tof2": HistPacking(8, 3360, (60, 7)),
36
+ "tof1_tof2": HistPacking(8, 3360, (60, 7)),
37
+ "silver": HistPacking(8, 3360, (60, 7)),
38
+ "disc_tof0": HistPacking(8, 336, (6, 7)),
39
+ "disc_tof1": HistPacking(8, 336, (6, 7)),
40
+ "disc_tof2": HistPacking(8, 336, (6, 7)),
41
+ "disc_tof3": HistPacking(8, 336, (6, 7)),
42
+ "pos0": HistPacking(12, 504, (6, 7)),
43
+ "pos1": HistPacking(12, 504, (6, 7)),
44
+ "pos2": HistPacking(12, 504, (6, 7)),
45
+ "pos3": HistPacking(12, 504, (6, 7)),
46
+ "hydrogen": HistPacking(8, 3360, (60, 7)),
47
+ "oxygen": HistPacking(8, 3360, (60, 7)),
48
+ }
49
+
50
+
51
+ def parse_histogram(dataset: xr.Dataset, attr_mgr: ImapCdfAttributes) -> xr.Dataset:
52
+ """
53
+ Parse and decompress binary histogram data for Lo.
54
+
55
+ Parameters
56
+ ----------
57
+ dataset : xr.Dataset
58
+ Lo science counts from packets_to_dataset function.
59
+ attr_mgr : ImapCdfAttributes
60
+ CDF attribute manager for Lo L1A.
61
+
62
+ Returns
63
+ -------
64
+ dataset : xr.Dataset
65
+ Parsed and decompressed histogram data.
66
+ """
67
+ hist_bin = dataset.sci_cnt
68
+
69
+ # initialize the starting bit for the sections of data
70
+ section_start = 0
71
+ # for each field type in the histogram data
72
+ for field in HIST_DATA_META:
73
+ data_meta = HIST_DATA_META[field]
74
+ # for each histogram binary string decompress
75
+ # the data
76
+ decompressed_data = [
77
+ decompress(
78
+ bin_str, data_meta.bit_length, section_start, data_meta.section_length
79
+ )
80
+ for bin_str in hist_bin.values
81
+ ]
82
+
83
+ # add on the epoch length (equal to number of packets) to the
84
+ # field shape
85
+ data_shape = (len(hist_bin), data_meta.shape[0], data_meta.shape[1])
86
+
87
+ # get the dimension names from the CDF attr manager
88
+ dims = [
89
+ value
90
+ for key, value in attr_mgr.get_variable_attributes(field).items()
91
+ if "DEPEND" in key
92
+ ]
93
+ # reshape the decompressed data
94
+ shaped_data = np.array(decompressed_data, dtype=np.uint32).reshape(data_shape)
95
+ # add the data to the dataset
96
+ dataset[field] = xr.DataArray(
97
+ shaped_data, dims=dims, attrs=attr_mgr.get_variable_attributes(field)
98
+ )
99
+
100
+ # increment for the start of the next section
101
+ section_start += data_meta.section_length
102
+
103
+ return dataset
104
+
105
+
106
+ def decompress(
107
+ bin_str: str, bits_per_index: int, section_start: int, section_length: int
108
+ ) -> list[int]:
109
+ """
110
+ Parse and decompress binary histogram data for Lo.
111
+
112
+ Parameters
113
+ ----------
114
+ bin_str : str
115
+ Binary string to decompress.
116
+ bits_per_index : int
117
+ Number of bits per index of the data section.
118
+ section_start : int
119
+ The start bit for the section of data.
120
+ section_length : int
121
+ The length of the section of data.
122
+
123
+ Returns
124
+ -------
125
+ decompressed_ints : list[int]
126
+ Decompressed integers for the data section.
127
+ """
128
+ # select the decompression method based on the bit length
129
+ # of the compressed data
130
+ if bits_per_index == 8:
131
+ decompress = Decompress.DECOMPRESS8TO16
132
+ elif bits_per_index == 12:
133
+ decompress = Decompress.DECOMPRESS12TO16
134
+ else:
135
+ raise ValueError(f"Invalid bits_per_index: {bits_per_index}")
136
+
137
+ # parse the binary and convert to integers
138
+ raw_ints = [
139
+ int(bin_str[i : i + bits_per_index], 2)
140
+ for i in range(section_start, section_start + section_length, bits_per_index)
141
+ ]
142
+
143
+ # decompress raw integers
144
+ decompressed_ints: list[int] = decompress_int(
145
+ raw_ints,
146
+ decompress,
147
+ DECOMPRESSION_TABLES,
148
+ )
149
+
150
+ return decompressed_ints
@@ -0,0 +1,59 @@
1
+ """Class for binary data strings."""
2
+
3
+
4
+ class BinaryString:
5
+ """
6
+ Iterate through a binary string.
7
+
8
+ The binary string class retains the current
9
+ binary string bit position and updates it
10
+ each time the string is accessed.
11
+
12
+ Parameters
13
+ ----------
14
+ bin : str
15
+ Binary string.
16
+
17
+ Attributes
18
+ ----------
19
+ bin : str
20
+ Binary string.
21
+ bit_pos : int
22
+ Current position in the binary string.
23
+
24
+ Methods
25
+ -------
26
+ next_bits(num_bits)
27
+ Returns the next x bits in the binary string
28
+ using the current bit position as the reference point.
29
+ The bit position is updated to be the bit immediately
30
+ following the last returned bit.
31
+ """
32
+
33
+ bin: str
34
+ bit_pos: int
35
+
36
+ def __init__(self, bin: str) -> None:
37
+ self.bin = bin
38
+ self.bit_pos = 0
39
+
40
+ def next_bits(self, num_bits: int) -> str:
41
+ """
42
+ Return the next x bits in the binary string.
43
+
44
+ The bit position updated to be the bit immediately
45
+ following the last returned bit.
46
+
47
+ Parameters
48
+ ----------
49
+ num_bits : int
50
+ The number of bits you want to read off the binary string.
51
+
52
+ Returns
53
+ -------
54
+ bits : str
55
+ A binary string containing the next x bits that were requested.
56
+ """
57
+ bits = self.bin[self.bit_pos : self.bit_pos + num_bits]
58
+ self.bit_pos += num_bits
59
+ return bits
@@ -0,0 +1,62 @@
1
+ """Decompression for 8 to 12, 8 to 16, and 12 to 16 bits."""
2
+
3
+ from enum import Enum
4
+ from pathlib import Path
5
+
6
+ import numpy as np
7
+
8
+
9
+ class Decompress(Enum):
10
+ """The decompression options."""
11
+
12
+ DECOMPRESS8TO12 = "8_to_12"
13
+ DECOMPRESS8TO16 = "8_to_16"
14
+ DECOMPRESS12TO16 = "12_to_16"
15
+
16
+
17
+ # Load all decompression tables into a dictionary.
18
+ DECOMPRESSION_TABLES = {
19
+ enum: np.loadtxt(
20
+ Path(__file__).parent.parent / f"decompression_tables/{enum.value}_bit.csv",
21
+ delimiter=",",
22
+ skiprows=1,
23
+ )
24
+ for enum in Decompress
25
+ }
26
+
27
+
28
+ def decompress_int(
29
+ compressed_values: list, decompression: Decompress, decompression_lookup: dict
30
+ ) -> list[int]:
31
+ # No idea what the correct type is for the return. Mypy says it is Any
32
+ """
33
+ Will decompress a data field using a specified bit conversion.
34
+
35
+ Parameters
36
+ ----------
37
+ compressed_values : list
38
+ Compressed integers.
39
+ decompression : Decompress
40
+ The decompression to use.
41
+ decompression_lookup : dict
42
+ Dictionary containing all the decompression tables.
43
+
44
+ Returns
45
+ -------
46
+ decompressed : list[int]
47
+ The decompressed integer.
48
+ """
49
+ valid_decompression = [
50
+ Decompress.DECOMPRESS8TO12,
51
+ Decompress.DECOMPRESS8TO16,
52
+ Decompress.DECOMPRESS12TO16,
53
+ ]
54
+ if decompression not in valid_decompression:
55
+ raise ValueError(
56
+ "Invalid decompression method. Must be one of the following Enums: "
57
+ + "Decompress.DECOMPRESS8TO12, Decompress.DECOMPRESS8TO12, "
58
+ + "Decompress.DECOMPRESS8TO12"
59
+ )
60
+ data = decompression_lookup[decompression]
61
+ decompressed: list[int] = data[compressed_values, 1]
62
+ return decompressed
@@ -0,0 +1,57 @@
1
+ """General Lo L0 data class used for parsing data and setting attributes."""
2
+
3
+ from dataclasses import dataclass, fields
4
+
5
+ from space_packet_parser.parser import Packet
6
+
7
+ from imap_processing.ccsds.ccsds_data import CcsdsData
8
+
9
+
10
+ @dataclass
11
+ class LoBase:
12
+ """
13
+ Data structure for common values across histogram and direct events data.
14
+
15
+ Attributes
16
+ ----------
17
+ ground_sw_version : str
18
+ Ground software version.
19
+ packet_file_name : str
20
+ File name of the source packet.
21
+ ccsds_header : CcsdsData
22
+ CCSDS header data.
23
+
24
+ Methods
25
+ -------
26
+ parse_data(packet):
27
+ Parse the packet and assign to class variable using the xtce defined named.
28
+ """
29
+
30
+ ground_sw_version: str
31
+ packet_file_name: str
32
+ ccsds_header: CcsdsData
33
+
34
+ def set_attributes(self, packet: Packet) -> None:
35
+ """
36
+ Set dataclass attributes with packet data.
37
+
38
+ Parameters
39
+ ----------
40
+ packet : space_packet_parser.parser.Packet
41
+ A single Lo L0 packet from space packet parser.
42
+ """
43
+ attributes = [field.name for field in fields(self)]
44
+
45
+ # For each item in packet, assign it to the matching attribute in the class.
46
+ for key, item in packet.data.items():
47
+ value = (
48
+ item.derived_value if item.derived_value is not None else item.raw_value
49
+ )
50
+ if "SPARE" in key or "CHKSUM" in key:
51
+ continue
52
+ if key not in attributes:
53
+ raise KeyError(
54
+ f"Did not find matching attribute in {self.__class__} data class"
55
+ f"for {key}"
56
+ )
57
+ setattr(self, key, value)
File without changes
@@ -0,0 +1,157 @@
1
+ """IMAP-Lo L1A Data Processing."""
2
+
3
+ import logging
4
+ from pathlib import Path
5
+
6
+ import numpy as np
7
+ import xarray as xr
8
+
9
+ from imap_processing import imap_module_directory
10
+ from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
11
+ from imap_processing.lo.l0.lo_apid import LoAPID
12
+ from imap_processing.lo.l0.lo_science import parse_histogram
13
+ from imap_processing.utils import packet_file_to_datasets
14
+
15
+ logger = logging.getLogger(__name__)
16
+ logger.setLevel(logging.INFO)
17
+
18
+
19
+ def lo_l1a(dependency: Path, data_version: str) -> list[xr.Dataset]:
20
+ """
21
+ Will process IMAP-Lo L0 data into L1A CDF data products.
22
+
23
+ Parameters
24
+ ----------
25
+ dependency : Path
26
+ Dependency file needed for data product creation.
27
+ Should always be only one for L1A.
28
+ data_version : str
29
+ Version of the data product being created.
30
+
31
+ Returns
32
+ -------
33
+ created_file_paths : list[Path]
34
+ Location of created CDF files.
35
+ """
36
+ xtce_file = imap_module_directory / "lo/packet_definitions/lo_xtce.xml"
37
+
38
+ logger.info("\nDecommutating packets and converting to dataset")
39
+ datasets_by_apid = packet_file_to_datasets(
40
+ packet_file=dependency.resolve(),
41
+ xtce_packet_definition=xtce_file.resolve(),
42
+ use_derived_value=False,
43
+ )
44
+
45
+ # create the attribute manager for this data level
46
+ attr_mgr = ImapCdfAttributes()
47
+ attr_mgr.add_instrument_global_attrs(instrument="lo")
48
+ attr_mgr.add_instrument_variable_attrs(instrument="lo", level="l1a")
49
+ attr_mgr.add_global_attribute("Data_version", data_version)
50
+
51
+ logger.info(
52
+ f"\nProcessing {LoAPID(LoAPID.ILO_SCI_CNT).name} "
53
+ f"packet (APID: {LoAPID.ILO_SCI_CNT.value})"
54
+ )
55
+ if LoAPID.ILO_SCI_CNT in datasets_by_apid:
56
+ logical_source = "imap_lo_l1a_histogram"
57
+ datasets_by_apid[LoAPID.ILO_SCI_CNT] = parse_histogram(
58
+ datasets_by_apid[LoAPID.ILO_SCI_CNT], attr_mgr
59
+ )
60
+ datasets_by_apid[LoAPID.ILO_SCI_CNT] = add_dataset_attrs(
61
+ datasets_by_apid[LoAPID.ILO_SCI_CNT], attr_mgr, logical_source
62
+ )
63
+
64
+ good_apids = [LoAPID.ILO_SCI_CNT]
65
+ logger.info(f"\nReturning datasets: {[LoAPID(apid) for apid in good_apids]}")
66
+ return [datasets_by_apid[good_apid] for good_apid in good_apids]
67
+
68
+
69
+ def add_dataset_attrs(
70
+ dataset: xr.Dataset, attr_mgr: ImapCdfAttributes, logical_source: str
71
+ ) -> xr.Dataset:
72
+ """
73
+ Add Attributes to the dataset.
74
+
75
+ Parameters
76
+ ----------
77
+ dataset : xr.Dataset
78
+ Lo dataset from packets_to_dataset function.
79
+ attr_mgr : ImapCdfAttributes
80
+ CDF attribute manager for Lo L1A.
81
+ logical_source : str
82
+ Logical source for the data.
83
+
84
+ Returns
85
+ -------
86
+ dataset : xr.Dataset
87
+ Data with attributes added.
88
+ """
89
+ # TODO: may want up split up these if statements into their
90
+ # own functions
91
+ if logical_source == "imap_lo_l1a_histogram":
92
+ azimuth_60 = xr.DataArray(
93
+ data=np.arange(0, 6, dtype=np.uint8),
94
+ name="azimuth_60",
95
+ dims=["azimuth_60"],
96
+ attrs=attr_mgr.get_variable_attributes("azimuth_60"),
97
+ )
98
+ azimuth_60_label = xr.DataArray(
99
+ data=azimuth_60.values.astype(str),
100
+ name="azimuth_60_label",
101
+ dims=["azimuth_60_label"],
102
+ attrs=attr_mgr.get_variable_attributes("azimuth_60_label"),
103
+ )
104
+ azimuth_6 = xr.DataArray(
105
+ data=np.arange(0, 60, dtype=np.uint8),
106
+ name="azimuth_6",
107
+ dims=["azimuth_6"],
108
+ attrs=attr_mgr.get_variable_attributes("azimuth_6"),
109
+ )
110
+ azimuth_6_label = xr.DataArray(
111
+ data=azimuth_6.values.astype(str),
112
+ name="azimuth_6_label",
113
+ dims=["azimuth_6_label"],
114
+ attrs=attr_mgr.get_variable_attributes("azimuth_6_label"),
115
+ )
116
+
117
+ esa_step = xr.DataArray(
118
+ data=np.arange(1, 8, dtype=np.uint8),
119
+ name="esa_step",
120
+ dims=["esa_step"],
121
+ attrs=attr_mgr.get_variable_attributes("esa_step"),
122
+ )
123
+ esa_step_label = xr.DataArray(
124
+ esa_step.values.astype(str),
125
+ name="esa_step_label",
126
+ dims=["esa_step_label"],
127
+ attrs=attr_mgr.get_variable_attributes("esa_step_label"),
128
+ )
129
+
130
+ dataset.shcoarse.attrs.update(attr_mgr.get_variable_attributes("shcoarse"))
131
+ dataset.epoch.attrs.update(attr_mgr.get_variable_attributes("epoch"))
132
+
133
+ dataset = dataset.assign_coords(
134
+ azimuth_60=azimuth_60,
135
+ azimuth_60_label=azimuth_60_label,
136
+ azimuth_6=azimuth_6,
137
+ azimuth_6_label=azimuth_6_label,
138
+ esa_step=esa_step,
139
+ esa_step_label=esa_step_label,
140
+ )
141
+ dataset.attrs.update(attr_mgr.get_global_attributes(logical_source))
142
+ # remove the binary field and CCSDS header from the dataset
143
+ dataset = dataset.drop_vars(
144
+ [
145
+ "sci_cnt",
146
+ "chksum",
147
+ "version",
148
+ "type",
149
+ "sec_hdr_flg",
150
+ "pkt_apid",
151
+ "seq_flgs",
152
+ "src_seq_ctr",
153
+ "pkt_len",
154
+ ]
155
+ )
156
+
157
+ return dataset
@@ -0,0 +1,160 @@
1
+ """IMAP-Lo L1B Data Processing."""
2
+
3
+ from collections import namedtuple
4
+ from dataclasses import Field
5
+ from pathlib import Path
6
+
7
+ import numpy as np
8
+ import xarray as xr
9
+
10
+ from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
11
+ from imap_processing.spice.time import met_to_j2000ns
12
+
13
+
14
+ def lo_l1b(dependencies: dict, data_version: str) -> list[Path]:
15
+ """
16
+ Will process IMAP-Lo L1A data into L1B CDF data products.
17
+
18
+ Parameters
19
+ ----------
20
+ dependencies : dict
21
+ Dictionary of datasets needed for L1B data product creation in xarray Datasets.
22
+ data_version : str
23
+ Version of the data product being created.
24
+
25
+ Returns
26
+ -------
27
+ created_file_paths : list[pathlib.Path]
28
+ Location of created CDF files.
29
+ """
30
+ # create the attribute manager for this data level
31
+ attr_mgr = ImapCdfAttributes()
32
+ attr_mgr.add_instrument_global_attrs(instrument="lo")
33
+ attr_mgr.add_instrument_variable_attrs(instrument="lo", level="l1b")
34
+ attr_mgr.add_global_attribute("Data_version", data_version)
35
+
36
+ # if the dependencies are used to create Annotated Direct Events
37
+
38
+ if "imap_lo_l1a_de" in dependencies and "imap_lo_l1a_spin" in dependencies:
39
+ logical_source = "imap_lo_l1b_de"
40
+ # TODO: TEMPORARY. Need to update to use the L1B data class once that exists
41
+ # and I have sample data.
42
+ data_field_tup = namedtuple("data_field_tup", ["name"])
43
+ data_fields = [
44
+ data_field_tup("ESA_STEP"),
45
+ data_field_tup("MODE"),
46
+ data_field_tup("TOF0"),
47
+ data_field_tup("TOF1"),
48
+ data_field_tup("TOF2"),
49
+ data_field_tup("TOF3"),
50
+ data_field_tup("COINCIDENCE_TYPE"),
51
+ data_field_tup("POS"),
52
+ data_field_tup("COINCIDENCE"),
53
+ data_field_tup("BADTIME"),
54
+ data_field_tup("DIRECTION"),
55
+ ]
56
+
57
+ dataset: list[Path] = create_datasets(attr_mgr, logical_source, data_fields) # type: ignore[arg-type]
58
+ # TODO Remove once data_fields is removed from create_datasets
59
+ return dataset
60
+
61
+
62
+ # TODO: This is going to work differently when I sample data.
63
+ # The data_fields input is temporary.
64
+ def create_datasets(
65
+ attr_mgr: ImapCdfAttributes,
66
+ logical_source: str,
67
+ data_fields: list[Field],
68
+ ) -> xr.Dataset:
69
+ """
70
+ Create a dataset using the populated data classes.
71
+
72
+ Parameters
73
+ ----------
74
+ attr_mgr : ImapCdfAttributes
75
+ Attribute manager used to get the data product field's attributes.
76
+ logical_source : str
77
+ The logical source of the data product that's being created.
78
+ data_fields : list[dataclasses.Field]
79
+ List of Fields for data classes.
80
+
81
+ Returns
82
+ -------
83
+ dataset : xarray.Dataset
84
+ Dataset with all data product fields in xr.DataArray.
85
+ """
86
+ # TODO: Once L1B DE processing is implemented using the spin packet
87
+ # and relative L1A DE time to calculate the absolute DE time,
88
+ # this epoch conversion will go away and the time in the DE dataclass
89
+ # can be used direction
90
+ epoch_converted_time = met_to_j2000ns([0, 1, 2])
91
+
92
+ # Create a data array for the epoch time
93
+ # TODO: might need to update the attrs to use new YAML file
94
+ epoch_time = xr.DataArray(
95
+ data=epoch_converted_time,
96
+ name="epoch",
97
+ dims=["epoch"],
98
+ attrs=attr_mgr.get_variable_attributes("epoch"),
99
+ )
100
+
101
+ if logical_source == "imap_lo_l1b_de":
102
+ direction_vec = xr.DataArray(
103
+ data=[0, 1, 2],
104
+ name="direction_vec",
105
+ dims=["direction_vec"],
106
+ attrs=attr_mgr.get_variable_attributes("direction_vec"),
107
+ )
108
+
109
+ direction_vec_label = xr.DataArray(
110
+ data=direction_vec.values.astype(str),
111
+ name="direction_vec_label",
112
+ dims=["direction_vec_label"],
113
+ attrs=attr_mgr.get_variable_attributes("direction_vec_label"),
114
+ )
115
+
116
+ dataset = xr.Dataset(
117
+ coords={
118
+ "epoch": epoch_time,
119
+ "direction_vec": direction_vec,
120
+ "direction_vec_label": direction_vec_label,
121
+ },
122
+ attrs=attr_mgr.get_global_attributes(logical_source),
123
+ )
124
+
125
+ # Loop through the data fields that were pulled from the
126
+ # data class. These should match the field names given
127
+ # to each field in the YAML attribute file
128
+ for data_field in data_fields:
129
+ field = data_field.name.lower()
130
+ # Create a list of all the dimensions using the DEPEND_I keys in the
131
+ # YAML attributes
132
+ dims = [
133
+ value
134
+ for key, value in attr_mgr.get_variable_attributes(field).items()
135
+ if "DEPEND" in key
136
+ ]
137
+
138
+ # Create a data array for the current field and add it to the dataset
139
+ # TODO: TEMPORARY. need to update to use l1a data once that's available.
140
+ # Won't need to check for the direction field when I have sample data either.
141
+ if field == "direction":
142
+ dataset[field] = xr.DataArray(
143
+ [[0, 0, 1], [0, 1, 0], [0, 0, 1]],
144
+ dims=dims,
145
+ attrs=attr_mgr.get_variable_attributes(field),
146
+ )
147
+ # TODO: This is temporary.
148
+ # The data type will be set in the data class when that's created
149
+ elif field in ["tof0", "tof1", "tof2", "tof3"]:
150
+ dataset[field] = xr.DataArray(
151
+ [np.float16(1), np.float16(1), np.float16(1)],
152
+ dims=dims,
153
+ attrs=attr_mgr.get_variable_attributes(field),
154
+ )
155
+ else:
156
+ dataset[field] = xr.DataArray(
157
+ [1, 1, 1], dims=dims, attrs=attr_mgr.get_variable_attributes(field)
158
+ )
159
+
160
+ return dataset