imap-processing 0.19.3__py3-none-any.whl → 1.0.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 (39) hide show
  1. imap_processing/_version.py +2 -2
  2. imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +132 -133
  3. imap_processing/cdf/config/imap_codice_l1b_variable_attrs.yaml +133 -132
  4. imap_processing/cdf/config/imap_constant_attrs.yaml +1 -1
  5. imap_processing/cdf/config/imap_enamaps_l2-common_variable_attrs.yaml +54 -60
  6. imap_processing/cdf/config/imap_enamaps_l2-healpix_variable_attrs.yaml +1 -2
  7. imap_processing/cdf/config/imap_enamaps_l2-rectangular_variable_attrs.yaml +5 -3
  8. imap_processing/cdf/config/imap_hi_global_cdf_attrs.yaml +1 -2
  9. imap_processing/cdf/config/imap_hi_variable_attrs.yaml +1 -0
  10. imap_processing/cdf/config/imap_ultra_l1c_variable_attrs.yaml +8 -6
  11. imap_processing/cdf/utils.py +5 -0
  12. imap_processing/cli.py +72 -54
  13. imap_processing/codice/codice_l1a.py +82 -23
  14. imap_processing/codice/codice_l1b.py +35 -6
  15. imap_processing/codice/constants.py +173 -135
  16. imap_processing/ena_maps/ena_maps.py +15 -17
  17. imap_processing/glows/l1b/glows_l1b.py +29 -21
  18. imap_processing/hi/hi_l1a.py +49 -29
  19. imap_processing/hi/hi_l1b.py +34 -0
  20. imap_processing/hi/hi_l1c.py +23 -17
  21. imap_processing/hi/hi_l2.py +225 -81
  22. imap_processing/ialirt/l0/ialirt_spice.py +1 -1
  23. imap_processing/ialirt/l0/parse_mag.py +33 -0
  24. imap_processing/ialirt/utils/create_xarray.py +12 -1
  25. imap_processing/lo/l1b/lo_l1b.py +111 -77
  26. imap_processing/lo/l1c/lo_l1c.py +10 -11
  27. imap_processing/lo/l2/lo_l2.py +43 -22
  28. imap_processing/mag/l1c/interpolation_methods.py +9 -1
  29. imap_processing/mag/l1c/mag_l1c.py +99 -45
  30. imap_processing/spice/geometry.py +28 -19
  31. imap_processing/ultra/l1c/helio_pset.py +2 -2
  32. imap_processing/ultra/l1c/spacecraft_pset.py +7 -4
  33. imap_processing/ultra/l2/ultra_l2.py +54 -27
  34. imap_processing/ultra/utils/ultra_l1_utils.py +4 -4
  35. {imap_processing-0.19.3.dist-info → imap_processing-1.0.0.dist-info}/METADATA +1 -1
  36. {imap_processing-0.19.3.dist-info → imap_processing-1.0.0.dist-info}/RECORD +39 -39
  37. {imap_processing-0.19.3.dist-info → imap_processing-1.0.0.dist-info}/LICENSE +0 -0
  38. {imap_processing-0.19.3.dist-info → imap_processing-1.0.0.dist-info}/WHEEL +0 -0
  39. {imap_processing-0.19.3.dist-info → imap_processing-1.0.0.dist-info}/entry_points.txt +0 -0
@@ -214,17 +214,17 @@ HI_COUNTERS_AGGREGATED_ACTIVE_VARIABLES = {
214
214
  "spo": True,
215
215
  "reserved1": False,
216
216
  "mst": True,
217
- "reserved2": False,
218
- "reserved3": False,
217
+ "ssdo": True,
218
+ "stssd": True,
219
219
  "reserved4": False,
220
220
  "reserved5": False,
221
- "low_tof_cutoff": False,
221
+ "low_tof_cutoff": True,
222
222
  "reserved6": False,
223
223
  "reserved7": False,
224
224
  "asic1_flag_invalid": True,
225
225
  "asic2_flag_invalid": True,
226
- "asic1_channel_invalid": False,
227
- "asic_2_channel_invalid": False,
226
+ "asic1_channel_invalid": True,
227
+ "asic2_channel_invalid": True,
228
228
  }
