imap-processing 0.16.2__py3-none-any.whl → 0.18.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 (110) hide show
  1. imap_processing/_version.py +2 -2
  2. imap_processing/ccsds/excel_to_xtce.py +12 -0
  3. imap_processing/cdf/config/imap_codice_global_cdf_attrs.yaml +6 -6
  4. imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +35 -0
  5. imap_processing/cdf/config/imap_codice_l1b_variable_attrs.yaml +35 -0
  6. imap_processing/cdf/config/imap_codice_l2_variable_attrs.yaml +24 -0
  7. imap_processing/cdf/config/imap_hi_variable_attrs.yaml +8 -8
  8. imap_processing/cdf/config/imap_hit_global_cdf_attrs.yaml +1 -1
  9. imap_processing/cdf/config/imap_hit_l1a_variable_attrs.yaml +163 -100
  10. imap_processing/cdf/config/imap_hit_l2_variable_attrs.yaml +398 -415
  11. imap_processing/cdf/config/imap_ialirt_l1_variable_attrs.yaml +97 -54
  12. imap_processing/cdf/config/imap_idex_global_cdf_attrs.yaml +9 -9
  13. imap_processing/cdf/config/imap_idex_l2b_variable_attrs.yaml +233 -57
  14. imap_processing/cdf/config/imap_idex_l2c_variable_attrs.yaml +16 -90
  15. imap_processing/cdf/config/imap_lo_global_cdf_attrs.yaml +30 -0
  16. imap_processing/cdf/config/imap_mag_global_cdf_attrs.yaml +15 -1
  17. imap_processing/cdf/config/imap_swapi_variable_attrs.yaml +19 -0
  18. imap_processing/cdf/config/imap_swe_l1b_variable_attrs.yaml +20 -0
  19. imap_processing/cdf/config/imap_swe_l2_variable_attrs.yaml +39 -0
  20. imap_processing/cdf/config/imap_ultra_global_cdf_attrs.yaml +168 -0
  21. imap_processing/cdf/config/imap_ultra_l1a_variable_attrs.yaml +103 -2
  22. imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +91 -11
  23. imap_processing/cdf/utils.py +7 -1
  24. imap_processing/cli.py +42 -13
  25. imap_processing/codice/codice_l1a.py +125 -78
  26. imap_processing/codice/codice_l1b.py +1 -1
  27. imap_processing/codice/codice_l2.py +0 -9
  28. imap_processing/codice/constants.py +481 -498
  29. imap_processing/hi/hi_l1a.py +4 -4
  30. imap_processing/hi/hi_l1b.py +2 -2
  31. imap_processing/hi/packet_definitions/TLM_HI_COMBINED_SCI.xml +218 -38
  32. imap_processing/hit/hit_utils.py +2 -2
  33. imap_processing/hit/l0/decom_hit.py +4 -3
  34. imap_processing/hit/l1a/hit_l1a.py +64 -24
  35. imap_processing/hit/l1b/constants.py +5 -0
  36. imap_processing/hit/l1b/hit_l1b.py +18 -16
  37. imap_processing/hit/l2/constants.py +1 -1
  38. imap_processing/hit/l2/hit_l2.py +4 -4
  39. imap_processing/ialirt/constants.py +21 -0
  40. imap_processing/ialirt/generate_coverage.py +188 -0
  41. imap_processing/ialirt/l0/parse_mag.py +62 -5
  42. imap_processing/ialirt/l0/process_swapi.py +1 -1
  43. imap_processing/ialirt/l0/process_swe.py +23 -7
  44. imap_processing/ialirt/utils/constants.py +22 -16
  45. imap_processing/ialirt/utils/create_xarray.py +42 -19
  46. imap_processing/idex/idex_constants.py +8 -5
  47. imap_processing/idex/idex_l2b.py +554 -58
  48. imap_processing/idex/idex_l2c.py +30 -196
  49. imap_processing/lo/l0/lo_apid.py +1 -0
  50. imap_processing/lo/l0/lo_star_sensor.py +48 -0
  51. imap_processing/lo/l1a/lo_l1a.py +74 -30
  52. imap_processing/lo/packet_definitions/lo_xtce.xml +5359 -106
  53. imap_processing/mag/constants.py +1 -0
  54. imap_processing/mag/l0/decom_mag.py +9 -6
  55. imap_processing/mag/l0/mag_l0_data.py +46 -0
  56. imap_processing/mag/l1d/__init__.py +0 -0
  57. imap_processing/mag/l1d/mag_l1d.py +133 -0
  58. imap_processing/mag/l1d/mag_l1d_data.py +588 -0
  59. imap_processing/mag/l2/__init__.py +0 -0
  60. imap_processing/mag/l2/mag_l2.py +25 -20
  61. imap_processing/mag/l2/mag_l2_data.py +191 -130
  62. imap_processing/quality_flags.py +20 -2
  63. imap_processing/spice/geometry.py +25 -3
  64. imap_processing/spice/pointing_frame.py +1 -1
  65. imap_processing/spice/spin.py +4 -0
  66. imap_processing/spice/time.py +51 -0
  67. imap_processing/swapi/l1/swapi_l1.py +12 -2
  68. imap_processing/swapi/l2/swapi_l2.py +59 -14
  69. imap_processing/swapi/swapi_utils.py +1 -1
  70. imap_processing/swe/l1b/swe_l1b.py +11 -4
  71. imap_processing/swe/l2/swe_l2.py +111 -17
  72. imap_processing/ultra/constants.py +49 -1
  73. imap_processing/ultra/l0/decom_tools.py +28 -14
  74. imap_processing/ultra/l0/decom_ultra.py +225 -15
  75. imap_processing/ultra/l0/ultra_utils.py +281 -8
  76. imap_processing/ultra/l1a/ultra_l1a.py +77 -8
  77. imap_processing/ultra/l1b/cullingmask.py +3 -3
  78. imap_processing/ultra/l1b/de.py +53 -15
  79. imap_processing/ultra/l1b/extendedspin.py +26 -2
  80. imap_processing/ultra/l1b/lookup_utils.py +171 -50
  81. imap_processing/ultra/l1b/quality_flag_filters.py +14 -0
  82. imap_processing/ultra/l1b/ultra_l1b_culling.py +198 -5
  83. imap_processing/ultra/l1b/ultra_l1b_extended.py +304 -66
  84. imap_processing/ultra/l1c/helio_pset.py +54 -7
  85. imap_processing/ultra/l1c/spacecraft_pset.py +9 -1
  86. imap_processing/ultra/l1c/ultra_l1c.py +2 -0
  87. imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +106 -109
  88. imap_processing/ultra/packet_definitions/ULTRA_SCI_COMBINED.xml +3 -3
  89. imap_processing/ultra/utils/ultra_l1_utils.py +13 -1
  90. imap_processing/utils.py +20 -42
  91. {imap_processing-0.16.2.dist-info → imap_processing-0.18.0.dist-info}/METADATA +2 -2
  92. {imap_processing-0.16.2.dist-info → imap_processing-0.18.0.dist-info}/RECORD +95 -103
  93. imap_processing/lo/l0/data_classes/star_sensor.py +0 -98
  94. imap_processing/lo/l0/utils/lo_base.py +0 -57
  95. imap_processing/ultra/lookup_tables/Angular_Profiles_FM45_LeftSlit.csv +0 -526
  96. imap_processing/ultra/lookup_tables/Angular_Profiles_FM45_RightSlit.csv +0 -526
  97. imap_processing/ultra/lookup_tables/Angular_Profiles_FM90_LeftSlit.csv +0 -526
  98. imap_processing/ultra/lookup_tables/Angular_Profiles_FM90_RightSlit.csv +0 -524
  99. imap_processing/ultra/lookup_tables/EgyNorm.mem.csv +0 -32769
  100. imap_processing/ultra/lookup_tables/FM45_Startup1_ULTRA_IMGPARAMS_20240719.csv +0 -2
  101. imap_processing/ultra/lookup_tables/FM90_Startup1_ULTRA_IMGPARAMS_20240719.csv +0 -2
  102. imap_processing/ultra/lookup_tables/dps_grid45_compressed.cdf +0 -0
  103. imap_processing/ultra/lookup_tables/ultra45_back-pos-luts.csv +0 -4097
  104. imap_processing/ultra/lookup_tables/ultra45_tdc_norm.csv +0 -2050
  105. imap_processing/ultra/lookup_tables/ultra90_back-pos-luts.csv +0 -4097
  106. imap_processing/ultra/lookup_tables/ultra90_tdc_norm.csv +0 -2050
  107. imap_processing/ultra/lookup_tables/yadjust.csv +0 -257
  108. {imap_processing-0.16.2.dist-info → imap_processing-0.18.0.dist-info}/LICENSE +0 -0
  109. {imap_processing-0.16.2.dist-info → imap_processing-0.18.0.dist-info}/WHEEL +0 -0
  110. {imap_processing-0.16.2.dist-info → imap_processing-0.18.0.dist-info}/entry_points.txt +0 -0
