imap-processing 0.9.0__py3-none-any.whl → 0.11.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of imap-processing might be problematic. Click here for more details.

Files changed (243) hide show
  1. imap_processing/_version.py +2 -2
  2. imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +749 -442
  3. imap_processing/cdf/config/imap_glows_global_cdf_attrs.yaml +7 -0
  4. imap_processing/cdf/config/imap_glows_l1a_variable_attrs.yaml +8 -2
  5. imap_processing/cdf/config/imap_glows_l1b_variable_attrs.yaml +0 -1
  6. imap_processing/cdf/config/imap_glows_l2_variable_attrs.yaml +358 -0
  7. imap_processing/cdf/config/imap_hi_variable_attrs.yaml +59 -25
  8. imap_processing/cdf/config/imap_hit_global_cdf_attrs.yaml +22 -0
  9. imap_processing/cdf/config/imap_idex_l1a_variable_attrs.yaml +32 -8
  10. imap_processing/cdf/config/imap_idex_l1b_variable_attrs.yaml +94 -5
  11. imap_processing/cdf/config/imap_lo_l1a_variable_attrs.yaml +65 -37
  12. imap_processing/cdf/config/imap_swapi_variable_attrs.yaml +16 -1
  13. imap_processing/cdf/config/imap_swe_global_cdf_attrs.yaml +7 -0
  14. imap_processing/cdf/config/imap_swe_l1a_variable_attrs.yaml +14 -14
  15. imap_processing/cdf/config/imap_swe_l1b_variable_attrs.yaml +25 -24
  16. imap_processing/cdf/config/imap_swe_l2_variable_attrs.yaml +238 -0
  17. imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +100 -92
  18. imap_processing/cdf/utils.py +2 -2
  19. imap_processing/cli.py +45 -9
  20. imap_processing/codice/codice_l1a.py +104 -58
  21. imap_processing/codice/constants.py +111 -155
  22. imap_processing/codice/data/esa_sweep_values.csv +256 -256
  23. imap_processing/codice/data/lo_stepping_values.csv +128 -128
  24. imap_processing/ena_maps/ena_maps.py +519 -0
  25. imap_processing/ena_maps/utils/map_utils.py +145 -0
  26. imap_processing/ena_maps/utils/spatial_utils.py +226 -0
  27. imap_processing/glows/__init__.py +3 -0
  28. imap_processing/glows/ancillary/imap_glows_pipeline_settings_v001.json +52 -0
  29. imap_processing/glows/l1a/glows_l1a.py +72 -14
  30. imap_processing/glows/l1b/glows_l1b.py +2 -1
  31. imap_processing/glows/l1b/glows_l1b_data.py +25 -1
  32. imap_processing/glows/l2/glows_l2.py +324 -0
  33. imap_processing/glows/l2/glows_l2_data.py +156 -51
  34. imap_processing/hi/l1a/science_direct_event.py +57 -51
  35. imap_processing/hi/l1b/hi_l1b.py +43 -28
  36. imap_processing/hi/l1c/hi_l1c.py +225 -42
  37. imap_processing/hi/utils.py +20 -3
  38. imap_processing/hit/l0/constants.py +2 -2
  39. imap_processing/hit/l0/decom_hit.py +1 -1
  40. imap_processing/hit/l1a/hit_l1a.py +94 -13
  41. imap_processing/hit/l1b/hit_l1b.py +158 -9
  42. imap_processing/ialirt/l0/process_codicehi.py +156 -0
  43. imap_processing/ialirt/l0/process_codicelo.py +5 -2
  44. imap_processing/ialirt/packet_definitions/ialirt.xml +28 -20
  45. imap_processing/ialirt/packet_definitions/ialirt_codicehi.xml +241 -0
  46. imap_processing/ialirt/packet_definitions/ialirt_swapi.xml +170 -0
  47. imap_processing/ialirt/packet_definitions/ialirt_swe.xml +258 -0
  48. imap_processing/ialirt/process_ephemeris.py +72 -40
  49. imap_processing/idex/decode.py +241 -0
  50. imap_processing/idex/idex_l1a.py +143 -81
  51. imap_processing/idex/idex_l1b.py +244 -10
  52. imap_processing/lo/l0/lo_science.py +61 -0
  53. imap_processing/lo/l1a/lo_l1a.py +98 -10
  54. imap_processing/lo/l1b/lo_l1b.py +2 -2
  55. imap_processing/lo/l1c/lo_l1c.py +2 -2
  56. imap_processing/lo/packet_definitions/lo_xtce.xml +1082 -9178
  57. imap_processing/mag/l0/decom_mag.py +2 -2
  58. imap_processing/mag/l1a/mag_l1a.py +7 -7
  59. imap_processing/mag/l1a/mag_l1a_data.py +62 -30
  60. imap_processing/mag/l1b/mag_l1b.py +11 -6
  61. imap_processing/quality_flags.py +18 -3
  62. imap_processing/spice/geometry.py +149 -177
  63. imap_processing/spice/kernels.py +26 -26
  64. imap_processing/spice/spin.py +233 -0
  65. imap_processing/spice/time.py +96 -31
  66. imap_processing/swapi/l1/swapi_l1.py +60 -31
  67. imap_processing/swapi/packet_definitions/swapi_packet_definition.xml +363 -384
  68. imap_processing/swe/l1a/swe_l1a.py +8 -3
  69. imap_processing/swe/l1a/swe_science.py +24 -24
  70. imap_processing/swe/l1b/swe_l1b.py +2 -1
  71. imap_processing/swe/l1b/swe_l1b_science.py +181 -122
  72. imap_processing/swe/l2/swe_l2.py +337 -70
  73. imap_processing/swe/utils/swe_utils.py +28 -0
  74. imap_processing/tests/cdf/test_utils.py +2 -2
  75. imap_processing/tests/codice/conftest.py +20 -17
  76. imap_processing/tests/codice/data/validation/imap_codice_l1a_hskp_20241110193622_v0.0.0.cdf +0 -0
  77. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-counters-aggregated_20241110193700_v0.0.0.cdf +0 -0
  78. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-counters-singles_20241110193700_v0.0.0.cdf +0 -0
  79. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-nsw-angular_20241110193700_v0.0.0.cdf +0 -0
  80. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-nsw-priority_20241110193700_v0.0.0.cdf +0 -0
  81. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-nsw-species_20241110193700_v0.0.0.cdf +0 -0
  82. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-sw-angular_20241110193700_v0.0.0.cdf +0 -0
  83. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-sw-priority_20241110193700_v0.0.0.cdf +0 -0
  84. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-sw-species_20241110193700_v0.0.0.cdf +0 -0
  85. imap_processing/tests/codice/test_codice_l0.py +55 -121
  86. imap_processing/tests/codice/test_codice_l1a.py +147 -59
  87. imap_processing/tests/conftest.py +81 -22
  88. imap_processing/tests/ena_maps/test_ena_maps.py +309 -0
  89. imap_processing/tests/ena_maps/test_map_utils.py +286 -0
  90. imap_processing/tests/ena_maps/test_spatial_utils.py +161 -0
  91. imap_processing/tests/glows/conftest.py +7 -1
  92. imap_processing/tests/glows/test_glows_l1a_cdf.py +3 -7
  93. imap_processing/tests/glows/test_glows_l1a_data.py +34 -6
  94. imap_processing/tests/glows/test_glows_l1b_data.py +29 -17
  95. imap_processing/tests/glows/test_glows_l2.py +101 -0
  96. imap_processing/tests/hi/conftest.py +3 -3
  97. imap_processing/tests/hi/data/l1/imap_hi_l1b_45sensor-de_20250415_v999.cdf +0 -0
  98. imap_processing/tests/hi/data/l1/imap_his_pset-calibration-prod-config_20240101_v001.csv +31 -0
  99. imap_processing/tests/hi/test_hi_l1b.py +14 -9
  100. imap_processing/tests/hi/test_hi_l1c.py +136 -36
  101. imap_processing/tests/hi/test_l1a.py +0 -2
  102. imap_processing/tests/hi/test_science_direct_event.py +18 -14
  103. imap_processing/tests/hi/test_utils.py +16 -11
  104. imap_processing/tests/hit/helpers/__init__.py +0 -0
  105. imap_processing/tests/hit/helpers/l1_validation.py +405 -0
  106. imap_processing/tests/hit/test_data/sci_sample.ccsds +0 -0
  107. imap_processing/tests/hit/test_decom_hit.py +8 -10
  108. imap_processing/tests/hit/test_hit_l1a.py +117 -180
  109. imap_processing/tests/hit/test_hit_l1b.py +149 -55
  110. imap_processing/tests/hit/validation_data/hit_l1b_standard_sample2_nsrl_v4_3decimals.csv +62 -0
  111. imap_processing/tests/hit/validation_data/sci_sample_raw.csv +62 -0
  112. imap_processing/tests/ialirt/test_data/l0/20240827095047_SWE_IALIRT_packet.bin +0 -0
  113. imap_processing/tests/ialirt/test_data/l0/BinLog CCSDS_FRAG_TLM_20240826_152323Z_IALIRT_data_for_SDC.bin +0 -0
  114. imap_processing/tests/ialirt/test_data/l0/eu_SWP_IAL_20240826_152033.csv +644 -0
  115. imap_processing/tests/ialirt/test_data/l0/hi_fsw_view_1_ccsds.bin +0 -0
  116. imap_processing/tests/ialirt/test_data/l0/idle_export_eu.SWE_IALIRT_20240827_093852.csv +914 -0
  117. imap_processing/tests/ialirt/test_data/l0/imap_codice_l1a_hi-ialirt_20240523200000_v0.0.0.cdf +0 -0
  118. imap_processing/tests/ialirt/unit/test_process_codicehi.py +106 -0
  119. imap_processing/tests/ialirt/unit/test_process_ephemeris.py +33 -5
  120. imap_processing/tests/ialirt/unit/test_process_swapi.py +85 -0
  121. imap_processing/tests/ialirt/unit/test_process_swe.py +106 -0
  122. imap_processing/tests/idex/conftest.py +29 -1
  123. imap_processing/tests/idex/test_data/compressed_2023_102_14_24_55.pkts +0 -0
  124. imap_processing/tests/idex/test_data/non_compressed_2023_102_14_22_26.pkts +0 -0
  125. imap_processing/tests/idex/test_idex_l0.py +6 -3
  126. imap_processing/tests/idex/test_idex_l1a.py +151 -1
  127. imap_processing/tests/idex/test_idex_l1b.py +124 -2
  128. imap_processing/tests/lo/test_lo_l1a.py +62 -2
  129. imap_processing/tests/lo/test_lo_science.py +85 -0
  130. imap_processing/tests/lo/validation_data/Instrument_FM1_T104_R129_20240803_ILO_SPIN_EU.csv +2 -0
  131. imap_processing/tests/mag/conftest.py +16 -0
  132. imap_processing/tests/mag/test_mag_decom.py +6 -4
  133. imap_processing/tests/mag/test_mag_l1a.py +36 -7
  134. imap_processing/tests/mag/test_mag_l1b.py +55 -4
  135. imap_processing/tests/mag/test_mag_validation.py +148 -0
  136. imap_processing/tests/mag/validation/L1a/T001/all_p_ones.txt +19200 -0
  137. imap_processing/tests/mag/validation/L1a/T001/mag-l0-l1a-t001-in.bin +0 -0
  138. imap_processing/tests/mag/validation/L1a/T001/mag-l0-l1a-t001-out.csv +17 -0
  139. imap_processing/tests/mag/validation/L1a/T002/all_n_ones.txt +19200 -0
  140. imap_processing/tests/mag/validation/L1a/T002/mag-l0-l1a-t002-in.bin +0 -0
  141. imap_processing/tests/mag/validation/L1a/T002/mag-l0-l1a-t002-out.csv +17 -0
  142. imap_processing/tests/mag/validation/L1a/T003/field_like.txt +19200 -0
  143. imap_processing/tests/mag/validation/L1a/T003/mag-l0-l1a-t003-in.bin +0 -0
  144. imap_processing/tests/mag/validation/L1a/T003/mag-l0-l1a-t003-out.csv +17 -0
  145. imap_processing/tests/mag/validation/L1a/T004/field_like.txt +19200 -0
  146. imap_processing/tests/mag/validation/L1a/T004/mag-l0-l1a-t004-in.bin +0 -0
  147. imap_processing/tests/mag/validation/L1a/T004/mag-l0-l1a-t004-out.csv +17 -0
  148. imap_processing/tests/mag/validation/L1a/T005/field_like_range_change.txt +19200 -0
  149. imap_processing/tests/mag/validation/L1a/T005/mag-l0-l1a-t005-in.bin +0 -0
  150. imap_processing/tests/mag/validation/L1a/T005/mag-l0-l1a-t005-out.csv +17 -0
  151. imap_processing/tests/mag/validation/L1a/T006/hdr_field.txt +19200 -0
  152. imap_processing/tests/mag/validation/L1a/T006/mag-l0-l1a-t006-in.bin +0 -0
  153. imap_processing/tests/mag/validation/L1a/T006/mag-l0-l1a-t006-out.csv +17 -0
  154. imap_processing/tests/mag/validation/L1a/T007/hdr_field_and_range_change.txt +19200 -0
  155. imap_processing/tests/mag/validation/L1a/T007/mag-l0-l1a-t007-in.bin +0 -0
  156. imap_processing/tests/mag/validation/L1a/T007/mag-l0-l1a-t007-out.csv +17 -0
  157. imap_processing/tests/mag/validation/L1a/T008/field_like_range_change.txt +19200 -0
  158. imap_processing/tests/mag/validation/L1a/T008/mag-l0-l1a-t008-in.bin +0 -0
  159. imap_processing/tests/mag/validation/L1a/T008/mag-l0-l1a-t008-out.csv +17 -0
  160. imap_processing/tests/mag/validation/L1b/T009/data.bin +0 -0
  161. imap_processing/tests/mag/validation/L1b/T009/field_like_all_ranges.txt +19200 -0
  162. imap_processing/tests/mag/validation/L1b/T009/mag-l1a-l1b-t009-in.csv +17 -0
  163. imap_processing/tests/mag/validation/L1b/T009/mag-l1a-l1b-t009-magi-out.csv +17 -0
  164. imap_processing/tests/mag/validation/L1b/T009/mag-l1a-l1b-t009-mago-out.csv +17 -0
  165. imap_processing/tests/mag/validation/L1b/T010/data.bin +0 -0
  166. imap_processing/tests/mag/validation/L1b/T010/field_like_all_ranges.txt +19200 -0
  167. imap_processing/tests/mag/validation/L1b/T010/mag-l1a-l1b-t010-in.csv +17 -0
  168. imap_processing/tests/mag/validation/L1b/T010/mag-l1a-l1b-t010-magi-out.csv +17 -0
  169. imap_processing/tests/mag/validation/L1b/T010/mag-l1a-l1b-t010-mago-out.csv +17 -0
  170. imap_processing/tests/mag/validation/L1b/T011/data.bin +0 -0
  171. imap_processing/tests/mag/validation/L1b/T011/field_like_all_ranges.txt +19200 -0
  172. imap_processing/tests/mag/validation/L1b/T011/mag-l1a-l1b-t011-in.csv +17 -0
  173. imap_processing/tests/mag/validation/L1b/T011/mag-l1a-l1b-t011-magi-out.csv +17 -0
  174. imap_processing/tests/mag/validation/L1b/T011/mag-l1a-l1b-t011-mago-out.csv +17 -0
  175. imap_processing/tests/spice/test_geometry.py +128 -133
  176. imap_processing/tests/spice/test_kernels.py +37 -37
  177. imap_processing/tests/spice/test_spin.py +184 -0
  178. imap_processing/tests/spice/test_time.py +43 -20
  179. imap_processing/tests/swapi/test_swapi_l1.py +11 -10
  180. imap_processing/tests/swapi/test_swapi_l2.py +13 -3
  181. imap_processing/tests/swe/test_swe_l1a.py +1 -1
  182. imap_processing/tests/swe/test_swe_l1b.py +20 -3
  183. imap_processing/tests/swe/test_swe_l1b_science.py +54 -35
  184. imap_processing/tests/swe/test_swe_l2.py +148 -5
  185. imap_processing/tests/test_cli.py +39 -7
  186. imap_processing/tests/test_quality_flags.py +19 -19
  187. imap_processing/tests/test_utils.py +3 -2
  188. imap_processing/tests/ultra/test_data/l0/ultra45_raw_sc_ultrarawimg_withFSWcalcs_FM45_40P_Phi28p5_BeamCal_LinearScan_phi2850_theta-000_20240207T102740.csv +3314 -3314
  189. imap_processing/tests/ultra/test_data/mock_data.py +161 -0
  190. imap_processing/tests/ultra/unit/conftest.py +73 -0
  191. imap_processing/tests/ultra/unit/test_badtimes.py +58 -0
  192. imap_processing/tests/ultra/unit/test_cullingmask.py +87 -0
  193. imap_processing/tests/ultra/unit/test_de.py +61 -60
  194. imap_processing/tests/ultra/unit/test_ultra_l1a.py +3 -3
  195. imap_processing/tests/ultra/unit/test_ultra_l1b.py +51 -77
  196. imap_processing/tests/ultra/unit/test_ultra_l1b_annotated.py +5 -5
  197. imap_processing/tests/ultra/unit/test_ultra_l1b_culling.py +114 -0
  198. imap_processing/tests/ultra/unit/test_ultra_l1b_extended.py +86 -26
  199. imap_processing/tests/ultra/unit/test_ultra_l1c.py +1 -1
  200. imap_processing/tests/ultra/unit/test_ultra_l1c_pset_bins.py +3 -3
  201. imap_processing/ultra/constants.py +11 -1
  202. imap_processing/ultra/l1a/ultra_l1a.py +2 -2
  203. imap_processing/ultra/l1b/badtimes.py +22 -5
  204. imap_processing/ultra/l1b/cullingmask.py +31 -5
  205. imap_processing/ultra/l1b/de.py +32 -37
  206. imap_processing/ultra/l1b/extendedspin.py +44 -20
  207. imap_processing/ultra/l1b/ultra_l1b.py +21 -22
  208. imap_processing/ultra/l1b/ultra_l1b_culling.py +190 -0
  209. imap_processing/ultra/l1b/ultra_l1b_extended.py +81 -30
  210. imap_processing/ultra/l1c/histogram.py +6 -2
  211. imap_processing/ultra/l1c/pset.py +6 -2
  212. imap_processing/ultra/l1c/ultra_l1c.py +2 -3
  213. imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +4 -3
  214. imap_processing/ultra/utils/ultra_l1_utils.py +70 -14
  215. imap_processing/utils.py +2 -2
  216. {imap_processing-0.9.0.dist-info → imap_processing-0.11.0.dist-info}/METADATA +7 -2
  217. {imap_processing-0.9.0.dist-info → imap_processing-0.11.0.dist-info}/RECORD +235 -152
  218. imap_processing/tests/codice/data/eu_unit_lookup_table.csv +0 -101
  219. imap_processing/tests/codice/data/idle_export_eu.COD_NHK_20230822_122700 2.csv +0 -100
  220. imap_processing/tests/codice/data/idle_export_raw.COD_NHK_20230822_122700.csv +0 -100
  221. imap_processing/tests/codice/data/imap_codice_l0_raw_20241110_v001.pkts +0 -0
  222. imap_processing/tests/hi/test_data/l1a/imap_hi_l1a_45sensor-de_20250415_v000.cdf +0 -0
  223. imap_processing/tests/hit/test_data/sci_sample1.ccsds +0 -0
  224. imap_processing/tests/ultra/unit/test_spatial_utils.py +0 -125
  225. imap_processing/ultra/utils/spatial_utils.py +0 -221
  226. /imap_processing/tests/hi/{test_data → data}/l0/20231030_H45_APP_NHK.bin +0 -0
  227. /imap_processing/tests/hi/{test_data → data}/l0/20231030_H45_APP_NHK.csv +0 -0
  228. /imap_processing/tests/hi/{test_data → data}/l0/20231030_H45_SCI_CNT.bin +0 -0
  229. /imap_processing/tests/hi/{test_data → data}/l0/20231030_H45_SCI_DE.bin +0 -0
  230. /imap_processing/tests/hi/{test_data → data}/l0/H90_NHK_20241104.bin +0 -0
  231. /imap_processing/tests/hi/{test_data → data}/l0/H90_sci_cnt_20241104.bin +0 -0
  232. /imap_processing/tests/hi/{test_data → data}/l0/H90_sci_de_20241104.bin +0 -0
  233. /imap_processing/tests/hi/{test_data → data}/l0/README.txt +0 -0
  234. /imap_processing/tests/idex/{imap_idex_l0_raw_20231214_v001.pkts → test_data/imap_idex_l0_raw_20231214_v001.pkts} +0 -0
  235. /imap_processing/tests/idex/{impact_14_tof_high_data.txt → test_data/impact_14_tof_high_data.txt} +0 -0
  236. /imap_processing/tests/mag/{imap_mag_l1a_norm-magi_20251017_v001.cdf → validation/imap_mag_l1a_norm-magi_20251017_v001.cdf} +0 -0
  237. /imap_processing/tests/mag/{mag_l0_test_data.pkts → validation/mag_l0_test_data.pkts} +0 -0
  238. /imap_processing/tests/mag/{mag_l0_test_output.csv → validation/mag_l0_test_output.csv} +0 -0
  239. /imap_processing/tests/mag/{mag_l1_test_data.pkts → validation/mag_l1_test_data.pkts} +0 -0
  240. /imap_processing/tests/mag/{mag_l1a_test_output.csv → validation/mag_l1a_test_output.csv} +0 -0
  241. {imap_processing-0.9.0.dist-info → imap_processing-0.11.0.dist-info}/LICENSE +0 -0
  242. {imap_processing-0.9.0.dist-info → imap_processing-0.11.0.dist-info}/WHEEL +0 -0
  243. {imap_processing-0.9.0.dist-info → imap_processing-0.11.0.dist-info}/entry_points.txt +0 -0
