Patch Processing

The following shows some simple examples of patch processing. See the proc module for a list of all processing functions.

Basic

There are several “basic” processing functions which manipulate the patch metadata, shape, etc. Many of these are covered in the patch tutorial, but here are a few that aren’t:

Transpose

The transpose patch function patch function simply transposes the dimensions of the patch, either by rotating the dimensions or to a new specified dimension.

import dascore as dc

patch = dc.get_example_patch()
print(f"dims before transpose: {patch.dims}")

transposed = patch.transpose()
print(f"dims after transpose: {transposed.dims}")

# Dimension order can be manually specified as well.
transposed = patch.transpose("time", "distance")
dims before transpose: ('distance', 'time')
dims after transpose: ('time', 'distance')

Squeeze

squeeze removes dimensions which have a single value (see also numpy.squeeze).

import dascore as dc

patch = dc.get_example_patch()
# Select first distance value to make distance dim flat.

flat_patch = patch.select(distance=0, samples=True)
print(f"Pre-squeeze dims: {flat_patch.shape}")

squeezed = flat_patch.squeeze()
print(f"Post-squeeze dims: {squeezed.shape}")
Pre-squeeze dims: (1, 2000)
Post-squeeze dims: (2000,)

Dropna

The dropna patch function patch function drops “nullish” values from a given label.

import numpy as np

import dascore as dc

patch = dc.get_example_patch()

# Create a patch with nan values
data = np.array(patch.data)
data[:, 0] = np.NaN
patch_with_nan = patch.new(data=data)

# Drop Nan along axis 1
dim = patch_with_nan.dims[1]
no_na_patch = patch_with_nan.dropna(dim)

assert not np.any(np.isnan(no_na_patch.data))

Decimate

decimate decimates a Patch along a given axis while by default performing low-pass filtering to avoid aliasing.

Data creation

First, we create a patch composed of two sine waves; one above the new decimation frequency and one below.

import dascore as dc

patch = dc.examples.get_example_patch(
    "sin_wav",
    sample_rate=1000,
    frequency=[200, 10],
    channel_count=2,
)
patch.viz.wiggle(show=True);

IIR filter

Next we decimate by 10x using IIR filter

decimated_iir = patch.decimate(time=10, filter_type='iir')
decimated_iir.viz.wiggle(show=True);

Notice the lowpass filter removed the 200 Hz signal and only the 10Hz wave remains.

FIR filter

Next we decimate by 10x using FIR filter.

decimated_fir = patch.decimate(time=10, filter_type='fir')
decimated_fir.viz.wiggle(show=True);

No Filter

Next, we decimate without a filter to purposely induce aliasing.

decimated_no_filt = patch.decimate(time=10, filter_type=None)
decimated_no_filt.viz.wiggle(show=True);

Taper

taper is used to taper the edges of a patch dimension to zero. To see this, let’s create a patch of all 1s and apply the taper function

import numpy as np
import dascore as dc

_patch = dc.get_example_patch()
patch_ones = _patch.new(data=np.ones_like(_patch.data))

The following code will apply a 10% taper, meaning a cosine taper is applied along the first and last 10% of the specified dimension.

patch_ones.taper(time=0.1).viz.waterfall();

Passing a tuple of values enables different amounts of tapering for each end of the dimension.

# Apply a 10% taper to the start and 30% to the end of distance dimension.
patch_ones.taper(distance=(0.1, 0.3)).viz.waterfall();

Either element of the tuple can be None which indicates no tapering is applied.

# Only apply 10% taper to the end of the distance dimension.
patch_ones.taper(distance=(None, 0.1)).viz.waterfall();

See also the edge effects recipe for using tapering to help filtering.

Rolling

The rolling patch function implements moving window operators similar to pandas rolling. It is useful for smoothing, calculating aggregated statistics, etc.

Here is an example of using a rolling mean to smooth along the time axis:

import dascore as dc

patch = dc.get_example_patch("example_event_1")
# Apply moving mean window over every 10 samples
dt = patch.get_coord('time').step

smoothed = patch.rolling(time=50*dt).mean()
smoothed.viz.waterfall(scale=.1);

Notice the NaN values at the start of the time axis. These can be trimmed with Patch.dropna.