@@ -20,231 +20,65 @@ Examples
20
20
 
21
21
  import logging
22
22
 
23
- import astropy_healpix.healpy as hp
24
- import numpy as np
25
23
  import xarray as xr
26
24
 
27
- from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
28
25
  from imap_processing.ena_maps.ena_maps import SkyTilingType
29
- from imap_processing.ena_maps.utils.coordinates import CoordNames
30
- from imap_processing.ena_maps.utils.spatial_utils import AzElSkyGrid
31
26
  from imap_processing.idex.idex_constants import (
32
27
  IDEX_EVENT_REFERENCE_FRAME,
33
- IDEX_HEALPIX_NESTED,
34
- IDEX_HEALPIX_NSIDE,
35
28
  IDEX_SPACING_DEG,
36
29
  )
37
- from imap_processing.idex.idex_utils import get_idex_attrs
30
+ from imap_processing.idex.idex_utils import get_idex_attrs, setup_dataset
38
31
 
39
32
  logger = logging.getLogger(__name__)
40
33
 
41
34
 
42
- def idex_l2c(l2b_dataset: xr.Dataset) -> list[xr.Dataset]:
35
+ def idex_l2c(l2b_datasets: list[xr.Dataset]) -> xr.Dataset:
43
36
  """
44
37
  Will process IDEX l2b data to create l2c data products.
45
38
 
46
39
  Parameters
47
40
  ----------
48
- l2b_dataset : xarray.Dataset
49
- IDEX L2b dataset.
41
+ l2b_datasets : list[xarray.Dataset]
42
+ IDEX L2b datasets.
50
43
 
51
44
  Returns
52
45
  -------
53
- l2b_dataset : list[xarray.Dataset]
46
+ l2b_dataset : xarray.Dataset
54
47
  The``xarray`` dataset containing the science data and supporting metadata.
55
48
  """
