imap-processing 0.11.0__py3-none-any.whl → 0.12.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 (288) hide show
  1. imap_processing/__init__.py +10 -11
  2. imap_processing/_version.py +2 -2
  3. imap_processing/ccsds/excel_to_xtce.py +65 -16
  4. imap_processing/cdf/config/imap_codice_global_cdf_attrs.yaml +6 -28
  5. imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +365 -42
  6. imap_processing/cdf/config/imap_glows_global_cdf_attrs.yaml +0 -5
  7. imap_processing/cdf/config/imap_hi_global_cdf_attrs.yaml +10 -11
  8. imap_processing/cdf/config/imap_hi_variable_attrs.yaml +17 -19
  9. imap_processing/cdf/config/imap_hit_global_cdf_attrs.yaml +26 -13
  10. imap_processing/cdf/config/imap_hit_l1a_variable_attrs.yaml +106 -116
  11. imap_processing/cdf/config/imap_hit_l1b_variable_attrs.yaml +120 -145
  12. imap_processing/cdf/config/imap_hit_l2_variable_attrs.yaml +14 -0
  13. imap_processing/cdf/config/imap_idex_global_cdf_attrs.yaml +6 -9
  14. imap_processing/cdf/config/imap_idex_l1a_variable_attrs.yaml +1 -1
  15. imap_processing/cdf/config/imap_lo_global_cdf_attrs.yaml +0 -12
  16. imap_processing/cdf/config/imap_lo_l1a_variable_attrs.yaml +1 -1
  17. imap_processing/cdf/config/imap_mag_global_cdf_attrs.yaml +9 -21
  18. imap_processing/cdf/config/imap_mag_l1a_variable_attrs.yaml +361 -0
  19. imap_processing/cdf/config/imap_mag_l1b_variable_attrs.yaml +160 -0
  20. imap_processing/cdf/config/imap_mag_l1c_variable_attrs.yaml +160 -0
  21. imap_processing/cdf/config/imap_spacecraft_global_cdf_attrs.yaml +18 -0
  22. imap_processing/cdf/config/imap_spacecraft_variable_attrs.yaml +40 -0
  23. imap_processing/cdf/config/imap_swapi_global_cdf_attrs.yaml +1 -5
  24. imap_processing/cdf/config/imap_swe_global_cdf_attrs.yaml +12 -4
  25. imap_processing/cdf/config/imap_swe_l1a_variable_attrs.yaml +16 -2
  26. imap_processing/cdf/config/imap_swe_l1b_variable_attrs.yaml +48 -52
  27. imap_processing/cdf/config/imap_swe_l2_variable_attrs.yaml +71 -47
  28. imap_processing/cdf/config/imap_ultra_global_cdf_attrs.yaml +2 -14
  29. imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +51 -2
  30. imap_processing/cdf/config/imap_ultra_l1c_variable_attrs.yaml +29 -14
  31. imap_processing/cdf/utils.py +13 -7
  32. imap_processing/cli.py +23 -8
  33. imap_processing/codice/codice_l1a.py +207 -85
  34. imap_processing/codice/constants.py +1322 -568
  35. imap_processing/codice/decompress.py +2 -6
  36. imap_processing/ena_maps/ena_maps.py +480 -116
  37. imap_processing/ena_maps/utils/coordinates.py +19 -0
  38. imap_processing/ena_maps/utils/map_utils.py +14 -17
  39. imap_processing/ena_maps/utils/spatial_utils.py +45 -47
  40. imap_processing/hi/l1a/hi_l1a.py +24 -18
  41. imap_processing/hi/l1a/histogram.py +0 -1
  42. imap_processing/hi/l1a/science_direct_event.py +6 -8
  43. imap_processing/hi/l1b/hi_l1b.py +31 -39
  44. imap_processing/hi/l1c/hi_l1c.py +405 -17
  45. imap_processing/hi/utils.py +58 -12
  46. imap_processing/hit/ancillary/imap_hit_l1b-to-l2-standard-dt0-factors_20250219_v002.csv +205 -0
  47. imap_processing/hit/ancillary/imap_hit_l1b-to-l2-standard-dt1-factors_20250219_v002.csv +205 -0
  48. imap_processing/hit/ancillary/imap_hit_l1b-to-l2-standard-dt2-factors_20250219_v002.csv +205 -0
  49. imap_processing/hit/ancillary/imap_hit_l1b-to-l2-standard-dt3-factors_20250219_v002.csv +205 -0
  50. imap_processing/hit/ancillary/imap_hit_l1b-to-l2-summed-dt0-factors_20250219_v002.csv +68 -0
  51. imap_processing/hit/hit_utils.py +173 -1
  52. imap_processing/hit/l0/constants.py +20 -11
  53. imap_processing/hit/l0/decom_hit.py +18 -4
  54. imap_processing/hit/l1a/hit_l1a.py +45 -54
  55. imap_processing/hit/l1b/constants.py +317 -0
  56. imap_processing/hit/l1b/hit_l1b.py +367 -18
  57. imap_processing/hit/l2/constants.py +281 -0
  58. imap_processing/hit/l2/hit_l2.py +614 -0
  59. imap_processing/hit/packet_definitions/hit_packet_definitions.xml +1323 -71
  60. imap_processing/ialirt/l0/mag_l0_ialirt_data.py +155 -0
  61. imap_processing/ialirt/l0/parse_mag.py +246 -0
  62. imap_processing/ialirt/l0/process_swe.py +252 -0
  63. imap_processing/ialirt/packet_definitions/ialirt.xml +7 -3
  64. imap_processing/ialirt/packet_definitions/ialirt_mag.xml +115 -0
  65. imap_processing/ialirt/utils/grouping.py +114 -0
  66. imap_processing/ialirt/utils/time.py +29 -0
  67. imap_processing/idex/atomic_masses.csv +22 -0
  68. imap_processing/idex/decode.py +2 -2
  69. imap_processing/idex/idex_constants.py +25 -0
  70. imap_processing/idex/idex_l1a.py +6 -7
  71. imap_processing/idex/idex_l1b.py +4 -31
  72. imap_processing/idex/idex_l2a.py +789 -0
  73. imap_processing/idex/idex_variable_unpacking_and_eu_conversion.csv +39 -33
  74. imap_processing/lo/l0/lo_science.py +6 -0
  75. imap_processing/lo/l1a/lo_l1a.py +0 -1
  76. imap_processing/lo/l1b/lo_l1b.py +177 -25
  77. imap_processing/mag/constants.py +8 -0
  78. imap_processing/mag/imap_mag_sdc-configuration_v001.yaml +6 -0
  79. imap_processing/mag/l0/decom_mag.py +10 -3
  80. imap_processing/mag/l1a/mag_l1a.py +22 -11
  81. imap_processing/mag/l1a/mag_l1a_data.py +28 -3
  82. imap_processing/mag/l1b/mag_l1b.py +190 -48
  83. imap_processing/mag/l1c/interpolation_methods.py +211 -0
  84. imap_processing/mag/l1c/mag_l1c.py +447 -9
  85. imap_processing/quality_flags.py +1 -0
  86. imap_processing/spacecraft/packet_definitions/scid_x252.xml +538 -0
  87. imap_processing/spacecraft/quaternions.py +123 -0
  88. imap_processing/spice/geometry.py +16 -19
  89. imap_processing/spice/repoint.py +120 -0
  90. imap_processing/swapi/l1/swapi_l1.py +4 -0
  91. imap_processing/swapi/l2/swapi_l2.py +0 -1
  92. imap_processing/swe/l1a/swe_l1a.py +47 -8
  93. imap_processing/swe/l1a/swe_science.py +5 -2
  94. imap_processing/swe/l1b/swe_l1b_science.py +103 -56
  95. imap_processing/swe/l2/swe_l2.py +60 -65
  96. imap_processing/swe/packet_definitions/swe_packet_definition.xml +1121 -1
  97. imap_processing/swe/utils/swe_constants.py +63 -0
  98. imap_processing/swe/utils/swe_utils.py +85 -28
  99. imap_processing/tests/ccsds/test_data/expected_output.xml +40 -1
  100. imap_processing/tests/ccsds/test_excel_to_xtce.py +23 -20
  101. imap_processing/tests/cdf/test_data/imap_instrument2_global_cdf_attrs.yaml +0 -2
  102. imap_processing/tests/codice/conftest.py +1 -1
  103. imap_processing/tests/codice/data/validation/imap_codice_l1a_hi-counters-aggregated_20241110193700_v0.0.0.cdf +0 -0
  104. imap_processing/tests/codice/data/validation/imap_codice_l1a_hi-counters-singles_20241110193700_v0.0.0.cdf +0 -0
  105. imap_processing/tests/codice/data/validation/imap_codice_l1a_hi-ialirt_20241110193700_v0.0.0.cdf +0 -0
  106. imap_processing/tests/codice/data/validation/imap_codice_l1a_hi-omni_20241110193700_v0.0.0.cdf +0 -0
  107. imap_processing/tests/codice/data/validation/imap_codice_l1a_hi-pha_20241110193700_v0.0.0.cdf +0 -0
  108. imap_processing/tests/codice/data/validation/imap_codice_l1a_hi-priorities_20241110193700_v0.0.0.cdf +0 -0
  109. imap_processing/tests/codice/data/validation/imap_codice_l1a_hi-sectored_20241110193700_v0.0.0.cdf +0 -0
  110. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-counters-aggregated_20241110193700_v0.0.0.cdf +0 -0
  111. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-counters-singles_20241110193700_v0.0.0.cdf +0 -0
  112. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-ialirt_20241110193700_v0.0.0.cdf +0 -0
  113. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-nsw-angular_20241110193700_v0.0.0.cdf +0 -0
  114. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-nsw-priority_20241110193700_v0.0.0.cdf +0 -0
  115. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-nsw-species_20241110193700_v0.0.0.cdf +0 -0
  116. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-pha_20241110193700_v0.0.0.cdf +0 -0
  117. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-sw-angular_20241110193700_v0.0.0.cdf +0 -0
  118. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-sw-priority_20241110193700_v0.0.0.cdf +0 -0
  119. imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-sw-species_20241110193700_v0.0.0.cdf +0 -0
  120. imap_processing/tests/codice/test_codice_l1a.py +110 -46
  121. imap_processing/tests/codice/test_decompress.py +4 -4
  122. imap_processing/tests/conftest.py +166 -10
  123. imap_processing/tests/ena_maps/conftest.py +51 -0
  124. imap_processing/tests/ena_maps/test_ena_maps.py +638 -109
  125. imap_processing/tests/ena_maps/test_map_utils.py +66 -43
  126. imap_processing/tests/ena_maps/test_spatial_utils.py +16 -20
  127. imap_processing/tests/hi/data/l0/H45_diag_fee_20250208.bin +0 -0
  128. imap_processing/tests/hi/data/l0/H45_diag_fee_20250208_verify.csv +205 -0
  129. imap_processing/tests/hi/test_hi_l1b.py +12 -15
  130. imap_processing/tests/hi/test_hi_l1c.py +234 -6
  131. imap_processing/tests/hi/test_l1a.py +30 -0
  132. imap_processing/tests/hi/test_science_direct_event.py +1 -1
  133. imap_processing/tests/hi/test_utils.py +24 -2
  134. imap_processing/tests/hit/helpers/l1_validation.py +39 -39
  135. imap_processing/tests/hit/test_data/hskp_sample.ccsds +0 -0
  136. imap_processing/tests/hit/test_data/imap_hit_l0_raw_20100105_v001.pkts +0 -0
  137. imap_processing/tests/hit/test_decom_hit.py +4 -0
  138. imap_processing/tests/hit/test_hit_l1a.py +24 -28
  139. imap_processing/tests/hit/test_hit_l1b.py +304 -40
  140. imap_processing/tests/hit/test_hit_l2.py +454 -0
  141. imap_processing/tests/hit/test_hit_utils.py +112 -2
  142. imap_processing/tests/hit/validation_data/hskp_sample_eu_3_6_2025.csv +89 -0
  143. imap_processing/tests/hit/validation_data/hskp_sample_raw.csv +89 -88
  144. imap_processing/tests/ialirt/test_data/l0/461971383-404.bin +0 -0
  145. imap_processing/tests/ialirt/test_data/l0/461971384-405.bin +0 -0
  146. imap_processing/tests/ialirt/test_data/l0/461971385-406.bin +0 -0
  147. imap_processing/tests/ialirt/test_data/l0/461971386-407.bin +0 -0
  148. imap_processing/tests/ialirt/test_data/l0/461971387-408.bin +0 -0
  149. imap_processing/tests/ialirt/test_data/l0/461971388-409.bin +0 -0
  150. imap_processing/tests/ialirt/test_data/l0/461971389-410.bin +0 -0
  151. imap_processing/tests/ialirt/test_data/l0/461971390-411.bin +0 -0
  152. imap_processing/tests/ialirt/test_data/l0/461971391-412.bin +0 -0
  153. imap_processing/tests/ialirt/test_data/l0/sample_decoded_i-alirt_data.csv +383 -0
  154. imap_processing/tests/ialirt/unit/test_grouping.py +81 -0
  155. imap_processing/tests/ialirt/unit/test_parse_mag.py +168 -0
  156. imap_processing/tests/ialirt/unit/test_process_swe.py +208 -3
  157. imap_processing/tests/ialirt/unit/test_time.py +16 -0
  158. imap_processing/tests/idex/conftest.py +62 -6
  159. imap_processing/tests/idex/test_data/imap_idex_l0_raw_20231218_v001.pkts +0 -0
  160. imap_processing/tests/idex/test_data/impact_14_tof_high_data.txt +4508 -4508
  161. imap_processing/tests/idex/test_idex_l1a.py +48 -4
  162. imap_processing/tests/idex/test_idex_l1b.py +3 -3
  163. imap_processing/tests/idex/test_idex_l2a.py +383 -0
  164. imap_processing/tests/lo/test_cdfs/imap_lo_l1a_de_20241022_v002.cdf +0 -0
  165. imap_processing/tests/lo/test_cdfs/imap_lo_l1a_spin_20241022_v002.cdf +0 -0
  166. imap_processing/tests/lo/test_lo_l1b.py +148 -4
  167. imap_processing/tests/lo/test_lo_science.py +1 -0
  168. imap_processing/tests/mag/conftest.py +69 -0
  169. imap_processing/tests/mag/test_mag_decom.py +1 -1
  170. imap_processing/tests/mag/test_mag_l1a.py +38 -0
  171. imap_processing/tests/mag/test_mag_l1b.py +34 -53
  172. imap_processing/tests/mag/test_mag_l1c.py +251 -20
  173. imap_processing/tests/mag/test_mag_validation.py +109 -25
  174. imap_processing/tests/mag/validation/L1b/T009/MAGScience-normal-(2,2)-8s-20250204-16h39.csv +17 -0
  175. imap_processing/tests/mag/validation/L1b/T009/mag-l1a-l1b-t009-magi-out.csv +16 -16
  176. imap_processing/tests/mag/validation/L1b/T009/mag-l1a-l1b-t009-mago-out.csv +16 -16
  177. imap_processing/tests/mag/validation/L1b/T010/MAGScience-normal-(2,2)-8s-20250206-12h05.csv +17 -0
  178. imap_processing/tests/mag/validation/L1b/T011/MAGScience-normal-(2,2)-8s-20250204-16h08.csv +17 -0
  179. imap_processing/tests/mag/validation/L1b/T011/mag-l1a-l1b-t011-magi-out.csv +16 -16
  180. imap_processing/tests/mag/validation/L1b/T011/mag-l1a-l1b-t011-mago-out.csv +16 -16
  181. imap_processing/tests/mag/validation/L1b/T012/MAGScience-normal-(2,2)-8s-20250204-16h08.csv +17 -0
  182. imap_processing/tests/mag/validation/L1b/T012/data.bin +0 -0
  183. imap_processing/tests/mag/validation/L1b/T012/field_like_all_ranges.txt +19200 -0
  184. imap_processing/tests/mag/validation/L1b/T012/mag-l1a-l1b-t012-cal.cdf +0 -0
  185. imap_processing/tests/mag/validation/L1b/T012/mag-l1a-l1b-t012-in.csv +17 -0
  186. imap_processing/tests/mag/validation/L1b/T012/mag-l1a-l1b-t012-magi-out.csv +17 -0
  187. imap_processing/tests/mag/validation/L1b/T012/mag-l1a-l1b-t012-mago-out.csv +17 -0
  188. imap_processing/tests/mag/validation/imap_calibration_mag_20240229_v01.cdf +0 -0
  189. imap_processing/tests/spacecraft/__init__.py +0 -0
  190. imap_processing/tests/spacecraft/data/SSR_2024_190_20_08_12_0483851794_2_DA_apid0594_1packet.pkts +0 -0
  191. imap_processing/tests/spacecraft/test_quaternions.py +71 -0
  192. imap_processing/tests/spice/test_data/fake_repoint_data.csv +5 -0
  193. imap_processing/tests/spice/test_geometry.py +6 -9
  194. imap_processing/tests/spice/test_repoint.py +111 -0
  195. imap_processing/tests/swapi/test_swapi_l1.py +7 -3
  196. imap_processing/tests/swe/l0_data/2024051010_SWE_HK_packet.bin +0 -0
  197. imap_processing/tests/swe/l0_data/2024051011_SWE_CEM_RAW_packet.bin +0 -0
  198. imap_processing/tests/swe/l0_validation_data/idle_export_eu.SWE_APP_HK_20240510_092742.csv +49 -0
  199. imap_processing/tests/swe/l0_validation_data/idle_export_eu.SWE_CEM_RAW_20240510_092742.csv +593 -0
  200. imap_processing/tests/swe/test_swe_l1a.py +18 -0
  201. imap_processing/tests/swe/test_swe_l1a_cem_raw.py +52 -0
  202. imap_processing/tests/swe/test_swe_l1a_hk.py +68 -0
  203. imap_processing/tests/swe/test_swe_l1b_science.py +23 -4
  204. imap_processing/tests/swe/test_swe_l2.py +112 -30
  205. imap_processing/tests/test_cli.py +2 -2
  206. imap_processing/tests/test_utils.py +138 -16
  207. imap_processing/tests/ultra/data/l0/FM45_UltraFM45_Functional_2024-01-22T0105_20240122T010548.CCSDS +0 -0
  208. imap_processing/tests/ultra/data/l0/ultra45_raw_sc_ultraimgrates_20220530_00.csv +164 -0
  209. imap_processing/tests/ultra/{test_data → data}/l0/ultra45_raw_sc_ultrarawimg_withFSWcalcs_FM45_40P_Phi28p5_BeamCal_LinearScan_phi2850_theta-000_20240207T102740.csv +3243 -3243
  210. imap_processing/tests/ultra/data/mock_data.py +341 -0
  211. imap_processing/tests/ultra/unit/conftest.py +69 -26
  212. imap_processing/tests/ultra/unit/test_badtimes.py +2 -0
  213. imap_processing/tests/ultra/unit/test_cullingmask.py +4 -0
  214. imap_processing/tests/ultra/unit/test_de.py +12 -4
  215. imap_processing/tests/ultra/unit/test_decom_apid_881.py +44 -0
  216. imap_processing/tests/ultra/unit/test_spacecraft_pset.py +78 -0
  217. imap_processing/tests/ultra/unit/test_ultra_l1a.py +28 -12
  218. imap_processing/tests/ultra/unit/test_ultra_l1b.py +34 -6
  219. imap_processing/tests/ultra/unit/test_ultra_l1b_culling.py +22 -26
  220. imap_processing/tests/ultra/unit/test_ultra_l1b_extended.py +86 -51
  221. imap_processing/tests/ultra/unit/test_ultra_l1c_pset_bins.py +94 -52
  222. imap_processing/ultra/l0/decom_tools.py +6 -5
  223. imap_processing/ultra/l1a/ultra_l1a.py +28 -56
  224. imap_processing/ultra/l1b/de.py +72 -28
  225. imap_processing/ultra/l1b/extendedspin.py +12 -14
  226. imap_processing/ultra/l1b/ultra_l1b.py +34 -9
  227. imap_processing/ultra/l1b/ultra_l1b_culling.py +65 -29
  228. imap_processing/ultra/l1b/ultra_l1b_extended.py +64 -19
  229. imap_processing/ultra/l1c/spacecraft_pset.py +86 -0
  230. imap_processing/ultra/l1c/ultra_l1c.py +7 -4
  231. imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +112 -61
  232. imap_processing/ultra/lookup_tables/ultra_90_dps_exposure_compressed.cdf +0 -0
  233. imap_processing/ultra/utils/ultra_l1_utils.py +20 -2
  234. imap_processing/utils.py +68 -28
  235. {imap_processing-0.11.0.dist-info → imap_processing-0.12.0.dist-info}/METADATA +8 -5
  236. {imap_processing-0.11.0.dist-info → imap_processing-0.12.0.dist-info}/RECORD +250 -199
  237. imap_processing/cdf/config/imap_mag_l1_variable_attrs.yaml +0 -237
  238. imap_processing/hi/l1a/housekeeping.py +0 -27
  239. imap_processing/tests/codice/data/imap_codice_l1a_hi-counters-aggregated_20240429_v001.cdf +0 -0
  240. imap_processing/tests/codice/data/imap_codice_l1a_hi-counters-singles_20240429_v001.cdf +0 -0
  241. imap_processing/tests/codice/data/imap_codice_l1a_hi-omni_20240429_v001.cdf +0 -0
  242. imap_processing/tests/codice/data/imap_codice_l1a_hi-sectored_20240429_v001.cdf +0 -0
  243. imap_processing/tests/codice/data/imap_codice_l1a_hskp_20100101_v001.cdf +0 -0
  244. imap_processing/tests/codice/data/imap_codice_l1a_lo-counters-aggregated_20240429_v001.cdf +0 -0
  245. imap_processing/tests/codice/data/imap_codice_l1a_lo-counters-singles_20240429_v001.cdf +0 -0
  246. imap_processing/tests/codice/data/imap_codice_l1a_lo-nsw-angular_20240429_v001.cdf +0 -0
  247. imap_processing/tests/codice/data/imap_codice_l1a_lo-nsw-priority_20240429_v001.cdf +0 -0
  248. imap_processing/tests/codice/data/imap_codice_l1a_lo-nsw-species_20240429_v001.cdf +0 -0
  249. imap_processing/tests/codice/data/imap_codice_l1a_lo-sw-angular_20240429_v001.cdf +0 -0
  250. imap_processing/tests/codice/data/imap_codice_l1a_lo-sw-priority_20240429_v001.cdf +0 -0
  251. imap_processing/tests/codice/data/imap_codice_l1a_lo-sw-species_20240429_v001.cdf +0 -0
  252. imap_processing/tests/codice/data/imap_codice_l1b_hi-counters-aggregated_20240429_v001.cdf +0 -0
  253. imap_processing/tests/codice/data/imap_codice_l1b_hi-counters-singles_20240429_v001.cdf +0 -0
  254. imap_processing/tests/codice/data/imap_codice_l1b_hi-omni_20240429_v001.cdf +0 -0
  255. imap_processing/tests/codice/data/imap_codice_l1b_hi-sectored_20240429_v001.cdf +0 -0
  256. imap_processing/tests/codice/data/imap_codice_l1b_hskp_20100101_v001.cdf +0 -0
  257. imap_processing/tests/codice/data/imap_codice_l1b_lo-counters-aggregated_20240429_v001.cdf +0 -0
  258. imap_processing/tests/codice/data/imap_codice_l1b_lo-counters-singles_20240429_v001.cdf +0 -0
  259. imap_processing/tests/codice/data/imap_codice_l1b_lo-nsw-angular_20240429_v001.cdf +0 -0
  260. imap_processing/tests/codice/data/imap_codice_l1b_lo-nsw-priority_20240429_v001.cdf +0 -0
  261. imap_processing/tests/codice/data/imap_codice_l1b_lo-nsw-species_20240429_v001.cdf +0 -0
  262. imap_processing/tests/codice/data/imap_codice_l1b_lo-sw-angular_20240429_v001.cdf +0 -0
  263. imap_processing/tests/codice/data/imap_codice_l1b_lo-sw-priority_20240429_v001.cdf +0 -0
  264. imap_processing/tests/codice/data/imap_codice_l1b_lo-sw-species_20240429_v001.cdf +0 -0
  265. imap_processing/tests/hi/data/l1/imap_hi_l1b_45sensor-de_20250415_v999.cdf +0 -0
  266. imap_processing/tests/hit/PREFLIGHT_raw_record_2023_256_15_59_04_apid1251.pkts +0 -0
  267. imap_processing/tests/hit/PREFLIGHT_raw_record_2023_256_15_59_04_apid1252.pkts +0 -0
  268. imap_processing/tests/hit/validation_data/hskp_sample_eu.csv +0 -89
  269. imap_processing/tests/hit/validation_data/sci_sample_raw1.csv +0 -29
  270. imap_processing/tests/idex/test_data/imap_idex_l0_raw_20231214_v001.pkts +0 -0
  271. imap_processing/tests/lo/test_cdfs/imap_lo_l1a_de_20100101_v001.cdf +0 -0
  272. imap_processing/tests/lo/test_cdfs/imap_lo_l1a_spin_20100101_v001.cdf +0 -0
  273. imap_processing/tests/ultra/test_data/mock_data.py +0 -161
  274. imap_processing/ultra/l1c/pset.py +0 -40
  275. /imap_processing/tests/ultra/{test_data → data}/l0/FM45_40P_Phi28p5_BeamCal_LinearScan_phi28.50_theta-0.00_20240207T102740.CCSDS +0 -0
  276. /imap_processing/tests/ultra/{test_data → data}/l0/FM45_7P_Phi0.0_BeamCal_LinearScan_phi0.04_theta-0.01_20230821T121304.CCSDS +0 -0
  277. /imap_processing/tests/ultra/{test_data → data}/l0/FM45_TV_Cycle6_Hot_Ops_Front212_20240124T063837.CCSDS +0 -0
  278. /imap_processing/tests/ultra/{test_data → data}/l0/Ultra45_EM_SwRI_Cal_Run7_ThetaScan_20220530T225054.CCSDS +0 -0
  279. /imap_processing/tests/ultra/{test_data → data}/l0/ultra45_raw_sc_auxdata_Ultra45_EM_SwRI_Cal_Run7_ThetaScan_20220530T225054.csv +0 -0
  280. /imap_processing/tests/ultra/{test_data → data}/l0/ultra45_raw_sc_enaphxtofhangimg_FM45_TV_Cycle6_Hot_Ops_Front212_20240124T063837.csv +0 -0
  281. /imap_processing/tests/ultra/{test_data → data}/l0/ultra45_raw_sc_ultraimgrates_Ultra45_EM_SwRI_Cal_Run7_ThetaScan_20220530T225054.csv +0 -0
  282. /imap_processing/tests/ultra/{test_data → data}/l0/ultra45_raw_sc_ultrarawimgevent_FM45_7P_Phi00_BeamCal_LinearScan_phi004_theta-001_20230821T121304.csv +0 -0
  283. /imap_processing/tests/ultra/{test_data → data}/l1/dps_exposure_helio_45_E1.cdf +0 -0
  284. /imap_processing/tests/ultra/{test_data → data}/l1/dps_exposure_helio_45_E12.cdf +0 -0
  285. /imap_processing/tests/ultra/{test_data → data}/l1/dps_exposure_helio_45_E24.cdf +0 -0
  286. {imap_processing-0.11.0.dist-info → imap_processing-0.12.0.dist-info}/LICENSE +0 -0
  287. {imap_processing-0.11.0.dist-info → imap_processing-0.12.0.dist-info}/WHEEL +0 -0
  288. {imap_processing-0.11.0.dist-info → imap_processing-0.12.0.dist-info}/entry_points.txt +0 -0
