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
@@ -23,26 +23,51 @@ def ultra_l1b(data_dict: dict, data_version: str) -> list[xr.Dataset]:
23
23
  -------
24
24
  output_datasets : list[xarray.Dataset]
25
25
  List of xarray.Dataset.
26
+
27
+ Notes
28
+ -----
29
+ General flow:
30
+ 1. l1a data products are created (upstream to this code)
31
+ 2. l1b de is created here and dropped in s3 kicking off processing again
32
+ 3. l1b extended, culling, badtimes created here
26
33
  """
27
34
  output_datasets = []
28
35
  instrument_id = 45 if any("45" in key for key in data_dict.keys()) else 90
29
36
 
30
- if (
31
- f"imap_ultra_l1a_{instrument_id}sensor-hk" in data_dict
32
- and f"imap_ultra_l1a_{instrument_id}sensor-de" in data_dict
33
- and f"imap_ultra_l1a_{instrument_id}sensor-rates" in data_dict
34
- ):
37
+ # L1b de data will be created if L1a de data is available
38
+ if f"imap_ultra_l1a_{instrument_id}sensor-de" in data_dict:
35
39
  de_dataset = calculate_de(
36
40
  data_dict[f"imap_ultra_l1a_{instrument_id}sensor-de"],
37
41
  f"imap_ultra_l1b_{instrument_id}sensor-de",
38
42
  data_version,
39
43
  )
44
+ output_datasets.append(de_dataset)
45
+ # L1b extended data will be created if L1a hk, rates,
46
+ # aux and l1b de data are available
47
+ elif (
48
+ f"imap_ultra_l1a_{instrument_id}sensor-hk" in data_dict
49
+ and f"imap_ultra_l1b_{instrument_id}sensor-de" in data_dict
50
+ and f"imap_ultra_l1a_{instrument_id}sensor-rates" in data_dict
51
+ and f"imap_ultra_l1a_{instrument_id}sensor-aux" in data_dict
52
+ ):
40
53
  extendedspin_dataset = calculate_extendedspin(
41
- data_dict[f"imap_ultra_l1a_{instrument_id}sensor-hk"],
42
- data_dict[f"imap_ultra_l1a_{instrument_id}sensor-rates"],
43
- de_dataset,
54
+ {
55
+ f"imap_ultra_l1a_{instrument_id}sensor-aux": data_dict[
56
+ f"imap_ultra_l1a_{instrument_id}sensor-aux"
57
+ ],
58
+ f"imap_ultra_l1a_{instrument_id}sensor-hk": data_dict[
59
+ f"imap_ultra_l1a_{instrument_id}sensor-hk"
60
+ ],
61
+ f"imap_ultra_l1a_{instrument_id}sensor-rates": data_dict[
62
+ f"imap_ultra_l1a_{instrument_id}sensor-rates"
63
+ ],
64
+ f"imap_ultra_l1b_{instrument_id}sensor-de": data_dict[
65
+ f"imap_ultra_l1b_{instrument_id}sensor-de"
66
+ ],
67
+ },
44
68
  f"imap_ultra_l1b_{instrument_id}sensor-extendedspin",
45
69
  data_version,
70
+ instrument_id,
46
71
  )
47
72
  cullingmask_dataset = calculate_cullingmask(
48
73
  extendedspin_dataset,
@@ -56,7 +81,7 @@ def ultra_l1b(data_dict: dict, data_version: str) -> list[xr.Dataset]:
56
81
  data_version,
57
82
  )
58
83
  output_datasets.extend(
59
- [de_dataset, extendedspin_dataset, cullingmask_dataset, badtimes_dataset]
84
+ [extendedspin_dataset, cullingmask_dataset, badtimes_dataset]
60
85
  )
61
86
  else:
62
87
  raise ValueError("Data dictionary does not contain the expected keys.")
@@ -1,31 +1,15 @@
1
1
  """Culls Events for ULTRA L1b."""
2
2
 
3
3
  import numpy as np
4
+ import pandas as pd
5
+ import xarray as xr
4
6
  from numpy.typing import NDArray
5
7
 
6
8
  from imap_processing.quality_flags import ImapAttitudeUltraFlags, ImapRatesUltraFlags
7
- from imap_processing.spice.spin import get_spin_data, interpolate_spin_data
9
+ from imap_processing.spice.spin import get_spin_data
8
10
  from imap_processing.ultra.constants import UltraConstants
9
11
 
10
12
 
11
- def get_spin(eventtimes_met: NDArray) -> NDArray:
12
- """
13
- Get spin number for each event.
14
-
15
- Parameters
16
- ----------
17
- eventtimes_met : NDArray
18
- Event Times in Mission Elapsed Time.
19
-
20
- Returns
21
- -------
22
- spin_number : NDArray
23
- Spin number at each event derived the from Universal Spin Table.
24
- """
25
- spin_df = interpolate_spin_data(eventtimes_met)
26
- return spin_df["spin_number"].values
27
-
28
-
29
13
  def get_energy_histogram(
30
14
  spin_number: NDArray, energy: NDArray
31
15
  ) -> tuple[NDArray, NDArray, NDArray, float]:
@@ -77,14 +61,18 @@ def get_energy_histogram(
77
61
  return hist, spin_edges, counts, mean_duration
78
62
 
79
63
 
80
- def flag_attitude(eventtimes_met: NDArray) -> tuple[NDArray, NDArray, NDArray, NDArray]:
64
+ def flag_attitude(
65
+ spin_number: NDArray, aux_dataset: xr.Dataset
66
+ ) -> tuple[NDArray, NDArray, NDArray, NDArray]:
81
67
  """
