API Reference

A toolkit for working with uniformly sampled time series data.

pysampled.Data is the most important class in this module. It allows for easy signal splicing, and includes wrappers for basic signal processing techniques. The pysampled.Data class encapsulates signal values (data) with the sampling rate and provides wrappers for performing basic signal processing. It uses the pysampled.Time class to ease the burden of managing time and converting between time (in seconds) and sample numbers.

Classes:

Data: Provides various signal processing methods for sampled data.

Time: Encapsulates sampling rate, sample number, and time for sampled data. Interval: Represents an interval with start and end times, includes iterator protocol.

Siglets: A collection of signal pieces for event-triggered analyses.

RunningWin: Manages running windows for data processing. DataList: A list of pysampled.Data objects with filtering capabilities based on metadata. Event: An interval with labels for event handling. Events: A list of Event objects with label-based selection.

Functions:

uniform_resample: Uniformly resamples a signal at a given sampling rate.

interpnan: Interpolates NaNs in a 1D signal. onoff_samples: Finds onset and offset samples of a 1D boolean signal. frac_power: Calculates the fraction of power in a specific frequency band.

Examples

CAUTION: In this module, when referring to time, integers are interpreted as sample numbers, and floats are interpreted as time in seconds.

sig = Data(np.random.random((10, 3)), sr=2, t0=5.) # 5 seconds
x3 = sig[5.:5.05]()
x3.interval().end
x3[:1]()                                           # retrieve the first sample (NOT until 1 s)
x3[0:5.5](), x3[5.0:5.5]()

sig.apply_running_win(lambda x: np.sqrt(np.mean(x**2)), win_size=0.25, win_inc=0.1)
class pysampled.core.Time(inp, sr)

Time when working with sampled data (including video). INTEGER IMPLIES SAMPLE NUMBER, FLOAT IMPLIES TIME IN SECONDS. Use this to encapsulate sampling rate (sr), sample number (sample), and time (s). When the sampling rate is changed, the sample number is updated, but the time is held constant. When the time is changed, sample number is updated. When the sample number is changed, the time is updated When working in Premiere Pro, use 29.97 fps drop-frame timecode to show the actual time in video. You should see semicolons instead of colons

Parameters:
  • inp (Union[str, float, int, Tuple[Union[str, float, int], float]]) – Input time. (str) hh;mm;ss;frame# (float) assumes provided input is time in seconds! (int) assumes the provided input is the sample number (tuple) assumes (timestamp/time/sample, sampling rate)

  • sr (float) – Sampling rate, in Hz. casted into a float.

Variables:
  • time (float) – Time in seconds.

  • sample (int) – Sample number.

  • sr (float) – Sampling rate

Examples

t = Time('00;09;53;29', 30)
t = Time(9.32, 180)
t = Time(12531, 180)
t = Time(9.32, sr=180)
t = Time(('00;09;53;29', 30), 72) # edge case - for dealing with timestamps from premiere pro
t.time
t.sample
property sr: float
change_sr(new_sr)
Parameters:

new_sr (float) –

Return type:

Time

property sample: int
property time: float

Return time in seconds

to_interval(iter_rate=None)

Return an interval object with start and end times being the same

Parameters:

iter_rate (float | None) –

Return type:

Interval

class pysampled.core.Interval(start, end, sr=30.0, iter_rate=None)

Interval object with start and stop times. Implements the iterator protocol. INCLUDES BOTH START AND END SAMPLES.

Pictorial understanding:

start           -> |                                           | <-
frames          -> |   |   |   |   |   |   |   |   |   |   |   | <- [self.sr, len(self)=12, self.t_data, self.t]
animation times -> |        |        |        |        |         <- [self.iter_rate, self._index, self.t_iter]

Frame sampling is used to pick the nearest frame corresponding to the animation times.

Parameters:
  • start (Union[Time, str, float, int, Tuple[Union[str, float, int], float]]) – Start time.

  • end (Union[Time, str, float, int, Tuple[Union[str, float, int], float]]) – End time.

  • sr (float) – Sampling rate, in Hz.

  • iter_rate (Optional[float]) – Iteration rate.

Example

intvl = Interval(('00;09;51;03', 30), ('00;09;54;11', 30), sr=180, iter_rate=env.Key().fps)
intvl.iter_rate = 24  # say 24 fps for animation
for nearest_sample, time, index in intvl:
    print((nearest_sample, time, index))
