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,583 @@
1
+ # ruff: noqa: PLR0913
2
+ """Module for GLOWS L1B data products."""
3
+
4
+ import dataclasses
5
+ import json
6
+ from dataclasses import InitVar, dataclass, field
7
+ from pathlib import Path
8
+ from typing import Optional
9
+
10
+ import numpy as np
11
+
12
+ from imap_processing.glows.utils.constants import TimeTuple
13
+
14
+
15
+ class AncillaryParameters:
16
+ """
17
+ GLOWS L1B Ancillary Parameters for decoding ancillary histogram data points.
18
+
19
+ This class reads from a JSON file input which defines ancillary parameters.
20
+ It validates to ensure the input file has all the required parameters.
21
+
22
+ Parameters
23
+ ----------
24
+ input_table : dict
25
+ Dictionary generated from input JSON file.
26
+
27
+ Attributes
28
+ ----------
29
+ version: str
30
+ version of the ancillary file
31
+ filter_temperature: dict
32
+ dictionary of filter temperature parameters, with keys ["min", "max", "n_bits",
33
+ "p01", "p02", "p03", "p04"]
34
+ hv_voltage: dict
35
+ dictionary of CEM voltage parameters, with keys ["min", "max", "n_bits",
36
+ "p01", "p02", "p03", "p04"]
37
+ spin_period: dict
38
+ dictionary of spin period parameters, with keys ["min", "max", "n_bits"]
39
+ spin_phase: dict
40
+ dictionary of spin phase parameters, with keys ["min", "max", "n_bits"]
41
+ pulse_length: dict
42
+ dictionary of pulse length parameters, with keys ["min", "max", "n_bits",
43
+ "p01", "p02", "p03", "p04"]
44
+ """
45
+
46
+ def __init__(self, input_table: dict):
47
+ """
48
+ Generate ancillary parameters from the given input.
49
+
50
+ Validates parameters and will throw a KeyError if input data is incorrect.
51
+ """
52
+ full_keys = ["min", "max", "n_bits", "p01", "p02", "p03", "p04"]
53
+ spin_keys = ["min", "max", "n_bits"]
54
+
55
+ try:
56
+ self.version = input_table["version"]
57
+ self.filter_temperature = input_table["filter_temperature"]
58
+ if any([key not in full_keys for key in self.filter_temperature.keys()]):
59
+ raise KeyError("Filter temperature parameters are incorrect.")
60
+ self.hv_voltage = input_table["hv_voltage"]
61
+ if any([key not in full_keys for key in self.hv_voltage.keys()]):
62
+ raise KeyError("HV voltage parameters are incorrect.")
63
+ self.spin_period = input_table["spin_period"]
64
+ if any([key not in spin_keys for key in self.spin_period.keys()]):
65
+ raise KeyError("Spin period parameters are incorrect.")
66
+ self.spin_phase = input_table["spin_phase"]
67
+ if any([key not in spin_keys for key in self.spin_phase.keys()]):
68
+ raise KeyError("Spin phase parameters are incorrect.")
69
+ self.pulse_length = input_table["pulse_length"]
70
+ if any([key not in full_keys for key in self.pulse_length.keys()]):
71
+ raise KeyError("Pulse length parameters are incorrect.")
72
+
73
+ except KeyError as e:
74
+ raise KeyError(
75
+ "GLOWS L1B Ancillary input_table does not conform to "
76
+ "expected format."
77
+ ) from e
78
+
79
+ def decode(self, param_key: str, encoded_value: np.double) -> np.double:
80
+ """
81
+ Decode parameters using the algorithm defined in section -.
82
+
83
+ The output parameter T_d is defined as:
84
+ T_d = (T_e - B) / A
85
+
86
+ where T_e is the encoded value and A and B are:
87
+ A = (2^n - 1) / (max - min)
88
+ B = -min * A
89
+
90
+ Max, min, and n are defined in an ancillary data file defined by
91
+ AncillaryParameters.
92
+
93
+ Parameters
94
+ ----------
95
+ param_key : str
96
+ The parameter to use for decoding. Should be one of "filter_temperature",
97
+ "hv_voltage", "spin_period", "spin_phase", or "pulse_length".
98
+ encoded_value : np.double
99
+ The encoded value to decode.
100
+
101
+ Returns
102
+ -------
103
+ decoded_value : np.double
104
+ The decoded value.
105
+ """
106
+ params = getattr(self, param_key)
107
+ # compute parameters a and b:
108
+ param_a = (2 ** params["n_bits"] - 1) / (params["max"] - params["min"])
109
+ param_b = -params["min"] * param_a
110
+
111
+ return np.double((encoded_value - param_b) / param_a)
112
+
113
+ def decode_std_dev(self, param_key: str, encoded_value: np.double) -> np.double:
114
+ """
115
+ Decode an encoded variance variable and compute the standard deviation.
116
+
117
+ The decoded value of encoded_value is given by:
118
+ variance = encoded_value / (param_a**2)
119
+
120
+ where param_a is defined as:
121
+ param_a = (2^n - 1) / (max - min)
122
+
123
+ The standard deviation is then the square root of the variance.
124
+
125
+ Parameters
126
+ ----------
127
+ param_key : str
128
+ The parameter to use for decoding. Should be one of "filter_temperature",
129
+ "hv_voltage", "spin_period", "spin_phase", or "pulse_length".
130
+ encoded_value : np.double
131
+ The encoded variance to decode.
132
+
133
+ Returns
134
+ -------
135
+ std_dev : np.double
136
+ The standard deviation of the encoded value.
137
+ """
138
+ params = getattr(self, param_key)
139
+ # compute parameters a and b:
140
+ param_a = (2 ** params["n_bits"] - 1) / (params["max"] - params["min"])
141
+
142
+ variance = encoded_value / (param_a**2)
143
+
144
+ return np.double(np.sqrt(variance))
145
+
146
+
147
+ @dataclass
148
+ class DirectEventL1B:
149
+ """
150
+ GLOWS L1B direct event data product.
151
+
152
+ This class uses dataclass "InitVar" types which are only used to create the
153
+ output dataclass and not used beyond the __post_init__ function. These attributes
154
+ represent data variables that are present in L1A but not passed on in the same form
155
+ to L1B.
156
+
157
+ Attributes
158
+ ----------
159
+ direct_events: np.ndarray
160
+ 4d array consisting of [seconds, subseconds, pulse_length, is_multi_event],
161
+ which is the DirectEvent structure from L1A. This is used to generate
162
+ direct_event_glows_times and direct_event_pulse_lengths.
163
+ seq_count_in_pkts_file: int
164
+ Sequence count in the input file, passed from L1A
165
+ unique_identifier: str
166
+ YYYY-MM-DDThh:mm:ss based on IMAP UTC time
167
+ number_of_de_packets: InitVar[np.double]
168
+ Number of DE packets in the block, passed in from L1A.
169
+ TODO: Missing from algorithm document, double check that this should be in L1B
170
+ imap_time_last_pps: np.double
171
+ Last PPS in IMAP clock format. Copied from imap_sclk_last_pps in L1A,
172
+ In seconds.
173
+ glows_time_last_pps: np.double
174
+ Last PPS in GLOWS clock format. Creaded from glows_sclk_last_pps and
175
+ glows_ssclk_last_pps in L1A. In seconds, with subseconds as decimal.
176
+ glows_ssclk_last_pps: InitVar[np.double]
177
+ Subseconds of the last PPS in GLOWS clock format. Used to update
178
+ glows_time_last_pps.
179
+ imap_time_next_pps: np.double
180
+ Next PPS in IMAP clock format. Copied from imap_slck_next_pps in L1A.
181
+ In seconds.
182
+ catbed_heater_active: InitVar[np.double]
183
+ Flag for catbed heater
184
+ spin_period_valid: InitVar[np.double]
185
+ Flag for valid spin period
186
+ spin_phase_at_next_pps_valid: InitVar[np.double]
187
+ Flag for valid spin phase at next PPS
188
+ spin_period_source: InitVar[np.double]
189
+ Source of spin period flag
190
+ spin_period: np.double
191
+ Spin period in seconds, decoded from ancillary data
192
+ spin_phase_at_next_pps: np.double
193
+ Spin phase at the next PPS in degrees, decoded from ancillary data
194
+ number_of_completed_spins: int
195
+ Number of completed spins in the block, passed from L1A
196
+ filter_temperature: np.double
197
+ Filter temperature in Celsius degrees, decoded from ancillary data
198
+ hv_voltage: np.double
199
+ CEM voltage in volts, decoded from ancillary data
200
+ glows_time_on_pps_valid: InitVar[np.double]
201
+ Flag for valid GLOWS time on PPS, ends up in flags array
202
+ time_status_valid: InitVar[np.double]
203
+ Flag for valid time status, ends up in flags array
204
+ housekeeping_valid: InitVar[np.double]
205
+ Flag for valid housekeeping, ends up in flags array
206
+ is_pps_autogenerated: InitVar[np.double]
207
+ Flag for autogenerated PPS, ends up in flags array
208
+ hv_test_in_progress: InitVar[np.double]
209
+ Flag for HV test in progress, ends up in flags array
210
+ pulse_test_in_progress: InitVar[np.double]
211
+ Flag for pulse test in progress, ends up in flags array
212
+ memory_error_detected: InitVar[np.double]
213
+ Flag for memory error detected, ends up in flags array
214
+ flags: ndarray
215
+ array of flags for extra information, per histogram. This is assembled from
216
+ L1A variables.
217
+ direct_event_glows_times: ndarray
218
+ array of times for direct events, GLOWS clock, subseconds as decimal part of
219
+ float. From direct_events.
220
+ direct_event_pulse_lengths: ndarray
221
+ array of pulse lengths [μs] for direct events. From direct_events
222
+ """
223
+
224
+ direct_events: InitVar[np.ndarray]
225
+ seq_count_in_pkts_file: np.double # Passed from L1A
226
+ # unique_identifier: str = field(init=False)
227
+ number_of_de_packets: np.double # TODO Is this required in L1B?
228
+ imap_time_last_pps: np.double
229
+ glows_time_last_pps: np.double
230
+ # Added to the end of glows_time_last_pps as subseconds
231
+ glows_ssclk_last_pps: InitVar[int]
232
+ imap_time_next_pps: np.double
233
+ catbed_heater_active: InitVar[np.double]
234
+ spin_period_valid: InitVar[np.double]
235
+ spin_phase_at_next_pps_valid: InitVar[np.double]
236
+ spin_period_source: InitVar[np.double]
237
+ spin_period: np.double
238
+ spin_phase_at_next_pps: np.double
239
+ number_of_completed_spins: np.double
240
+ filter_temperature: np.double
241
+ hv_voltage: np.double
242
+ glows_time_on_pps_valid: InitVar[np.double]
243
+ time_status_valid: InitVar[np.double]
244
+ housekeeping_valid: InitVar[np.double]
245
+ is_pps_autogenerated: InitVar[np.double]
246
+ hv_test_in_progress: InitVar[np.double]
247
+ pulse_test_in_progress: InitVar[np.double]
248
+ memory_error_detected: InitVar[np.double]
249
+
250
+ # pkts_file_name: str # TODO: Add once L1A questions are answered
251
+ # l1a_file_name: str # TODO: Add once L1A questions are answered
252
+ # ancillary_data_files: np.ndarray # TODO: Add once L1A questions are answered
253
+ # The following variables are created from the InitVar data
254
+ de_flags: Optional[np.ndarray] = field(init=False, default=None)
255
+ # TODO: First two values of DE are sec/subsec
256
+ direct_event_glows_times: Optional[np.ndarray] = field(init=False, default=None)
257
+ # 3rd value is pulse length
258
+ direct_event_pulse_lengths: Optional[np.ndarray] = field(init=False, default=None)
259
+ # TODO: where does the multi-event flag go?
260
+
261
+ def __post_init__(
262
+ self,
263
+ direct_events: np.ndarray,
264
+ glows_ssclk_last_pps: int,
265
+ catbed_heater_active: np.double,
266
+ spin_period_valid: np.double,
267
+ spin_phase_at_next_pps_valid: np.double,
268
+ spin_period_source: np.double,
269
+ glows_time_on_pps_valid: np.double,
270
+ time_status_valid: np.double,
271
+ housekeeping_valid: np.double,
272
+ is_pps_autogenerated: np.double,
273
+ hv_test_in_progress: np.double,
274
+ pulse_test_in_progress: np.double,
275
+ memory_error_detected: np.double,
276
+ ) -> None:
277
+ """
278
+ Generate the L1B data for direct events using the inputs from InitVar.
279
+
280
+ Parameters
281
+ ----------
282
+ direct_events : np.ndarray
283
+ Direct events.
284
+ glows_ssclk_last_pps : int
285
+ Glows subsecond clock for the last PPS.
286
+ catbed_heater_active : np.double
287
+ Flag if the catbed heater is active.
288
+ spin_period_valid : np.double
289
+ Valid spin period.
290
+ spin_phase_at_next_pps_valid : np.double
291
+ Flag indicating if the next spin phase is valid.
292
+ spin_period_source : np.double
293
+ Spin period source.
294
+ glows_time_on_pps_valid : np.double
295
+ Flag indicating if the glows time is valid.
296
+ time_status_valid : np.double
297
+ Flag indicating if time status is valid.
298
+ housekeeping_valid : np.double
299
+ Flag indicating if housekeeping is valid.
300
+ is_pps_autogenerated : np.double
301
+ Flag indicating if the PPS is autogenerated.
302
+ hv_test_in_progress : np.double
303
+ Flag indicating if a HV (high voltage) test is in progress.
304
+ pulse_test_in_progress : np.double
305
+ Flag indicating if a pulse test is in progress.
306
+ memory_error_detected : np.double
307
+ Flag indicating if a memory error is detected.
308
+ """
309
+ self.direct_event_glows_times, self.direct_event_pulse_lengths = (
310
+ self.process_direct_events(direct_events)
311
+ )
312
+
313
+ # TODO: double check that this time is in unix time and is the correct variable
314
+ # TODO: This cannot be in the data because it's a string, put it in the
315
+ # attributes
316
+ # self.unique_identifier = np.datetime_as_string(
317
+ # np.datetime64(int(self.imap_time_last_pps), "ns"), "s"
318
+ # )
319
+ self.glows_time_last_pps = TimeTuple(
320
+ int(self.glows_time_last_pps), glows_ssclk_last_pps
321
+ ).to_seconds()
322
+
323
+ with open(
324
+ Path(__file__).parents[1] / "ancillary" / "l1b_conversion_table_v001.json"
325
+ ) as f:
326
+ self.ancillary_parameters = AncillaryParameters(json.loads(f.read()))
327
+
328
+ self.filter_temperature = self.ancillary_parameters.decode(
329
+ "filter_temperature", self.filter_temperature
330
+ )
331
+ self.hv_voltage = self.ancillary_parameters.decode(
332
+ "hv_voltage", self.hv_voltage
333
+ )
334
+ self.spin_period = self.ancillary_parameters.decode(
335
+ "spin_period", self.spin_period
336
+ )
337
+
338
+ self.de_flags = np.array(
339
+ [
340
+ catbed_heater_active,
341
+ spin_period_valid,
342
+ spin_phase_at_next_pps_valid,
343
+ spin_period_source,
344
+ glows_time_on_pps_valid,
345
+ time_status_valid,
346
+ housekeeping_valid,
347
+ is_pps_autogenerated,
348
+ hv_test_in_progress,
349
+ pulse_test_in_progress,
350
+ memory_error_detected,
351
+ ]
352
+ )
353
+
354
+ @staticmethod
355
+ def process_direct_events(direct_events: np.ndarray) -> tuple:
356
+ """
357
+ Will process direct events data, separating out the time flags and pulse length.
358
+
359
+ Parameters
360
+ ----------
361
+ direct_events : np.ndarray
362
+ Direct event data from L1A, with shape (n, 4) where n is the number of
363
+ direct events.
364
+
365
+ Returns
366
+ -------
367
+ (times, pulse_lengths) : tuple
368
+ Tuple of two np.ndarrays, the first being the times of the direct events
369
+ and the second being the pulse lengths. Both of shape (n,).
370
+ """
371
+ times = np.zeros((direct_events.shape[0],))
372
+ pulse_lengths = np.zeros((direct_events.shape[0],))
373
+ for index, de in enumerate(direct_events):
374
+ times[index] = TimeTuple(de[0], de[1]).to_seconds()
375
+ pulse_lengths[index] = de[2]
376
+
377
+ return times, pulse_lengths
378
+
379
+
380
+ @dataclass
381
+ class HistogramL1B:
382
+ """
383
+ GLOWS L1B histogram data product, generated from GLOWS L1A histogram data product.
384
+
385
+ All the spice attributes come from the SPICE kernels and are not initialized.
386
+ Other variables are initialized as their encoded or unprocessed values, and then
387
+ decoded or processed in the __post_init__ method.
388
+
389
+ IMPORTANT: The order of the fields inherited from L1A must match the order of the
390
+ fields in the DataSet created in decom_glows.py.
391
+
392
+ Attributes
393
+ ----------
394
+ histograms
395
+ array of block-accumulated count numbers
396
+ flight_software_version: str
397
+ seq_count_in_pkts_file: int
398
+ last_spin_id: int
399
+ The ID of the previous spin
400
+ flags_set_onboard: int
401
+ is_generated_on_ground: int
402
+ number_of_spins_per_block
403
+ nblock
404
+ unique_block_identifier
405
+ YYYY-MM-DDThh:mm:ss based on IMAP UTC time
406
+ number_of_bins_per_histogram
407
+ nbin
408
+ number_of_events
409
+ total number of events/counts in histogram
410
+ imap_spin_angle_bin_cntr
411
+ IMAP spin angle ψ for bin centers, see Sec. -
412
+ filter_temperature_average
413
+ block-averaged value, decoded to Celsius degrees using Eq. (47)
414
+ filter_temperature_std_dev
415
+ standard deviation (1 sigma), decoded to Celsius degrees using Eq. (51)
416
+ hv_voltage_average
417
+ block-averaged value, decoded to volts using Eq. (47)
418
+ hv_voltage_std_dev
419
+ standard deviation (1 sigma), decoded to volts using Eq. (51)
420
+ spin_period_average
421
+ block-averaged onboard value, decoded to seconds using Eq. (47)
422
+ spin_period_std_dev
423
+ standard deviation (1 sigma), decoded to seconds using Eq. (51)
424
+ pulse_length_average
425
+ block-averaged value, decoded to μs using Eq. (47)
426
+ pulse_length_std_dev
427
+ standard deviation (1 sigma), decoded to μs using Eq. (51)
428
+ glows_start_time
429
+ GLOWS clock, subseconds as decimal part of float, see Sec. -.1
430
+ glows_end_time_offset
431
+ GLOWS clock, subseconds as decimal part of float, see Sec. -.1
432
+ imap_start_time
433
+ IMAP clock, subseconds as decimal part of float, see Sec. -.1
434
+ imap_end_time_offset
435
+ IMAP clock, subseconds as decimal part of float, see Sec. -.1
436
+ histogram_flag_array
437
+ flags for bad-time information per bin, consisting of [is_close_to_uv_source,
438
+ is_inside_excluded_region, is_excluded_by_instr_team, is_suspected_transient]
439
+ spin_period_ground_average
440
+ block-averaged value computed on ground, see Sec. -.1
441
+ spin_period_ground_std_dev
442
+ standard deviation (1 sigma), see Sec. -.1
443
+ position_angle_offset_average
444
+ block-averaged value in degrees, see Sec. - and -.1
445
+ position_angle_offset_std_dev
446
+ standard deviation (1 sigma), see Sec. - and -.1
447
+ spin_axis_orientation_std_dev
448
+ standard deviation( 1 sigma): ∆λ, ∆φ for ⟨λ⟩, ⟨φ⟩
449
+ spin_axis_orientation_average
450
+ block-averaged spin-axis ecliptic longitude ⟨λ⟩ and latitude ⟨φ⟩ in degrees
451
+ spacecraft_location_average
452
+ block-averaged Cartesian ecliptic coordinates ⟨X⟩, ⟨Y ⟩, ⟨Z⟩ [km] of IMAP
453
+ spacecraft_location_std_dev
454
+ standard deviations (1 sigma) ∆X, ∆Y , ∆Z for ⟨X⟩, ⟨Y ⟩, ⟨Z⟩
455
+ spacecraft_velocity_average
456
+ block-averaged values ⟨VX⟩, ⟨VY⟩, ⟨VZ⟩ [km/s] of IMAP velocity components
457
+ (Cartesian ecliptic frame)
458
+ spacecraft_velocity_std_dev
459
+ standard deviations (1 sigma) ∆VX , ∆VY , ∆VZ for ⟨VX ⟩, ⟨VY ⟩, ⟨VZ ⟩
460
+ flags
461
+ flags for extra information, per histogram. This should be a human-readable
462
+ structure.
463
+ """
464
+
465
+ histograms: np.ndarray
466
+ flight_software_version: str
467
+ # pkts_file_name: str TODO: add this in L0
468
+ seq_count_in_pkts_file: int
469
+ # l1a_file_name: str TODO: add this
470
+ # ancillary_data_files: np.ndarray TODO Add this
471
+ last_spin_id: int
472
+ flags_set_onboard: int # TODO: this should be renamed in L1B
473
+ is_generated_on_ground: int
474
+ number_of_spins_per_block: int
475
+ number_of_bins_per_histogram: int
476
+ number_of_events: int
477
+ filter_temperature_average: np.double
478
+ filter_temperature_std_dev: np.double
479
+ hv_voltage_average: np.double
480
+ hv_voltage_std_dev: np.double
481
+ spin_period_average: np.double
482
+ spin_period_std_dev: np.double
483
+ pulse_length_average: np.double
484
+ pulse_length_std_dev: np.double
485
+ imap_start_time: np.double # No conversion needed from l1a->l1b
486
+ imap_end_time_offset: np.double # No conversion needed from l1a->l1b
487
+ glows_start_time: np.double # No conversion needed from l1a->l1b
488
+ glows_end_time_offset: np.double # No conversion needed from l1a->l1b
489
+ # unique_block_identifier: str = field(
490
+ # init=False
491
+ # ) # Could be datetime TODO: Can't put a string in data
492
+ imap_spin_angle_bin_cntr: np.ndarray = field(init=False) # Same size as bins
493
+ histogram_flag_array: np.ndarray = field(init=False)
494
+ spin_period_ground_average: np.double = field(init=False) # retrieved from SPICE?
495
+ spin_period_ground_std_dev: np.double = field(init=False) # retrieved from SPICE?
496
+ position_angle_offset_average: np.double = field(init=False) # retrieved from SPICE
497
+ position_angle_offset_std_dev: np.double = field(init=False) # retrieved from SPICE
498
+ spin_axis_orientation_std_dev: np.double = field(init=False) # retrieved from SPICE
499
+ spin_axis_orientation_average: np.double = field(init=False) # retrieved from SPICE
500
+ spacecraft_location_average: np.ndarray = field(init=False) # retrieved from SPIC
501
+ spacecraft_location_std_dev: np.ndarray = field(init=False) # retrieved from SPIC
502
+ spacecraft_velocity_average: np.ndarray = field(init=False) # retrieved from SPIC
503
+ spacecraft_velocity_std_dev: np.ndarray = field(init=False) # retrieved from SPIC
504
+ flags: np.ndarray = field(init=False)
505
+ # TODO:
506
+ # - Determine a good way to output flags as "human readable"
507
+ # - Add spice pieces
508
+ # - add in the filenames for the input files - should they be global attributes?
509
+ # - also unique identifiers
510
+ # - Bad angle algorithm using SPICE locations
511
+ # - Move ancillary file to AWS
512
+
513
+ def __post_init__(self) -> None:
514
+ """Will process data."""
515
+ # self.histogram_flag_array = np.zeros((2,))
516
+
517
+ # TODO: These pieces will need to be filled in from SPICE kernels. For now,
518
+ # they are placeholders. GLOWS example code has better placeholders if needed.
519
+ self.spin_period_ground_average = np.double(-999.9)
520
+ self.spin_period_ground_std_dev = np.double(-999.9)
521
+ self.position_angle_offset_average = np.double(-999.9)
522
+ self.position_angle_offset_std_dev = np.double(-999.9)
523
+ self.spin_axis_orientation_std_dev = np.double(-999.9)
524
+ self.spin_axis_orientation_average = np.double(-999.9)
525
+ self.spacecraft_location_average = np.array([-999.9, -999.9, -999.9])
526
+ self.spacecraft_location_std_dev = np.array([-999.9, -999.9, -999.9])
527
+ self.spacecraft_velocity_average = np.array([-999.9, -999.9, -999.9])
528
+ self.spacecraft_velocity_std_dev = np.array([-999.9, -999.9, -999.9])
529
+ # Will require some additional inputs
530
+ self.imap_spin_angle_bin_cntr = np.zeros((3600,))
531
+
532
+ # TODO: This should probably be an AWS file
533
+ # TODO Pass in AncillaryParameters object instead of reading here.
534
+ with open(
535
+ Path(__file__).parents[1] / "ancillary" / "l1b_conversion_table_v001.json"
536
+ ) as f:
537
+ self.ancillary_parameters = AncillaryParameters(json.loads(f.read()))
538
+
539
+ self.filter_temperature_average = self.ancillary_parameters.decode(
540
+ "filter_temperature", self.filter_temperature_average
541
+ )
542
+ self.filter_temperature_std_dev = self.ancillary_parameters.decode_std_dev(
543
+ "filter_temperature", self.filter_temperature_std_dev
544
+ )
545
+
546
+ self.hv_voltage_average = self.ancillary_parameters.decode(
547
+ "hv_voltage", self.hv_voltage_average
548
+ )
549
+ self.hv_voltage_std_dev = self.ancillary_parameters.decode_std_dev(
550
+ "hv_voltage", self.hv_voltage_std_dev
551
+ )
552
+ self.spin_period_average = self.ancillary_parameters.decode(
553
+ "spin_period", self.spin_period_average
554
+ )
555
+ self.spin_period_std_dev = self.ancillary_parameters.decode_std_dev(
556
+ "spin_period", self.spin_period_std_dev
557
+ )
558
+ self.pulse_length_average = self.ancillary_parameters.decode(
559
+ "pulse_length", self.pulse_length_average
560
+ )
561
+ self.pulse_length_std_dev = self.ancillary_parameters.decode_std_dev(
562
+ "pulse_length", self.pulse_length_std_dev
563
+ )
564
+
565
+ self.histogram_flag_array = np.zeros((4, 3600))
566
+ # self.unique_block_identifier = np.datetime_as_string(
567
+ # np.datetime64(int(self.imap_start_time), "ns"), "s"
568
+ # )
569
+ self.flags = np.zeros((17, 3600))
570
+
571
+ def output_data(self) -> tuple:
572
+ """
573
+ Output the L1B DataArrays as a tuple.
574
+
575
+ It is faster to return the values like this than to use to_dict() from
576
+ dataclasses.
577
+
578
+ Returns
579
+ -------
580
+ tuple
581
+ A tuple containing each attribute value in the class.
582
+ """
583
+ return tuple(getattr(self, out.name) for out in dataclasses.fields(self))