What happened?
TimeIntervals.get_duration (added in #2146) uses np.max on stop_time data. Stop times are allowed to be NaN (e.g. for ongoing/unbounded intervals), and np.max propagates NaN, so get_duration returns nan whenever any stop time is NaN. The same issue applies to get_starting_time, which uses np.min on start_time.
Expected behavior
get_starting_time should ignore NaNs (use np.nanmin), and return None if the table is empty or all start times are NaN.
get_duration should ignore NaNs (use np.nanmin/np.nanmax), with these edge cases:
- All start times and all stop times are NaN → return
NaN.
- All stop times are NaN but valid start times exist → return the span of the start times (latest start − earliest start).
- Empty table → return
None.
Steps to reproduce
import numpy as np
from pynwb.epoch import TimeIntervals
ti = TimeIntervals(name="intervals")
ti.add_interval(start_time=0.0, stop_time=1.0)
ti.add_interval(start_time=2.0, stop_time=np.nan) # ongoing interval
print(ti.get_duration()) # -> nan, expected 2.0 (latest valid stop is 1.0; here all-NaN-stop fallback not triggered)
Operating system
N/A
Python version
N/A
Code of Conduct
What happened?
TimeIntervals.get_duration(added in #2146) usesnp.maxonstop_timedata. Stop times are allowed to be NaN (e.g. for ongoing/unbounded intervals), andnp.maxpropagates NaN, soget_durationreturnsnanwhenever any stop time is NaN. The same issue applies toget_starting_time, which usesnp.minonstart_time.Expected behavior
get_starting_timeshould ignore NaNs (usenp.nanmin), and returnNoneif the table is empty or all start times are NaN.get_durationshould ignore NaNs (usenp.nanmin/np.nanmax), with these edge cases:NaN.None.Steps to reproduce
Operating system
N/A
Python version
N/A
Code of Conduct