property sr: float
change_sr(new_sr)
Parameters:

new_sr (float) –

Return type:

Interval

property dur_time: float

Duration in seconds

property dur_sample: int

Duration in number of samples

property t_iter: ndarray

Time Vector for the interval at iteration frame rate

property t_data: ndarray

Time vector at the data sampling rate

property t: ndarray

Time Vector relative to the start time.

add(other)

Add to object, rather than returning a new object

Parameters:

other (Time | int | float) –

Return type:

None

sub(other)
Parameters:

other (Time | int | float) –

Return type:

None

union(other)

Merge intervals to make an interval from minimum start time to maximum end time. Other can be an interval, or a tuple of intervals.

iter_rate and sr are inherited from the original event. Therefore, e1.union(e2) doesn’t have to be the same as e2.union(e1)

Parameters:

other (Interval) –

Return type:

Interval

intersection(other)
Parameters:

other (Interval) –

Return type:

Interval | Tuple

class pysampled.core.Data(sig, sr, axis=None, history=None, t0=0.0, meta=None, signal_names=None, signal_coords=None)

Signal processing class for sampled data. It is the most important class in this module. It allows for easy signal splicing, and includes wrappers for basic signal processing techniques. This class encapsulates signal values (data) with the sampling rate and provides wrappers for performing basic signal processing. It uses the pysampled.Time class to ease the burden of managing time and converting between time (in seconds) and sample numbers.

NOTE: When inheriting from this class, if the parameters of the ` __init__` method change, then make sure to rewrite the _clone method.

Parameters:
  • sig (np.ndarray) – Signal data.

  • sr (float) – Sampling rate.

  • axis (Optional[int]) – Time axis.

  • history (Optional[List[Tuple[str, Optional[Any]]]]) – History of operations.

  • t0 (float) – Time at start sample.

  • meta (Optional[dict]) – Metadata.

  • signal_names (Optional[List[str]]) – Names of the signals (e.g., [“acc1”, “acc2”]).

  • signal_coords (Optional[List[str]]) – Coordinates of the signals (e.g., [“x”, “y”, “z”]).

Example

x3 = sampled.Data(np.random.random((10, 3)), sr=2, t0=5.)

1 or 2-level indexing for multi-axis signals: signal_names (top level) and signal_coords (bottom level). This is particularly useful for multi-axis signals such as accelerometer data, where each signal has multiple coordinates (e.g., x, y, z).

Example

Suppose there are two accelerometer signals, each with x, y, z coordinates: - signal_names = [“acc1”, “acc2”] - signal_coords = [“x”, “y”, “z”]

You can access specific signals or coordinates using their names or labels.

s = Data(np.random.random((1000, 6)), sr=100, signal_names=["acc1", "acc2"], signal_coords=["x", "y", "z"])
# This assumes that the 6 columns are ordered as [acc1_x, acc1_y, acc1_z, acc2_x, acc2_y, acc2_z]
acc1_data = s["acc1"]  # Access all coordinates of acc1
x_coord_data = s["x"]  # Access the x-coordinate of all signals
Propagation invariants (1.2.0+):

Every chained method either routes through _clone() (rate-preserving) or _clone_with_rate() (rate-changing). Both helpers shallow-copy meta, signal_names, signal_coords, and _history so a clone never aliases the parent’s mutable state. The rate-changing methods are: resample, apply_running_win, fft_as_sampled, psd_as_sampled, frac_power. Methods like diff and instantaneous_frequency preserve the rate (and route through _clone).

transpose() preserves signal_names and signal_coords because they describe the logical signal axis, independent of which physical axis it lives on.

The apply family (apply(), apply_along_signals(), apply_to_each_signal()) shares one label-propagation rule: labels propagate iff n_signals(output) == n_signals(input). On mismatch they reset to defaults. Explicit signal_names= / signal_coords= always override.

The split family is:
__call__(col=None)

Return either a specific column or the entire set 2D signal.

For 1-D signals there is no signal axis, so an integer col is accepted but ignored — the full signal is returned regardless of the index value.

Examples

s = sampled.generate_signal("accelerometer")
s()
s(0) # first axis of the accelerometer signal
plt.figure()
plt.plot(s.t, s(0)) # plot the first axis of the accelerometer signal
plt.show(block=False)

