Skip to content

Commit 4df80a0

Browse files
Harrison #56 - PMCL - GLOWS: Use Lo l1b housekeeping CDF to determine daily pivot angle for L3e
1 parent eb3dd0b commit 4df80a0

14 files changed

Lines changed: 154 additions & 125 deletions

imap_l3_processing/glows/glows_processor.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
from imap_l3_processing.glows.l3e.glows_l3e_initializer import GlowsL3EInitializer, GlowsL3EInitializerOutput
3939
from imap_l3_processing.glows.l3e.glows_l3e_lo_model import GlowsL3ELoData
4040
from imap_l3_processing.glows.l3e.glows_l3e_ultra_model import GlowsL3EUltraData
41-
from imap_l3_processing.glows.l3e.glows_l3e_utils import determine_call_args_for_l3e_executable
41+
from imap_l3_processing.glows.l3e.glows_l3e_utils import determine_call_args_for_l3e_executable, get_lo_pivot_angles
4242
from imap_l3_processing.models import InputMetadata
4343
from imap_l3_processing.processor import Processor
4444
from imap_l3_processing.utils import save_data
@@ -260,7 +260,7 @@ def process_l3e_lo(
260260
repointing: int,
261261
repointing_start: datetime,
262262
epoch_delta: timedelta,
263-
elongation_value: int,
263+
elongation_value: float,
264264
version: int
265265
) -> list[Path]:
266266
repointing_midpoint = repointing_start + epoch_delta
@@ -437,20 +437,17 @@ def process_l3e_hi(parent_file_names: list[str], repointing: int, repointing_sta
437437
def process_l3e(initializer_data: GlowsL3EInitializerOutput):
438438
products_list = []
439439

440+
lo_pivot_angles = get_lo_pivot_angles(initializer_data.repointings.repointing_numbers)
440441
for repointing in initializer_data.repointings.repointing_numbers:
441442
with SwallowExceptionAndLog(f"Exception encountered when processing L3e for repointing {repointing}"):
442443
start_repointing, end_repointing = get_pointing_date_range(repointing)
443444
epoch_delta: timedelta = (end_repointing - start_repointing) / 2
444445

445446
with SwallowExceptionAndLog(f"Exception encountered when processing L3e lo for repointing {repointing}"):
446447
lo_parent_file_names = initializer_data.dependencies.get_lo_parents()
447-
repointing_doy = start_repointing.timetuple().tm_yday
448-
lo_elongation = initializer_data.dependencies.elongation.get(f"{start_repointing.year}{repointing_doy:03}")
449-
if lo_elongation is not None:
450-
lo_version = initializer_data.repointings.lo_repointings[repointing]
451-
products_list.extend(process_l3e_lo(lo_parent_file_names, repointing, start_repointing, epoch_delta, lo_elongation, lo_version))
452-
else:
453-
logger.warning(f"Skipping L3e Lo processing for {repointing=} because there is no elongation data")
448+
lo_elongation = lo_pivot_angles[repointing]
449+
lo_version = initializer_data.repointings.lo_repointings[repointing]
450+
products_list.extend(process_l3e_lo(lo_parent_file_names, repointing, start_repointing, epoch_delta, lo_elongation, lo_version))
454451

455452
with SwallowExceptionAndLog(f"Exception encountered when processing L3e hi-90 for repointing {repointing}"):
456453
hi_parent_file_names = initializer_data.dependencies.get_hi_parents()

imap_l3_processing/glows/l3e/glows_l3e_dependencies.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ class GlowsL3EDependencies:
3434
ionization_files: Path
3535
pipeline_settings: dict
3636
pipeline_settings_file: Path
37-
elongation: dict
38-
elongation_file: Path
3937
repointing_file: Path
4038
spice_kernels: list[str] = field(default_factory=list)
4139

@@ -62,16 +60,8 @@ def fetch_dependencies(cls, dependencies: ProcessingInputCollection):
6260

6361
energy_grid_lo_dependency = dependencies.get_file_paths(source='glows', descriptor='energy-grid-lo')
6462
tess_xyz_dependency = dependencies.get_file_paths(source='glows', descriptor='tess-xyz-8')
65-
elongation_dependency = dependencies.get_file_paths(source='lo', descriptor='elongation-data')
6663
energy_grid_lo_path = imap_data_access.download(energy_grid_lo_dependency[0])
6764
tess_xyz_path = imap_data_access.download(tess_xyz_dependency[0])
68-
elongation_path = imap_data_access.download(elongation_dependency[0])
69-
with open(elongation_path) as f:
70-
elongation_data = {}
71-
lines = [line.rstrip('\n') for line in f.readlines()]
72-
for line in lines:
73-
repointing, elongation = line.split('\t')
74-
elongation_data[repointing] = int(elongation)
7565

7666
energy_grid_hi_dependency = dependencies.get_file_paths(source='glows', descriptor='energy-grid-hi')
7767
energy_grid_hi_path = imap_data_access.download(energy_grid_hi_dependency[0])
@@ -102,8 +92,6 @@ def fetch_dependencies(cls, dependencies: ProcessingInputCollection):
10292
ionization_files_path,
10393
pipeline_settings,
10494
pipeline_settings_path,
105-
elongation_data,
106-
elongation_path,
10795
repoint_file_path
10896
)
10997