@@ -6,6 +6,7 @@ import pytest
6
6
  import xarray as xr
7
7
 
8
8
  from imap_processing import imap_module_directory
9
+ from imap_processing.cdf.utils import write_cdf
9
10
  from imap_processing.swe.l1a.swe_l1a import swe_l1a
10
11
  from imap_processing.swe.l1b.swe_l1b import swe_l1b
11
12
  from imap_processing.swe.l2.swe_l2 import (
@@ -13,7 +14,9 @@ from imap_processing.swe.l2.swe_l2 import (
13
14
  VELOCITY_CONVERSION_FACTOR,
14
15
  calculate_flux,
15
16
  calculate_phase_space_density,
17
+ find_angle_bin_indices,
16
18
  get_particle_energy,
19
+ put_data_into_angle_bins,
17
20
  swe_l2,
18
21
  )
19
22
  from imap_processing.swe.utils.swe_utils import read_lookup_table
@@ -108,18 +111,158 @@ def test_calculate_flux():
108
111
  assert type(flux) == np.ndarray
109
112
 
110
113
 
114
+ def test_find_angle_bin_indices():
115
+ """Test find_angle_bin_indices function."""
116
+ spin_angle_bin_center = np.arange(6, 360, 12)
117
+
118
+ # List with various start, middle, end angles or
119
+ # far left or far right edge angles
120
+ start_angles = [0, 0.11, 3, 6, 11.99, 12, 355]
121
+ expected_angle_bin_indices = np.array([0, 0, 0, 0, 0, 1, 29])
122
+ angle_bin_indices = find_angle_bin_indices(start_angles)
123
+ np.testing.assert_array_equal(angle_bin_indices, expected_angle_bin_indices)
124
+ # Test that angle bin indices lands in correct center bin
125
+ np.testing.assert_array_equal(
126
+ spin_angle_bin_center[angle_bin_indices],
127
+ np.array([6, 6, 6, 6, 6, 18, 354]),
128
+ )
129
+
130
+ # Test for angles that are outside the range
131
+ with pytest.raises(
132
+ ValueError, match=r"Input angle values must be in the range \[0, 360\)"
133
+ ):
134
+ find_angle_bin_indices(np.array([-1]))
135
+
136
+ with pytest.raises(
137
+ ValueError, match=r"Input angle values must be in the range \[0, 360\)"
138
+ ):
139
+ find_angle_bin_indices(np.array([360]))
140
+
141
+
142
+ def test_put_data_into_angle_bins():
143
+ """Test put_data_into_angle_bins function."""
144
+ num_cycles = 1
145
+ num_esa_step = 24
146
+ num_angle_bins = 30
147
+ num_cems = 7
148
+ # Create test counts data to test
149
+ # Find all even numbers in the range 0 to 30
150
+ even_numbers = np.arange(0, 30, 2)
151
+ # repeat it twice now to get:
152
+ # [0, 0, 2, 2, ...., 28, 28]
153
+ example_data = np.repeat(even_numbers, 2)
154
+ energy_angle_test_data = np.tile(example_data, (num_cycles, num_esa_step, 1))
155
+ # Expand to include 7 CEMs by repeating across last dimension
156
+ test_data = np.repeat(energy_angle_test_data[..., np.newaxis], num_cems, axis=-1)
157
+
158
+ # Took this example from intermediate output from actual data
159
+ angle_bins_example = [
160
+ 12,
161
+ 14,
162
+ 14,
163
+ 16,
164
+ 16,
165
+ 18,
166
+ 18,
167
+ 20,
168
+ 20,
169
+ 22,
170
+ 22,
171
+ 24,
172
+ 24,
173
+ 26,
174
+ 26,
175
+ 28,
176
+ 28,
177
+ 0,
178
+ 0,
179
+ 2,
180
+ 2,
181
+ 4,
182
+ 4,
183
+ 6,
184
+ 6,
185
+ 8,
186
+ 8,
187
+ 10,
188
+ 10,
189
+ 12,
190
+ ]
191
+ # Now data with every row to be same as angle_bins_example
192
+ test_angle_bin_indices_data = np.full(
193
+ (num_cycles, num_esa_step, num_angle_bins), angle_bins_example
194
+ )
195
+
196
+ binned_data = put_data_into_angle_bins(test_data, test_angle_bin_indices_data)
197
+ assert binned_data.shape == (num_cycles, num_esa_step, num_angle_bins, num_cems)
198
+
199
+ # Test that the binned data has correct values in correct bins by
200
+ # checking that odd number columns are filled with nan
201
+ expected_binned_data = np.full(
202
+ (num_cycles, num_esa_step, num_angle_bins, num_cems), np.nan
203
+ )
204
+ np.testing.assert_array_equal(
205
+ binned_data[0, 0, 1::2, 0], expected_binned_data[0, 0, 1::2, 0]
206
+ )
207
+
208
+ # Now check that mean calculation is correct
209
+ even_col_mean_data = binned_data[0, 0, 0::2, 0]
210
+ # Expected mean of even columns is below
211
+ expected_mean_data = np.array(
212
+ [
213
+ 17.0,
214
+ 19.0,
215
+ 21.0,
216
+ 23.0,
217
+ 25.0,
218
+ 27.0,
219
+ 14.0,
220
+ 1.0,
221
+ 3.0,
222
+ 5.0,
223
+ 7.0,
224
+ 9.0,
225
+ 11.0,
226
+ 13.0,
227
+ 15.0,
228
+ ]
229
+ )
230
+ np.testing.assert_array_equal(even_col_mean_data, expected_mean_data)
231
+
232
+
233
+ @patch(
234
+ "imap_processing.swe.l1b.swe_l1b_science.read_in_flight_cal_data",
235
+ return_value=pd.DataFrame(
236
+ {
237
+ "met_time": [453050300, 453077900],
238
+ "cem1": [1, 1],
239
+ "cem2": [1, 1],
240
+ "cem3": [1, 1],
241
+ "cem4": [1, 1],
242
+ "cem5": [1, 1],
243
+ "cem6": [1, 1],
244
+ "cem7": [1, 1],
245
+ }
246
+ ),
247
+ )
111
248
  @pytest.mark.usefixtures("use_fake_spin_data_for_time")
112
- def test_swe_l2(use_fake_spin_data_for_time):
249
+ def test_swe_l2(mock_read_in_flight_cal_data, use_fake_spin_data_for_time):
113
250
  """Test L2 processing."""
114
251
  data_start_time = 453051293.099714
115
- data_end_time = 453066734
252
+ data_end_time = 453070000.0
116
253
  use_fake_spin_data_for_time(data_start_time, data_end_time)
117
254
 
118
255
  test_data_path = "tests/swe/l0_data/2024051010_SWE_SCIENCE_packet.bin"
119
256
  l1a_datasets = swe_l1a(imap_module_directory / test_data_path, "002")
120
257
 
121
- l1b_dataset = swe_l1b(l1a_datasets, "002")
122
- l2_dataset = swe_l2(l1b_dataset, "002")
258
+ l1b_dataset = swe_l1b(l1a_datasets[0], "002")
259
+ l2_dataset = swe_l2(l1b_dataset[0], "002")
123
260
 
124
261
  assert type(l2_dataset) == xr.Dataset
125
- assert l2_dataset["spin_phase"].shape == (6, 24, 30, 7)
262
+ assert l2_dataset["phase_space_density_spin_sector"].shape == (6, 24, 30, 7)
263
+ assert l2_dataset["flux_spin_sector"].shape == (6, 24, 30, 7)
264
+ assert l2_dataset["acquisition_time"].shape == (6, 24, 30)
265
+
266
+ # Write L2 to CDF
267
+ l2_cdf_filepath = write_cdf(l2_dataset)
268
+ assert l2_cdf_filepath.name == "imap_swe_l2_sci_20240510_v002.cdf"
@@ -6,7 +6,7 @@ from unittest import mock
6
6
  import pytest
7
7
  import xarray as xr
8
8
 
9
- from imap_processing.cli import Codice, Hi, Hit, Ultra, _validate_args, main
9
+ from imap_processing.cli import Codice, Hi, Hit, Swe, Ultra, _validate_args, main
10
10
 
11
11
 
12
12
  @pytest.fixture()
@@ -101,7 +101,9 @@ def test_codice(mock_codice_l1a, mock_instrument_dependencies):
101
101
  "'start_date': '20230822'"
102
102
  "}]"
103
103
  )
