diff --git a/src/impulse_query_engine/model/series/sample_series.py b/src/impulse_query_engine/model/series/sample_series.py index d9b97ba..e77c434 100644 --- a/src/impulse_query_engine/model/series/sample_series.py +++ b/src/impulse_query_engine/model/series/sample_series.py @@ -1086,6 +1086,10 @@ def resample(self, sample_rate=1.0): # last interval of length 0 is a closed interval. Allow resampled series to start and end at last timestamp if (stop_index == len(self) - 1) and (self.tstarts[-1] == self.tends[-1]): tstarts = tmp_tstarts[tmp_tstarts <= t_max] + # interior zero-duration block (t_min == t_max, not the trailing point-in-time) + # leaves tstarts empty; skip to avoid an unmatched tend being appended. + if len(tstarts) == 0: + continue tends = np.append(tstarts[1:], t_max) values = self._interp1d()(tstarts) new_tstarts.extend(tstarts) diff --git a/tests/impulse_query_engine/unit/model/series/sample_series_test.py b/tests/impulse_query_engine/unit/model/series/sample_series_test.py index ac42c18..0f09078 100644 --- a/tests/impulse_query_engine/unit/model/series/sample_series_test.py +++ b/tests/impulse_query_engine/unit/model/series/sample_series_test.py @@ -878,6 +878,33 @@ def test_resample8(): nptest.assert_array_equal(exp_values, result.values) +def test_resample_with_interior_point_in_time(): + # Zero-duration sample (tstart == tend) in the middle of the series used + # to make the per-block branch extend new_tends without extending + # new_tstarts/new_values, tripping the constructor assertion. + s1 = SampleSeries([0, 2, 3], [1, 2, 4], [10, 20, 30]) + result = s1.resample(sample_rate=1.0) + exp_tstarts = [0, 3] + exp_tends = [1, 4] + exp_values = [10, 30] + nptest.assert_array_equal(exp_tstarts, result.tstarts) + nptest.assert_array_equal(exp_tends, result.tends) + nptest.assert_array_equal(exp_values, result.values) + + +def test_resample_with_interior_and_trailing_point_in_time(): + # Interior point-in-time is skipped; trailing point-in-time is preserved + # by the existing special case for the last block. + s1 = SampleSeries([0, 2, 3], [1, 2, 3], [10, 20, 30]) + result = s1.resample(sample_rate=1.0) + exp_tstarts = [0, 3] + exp_tends = [1, 3] + exp_values = [10, 30] + nptest.assert_array_equal(exp_tstarts, result.tstarts) + nptest.assert_array_equal(exp_tends, result.tends) + nptest.assert_array_equal(exp_values, result.values) + + def test_rolling_average1(): s1 = SampleSeries([0, 1, 2, 3, 4, 5, 10], [1, 2, 3, 4, 5, 10, 11], [5, 5, 5, 3, 5, 1, 2]) s1_avg = s1.rolling_average(window_size=3)