@@ -163,7 +151,6 @@ def get_lo_parents(self):
163151
self.ionization_files.name,
164152
self.pipeline_settings_file.name,
165153
self.repointing_file.name,
166-
self.elongation_file.name,
167154
*self.spice_kernels
168155
]
169156

imap_l3_processing/glows/l3e/glows_l3e_initializer.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ def get_repointings_to_process(l3d_output: GlowsL3DProcessorOutput, previous_l3d
3535
pipeline_settings_l3bcde = get_most_recently_uploaded_ancillary(imap_data_access.query(table='ancillary', instrument='glows', descriptor='pipeline-settings-l3bcde'))
3636
energy_grid_lo = get_most_recently_uploaded_ancillary(imap_data_access.query(table='ancillary', instrument='glows', descriptor='energy-grid-lo'))
3737
tess_xyz_8 = get_most_recently_uploaded_ancillary(imap_data_access.query(table='ancillary', instrument='glows', descriptor='tess-xyz-8'))
38-
elongation_data = get_most_recently_uploaded_ancillary(imap_data_access.query(table='ancillary', instrument='lo', descriptor='elongation-data'))
3938
energy_grid_hi = get_most_recently_uploaded_ancillary(imap_data_access.query(table='ancillary', instrument='glows', descriptor='energy-grid-hi'))
4039
energy_grid_ultra = get_most_recently_uploaded_ancillary(imap_data_access.query(table='ancillary', instrument='glows', descriptor='energy-grid-ultra'))
4140
tess_ang_16 = get_most_recently_uploaded_ancillary(imap_data_access.query(table='ancillary', instrument='glows', descriptor='tess-ang-16'))
@@ -47,7 +46,6 @@ def get_repointings_to_process(l3d_output: GlowsL3DProcessorOutput, previous_l3d
4746
AncillaryInput(str(pipeline_settings_l3bcde["file_path"])),
4847
AncillaryInput(str(energy_grid_lo["file_path"])),
4948
AncillaryInput(str(tess_xyz_8["file_path"])),
50-
AncillaryInput(str(elongation_data["file_path"])),
5149
AncillaryInput(str(energy_grid_hi["file_path"])),
5250
AncillaryInput(str(energy_grid_ultra["file_path"])),
5351
AncillaryInput(str(tess_ang_16["file_path"])),

imap_l3_processing/glows/l3e/glows_l3e_utils.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
from __future__ import annotations
12
from dataclasses import dataclass
2-
from datetime import datetime
3+
from datetime import datetime, timedelta
34
from pathlib import Path
45

56
import imap_data_access
@@ -125,3 +126,44 @@ def find_first_updated_cr(new_l3d: Path, old_l3d: str) -> Optional[int]:
125126
return int(old_l3d_cdf['cr_grid'][-1]) + 1
126127

127128
return None
129+
130+
@dataclass
131+
class LoL1bNHK:
132+
epoch: np.ndarray
133+
angle: np.ndarray
134+
135+
@classmethod
136+
def read_from_cdf(cls, path: Path) -> LoL1bNHK:
137+
with CDF(str(path)) as cdf:
138+
epoch = cdf['epoch'][...]
139+
angle = cdf['pcc_coarse_pot_pri'][...]
140+
return cls(epoch, angle)
141+
142+
def get_pivot_angle(self) -> float:
143+
if len(self.epoch) == 0:
144+
return 90
145+
t0 = self.epoch[0]
146+
start = t0 + timedelta(hours=3)
147+
end = t0 + timedelta(hours=15)
148+
start_index, end_index = np.searchsorted(self.epoch, [start, end])
149+
angles = self.angle[start_index:end_index]
150+
if len(angles) == 0:
151+
return 90
152+
return np.round(np.median(angles))
153+
154+
def get_lo_pivot_angles(repointings: list[int]) -> dict[int, float]:
155+
l1b_results = imap_data_access.query(
156+
instrument="lo",
157+
data_level="l1b",
158+
descriptor="nhk",
159+
version="latest",
160+
)
161+
paths_by_repointing = {f["repointing"]:f["file_path"] for f in l1b_results}
162+
result = {}
163+
for repointing in repointings:
164+
if path := paths_by_repointing.get(repointing):
165+
downloaded_path = imap_data_access.download(path)
166+
result[repointing] = LoL1bNHK.read_from_cdf(downloaded_path).get_pivot_angle()
167+
else:
168+
result[repointing] = 90
169+
return result

run_local.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,6 @@ def run_glows_l3e_with_less_mocks(mock_spiceypy):
648648
AncillaryInput("imap_glows_speed-3d_19640117_v002.dat"),
649649
AncillaryInput("imap_glows_sw-eqtr-electrons_19710416_v002.dat"),
650650
AncillaryInput("imap_glows_tess-xyz-8_20100101_v002.dat"),
651-
AncillaryInput("imap_lo_elongation-data_20100101_v001.dat"),
652651
ScienceInput(l3d_file),
653652
RepointInput("imap_2001_052_001.repoint.csv"),
654653
)

tests/glows/l3e/test_glows_l3e_dependencies.py

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,13 @@ def test_fetch_dependencies(self, mock_download):
2626
mock_sw_eqtr_electrons = Path('sw_eqtr_electrons_sdc_path')
2727
ionization_files = Path('ionization_files_path')
2828
mock_pipeline_settings = Path('l3bcde_pipeline_settings.json')
29-
mock_lo_elongation_file = Path('lo_elongation_data.dat')
3029
mock_tess_ang_16 = Path('tess_ang_16_path')
3130
mock_repoint_file = Path('repoint.csv')
3231

3332
mock_processing_input_collection.get_file_paths.side_effect = [
3433
[mock_lya_series], [mock_solar_uv_anisotropy], [mock_speed_3d_sw], [mock_density_3d_sw],
3534
[mock_phion_hydrogen], [mock_sw_eqtr_electrons], [ionization_files], [mock_pipeline_settings],
36-
[mock_tess_xyz_8], [mock_energy_grid_lo], [mock_lo_elongation_file],
35+
[mock_tess_xyz_8], [mock_energy_grid_lo],
3736
[mock_energy_grid_hi],
3837
[mock_energy_grid_ultra], [mock_tess_ang_16],
3938
[mock_repoint_file]
@@ -50,7 +49,6 @@ def test_fetch_dependencies(self, mock_download):
5049
mock_ionization_files_path = Mock()
5150
mock_energy_grid_lo_path = Mock()
5251
mock_tess_xyz_8_path = Mock()
53-
mock_lo_elongation_path = get_test_data_path('glows/imap_lo_elongation-data_20100101_v001.dat')
5452
mock_energy_grid_hi_path = Mock()
5553
mock_energy_grid_ultra_path = Mock()
5654
mock_tess_ang_16_path = Mock()
@@ -59,15 +57,15 @@ def test_fetch_dependencies(self, mock_download):
5957
mock_download.side_effect = [
6058
mock_lya_series_path, mock_solar_uv_anisotropy_path, mock_speed_3d_sw_path,
6159
mock_density_3d_sw_path, mock_phion_hydrogen_path, mock_sw_eqtr_electrons_path, mock_ionization_files_path,
62-
fake_pipeline_settings_path, mock_energy_grid_lo_path, mock_tess_xyz_8_path, mock_lo_elongation_path,
60+
fake_pipeline_settings_path, mock_energy_grid_lo_path, mock_tess_xyz_8_path,
6361
mock_energy_grid_hi_path,
6462
mock_energy_grid_ultra_path, mock_tess_ang_16_path,
6563
mock_downloaded_repoint_file,
6664
]
6765

6866
actual_dependencies = GlowsL3EDependencies.fetch_dependencies(mock_processing_input_collection)
6967

70-
self.assertEqual(15, mock_processing_input_collection.get_file_paths.call_count)
68+
self.assertEqual(14, mock_processing_input_collection.get_file_paths.call_count)
7169

7270
mock_processing_input_collection.get_file_paths.assert_has_calls([
7371
call(source="glows", descriptor="lya"),
@@ -80,7 +78,6 @@ def test_fetch_dependencies(self, mock_download):
8078
call(source="glows", descriptor="pipeline-settings-l3bcde"),
8179
call(source="glows", descriptor="energy-grid-lo"),
8280
call(source="glows", descriptor="tess-xyz-8"),
83-
call(source="lo", descriptor="elongation-data"),
8481
call(source="glows", descriptor="energy-grid-hi"),
8582
call(source="glows", descriptor="energy-grid-ultra"),
8683
call(source="glows", descriptor="tess-ang-16"),
@@ -98,7 +95,6 @@ def test_fetch_dependencies(self, mock_download):
9895
call(mock_pipeline_settings),
9996
call(mock_tess_xyz_8),
10097
call(mock_energy_grid_lo),
101-
call(mock_lo_elongation_file),
10298
call(mock_energy_grid_hi),
10399
call(mock_energy_grid_ultra),
104100
call(mock_tess_ang_16),
@@ -135,12 +131,6 @@ def test_fetch_dependencies(self, mock_download):
135131
self.assertEqual(mock_tess_xyz_8_path, actual_dependencies.tess_xyz_8)
136132
self.assertEqual(mock_tess_ang_16_path, actual_dependencies.tess_ang16)
137133
self.assertEqual(fake_pipeline_settings_path, actual_dependencies.pipeline_settings_file)
138-
self.assertEqual(365, len(actual_dependencies.elongation))
139-
first_dict_value = actual_dependencies.elongation['2010001']
140-
last_dict_value = actual_dependencies.elongation['2010365']
141-
self.assertEqual(mock_lo_elongation_path, actual_dependencies.elongation_file)
142-
self.assertEqual(105, first_dict_value)
143-
self.assertEqual(105, last_dict_value)
144134

145135
self.assertEqual(mock_downloaded_repoint_file, actual_dependencies.repointing_file)
146136

@@ -213,7 +203,6 @@ def test_get_lo_parents(self):
213203
"ionization_files.dat",
214204
"pipeline_settings.json",
215205
"repointing_file.csv",
216-
"elongation.csv"
217206
]
218207

219208
self.assertEqual(expected_parent_file_names, dependencies.get_lo_parents())
@@ -269,8 +258,6 @@ def test_rename_dependencies(self, mock_shutil):
269258
}
270259
},
271260
Path("path/to/some/pipeline_settings_file.csv"),
272-
{},
273-
Path("path/to/some/elongation_file.csv"),
274261
Path("repoint.csv")
275262
)
276263