104
- instrument = Codice("l1a", dependency_str, "20230822", "20230822", "v001", True)
104
+ instrument = Codice(
105
+ "l1a", "hskp", dependency_str, "20230822", "20230822", "v001", True
106
+ )
105
107
  instrument.process()
106
108
  assert mocks["mock_query"].call_count == 1
107
109
  assert mocks["mock_download"].call_count == 1
@@ -134,7 +136,7 @@ def test_hi_l1(mock_instrument_dependencies, data_level, n_prods):
134
136
  "}]"
135
137
  )
136
138
  instrument = Hi(
137
- data_level, dependency_str, "20231212", "20231213", "v005", True
139
+ data_level, "sci", dependency_str, "20231212", "20231213", "v005", True
138
140
  )
139
141
  instrument.process()
140
142
  assert mocks["mock_query"].call_count == 1
@@ -161,7 +163,9 @@ def test_ultra_l1a(mock_ultra_l1a, mock_instrument_dependencies):
161
163
  "'start_date': '20240207'"
162
164
  "}]"
163
165
  )
164
- instrument = Ultra("l1a", dependency_str, "20240207", "20240208", "v001", True)
166
+ instrument = Ultra(
167
+ "l1a", "raw", dependency_str, "20240207", "20240208", "v001", True
168
+ )
165
169
  instrument.process()