@@ -2,8 +2,11 @@
2
2
 
3
3
  from pathlib import Path
4
4
 
5
+ import numpy as np
5
6
  import pytest
7
+ import xarray as xr
6
8
 
9
+ from imap_processing.cdf.utils import load_cdf
7
10
  from imap_processing.mag.l1a.mag_l1a import mag_l1a
8
11
 
9
12
 
@@ -14,3 +17,69 @@ def validation_l1a():
14
17
  # Test file contains only normal packets
15
18
  l1a = mag_l1a(test_file, "v000")
16
19
  return l1a
20
+
21
+
22
+ def mag_l1a_dataset_generator(length):
23
+ epoch = xr.DataArray(np.arange(length), name="epoch", dims=["epoch"])
24
+ direction = xr.DataArray(np.arange(4), name="direction", dims=["direction"])
25
+ compression = xr.DataArray(np.arange(2), name="compression", dims=["compression"])
26
+
27
+ direction_label = xr.DataArray(
28
+ direction.values.astype(str),
29
+ name="direction_label",
30
+ dims=["direction_label"],
31
+ )
32
+
33
+ compression_label = xr.DataArray(
34
+ compression.values.astype(str),
35
+ name="compression_label",
36
+ dims=["compression_label"],
37
+ )
38
+
39
+ vectors = xr.DataArray(
40
+ np.zeros((length, 4)),
41
+ dims=["epoch", "direction"],
42
+ coords={"epoch": epoch, "direction": direction},
43
+ )
44
+ compression_flags = xr.DataArray(
45
+ np.zeros((length, 2), dtype=np.int8), dims=["epoch", "compression"]
46
+ )
47
+
48
+ output_dataset = xr.Dataset(
49
+ coords={"epoch": epoch, "direction": direction, "compression": compression},
50
+ )
51
+ output_dataset["vectors"] = vectors
52
+ output_dataset["compression_flags"] = compression_flags
53
+ output_dataset["direction_label"] = direction_label
54
+ output_dataset["compression_label"] = compression_label
55
+ output_dataset.attrs["Logical_source"] = ["imap_mag_l1a_norm-mago"]
56
+
57
+ return output_dataset
58
+
59
+
60
+ @pytest.fixture()
61
+ def mag_test_calibration_data():
62
+ imap_dir = Path(__file__).parent
63
+ cal_file = imap_dir / "validation" / "imap_calibration_mag_20240229_v01.cdf"
64
+ calibration_data = load_cdf(cal_file)
65
+ return calibration_data
66
+
67
+
68
+ def generate_test_epoch(end, vectors_per_second, starting_point=0, gaps=None):
69
+ spacing = 1 / vectors_per_second[0]
70
+ output = np.array([])
71
+ prev = starting_point
72
+ if gaps:
73
+ for index, gap in enumerate(gaps):
74
+ if len(vectors_per_second) != 1:
75
+ spacing = 1 / vectors_per_second[index]
76
+ output = np.concatenate(
77
+ (output, np.arange(prev, gap[0] + spacing, step=spacing) * 1e9)
78
+ )
79
+ prev = gap[1]
80
+ spacing = 1 / vectors_per_second[-1]
81
+ output = np.concatenate(
82
+ (output, np.arange(prev, end + spacing, step=spacing) * 1e9)
83
+ )
84
+
85
+ return output
@@ -13,7 +13,7 @@ from imap_processing.mag.l0.decom_mag import decom_packets, generate_dataset
13
13
  def cdf_attrs():