229
229
  HI_COUNTERS_AGGREGATED_VARIABLE_NAMES = [
230
230
  name
@@ -236,8 +236,9 @@ HI_COUNTERS_AGGREGATED_VARIABLE_NAMES = [
236
236
  REQUIRES_DESPINNING = [
237
237
  "imap_codice_l1a_lo-sw-angular",
238
238
  "imap_codice_l1a_lo-nsw-angular",
239
- "imap_codice_l1a_lo-sw-priority",
240
- "imap_codice_l1a_lo-nsw-priority",
239
+ # TBD if this requires despinning
240
+ # "imap_codice_l1a_lo-sw-priority",
241
+ # "imap_codice_l1a_lo-nsw-priority",
241
242
  ]
242
243
 
243
244
  # Energy tables for CoDICE-Hi data products. These values represent the edges
@@ -268,149 +269,158 @@ IALIRT_ENERGY_TABLE = {
268
269
 
269
270
  OMNI_ENERGY_TABLE = {
270
271
  "h": [
271
- 0.05,
272
- 0.070710678,
273
- 0.1,
274
- 0.141421356,
275
- 0.2,
276
- 0.282842712,
277
- 0.4,
278
- 0.565685425,
279
- 0.8,
280
- 1.13137085,
281
- 1.6,
282
- 2.2627417,
283
- 3.2,
284
- 4.5254834,
285
- 6.4,
286
- 9.050966799,
272
+ 0.0200000000,
273
+ 0.0282842712,
274
+ 0.0400000000,
275
+ 0.0565685425,
276
+ 0.0800000000,
277
+ 0.1131370850,
278
+ 0.1600000000,
279
+ 0.2262741700,
280
+ 0.3200000000,
281
+ 0.4525483400,
282
+ 0.6400000000,
283
+ 0.9050966799,
284
+ 1.2800000000,
285
+ 1.8101933598,
286
+ 2.5600000000,
287
+ 3.6203867197,
287
288
  ],
288
289
  "he3": [
289
- 0.035355339,
290
- 0.05,
291
- 0.070710678,
292
- 0.1,
293
- 0.141421356,
294
- 0.2,
295
- 0.282842712,
296
- 0.4,
297
- 0.565685425,
298
- 0.8,
299
- 1.13137085,
300
- 1.6,
301
- 2.2627417,
302
- 3.2,
303
- 4.5254834,
304
- 6.4,
290
+ 0.0200000000,
291
+ 0.0282842712,
292
+ 0.0400000000,
293
+ 0.0565685425,
294
+ 0.0800000000,
295
+ 0.1131370850,
296
+ 0.1600000000,
297
+ 0.2262741700,
298
+ 0.3200000000,
299
+ 0.4525483400,
300
+ 0.6400000000,
301
+ 0.9050966799,
302
+ 1.2800000000,
303
+ 1.8101933598,
304
+ 2.5600000000,
305
+ 3.6203867197,
305
306
  ],
306
307
  "he4": [
307
- 0.035355339,
308
- 0.05,
309
- 0.070710678,
310
- 0.1,
311
- 0.141421356,
312
- 0.2,
313
- 0.282842712,
314
- 0.4,
315
- 0.565685425,
316
- 0.8,
317
- 1.13137085,
318
- 1.6,
319
- 2.2627417,
320
- 3.2,
321
- 4.5254834,
322
- 6.4,
308
+ 0.0200000000,
309
+ 0.0282842712,
310
+ 0.0400000000,
311
+ 0.0565685425,
312
+ 0.0800000000,
313
+ 0.1131370850,
314
+ 0.1600000000,
315
+ 0.2262741700,
316
+ 0.3200000000,
317
+ 0.4525483400,
318
+ 0.6400000000,
319
+ 0.9050966799,
320
+ 1.2800000000,
321
+ 1.8101933598,
322
+ 2.5600000000,
323
+ 3.6203867197,
323
324
  ],
324
325
  "c": [
325
- 0.025,
326
- 0.035355339,
327
- 0.05,
328
- 0.070710678,
329
- 0.1,
330
- 0.141421356,
331
- 0.2,
332
- 0.282842712,
333
- 0.4,
334
- 0.565685425,
335
- 0.8,
336
- 1.13137085,
337
- 1.6,
338
- 2.2627417,
339
- 3.2,
340
- 4.5254834,
341
- 6.4,
342
- 9.050966799,
343
- 12.8,
326
+ 0.0200000000,
327
+ 0.0282842712,
328
+ 0.0400000000,
329
+ 0.0565685425,
330
+ 0.0800000000,
331
+ 0.1131370850,
332
+ 0.1600000000,
333
+ 0.2262741700,
334
+ 0.3200000000,
335
+ 0.4525483400,
336
+ 0.6400000000,
337
+ 0.9050966799,
338
+ 1.2800000000,
339
+ 1.8101933598,
340
+ 2.5600000000,
341
+ 3.6203867197,
342
+ 5.1200000000,
343
+ 7.2407734394,
344
+ 10.2400000000,
344
345
  ],
345
346
  "o": [
346
- 0.025,
347
- 0.035355339,
348
- 0.05,
349
- 0.070710678,
350
- 0.1,
351
- 0.141421356,
352
- 0.2,
353
- 0.282842712,
354
- 0.4,
355
- 0.565685425,
356
- 0.8,
357
- 1.13137085,
358
- 1.6,
359
- 2.2627417,
360
- 3.2,
361
- 4.5254834,
362
- 6.4,
363
- 9.050966799,
364
- 12.8,
347
+ 0.0200000000,
348
+ 0.0282842712,
349
+ 0.0400000000,
350
+ 0.0565685425,
351
+ 0.0800000000,
352
+ 0.1131370850,
353
+ 0.1600000000,
354
+ 0.2262741700,
355
+ 0.3200000000,
356
+ 0.4525483400,
357
+ 0.6400000000,
358
+ 0.9050966799,
359
+ 1.2800000000,
360
+ 1.8101933598,
361
+ 2.5600000000,
362
+ 3.6203867197,
363
+ 5.1200000000,
364
+ 7.2407734394,
365
+ 10.2400000000,
365
366
  ],
366
367
  "ne_mg_si": [
367
- 0.01767767,
368
- 0.025,
369
- 0.035355339,
370
- 0.05,
371
- 0.070710678,
372
- 0.1,
373
- 0.141421356,
374
- 0.2,
375
- 0.282842712,
376
- 0.4,
377
- 0.565685425,
378
- 0.8,
379
- 1.13137085,
380
- 1.6,
381
- 2.2627417,
382
- 3.2,
368
+ 0.0200000000,
369
+ 0.0282842712,
370
+ 0.0400000000,
371
+ 0.0565685425,
372
+ 0.0800000000,
373
+ 0.1131370850,
374
+ 0.1600000000,
375
+ 0.2262741700,
376
+ 0.3200000000,
377
+ 0.4525483400,
378
+ 0.6400000000,
379
+ 0.9050966799,
380
+ 1.2800000000,
381
+ 1.8101933598,
382
+ 2.5600000000,
383
+ 3.6203867197,
383
384
  ],
384
385
  "fe": [
385
- 0.01767767,
386
- 0.025,
387
- 0.035355339,
388
- 0.05,
389
- 0.070710678,
390
- 0.1,
391
- 0.141421356,
392
- 0.2,
393
- 0.282842712,
394
- 0.4,
395
- 0.565685425,
396
- 0.8,
397
- 1.13137085,
398
- 1.6,
399
- 2.2627417,
400
- 3.2,
401
- 4.5254834,
402
- 6.4,
403
- 9.050966799,
386
+ 0.0200000000,
387
+ 0.0282842712,
388
+ 0.0400000000,
389
+ 0.0565685425,
390
+ 0.0800000000,
391
+ 0.1131370850,
392
+ 0.1600000000,
393
+ 0.2262741700,
394
+ 0.3200000000,
395
+ 0.4525483400,
396
+ 0.6400000000,
397
+ 0.9050966799,
398
+ 1.2800000000,
399
+ 1.8101933598,
400
+ 2.5600000000,
401
+ 3.6203867197,
402
+ 5.1200000000,
403
+ 7.2407734394,
404
+ 10.2400000000,
405
+ ],
406
+ "uh": [
407
+ 0.0200000000,
408
+ 0.0282842712,
409
+ 0.0400000000,
410
+ 0.0565685425,
411
+ 0.0800000000,
412
+ 0.1131370850,
404
413
  ],
405
- "uh": [0.01767767, 0.025, 0.035355339, 0.05, 0.070710678, 0.1],
406
- "junk": [0.05, 0.070710678],
414
+ "junk": [0.0200000000, 0.0282842712],
407
415
  }
408
416
 
417
+ # In the future, we get csv file with these column:
418
+ # species, min_energy, max_energy, product (descriptor of the product)
409
419
  SECTORED_ENERGY_TABLE = {
410
- "h": [0.05, 0.1, 0.2, 0.4, 0.8, 1.6, 3.2, 6.4, 12.8],
411
- "he3he4": [0.025, 0.05, 0.1, 0.2, 0.4, 0.8, 1.6, 3.2, 6.4],
412
- "cno": [0.025, 0.05, 0.1, 0.2, 0.4, 0.8, 1.6, 3.2, 6.4],
413
- "fe": [0.0125, 0.025, 0.05, 0.1, 0.2, 0.4, 0.8, 1.6, 3.2],
420
+ "h": [0.020, 0.040, 0.080, 0.160, 0.320, 0.640, 1.280, 2.560, 5.120],
421
+ "he3he4": [0.020, 0.040, 0.080, 0.160, 0.320, 0.640, 1.280, 2.560, 5.120],
422
+ "cno": [0.020, 0.040, 0.080, 0.160, 0.320, 0.640, 1.280, 2.560, 5.120],
423
+ "fe": [0.020, 0.040, 0.080, 0.160, 0.320, 0.640, 1.280, 2.560, 5.120],
414
424
  }
415
425
 
416
426
  # Various configurations to support processing of individual data products
@@ -961,7 +971,11 @@ ESA_SWEEP_TABLE_ID_LOOKUP = {
961
971
  # use. Currently, LO Stepping table 0 is used for every plan_id/plan_step
962
972
  # combination, but may change in the future. These are defined in the "Lo
963
973
  # Stepping" tab of the "*-SCI-LUT-*.xml" spreadsheet that largely defines CoDICE
964
- # processing.
974
+ # processing. Eg.
975
+ # (plan_id, plan_step) -> id of acquisition time
976
+ # (0, 0) -> 0
977
+
978
+
965
979
  LO_STEPPING_TABLE_ID_LOOKUP = {
966
980
  (0, 0): 0,
967
981
  (0, 1): 0,
@@ -2181,6 +2195,30 @@ ACQUISITION_TIMES = {
2181
2195
  ],
2182
2196
  }
2183
2197
 
2198
+ # These are for product that requires despinning in l1b.
2199
+ SW_INDEX_TO_POSITION = [1, 2, 3, 23, 24]
2200
+ NSW_INDEX_TO_POSITION = [
2201
+ 4,
2202
+ 5,
2203
+ 6,
2204
+ 7,
2205
+ 8,
2206
+ 9,
2207
+ 10,
2208
+ 11,
2209
+ 12,
2210
+ 13,
2211
+ 14,
2212
+ 15,
2213
+ 16,
2214
+ 17,
2215
+ 18,
2216
+ 19,
2217
+ 20,
2218
+ 21,
2219
+ 22,
2220
+ ]
2221
+
2184
2222
  # TODO: Update EFFICIENCY value when better information is available.
2185
2223
  # Constant for CoDICE Intensity calculations.
2186
2224
  EFFICIENCY = 1
@@ -1222,7 +1222,6 @@ class RectangularSkyMap(AbstractSkyMap):
1222
1222
  self,
1223
1223
  instrument: str,
1224
1224
  level: str,
1225
- frame: str,
1226
1225
  descriptor: str,
1227
1226
  sensor: str | None = None,
1228
1227
  ) -> xr.Dataset:
@@ -1235,8 +1234,6 @@ class RectangularSkyMap(AbstractSkyMap):
1235
1234
  Instrument name. "hi", "lo", "ultra".
1236
1235
  level : str
1237
1236
  Product level. "l2" or "l3".
1238
- frame : str
1239
- Map frame. "sf", "hf" or "hk".
1240
1237
  descriptor : str
1241
1238
  Descriptor for filename.
1242
1239
  sensor : str, optional
@@ -1318,16 +1315,14 @@ class RectangularSkyMap(AbstractSkyMap):
1318
1315
  )
1319
1316
 
1320
1317
  # Now set global attributes
1321
- map_attrs = cdf_attrs.get_global_attributes(
1322
- f"imap_{instrument}_{level}_enamap-{frame}"
1323
- )
1318
+ map_attrs = cdf_attrs.get_global_attributes(f"imap_{instrument}_{level}_enamap")
1324
1319
  map_attrs["Spacing_degrees"] = str(self.spacing_deg)
1325
1320
  for key in ["Data_type", "Logical_source", "Logical_source_description"]:
1326
1321
  map_attrs[key] = map_attrs[key].format(
1327
1322
  descriptor=descriptor,
1328
1323
  sensor=sensor,
1329
1324
  )
1330
- # Always add the following attributes to the map
1325
+ # Always add the following attributes to the map
1331
1326
  map_attrs.update(
1332
1327
  {
1333
1328
  "Sky_tiling_type": self.tiling_type.value,
@@ -1336,25 +1331,28 @@ class RectangularSkyMap(AbstractSkyMap):
1336
1331
  )
1337
1332
  cdf_ds.attrs.update(map_attrs)
1338
1333
 
1339
- # Set the variable attributes
1340
- for var in [*cdf_ds.data_vars, *cdf_ds.coords]:
1334
+ # Set the variable and coordinate attributes
1335
+ for name, data_array in {**cdf_ds.data_vars, **cdf_ds.coords}.items():
1341
1336
  try:
1342
- # Don't check schema on label or delta variables
1343
- ignore_schema_substrings = ["_label", "_delta"]
1344
- check_schema = (
1345
- False if any(s in var for s in ignore_schema_substrings) else True
1346
- )
1337
+ # We only check the schema on data variables that include "epoch"
1338
+ # in their list of dimensions (But not epoch itself).
1339
+ check_schema = name != "epoch" and "epoch" in data_array.dims
1347
1340
  var_attrs = cdf_attrs.get_variable_attributes(
1348
- variable_name=var,
1341
+ variable_name=name,
1349
1342
  check_schema=check_schema,
1350
1343
  )
1351
1344
  except KeyError as e:
1352
1345
  raise KeyError(
1353
- f"Attributes for variable {var} not found in "
1346
+ f"Attributes for variable {name} not found in "
1354
1347
  f"loaded variable attributes."
1355
1348
  ) from e
1356
1349
 
1357
- cdf_ds[var].attrs.update(var_attrs)
1350
+ cdf_ds[name].attrs.update(var_attrs)
1351
+
1352
+ # Manually adjust epoch attributes
1353
+ cdf_ds["epoch"].attrs.update(
1354
+ {"DELTA_PLUS_VAR": "epoch_delta", "BIN_LOCATION": 0}
1355
+ )
1358
1356
 
1359
1357
  return cdf_ds
1360
1358
 
@@ -28,12 +28,12 @@ def glows_l1b(
28
28
  pipeline_settings_dataset: xr.Dataset,
29
29
  ) -> xr.Dataset:
30
30
  """
31
- Will process the GLOWS L1B data and format the output datasets.
31
+ Will process the histogram GLOWS L1B data and format the output datasets.
32
32
 
33
33
  Parameters
34
34
  ----------
35
35
  input_dataset : xr.Dataset
36
- Dataset of input values.
36
+ Dataset of input values for L1A histogram data.
37
37
  excluded_regions : xr.Dataset
38
38
  Dataset containing excluded sky regions with ecliptic coordinates. This
39
39
  is the output from GlowsAncillaryCombiner.
@@ -77,29 +77,37 @@ def glows_l1b(
77
77
  ) as f:
78
78
  ancillary_parameters = AncillaryParameters(json.loads(f.read()))
79
79
 
80
- logical_source = (
81
- input_dataset.attrs["Logical_source"][0]
82
- if isinstance(input_dataset.attrs["Logical_source"], list)
83
- else input_dataset.attrs["Logical_source"]
80
+ output_dataarrays = process_histogram(
81
+ input_dataset, ancillary_exclusions, ancillary_parameters, pipeline_settings
82
+ )
83
+ output_dataset = create_l1b_hist_output(
84
+ output_dataarrays, input_dataset["epoch"], input_dataset["bins"], cdf_attrs
84
85
  )
85
86
 
86
- if "hist" in logical_source:
87
- output_dataarrays = process_histogram(
88
- input_dataset, ancillary_exclusions, ancillary_parameters, pipeline_settings
89
- )
90
- output_dataset = create_l1b_hist_output(
91
- output_dataarrays, input_dataset["epoch"], input_dataset["bins"], cdf_attrs
92
- )
87
+ return output_dataset
93
88
 
94
- elif "de" in logical_source:
95
- output_dataset = create_l1b_de_output(input_dataset, cdf_attrs)
96
89
 
97
- else:
98
- raise ValueError(
99
- f"Logical_source {input_dataset.attrs['Logical_source']} for input file "
100
- f"does not match histogram "
101
- "('hist') or direct event ('de')."
102
- )
90
+ def glows_l1b_de(
91
+ input_dataset: xr.Dataset,
92
+ ) -> xr.Dataset:
93
+ """
94
+ Process GLOWS L1B direct events data.
95
+
96
+ Parameters
97
+ ----------
98
+ input_dataset : xr.Dataset
99
+ The input dataset to process.
100
+
101
+ Returns
102
+ -------
103
+ xr.Dataset
104
+ The processed L1B direct events dataset.
105
+ """
106
+ cdf_attrs = ImapCdfAttributes()
107
+ cdf_attrs.add_instrument_global_attrs("glows")
108
+ cdf_attrs.add_instrument_variable_attrs("glows", "l1b")
109
+
110
+ output_dataset = create_l1b_de_output(input_dataset, cdf_attrs)
103
111
 
104
112
  return output_dataset
105
113
 
@@ -57,23 +57,23 @@ TOTAL_COUNTERS = ("a_total", "b_total", "c_total", "fee_de_recd", "fee_de_sent")
57
57
  # This is a mapping of variable name to index when the dump_data in the
58
58
  # HVSCI MEMDMP packet is interpreted as an array of uint32 values.
59
59
  MEMDMP_DATA_INDS = {
60
- "lastbin_shorten": 9,
60
+ "lastbin_shorten": 10,
61
61
  "coinc_length": 60,
62
62
  "de_timetag": 65,
63
- "ab_min": 67,
64
- "ab_max": 68,
65
- "ac_min": 69,
66
- "ac_max": 70,
67
- "ba_min": 71,
68
- "ba_max": 72,
69
- "bc_min": 73,
70
- "bc_max": 74,
71
- "ca_min": 75,
72
- "ca_max": 76,
73
- "cb_min": 77,
74
- "cb_max": 78,
75
- "cc_min": 79,
76
- "cc_max": 80,
63
+ "ab_max": 67,
64
+ "ab_min": 68,
65
+ "ac_max": 69,
66
+ "ac_min": 70,
67
+ "ba_max": 71,
68
+ "ba_min": 72,
69
+ "bc_max": 73,
70
+ "bc_min": 74,
71
+ "ca_max": 75,
72
+ "ca_min": 76,
73
+ "cb_max": 77,
74
+ "cb_min": 78,
75
+ "cc_max": 79,
76
+ "cc_min": 80,
77
77
  "cfd_dac_a": 82,
78
78
  "cfd_dac_b": 83,
79
79
  "cfd_dac_c": 84,
@@ -264,25 +264,40 @@ def create_de_dataset(de_data_dict: dict[str, npt.ArrayLike]) -> xr.Dataset:
264
264
  attrs=epoch_attrs,
265
265
  )
266
266
 
267
- event_met_attrs = attr_mgr.get_variable_attributes(
268
- "hi_de_event_met", check_schema=False
269
- )
270
- # For L1A DE, event_met is its own dimension, so we remove the DEPEND_0 attribute
271
- _ = event_met_attrs.pop("DEPEND_0")
272
-
273
267
  # Compute the meta-event MET in seconds
274
268
  meta_event_met = (
275
269
  np.array(de_data_dict["esa_step_seconds"]).astype(np.float64)
276
270
  + np.array(de_data_dict["esa_step_milliseconds"]) * MILLISECOND_TO_S
277
271
  )
278
- # Compute the MET of each event in seconds
279
- # event MET = meta_event_met + de_clock
280
- # See Hi Algorithm Document section 2.2.5
281
- event_met_array = np.array(
282
- meta_event_met[de_data_dict["ccsds_index"]]
283
- + np.array(de_data_dict["de_tag"]) * DE_CLOCK_TICK_S,
284
- dtype=event_met_attrs.pop("dtype"),
272
+
273
+ event_met_attrs = attr_mgr.get_variable_attributes(
274
+ "hi_de_event_met", check_schema=False
285
275
  )
276
+ # For L1A DE, event_met is its own dimension, so we remove the DEPEND_0 attribute
277
+ _ = event_met_attrs.pop("DEPEND_0")
278
+ event_met_dtype = event_met_attrs.pop("dtype")
279
+
280
+ # If there are no events, add a single event with fill values
281
+ if len(de_data_dict["de_tag"]) == 0:
282
+ logger.warning(
283
+ "No direct events found in SCIDE packets. "
284
+ "Creating a false DE entry with fill values."
285
+ )
286
+ for key in ["de_tag", "trigger_id", "tof_1", "tof_2", "tof_3", "ccsds_index"]:
287
+ attrs = attr_mgr.get_variable_attributes(f"hi_de_{key}", check_schema=False)
288
+ de_data_dict[key] = [attrs["FILLVAL"]]
289
+ event_met_array = np.array([event_met_attrs["FILLVAL"]], dtype=event_met_dtype)
290
+ else:
291
+ # Compute the MET of each event in seconds
292
+ # event MET = meta_event_met + de_clock
293
+ # See Hi Algorithm Document section 2.2.5
294
+ event_met_array = np.array(
295
+ meta_event_met[de_data_dict["ccsds_index"]]
296
+ + np.array(de_data_dict["de_tag"]) * DE_CLOCK_TICK_S,
297
+ dtype=event_met_dtype,
298
+ )
299
+
300
+ # Create the event_met coordinate
286
301
  event_met = xr.DataArray(
287
302
  event_met_array,
288
303
  name="event_met",
@@ -290,10 +305,12 @@ def create_de_dataset(de_data_dict: dict[str, npt.ArrayLike]) -> xr.Dataset:
290
305
  attrs=event_met_attrs,
291
306
  )
292
307
 
308
+ # Create a dataset with only coordinates
293
309
  dataset = xr.Dataset(
294
310
  coords={"epoch": epoch, "event_met": event_met},
295
311
  )
296
312
 
313
+ # Add variable to the dataset
297
314
  for var_name, data in de_data_dict.items():
298
315
  attrs = attr_mgr.get_variable_attributes(
299
316
  f"hi_de_{var_name}", check_schema=False
@@ -557,9 +574,12 @@ def finish_memdmp_dataset(input_ds: xr.Dataset) -> xr.Dataset:
557
574
  # offset index with a stride of the number of bytes in the dump
558
575
  # data divided by 4 (32-bit values).
559
576
  new_vars[new_var] = xr.DataArray(
560
- data=full_uint32_data[offset::index_stride],
577
+ data=full_uint32_data[offset::index_stride].astype(np.uint32),
561
578
  dims=["epoch"],
562
579
  )
580
+ # Need to add one to de_timetag value
581
+ if new_var == "de_timetag":
582
+ new_vars[new_var].data += 1
563
583
 
564
584
  # Remove binary memory dump data and add parsed variables
565
585
  dataset = dataset.drop("dump_data")