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
@@ -1,33 +1,39 @@
1
- index,mnemonic,var_name,starting_bit,nbits_padding_before,unsigned_nbits,unit,c0,c1,c2,c3,c4,c5,c6,c7,convertAs,packetName
2
- 1,current_1v_pol,idx__txhdrprochkch01,4,4,12,mA,0,0.9029253,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
3
- 2,current_1p9v_pol,idx__txhdrprochkch01,20,4,12,mA,0,0.9029253,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
4
- 3,temperature_1,idx__txhdrprochkch23,4,4,12,C,162.8276,-0.2668687,0.000332379,-2.43E-07,9.03E-11,-1.33E-14,0.00E+00,0.00E+00,UNSEGMENTED_POLY,IDEX_SCI
5
- 4,temperature_2,idx__txhdrprochkch23,20,4,12,C,162.8276,-0.2668687,0.000332379,-2.43E-07,9.03E-11,-1.33E-14,0.00E+00,0.00E+00,UNSEGMENTED_POLY,IDEX_SCI
6
- 5,voltage_1v_bus,idx__txhdrprochkch45,4,4,12,V,0,0.000805861,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
7
- 6,fpga_temperature,idx__txhdrprochkch45,20,4,12,C,358.31,-0.1187104,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
8
- 7,voltage_1p9v_bus,idx__txhdrprochkch67,4,4,12,V,0,0.000805861,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
9
- 8,voltage_3p3v_bus,idx__txhdrprochkch67,20,4,12,V,0,0.001611722,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
10
- 9,detector_voltage,idx__txhdrhvpshkch01,4,4,12,V,0,1.4652,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
11
- 10,sensor_voltage,idx__txhdrhvpshkch01,20,4,12,V,0,1.4652,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
12
- 11,target_voltage,idx__txhdrhvpshkch23,4,4,12,V,0,1.4652,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
13
- 12,reflectron_voltage,idx__txhdrhvpshkch23,20,4,12,V,0,1.4652,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
14
- 13,rejection_voltage,idx__txhdrhvpshkch45,4,4,12,V,0,1.4652,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
15
- 14,current_hvps_sensor,idx__txhdrhvpshkch45,20,4,12,mA,0,7.33E-06,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
16
- 15,positive_current_hvps,idx__txhdrhvpshkch67,4,4,12,mA,0,2.43E-05,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
17
- 16,negative_current_hvps,idx__txhdrhvpshkch67,20,4,12,mA,0,2.43E-05,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
18
- 17,voltage_3p3_ref,idx__txhdrlvhk0ch01,4,4,12,V,0,0.00161172,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
19
- 18,voltage_3p3_op_ref,idx__txhdrlvhk0ch01,20,4,12,V,0,0.00161172,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
20
- 19,voltage_neg6v_bus,idx__txhdrlvhk0ch23,4,4,12,V,-33,0.00886447,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
21
- 20,voltage_pos6v_bus,idx__txhdrlvhk0ch23,20,4,12,V,0,0.00241758,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
22
- 21,voltage_pos16v_bus,idx__txhdrlvhk0ch45,4,4,12,V,0,0.00482711,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
23
- 22,voltage_pos3p3v_bus,idx__txhdrlvhk0ch45,20,4,12,V,0,0.00161172,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
24
- 23,voltage_neg5v_bus,idx__txhdrlvhk0ch67,4,4,12,V,-33,0.00886447,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
25
- 24,voltage_pos5v_bus,idx__txhdrlvhk0ch67,20,4,12,V,0,0.00161172,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
26
- 25,current_3p3_bus,idx__txhdrlvhk1ch01,4,4,12,A,0,0.00161172,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
27
- 26,current_16v_bus,idx__txhdrlvhk1ch01,20,4,12,A,0,0.000161172,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
28
- 27,current_6v_bus,idx__txhdrlvhk1ch23,4,4,12,A,0,8.06E-05,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
29
- 28,current_neg6v_bus,idx__txhdrlvhk1ch23,20,4,12,A,0,-8.06E-05,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
30
- 29,current_5v_bus,idx__txhdrlvhk1ch45,4,4,12,A,0,4.03E-05,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
31
- 30,current_neg5v_bus,idx__txhdrlvhk1ch45,20,4,12,A,0,-2.01E-05,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
32
- 31,current_2p5v_bus,idx__txhdrlvhk1ch67,4,4,12,A,0,0.00161172,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
33
- 32,current_neg2p5v_bus,idx__txhdrlvhk1ch67,20,4,12,A,0,-4.03E-05,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
1
+ index,mnemonic,var_name,starting_bit,nbits_padding_before,unsigned_nbits,unit,dn_range_start,dn_range_stop,c0,c1,c2,c3,c4,c5,c6,c7,convertAs,packetName
2
+ 1,current_1v_pol,idx__txhdrprochkch01,4,4,12,mA,,,0,0.9029253,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
3
+ 2,current_1p9v_pol,idx__txhdrprochkch01,20,4,12,mA,,,0,0.9029253,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
4
+ 3,temperature_1,idx__txhdrprochkch23,4,4,12,C,0,2063,162.8276,-0.2668687,0.000332379,-2.43E-07,9.03E-11,-1.33E-14,0,0,SEGMENTED_POLY,IDEX_SCI
5
+ 4,temperature_1,idx__txhdrprochkch23,4,4,12,C,2064,3853,714.2124,-1.194011,0.000859909,-3.15E-07,5.75E-11,-4.21E-15,0,0,SEGMENTED_POLY,IDEX_SCI
6
+ 5,temperature_1,idx__txhdrprochkch23,4,4,12,C,4854,4051,136881.2,-105.4644,0.02710281,-2.32E-06,0,0,0,0,SEGMENTED_POLY,IDEX_SCI
7
+ 6,temperature_1,idx__txhdrprochkch23,4,4,12,C,4052,4095,-100809.9,50.03809,-0.00621209,0,0,0,0,0,SEGMENTED_POLY,IDEX_SCI
8
+ 7,temperature_2,idx__txhdrprochkch23,20,4,12,C,0,2063,162.8276,-0.2668687,0.000332379,-2.43E-07,9.03E-11,-1.33E-14,0,0,SEGMENTED_POLY,IDEX_SCI
9
+ 8,temperature_2,idx__txhdrprochkch23,20,4,12,C,2064,3853,714.2124,-1.194011,0.000859909,-3.15E-07,5.75E-11,-4.21E-15,0,0,SEGMENTED_POLY,IDEX_SCI
10
+ 9,temperature_2,idx__txhdrprochkch23,20,4,12,C,4854,4051,136881.2,-105.4644,0.02710281,-2.32E-06,0,0,0,0,SEGMENTED_POLY,IDEX_SCI
11
+ 10,temperature_2,idx__txhdrprochkch23,20,4,12,C,4052,4095,-100809.9,50.03809,-0.00621209,0,0,0,0,0,SEGMENTED_POLY,IDEX_SCI
12
+ 11,voltage_1v_bus,idx__txhdrprochkch45,4,4,12,V,,,0,0.000805861,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
13
+ 12,fpga_temperature,idx__txhdrprochkch45,20,4,12,C,,,358.31,-0.1187104,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
14
+ 13,voltage_1p9v_bus,idx__txhdrprochkch67,4,4,12,V,,,0,0.000805861,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
15
+ 14,voltage_3p3v_bus,idx__txhdrprochkch67,20,4,12,V,,,0,0.001611722,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
16
+ 15,detector_voltage,idx__txhdrhvpshkch01,4,4,12,V,,,0,1.4652,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
17
+ 16,sensor_voltage,idx__txhdrhvpshkch01,20,4,12,V,,,0,1.4652,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
18
+ 17,target_voltage,idx__txhdrhvpshkch23,4,4,12,V,,,0,1.4652,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
19
+ 18,reflectron_voltage,idx__txhdrhvpshkch23,20,4,12,V,,,0,1.4652,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
20
+ 19,rejection_voltage,idx__txhdrhvpshkch45,4,4,12,V,,,0,1.4652,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
21
+ 20,current_hvps_sensor,idx__txhdrhvpshkch45,20,4,12,mA,,,0,7.33E-06,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
22
+ 21,positive_current_hvps,idx__txhdrhvpshkch67,4,4,12,mA,,,0,2.43E-05,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
23
+ 22,negative_current_hvps,idx__txhdrhvpshkch67,20,4,12,mA,,,0,2.43E-05,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
24
+ 23,voltage_3p3_ref,idx__txhdrlvhk0ch01,4,4,12,V,,,0,0.00161172,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
25
+ 24,voltage_3p3_op_ref,idx__txhdrlvhk0ch01,20,4,12,V,,,0,0.00161172,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
26
+ 25,voltage_neg6v_bus,idx__txhdrlvhk0ch23,4,4,12,V,,,-33,0.00886447,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
27
+ 26,voltage_pos6v_bus,idx__txhdrlvhk0ch23,20,4,12,V,,,0,0.00241758,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
28
+ 27,voltage_pos16v_bus,idx__txhdrlvhk0ch45,4,4,12,V,,,0,0.00482711,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
29
+ 28,voltage_pos3p3v_bus,idx__txhdrlvhk0ch45,20,4,12,V,,,0,0.00161172,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
30
+ 29,voltage_neg5v_bus,idx__txhdrlvhk0ch67,4,4,12,V,,,-33,0.00886447,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
31
+ 30,voltage_pos5v_bus,idx__txhdrlvhk0ch67,20,4,12,V,,,0,0.00161172,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
32
+ 31,current_3p3_bus,idx__txhdrlvhk1ch01,4,4,12,A,,,0,0.00161172,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
33
+ 32,current_16v_bus,idx__txhdrlvhk1ch01,20,4,12,A,,,0,0.000161172,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
34
+ 33,current_6v_bus,idx__txhdrlvhk1ch23,4,4,12,A,,,0,8.06E-05,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
35
+ 34,current_neg6v_bus,idx__txhdrlvhk1ch23,20,4,12,A,,,0,-8.06E-05,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
36
+ 35,current_5v_bus,idx__txhdrlvhk1ch45,4,4,12,A,,,0,4.03E-05,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
37
+ 36,current_neg5v_bus,idx__txhdrlvhk1ch45,20,4,12,A,,,0,-2.01E-05,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
38
+ 37,current_2p5v_bus,idx__txhdrlvhk1ch67,4,4,12,A,,,0,0.00161172,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
39
+ 38,current_neg2p5v_bus,idx__txhdrlvhk1ch67,20,4,12,A,,,0,-4.03E-05,0,0,0,0,0,0,UNSEGMENTED_POLY,IDEX_SCI
@@ -410,6 +410,12 @@ def combine_segmented_packets(dataset: xr.Dataset) -> xr.Dataset:
410
410
  dataset.coords["epoch"] = dataset["epoch"].values[seg_starts]