plt.plot(*s(''))
# Supply an empty string to return a tuple of time and signal.
# This is useful when testing out signal manipulations.
plt.plot(*s.highpass(2).magnitude()(''))
Parameters:

col (int | str | None) –

Return type:

ndarray

copy()

Make a copy of the signal. Used by the set_nan() method to avoid changing the original signal.

Return type:

Data

analytic()

Extract the analytic signal. The analytic signal is a complex-valued signal whose real part is the original signal and whose imaginary part is the Hilbert transform of the original signal. It is useful for calculating the instantaneous attributes of a signal, such as its amplitude envelope, instantaneous phase, and instantaneous frequency (diff of instantaneous phase).

This method is not intended to be called directly. Instead, use the envelope, phase, and instantaneous_frequency methods to extract the envelope, instantaneous phase, and instantaneous frequency of the signal.

Return type:

Data

envelope(type='upper', lowpass=True)

Analytic envelope of the signal. It is optionally lowpass filtered. Note that the signal already needs to be bandpass filtered before applying the envelope. If not, either a value should be specified for lowpass, or lowpass should be set to False.

Parameters:
  • type (str, optional) – Upper or lowe envelope. Defaults to “upper”.

  • lowpass (Union[bool, float], optional) – Optionally lowpass filter the envelope, with the cutoff frequency defaulting to the lower end of the bandpass filtered signal. Defaults to True.

Returns:

Envelope of the signal

Return type:

Data

envelope2(side='upper', lowpass=None)

Maxima/minima-based envelope. Set side='lower' for the lower envelope.

phase()

Extract the instantaneous phase is the phase of the analytic signal. It is the angle of the complex number formed by the real and imaginary parts of the analytic signal. It is useful for calculating phase-locking (synchronization) between signals.

Return type:

Data

instantaneous_frequency()

Extract the instantaneous frequency of the signal.

Return type:

Data

bandpass(low, high, order=None)

Design and apply an FIR (finite impulse response) bandpass filter to the signal. To apply an IIR (infinite impulse response) filter instead, use the lowpass and highpass methods in tandem.

Parameters:
  • low (float) – Lower cutoff frequency.

  • high (float) – Upper cutoff frequency.

  • order (Optional[int], optional) – Order of the filter. Defaults to half a second of the signal.

Returns:

Bandpass filtered signal.

Return type:

Data

notch(cutoff, q=30)

Apply a notch filter to the signal. A notch filter is a band-stop filter that removes a specific frequency from the signal. It is mostly used to remove power line interference. The cutoff frequency is the frequency to be removed, and the Q factor is the ratio of the center frequency to the bandwidth.

Parameters:
  • cutoff (float) – Frequency to be removed

  • q (float, optional) – Ratio of the center frequency to the bandwidth. Defaults to 30, setting the bandwidth to 2 Hz for a 60 Hz power line frequency in North America.

Returns:

Notch-filtered signal.

Return type:

Data

lowpass(cutoff, order=None)

Apply a lowpass butterworth IIR filter to the signal. Signal below the cutoff frequency is retained, and the order determines the steepness of the roll-off of the filter.

Parameters:
  • cutoff (float) – Cutoff frequency.

  • order (Optional[int], optional) – Filter order. Defaults to 6.

Returns:

Lowpass filtered data.

Return type:

Data

highpass(cutoff, order=None)

Apply a highpass butterworth IIR filter to the signal. Signal above the cutoff frequency is retained, and the order determines the steepness of the roll-off of the filter.

Parameters:
  • cutoff (float) – Cutoff frequency.

  • order (Optional[int], optional) – Filter order. Defaults to 6.

Returns:

Highpass filtered data.

Return type:

Data

get_trend_airPLS(*args, **kwargs)
Return type:

Data

detrend_airPLS(*args, **kwargs)
Return type:

Data

medfilt(order=11)

Apply a median filter to the signal.

Parameters:

order (Union[int, float]) –

  • If an int, it represents the kernel size in samples.

  • If a float, it is interpreted as a duration in seconds and

converted to samples.

Returns:

A new Data instance with the median-filtered signal.

Return type:

Data

Notes

  • The filter order is adjusted to be an odd integer. The start and end of the signal remain unfiltered to preserve boundary values.

interpnan(maxgap=None, **kwargs)

