Skip to content

Commit 0384ba2

Browse files
author
Menlo Innovations - CAVA Project
committed
Harrison 2381 - PMCL/TLAY - Use average of last three spacecraft potentials and halo core values when finding breackpoints. Instead of 4 values except most recent.
1 parent 9228170 commit 0384ba2

4 files changed

Lines changed: 33 additions & 35 deletions

File tree

imap_processing/swe/l3/science/pitch_calculations.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,8 @@ def piece_wise_model(x: np.ndarray, b0: float, b1: float,
2020
]))
2121

2222

23-
def find_breakpoints(energies: np.ndarray, averaged_psd: np.ndarray, initial_spacecraft_potential_guess: float,
24-
initial_core_halo_break_point_guess: float,
25-
latest_spacecraft_potential: float, latest_core_halo_breakpoint: float,
23+
def find_breakpoints(energies: np.ndarray, averaged_psd: np.ndarray, latest_spacecraft_potentials: list[float],
24+
latest_core_halo_break_points: list[float],
2625
config: SweConfiguration) -> tuple[
2726
float, float]:
2827
log_psd = np.log(averaged_psd)
@@ -38,7 +37,8 @@ def find_breakpoints(energies: np.ndarray, averaged_psd: np.ndarray, initial_spa
3837
b3: float = slopes[core_index]
3938
b5: float = slopes[halo_index]
4039
b0: float = np.exp(log_psd[0] + b1 * energies[0])
41-
initial_guesses = (b0, b1, initial_spacecraft_potential_guess, b3, initial_core_halo_break_point_guess, b5)
40+
initial_guesses = (
41+
b0, b1, np.average(latest_spacecraft_potentials), b3, np.average(latest_core_halo_break_points), b5)
4242

4343
first_min_index = 0
4444
for i in range(1, len(slope_ratios) - 1):
@@ -59,8 +59,8 @@ def find_breakpoints(energies: np.ndarray, averaged_psd: np.ndarray, initial_spa
5959
delta_b2 = -1.0
6060
delta_b4 = 10
6161

62-
return try_curve_fit_until_valid(energies, log_psd, initial_guesses, latest_spacecraft_potential,
63-
latest_core_halo_breakpoint, delta_b2, delta_b4)
62+
return try_curve_fit_until_valid(energies, log_psd, initial_guesses, latest_spacecraft_potentials[-1],
63+
latest_core_halo_break_points[-1], delta_b2, delta_b4)
6464

6565

6666
def try_curve_fit_until_valid(energies: np.ndarray, log_psd: np.ndarray, initial_guesses: tuple[float, ...],

imap_processing/swe/swe_processor.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,15 @@ def calculate_pitch_angle_products(self, dependencies: SweL3Dependencies) -> Swe
5050
energy_spectrum_inbound = []
5151
energy_spectrum_outbound = []
5252
spacecraft_potential_history = [config["spacecraft_potential_initial_guess"] for _ in
53-
range(4)]
54-
halo_core_history = [config["core_halo_breakpoint_initial_guess"] for _ in range(4)]
53+
range(3)]
54+
halo_core_history = [config["core_halo_breakpoint_initial_guess"] for _ in range(3)]
5555

5656
for i in range(len(swe_epoch)):
5757
averaged_psd = average_over_look_directions(swe_l2_data.phase_space_density[i],
5858
np.array(config["geometric_fractions"]))
5959
spacecraft_potential, halo_core = find_breakpoints(swe_l2_data.energy, averaged_psd,
60-
np.average(spacecraft_potential_history[:3]),
61-
np.average(halo_core_history[:3]),
62-
spacecraft_potential_history[-1], halo_core_history[-1],
60+
spacecraft_potential_history,
61+
halo_core_history,
6362
config)
6463
spacecraft_potential_history = [*spacecraft_potential_history[1:], spacecraft_potential]
6564
halo_core_history = [*halo_core_history[1:], halo_core]

tests/swe/l3/science/test_pitch_calculations.py

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,7 @@ def test_find_breakpoints_with_noisy_data(self):
122122
3.69484446e-01, 2.19359553e-01, 1.19059738e-01, 5.64115725e-02,
123123
2.30604686e-02, 9.14406238e-03, 4.24754874e-03, 1.61814681e-03])
124124
spacecraft_potential, core_halo_breakpoint = find_breakpoints(
125-
xs, avg_flux, 10, 80,
126-
11, 81, config)
125+
xs, avg_flux, [10, 10, 10], [80, 80, 80], config)
127126
self.assertAlmostEqual(11.1, spacecraft_potential, 1)
128127
self.assertAlmostEqual(81.1, core_halo_breakpoint, 1)
129128