411
411
  # drop any group of segmented epochs that aren't sequential
412
412
  dataset.coords["epoch"] = dataset["epoch"].values[valid_groups]
413
+ # Set met to the first segment start times for the valid groups.
414
+ # shcoarse will be retained as a per packet coordinate and met
415
+ # is used as the mission elapsed time for each segment
416
+ dataset["met"] = xr.DataArray(
417
+ dataset["shcoarse"].values[seg_starts][valid_groups], dims="epoch"
418
+ )
413
419
 
414
420
  return dataset
415
421
 
@@ -286,7 +286,6 @@ def add_dataset_attrs(
286
286
  "seq_flgs",
287
287
  "src_seq_ctr",
288
288
  "pkt_len",
289
- "shcoarse",
290
289
  "data",
291
290
  "events",
292
291
  ]
@@ -1,8 +1,8 @@
1
1
  """IMAP-Lo L1B Data Processing."""
2
2
 
3
- from collections import namedtuple
4
3
  from dataclasses import Field
5
4
  from pathlib import Path
5
+ from typing import Any, Union
6
6
 
7
7
  import numpy as np
8
8
  import xarray as xr
@@ -28,35 +28,187 @@ def lo_l1b(dependencies: dict, data_version: str) -> list[Path]:
28
28
  Location of created CDF files.
