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.
- imap_processing/_version.py +2 -2
- imap_processing/ccsds/excel_to_xtce.py +12 -0
- imap_processing/cdf/config/imap_codice_global_cdf_attrs.yaml +6 -6
- imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +35 -0
- imap_processing/cdf/config/imap_codice_l1b_variable_attrs.yaml +35 -0
- imap_processing/cdf/config/imap_codice_l2_variable_attrs.yaml +24 -0
- imap_processing/cdf/config/imap_hi_variable_attrs.yaml +8 -8
- imap_processing/cdf/config/imap_hit_global_cdf_attrs.yaml +1 -1
- imap_processing/cdf/config/imap_hit_l1a_variable_attrs.yaml +163 -100
- imap_processing/cdf/config/imap_hit_l2_variable_attrs.yaml +398 -415
- imap_processing/cdf/config/imap_ialirt_l1_variable_attrs.yaml +97 -54
- imap_processing/cdf/config/imap_idex_global_cdf_attrs.yaml +9 -9
- imap_processing/cdf/config/imap_idex_l2b_variable_attrs.yaml +233 -57
- imap_processing/cdf/config/imap_idex_l2c_variable_attrs.yaml +16 -90
- imap_processing/cdf/config/imap_lo_global_cdf_attrs.yaml +30 -0
- imap_processing/cdf/config/imap_mag_global_cdf_attrs.yaml +15 -1
- imap_processing/cdf/config/imap_swapi_variable_attrs.yaml +19 -0
- imap_processing/cdf/config/imap_swe_l1b_variable_attrs.yaml +20 -0
- imap_processing/cdf/config/imap_swe_l2_variable_attrs.yaml +39 -0
- imap_processing/cdf/config/imap_ultra_global_cdf_attrs.yaml +168 -0
- imap_processing/cdf/config/imap_ultra_l1a_variable_attrs.yaml +103 -2
- imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +91 -11
- imap_processing/cdf/utils.py +7 -1
- imap_processing/cli.py +42 -13
- imap_processing/codice/codice_l1a.py +125 -78
- imap_processing/codice/codice_l1b.py +1 -1
- imap_processing/codice/codice_l2.py +0 -9
- imap_processing/codice/constants.py +481 -498
- imap_processing/hi/hi_l1a.py +4 -4
- imap_processing/hi/hi_l1b.py +2 -2
- imap_processing/hi/packet_definitions/TLM_HI_COMBINED_SCI.xml +218 -38
- imap_processing/hit/hit_utils.py +2 -2
- imap_processing/hit/l0/decom_hit.py +4 -3
- imap_processing/hit/l1a/hit_l1a.py +64 -24
- imap_processing/hit/l1b/constants.py +5 -0
- imap_processing/hit/l1b/hit_l1b.py +18 -16
- imap_processing/hit/l2/constants.py +1 -1
- imap_processing/hit/l2/hit_l2.py +4 -4
- imap_processing/ialirt/constants.py +21 -0
- imap_processing/ialirt/generate_coverage.py +188 -0
- imap_processing/ialirt/l0/parse_mag.py +62 -5
- imap_processing/ialirt/l0/process_swapi.py +1 -1
- imap_processing/ialirt/l0/process_swe.py +23 -7
- imap_processing/ialirt/utils/constants.py +22 -16
- imap_processing/ialirt/utils/create_xarray.py +42 -19
- imap_processing/idex/idex_constants.py +8 -5
- imap_processing/idex/idex_l2b.py +554 -58
- imap_processing/idex/idex_l2c.py +30 -196
- imap_processing/lo/l0/lo_apid.py +1 -0
- imap_processing/lo/l0/lo_star_sensor.py +48 -0
- imap_processing/lo/l1a/lo_l1a.py +74 -30
- imap_processing/lo/packet_definitions/lo_xtce.xml +5359 -106
- imap_processing/mag/constants.py +1 -0
- imap_processing/mag/l0/decom_mag.py +9 -6
- imap_processing/mag/l0/mag_l0_data.py +46 -0
- imap_processing/mag/l1d/__init__.py +0 -0
- imap_processing/mag/l1d/mag_l1d.py +133 -0
- imap_processing/mag/l1d/mag_l1d_data.py +588 -0
- imap_processing/mag/l2/__init__.py +0 -0
- imap_processing/mag/l2/mag_l2.py +25 -20
- imap_processing/mag/l2/mag_l2_data.py +191 -130
- imap_processing/quality_flags.py +20 -2
- imap_processing/spice/geometry.py +25 -3
- imap_processing/spice/pointing_frame.py +1 -1
- imap_processing/spice/spin.py +4 -0
- imap_processing/spice/time.py +51 -0
- imap_processing/swapi/l1/swapi_l1.py +12 -2
- imap_processing/swapi/l2/swapi_l2.py +59 -14
- imap_processing/swapi/swapi_utils.py +1 -1
- imap_processing/swe/l1b/swe_l1b.py +11 -4
- imap_processing/swe/l2/swe_l2.py +111 -17
- imap_processing/ultra/constants.py +49 -1
- imap_processing/ultra/l0/decom_tools.py +28 -14
- imap_processing/ultra/l0/decom_ultra.py +225 -15
- imap_processing/ultra/l0/ultra_utils.py +281 -8
- imap_processing/ultra/l1a/ultra_l1a.py +77 -8
- imap_processing/ultra/l1b/cullingmask.py +3 -3
- imap_processing/ultra/l1b/de.py +53 -15
- imap_processing/ultra/l1b/extendedspin.py +26 -2
- imap_processing/ultra/l1b/lookup_utils.py +171 -50
- imap_processing/ultra/l1b/quality_flag_filters.py +14 -0
- imap_processing/ultra/l1b/ultra_l1b_culling.py +198 -5
- imap_processing/ultra/l1b/ultra_l1b_extended.py +304 -66
- imap_processing/ultra/l1c/helio_pset.py +54 -7
- imap_processing/ultra/l1c/spacecraft_pset.py +9 -1
- imap_processing/ultra/l1c/ultra_l1c.py +2 -0
- imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +106 -109
- imap_processing/ultra/packet_definitions/ULTRA_SCI_COMBINED.xml +3 -3
- imap_processing/ultra/utils/ultra_l1_utils.py +13 -1
- imap_processing/utils.py +20 -42
- {imap_processing-0.16.2.dist-info → imap_processing-0.18.0.dist-info}/METADATA +2 -2
- {imap_processing-0.16.2.dist-info → imap_processing-0.18.0.dist-info}/RECORD +95 -103
- imap_processing/lo/l0/data_classes/star_sensor.py +0 -98
- imap_processing/lo/l0/utils/lo_base.py +0 -57
- imap_processing/ultra/lookup_tables/Angular_Profiles_FM45_LeftSlit.csv +0 -526
- imap_processing/ultra/lookup_tables/Angular_Profiles_FM45_RightSlit.csv +0 -526
- imap_processing/ultra/lookup_tables/Angular_Profiles_FM90_LeftSlit.csv +0 -526
- imap_processing/ultra/lookup_tables/Angular_Profiles_FM90_RightSlit.csv +0 -524
- imap_processing/ultra/lookup_tables/EgyNorm.mem.csv +0 -32769
- imap_processing/ultra/lookup_tables/FM45_Startup1_ULTRA_IMGPARAMS_20240719.csv +0 -2
- imap_processing/ultra/lookup_tables/FM90_Startup1_ULTRA_IMGPARAMS_20240719.csv +0 -2
- imap_processing/ultra/lookup_tables/dps_grid45_compressed.cdf +0 -0
- imap_processing/ultra/lookup_tables/ultra45_back-pos-luts.csv +0 -4097
- imap_processing/ultra/lookup_tables/ultra45_tdc_norm.csv +0 -2050
- imap_processing/ultra/lookup_tables/ultra90_back-pos-luts.csv +0 -4097
- imap_processing/ultra/lookup_tables/ultra90_tdc_norm.csv +0 -2050
- imap_processing/ultra/lookup_tables/yadjust.csv +0 -257
- {imap_processing-0.16.2.dist-info → imap_processing-0.18.0.dist-info}/LICENSE +0 -0
- {imap_processing-0.16.2.dist-info → imap_processing-0.18.0.dist-info}/WHEEL +0 -0
- {imap_processing-0.16.2.dist-info → imap_processing-0.18.0.dist-info}/entry_points.txt +0 -0
imap_processing/idex/idex_l2c.py
CHANGED
|
@@ -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(
|
|
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
|
-
|
|
49
|
-
IDEX L2b
|
|
41
|
+
l2b_datasets : list[xarray.Dataset]
|
|
42
|
+
IDEX L2b datasets.
|
|
50
43
|
|
|
51
44
|
Returns
|
|
52
45
|
-------
|
|
53
|
-
l2b_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
|
-
#
|
|
63
|
-
#
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
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(
|
|
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
|
imap_processing/lo/l0/lo_apid.py
CHANGED
|
@@ -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
|
imap_processing/lo/l1a/lo_l1a.py
CHANGED
|
@@ -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]
|
|
60
|
-
|
|
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]
|
|
73
|
-
|
|
74
|
-
)
|
|
75
|
-
|
|
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]
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
],
|
|
89
|
-
|
|
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
|
-
|
|
94
|
-
|
|
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.
|
|
98
|
-
|
|
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
|
-
|
|
101
|
-
|
|
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
|
-
|
|
105
|
-
|
|
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(
|