Skip to content

Commit 561aa28

Browse files
authored
Fix GLOWS L2 - add per-bin zero handling for flux calculations (#2890)
* Check that exposure times are not zero to prevent division by zero when calculating photon flux and flux uncertainties. Add testing for this case. * Address PR comments - check that all exposure times are the same value * Add handling for dataset with zero flux and exposure times to return an empty dataset
1 parent 28fec45 commit 561aa28

4 files changed

Lines changed: 49 additions & 4 deletions

File tree

imap_processing/glows/l2/glows_l2.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ def glows_l2(
6363
if l2.number_of_good_l1b_inputs == 0:
6464
logger.warning("No good data found in L1B dataset. Returning empty list.")
6565
return []
66+
elif (
67+
np.all(l2.daily_lightcurve.photon_flux == 0)
68+
and np.all(l2.daily_lightcurve.flux_uncertainties == 0)
69+
and np.all(l2.daily_lightcurve.exposure_times == 0)
70+
):
71+
logger.warning("All flux and exposure times are zero. Returning empty list.")
72+
return []
6673
else:
6774
return [create_l2_dataset(l2, cdf_attrs)]
6875

imap_processing/glows/l2/glows_l2_data.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,11 @@ def __post_init__(self, l1b_data: xr.Dataset, position_angle: float) -> None:
106106
self.photon_flux = np.zeros(self.number_of_bins)
107107
self.flux_uncertainties = np.zeros(self.number_of_bins)
108108

109-
# TODO: Only where exposure counts != 0
110-
if len(self.exposure_times) != 0:
109+
if (
110+
len(self.exposure_times) != 0
111+
and self.exposure_times[0] > 0
112+
and len(np.unique(self.exposure_times)) == 1
113+
):
111114
self.photon_flux = self.raw_histograms / self.exposure_times
112115
self.flux_uncertainties = raw_uncertainties / self.exposure_times
113116

imap_processing/tests/glows/test_glows_l2.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,21 @@ def test_glows_l2(
7474
assert np.allclose(l2["filter_temperature_average"].values, [57.6], rtol=0.1)
7575

7676
# Test case 2: L1B dataset has no good times (all flags 0)
77-
l1b_hist_dataset["flags"].values = np.zeros(l1b_hist_dataset.flags.shape)
77+
l1b_hist_dataset_no_good_times = l1b_hist_dataset.copy(deep=True)
78+
l1b_hist_dataset_no_good_times["flags"].values = np.zeros(
79+
l1b_hist_dataset_no_good_times.flags.shape
80+
)
81+
caplog.set_level("WARNING")
82+
result = glows_l2(l1b_hist_dataset_no_good_times, mock_pipeline_settings, None)
83+
assert result == []
84+
assert any(record.levelname == "WARNING" for record in caplog.records)
85+
86+
# Test case 3: Dataset has zero exposure and flux values
87+
l1b_hist_dataset_zero_values = l1b_hist_dataset.copy(deep=True)
88+
l1b_hist_dataset_zero_values["spin_period_average"].data[:] = 0
89+
l1b_hist_dataset_zero_values["number_of_spins_per_block"].data[:] = 0
7890
caplog.set_level("WARNING")
79-
result = glows_l2(l1b_hist_dataset, mock_pipeline_settings, None)
91+
result = glows_l2(l1b_hist_dataset_zero_values, mock_pipeline_settings, None)
8092
assert result == []
8193
assert any(record.levelname == "WARNING" for record in caplog.records)
8294

imap_processing/tests/glows/test_glows_l2_data.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,29 @@ def test_zero_exposure_bins(l1b_dataset, mock_ecliptic_bin_centers):
175175
assert np.allclose(lc.exposure_times, expected_exposure)
176176

177177

178+
def test_zero_exposure_values(l1b_dataset, mock_ecliptic_bin_centers):
179+
"""Zero exposure yields zero flux and zero uncertainty per bin."""
180+
181+
# Note: all bins have the same exposure time, so if one is zero all are zero.
182+
183+
# Update values used to calculate exposure times to
184+
# ensure a zero exposure result.
185+
l1b_dataset["spin_period_average"].data[:] = 0
186+
l1b_dataset["number_of_spins_per_block"].data[:] = 0
187+
188+
with np.errstate(divide="raise", invalid="raise"):
189+
lc = DailyLightcurve(l1b_dataset, position_angle=0.0)
190+
191+
expected = np.zeros(l1b_dataset.sizes["bins"], dtype=float)
192+
assert lc.exposure_times.shape == expected.shape
193+
assert len(np.unique(lc.exposure_times)) == 1
194+
assert np.array_equal(lc.exposure_times, expected)
195+
assert np.array_equal(lc.photon_flux, expected)
196+
assert np.array_equal(lc.flux_uncertainties, expected)
197+
assert np.all(np.isfinite(lc.photon_flux))
198+
assert np.all(np.isfinite(lc.flux_uncertainties))
199+
200+
178201
def test_number_of_bins(l1b_dataset, mock_ecliptic_bin_centers):
179202
lc = DailyLightcurve(l1b_dataset, position_angle=0.0)
180203
assert lc.number_of_bins == 4

0 commit comments

Comments
 (0)