82
68
  Flag data based on attitude.
83
69
 
84
70
  Parameters
85
71
  ----------
86
- eventtimes_met : NDArray
87
- Event Times in Mission Elapsed Time.
72
+ spin_number : NDArray
73
+ Spin number at each direct event.
74
+ aux_dataset : xarray.Dataset
75
+ Auxiliary dataset.
88
76
 
89
77
  Returns
90
78
  -------
@@ -97,7 +85,7 @@ def flag_attitude(eventtimes_met: NDArray) -> tuple[NDArray, NDArray, NDArray, N
97
85
  spin_starttime : NDArray
98
86
  Spin start time.
99
87
  """
100
- spins = np.unique(get_spin(eventtimes_met)) # Get unique spins
88
+ spins = np.unique(spin_number) # Get unique spins
101
89
  spin_df = get_spin_data() # Load spin data
102
90
 
103
91
  spin_period = spin_df.loc[spin_df.spin_number.isin(spins), "spin_period_sec"]
@@ -111,6 +99,8 @@ def flag_attitude(eventtimes_met: NDArray) -> tuple[NDArray, NDArray, NDArray, N
111
99
  spin_rates.shape, ImapAttitudeUltraFlags.NONE.value, dtype=np.uint16
112
100
  )
113
101
  quality_flags[bad_spin_rate_indices] |= ImapAttitudeUltraFlags.SPINRATE.value
102
+ mismatch_indices = compare_aux_univ_spin_table(aux_dataset, spins, spin_df)
103
+ quality_flags[mismatch_indices] |= ImapAttitudeUltraFlags.AUXMISMATCH.value
114
104
 
115
105
  return quality_flags, spin_rates, spin_period, spin_starttime
116
106
 
@@ -144,15 +134,15 @@ def get_n_sigma(count_rates: NDArray, mean_duration: float, sigma: int = 6) -> N
144
134
 
145
135
 
146
136
  def flag_spin(
147
- eventtimes_met: NDArray, energy: NDArray, sigma: int = 6
137
+ spin_number: NDArray, energy: NDArray, sigma: int = 6
148
138
  ) -> tuple[NDArray, NDArray, NDArray, NDArray]:
149
139
  """
150
140
  Flag data based on counts and negative energies.
151
141
 
152
142
  Parameters
153
143
  ----------
154
- eventtimes_met : NDArray
155
- Event Times in Mission Elapsed Time.
144
+ spin_number : NDArray
145
+ Spin number at each direct event.
156
146
  energy : NDArray
157
147
  Energy data.
158
148
  sigma : int (default=6)
@@ -169,8 +159,9 @@ def flag_spin(
169
159
  n_sigma_per_energy_reshape : NDArray
170
160
  N sigma per energy.
171
161
  """
172
- spin = get_spin(eventtimes_met)
173
- count_rates, spin_edges, counts, duration = get_energy_histogram(spin, energy)
162
+ count_rates, spin_edges, counts, duration = get_energy_histogram(
163
+ spin_number, energy
164
+ )
174
165
  quality_flags = np.full(
175
166
  count_rates.shape, ImapRatesUltraFlags.NONE.value, dtype=np.uint16
176
167
  )
@@ -181,10 +172,55 @@ def flag_spin(
181
172
 
182
173
  bin_edges = np.array(UltraConstants.CULLING_ENERGY_BIN_EDGES)
183
174
  energy_midpoints = np.sqrt(bin_edges[:-1] * bin_edges[1:])
184
- spin = np.unique(spin)
175
+ spin = np.unique(spin_number)
185
176
 
186
177
  # Indices where the counts exceed the threshold
187
178
  indices_n_sigma = count_rates > threshold[:, np.newaxis]
188
179
  quality_flags[indices_n_sigma] |= ImapRatesUltraFlags.HIGHRATES.value
189
180
 
190
181
  return quality_flags, spin, energy_midpoints, threshold
182
+
183
+
184
+ def compare_aux_univ_spin_table(
185
+ aux_dataset: xr.Dataset, spins: NDArray, spin_df: pd.DataFrame
186
+ ) -> NDArray:
187
+ """
188
+ Compare the auxiliary and Universal Spin Table.
189
+
190
+ Parameters
191
+ ----------
192
+ aux_dataset : xarray.Dataset
193
+ Auxiliary dataset.
194
+ spins : np.ndarray
195
+ Array of spin numbers to compare.
196
+ spin_df : pd.DataFrame
197
+ Universal Spin Table.
198
+
199
+ Returns
200
+ -------
201
+ mismatch_indices : np.ndarray
202
+ Boolean array indicating which spins have mismatches.
203
+ """
204
+ univ_mask = np.isin(spin_df["spin_number"].values, spins)
205
+ aux_mask = np.isin(aux_dataset["SPINNUMBER"].values, spins)
206
+
207
+ filtered_univ = spin_df[univ_mask]
208
+ filtered_aux = {field: aux_dataset[field].values[aux_mask] for field in aux_dataset}
209
+
210
+ mismatch_indices = np.zeros(len(spins), dtype=bool)
211
+
212
+ fields_to_compare = [
213
+ ("TIMESPINSTART", "spin_start_sec"),
214
+ ("TIMESPINSTARTSUB", "spin_start_subsec"),
215
+ ("DURATION", "spin_period_sec"),
216
+ ("TIMESPINDATA", "spin_start_time"),
217
+ ("SPINPERIOD", "spin_period_sec"),
218
+ ]
219
+
220
+ for aux_field, spin_field in fields_to_compare:
221
+ aux_values = filtered_aux[aux_field]
222
+ spin_values = filtered_univ[spin_field].values
223
+
224
+ mismatch_indices |= aux_values != spin_values
225
+
226
+ return mismatch_indices
@@ -10,7 +10,7 @@ import xarray
10
10
  from numpy import ndarray
11
11
  from numpy.typing import NDArray
12
12
 
13
- from imap_processing.spice.geometry import cartesian_to_spherical
13
+ from imap_processing.spice.spin import get_spin_data
14
14
  from imap_processing.ultra.constants import UltraConstants
15
15
  from imap_processing.ultra.l1b.lookup_utils import (
16
16
  get_back_position,
@@ -751,31 +751,76 @@ def determine_species(tof: np.ndarray, path_length: np.ndarray, type: str) -> ND
751
751
  return species_bin
752
752
 
753
753
 
754
- def get_de_az_el(v: NDArray) -> tuple[NDArray, NDArray]:
754
+ def get_phi_theta(
755
+ front_position: tuple, back_position: tuple, d: np.ndarray
756
+ ) -> tuple[NDArray, NDArray]:
755
757
  """
756
- Compute azimuth (phi) angles and elevation (theta).
758
+ Compute the instrument angles with range -90 -> 90 degrees.
759
+
760
+ Further description is available on page 18 of
761
+ the Ultra Algorithm Theoretical Basis Document.
757
762
 
758
763
  Parameters
759
764
  ----------
760
- v : np.ndarray
761
- A NumPy array with shape (n, 3) where each
762
- row represents a vector
763
- with x, y, z-components.
765
+ front_position : tuple of floats
766
+ Front position (xf,yf) (hundredths of a millimeter).
767
+ back_position : tuple of floats
768
+ Back position (xb,yb) (hundredths of a millimeter).
769
+ d : np.ndarray
770
+ Distance from slit to foil (hundredths of a millimeter).
764
771
 
765
772
  Returns
766
773
  -------
767
- spherical_coords : np.ndarray
768
- A NumPy array with shape (n, 3), where each row contains
769
- the spherical coordinates (r, azimuth, elevation):
774
+ phi : np.array
775
+ Ultra instrument frame event azimuth.
776
+ theta : np.array
777
+ Ultra instrument frame event elevation.
778
+ """
779
+ path_length = get_path_length(front_position, back_position, d)
780
+
781
+ phi = np.arctan((front_position[1] - back_position[1]) / d)
782
+ theta = np.arcsin((front_position[0] - back_position[0]) / path_length)
783
+
784
+ return np.degrees(phi), np.degrees(theta)
785
+
770
786
 
771
- - azimuth : angle in the xy-plane
772
- In radians:
773
- output range=[0, 2*pi].
774
- - elevation : angle from the xy-plane
775
- In radians:
776
- output range=[-pi/2, pi/2].
787
+ def get_eventtimes(
788
+ spin: NDArray, phase_angle: NDArray
789
+ ) -> tuple[NDArray, NDArray, NDArray]:
777
790
  """
778
- # Compute azimuth (phi) angles and elevation (theta)
779
- spherical_coords = cartesian_to_spherical(v, degrees=False)
791
+ Get the event times.
792
+
793
+ Parameters
794
+ ----------
795
+ spin : np.ndarray
796
+ Spin number.
797
+ phase_angle : np.ndarray
798
+ Phase angle.
799
+
800
+ Returns
801
+ -------
802
+ event_times : np.ndarray
803
+ Event times.
804
+ spin_starts : np.ndarray
805
+ Spin start times.
806
+ spin_period_sec : np.ndarray
807
+ Spin period in seconds.
808
+
809
+ Notes
810
+ -----
811
+ Equation for event time:
812
+ t = t_(spin start) + t_(spin start sub)/1000 +
813
+ t_spin_period_sec * phase_angle/720
814
+ """
815
+ spin_df = get_spin_data()
816
+ index = np.searchsorted(spin_df["spin_number"].values, spin)
817
+ spin_starts = (
818
+ spin_df["spin_start_sec"].values[index]
819
+ + spin_df["spin_start_subsec"].values[index] / 1000
820
+ )
821
+
822
+ spin_period_sec = spin_df["spin_period_sec"].values[index]
823
+
824
+ event_times = spin_starts + spin_period_sec * (phase_angle / 720)
780
825
 
781
- return spherical_coords[:, 1], spherical_coords[:, 2]
826
+ return event_times, spin_starts, spin_period_sec
@@ -0,0 +1,86 @@
1
+ """Calculate Pointing Set Grids."""
2
+
3
+ import numpy as np
4
+ import pandas as pd
5
+ import xarray as xr
6
+
7
+ from imap_processing import imap_module_directory
8
+ from imap_processing.ultra.l1c.ultra_l1c_pset_bins import (
9
+ build_energy_bins,
10
+ get_background_rates,
11
+ get_spacecraft_exposure_times,
12
+ get_spacecraft_histogram,
13
+ )
14
+ from imap_processing.ultra.utils.ultra_l1_utils import create_dataset
15
+
16
+ # TODO: This is a placeholder for the API lookup table directory.
17
+ TEST_PATH = imap_module_directory / "tests" / "ultra" / "data" / "l1"
18
+
19
+
20
+ def calculate_spacecraft_pset(
21
+ de_dataset: xr.Dataset,
22
+ extendedspin_dataset: xr.Dataset,
23
+ cullingmask_dataset: xr.Dataset,
24
+ name: str,
25
+ data_version: str,
26
+ ) -> xr.Dataset:
27
+ """
28
+ Create dictionary with defined datatype for Pointing Set Grid Data.
29
+
30
+ Parameters
31
+ ----------
32
+ de_dataset : xarray.Dataset
33
+ Dataset containing de data.
34
+ extendedspin_dataset : xarray.Dataset
35
+ Dataset containing extendedspin data.
36
+ cullingmask_dataset : xarray.Dataset
37
+ Dataset containing cullingmask data.
38
+ name : str
39
+ Name of the dataset.
40
+ data_version : str
41
+ Version of the data.
42
+
43
+ Returns
44
+ -------
45
+ dataset : xarray.Dataset
46
+ Dataset containing the data.
47
+ """
48
+ pset_dict: dict[str, np.ndarray] = {}
49
+
50
+ v_mag_dps_spacecraft = np.linalg.norm(de_dataset["velocity_dps_sc"].values, axis=1)
51
+ vhat_dps_spacecraft = (
52
+ de_dataset["velocity_dps_sc"].values / v_mag_dps_spacecraft[:, np.newaxis]
53
+ )
54
+
55
+ intervals, _, energy_bin_geometric_means = build_energy_bins()
56
+ counts, latitude, longitude, n_pix = get_spacecraft_histogram(
57
+ vhat_dps_spacecraft,
58
+ de_dataset["energy_spacecraft"].values,
59
+ intervals,
60
+ nside=128,
61
+ )
62
+ healpix = np.arange(n_pix)
63
+
64
+ # calculate background rates
65
+ background_rates = get_background_rates()
66
+
67
+ # TODO: calculate sensitivity and interpolate based on energy.
68
+
69
+ # Calculate exposure
70
+ constant_exposure = TEST_PATH / "ultra_90_dps_exposure.csv"
71
+ df_exposure = pd.read_csv(constant_exposure)
72
+ exposure_pointing = get_spacecraft_exposure_times(df_exposure)
73
+
74
+ # For ISTP, epoch should be the center of the time bin.
75
+ pset_dict["epoch"] = de_dataset.epoch.data[0].astype(np.int64)
76
+ pset_dict["counts"] = counts
77
+ pset_dict["latitude"] = latitude
78
+ pset_dict["longitude"] = longitude
79
+ pset_dict["energy_bin_geometric_mean"] = energy_bin_geometric_means
80
+ pset_dict["background_rates"] = background_rates
81
+ pset_dict["exposure_factor"] = exposure_pointing
82
+ pset_dict["healpix"] = healpix
83
+
84
+ dataset = create_dataset(pset_dict, name, "l1c", data_version)
85
+
86
+ return dataset
@@ -3,7 +3,7 @@
3
3
  import xarray as xr
4
4
 
5
5
  from imap_processing.ultra.l1c.histogram import calculate_histogram
6
- from imap_processing.ultra.l1c.pset import calculate_pset
6
+ from imap_processing.ultra.l1c.spacecraft_pset import calculate_spacecraft_pset
7
7
 
8
8
 
9
9
  def ultra_l1c(data_dict: dict, data_version: str) -> list[xr.Dataset]:
@@ -39,12 +39,15 @@ def ultra_l1c(data_dict: dict, data_version: str) -> list[xr.Dataset]:
39
39
  and f"imap_ultra_l1b_{instrument_id}sensor-de" in data_dict
40
40
  and f"imap_ultra_l1b_{instrument_id}sensor-extendedspin" in data_dict
41
41
  ):
42
- pset_dataset = calculate_pset(
42
+ spacecraft_pset = calculate_spacecraft_pset(
43
43
  data_dict[f"imap_ultra_l1b_{instrument_id}sensor-de"],
44
- f"imap_ultra_l1c_{instrument_id}sensor-pset",
44
+ data_dict[f"imap_ultra_l1b_{instrument_id}sensor-extendedspin"],
45
+ data_dict[f"imap_ultra_l1b_{instrument_id}sensor-cullingmask"],
46
+ f"imap_ultra_l1c_{instrument_id}sensor-spacecraftpset",
45
47
  data_version,
46
48
  )
47
- output_datasets = [pset_dataset]
49
+ # TODO: add calculate_helio_pset here
50
+ output_datasets = [spacecraft_pset]
48
51
  else:
49
52
  raise ValueError("Data dictionary does not contain the expected keys.")
50
53