Interpolate NaN values. This method is useful for interpolating missing values in the signal. It uses the scipy.interpolate.interp1d function to interpolate the missing values. kwargs will be passed to scipy.interpolate.interp1d

Parameters:

maxgap (Optional[Union[int, float, np.ndarray]]) – Various ways to specify where to perform interpolation. Defaults to None. (NoneType) all NaN values will be interpolated. (int) stretches of NaN values smaller than or equal to maxgap, in samples, will be interpolated. (float) stretches of NaN values smaller than or equal to maxgap, in seconds, will be interpolated. (boolean array) will be used as a mask where interpolation will only happen where maxgap is True.

Returns:

_description_

Return type:

Data

shift_baseline(offset=None)
Parameters:

offset (float | None) –

Return type:

Data

shift_left(time=None)
Parameters:

time (float | None) –

Return type:

Data

get_total_left_shift()

Return the total amount of time by which the signal was shifted to the left.

Return type:

float

reset_left_shift()
Return type:

Data

scale(scale_factor)
Parameters:

scale_factor (float) –

Return type:

Data

property t: ndarray
property dur: float
t_start()
Return type:

float

t_end()
Return type:

float

interval()
Return type:

Interval

take_by_interval(key)
Parameters:

key (Interval) –

Return type:

Data

__getitem__(key)

This method is used for flexible indexing along either the signals or time dimensions, or to retrieve metadata.

Metadata retrieval:

If key is in the metadata of the signal, then return the value of that metadata. Keeping it here for backwards compatibility. Not recommended. Instead, use sig.meta[key] to retrieve metadata.

Signal indexing:

If key is a string or a list of strings, then it is assumed to be signal name(s) or coordinate(s). For example,

s = pysampled.Data(np.random.random((100, 6)), sr=2, t0=5., signal_names=["acc1", "acc2"], signal_coords=["x", "y", "z"])
s["acc1"]      # s["acc1"]() is equivalent to s()[:, :3]
s["x"]         # s["x"]() is equivalent to s()[:, [0, 3]]
s["x", "y"]    # s["x", "y"]() is equivalent to s()[:, [0, 1, 3, 4]]
s["acc1"]["x"] # s["acc1"]["x"]() is equivalent to s()[:, [3]] and NOT s()[:, 3]
Interpolation:

If key is a list, tuple, int, or float, then return the interpolated value(s) at those times. If it is an int, return the value at the corresponding sample. List or tuple of integers will be treated as a list or tuple of times, and NOT samples. If it is a float, return the interpolated value at that time.

s[5.05]    # returns linearly interpolated value at 5.05 seconds
s[5]       # returns the value at the 5th sample
s[[5.05, 5.45]]  # returns linearly interpolated values at 5.05 and 5.45 seconds
s[[5, 10]]       # returns the values at time 5 and 10 seconds
Time-based indexing:

Slice the signal in time.

s[10.:20.]  # returns a new signal with data between 10 and 20 seconds
s[10:20]    # returns a new signal with data between 10 and 20 samples (including both ends)
More examples:

x3 = sampled.Data(np.random.random((10, 3)), sr=2, t0=5.)

Indexing with list, tuple, int, or float will return numpy arrays:

x3[[5.05, 5.45]] # returns linearly interpolated values x3[5.05] # returns linearly interpolated value x3[2.] # this should error out because it is outside the range x3[2], x3[-1], x3[len(x3)-1] # this is effectively like array-indexing, last two should be the same

Indexing with interval or slice returns sampled.Data:

x3[5.:5.05]() # should return only one value x3[5.:5.05].interval().end # should return 5 x3[:1]() # retrieve by position if it is an integer - Equivalent to x3[0], but for signals with axis=1, x3[:1] will preserve dimensionality of retrieved signal x3[0.:1.]() # this will return an empty signal, and the interval() on that won’t make sense x3[:5.5]() # should return first two values x3[0:5.5](), x3[5.0:5.5]() # should be the same as above, also examine x3[0:5.5].interval().start -> this should be 5.0

Parameters:

key (int | float | slice | Interval | str) –

Return type:

ndarray | Data | Any

make_running_win(win_size=0.25, win_inc=0.1)

Create a running window configuration for processing data.

Parameters:
  • win_size (float, optional) – The size of the window in seconds. Defaults to 0.25.

  • win_inc (float, optional) – The increment of the window in seconds. Defaults to 0.1.

