Skip to content

Commit

Permalink
gwpy.timeseries: raise ValueError in TimeSeries.read
Browse files Browse the repository at this point in the history
if gap='raise' is given and the file(s) return a proper subset of the request
fixes gwpy#1211
  • Loading branch information
duncanmmacleod committed Jul 2, 2020
1 parent 3025316 commit a2a5f95
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 7 deletions.
57 changes: 50 additions & 7 deletions gwpy/timeseries/io/core.py
Expand Up @@ -61,13 +61,14 @@ def _join(data):
tsd = data.pop(0)
out.append(tsd, gap=gap, pad=pad)
del tsd
if gap == "pad":
if gap in ("pad", "raise"):
for key in out:
out[key] = _pad_series(
out[key],
pad,
start,
end,
error=(gap == "raise"),
)
return out
else:
Expand All @@ -76,21 +77,54 @@ def _join(data):
def _join(arrays):
list_ = TimeSeriesBaseList(*arrays)
joined = list_.join(pad=pad, gap=gap)
if gap == "pad":
if gap in ("pad", "raise"):
return _pad_series(
joined,
pad,
start,
end,
error=(gap == "raise"),
)
return joined
return _join


def _pad_series(ts, pad, start=None, end=None):
def _pad_series(ts, pad, start=None, end=None, error=False):
"""Pad a timeseries to match the specified [start, end) limits
To cover a gap in data returned from a data source
To cover a gap in data returned from a data source.
Parameters
----------
ts : `gwpy.types.Series`
the input series
pad : `float`, `astropy.units.Quantity`
the value with which to pad
start : `float`, `astropy.units.Quantity`, optional
the desired start point of the X-axis, defaults to
the start point of the incoming series
end : `float`, `astropy.units.Quantity`, optional
the desired end point of the X-axis, defaults to
the end point of the incoming series
error : `bool`, optional
raise `ValueError` when gaps are present, rather than padding
anything
Returns
-------
series : instance of incoming series type
a padded version of the series. This may be the same
object if not padding is needed.
Raises
------
ValueError
if `error=True` is given and padding would have been required
to match the request.
"""
span = ts.span
if start is None:
Expand All @@ -99,6 +133,15 @@ def _pad_series(ts, pad, start=None, end=None):
end = span[1]
pada = max(int((span[0] - start) * ts.sample_rate.value), 0)
padb = max(int((end - span[1]) * ts.sample_rate.value), 0)
if pada or padb:
return ts.pad((pada, padb), mode='constant', constant_values=(pad,))
return ts
if not (pada or padb): # if noop, just return the input
return ts
if error: # if error, bail out now
raise ValueError(
"{} with span {} does not cover requested interval {}".format(
type(ts).__name__,
span,
type(span)(start, end),
)
)
# otherwise applying the padding
return ts.pad((pada, padb), mode='constant', constant_values=(pad,))
18 changes: 18 additions & 0 deletions gwpy/timeseries/tests/test_timeseries.py
Expand Up @@ -442,6 +442,24 @@ def test_read_pad(self, pre, post):
b,
)

def test_read_pad_raise(self):
"""Check that `TimeSeries.read` with `gap='raise'` actually
raises appropriately.
[regression: https://github.com/gwpy/gwpy/issues/1211]
"""
from gwpy.io.cache import file_segment
span = file_segment(utils.TEST_HDF5_FILE)
with pytest.raises(ValueError):
self.TEST_CLASS.read(
utils.TEST_HDF5_FILE,
"H1:LDAS-STRAIN",
pad=0.,
start=span[0],
end=span[1]+1.,
gap="raise",
)

@utils.skip_missing_dependency('nds2')
def test_from_nds2_buffer_dynamic_scaled(self):
# build fake buffer for LIGO channel
Expand Down

0 comments on commit a2a5f95

Please sign in to comment.