29
29
  """
30
30
  # create the attribute manager for this data level
31
- attr_mgr = ImapCdfAttributes()
32
- attr_mgr.add_instrument_global_attrs(instrument="lo")
33
- attr_mgr.add_instrument_variable_attrs(instrument="lo", level="l1b")
34
- attr_mgr.add_global_attribute("Data_version", data_version)
31
+ attr_mgr_l1b = ImapCdfAttributes()
32
+ attr_mgr_l1b.add_instrument_global_attrs(instrument="lo")
33
+ attr_mgr_l1b.add_instrument_variable_attrs(instrument="lo", level="l1b")
34
+ attr_mgr_l1b.add_global_attribute("Data_version", data_version)
35
+ # create the attribute manager to access L1A fillval attributes
36
+ attr_mgr_l1a = ImapCdfAttributes()
37
+ attr_mgr_l1a.add_instrument_variable_attrs(instrument="lo", level="l1a")
35
38
 
36
39
  # if the dependencies are used to create Annotated Direct Events
37
-
38
40
  if "imap_lo_l1a_de" in dependencies and "imap_lo_l1a_spin" in dependencies:
39
41
  logical_source = "imap_lo_l1b_de"
40
- # TODO: TEMPORARY. Need to update to use the L1B data class once that exists
41
- # and I have sample data.
42
- data_field_tup = namedtuple("data_field_tup", ["name"])
43
- data_fields = [
44
- data_field_tup("ESA_STEP"),
45
- data_field_tup("MODE"),
46
- data_field_tup("TOF0"),
47
- data_field_tup("TOF1"),
48
- data_field_tup("TOF2"),
49
- data_field_tup("TOF3"),
50
- data_field_tup("COINCIDENCE_TYPE"),
51
- data_field_tup("POS"),
52
- data_field_tup("COINCIDENCE"),
53
- data_field_tup("BADTIME"),
54
- data_field_tup("DIRECTION"),
55
- ]
42
+ # get the dependency dataset for l1b direct events
43
+ l1a_de = dependencies["imap_lo_l1a_de"]
44
+ spin_data = dependencies["imap_lo_l1a_spin"]
56
45
 
57
- dataset: list[Path] = create_datasets(attr_mgr, logical_source, data_fields) # type: ignore[arg-type]
58
- # TODO Remove once data_fields is removed from create_datasets
59
- return dataset
46
+ # Initialize the L1B DE dataset
47
+ l1b_de = initialize_l1b_de(l1a_de, attr_mgr_l1b, logical_source)
48
+ # Get the start and end times for each spin epoch
49
+ acq_start, acq_end = convert_start_end_acq_times(spin_data)
50
+ # Get the average spin durations for each epoch
51
+ avg_spin_durations = get_avg_spin_durations(acq_start, acq_end) # noqa: F841
52
+ # get spin angle (0 - 360 degrees) for each DE
53
+ spin_angle = get_spin_angle(l1a_de)
54
+ # calculate and set the spin bin based on the spin angle
55
+ # spin bins are 0 - 60 bins
56
+ l1b_de = set_spin_bin(l1b_de, spin_angle)
57
+
58
+ return [l1b_de]
59
+
60
+
61
+ def initialize_l1b_de(
62
+ l1a_de: xr.Dataset, attr_mgr_l1b: ImapCdfAttributes, logical_source: str
63
+ ) -> xr.Dataset:
64
+ """
65
+ Initialize the L1B DE dataset.
66
+
67
+ Create an empty L1B DE dataset and copy over fields from the L1A DE that will
68
+ not change during L1B processing.
69
+
70
+ Parameters
71
+ ----------
72
+ l1a_de : xarray.Dataset
73
+ The L1A DE dataset.
74
+ attr_mgr_l1b : ImapCdfAttributes
75
+ Attribute manager used to get the global attributes for the L1B DE dataset.
76
+ logical_source : str
77
+ The logical source of the direct event product.
78
+
79
+ Returns
80
+ -------
81
+ l1b_de : xarray.Dataset
82
+ The initialized L1B DE dataset.
83
+ """
84
+ l1b_de = xr.Dataset(
85
+ attrs=attr_mgr_l1b.get_global_attributes(logical_source),
86
+ )
87
+
88
+ # Copy over fields from L1A DE that will not change in L1B processing
89
+ l1b_de["pos"] = xr.DataArray(
90
+ l1a_de["pos"].values,
91
+ dims=["epoch"],
92
+ # TODO: Add pos to YAML file
93
+ # attrs=attr_mgr.get_variable_attributes("pos"),
94
+ )
95
+ l1b_de["mode"] = xr.DataArray(
96
+ l1a_de["mode"].values,
97
+ dims=["epoch"],
98
+ # TODO: Add mode to YAML file
99
+ # attrs=attr_mgr.get_variable_attributes("mode"),
100
+ )
101
+ l1b_de["absent"] = xr.DataArray(
102
+ l1a_de["coincidence_type"].values,
103
+ dims=["epoch"],
104
+ # TODO: Add absent to YAML file
105
+ # attrs=attr_mgr.get_variable_attributes("absent"),
106
+ )
107
+ l1b_de["esa_step"] = xr.DataArray(
108
+ l1a_de["esa_step"].values,
109
+ dims=["epoch"],
110
+ # TODO: Add esa_step to YAML file
111
+ # attrs=attr_mgr.get_variable_attributes("esa_step"),
112
+ )
113
+
114
+ return l1b_de
115
+
116
+
117
+ def convert_start_end_acq_times(
118
+ spin_data: xr.Dataset,
119
+ ) -> tuple[xr.DataArray, xr.DataArray]:
120
+ """
121
+ Convert the start and end times from the spin data.
122
+
123
+ The L1A spin data start and end acquisition times are stored in seconds and
124
+ subseconds (microseconds). This function converts them to a single time in seconds.
125
+
126
+ Parameters
127
+ ----------
128
+ spin_data : xarray.Dataset
129
+ The L1A Spin dataset containing the start and end acquisition times.
130
+
131
+ Returns
132
+ -------
133
+ tuple[xr.DataArray, xr.DataArray]
134
+ A tuple containing the start and end acquisition times as xarray DataArrays.
135
+ """
136
+ # Convert subseconds from microseconds to seconds
137
+ acq_start = spin_data["acq_start_sec"] + spin_data["acq_start_subsec"] * 1e-6
138
+ acq_end = spin_data["acq_end_sec"] + spin_data["acq_end_subsec"] * 1e-6
139
+ return (acq_start, acq_end)
140
+
141
+
142
+ def get_avg_spin_durations(
143
+ acq_start: xr.DataArray, acq_end: xr.DataArray
144
+ ) -> xr.DataArray:
145
+ """
146
+ Get the average spin duration for each spin epoch.
147
+
148
+ Parameters
149
+ ----------
150
+ acq_start : xarray.DataArray
151
+ The start acquisition times for each spin epoch.
152
+ acq_end : xarray.DataArray
153
+ The end acquisition times for each spin epoch.
154
+
155
+ Returns
156
+ -------
157
+ avg_spin_durations : xarray.DataArray
158
+ The average spin duration for each spin epoch.
159
+ """
160
+ # Get the avg spin duration for each spin epoch
161
+ # There are 28 spins per epoch (1 aggregated science cycle)
162
+ avg_spin_durations = (acq_end - acq_start) / 28
163
+ return avg_spin_durations
164
+
165
+
166
+ def get_spin_angle(l1a_de: xr.Dataset) -> Union[np.ndarray[np.float64], Any]:
167
+ """
168
+ Get the spin angle (0 - 360 degrees) for each DE.
169
+
170
+ Parameters
171
+ ----------
172
+ l1a_de : xarray.Dataset
173
+ The L1A DE dataset.
174
+
175
+ Returns
176
+ -------
177
+ spin_angle : np.ndarray
178
+ The spin angle for each DE.
179
+ """
180
+ de_times = l1a_de["de_time"].values
181
+ # DE Time is 12 bit DN. The max possible value is 4096
182
+ spin_angle = np.array(de_times / 4096 * 360, dtype=np.float64)
183
+ return spin_angle
184
+
185
+
186
+ def set_spin_bin(l1b_de: xr.Dataset, spin_angle: np.ndarray) -> xr.Dataset:
187
+ """
188
+ Set the spin bin (0 - 60 bins) for each Direct Event where each bin is 6 degrees.
189
+
190
+ Parameters
191
+ ----------
192
+ l1b_de : xarray.Dataset
193
+ The L1B Direct Event dataset.
194
+ spin_angle : np.ndarray
195
+ The spin angle (0-360 degrees) for each Direct Event.
196
+
197
+ Returns
198
+ -------
199
+ l1b_de : xarray.Dataset
200
+ The L1B DE dataset with the spin bin added.
201
+ """
202
+ # Get the spin bin for each DE
203
+ # Spin bins are 0 - 60 where each bin is 6 degrees
204
+ spin_bin = (spin_angle // 6).astype(int)
205
+ l1b_de["spin_bin"] = xr.DataArray(
206
+ spin_bin,
207
+ dims=["epoch"],
208
+ # TODO: Add spin angle to YAML file
209
+ # attrs=attr_mgr.get_variable_attributes("spin_bin"),
210
+ )
211
+ return l1b_de
60
212
 
61
213
 
62
214
  # TODO: This is going to work differently when I sample data.
@@ -59,6 +59,14 @@ class PrimarySensor(Enum):
59
59
  MAGI = 1
60
60
 
61
61
 
62
+ class ModeFlags(Enum):
63
+ """Enum for MAG mode flags: burst and normal (BURST + NORM)."""
64
+
65
+ NORM = 0
66
+ BURST = 1
67
+ MISSING = -1
68
+
69
+
62
70
  FIBONACCI_SEQUENCE = [
63
71
  1,
64
72
  2,
@@ -0,0 +1,6 @@
1
+ # This file describes configuration changes that are not expected to change often,
2
+ # but may change.
3
+
4
+ # interpolation method used in L1C processing
5
+ L1C_interpolation_method: "linear"
6
+
@@ -164,12 +164,19 @@ def generate_dataset(
164
164
 
165
165
  for key, value in support_data.items():
166
166
  # Time varying values
167
- if key not in ["SHCOARSE", "VECTORS"]:
168
- output[key] = xr.DataArray(
167
+ if key not in [
168
+ "SHCOARSE",
169
+ "VECTORS",
170
+ "PUS_SPARE1",
171
+ "PUS_SPARE2",
172
+ "SPARE1",
173
+ "SPARE2",
174
+ ]:
175
+ output[key.lower()] = xr.DataArray(
169
176
  value,
170
177
  name=key.lower(),
171
178
  dims=["epoch"],
172
- attrs=attribute_manager.get_variable_attributes(key),
179
+ attrs=attribute_manager.get_variable_attributes(key.lower()),
173
180
  )
174
181
 
175
182
  return output
@@ -50,7 +50,7 @@ def mag_l1a(packet_filepath: Path, data_version: str) -> list[xr.Dataset]:
50
50
  # Create attribute manager and add MAG L1A attributes and global variables
51
51
  attribute_manager = ImapCdfAttributes()
52
52
  attribute_manager.add_instrument_global_attrs("mag")
53
- attribute_manager.add_instrument_variable_attrs("mag", "l1")
53
+ attribute_manager.add_instrument_variable_attrs("mag", "l1a")
54
54
 
55
55
  attribute_manager.add_global_attribute("Data_version", data_version)
56
56
  attribute_manager.add_global_attribute("Input_files", str(input_files))
@@ -276,11 +276,6 @@ def generate_dataset(
276
276
  dataset : xarray.Dataset
277
277
  One xarray dataset with proper CDF attributes and shape containing MAG L1A data.
278
278
  """