Returns:

An instance of the RunningWin class configured with the total number of samples, window size in samples, and window increment in samples.

Return type:

RunningWin

apply_running_win(func, win_size=0.25, win_inc=0.1)

Process the signal using a running window by applying func to each window.

Args: func (Callable[[np.ndarray, int], Any]): Function to apply to each window. win_size (float, optional): Window size in seconds. Defaults to 0.25. win_inc (float, optional): Window increment (step size) in seconds. Defaults to 0.1.

Returns:

A new Data instance containing the processed signal.

Return type:

Data

Parameters:
  • func (Callable[[ndarray, int], Any]) –

  • win_size (float) –

  • win_inc (float) –

Example

Extract RMS envelope self.apply_running_win(lambda x: np.sqrt(np.mean(x**2)), win_size, win_inc)

onoff_times()

Onset and offset times of a thresholded 1D sampled.Data object.

Example

sig = sampled.generate_signal("sine_wave")
onset_times, offset_times = (sig > 0.5).onoff_times()
Return type:

Tuple[List[float], List[float]]

find_crossings(th=0.0, th_time=None)

Find the times at which the signal crosses a given threshold th. Without th_time, it is simpler to use Data.onoff_times().

Parameters:
  • th (float, optional) – Threshold. Defaults to 0.0.

  • th_time (Optional[float], optional) – Ignore crossings that are less than th_time apart. Caution - uses median filter, check carefully. Defaults to None.

Returns:

Tuple of two lists with times at which the signal crosses the threshold from below and above.

Return type:

Tuple[List[float], List[float]]

get_signal_axis()

Get the signal axis for a 2D signal. Returns None for a 1D signal.

Return type:

int | None

n_signals()

Number of signals. Returns 1 for 1D signals, and makes sense only for 2D signals.

Return type:

int

split_by_signal_name()

Split into one Data per signal_name. Equivalent to [self[name] for name in self.signal_names]. For a 1D signal, returns [self] (matches split_to_1d).

Return type:

List[Data]

split_by_signal_coord()

Split into one Data per signal_coord. Equivalent to [self[coord] for coord in self.signal_coords]. For a 1D signal, returns [self].

Return type:

List[Data]

split_to_1d()

Split a 2D signal into 1D signals. Returns a list of 1D signals. Returns the signal itself, still in a list, for a 1D signal.

Return type:

List[Data]

transpose()

Transpose a 2D signal. Nothing is done for a 1D signal.

Return type:

Data

fft(win_size=None, win_inc=None, zero_mean=False)

Compute the fast Fourier transform (FFT) of the signal. The FFT is computed using the scipy.fft module. If win_size is specified, a sliding window FFT is computed. If win_size is specified and win_inc is not, then a sliding window FFT is performed with no overlap. If zero_mean is True, the mean of the signal is subtracted before computing the FFT. Consider using the fft_as_sampled() method.

Parameters:
  • win_size (Optional[float], optional) – Window size for the sliding window fft. Defaults to None.

  • win_inc (Optional[float], optional) – Window increment for overlapping sliding windows. Defaults to None.

  • zero_mean (bool, optional) – Optionally subtract the mean before computing the FFT. Defaults to False.

Returns:

A tuple of frequency and amplitude arrays.

Return type:

Tuple[np.ndarray, np.ndarray]

fft_as_sampled(*args, **kwargs)

Format the output of fft() as a Data object. Think of the sampling rate of the returned object as number of samples per Hz instead of number of samples per second.

Returns:

Fourier transform of the signal.

Return type:

Data

psd(win_size=5.0, win_inc=None, **kwargs)

Compute the power spectral density using the Welch method. If the signal is 2D, the PSD is computed for each signal separated using the split_to_1d() method. Consider using the psd_as_sampled() method.

Parameters:
  • win_size (float, optional) – Size of the sliding window. Defaults to 5.0.

  • win_inc (Optional[float], optional) – Increment for the sliding window. None implies no overlap between sliding windows. Defaults to None.

Returns:

Tuple of frequency and power spectral density. For 2D signals, the power spectral density is also a 2D array.

Return type:

Tuple[np.ndarray, np.ndarray]

psd_as_sampled(*args, **kwargs)

Format the output of psd() as a Data object. Think of the sampling rate of the returned object as number of samples per Hz instead of number of samples per second.

Returns:

