Skip to content
16 changes: 16 additions & 0 deletions benchmarks/test_patch_benchmarks.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,22 @@ def test_wiener_filter(self, example_patch):
patch = example_patch
patch.wiener_filter(time=3, samples=True)

@pytest.mark.benchmark
def test_line_mute(self, example_patch):
"""Time 2D line mute with velocity lines."""
patch = example_patch
patch.line_mute(
time=(0, [0, 0.3]),
distance=(None, [0, 300]),
smooth=0.02,
)

@pytest.mark.benchmark
def test_slope_mute(self, example_patch):
"""Time slope mute between velocities."""
patch = example_patch
patch.slope_mute(slopes=(1000, 3000))


class TestTransformBenchmarks:
"""Benchmarks for patch transform operations."""
Expand Down
3 changes: 3 additions & 0 deletions dascore/core/patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ def T(self): # noqa: N802
apply_ufunc = dascore.utils.array.apply_ufunc
get_patch_names = get_patch_names
get_axis = dascore.proc.get_axis
full = dascore.proc.full

def get_patch_name(self, *args, **kwargs) -> str:
"""
Expand Down Expand Up @@ -438,6 +439,8 @@ def iresample(self, *args, **kwargs):
standardize = dascore.proc.standardize
taper = dascore.proc.taper
taper_range = dascore.proc.taper_range
line_mute = dascore.proc.line_mute
slope_mute = dascore.proc.slope_mute
rolling = dascore.proc.rolling
whiten = dascore.proc.whiten

Expand Down
1 change: 1 addition & 0 deletions dascore/proc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from .resample import decimate, interpolate, resample
from .rolling import rolling
from .taper import taper, taper_range
from .mute import line_mute, slope_mute
from .units import convert_units, set_units, simplify_units
from .whiten import whiten
from .hampel import hampel_filter
Expand Down
28 changes: 28 additions & 0 deletions dascore/proc/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -789,3 +789,31 @@ def flip(patch, *dims, flip_coords=True):
data = np.flip(patch.data, axis=axes) if dims else patch.data
coords = patch.coords.flip(*dims) if flip_coords else patch.coords
return patch.new(data=data, coords=coords)


@patch_function()
def full(patch, fill_value):
"""
Return an identical patch with the data replaced by fill_value.

Parameters
----------
patch
The patch to fill.
fill_value
The value in the output patch.

Examples
--------
>>> import dascore as dc
>>> patch = dc.get_example_patch()
>>>
>>> # Get a patch identical to original but with data array containing
>>> # Only 1s.
>>> one_patch = patch.full(1.0)
>>>
>>> # Same thing, except for 0s.
>>> zero_patch = patch.full(0.0)
"""
array = np.full(patch.data.shape, fill_value)
return patch.update(data=array)
25 changes: 17 additions & 8 deletions dascore/proc/filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from __future__ import annotations

import sys
import warnings
from collections.abc import Sequence

import numpy as np
Expand Down Expand Up @@ -438,13 +439,13 @@ def gaussian_filter(


@patch_function()
@compose_docstring(sample_explanation=samples_arg_description)
def slope_filter(
patch: PatchType,
filt: Sequence[float],
dims: tuple[str, str] = ("distance", "time"),
directional: bool = False,
notch: bool = False,
notch: bool | None = None,
invert: bool = False,
Comment thread
d-chambers marked this conversation as resolved.
) -> PatchType:
"""
Filter the patch over certain slopes in the 2D Fourier domain.
Expand Down Expand Up @@ -472,6 +473,8 @@ def slope_filter(
This can be used for up/down or left/right separation, assuming a
near-linear fiber layout.
notch
Deprecated, use invert.
invert
If True, the filter represents a notch, meaning the slopes
specified by the inner `filt` parameters are attenuated rather
than those outside of them.
Expand All @@ -498,7 +501,7 @@ def slope_filter(
>>> patch_filtered = patch.slope_filter(
... filt=filt,
... directional=False,
... notch=False
... invert=False
... )
>>> # Plot results
>>> fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 8))
Expand All @@ -507,8 +510,8 @@ def slope_filter(
>>> ax2 = patch_filtered.viz.waterfall(ax=ax2, scale=0.5)
>>> _ = ax2.set_title('Filtered')
>>>
>>> # Example 2: Notch filter
>>> patch_filtered = patch.slope_filter(filt=filt, notch=True)
>>> # Example 2: Inverted (notch) filter
>>> patch_filtered = patch.slope_filter(filt=filt, invert=True)
>>>
>>> # Example 3: specify units
>>> filt = np.array([2e3,2.2e3,8e3,2e4]) * dc.get_unit("m/s")
Expand All @@ -527,7 +530,7 @@ def _check_inputs(patch, filt, dims):
msg = f"Cant apply slope filter. {missing} are missing from patch."
raise ParameterError(msg)

def _get_taper_mask(filt, slope, notch):
def _get_taper_mask(filt, slope, invert):
"""Get a mask for applying taper and attenuation."""
fac = np.where(
(slope >= filt[0]) & (slope <= filt[1]),
Expand All @@ -540,7 +543,7 @@ def _get_taper_mask(filt, slope, notch):
np.sin(0.5 * np.pi * (slope - filt[2]) / (filt[3] - filt[2])),
fac,
)
fac = fac if notch else 1.0 - fac
fac = fac if invert else 1.0 - fac
return fac

def _get_slope_array(dft_patch, directional, freq_dims):
Expand Down Expand Up @@ -596,7 +599,13 @@ def _maybe_transform_units(filt, dft_patch, freq_dims):
slope = _get_slope_array(dft_patch, directional, freq_dims)
filt = _maybe_transform_units(filt, dft_patch, freq_dims)

mask = _get_taper_mask(filt, slope, notch)
# TODO remove in dascore 0.2.
if notch is not None:
msg = "The `notch` parameter of slope filter is deprecated. Use invert."
warnings.warn(msg, DeprecationWarning, stacklevel=2)
invert = notch

mask = _get_taper_mask(filt, slope, invert)
new_data = dft_patch.data * mask
out = dft_patch.update(data=new_data)
if transformed:
Expand Down
Loading
Loading