imap-processing 0.8.0__py3-none-any.whl → 0.9.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 +2 -0
- imap_processing/cdf/config/imap_hi_variable_attrs.yaml +100 -1
- imap_processing/cdf/config/imap_hit_global_cdf_attrs.yaml +14 -0
- imap_processing/cdf/config/imap_hit_l1a_variable_attrs.yaml +63 -1
- imap_processing/cdf/config/imap_idex_global_cdf_attrs.yaml +7 -0
- imap_processing/cdf/config/imap_idex_l1a_variable_attrs.yaml +574 -231
- imap_processing/cdf/config/imap_idex_l1b_variable_attrs.yaml +326 -0
- imap_processing/cdf/config/imap_lo_l1a_variable_attrs.yaml +33 -23
- imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +7 -4
- imap_processing/cdf/utils.py +3 -5
- imap_processing/cli.py +13 -4
- imap_processing/codice/codice_l1a.py +5 -5
- imap_processing/codice/constants.py +9 -9
- imap_processing/codice/decompress.py +6 -2
- imap_processing/glows/l1a/glows_l1a.py +1 -2
- imap_processing/hi/l1a/hi_l1a.py +4 -4
- imap_processing/hi/l1a/histogram.py +106 -108
- imap_processing/hi/l1a/science_direct_event.py +91 -224
- imap_processing/hi/packet_definitions/TLM_HI_COMBINED_SCI.xml +3994 -0
- imap_processing/hit/l0/constants.py +2 -2
- imap_processing/hit/l0/decom_hit.py +12 -101
- imap_processing/hit/l1a/hit_l1a.py +164 -23
- imap_processing/ialirt/l0/process_codicelo.py +153 -0
- imap_processing/ialirt/l0/process_hit.py +5 -5
- imap_processing/ialirt/packet_definitions/ialirt_codicelo.xml +281 -0
- imap_processing/ialirt/process_ephemeris.py +212 -0
- imap_processing/idex/idex_l1a.py +55 -75
- imap_processing/idex/idex_l1b.py +192 -0
- imap_processing/idex/idex_variable_unpacking_and_eu_conversion.csv +33 -0
- imap_processing/idex/packet_definitions/idex_packet_definition.xml +97 -595
- imap_processing/lo/l0/decompression_tables/decompression_tables.py +16 -0
- imap_processing/lo/l0/lo_science.py +44 -12
- imap_processing/lo/l1a/lo_l1a.py +76 -8
- imap_processing/lo/packet_definitions/lo_xtce.xml +9877 -87
- imap_processing/mag/l1a/mag_l1a.py +1 -2
- imap_processing/mag/l1a/mag_l1a_data.py +1 -2
- imap_processing/mag/l1b/mag_l1b.py +2 -1
- imap_processing/spice/geometry.py +37 -19
- imap_processing/spice/time.py +144 -2
- imap_processing/swapi/l1/swapi_l1.py +3 -3
- imap_processing/swapi/packet_definitions/swapi_packet_definition.xml +1535 -446
- imap_processing/swe/l2/swe_l2.py +134 -17
- imap_processing/tests/ccsds/test_data/expected_output.xml +1 -1
- imap_processing/tests/codice/test_codice_l1a.py +8 -8
- imap_processing/tests/codice/test_decompress.py +4 -4
- imap_processing/tests/conftest.py +46 -43
- imap_processing/tests/hi/test_data/l0/H90_NHK_20241104.bin +0 -0
- imap_processing/tests/hi/test_data/l0/H90_sci_cnt_20241104.bin +0 -0
- imap_processing/tests/hi/test_data/l0/H90_sci_de_20241104.bin +0 -0
- imap_processing/tests/hi/test_hi_l1b.py +2 -2
- imap_processing/tests/hi/test_l1a.py +31 -58
- imap_processing/tests/hi/test_science_direct_event.py +58 -0
- imap_processing/tests/hit/test_data/sci_sample1.ccsds +0 -0
- imap_processing/tests/hit/test_decom_hit.py +60 -50
- imap_processing/tests/hit/test_hit_l1a.py +327 -12
- imap_processing/tests/hit/test_hit_l1b.py +76 -0
- imap_processing/tests/hit/validation_data/hskp_sample_eu.csv +89 -0
- imap_processing/tests/hit/validation_data/sci_sample_raw1.csv +29 -0
- imap_processing/tests/ialirt/test_data/l0/apid01152.tlm +0 -0
- imap_processing/tests/ialirt/test_data/l0/imap_codice_l1a_lo-ialirt_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/ialirt/unit/test_process_codicelo.py +106 -0
- imap_processing/tests/ialirt/unit/test_process_ephemeris.py +109 -0
- imap_processing/tests/ialirt/unit/test_process_hit.py +9 -6
- imap_processing/tests/idex/conftest.py +1 -1
- imap_processing/tests/idex/test_idex_l0.py +1 -1
- imap_processing/tests/idex/test_idex_l1a.py +7 -1
- imap_processing/tests/idex/test_idex_l1b.py +126 -0
- imap_processing/tests/lo/test_lo_l1a.py +7 -16
- imap_processing/tests/lo/test_lo_science.py +67 -3
- imap_processing/tests/lo/test_pkts/imap_lo_l0_raw_20240803_v002.pkts +0 -0
- imap_processing/tests/lo/validation_data/Instrument_FM1_T104_R129_20240803_ILO_SCI_DE_dec_DN_with_fills.csv +1999 -0
- imap_processing/tests/mag/test_mag_l1b.py +39 -5
- imap_processing/tests/spice/test_geometry.py +32 -6
- imap_processing/tests/spice/test_time.py +135 -6
- imap_processing/tests/swapi/test_swapi_decom.py +75 -69
- imap_processing/tests/swapi/test_swapi_l1.py +4 -4
- imap_processing/tests/swe/test_swe_l2.py +64 -8
- imap_processing/tests/test_utils.py +1 -1
- imap_processing/tests/ultra/test_data/l0/ultra45_raw_sc_ultrarawimg_withFSWcalcs_FM45_40P_Phi28p5_BeamCal_LinearScan_phi2850_theta-000_20240207T102740.csv +3314 -3314
- imap_processing/tests/ultra/unit/test_de.py +8 -3
- imap_processing/tests/ultra/unit/test_spatial_utils.py +125 -0
- imap_processing/tests/ultra/unit/test_ultra_l1b_extended.py +39 -29
- imap_processing/tests/ultra/unit/test_ultra_l1c_pset_bins.py +2 -25
- imap_processing/ultra/constants.py +4 -0
- imap_processing/ultra/l1b/de.py +8 -14
- imap_processing/ultra/l1b/ultra_l1b_extended.py +29 -70
- imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +1 -36
- imap_processing/ultra/utils/spatial_utils.py +221 -0
- {imap_processing-0.8.0.dist-info → imap_processing-0.9.0.dist-info}/METADATA +1 -1
- {imap_processing-0.8.0.dist-info → imap_processing-0.9.0.dist-info}/RECORD +94 -76
- imap_processing/hi/l0/__init__.py +0 -0
- imap_processing/hi/l0/decom_hi.py +0 -24
- imap_processing/hi/packet_definitions/hi_packet_definition.xml +0 -482
- imap_processing/tests/hi/test_decom.py +0 -55
- imap_processing/tests/hi/test_l1a_sci_de.py +0 -72
- {imap_processing-0.8.0.dist-info → imap_processing-0.9.0.dist-info}/LICENSE +0 -0
- {imap_processing-0.8.0.dist-info → imap_processing-0.9.0.dist-info}/WHEEL +0 -0
- {imap_processing-0.8.0.dist-info → imap_processing-0.9.0.dist-info}/entry_points.txt +0 -0
|
@@ -8,7 +8,6 @@ import numpy as np
|
|
|
8
8
|
import xarray as xr
|
|
9
9
|
|
|
10
10
|
from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
|
|
11
|
-
from imap_processing.cdf.utils import J2000_EPOCH
|
|
12
11
|
from imap_processing.mag.constants import DataMode, PrimarySensor
|
|
13
12
|
from imap_processing.mag.l0 import decom_mag
|
|
14
13
|
from imap_processing.mag.l0.mag_l0_data import MagL0
|
|
@@ -17,7 +16,7 @@ from imap_processing.mag.l1a.mag_l1a_data import (
|
|
|
17
16
|
MagL1aPacketProperties,
|
|
18
17
|
TimeTuple,
|
|
19
18
|
)
|
|
20
|
-
from imap_processing.spice.time import met_to_j2000ns
|
|
19
|
+
from imap_processing.spice.time import J2000_EPOCH, met_to_j2000ns
|
|
21
20
|
|
|
22
21
|
logger = logging.getLogger(__name__)
|
|
23
22
|
|
|
@@ -9,7 +9,6 @@ from math import floor
|
|
|
9
9
|
import numpy as np
|
|
10
10
|
import numpy.typing as npt
|
|
11
11
|
|
|
12
|
-
from imap_processing.cdf.utils import J2000_EPOCH
|
|
13
12
|
from imap_processing.mag.constants import (
|
|
14
13
|
AXIS_COUNT,
|
|
15
14
|
FIBONACCI_SEQUENCE,
|
|
@@ -17,7 +16,7 @@ from imap_processing.mag.constants import (
|
|
|
17
16
|
MAX_FINE_TIME,
|
|
18
17
|
RANGE_BIT_WIDTH,
|
|
19
18
|
)
|
|
20
|
-
from imap_processing.spice.time import met_to_j2000ns
|
|
19
|
+
from imap_processing.spice.time import J2000_EPOCH, met_to_j2000ns
|
|
21
20
|
|
|
22
21
|
|
|
23
22
|
@dataclass
|
|
@@ -202,6 +202,7 @@ def calibrate_vector(
|
|
|
202
202
|
updated_vector = input_vector.copy()
|
|
203
203
|
|
|
204
204
|
updated_vector[:3] = np.matmul(
|
|
205
|
-
|
|
205
|
+
calibration_matrix.values[:, :, int(input_vector[3])], input_vector[:3]
|
|
206
206
|
)
|
|
207
|
+
|
|
207
208
|
return updated_vector
|
|
@@ -64,8 +64,6 @@ class SpiceFrame(IntEnum):
|
|
|
64
64
|
IMAP_GLOWS = -43750
|
|
65
65
|
|
|
66
66
|
|
|
67
|
-
# TODO: Update boresight for in-situ instruments
|
|
68
|
-
# TODO: Confirm ENA boresight vectors
|
|
69
67
|
BORESIGHT_LOOKUP = {
|
|
70
68
|
SpiceFrame.IMAP_LO: np.array([0, -1, 0]),
|
|
71
69
|
SpiceFrame.IMAP_HI_45: np.array([0, 1, 0]),
|
|
@@ -73,12 +71,12 @@ BORESIGHT_LOOKUP = {
|
|
|
73
71
|
SpiceFrame.IMAP_ULTRA_45: np.array([0, 0, 1]),
|
|
74
72
|
SpiceFrame.IMAP_ULTRA_90: np.array([0, 0, 1]),
|
|
75
73
|
SpiceFrame.IMAP_MAG: np.array([0, 0, 1]),
|
|
76
|
-
SpiceFrame.IMAP_SWE: np.array([
|
|
77
|
-
SpiceFrame.IMAP_SWAPI: np.array([0,
|
|
74
|
+
SpiceFrame.IMAP_SWE: np.array([-1, 0, 0]),
|
|
75
|
+
SpiceFrame.IMAP_SWAPI: np.array([0, 1, 0]),
|
|
78
76
|
SpiceFrame.IMAP_CODICE: np.array([0, 0, 1]),
|
|
79
|
-
SpiceFrame.IMAP_HIT: np.array([0,
|
|
80
|
-
SpiceFrame.IMAP_IDEX: np.array([0,
|
|
81
|
-
SpiceFrame.IMAP_GLOWS: np.array([0, 0, 1]),
|
|
77
|
+
SpiceFrame.IMAP_HIT: np.array([0, 1, 0]),
|
|
78
|
+
SpiceFrame.IMAP_IDEX: np.array([0, 1, 0]),
|
|
79
|
+
SpiceFrame.IMAP_GLOWS: np.array([0, 0, -1]),
|
|
82
80
|
}
|
|
83
81
|
|
|
84
82
|
|
|
@@ -326,8 +324,11 @@ def frame_transform(
|
|
|
326
324
|
Ephemeris time(s) corresponding to position(s).
|
|
327
325
|
position : np.ndarray
|
|
328
326
|
<x, y, z> vector or array of vectors in reference frame `from_frame`.
|
|
329
|
-
|
|
330
|
-
|
|
327
|
+
There are several possible shapes for the input position and et:
|
|
328
|
+
1. A single position vector may be provided for multiple `et` query times
|
|
329
|
+
2. A single `et` may be provided for multiple position vectors,
|
|
330
|
+
3. The same number of `et` and position vectors may be provided.
|
|
331
|
+
But it is not allowed to have n position vectors and m `et`, where n != m.
|
|
331
332
|
from_frame : SpiceFrame
|
|
332
333
|
Reference frame of input vector(s).
|
|
333
334
|
to_frame : SpiceFrame
|
|
@@ -350,11 +351,13 @@ def frame_transform(
|
|
|
350
351
|
f"Each input position vector must have 3 elements."
|
|
351
352
|
)
|
|
352
353
|
if not len(position) == np.asarray(et).size:
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
354
|
+
if np.asarray(et).size != 1:
|
|
355
|
+
raise ValueError(
|
|
356
|
+
"Mismatch in number of position vectors and "
|
|
357
|
+
"Ephemeris times provided."
|
|
358
|
+
f"Position has {len(position)} elements and et has "
|
|
359
|
+
f"{np.asarray(et).size} elements."
|
|
360
|
+
)
|
|
358
361
|
|
|
359
362
|
# rotate will have shape = (3, 3) or (n, 3, 3)
|
|
360
363
|
# position will have shape = (3,) or (n, 3)
|
|
@@ -494,6 +497,7 @@ def basis_vectors(
|
|
|
494
497
|
|
|
495
498
|
def cartesian_to_spherical(
|
|
496
499
|
v: NDArray,
|
|
500
|
+
degrees: bool = True,
|
|
497
501
|
) -> NDArray:
|
|
498
502
|
"""
|
|
499
503
|
Convert cartesian coordinates to spherical coordinates.
|
|
@@ -504,6 +508,9 @@ def cartesian_to_spherical(
|
|
|
504
508
|
A NumPy array with shape (n, 3) where each
|
|
505
509
|
row represents a vector
|
|
506
510
|
with x, y, z-components.
|
|
511
|
+
degrees : bool
|
|
512
|
+
If True, the azimuth and elevation angles are returned in degrees.
|
|
513
|
+
Defaults to True.
|
|
507
514
|
|
|
508
515
|
Returns
|
|
509
516
|
-------
|
|
@@ -512,8 +519,16 @@ def cartesian_to_spherical(
|
|
|
512
519
|
the spherical coordinates (r, azimuth, elevation):
|
|
513
520
|
|
|
514
521
|
- r : Distance of the point from the origin.
|
|
515
|
-
- azimuth : angle in the xy-plane
|
|
516
|
-
|
|
522
|
+
- azimuth : angle in the xy-plane
|
|
523
|
+
In degrees if degrees parameter is True (by default):
|
|
524
|
+
output range=[0, 360],
|
|
525
|
+
otherwise in radians if degrees parameter is False:
|
|
526
|
+
output range=[0, 2*pi].
|
|
527
|
+
- elevation : angle from the z-axis
|
|
528
|
+
In degrees if degrees parameter is True (by default):
|
|
529
|
+
output range=[0, 180],
|
|
530
|
+
otherwise in radians if degrees parameter is False:
|
|
531
|
+
output range=[-pi/2, pi/2].
|
|
517
532
|
"""
|
|
518
533
|
# Magnitude of the velocity vector
|
|
519
534
|
magnitude_v = np.linalg.norm(v, axis=-1, keepdims=True)
|
|
@@ -528,9 +543,12 @@ def cartesian_to_spherical(
|
|
|
528
543
|
|
|
529
544
|
# Ensure azimuth is from 0 to 2PI
|
|
530
545
|
az = az % (2 * np.pi)
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
546
|
+
|
|
547
|
+
if degrees:
|
|
548
|
+
az = np.degrees(az)
|
|
549
|
+
el = np.degrees(el)
|
|
550
|
+
|
|
551
|
+
spherical_coords = np.stack((np.squeeze(magnitude_v), az, el), axis=-1)
|
|
534
552
|
|
|
535
553
|
return spherical_coords
|
|
536
554
|
|
imap_processing/spice/time.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Time conversion functions that rely on SPICE."""
|
|
2
2
|
|
|
3
3
|
import typing
|
|
4
|
-
from collections.abc import Collection
|
|
4
|
+
from collections.abc import Collection, Iterable
|
|
5
5
|
from typing import Union
|
|
6
6
|
|
|
7
7
|
import numpy as np
|
|
@@ -13,6 +13,32 @@ from imap_processing.spice.kernels import ensure_spice
|
|
|
13
13
|
|
|
14
14
|
TICK_DURATION = 2e-5 # 20 microseconds as defined in imap_sclk_0000.tsc
|
|
15
15
|
|
|
16
|
+
# Hard code the J2000 epoch. This allows for CDF epoch to be converted without
|
|
17
|
+
# use of SPICE though it should be noted that this results in a 5-second error
|
|
18
|
+
# due to the occurrence of 5 leap-seconds since the J2000 epoch.
|
|
19
|
+
# TODO: Implement a function for converting CDF epoch to UTC correctly.
|
|
20
|
+
# see github ticket #1208
|
|
21
|
+
# The UTC string was generated by:
|
|
22
|
+
# >>> spiceypy.et2utc(0, "ISOC", 9)
|
|
23
|
+
J2000_EPOCH = np.datetime64("2000-01-01T11:58:55.816072737", "ns")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def met_to_sclkticks(met: npt.ArrayLike) -> npt.NDArray[float]:
|
|
27
|
+
"""
|
|
28
|
+
Convert Mission Elapsed Time (MET) to floating point spacecraft clock ticks.
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
met : float, numpy.ndarray
|
|
33
|
+
Number of seconds since epoch according to the spacecraft clock.
|
|
34
|
+
|
|
35
|
+
Returns
|
|
36
|
+
-------
|
|
37
|
+
numpy.ndarray[float]
|
|
38
|
+
The mission elapsed time converted to nanoseconds since the J2000 epoch.
|
|
39
|
+
"""
|
|
40
|
+
return np.asarray(met, dtype=float) / TICK_DURATION
|
|
41
|
+
|
|
16
42
|
|
|
17
43
|
def met_to_j2000ns(
|
|
18
44
|
met: npt.ArrayLike,
|
|
@@ -40,7 +66,7 @@ def met_to_j2000ns(
|
|
|
40
66
|
"tick" which is defined to be 20 microseconds, according to the sclk kernel,
|
|
41
67
|
it is preferable to use the higher accuracy method.
|
|
42
68
|
"""
|
|
43
|
-
sclk_ticks =
|
|
69
|
+
sclk_ticks = met_to_sclkticks(met)
|
|
44
70
|
return np.asarray(_sct2e_wrapper(sclk_ticks) * 1e9, dtype=np.int64)
|
|
45
71
|
|
|
46
72
|
|
|
@@ -64,6 +90,53 @@ def j2000ns_to_j2000s(j2000ns: npt.ArrayLike) -> npt.NDArray[float]:
|
|
|
64
90
|
return np.asarray(j2000ns, dtype=np.float64) / 1e9
|
|
65
91
|
|
|
66
92
|
|
|
93
|
+
@typing.no_type_check
|
|
94
|
+
@ensure_spice(time_kernels_only=True)
|
|
95
|
+
def met_to_utc(met: npt.ArrayLike, precision: int = 9) -> npt.NDArray[str]:
|
|
96
|
+
"""
|
|
97
|
+
Convert mission elapsed time (MET) to UTC.
|
|
98
|
+
|
|
99
|
+
Parameters
|
|
100
|
+
----------
|
|
101
|
+
met : float, numpy.ndarray
|
|
102
|
+
Number of seconds since epoch according to the spacecraft clock.
|
|
103
|
+
precision : int
|
|
104
|
+
The number of digits of precision to which fractional seconds
|
|
105
|
+
are to be computed.
|
|
106
|
+
|
|
107
|
+
Returns
|
|
108
|
+
-------
|
|
109
|
+
numpy.ndarray[str]
|
|
110
|
+
The mission elapsed time converted to UTC string. The UTC string(s)
|
|
111
|
+
returned will be of the form '1987-04-12T16:31:12.814' with the
|
|
112
|
+
fractional seconds precision as specified by the precision keyword.
|
|
113
|
+
"""
|
|
114
|
+
sclk_ticks = met_to_sclkticks(met)
|
|
115
|
+
et = _sct2e_wrapper(sclk_ticks)
|
|
116
|
+
return spice.et2utc(et, "ISOC", prec=precision)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def met_to_datetime64(
|
|
120
|
+
met: npt.ArrayLike,
|
|
121
|
+
) -> Union[np.datetime64, npt.NDArray[np.datetime64]]:
|
|
122
|
+
"""
|
|
123
|
+
Convert mission elapsed time (MET) to datetime.datetime.
|
|
124
|
+
|
|
125
|
+
Parameters
|
|
126
|
+
----------
|
|
127
|
+
met : float, numpy.ndarray
|
|
128
|
+
Number of seconds since epoch according to the spacecraft clock.
|
|
129
|
+
|
|
130
|
+
Returns
|
|
131
|
+
-------
|
|
132
|
+
numpy.ndarray[str]
|
|
133
|
+
The mission elapsed time converted to UTC string.
|
|
134
|
+
"""
|
|
135
|
+
if isinstance(met, typing.Iterable):
|
|
136
|
+
return np.asarray([np.datetime64(utc) for utc in met_to_utc(met)])
|
|
137
|
+
return np.datetime64(met_to_utc(met))
|
|
138
|
+
|
|
139
|
+
|
|
67
140
|
@typing.no_type_check
|
|
68
141
|
@ensure_spice
|
|
69
142
|
def _sct2e_wrapper(
|
|
@@ -90,3 +163,72 @@ def _sct2e_wrapper(
|
|
|
90
163
|
return np.array([spice.sct2e(IMAP_SC_ID, s) for s in sclk_ticks])
|
|
91
164
|
else:
|
|
92
165
|
return spice.sct2e(IMAP_SC_ID, sclk_ticks)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
@typing.no_type_check
|
|
169
|
+
@ensure_spice
|
|
170
|
+
def str_to_et(
|
|
171
|
+
time_str: Union[str, Iterable[str]],
|
|
172
|
+
) -> Union[float, np.ndarray]:
|
|
173
|
+
"""
|
|
174
|
+
Convert string to ephemeris time.
|
|
175
|
+
|
|
176
|
+
Decorated wrapper for spiceypy.str2et that vectorizes the function in addition
|
|
177
|
+
to wrapping with the @ensure_spice automatic kernel furnishing functionality.
|
|
178
|
+
https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.str2et
|
|
179
|
+
|
|
180
|
+
Parameters
|
|
181
|
+
----------
|
|
182
|
+
time_str : str or Iterable[str]
|
|
183
|
+
Input string(s) to be converted to ephemeris time.
|
|
184
|
+
|
|
185
|
+
Returns
|
|
186
|
+
-------
|
|
187
|
+
ephemeris_time: np.ndarray
|
|
188
|
+
Ephemeris time, seconds past J2000.
|
|
189
|
+
"""
|
|
190
|
+
if isinstance(time_str, str):
|
|
191
|
+
return spice.str2et(time_str)
|
|
192
|
+
else:
|
|
193
|
+
return np.array([spice.str2et(t) for t in time_str])
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
@typing.no_type_check
|
|
197
|
+
@ensure_spice
|
|
198
|
+
def et_to_utc(
|
|
199
|
+
et: Union[float, Iterable[float]],
|
|
200
|
+
format_str: str = "ISOC",
|
|
201
|
+
precision: int = 3,
|
|
202
|
+
utclen: int = 24,
|
|
203
|
+
) -> Union[str, np.ndarray]:
|
|
204
|
+
"""
|
|
205
|
+
Convert ephemeris time to UTC.
|
|
206
|
+
|
|
207
|
+
Decorated wrapper for spiceypy.et2utc that vectorizes the function in addition
|
|
208
|
+
to wrapping with the @ensure_spice automatic kernel furnishing functionality.
|
|
209
|
+
https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.et2utc
|
|
210
|
+
|
|
211
|
+
Parameters
|
|
212
|
+
----------
|
|
213
|
+
et : float or Iterable[float]
|
|
214
|
+
Input ephemeris time(s) to be converted to UTC.
|
|
215
|
+
format_str : str
|
|
216
|
+
Format of the output time string. Default is "ISOC". All options:
|
|
217
|
+
"C" Calendar format, UTC.
|
|
218
|
+
"D" Day-of-Year format, UTC.
|
|
219
|
+
"J" Julian Date format, UTC.
|
|
220
|
+
"ISOC" ISO Calendar format, UTC.
|
|
221
|
+
"ISOD" ISO Day-of-Year format, UTC.
|
|
222
|
+
precision : int
|
|
223
|
+
Digits of precision in fractional seconds or days. Default is 3.
|
|
224
|
+
utclen : int
|
|
225
|
+
The length of the output string. Default is 24 (to accommodate the
|
|
226
|
+
"YYYY-MM-DDT00:00:00.000" format + 1). From the NAIF docs: if the output string
|
|
227
|
+
is expected to have `x` characters, utclen` must be x + 1.
|
|
228
|
+
|
|
229
|
+
Returns
|
|
230
|
+
-------
|
|
231
|
+
utc_time : str or np.ndarray
|
|
232
|
+
UTC time(s).
|
|
233
|
+
"""
|
|
234
|
+
return spice.et2utc(et, format_str, precision, utclen)
|
|
@@ -39,7 +39,7 @@ def filter_good_data(full_sweep_sci: xr.Dataset) -> npt.NDArray:
|
|
|
39
39
|
"""
|
|
40
40
|
# PLAN_ID for current sweep should all be one value and
|
|
41
41
|
# SWEEP_TABLE should all be one value.
|
|
42
|
-
plan_id = full_sweep_sci["
|
|
42
|
+
plan_id = full_sweep_sci["plan_id"].data.reshape(-1, 12)
|
|
43
43
|
sweep_table = full_sweep_sci["sweep_table"].data.reshape(-1, 12)
|
|
44
44
|
|
|
45
45
|
mode = full_sweep_sci["mode"].data.reshape(-1, 12)
|
|
@@ -72,7 +72,7 @@ def filter_good_data(full_sweep_sci: xr.Dataset) -> npt.NDArray:
|
|
|
72
72
|
)
|
|
73
73
|
logger.debug(
|
|
74
74
|
"Plan ID should be same: "
|
|
75
|
-
f"{full_sweep_sci['
|
|
75
|
+
f"{full_sweep_sci['plan_id'].data[bad_cycle_indices]}"
|
|
76
76
|
)
|
|
77
77
|
logger.debug(
|
|
78
78
|
f"Mode Id should be 3(HVSCI): {full_sweep_sci['mode'].data[bad_cycle_indices]}"
|
|
@@ -615,7 +615,7 @@ def process_swapi_science(
|
|
|
615
615
|
attrs=cdf_manager.get_variable_attributes("sweep_table"),
|
|
616
616
|
)
|
|
617
617
|
dataset["plan_id"] = xr.DataArray(
|
|
618
|
-
good_sweep_sci["
|
|
618
|
+
good_sweep_sci["plan_id"].data.reshape(total_full_sweeps, 12)[:, 0],
|
|
619
619
|
name="plan_id",
|
|
620
620
|
dims=["epoch"],
|
|
621
621
|
attrs=cdf_manager.get_variable_attributes("plan_id"),
|