Power spectral density of the signal.

Return type:

Data

frac_power(freq_lim, win_size=5.0, win_inc=2.5, freq_dx=0.05, highpass_cutoff=0.2)

Calculate the fraction of power in a specific frequency band.

Parameters:
  • freq_lim (Tuple[float, float]) – Frequency band limits (low, high) in Hz.

  • win_size (float) – Window size in seconds. Default is 5.0.

  • win_inc (float) – Window increment in seconds. Default is 2.5.

  • freq_dx (float) – Frequency resolution in Hz. Default is 0.05.

  • highpass_cutoff (float) – Highpass filter cutoff frequency in Hz. Default is 0.2.

Returns:

A new Data object containing the fraction of power in the specified band.

Return type:

Data

diff()

Differentiate the signal.

Unlike np.diff, the number of samples is preserved, and the units will be in per second, as opposed to per sample. In other words, the np.diff output is multiplied by the sampling rate of the signal.

Returns:

The differentiated signal with the same number of samples as the input.

Return type:

Data

Raises:

ValueError – If the signal has fewer than 2 samples along the sample axis.

magnitude()

Compute the magnitude of a multi-axis signal per signal_name.

For each name in signal_names, takes the L2 norm across that name’s signal_coords. The output has shape (n_samples, len(signal_names)) (or its transpose), with signal_names preserved and signal_coords set to ["mag"]. For 1D signals, returns self unchanged.

Behavior change in 1.2.0: previously this method computed a single global L2 norm across all non-time columns, regardless of how the signals were grouped by name. Callers relying on the old behavior can recover it with sig.apply_along_signals(np.linalg.norm).

Return type:

Data

apply(func, *args, **kwargs)

Apply a function func to the signal. Common uses include performing simple arithmetic manipulations, such as scaling.

Label propagation rule (1.2.0): if func returns the same number of signals as the input, signal_names and signal_coords are preserved. If the count differs, both are reset to defaults — unless the caller passes signal_names= or signal_coords= explicitly, in which case those always win.

Parameters:

func (Callable[[...], ndarray]) –

Return type:

Data

apply_along_signals(func, *args, **kwargs)

Apply a function func along the signal axis. Same label rule as apply() — propagate iff n_signals matches.

Parameters:

func (Callable[[...], ndarray]) –

Return type:

Data

apply_to_each_signal(func, *args, **kwargs)

Apply a function to each signal (if self is a collection of signals) separately, and put it back together. Same label rule as apply() — propagate iff n_signals matches.

Parameters:

func (Callable[[...], ndarray]) –

Return type:

Data

regress(ref_sig)

Regress a reference signal out of the current signal. For example, to regress the isosbestic signal out of a calcium signal.

Parameters:

ref_sig (Data) –

Return type:

Data

resample(new_sr, *args, **kwargs)

Resample a signal using scipy.signal.resample. args and kwargs will be passed to scipy.signal.resample.

Parameters:

new_sr (float) –

Return type:

Data

smooth(win_size=0.5, kernel_type='flat', ensure_odd_kernel_len=True)

Moving average smoothing with different kernels while preserving the number of samples in the signal. The kernel_type can be one of the following: ‘flat’, ‘hanning’, ‘hamming’, ‘bartlett’, ‘blackman’

Parameters:
  • win_size (float, optional) – Smoothing window size, specified in seconds. Defaults to 0.5.

  • kernel_type (str, optional) – Type of smoothing window. Defaults to “flat”.

  • ensure_odd_kernel_len (bool, optional) – Because of the implementation in _smooth, to ensure zero-phase filtering, we need to shift the filtered signal by half a sample (by adjusting the start time) when the kernel length is an even number of samples. This is not very elegant. Defaults to True.

Returns:

A new Data instance containing the smoothed signal.

Return type:

Data

moving_average(win_size=0.5)

Moving average smoothing. Same as applying the “flat” window in the smooth method. This method trims the signal ends by half the window.

Parameters:

win_size (float, optional) – Smoothing window size, specified in seconds. Defaults to 0.5.

Returns:

A new Data instance containing the smoothed signal.

Return type:

Data

xlim()
Return type:

Tuple[float, float]

ylim()
Return type:

Tuple[float, float]

logdj(interpnan_maxgap=None)

