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
imap_processing/ultra/l1b/de.py
CHANGED
|
@@ -3,6 +3,26 @@
|
|
|
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,
|
|
14
|
+
get_coincidence_positions,
|
|
15
|
+
get_ctof,
|
|
16
|
+
get_energy_pulse_height,
|
|
17
|
+
get_energy_ssd,
|
|
18
|
+
get_front_x_position,
|
|
19
|
+
get_front_y_position,
|
|
20
|
+
get_path_length,
|
|
21
|
+
get_ph_tof_and_back_positions,
|
|
22
|
+
get_ssd_back_position_and_tof_offset,
|
|
23
|
+
get_ssd_tof,
|
|
24
|
+
get_unit_vector,
|
|
25
|
+
)
|
|
6
26
|
from imap_processing.ultra.utils.ultra_l1_utils import create_dataset
|
|
7
27
|
|
|
8
28
|
|
|
@@ -13,46 +33,164 @@ def calculate_de(de_dataset: xr.Dataset, name: str) -> xr.Dataset:
|
|
|
13
33
|
Parameters
|
|
14
34
|
----------
|
|
15
35
|
de_dataset : xarray.Dataset
|
|
16
|
-
|
|
36
|
+
L1a dataset containing direct event data.
|
|
17
37
|
name : str
|
|
18
|
-
Name of the dataset.
|
|
38
|
+
Name of the l1a dataset.
|
|
19
39
|
|
|
20
40
|
Returns
|
|
21
41
|
-------
|
|
22
42
|
dataset : xarray.Dataset
|
|
23
|
-
|
|
43
|
+
L1b de dataset.
|
|
24
44
|
"""
|
|
25
45
|
de_dict = {}
|
|
46
|
+
sensor = parse_filename_like(name)["sensor"][0:2]
|
|
26
47
|
|
|
27
|
-
#
|
|
28
|
-
|
|
48
|
+
# Instantiate arrays
|
|
49
|
+
yf = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float32)
|
|
50
|
+
xb = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float32)
|
|
51
|
+
yb = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float32)
|
|
52
|
+
xc = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float32)
|
|
53
|
+
d = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float64)
|
|
54
|
+
r = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float32)
|
|
55
|
+
tof = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float32)
|
|
56
|
+
etof = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float32)
|
|
57
|
+
ctof = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float32)
|
|
58
|
+
energy = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float32)
|
|
59
|
+
# TODO: Confirm with Ultra team what fill values and dtype we want.
|
|
60
|
+
species_bin = np.full(len(de_dataset["epoch"]), "UNKNOWN", dtype="U10")
|
|
61
|
+
t2 = np.full(len(de_dataset["epoch"]), np.nan, dtype=np.float32)
|
|
29
62
|
|
|
63
|
+
# Drop events with invalid start type.
|
|
64
|
+
de_dataset = de_dataset.where(
|
|
65
|
+
de_dataset["START_TYPE"] != np.iinfo(np.int64).min, drop=True
|
|
66
|
+
)
|
|
67
|
+
# Define epoch.
|
|
30
68
|
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
|
-
|
|
69
|
+
|
|
70
|
+
xf = get_front_x_position(
|
|
71
|
+
de_dataset["START_TYPE"].data,
|
|
72
|
+
de_dataset["START_POS_TDC"].data,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# Pulse height
|
|
76
|
+
ph_indices = np.nonzero(
|
|
77
|
+
np.isin(de_dataset["STOP_TYPE"], [StopType.Top.value, StopType.Bottom.value])
|
|
78
|
+
)[0]
|
|
79
|
+
tof[ph_indices], t2[ph_indices], xb[ph_indices], yb[ph_indices] = (
|
|
80
|
+
get_ph_tof_and_back_positions(de_dataset, xf, f"ultra{sensor}")
|
|
81
|
+
)
|
|
82
|
+
d[ph_indices], yf[ph_indices] = get_front_y_position(
|
|
83
|
+
de_dataset["START_TYPE"].data[ph_indices], yb[ph_indices]
|
|
84
|
+
)
|
|
85
|
+
energy[ph_indices] = get_energy_pulse_height(
|
|
86
|
+
de_dataset["STOP_TYPE"].data[ph_indices],
|
|
87
|
+
de_dataset["ENERGY_PH"].data[ph_indices],
|
|
88
|
+
xb[ph_indices],
|
|
89
|
+
yb[ph_indices],
|
|
90
|
+
)
|
|
91
|
+
r[ph_indices] = get_path_length(
|
|
92
|
+
(xf[ph_indices], yf[ph_indices]),
|
|
93
|
+
(xb[ph_indices], yb[ph_indices]),
|
|
94
|
+
d[ph_indices],
|
|
95
|
+
)
|
|
96
|
+
species_bin[ph_indices] = determine_species(tof[ph_indices], r[ph_indices], "PH")
|
|
97
|
+
etof[ph_indices], xc[ph_indices] = get_coincidence_positions(
|
|
98
|
+
de_dataset.isel(epoch=ph_indices), t2[ph_indices], f"ultra{sensor}"
|
|
99
|
+
)
|
|
100
|
+
ctof[ph_indices], _ = get_ctof(tof[ph_indices], r[ph_indices], "PH")
|
|
101
|
+
|
|
102
|
+
# SSD
|
|
103
|
+
ssd_indices = np.nonzero(np.isin(de_dataset["STOP_TYPE"], StopType.SSD.value))[0]
|
|
104
|
+
tof[ssd_indices] = get_ssd_tof(de_dataset, xf)
|
|
105
|
+
yb[ssd_indices], _, ssd_number = get_ssd_back_position_and_tof_offset(de_dataset)
|
|
106
|
+
xc[ssd_indices] = np.zeros(len(ssd_indices))
|
|
107
|
+
xb[ssd_indices] = np.zeros(len(ssd_indices))
|
|
108
|
+
etof[ssd_indices] = np.zeros(len(ssd_indices))
|
|
109
|
+
d[ssd_indices], yf[ssd_indices] = get_front_y_position(
|
|
110
|
+
de_dataset["START_TYPE"].data[ssd_indices], yb[ssd_indices]
|
|
111
|
+
)
|
|
112
|
+
energy[ssd_indices] = get_energy_ssd(de_dataset, ssd_number)
|
|
113
|
+
r[ssd_indices] = get_path_length(
|
|
114
|
+
(xf[ssd_indices], yf[ssd_indices]),
|
|
115
|
+
(xb[ssd_indices], yb[ssd_indices]),
|
|
116
|
+
d[ssd_indices],
|
|
117
|
+
)
|
|
118
|
+
species_bin[ssd_indices] = determine_species(
|
|
119
|
+
tof[ssd_indices], r[ssd_indices], "SSD"
|
|
120
|
+
)
|
|
121
|
+
ctof[ssd_indices], _ = get_ctof(tof[ssd_indices], r[ssd_indices], "SSD")
|
|
122
|
+
|
|
123
|
+
# Combine ph_yb and ssd_yb along with their indices
|
|
124
|
+
de_dict["x_front"] = xf.astype(np.float32)
|
|
125
|
+
de_dict["y_front"] = yf
|
|
126
|
+
de_dict["x_back"] = xb
|
|
127
|
+
de_dict["y_back"] = yb
|
|
128
|
+
de_dict["x_coin"] = xc
|
|
129
|
+
de_dict["tof_start_stop"] = tof
|
|
130
|
+
de_dict["tof_stop_coin"] = etof
|
|
131
|
+
de_dict["tof_corrected"] = ctof
|
|
132
|
+
de_dict["front_back_distance"] = d
|
|
133
|
+
de_dict["path_length"] = r
|
|
134
|
+
|
|
135
|
+
keys = [
|
|
136
|
+
"coincidence_type",
|
|
137
|
+
"start_type",
|
|
138
|
+
"event_type",
|
|
139
|
+
"de_event_met",
|
|
140
|
+
]
|
|
141
|
+
dataset_keys = ["COIN_TYPE", "START_TYPE", "STOP_TYPE", "SHCOARSE"]
|
|
142
|
+
|
|
143
|
+
de_dict.update(
|
|
144
|
+
{key: de_dataset[dataset_key] for key, dataset_key in zip(keys, dataset_keys)}
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
vx_ultra, vy_ultra, vz_ultra = get_unit_vector(
|
|
148
|
+
(de_dict["x_front"], de_dict["y_front"]),
|
|
149
|
+
(de_dict["x_back"], de_dict["y_back"]),
|
|
150
|
+
de_dict["front_back_distance"],
|
|
151
|
+
de_dict["tof_start_stop"],
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
de_dict["vx_ultra"] = vx_ultra.astype(np.float32)
|
|
155
|
+
de_dict["vy_ultra"] = vy_ultra.astype(np.float32)
|
|
156
|
+
de_dict["vz_ultra"] = vz_ultra.astype(np.float32)
|
|
157
|
+
de_dict["energy"] = energy
|
|
158
|
+
de_dict["species"] = species_bin
|
|
159
|
+
|
|
160
|
+
# Annotated Events.
|
|
161
|
+
position = np.stack(
|
|
162
|
+
(de_dict["vx_ultra"], de_dict["vy_ultra"], de_dict["vz_ultra"]), axis=-1
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
ultra_frame = getattr(SpiceFrame, f"IMAP_ULTRA_{sensor}")
|
|
166
|
+
sc_velocity, sc_dps_velocity, helio_velocity = get_annotated_particle_velocity(
|
|
167
|
+
de_dataset.data_vars["EVENTTIMES"],
|
|
168
|
+
position,
|
|
169
|
+
ultra_frame,
|
|
170
|
+
SpiceFrame.IMAP_DPS,
|
|
171
|
+
SpiceFrame.IMAP_SPACECRAFT,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
de_dict["vx_sc"], de_dict["vy_sc"], de_dict["vz_sc"] = (
|
|
175
|
+
sc_velocity[:, 0],
|
|
176
|
+
sc_velocity[:, 1],
|
|
177
|
+
sc_velocity[:, 2],
|
|
178
|
+
)
|
|
179
|
+
de_dict["vx_dps_sc"], de_dict["vy_dps_sc"], de_dict["vz_dps_sc"] = (
|
|
180
|
+
sc_dps_velocity[:, 0],
|
|
181
|
+
sc_dps_velocity[:, 1],
|
|
182
|
+
sc_dps_velocity[:, 2],
|
|
183
|
+
)
|
|
184
|
+
de_dict["vx_dps_helio"], de_dict["vy_dps_helio"], de_dict["vz_dps_helio"] = (
|
|
185
|
+
helio_velocity[:, 0],
|
|
186
|
+
helio_velocity[:, 1],
|
|
187
|
+
helio_velocity[:, 2],
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
# TODO: TBD.
|
|
191
|
+
de_dict["event_efficiency"] = np.full(
|
|
192
|
+
len(de_dataset["epoch"]), np.nan, dtype=np.float32
|
|
193
|
+
)
|
|
56
194
|
|
|
57
195
|
dataset = create_dataset(de_dict, name, "l1b")
|
|
58
196
|
|
|
@@ -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,9 +648,11 @@ 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(
|
|
651
|
+
def get_ctof(
|
|
652
|
+
tof: np.ndarray, path_length: np.ndarray, type: str
|
|
653
|
+
) -> tuple[NDArray, NDArray]:
|
|
649
654
|
"""
|
|
650
|
-
Calculate the corrected TOF.
|
|
655
|
+
Calculate the corrected TOF and the magnitude of the particle velocity.
|
|
651
656
|
|
|
652
657
|
The corrected TOF (ctof) is the TOF normalized with respect
|
|
653
658
|
to a fixed distance dmin between the front and back detectors.
|
|
@@ -662,30 +667,36 @@ def get_ctof(tof: np.ndarray, path_length: np.ndarray) -> NDArray:
|
|
|
662
667
|
Time of flight (tenths of a nanosecond).
|
|
663
668
|
path_length : np.ndarray
|
|
664
669
|
Path length (r) (hundredths of a millimeter).
|
|
670
|
+
type : str
|
|
671
|
+
Type of event, either "PH" or "SSD".
|
|
665
672
|
|
|
666
673
|
Returns
|
|
667
674
|
-------
|
|
668
675
|
ctof : np.ndarray
|
|
669
676
|
Corrected TOF (tenths of a ns).
|
|
677
|
+
magnitude_v : np.ndarray
|
|
678
|
+
Magnitude of the particle velocity (km/s).
|
|
670
679
|
"""
|
|
680
|
+
dmin_ctof = getattr(UltraConstants, f"DMIN_{type}_CTOF")
|
|
681
|
+
|
|
671
682
|
# Multiply times 100 to convert to hundredths of a millimeter.
|
|
672
|
-
ctof = tof *
|
|
683
|
+
ctof = tof * dmin_ctof * 100 / path_length
|
|
673
684
|
|
|
674
|
-
|
|
685
|
+
# Convert from mm/0.1ns to km/s.
|
|
686
|
+
magnitude_v = dmin_ctof / ctof * 1e4
|
|
675
687
|
|
|
688
|
+
return ctof, magnitude_v
|
|
676
689
|
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
) -> NDArray:
|
|
690
|
+
|
|
691
|
+
def determine_species(tof: np.ndarray, path_length: np.ndarray, type: str) -> NDArray:
|
|
680
692
|
"""
|
|
681
693
|
Determine the species for pulse-height events.
|
|
682
694
|
|
|
683
|
-
Species is determined from the particle
|
|
695
|
+
Species is determined from the particle velocity.
|
|
684
696
|
For velocity, the particle TOF is normalized with respect
|
|
685
697
|
to a fixed distance dmin between the front and back detectors.
|
|
686
698
|
The normalized TOF is termed the corrected TOF (ctof).
|
|
687
|
-
Particle species are determined from
|
|
688
|
-
the energy and ctof using a lookup table.
|
|
699
|
+
Particle species are determined from ctof using thresholds.
|
|
689
700
|
|
|
690
701
|
Further description is available on pages 42-44 of
|
|
691
702
|
IMAP-Ultra Flight Software Specification document
|
|
@@ -693,72 +704,27 @@ def determine_species_pulse_height(
|
|
|
693
704
|
|
|
694
705
|
Parameters
|
|
695
706
|
----------
|
|
696
|
-
energy : np.ndarray
|
|
697
|
-
Energy from the SSD event (keV).
|
|
698
707
|
tof : np.ndarray
|
|
699
708
|
Time of flight of the SSD event (tenths of a nanosecond).
|
|
700
709
|
path_length : np.ndarray
|
|
701
710
|
Path length (r) (hundredths of a millimeter).
|
|
711
|
+
type : str
|
|
712
|
+
Type of data (PH or SSD).
|
|
702
713
|
|
|
703
714
|
Returns
|
|
704
715
|
-------
|
|
705
|
-
|
|
716
|
+
species_bin : np.array
|
|
706
717
|
Species bin.
|
|
707
718
|
"""
|
|
708
|
-
#
|
|
709
|
-
ctof = get_ctof(tof, path_length)
|
|
710
|
-
#
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
#
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
) -> NDArray:
|
|
721
|
-
"""
|
|
722
|
-
Determine the species for SSD events.
|
|
723
|
-
|
|
724
|
-
Species is determined from the particle's energy and velocity.
|
|
725
|
-
For velocity, the particle's TOF is normalized with respect
|
|
726
|
-
to a fixed distance dmin between the front and back detectors.
|
|
727
|
-
For SSD events, an adjustment is also made to the path length
|
|
728
|
-
to account for the shorter distances that such events
|
|
729
|
-
travel to reach the detector. The normalized TOF is termed
|
|
730
|
-
the corrected tof (ctof). Particle species are determined from
|
|
731
|
-
the energy and cTOF using a lookup table.
|
|
732
|
-
|
|
733
|
-
Further description is available on pages 42-44 of
|
|
734
|
-
IMAP-Ultra Flight Software Specification document
|
|
735
|
-
(7523-9009_Rev_-.pdf).
|
|
736
|
-
|
|
737
|
-
Parameters
|
|
738
|
-
----------
|
|
739
|
-
energy : np.ndarray
|
|
740
|
-
Energy from the SSD event (keV).
|
|
741
|
-
tof : np.ndarray
|
|
742
|
-
Time of flight of the SSD event (tenths of a nanosecond).
|
|
743
|
-
path_length : np.ndarray
|
|
744
|
-
Path length (r) (hundredths of a millimeter).
|
|
745
|
-
|
|
746
|
-
Returns
|
|
747
|
-
-------
|
|
748
|
-
bin : np.ndarray
|
|
749
|
-
Species bin.
|
|
750
|
-
"""
|
|
751
|
-
# SSD event TOF normalization to Z axis
|
|
752
|
-
ctof = get_ctof(tof, path_length)
|
|
753
|
-
|
|
754
|
-
bin = np.zeros(len(ctof)) # placeholder
|
|
755
|
-
|
|
756
|
-
# TODO: get these lookup tables
|
|
757
|
-
# if r < get_image_params("PathSteepThresh"):
|
|
758
|
-
# # bin = ExTOFSpeciesSteep[energy, ctof]
|
|
759
|
-
# elif r < get_image_params("PathMediumThresh"):
|
|
760
|
-
# # bin = ExTOFSpeciesMedium[energy, ctof]
|
|
761
|
-
# else:
|
|
762
|
-
# # bin = ExTOFSpeciesFlat[energy, ctof]
|
|
763
|
-
|
|
764
|
-
return bin
|
|
719
|
+
# Event TOF normalization to Z axis
|
|
720
|
+
ctof, _ = get_ctof(tof, path_length, type)
|
|
721
|
+
# Initialize bin array
|
|
722
|
+
species_bin = np.full(len(ctof), "UNKNOWN", dtype="U10")
|
|
723
|
+
|
|
724
|
+
# Assign "H" to bins where cTOF is within the specified range
|
|
725
|
+
species_bin[
|
|
726
|
+
(ctof > UltraConstants.CTOF_SPECIES_MIN)
|
|
727
|
+
& (ctof < UltraConstants.CTOF_SPECIES_MAX)
|
|
728
|
+
] = "H"
|
|
729
|
+
|
|
730
|
+
return species_bin
|