166
170
  assert mocks["mock_query"].call_count == 1
167
171
  assert mocks["mock_download"].call_count == 1
@@ -178,7 +182,7 @@ def test_ultra_l1b(mock_ultra_l1b, mock_instrument_dependencies):
178
182
  mock_ultra_l1b.return_value = ["l1b_dataset0", "l1b_dataset1"]
179
183
  mocks["mock_write_cdf"].side_effect = ["/path/to/product0", "/path/to/product1"]
180
184
 
181
- instrument = Ultra("l1b", "[]", "20240207", "20240208", "v001", True)
185
+ instrument = Ultra("l1b", "de", "[]", "20240207", "20240208", "v001", True)
182
186
  instrument.process()
183
187
  assert mocks["mock_query"].call_count == 0
184
188
  assert mocks["mock_download"].call_count == 0
@@ -195,7 +199,7 @@ def test_ultra_l1c(mock_ultra_l1c, mock_instrument_dependencies):
195
199
  mock_ultra_l1c.return_value = ["l1c_dataset0", "l1c_dataset1"]
196
200
  mocks["mock_write_cdf"].side_effect = ["/path/to/product0", "/path/to/product1"]
197
201
 
198
- instrument = Ultra("l1c", "[]", "20240207", "20240208", "v001", True)
202
+ instrument = Ultra("l1c", "pset", "[]", "20240207", "20240208", "v001", True)
199
203
  instrument.process()
