Skip to content

Commit 2221760

Browse files
author
Menlo Innovations - CAVA Project
committed
Harrison L3 2881 - GSTU/EYEA - Lo: Add spxnbs support in processor
1 parent ae6023e commit 2221760

2 files changed

Lines changed: 61 additions & 44 deletions

File tree

imap_l3_processing/lo/lo_processor.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import dataclasses
22
from pathlib import Path
3-
from typing import Optional
43

54
import numpy as np
65
from imap_processing.spice.geometry import SpiceFrame
@@ -29,7 +28,11 @@ def process(self, spice_frame_name: SpiceFrame = SpiceFrame.ECLIPJ2000) -> list[
2928
match descriptor:
3029
case MapDescriptorParts(quantity=MapQuantity.SpectralIndex):
3130
deps = LoL3SpectralFitDependencies.fetch_dependencies(self.dependencies)
32-
spectral_fit_data = perform_spectral_fit(deps.map_data, descriptor.spectral_index_energy_range)
31+
spectral_fit_data = perform_spectral_fit(deps.map_data, descriptor.spectral_index_energy_range or (4, 8))
32+
data_product = RectangularSpectralIndexDataProduct(self.input_metadata, spectral_fit_data)
33+
case MapDescriptorParts(quantity=MapQuantity.SpectralIndexNBS):
34+
deps = LoL3SpectralFitDependencies.fetch_dependencies(self.dependencies)
35+
spectral_fit_data = perform_spectral_fit(deps.map_data, descriptor.spectral_index_energy_range or (0, 8))
3336
data_product = RectangularSpectralIndexDataProduct(self.input_metadata, spectral_fit_data)
3437
case MapDescriptorParts(quantity=MapQuantity.ISNBackgroundSubtracted):
3538
deps = LoL3ISNBackgroundSubtractedDependencies.fetch_dependencies(self.dependencies)
@@ -58,12 +61,8 @@ def _collapse_pset_dimension(pset: InputRectangularPointingSet) -> InputRectangu
5861
hae_latitude=np.mean(pset.hae_latitude, axis=-1))
5962

6063

61-
def perform_spectral_fit(data: RectangularIntensityMapData, spectral_index_range: Optional[tuple[int,int]]) -> RectangularSpectralIndexMapData:
62-
if spectral_index_range is not None:
63-
start, end = spectral_index_range
64-
intensity_data = slice_energy_range_by_bin(data.intensity_map_data, start, end)
65-
else:
66-
intensity_data = data.intensity_map_data
64+
def perform_spectral_fit(data: RectangularIntensityMapData, spectral_index_range: tuple[int,int]) -> RectangularSpectralIndexMapData:
65+
intensity_data = slice_energy_range_by_bin(data.intensity_map_data, spectral_index_range[0], spectral_index_range[1])
6766
return RectangularSpectralIndexMapData(
6867
spectral_index_map_data=fit_spectral_index_map(intensity_data),
6968
coords=data.coords

tests/lo/test_lo_processor.py

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,26 @@
1111
from imap_l3_processing.maps.map_models import RectangularSpectralIndexDataProduct, RectangularIntensityDataProduct, \
1212
InputRectangularPointingSet, ISNRateData, ISNBackgroundSubtractedData, ISNBackgroundSubtractedMapData
1313
from imap_l3_processing.models import InputMetadata, Instrument
14+
from tests.maps import test_builders
1415

1516

1617
class TestLoProcessor(unittest.TestCase):
1718

1819
@patch('imap_l3_processing.hi.hi_processor.MapProcessor.get_parent_file_names')
20+
@patch('imap_l3_processing.lo.lo_processor.slice_energy_range_by_bin')
1921
@patch('imap_l3_processing.lo.lo_processor.LoL3SpectralFitDependencies.fetch_dependencies')
2022
@patch('imap_l3_processing.lo.lo_processor.fit_spectral_index_map')
2123
@patch('imap_l3_processing.lo.lo_processor.save_data')
22-
def test_process_spectral_index(self, mock_save_data,
23-
mock_fit_spectral_index_map, mock_fetch_dependencies,
24-
mock_get_parent_file_names):
24+
def test_process_spectral_index(self, mock_save_data, mock_fit_spectral_index_map, mock_fetch_dependencies,
25+
mock_slice_energy_range_by_bin, mock_get_parent_file_names):
2526
mock_get_parent_file_names.return_value = ["some_input_file_name"]
2627

2728
input_collection = Mock()
28-
lo_l3_spectral_fit_dependency = mock_fetch_dependencies.return_value
29+
lo_l3_spectral_fit_dependency = Mock()
30+
lo_l3_spectral_fit_dependency.map_data.intensity_map_data = test_builders.create_intensity_map_data()
2931
lo_l3_spectral_fit_dependency.map_data.intensity_map_data.energy = np.array(
30-
[1, 10, 1000, 10000, 100000, 1000000, 10000000])
31-
mock_fit_spectral_index_map.return_value = Mock()
32+
[1, 10, 100, 1000, 10000, 100000, 1000000, 10000000])
33+
mock_fetch_dependencies.return_value = lo_l3_spectral_fit_dependency
3234

