imap-processing 0.7.0__py3-none-any.whl → 0.8.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 +34 -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 +36 -8
- imap_processing/cdf/config/imap_hit_l1b_variable_attrs.yaml +9 -0
- imap_processing/cdf/config/imap_idex_global_cdf_attrs.yaml +7 -7
- imap_processing/cdf/config/imap_idex_l1a_variable_attrs.yaml +32 -33
- 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 +133 -78
- imap_processing/cdf/config/imap_variable_schema.yaml +13 -0
- imap_processing/cdf/imap_cdf_manager.py +31 -27
- imap_processing/cli.py +12 -10
- imap_processing/codice/codice_l1a.py +151 -61
- imap_processing/codice/constants.py +1 -1
- imap_processing/codice/decompress.py +4 -9
- imap_processing/codice/utils.py +1 -0
- 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/histogram.py +1 -1
- imap_processing/hi/l1a/science_direct_event.py +1 -1
- imap_processing/hi/l1b/hi_l1b.py +85 -11
- imap_processing/hi/l1c/hi_l1c.py +23 -1
- 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 +186 -153
- imap_processing/hit/l1a/hit_l1a.py +20 -175
- imap_processing/hit/l1b/hit_l1b.py +33 -153
- imap_processing/idex/idex_l1a.py +10 -9
- imap_processing/lo/l0/decompression_tables/decompression_tables.py +1 -1
- imap_processing/lo/l0/lo_science.py +1 -1
- imap_processing/lo/packet_definitions/lo_xtce.xml +1 -3296
- imap_processing/mag/l0/decom_mag.py +4 -3
- imap_processing/mag/l1a/mag_l1a.py +11 -11
- imap_processing/mag/l1b/mag_l1b.py +89 -7
- imap_processing/spice/geometry.py +126 -4
- imap_processing/swapi/l1/swapi_l1.py +1 -1
- imap_processing/swapi/l2/swapi_l2.py +1 -1
- imap_processing/swe/l1b/swe_l1b_science.py +8 -8
- imap_processing/tests/ccsds/test_data/expected_output.xml +1 -0
- 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 +54 -15
- 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/glows/test_glows_l2_data.py +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 +71 -1
- imap_processing/tests/hi/test_hi_l1c.py +10 -2
- imap_processing/tests/hi/test_utils.py +4 -3
- imap_processing/tests/hit/{test_hit_decom.py → test_decom_hit.py} +84 -35
- imap_processing/tests/hit/test_hit_l1a.py +2 -197
- imap_processing/tests/hit/test_hit_l1b.py +156 -25
- imap_processing/tests/hit/test_hit_utils.py +218 -0
- imap_processing/tests/idex/conftest.py +1 -1
- 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 +3 -3
- imap_processing/tests/idex/test_idex_l1a.py +1 -1
- imap_processing/tests/lo/test_lo_science.py +2 -2
- imap_processing/tests/mag/imap_mag_l1a_norm-magi_20251017_v001.cdf +0 -0
- imap_processing/tests/mag/test_mag_l1b.py +59 -3
- imap_processing/tests/spice/test_data/imap_ena_sim_metakernel.template +3 -1
- imap_processing/tests/spice/test_geometry.py +84 -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/test_utils.py +1 -1
- 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 +108 -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 +21 -11
- imap_processing/tests/ultra/unit/test_ultra_l1c_pset_bins.py +9 -44
- imap_processing/ultra/constants.py +8 -3
- imap_processing/ultra/l1b/de.py +174 -30
- imap_processing/ultra/l1b/ultra_l1b_annotated.py +24 -10
- imap_processing/ultra/l1b/ultra_l1b_extended.py +21 -14
- imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +70 -119
- {imap_processing-0.7.0.dist-info → imap_processing-0.8.0.dist-info}/METADATA +15 -14
- {imap_processing-0.7.0.dist-info → imap_processing-0.8.0.dist-info}/RECORD +98 -113
- 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/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/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/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.8.0.dist-info}/LICENSE +0 -0
- {imap_processing-0.7.0.dist-info → imap_processing-0.8.0.dist-info}/WHEEL +0 -0
- {imap_processing-0.7.0.dist-info → imap_processing-0.8.0.dist-info}/entry_points.txt +0 -0
imap_processing/ultra/l1b/de.py
CHANGED
|
@@ -3,6 +3,27 @@
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
import xarray as xr
|
|
5
5
|
|
|
6
|
+
from imap_processing.cdf.utils import parse_filename_like
|
|
7
|
+
from imap_processing.spice.geometry import SpiceFrame
|
|
8
|
+
from imap_processing.ultra.l1b.ultra_l1b_annotated import (
|
|
9
|
+
get_annotated_particle_velocity,
|
|
10
|
+
)
|
|
11
|
+
from imap_processing.ultra.l1b.ultra_l1b_extended import (
|
|
12
|
+
StopType,
|
|
13
|
+
determine_species_pulse_height,
|
|
14
|
+
determine_species_ssd,
|
|
15
|
+
get_coincidence_positions,
|
|
16
|
+
get_ctof,
|
|
17
|
+
get_energy_pulse_height,
|
|
18
|
+
get_energy_ssd,
|
|
19
|
+
get_front_x_position,
|
|
20
|
+
get_front_y_position,
|
|
21
|
+
get_path_length,
|
|
22
|
+
get_ph_tof_and_back_positions,
|
|
23
|
+
get_ssd_back_position_and_tof_offset,
|
|
24
|
+
get_ssd_tof,
|
|
25
|
+
get_unit_vector,
|
|
26
|
+
)
|
|
6
27
|
from imap_processing.ultra.utils.ultra_l1_utils import create_dataset
|
|
7
28
|
|
|
8
29
|
|
|
@@ -13,46 +34,169 @@ def calculate_de(de_dataset: xr.Dataset, name: str) -> xr.Dataset:
|
|
|
13
34
|
Parameters
|
|
14
35
|
----------
|
|
15
36
|
de_dataset : xarray.Dataset
|
|
16
|
-
|
|
37
|
+
L1a dataset containing direct event data.
|
|
17
38
|
name : str
|
|
18
|
-
Name of the dataset.
|
|
39
|
+
Name of the l1a dataset.
|
|
19
40
|
|
|
20
41
|
Returns
|
|
21
42
|
-------
|
|
22
43
|
dataset : xarray.Dataset
|
|
23
|
-
|
|
44
|
+
L1b de dataset.
|
|
24
45
|
"""
|
|
25
46
|
de_dict = {}
|
|
47
|
+
sensor = parse_filename_like(name)["sensor"][0:2]
|
|
26
48
|
|
|
27
|
-
#
|
|
28
|
-
|
|
49
|
+
# Instantiate arrays
|
|
50
|
+
yf = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float32)
|
|
51
|
+
xb = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float32)
|
|
52
|
+
yb = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float32)
|
|
53
|
+
xc = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float32)
|
|
54
|
+
d = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float64)
|
|
55
|
+
r = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float32)
|
|
56
|
+
tof = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float32)
|
|
57
|
+
etof = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float32)
|
|
58
|
+
ctof = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float32)
|
|
59
|
+
energy = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float32)
|
|
60
|
+
# TODO: uint8 fills with zeros instead of nans.
|
|
61
|
+
# Confirm with Ultra team what fill values and dtype we want.
|
|
62
|
+
species_bin = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.uint8)
|
|
63
|
+
t2 = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float32)
|
|
29
64
|
|
|
65
|
+
# Drop events with invalid start type.
|
|
66
|
+
de_dataset = de_dataset.where(
|
|
67
|
+
de_dataset["START_TYPE"] != np.iinfo(np.int64).min, drop=True
|
|
68
|
+
)
|
|
69
|
+
# Define epoch.
|
|
30
70
|
de_dict["epoch"] = de_dataset["epoch"]
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
71
|
+
|
|
72
|
+
xf = get_front_x_position(
|
|
73
|
+
de_dataset["START_TYPE"].data,
|
|
74
|
+
de_dataset["START_POS_TDC"].data,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Pulse height
|
|
78
|
+
ph_indices = np.nonzero(
|
|
79
|
+
np.isin(de_dataset["STOP_TYPE"], [StopType.Top.value, StopType.Bottom.value])
|
|
80
|
+
)[0]
|
|
81
|
+
tof[ph_indices], t2[ph_indices], xb[ph_indices], yb[ph_indices] = (
|
|
82
|
+
get_ph_tof_and_back_positions(de_dataset, xf, f"ultra{sensor}")
|
|
83
|
+
)
|
|
84
|
+
d[ph_indices], yf[ph_indices] = get_front_y_position(
|
|
85
|
+
de_dataset["START_TYPE"].data[ph_indices], yb[ph_indices]
|
|
86
|
+
)
|
|
87
|
+
energy[ph_indices] = get_energy_pulse_height(
|
|
88
|
+
de_dataset["STOP_TYPE"].data[ph_indices],
|
|
89
|
+
de_dataset["ENERGY_PH"].data[ph_indices],
|
|
90
|
+
xb[ph_indices],
|
|
91
|
+
yb[ph_indices],
|
|
92
|
+
)
|
|
93
|
+
r[ph_indices] = get_path_length(
|
|
94
|
+
(xf[ph_indices], yf[ph_indices]),
|
|
95
|
+
(xb[ph_indices], yb[ph_indices]),
|
|
96
|
+
d[ph_indices],
|
|
97
|
+
)
|
|
98
|
+
species_bin[ph_indices] = determine_species_pulse_height(
|
|
99
|
+
energy[ph_indices], tof[ph_indices], r[ph_indices]
|
|
100
|
+
)
|
|
101
|
+
etof[ph_indices], xc[ph_indices] = get_coincidence_positions(
|
|
102
|
+
de_dataset.isel(epoch=ph_indices), t2[ph_indices], f"ultra{sensor}"
|
|
103
|
+
)
|
|
104
|
+
ctof[ph_indices] = get_ctof(tof[ph_indices], r[ph_indices], "PH")
|
|
105
|
+
|
|
106
|
+
# SSD
|
|
107
|
+
ssd_indices = np.nonzero(np.isin(de_dataset["STOP_TYPE"], StopType.SSD.value))[0]
|
|
108
|
+
tof[ssd_indices] = get_ssd_tof(de_dataset, xf)
|
|
109
|
+
yb[ssd_indices], _, ssd_number = get_ssd_back_position_and_tof_offset(de_dataset)
|
|
110
|
+
xc[ssd_indices] = np.zeros(len(ssd_indices))
|
|
111
|
+
xb[ssd_indices] = np.zeros(len(ssd_indices))
|
|
112
|
+
etof[ssd_indices] = np.zeros(len(ssd_indices))
|
|
113
|
+
d[ssd_indices], yf[ssd_indices] = get_front_y_position(
|
|
114
|
+
de_dataset["START_TYPE"].data[ssd_indices], yb[ssd_indices]
|
|
115
|
+
)
|
|
116
|
+
energy[ssd_indices] = get_energy_ssd(de_dataset, ssd_number)
|
|
117
|
+
r[ssd_indices] = get_path_length(
|
|
118
|
+
(xf[ssd_indices], yf[ssd_indices]),
|
|
119
|
+
(xb[ssd_indices], yb[ssd_indices]),
|
|
120
|
+
d[ssd_indices],
|
|
121
|
+
)
|
|
122
|
+
species_bin[ssd_indices] = determine_species_ssd(
|
|
123
|
+
energy[ssd_indices],
|
|
124
|
+
tof[ssd_indices],
|
|
125
|
+
r[ssd_indices],
|
|
126
|
+
)
|
|
127
|
+
ctof[ssd_indices] = get_ctof(tof[ssd_indices], r[ssd_indices], "SSD")
|
|
128
|
+
|
|
129
|
+
# Combine ph_yb and ssd_yb along with their indices
|
|
130
|
+
de_dict["x_front"] = xf.astype(np.float32)
|
|
131
|
+
de_dict["y_front"] = yf
|
|
132
|
+
de_dict["x_back"] = xb
|
|
133
|
+
de_dict["y_back"] = yb
|
|
134
|
+
de_dict["x_coin"] = xc
|
|
135
|
+
de_dict["tof_start_stop"] = tof
|
|
136
|
+
de_dict["tof_stop_coin"] = etof
|
|
137
|
+
de_dict["tof_corrected"] = ctof
|
|
138
|
+
de_dict["front_back_distance"] = d
|
|
139
|
+
de_dict["path_length"] = r
|
|
140
|
+
|
|
141
|
+
keys = [
|
|
142
|
+
"coincidence_type",
|
|
143
|
+
"start_type",
|
|
144
|
+
"event_type",
|
|
145
|
+
"de_event_met",
|
|
146
|
+
]
|
|
147
|
+
dataset_keys = ["COIN_TYPE", "START_TYPE", "STOP_TYPE", "SHCOARSE"]
|
|
148
|
+
|
|
149
|
+
de_dict.update(
|
|
150
|
+
{key: de_dataset[dataset_key] for key, dataset_key in zip(keys, dataset_keys)}
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
vx_ultra, vy_ultra, vz_ultra = get_unit_vector(
|
|
154
|
+
(de_dict["x_front"], de_dict["y_front"]),
|
|
155
|
+
(de_dict["x_back"], de_dict["y_back"]),
|
|
156
|
+
de_dict["front_back_distance"],
|
|
157
|
+
de_dict["tof_start_stop"],
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
de_dict["vx_ultra"] = vx_ultra.astype(np.float32)
|
|
161
|
+
de_dict["vy_ultra"] = vy_ultra.astype(np.float32)
|
|
162
|
+
de_dict["vz_ultra"] = vz_ultra.astype(np.float32)
|
|
163
|
+
de_dict["energy"] = energy
|
|
164
|
+
de_dict["species"] = species_bin
|
|
165
|
+
|
|
166
|
+
# Annotated Events.
|
|
167
|
+
position = np.stack(
|
|
168
|
+
(de_dict["vx_ultra"], de_dict["vy_ultra"], de_dict["vz_ultra"]), axis=-1
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
ultra_frame = getattr(SpiceFrame, f"IMAP_ULTRA_{sensor}")
|
|
172
|
+
sc_velocity, sc_dps_velocity, helio_velocity = get_annotated_particle_velocity(
|
|
173
|
+
de_dataset.data_vars["EVENTTIMES"],
|
|
174
|
+
position,
|
|
175
|
+
ultra_frame,
|
|
176
|
+
SpiceFrame.IMAP_DPS,
|
|
177
|
+
SpiceFrame.IMAP_SPACECRAFT,
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
de_dict["vx_sc"], de_dict["vy_sc"], de_dict["vz_sc"] = (
|
|
181
|
+
sc_velocity[:, 0],
|
|
182
|
+
sc_velocity[:, 1],
|
|
183
|
+
sc_velocity[:, 2],
|
|
184
|
+
)
|
|
185
|
+
de_dict["vx_dps_sc"], de_dict["vy_dps_sc"], de_dict["vz_dps_sc"] = (
|
|
186
|
+
sc_dps_velocity[:, 0],
|
|
187
|
+
sc_dps_velocity[:, 1],
|
|
188
|
+
sc_dps_velocity[:, 2],
|
|
189
|
+
)
|
|
190
|
+
de_dict["vx_dps_helio"], de_dict["vy_dps_helio"], de_dict["vz_dps_helio"] = (
|
|
191
|
+
helio_velocity[:, 0],
|
|
192
|
+
helio_velocity[:, 1],
|
|
193
|
+
helio_velocity[:, 2],
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
# TODO: TBD.
|
|
197
|
+
de_dict["event_efficiency"] = np.full(
|
|
198
|
+
len(de_dataset["epoch"]), np.nan, dtype=np.float32
|
|
199
|
+
)
|
|
56
200
|
|
|
57
201
|
dataset = create_dataset(de_dict, name, "l1b")
|
|
58
202
|
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"""Calculates Annotated Events for ULTRA L1b."""
|
|
2
2
|
|
|
3
|
-
import typing
|
|
4
|
-
|
|
5
3
|
import numpy as np
|
|
6
4
|
|
|
7
5
|
from imap_processing.spice.geometry import (
|
|
@@ -9,17 +7,15 @@ from imap_processing.spice.geometry import (
|
|
|
9
7
|
frame_transform,
|
|
10
8
|
imap_state,
|
|
11
9
|
)
|
|
12
|
-
from imap_processing.spice.kernels import ensure_spice
|
|
13
10
|
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
@typing.no_type_check
|
|
17
|
-
def get_particle_velocity(
|
|
12
|
+
def get_annotated_particle_velocity(
|
|
18
13
|
time: np.ndarray,
|
|
19
14
|
instrument_velocity: np.ndarray,
|
|
20
15
|
instrument_frame: SpiceFrame,
|
|
21
16
|
pointing_frame: SpiceFrame,
|
|
22
|
-
|
|
17
|
+
spacecraft_frame: SpiceFrame,
|
|
18
|
+
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
23
19
|
"""
|
|
24
20
|
Get the particle velocity in the pointing (DPS) frame wrt the spacecraft.
|
|
25
21
|
|
|
@@ -33,11 +29,15 @@ def get_particle_velocity(
|
|
|
33
29
|
Instrument frame.
|
|
34
30
|
pointing_frame : SpiceFrame
|
|
35
31
|
Pointing frame.
|
|
32
|
+
spacecraft_frame : SpiceFrame
|
|
33
|
+
Spacecraft frame.
|
|
36
34
|
|
|
37
35
|
Returns
|
|
38
36
|
-------
|
|
39
37
|
particle_velocity_spacecraft : np.ndarray
|
|
40
38
|
Particle velocity in the spacecraft frame.
|
|
39
|
+
particle_velocity_dps_spacecraft : np.ndarray
|
|
40
|
+
Particle velocity in DPS frame at rest WRT spacecraft .
|
|
41
41
|
particle_velocity_heliosphere : np.ndarray
|
|
42
42
|
Particle velocity in the heliosphere frame.
|
|
43
43
|
|
|
@@ -45,8 +45,16 @@ def get_particle_velocity(
|
|
|
45
45
|
----------
|
|
46
46
|
https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy
|
|
47
47
|
"""
|
|
48
|
-
# Particle velocity in the
|
|
48
|
+
# Particle velocity in the spacecraft frame.
|
|
49
49
|
particle_velocity_spacecraft = frame_transform(
|
|
50
|
+
et=time,
|
|
51
|
+
position=instrument_velocity,
|
|
52
|
+
from_frame=instrument_frame,
|
|
53
|
+
to_frame=spacecraft_frame,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
# Particle velocity in the pointing (DPS) frame wrt spacecraft.
|
|
57
|
+
particle_velocity_dps_spacecraft = frame_transform(
|
|
50
58
|
et=time,
|
|
51
59
|
position=instrument_velocity,
|
|
52
60
|
from_frame=instrument_frame,
|
|
@@ -61,6 +69,12 @@ def get_particle_velocity(
|
|
|
61
69
|
|
|
62
70
|
# Apply Compton-Getting.
|
|
63
71
|
# Particle velocity in the DPS frame wrt to the heliosphere
|
|
64
|
-
particle_velocity_heliosphere =
|
|
72
|
+
particle_velocity_heliosphere = (
|
|
73
|
+
spacecraft_velocity + particle_velocity_dps_spacecraft
|
|
74
|
+
)
|
|
65
75
|
|
|
66
|
-
return
|
|
76
|
+
return (
|
|
77
|
+
particle_velocity_spacecraft,
|
|
78
|
+
particle_velocity_dps_spacecraft,
|
|
79
|
+
particle_velocity_heliosphere,
|
|
80
|
+
)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Calculates Extended Raw Events for ULTRA L1b."""
|
|
2
2
|
|
|
3
|
+
# TODO: Come back and add in FSW logic.
|
|
3
4
|
import logging
|
|
4
5
|
from enum import Enum
|
|
5
6
|
from typing import ClassVar
|
|
@@ -252,7 +253,9 @@ def get_ph_tof_and_back_positions(
|
|
|
252
253
|
return tof, t2, xb, yb
|
|
253
254
|
|
|
254
255
|
|
|
255
|
-
def get_path_length(
|
|
256
|
+
def get_path_length(
|
|
257
|
+
front_position: tuple, back_position: tuple, d: np.ndarray
|
|
258
|
+
) -> NDArray:
|
|
256
259
|
"""
|
|
257
260
|
Calculate the path length.
|
|
258
261
|
|
|
@@ -262,15 +265,15 @@ def get_path_length(front_position: tuple, back_position: tuple, d: float) -> fl
|
|
|
262
265
|
Front position (xf,yf) (hundredths of a millimeter).
|
|
263
266
|
back_position : tuple of floats
|
|
264
267
|
Back position (xb,yb) (hundredths of a millimeter).
|
|
265
|
-
d :
|
|
268
|
+
d : np.ndarray
|
|
266
269
|
Distance from slit to foil (hundredths of a millimeter).
|
|
267
270
|
|
|
268
271
|
Returns
|
|
269
272
|
-------
|
|
270
|
-
path_length :
|
|
273
|
+
path_length : np.ndarray
|
|
271
274
|
Path length (r) (hundredths of a millimeter).
|
|
272
275
|
"""
|
|
273
|
-
path_length
|
|
276
|
+
path_length = np.sqrt(
|
|
274
277
|
(front_position[0] - back_position[0]) ** 2
|
|
275
278
|
+ (front_position[1] - back_position[1]) ** 2
|
|
276
279
|
+ (d) ** 2
|
|
@@ -434,9 +437,9 @@ def get_coincidence_positions(
|
|
|
434
437
|
return etof, xc_array * 100
|
|
435
438
|
|
|
436
439
|
|
|
437
|
-
def
|
|
438
|
-
front_position: tuple[
|
|
439
|
-
back_position: tuple[
|
|
440
|
+
def get_unit_vector(
|
|
441
|
+
front_position: tuple[NDArray, NDArray],
|
|
442
|
+
back_position: tuple[NDArray, NDArray],
|
|
440
443
|
d: np.ndarray,
|
|
441
444
|
tof: np.ndarray,
|
|
442
445
|
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
@@ -486,9 +489,9 @@ def get_particle_velocity(
|
|
|
486
489
|
vhat_y = -v_y / magnitude_v
|
|
487
490
|
vhat_z = -v_z / magnitude_v
|
|
488
491
|
|
|
489
|
-
vhat_x[tof < 0] = np.
|
|
490
|
-
vhat_y[tof < 0] = np.
|
|
491
|
-
vhat_z[tof < 0] = np.
|
|
492
|
+
vhat_x[tof < 0] = np.nan # used as fillvals
|
|
493
|
+
vhat_y[tof < 0] = np.nan
|
|
494
|
+
vhat_z[tof < 0] = np.nan
|
|
492
495
|
|
|
493
496
|
return vhat_x, vhat_y, vhat_z
|
|
494
497
|
|
|
@@ -645,7 +648,7 @@ def get_energy_ssd(de_dataset: xarray.Dataset, ssd: np.ndarray) -> NDArray[np.fl
|
|
|
645
648
|
return energy_norm
|
|
646
649
|
|
|
647
650
|
|
|
648
|
-
def get_ctof(tof: np.ndarray, path_length: np.ndarray) -> NDArray:
|
|
651
|
+
def get_ctof(tof: np.ndarray, path_length: np.ndarray, type: str) -> NDArray:
|
|
649
652
|
"""
|
|
650
653
|
Calculate the corrected TOF.
|
|
651
654
|
|
|
@@ -662,14 +665,18 @@ def get_ctof(tof: np.ndarray, path_length: np.ndarray) -> NDArray:
|
|
|
662
665
|
Time of flight (tenths of a nanosecond).
|
|
663
666
|
path_length : np.ndarray
|
|
664
667
|
Path length (r) (hundredths of a millimeter).
|
|
668
|
+
type : str
|
|
669
|
+
Type of event, either "ph" or "ssd".
|
|
665
670
|
|
|
666
671
|
Returns
|
|
667
672
|
-------
|
|
668
673
|
ctof : np.ndarray
|
|
669
674
|
Corrected TOF (tenths of a ns).
|
|
670
675
|
"""
|
|
676
|
+
dmin_ctof = getattr(UltraConstants, f"DMIN_{type}_CTOF")
|
|
677
|
+
|
|
671
678
|
# Multiply times 100 to convert to hundredths of a millimeter.
|
|
672
|
-
ctof = tof *
|
|
679
|
+
ctof = tof * dmin_ctof * 100 / path_length
|
|
673
680
|
|
|
674
681
|
return ctof
|
|
675
682
|
|
|
@@ -706,7 +713,7 @@ def determine_species_pulse_height(
|
|
|
706
713
|
Species bin.
|
|
707
714
|
"""
|
|
708
715
|
# PH event TOF normalization to Z axis
|
|
709
|
-
ctof = get_ctof(tof, path_length)
|
|
716
|
+
ctof = get_ctof(tof, path_length, "PH")
|
|
710
717
|
# TODO: need lookup tables
|
|
711
718
|
# placeholder
|
|
712
719
|
bin = np.zeros(len(ctof))
|
|
@@ -749,7 +756,7 @@ def determine_species_ssd(
|
|
|
749
756
|
Species bin.
|
|
750
757
|
"""
|
|
751
758
|
# SSD event TOF normalization to Z axis
|
|
752
|
-
ctof = get_ctof(tof, path_length)
|
|
759
|
+
ctof = get_ctof(tof, path_length, "SSD")
|
|
753
760
|
|
|
754
761
|
bin = np.zeros(len(ctof)) # placeholder
|
|
755
762
|
|