14
14
  test_attrs = ImapCdfAttributes()
15
15
  test_attrs.add_instrument_global_attrs("mag")
16
- test_attrs.add_instrument_variable_attrs("mag", "l1")
16
+ test_attrs.add_instrument_variable_attrs("mag", "l1a")
17
17
  test_attrs.add_global_attribute("Data_version", "v001")
18
18
  return test_attrs
19
19
 
@@ -919,3 +919,41 @@ def test_mag_packet_properties():
919
919
  )
920
920
 
921
921
  assert packet_properties.compression_width == 18
922
+
923
+
924
+ def test_changing_vecsec():
925
+ packet_one = MagL1aPacketProperties(
926
+ 1000,
927
+ TimeTuple(1000, 0),
928
+ 2, # 2 vectors per second
929
+ 1, # 2 seconds of data
930
+ 0,
931
+ 0,
932
+ 1,
933
+ 0,
934
+ )
935
+ packet_two = MagL1aPacketProperties(
936
+ 2000,
937
+ TimeTuple(2000, 0),
938
+ 8, # 8 vectors per second
939
+ 1, # 2 seconds of data
940
+ 1,
941
+ 0,
942
+ 1,
943
+ 0,
944
+ )
945
+
946
+ four_vectors = np.full((4, 5), [1, 2, 3, 4, 2])
947
+ sixteen_vectors = np.full((16, 5), [1, 2, 3, 4, 2])
948
+
949
+ mag_l1a = MagL1a(True, 1, 1, four_vectors, packet_one)
950
+ mag_l1a.append_vectors(sixteen_vectors, packet_two)
951
+
952
+ assert mag_l1a.vectors.shape[0] == 20
953
+ assert len(mag_l1a.packet_definitions.keys()) == 2
954
+ expected = [2, 8]
955
+ for index, value in enumerate(mag_l1a.packet_definitions.values()):
956
+ assert expected[index] == value.vectors_per_second
957
+
958
+ assert ":2," in mag_l1a.vectors_per_second_attribute()
959
+ assert ":8" in mag_l1a.vectors_per_second_attribute()
@@ -4,6 +4,7 @@ import numpy as np
4
4
  import pytest
