@@ -38,6 +38,13 @@ def test_nearest_time_indices_accepts_unsorted_reference_times(self):
3838
3939 npt .assert_array_equal (indices , np .array ([1 , 2 , 0 ]))
4040
41+ def test_nearest_time_indices_ignores_nonfinite_reference_times (self ):
42+ indices = nearest_time_indices (
43+ np .array ([np .nan , 10.0 , 0.0 ]), np .array ([0.2 , 9.0 ])
44+ )
45+
46+ npt .assert_array_equal (indices , np .array ([2 , 1 ]))
47+
4148 def test_aggregate_time_offset_sweeps_preserves_rmse_and_max_semantics (self ):
4249 aggregated = aggregate_time_offset_sweeps (
4350 [
@@ -133,6 +140,27 @@ def test_interpolation_rejects_negative_max_time_delta(self):
133140 max_time_delta_s = - 1.0 ,
134141 )
135142
143+ def test_interpolation_skips_nonfinite_reference_rows (self ):
144+ interpolated , valid = interpolate_reference_values (
145+ np .array ([0.0 , 1.0 , 2.0 , np .nan , 3.0 ]),
146+ np .array ([[0.0 ], [np .nan ], [2.0 ], [99.0 ], [3.0 ]]),
147+ np .array ([0.5 , 1.5 , 2.5 ]),
148+ )
149+
150+ npt .assert_allclose (interpolated , np .array ([[0.5 ], [1.5 ], [2.5 ]]))
151+ npt .assert_array_equal (valid , np .array ([True , True , True ]))
152+
153+ def test_interpolation_rejects_without_two_finite_reference_rows (self ):
154+ with self .assertRaisesRegex (
155+ ValueError ,
156+ "at least two finite reference rows are required for interpolation" ,
157+ ):
158+ interpolate_reference_values (
159+ np .array ([0.0 , 1.0 ]),
160+ np .array ([[0.0 ], [np .nan ]]),
161+ np .array ([0.5 ]),
162+ )
163+
136164 def test_interpolation_rejects_scalar_reference_values (self ):
137165 with self .assertRaisesRegex (
138166 ValueError ,
@@ -193,6 +221,34 @@ def test_make_bias_training_examples_uses_nearest_reference(self):
193221
194222 npt .assert_allclose (examples .residual , np .array ([[1.0 ], [1.0 ]]))
195223
224+ def test_make_bias_training_examples_skips_nonfinite_reference_rows (self ):
225+ examples = make_bias_training_examples (
226+ np .array ([0.0 , 1.0 , 2.0 ]),
227+ np .array ([[1.0 ], [3.0 ], [5.0 ]]),
228+ np .array ([0.0 , 1.0 , 2.0 , np .nan ]),
229+ np .array ([[0.0 ], [np .nan ], [4.0 ], [99.0 ]]),
230+ max_time_delta_s = 0.25 ,
231+ )
232+
233+ npt .assert_allclose (examples .measured , np .array ([[1.0 ], [5.0 ]]))
234+ npt .assert_allclose (examples .reference , np .array ([[0.0 ], [4.0 ]]))
235+ npt .assert_allclose (examples .residual , np .array ([[1.0 ], [1.0 ]]))
236+ npt .assert_allclose (examples .time_delta_s , np .array ([0.0 , 0.0 ]))
237+
238+ def test_make_bias_training_examples_returns_empty_without_finite_reference_rows (
239+ self ,
240+ ):
241+ examples = make_bias_training_examples (
242+ np .array ([0.0 , 1.0 ]),
243+ np .array ([[1.0 ], [2.0 ]]),
244+ np .array ([np .nan , 1.0 ]),
245+ np .array ([[0.0 ], [np .nan ]]),
246+ feature_values = np .array ([[1.0 ], [2.0 ]]),
247+ )
248+
249+ self .assertEqual (examples .measured .shape , (0 , 1 ))
250+ self .assertEqual (examples .features .shape , (0 , 1 ))
251+
196252 def test_make_bias_training_examples_validates_feature_rows_without_references (
197253 self ,
198254 ):
0 commit comments