56
- logger.info(
57
- f"Running IDEX L2C processing on datasets: "
58
- f"{l2b_dataset.attrs['Logical_source']}"
59
- )
49
+ logger.info("Running IDEX L2C processing")
60
50
  # create the attribute manager for this data level
61
51
  idex_attrs = get_idex_attrs("l2c")
62
- # Epoch should be the start of the collection period.
63
- # TODO should epoch be start of sci acquisition?
64
- epoch = xr.DataArray(
65
- l2b_dataset["epoch"].data[0:1].astype(np.int64),
66
- name="epoch",
67
- dims=["epoch"],
68
- attrs=idex_attrs.get_variable_attributes(
69
- "epoch_collection_set", check_schema=False
70
- ),
71
- )
72
- l2c_healpix_dataset = idex_healpix_map(l2b_dataset, epoch, idex_attrs)
73
- l2c_rectangular_dataset = idex_rectangular_map(l2b_dataset, epoch, idex_attrs)
74
-
75
- # TODO exposure time
76
- logger.info("IDEX L2C science data processing completed.")
77
- return [l2c_healpix_dataset, l2c_rectangular_dataset]
78
-
79
-
80
- def idex_healpix_map(
81
- l1b_dataset: xr.Dataset,
82
- epoch_da: xr.DataArray,
83
- idex_attrs: ImapCdfAttributes,
84
- nside: int = IDEX_HEALPIX_NSIDE,
85
- nested: bool = IDEX_HEALPIX_NESTED,
86
- ) -> xr.Dataset:
87
- """
88
- Create a healpix map out of a l1b dataset.
89
-
90
- Parameters
91
- ----------
92
- l1b_dataset : xarray.Dataset
93
- IDEX L2b dataset.
94
- epoch_da : xarray.DataArray
95
- Epoch data array of the collection. Size: (1,).
96
- idex_attrs : ImapCdfAttributes
97
- The attribute manager for this data level.
98
- nside : int
99
- Healpix nside parameter.
100
- nested : bool
101
- Healpix nested parameter.
102
-
103
- Returns
104
- -------
105
- map : xarray.Dataset
106
- Spatially binned dust counts in a healpix map format.
107
- """
108
- longitude = l1b_dataset["longitude"]
109
- latitude = l1b_dataset["latitude"]
110
-
111
- # Get the healpix indices
112
- hpix_idx = hp.ang2pix(
113
- nside, nest=nested, lonlat=True, theta=longitude, phi=latitude
114
- )
115
-
116
- n_pix = hp.nside2npix(nside)
117
- healpix = xr.DataArray(
118
- np.arange(n_pix),
119
- name=CoordNames.HEALPIX_INDEX.value,
120
- dims=CoordNames.HEALPIX_INDEX.value,
121
- attrs=idex_attrs.get_variable_attributes("pixel_index", check_schema=False),
122
- )
123
-
124
- # Create a histogram of the raw dust event counts for each pixel
125
- counts = np.histogram(hpix_idx, bins=n_pix, range=(0, n_pix))[0]
126
- # Add epoch dimension
127
- counts_da = xr.DataArray(
128
- counts[np.newaxis, :].astype(np.int64),
129
- name="counts",
130
- dims=("epoch", CoordNames.HEALPIX_INDEX.value),
131
- attrs=idex_attrs.get_variable_attributes("healpix_counts"),
132
- )
133
- pixel_label = xr.DataArray(
134
- healpix.astype(str),
135
- name="pixel_label",
136
- dims="pixel_index",
137
- attrs=idex_attrs.get_variable_attributes("pixel_label", check_schema=False),
138
- )
139
- l2c_dataset = xr.Dataset(
140
- coords={CoordNames.HEALPIX_INDEX.value: healpix, "epoch": epoch_da},
141
- data_vars={
142
- "counts": counts_da,
143
- "longitude": longitude,
144
- "latitude": latitude,
145
- "pixel_label": pixel_label,
146
- },
52
+ # Concat the list of l2b datasets into a single dataset
53
+ # Only concat the variables that have "epoch" as a dimension
54
+ l2b_dataset = xr.concat(
55
+ l2b_datasets, "epoch", data_vars="minimal", coords="minimal"
147
56
  )
148
- map_attrs = {
149
- "Sky_tiling_type": SkyTilingType.HEALPIX.value,
150
- "HEALPix_nside": str(nside),
151
- "HEALPix_nest": str(nested),
152
- "Spice_reference_frame": IDEX_EVENT_REFERENCE_FRAME.name,
153
- "num_points": str(n_pix),
154
- } | idex_attrs.get_global_attributes("imap_idex_l2c_sci-healpix")
155
- l2c_dataset.attrs.update(map_attrs)
156
-
157
- return l2c_dataset
158
-
159
57
 
160
- def idex_rectangular_map(
161
- l1b_dataset: xr.Dataset,
162
- epoch_da: xr.DataArray,
163
- idex_attrs: ImapCdfAttributes,
164
- spacing_deg: int = IDEX_SPACING_DEG,
165
- ) -> xr.Dataset:
166
- """
167
- Create a rectangular map out of a l1b dataset.
168
-
169
- Parameters
170
- ----------
171
- l1b_dataset : xarray.Dataset
172
- IDEX L2b dataset.
173
- epoch_da : xarray.DataArray
174
- Epoch data array of the collection. Size: (1,).
175
- idex_attrs : ImapCdfAttributes
176
- The attribute manager for this data level.
177
- spacing_deg : int
178
- The spacing in degrees for the rectangular grid.
179
-
180
- Returns
181
- -------
182
- map : xarray.Dataset
183
- Spatially binned dust counts in a rectangular map format.
184
- """
185
- # Get the rectangular grid with the specified spacing
186
- grid = AzElSkyGrid(spacing_deg)
187
- # Make sure longitude values are in the range [0, 360)
188
- longitude_wrapped = np.mod(l1b_dataset["longitude"], 360)
189
- latitude = l1b_dataset["latitude"]
190
- # Create a 2d histogram of the raw dust event counts for each pixel using the grid
191
- # bin edges
192
- counts, _, _ = np.histogram2d(
193
- longitude_wrapped, latitude, bins=[grid.az_bin_edges, grid.el_bin_edges]
194
- )
195
- counts_da = xr.DataArray(
196
- counts[np.newaxis, :, :].astype(np.int64),
197
- name="counts",
198
- dims=("epoch", "rectangular_lon_pixel", "rectangular_lat_pixel"),
199
- attrs=idex_attrs.get_variable_attributes("rectangular_counts"),
200
- )
201
- rec_lon_pixels = xr.DataArray(
202
- name="rectangular_lon_pixel",
203
- data=grid.az_bin_midpoints,
204
- dims="rectangular_lon_pixel",
205
- attrs=idex_attrs.get_variable_attributes(
206
- "rectangular_lon_pixel", check_schema=False
207
- ),
208
- )
209
- rec_lat_pixels = xr.DataArray(
210
- name="rectangular_lat_pixel",
211
- data=grid.el_bin_midpoints,
212
- dims="rectangular_lat_pixel",
213
- attrs=idex_attrs.get_variable_attributes(
214
- "rectangular_lat_pixel", check_schema=False
215
- ),
216
- )
217
-
218
- l2c_dataset = xr.Dataset(
219
- coords={
220
- "epoch": epoch_da,
221
- "rectangular_lon_pixel": rec_lon_pixels,
222
- "rectangular_lat_pixel": rec_lat_pixels,
223
- },
224
- data_vars={
225
- "counts": counts_da,
226
- "longitude": longitude_wrapped,
227
- "latitude": latitude,
228
- "rectangular_lon_pixel_label": rec_lon_pixels.astype(str),
229
- "rectangular_lat_pixel_label": rec_lat_pixels.astype(str),
230
- },
231
- )
232
- l2c_dataset[
233
- "rectangular_lon_pixel_label"
234
- ].attrs = idex_attrs.get_variable_attributes(
235
- "rectangular_lon_pixel_label", check_schema=False
236
- )
237
- l2c_dataset[
238
- "rectangular_lat_pixel_label"
239
- ].attrs = idex_attrs.get_variable_attributes(
240
- "rectangular_lat_pixel_label", check_schema=False
241
- )
58
+ arrays_to_copy = [
59
+ "counts_by_charge_map",
60
+ "counts_by_mass_map",
61
+ "rate_by_charge_map",
62
+ "rate_by_mass_map",
63
+ "epoch",
64
+ "impact_day_of_year",
65
+ "impact_charge_bins",
66
+ "mass_bins",
67
+ "charge_labels",
68
+ "mass_labels",
69
+ "rectangular_lon_pixel_label",
70
+ "rectangular_lat_pixel_label",
71
+ ]
72
+
73
+ l2c_dataset = setup_dataset(l2b_dataset, arrays_to_copy, idex_attrs)
74
+
75
+ # Add map attributes
242
76
  map_attrs = {
243
77
  "sky_tiling_type": SkyTilingType.RECTANGULAR.value,
244
- "Spacing_degrees": str(spacing_deg),
78
+ "Spacing_degrees": str(IDEX_SPACING_DEG),
245
79
  "Spice_reference_frame": IDEX_EVENT_REFERENCE_FRAME.name,
246
- "num_points": str(counts.size),
247
80
  } | idex_attrs.get_global_attributes("imap_idex_l2c_sci-rectangular")
248
81
 
249
82
  l2c_dataset.attrs.update(map_attrs)
83
+ logger.info("IDEX L2C science data processing completed.")
250
84
  return l2c_dataset
@@ -13,3 +13,4 @@ class LoAPID(IntEnum):
13
13
  ILO_SCI_DE = 706 # Science direct event data
14
14
  ILO_STAR = 707 # Science star sensor data, every spin
15
15
  ILO_SPIN = 708 # Spin information for each science cycle (28 spins)
16
+ ILO_DIAG_PCC = 725 # Diagnostic pivot platform information
@@ -0,0 +1,48 @@
1
+ """Processing function for Lo star sensor data."""
2
+
3
+ import logging
4
+
5
+ import numpy as np
6
+ import xarray as xr
7
+
8
+ from imap_processing.lo.l0.utils.bit_decompression import (
9
+ DECOMPRESSION_TABLES,
10
+ Decompress,
11
+ )
12
+
13
+ logger = logging.getLogger(__name__)
14
+ logger.setLevel(logging.INFO)
15
+
16
+
17
+ def process_star_sensor(ds: xr.Dataset) -> xr.Dataset:
18
+ """
19
+ Process Lo star sensor data.
20
+
21
+ Parameters
22
+ ----------
23
+ ds : xr.Dataset
24
+ The packet dataset containing Lo star sensor data.
25
+
26
+ Returns
27
+ -------
28
+ xr.Dataset
29
+ Processed dataset with a decompressed data field.
30
+ """
31
+ # Make one long flat buffer
32
+ # This assumes that all data_compressed entries are of the same length
33
+ # but allows for only one frombuffer call
34
+ buffer = b"".join(ds["data_compressed"].values)
35
+ data = np.frombuffer(buffer, dtype=np.uint8).reshape(-1, 720)
36
+
37
+ # Decompress from 8 -> 12 bits using the decompression tables
38
+ decompression = DECOMPRESSION_TABLES[Decompress.DECOMPRESS8TO12].astype(np.uint16)
39
+ # Use the mean value column (2)
40
+ data = decompression[data, 2]
41
+
42
+ # There is already a variable called "count" in the dataset that
43
+ # came with the packet
44
+ ds["data_index"] = xr.DataArray(np.arange(720), dims="data_index")
45
+ ds["data"] = xr.DataArray(data, dims=("epoch", "data_index"))
46
+ # Remove the original compressed data field
47
+ ds = ds.drop_vars("data_compressed")
48
+ return ds
@@ -15,6 +15,7 @@ from imap_processing.lo.l0.lo_science import (
15
15
  parse_events,
16
16
  parse_histogram,
17
17
  )
18
+ from imap_processing.lo.l0.lo_star_sensor import process_star_sensor
18
19
  from imap_processing.utils import convert_to_binary_string, packet_file_to_datasets
19
20
 
20
21
  logger = logging.getLogger(__name__)
@@ -44,66 +45,109 @@ def lo_l1a(dependency: Path) -> list[xr.Dataset]:
44
45
  xtce_packet_definition=xtce_file.resolve(),
45
46
  use_derived_value=False,
46
47
  )