279
- # TODO: add:
280
- # gaps_in_data global attr
281
- # magl1avectordefinition data
282
-
283
- # TODO: Just leave time in datetime64 type with vector as dtype object to avoid this
284
279
  # Get the timestamp from the end of the vector
285
280
  time_data = single_file_l1a.vectors[:, 4]
286
281
 
@@ -288,14 +283,18 @@ def generate_dataset(
288
283
  np.arange(2),
289
284
  name="compression",
290
285
  dims=["compression"],
291
- attrs=attribute_manager.get_variable_attributes("compression_attrs"),
286
+ attrs=attribute_manager.get_variable_attributes(
287
+ "compression_attrs", check_schema=False
288
+ ),
292
289
  )
293
290
 
294
291
  direction = xr.DataArray(
295
292
  np.arange(4),
296
293
  name="direction",
297
294
  dims=["direction"],
298
- attrs=attribute_manager.get_variable_attributes("direction_attrs"),
295
+ attrs=attribute_manager.get_variable_attributes(
296
+ "direction_attrs", check_schema=False
297
+ ),
299
298
  )
300
299
 
301
300
  # TODO: Epoch here refers to the start of the sample. Confirm that this is
@@ -338,6 +337,19 @@ def generate_dataset(
338
337
  "compression_label", check_schema=False
339
338
  ),
