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,342 @@
1
+ """Tests Extended Raw Events for ULTRA L1b."""
2
+
3
+ import numpy as np
4
+ import pandas as pd
5
+ import pytest
6
+
7
+ from imap_processing.ultra.l1b.ultra_l1b_extended import (
8
+ CoinType,
9
+ StartType,
10
+ StopType,
11
+ calculate_etof_xc,
12
+ determine_species_pulse_height,
13
+ determine_species_ssd,
14
+ get_coincidence_positions,
15
+ get_ctof,
16
+ get_energy_pulse_height,
17
+ get_energy_ssd,
18
+ get_front_x_position,
19
+ get_front_y_position,
20
+ get_particle_velocity,
21
+ get_path_length,
22
+ get_ph_tof_and_back_positions,
23
+ get_ssd_back_position_and_tof_offset,
24
+ get_ssd_tof,
25
+ )
26
+
27
+
28
+ @pytest.fixture()
29
+ def yf_fixture(de_dataset, events_fsw_comparison_theta_0):
30
+ """Fixture to compute and return yf and related data."""
31
+ df = pd.read_csv(events_fsw_comparison_theta_0)
32
+ df_filt = df[df["StartType"] != -1]
33
+
34
+ d, yf = get_front_y_position(
35
+ de_dataset["START_TYPE"].data, df_filt.Yb.values.astype("float")
36
+ )
37
+
38
+ return df_filt, d, yf
39
+
40
+
41
+ def test_get_front_x_position(
42
+ de_dataset,
43
+ yf_fixture,
44
+ ):
45
+ """Tests get_front_x_position function."""
46
+
47
+ df_filt, _, _ = yf_fixture
48
+
49
+ xf = get_front_x_position(
50
+ de_dataset["START_TYPE"].data,
51
+ de_dataset["START_POS_TDC"].data,
52
+ )
53
+
54
+ assert xf == pytest.approx(df_filt["Xf"].astype("float"), 1e-5)
55
+
56
+
57
+ def test_get_front_y_position(yf_fixture):
58
+ """Tests get_front_y_position function."""
59
+ df_filt, d, yf = yf_fixture
60
+
61
+ assert yf == pytest.approx(df_filt["Yf"].astype("float"), abs=1e-5)
62
+ assert d == pytest.approx(df_filt["d"].astype("float"), abs=1e-5)
63
+
64
+
65
+ def test_get_path_length(de_dataset, yf_fixture):
66
+ """Tests get_path_length function."""
67
+
68
+ df_filt, d, yf = yf_fixture
69
+
70
+ test_xf = df_filt["Xf"].astype("float").values
71
+ test_yf = df_filt["Yf"].astype("float").values
72
+
73
+ test_xb = df_filt["Xb"].astype("float").values
74
+ test_yb = df_filt["Yb"].astype("float").values
75
+ r = get_path_length((test_xf, test_yf), (test_xb, test_yb), d)
76
+ assert r == pytest.approx(df_filt["r"].astype("float"), abs=1e-5)
77
+
78
+
79
+ def test_get_ph_tof_and_back_positions(
80
+ de_dataset,
81
+ yf_fixture,
82
+ ):
83
+ """Tests get_ph_tof_and_back_positions function."""
84
+
85
+ df_filt, _, _ = yf_fixture
86
+
87
+ ph_tof, _, ph_xb, ph_yb = get_ph_tof_and_back_positions(
88
+ de_dataset, df_filt.Xf.astype("float").values, "ultra45"
89
+ )
90
+
91
+ ph_indices = np.nonzero(
92
+ np.isin(de_dataset["STOP_TYPE"], [StopType.Top.value, StopType.Bottom.value])
93
+ )[0]
94
+
95
+ selected_rows = df_filt.iloc[ph_indices]
96
+
97
+ np.testing.assert_array_equal(ph_xb, selected_rows["Xb"].astype("float"))
98
+ np.testing.assert_array_equal(ph_yb, selected_rows["Yb"].astype("float"))
99
+ np.testing.assert_allclose(
100
+ ph_tof, selected_rows["TOF"].astype("float"), atol=1e-5, rtol=0
101
+ )
102
+
103
+
104
+ def test_get_ssd_back_position_and_tof_offset(
105
+ de_dataset,
106
+ events_fsw_comparison_theta_0,
107
+ ):
108
+ """Tests get_ssd_back_position function."""
109
+ yb, tof_offset, ssd_number = get_ssd_back_position_and_tof_offset(de_dataset)
110
+
111
+ df = pd.read_csv(events_fsw_comparison_theta_0)
112
+ df_filt = df[(df["StartType"] != -1) & (df["StopType"] >= 8)]
113
+
114
+ np.testing.assert_array_equal(yb, df_filt["Yb"].astype("float"))
115
+
116
+ tof_offset_lt = tof_offset[df_filt["StartType"] == StartType.Left.value]
117
+ tof_offset_rt = tof_offset[df_filt["StartType"] == StartType.Right.value]
118
+
119
+ ssd_number_lt = ssd_number[df_filt["StartType"] == StartType.Left.value]
120
+ ssd_number_rt = ssd_number[df_filt["StartType"] == StartType.Right.value]
121
+
122
+ np.testing.assert_array_equal(
123
+ tof_offset_lt[ssd_number_lt == 3],
124
+ np.full(len(tof_offset_lt[ssd_number_lt == 3]), -4.2),
125
+ )
126
+ np.testing.assert_array_equal(
127
+ tof_offset_rt[ssd_number_rt == 7],
128
+ np.full(len(tof_offset_rt[ssd_number_rt == 7]), -6),
129
+ )
130
+ np.testing.assert_array_equal(
131
+ tof_offset_rt[ssd_number_rt == 4],
132
+ np.full(len(tof_offset_rt[ssd_number_rt == 4]), -4),
133
+ )
134
+
135
+ assert np.all(ssd_number_lt >= 0), "Values in ssd_number_lt out of range."
136
+
137
+ assert np.all(ssd_number_lt <= 7), "Values in ssd_number_lt out of range."
138
+
139
+ assert np.all(ssd_number_rt >= 0), "Values in ssd_number_rt out of range."
140
+
141
+ assert np.all(ssd_number_rt <= 7), "Values in ssd_number_rt out of range."
142
+
143
+
144
+ def test_get_coincidence_positions(de_dataset, yf_fixture):
145
+ """Tests get_coincidence_positions function."""
146
+ df_filt, _, _ = yf_fixture
147
+ # Get particle tof (t2).
148
+ _, t2, _, _ = get_ph_tof_and_back_positions(
149
+ de_dataset, df_filt.Xf.astype("float").values, "ultra45"
150
+ )
151
+
152
+ # Filter for stop type.
153
+ indices = np.nonzero(
154
+ np.isin(de_dataset["STOP_TYPE"], [StopType.Top.value, StopType.Bottom.value])
155
+ )[0]
156
+ de_filtered = de_dataset.isel(epoch=indices)
157
+ rows = df_filt.iloc[indices]
158
+
159
+ # Get coincidence position and eTOF.
160
+ etof, xc = get_coincidence_positions(de_filtered, t2, "ultra45")
161
+
162
+ np.testing.assert_allclose(xc, rows["Xc"].astype("float"), atol=1e-4, rtol=0)
163
+ np.testing.assert_allclose(
164
+ etof, rows["eTOF"].astype("float").values, rtol=0, atol=1e-06
165
+ )
166
+
167
+
168
+ def test_calculate_etof_xc(de_dataset, yf_fixture):
169
+ """Tests calculate_etof_xc function."""
170
+ df_filt, _, _ = yf_fixture
171
+ # Get particle tof (t2).
172
+ _, t2, _, _ = get_ph_tof_and_back_positions(
173
+ de_dataset, df_filt.Xf.astype("float").values, "ultra45"
174
+ )
175
+ # Filter based on STOP_TYPE.
176
+ indices = np.nonzero(
177
+ np.isin(de_dataset["STOP_TYPE"], [StopType.Top.value, StopType.Bottom.value])
178
+ )[0]
179
+ de_filtered = de_dataset.isel(epoch=indices)
180
+ df_filtered = df_filt.iloc[indices]
181
+
182
+ # Filter for COIN_TYPE Top and Bottom.
183
+ index_top = np.nonzero(np.isin(de_filtered["COIN_TYPE"], CoinType.Top.value))[0]
184
+ de_top = de_filtered.isel(epoch=index_top)
185
+ df_top = df_filtered.iloc[index_top]
186
+
187
+ index_bottom = np.nonzero(np.isin(de_filtered["COIN_TYPE"], CoinType.Bottom.value))[
188
+ 0
189
+ ]
190
+ de_bottom = de_filtered.isel(epoch=index_bottom)
191
+ df_bottom = df_filtered.iloc[index_bottom]
192
+
193
+ # Calculate for Top and Bottom
194
+ etof_top, xc_top = calculate_etof_xc(de_top, t2[index_top], "ultra45", "TP")
195
+ etof_bottom, xc_bottom = calculate_etof_xc(
196
+ de_bottom, t2[index_bottom], "ultra45", "BT"
197
+ )
198
+
199
+ # Assertions for Top
200
+ np.testing.assert_allclose(
201
+ xc_top * 100, df_top["Xc"].astype("float"), atol=1e-4, rtol=0
202
+ )
203
+ np.testing.assert_allclose(
204
+ etof_top, df_top["eTOF"].astype("float").values, atol=1e-06, rtol=0
205
+ )
206
+
207
+ # Assertions for Bottom
208
+ np.testing.assert_allclose(
209
+ xc_bottom * 100, df_bottom["Xc"].astype("float"), atol=1e-4, rtol=0
210
+ )
211
+ np.testing.assert_allclose(
212
+ etof_bottom, df_bottom["eTOF"].astype("float").values, atol=1e-06, rtol=0
213
+ )
214
+
215
+
216
+ def test_get_particle_velocity(de_dataset, yf_fixture):
217
+ """Tests get_particle_velocity function."""
218
+ df_filt, _, _ = yf_fixture
219
+
220
+ ph_indices = np.nonzero(
221
+ np.isin(de_dataset["STOP_TYPE"], [StopType.Top.value, StopType.Bottom.value])
222
+ )[0]
223
+
224
+ ph_rows = df_filt.iloc[ph_indices]
225
+ test_xf = ph_rows["Xf"].astype("float").values
226
+ test_yf = ph_rows["Yf"].astype("float").values
227
+ test_xb = ph_rows["Xb"].astype("float").values
228
+ test_yb = ph_rows["Yb"].astype("float").values
229
+ test_d = ph_rows["d"].astype("float").values
230
+ test_tof = ph_rows["TOF"].astype("float").values
231
+
232
+ vhat_x, vhat_y, vhat_z = get_particle_velocity(
233
+ (test_xf, test_yf),
234
+ (test_xb, test_yb),
235
+ test_d,
236
+ test_tof,
237
+ )
238
+ # FSW test data should be negative and not have an analysis
239
+ # for negative tof values.
240
+ assert vhat_x[test_tof > 0] == pytest.approx(
241
+ -df_filt["vhatX"].iloc[ph_indices].astype("float").values[test_tof > 0],
242
+ rel=1e-2,
243
+ )
244
+ assert vhat_y[test_tof > 0] == pytest.approx(
245
+ -df_filt["vhatY"].iloc[ph_indices].astype("float").values[test_tof > 0],
246
+ rel=1e-2,
247
+ )
248
+ assert vhat_z[test_tof > 0] == pytest.approx(
249
+ -df_filt["vhatZ"].iloc[ph_indices].astype("float").values[test_tof > 0],
250
+ rel=1e-2,
251
+ )
252
+
253
+
254
+ def test_get_ssd_tof(de_dataset, yf_fixture):
255
+ """Tests get_ssd_tof function."""
256
+ df_filt, _, _ = yf_fixture
257
+ df_ssd = df_filt[df_filt["StopType"].isin(StopType.SSD.value)]
258
+ test_xf = df_filt["Xf"].astype("float").values
259
+
260
+ ssd_tof = get_ssd_tof(de_dataset, test_xf)
261
+
262
+ np.testing.assert_allclose(
263
+ ssd_tof, df_ssd["TOF"].astype("float"), atol=1e-05, rtol=0
264
+ )
265
+
266
+
267
+ def test_get_energy_ssd(de_dataset, yf_fixture):
268
+ """Tests get_energy_ssd function."""
269
+ df_filt, _, _ = yf_fixture
270
+ df_ssd = df_filt[df_filt["StopType"].isin(StopType.SSD.value)]
271
+ _, _, ssd_number = get_ssd_back_position_and_tof_offset(de_dataset)
272
+ energy = get_energy_ssd(de_dataset, ssd_number)
273
+ test_energy = df_ssd["Energy"].astype("float")
274
+
275
+ assert np.array_equal(test_energy, energy)
276
+
277
+
278
+ def test_get_energy_pulse_height(de_dataset, yf_fixture):
279
+ """Tests get_energy_ssd function."""
280
+ df_filt, _, _ = yf_fixture
281
+ df_ph = df_filt[df_filt["StopType"].isin(StopType.PH.value)]
282
+ ph_indices = np.nonzero(
283
+ np.isin(de_dataset["STOP_TYPE"], [StopType.Top.value, StopType.Bottom.value])
284
+ )[0]
285
+
286
+ test_xb = df_filt["Xb"].astype("float").values
287
+ test_yb = df_filt["Yb"].astype("float").values
288
+
289
+ energy = get_energy_pulse_height(
290
+ de_dataset["STOP_TYPE"].data, de_dataset["ENERGY_PH"].data, test_xb, test_yb
291
+ )
292
+ test_energy = df_ph["Energy"].astype("float")
293
+
294
+ assert np.array_equal(test_energy, energy[ph_indices])
295
+
296
+
297
+ def test_get_ctof(yf_fixture):
298
+ """Tests get_ctof function."""
299
+ df_filt, _, _ = yf_fixture
300
+
301
+ df_ph_ssd = df_filt[
302
+ df_filt["StopType"].isin([StopType.SSD.value, StopType.PH.value])
303
+ ]
304
+
305
+ ctof = get_ctof(
306
+ df_ph_ssd["TOF"].astype("float").to_numpy(),
307
+ df_ph_ssd["r"].astype("float").to_numpy(),
308
+ )
309
+
310
+ np.testing.assert_allclose(
311
+ ctof, df_ph_ssd["cTOF"].astype("float"), atol=1e-05, rtol=0
312
+ )
313
+
314
+
315
+ def test_determine_species_ph(yf_fixture):
316
+ """Tests determine_species_ph function."""
317
+ df_filt, _, _ = yf_fixture
318
+ df_ph = df_filt[df_filt["StopType"].isin(StopType.PH.value)]
319
+
320
+ bin = determine_species_pulse_height(
321
+ df_ph["Energy"].astype("float").to_numpy(),
322
+ df_ph["TOF"].astype("float").to_numpy(),
323
+ df_ph["r"].astype("float").to_numpy(),
324
+ )
325
+
326
+ # TODO: add in bin values.
327
+ np.testing.assert_allclose(bin, np.zeros(len(bin)), atol=1e-05, rtol=0)
328
+
329
+
330
+ def test_determine_species_ssd(yf_fixture):
331
+ """Tests determine_species_ssd function."""
332
+ df_filt, _, _ = yf_fixture
333
+ df_ssd = df_filt[df_filt["StopType"].isin(StopType.SSD.value)]
334
+
335
+ bin = determine_species_ssd(
336
+ df_ssd["Energy"].astype("float").to_numpy(),
337
+ df_ssd["TOF"].astype("float").to_numpy(),
338
+ df_ssd["r"].astype("float").to_numpy(),
339
+ )
340
+
341
+ # TODO: add in bin values.
342
+ np.testing.assert_allclose(bin, np.zeros(len(bin)), atol=1e-05, rtol=0)
@@ -0,0 +1,104 @@
1
+ import numpy as np
2
+ import pytest
3
+ import xarray as xr
4
+
5
+ from imap_processing.ultra.l1c.ultra_l1c import ultra_l1c
6
+ from imap_processing.ultra.utils.ultra_l1_utils import create_dataset
7
+
8
+
9
+ @pytest.fixture()
10
+ def mock_data_l1b_dict():
11
+ # Create sample data for the xarray Dataset
12
+ epoch = np.arange(
13
+ "2024-02-07T15:28:37", "2024-02-07T15:28:42", dtype="datetime64[s]"
14
+ ).astype("datetime64[ns]")
15
+
16
+ data_vars_histogram = {
17
+ "sid": ("epoch", np.zeros(5)),
18
+ "row": ("epoch", np.zeros(5)),
19
+ "column": ("epoch", np.zeros(5)),
20
+ "shcoarse": ("epoch", np.zeros(5)),
21
+ "spin": ("epoch", np.zeros(5)),
22
+ "packetdata": ("epoch", np.zeros(5)),
23
+ }
24
+
25
+ coords = {"epoch": epoch}
26
+
27
+ attrs_histogram = {
28
+ "Logical_source": "imap_ultra_l1a_45sensor-histogram",
29
+ "Logical_source_description": "IMAP Mission ULTRA Instrument "
30
+ "Level-1A Single-Sensor Data",
31
+ }
32
+
33
+ dataset_histogram = xr.Dataset(
34
+ data_vars=data_vars_histogram, coords=coords, attrs=attrs_histogram
35
+ )
36
+
37
+ data_vars_cullingmask = {
38
+ "spin_number": ("epoch", np.zeros(5)),
39
+ }
40
+
41
+ attrs_cullingmask = {
42
+ "Logical_source": "imap_ultra_l1b_45sensor-cullingmask",
43
+ "Logical_source_description": "IMAP Mission ULTRA Instrument "
44
+ "Level-1B Culling Mask Data",
45
+ }
46
+
47
+ dataset_cullingmask = xr.Dataset(
48
+ data_vars_cullingmask, coords={"epoch": epoch}, attrs=attrs_cullingmask
49
+ )
50
+
51
+ data_dict = {
52
+ "imap_ultra_l1b_45sensor-cullingmask": dataset_cullingmask,
53
+ "imap_ultra_l1a_45sensor-histogram": dataset_histogram,
54
+ }
55
+ return data_dict
56
+
57
+
58
+ @pytest.fixture()
59
+ def mock_data_l1c_dict():
60
+ epoch = np.array(
61
+ [760591786368000000, 760591787368000000, 760591788368000000],
62
+ dtype="datetime64[ns]",
63
+ )
64
+ data_dict = {"epoch": epoch, "sid": np.zeros(3)}
65
+ return data_dict
66
+
67
+
68
+ def test_create_dataset(mock_data_l1c_dict):
69
+ """Tests that dataset is created as expected."""
70
+ dataset = create_dataset(
71
+ mock_data_l1c_dict, "imap_ultra_l1c_45sensor-histogram", "l1c"
72
+ )
73
+
74
+ assert "epoch" in dataset.coords
75
+ assert dataset.coords["epoch"].dtype == "datetime64[ns]"
76
+ assert dataset.attrs["Logical_source"] == "imap_ultra_l1c_45sensor-histogram"
77
+ assert dataset["sid"].attrs["UNITS"] == " "
78
+ np.testing.assert_array_equal(dataset["sid"], np.zeros(3))
79
+
80
+
81
+ def test_ultra_l1c(mock_data_l1b_dict):
82
+ """Tests that L1c data is created."""
83
+ output_datasets = ultra_l1c(mock_data_l1b_dict, data_version="001")
84
+
85
+ assert len(output_datasets) == 1
86
+ assert (
87
+ output_datasets[0].attrs["Logical_source"]
88
+ == "imap_ultra_l1c_45sensor-histogram"
89
+ )
90
+ assert (
91
+ output_datasets[0].attrs["Logical_source_description"]
92
+ == "IMAP-Ultra Instrument Level-1C Pointing Set Grid Histogram Data."
93
+ )
94
+
95
+
96
+ def test_ultra_l1c_error(mock_data_l1b_dict):
97
+ """Tests that L1b data throws an error."""
98
+ mock_data_l1b_dict["bad_key"] = mock_data_l1b_dict.pop(
99
+ "imap_ultra_l1a_45sensor-histogram"
100
+ )
101
+ with pytest.raises(
102
+ ValueError, match="Data dictionary does not contain the expected keys."
103
+ ):
104
+ ultra_l1c(mock_data_l1b_dict, data_version="001")
@@ -0,0 +1,35 @@
1
+ "Tests bins for pointing sets"
2
+
3
+ import numpy as np
4
+
5
+ from imap_processing.ultra.l1c.ultra_l1c_pset_bins import (
6
+ build_energy_bins,
7
+ build_spatial_bins,
8
+ )
9
+
10
+
11
+ def test_build_energy_bins():
12
+ """Tests build_energy_bins function."""
13
+ energy_bin_start, energy_bin_end = build_energy_bins()
14
+
15
+ assert energy_bin_start[0] == 3.5
16
+ assert len(energy_bin_start) == 90
17
+ assert len(energy_bin_end) == 90
18
+
19
+ # Comparison to expected values.
20
+ np.testing.assert_allclose(energy_bin_end[0], 3.6795, atol=1e-4)
21
+ np.testing.assert_allclose(energy_bin_start[-1], 299.9724, atol=1e-4)
22
+ np.testing.assert_allclose(energy_bin_end[-1], 315.3556, atol=1e-4)
23
+
24
+
25
+ def test_build_spatial_bins():
26
+ """Tests build_spatial_bins function."""
27
+ az_bin_edges, el_bin_edges = build_spatial_bins()
28
+
29
+ assert az_bin_edges[0] == 0
30
+ assert az_bin_edges[-1] == 360
31
+ assert len(az_bin_edges) == 721
32
+
33
+ assert el_bin_edges[0] == -90
34
+ assert el_bin_edges[-1] == 90
35
+ assert len(el_bin_edges) == 361
@@ -0,0 +1 @@
1
+ __version__ = "001"
@@ -0,0 +1,60 @@
1
+ """Module for constants and useful shared classes used in Ultra."""
2
+
3
+ from dataclasses import dataclass
4
+
5
+
6
+ @dataclass(frozen=True)
7
+ class UltraConstants:
8
+ """
9
+ Constants for Ultra which can be used across different levels or classes.
10
+
11
+ Attributes
12
+ ----------
13
+ D_SLIT_FOIL: float
14
+ Shortest distance from slit to foil [mm]
15
+ SLIT_Z: float
16
+ Position of slit on Z axis [mm]
17
+ YF_ESTIMATE_LEFT: float
18
+ Front position of particle for left shutter [mm]
19
+ YF_ESTIMATE_RIGHT: float
20
+ Front position of particle for right shutter [mm]
21
+ N_ELEMENTS: int
22
+ Number of elements in lookup table
23
+ TRIG_CONSTANT: float
24
+ Trigonometric constant [mm]
25
+ COMPOSITE_ENERGY_THRESHOLD: int
26
+ DN threshold for composite energy
27
+ Z_DSTOP: float
28
+ Position of stop foil on Z axis [mm]
29
+ Z_DS: float
30
+ Position of slit on Z axis [mm]
31
+ DF: float
32
+ Distance from slit to foil [mm]
33
+ DMIN: float
34
+ Minimum distance between front and back detectors [mm]
35
+ DMIN_SSD_CTOF: float
36
+ SSD-specific correction to DMIN for time-of-flight normalization
37
+ """
38
+
39
+ D_SLIT_FOIL: float = 3.39
40
+ SLIT_Z: float = 44.89
41
+ YF_ESTIMATE_LEFT: float = 40.0
42
+ YF_ESTIMATE_RIGHT: float = -40.0
43
+ N_ELEMENTS: int = 256
44
+ TRIG_CONSTANT: float = 81.92
45
+
46
+ # Composite energy threshold for SSD events
47
+ COMPOSITE_ENERGY_THRESHOLD: int = 1707
48
+
49
+ # Geometry-related constants
50
+ Z_DSTOP: float = 2.6 / 2 # Position of stop foil on Z axis [mm]
51
+ Z_DS: float = 46.19 - (2.6 / 2) # Position of slit on Z axis [mm]
52
+ DF: float = 3.39 # Distance from slit to foil [mm]
53
+
54
+ # Derived constants
55
+ DMIN: float = (
56
+ Z_DS - (2**0.5) * DF
57
+ ) # Minimum distance between front and back detectors [mm]
58
+ DMIN_SSD_CTOF: float = (DMIN**2) / (
59
+ DMIN - Z_DSTOP
60
+ ) # SSD-specific correction to DMIN [mm]
File without changes