Computes the log dimensionless jerk, which measures signal smoothness. Values closer to zero indicate a smoother signal. Note: This calculation is only valid for velocity signals (vectors) and not scalar speed signals.

Args:

interpnan_maxgap (Optional[int], optional): maximum gap (in number of samples) to interpolate. None (default) interpolates all gaps. Supply 0 to not interpolate.

Returns:

float: log dimensionless jerk

Parameters:

interpnan_maxgap (int | None) –

Return type:

float

logdj2(interpnan_maxgap=None)

Use the logdj() method instead—it automatically calls this method for a 1D signal. This method computes the log dimensionless jerk from a speed signal. Important: This method is only valid when self represents a speed signal (a scalar speed rather than a vector velocity signal). The implementation for computing logdj is different for speed and velocity signals.

Parameters:

interpnan_maxgap (int | None) –

Return type:

float

sparc(fc=10.0, amp_th=0.05, interpnan_maxgap=None, shift_baseline=False, mean_normalize=True)

Compute the spectral arc length, another measure of signal smoothness. Values closer to zero indicate a smoother signal. The results from sparc were unpredictable, and therefore, we recommend using logdj instead. CAUTION: makes sense ONLY if self is a speed signal (as in, a scalar speed, as opposed to a vector velocity signal).

Parameters:
  • fc (float, optional) – Cutoff frequency. Defaults to 10.0 Hz.

  • amp_th (float, optional) – Amplitude threshold. Defaults to 0.05.

  • interpnan_maxgap (Optional[int], optional) – maximum gap (in number of samples) to interpolate. None (default) interpolates all gaps. Supply 0 to not interpolate.

  • shift_baseline (bool, optional) – Set it to True to subtract the mean from the signal before computing sparc. Defaults to False.

  • mean_normalize (bool, optional) – Divide the signal by the mean. Requred to make smoothness metric insensitive to signal amplitude. Defaults to True.

Returns:

sparc value

Return type:

float

References

Balasubramanian, S., Melendez-Calderon, A., & Burdet, E. (2011). A robust and sensitive metric for quantifying movement smoothness. IEEE Transactions on Biomedical Engineering, 59(8), 2126-2136.

set_nan(interval_list)

Set parts of a signal to np.nan. Works on a copy of the signal. All numbers in interval_list are treated as time points (and not samples). Works for both 1D and 2D signals.

Example

acc = sampled.generate_signal(“accelerometer”) noisy_segments = [(0.5, 1.0), (2.0, 2.5)] acc = acc.set_nan(noisy_segments) # instead of set_nan, use remove_and_interpolate

Parameters:

interval_list (List[Tuple[float, float]]) –

Return type:

Data

remove_and_interpolate(interval_list, maxgap=None, **kwargs)

Remove parts of a signal, and interpolate between those points.

Parameters:
  • interval_list (List[Tuple[float, float]]) –

  • maxgap (int | None) –

Return type:

Data

plot()
Return type:

matplotlib.axes.Axes

class pysampled.core.DataList(iterable=(), /)

A list of pysampled.Data objects with filtering capabilities based on metadata.

__call__(**kwargs)

Call self as a function.

Return type:

DataList

class pysampled.core.Event(start, end=None, **kwargs)

Interval with labels.

Parameters:
  • start (Union[Interval, Time, str, float, int, Tuple[Union[str, float, int], float]]) – Start time.

  • end (Optional[Union[Time, str, float, int, Tuple[Union[str, float, int], float]]]) – End time.

  • labels (list of strings) – (supply as a kwarg) Hashtags defining the event.

add_labels(*new_labels)
Parameters:

new_labels (str) –

Return type:

None

remove_labels(*labels_to_remove)
Parameters:

labels_to_remove (str) –

Return type:

None

class pysampled.core.Events(iterable=(), /)

List of event objects that can be selected by labels using the Events.get() method.

append(key)

Append object to the end of the list.

Parameters:

key (Event | Interval) –

Return type:

None

get(label)
Parameters:

label (str) –

Return type:

Events

class pysampled.core.RunningWin(n_samples, win_size_samples, win_inc_samples=1, step=None, offset=0)

Manages running windows for data processing.

Parameters:
  • n_samples (int) – Number of samples.

  • win_size_samples (int) – Window size specified in number of samples.

  • win_inc_samples (int) – Window increment specified in number of samples.

  • step (Optional[int]) – Step size.

  • offset (int) – Offset for running windows. This is useful when the object you’re slicing has an inherent offset that you need to consider. For example, consider creating running windows on a sliced optitrack marker Think of offset as start_sample