3335
metadata = InputMetadata(instrument="lo",
3436
data_level="l3",
@@ -40,8 +42,10 @@ def test_process_spectral_index(self, mock_save_data,
4042
processor = LoProcessor(input_collection, input_metadata=metadata)
4143
product = processor.process()
4244

43-
mock_fetch_dependencies.assert_called_with(input_collection)
44-
mock_fit_spectral_index_map.assert_called_once_with(lo_l3_spectral_fit_dependency.map_data.intensity_map_data)
45+
mock_fetch_dependencies.assert_called_once_with(input_collection)
46+
mock_slice_energy_range_by_bin.assert_called_once_with(
47+
lo_l3_spectral_fit_dependency.map_data.intensity_map_data, 4, 8)
48+
mock_fit_spectral_index_map.assert_called_once_with(mock_slice_energy_range_by_bin.return_value)
4549

4650
data_product = mock_save_data.call_args_list[0].args[0]
4751

@@ -59,42 +63,57 @@ def test_process_spectral_index(self, mock_save_data,
5963
@patch('imap_l3_processing.lo.lo_processor.save_data')
6064
@patch('imap_l3_processing.lo.lo_processor.slice_energy_range_by_bin')
6165
def test_process_spectral_index_with_range_specified(self, mock_slice_energy_range_by_bin, mock_save_data,
62-
mock_fit_spectral_index_map, mock_fetch_dependencies,
63-
mock_get_parent_file_names):
64-
mock_get_parent_file_names.return_value = ["some_input_file_name"]
66+
mock_fit_spectral_index_map, mock_fetch_dependencies,
67+
mock_get_parent_file_names):
68+
test_cases = [
69+
("l090-spx0104-h-hf-sp-ram-hae-6deg-1yr", (1, 4)),
70+
("l090-spxnbs0105-h-hf-sp-ram-hae-6deg-1yr", (1, 5)),
71+
("l090-spx-h-hf-sp-ram-hae-6deg-1yr", (4, 8)),
72+
("l090-spxnbs-h-hf-sp-ram-hae-6deg-1yr", (0, 8)),
73+
]
6574

66-
input_collection = Mock()
67-
lo_l3_spectral_fit_dependency = mock_fetch_dependencies.return_value
68-
lo_l3_spectral_fit_dependency.map_data.intensity_map_data.energy = np.array(
69-
[1, 10, 1000, 10000, 100000, 1000000, 10000000])
75+
for descriptor, (expected_energy_start, expected_energy_end) in test_cases:
76+
mock_fit_spectral_index_map.reset_mock()
77+
mock_fetch_dependencies.reset_mock()
78+
mock_slice_energy_range_by_bin.reset_mock()
79+
mock_save_data.reset_mock()
7080

71-
mock_fit_spectral_index_map.return_value = Mock()
81+
with self.subTest(descriptor):
82+
mock_get_parent_file_names.return_value = ["some_input_file_name"]
7283

84+
input_collection = Mock()
85+
lo_l3_spectral_fit_dependency = mock_fetch_dependencies.return_value
86+
lo_l3_spectral_fit_dependency.map_data.intensity_map_data.energy = np.array(
87+
[1, 10, 1000, 10000, 100000, 1000000, 10000000])
7388

74-
metadata = InputMetadata(instrument="lo",
75-
data_level="l3",
76-
version="v000",
77-
start_date=datetime(2020, 1, 1, 1),
78-
end_date=datetime(2020, 1, 1, 1),
79-
descriptor="l090-spx0104-h-hf-sp-ram-hae-6deg-1yr")
89+
metadata = InputMetadata(instrument="lo",
90+
data_level="l3",
91+
version="v000",
92+
start_date=datetime(2020, 1, 1, 1),
93+
end_date=datetime(2020, 1, 1, 1),
94+
descriptor=descriptor)
8095

81-
processor = LoProcessor(input_collection, input_metadata=metadata)
82-
product = processor.process()
96+
processor = LoProcessor(input_collection, input_metadata=metadata)
97+
product = processor.process()
8398

84-
mock_fetch_dependencies.assert_called_with(input_collection)
85-
mock_slice_energy_range_by_bin.assert_called_with(lo_l3_spectral_fit_dependency.map_data.intensity_map_data, 1, 4)
99+
mock_fetch_dependencies.assert_called_once_with(input_collection)
100+
mock_slice_energy_range_by_bin.assert_called_once_with(
101+
lo_l3_spectral_fit_dependency.map_data.intensity_map_data,
102+
expected_energy_start,
103+
expected_energy_end
104+
)
86105

87-
mock_fit_spectral_index_map.assert_called_once_with(mock_slice_energy_range_by_bin.return_value)
106+
mock_fit_spectral_index_map.assert_called_once_with(mock_slice_energy_range_by_bin.return_value)
88107

89-
data_product = mock_save_data.call_args_list[0].args[0]
108+
data_product = mock_save_data.call_args_list[0].args[0]
90109

91-
self.assertIsInstance(data_product, RectangularSpectralIndexDataProduct)
92-
self.assertEqual(data_product.data.spectral_index_map_data,
93-
mock_fit_spectral_index_map.return_value)
94-
self.assertEqual(data_product.data.coords, lo_l3_spectral_fit_dependency.map_data.coords)
95-
self.assertEqual(data_product.input_metadata, processor.input_metadata)
96-
self.assertEqual(data_product.parent_file_names, ["some_input_file_name"])
97-
self.assertEqual([mock_save_data.return_value], product)
110+
self.assertIsInstance(data_product, RectangularSpectralIndexDataProduct)
111+
self.assertEqual(data_product.data.spectral_index_map_data,
112+
mock_fit_spectral_index_map.return_value)
113+
self.assertEqual(data_product.data.coords, lo_l3_spectral_fit_dependency.map_data.coords)
114+
self.assertEqual(data_product.input_metadata, processor.input_metadata)
115+
self.assertEqual(data_product.parent_file_names, ["some_input_file_name"])
116+
self.assertEqual([mock_save_data.return_value], product)
98117

99118
@patch('imap_l3_processing.lo.lo_processor.MapProcessor.get_parent_file_names')
100119
@patch("imap_l3_processing.lo.lo_processor.HiLoL3SurvivalDependencies.fetch_dependencies")
@@ -180,7 +199,6 @@ def test_rejects_unimplemented_descriptors(self):
180199
self.assertEqual(exception_args, cm.exception.args)
181200

182201
def test_isn_background_subtraction(self):
183-
184202
input_data: ISNRateData = ISNRateData(
185203
epoch=sentinel.epoch,
186204
solid_angle=sentinel.solid_angle,

0 commit comments

Comments
 (0)