imap-processing 0.19.4__py3-none-any.whl → 1.0.1__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 (50) hide show
  1. imap_processing/_version.py +2 -2
  2. imap_processing/cdf/config/imap_codice_global_cdf_attrs.yaml +13 -1
  3. imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +44 -44
  4. imap_processing/cdf/config/imap_codice_l1b_variable_attrs.yaml +127 -126
  5. imap_processing/cdf/config/imap_codice_l2-hi-omni_variable_attrs.yaml +635 -0
  6. imap_processing/cdf/config/imap_codice_l2-hi-sectored_variable_attrs.yaml +422 -0
  7. imap_processing/cdf/config/imap_constant_attrs.yaml +1 -1
  8. imap_processing/cdf/config/imap_enamaps_l2-common_variable_attrs.yaml +61 -55
  9. imap_processing/cdf/config/imap_enamaps_l2-healpix_variable_attrs.yaml +3 -2
  10. imap_processing/cdf/config/imap_enamaps_l2-rectangular_variable_attrs.yaml +17 -5
  11. imap_processing/cli.py +6 -11
  12. imap_processing/codice/codice_l1a.py +42 -21
  13. imap_processing/codice/codice_l2.py +640 -127
  14. imap_processing/codice/constants.py +224 -129
  15. imap_processing/ena_maps/ena_maps.py +124 -70
  16. imap_processing/ena_maps/utils/coordinates.py +5 -0
  17. imap_processing/ena_maps/utils/corrections.py +268 -0
  18. imap_processing/ena_maps/utils/map_utils.py +143 -42
  19. imap_processing/hi/hi_l2.py +10 -15
  20. imap_processing/ialirt/constants.py +7 -1
  21. imap_processing/ialirt/generate_coverage.py +1 -1
  22. imap_processing/ialirt/l0/ialirt_spice.py +1 -1
  23. imap_processing/ialirt/l0/parse_mag.py +33 -0
  24. imap_processing/ialirt/l0/process_codice.py +66 -0
  25. imap_processing/ialirt/utils/create_xarray.py +2 -0
  26. imap_processing/idex/idex_l2a.py +2 -2
  27. imap_processing/idex/idex_l2b.py +1 -1
  28. imap_processing/lo/l1c/lo_l1c.py +61 -3
  29. imap_processing/lo/l2/lo_l2.py +79 -11
  30. imap_processing/mag/l1a/mag_l1a.py +2 -2
  31. imap_processing/mag/l1a/mag_l1a_data.py +71 -13
  32. imap_processing/mag/l1c/interpolation_methods.py +34 -13
  33. imap_processing/mag/l1c/mag_l1c.py +117 -67
  34. imap_processing/mag/l1d/mag_l1d_data.py +3 -1
  35. imap_processing/spice/geometry.py +39 -28
  36. imap_processing/spice/pointing_frame.py +77 -50
  37. imap_processing/swapi/l1/swapi_l1.py +12 -4
  38. imap_processing/swe/utils/swe_constants.py +7 -7
  39. imap_processing/ultra/l1b/extendedspin.py +1 -1
  40. imap_processing/ultra/l1b/ultra_l1b_culling.py +2 -2
  41. imap_processing/ultra/l1b/ultra_l1b_extended.py +1 -1
  42. imap_processing/ultra/l1c/helio_pset.py +1 -1
  43. imap_processing/ultra/l1c/spacecraft_pset.py +2 -2
  44. imap_processing/ultra/l2/ultra_l2.py +3 -3
  45. imap_processing-1.0.1.dist-info/METADATA +121 -0
  46. {imap_processing-0.19.4.dist-info → imap_processing-1.0.1.dist-info}/RECORD +49 -47
  47. imap_processing-0.19.4.dist-info/METADATA +0 -120
  48. {imap_processing-0.19.4.dist-info → imap_processing-1.0.1.dist-info}/LICENSE +0 -0
  49. {imap_processing-0.19.4.dist-info → imap_processing-1.0.1.dist-info}/WHEEL +0 -0
  50. {imap_processing-0.19.4.dist-info → imap_processing-1.0.1.dist-info}/entry_points.txt +0 -0
@@ -39,10 +39,12 @@ pixel_index_label:
39
39
  # (longitude, latitude are not dimension coordinates for healpix tiling, but rather
40
40
  # describe the lon/lat coordinate of the Healpix pixel center)
41
41
  longitude:
42
+ CATDESC: "HEALPix Pixel center longitude in {frame} reference frame in the range [0, 360]"
42
43
  DEPEND_1: pixel_index
43
44
  LABL_PTR_1: pixel_index_label
44
45
 
45
46
  latitude:
47
+ CATDESC: "HEALPix Pixel center latitude in {frame} reference frame in the range [-90, 90]"
46
48
  DEPEND_1: pixel_index
