pywavelet 0.1.0__tar.gz → 0.1.2__tar.gz
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.
- {pywavelet-0.1.0 → pywavelet-0.1.2}/CHANGELOG.rst +44 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/PKG-INFO +1 -1
- {pywavelet-0.1.0 → pywavelet-0.1.2}/src/pywavelet/_version.py +2 -2
- {pywavelet-0.1.0 → pywavelet-0.1.2}/src/pywavelet/logger.py +6 -2
- {pywavelet-0.1.0 → pywavelet-0.1.2}/src/pywavelet/transforms/__init__.py +1 -2
- pywavelet-0.1.2/src/pywavelet/transforms/forward/__init__.py +3 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/src/pywavelet/transforms/forward/from_freq.py +13 -4
- {pywavelet-0.1.0 → pywavelet-0.1.2}/src/pywavelet/transforms/forward/from_time.py +13 -1
- {pywavelet-0.1.0 → pywavelet-0.1.2}/src/pywavelet/transforms/forward/main.py +7 -15
- {pywavelet-0.1.0 → pywavelet-0.1.2}/src/pywavelet/transforms/inverse/main.py +3 -4
- {pywavelet-0.1.0 → pywavelet-0.1.2}/src/pywavelet/transforms/inverse/to_freq.py +11 -3
- {pywavelet-0.1.0 → pywavelet-0.1.2}/src/pywavelet/transforms/inverse/to_time.py +13 -3
- {pywavelet-0.1.0/src/pywavelet/transforms → pywavelet-0.1.2/src/pywavelet}/types/__init__.py +1 -2
- {pywavelet-0.1.0/src/pywavelet/transforms → pywavelet-0.1.2/src/pywavelet}/types/common.py +7 -7
- {pywavelet-0.1.0/src/pywavelet/transforms → pywavelet-0.1.2/src/pywavelet}/types/frequencyseries.py +31 -23
- {pywavelet-0.1.0/src/pywavelet/transforms → pywavelet-0.1.2/src/pywavelet}/types/plotting.py +47 -26
- {pywavelet-0.1.0/src/pywavelet/transforms → pywavelet-0.1.2/src/pywavelet}/types/timeseries.py +58 -38
- {pywavelet-0.1.0/src/pywavelet/transforms → pywavelet-0.1.2/src/pywavelet}/types/wavelet.py +113 -31
- {pywavelet-0.1.0/src/pywavelet/transforms/forward → pywavelet-0.1.2/src/pywavelet/types}/wavelet_bins.py +5 -6
- {pywavelet-0.1.0 → pywavelet-0.1.2}/src/pywavelet/utils.py +1 -1
- {pywavelet-0.1.0 → pywavelet-0.1.2}/src/pywavelet.egg-info/PKG-INFO +1 -1
- {pywavelet-0.1.0 → pywavelet-0.1.2}/src/pywavelet.egg-info/SOURCES.txt +7 -8
- {pywavelet-0.1.0 → pywavelet-0.1.2}/tests/conftest.py +2 -2
- {pywavelet-0.1.0 → pywavelet-0.1.2}/tests/test_lnl.py +2 -16
- {pywavelet-0.1.0 → pywavelet-0.1.2}/tests/test_mask.py +2 -16
- {pywavelet-0.1.0 → pywavelet-0.1.2}/tests/test_roundtrip_conversion.py +47 -22
- {pywavelet-0.1.0 → pywavelet-0.1.2}/tests/test_snr.py +3 -6
- {pywavelet-0.1.0 → pywavelet-0.1.2}/tests/test_timefreq_type.py +15 -12
- {pywavelet-0.1.0 → pywavelet-0.1.2}/tests/test_wavelet_plot.py +9 -2
- {pywavelet-0.1.0 → pywavelet-0.1.2}/tests/utils/__init__.py +1 -1
- {pywavelet-0.1.0 → pywavelet-0.1.2}/tests/utils/generate_data.py +9 -12
- {pywavelet-0.1.0 → pywavelet-0.1.2}/tests/utils/plotting.py +70 -23
- pywavelet-0.1.0/src/pywavelet/transforms/forward/__init__.py +0 -4
- pywavelet-0.1.0/src/pywavelet/transforms/types/wavelet_mask.py +0 -34
- {pywavelet-0.1.0 → pywavelet-0.1.2}/.github/workflows/ci.yml +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/.github/workflows/docs.yml +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/.github/workflows/pypi.yml +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/.gitignore +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/.pre-commit-config.yaml +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/CITATION.cff +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/README.rst +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/docs/_config.yml +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/docs/_static/demo.gif +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/docs/_toc.yml +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/docs/api.rst +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/docs/example.ipynb +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/docs/index.rst +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/docs/logo.png +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/docs/roundtrip_freq.png +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/docs/roundtrip_time.png +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/pyproject.toml +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/setup.cfg +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/src/pywavelet/__init__.py +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/src/pywavelet/transforms/inverse/__init__.py +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/src/pywavelet/transforms/phi_computer.py +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/src/pywavelet.egg-info/dependency_links.txt +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/src/pywavelet.egg-info/requires.txt +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/src/pywavelet.egg-info/top_level.txt +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/tests/test_data/roundtrip_chirp_freq.npz +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/tests/test_data/roundtrip_chirp_time.npz +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/tests/test_data/roundtrip_pure_f0_freq.npz +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/tests/test_data/roundtrip_sine_freq.npz +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/tests/test_data/roundtrip_sine_time.npz +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/tests/test_phi.py +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/tests/test_psd.py +0 -0
- {pywavelet-0.1.0 → pywavelet-0.1.2}/tests/test_version.py +0 -0
@@ -5,16 +5,60 @@ CHANGELOG
|
|
5
5
|
=========
|
6
6
|
|
7
7
|
|
8
|
+
.. _changelog-v0.1.2:
|
9
|
+
|
10
|
+
v0.1.2 (2025-01-20)
|
11
|
+
===================
|
12
|
+
|
13
|
+
Bug Fixes
|
14
|
+
---------
|
15
|
+
|
16
|
+
* fix: adjust the WaveletMask repr (`50c6201`_)
|
17
|
+
|
18
|
+
.. _50c6201: https://github.com/pywavelet/pywavelet/commit/50c6201efb7689dd9757a5e4c6047d241015cb96
|
19
|
+
|
20
|
+
|
21
|
+
.. _changelog-v0.1.1:
|
22
|
+
|
23
|
+
v0.1.1 (2025-01-16)
|
24
|
+
===================
|
25
|
+
|
26
|
+
Chores
|
27
|
+
------
|
28
|
+
|
29
|
+
* chore(release): 0.1.1 (`bd15453`_)
|
30
|
+
|
31
|
+
Unknown
|
32
|
+
-------
|
33
|
+
|
34
|
+
* Merge branch 'main' of github.com:avivajpeyi/pywavelet into main (`69eefa2`_)
|
35
|
+
|
36
|
+
.. _bd15453: https://github.com/pywavelet/pywavelet/commit/bd15453e028705548232b802b2d21bbebd307ca7
|
37
|
+
.. _69eefa2: https://github.com/pywavelet/pywavelet/commit/69eefa29b7873c30fcb74ad1e051eb20101a277a
|
38
|
+
|
39
|
+
|
8
40
|
.. _changelog-v0.1.0:
|
9
41
|
|
10
42
|
v0.1.0 (2025-01-15)
|
11
43
|
===================
|
12
44
|
|
45
|
+
Bug Fixes
|
46
|
+
---------
|
47
|
+
|
48
|
+
* fix: refactor type outside transforms (`efb8878`_)
|
49
|
+
|
50
|
+
Chores
|
51
|
+
------
|
52
|
+
|
53
|
+
* chore(release): 0.1.0 (`c5a3fde`_)
|
54
|
+
|
13
55
|
Features
|
14
56
|
--------
|
15
57
|
|
16
58
|
* feat: add wavelet mask and more tests (`e009903`_)
|
17
59
|
|
60
|
+
.. _efb8878: https://github.com/pywavelet/pywavelet/commit/efb88789f8468ff18f99abaf6168bb8fc0f5947b
|
61
|
+
.. _c5a3fde: https://github.com/pywavelet/pywavelet/commit/c5a3fdea455c16478f04049f14bc35dfcf4efb15
|
18
62
|
.. _e009903: https://github.com/pywavelet/pywavelet/commit/e00990300d9c013438580c2bc47ea93570fd95be
|
19
63
|
|
20
64
|
|
@@ -1,11 +1,15 @@
|
|
1
|
+
import logging
|
1
2
|
import sys
|
2
3
|
import warnings
|
4
|
+
|
3
5
|
from rich.logging import RichHandler
|
4
|
-
import logging
|
5
6
|
|
6
7
|
FORMAT = "%(message)s"
|
7
8
|
logging.basicConfig(
|
8
|
-
level="INFO",
|
9
|
+
level="INFO",
|
10
|
+
format=FORMAT,
|
11
|
+
datefmt="[%X]",
|
12
|
+
handlers=[RichHandler(rich_tracebacks=True)],
|
9
13
|
)
|
10
14
|
|
11
15
|
logger = logging.getLogger("pywavelet")
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from .forward import from_freq_to_wavelet, from_time_to_wavelet
|
1
|
+
from .forward import from_freq_to_wavelet, from_time_to_wavelet
|
2
2
|
from .inverse import from_wavelet_to_freq, from_wavelet_to_time
|
3
3
|
|
4
4
|
__all__ = [
|
@@ -6,5 +6,4 @@ __all__ = [
|
|
6
6
|
"from_wavelet_to_freq",
|
7
7
|
"from_time_to_wavelet",
|
8
8
|
"from_freq_to_wavelet",
|
9
|
-
"compute_bins",
|
10
9
|
]
|
@@ -1,8 +1,10 @@
|
|
1
1
|
"""helper functions for transform_freq"""
|
2
|
+
|
2
3
|
import numpy as np
|
3
4
|
from numba import njit
|
4
5
|
from numpy import fft
|
5
6
|
|
7
|
+
|
6
8
|
def transform_wavelet_freq_helper(
|
7
9
|
data: np.ndarray, Nf: int, Nt: int, phif: np.ndarray
|
8
10
|
) -> np.ndarray:
|
@@ -13,8 +15,16 @@ def transform_wavelet_freq_helper(
|
|
13
15
|
__core(Nf, Nt, DX, freq_strain, phif, wave)
|
14
16
|
return wave
|
15
17
|
|
18
|
+
|
16
19
|
# @njit()
|
17
|
-
def __core(
|
20
|
+
def __core(
|
21
|
+
Nf: int,
|
22
|
+
Nt: int,
|
23
|
+
DX: np.ndarray,
|
24
|
+
freq_strain: np.ndarray,
|
25
|
+
phif: np.ndarray,
|
26
|
+
wave: np.ndarray,
|
27
|
+
):
|
18
28
|
for f_bin in range(0, Nf + 1):
|
19
29
|
__fill_wave_1(f_bin, Nt, Nf, DX, freq_strain, phif)
|
20
30
|
# Numba doesn't support np.ifft so we cant jit this
|
@@ -22,8 +32,6 @@ def __core(Nf:int, Nt:int, DX:np.ndarray, freq_strain:np.ndarray, phif:np.ndarra
|
|
22
32
|
__fill_wave_2(f_bin, DX_trans, wave, Nt, Nf)
|
23
33
|
|
24
34
|
|
25
|
-
|
26
|
-
|
27
35
|
@njit()
|
28
36
|
def __fill_wave_1(
|
29
37
|
f_bin: int,
|
@@ -55,6 +63,7 @@ def __fill_wave_1(
|
|
55
63
|
else:
|
56
64
|
DX[i] = phif[j] * data[jj]
|
57
65
|
|
66
|
+
|
58
67
|
@njit()
|
59
68
|
def __fill_wave_2(
|
60
69
|
f_bin: int, DX_trans: np.ndarray, wave: np.ndarray, Nt: int, Nf: int
|
@@ -72,7 +81,7 @@ def __fill_wave_2(
|
|
72
81
|
if (n + f_bin) % 2:
|
73
82
|
wave[n, f_bin] = -DX_trans[n].imag
|
74
83
|
else:
|
75
|
-
wave[n, f_bin] =
|
84
|
+
wave[n, f_bin] = DX_trans[n].real
|
76
85
|
else:
|
77
86
|
if (n + f_bin) % 2:
|
78
87
|
wave[n, f_bin] = DX_trans[n].imag
|
@@ -1,4 +1,5 @@
|
|
1
1
|
"""helper functions for transform_time.py"""
|
2
|
+
|
2
3
|
import numpy as np
|
3
4
|
from numba import njit
|
4
5
|
from numpy import fft
|
@@ -20,7 +21,18 @@ def transform_wavelet_time_helper(
|
|
20
21
|
__core(Nf, Nt, K, ND, wdata, data_pad, phi, wave, mult)
|
21
22
|
return wave
|
22
23
|
|
23
|
-
|
24
|
+
|
25
|
+
def __core(
|
26
|
+
Nf: int,
|
27
|
+
Nt: int,
|
28
|
+
K: int,
|
29
|
+
ND: int,
|
30
|
+
wdata: np.ndarray,
|
31
|
+
data_pad: np.ndarray,
|
32
|
+
phi: np.ndarray,
|
33
|
+
wave: np.ndarray,
|
34
|
+
mult: int,
|
35
|
+
) -> None:
|
24
36
|
for time_bin_i in range(0, Nt):
|
25
37
|
__fill_wave_1(time_bin_i, K, ND, Nf, wdata, data_pad, phi)
|
26
38
|
wdata_trans = np.fft.rfft(wdata, K)
|
@@ -3,15 +3,15 @@ from typing import Union
|
|
3
3
|
import numpy as np
|
4
4
|
|
5
5
|
from ...logger import logger
|
6
|
+
from ...types import FrequencySeries, TimeSeries, Wavelet
|
7
|
+
from ...types.wavelet_bins import _get_bins, _preprocess_bins
|
6
8
|
from ..phi_computer import phi_vec, phitilde_vec_norm
|
7
|
-
from ..types import FrequencySeries, TimeSeries, Wavelet
|
8
9
|
from .from_freq import transform_wavelet_freq_helper
|
9
10
|
from .from_time import transform_wavelet_time_helper
|
10
|
-
from .wavelet_bins import _get_bins, _preprocess_bins
|
11
|
-
|
12
11
|
|
13
12
|
__all__ = ["from_time_to_wavelet", "from_freq_to_wavelet"]
|
14
13
|
|
14
|
+
|
15
15
|
def from_time_to_wavelet(
|
16
16
|
timeseries: TimeSeries,
|
17
17
|
Nf: Union[int, None] = None,
|
@@ -74,9 +74,7 @@ def from_time_to_wavelet(
|
|
74
74
|
mult = min(mult, Nt // 2) # Ensure mult is not larger than ND/2
|
75
75
|
phi = phi_vec(Nf, dt=dt, d=nx, q=mult)
|
76
76
|
wave = transform_wavelet_time_helper(timeseries.data, Nf, Nt, phi, mult).T
|
77
|
-
return Wavelet(
|
78
|
-
wave * np.sqrt(2), time=t_bins, freq=f_bins
|
79
|
-
)
|
77
|
+
return Wavelet(wave * np.sqrt(2), time=t_bins, freq=f_bins)
|
80
78
|
|
81
79
|
|
82
80
|
def from_freq_to_wavelet(
|
@@ -117,12 +115,6 @@ def from_freq_to_wavelet(
|
|
117
115
|
t_bins, f_bins = _get_bins(freqseries, Nf, Nt)
|
118
116
|
dt = freqseries.dt
|
119
117
|
phif = phitilde_vec_norm(Nf, Nt, dt=dt, d=nx)
|
120
|
-
wave = transform_wavelet_freq_helper(
|
121
|
-
|
122
|
-
)
|
123
|
-
|
124
|
-
return Wavelet(
|
125
|
-
(2 / Nf) * wave.T * np.sqrt(2),
|
126
|
-
time=t_bins,
|
127
|
-
freq=f_bins
|
128
|
-
)
|
118
|
+
wave = transform_wavelet_freq_helper(freqseries.data, Nf, Nt, phif)
|
119
|
+
|
120
|
+
return Wavelet((2 / Nf) * wave.T * np.sqrt(2), time=t_bins, freq=f_bins)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import numpy as np
|
2
2
|
|
3
3
|
from ...transforms.phi_computer import phi_vec, phitilde_vec_norm
|
4
|
-
from
|
4
|
+
from ...types import FrequencySeries, TimeSeries, Wavelet
|
5
5
|
from .to_freq import inverse_wavelet_freq_helper_fast
|
6
6
|
from .to_time import inverse_wavelet_time_helper_fast
|
7
7
|
|
@@ -9,6 +9,7 @@ __all__ = ["from_wavelet_to_time", "from_wavelet_to_freq"]
|
|
9
9
|
|
10
10
|
INV_ROOT2 = 1.0 / np.sqrt(2)
|
11
11
|
|
12
|
+
|
12
13
|
def from_wavelet_to_time(
|
13
14
|
wave_in: Wavelet,
|
14
15
|
dt: float,
|
@@ -55,9 +56,7 @@ def from_wavelet_to_time(
|
|
55
56
|
|
56
57
|
|
57
58
|
def from_wavelet_to_freq(
|
58
|
-
wave_in: Wavelet,
|
59
|
-
dt: float,
|
60
|
-
nx:float=4.0
|
59
|
+
wave_in: Wavelet, dt: float, nx: float = 4.0
|
61
60
|
) -> FrequencySeries:
|
62
61
|
"""
|
63
62
|
Perform an inverse wavelet transform to the frequency domain.
|
@@ -1,4 +1,5 @@
|
|
1
1
|
"""functions for computing the inverse wavelet transforms"""
|
2
|
+
|
2
3
|
import numpy as np
|
3
4
|
from numba import njit
|
4
5
|
from numpy import fft
|
@@ -12,13 +13,20 @@ def inverse_wavelet_freq_helper_fast(
|
|
12
13
|
ND = Nf * Nt
|
13
14
|
|
14
15
|
prefactor2s = np.zeros(Nt, np.complex128)
|
15
|
-
res = np.zeros(ND//2 +1, dtype=np.complex128)
|
16
|
+
res = np.zeros(ND // 2 + 1, dtype=np.complex128)
|
16
17
|
__core(Nf, Nt, prefactor2s, wave_in, phif, res)
|
17
18
|
|
18
|
-
|
19
19
|
return res
|
20
20
|
|
21
|
-
|
21
|
+
|
22
|
+
def __core(
|
23
|
+
Nf: int,
|
24
|
+
Nt: int,
|
25
|
+
prefactor2s: np.ndarray,
|
26
|
+
wave_in: np.ndarray,
|
27
|
+
phif: np.ndarray,
|
28
|
+
res: np.ndarray,
|
29
|
+
) -> None:
|
22
30
|
for m in range(0, Nf + 1):
|
23
31
|
__pack_wave_inverse(m, Nt, Nf, prefactor2s, wave_in)
|
24
32
|
fft_prefactor2s = np.fft.fft(prefactor2s)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
"""functions for computing the inverse wavelet transforms"""
|
2
|
+
|
2
3
|
import numpy as np
|
3
4
|
from numba import njit
|
4
5
|
from numpy import fft
|
@@ -21,7 +22,16 @@ def inverse_wavelet_time_helper_fast(
|
|
21
22
|
return res[:ND]
|
22
23
|
|
23
24
|
|
24
|
-
def __core(
|
25
|
+
def __core(
|
26
|
+
Nf: int,
|
27
|
+
Nt: int,
|
28
|
+
K: int,
|
29
|
+
ND: int,
|
30
|
+
wave_in: np.ndarray,
|
31
|
+
phi: np.ndarray,
|
32
|
+
res: np.ndarray,
|
33
|
+
afins: np.ndarray,
|
34
|
+
) -> None:
|
25
35
|
for n in range(0, Nt):
|
26
36
|
if n % 2 == 0:
|
27
37
|
pack_wave_time_helper_compact(n, Nf, Nt, wave_in, afins)
|
@@ -29,9 +39,9 @@ def __core(Nf: int, Nt: int, K: int, ND: int, wave_in: np.ndarray, phi: np.ndarr
|
|
29
39
|
unpack_time_wave_helper_compact(n, Nf, Nt, K, phi, ffts_fin, res)
|
30
40
|
|
31
41
|
# wrap boundary conditions
|
32
|
-
res[: min(K + Nf, ND)] += res[ND: min(ND + K + Nf, 2 * ND)]
|
42
|
+
res[: min(K + Nf, ND)] += res[ND : min(ND + K + Nf, 2 * ND)]
|
33
43
|
if K + Nf > ND:
|
34
|
-
res[: K + Nf - ND] += res[2 * ND: ND + K * Nf]
|
44
|
+
res[: K + Nf - ND] += res[2 * ND : ND + K * Nf]
|
35
45
|
|
36
46
|
|
37
47
|
def unpack_time_wave_helper(
|
@@ -1,9 +1,9 @@
|
|
1
|
-
from typing import
|
1
|
+
from typing import Tuple, Union
|
2
2
|
|
3
3
|
import numpy as xp
|
4
|
-
from numpy.fft import
|
4
|
+
from numpy.fft import fft, irfft, rfft, rfftfreq # type: ignore
|
5
5
|
|
6
|
-
from
|
6
|
+
from ..logger import logger
|
7
7
|
|
8
8
|
|
9
9
|
def _len_check(d):
|
@@ -19,7 +19,7 @@ def is_documented_by(original):
|
|
19
19
|
return wrapper
|
20
20
|
|
21
21
|
|
22
|
-
def fmt_time(seconds: float, units=False) -> Tuple[str, str]:
|
22
|
+
def fmt_time(seconds: float, units=False) -> Union[str, Tuple[str, str]]:
|
23
23
|
"""Returns formatted time and units [ms, s, min, hr, day]"""
|
24
24
|
t, u = "", ""
|
25
25
|
if seconds < 1e-3:
|
@@ -42,12 +42,12 @@ def fmt_time(seconds: float, units=False) -> Tuple[str, str]:
|
|
42
42
|
|
43
43
|
def fmt_timerange(trange):
|
44
44
|
t0 = fmt_time(trange[0])
|
45
|
-
tend, units = fmt_time(trange[1], units
|
45
|
+
tend, units = fmt_time(trange[1], units=True)
|
46
46
|
return f"[{t0}, {tend}] {units}"
|
47
47
|
|
48
48
|
|
49
|
-
def fmt_pow2(n:float)->str:
|
49
|
+
def fmt_pow2(n: float) -> str:
|
50
50
|
pow2 = xp.log2(n)
|
51
51
|
if pow2.is_integer():
|
52
52
|
return f"2^{int(pow2)}"
|
53
|
-
return f"{n:,}"
|
53
|
+
return f"{n:,}"
|
{pywavelet-0.1.0/src/pywavelet/transforms → pywavelet-0.1.2/src/pywavelet}/types/frequencyseries.py
RENAMED
@@ -1,11 +1,13 @@
|
|
1
|
+
from typing import Optional, Tuple, Union
|
2
|
+
|
1
3
|
import matplotlib.pyplot as plt
|
2
|
-
from typing import Tuple, Union, Optional
|
3
4
|
|
4
|
-
from .common import
|
5
|
+
from .common import fmt_pow2, fmt_time, irfft, is_documented_by, xp
|
5
6
|
from .plotting import plot_freqseries, plot_periodogram
|
6
7
|
|
7
8
|
__all__ = ["FrequencySeries"]
|
8
9
|
|
10
|
+
|
9
11
|
class FrequencySeries:
|
10
12
|
"""
|
11
13
|
A class to represent a one-sided frequency series, with various methods for
|
@@ -39,9 +41,13 @@ class FrequencySeries:
|
|
39
41
|
If any frequency is negative or if `data` and `freq` do not have the same length.
|
40
42
|
"""
|
41
43
|
if xp.any(freq < 0):
|
42
|
-
raise ValueError(
|
44
|
+
raise ValueError(
|
45
|
+
"FrequencySeries must be one-sided (only non-negative frequencies)"
|
46
|
+
)
|
43
47
|
if len(data) != len(freq):
|
44
|
-
raise ValueError(
|
48
|
+
raise ValueError(
|
49
|
+
f"data and freq must have the same length ({len(data)} != {len(freq)})"
|
50
|
+
)
|
45
51
|
self.data = data
|
46
52
|
self.freq = freq
|
47
53
|
self.t0 = t0
|
@@ -53,10 +59,10 @@ class FrequencySeries:
|
|
53
59
|
)
|
54
60
|
|
55
61
|
@is_documented_by(plot_periodogram)
|
56
|
-
def plot_periodogram(
|
57
|
-
|
58
|
-
|
59
|
-
)
|
62
|
+
def plot_periodogram(
|
63
|
+
self, ax=None, **kwargs
|
64
|
+
) -> Tuple[plt.Figure, plt.Axes]:
|
65
|
+
return plot_periodogram(self.data, self.freq, self.fs, ax=ax, **kwargs)
|
60
66
|
|
61
67
|
def __len__(self):
|
62
68
|
"""Return the length of the frequency series."""
|
@@ -127,7 +133,9 @@ class FrequencySeries:
|
|
127
133
|
n = fmt_pow2(len(self))
|
128
134
|
return f"FrequencySeries(n={n}, frange=[{self.range[0]:.2f}, {self.range[1]:.2f}] Hz, T={dur}, fs={self.fs:.2f} Hz)"
|
129
135
|
|
130
|
-
def noise_weighted_inner_product(
|
136
|
+
def noise_weighted_inner_product(
|
137
|
+
self, other: "FrequencySeries", psd: "FrequencySeries"
|
138
|
+
) -> float:
|
131
139
|
"""
|
132
140
|
Compute the noise-weighted inner product of two FrequencySeries.
|
133
141
|
|
@@ -144,9 +152,11 @@ class FrequencySeries:
|
|
144
152
|
The noise-weighted inner product of the two FrequencySeries.
|
145
153
|
"""
|
146
154
|
integrand = xp.real(xp.conj(self.data) * other.data / psd.data)
|
147
|
-
return (4 * self.dt/self.ND) * xp.nansum(integrand)
|
155
|
+
return (4 * self.dt / self.ND) * xp.nansum(integrand)
|
148
156
|
|
149
|
-
def matched_filter_snr(
|
157
|
+
def matched_filter_snr(
|
158
|
+
self, other: "FrequencySeries", psd: "FrequencySeries"
|
159
|
+
) -> float:
|
150
160
|
"""
|
151
161
|
Compute the signal-to-noise ratio (SNR) of a matched filter.
|
152
162
|
|
@@ -199,15 +209,15 @@ class FrequencySeries:
|
|
199
209
|
|
200
210
|
# Create and return a TimeSeries object
|
201
211
|
from .timeseries import TimeSeries
|
202
|
-
return TimeSeries(time_data, time)
|
203
212
|
|
213
|
+
return TimeSeries(time_data, time)
|
204
214
|
|
205
215
|
def to_wavelet(
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
216
|
+
self,
|
217
|
+
Nf: Union[int, None] = None,
|
218
|
+
Nt: Union[int, None] = None,
|
219
|
+
nx: Optional[float] = 4.0,
|
220
|
+
) -> "Wavelet":
|
211
221
|
"""
|
212
222
|
Convert the frequency series to a wavelet using inverse Fourier transform.
|
213
223
|
|
@@ -216,9 +226,9 @@ class FrequencySeries:
|
|
216
226
|
Wavelet
|
217
227
|
The corresponding wavelet.
|
218
228
|
"""
|
219
|
-
from ..forward import from_freq_to_wavelet
|
220
|
-
return from_freq_to_wavelet(self, Nf=Nf, Nt=Nt, nx=nx)
|
229
|
+
from ..transforms.forward import from_freq_to_wavelet
|
221
230
|
|
231
|
+
return from_freq_to_wavelet(self, Nf=Nf, Nt=Nt, nx=nx)
|
222
232
|
|
223
233
|
def __eq__(self, other):
|
224
234
|
"""Check if two FrequencySeries objects are equal."""
|
@@ -228,10 +238,8 @@ class FrequencySeries:
|
|
228
238
|
|
229
239
|
def __copy__(self):
|
230
240
|
return FrequencySeries(
|
231
|
-
xp.copy(self.data),
|
232
|
-
xp.copy(self.freq),
|
233
|
-
t0=self.t0
|
241
|
+
xp.copy(self.data), xp.copy(self.freq), t0=self.t0
|
234
242
|
)
|
235
243
|
|
236
244
|
def copy(self):
|
237
|
-
return self.__copy__()
|
245
|
+
return self.__copy__()
|