200
204
  assert mocks["mock_query"].call_count == 0
201
205
  assert mocks["mock_download"].call_count == 0
@@ -221,9 +225,37 @@ def test_hit_l1a(mock_hit_l1a, mock_instrument_dependencies):
221
225
  "'start_date': '20100105'"
222
226
  "}]"
223
227
  )
224
- instrument = Hit("l1a", dependency_str, "20100105", "20100101", "v001", True)
228
+ instrument = Hit("l1a", "raw", dependency_str, "20100105", "20100101", "v001", True)
225
229
  instrument.process()
226
230
  assert mocks["mock_query"].call_count == 1
227
231
  assert mocks["mock_download"].call_count == 1
228
232
  assert mock_hit_l1a.call_count == 1
229
233
  assert mocks["mock_upload"].call_count == 2
234
+
235
+
236
+ @mock.patch("imap_processing.cli.swe_l1a")
237
+ def test_post_processing(mock_swe_l1a, mock_instrument_dependencies):
238
+ """Test coverage for post processing"""
239
+ mocks = mock_instrument_dependencies
240
+ mocks["mock_query"].return_value = [{"file_path": "/path/to/file0"}]
241
+ mocks["mock_download"].return_value = "dependency0"
242
+ # Return empty list to simulate no data to write
243
+ mock_swe_l1a.return_value = []
244
+
245
+ dependency_str = (
246
+ "[{"
247
+ "'instrument': 'hit',"
248
+ "'data_level': 'l0',"
249
+ "'descriptor': 'raw',"
250
+ "'version': 'v001',"
251
+ "'start_date': '20100105'"
252
+ "}]"
253
+ )
254
+ instrument = Swe("l1a", "raw", dependency_str, "20100105", "20100101", "v001", True)
255
+
256
+ # This function calls both the instrument.do_processing() and
257
+ # instrument.post_processing()
258
+ instrument.process()
259
+ assert mock_swe_l1a.call_count == 1
260
+ # This test is testing that no upload happened
261
+ assert mocks["mock_upload"].call_count == 0
@@ -2,7 +2,7 @@
2
2
 
