Skip to content

Commit

Permalink
Merge pull request #26 from xdas-dev/dev
Browse files Browse the repository at this point in the history
Version 0.2.1
  • Loading branch information
atrabattoni authored Dec 3, 2024
2 parents 3a3f6c7 + f24278d commit 3ef0714
Show file tree
Hide file tree
Showing 22 changed files with 629 additions and 73 deletions.
2 changes: 2 additions & 0 deletions docs/api/fft.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@
:toctree: ../_autosummary
fft
ifft
rfft
irfft
```
11 changes: 10 additions & 1 deletion docs/api/signal.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,13 @@
sosfilt
sosfiltfilt
medfilt
```
```

## Spectral analysisi

```{eval-rst}
.. autosummary::
:toctree: ../_autosummary
stft
```
7 changes: 3 additions & 4 deletions docs/cite.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

If you use *Xdas* for your research, please consider citing the following reference:

> Trabattoni A., van den Ende M., Baillet M., Rivet D., Strumia C., Stutzmann E.,
> Biagioli F. (2024): *Xdas: a Python Framework for Distributed Acoustic Sensing*,
> in prep.
> Trabattoni, A., Baillet, M., Ende, M. van den, Rivet, D., Stutzman, E., Strumia,
> C., & Biagioli, F. (2024). *Xdas: A Python Framework for Distributed Acoustic
> Sensing.* [https://doi.org/10.31223/X5141G](https://doi.org/10.31223/X5141G)
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
author = "Alister Trabattoni"

# The full version, including alpha/beta/rc tags
release = "0.2"
release = "0.2.1"


# -- General configuration ---------------------------------------------------
Expand Down
13 changes: 11 additions & 2 deletions docs/release-notes.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
# Release notes

## 0.2.1
- Add `xdas.signal.stft`.
- Add inverse Fourier transforms `xdas.fft.ifft` and `xdas.fft.irfft`.
- Add support for APSensing format.
- Improve overlap error message.
- Fix decimation of freshly opened multi-file datasets.
- Fix `zerophase` keyword argument for `xdas.signal.filter`.
- Fix applying fft functions in presence of non-dimensional coordinates.

## 0.2

- Add Dask virtualization backend for non-HDF5 formats (@atrabattoni).
- Add support for miniSEED format (@atrabattoni, @chauvetige).
- Add support for Silixa (TDMS) format (@atrabattoni, @Stutzmann).
- Add support for miniSEED format (@atrabattoni, @chauvetige).
- Add support for Silixa (TDMS) format (@atrabattoni, @Stutzmann).

## 0.1.2

Expand Down
4 changes: 2 additions & 2 deletions docs/user-guide/atoms.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ There are three "flavours" declaring the atoms that can be used to compose a seq
```{code-cell}
import numpy as np
import xdas
import xdas.signal as xp
import xdas.signal as xs
from xdas.atoms import Partial, Sequential, IIRFilter
sequence = Sequential(
[
xp.taper(..., dim="time"),
xs.taper(..., dim="time"),
Partial(np.square),
IIRFilter(order=4, cutoff=1.5, btype="highpass", dim="time"),
]
Expand Down
8 changes: 4 additions & 4 deletions docs/user-guide/convert-displacement.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ strain_rate.plot(yincrease=False, vmin=-0.5, vmax=0.5);
Then convert strain rate to deformation and then to displacement.

```{code-cell}
import xdas.signal as xp
import xdas.signal as xs
strain = xp.integrate(strain_rate, dim="time")
deformation = xp.integrate(strain, dim="distance")
displacement = xp.sliding_mean_removal(deformation, wlen=2000.0, dim="distance")
strain = xs.integrate(strain_rate, dim="time")
deformation = xs.integrate(strain, dim="distance")
displacement = xs.sliding_mean_removal(deformation, wlen=2000.0, dim="distance")
displacement.plot(yincrease=False, vmin=-0.5, vmax=0.5);
```

Expand Down
1 change: 1 addition & 0 deletions docs/user-guide/data-formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Xdas support the following DAS formats:

| Constructor | Instrument | `engine` argument | Virtualization |
|:-----------------:|:-----------------:|:-----------------:|:-----------------:|
| AP Sensing | DAS N5* | `"apsensing"` | HDF5 |
| ASN | OptoDAS | `"asn"` | HDF5 |
| FEBUS | A1 | `"febus"` | HDF5 |
| OptaSense | OLA, ODH*, ... | `"optasense"` | HDF5 |
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "xdas"
version = "0.2"
version = "0.2.1"
requires-python = ">= 3.10"
authors = [
{ name = "Alister Trabattoni", email = "alister.trabattoni@gmail.com" },
Expand Down
10 changes: 5 additions & 5 deletions tests/test_atoms.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import xdas
import xdas as xd
import xdas.signal as xp
import xdas.signal as xs
from xdas.atoms import (
DownSample,
FIRFilter,
Expand All @@ -22,8 +22,8 @@ class TestPartialAtom:
def test_init(self):
Sequential(
[
Partial(xp.taper, dim="time"),
Partial(xp.taper, dim="distance"),
Partial(xs.taper, dim="time"),
Partial(xs.taper, dim="distance"),
Partial(np.abs),
Partial(np.square),
]
Expand Down Expand Up @@ -176,7 +176,7 @@ def test_firfilter(self):
da = wavelet_wavefronts()
chunks = xdas.split(da, 6, "time")
taps = sp.firwin(11, 0.4, pass_zero="lowpass")
expected = xp.lfilter(taps, 1.0, da, "time")
expected = xs.lfilter(taps, 1.0, da, "time")
expected["time"] -= np.timedelta64(20, "ms") * 5
atom = FIRFilter(11, 10.0, "lowpass", dim="time")
result = atom(da)
Expand All @@ -194,7 +194,7 @@ def test_resample_poly(self):
da = wavelet_wavefronts()
chunks = xdas.split(da, 6, "time")

expected = xp.resample_poly(da, 5, 2, "time")
expected = xs.resample_poly(da, 5, 2, "time")
atom = ResamplePoly(125, maxfactor=10, dim="time")
result = atom(da)
result_chunked = xdas.concatenate(
Expand Down
14 changes: 14 additions & 0 deletions tests/test_dataarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,20 @@ def test_sel(self):
result = da.sel(distance=0, method="nearest", drop=True)
assert "distance" not in result.coords

def test_better_error_when_sel_with_overlaps(self):
da = DataArray(
np.arange(80).reshape(20, 4),
{
"time": {
"tie_values": [0.0, 0.5, 0.4, 1.0],
"tie_indices": [0, 9, 10, 19],
},
"distance": [0.0, 10.0, 20.0, 30.0],
},
)
with pytest.raises(ValueError, match="overlaps were found"):
da.sel(time=slice(0.1, 0.6))

def test_isel(self):
da = wavelet_wavefronts()
result = da.isel(first=0)
Expand Down
47 changes: 47 additions & 0 deletions tests/test_fft.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import numpy as np

import xdas as xd
import xdas.fft as xfft


class TestRFFT:
def test_with_non_dimensional(self):
da = xd.synthetics.wavelet_wavefronts()
da["latitude"] = ("distance", np.arange(da.sizes["distance"]))
xfft.rfft(da)


class TestInverseTransforms:
def test_standard(self):
expected = xd.synthetics.wavelet_wavefronts()
result = xfft.ifft(
xfft.fft(expected, dim={"time": "frequency"}),
dim={"frequency": "time"},
)
assert np.allclose(np.real(result).values, expected.values)
assert np.allclose(np.imag(result).values, 0)
for name in result.coords:
if name == "time":
ref = expected["time"].values
ref = (ref - ref[0]) / np.timedelta64(1, "s")
ref += result["time"][0].values
assert np.allclose(result["time"].values, ref)
else:
assert result[name].equals(expected[name])

def test_real(self):
expected = xd.synthetics.wavelet_wavefronts()
result = xfft.irfft(
xfft.rfft(expected, dim={"time": "frequency"}),
expected.sizes["time"],
dim={"frequency": "time"},
)
assert np.allclose(result.values, expected.values)
for name in result.coords:
if name == "time":
ref = expected["time"].values
ref = (ref - ref[0]) / np.timedelta64(1, "s")
ref += result["time"][0].values
assert np.allclose(result["time"].values, ref)
else:
assert result[name].equals(expected[name])
Loading

0 comments on commit 3ef0714

Please sign in to comment.