imap-processing 0.7.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/__init__.py +1 -1
- imap_processing/_version.py +2 -2
- imap_processing/ccsds/excel_to_xtce.py +36 -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 +136 -9
- 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_hit_l1b_variable_attrs.yaml +9 -0
- imap_processing/cdf/config/imap_idex_global_cdf_attrs.yaml +14 -7
- imap_processing/cdf/config/imap_idex_l1a_variable_attrs.yaml +577 -235
- 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_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 +137 -79
- imap_processing/cdf/config/imap_variable_schema.yaml +13 -0
- imap_processing/cdf/imap_cdf_manager.py +31 -27
- imap_processing/cdf/utils.py +3 -5
- imap_processing/cli.py +25 -14
- imap_processing/codice/codice_l1a.py +153 -63
- imap_processing/codice/constants.py +10 -10
- imap_processing/codice/decompress.py +10 -11
- imap_processing/codice/utils.py +1 -0
- imap_processing/glows/l1a/glows_l1a.py +1 -2
- 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/hi_l1a.py +4 -4
- imap_processing/hi/l1a/histogram.py +107 -109
- imap_processing/hi/l1a/science_direct_event.py +92 -225
- imap_processing/hi/l1b/hi_l1b.py +85 -11
- imap_processing/hi/l1c/hi_l1c.py +23 -1
- imap_processing/hi/packet_definitions/TLM_HI_COMBINED_SCI.xml +3994 -0
- 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 +100 -156
- imap_processing/hit/l1a/hit_l1a.py +170 -184
- imap_processing/hit/l1b/hit_l1b.py +33 -153
- 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 +65 -84
- 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 +17 -1
- imap_processing/lo/l0/lo_science.py +45 -13
- imap_processing/lo/l1a/lo_l1a.py +76 -8
- imap_processing/lo/packet_definitions/lo_xtce.xml +8344 -1849
- imap_processing/mag/l0/decom_mag.py +4 -3
- imap_processing/mag/l1a/mag_l1a.py +12 -13
- imap_processing/mag/l1a/mag_l1a_data.py +1 -2
- imap_processing/mag/l1b/mag_l1b.py +90 -7
- imap_processing/spice/geometry.py +156 -16
- imap_processing/spice/time.py +144 -2
- imap_processing/swapi/l1/swapi_l1.py +4 -4
- imap_processing/swapi/l2/swapi_l2.py +1 -1
- imap_processing/swapi/packet_definitions/swapi_packet_definition.xml +1535 -446
- imap_processing/swe/l1b/swe_l1b_science.py +8 -8
- imap_processing/swe/l2/swe_l2.py +134 -17
- imap_processing/tests/ccsds/test_data/expected_output.xml +2 -1
- 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 +100 -58
- 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/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_data/l1a/imap_hi_l1a_45sensor-de_20250415_v000.cdf +0 -0
- imap_processing/tests/hi/test_hi_l1b.py +73 -3
- imap_processing/tests/hi/test_hi_l1c.py +10 -2
- imap_processing/tests/hi/test_l1a.py +31 -58
- imap_processing/tests/hi/test_science_direct_event.py +58 -0
- imap_processing/tests/hi/test_utils.py +4 -3
- imap_processing/tests/hit/test_data/sci_sample1.ccsds +0 -0
- imap_processing/tests/hit/{test_hit_decom.py → test_decom_hit.py} +95 -36
- imap_processing/tests/hit/test_hit_l1a.py +299 -179
- imap_processing/tests/hit/test_hit_l1b.py +231 -24
- imap_processing/tests/hit/test_hit_utils.py +218 -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 +2 -2
- 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 +4 -4
- imap_processing/tests/idex/test_idex_l1a.py +8 -2
- 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 +69 -5
- 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/imap_mag_l1a_norm-magi_20251017_v001.cdf +0 -0
- imap_processing/tests/mag/test_mag_l1b.py +97 -7
- imap_processing/tests/spice/test_data/imap_ena_sim_metakernel.template +3 -1
- imap_processing/tests/spice/test_geometry.py +115 -9
- 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/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/swe/test_swe_l2.py +64 -8
- imap_processing/tests/test_utils.py +2 -2
- 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/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 +113 -0
- imap_processing/tests/ultra/unit/test_spatial_utils.py +125 -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 +55 -35
- imap_processing/tests/ultra/unit/test_ultra_l1c_pset_bins.py +10 -68
- imap_processing/ultra/constants.py +12 -3
- imap_processing/ultra/l1b/de.py +168 -30
- imap_processing/ultra/l1b/ultra_l1b_annotated.py +24 -10
- imap_processing/ultra/l1b/ultra_l1b_extended.py +46 -80
- imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +60 -144
- imap_processing/ultra/utils/spatial_utils.py +221 -0
- {imap_processing-0.7.0.dist-info → imap_processing-0.9.0.dist-info}/METADATA +15 -14
- {imap_processing-0.7.0.dist-info → imap_processing-0.9.0.dist-info}/RECORD +142 -139
- 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/hi/l0/decom_hi.py +0 -24
- imap_processing/hi/packet_definitions/hi_packet_definition.xml +0 -482
- 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/hi/test_decom.py +0 -55
- imap_processing/tests/hi/test_l1a_sci_de.py +0 -72
- 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/{hi/l0/__init__.py → tests/glows/test_glows_l2_data.py} +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.9.0.dist-info}/LICENSE +0 -0
- {imap_processing-0.7.0.dist-info → imap_processing-0.9.0.dist-info}/WHEEL +0 -0
- {imap_processing-0.7.0.dist-info → imap_processing-0.9.0.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"""Functions to support I-ALiRT CoDICE Lo processing."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
import xarray as xr
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def find_groups(data: xr.Dataset) -> xr.Dataset:
|
|
13
|
+
"""
|
|
14
|
+
Find all occurrences of the sequential set of 233 values 0-232.
|
|
15
|
+
|
|
16
|
+
If a value is missing, or we are starting/ending
|
|
17
|
+
in the middle of a sequence we do not count that as a valid group.
|
|
18
|
+
|
|
19
|
+
Parameters
|
|
20
|
+
----------
|
|
21
|
+
data : xr.Dataset
|
|
22
|
+
CoDICE Lo Dataset.
|
|
23
|
+
|
|
24
|
+
Returns
|
|
25
|
+
-------
|
|
26
|
+
grouped_data : xr.Dataset
|
|
27
|
+
Grouped data.
|
|
28
|
+
"""
|
|
29
|
+
subcom_range = (0, 232)
|
|
30
|
+
|
|
31
|
+
data = data.sortby("cod_lo_acq", ascending=True)
|
|
32
|
+
|
|
33
|
+
# Use cod_lo_counter == 0 to define the beginning of the group.
|
|
34
|
+
# Find cod_lo_acq at this index and use it as the beginning time for the group.
|
|
35
|
+
start_sc_ticks = data["cod_lo_acq"][(data["cod_lo_counter"] == subcom_range[0])]
|
|
36
|
+
start_sc_tick = start_sc_ticks.min()
|
|
37
|
+
# Use cod_lo_counter == 232 to define the end of the group.
|
|
38
|
+
last_sc_ticks = data["cod_lo_acq"][
|
|
39
|
+
([data["cod_lo_counter"] == subcom_range[-1]][-1])
|
|
40
|
+
]
|
|
41
|
+
last_sc_tick = last_sc_ticks.max()
|
|
42
|
+
|
|
43
|
+
# Filter out data before the first cod_lo_counter=0 and
|
|
44
|
+
# after the last cod_lo_counter=232.
|
|
45
|
+
grouped_data = data.where(
|
|
46
|
+
(data["cod_lo_acq"] >= start_sc_tick) & (data["cod_lo_acq"] <= last_sc_tick),
|
|
47
|
+
drop=True,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
# Assign labels based on the cod_lo_acq times.
|
|
51
|
+
group_labels = np.searchsorted(
|
|
52
|
+
start_sc_ticks, grouped_data["cod_lo_acq"], side="right"
|
|
53
|
+
)
|
|
54
|
+
# Example:
|
|
55
|
+
# grouped_data.coords
|
|
56
|
+
# Coordinates:
|
|
57
|
+
# * epoch (epoch) int64 7kB 315922822184000000 ... 315923721184000000
|
|
58
|
+
# * group (group) int64 7kB 1 1 1 1 1 1 1 1 1 ... 15 15 15 15 15 15 15 15 15
|
|
59
|
+
grouped_data["group"] = ("group", group_labels)
|
|
60
|
+
|
|
61
|
+
return grouped_data
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def append_cod_lo_data(dataset: xr.Dataset) -> xr.Dataset:
|
|
65
|
+
"""
|
|
66
|
+
Append the cod_lo_## data values and create an xarray.
|
|
67
|
+
|
|
68
|
+
Parameters
|
|
69
|
+
----------
|
|
70
|
+
dataset : xr.Dataset
|
|
71
|
+
Original dataset of group.
|
|
72
|
+
|
|
73
|
+
Returns
|
|
74
|
+
-------
|
|
75
|
+
appended_dataset : xr.Dataset
|
|
76
|
+
Dataset with cod_lo_## stacked.
|
|
77
|
+
"""
|
|
78
|
+
# Number of codice lo data rows
|
|
79
|
+
num_cod_lo_rows = 15
|
|
80
|
+
cod_lo_data = np.stack(
|
|
81
|
+
[dataset[f"cod_lo_data_{i:02}"].values for i in range(num_cod_lo_rows)], axis=1
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
repeated_data = {
|
|
85
|
+
var: np.repeat(dataset[var].values, num_cod_lo_rows)
|
|
86
|
+
for var in dataset.data_vars
|
|
87
|
+
if not var.startswith("cod_lo_data_")
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
repeated_data["cod_lo_appended"] = cod_lo_data.flatten()
|
|
91
|
+
repeated_epoch = np.repeat(dataset["epoch"].values, num_cod_lo_rows)
|
|
92
|
+
|
|
93
|
+
appended_dataset = xr.Dataset(
|
|
94
|
+
data_vars={name: ("epoch", values) for name, values in repeated_data.items()},
|
|
95
|
+
coords={"epoch": repeated_epoch},
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
return appended_dataset
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def process_codicelo(xarray_data: xr.Dataset) -> list[dict]:
|
|
102
|
+
"""
|
|
103
|
+
Create final data products.
|
|
104
|
+
|
|
105
|
+
Parameters
|
|
106
|
+
----------
|
|
107
|
+
xarray_data : xr.Dataset
|
|
108
|
+
Parsed data.
|
|
109
|
+
|
|
110
|
+
Returns
|
|
111
|
+
-------
|
|
112
|
+
codicelo_data : list[dict]
|
|
113
|
+
Dictionary of final data product.
|
|
114
|
+
|
|
115
|
+
Notes
|
|
116
|
+
-----
|
|
117
|
+
This function is incomplete and will need to be updated to include the
|
|
118
|
+
necessary calculations and data products.
|
|
119
|
+
- Calculate species counts (pg 27 of Algorithm Document)
|
|
120
|
+
- Calculate rates (assume 4 minutes per group)
|
|
121
|
+
- Calculate L2 CoDICE pseudodensities (pg 37 of Algorithm Document)
|
|
122
|
+
- Calculate the public data products
|
|
123
|
+
"""
|
|
124
|
+
grouped_data = find_groups(xarray_data)
|
|
125
|
+
unique_groups = np.unique(grouped_data["group"])
|
|
126
|
+
codicelo_data: list[dict[str, Any]] = [{}]
|
|
127
|
+
|
|
128
|
+
for group in unique_groups:
|
|
129
|
+
# cod_lo_counter values for the group should be 0-232 with no duplicates.
|
|
130
|
+
subcom_values = grouped_data["cod_lo_counter"][
|
|
131
|
+
(grouped_data["group"] == group).values
|
|
132
|
+
]
|
|
133
|
+
|
|
134
|
+
# Ensure no duplicates and all values from 0 to 232 are present
|
|
135
|
+
if not np.array_equal(subcom_values, np.arange(233)):
|
|
136
|
+
logger.warning(
|
|
137
|
+
f"Group {group} does not contain all values from 0 to "
|
|
138
|
+
f"232 without duplicates."
|
|
139
|
+
)
|
|
140
|
+
continue
|
|
141
|
+
|
|
142
|
+
mask = grouped_data["group"] == group
|
|
143
|
+
filtered_indices = np.where(mask)[0]
|
|
144
|
+
group_data = grouped_data.isel(epoch=filtered_indices)
|
|
145
|
+
|
|
146
|
+
append_cod_lo_data(group_data)
|
|
147
|
+
|
|
148
|
+
# TODO: calculate species counts
|
|
149
|
+
# TODO: calculate rates
|
|
150
|
+
# TODO: calculate L2 CoDICE pseudodensities
|
|
151
|
+
# TODO: calculate the public data products
|
|
152
|
+
|
|
153
|
+
return codicelo_data
|
|
@@ -161,13 +161,12 @@ def process_hit(xarray_data: xr.Dataset) -> list[dict]:
|
|
|
161
161
|
|
|
162
162
|
Parameters
|
|
163
163
|
----------
|
|
164
|
-
xarray_data :
|
|
165
|
-
|
|
166
|
-
set for processing.
|
|
164
|
+
xarray_data : xr.Dataset
|
|
165
|
+
Parsed data.
|
|
167
166
|
|
|
168
167
|
Returns
|
|
169
168
|
-------
|
|
170
|
-
hit_data : dict
|
|
169
|
+
hit_data : list[dict]
|
|
171
170
|
Dictionary final data product.
|
|
172
171
|
"""
|
|
173
172
|
hit_data = []
|
|
@@ -182,10 +181,11 @@ def process_hit(xarray_data: xr.Dataset) -> list[dict]:
|
|
|
182
181
|
|
|
183
182
|
# Ensure no duplicates and all values from 0 to 59 are present
|
|
184
183
|
if not np.array_equal(subcom_values, np.arange(60)):
|
|
185
|
-
|
|
184
|
+
logger.warning(
|
|
186
185
|
f"Group {group} does not contain all values from 0 to "
|
|
187
186
|
f"59 without duplicates."
|
|
188
187
|
)
|
|
188
|
+
continue
|
|
189
189
|
|
|
190
190
|
fast_rate_1 = grouped_data["hit_fast_rate_1"][
|
|
191
191
|
(grouped_data["group"] == group).values
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
<?xml version='1.0' encoding='UTF-8'?>
|
|
2
|
+
<xtce:SpaceSystem xmlns:xtce="http://www.omg.org/space/xtce" name="ialirt">
|
|
3
|
+
<xtce:Header date="2023-08-24T07:53:00MST" version="1.0" author="IMAP SDC" />
|
|
4
|
+
<xtce:TelemetryMetaData>
|
|
5
|
+
<xtce:ParameterTypeSet>
|
|
6
|
+
<!-- This file was manually created using content from:
|
|
7
|
+
I-ALiRT Packet Definitions: https://lasp.colorado.edu/galaxy/x/44nKCQ
|
|
8
|
+
-->
|
|
9
|
+
<xtce:IntegerParameterType name="uint0" signed="false">
|
|
10
|
+
<xtce:IntegerDataEncoding sizeInBits="0" encoding="unsigned" />
|
|
11
|
+
<xtce:UnitSet />
|
|
12
|
+
</xtce:IntegerParameterType>
|
|
13
|
+
<xtce:IntegerParameterType name="uint1" signed="false">
|
|
14
|
+
<xtce:IntegerDataEncoding sizeInBits="1" encoding="unsigned" />
|
|
15
|
+
<xtce:UnitSet />
|
|
16
|
+
</xtce:IntegerParameterType>
|
|
17
|
+
<xtce:IntegerParameterType name="uint2" signed="false">
|
|
18
|
+
<xtce:IntegerDataEncoding sizeInBits="2" encoding="unsigned" />
|
|
19
|
+
<xtce:UnitSet />
|
|
20
|
+
</xtce:IntegerParameterType>
|
|
21
|
+
<xtce:IntegerParameterType name="uint3" signed="false">
|
|
22
|
+
<xtce:IntegerDataEncoding sizeInBits="3" encoding="unsigned" />
|
|
23
|
+
<xtce:UnitSet />
|
|
24
|
+
</xtce:IntegerParameterType>
|
|
25
|
+
<xtce:IntegerParameterType name="uint4" signed="false">
|
|
26
|
+
<xtce:IntegerDataEncoding sizeInBits="4" encoding="unsigned" />
|
|
27
|
+
<xtce:UnitSet />
|
|
28
|
+
</xtce:IntegerParameterType>
|
|
29
|
+
<xtce:IntegerParameterType name="uint5" signed="false">
|
|
30
|
+
<xtce:IntegerDataEncoding sizeInBits="5" encoding="unsigned" />
|
|
31
|
+
<xtce:UnitSet />
|
|
32
|
+
</xtce:IntegerParameterType>
|
|
33
|
+
<xtce:IntegerParameterType name="uint6" signed="false">
|
|
34
|
+
<xtce:IntegerDataEncoding sizeInBits="6" encoding="unsigned" />
|
|
35
|
+
<xtce:UnitSet />
|
|
36
|
+
</xtce:IntegerParameterType>
|
|
37
|
+
<xtce:IntegerParameterType name="uint7" signed="false">
|
|
38
|
+
<xtce:IntegerDataEncoding sizeInBits="7" encoding="unsigned" />
|
|
39
|
+
<xtce:UnitSet />
|
|
40
|
+
</xtce:IntegerParameterType>
|
|
41
|
+
<xtce:IntegerParameterType name="uint8" signed="false">
|
|
42
|
+
<xtce:IntegerDataEncoding sizeInBits="8" encoding="unsigned" />
|
|
43
|
+
<xtce:UnitSet />
|
|
44
|
+
</xtce:IntegerParameterType>
|
|
45
|
+
<xtce:IntegerParameterType name="uint9" signed="false">
|
|
46
|
+
<xtce:IntegerDataEncoding sizeInBits="9" encoding="unsigned" />
|
|
47
|
+
<xtce:UnitSet />
|
|
48
|
+
</xtce:IntegerParameterType>
|
|
49
|
+
<xtce:IntegerParameterType name="uint10" signed="false">
|
|
50
|
+
<xtce:IntegerDataEncoding sizeInBits="10" encoding="unsigned" />
|
|
51
|
+
<xtce:UnitSet />
|
|
52
|
+
</xtce:IntegerParameterType>
|
|
53
|
+
<xtce:IntegerParameterType name="uint11" signed="false">
|
|
54
|
+
<xtce:IntegerDataEncoding sizeInBits="11" encoding="unsigned" />
|
|
55
|
+
<xtce:UnitSet />
|
|
56
|
+
</xtce:IntegerParameterType>
|
|
57
|
+
<xtce:IntegerParameterType name="uint12" signed="false">
|
|
58
|
+
<xtce:IntegerDataEncoding sizeInBits="12" encoding="unsigned" />
|
|
59
|
+
<xtce:UnitSet />
|
|
60
|
+
</xtce:IntegerParameterType>
|
|
61
|
+
<xtce:IntegerParameterType name="uint13" signed="false">
|
|
62
|
+
<xtce:IntegerDataEncoding sizeInBits="13" encoding="unsigned" />
|
|
63
|
+
<xtce:UnitSet />
|
|
64
|
+
</xtce:IntegerParameterType>
|
|
65
|
+
<xtce:IntegerParameterType name="uint14" signed="false">
|
|
66
|
+
<xtce:IntegerDataEncoding sizeInBits="14" encoding="unsigned" />
|
|
67
|
+
<xtce:UnitSet />
|
|
68
|
+
</xtce:IntegerParameterType>
|
|
69
|
+
<xtce:IntegerParameterType name="uint15" signed="false">
|
|
70
|
+
<xtce:IntegerDataEncoding sizeInBits="15" encoding="unsigned" />
|
|
71
|
+
<xtce:UnitSet />
|
|
72
|
+
</xtce:IntegerParameterType>
|
|
73
|
+
<xtce:IntegerParameterType name="uint16" signed="false">
|
|
74
|
+
<xtce:IntegerDataEncoding sizeInBits="16" encoding="unsigned" />
|
|
75
|
+
<xtce:UnitSet />
|
|
76
|
+
</xtce:IntegerParameterType>
|
|
77
|
+
<xtce:IntegerParameterType name="uint17" signed="false">
|
|
78
|
+
<xtce:IntegerDataEncoding sizeInBits="17" encoding="unsigned" />
|
|
79
|
+
<xtce:UnitSet />
|
|
80
|
+
</xtce:IntegerParameterType>
|
|
81
|
+
<xtce:IntegerParameterType name="uint18" signed="false">
|
|
82
|
+
<xtce:IntegerDataEncoding sizeInBits="18" encoding="unsigned" />
|
|
83
|
+
<xtce:UnitSet />
|
|
84
|
+
</xtce:IntegerParameterType>
|
|
85
|
+
<xtce:IntegerParameterType name="uint19" signed="false">
|
|
86
|
+
<xtce:IntegerDataEncoding sizeInBits="19" encoding="unsigned" />
|
|
87
|
+
<xtce:UnitSet />
|
|
88
|
+
</xtce:IntegerParameterType>
|
|
89
|
+
<xtce:IntegerParameterType name="uint20" signed="false">
|
|
90
|
+
<xtce:IntegerDataEncoding sizeInBits="20" encoding="unsigned" />
|
|
91
|
+
<xtce:UnitSet />
|
|
92
|
+
</xtce:IntegerParameterType>
|
|
93
|
+
<xtce:IntegerParameterType name="uint21" signed="false">
|
|
94
|
+
<xtce:IntegerDataEncoding sizeInBits="21" encoding="unsigned" />
|
|
95
|
+
<xtce:UnitSet />
|
|
96
|
+
</xtce:IntegerParameterType>
|
|
97
|
+
<xtce:IntegerParameterType name="uint22" signed="false">
|
|
98
|
+
<xtce:IntegerDataEncoding sizeInBits="22" encoding="unsigned" />
|
|
99
|
+
<xtce:UnitSet />
|
|
100
|
+
</xtce:IntegerParameterType>
|
|
101
|
+
<xtce:IntegerParameterType name="uint23" signed="false">
|
|
102
|
+
<xtce:IntegerDataEncoding sizeInBits="23" encoding="unsigned" />
|
|
103
|
+
<xtce:UnitSet />
|
|
104
|
+
</xtce:IntegerParameterType>
|
|
105
|
+
<xtce:IntegerParameterType name="uint24" signed="false">
|
|
106
|
+
<xtce:IntegerDataEncoding sizeInBits="24" encoding="unsigned" />
|
|
107
|
+
<xtce:UnitSet />
|
|
108
|
+
</xtce:IntegerParameterType>
|
|
109
|
+
<xtce:IntegerParameterType name="uint25" signed="false">
|
|
110
|
+
<xtce:IntegerDataEncoding sizeInBits="25" encoding="unsigned" />
|
|
111
|
+
<xtce:UnitSet />
|
|
112
|
+
</xtce:IntegerParameterType>
|
|
113
|
+
<xtce:IntegerParameterType name="uint26" signed="false">
|
|
114
|
+
<xtce:IntegerDataEncoding sizeInBits="26" encoding="unsigned" />
|
|
115
|
+
<xtce:UnitSet />
|
|
116
|
+
</xtce:IntegerParameterType>
|
|
117
|
+
<xtce:IntegerParameterType name="uint27" signed="false">
|
|
118
|
+
<xtce:IntegerDataEncoding sizeInBits="27" encoding="unsigned" />
|
|
119
|
+
<xtce:UnitSet />
|
|
120
|
+
</xtce:IntegerParameterType>
|
|
121
|
+
<xtce:IntegerParameterType name="uint28" signed="false">
|
|
122
|
+
<xtce:IntegerDataEncoding sizeInBits="28" encoding="unsigned" />
|
|
123
|
+
<xtce:UnitSet />
|
|
124
|
+
</xtce:IntegerParameterType>
|
|
125
|
+
<xtce:IntegerParameterType name="uint29" signed="false">
|
|
126
|
+
<xtce:IntegerDataEncoding sizeInBits="29" encoding="unsigned" />
|
|
127
|
+
<xtce:UnitSet />
|
|
128
|
+
</xtce:IntegerParameterType>
|
|
129
|
+
<xtce:IntegerParameterType name="uint30" signed="false">
|
|
130
|
+
<xtce:IntegerDataEncoding sizeInBits="30" encoding="unsigned" />
|
|
131
|
+
<xtce:UnitSet />
|
|
132
|
+
</xtce:IntegerParameterType>
|
|
133
|
+
<xtce:IntegerParameterType name="uint31" signed="false">
|
|
134
|
+
<xtce:IntegerDataEncoding sizeInBits="31" encoding="unsigned" />
|
|
135
|
+
<xtce:UnitSet />
|
|
136
|
+
</xtce:IntegerParameterType>
|
|
137
|
+
<xtce:IntegerParameterType name="uint32" signed="false">
|
|
138
|
+
<xtce:IntegerDataEncoding sizeInBits="32" encoding="unsigned" />
|
|
139
|
+
<xtce:UnitSet />
|
|
140
|
+
</xtce:IntegerParameterType>
|
|
141
|
+
<xtce:IntegerParameterType name="uint48" signed="false">
|
|
142
|
+
<xtce:IntegerDataEncoding sizeInBits="48" encoding="unsigned" />
|
|
143
|
+
<xtce:UnitSet />
|
|
144
|
+
</xtce:IntegerParameterType>
|
|
145
|
+
</xtce:ParameterTypeSet>
|
|
146
|
+
<xtce:ParameterSet>
|
|
147
|
+
<!-- Within the ParameterSet, utilize the data types defined in the ParameterTypeSet to create variables
|
|
148
|
+
with their respective data types. -->
|
|
149
|
+
|
|
150
|
+
<!--CCSDS Header Elements-->
|
|
151
|
+
<xtce:Parameter name="VERSION" parameterTypeRef="uint3">
|
|
152
|
+
<xtce:LongDescription>CCSDS Packet Version Number (always 0)</xtce:LongDescription>
|
|
153
|
+
</xtce:Parameter>
|
|
154
|
+
<xtce:Parameter name="TYPE" parameterTypeRef="uint1">
|
|
155
|
+
<xtce:LongDescription>CCSDS Packet Type Indicator (0=telemetry)</xtce:LongDescription>
|
|
156
|
+
</xtce:Parameter>
|
|
157
|
+
<xtce:Parameter name="SEC_HDR_FLG" parameterTypeRef="uint1">
|
|
158
|
+
<xtce:LongDescription>CCSDS Packet Secondary Header Flag (always 1)</xtce:LongDescription>
|
|
159
|
+
</xtce:Parameter>
|
|
160
|
+
<xtce:Parameter name="PKT_APID" parameterTypeRef="uint11">
|
|
161
|
+
<xtce:LongDescription>CCSDS Packet Application Process ID</xtce:LongDescription>
|
|
162
|
+
</xtce:Parameter>
|
|
163
|
+
<xtce:Parameter name="SEQ_FLGS" parameterTypeRef="uint2">
|
|
164
|
+
<xtce:LongDescription>CCSDS Packet Grouping Flags (3=not part of group)</xtce:LongDescription>
|
|
165
|
+
</xtce:Parameter>
|
|
166
|
+
<xtce:Parameter name="SRC_SEQ_CTR" parameterTypeRef="uint14">
|
|
167
|
+
<xtce:LongDescription>CCSDS Packet Sequence Count (increments with each new packet)</xtce:LongDescription>
|
|
168
|
+
</xtce:Parameter>
|
|
169
|
+
<xtce:Parameter name="PKT_LEN" parameterTypeRef="uint16">
|
|
170
|
+
<xtce:LongDescription>CCSDS Packet Length (number of bytes after Packet length minus 1)</xtce:LongDescription>
|
|
171
|
+
</xtce:Parameter>
|
|
172
|
+
<!-- CoDICE LO -->
|
|
173
|
+
<xtce:Parameter name="COD_LO_SHCOARSE" parameterTypeRef="uint32">
|
|
174
|
+
<xtce:LongDescription>CODICE LO MET at End of Data Acquisition</xtce:LongDescription>
|
|
175
|
+
</xtce:Parameter>
|
|
176
|
+
<xtce:Parameter name="COD_LO_ACQ" parameterTypeRef="uint32">
|
|
177
|
+
<xtce:LongDescription>CODICE LO MET at End of Data Acquisition</xtce:LongDescription>
|
|
178
|
+
</xtce:Parameter>
|
|
179
|
+
<xtce:Parameter name="COD_LO_STATUS" parameterTypeRef="uint8">
|
|
180
|
+
<xtce:LongDescription>CODICE LO Status</xtce:LongDescription>
|
|
181
|
+
</xtce:Parameter>
|
|
182
|
+
<xtce:Parameter name="COD_LO_COUNTER" parameterTypeRef="uint8">
|
|
183
|
+
<xtce:LongDescription>CODICE LO Counter</xtce:LongDescription>
|
|
184
|
+
</xtce:Parameter>
|
|
185
|
+
<xtce:Parameter name="COD_LO_DATA_00" parameterTypeRef="uint8">
|
|
186
|
+
<xtce:LongDescription>CODICE LO Data_00</xtce:LongDescription>
|
|
187
|
+
</xtce:Parameter>
|
|
188
|
+
<xtce:Parameter name="COD_LO_DATA_01" parameterTypeRef="uint8">
|
|
189
|
+
<xtce:LongDescription>CODICE LO Data_01</xtce:LongDescription>
|
|
190
|
+
</xtce:Parameter>
|
|
191
|
+
<xtce:Parameter name="COD_LO_DATA_02" parameterTypeRef="uint8">
|
|
192
|
+
<xtce:LongDescription>CODICE LO Data_02</xtce:LongDescription>
|
|
193
|
+
</xtce:Parameter>
|
|
194
|
+
<xtce:Parameter name="COD_LO_DATA_03" parameterTypeRef="uint8">
|
|
195
|
+
<xtce:LongDescription>CODICE LO Data_03</xtce:LongDescription>
|
|
196
|
+
</xtce:Parameter>
|
|
197
|
+
<xtce:Parameter name="COD_LO_DATA_04" parameterTypeRef="uint8">
|
|
198
|
+
<xtce:LongDescription>CODICE LO Data_04</xtce:LongDescription>
|
|
199
|
+
</xtce:Parameter>
|
|
200
|
+
<xtce:Parameter name="COD_LO_DATA_05" parameterTypeRef="uint8">
|
|
201
|
+
<xtce:LongDescription>CODICE LO Data_05</xtce:LongDescription>
|
|
202
|
+
</xtce:Parameter>
|
|
203
|
+
<xtce:Parameter name="COD_LO_DATA_06" parameterTypeRef="uint8">
|
|
204
|
+
<xtce:LongDescription>CODICE LO Data_06</xtce:LongDescription>
|
|
205
|
+
</xtce:Parameter>
|
|
206
|
+
<xtce:Parameter name="COD_LO_DATA_07" parameterTypeRef="uint8">
|
|
207
|
+
<xtce:LongDescription>CODICE LO Data_07</xtce:LongDescription>
|
|
208
|
+
</xtce:Parameter>
|
|
209
|
+
<xtce:Parameter name="COD_LO_DATA_08" parameterTypeRef="uint8">
|
|
210
|
+
<xtce:LongDescription>CODICE LO Data_08</xtce:LongDescription>
|
|
211
|
+
</xtce:Parameter>
|
|
212
|
+
<xtce:Parameter name="COD_LO_DATA_09" parameterTypeRef="uint8">
|
|
213
|
+
<xtce:LongDescription>CODICE LO Data_09</xtce:LongDescription>
|
|
214
|
+
</xtce:Parameter>
|
|
215
|
+
<xtce:Parameter name="COD_LO_DATA_10" parameterTypeRef="uint8">
|
|
216
|
+
<xtce:LongDescription>CODICE LO Data_10</xtce:LongDescription>
|
|
217
|
+
</xtce:Parameter>
|
|
218
|
+
<xtce:Parameter name="COD_LO_DATA_11" parameterTypeRef="uint8">
|
|
219
|
+
<xtce:LongDescription>CODICE LO Data_11</xtce:LongDescription>
|
|
220
|
+
</xtce:Parameter>
|
|
221
|
+
<xtce:Parameter name="COD_LO_DATA_12" parameterTypeRef="uint8">
|
|
222
|
+
<xtce:LongDescription>CODICE LO Data_12</xtce:LongDescription>
|
|
223
|
+
</xtce:Parameter>
|
|
224
|
+
<xtce:Parameter name="COD_LO_DATA_13" parameterTypeRef="uint8">
|
|
225
|
+
<xtce:LongDescription>CODICE LO Data_13</xtce:LongDescription>
|
|
226
|
+
</xtce:Parameter>
|
|
227
|
+
<xtce:Parameter name="COD_LO_DATA_14" parameterTypeRef="uint8">
|
|
228
|
+
<xtce:LongDescription>CODICE LO Data_14</xtce:LongDescription>
|
|
229
|
+
</xtce:Parameter>
|
|
230
|
+
<xtce:Parameter name="COD_LO_SPARE_0" parameterTypeRef="uint8">
|
|
231
|
+
<xtce:LongDescription>CODICE LO Spare 0</xtce:LongDescription>
|
|
232
|
+
</xtce:Parameter>
|
|
233
|
+
<!-- CoDICE LO -->
|
|
234
|
+
</xtce:ParameterSet>
|
|
235
|
+
<!-- End metadata -->
|
|
236
|
+
<xtce:ContainerSet>
|
|
237
|
+
<xtce:SequenceContainer name="CCSDSPacket" >
|
|
238
|
+
<xtce:EntryList>
|
|
239
|
+
<xtce:ParameterRefEntry parameterRef="VERSION" />
|
|
240
|
+
<xtce:ParameterRefEntry parameterRef="TYPE" />
|
|
241
|
+
<xtce:ParameterRefEntry parameterRef="SEC_HDR_FLG" />
|
|
242
|
+
<xtce:ParameterRefEntry parameterRef="PKT_APID" />
|
|
243
|
+
<xtce:ParameterRefEntry parameterRef="SEQ_FLGS" />
|
|
244
|
+
<xtce:ParameterRefEntry parameterRef="SRC_SEQ_CTR" />
|
|
245
|
+
<xtce:ParameterRefEntry parameterRef="PKT_LEN" />
|
|
246
|
+
</xtce:EntryList>
|
|
247
|
+
</xtce:SequenceContainer>
|
|
248
|
+
<xtce:SequenceContainer name="IALiRTPacket">
|
|
249
|
+
<xtce:BaseContainer containerRef="CCSDSPacket">
|
|
250
|
+
<xtce:RestrictionCriteria>
|
|
251
|
+
<xtce:Comparison parameterRef="PKT_APID" value="1152" useCalibratedValue="false" />
|
|
252
|
+
</xtce:RestrictionCriteria>
|
|
253
|
+
</xtce:BaseContainer>
|
|
254
|
+
<xtce:EntryList>
|
|
255
|
+
<!-- CoDICE LO -->
|
|
256
|
+
<xtce:ParameterRefEntry parameterRef="COD_LO_SHCOARSE"/>
|
|
257
|
+
<xtce:ParameterRefEntry parameterRef="COD_LO_ACQ"/>
|
|
258
|
+
<xtce:ParameterRefEntry parameterRef="COD_LO_STATUS"/>
|
|
259
|
+
<xtce:ParameterRefEntry parameterRef="COD_LO_COUNTER"/>
|
|
260
|
+
<xtce:ParameterRefEntry parameterRef="COD_LO_DATA_00"/>
|
|
261
|
+
<xtce:ParameterRefEntry parameterRef="COD_LO_DATA_01"/>
|
|
262
|
+
<xtce:ParameterRefEntry parameterRef="COD_LO_DATA_02"/>
|
|
263
|
+
<xtce:ParameterRefEntry parameterRef="COD_LO_DATA_03"/>
|
|
264
|
+
<xtce:ParameterRefEntry parameterRef="COD_LO_DATA_04"/>
|
|
265
|
+
<xtce:ParameterRefEntry parameterRef="COD_LO_DATA_05"/>
|
|
266
|
+
<xtce:ParameterRefEntry parameterRef="COD_LO_DATA_06"/>
|
|
267
|
+
<xtce:ParameterRefEntry parameterRef="COD_LO_DATA_07"/>
|
|
268
|
+
<xtce:ParameterRefEntry parameterRef="COD_LO_DATA_08"/>
|
|
269
|
+
<xtce:ParameterRefEntry parameterRef="COD_LO_DATA_09"/>
|
|
270
|
+
<xtce:ParameterRefEntry parameterRef="COD_LO_DATA_10"/>
|
|
271
|
+
<xtce:ParameterRefEntry parameterRef="COD_LO_DATA_11"/>
|
|
272
|
+
<xtce:ParameterRefEntry parameterRef="COD_LO_DATA_12"/>
|
|
273
|
+
<xtce:ParameterRefEntry parameterRef="COD_LO_DATA_13"/>
|
|
274
|
+
<xtce:ParameterRefEntry parameterRef="COD_LO_DATA_14"/>
|
|
275
|
+
<xtce:ParameterRefEntry parameterRef="COD_LO_SPARE_0"/>
|
|
276
|
+
<!-- CoDICE LO -->
|
|
277
|
+
</xtce:EntryList>
|
|
278
|
+
</xtce:SequenceContainer>
|
|
279
|
+
</xtce:ContainerSet>
|
|
280
|
+
</xtce:TelemetryMetaData>
|
|
281
|
+
</xtce:SpaceSystem>
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Find azimuth (degrees), elevation (degrees), and doppler shift (Hz).
|
|
3
|
+
|
|
4
|
+
Based on ephemeris data and ground station location (longitude, latitude, altitude).
|
|
5
|
+
|
|
6
|
+
Reference: https://spiceypy.readthedocs.io/en/main/documentation.html.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import logging
|
|
10
|
+
import typing
|
|
11
|
+
from typing import Union
|
|
12
|
+
|
|
13
|
+
import numpy as np
|
|
14
|
+
import spiceypy as spice
|
|
15
|
+
from numpy import ndarray
|
|
16
|
+
|
|
17
|
+
from imap_processing.spice.geometry import SpiceBody
|
|
18
|
+
from imap_processing.spice.kernels import ensure_spice
|
|
19
|
+
from imap_processing.spice.time import et_to_utc, str_to_et
|
|
20
|
+
|
|
21
|
+
# Logger setup
|
|
22
|
+
logger = logging.getLogger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@typing.no_type_check
|
|
26
|
+
def calculate_doppler(
|
|
27
|
+
observation_time: Union[float, np.ndarray],
|
|
28
|
+
) -> Union[int, ndarray[float]]:
|
|
29
|
+
"""
|
|
30
|
+
Calculate the doppler shift. Placeholder for now.
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
observation_time : float or np.ndarray
|
|
35
|
+
Time at which the state of the target relative to the observer
|
|
36
|
+
is to be computed. Expressed as ephemeris time, seconds past J2000 TDB.
|
|
37
|
+
|
|
38
|
+
Returns
|
|
39
|
+
-------
|
|
40
|
+
doppler : float or np.ndarray[float]
|
|
41
|
+
Doppler shift. Currently a throwaway value.
|
|
42
|
+
"""
|
|
43
|
+
if isinstance(observation_time, np.ndarray):
|
|
44
|
+
return np.ones(len(observation_time), dtype=float)
|
|
45
|
+
else:
|
|
46
|
+
return 1
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@typing.no_type_check
|
|
50
|
+
@ensure_spice
|
|
51
|
+
def latitude_longitude_to_ecef(
|
|
52
|
+
longitude: float, latitude: float, altitude: float
|
|
53
|
+
) -> ndarray:
|
|
54
|
+
"""
|
|
55
|
+
Convert geodetic coordinates to rectangular coordinates.
|
|
56
|
+
|
|
57
|
+
Earth-Centered, Earth-Fixed (ECEF) coordinates are a Cartesian coordinate system
|
|
58
|
+
with an origin at the center of the Earth.
|
|
59
|
+
|
|
60
|
+
Parameters
|
|
61
|
+
----------
|
|
62
|
+
longitude : float
|
|
63
|
+
Longitude in decimal degrees. Positive east of prime meridian, negative to west.
|
|
64
|
+
latitude : float
|
|
65
|
+
Latitude in decimal degrees. Positive north of equator, negative to south.
|
|
66
|
+
altitude : float
|
|
67
|
+
Altitude in kilometers.
|
|
68
|
+
|
|
69
|
+
Returns
|
|
70
|
+
-------
|
|
71
|
+
rect_coords : ndarray
|
|
72
|
+
Rectangular coordinates in kilometers.
|
|
73
|
+
"""
|
|
74
|
+
latitude_radians = np.deg2rad(latitude)
|
|
75
|
+
longitude_radians = np.deg2rad(longitude)
|
|
76
|
+
|
|
77
|
+
# Retrieve Earth's radii from SPICE
|
|
78
|
+
# https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.bod
|
|
79
|
+
# (url cont.) vrd
|
|
80
|
+
radii = spice.bodvrd("EARTH", "RADII", 3)[1]
|
|
81
|
+
equatorial_radius = radii[0] # Equatorial radius in km
|
|
82
|
+
polar_radius = radii[2] # Polar radius in km
|
|
83
|
+
flattening = (equatorial_radius - polar_radius) / equatorial_radius
|
|
84
|
+
|
|
85
|
+
# Convert geodetic coordinates to rectangular coordinates
|
|
86
|
+
# https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.geo
|
|
87
|
+
# (url cont.) rec
|
|
88
|
+
rect_coords = spice.georec(
|
|
89
|
+
longitude_radians, latitude_radians, altitude, equatorial_radius, flattening
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
return rect_coords
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@typing.no_type_check
|
|
96
|
+
@ensure_spice
|
|
97
|
+
def calculate_azimuth_and_elevation(
|
|
98
|
+
longitude: float,
|
|
99
|
+
latitude: float,
|
|
100
|
+
altitude: float,
|
|
101
|
+
observation_time: Union[float, np.ndarray],
|
|
102
|
+
target: SpiceBody = SpiceBody.IMAP.name,
|
|
103
|
+
) -> tuple:
|
|
104
|
+
"""
|
|
105
|
+
Calculate azimuth and elevation.
|
|
106
|
+
|
|
107
|
+
Parameters
|
|
108
|
+
----------
|
|
109
|
+
longitude : float
|
|
110
|
+
Longitude in decimal degrees. Positive east of prime meridian,
|
|
111
|
+
negative to west.
|
|
112
|
+
latitude : float
|
|
113
|
+
Latitude in decimal degrees. Positive north of equator, negative
|
|
114
|
+
to south.
|
|
115
|
+
altitude : float
|
|
116
|
+
Altitude in kilometers.
|
|
117
|
+
observation_time : float or np.ndarray
|
|
118
|
+
Time at which the state of the target relative to the observer
|
|
119
|
+
is to be computed. Expressed as ephemeris time, seconds past J2000 TDB.
|
|
120
|
+
target : str (Optional)
|
|
121
|
+
The target body. Default is "IMAP".
|
|
122
|
+
|
|
123
|
+
Returns
|
|
124
|
+
-------
|
|
125
|
+
azimuth : np.ndarray
|
|
126
|
+
Azimuth in degrees.
|
|
127
|
+
elevation : np.ndarray
|
|
128
|
+
Elevation in degrees.
|
|
129
|
+
"""
|
|
130
|
+
observer_position_ecef = latitude_longitude_to_ecef(longitude, latitude, altitude)
|
|
131
|
+
|
|
132
|
+
if not isinstance(observation_time, np.ndarray):
|
|
133
|
+
observation_time = [observation_time]
|
|
134
|
+
|
|
135
|
+
azimuth = []
|
|
136
|
+
elevation = []
|
|
137
|
+
|
|
138
|
+
# https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.azlcpo
|
|
139
|
+
for timestamp in observation_time:
|
|
140
|
+
azel_results = spice.azlcpo(
|
|
141
|
+
method="Ellipsoid", # Only method supported
|
|
142
|
+
target=target, # target ephemeris object
|
|
143
|
+
et=timestamp, # time of observation
|
|
144
|
+
abcorr="LT+S", # Aberration correction
|
|
145
|
+
azccw=False, # Azimuth measured clockwise from the positive y-axis
|
|
146
|
+
elplsz=True, # Elevation increases from the XY plane toward +Z
|
|
147
|
+
obspos=observer_position_ecef, # observer pos. to center of motion
|
|
148
|
+
obsctr="EARTH", # Name of the center of motion
|
|
149
|
+
obsref="IAU_EARTH", # Body-fixed, body-centered reference frame wrt
|
|
150
|
+
# observer's center
|
|
151
|
+
)
|
|
152
|
+
azimuth.append(np.rad2deg(azel_results[0][1]))
|
|
153
|
+
elevation.append(np.rad2deg(azel_results[0][2]))
|
|
154
|
+
|
|
155
|
+
# TODO: potentially use the velocity components returned from azlcpo to
|
|
156
|
+
# TODO: calculate doppler
|
|
157
|
+
|
|
158
|
+
return np.asarray(azimuth), np.asarray(elevation)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def build_output(
|
|
162
|
+
longitude: float,
|
|
163
|
+
latitude: float,
|
|
164
|
+
altitude: float,
|
|
165
|
+
time_endpoints: tuple[str, str],
|
|
166
|
+
time_step: float,
|
|
167
|
+
) -> dict[str, np.ndarray]:
|
|
168
|
+
"""
|
|
169
|
+
Build the output dictionary containing time, azimuth, elevation, and doppler.
|
|
170
|
+
|
|
171
|
+
Parameters
|
|
172
|
+
----------
|
|
173
|
+
longitude : float
|
|
174
|
+
Longitude in decimal degrees. Positive east of prime meridian, negative to west.
|
|
175
|
+
latitude : float
|
|
176
|
+
Latitude in decimal degrees. Positive north of equator, negative to south.
|
|
177
|
+
altitude : float
|
|
178
|
+
Altitude in kilometers.
|
|
179
|
+
time_endpoints : tuple[str, str]
|
|
180
|
+
Start and stop times in UTC.
|
|
181
|
+
time_step : float
|
|
182
|
+
Seconds between data points.
|
|
183
|
+
|
|
184
|
+
Returns
|
|
185
|
+
-------
|
|
186
|
+
output_dict: dict[str, np.ndarray]
|
|
187
|
+
Keys are time, azimuth, elevation and doppler. Values are calculated for every
|
|
188
|
+
timestamp between start_utc_input and stop_utc_input, spaced by time_step.
|
|
189
|
+
"""
|
|
190
|
+
output_dict: dict[str, np.ndarray] = {}
|
|
191
|
+
|
|
192
|
+
start_et_input = str_to_et(time_endpoints[0])
|
|
193
|
+
stop_et_input = str_to_et(time_endpoints[1])
|
|
194
|
+
time_range = np.arange(start_et_input, stop_et_input, time_step)
|
|
195
|
+
|
|
196
|
+
# For now, assume that kernel management will be handled by ensure spice
|
|
197
|
+
# for obs_time in np.arange(start_et_input, stop_et_input, time_step):
|
|
198
|
+
azimuth, elevation = calculate_azimuth_and_elevation(
|
|
199
|
+
longitude, latitude, altitude, time_range
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
output_dict["time"] = et_to_utc(time_range, format_str="ISOC")
|
|
203
|
+
output_dict["azimuth"] = azimuth
|
|
204
|
+
output_dict["elevation"] = elevation
|
|
205
|
+
output_dict["doppler"] = calculate_doppler(time_range)
|
|
206
|
+
|
|
207
|
+
logger.info(
|
|
208
|
+
f"Calculated azimuth, elevation and doppler for time range from "
|
|
209
|
+
f"{start_et_input} to {stop_et_input}."
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
return output_dict
|