@@ -146,18 +145,18 @@ def test_find_breakpoints_with_synthetic_data(self):
146145
noise_floor = 1
147146
avg_flux += noise_floor
148147
spacecraft_potential, core_halo_breakpoint = find_breakpoints(
149-
xs, avg_flux, 10, 80,
150-
11, 82, config)
148+
xs, avg_flux, [10, 10, 10], [80, 80, 80],
149+
config)
151150
self.assertAlmostEqual(expected_potential, spacecraft_potential, 2)
152151
self.assertAlmostEqual(expected_core_halo, core_halo_breakpoint, 0)
153152

154153
def test_find_breakpoints_using_initial_guess(self):
155154
config = build_swe_configuration()
156155

157156
cases = [
158-
(4, 40, 4, 50),
159-
(10, 80, 12, 100),
160-
(12, 60, 10, 80),
157+
(4, 40, [4, 4, 4], [50, 50, 50]),
158+
(10, 80, [12, 12, 12], [100, 100, 100]),
159+
(12, 60, [10, 10, 10], [80, 80, 80]),
161160
]
162161
for case in cases:
163162
with self.subTest(case):
@@ -172,7 +171,7 @@ def test_find_breakpoints_using_initial_guess(self):
172171
avg_flux += noise_floor
173172

174173
spacecraft_potential, core_halo_breakpoint = find_breakpoints(
175-
xs, avg_flux, guess_potential, guess_halo, 10, 80, config)
174+
xs, avg_flux, guess_potential, guess_halo, config)
176175
self.assertAlmostEqual(expected_potential, spacecraft_potential, 2)
177176
self.assertAlmostEqual(expected_core_halo, core_halo_breakpoint, 0)
178177

@@ -199,9 +198,8 @@ def test_find_breakpoints_determines_b_deltas_correctly(self, mock_try_curve_fit
199198
avg_flux = np.exp(log_flux)
200199

201200
result = find_breakpoints(
202-
xs, avg_flux, 10, 80, 15,
203-
90, config)
204-
mock_try_curve_fit_until_valid.assert_called_with(ANY, ANY, ANY, 15, 90, expected_b2_delta,
201+
xs, avg_flux, [10, 10, 10], [80, 80, 80], config)
202+
mock_try_curve_fit_until_valid.assert_called_with(ANY, ANY, ANY, 10, 80, expected_b2_delta,
205203
expected_b4_delta)
206204

207205
self.assertEqual(mock_try_curve_fit_until_valid.return_value, result)
@@ -233,8 +231,8 @@ def test_find_breakpoints_uses_config_for_slope_guesses(self, mock_curve_fit):
233231
avg_flux = np.exp(log_flux)
234232

235233
spacecraft_potential, core_halo_breakpoint = find_breakpoints(
236-
xs, avg_flux, 10, 80,
237-
11, 81, config)
234+
xs, avg_flux, [10, 10, 10], [80, 80, 80],
235+
config)
238236
expected_guesses = [ANY, b1, 10, b3, 80, b5]
239237
rounded_actuals = [round(x, 6) for x in mock_curve_fit.call_args.args[3]]
240238
self.assertEqual(expected_guesses, rounded_actuals)
@@ -264,8 +262,7 @@ def test_find_breakpoints_uses_config_for_slope_ratio(self, mock_curve_fit):
264262
avg_flux = np.exp(log_flux)
265263