3
3
  import numpy as np
4
4
 
5
- from imap_processing.quality_flags import HitFlags, ImapLoFlags, ImapUltraFlags
5
+ from imap_processing.quality_flags import HitFlags, ImapHkUltraFlags, ImapLoFlags
6
6
 
7
7
 
8
8
  def test_quality_flags():
@@ -10,30 +10,30 @@ def test_quality_flags():
10
10
 
11
11
  # Test individual flags
12
12
  assert HitFlags.NONE == 0x0
13
- assert ImapUltraFlags.NONE == 0x0
13
+ assert ImapHkUltraFlags.NONE == 0x0
14
14
  assert ImapLoFlags.NONE == 0x0
15
15
  assert HitFlags.INF == 2**0
16
- assert ImapUltraFlags.INF == 2**0
16
+ assert ImapHkUltraFlags.INF == 2**0
17
17
  assert ImapLoFlags.INF == 2**0
18
18
  assert HitFlags.NEG == 2**1
19
- assert ImapUltraFlags.NEG == 2**1
19
+ assert ImapHkUltraFlags.NEG == 2**1
20
20
  assert ImapLoFlags.NEG == 2**1
21
- assert ImapUltraFlags.BADSPIN == 2**2
21
+ assert ImapHkUltraFlags.BADSPIN == 2**2
22
22
  assert ImapLoFlags.BADSPIN == 2**2
