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
@@ -0,0 +1,115 @@
1
+ <?xml version='1.0' encoding='UTF-8'?>
2
+ <xtce:SpaceSystem xmlns:xtce="http://www.omg.org/space/xtce" name="ialirt">
3
+ <xtce:Header date="2023-08-24T07:53:00MST" version="1.0" author="IMAP SDC" />
4
+ <xtce:TelemetryMetaData>
5
+ <xtce:ParameterTypeSet>
6
+ <!-- This file was manually created using content from:
7
+ I-ALiRT Packet Definitions: https://lasp.colorado.edu/galaxy/x/44nKCQ
8
+ -->
9
+ <xtce:IntegerParameterType name="uint1" signed="false">
10
+ <xtce:IntegerDataEncoding sizeInBits="1" encoding="unsigned" />
11
+ <xtce:UnitSet />
12
+ </xtce:IntegerParameterType>
13
+ <xtce:IntegerParameterType name="uint2" signed="false">
14
+ <xtce:IntegerDataEncoding sizeInBits="2" encoding="unsigned" />
15
+ <xtce:UnitSet />
16
+ </xtce:IntegerParameterType>
17
+ <xtce:IntegerParameterType name="uint3" signed="false">
18
+ <xtce:IntegerDataEncoding sizeInBits="3" encoding="unsigned" />
19
+ <xtce:UnitSet />
20
+ </xtce:IntegerParameterType>
21
+ <xtce:IntegerParameterType name="uint11" signed="false">
22
+ <xtce:IntegerDataEncoding sizeInBits="11" encoding="unsigned" />
23
+ <xtce:UnitSet />
24
+ </xtce:IntegerParameterType>
25
+ <xtce:IntegerParameterType name="uint14" signed="false">
26
+ <xtce:IntegerDataEncoding sizeInBits="14" encoding="unsigned" />
27
+ <xtce:UnitSet />
28
+ </xtce:IntegerParameterType>
29
+ <xtce:IntegerParameterType name="uint16" signed="false">
30
+ <xtce:IntegerDataEncoding sizeInBits="16" encoding="unsigned" />
31
+ <xtce:UnitSet />
32
+ </xtce:IntegerParameterType>
33
+ <xtce:IntegerParameterType name="uint24" signed="false">
34
+ <xtce:IntegerDataEncoding sizeInBits="24" encoding="unsigned" />
35
+ <xtce:UnitSet />
36
+ </xtce:IntegerParameterType>
37
+ <xtce:IntegerParameterType name="uint32" signed="false">
38
+ <xtce:IntegerDataEncoding sizeInBits="32" encoding="unsigned" />
39
+ <xtce:UnitSet />
40
+ </xtce:IntegerParameterType>
41
+ </xtce:ParameterTypeSet>
42
+ <xtce:ParameterSet>
43
+
44
+ <!--CCSDS Header Elements-->
45
+ <xtce:Parameter name="VERSION" parameterTypeRef="uint3">
46
+ <xtce:LongDescription>CCSDS Packet Version Number (always 0)</xtce:LongDescription>
47
+ </xtce:Parameter>
48
+ <xtce:Parameter name="TYPE" parameterTypeRef="uint1">
49
+ <xtce:LongDescription>CCSDS Packet Type Indicator (0=telemetry)</xtce:LongDescription>
50
+ </xtce:Parameter>
51
+ <xtce:Parameter name="SEC_HDR_FLG" parameterTypeRef="uint1">
52
+ <xtce:LongDescription>CCSDS Packet Secondary Header Flag (always 1)</xtce:LongDescription>
53
+ </xtce:Parameter>
54
+ <xtce:Parameter name="PKT_APID" parameterTypeRef="uint11">
55
+ <xtce:LongDescription>CCSDS Packet Application Process ID</xtce:LongDescription>
56
+ </xtce:Parameter>
57
+ <xtce:Parameter name="SEQ_FLGS" parameterTypeRef="uint2">
58
+ <xtce:LongDescription>CCSDS Packet Grouping Flags (3=not part of group)</xtce:LongDescription>
59
+ </xtce:Parameter>
60
+ <xtce:Parameter name="SRC_SEQ_CTR" parameterTypeRef="uint14">
61
+ <xtce:LongDescription>CCSDS Packet Sequence Count (increments with each new packet)</xtce:LongDescription>
62
+ </xtce:Parameter>
63
+ <xtce:Parameter name="PKT_LEN" parameterTypeRef="uint16">
64
+ <xtce:LongDescription>CCSDS Packet Length (number of bytes after Packet length minus 1)</xtce:LongDescription>
65
+ </xtce:Parameter>
66
+ <!-- MAG -->
67
+ <xtce:Parameter name="MAG_SHCOARSE" parameterTypeRef="uint32">
68
+ <xtce:LongDescription>MAG MET at End of Data Acquisition</xtce:LongDescription>
69
+ </xtce:Parameter>
70
+ <xtce:Parameter name="MAG_ACQ_TM_COARSE" parameterTypeRef="uint32">
71
+ <xtce:LongDescription>MAG Coarse Acquisition Time</xtce:LongDescription>
72
+ </xtce:Parameter>
73
+ <xtce:Parameter name="MAG_ACQ_TM_FINE" parameterTypeRef="uint16">
74
+ <xtce:LongDescription>MAG Fine Acquisition Time</xtce:LongDescription>
75
+ </xtce:Parameter>
76
+ <xtce:Parameter name="MAG_STATUS" parameterTypeRef="uint24">
77
+ <xtce:LongDescription>MAG Status</xtce:LongDescription>
78
+ </xtce:Parameter>
79
+ <xtce:Parameter name="MAG_DATA" parameterTypeRef="uint24">
80
+ <xtce:LongDescription>MAG Data</xtce:LongDescription>
81
+ </xtce:Parameter>
82
+ <!-- MAG -->
83
+ </xtce:ParameterSet>
84
+ <!-- End metadata -->
85
+ <xtce:ContainerSet>
86
+ <xtce:SequenceContainer name="CCSDSPacket" >
87
+ <xtce:EntryList>
88
+ <xtce:ParameterRefEntry parameterRef="VERSION" />
89
+ <xtce:ParameterRefEntry parameterRef="TYPE" />
90
+ <xtce:ParameterRefEntry parameterRef="SEC_HDR_FLG" />
91
+ <xtce:ParameterRefEntry parameterRef="PKT_APID" />
92
+ <xtce:ParameterRefEntry parameterRef="SEQ_FLGS" />
93
+ <xtce:ParameterRefEntry parameterRef="SRC_SEQ_CTR" />
94
+ <xtce:ParameterRefEntry parameterRef="PKT_LEN" />
95
+ </xtce:EntryList>
96
+ </xtce:SequenceContainer>
97
+ <xtce:SequenceContainer name="IALiRTPacket">
98
+ <xtce:BaseContainer containerRef="CCSDSPacket">
99
+ <xtce:RestrictionCriteria>
100
+ <xtce:Comparison parameterRef="PKT_APID" value="1001" useCalibratedValue="false" />
101
+ </xtce:RestrictionCriteria>
102
+ </xtce:BaseContainer>
103
+ <xtce:EntryList>
104
+ <!-- MAG -->
105
+ <xtce:ParameterRefEntry parameterRef="MAG_SHCOARSE"/>
106
+ <xtce:ParameterRefEntry parameterRef="MAG_ACQ_TM_COARSE"/>
107
+ <xtce:ParameterRefEntry parameterRef="MAG_ACQ_TM_FINE"/>
108
+ <xtce:ParameterRefEntry parameterRef="MAG_STATUS"/>
109
+ <xtce:ParameterRefEntry parameterRef="MAG_DATA"/>
110
+ <!-- MAG -->
111
+ </xtce:EntryList>
112
+ </xtce:SequenceContainer>
113
+ </xtce:ContainerSet>
114
+ </xtce:TelemetryMetaData>
115
+ </xtce:SpaceSystem>
@@ -0,0 +1,114 @@
1
+ """Common grouping functions for I-ALiRT instruments."""
2
+
3
+ import logging
4
+
5
+ import numpy as np
6
+ import xarray as xr
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+
11
+ def filter_valid_groups(grouped_data: xr.Dataset) -> xr.Dataset:
12
+ """
13
+ Filter out groups where `src_seq_ctr` diff are not 1.
14
+
15
+ Parameters
16
+ ----------
17
+ grouped_data : xr.Dataset
18
+ Dataset with a "group" coordinate.
19
+
20
+ Returns
21
+ -------
22
+ filtered_data : xr.Dataset
23
+ Filtered dataset with only valid groups remaining.
24
+ """
25
+ valid_groups = []
26
+ unique_groups = np.unique(grouped_data["group"].values)
27
+
28
+ for group in unique_groups:
29
+ src_seq_ctr = grouped_data["src_seq_ctr"][
30
+ (grouped_data["group"] == group).values
31
+ ]
32
+ src_seq_ctr_diff = np.diff(src_seq_ctr) % 16384
33
+
34
+ # Accept group only if all diffs are 1.
35
+ if np.all(src_seq_ctr_diff == 1):
36
+ valid_groups.append(group)
37
+ else:
38
+ logger.info(f"src_seq_ctr_diff != 1 for group {group}.")
39
+
40
+ filtered_data = grouped_data.where(
41
+ xr.DataArray(np.isin(grouped_data["group"], valid_groups), dims="epoch"),
42
+ drop=True,
43
+ )
44
+
45
+ return filtered_data
46
+
47
+
48
+ def find_groups(
49
+ accumulated_data: xr.Dataset,
50
+ sequence_range: tuple,
51
+ sequence_name: str,
52
+ time_name: str,
53
+ ) -> xr.Dataset:
54
+ """
55
+ Group data based on time and sequence number values.
56
+
57
+ Parameters
58
+ ----------
59
+ accumulated_data : xr.Dataset
60
+ Packets dataset accumulated over 1 min.
61
+ sequence_range : tuple
62
+ Tuple of two integers defining the range of group values.
63
+ sequence_name : str
64
+ Name of the sequence variable.
65
+ time_name : str
66
+ Name of the time variable.
67
+
68
+ Returns
69
+ -------
70
+ grouped_data : xr.Dataset
71
+ Filtered data with "group" coordinate.
72
+
73
+ Notes
74
+ -----
75
+ Filters data based on:
76
+ 1. Time values between the first and last sequence_range values.
77
+ Take out time values before sequence_range[0] and after sequence_range[-1].
78
+ 2. Sequence values src_seq_ctr between the first and
79
+ last sequence_range. These must be consecutive.
80
+ """
81
+ sorted_data = accumulated_data.sortby(time_name, ascending=True)
82
+
83
+ # Use sequence_range == 0 to define the beginning of the group.
84
+ # Find time at this index and use it as the beginning time for the group.
85
+ start_times = sorted_data[time_name][
86
+ (sorted_data[sequence_name] == sequence_range[0])
87
+ ]
88
+ start_time = start_times.min()
89
+ # Use max sequence_range to define the end of the group.
90
+ end_times = sorted_data[time_name][
91
+ ([sorted_data[sequence_name] == sequence_range[-1]][-1])
92
+ ]
93
+ end_time = end_times.max()
94
+
95
+ # Filter data before the sequence_range=0
96
+ # and after the last value of sequence_range.
97
+ grouped_data = sorted_data.where(
98
+ (sorted_data[time_name] >= start_time) & (sorted_data[time_name] <= end_time),
99
+ drop=True,
100
+ )
101
+
102
+ # Assign labels based on the start_times.
103
+ group_labels = np.searchsorted(start_times, grouped_data[time_name], side="right")
104
+ # Example:
105
+ # grouped_data.coords
106
+ # Coordinates:
107
+ # * epoch (epoch) int64 7kB 315922822184000000 ... 315923721184000000
108
+ # group (epoch) int64 7kB 1 1 1 1 1 1 1 1 1 ... 15 15 15 15 15 15 15 15 15
109
+ grouped_data = grouped_data.assign_coords(group=("epoch", group_labels))
110
+
111
+ # Filter out groups with non-sequential src_seq_ctr values.
112
+ filtered_data = filter_valid_groups(grouped_data)
113
+
114
+ return filtered_data
@@ -0,0 +1,29 @@
1
+ """Common time functions for I-ALiRT instruments."""
2
+
3
+ import xarray as xr
4
+
5
+
6
+ def calculate_time(
7
+ coarse_time: xr.DataArray, fine_time: xr.DataArray, conversion: int
8
+ ) -> xr.DataArray:
9
+ """
10
+ Calculate the time.
11
+
12
+ Parameters
13
+ ----------
14
+ coarse_time : xr.DataArray
15
+ Coarse time.
16
+ fine_time : xr.DataArray
17
+ Fine time.
18
+ conversion : int
19
+ Fine time units = 1 second.
20
+
21
+ Returns
22
+ -------
23
+ time_seconds: xr.DataArray
24
+ Calculated time.
25
+ """
26
+ fine_time_fraction = fine_time / conversion
27
+ time_seconds = coarse_time + fine_time_fraction
28
+
29
+ return time_seconds
@@ -0,0 +1,22 @@
1
+ Mass,Name
2
+ 1,H
3
+ 2,H2
4
+ 12,C
5
+ 16,O
6
+ 22,Na
7
+ 23,Mg24
8
+ 24,Mg25
9
+ 25,Mg26
10
+ 27,Si28
11
+ 28,Si29
12
+ 29,Si30
13
+ 39,K39
14
+ 39,Ca40
15
+ 40,K41
16
+ 41,Ca42
17
+ 43,Ca44
18
+ 53,Fe54
19
+ 55,Fe56
20
+ 56,Fe57
21
+ 57,Fe58
22
+ 196,Au197
@@ -174,7 +174,7 @@ def rice_decode(compressed_data: str, nbit10: bool, sample_count: int) -> list[i
174
174
 
175
175
  Returns
176
176
  -------
177
- list
177
+ list[int]
178
178
  Decompressed data as a list of integers.
179
179
  """
180
180
  # Constants:
@@ -186,7 +186,7 @@ def rice_decode(compressed_data: str, nbit10: bool, sample_count: int) -> list[i
186
186
  sub_frame_per_frame = frame_size / SUB_FRAME_SIZE
187
187
 
188
188
  bits = compressed_data
189
- out_data = []
189
+ out_data: list[int] = []
190
190
  sub_frame_count = 0
191
191
  bp = 0
192
192
  # Decode all subframes
@@ -1,6 +1,7 @@
1
1
  """Contains dataclasses to support IDEX processing."""
2
2
 
3
3
  from dataclasses import dataclass
4
+ from enum import Enum
4
5
 
5
6
 
6
7
  @dataclass
@@ -25,3 +26,27 @@ class IdexConstants:
25
26
  DATA_MAX: int = 4096
26
27
  SAMPLE_RATE_MIN: int = -130
27
28
  SAMPLE_RATE_MAX: int = 130
29
+
30
+
31
+ # FM sampling rate (quartz oscillator)
32
+ # Seconds per sample.
33
+ FM_SAMPLING_RATE = 0.0038466235767167234e-6
34
+ # Nanoseconds to seconds conversion
35
+ NS_TO_S = 1e-9
36
+ # Microseconds to seconds conversion
37
+ US_TO_S = 1e-6
38
+
39
+ TARGET_HIGH_FREQUENCY_CUTOFF = 100
40
+
41
+ TARGET_NOISE_FREQUENCY = 7000
42
+
43
+
44
+ class ConversionFactors(float, Enum):
45
+ """Conversion factor values (DN to picocoulombs) for each of the six waveforms."""
46
+
47
+ TOF_High = 2.89e-4
48
+ TOF_Low = 5.14e-4
49
+ TOF_Mid = 1.13e-2
50
+ Target_Low = 1.58e1
51
+ Target_High = 1.63e-1
52
+ Ion_Grid = 7.46e-4
@@ -162,10 +162,10 @@ def _read_waveform_bits(waveform_raw: str, high_sample: bool = True) -> list[int
162
162
 
163
163
  Returns
164
164
  -------
165
- ints : list
165
+ ints : list[int]
166
166
  List of the waveform.
167
167
  """
168
- ints = []
168
+ ints: list[int] = []
169
169
  if high_sample:
170
170
  for i in range(0, len(waveform_raw), 32):
171
171
  # 32-bit chunks, divided up into 2, 10, 10, 10
@@ -398,6 +398,7 @@ class RawDustEvent:
398
398
  # To extract the high gain bits, the bitwise right shift (>> 20) moves the bits
399
399
  # 20 positions to the right, and the mask (0b1111111111) keeps only the least
400
400
  # significant 10 bits.
401
+ # TODO use the delay corresponding to the trigger
401
402
  high_gain_delay = (packet["IDX__TXHDRSAMPDELAY"] >> 22) & 0b1111111111
402
403
  n_blocks = packet["IDX__TXHDRBLOCKS"]
403
404
 
@@ -410,22 +411,20 @@ class RawDustEvent:
410
411
  # Bits 13-16 represent the number of high sampling pre-trigger blocks.
411
412
  # We can extract this by shifting right by 16 bits and applying a mask to keep
412
413
  # the last 4 bits.
413
-
414
414
  num_low_sample_pretrigger_blocks = (n_blocks >> 6) & 0b111111
415
415
  num_high_sample_pretrigger_blocks = (n_blocks >> 16) & 0b1111
416
-
417
416
  # Calculate the low and high sample trigger times based on the high gain delay
418
417
  # and the number of high sample/low sample pretrigger blocks
419
418
  self.low_sample_trigger_time = (
420
419
  self.LOW_SAMPLE_RATE
421
420
  * (num_low_sample_pretrigger_blocks + 1)
422
421
  * self.NUMBER_SAMPLES_PER_LOW_SAMPLE_BLOCK
423
- - self.HIGH_SAMPLE_RATE * high_gain_delay
424
422
  )
425
423
  self.high_sample_trigger_time = (
426
424
  self.HIGH_SAMPLE_RATE
427
425
  * (num_high_sample_pretrigger_blocks + 1)
428
426
  * self.NUMBER_SAMPLES_PER_HIGH_SAMPLE_BLOCK
427
+ - self.HIGH_SAMPLE_RATE * high_gain_delay
429
428
  )
430
429
 
431
430
  def _parse_high_sample_waveform(self, waveform_raw: str) -> list[int]:
@@ -442,7 +441,7 @@ class RawDustEvent:
442
441
 
443
442
  Returns
444
443
  -------
445
- ints : list
444
+ ints : list[int]
446
445
  List of the high sample waveform.
447
446
  """
448
447
  samples = self.MAX_HIGH_BLOCKS * self.NUMBER_SAMPLES_PER_HIGH_SAMPLE_BLOCK
@@ -467,7 +466,7 @@ class RawDustEvent:
467
466
 
468
467
  Returns
469
468
  -------
470
- ints : list
469
+ ints : list[int]
471
470
  List of processed low sample waveform.
472
471
  """
473
472
  samples = self.MAX_LOW_BLOCKS * self.NUMBER_SAMPLES_PER_LOW_SAMPLE_BLOCK
@@ -23,6 +23,7 @@ import xarray as xr
23
23
 
24
24
  from imap_processing import imap_module_directory
25
25
  from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
26
+ from imap_processing.idex.idex_constants import ConversionFactors
26
27
  from imap_processing.spice.geometry import (
27
28
  SpiceBody,
28
29
  SpiceFrame,
@@ -38,34 +39,6 @@ from imap_processing.utils import convert_raw_to_eu
38
39
  logger = logging.getLogger(__name__)
39
40
 
40
41
 
41
- class ConversionFactors(float, Enum):
42
- """
43
- Enum class for conversion factor values.
44
-
45
- Attributes
46
- ----------
47
- TOF_High : float
48
- Time of flight high conversion factor.
49
- TOF_Low : float
50
- Time of flight low conversion factor.
51
- TOF_Mid : float
52
- Time of flight mid conversion factor.
53
- Target_Low : float
54
- Target Low conversion factor.
55
- Target_High : float
56
- Target High conversion factor.
57
- Ion_Grid : float
58
- Ion Grid conversion factor.
59
- """
60
-
61
- TOF_High = 2.89e-4
62
- TOF_Low = 5.14e-4
63
- TOF_Mid = 1.13e-2
64
- Target_Low = 1.58e1
65
- Target_High = 1.63e-1
66
- Ion_Grid = 7.46e-4
67
-
68
-
69
42
  class TriggerMode(Enum):
70
43
  """
71
44
  Enum class for data collection trigger Modes.
@@ -183,8 +156,6 @@ def idex_l1b(l1a_dataset: xr.Dataset, data_version: str) -> xr.Dataset:
183
156
  for var in vars_to_copy:
184
157
  l1b_dataset[var] = l1a_dataset[var].copy()
185
158
 
186
- # TODO: Spice data?
187
-
188
159
  logger.info("IDEX L1B science data processing completed.")
189
160
 
190
161
  return l1b_dataset
@@ -216,7 +187,9 @@ def unpack_instrument_settings(
216
187
  values are the unpacked xr.DataArrays.
217
188
  """
218
189
  telemetry_data = {}
219
-
190
+ # Unpack each instrument setting only once (remove duplicated rows for segmented
191
+ # polynomials)
192
+ var_information_df = var_information_df.drop_duplicates(subset=["mnemonic"])
220
193
  for _, row in var_information_df.iterrows():
221
194
  unpacked_name = row["mnemonic"]
222
195