48
+ datasets_by_apid_derived = packet_file_to_datasets(
49
+ packet_file=dependency.resolve(),
50
+ xtce_packet_definition=xtce_file.resolve(),
51
+ use_derived_value=True,
52
+ )
47
53
 
48
54
  # create the attribute manager for this data level
49
55
  attr_mgr = ImapCdfAttributes()
50
56
  attr_mgr.add_instrument_global_attrs(instrument="lo")
51
57
  attr_mgr.add_instrument_variable_attrs(instrument="lo", level="l1a")
52
58
 
59
+ datasets_to_return = []
60
+
53
61
  if LoAPID.ILO_SPIN in datasets_by_apid:
54
62
  logger.info(
55
63
  f"\nProcessing {LoAPID(LoAPID.ILO_SPIN).name} "
56
64
  f"packet (APID: {LoAPID.ILO_SPIN.value})"
57
65
  )
58
66
  logical_source = "imap_lo_l1a_spin"
59
- datasets_by_apid[LoAPID.ILO_SPIN] = organize_spin_data(
60
- datasets_by_apid[LoAPID.ILO_SPIN], attr_mgr
61
- )
62
-
63
- datasets_by_apid[LoAPID.ILO_SPIN] = add_dataset_attrs(
64
- datasets_by_apid[LoAPID.ILO_SPIN], attr_mgr, logical_source
65
- )
67
+ ds = datasets_by_apid[LoAPID.ILO_SPIN]
68
+ ds = organize_spin_data(ds, attr_mgr)
69
+ ds = add_dataset_attrs(ds, attr_mgr, logical_source)
70
+ datasets_to_return.append(ds)
66
71
  if LoAPID.ILO_SCI_CNT in datasets_by_apid:
67
72
  logger.info(
68
73
  f"\nProcessing {LoAPID(LoAPID.ILO_SCI_CNT).name} "
69
74
  f"packet (APID: {LoAPID.ILO_SCI_CNT.value})"
70
75
  )
71
76
  logical_source = "imap_lo_l1a_histogram"
72
- datasets_by_apid[LoAPID.ILO_SCI_CNT] = parse_histogram(
73
- datasets_by_apid[LoAPID.ILO_SCI_CNT], attr_mgr
74
- )
75
- datasets_by_apid[LoAPID.ILO_SCI_CNT] = add_dataset_attrs(
76
- datasets_by_apid[LoAPID.ILO_SCI_CNT], attr_mgr, logical_source
77
- )
77
+ ds = datasets_by_apid[LoAPID.ILO_SCI_CNT]
78
+ ds = parse_histogram(ds, attr_mgr)
79
+ ds = add_dataset_attrs(ds, attr_mgr, logical_source)
80
+ datasets_to_return.append(ds)
78
81
  if LoAPID.ILO_SCI_DE in datasets_by_apid:
79
82
  logger.info(
80
83
  f"\nProcessing {LoAPID(LoAPID.ILO_SCI_DE).name} "
81
84
  f"packet (APID: {LoAPID.ILO_SCI_DE.value})"
82
85
  )