23
- assert ImapUltraFlags.FLAG1 == 2**3
23
+ assert ImapHkUltraFlags.FLAG1 == 2**3
24
24
  assert ImapLoFlags.FLAG2 == 2**3
25
25
  assert HitFlags.FLAG3 == 2**2
26
26
 
27
27
  # Test combined flags for Ultra
28
28
  flag = (
29
- ImapUltraFlags.INF
30
- | ImapUltraFlags.NEG
31
- | ImapUltraFlags.BADSPIN
32
- | ImapUltraFlags.FLAG1
29
+ ImapHkUltraFlags.INF
30
+ | ImapHkUltraFlags.NEG
31
+ | ImapHkUltraFlags.BADSPIN
32
+ | ImapHkUltraFlags.FLAG1
33
33
  )
34
- assert flag & ImapUltraFlags.INF
35
- assert flag & ImapUltraFlags.BADSPIN
36
- assert flag & ImapUltraFlags.FLAG1
34
+ assert flag & ImapHkUltraFlags.INF
35
+ assert flag & ImapHkUltraFlags.BADSPIN
36
+ assert flag & ImapHkUltraFlags.FLAG1
37
37
  assert flag.name == "INF|NEG|BADSPIN|FLAG1"
38
38
  assert flag.value == 15
39
39
 