47
49
  LABL_PTR_1: pixel_index_label
48
50
 
@@ -52,9 +54,8 @@ ena_intensity:
52
54
  DEPEND_2: pixel_index
53
55
  LABL_PTR_1: energy_label
54
56
  LABL_PTR_2: pixel_index_label
55
- DISPLAY_TYPE: image
56
57
 
57
- ena_intensity_stat_unc:
58
+ ena_intensity_stat_uncert:
58
59
  DEPEND_1: energy
59
60
  DEPEND_2: pixel_index
60
61
  LABL_PTR_1: energy_label
@@ -19,9 +19,10 @@ longitude_label:
19
19
  DEPEND_1: longitude
20
20
 
21
21
  longitude_delta:
22
- VAR_TYPE: metadata
22
+ VAR_TYPE: support_data
23
23
  dtype: float32
24
24
  CATDESC: Half-width of longitude pixel
25
+ DEPEND_1: longitude
25
26
  FORMAT: F12.6
26
27
  UNITS: degrees
27
28
  FIELDNAM: longitude delta
@@ -35,9 +36,10 @@ latitude_label:
35
36
  DEPEND_1: latitude
36
37
 
37
38
  latitude_delta:
38
- VAR_TYPE: metadata
39
+ VAR_TYPE: support_data
39
40
  dtype: float32
40
41
  CATDESC: Half-width of latitude pixel
42
+ DEPEND_1: latitude
41
43
  FORMAT: F12.6
42
44
  UNITS: degrees
43
45
  FIELDNAM: latitude delta
@@ -47,14 +49,24 @@ latitude_delta:
47
49
  # attributes file, imap_enamaps_l2-common_variable_attrs.yaml
48
50
 
49
51
  longitude:
52
+ CATDESC: "Pixel center longitude in {frame} reference frame in the range [0, 360]"
50
53
  DELTA_MINUS_VAR: longitude_delta
51
54
  DELTA_PLUS_VAR: longitude_delta
52
- SCALE_TYP: linear
55
+ SCALETYP: linear
56
+ LABL_PTR_1: longitude_label
57
+ MONOTON: INCREASE
58
+ FORMAT: I3
59
+
53
60
 
54
61
  latitude:
62
+ CATDESC: "Pixel center latitude in {frame} reference frame in the range [-90, 90]"
55
63
  DELTA_MINUS_VAR: latitude_delta
56
64
  DELTA_PLUS_VAR: latitude_delta
57
- SCALE_TYP: linear
65
+ SCALETYP: linear
66
+ LABL_PTR_1: latitude_label
67
+ MONOTON: INCREASE
68
+ BIN_LOCATION: 0.5
69
+ FORMAT: I2
58
70
 
59
71
  # Define Data variables
60
72
  ena_intensity:
@@ -65,7 +77,7 @@ ena_intensity:
65
77
  LABL_PTR_2: longitude_label
66
78
  LABL_PTR_3: latitude_label
67
79
 
68
- ena_intensity_stat_unc:
80
+ ena_intensity_stat_uncert:
69
81
  DEPEND_1: energy
70
82
  DEPEND_2: longitude
71
83
  DEPEND_3: latitude
imap_processing/cli.py CHANGED
@@ -632,13 +632,7 @@ class Codice(ProcessInstrument):
632
632
  datasets = [codice_l1b.process_codice_l1b(science_files[0])]
633
633
 
634
634
  if self.data_level == "l2":
635
- science_files = dependencies.get_file_paths(source="codice")
636
- if len(science_files) != 1:
637
- raise ValueError(
638
- f"CoDICE L2 requires exactly one input science file, received: "
639
- f"{science_files}."
640
- )
641
- datasets = [codice_l2.process_codice_l2(science_files[0])]
635
+ datasets = [codice_l2.process_codice_l2(self.descriptor, dependencies)]
642
636
 
643
637
  return datasets
644
638
 
@@ -1212,8 +1206,9 @@ class Mag(ProcessInstrument):
1212
1206
  if "raw" not in ds.attrs["Logical_source"] and not np.all(
1213
1207
  ds["epoch"].values[1:] > ds["epoch"].values[:-1]
1214
1208
  ):
1215
- raise ValueError(
1216
- "Timestamps for output file are not monotonically increasing."
1209
+ logger.warning(
1210
+ f"Timestamps for output file {ds.attrs['Logical_source']} are not "
1211
+ f"monotonically increasing."
1217
1212
  )
1218
1213
  return datasets
1219
1214
 
@@ -1255,7 +1250,7 @@ class Spacecraft(ProcessInstrument):
1255
1250
  )
1256
1251
  ah_paths = [path for path in spice_inputs if ".ah" in path.suffixes]
1257
1252
  pointing_kernel_paths = pointing_frame.generate_pointing_attitude_kernel(
1258
- ah_paths[-1]
1253
+ ah_paths
1259
1254
  )
