imap-processing 0.17.0__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 (89) 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 +11 -0
  5. imap_processing/cdf/config/imap_codice_l1b_variable_attrs.yaml +11 -0
  6. imap_processing/cdf/config/imap_codice_l2_variable_attrs.yaml +24 -0
  7. imap_processing/cdf/config/imap_hit_l1a_variable_attrs.yaml +163 -100
  8. imap_processing/cdf/config/imap_hit_l2_variable_attrs.yaml +4 -4
  9. imap_processing/cdf/config/imap_ialirt_l1_variable_attrs.yaml +97 -54
  10. imap_processing/cdf/config/imap_idex_l2b_variable_attrs.yaml +119 -36
  11. imap_processing/cdf/config/imap_idex_l2c_variable_attrs.yaml +16 -90
  12. imap_processing/cdf/config/imap_lo_global_cdf_attrs.yaml +30 -0
  13. imap_processing/cdf/config/imap_mag_global_cdf_attrs.yaml +15 -1
  14. imap_processing/cdf/config/imap_ultra_global_cdf_attrs.yaml +60 -0
  15. imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +91 -11
  16. imap_processing/cli.py +28 -5
  17. imap_processing/codice/codice_l1a.py +36 -48
  18. imap_processing/codice/codice_l1b.py +1 -1
  19. imap_processing/codice/codice_l2.py +0 -9
  20. imap_processing/codice/constants.py +481 -498
  21. imap_processing/hit/l0/decom_hit.py +2 -2
  22. imap_processing/hit/l1a/hit_l1a.py +64 -24
  23. imap_processing/hit/l1b/constants.py +5 -0
  24. imap_processing/hit/l1b/hit_l1b.py +18 -16
  25. imap_processing/hit/l2/constants.py +1 -1
  26. imap_processing/hit/l2/hit_l2.py +4 -5
  27. imap_processing/ialirt/constants.py +21 -0
  28. imap_processing/ialirt/generate_coverage.py +188 -0
  29. imap_processing/ialirt/l0/parse_mag.py +62 -5
  30. imap_processing/ialirt/l0/process_swapi.py +1 -1
  31. imap_processing/ialirt/l0/process_swe.py +23 -7
  32. imap_processing/ialirt/utils/constants.py +22 -16
  33. imap_processing/ialirt/utils/create_xarray.py +42 -19
  34. imap_processing/idex/idex_constants.py +1 -5
  35. imap_processing/idex/idex_l2b.py +246 -67
  36. imap_processing/idex/idex_l2c.py +30 -196
  37. imap_processing/lo/l0/lo_apid.py +1 -0
  38. imap_processing/lo/l1a/lo_l1a.py +44 -0
  39. imap_processing/lo/packet_definitions/lo_xtce.xml +5359 -106
  40. imap_processing/mag/constants.py +1 -0
  41. imap_processing/mag/l1d/__init__.py +0 -0
  42. imap_processing/mag/l1d/mag_l1d.py +133 -0
  43. imap_processing/mag/l1d/mag_l1d_data.py +588 -0
  44. imap_processing/mag/l2/__init__.py +0 -0
  45. imap_processing/mag/l2/mag_l2.py +25 -20
  46. imap_processing/mag/l2/mag_l2_data.py +191 -130
  47. imap_processing/quality_flags.py +20 -2
  48. imap_processing/spice/geometry.py +25 -3
  49. imap_processing/spice/pointing_frame.py +1 -1
  50. imap_processing/spice/spin.py +4 -0
  51. imap_processing/spice/time.py +51 -0
  52. imap_processing/swapi/l2/swapi_l2.py +52 -8
  53. imap_processing/swapi/swapi_utils.py +1 -1
  54. imap_processing/swe/l1b/swe_l1b.py +2 -4
  55. imap_processing/ultra/constants.py +49 -1
  56. imap_processing/ultra/l0/decom_tools.py +15 -8
  57. imap_processing/ultra/l0/decom_ultra.py +35 -11
  58. imap_processing/ultra/l0/ultra_utils.py +97 -5
  59. imap_processing/ultra/l1a/ultra_l1a.py +25 -4
  60. imap_processing/ultra/l1b/cullingmask.py +3 -3
  61. imap_processing/ultra/l1b/de.py +53 -15
  62. imap_processing/ultra/l1b/extendedspin.py +26 -2
  63. imap_processing/ultra/l1b/lookup_utils.py +171 -50
  64. imap_processing/ultra/l1b/quality_flag_filters.py +14 -0
  65. imap_processing/ultra/l1b/ultra_l1b_culling.py +198 -5
  66. imap_processing/ultra/l1b/ultra_l1b_extended.py +304 -66
  67. imap_processing/ultra/l1c/helio_pset.py +54 -7
  68. imap_processing/ultra/l1c/spacecraft_pset.py +9 -1
  69. imap_processing/ultra/l1c/ultra_l1c.py +2 -0
  70. imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +106 -109
  71. imap_processing/ultra/utils/ultra_l1_utils.py +13 -1
  72. {imap_processing-0.17.0.dist-info → imap_processing-0.18.0.dist-info}/METADATA +2 -2
  73. {imap_processing-0.17.0.dist-info → imap_processing-0.18.0.dist-info}/RECORD +76 -83
  74. imap_processing/ultra/lookup_tables/Angular_Profiles_FM45_LeftSlit.csv +0 -526
  75. imap_processing/ultra/lookup_tables/Angular_Profiles_FM45_RightSlit.csv +0 -526
  76. imap_processing/ultra/lookup_tables/Angular_Profiles_FM90_LeftSlit.csv +0 -526
  77. imap_processing/ultra/lookup_tables/Angular_Profiles_FM90_RightSlit.csv +0 -524
  78. imap_processing/ultra/lookup_tables/EgyNorm.mem.csv +0 -32769
  79. imap_processing/ultra/lookup_tables/FM45_Startup1_ULTRA_IMGPARAMS_20240719.csv +0 -2
  80. imap_processing/ultra/lookup_tables/FM90_Startup1_ULTRA_IMGPARAMS_20240719.csv +0 -2
  81. imap_processing/ultra/lookup_tables/dps_grid45_compressed.cdf +0 -0
  82. imap_processing/ultra/lookup_tables/ultra45_back-pos-luts.csv +0 -4097
  83. imap_processing/ultra/lookup_tables/ultra45_tdc_norm.csv +0 -2050
  84. imap_processing/ultra/lookup_tables/ultra90_back-pos-luts.csv +0 -4097
  85. imap_processing/ultra/lookup_tables/ultra90_tdc_norm.csv +0 -2050
  86. imap_processing/ultra/lookup_tables/yadjust.csv +0 -257
  87. {imap_processing-0.17.0.dist-info → imap_processing-0.18.0.dist-info}/LICENSE +0 -0
  88. {imap_processing-0.17.0.dist-info → imap_processing-0.18.0.dist-info}/WHEEL +0 -0
  89. {imap_processing-0.17.0.dist-info → imap_processing-0.18.0.dist-info}/entry_points.txt +0 -0