@@ -56,16 +56,16 @@ def test_quality_flags():
56
56
  data = np.array([-6, np.inf, 2, 3])
57
57
  quality = np.array(
58
58
  [
59
- ImapUltraFlags.INF | ImapUltraFlags.NEG,
60
- ImapUltraFlags.INF,
61
- ImapUltraFlags.NONE,
62
- ImapUltraFlags.NONE,
59
+ ImapHkUltraFlags.INF | ImapHkUltraFlags.NEG,
60
+ ImapHkUltraFlags.INF,
61
+ ImapHkUltraFlags.NONE,
62
+ ImapHkUltraFlags.NONE,
63
63
  ]
64
64
  )
65
65
  # Select data without INF flags
66
- non_inf_mask = (quality & ImapUltraFlags.INF.value) == 0
66
+ non_inf_mask = (quality & ImapHkUltraFlags.INF.value) == 0
67
67
  np.array_equal(data[non_inf_mask], np.array([-6, 2, 3]))
68
68
 
69
69
  # Select data without NEG or INF flags
70
- non_neg_mask = (quality & ImapUltraFlags.NEG.value) == 0
70
+ non_neg_mask = (quality & ImapHkUltraFlags.NEG.value) == 0
71
71
  np.array_equal(data[non_inf_mask & non_neg_mask], np.array([2, 3]))
@@ -90,7 +90,8 @@ def test_packet_file_to_datasets(use_derived_value, expected_mode):
90
90
  datasets_by_apid = utils.packet_file_to_datasets(
91
91
  packet_files, packet_definition, use_derived_value=use_derived_value
92
92
  )
93
- # 3 apids in the test data
93
+ # 2 apids in the SWAPI test data that we decommutate
94
+ # (2 others are not included in the XTCE definition, but are in the raw packet file)
94
95
  assert len(datasets_by_apid) == 2
95
96
  data = datasets_by_apid[1188]
96
97
  assert data["sec_hdr_flg"].dtype == np.uint8
@@ -99,7 +100,7 @@ def test_packet_file_to_datasets(use_derived_value, expected_mode):
99
100
 
100
101
 
101
102
  def test_packet_file_to_datasets_flat_definition():
102
- test_file = "tests/idex/imap_idex_l0_raw_20231214_v001.pkts"
103
+ test_file = "tests/idex/test_data/imap_idex_l0_raw_20231214_v001.pkts"
103
104
  packet_files = imap_module_directory / test_file
104
105
  packet_definition = (
105
106
  imap_module_directory / "idex/packet_definitions/idex_packet_definition.xml"