5
5
  import xarray as xr
6
6
 
7
+ from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
7
8
  from imap_processing.cdf.utils import load_cdf, write_cdf
8
9
  from imap_processing.mag.l1b.mag_l1b import (
9
10
  calibrate_vector,
@@ -11,55 +12,30 @@ from imap_processing.mag.l1b.mag_l1b import (
11
12
  mag_l1b_processing,
12
13
  rescale_vector,
13
14
  )
15
+ from imap_processing.tests.mag.conftest import (
16
+ mag_l1a_dataset_generator,
17
+ )
14
18
 
15
19
 
16
- @pytest.fixture(scope="module")
17
- def mag_l1a_dataset():
18
- epoch = xr.DataArray(np.arange(20), name="epoch", dims=["epoch"])
19
- direction = xr.DataArray(np.arange(4), name="direction", dims=["direction"])
20
- compression = xr.DataArray(np.arange(2), name="compression", dims=["compression"])
21
-
22
- direction_label = xr.DataArray(
23
- direction.values.astype(str),
24
- name="direction_label",
25
- dims=["direction_label"],
26
- )
27
-
28
- compression_label = xr.DataArray(
29
- compression.values.astype(str),
30
- name="compression_label",
31
- dims=["compression_label"],
32
- )
33
-
34
- vectors = xr.DataArray(
35
- np.zeros((20, 4)),
36
- dims=["epoch", "direction"],
37
- coords={"epoch": epoch, "direction": direction},
38
- )
39
- compression_flags = xr.DataArray(
40
- np.zeros((20, 2), dtype=np.int8), dims=["epoch", "compression"]
41
- )
42
- compression_flags[1, :] = np.array([1, 18], dtype=np.int8)
43
-
44
- vectors[0, :] = np.array([1, 1, 1, 0])
45
- vectors[1, :] = np.array([7982, 48671, -68090, 0])
46
-
47
- output_dataset = xr.Dataset(
48
- coords={"epoch": epoch, "direction": direction, "compression": compression},
20
+ def test_mag_processing(mag_test_calibration_data):
21
+ # All specific test values come from MAG team to accommodate various cases.
22
+ # Each vector is multiplied by the matrix in the calibration data for the given
23
+ # range to get the calibrated vector.
24
+ mag_l1a_dataset = mag_l1a_dataset_generator(20)
25
+ mag_l1a_dataset["compression_flags"].data[1, :] = np.array([1, 18], dtype=np.int8)
26
+
27
+ mag_l1a_dataset["vectors"].data[0, :] = np.array([1, 1, 1, 0])
28
+ mag_l1a_dataset["vectors"].data[1, :] = np.array([7982, 48671, -68090, 0])
29
+ mag_attributes = ImapCdfAttributes()
30
+ mag_attributes.add_instrument_global_attrs("mag")
31
+ mag_attributes.add_instrument_variable_attrs("mag", "l1b")
32
+ mag_l1b = mag_l1b_processing(
33
+ mag_l1a_dataset,
34
+ mag_test_calibration_data,
35
+ mag_attributes,
36
+ "imap_mag_l1b_norm-mago",
49
37
  )
50
- output_dataset["vectors"] = vectors
51
- output_dataset["compression_flags"] = compression_flags
52
- output_dataset["direction_label"] = direction_label
53
- output_dataset["compression_label"] = compression_label
54
- output_dataset.attrs["Logical_source"] = ["imap_mag_l1a_norm-mago"]
55
38
 
56
- return output_dataset
57
-
58
-
59
- def test_mag_processing(mag_l1a_dataset):
60
- mag_l1a_dataset.attrs["Logical_source"] = ["imap_mag_l1a_norm-mago"]
61
-
62
- mag_l1b = mag_l1b_processing(mag_l1a_dataset)
63
39
  np.testing.assert_allclose(
64
40
  mag_l1b["vectors"][0].values, [2.2972, 2.2415, 2.2381, 0], atol=1e-4
65
41
  )
@@ -68,13 +44,16 @@ def test_mag_processing(mag_l1a_dataset):
68
44
  [4584.1029091, 27238.73161294, -38405.22240195, 0.0],
69
45
  )
70
46
 
71
- # np.testing.assert_allclose(mag_l1b["vectors"][1].values, [0, 0, 0, 0])
47
+ np.testing.assert_allclose(mag_l1b["vectors"][2].values, [0, 0, 0, 0])
72
48
 
73
49
  assert mag_l1b["vectors"].values.shape == mag_l1a_dataset["vectors"].values.shape
74
50
 
75
- mag_l1a_dataset.attrs["Logical_source"] = ["imap_mag_l1a_norm-magi"]
76
-
77
- mag_l1b = mag_l1b_processing(mag_l1a_dataset)
51
+ mag_l1b = mag_l1b_processing(
52
+ mag_l1a_dataset,
53
+ mag_test_calibration_data,
54
+ mag_attributes,
55
+ "imap_mag_l1b_norm-magi",
56
+ )
78
57
 
79
58
  np.testing.assert_allclose(
80
59
  mag_l1b["vectors"][0].values, [2.27538, 2.23416, 2.23682, 0], atol=1e-5
@@ -83,7 +62,9 @@ def test_mag_processing(mag_l1a_dataset):
83
62
  assert mag_l1b["vectors"].values.shape == mag_l1a_dataset["vectors"].values.shape
84
63
 
85
64
 
86
- def test_mag_attributes(mag_l1a_dataset):
65
+ def test_mag_attributes():
66
+ mag_l1a_dataset = mag_l1a_dataset_generator(20)
67
+
87
68
  mag_l1a_dataset.attrs["Logical_source"] = ["imap_mag_l1a_norm-mago"]
88
69
 
89
70
  output = mag_l1b(mag_l1a_dataset, "v001")
@@ -94,8 +75,6 @@ def test_mag_attributes(mag_l1a_dataset):
94
75
  output = mag_l1b(mag_l1a_dataset, "v001")
95
76
  assert output.attrs["Logical_source"] == "imap_mag_l1b_burst-magi"
96
77
 
97
- assert output.attrs["Data_level"] == "L1B"
98
-
99
78
 
100
79
  def test_cdf_output():
101
80
  l1a_cdf = load_cdf(
@@ -110,7 +89,9 @@ def test_cdf_output():
110
89
  assert Path.exists(output_path)
111
90
 
112
91
 
113
- def test_mag_compression_scale(mag_l1a_dataset):
92
+ def test_mag_compression_scale():
93
+ mag_l1a_dataset = mag_l1a_dataset_generator(20)
94
+
114
95
  test_calibration = np.array(
115
96
  [
116
97
  [2.2972202, 0.0, 0.0],
@@ -1,40 +1,271 @@
1
+ from pathlib import Path
2
+
1
3
  import numpy as np
2
4
  import pytest
3
5
  import xarray as xr
6
+ import yaml
4
7
 
5
- from imap_processing.mag.l1c.mag_l1c import mag_l1c
8
+ from imap_processing.mag.l1c.interpolation_methods import InterpolationFunction
9
+ from imap_processing.mag.l1c.mag_l1c import (
10
+ fill_normal_data,
11
+ find_all_gaps,
12
+ find_gaps,
13
+ generate_timeline,
14
+ interpolate_gaps,
15
+ mag_l1c,
16
+ process_mag_l1c,
17
+ )
18
+ from imap_processing.tests.mag.conftest import (
19
+ generate_test_epoch,
20
+ mag_l1a_dataset_generator,
21
+ )
6
22
 
7
23
 
8
24
  @pytest.fixture(scope="module")
9
25
  def mag_l1b_dataset():
10
- epoch = xr.DataArray(np.arange(20), name="epoch", dims=["epoch"])
11
- direction = xr.DataArray(np.arange(4), name="direction", dims=["direction"])
12
- vectors = xr.DataArray(
13
- np.zeros((20, 4)),
14
- dims=["epoch", "direction"],
15
- coords={"epoch": epoch, "direction": direction},
16
- )
26
+ output_dataset = mag_l1a_dataset_generator(10)
17
27
 
28
+ output_dataset["epoch"] = xr.DataArray(
29
+ np.arange(0.1, 5.1, step=0.5) * 1e9, name="epoch", dims=["epoch"]
30
+ )
31
+ vectors = np.array([[i, i, i, 2] for i in range(1, 11)])
18
32
  vectors[0, :] = np.array([1, 1, 1, 0])
33
+ output_dataset["vectors"].data = vectors
34
+
35
+ return output_dataset
36
+
37
+
38
+ @pytest.fixture()
39
+ def norm_dataset():
40
+ dataset = mag_l1a_dataset_generator(10)
41
+ epoch_vals = generate_test_epoch(6, [2, 4, 4], 0, [[2, 4], [4.25, 5.5]])
42
+ vectors_per_second_attr = "0:2,4000000000:4"
43
+ dataset.attrs["vectors_per_second"] = vectors_per_second_attr
44
+ dataset["epoch"] = epoch_vals
45
+ dataset.attrs["Logical_source"] = "imap_mag_l1b_norm-mago"
46
+ vectors = np.array([[i, i, i, 2] for i in range(1, 11)])
47
+ dataset["vectors"].data = vectors
48
+
49
+ return dataset
50
+
51
+
52
+ @pytest.fixture()
53
+ def burst_dataset():
54
+ dataset = mag_l1a_dataset_generator(17)
55
+ epoch_vals = generate_test_epoch(5.1, [5], 1.9)
56
+ dataset["epoch"] = epoch_vals
57
+ dataset.attrs["Logical_source"] = ["imap_mag_l1b_burst-mago"]
58
+ vectors = np.array([[i, i, i, 2] for i in range(1, 18)])
59
+ dataset["vectors"].data = vectors
60
+ return dataset
61
+
62
+
63
+ def test_configuration_file():
64
+ with open(
65
+ Path(__file__).parent.parent.parent
66
+ / "mag"
67
+ / "imap_mag_sdc-configuration_v001.yaml"
68
+ ) as f:
69
+ configuration = yaml.safe_load(f)
70
+
71
+ assert configuration["L1C_interpolation_method"] in [
72
+ e.name for e in InterpolationFunction
73
+ ]
19
74
 
20
- output_dataset = xr.Dataset(
21
- coords={"epoch": epoch, "direction": direction},
75
+ # should not raise an error
76
+ configuration_file = InterpolationFunction[
77
+ configuration["L1C_interpolation_method"]
78
+ ]
79
+ configuration_file([1], [1], [1])
80
+
81
+
82
+ def test_process_mag_l1c(norm_dataset, burst_dataset):
83
+ l1c = process_mag_l1c(norm_dataset, burst_dataset, InterpolationFunction.linear)
84
+ expected_output_timeline = (
85
+ np.array([0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.25, 4.75, 5.25, 5.5, 5.75, 6])
86
+ * 1e9
22
87
  )
23
- output_dataset["vectors"] = vectors
88
+ assert np.array_equal(l1c[:, 0], expected_output_timeline)
89
+ # Every new timestamp should have data
90
+ assert (
91
+ np.count_nonzero([np.sum(l1c[i, 1:4]) for i in range(l1c.shape[0])])
92
+ == l1c.shape[0]
93
+ )
94
+ expected_flags = np.zeros(15)
95
+ # filled sections should have 1 as a flag
96
+ expected_flags[5:8] = 1
97
+ expected_flags[10:12] = 1
98
+ assert np.array_equal(l1c[:, 5], expected_flags)
99
+ assert np.array_equal(l1c[:5, 1:5], norm_dataset["vectors"].data[:5, :])
100
+ for i in range(5, 8):
101
+ e = l1c[i, 0]
102
+ burst_vectors = burst_dataset.sel(epoch=int(e), method="nearest")[
103
+ "vectors"
104
+ ].data
105
+ # We're just finding the closest burst values to the array, so they won't be
106
+ # identical.
107
+ assert np.allclose(l1c[i, 1:5], burst_vectors, rtol=0, atol=1)
24
108
 
25
- return output_dataset
109
+ assert np.array_equal(l1c[8:10, 1:5], norm_dataset["vectors"].data[5:7, :])
110
+ for i in range(10, 12):
111
+ e = l1c[i, 0]
112
+ burst_vectors = burst_dataset.sel(epoch=int(e), method="nearest")[
113
+ "vectors"
114
+ ].data
115
+ # We're just finding the closest burst values to the array, so they won't be
116
+ # identical.
117
+ assert np.allclose(l1c[i, 1:5], burst_vectors, rtol=0, atol=1)
118
+
119
+
120
+ def test_interpolate_gaps(norm_dataset, mag_l1b_dataset):
121
+ # np.array([0, 0.5, 1, 1.5, 2, 4, 4.25, 5.5, 5.75, 6]) * 1e9
122
+ gaps = np.array([[2, 4], [4.25, 5.5]]) * 1e9
123
+ generated_timeline = generate_timeline(norm_dataset["epoch"].data, gaps)
124
+ norm_timeline = fill_normal_data(norm_dataset, generated_timeline)
125
+ gaps = np.array([[2, 4]]) * 1e9
126
+ output = interpolate_gaps(
127
+ mag_l1b_dataset, gaps, norm_timeline, InterpolationFunction.linear
128
+ )
129
+ expected_output = np.array(
130
+ [
131
+ [5.8, 5.8, 5.8, 2, 1, 0, 0],
132
+ [6.8, 6.8, 6.8, 2, 1, 0, 0],
133
+ [7.8, 7.8, 7.8, 2, 1, 0, 0],
134
+ ]
135
+ )
136
+
137
+ assert np.allclose(output[5:8, 1:], expected_output)
138
+
139
+ input_norm_timeline = np.array(
140
+ [
141
+ [1.50e09, 4, 4, 4, 2, 0, 0, 0],
142
+ [2.00e09, 5, 5, 5, 2, 0, 0, 0],
143
+ [2.50e09, 0, 0, 0, 0, 1, 0, 0],
144
+ [3.00e09, 0, 0, 0, 0, 1, 0, 0],
145
+ [3.50e09, 0, 0, 0, 0, 1, 0, 0],
146
+ [4.00e09, 6, 6, 6, 2, 0, 0, 0],
147
+ [4.25e09, 7, 7, 7, 2, 0, 0, 0],
148
+ ]
149
+ )
150
+
151
+ # output - all timestamps with -1 should be filled with interpolated values.
152
+ expected_output = np.array(
153
+ [
154
+ [1.50e09, 4, 4, 4, 2, 0, 0, 0],
155
+ [2.00e09, 5, 5, 5, 2, 0, 0, 0],
156
+ [2.50e09, 5.8, 5.8, 5.8, 2, 1, 0, 0],
157
+ [3.00e09, 6.8, 6.8, 6.8, 2, 1, 0, 0],
158
+ [3.50e09, 7.8, 7.8, 7.8, 2, 1, 0, 0],
159
+ [4.00e09, 6, 6, 6, 2, 0, 0, 0],
160
+ [4.25e09, 7, 7, 7, 2, 0, 0, 0],
161
+ ]
162
+ )
26
163
 
164
+ output = interpolate_gaps(
165
+ mag_l1b_dataset, gaps, input_norm_timeline, InterpolationFunction.linear
166
+ )
167
+
168
+ assert np.allclose(output, expected_output)
169
+
170
+
171
+ def test_mag_l1c(norm_dataset, burst_dataset):
172
+ l1c = mag_l1c(burst_dataset, norm_dataset, "v001")
173
+ assert l1c["vector_magnitude"].shape == (len(l1c["epoch"].data),)
174
+ assert l1c["vector_magnitude"].data[0] == np.linalg.norm(l1c["vectors"].data[0][:4])
175
+ assert l1c["vector_magnitude"].data[-1] == np.linalg.norm(
176
+ l1c["vectors"].data[-1][:4]
177
+ )
178
+
179
+ expected_vars = [
180
+ "vectors",
181
+ "compression_flags",
182
+ "vector_magnitude",
183
+ "generated_flag",
184
+ ]
185
+
186
+ for var in expected_vars:
187
+ assert var in l1c.data_vars
27
188
 
28
- def test_mag_attributes(mag_l1b_dataset):
29
- # Fixture from test_mag_l1b.py, since L1A and L1B are very similar
30
- mag_l1b_dataset.attrs["Logical_source"] = ["imap_mag_l1b_norm-mago"]
31
189
 
32
- output = mag_l1c(mag_l1b_dataset, mag_l1b_dataset, "v001")
190
+ def test_mag_attributes(norm_dataset, burst_dataset):
191
+ output = mag_l1c(norm_dataset, burst_dataset, "v001")
33
192
  assert output.attrs["Logical_source"] == "imap_mag_l1c_norm-mago"
34
193
 
35
- mag_l1b_dataset.attrs["Logical_source"] = ["imap_mag_l1b_norm-magi"]
194
+ expected_attrs = ["missing_sequences", "interpolation_method"]
195
+ for attr in expected_attrs:
196
+ assert attr in output.attrs
197
+
198
+
199
+ def test_find_all_gaps():
200
+ epoch_test = generate_test_epoch(5.5, [2, 2], 0, [[2, 5]])
201
+
202
+ vectors_per_second_attr = "0:2"
203
+ output = find_all_gaps(epoch_test, vectors_per_second_attr)
204
+ expected_gaps = np.array([[2, 5]]) * 1e9
205
+ assert np.array_equal(output, expected_gaps)
206
+
207
+ epoch_test = np.array([0, 0.5, 1, 1.5, 2, 4, 4.25, 4.5, 4.75, 5.5]) * 1e9
208
+ vectors_per_second_attr = "0:2,4000000000:4"
209
+ expected_gaps = np.array([[2, 4], [4.75, 5.5]]) * 1e9
210
+ output = find_all_gaps(epoch_test, vectors_per_second_attr)
211
+ assert np.array_equal(output, expected_gaps)
212
+
213
+
214
+ def test_find_gaps():
215
+ # Test should be in ns
216
+ epoch_test = generate_test_epoch(3.5, [2], 0, [[0.5, 2], [2, 3.5]])
217
+ print(epoch_test)
218
+ gaps = find_gaps(epoch_test, 2)
219
+ expected_return = np.array([[0.5, 2], [2, 3.5]]) * 1e9
220
+
221
+ assert np.array_equal(gaps, expected_return)
222
+
223
+ epoch_test = generate_test_epoch(5, [2], gaps=[[0.5, 2], [3, 4]])
224
+ gaps = find_gaps(epoch_test, 2)
225
+ expected_return = np.array([[0.5, 2], [3, 4]]) * 1e9
226
+
227
+ assert np.array_equal(gaps, expected_return)
228
+
229
+ epoch_test = generate_test_epoch(3, [4], gaps=[[0.5, 1], [2, 3]])
230
+ gaps = find_gaps(epoch_test, 4)
231
+ expected_return = np.array([[0.5, 1], [2, 3]]) * 1e9
232
+
233
+ assert np.array_equal(gaps, expected_return)
234
+
235
+
236
+ def test_generate_timeline():
237
+ epoch_test = generate_test_epoch(3, [4], gaps=[[0.5, 1], [2, 3]])
238
+
239
+ gaps = np.array([[0.5, 1], [2, 3]]) * 1e9
240
+ expected_output = np.array([0, 0.25, 0.5, 1, 1.25, 1.5, 1.75, 2, 2.5, 3]) * 1e9
241
+ output = generate_timeline(epoch_test, gaps)
242
+ assert np.array_equal(output, expected_output)
243
+
244
+ epoch_test = generate_test_epoch(5, [2], starting_point=1)
245
+ # Expected output from find_gaps if none are found
246
+ gaps = np.zeros((0, 2))
247
+ output = generate_timeline(epoch_test, gaps)
248
+ assert np.array_equal(output, epoch_test)
249
+
250
+ epoch_test = generate_test_epoch(5, [2], starting_point=1, gaps=[[3, 5]])
251
+ gaps = np.array([[3, 5]]) * 1e9
252
+
253
+ expected_output = np.array([1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5]) * 1e9
254
+ output = generate_timeline(epoch_test, gaps)
255
+ assert np.array_equal(output, expected_output)
256
+
257
+
258
+ def test_fill_normal_data(mag_l1b_dataset):
259
+ output_timeline = np.arange(0.1, 6.1, step=0.5) * 1e9
260
+ output = fill_normal_data(mag_l1b_dataset, output_timeline)
36
261
 
37
- output = mag_l1c(mag_l1b_dataset, mag_l1b_dataset, "v001")
38
- assert output.attrs["Logical_source"] == "imap_mag_l1c_norm-magi"
262
+ assert output.shape == (12, 8)
263
+ # all vectors should be nonzero
264
+ assert np.count_nonzero(output[:-2, 1:4]) == 30
265
+ # last two vectors should be zero
266
+ assert np.count_nonzero(output[-2:, 1:5]) == 0
39
267
 
40
- assert output.attrs["Data_level"] == "L1C"
268
+ # spot check
269
+ assert np.array_equal(output[0, 1:5], mag_l1b_dataset["vectors"].data[0, :])
270
+ assert np.array_equal(output[5, 1:5], mag_l1b_dataset["vectors"].data[5, :])
271
+ assert np.array_equal(output[9, 1:5], mag_l1b_dataset["vectors"].data[9, :])