340
339
  )
340
+ global_attributes = attribute_manager.get_global_attributes(logical_file_id)
341
+ # TODO: this method won't work because these values are not in the schema.
342
+ global_attributes["is_mago"] = str(bool(single_file_l1a.is_mago))
343
+ global_attributes["is_active"] = str(bool(single_file_l1a.is_active))
344
+ global_attributes["vectors_per_second"] = (
345
+ single_file_l1a.vectors_per_second_attribute()
346
+ )
347
+ # empty arrays are removed in cdflib
348
+ global_attributes["missing_sequences"] = (
349
+ single_file_l1a.missing_sequences
350
+ if single_file_l1a.missing_sequences
351
+ else "None"
352
+ )
341
353
 
342
354
  output = xr.Dataset(
343
355
  coords={
@@ -345,13 +357,12 @@ def generate_dataset(
345
357
  "direction": direction,
346
358
  "compression": compression,
347
359
  },
348
- attrs=attribute_manager.get_global_attributes(logical_file_id),
360
+ attrs=global_attributes,
349
361
  )
362
+
350
363
  output["direction_label"] = direction_label
351
364
  output["compression_label"] = compression_label
352
365
  output["vectors"] = vectors
353
366
  output["compression_flags"] = compression_flags
354
367
 
355
- # TODO: Put is_mago and active in the header
356
-
357
368
  return output
@@ -240,6 +240,7 @@ class MagL1a:
240
240
  decode_fib_zig_zag()
241
241
  twos_complement()
242
242
  update_compression_array()
243
+ vectors_per_second_attribute()
243
244
  """
244
245
 
245
246
  is_mago: bool
@@ -285,7 +286,8 @@ class MagL1a:
285
286
  vector_sequence = packet_properties.src_seq_ctr
286
287
 
287
288
  self.vectors = np.concatenate([self.vectors, additional_vectors])
288
- self.packet_definitions[self.start_time] = packet_properties
289
+ start_time = np.int64(met_to_ttj2000ns(packet_properties.shcoarse))
290
+ self.packet_definitions[start_time] = packet_properties
289
291
 
290
292
  # Every additional packet should be the next one in the sequence, if not, add
291
293
  # the missing sequence(s) to the gap data
@@ -349,9 +351,7 @@ class MagL1a:
349
351
  cdf.utils.met_to_j2000ns.
350
352
  """
351
353
  timedelta = np.timedelta64(int(1 / vectors_per_sec * 1e9), "ns")
352
- # TODO: From finetime and coarsetime, depends per packet
353
354
  start_time_ns = start_time.to_j2000ns()
354
-
355
355
  # Calculate time skips for each vector in ns
356
356
  times = np.reshape(
357
357
  np.arange(
@@ -1092,3 +1092,28 @@ class MagL1a:
1092
1092
  value = int((value >> 1) ^ (-(value & 1)))
1093
1093
 
1094
1094
  return value
1095
+
1096
+ def vectors_per_second_attribute(self) -> str:
1097
+ """
1098
+ Generate a string describing the vectors per second.
1099
+
1100
+ Format is {start time}:{vectors per second},{start time}:{vectors per second}
1101
+ where it's only included if vectors per second changes.
1102
+
1103
+ Returns
1104
+ -------
1105
+ output_str : str
1106
+ Output string describing the vectors per second in all the packets.
1107
+ """
1108
+ output_str = ""
1109
+ last_vectors_per_second = None
1110
+ for start_time, packet in self.packet_definitions.items():
1111
+ vecsec = packet.vectors_per_second
1112
+ if vecsec != last_vectors_per_second:
1113
+ if output_str == "":
1114
+ output_str = f"{start_time}:{vecsec}"
1115
+ else:
1116
+ output_str += f",{start_time}:{vecsec}"
1117
+ last_vectors_per_second = vecsec
1118
+
1119
+ return output_str