gwpy 3.0.8__py3-none-any.whl → 3.0.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of gwpy might be problematic. Click here for more details.
- gwpy/_version.py +2 -2
- gwpy/astro/range.py +3 -3
- gwpy/astro/tests/test_range.py +4 -5
- gwpy/cli/gwpy_plot.py +1 -1
- gwpy/cli/qtransform.py +1 -1
- gwpy/cli/tests/base.py +11 -1
- gwpy/detector/units.py +2 -1
- gwpy/frequencyseries/tests/test_hist.py +4 -3
- gwpy/io/datafind.py +1 -0
- gwpy/io/ffldatafind.py +27 -16
- gwpy/io/tests/test_ffldatafind.py +10 -3
- gwpy/plot/plot.py +12 -2
- gwpy/plot/tests/test_segments.py +1 -1
- gwpy/plot/tex.py +6 -4
- gwpy/segments/flag.py +13 -11
- gwpy/signal/filter_design.py +5 -4
- gwpy/signal/tests/test_coherence.py +31 -10
- gwpy/signal/tests/test_filter_design.py +3 -3
- gwpy/spectrogram/tests/test_spectrogram.py +2 -2
- gwpy/table/io/ligolw.py +1 -1
- gwpy/table/tests/test_io_ligolw.py +1 -1
- gwpy/testing/errors.py +1 -0
- gwpy/testing/fixtures.py +1 -18
- gwpy/testing/utils.py +15 -6
- gwpy/timeseries/core.py +0 -1
- gwpy/timeseries/io/cache.py +47 -29
- gwpy/timeseries/io/gwf/lalframe.py +8 -0
- gwpy/timeseries/statevector.py +4 -2
- gwpy/timeseries/tests/test_core.py +7 -13
- gwpy/timeseries/tests/test_io_cache.py +74 -0
- gwpy/timeseries/tests/test_io_gwf_framecpp.py +1 -1
- gwpy/timeseries/tests/test_statevector.py +29 -17
- gwpy/timeseries/tests/test_timeseries.py +37 -34
- gwpy/types/array.py +16 -3
- gwpy/types/index.py +7 -5
- gwpy/types/tests/test_array.py +12 -10
- gwpy/types/tests/test_array2d.py +5 -9
- gwpy/types/tests/test_series.py +5 -5
- gwpy/utils/sphinx/zenodo.py +5 -1
- gwpy/utils/tests/test_sphinx_zenodo.py +23 -0
- gwpy-3.0.10.dist-info/METADATA +125 -0
- {gwpy-3.0.8.dist-info → gwpy-3.0.10.dist-info}/RECORD +46 -45
- {gwpy-3.0.8.dist-info → gwpy-3.0.10.dist-info}/WHEEL +1 -1
- gwpy-3.0.8.dist-info/METADATA +0 -124
- {gwpy-3.0.8.dist-info → gwpy-3.0.10.dist-info}/LICENSE +0 -0
- {gwpy-3.0.8.dist-info → gwpy-3.0.10.dist-info}/entry_points.txt +0 -0
- {gwpy-3.0.8.dist-info → gwpy-3.0.10.dist-info}/top_level.txt +0 -0
gwpy/_version.py
CHANGED
gwpy/astro/range.py
CHANGED
|
@@ -25,7 +25,7 @@ import warnings
|
|
|
25
25
|
from functools import wraps
|
|
26
26
|
from math import pi
|
|
27
27
|
|
|
28
|
-
from scipy.integrate import
|
|
28
|
+
from scipy.integrate import trapezoid
|
|
29
29
|
from scipy.interpolate import interp1d
|
|
30
30
|
|
|
31
31
|
from astropy import (
|
|
@@ -238,7 +238,7 @@ def sensemon_range(psd, snr=8, mass1=1.4, mass2=1.4, fmin=None, fmax=None,
|
|
|
238
238
|
integrand = sensemon_range_psd(psd[frange], snr=snr, mass1=mass1,
|
|
239
239
|
mass2=mass2, horizon=horizon)
|
|
240
240
|
return (units.Quantity(
|
|
241
|
-
|
|
241
|
+
trapezoid(integrand.value, f.value[frange]),
|
|
242
242
|
unit=integrand.unit * units.Hertz,
|
|
243
243
|
) ** (1/2.)).to('Mpc')
|
|
244
244
|
|
|
@@ -528,7 +528,7 @@ def burst_range(psd, snr=8, energy=1e-2, fmin=100, fmax=500):
|
|
|
528
528
|
# calculate integrand and integrate
|
|
529
529
|
integrand = burst_range_spectrum(
|
|
530
530
|
psd[frange], snr=snr, energy=energy) ** 3
|
|
531
|
-
out =
|
|
531
|
+
out = trapezoid(integrand.value, f[frange])
|
|
532
532
|
# normalize and return
|
|
533
533
|
return (units.Quantity(
|
|
534
534
|
out / (fmax - fmin),
|
gwpy/astro/tests/test_range.py
CHANGED
|
@@ -24,7 +24,7 @@ from unittest import mock
|
|
|
24
24
|
import pytest
|
|
25
25
|
|
|
26
26
|
from astropy import units
|
|
27
|
-
from scipy.integrate import
|
|
27
|
+
from scipy.integrate import trapezoid
|
|
28
28
|
|
|
29
29
|
from ... import astro
|
|
30
30
|
from ...testing import utils
|
|
@@ -71,7 +71,7 @@ def test_sensemon_range_psd(psd):
|
|
|
71
71
|
r = astro.sensemon_range_psd(psd[frange])
|
|
72
72
|
assert isinstance(r, FrequencySeries)
|
|
73
73
|
utils.assert_quantity_almost_equal(
|
|
74
|
-
|
|
74
|
+
trapezoid(r, r.frequencies) ** (1/2.),
|
|
75
75
|
TEST_RESULTS['sensemon_range'],
|
|
76
76
|
)
|
|
77
77
|
assert r.f0.value > 0
|
|
@@ -103,9 +103,8 @@ def test_inspiral_range_psd(psd):
|
|
|
103
103
|
frange = (psd.frequencies.value < 4096)
|
|
104
104
|
r = astro.inspiral_range_psd(psd[frange])
|
|
105
105
|
assert isinstance(r, FrequencySeries)
|
|
106
|
-
print(trapz(r, r.frequencies) ** (1/2.))
|
|
107
106
|
utils.assert_quantity_almost_equal(
|
|
108
|
-
|
|
107
|
+
trapezoid(r, r.frequencies) ** (1/2.),
|
|
109
108
|
TEST_RESULTS['inspiral_range'],
|
|
110
109
|
)
|
|
111
110
|
assert r.f0.value > 0
|
|
@@ -129,7 +128,7 @@ def test_burst_range_spectrum(psd):
|
|
|
129
128
|
r = astro.burst_range_spectrum(psd[frange])
|
|
130
129
|
assert isinstance(r, FrequencySeries)
|
|
131
130
|
utils.assert_quantity_almost_equal(
|
|
132
|
-
(
|
|
131
|
+
(trapezoid(r**3, f[frange]) / (400 * units.Hz)) ** (1/3.),
|
|
133
132
|
TEST_RESULTS['burst_range'],
|
|
134
133
|
)
|
|
135
134
|
assert r.f0.value > 0
|
gwpy/cli/gwpy_plot.py
CHANGED
|
@@ -55,7 +55,7 @@ Examples:
|
|
|
55
55
|
$ gwpy-plot coherencegram --chan H1:GDS-CALIB_STRAIN H1:PEM-CS_ACC_PSL_PERISCOPE_X_DQ --start 1126260017 --duration 600
|
|
56
56
|
|
|
57
57
|
Written by {__author__}.
|
|
58
|
-
Report bugs to https://
|
|
58
|
+
Report bugs to https://gitlab.com/gwpy/gwpy/-/issues/.
|
|
59
59
|
""" # noqa: E501
|
|
60
60
|
|
|
61
61
|
|
gwpy/cli/qtransform.py
CHANGED
|
@@ -215,7 +215,7 @@ class Qtransform(Spectrogram):
|
|
|
215
215
|
outseg = Segment(gps, gps).protract(args.plot[self.plot_num])
|
|
216
216
|
|
|
217
217
|
# use the precomputed ASD as the whitener if needed
|
|
218
|
-
if self.qxfrm_args.get("whiten"):
|
|
218
|
+
if self.qxfrm_args.get("whiten") is True:
|
|
219
219
|
self.qxfrm_args["whiten"] = asd
|
|
220
220
|
|
|
221
221
|
# This section tries to optimize the amount of data that is
|
gwpy/cli/tests/base.py
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"""Unit tests for :mod:`gwpy.cli`
|
|
20
20
|
"""
|
|
21
21
|
|
|
22
|
+
import warnings
|
|
22
23
|
from argparse import ArgumentParser
|
|
23
24
|
from unittest import mock
|
|
24
25
|
|
|
@@ -237,7 +238,16 @@ class _TestCliProduct(object):
|
|
|
237
238
|
xmin = min(series.xspan[0] for series in data)
|
|
238
239
|
xmax = max(series.xspan[1] for series in data)
|
|
239
240
|
|
|
240
|
-
|
|
241
|
+
# ignore warnings from matplotlib about having no labels
|
|
242
|
+
# (because we have cut some corners in preparing this test)
|
|
243
|
+
with warnings.catch_warnings():
|
|
244
|
+
warnings.filterwarnings(
|
|
245
|
+
"ignore",
|
|
246
|
+
message="No artists with labels found to put in legend",
|
|
247
|
+
category=UserWarning,
|
|
248
|
+
)
|
|
249
|
+
plotprod.set_plot_properties()
|
|
250
|
+
|
|
241
251
|
ax = plotprod.ax
|
|
242
252
|
|
|
243
253
|
ymin, ymax = ax.get_ylim()
|
gwpy/detector/units.py
CHANGED
|
@@ -167,6 +167,7 @@ for unit, aliases in [
|
|
|
167
167
|
# GW observatories like to record 'time' as the unit
|
|
168
168
|
(units.Unit('second'), (
|
|
169
169
|
'time',
|
|
170
|
+
'time (s)',
|
|
170
171
|
'time [s]',
|
|
171
172
|
'Time [sec]',
|
|
172
173
|
'Time (sec)',
|
|
@@ -186,7 +187,7 @@ units.def_unit(['NONE', 'undef'], namespace=_ns,
|
|
|
186
187
|
|
|
187
188
|
# other dimenionless units
|
|
188
189
|
units.def_unit('strain', namespace=_ns)
|
|
189
|
-
units.def_unit('coherence', namespace=_ns)
|
|
190
|
+
units.def_unit('coherence', represents=units.dimensionless_unscaled, namespace=_ns)
|
|
190
191
|
|
|
191
192
|
# alias for 'second' but with prefices
|
|
192
193
|
units.def_unit((['sec'], ['sec']), represents=units.second, prefixes=True,
|
|
@@ -77,7 +77,8 @@ class TestSpectralVariance(_TestArray2D):
|
|
|
77
77
|
utils.assert_array_equal(array.yindex, array.bins[:-1])
|
|
78
78
|
|
|
79
79
|
def test_transpose(self, array):
|
|
80
|
-
|
|
80
|
+
with pytest.raises(NotImplementedError):
|
|
81
|
+
array.T
|
|
81
82
|
|
|
82
83
|
# -- test utilities -------------------------
|
|
83
84
|
|
|
@@ -110,10 +111,10 @@ class TestSpectralVariance(_TestArray2D):
|
|
|
110
111
|
pytest.skip("float precision test not supported for SpectralVariance")
|
|
111
112
|
|
|
112
113
|
def test_is_compatible_yindex(self, array):
|
|
113
|
-
|
|
114
|
+
pytest.skip(f"not implemented for {type(self).__name__}")
|
|
114
115
|
|
|
115
116
|
def test_is_compatible_error_yindex(self, array):
|
|
116
|
-
|
|
117
|
+
pytest.skip(f"not implemented for {type(self).__name__}")
|
|
117
118
|
|
|
118
119
|
def test_plot(self, array):
|
|
119
120
|
with rc_context(rc={'text.usetex': False}):
|
gwpy/io/datafind.py
CHANGED
|
@@ -65,6 +65,7 @@ GRB_TYPE = re.compile(r'^(?!.*_GRB\d{6}([A-Z])?$)') # *_GRBYYMMDD{A}
|
|
|
65
65
|
HIGH_PRIORITY_TYPE = re.compile("({})".format("|".join((
|
|
66
66
|
r'\A[A-Z]\d_HOFT_C\d\d(_T\d{7}_v\d)?\Z', # X1_HOFT_CXY
|
|
67
67
|
r'\AV1Online\Z',
|
|
68
|
+
r'\AHoftOnline\Z',
|
|
68
69
|
r'\AV1O[0-9]+([A-Z]+)?Repro[0-9]+[A-Z]+\Z', # V1OXReproXY
|
|
69
70
|
))))
|
|
70
71
|
LOW_PRIORITY_TYPE = re.compile("({})".format("|".join((
|
gwpy/io/ffldatafind.py
CHANGED
|
@@ -28,8 +28,9 @@ __author__ = "Duncan Macleod <duncan.macleod@ligo.org>"
|
|
|
28
28
|
|
|
29
29
|
import os
|
|
30
30
|
import re
|
|
31
|
-
from
|
|
31
|
+
from collections import defaultdict
|
|
32
32
|
from functools import lru_cache
|
|
33
|
+
from warnings import warn
|
|
33
34
|
|
|
34
35
|
from ligo.segments import (
|
|
35
36
|
segment,
|
|
@@ -37,8 +38,10 @@ from ligo.segments import (
|
|
|
37
38
|
)
|
|
38
39
|
|
|
39
40
|
from .cache import (
|
|
41
|
+
_CacheEntry,
|
|
40
42
|
_iter_cache,
|
|
41
43
|
cache_segments,
|
|
44
|
+
file_segment,
|
|
42
45
|
read_cache_entry,
|
|
43
46
|
)
|
|
44
47
|
|
|
@@ -123,10 +126,10 @@ def _find_ffl_files(basedir=None):
|
|
|
123
126
|
def _find_ffls(basedir=None):
|
|
124
127
|
"""Find all readable FFL files.
|
|
125
128
|
"""
|
|
126
|
-
ffls =
|
|
129
|
+
ffls = defaultdict(list)
|
|
127
130
|
for path in _find_ffl_files(basedir=basedir):
|
|
128
131
|
try:
|
|
129
|
-
ffls[_get_site_tag(path)]
|
|
132
|
+
ffls[_get_site_tag(path)].append(path)
|
|
130
133
|
except (
|
|
131
134
|
OSError, # file is empty (or cannot be read at all)
|
|
132
135
|
AttributeError, # last entry didn't match _SITE_REGEX
|
|
@@ -135,8 +138,8 @@ def _find_ffls(basedir=None):
|
|
|
135
138
|
return ffls
|
|
136
139
|
|
|
137
140
|
|
|
138
|
-
def
|
|
139
|
-
"""Return the
|
|
141
|
+
def _ffl_paths(site, tag, basedir=None):
|
|
142
|
+
"""Return the paths of all FFL files for a given site and tag.
|
|
140
143
|
"""
|
|
141
144
|
try:
|
|
142
145
|
return _find_ffls(basedir=basedir)[(site, tag)]
|
|
@@ -147,15 +150,18 @@ def _ffl_path(site, tag, basedir=None):
|
|
|
147
150
|
|
|
148
151
|
|
|
149
152
|
@lru_cache()
|
|
150
|
-
def
|
|
151
|
-
"""Read
|
|
153
|
+
def _read_ffls(site, tag, basedir=None):
|
|
154
|
+
"""Read all FFL files for a given site and tag
|
|
155
|
+
as a list of `CacheEntry` objects.
|
|
152
156
|
"""
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
157
|
+
entries = []
|
|
158
|
+
for ffl in _ffl_paths(site, tag, basedir=basedir):
|
|
159
|
+
with open(ffl, "r") as fobj:
|
|
160
|
+
entries.extend(
|
|
161
|
+
_CacheEntry(site, tag, entry.segment, entry.path)
|
|
162
|
+
for entry in _iter_cache(fobj, gpstype=float)
|
|
163
|
+
)
|
|
164
|
+
return entries
|
|
159
165
|
|
|
160
166
|
|
|
161
167
|
def _handle_error(action, message):
|
|
@@ -261,7 +267,7 @@ def find_urls(
|
|
|
261
267
|
span = segment(gpsstart, gpsend)
|
|
262
268
|
|
|
263
269
|
cache = [
|
|
264
|
-
e for e in
|
|
270
|
+
e for e in _read_ffls(site, tag) if (
|
|
265
271
|
e.observatory == site
|
|
266
272
|
and e.description == tag
|
|
267
273
|
and e.segment.intersects(span)
|
|
@@ -305,11 +311,16 @@ def find_latest(site, tag, on_missing="warn"):
|
|
|
305
311
|
for a specific site and tag.
|
|
306
312
|
"""
|
|
307
313
|
try:
|
|
308
|
-
|
|
314
|
+
fflfiles = _ffl_paths(site, tag)
|
|
309
315
|
except ValueError: # no readable FFL file
|
|
310
316
|
urls = []
|
|
311
317
|
else:
|
|
312
|
-
urls = [
|
|
318
|
+
urls = [
|
|
319
|
+
read_cache_entry(_read_last_line(fflfile), gpstype=float)
|
|
320
|
+
for fflfile in fflfiles
|
|
321
|
+
]
|
|
322
|
+
if urls: # if multiple, find the latest one
|
|
323
|
+
urls = sorted(urls, key=file_segment)[-1:]
|
|
313
324
|
|
|
314
325
|
if not urls:
|
|
315
326
|
_handle_error(on_missing, "No files found")
|
|
@@ -96,9 +96,11 @@ def test_is_ffl_file(path, result):
|
|
|
96
96
|
# -- test ffl UI ------------
|
|
97
97
|
|
|
98
98
|
FFLS = {
|
|
99
|
-
"test.ffl": [
|
|
99
|
+
"a/test.ffl": [
|
|
100
100
|
"/tmp/X-test-0-1.gwf 0 1 0 0",
|
|
101
101
|
"/tmp/X-test-1-1.gwf 1 1 0 0",
|
|
102
|
+
],
|
|
103
|
+
"b/test.ffl": [
|
|
102
104
|
"/tmp/X-test-2-1.gwf 2 1 0 0",
|
|
103
105
|
],
|
|
104
106
|
"test2.ffl": [
|
|
@@ -114,7 +116,11 @@ FFLS = {
|
|
|
114
116
|
"test-empty.ffl": [],
|
|
115
117
|
"test-bad.ffl": ["badness"],
|
|
116
118
|
}
|
|
117
|
-
TEST_URLS = [
|
|
119
|
+
TEST_URLS = [
|
|
120
|
+
x.split()[0]
|
|
121
|
+
for key in ("a/test.ffl", "b/test.ffl")
|
|
122
|
+
for x in FFLS[key]
|
|
123
|
+
]
|
|
118
124
|
|
|
119
125
|
|
|
120
126
|
@pytest.fixture(autouse=True)
|
|
@@ -124,6 +130,7 @@ def mock_ffl(tmp_path):
|
|
|
124
130
|
"""
|
|
125
131
|
for path, lines in FFLS.items():
|
|
126
132
|
ffl = tmp_path / path
|
|
133
|
+
ffl.parent.mkdir(parents=True, exist_ok=True)
|
|
127
134
|
ffl.write_text("\n".join(lines))
|
|
128
135
|
with mock.patch.dict(
|
|
129
136
|
"os.environ",
|
|
@@ -190,7 +197,7 @@ def test_find_latest():
|
|
|
190
197
|
assert ffldatafind.find_latest(
|
|
191
198
|
"X",
|
|
192
199
|
"test",
|
|
193
|
-
) == sorted(x.split()[0] for x in FFLS["test.ffl"])[-1:]
|
|
200
|
+
) == sorted(x.split()[0] for x in FFLS["b/test.ffl"])[-1:]
|
|
194
201
|
|
|
195
202
|
|
|
196
203
|
@pytest.mark.parametrize(("on_missing", "ctx"), (
|
gwpy/plot/plot.py
CHANGED
|
@@ -27,7 +27,12 @@ from itertools import zip_longest
|
|
|
27
27
|
|
|
28
28
|
import numpy
|
|
29
29
|
|
|
30
|
-
from matplotlib import (
|
|
30
|
+
from matplotlib import (
|
|
31
|
+
_pylab_helpers,
|
|
32
|
+
backends,
|
|
33
|
+
figure,
|
|
34
|
+
get_backend,
|
|
35
|
+
)
|
|
31
36
|
from matplotlib.artist import setp
|
|
32
37
|
from matplotlib.gridspec import GridSpec
|
|
33
38
|
from matplotlib.ticker import LogFormatterSciNotation
|
|
@@ -53,7 +58,12 @@ iterable_types = (list, tuple, KeysView, ValuesView,)
|
|
|
53
58
|
def interactive_backend():
|
|
54
59
|
"""Returns `True` if the current backend is interactive
|
|
55
60
|
"""
|
|
56
|
-
|
|
61
|
+
try:
|
|
62
|
+
interactive_bk = backends.backend_registry.list_builtin(
|
|
63
|
+
backends.BackendFilter.INTERACTIVE,
|
|
64
|
+
)
|
|
65
|
+
except AttributeError: # matplotlib < 3.9.0
|
|
66
|
+
from matplotlib.rcsetup import interactive_bk
|
|
57
67
|
return get_backend() in interactive_bk
|
|
58
68
|
|
|
59
69
|
|
gwpy/plot/tests/test_segments.py
CHANGED
gwpy/plot/tex.py
CHANGED
|
@@ -39,10 +39,12 @@ def _test_usetex():
|
|
|
39
39
|
from matplotlib import (pyplot, rc_context)
|
|
40
40
|
with rc_context({"text.usetex": True}):
|
|
41
41
|
fig = pyplot.figure()
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
try:
|
|
43
|
+
ax = fig.gca()
|
|
44
|
+
ax.set_xlabel(r"\LaTeX")
|
|
45
|
+
fig.canvas.draw()
|
|
46
|
+
finally:
|
|
47
|
+
pyplot.close(fig)
|
|
46
48
|
|
|
47
49
|
|
|
48
50
|
@lru_cache(maxsize=None)
|
gwpy/segments/flag.py
CHANGED
|
@@ -453,18 +453,20 @@ class DataQualityFlag(object):
|
|
|
453
453
|
Examples
|
|
454
454
|
--------
|
|
455
455
|
>>> from gwpy.segments import DataQualityFlag
|
|
456
|
-
>>> print(DataQualityFlag.fetch_open_data(
|
|
457
|
-
...
|
|
456
|
+
>>> print(DataQualityFlag.fetch_open_data(
|
|
457
|
+
... "H1_DATA",
|
|
458
|
+
... "Sep 14 2015",
|
|
459
|
+
... "Sep 15 2015",
|
|
460
|
+
... ))
|
|
458
461
|
<DataQualityFlag('H1:DATA',
|
|
459
|
-
known=[[
|
|
460
|
-
active=[[
|
|
461
|
-
[
|
|
462
|
-
[
|
|
463
|
-
|
|
464
|
-
[
|
|
465
|
-
[
|
|
466
|
-
[
|
|
467
|
-
[946415770 ... 946422986)],
|
|
462
|
+
known=[[1126224017 ... 1126310417)]
|
|
463
|
+
active=[[1126251604 ... 1126252133)
|
|
464
|
+
[1126252291 ... 1126274322)
|
|
465
|
+
[1126276234 ... 1126281754)
|
|
466
|
+
...
|
|
467
|
+
[1126308670 ... 1126309577)
|
|
468
|
+
[1126309637 ... 1126309817)
|
|
469
|
+
[1126309877 ... 1126310417)]
|
|
468
470
|
description=None)>
|
|
469
471
|
"""
|
|
470
472
|
start = to_gps(start).gpsSeconds
|
gwpy/signal/filter_design.py
CHANGED
|
@@ -30,6 +30,7 @@ from scipy import signal
|
|
|
30
30
|
|
|
31
31
|
from astropy.units import (Unit, Quantity)
|
|
32
32
|
|
|
33
|
+
from ..types.array import COPY_IF_NEEDED
|
|
33
34
|
from .window import (get_window, planck)
|
|
34
35
|
|
|
35
36
|
__author__ = "Duncan Macleod <duncan.macleod@ligo.org>"
|
|
@@ -88,8 +89,8 @@ def _design_fir(wp, ws, sample_rate, gpass, gstop, window='hamming', **kwargs):
|
|
|
88
89
|
if wp[0] > ws[0]:
|
|
89
90
|
kwargs.setdefault('pass_zero', False)
|
|
90
91
|
if ws.shape == (1,):
|
|
91
|
-
kwargs.setdefault(
|
|
92
|
-
kwargs.setdefault('
|
|
92
|
+
kwargs.setdefault("width", ws.item() - wp.item())
|
|
93
|
+
kwargs.setdefault('fs', sample_rate)
|
|
93
94
|
return signal.firwin(nt, wp, window=window, **kwargs)
|
|
94
95
|
|
|
95
96
|
|
|
@@ -281,9 +282,9 @@ def bilinear_zpk(zeros, poles, gain, fs=1.0, unit='Hz'):
|
|
|
281
282
|
zpk : `tuple`
|
|
282
283
|
digital version of input zpk
|
|
283
284
|
"""
|
|
284
|
-
zeros = numpy.array(zeros, dtype=float, copy=
|
|
285
|
+
zeros = numpy.array(zeros, dtype=float, copy=COPY_IF_NEEDED)
|
|
285
286
|
zeros = zeros[numpy.isfinite(zeros)]
|
|
286
|
-
poles = numpy.array(poles, dtype=float, copy=
|
|
287
|
+
poles = numpy.array(poles, dtype=float, copy=COPY_IF_NEEDED)
|
|
287
288
|
gain = gain
|
|
288
289
|
|
|
289
290
|
# convert from Hz to rad/s if needed
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
|
|
22
22
|
__author__ = "Alex Southgate <alex.southgate@ligo.org>"
|
|
23
23
|
|
|
24
|
+
import warnings
|
|
25
|
+
|
|
24
26
|
import numpy as np
|
|
25
27
|
import pytest
|
|
26
28
|
import scipy.signal as sig
|
|
@@ -121,7 +123,11 @@ def test_coherence_resample(unequal_fs_series_data):
|
|
|
121
123
|
# the first coherence val coh12 is broken intentionally since
|
|
122
124
|
# secondarr data should not have fs_1, instead fs_2
|
|
123
125
|
coh12 = spectral.coherence(first, second, segmentlength=seglen)
|
|
124
|
-
|
|
126
|
+
with pytest.warns(
|
|
127
|
+
UserWarning,
|
|
128
|
+
match="Sampling frequencies are unequal",
|
|
129
|
+
):
|
|
130
|
+
coh13 = spectral.coherence(first, third, segmentlength=seglen)
|
|
125
131
|
|
|
126
132
|
# get the frequency at minimum coherence, this should be the extra
|
|
127
133
|
# component in secondarr
|
|
@@ -136,7 +142,7 @@ def test_coherence_resample(unequal_fs_series_data):
|
|
|
136
142
|
assert not (4 <= maxf12.value <= 6)
|
|
137
143
|
|
|
138
144
|
|
|
139
|
-
def
|
|
145
|
+
def test_coherence_resample_downsample(series_data):
|
|
140
146
|
"""Ensure warning is raised by unequal sampling frequencies.
|
|
141
147
|
"""
|
|
142
148
|
firstarr, secondarr, seglen = series_data
|
|
@@ -145,15 +151,30 @@ def test_coherence_resample_arg(series_data):
|
|
|
145
151
|
first = TimeSeries(firstarr, sample_rate=f_s)
|
|
146
152
|
second = TimeSeries(secondarr, sample_rate=f_s * 2.32)
|
|
147
153
|
|
|
148
|
-
with pytest.warns(
|
|
149
|
-
|
|
154
|
+
with pytest.warns(
|
|
155
|
+
UserWarning,
|
|
156
|
+
match="Sampling frequencies are unequal",
|
|
157
|
+
):
|
|
158
|
+
coh1 = spectral.coherence(first, second, segmentlength=seglen)
|
|
150
159
|
|
|
160
|
+
# check that forcibly disabling downsample results in an error
|
|
151
161
|
with pytest.raises(ValueError):
|
|
152
|
-
spectral.coherence(
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
162
|
+
spectral.coherence(
|
|
163
|
+
first,
|
|
164
|
+
second,
|
|
165
|
+
segmentlength=seglen,
|
|
166
|
+
downsample=False,
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
# but that accepting downsampling gives you the same result as
|
|
170
|
+
# doing nothing (but doesn't emit a warning)
|
|
171
|
+
with warnings.catch_warnings():
|
|
172
|
+
warnings.simplefilter("error", DeprecationWarning)
|
|
173
|
+
coh2 = spectral.coherence(
|
|
174
|
+
first,
|
|
175
|
+
second,
|
|
176
|
+
segmentlength=seglen,
|
|
177
|
+
downsample=True,
|
|
178
|
+
)
|
|
158
179
|
|
|
159
180
|
assert all(np.array(coh1.data) == np.array(coh2.data))
|
|
@@ -50,7 +50,7 @@ LOWPASS_IIR_100HZ = signal.iirdesign(
|
|
|
50
50
|
analog=False, ftype='cheby1', output='zpk',
|
|
51
51
|
)
|
|
52
52
|
LOWPASS_FIR_100HZ = signal.firwin(
|
|
53
|
-
30, 100, window='hamming', width=50.,
|
|
53
|
+
30, 100, window='hamming', width=50., fs=1024.,
|
|
54
54
|
)
|
|
55
55
|
|
|
56
56
|
HIGHPASS_IIR_100HZ = signal.iirdesign(
|
|
@@ -60,7 +60,7 @@ HIGHPASS_IIR_100HZ = signal.iirdesign(
|
|
|
60
60
|
analog=False, ftype='cheby1', output='zpk',
|
|
61
61
|
)
|
|
62
62
|
HIGHPASS_FIR_100HZ = signal.firwin(
|
|
63
|
-
45, 100, window='hamming', pass_zero=False, width=-100/3.,
|
|
63
|
+
45, 100, window='hamming', pass_zero=False, width=-100/3., fs=1024.,
|
|
64
64
|
)
|
|
65
65
|
|
|
66
66
|
BANDPASS_IIR_100HZ_200HZ = signal.iirdesign(
|
|
@@ -70,7 +70,7 @@ BANDPASS_IIR_100HZ_200HZ = signal.iirdesign(
|
|
|
70
70
|
analog=False, ftype='cheby1', output='zpk',
|
|
71
71
|
)
|
|
72
72
|
BANDPASS_FIR_100HZ_200HZ = signal.firwin(
|
|
73
|
-
45, (100, 200.), window='hamming', pass_zero=False,
|
|
73
|
+
45, (100, 200.), window='hamming', pass_zero=False, fs=1024.,
|
|
74
74
|
)
|
|
75
75
|
|
|
76
76
|
|
|
@@ -175,11 +175,11 @@ class TestSpectrogram(_TestArray2D):
|
|
|
175
175
|
|
|
176
176
|
# test simple filter
|
|
177
177
|
a2 = array.filter(*zpk)
|
|
178
|
-
utils.
|
|
178
|
+
utils.assert_quantity_sub_equal(array * fresp, a2)
|
|
179
179
|
|
|
180
180
|
# test inplace filtering
|
|
181
181
|
array.filter(lti, inplace=True)
|
|
182
|
-
utils.
|
|
182
|
+
utils.assert_quantity_sub_equal(array, a2)
|
|
183
183
|
|
|
184
184
|
# test errors
|
|
185
185
|
with pytest.raises(TypeError):
|
gwpy/table/io/ligolw.py
CHANGED
|
@@ -70,7 +70,7 @@ def test_to_astropy_table_empty():
|
|
|
70
70
|
tab = EventTable(llwtable, columns=["peak", "ifo"])
|
|
71
71
|
assert set(tab.colnames) == {"peak", "ifo"}
|
|
72
72
|
assert tab['peak'].dtype.type is numpy.object_
|
|
73
|
-
assert tab['ifo'].dtype.type is numpy.
|
|
73
|
+
assert tab['ifo'].dtype.type is numpy.str_
|
|
74
74
|
|
|
75
75
|
|
|
76
76
|
@pytest.mark.requires("ligo.lw.lsctables")
|
gwpy/testing/errors.py
CHANGED
gwpy/testing/fixtures.py
CHANGED
|
@@ -52,25 +52,8 @@ def tmpfile():
|
|
|
52
52
|
|
|
53
53
|
# -- plotting -----------------------------------------------------------------
|
|
54
54
|
|
|
55
|
-
def _test_usetex():
|
|
56
|
-
"""Return `True` if we can render figures using `text.usetex`.
|
|
57
|
-
"""
|
|
58
|
-
from matplotlib import pyplot
|
|
59
|
-
with rc_context(rc={'text.usetex': True}):
|
|
60
|
-
fig = pyplot.figure()
|
|
61
|
-
fig.gca()
|
|
62
|
-
try:
|
|
63
|
-
fig.canvas.draw()
|
|
64
|
-
except RuntimeError:
|
|
65
|
-
return False
|
|
66
|
-
else:
|
|
67
|
-
return True
|
|
68
|
-
finally:
|
|
69
|
-
pyplot.close(fig)
|
|
70
|
-
|
|
71
|
-
|
|
72
55
|
SKIP_TEX = pytest.mark.skipif(
|
|
73
|
-
not has_tex()
|
|
56
|
+
not has_tex(),
|
|
74
57
|
reason='TeX is not available',
|
|
75
58
|
)
|
|
76
59
|
|
gwpy/testing/utils.py
CHANGED
|
@@ -34,12 +34,14 @@ from numpy.testing import (assert_array_equal, assert_allclose)
|
|
|
34
34
|
|
|
35
35
|
from astropy.time import Time
|
|
36
36
|
|
|
37
|
-
from
|
|
37
|
+
from gwpy.io.cache import file_segment
|
|
38
|
+
from gwpy.utils.decorators import deprecated_function
|
|
38
39
|
|
|
39
40
|
# -- useful constants ---------------------------------------------------------
|
|
40
41
|
|
|
41
42
|
TEST_DATA_DIR = os.path.join(os.path.dirname(__file__), 'data')
|
|
42
43
|
TEST_GWF_FILE = os.path.join(TEST_DATA_DIR, 'HLV-HW100916-968654552-1.gwf')
|
|
44
|
+
TEST_GWF_SPAN = file_segment(TEST_GWF_FILE)
|
|
43
45
|
TEST_HDF5_FILE = os.path.join(TEST_DATA_DIR, 'HLV-HW100916-968654552-1.hdf')
|
|
44
46
|
|
|
45
47
|
|
|
@@ -328,11 +330,18 @@ def TemporaryFilename(*args, **kwargs): # pylint: disable=invalid-name
|
|
|
328
330
|
os.remove(name)
|
|
329
331
|
|
|
330
332
|
|
|
331
|
-
def test_read_write(
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
333
|
+
def test_read_write(
|
|
334
|
+
data,
|
|
335
|
+
format,
|
|
336
|
+
extension=None,
|
|
337
|
+
autoidentify=True,
|
|
338
|
+
read_args=[],
|
|
339
|
+
read_kw={},
|
|
340
|
+
write_args=[],
|
|
341
|
+
write_kw={},
|
|
342
|
+
assert_equal=assert_quantity_sub_equal,
|
|
343
|
+
assert_kw={},
|
|
344
|
+
):
|
|
336
345
|
"""Test that data can be written to and read from a file in some format
|
|
337
346
|
|
|
338
347
|
Parameters
|
gwpy/timeseries/core.py
CHANGED
|
@@ -793,7 +793,6 @@ class TimeSeriesBase(Series):
|
|
|
793
793
|
op_ = ufunc.__name__
|
|
794
794
|
out = out.view(StateTimeSeries)
|
|
795
795
|
out.__metadata_finalize__(orig)
|
|
796
|
-
out.override_unit('')
|
|
797
796
|
oname = orig.name if isinstance(orig, type(self)) else orig
|
|
798
797
|
vname = value.name if isinstance(value, type(self)) else value
|
|
799
798
|
out.name = '{0!s} {1!s} {2!s}'.format(oname, op_, vname)
|