83
86
  logical_source = "imap_lo_l1a_de"
84
- datasets_by_apid[LoAPID.ILO_SCI_DE]["data"] = xr.DataArray(
85
- [
86
- convert_to_binary_string(data)
87
- for data in datasets_by_apid[LoAPID.ILO_SCI_DE]["data"].values
88
- ],
89
- dims=datasets_by_apid[LoAPID.ILO_SCI_DE]["data"].dims,
90
- attrs=datasets_by_apid[LoAPID.ILO_SCI_DE]["data"].attrs,
87
+ ds = datasets_by_apid[LoAPID.ILO_SCI_DE]
88
+ # Process the "data" array into a string
89
+ ds["data"] = xr.DataArray(
90
+ [convert_to_binary_string(data) for data in ds["data"].values],
91
+ dims=ds["data"].dims,
92
+ attrs=ds["data"].attrs,
91
93
  )
92
94
 
93
- datasets_by_apid[LoAPID.ILO_SCI_DE] = combine_segmented_packets(
94
- datasets_by_apid[LoAPID.ILO_SCI_DE]
95
+ ds = combine_segmented_packets(ds)
96
+ ds = parse_events(ds, attr_mgr)
97
+ ds = add_dataset_attrs(ds, attr_mgr, logical_source)
98
+ datasets_to_return.append(ds)
99
+ if LoAPID.ILO_STAR in datasets_by_apid:
100
+ logger.info(
101
+ f"\nProcessing {LoAPID(LoAPID.ILO_STAR).name} "
102
+ f"packet (APID: {LoAPID.ILO_STAR.value})"
95
103
  )
96
-
97
- datasets_by_apid[LoAPID.ILO_SCI_DE] = parse_events(
98
- datasets_by_apid[LoAPID.ILO_SCI_DE], attr_mgr
104
+ logical_source = "imap_lo_l1a_star"
105
+ ds = datasets_by_apid[LoAPID.ILO_STAR]
106
+ ds = process_star_sensor(ds)
107
+ ds = add_dataset_attrs(ds, attr_mgr, logical_source)
108
+ datasets_to_return.append(ds)
109
+ if LoAPID.ILO_DIAG_PCC in datasets_by_apid:
110
+ logger.info(
111
+ f"\nProcessing {LoAPID(LoAPID.ILO_DIAG_PCC).name} "
112
+ f"packet (APID: {LoAPID.ILO_DIAG_PCC.value})"
99
113
  )
100
- datasets_by_apid[LoAPID.ILO_SCI_DE] = add_dataset_attrs(
101
- datasets_by_apid[LoAPID.ILO_SCI_DE], attr_mgr, logical_source
114
+ logical_source = "imap_lo_l1a_pcc"
115
+ ds = datasets_by_apid[LoAPID.ILO_DIAG_PCC]
116
+ ds = add_dataset_attrs(ds, attr_mgr, logical_source)
117
+ datasets_to_return.append(ds)
118
+ if LoAPID.ILO_APP_NHK in datasets_by_apid:
119
+ logger.info(
120
+ f"\nProcessing {LoAPID(LoAPID.ILO_APP_NHK).name} "
121
+ f"packet (APID: {LoAPID.ILO_APP_NHK.value})"
102
122
  )
123
+ logical_source = "imap_lo_l1a_nhk"
124
+ ds = datasets_by_apid[LoAPID.ILO_APP_NHK]
125
+ ds = add_dataset_attrs(ds, attr_mgr, logical_source)
126
+ datasets_to_return.append(ds)
127
+
128
+ # Engineering units conversion
129
+ logical_source = "imap_lo_l1b_nhk"
130
+ ds = datasets_by_apid_derived[LoAPID.ILO_APP_NHK]
131
+ ds = add_dataset_attrs(ds, attr_mgr, logical_source)
132
+ datasets_to_return.append(ds)
133
+ if LoAPID.ILO_APP_SHK in datasets_by_apid:
134
+ logger.info(
135
+ f"\nProcessing {LoAPID(LoAPID.ILO_APP_SHK).name} "
136
+ f"packet (APID: {LoAPID.ILO_APP_SHK.value})"
137
+ )
138
+ logical_source = "imap_lo_l1a_shk"
139
+ ds = datasets_by_apid[LoAPID.ILO_APP_SHK]
140
+ ds = add_dataset_attrs(ds, attr_mgr, logical_source)
141
+ datasets_to_return.append(ds)
142
+
143
+ # Engineering units conversion
144
+ logical_source = "imap_lo_l1b_shk"
145
+ ds = datasets_by_apid_derived[LoAPID.ILO_APP_SHK]
146
+ ds = add_dataset_attrs(ds, attr_mgr, logical_source)
147
+ datasets_to_return.append(ds)
103
148
 
104
- good_apids = [LoAPID.ILO_SPIN, LoAPID.ILO_SCI_CNT, LoAPID.ILO_SCI_DE]
105
- logger.info(f"\nReturning datasets: {[LoAPID(apid) for apid in good_apids]}")
106
- return [datasets_by_apid[good_apid] for good_apid in good_apids]
149
+ logger.info(f"Returning [{len(datasets_to_return)}] datasets")
150
+ return datasets_to_return
107
151
 
108
152
 
109
153
  def add_dataset_attrs(