@@ -358,7 +345,5 @@ def _create_l3e_dependencies(self) -> GlowsL3EDependencies:
358345
ionization_files=Path("some/folder/ionization_files.dat"),
359346
pipeline_settings_file=Path("some/folder/pipeline_settings.json"),
360347
pipeline_settings={},
361-
elongation_file=Path("some/folder/elongation.csv"),
362-
elongation={},
363348
repointing_file=Path("some/folder/repointing_file.csv"),
364349
)

tests/glows/l3e/test_glows_l3e_initializer.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ def test_get_repointings_to_process(self, mock_query, mock_get_most_recently_upl
2626
'imap_glows_pipeline-settings-l3bcde_20200101_v000.cdf',
2727
'imap_glows_energy-grid-lo_20200101_v000.cdf',
2828
'imap_glows_tess-xyz-8_20200101_v000.cdf',
29-
'imap_glows_elongation-data_20200101_v000.cdf',
3029
'imap_glows_energy-grid-hi_20200101_v000.cdf',
3130
'imap_glows_energy-grid-ultra_20200101_v000.cdf',
3231
'imap_glows_tess-ang-16_20200101_v000.cdf',
@@ -37,7 +36,6 @@ def test_get_repointings_to_process(self, mock_query, mock_get_most_recently_upl
3736
create_mock_query_results(['imap_glows_pipeline-settings-l3bcde_20200101_v000.cdf'])[0],
3837
create_mock_query_results(['imap_glows_energy-grid-lo_20200101_v000.cdf'])[0],
3938
create_mock_query_results(['imap_glows_tess-xyz-8_20200101_v000.cdf'])[0],
40-
create_mock_query_results(['imap_glows_elongation-data_20200101_v000.cdf'])[0],
4139
create_mock_query_results(['imap_glows_energy-grid-hi_20200101_v000.cdf'])[0],
4240
create_mock_query_results(['imap_glows_energy-grid-ultra_20200101_v000.cdf'])[0],
4341
create_mock_query_results(['imap_glows_tess-ang-16_20200101_v000.cdf'])[0],
@@ -93,7 +91,6 @@ def test_get_repointings_to_process(self, mock_query, mock_get_most_recently_upl
9391
call(table="ancillary", instrument='glows', descriptor='pipeline-settings-l3bcde'),
9492
call(table="ancillary", instrument='glows', descriptor='energy-grid-lo'),
9593
call(table="ancillary", instrument='glows', descriptor='tess-xyz-8'),
96-
call(table="ancillary", instrument='lo', descriptor='elongation-data'),
9794
call(table="ancillary", instrument='glows', descriptor='energy-grid-hi'),
9895
call(table="ancillary", instrument='glows', descriptor='energy-grid-ultra'),
9996
call(table="ancillary", instrument='glows', descriptor='tess-ang-16'),
@@ -118,7 +115,6 @@ def test_get_repointings_to_process(self, mock_query, mock_get_most_recently_upl
118115
'imap_glows_pipeline-settings-l3bcde_20200101_v000.cdf',
119116
'imap_glows_energy-grid-lo_20200101_v000.cdf',
120117
'imap_glows_tess-xyz-8_20200101_v000.cdf',
121-
'imap_glows_elongation-data_20200101_v000.cdf',
122118
'imap_glows_energy-grid-hi_20200101_v000.cdf',
123119
'imap_glows_energy-grid-ultra_20200101_v000.cdf',
124120
'imap_glows_tess-ang-16_20200101_v000.cdf',
@@ -170,7 +166,6 @@ def test_get_repointings_to_process_handles_no_previous_l3d(self, mock_find_firs
170166
create_mock_query_results(['imap_glows_pipeline-settings-l3bcde_20200101_v000.cdf'])[0],
171167
create_mock_query_results(['imap_glows_energy-grid-lo_20200101_v000.cdf'])[0],
172168
create_mock_query_results(['imap_glows_tess-xyz-8_20200101_v000.cdf'])[0],
173-
create_mock_query_results(['imap_glows_elongation-data_20200101_v000.cdf'])[0],
174169
create_mock_query_results(['imap_glows_energy-grid-hi_20200101_v000.cdf'])[0],
175170
create_mock_query_results(['imap_glows_energy-grid-ultra_20200101_v000.cdf'])[0],
176171
create_mock_query_results(['imap_glows_tess-ang-16_20200101_v000.cdf'])[0],

0 commit comments

Comments
 (0)