Variables:
  • run_win (List[slice]) – List of slice objects, one per running window.

  • center_idx (List) – Indices of center samples.

__call__(data=None)

Call self as a function.

Parameters:

data (ndarray | None) –

Return type:

List[slice] | List[ndarray]

class pysampled.core.Siglets(sig, events, window)

A collection of pieces of signals to do event-triggered analyses.

Parameters:
  • sig (Data) – Signal data.

  • events (List[float]) – A list of event times (in seconds). Even if integers are provided, they will be converted to floats.

  • window (Union[Interval, Tuple[float, float], Tuple[int, int]]) – Window relative to the events for event-triggered analysis. For example, (-1., 2.) means 1 second before the event and 2 seconds after the event. CAUTION: (-10, 20) means 10 samples before the event and 20 samples after the event.

AX_TIME = 0
AX_TRIALS = 1
property sr: float
property t: ndarray

Return the time vector of the event window

property n: int

Return the number of siglets

__call__(func=None, axis='events', *args, **kwargs)

Call self as a function.

Parameters:
  • func (Callable[[...], ndarray] | None) –

  • axis (int | str) –

Return type:

ndarray

apply_along_events(func, *args, **kwargs)
Parameters:

func (Callable[[...], ndarray]) –

Return type:

ndarray

apply_along_time(func, *args, **kwargs)
Parameters:

func (Callable[[...], ndarray]) –

Return type:

ndarray

apply(func, axis='events', *args, **kwargs)
Parameters:
  • func (Callable[[...], ndarray]) –

  • axis (int | str) –

Return type:

ndarray

mean(axis='events')
Parameters:

axis (int | str) –

Return type:

ndarray

sem(axis='events')
Parameters:

axis (int | str) –

Return type:

ndarray

is_uniform()
Return type:

bool

plot()
Return type:

matplotlib.axes.Axes

pysampled.core.interpnan(sig, maxgap=None, min_data_frac=0.2, **kwargs)

Interpolate NaNs in a 1D signal.

Parameters:
  • sig (np.ndarray) – 1D numpy array.

  • maxgap (Optional[Union[int, np.ndarray]]) – Maximum gap to interpolate. (NoneType) all NaN values will be interpolated. (int) stretches of NaN values smaller than or equal to maxgap will be interpolated. (boolean array) will be used as a mask where interpolation will only happen where maxgap is True.

  • min_data_frac (float) – Minimum data fraction.

  • **kwargs – Additional arguments for scipy.interpolate.interp1d. commonly used: kind=’cubic’

Returns:

Interpolated signal.

Return type:

np.ndarray

pysampled.core.onoff_samples(tfsig)

Find onset and offset samples of a 1D boolean signal (e.g. Thresholded TTL pulse).

Parameters:

tfsig (np.ndarray) – 1D boolean signal.

Returns:

Onset and offset samples.

Return type:

Tuple[List[int], List[int]]

pysampled.core.uniform_resample(time, sig, sr, t_min=None, t_max=None)

Uniformly resample a signal at a given sampling rate sr.

Parameters:
  • time (np.ndarray) – Non-decreasing array of time points.

  • sig (np.ndarray) – Signal data.

  • sr (float) – Sampling rate in Hz.

  • t_min (Optional[float]) – Start time for the output array.

  • t_max (Optional[float]) – End time for the output array.

Returns:

Uniformly resampled data.

Return type:

Data

pysampled.core.generate_signal(signal_type='white_noise', sr=100, duration=10)

Generate a signal of a specific type. Intended for testing and demonstration purposes.

Parameters:
  • signal_type (str) – Signal type. Either “white_noise”, “sine_wave”, “three_sine_waves”, “ekg”, or “accelerometer”. It can also be “1d” or “2d” which return white_noise and accelerometer signals respectively.

  • sr (float) – Sampling rate.

  • duration (float) – Duration.

Returns:

Signal data.

Return type:

Data

pysampled.core.plot(*args, **kwargs)

Make plotting easier in the ipython console. Works for sampled.Data objects, lists of sampled.Data objects, and regular numpy arrays. Note that this will not work with “minimal” dependency installation.

Return type:

matplotlib.axes.Axes