@@ -131,6 +131,7 @@ MAX_FINE_TIME = np.iinfo(np.uint16).max # maximum 16 bit unsigned int
131
131
  AXIS_COUNT = 3
132
132
  RANGE_BIT_WIDTH = 2
133
133
  MAX_COMPRESSED_VECTOR_BITS = 60
134
+ FILLVAL = -1e31
134
135
 
135
136
 
136
137
  def vectors_per_second_from_string(vecsec_string: str) -> dict:
File without changes
@@ -0,0 +1,133 @@
1
+ """Module for generating Level 1d magnetic field data."""
2
+
3
+ import numpy as np
4
+ import xarray as xr
5
+
6
+ from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
7
+ from imap_processing.mag.constants import DataMode
8
+ from imap_processing.mag.l1d.mag_l1d_data import MagL1d, MagL1dConfiguration
9
+ from imap_processing.mag.l2.mag_l2_data import ValidFrames
10
+
11
+
12
+ def mag_l1d(
13
+ science_data: list[xr.Dataset],
14
+ calibration_dataset: xr.Dataset,
15
+ day_to_process: np.datetime64,
16
+ ) -> list[xr.Dataset]:
17
+ """
18
+ Generate Level 1d magnetic field data from Level 1b/1c data.
19
+
20
+ Both norm and burst mode are calculated at the same time. Normal mode MAGO and MAGI
21
+ L1C data is required, burst mode MAGO and MAGI L1B data is optional.
22
+
23
+ Parameters
24
+ ----------
25
+ science_data : list[xr.Dataset]
26
+ The list of input datasets containing the MAG L1C and L1B data. This is required
27
+ to have at least one normal mode dataset for MAGo and MAGi, and optionally
28
+ burst mode datasets for MAGo and MAGi. There cannot be duplicates, so two
29
+ norm-mago files is invalid.
30
+ calibration_dataset : xr.Dataset
31
+ The calibration dataset to use for processing. Generated from multiple L1D
32
+ ancillary files using MagAncillaryCombiner class.
33
+ day_to_process : np.datetime64
34
+ The day to process, in np.datetime64[D] format. This is used to select the
35
+ correct ancillary parameters and to remove excessive data from the output.
36
+
37
+ Returns
38
+ -------
39
+ list[xr.Dataset]
40
+ A list containing the generated Level 1d dataset(s).
41
+ """
42
+ input_magi_norm = None
43
+ input_mago_norm = None
44
+ input_magi_burst = None
45
+ input_mago_burst = None
46
+ for dataset in science_data:
47
+ source = dataset.attrs.get("Logical_source", "")
48
+ if "norm-magi" in source:
49
+ input_magi_norm = dataset
50
+ elif "norm-mago" in source:
51
+ input_mago_norm = dataset
52
+ elif "burst-magi" in source:
53
+ input_magi_burst = dataset
54
+ elif "burst-mago" in source:
55
+ input_mago_burst = dataset
56
+ else:
57
+ raise ValueError(f"Input data has invalid logical source {source}")
58
+
59
+ if input_magi_norm is None or input_mago_norm is None:
60
+ raise ValueError(
61
+ "Both MAGo and MAGi normal mode datasets are required for L1d processing."
62
+ )
63
+
64
+ day: np.datetime64 = day_to_process.astype("datetime64[D]")
65
+
66
+ output_datasets = []
67
+
68
+ # Read configuration out of file
69
+ config = MagL1dConfiguration(calibration_dataset, day)
70
+
71
+ # Only the first 3 components are used for L1d
72
+ mago_vectors = input_mago_norm["vectors"].data[:, :3]
73
+ magi_vectors = input_magi_norm["vectors"].data[:, :3]
74
+
75
+ # TODO: verify that MAGO is primary sensor for all vectors before applying
76
+ # gradiometry
77
+
78
+ # TODO: L1D attributes
79
+ attributes = ImapCdfAttributes()
80
+ attributes.add_instrument_global_attrs("mag")
81
+ attributes.add_instrument_variable_attrs("mag", "l2")
82
+
83
+ l1d_norm = MagL1d(
84
+ vectors=mago_vectors,
85
+ epoch=input_mago_norm["epoch"].data,
86
+ range=input_mago_norm["vectors"].data[:, 3],
87
+ global_attributes={},
88
+ quality_flags=np.zeros(len(input_mago_norm["epoch"].data)),
89
+ quality_bitmask=np.zeros(len(input_mago_norm["epoch"].data)),
90
+ data_mode=DataMode.NORM,
91
+ magi_vectors=magi_vectors,
92
+ magi_range=input_magi_norm["vectors"].data[:, 3],
93
+ magi_epoch=input_magi_norm["epoch"].data,
94
+ config=config,
95
+ day=day,
96
+ )
97
+
98
+ l1d_norm.rotate_frame(ValidFrames.SRF)
99
+ norm_srf_dataset = l1d_norm.generate_dataset(attributes, day_to_process)
100
+ l1d_norm.rotate_frame(ValidFrames.DSRF)
101
+ norm_dsrf_dataset = l1d_norm.generate_dataset(attributes, day_to_process)
102
+ output_datasets.append(norm_srf_dataset)
103
+ output_datasets.append(norm_dsrf_dataset)
104
+
105
+ if input_mago_burst is not None and input_magi_burst is not None:
106
+ # If burst data is provided, use it to create the burst L1d dataset
107
+ mago_burst_vectors = input_mago_burst["vectors"].data[:, :3]
108
+ magi_burst_vectors = input_magi_burst["vectors"].data[:, :3]
109
+
110
+ l1d_burst = MagL1d(
111
+ vectors=mago_burst_vectors,
112
+ epoch=input_mago_burst["epoch"].data,
113
+ range=input_mago_burst["vectors"].data[:, 3],
114
+ global_attributes={},
115
+ quality_flags=np.zeros(len(input_mago_burst["epoch"].data)),
116
+ quality_bitmask=np.zeros(len(input_mago_burst["epoch"].data)),
117
+ data_mode=DataMode.BURST,
118
+ magi_vectors=magi_burst_vectors,
119
+ magi_range=input_magi_burst["vectors"].data[:, 3],
120
+ magi_epoch=input_magi_burst["epoch"].data,
121
+ config=config,
122
+ spin_offsets=l1d_norm.spin_offsets,
123
+ day=day,
124
+ )
125
+ l1d_burst.rotate_frame(ValidFrames.SRF)
126
+ burst_srf_dataset = l1d_burst.generate_dataset(attributes, day_to_process)
127
+ l1d_burst.rotate_frame(ValidFrames.DSRF)
128
+ burst_dsrf_dataset = l1d_burst.generate_dataset(attributes, day_to_process)
129
+ output_datasets.append(burst_srf_dataset)
130
+ output_datasets.append(burst_dsrf_dataset)
131
+
132
+ # TODO: Output ancillary files
133
+ return output_datasets