imap-processing 0.7.0__py3-none-any.whl → 0.8.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/__init__.py +1 -1
- imap_processing/_version.py +2 -2
- imap_processing/ccsds/excel_to_xtce.py +34 -2
- imap_processing/cdf/config/imap_codice_global_cdf_attrs.yaml +1 -1
- imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +145 -30
- imap_processing/cdf/config/imap_glows_l1b_variable_attrs.yaml +36 -36
- imap_processing/cdf/config/imap_hi_variable_attrs.yaml +36 -8
- imap_processing/cdf/config/imap_hit_l1b_variable_attrs.yaml +9 -0
- imap_processing/cdf/config/imap_idex_global_cdf_attrs.yaml +7 -7
- imap_processing/cdf/config/imap_idex_l1a_variable_attrs.yaml +32 -33
- imap_processing/cdf/config/imap_mag_l1_variable_attrs.yaml +24 -28
- imap_processing/cdf/config/imap_ultra_l1a_variable_attrs.yaml +1 -0
- imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +133 -78
- imap_processing/cdf/config/imap_variable_schema.yaml +13 -0
- imap_processing/cdf/imap_cdf_manager.py +31 -27
- imap_processing/cli.py +12 -10
- imap_processing/codice/codice_l1a.py +151 -61
- imap_processing/codice/constants.py +1 -1
- imap_processing/codice/decompress.py +4 -9
- imap_processing/codice/utils.py +1 -0
- imap_processing/glows/l1b/glows_l1b.py +3 -3
- imap_processing/glows/l1b/glows_l1b_data.py +59 -37
- imap_processing/glows/l2/glows_l2_data.py +123 -0
- imap_processing/hi/l1a/histogram.py +1 -1
- imap_processing/hi/l1a/science_direct_event.py +1 -1
- imap_processing/hi/l1b/hi_l1b.py +85 -11
- imap_processing/hi/l1c/hi_l1c.py +23 -1
- imap_processing/hi/utils.py +1 -1
- imap_processing/hit/hit_utils.py +221 -0
- imap_processing/hit/l0/constants.py +118 -0
- imap_processing/hit/l0/decom_hit.py +186 -153
- imap_processing/hit/l1a/hit_l1a.py +20 -175
- imap_processing/hit/l1b/hit_l1b.py +33 -153
- imap_processing/idex/idex_l1a.py +10 -9
- imap_processing/lo/l0/decompression_tables/decompression_tables.py +1 -1
- imap_processing/lo/l0/lo_science.py +1 -1
- imap_processing/lo/packet_definitions/lo_xtce.xml +1 -3296
- imap_processing/mag/l0/decom_mag.py +4 -3
- imap_processing/mag/l1a/mag_l1a.py +11 -11
- imap_processing/mag/l1b/mag_l1b.py +89 -7
- imap_processing/spice/geometry.py +126 -4
- imap_processing/swapi/l1/swapi_l1.py +1 -1
- imap_processing/swapi/l2/swapi_l2.py +1 -1
- imap_processing/swe/l1b/swe_l1b_science.py +8 -8
- imap_processing/tests/ccsds/test_data/expected_output.xml +1 -0
- imap_processing/tests/ccsds/test_excel_to_xtce.py +4 -4
- imap_processing/tests/cdf/test_imap_cdf_manager.py +0 -10
- imap_processing/tests/codice/conftest.py +1 -17
- imap_processing/tests/codice/data/imap_codice_l0_raw_20241110_v001.pkts +0 -0
- imap_processing/tests/codice/test_codice_l0.py +8 -2
- imap_processing/tests/codice/test_codice_l1a.py +127 -107
- imap_processing/tests/codice/test_codice_l1b.py +1 -0
- imap_processing/tests/codice/test_decompress.py +7 -7
- imap_processing/tests/conftest.py +54 -15
- imap_processing/tests/glows/conftest.py +6 -0
- imap_processing/tests/glows/test_glows_l1b.py +9 -9
- imap_processing/tests/glows/test_glows_l1b_data.py +9 -9
- imap_processing/tests/glows/test_glows_l2_data.py +0 -0
- imap_processing/tests/hi/test_data/l1a/imap_hi_l1a_45sensor-de_20250415_v000.cdf +0 -0
- imap_processing/tests/hi/test_hi_l1b.py +71 -1
- imap_processing/tests/hi/test_hi_l1c.py +10 -2
- imap_processing/tests/hi/test_utils.py +4 -3
- imap_processing/tests/hit/{test_hit_decom.py → test_decom_hit.py} +84 -35
- imap_processing/tests/hit/test_hit_l1a.py +2 -197
- imap_processing/tests/hit/test_hit_l1b.py +156 -25
- imap_processing/tests/hit/test_hit_utils.py +218 -0
- imap_processing/tests/idex/conftest.py +1 -1
- imap_processing/tests/idex/imap_idex_l0_raw_20231214_v001.pkts +0 -0
- imap_processing/tests/idex/impact_14_tof_high_data.txt +4444 -4444
- imap_processing/tests/idex/test_idex_l0.py +3 -3
- imap_processing/tests/idex/test_idex_l1a.py +1 -1
- imap_processing/tests/lo/test_lo_science.py +2 -2
- imap_processing/tests/mag/imap_mag_l1a_norm-magi_20251017_v001.cdf +0 -0
- imap_processing/tests/mag/test_mag_l1b.py +59 -3
- imap_processing/tests/spice/test_data/imap_ena_sim_metakernel.template +3 -1
- imap_processing/tests/spice/test_geometry.py +84 -4
- imap_processing/tests/swe/conftest.py +33 -0
- imap_processing/tests/swe/l1_validation/swe_l0_unpacked-data_20240510_v001_VALIDATION_L1B_v3.dat +4332 -0
- imap_processing/tests/swe/test_swe_l1b.py +29 -8
- imap_processing/tests/test_utils.py +1 -1
- imap_processing/tests/ultra/test_data/l1/dps_exposure_helio_45_E12.cdf +0 -0
- imap_processing/tests/ultra/test_data/l1/dps_exposure_helio_45_E24.cdf +0 -0
- imap_processing/tests/ultra/unit/test_de.py +108 -0
- imap_processing/tests/ultra/unit/test_ultra_l1b.py +27 -3
- imap_processing/tests/ultra/unit/test_ultra_l1b_annotated.py +31 -10
- imap_processing/tests/ultra/unit/test_ultra_l1b_extended.py +21 -11
- imap_processing/tests/ultra/unit/test_ultra_l1c_pset_bins.py +9 -44
- imap_processing/ultra/constants.py +8 -3
- imap_processing/ultra/l1b/de.py +174 -30
- imap_processing/ultra/l1b/ultra_l1b_annotated.py +24 -10
- imap_processing/ultra/l1b/ultra_l1b_extended.py +21 -14
- imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +70 -119
- {imap_processing-0.7.0.dist-info → imap_processing-0.8.0.dist-info}/METADATA +15 -14
- {imap_processing-0.7.0.dist-info → imap_processing-0.8.0.dist-info}/RECORD +98 -113
- imap_processing/cdf/cdf_attribute_manager.py +0 -322
- imap_processing/cdf/config/shared/default_global_cdf_attrs_schema.yaml +0 -246
- imap_processing/cdf/config/shared/default_variable_cdf_attrs_schema.yaml +0 -466
- imap_processing/hit/l0/data_classes/housekeeping.py +0 -240
- imap_processing/hit/l0/data_classes/science_packet.py +0 -259
- imap_processing/hit/l0/utils/hit_base.py +0 -57
- imap_processing/tests/cdf/shared/default_global_cdf_attrs_schema.yaml +0 -246
- imap_processing/tests/cdf/shared/default_variable_cdf_attrs_schema.yaml +0 -466
- imap_processing/tests/cdf/test_cdf_attribute_manager.py +0 -353
- imap_processing/tests/codice/data/imap_codice_l0_hi-counters-aggregated_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_hi-counters-singles_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_hi-omni_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_hi-pha_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_hi-sectored_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_hskp_20100101_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_lo-counters-aggregated_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_lo-counters-singles_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_lo-nsw-angular_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_lo-nsw-priority_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_lo-nsw-species_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_lo-pha_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_lo-sw-angular_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_lo-sw-priority_20240429_v001.pkts +0 -0
- imap_processing/tests/codice/data/imap_codice_l0_lo-sw-species_20240429_v001.pkts +0 -0
- imap_processing/tests/idex/imap_idex_l0_raw_20230725_v001.pkts +0 -0
- imap_processing/tests/mag/imap_mag_l1a_burst-magi_20231025_v001.cdf +0 -0
- /imap_processing/tests/hit/test_data/{imap_hit_l0_hk_20100105_v001.pkts → imap_hit_l0_raw_20100105_v001.pkts} +0 -0
- {imap_processing-0.7.0.dist-info → imap_processing-0.8.0.dist-info}/LICENSE +0 -0
- {imap_processing-0.7.0.dist-info → imap_processing-0.8.0.dist-info}/WHEEL +0 -0
- {imap_processing-0.7.0.dist-info → imap_processing-0.8.0.dist-info}/entry_points.txt +0 -0
|
@@ -1,39 +1,23 @@
|
|
|
1
1
|
"""Decommutate HIT CCSDS data and create L1a data products."""
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from enum import IntEnum
|
|
5
4
|
|
|
6
|
-
import numpy as np
|
|
7
5
|
import xarray as xr
|
|
8
6
|
|
|
9
|
-
from imap_processing import imap_module_directory
|
|
10
7
|
from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
|
|
11
|
-
from imap_processing.
|
|
8
|
+
from imap_processing.hit.hit_utils import (
|
|
9
|
+
HitAPID,
|
|
10
|
+
get_attribute_manager,
|
|
11
|
+
get_datasets_by_apid,
|
|
12
|
+
process_housekeeping_data,
|
|
13
|
+
)
|
|
14
|
+
from imap_processing.hit.l0.decom_hit import decom_hit
|
|
12
15
|
|
|
13
16
|
logger = logging.getLogger(__name__)
|
|
14
17
|
|
|
15
18
|
# TODO review logging levels to use (debug vs. info)
|
|
16
19
|
|
|
17
20
|
|
|
18
|
-
class HitAPID(IntEnum):
|
|
19
|
-
"""
|
|
20
|
-
HIT APID Mappings.
|
|
21
|
-
|
|
22
|
-
Attributes
|
|
23
|
-
----------
|
|
24
|
-
HIT_HSKP: int
|
|
25
|
-
Housekeeping
|
|
26
|
-
HIT_SCIENCE : int
|
|
27
|
-
Science
|
|
28
|
-
HIT_IALRT : int
|
|
29
|
-
I-ALiRT
|
|
30
|
-
"""
|
|
31
|
-
|
|
32
|
-
HIT_HSKP = 1251
|
|
33
|
-
HIT_SCIENCE = 1252
|
|
34
|
-
HIT_IALRT = 1253
|
|
35
|
-
|
|
36
|
-
|
|
37
21
|
def hit_l1a(packet_file: str, data_version: str) -> list[xr.Dataset]:
|
|
38
22
|
"""
|
|
39
23
|
Will process HIT L0 data into L1A data products.
|
|
@@ -50,29 +34,19 @@ def hit_l1a(packet_file: str, data_version: str) -> list[xr.Dataset]:
|
|
|
50
34
|
processed_data : list[xarray.Dataset]
|
|
51
35
|
List of Datasets of L1A processed data.
|
|
52
36
|
"""
|
|
53
|
-
#
|
|
54
|
-
|
|
55
|
-
# Unpack ccsds file
|
|
56
|
-
packet_definition = (
|
|
57
|
-
imap_module_directory / "hit/packet_definitions/hit_packet_definitions.xml"
|
|
58
|
-
)
|
|
59
|
-
datasets_by_apid = packet_file_to_datasets(
|
|
60
|
-
packet_file=packet_file,
|
|
61
|
-
xtce_packet_definition=packet_definition,
|
|
62
|
-
use_derived_value=False,
|
|
63
|
-
)
|
|
37
|
+
# Unpack ccsds file to xarray datasets
|
|
38
|
+
datasets_by_apid = get_datasets_by_apid(packet_file)
|
|
64
39
|
|
|
65
40
|
# Create the attribute manager for this data level
|
|
66
|
-
attr_mgr =
|
|
67
|
-
attr_mgr.add_instrument_global_attrs(instrument="hit")
|
|
68
|
-
attr_mgr.add_instrument_variable_attrs(instrument="hit", level="l1a")
|
|
69
|
-
attr_mgr.add_global_attribute("Data_version", data_version)
|
|
41
|
+
attr_mgr = get_attribute_manager(data_version, "l1a")
|
|
70
42
|
|
|
71
|
-
# Process
|
|
43
|
+
# Process l1a data products
|
|
72
44
|
if HitAPID.HIT_HSKP in datasets_by_apid:
|
|
73
|
-
|
|
74
|
-
|
|
45
|
+
logger.info("Creating HIT L1A housekeeping dataset")
|
|
46
|
+
datasets_by_apid[HitAPID.HIT_HSKP] = process_housekeeping_data(
|
|
47
|
+
datasets_by_apid[HitAPID.HIT_HSKP], attr_mgr, "imap_hit_l1a_hk"
|
|
75
48
|
)
|
|
49
|
+
|
|
76
50
|
if HitAPID.HIT_SCIENCE in datasets_by_apid:
|
|
77
51
|
# TODO complete science data processing
|
|
78
52
|
print("Skipping science data for now")
|
|
@@ -83,44 +57,6 @@ def hit_l1a(packet_file: str, data_version: str) -> list[xr.Dataset]:
|
|
|
83
57
|
return list(datasets_by_apid.values())
|
|
84
58
|
|
|
85
59
|
|
|
86
|
-
def concatenate_leak_variables(
|
|
87
|
-
dataset: xr.Dataset, adc_channels: xr.DataArray
|
|
88
|
-
) -> xr.Dataset:
|
|
89
|
-
"""
|
|
90
|
-
Concatenate leak variables in the dataset.
|
|
91
|
-
|
|
92
|
-
Updates the housekeeping dataset to replace the individual
|
|
93
|
-
leak_i_00, leak_i_01, ..., leak_i_63 variables with a single
|
|
94
|
-
leak_i variable as a 2D array. "i" here represents current
|
|
95
|
-
in the leakage current [Voltage] data.
|
|
96
|
-
|
|
97
|
-
Parameters
|
|
98
|
-
----------
|
|
99
|
-
dataset : xarray.Dataset
|
|
100
|
-
Dataset containing 64 leak variables.
|
|
101
|
-
adc_channels : xarray.DataArray
|
|
102
|
-
DataArray to be used as a dimension for the concatenated leak variables.
|
|
103
|
-
|
|
104
|
-
Returns
|
|
105
|
-
-------
|
|
106
|
-
dataset : xarray.Dataset
|
|
107
|
-
Updated dataset with concatenated leak variables.
|
|
108
|
-
"""
|
|
109
|
-
# Stack 64 leak variables (leak_00, leak_01, ..., leak_63)
|
|
110
|
-
leak_vars = [dataset[f"leak_i_{i:02d}"] for i in range(64)]
|
|
111
|
-
|
|
112
|
-
# Concatenate along 'adc_channels' and reorder dimensions
|
|
113
|
-
stacked_leaks = xr.concat(leak_vars, dim=adc_channels).transpose(
|
|
114
|
-
"epoch", "adc_channels"
|
|
115
|
-
)
|
|
116
|
-
dataset["leak_i"] = stacked_leaks
|
|
117
|
-
|
|
118
|
-
# Drop the individual leak variables
|
|
119
|
-
updated_dataset = dataset.drop_vars([f"leak_i_{i:02d}" for i in range(64)])
|
|
120
|
-
|
|
121
|
-
return updated_dataset
|
|
122
|
-
|
|
123
|
-
|
|
124
60
|
def process_science(dataset: xr.Dataset, attr_mgr: ImapCdfAttributes) -> xr.Dataset:
|
|
125
61
|
"""
|
|
126
62
|
Will process science dataset for CDF product.
|
|
@@ -147,10 +83,12 @@ def process_science(dataset: xr.Dataset, attr_mgr: ImapCdfAttributes) -> xr.Data
|
|
|
147
83
|
logger.info("Creating HIT L1A science datasets")
|
|
148
84
|
|
|
149
85
|
# Logical sources for the two products.
|
|
150
|
-
# logical_sources = ["
|
|
86
|
+
# logical_sources = ["imap_hit_l1a_count-rates", "imap_hit_l1a_pulse-height-event"]
|
|
87
|
+
|
|
88
|
+
# Decommutate and decompress the science data
|
|
89
|
+
sci_dataset = decom_hit(dataset)
|
|
151
90
|
|
|
152
91
|
# TODO: Complete this function
|
|
153
|
-
# - call decom_hit.py to decommutate the science data
|
|
154
92
|
# - split the science data into count rates and event datasets
|
|
155
93
|
# - update dimensions and add attributes to the dataset and data arrays
|
|
156
94
|
# - return list of two datasets (count rates and events)?
|
|
@@ -158,97 +96,4 @@ def process_science(dataset: xr.Dataset, attr_mgr: ImapCdfAttributes) -> xr.Data
|
|
|
158
96
|
# logger.info("HIT L1A event dataset created")
|
|
159
97
|
# logger.info("HIT L1A count rates dataset created")
|
|
160
98
|
|
|
161
|
-
return
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
def process_housekeeping(
|
|
165
|
-
dataset: xr.Dataset, attr_mgr: ImapCdfAttributes
|
|
166
|
-
) -> xr.Dataset:
|
|
167
|
-
"""
|
|
168
|
-
Will process housekeeping dataset for CDF product.
|
|
169
|
-
|
|
170
|
-
Updates the housekeeping dataset to replace with a single
|
|
171
|
-
leak_i variable as a 2D array. Also updates the dataset
|
|
172
|
-
attributes and coordinates and data variable dimensions
|
|
173
|
-
according to specifications in a cdf yaml file.
|
|
174
|
-
|
|
175
|
-
Parameters
|
|
176
|
-
----------
|
|
177
|
-
dataset : xarray.Dataset
|
|
178
|
-
Dataset containing HIT housekeeping data.
|
|
179
|
-
|
|
180
|
-
attr_mgr : ImapCdfAttributes
|
|
181
|
-
Attribute manager used to get the data product field's attributes.
|
|
182
|
-
|
|
183
|
-
Returns
|
|
184
|
-
-------
|
|
185
|
-
dataset : xarray.Dataset
|
|
186
|
-
An updated dataset ready for CDF conversion.
|
|
187
|
-
"""
|
|
188
|
-
logger.info("Creating HIT L1A housekeeping dataset")
|
|
189
|
-
|
|
190
|
-
logical_source = "imap_hit_l1a_hk"
|
|
191
|
-
|
|
192
|
-
# Drop keys that are not CDF data variables
|
|
193
|
-
drop_keys = [
|
|
194
|
-
"pkt_apid",
|
|
195
|
-
"sc_tick",
|
|
196
|
-
"version",
|
|
197
|
-
"type",
|
|
198
|
-
"sec_hdr_flg",
|
|
199
|
-
"seq_flgs",
|
|
200
|
-
"src_seq_ctr",
|
|
201
|
-
"pkt_len",
|
|
202
|
-
"hskp_spare1",
|
|
203
|
-
"hskp_spare2",
|
|
204
|
-
"hskp_spare3",
|
|
205
|
-
"hskp_spare4",
|
|
206
|
-
"hskp_spare5",
|
|
207
|
-
]
|
|
208
|
-
|
|
209
|
-
# Drop variables not needed for CDF
|
|
210
|
-
dataset = dataset.drop_vars(drop_keys)
|
|
211
|
-
|
|
212
|
-
# Create data arrays for dependencies
|
|
213
|
-
adc_channels = xr.DataArray(
|
|
214
|
-
np.arange(64, dtype=np.uint8),
|
|
215
|
-
name="adc_channels",
|
|
216
|
-
dims=["adc_channels"],
|
|
217
|
-
attrs=attr_mgr.get_variable_attributes("adc_channels"),
|
|
218
|
-
)
|
|
219
|
-
|
|
220
|
-
# NOTE: LABL_PTR_1 should be CDF_CHAR.
|
|
221
|
-
adc_channels_label = xr.DataArray(
|
|
222
|
-
adc_channels.values.astype(str),
|
|
223
|
-
name="adc_channels_label",
|
|
224
|
-
dims=["adc_channels_label"],
|
|
225
|
-
attrs=attr_mgr.get_variable_attributes("adc_channels_label"),
|
|
226
|
-
)
|
|
227
|
-
|
|
228
|
-
# Update dataset coordinates and attributes
|
|
229
|
-
dataset = dataset.assign_coords(
|
|
230
|
-
{
|
|
231
|
-
"adc_channels": adc_channels,
|
|
232
|
-
"adc_channels_label": adc_channels_label,
|
|
233
|
-
}
|
|
234
|
-
)
|
|
235
|
-
dataset.attrs = attr_mgr.get_global_attributes(logical_source)
|
|
236
|
-
|
|
237
|
-
# Stack 64 leak variables (leak_00, leak_01, ..., leak_63)
|
|
238
|
-
dataset = concatenate_leak_variables(dataset, adc_channels)
|
|
239
|
-
|
|
240
|
-
# Assign attributes and dimensions to each data array in the Dataset
|
|
241
|
-
for field in dataset.data_vars.keys():
|
|
242
|
-
# Create a dict of dimensions using the DEPEND_I keys in the
|
|
243
|
-
# attributes
|
|
244
|
-
dims = {
|
|
245
|
-
key: value
|
|
246
|
-
for key, value in attr_mgr.get_variable_attributes(field).items()
|
|
247
|
-
if "DEPEND" in key
|
|
248
|
-
}
|
|
249
|
-
dataset[field].attrs = attr_mgr.get_variable_attributes(field)
|
|
250
|
-
dataset[field].assign_coords(dims)
|
|
251
|
-
|
|
252
|
-
dataset.epoch.attrs = attr_mgr.get_variable_attributes("epoch")
|
|
253
|
-
|
|
254
|
-
return dataset
|
|
99
|
+
return sci_dataset
|
|
@@ -1,179 +1,59 @@
|
|
|
1
1
|
"""IMAP-HIT L1B data processing."""
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from dataclasses import fields
|
|
5
4
|
|
|
6
|
-
import numpy as np
|
|
7
5
|
import xarray as xr
|
|
8
6
|
|
|
9
|
-
from imap_processing.
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
from imap_processing.hit.hit_utils import (
|
|
8
|
+
HitAPID,
|
|
9
|
+
get_attribute_manager,
|
|
10
|
+
get_datasets_by_apid,
|
|
11
|
+
process_housekeeping_data,
|
|
12
|
+
)
|
|
12
13
|
|
|
13
14
|
logger = logging.getLogger(__name__)
|
|
14
15
|
|
|
15
16
|
# TODO review logging levels to use (debug vs. info)
|
|
16
17
|
|
|
17
18
|
|
|
18
|
-
def hit_l1b(
|
|
19
|
+
def hit_l1b(dependencies: dict, data_version: str) -> list[xr.Dataset]:
|
|
19
20
|
"""
|
|
20
21
|
Will process HIT data to L1B.
|
|
21
22
|
|
|
23
|
+
Processes dependencies needed to create L1B data products.
|
|
24
|
+
|
|
22
25
|
Parameters
|
|
23
26
|
----------
|
|
24
|
-
|
|
25
|
-
L1A
|
|
27
|
+
dependencies : dict
|
|
28
|
+
Dictionary of dependencies that are L1A xarray datasets
|
|
29
|
+
for science data and a file path string to a CCSDS file
|
|
30
|
+
for housekeeping data.
|
|
26
31
|
data_version : str
|
|
27
32
|
Version of the data product being created.
|
|
28
33
|
|
|
29
34
|
Returns
|
|
30
35
|
-------
|
|
31
|
-
|
|
32
|
-
L1B
|
|
36
|
+
processed_data : list[xarray.Dataset]
|
|
37
|
+
List of L1B datasets.
|
|
33
38
|
"""
|
|
34
|
-
#
|
|
35
|
-
attr_mgr =
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
39
|
+
# Create the attribute manager for this data level
|
|
40
|
+
attr_mgr = get_attribute_manager(data_version, "l1b")
|
|
41
|
+
|
|
42
|
+
# Create L1B datasets
|
|
43
|
+
datasets: list = []
|
|
44
|
+
if "imap_hit_l0_raw" in dependencies:
|
|
45
|
+
# Unpack ccsds file to xarray datasets
|
|
46
|
+
packet_file = dependencies["imap_hit_l0_raw"]
|
|
47
|
+
datasets_by_apid = get_datasets_by_apid(packet_file, derived=True)
|
|
48
|
+
# Process housekeeping to l1b.
|
|
49
|
+
datasets.append(
|
|
50
|
+
process_housekeeping_data(
|
|
51
|
+
datasets_by_apid[HitAPID.HIT_HSKP], attr_mgr, "imap_hit_l1b_hk"
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
logger.info("HIT L1B housekeeping dataset created")
|
|
55
|
+
if "imap_hit_l1a_countrates" in dependencies:
|
|
56
|
+
# TODO: process science data. placeholder for future code
|
|
51
57
|
pass
|
|
52
58
|
|
|
53
59
|
return datasets
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
# TODO: This is going to work differently when we have sample data
|
|
57
|
-
def create_hk_dataset(attr_mgr: ImapCdfAttributes) -> xr.Dataset:
|
|
58
|
-
"""
|
|
59
|
-
Create a housekeeping dataset.
|
|
60
|
-
|
|
61
|
-
Parameters
|
|
62
|
-
----------
|
|
63
|
-
attr_mgr : ImapCdfAttributes
|
|
64
|
-
Attribute manager used to get the data product field's attributes.
|
|
65
|
-
|
|
66
|
-
Returns
|
|
67
|
-
-------
|
|
68
|
-
hk_dataset : xarray.dataset
|
|
69
|
-
Dataset with all data product fields in xarray.DataArray.
|
|
70
|
-
"""
|
|
71
|
-
logger.info("Creating datasets for HIT L1B data")
|
|
72
|
-
|
|
73
|
-
# TODO: TEMPORARY. Need to update to use the L1B data class once that exists.
|
|
74
|
-
# Using l1a housekeeping data class for now since l1b housekeeping has the
|
|
75
|
-
# same data fields
|
|
76
|
-
data_fields = fields(Housekeeping)
|
|
77
|
-
|
|
78
|
-
# TODO define keys to skip. This will change later.
|
|
79
|
-
skip_keys = [
|
|
80
|
-
"shcoarse",
|
|
81
|
-
"ground_sw_version",
|
|
82
|
-
"packet_file_name",
|
|
83
|
-
"ccsds_header",
|
|
84
|
-
"leak_i_raw",
|
|
85
|
-
]
|
|
86
|
-
|
|
87
|
-
logical_source = "imap_hit_l1b_hk"
|
|
88
|
-
|
|
89
|
-
# Create fake data for now
|
|
90
|
-
|
|
91
|
-
# Convert integers into datetime64[s]
|
|
92
|
-
epoch_converted_time = met_to_j2000ns([0, 1, 2])
|
|
93
|
-
|
|
94
|
-
# Shape for dims
|
|
95
|
-
n_epoch = 3
|
|
96
|
-
n_channels = 64
|
|
97
|
-
|
|
98
|
-
# Create xarray data arrays for dependencies
|
|
99
|
-
epoch_time = xr.DataArray(
|
|
100
|
-
data=epoch_converted_time,
|
|
101
|
-
name="epoch",
|
|
102
|
-
dims=["epoch"],
|
|
103
|
-
attrs=attr_mgr.get_variable_attributes("epoch"),
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
adc_channels = xr.DataArray(
|
|
107
|
-
np.arange(n_channels, dtype=np.uint16),
|
|
108
|
-
name="adc_channels",
|
|
109
|
-
dims=["adc_channels"],
|
|
110
|
-
attrs=attr_mgr.get_variable_attributes("adc_channels"),
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
# Create xarray dataset
|
|
114
|
-
hk_dataset = xr.Dataset(
|
|
115
|
-
coords={"epoch": epoch_time, "adc_channels": adc_channels},
|
|
116
|
-
attrs=attr_mgr.get_global_attributes(logical_source),
|
|
117
|
-
)
|
|
118
|
-
|
|
119
|
-
# Create xarray data array for each data field
|
|
120
|
-
for data_field in data_fields:
|
|
121
|
-
field = data_field.name.lower()
|
|
122
|
-
if field not in skip_keys:
|
|
123
|
-
# Create a list of all the dimensions using the DEPEND_I keys in the
|
|
124
|
-
# attributes
|
|
125
|
-
dims = [
|
|
126
|
-
value
|
|
127
|
-
for key, value in attr_mgr.get_variable_attributes(field).items()
|
|
128
|
-
if "DEPEND" in key
|
|
129
|
-
]
|
|
130
|
-
|
|
131
|
-
# TODO: This is temporary.
|
|
132
|
-
# The data will be set in the data class when that's created
|
|
133
|
-
if field == "leak_i":
|
|
134
|
-
# 2D array - needs two dims
|
|
135
|
-
hk_dataset[field] = xr.DataArray(
|
|
136
|
-
np.ones((n_epoch, n_channels), dtype=np.uint16),
|
|
137
|
-
dims=dims,
|
|
138
|
-
attrs=attr_mgr.get_variable_attributes(field),
|
|
139
|
-
)
|
|
140
|
-
elif field in [
|
|
141
|
-
"preamp_l234a",
|
|
142
|
-
"preamp_l1a",
|
|
143
|
-
"preamp_l1b",
|
|
144
|
-
"preamp_l234b",
|
|
145
|
-
"temp0",
|
|
146
|
-
"temp1",
|
|
147
|
-
"temp2",
|
|
148
|
-
"temp3",
|
|
149
|
-
"analog_temp",
|
|
150
|
-
"hvps_temp",
|
|
151
|
-
"idpu_temp",
|
|
152
|
-
"lvps_temp",
|
|
153
|
-
"ebox_3d4vd",
|
|
154
|
-
"ebox_5d1vd",
|
|
155
|
-
"ebox_p12va",
|
|
156
|
-
"ebox_m12va",
|
|
157
|
-
"ebox_p5d7va",
|
|
158
|
-
"ebox_m5d7va",
|
|
159
|
-
"ref_p5v",
|
|
160
|
-
"l1ab_bias",
|
|
161
|
-
"l2ab_bias",
|
|
162
|
-
"l34a_bias",
|
|
163
|
-
"l34b_bias",
|
|
164
|
-
"ebox_p2d0vd",
|
|
165
|
-
]:
|
|
166
|
-
hk_dataset[field] = xr.DataArray(
|
|
167
|
-
np.ones(3, dtype=np.float16),
|
|
168
|
-
dims=dims,
|
|
169
|
-
attrs=attr_mgr.get_variable_attributes(field),
|
|
170
|
-
)
|
|
171
|
-
else:
|
|
172
|
-
hk_dataset[field] = xr.DataArray(
|
|
173
|
-
[1, 1, 1],
|
|
174
|
-
dims=dims,
|
|
175
|
-
attrs=attr_mgr.get_variable_attributes(field),
|
|
176
|
-
)
|
|
177
|
-
|
|
178
|
-
logger.info("HIT L1B datasets created")
|
|
179
|
-
return hk_dataset
|
imap_processing/idex/idex_l1a.py
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
Perform IDEX L1a Processing.
|
|
3
3
|
|
|
4
4
|
This module processes decommutated IDEX packets and creates L1a data products.
|
|
5
|
+
|
|
6
|
+
Examples
|
|
7
|
+
--------
|
|
8
|
+
.. code-block:: python
|
|
9
|
+
|
|
10
|
+
from imap_processing.idex.idex_l1a import PacketParser
|
|
11
|
+
|
|
12
|
+
l0_file = "imap_processing/tests/idex/imap_idex_l0_sci_20231214_v001.pkts"
|
|
13
|
+
l1a_data = PacketParser(l0_file, data_version)
|
|
14
|
+
l1a_data.write_l1a_cdf()
|
|
5
15
|
"""
|
|
6
16
|
|
|
7
17
|
import logging
|
|
@@ -102,15 +112,6 @@ class PacketParser:
|
|
|
102
112
|
The path and filename to the L0 file to read.
|
|
103
113
|
data_version : str
|
|
104
114
|
The version of the data product being created.
|
|
105
|
-
|
|
106
|
-
Examples
|
|
107
|
-
--------
|
|
108
|
-
.. code-block:: python
|
|
109
|
-
|
|
110
|
-
from imap_processing.idex.idex_l1a import PacketParser
|
|
111
|
-
l0_file = "imap_processing/tests/idex/imap_idex_l0_sci_20230725_v001.pkts"
|
|
112
|
-
l1a_data = PacketParser(l0_file, data_version)
|
|
113
|
-
l1a_data.write_l1a_cdf()
|
|
114
115
|
"""
|
|
115
116
|
|
|
116
117
|
def __init__(self, packet_file: Union[str, Path], data_version: str) -> None:
|
|
@@ -63,7 +63,7 @@ CASE_DECODER = {
|
|
|
63
63
|
(1, 0): VariableFields(True, True, True, False, False, False),
|
|
64
64
|
(2, 0): VariableFields(True, True, False, False, False, True),
|
|
65
65
|
(3, 0): VariableFields(True, False, False, False, False, False),
|
|
66
|
-
(4, 1): VariableFields(True, False,
|
|
66
|
+
(4, 1): VariableFields(True, False, True, False, False, True),
|
|
67
67
|
(4, 0): VariableFields(True, False, False, True, False, False),
|
|
68
68
|
(5, 0): VariableFields(True, False, True, False, False, False),
|
|
69
69
|
(6, 1): VariableFields(True, False, False, False, False, True),
|
|
@@ -367,7 +367,7 @@ def combine_segmented_packets(dataset: xr.Dataset) -> xr.Dataset:
|
|
|
367
367
|
# Mark the segment splits with comma to identify padding bits
|
|
368
368
|
# when parsing the binary
|
|
369
369
|
dataset["events"] = [
|
|
370
|
-
"
|
|
370
|
+
"".join(dataset["data"].values[start : end + 1])
|
|
371
371
|
for start, end in zip(seg_starts, seg_ends)
|
|
372
372
|
]
|
|
373
373
|
# drop any group of segmented packets that aren't sequential
|