266264
spacecraft_potential, core_halo_breakpoint = find_breakpoints(
267-
xs, avg_flux, 10, 80,
268-
11, 81, config)
265+
xs, avg_flux, [10, 10, 10], [80, 80, 80], config)
269266

270267
np.testing.assert_almost_equal(mock_curve_fit.call_args.args[1], xs[:data_length])
271268
np.testing.assert_almost_equal(mock_curve_fit.call_args.args[2], log_flux[:data_length])

tests/swe/test_swe_processor.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -146,14 +146,13 @@ def test_calculate_pitch_angle_products(self, mock_find_closest_neighbor,
146146
call(NumpyArrayMatcher(swe_l2_data.phase_space_density[1]), NumpyArrayMatcher(geometric_fractions)),
147147
call(NumpyArrayMatcher(swe_l2_data.phase_space_density[2]), NumpyArrayMatcher(geometric_fractions))])
148148

149-
spacecraft_potential_initial_guess = swe_config['spacecraft_potential_initial_guess']
150-
halo_core_initial_guess = swe_config['core_halo_breakpoint_initial_guess']
151149
mock_find_breakpoints.assert_has_calls([
152-
call(swe_l2_data.energy, mock_average_over_look_directions.return_value, spacecraft_potential_initial_guess,
153-
halo_core_initial_guess, 15, 90, swe_config),
154-
call(swe_l2_data.energy, mock_average_over_look_directions.return_value, spacecraft_potential_initial_guess,
155-
halo_core_initial_guess, 12, 96, swe_config),
156-
call(swe_l2_data.energy, mock_average_over_look_directions.return_value, 14, 92, 16, 86, swe_config),
150+
call(swe_l2_data.energy, mock_average_over_look_directions.return_value, [15, 15, 15],
151+
[90, 90, 90], swe_config),
152+
call(swe_l2_data.energy, mock_average_over_look_directions.return_value, [15, 15, 12],
153+
[90, 90, 96], swe_config),
154+
call(swe_l2_data.energy, mock_average_over_look_directions.return_value, [15, 12, 16],
155+
[90, 96, 86], swe_config),
157156
])
158157

159158
self.assertEqual(UpstreamDataDependency("swe", "l3", datetime(2025, 2, 21),
@@ -174,7 +173,9 @@ def test_calculate_pitch_angle_products(self, mock_find_closest_neighbor,
174173
def call_with_array_matchers(*args):
175174
return call(*[NumpyArrayMatcher(x) for x in args])
176175

177-
self.assertEqual(mock_correct_and_rebin.call_args_list, [
176+
actual_calls = mock_correct_and_rebin.call_args_list
177+
178+
expected_calls = [
178179
call_with_array_matchers(swe_l2_data.flux[0], swe_l2_data.energy - 12, swe_l2_data.inst_el,
179180
swe_l2_data.inst_az_spin_sector[0],
180181
closest_mag_data[0], closest_swapi_data[0], swe_config),
@@ -193,7 +194,8 @@ def call_with_array_matchers(*args):
193194
call_with_array_matchers(swe_l2_data.phase_space_density[2], swe_l2_data.energy - 19, swe_l2_data.inst_el,
194195
swe_l2_data.inst_az_spin_sector[2],
195196
closest_mag_data[2], closest_swapi_data[2], swe_config)
196-
])
197+
]
198+
self.assertEqual(actual_calls, expected_calls)
197199
mock_integrate_distribution_to_get_1d_spectrum.assert_has_calls([
198200
call(rebinned_by_pitch[1], swe_config),
199201
call(rebinned_by_pitch[3], swe_config),

0 commit comments

Comments
 (0)