1260
1255
  processed_dataset.extend(pointing_kernel_paths)
1261
1256
  else:
@@ -1305,7 +1300,7 @@ class Swapi(ProcessInstrument):
1305
1300
  )
1306
1301
 
1307
1302
  # process science or housekeeping data
1308
- datasets = swapi_l1(dependencies)
1303
+ datasets = swapi_l1(dependencies, descriptor=self.descriptor)
1309
1304
  elif self.data_level == "l2":
1310
1305
  if len(dependency_list) != 3:
1311
1306
  raise ValueError(
@@ -89,7 +89,7 @@ class CoDICEL1aPipeline:
89
89
  self.plan_step = plan_step
90
90
  self.view_id = view_id
91
91
 
92
- def apply_despinning(self) -> None:
92
+ def apply_despinning(self) -> None: # noqa: PLR0912 (too many branches)
93
93
  """
94
94
  Apply the despinning algorithm to lo- angular and priority products.
95
95
 
@@ -108,10 +108,10 @@ class CoDICEL1aPipeline:
108
108
  # The dimensions are dependent on the specific data product
109
109
  if "angular" in self.config["dataset_name"]:
110
110
  despun_dims: tuple[int, ...] = (
111
+ num_counters,
111
112
  num_energies,
112
113
  num_positions,
113
114
  num_spins,
114
- num_counters,
115
115
  )
116
116
  elif "priority" in self.config["dataset_name"]:
117
117
  despun_dims = (num_energies, num_spins, num_counters)
@@ -130,23 +130,33 @@ class CoDICEL1aPipeline:
130
130
  for energy_index in range(num_energies):
131
131
  pixel_orientation = constants.PIXEL_ORIENTATIONS[energy_index]
132
132
  for spin_sector_index in range(num_spin_sectors):
133
- for azimuth_index in range(num_spins):
134
- if pixel_orientation == "A" and azimuth_index < 12:
133
+ for azimuth_index in range(num_positions):
134
+ if "-sw-" in self.config["dataset_name"]:
135
+ # do something
136
+ position_index = constants.SW_INDEX_TO_POSITION[
137
+ azimuth_index
138
+ ]
139
+ elif "-nsw-" in self.config["dataset_name"]:
140
+ position_index = constants.NSW_INDEX_TO_POSITION[
141
+ azimuth_index
142
+ ]
143
+
144
+ if pixel_orientation == "A" and position_index < 12:
135
145
  despun_spin_sector = spin_sector_index
136
- elif pixel_orientation == "A" and azimuth_index >= 12:
146
+ elif pixel_orientation == "A" and position_index >= 12:
137
147
  despun_spin_sector = spin_sector_index + 12
138
- elif pixel_orientation == "B" and azimuth_index < 12:
148
+ elif pixel_orientation == "B" and position_index < 12:
139
149
  despun_spin_sector = spin_sector_index + 12
140
- elif pixel_orientation == "B" and azimuth_index >= 12:
150
+ elif pixel_orientation == "B" and position_index >= 12:
141
151
  despun_spin_sector = spin_sector_index
142
152
 
143
153
  if "angular" in self.config["dataset_name"]:
144
154
  spin_data = epoch_data[
145
- energy_index, :, spin_sector_index, :
146
- ] # (5, 4)
147
- despun_data[i][energy_index, :, despun_spin_sector, :] = (
148
- spin_data
149
- )
155
+ :, energy_index, azimuth_index, spin_sector_index
156
+ ]
157
+ despun_data[i][
158
+ :, energy_index, azimuth_index, despun_spin_sector
159
+ ] = spin_data
150
160
  elif "priority" in self.config["dataset_name"]:
151
161
  spin_data = epoch_data[energy_index, spin_sector_index, :]
152
162
  despun_data[i][energy_index, despun_spin_sector, :] = (
@@ -327,7 +337,7 @@ class CoDICEL1aPipeline:
327
337
  # each counter's data can be placed in a separate CDF data variable.
328
338
  # For Lo SW species, all_data has shape (9, 16, 128, 1) -> (epochs,
329
339
  # num_counters, num_energy_steps, num_spin_sectors)
330
- if self._is_lo_species_dataset():
340
+ if self._is_different_dimension():
331
341
  # For Lo species datasets, counters are the second dimension (index 1)
332
342
  num_counters = all_data.shape[1]
333
343
  else:
@@ -338,8 +348,10 @@ class CoDICEL1aPipeline:
338
348
  range(num_counters), self.config["variable_names"], strict=False
339
349
  ):
340
350
  # Extract the counter data
341
- if self._is_lo_species_dataset():
351
+ if self._is_different_dimension():
342
352
  counter_data = all_data[:, counter, :, :]
353
+ elif "sectored" in self.config["dataset_name"]:
354
+ counter_data = all_data[:, counter, :, :, :]
343
355
  else:
344
356
  counter_data = all_data[..., counter]
345
357
 
@@ -720,18 +732,25 @@ class CoDICEL1aPipeline:
720
732
 
721
733
  # Reshape the data based on how it is written to the data array of
722
734
  # the packet data. The number of counters is the last dimension / axis.
723
- if self._is_lo_species_dataset():
735
+ if self._is_different_dimension():
724
736
  # For Lo species datasets, counters are the first dimension
725
737
  reshape_dims = (
726
738
  self.config["num_counters"],
727
739
  *self.config["dims"].values(),
728
740
  )
741
+ elif "sectored" in self.config["dataset_name"]:
742
+ # For sectored datasets, counters are the second dimension
743
+ reshape_dims = (
744
+ self.config["num_counters"],
745
+ *self.config["dims"].values(),
746
+ )
729
747
  else:
730
748
  # For all other datasets, counters are the last dimension
731
749
  reshape_dims = (
732
750
  *self.config["dims"].values(),
733
751
  self.config["num_counters"],
734
752
  )
753
+
735
754
  for packet_data in self.raw_data:
736
755
  reshaped_packet_data = np.array(packet_data, dtype=np.uint32).reshape(
737
756
  reshape_dims
@@ -745,7 +764,7 @@ class CoDICEL1aPipeline:
745
764
  # No longer need to keep the raw data around
746
765
  del self.raw_data
747
766
 
748
- def _is_lo_species_dataset(self) -> bool:
767
+ def _is_different_dimension(self) -> bool:
749
768
  """
750
769
  Check if the current dataset is a Lo species dataset.
751
770
 
@@ -761,6 +780,8 @@ class CoDICEL1aPipeline:
761
780
  return self.config["dataset_name"] in [
762
781
  "imap_codice_l1a_lo-sw-species",
763
782
  "imap_codice_l1a_lo-nsw-species",
783
+ "imap_codice_l1a_lo-sw-angular",
784
+ "imap_codice_l1a_lo-nsw-angular",
764
785
  ]
765
786
 
766
787
  def set_data_product_config(self, apid: int, dataset: xr.Dataset) -> None:
@@ -1653,23 +1674,23 @@ def process_codice_l1a(file_path: Path) -> list[xr.Dataset]:
1653
1674
  # Housekeeping data
1654
1675
  if apid == CODICEAPID.COD_NHK:
1655
1676
  processed_dataset = create_hskp_dataset(dataset)
1656
- logger.info(f"\nFinal data product:\n{processed_dataset}\n")
1677
+ logger.info(f"\nProcessed {CODICEAPID(apid).name} packet\n")
1657
1678
 
1658
1679
  # Event data
1659
1680
  elif apid in [CODICEAPID.COD_LO_PHA, CODICEAPID.COD_HI_PHA]:
1660
1681
  processed_dataset = create_direct_event_dataset(apid, dataset)
1661
- logger.info(f"\nFinal data product:\n{processed_dataset}\n")
1682
+ logger.info(f"\nProcessed {CODICEAPID(apid).name} packet\n")
1662
1683
 
1663
1684
  # I-ALiRT data
1664
1685
  elif apid in [CODICEAPID.COD_LO_IAL, CODICEAPID.COD_HI_IAL]:
1665
1686
  processed_dataset = create_ialirt_dataset(apid, dataset)
1666
- logger.info(f"\nFinal data product:\n{processed_dataset}\n")
1687
+ logger.info(f"\nProcessed {CODICEAPID(apid).name} packet\n")
1667
1688
 
1668
1689
  # hi-omni data
1669
1690
  elif apid == CODICEAPID.COD_HI_OMNI_SPECIES_COUNTS:
1670
1691
  science_values = [packet.data for packet in dataset.data]
1671
1692
  processed_dataset = create_binned_dataset(apid, dataset, science_values)
1672
- logger.info(f"\nFinal data product:\n{processed_dataset}\n")
1693
+ logger.info(f"\nProcessed {CODICEAPID(apid).name} packet\n")
1673
1694
 
1674
1695
  # Everything else
1675
1696
  elif apid in constants.APIDS_FOR_SCIENCE_PROCESSING:
@@ -1687,7 +1708,7 @@ def process_codice_l1a(file_path: Path) -> list[xr.Dataset]:
1687
1708
  pipeline.define_coordinates()
1688
1709
  processed_dataset = pipeline.define_data_variables()
1689
1710
 
1690
- logger.info(f"\nFinal data product:\n{processed_dataset}\n")
1711
+ logger.info(f"\nProcessed {CODICEAPID(apid).name} packet\n")
1691
1712
 
1692
1713
  # For APIDs that don't require processing
1693
1714
  else: