ap_features package

Contents

ap_features package#

Submodules#

ap_features.average module#

class ap_features.average.Average(y, x, ys, xs)#

Bases: tuple

x#

Alias for field number 1

xs#

Alias for field number 3

y#

Alias for field number 0

ys#

Alias for field number 2

exception ap_features.average.InvalidSubSignalError[source]#

Bases: RuntimeError

ap_features.average.average_and_interpolate(ys: Sequence[ndarray | List[float] | Sequence[float]], xs: Sequence[ndarray | List[float] | Sequence[float]] | None = None, N: int = 200) Average[source]#

Get the average of list of signals assuming that they align at the same x value

Parameters:
  • ys (Array) – The signal values

  • xs (Array) – The x-values

  • N (int) – Length of output array (Default: 200)

Returns:

  • Y_avg (array) – The average y values

  • X (array) – The new x-values

ap_features.average.clean_data(ys: Sequence[ndarray | List[float] | Sequence[float]], xs: Sequence[ndarray | List[float] | Sequence[float]] | None) Tuple[Sequence[ndarray | List[float] | Sequence[float]], Sequence[ndarray | List[float] | Sequence[float]]][source]#

Make sure xs and ys have the correct shapes and remove empty sub-signals

Parameters:
  • ys (Sequence[Array]) – First list

  • xs (Optional[Sequence[Array]]) – Second list

Returns:

(ys, xs) - cleaned version

Return type:

Tuple[Sequence[Array], Sequence[Array]]

Note

The order you send in the array will be the same as the order it is returned. Apart from this fact, the order doesn’t matter.

Raises:
ap_features.average.create_longest_time_array(xs: Sequence[ndarray | List[float] | Sequence[float]], N: int) ndarray[source]#

Given a list of sub-signals create a new array of length N that cover all values

Parameters:
  • xs (Sequence[Array]) – List of monotonic sub sub-signal

  • N (int) – Size of output array

Returns:

Array that cover all values of length N

Return type:

np.ndarray

ap_features.average.interpolate(X: ndarray | List[float] | Sequence[float], x: ndarray | List[float] | Sequence[float], y: ndarray | List[float] | Sequence[float]) ndarray[source]#

Interpolate array

Parameters:
  • X (Array) – x-coordinates at which to evaluate the interpolated values

  • x (Array) – x-coordinates of the data points

  • y (Array) – y-coordinates of the data points

Returns:

Interpolated y-coordinates

Return type:

np.ndarray

Note

This function will try to perform spline interpolation using scipy.interpolate.UnivariateSpline and fall back to numpy.interp in case that doesn’t work

ap_features.background module#

class ap_features.background.Background(x, y, y_filt, corrected, background, F0, method)[source]#

Bases: NamedTuple

F0: float#

Alias for field number 5

background: ndarray | List[float] | Sequence[float]#

Alias for field number 4

corrected: ndarray | List[float] | Sequence[float]#

Alias for field number 3

method: BackgroundCorrection#

Alias for field number 6

x: ndarray | List[float] | Sequence[float]#

Alias for field number 0

y: ndarray | List[float] | Sequence[float]#

Alias for field number 1

y_filt: ndarray | List[float] | Sequence[float]#

Alias for field number 2

class ap_features.background.BackgroundCorrection(value)[source]#

Bases: str, Enum

An enumeration.

full = 'full'#
none = 'none'#
subtract = 'subtract'#
class ap_features.background.BackgroundCostFunction(value)[source]#

Bases: str, Enum

An enumeration.

ah = 'ah'#
atq = 'atq'#
sh = 'sh'#
stq = 'stq'#
ap_features.background.background(x: ndarray | List[float] | Sequence[float], y: ndarray | List[float] | Sequence[float], order: int = 2, threshold: float = 0.01, cost_function: BackgroundCostFunction = BackgroundCostFunction.atq, **kwargs) ndarray[source]#

Compute an estimation of the background (aka baseline) in chemical spectra. The background is estimated by a polynomial with order using a cost-function and a threshold parameter. This is a re-implementation of a MATLAB script that can be found here

Parameters:
  • x (Array) – Time stamps

  • y (Array) – Signal

  • order (int, optional) – Polynomial order, by default 2

  • threshold (float, optional) – The threshold parameters, by default 0.01

  • cost_function (BackgroundCostFunction, optional) – Cost function to be minimized, by default BackgroundCostFunction.atq. The cost functions can have the following forms:

Returns:

The estimated baseline

Return type:

np.ndarray

Notes

The cost function can have the four following values:

  • sh - symmetric Huber function :

    \[\begin{split}f(x) = \begin{cases} x^2, \; \text{ if } |x| < \text{threshold} \\ 2 \text{threshold} |x|-\text{threshold}^2, \; \text{otherwise} \end{cases}\end{split}\]
  • ah - asymmetric Huber function :

    \[\begin{split}f(x) = \begin{cases} x^2, \; \text{ if } x < \text{threshold} \\ 2 \text{threshold} x-\text{threshold}^2 , \; \text{otherwise} \end{cases}\end{split}\]
  • stq - symmetric truncated quadratic :

    \[\begin{split}f(x) = \begin{cases} x^2, \; \text{ if } |x| < \text{threshold} \\ \text{threshold}^2 , \; \text{otherwise} \end{cases}\end{split}\]
  • atq - asymmetric truncated quadratic :

    \[\begin{split}f(x) = \begin{cases} x^2, \; \text{ if } x < \text{threshold} \\ \text{threshold}^2 , \; \text{otherwise} \end{cases}\end{split}\]

References

[1] Mazet, V., Carteret, C., Brie, D., Idier, J. and Humbert, B., 2005. Background removal from spectra by designing and minimising a non-quadratic cost function. Chemometrics and intelligent laboratory systems, 76(2), pp.121-133.

ap_features.background.correct_background(x: ndarray | List[float] | Sequence[float], y: ndarray | List[float] | Sequence[float], method: BackgroundCorrection, filter_kernel_size: int = 0, force_positive: bool = False, **kwargs) Background[source]#
ap_features.background.full_background_correction(x: ndarray | List[float] | Sequence[float], y: ndarray | List[float] | Sequence[float], filter_kernel_size=0, **kwargs) Background[source]#

Perform at background correction. First estimate background \(b\), and let \(F_0 = b(0)\). The corrected background is then \(\frac{y - b}{F_0}\). Additional argument can be passed to background corrected algorithm as keyword arguments.

Parameters:
  • x (Array) – Time points

  • y (Array) – Fluorescence amplitude

Returns:

Namedtuple containing the corrected trace and the background.

Return type:

Background

ap_features.background.get_filtered_signal(y: ndarray | List[float] | Sequence[float], filter_kernel_size: int = 0) ndarray | List[float] | Sequence[float][source]#

ap_features.beat module#

class ap_features.beat.Beat(y: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float], pacing: ndarray | List[float] | Sequence[float] | None = None, y_rest: float | None = None, y_max: float | None = None, parent: Beats | None = None, backend: Backend = Backend.numba, beat_number: int | None = None)[source]#

Bases: Trace

apd(factor: float, use_spline: bool = True) float[source]#

The action potential duration

Parameters:
  • factor (int) – Integer between 0 and 100

  • use_spline (bool, optional) – Use spline interpolation, by default True.

Returns:

action potential duration

Return type:

float

apd_point(factor: float, use_spline: bool = True, strategy: APDPointStrategy = APDPointStrategy.big_diff_plus_one) Tuple[float, float][source]#

Return the first and second intersection of the APD p line

Parameters:
  • factor (int) – The APD

  • use_spline (bool, optional) – Use spline interpolation or not, by default True

Returns:

Two points corresponding to the first and second intersection of the APD p line

Return type:

Tuple[float, float]

apd_points(factor: float, use_spline: bool = True) List[float][source]#

Return all intersections of the APD p line

Parameters:
  • factor (int) – The APD

  • use_spline (bool, optional) – Use spline interpolation or not, by default True

Returns:

Two points corresponding to the first and second intersection of the APD p line

Return type:

List[float]

apd_up_xy(low, high)[source]#

Find the duration between first intersection (i.e during the upstroke) of two APD lines

Parameters:
  • low (int) – First APD line (value between 0 and 100)

  • high (int) – Second APD line (value between 0 and 100)

Returns:

The time between low to high

Return type:

float

as_beats() Beats[source]#

Convert trace from Beat to Beats

capd(factor: float, beat_rate: float | None = None, formula: str = 'friderica', use_spline: bool = True, use_median_beat_rate: bool = False) float[source]#

Correct the given APD (or any QT measurement) for the beat rate. normally the faster the HR (or the shorter the RR interval), the shorter the QT interval, and vice versa

Parameters:
  • factor (int) – Integer between 0 and 100

  • beat_rate (float) – The beat rate (number of beats per minute)

  • formula (str, optional) – Formula for computing th corrected APD, either ‘friderica’ or ‘bazett’, by default ‘friderica’,

Returns:

The corrected APD

Return type:

float

Notes

Friderica formula (default):

\[APD (RR)^{-1/3}\]

Bazett formula:

\[APD (RR)^{-1/2}\]

where \(RR\) is the R-R interval in an ECG. For an action potential this would be equivalent to the inverse of the beating frequency (or 60 divided by the beat rate)

Luo, Shen, et al. “A comparison of commonly used QT correction formulae: the effect of heart rate on the QTc of normal ECGs.” Journal of electrocardiology 37 (2004): 81-90.

property cost_terms#
detect_ead(sigma: float = 1, prominence_level: float = 0.07) Tuple[bool, int | None][source]#

Detect (Early after depolarizations) EADs based on peak prominence.

Parameters:
  • y (Array) – The signal that you want to detect EADs

  • sigma (float) – Standard deviation in the gaussian smoothing kernel Default: 1.0

  • prominence_level (float) – How prominent a peak should be in order to be characterized as an EAD. This value should be between 0 and 1, with a greater value being more prominent. Default: 0.07

Returns:

  • bool – Flag indicating if an EAD is found or not

  • int or None – Index where we found the EAD. If no EAD is found then this will be None. I more than one peaks are found then only the first will be returned.

integrate_apd(factor: float, use_spline: bool = True, normalize: bool = False) float[source]#

Compute the integral of the signals above the APD p line

Parameters:
  • factor (float) – Which APD line

  • use_spline (bool, optional) – Use spline interpolation, by default True

  • normalize (bool, optional) – If true normalize signal first, so that max value is 1.0, and min value is zero before performing the computation, by default False

Returns:

Integral above the APD p line

Return type:

float

is_valid()[source]#

Check if intersection with APD50 line gives two points

maximum_relative_upstroke_velocity(upstroke_duration: int = 50, sigmoid_fit: bool = True)[source]#

Estimate maximum relative upstroke velocity

Parameters:
  • upstroke_duration (int) – Duration in milliseconds of upstroke (Default: 50). This does not have to be exact up should at least be longer than the upstroke.

  • sigmoid_fit (bool) – If True then use a sigmoid function to fit the data of the upstroke and report the maximum derivate of the sigmoid as the maximum upstroke.

maximum_upstroke_velocity(use_spline: bool = True, normalize: bool = False) float[source]#

Compute maximum upstroke velocity

Parameters:
  • use_spline (bool, optional) – Use spline interpolation, by default True

  • normalize (bool, optional) – If true normalize signal first, so that max value is 1.0, and min value is zero before performing the computation, by default False

Returns:

The maximum upstroke velocity

Return type:

float

property parent: Beats | None#

If the beat comes from several Beats object then this will return those Beats

Returns:

The parent Beats

Return type:

Beats

peaks(prominence_level: float = 0.1) List[int][source]#

Return the list of peak indices given a prominence level

tau(a: float) float[source]#

Decay time. Time for the signal amplitude to go from maximum to (1 - a) * 100 % of maximum

Parameters:

a (float) – The value for which you want to estimate the time decay

Returns:

Decay time

Return type:

float

time_above_apd_line(factor: float) float[source]#

Compute the amount of time spent above APD p line

triangulation(low: int = 30, high: int = 80, use_spline: bool = True) float[source]#

Compute the triangulation which is the last intersection of the \(\mathrm{APD} \; p_{\mathrm{high}}\) line minus the last intersection of the \(\mathrm{APD} \; p_{\mathrm{low}}\) line

Parameters:
  • low (int, optional) – Lower APD value, by default 30

  • high (int, optional) – Higher APD value, by default 80

  • use_spline (bool, optional) – Use spline interpolation, by default True.

Returns:

The triangulations

Return type:

float

ttp(use_pacing: bool = True) float[source]#

Computed the time to peak from pacing is triggered to maximum amplitude. Note, if pacing is not provided it will compute the time from the beginning of the trace (which might not be consistent) to the peak.

Parameters:

use_pacing (bool, optional) – If pacing is available compute time to peak from start of packing, by default True

Returns:

Time to peak

Return type:

float

upstroke(a: float) float[source]#

Compute the time from (1-a)*100 % signal amplitude to peak. For example if if a = 0.8 if will compute the time from the starting value of APD80 to the upstroke.

Parameters:

a (float) – Fraction of signal amplitude

Returns:

The upstroke value

Return type:

float

property y_max: float | None#

Return maximum value if specified, otherwise None

property y_normalized: ndarray#

Return normalized signal

property y_rest: float | None#

Return resting value if specified, otherwise None

class ap_features.beat.BeatCollection(y: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float], pacing: ndarray | List[float] | Sequence[float] | None = None, mask: ndarray | List[float] | Sequence[float] | None = None, parent: BeatSeriesCollection | None = None, backend: Backend = Backend.numba)[source]#

Bases: Trace

property num_traces#
property parent: BeatSeriesCollection | None#

If the beat comes from a BeatSeries object then this will return that BeatSeries

Returns:

The parent BeatSeries

Return type:

BeatSeries

class ap_features.beat.BeatSeriesCollection(y: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float] | None, pacing: ndarray | List[float] | Sequence[float] | None = None, backend: Backend = Backend.numba)[source]#

Bases: Trace

property num_beats: List[int]#
class ap_features.beat.Beats(y: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float], pacing: ndarray | List[float] | Sequence[float] | None = None, background_correction_method: BackgroundCorrection = BackgroundCorrection.none, zero_index: int | None = None, background_correction_kernel: int = 0, backend: Backend = Backend.numba, intervals: List[Interval] | None = None, chopping_options: Dict[str, float] | None = None, force_positive: bool = False)[source]#

Bases: Trace

aligned_beats(N=200) List[Beat][source]#
apd_slope(factor: float, corrected_apd: bool = False) Tuple[float, float][source]#
as_beat() Beat[source]#

Convert trace from Beats to Beat

average_beat(filters: Sequence[Filters] | None = None, N: int = 200, x: float = 1.0, apd_point: float = 50) Beat[source]#

Compute an average beat based on aligning the individual beats

Parameters:
  • filters (Optional[Sequence[_filters.Filters]], optional) – A list of filters that should be used to decide which beats that should be included in the averaging, by default None

  • N (int, optional) – Length of output signal, by default 200. Note that the output signal will be interpolated so that it has this length. This is done because the different beats might have different lengths.

  • x (float, optional) – The number of standard deviations used in the filtering, by default 1.0

Returns:

An average beat.

Return type:

Beat

property background: ndarray#
property beat_rate: float#

The beat rate, i.e number of beats per minute, which is simply 60 divided by the beating frequency

property beat_rates: List[float]#

Beat rate for all beats

Returns:

List of beat rates

Return type:

List[float]

property beating_frequencies: Sequence[float]#

Get the frequency for each beat

Returns:

List of frequencies

Return type:

List[float]

property beating_frequency: float#

The median frequency of all beats

property beats: List[Beat]#

Chop signal into individual beats. You can also pass in any options that should be provided to the chopping algorithm.

Returns:

A list of chopped beats

Return type:

List[Beat]

chop_data(threshold_factor=0.5, min_window=50, max_window=5000, N=None, extend_front=None, extend_end=None, ignore_pacing=False, intervals=None)[source]#
property chopped_data: ChoppedData#
correct_background(background_correction_method: BackgroundCorrection, copy: bool = True) Beats[source]#
filter(kernel_size: int = 3, copy: bool = True) Beats[source]#
filter_beats(filters: Sequence[Filters], x: float = 1.0) List[Beat][source]#

Get a subset of the chopped beats based on similarities in different features.

Parameters:
  • filters (Sequence[_filters.Filters]) – A list of filters that should be used for filtering

  • x (float, optional) – How many standard deviations away from the mean the different beats should be to be included, by default 1.0

Returns:

A list of filtered beats

Return type:

List[Beat]

property intervals: List[Beat]#

A ist of time intervals for each beat

property num_beats: int#
property original_y: ndarray#
plot_beats(ylabel: str = '', align: bool = False, fname: str = '')[source]#
remove_points(t_start: float, t_end: float) Beats[source]#
remove_spikes(spike_duration: int) Beats[source]#
property y: ndarray#

The trace

class ap_features.beat.State(y: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float] | None, pacing: ndarray | List[float] | Sequence[float] | None = None, backend: Backend = Backend.numba)[source]#

Bases: Trace

property cost_terms#
property num_states#
class ap_features.beat.StateCollection(y: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float], pacing: ndarray | List[float] | Sequence[float] | None = None, mask: ndarray | List[float] | Sequence[float] | None = None, parent: StateSeriesCollection | None = None)[source]#

Bases: Trace

property cost_terms#
property mask: ndarray | List[float] | Sequence[float] | None#
property num_states#
property num_traces#
property parent: StateSeriesCollection | None#

If the beat comes from a BeatSeries object then this will return that BeatSeries

Returns:

The parent BeatSeries

Return type:

BeatSeries

class ap_features.beat.StateSeriesCollection(y: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float] | None, pacing: ndarray | List[float] | Sequence[float] | None = None, backend: Backend = Backend.numba)[source]#

Bases: Trace

property num_beats: List[int]#
class ap_features.beat.Trace(y: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float] | None, pacing: ndarray | List[float] | Sequence[float] | None = None, backend: Backend = Backend.numba)[source]#

Bases: object

amp() float[source]#

Return the difference between the maximum and minimum value

as_spline(k: int = 3, s: int | None = None) UnivariateSpline[source]#

Convert trace to spline

Parameters:
  • k (int, optional) – Degree of the smoothing spline. Must be 1 <= k <= 5. Default is k = 3, a cubic spline, by default 3.

  • s (float or None, optional) – Positive smoothing factor used to choose the number of knots. If 0, spline will interpolate through all data points, by default 0

Returns:

A spline representation of the trace

Return type:

UnivariateSpline

copy(**kwargs)[source]#

Create a copy of the trace

property duration: float#

The duration of the trace, i.e last time point minus the first

ensure_time_unit(unit: str) None[source]#

Convert time to milliseconds or seconds

Parameters:

unit (str) – A string with ‘ms’ or ‘s’

max() float[source]#

Return the maximum value of the trace

min() float[source]#

Return the minimum value of the trace

property pacing: ndarray#

Array of pacing amplitudes. If no pacing info is available, then this will be an array of zeros with same length as the trace

plot(fname: str = '', include_pacing: bool = False, include_background: bool = False, ylabel: str = '')[source]#

Plot the trace with matplotlib

Parameters:
  • fname (str, optional) – Name of the figure to be saved. If not provided the figure will note be saved, but you can show by calling plt.show

  • include_pacing (bool, optional) – Whether to include pacing in the plot, by default False

  • include_background (bool, optional) – Whether to include the background, by default False

  • ylabel (str, optional) – Label on the y-axis, by default “”

Returns:

If matplotlib is installed it will return a tuple containing the figure and the axes.

Return type:

Tuple[plt.Figure, plt.Axes] | None

slice(start: float, end: float, copy: bool = True) Trace[source]#

Create a slice of the original trace

Parameters:
  • start (float) – Start time of slice

  • end (float) – End time of slice

  • copy (bool, optional) – If true create a copy of the original array otherwise return a slice of the original array, by default True

Returns:

A sliced trace

Return type:

Trace

property t: ndarray#

The time stamps

property time_unit: str#

The time unit ‘ms’ or ‘s’

property y: ndarray#

The trace

ap_features.beat.align_beats(beats: List[Beat], apd_point=50, N=200, parent=None, strategy: APDPointStrategy = APDPointStrategy.big_diff_plus_one)[source]#
ap_features.beat.apd_slope(beats: List[Beat], factor: float, corrected_apd: bool = False) Tuple[float, float][source]#

Compute a linear interpolation of the apd values for each beat. This is useful in order to see if there is a correlation between the APD values and the beat number. If the resulting the slope is relatively close to zero there is no such dependency.

Parameters:
  • beats (List[Beat]) – List of beats

  • factor (float) – The apd value

  • corrected_apd (bool, optional) – Whether to use corrected or regular apd, by default False

Returns:

A tuple with the (constant, slope) for the linear interpolation. The slope here can be interpreted as the change in APD per minute.

Return type:

Tuple[float, float]

ap_features.beat.average_beat(beats: List[Beat], N: int = 200, filters: Sequence[Filters] | None = None, x: float = 1.0, apd_point: float = 50) Beat[source]#
ap_features.beat.chopped_data_to_beats(chopped_data: ChoppedData, parent: Beats | None = None) List[Beat][source]#

Convert a ChoppedData object to a list of Beats

Parameters:
  • chopped_data (chopping.ChoppedData) – The chopped data

  • parent (Optional[Beats], optional) – Parent trace, by default None

Returns:

List of Beats

Return type:

List[Beat]

ap_features.beat.copy_function(copy: bool)[source]#
ap_features.beat.filter_beats(beats: List[Beat], filters: Sequence[Filters], x: float = 1.0) List[Beat][source]#

Filter beats based of similarities of the filters

Parameters:
  • beats (List[Beat]) – List of beats

  • filters (Sequence[_filters.Filters]) – List of filters

  • x (float, optional) – How many standard deviations away from the mean the different beats should be to be included, by default 1.0

Returns:

A list of filtered beats

Return type:

List[Beat]

Raises:

_filters.InvalidFilter – If a filter in the list of filters is not valid.

ap_features.beat.identity(x: Any, y: Any | None = None, z: Any | None = None) Any[source]#
ap_features.beat.remove_bad_indices(feature_list: List[List[float]], bad_indices: Set[int])[source]#

ap_features.chopping module#

class ap_features.chopping.ChoppedData(data, times, pacing, parameters, intervals, upstroke_times)#

Bases: tuple

data#

Alias for field number 0

intervals#

Alias for field number 4

pacing#

Alias for field number 2

parameters#

Alias for field number 3

times#

Alias for field number 1

upstroke_times#

Alias for field number 5

exception ap_features.chopping.EmptyChoppingError[source]#

Bases: RuntimeError

class ap_features.chopping.Interval(start, end)#

Bases: tuple

end#

Alias for field number 1

start#

Alias for field number 0

exception ap_features.chopping.InvalidChoppingError[source]#

Bases: RuntimeError

ap_features.chopping.check_intervals(intervals: List[Interval]) None[source]#

Check starts and ends and make sure that they are consistent

Parameters:
  • starts (Array) – List of start points

  • ends (Array) – List of end points

Returns:

starts, ends

Return type:

Tuple[Array, Array]

Raises:
ap_features.chopping.chop_data(data: ndarray | List[float] | Sequence[float], time: ndarray | List[float] | Sequence[float], **kwargs) ChoppedData[source]#

Chop data into individual beats

Parameters:
  • data (Array) – The signal amplitude

  • time (Array) – Time stamps

Returns:

Data chopped into individual beats

Return type:

ChoppedData

ap_features.chopping.chop_data_with_pacing(data: ndarray | List[float] | Sequence[float], time: ndarray | List[float] | Sequence[float], pacing: ndarray | List[float] | Sequence[float], extend_front: float = 0, extend_end: float = 0, min_window: float = 300, max_window: float = 2000, intervals: List[Interval] | None = None, **kwargs) ChoppedData[source]#

Chop data based on pacing

Parameters:
  • data (Array) – The data to be chopped

  • time (Array) – The time stamps for the data

  • pacing (Array) – The pacing amplitude

  • extend_front (float) – Extend the start of each sub-signal this many milliseconds before the threshold is detected. Default: 0 ms

  • extend_end (float) – Extend the end of each sub-signal this many milliseconds. Default 0 ms.

  • min_window (float) – Minimum size of chopped signal

  • max_window (float) – Minimum size of chopped signal

Returns:

Named tuple with the chopped data

Return type:

ChoppedData

Notes

We first find where the pacing for each beat starts by finding the indices where the pacing amplitude goes form zero to something positive. Then we iterate over these indices and let the start of each beat be the start of the pacing (minus extend_front, which has a default value of zero) and the end will be the time of the beginning of the next beat (plus extend_end which is also has as default value of zero).

ap_features.chopping.chop_data_without_pacing(data: ndarray | List[float] | Sequence[float], time: ndarray | List[float] | Sequence[float], threshold_factor: float = 0.5, min_window: float = 50, max_window: float = 5000, N: int | None = None, extend_front: float | None = None, extend_end: float | None = None, intervals: List[Interval] | None = None, **kwargs) ChoppedData[source]#

Chop data into beats

Parameters:
  • data (list or array) – The data that you want to chop

  • time (list or array) – The time points. If none is provided time will be just the indices.

  • threshold_factor (float) – Thresholds for where the signal should be chopped (Default: 0.3)

  • extend_front (scalar) – Extend the start of each sub-signal this many milliseconds before the threshold is detected. Default: 300 ms

  • extend_end (scalar) – Extend the end of each sub-signal this many milliseconds. Default 60 ms.

  • min_window (scalar) – Length of minimum window

  • max_window (scalar) – Length of maximum window

  • N (int) – Length of output signals

Returns:

The chopped data

Return type:

ChoppedData

Notes

The signals extracted from the MPS data consist of data from several beats, and in order to e.g compute properties from an average beat, we need a way to chop the signal into different beats. Suppose we have the signal \(y(t), t \in [0, T]\), where we assume that filtering and background correction have already been applied. Suppose we have \(N\) sub-signals, \(z_1, z_2, \cdots, z_N\), each representing one beat. Let \(\tau_i = [\tau_i^0, \tau_i^1], i = 1, \cdots N\) be non-empty intervals corresponding to the support of each sub-signal ( \(\tau_i = \{ t \in [0,T]: z_i(t) \neq 0 \}\)), with \(\tau_i^j < \tau_{i+1}^j \forall i\) and \(\bigcup_{i=1}^N \tau_i = [0, T]\). Note that the intersection :math:` tau_i cap tau_{i+1}` can be non-empty. The aim is now to find good candidates for \(\tau_i^j , i = 1 \cdots N, j = 0,1\). We have two different scenarios, namely with or without pacing information.

If pacing information is available we can e.g set \(\tau_i^0\) to be 30 ms before each stimulus is applied and \(\tau_i^1\) to be 60 ms before the next stimulus is applied.

If pacing information is not available then we need to estimate the beginning and end of each interval. We proceed as follows:

  1. Choose some threshold value \(\eta\) (default \(\eta = 0.5\)), and compute \(y_{\eta}\)

  2. Let \(h = y - y_{\eta}\), and define the set

\[\mathcal{T}_0 = \{ t : h(t) = 0 \}\]
  1. Sort the elements of \(\mathcal{T}_0\) in increasing order, i.e \(\mathcal{T}_0 = (t_1, t_2, \cdots, t_M)\), with \(t_i < t_{i+1}\).

  2. Select a minimum duration of a beat \(\nu\) (default \(\nu = 50\) ms) and define the set

\[\mathcal{T}_1 = \{t_i \in \mathcal{T}_0 : t_{i+1} - t_i > \eta \}\]

to be be the subset of \(\mathcal{T}_0\) where the difference between to subsequent time stamps are greater than \(\eta\).

  1. Let \(\delta > 0\) (default \(\delta\) = 0.1 ms), and set

\[\begin{split}\{\tilde{\tau_1}^0, \tilde{\tau_2}^0, \cdots,\tilde{\tau_N}^0\} := \{ t \in \mathcal{T}_1 : h(t + \delta) > 0 \} \\ \{\tilde{\tau_1}^1, \tilde{\tau_2}^1, \cdots,\tilde{\tau_N}^1\} := \{ t \in \mathcal{T}_1 : h(t + \delta) < 0 \} \\\end{split}\]

Note that we need to also make sure that all beats have a start and an end.

  1. Extend each sub-signal at the beginning and end, i,e if \(a,b \geq 0\), define

\[\begin{split}\tau_i^0 = \tilde{\tau_i}^0 - a \\ \tau_i^1 = \tilde{\tau_i}^1 + b\end{split}\]
ap_features.chopping.chop_intervals(data: ndarray | List[float] | Sequence[float], time: ndarray | List[float] | Sequence[float], intervals: List[Interval], pacing: ndarray | List[float] | Sequence[float] | None = None, N: int | None = None, max_window: float = 2000, min_window: float = 50) Tuple[List[ndarray | List[float] | Sequence[float]], List[ndarray | List[float] | Sequence[float]], List[ndarray | List[float] | Sequence[float]]][source]#

Chop the data based on starts and ends

Parameters:
  • data (Array) – The signal amplitude

  • time (Array) – The time stamps

  • intervals (List[Interval]) – List of intervals with start and ends

  • pacing (Optional[Array], optional) – Pacing amplitude, by default None

  • N (Optional[int], optional) – Number of points in each chopped signal, by default None. If this is different from None then each signal will be interpolated so that it has N points

  • max_window (float, optional) – Maximum allowed size of a chopped signal, by default 2000

  • min_window (float, optional) – Minimum allowed size of a chopped signal, by default 50

Returns:

Chopped data, times, pacing

Return type:

Tuple[List[Array], List[Array], List[Array]]

ap_features.chopping.create_intervals(starts: ndarray | List[float] | Sequence[float], ends: ndarray | List[float] | Sequence[float]) List[Interval][source]#
ap_features.chopping.cutoff_final_interval(intervals: List[Interval], end_time: float) List[Interval][source]#
ap_features.chopping.default_chopping_options()[source]#
ap_features.chopping.extend_intervals(intervals, extend_front, extend_end)[source]#
ap_features.chopping.filter_start_ends_in_chopping(starts: ndarray | List[float] | Sequence[float], ends: ndarray | List[float] | Sequence[float], extend_front: float | None = None, extend_end: float | None = None) List[Interval][source]#

Adjust start and ends based on extend_front and extent_end

Parameters:
  • starts (Array) – The start points

  • ends (Array) – The end points

  • extend_front (Optional[float], optional) – How much you want to extent the front. If not provided it will try to use the half distance between the minimum start and end, by default None

  • extend_end (Optional[float], optional) – How much you want to extend the end. If not provided it will try to use the half distance between the minimum start and end, by default None

Returns:

List of the filtered intervals

Return type:

List[Interval]

Raises:
ap_features.chopping.find_pacing_indices(pacing: ndarray | List[float] | Sequence[float]) ndarray[source]#

Return indices of where the pacing array changes from a low to a high values

Parameters:

pacing (list or np.ndarray) – The array with pacing amplitude

Returns:

List of indices where the pacing is triggered

Return type:

np.ndarray

ap_features.chopping.find_start_and_ends(time: ndarray | List[float] | Sequence[float], data: ndarray | List[float] | Sequence[float], threshold_factor: float, min_window: float, extend_front: float | None, extend_end: float | None) Tuple[List[Interval], ndarray | List[float] | Sequence[float]][source]#

Find the starts and ends of a signal.

Parameters:
  • time (Array) – Array of time stamps

  • data (Array) – Signal amplitude

  • threshold_factor (float) – Threshold for where to chop

  • min_window (float) – Length of minimum chopped signal

  • extend_front (Optional[float]) – How many ms the signal should be extended at the front

  • extend_end (Optional[float]) – How many ms the signal should be extended at the end

Returns:

(starts, ends) for interval, and upstroke times

Return type:

Tuple[List[Interval], Array]

Raises:

EmptyChoppingError – If starts or ends is or become zero

ap_features.chopping.find_start_end_index(time_stamps: ndarray | List[float] | Sequence[float], start: float, end: float) Tuple[int, int][source]#
ap_features.chopping.get_extend_value(extend: float | None, intervals: List[Interval], default: float) float[source]#
ap_features.chopping.locate_chop_points(time: ndarray | List[float] | Sequence[float], data: ndarray | List[float] | Sequence[float], threshold_factor: float, min_window: float = 50, eps: float | None = None) Tuple[ndarray | List[float] | Sequence[float], ndarray | List[float] | Sequence[float], ndarray | List[float] | Sequence[float]][source]#

Find the points where to chop

Parameters:
  • time (Array) – Time stamps

  • data (Array) – The signal amplitude

  • threshold_factor (float) – The threshold for where to chop

  • min_window (float, optional) – Minimum allow size of signal in ms, by default 50

  • eps (float, optional) – Perturbation use to find the sign of the signal derivative, by default 0.1

Returns:

starts, ends, zeros

Return type:

Tuple[Array, Array, Array]

ap_features.chopping.pacing_to_start_ends(time: ndarray | List[float] | Sequence[float], pacing: ndarray | List[float] | Sequence[float], extend_front: float, extend_end: float, add_final: bool = True) Tuple[List[Interval], ndarray | List[float] | Sequence[float]][source]#

Convert an array of pacing amplitudes to start and end points

Parameters:
  • time (Array) – Time stamps

  • pacing (Array) – Array of pacing amplitudes

  • extend_front (float) – How many ms you want to extend the array in front

  • extend_end (float) – How many ms you want to extend the array at the end

  • add_final (bool, optional) – Whether you want to add a final end point for the last index, by default True

Returns:

(starts, ends) for interval, and upstroke times

Return type:

Tuple[List[Interval], Array]

ap_features.features module#

class ap_features.features.APDCoords(x1, x2, y1, y2, yth)#

Bases: tuple

x1#

Alias for field number 0

x2#

Alias for field number 1

y1#

Alias for field number 2

y2#

Alias for field number 3

yth#

Alias for field number 4

class ap_features.features.APDPointStrategy(value)[source]#

Bases: str, Enum

An enumeration.

big_diff_last = 'big_diff_last'#
big_diff_plus_one = 'big_diff_plus_one'#
first_last = 'first_last'#
exception ap_features.features.UnequalLengthError[source]#

Bases: RuntimeError

class ap_features.features.Upstroke(index, value, upstroke, dt, x0, sigmoid, time_APD20_to_APD80)#

Bases: tuple

dt#

Alias for field number 3

index#

Alias for field number 0

sigmoid#

Alias for field number 5

time_APD20_to_APD80#

Alias for field number 6

upstroke#

Alias for field number 2

value#

Alias for field number 1

x0#

Alias for field number 4

ap_features.features.all_cost_terms(arr: ndarray, t: ndarray, mask: ndarray | None = None, backend: Backend = Backend.numba, normalize_time: bool = True) ndarray[source]#
ap_features.features.apd(factor: float, V: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float], v_r: float | None = None, v_max: float | None = None, use_spline: bool = True, backend: Backend = Backend.python) float[source]#

Return the action potential duration at the given factor repolarization, so that factor = 0 would be zero, and factor = 1 given the time from triggering to potential is down to resting potential.

Parameters:
  • factor (int) – The APD factor between 0 and 100

  • V (Array) – The signal

  • t (Array) – The time stamps

  • v_r (Optional[float], optional) – The resting value, by default None. If None the minimum value is chosen

  • v_max (Optional[float], optional) – The maximum value, by default None. If None the maximum value is chosen

  • use_spline (bool, optional) – Use spline interpolation, by default True. Only applicable for python Backend.

  • backend (utils.Backend, optional) – Which backend to use by default Backend.python. Choices, ‘python’, ‘numba’

Returns:

  • float – The action potential duration

  • .. Note:: – If the signal has more intersection than two with the APX_X line, then the first and second occurrence will be used.

Raises:
  • ValueError – If factor is outside the range of (0, 100)

  • ValueError – If shape of x and y does not match

  • RunTimeError – In unable to compute APD

Notes

If the signal represent voltage, we would like to compute the action potential duration at a given factor of the signal. Formally, Let \(p \in (0, 100)\), and define

\[y_p = \tilde{y} - \left(1- \frac{p}{100} \right).\]

Now let \(\mathcal{T}\) denote the set of solutions of \(y_p = 0\), i.e

\[y_p(t) = 0, \;\; \forall t \in \mathcal{T}\]

Then there are three different scenarios; \(\mathcal{T}\) contains one, two or more than two elements. Note that \(\mathcal{T}\) cannot be empty (because of the intermediate value theorem). The only valid scenario is the case when \(\mathcal{T}\) contains two (or more) elements. In this case we define

\[\mathrm{APD} \; p = \max \mathcal{T} - \min \mathcal{T}\]

for \(p < 0.5\) and

\[\mathrm{APD} \; p = \min \mathcal{T} / \min \mathcal{T} - \min \mathcal{T}\]
ap_features.features.apd_coords(factor: float, V: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float], v_r: float | None = None, v_max: float | None = None, use_spline=True) APDCoords[source]#
Return the coordinates of the start and stop

of the APD, and not the duration itself

Parameters:
  • factor (int) – The APD factor between 0 and 100.

  • V (Array) – The signal

  • t (Array) – The time stamps

  • v_r (Optional[float], optional) – The resting value, by default None. If None the minimum value is chosen

  • v_max (Optional[float], optional) – The maximum value, by default None. If None the maximum value is chosen

  • use_spline (bool, optional) – Use spline interpolation, by default True. Only applicable for python Backend.

Returns:

APD coordinates

Return type:

APDCoords

ap_features.features.apd_point(factor: float, V: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float], v_r: float | None = None, v_max: float | None = None, use_spline=True, strategy: APDPointStrategy = APDPointStrategy.big_diff_plus_one) Tuple[float, float][source]#

Returns exactly two intersections of the APD p line.

Parameters:
  • factor (int) – The APD line

  • V (np.ndarray) – The signal

  • t (np.ndarray) – The time stamps

  • v_r (Optional[float], optional) – The resting value, by default None. If None the minimum value is chosen

  • v_max (Optional[float], optional) – The maximum value, by default None. If None the maximum value is chosen

  • use_spline (bool, optional) – Use spline interpolation or not, by default True

  • strategy (APDPointStrategy) – Strategy for picking two apd points, either first_last, big_diff_plus_one or big_diff_last, by default big_diff_plus_one

Returns:

Two points corresponding to the first and second intersection of the APD p line

Return type:

Tuple[float, float]

Raises:

RuntimeError – If spline interpolation fails

Notes

Different strategies are used based on the number of intersections. If only two intersections are used, we are done, while if there are fewer then the same value will be returned for both the start and end. If no intersections are found the value 0 will be used. If more than two intersections are found then the neighboring intersections with the largest gap will be returned.

ap_features.features.apd_points(factor: float, V: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float], v_r: float | None = None, v_max: float | None = None, use_spline: bool = True) List[float][source]#

Returns the indices of all the intersections of the APD p line

Parameters:
  • factor (int) – The APD line

  • V (np.ndarray) – The signal

  • t (np.ndarray) – The time stamps

  • v_r (Optional[float], optional) – The resting value, by default None. If None the minimum value is chosen

  • v_max (Optional[float], optional) – The maximum value, by default None. If None the maximum value is chosen

  • use_spline (bool, optional) – Use spline interpolation or not, by default True

Returns:

All indices of points intersecting the APD p line

Return type:

List[float]

Raises:

RuntimeError – If spline interpolation fails

ap_features.features.apd_up_xy(y: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float], low: int, high: int, backend: Backend = Backend.python) float[source]#

Find the duration between first intersection (i.e during the upstroke) of two APD lines

Parameters:
  • t (np.ndarray) – Time values

  • y (np.ndarray) – The trace

  • low (int) – First APD line (value between 0 and 100)

  • high (int) – Second APD line (value between 0 and 100)

  • backend (utils.Backend, optional) – Which backend to use by default Backend.python. Choices, ‘python’, ‘numba’

Returns:

The time between low to high

Return type:

float

ap_features.features.beating_frequency(times: List[ndarray | List[float] | Sequence[float]], unit: str = 'ms') float[source]#

Returns the approximate beating frequency in Hz by finding the average duration of each beat

Parameters:
  • times (List[Array]) – Time stamps of all beats

  • unit (str, optional) – Unit of time, by default “ms”

Returns:

Beating frequency in Hz

Return type:

float

ap_features.features.beating_frequency_from_apd_line(y: ndarray, time: ndarray, unit: str = 'ms') Sequence[float][source]#

Returns the beating frequency in Hz by using the intersection of the APD50 line

Parameters:
  • signals (List[Array]) – The signal values for each beat

  • times (List[Array]) – The time stamps of all beats

  • unit (str, optional) – Unit of time, by default “ms”

Returns:

Beating frequency in Hz for each beat

Return type:

List[float]

ap_features.features.beating_frequency_from_peaks(signals: List[ndarray | List[float] | Sequence[float]], times: List[ndarray | List[float] | Sequence[float]], unit: str = 'ms') Sequence[float][source]#

Returns the beating frequency in Hz by using the peak values of the signals in each beat

Parameters:
  • signals (List[Array]) – The signal values for each beat

  • times (List[Array]) – The time stamps of all beats

  • unit (str, optional) – Unit of time, by default “ms”

Returns:

Beating frequency in Hz for each beat

Return type:

List[float]

ap_features.features.corrected_apd(apd: float, beat_rate: float, formula: str = 'friderica')[source]#

Correct the given APD (or any QT measurement) for the beat rate. normally the faster the HR (or the shorter the RR interval), the shorter the QT interval, and vice versa

Parameters:
  • apd (float) – The action potential duration

  • beat_rate (float) – The beat rate (number of beats per minute)

  • formula (str, optional) – Formula for computing th corrected APD, either ‘friderica’ or ‘bazett’, by default ‘friderica’,

Returns:

The corrected APD

Return type:

float

Notes

Friderica formula (default):

\[APD (RR)^{-1/3}\]

Bazett formula:

\[APD (RR)^{-1/2}\]

where \(RR\) is the R-R interval in an ECG. For an action potential this would be equivalent to the inverse of the beating frequency (or 60 divided by the beat rate)

Luo, Shen, et al. “A comparison of commonly used QT correction formulae: the effect of heart rate on the QTc of normal ECGs.” Journal of electrocardiology 37 (2004): 81-90.

ap_features.features.cost_terms(v: ndarray | List[float] | Sequence[float], ca: ndarray | List[float] | Sequence[float], t_v: ndarray | List[float] | Sequence[float], t_ca: ndarray | List[float] | Sequence[float], backend: Backend = Backend.numba) ndarray[source]#
ap_features.features.cost_terms_trace(y: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float], backend: Backend = Backend.numba) ndarray[source]#
ap_features.features.detect_ead(y: ndarray | List[float] | Sequence[float], sigma: float = 1, prominence_level: float = 0.07) Tuple[bool, int | None][source]#

Detect (Early after depolarizations) EADs based on peak prominence.

Parameters:
  • y (Array) – The signal that you want to detect EADs

  • sigma (float) – Standard deviation in the gaussian smoothing kernel Default: 1.0

  • prominence_level (float) – How prominent a peak should be in order to be characterized as an EAD. This value should be between 0 and 1, with a greater value being more prominent. Default: 0.07

Returns:

  • bool – Flag indicating if an EAD is found or not

  • int or None – Index where we found the EAD. If no EAD is found then this will be None. I more than one peaks are found then only the first will be returned.

Notes

Given a signal \(y\) we want to determine wether we have an EAD present in the signal. EADs are abnormal depolarizations happening after the upstroke in an action potential.

We assume that an EAD occurs between the maximum value of the signal (i.e the peak) and the next minimum value (i.e when the signal is at rest)

To remove noisy patterns we first smooth the signal with a gaussian filter. Then we take out only the part of the signal that is between its maximum and the next minimum values. Then we find the peaks with a Topographic Prominence greater than the given prominence level

ap_features.features.find_upstroke_values(t: ndarray, y: ndarray, upstroke_duration: int = 50, normalize: bool = True) ndarray[source]#
ap_features.features.integrate_apd(y, t=None, factor=30, use_spline=True, normalize=False)[source]#

Compute the integral of the signals above the APD p line

Parameters:
  • y (array) – The signal

  • t (array) – The time points

  • factor (float) – Which APD line, by default 0.3

  • use_spline (bool) – Use spline interpolation (Default : True)

  • normalize (bool) – If true normalize signal first, so that max value is 1.0, and min value is zero before performing the computation.

Returns:

integral – The integral above the line defined by the APD p line.

Return type:

float

Notes

This feature represents the integral of the signal above the horizontal line defined by \(\mathrm{APD} p\). First let

\[y_p = \tilde{y} - \left(1- \frac{p}{100} \right),\]

and let \(t_1\) and \(t_2\) be the two solutions solving \(y_p(t_i) = 0, i=1,2\) (assume that we have 2 solutions only). The integral we are seeking can now be computed as follows:

\[\mathrm{Int} \; p = \int_{t_1}^{t_2} \left[ y - y(t_1) \right] \mathrm{d}t\]
ap_features.features.max_relative_upstroke_velocity(t: ndarray, y: ndarray, upstroke_duration: int = 50, sigmoid_fit: bool = True) Upstroke[source]#

Estimate maximum relative upstroke velocity

Parameters:
  • t (np.ndarray) – Time values

  • y (np.ndarray) – The trace

  • upstroke_duration (int) – Duration in milliseconds of upstroke (Default: 50). This does not have to be exact up should at least be longer than the upstroke.

  • sigmoid_fit (bool) – If True then use a sigmoid function to fit the data of the upstroke and report the maximum derivate of the sigmoid as the maximum upstroke.

Notes

Brief outline of current algorithm: 1. Interpolate data to have time resolution of 1 ms. 2. Find first intersection with ADP50 line 3. Select 25 ms before and after the point found in 2 4. Normalize the 50 ms (upstroke_duration) from 3 so that we have a max and min value of 1 and 0 respectively. If sigmoid fit is True Fit the normalize trace to a sigmoid function and compte the maximum derivate of the sigmoid else: 5. Compute the successive differences in amplitude (i.e delta y) and report the maximum value of these

ap_features.features.maximum_upstroke_velocity(y: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float] | None = None, use_spline: bool = True, normalize: bool = False) float[source]#

Compute maximum upstroke velocity

Parameters:
  • y (array) – The signal

  • t (array) – The time points

  • use_spline (bool) – Use spline interpolation (Default : True)

  • normalize (bool) – If true normalize signal first, so that max value is 1.0, and min value is zero before performing the computation.

Returns:

The maximum upstroke velocity

Return type:

float

Notes

If \(y\) is the voltage, this feature corresponds to the maximum upstroke velocity. In the case when \(y\) is a continuous signal, i.e a 5th order spline interpolant of the data, then we can simply find the roots of the second derivative, and evaluate the derivative at that point, i.e

\[\max \frac{\mathrm{d}y}{\mathrm{d}t} = \frac{\mathrm{d}y}{\mathrm{d}t} (t^*),\]

where

\[\frac{\mathrm{d}^2y}{\mathrm{d}^2t}(t^*) = 0.\]

If we decide to use the discrete version of the signal then the above each derivative is approximated using a forward difference, i.e

\[\frac{\mathrm{d}y}{\mathrm{d}t}(t_i) \approx \frac{y_{i+1}-y_i}{t_{i+1} - t_i}.\]
ap_features.features.sign_change(y: ndarray) ndarray[source]#
ap_features.features.tau(x: ndarray | List[float] | Sequence[float], y: ndarray | List[float] | Sequence[float], a: float = 0.75, backend: Backend = Backend.python) float[source]#

Decay time. Time for the signal amplitude to go from maximum to (1 - a) * 100 % of maximum

Parameters:
  • x (Array) – The time stamps

  • y (Array) – The signal

  • a (float, optional) – The value for which you want to estimate the time decay, by default 0.75. If the value is larger than 1.0 it will be divided by 100

  • backend (utils.Backend, optional) – Which backend to use by default Backend.python. Choices, ‘python’, ‘numba’

Returns:

Decay time

Return type:

float

ap_features.features.time_above_apd_line(V: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float], factor: float, v_r: float | None = None, v_max: float | None = None) float[source]#

Compute the amount of time spent above APD p line

Parameters:
  • V (Array) – Signal

  • t (Array) – Time stamps

  • factor (float) – The p in APD line

  • v_r (Optional[float], optional) – Resting value, by default None

  • v_max (Optional[float], optional) – Maximum value, by default None

Returns:

Total time spent above the APD p line

Return type:

float

ap_features.features.time_to_peak(y: ndarray | List[float] | Sequence[float], x: ndarray | List[float] | Sequence[float], pacing: ndarray | List[float] | Sequence[float] | None = None, backend: Backend = Backend.python) float[source]#

Computed the time to peak from pacing is triggered to maximum amplitude. Note, if pacing is not provided it will compute the time from the beginning of the trace (which might not be consistent) to the peak.

Parameters:
  • y (Array) – The signal

  • x (Array) – The time stamps

  • pacing (Optional[Array], optional) – The pacing amplitude, by default None

  • backend (utils.Backend, optional) – Which backend to use by default Backend.python. Choices, ‘python’, ‘numba’

Returns:

Time to peak

Return type:

float

ap_features.features.triangulation(V: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float], low: int = 30, high: int = 80, v_r: float | None = None, v_max: float | None = None, use_spline: bool = True, backend: Backend = Backend.python) float[source]#

Compute the triangulation which is the last intersection of the \(\mathrm{APD} \; p_{\mathrm{high}}\) line minus the last intersection of the \(\mathrm{APD} \; p_{\mathrm{low}}\) line

Parameters:
  • V (Array) – The signal

  • t (Array) – The time stamps

  • low (int, optional) – Lower APD value, by default 30

  • high (int, optional) – Higher APD value, by default 80

  • v_r (Optional[float], optional) – The resting value, by default None. If None the minimum value is chosen

  • v_max (Optional[float], optional) – The maximum value, by default None. If None the maximum value is chosen

  • use_spline (bool, optional) – Use spline interpolation, by default True. Only applicable for python Backend.

  • backend (utils.Backend, optional) – Which backend to use by default Backend.python. Choices, ‘python’, ‘numba’

Returns:

The triangulation

Return type:

float

ap_features.features.upstroke(x: ndarray | List[float] | Sequence[float], y: ndarray | List[float] | Sequence[float], a: float = 0.8, backend: Backend = Backend.python) float[source]#

Compute the time from (1-a)*100 % signal amplitude to peak. For example if if a = 0.8 if will compute the time from the starting value of APD80 to the upstroke.

Parameters:
  • x (Array) – The time stamps

  • y (Array) – The signal

  • a (float, optional) – Fraction of signal amplitude, by default 0.8. If the value is larger than 1.0 it will be divided by 100

  • backend (utils.Backend, optional) – Which backend to use by default Backend.python. Choices, ‘python’, ‘numba’

Returns:

The upstroke value

Return type:

float

Raises:

ValueError – If a is outside the range of (0, 1)

ap_features.filters module#

class ap_features.filters.Filters(value)[source]#

Bases: str, Enum

An enumeration.

apd30 = 'apd30'#
apd50 = 'apd50'#
apd70 = 'apd70'#
apd80 = 'apd80'#
apd90 = 'apd90'#
length = 'length'#
time_to_peak = 'time_to_peak'#
exception ap_features.filters.InvalidFilter[source]#

Bases: RuntimeError

ap_features.filters.filt(y: ndarray | List[float] | Sequence[float], kernel_size: int = 3)[source]#

Filer signal using a median filter. Default kernel_size is 3

ap_features.filters.filter_signals(data: Sequence[ndarray | List[float] | Sequence[float]] | Dict[Any, ndarray | List[float] | Sequence[float]], x: float = 1, center='mean') Sequence[int][source]#
ap_features.filters.find_spike_points(pacing, spike_duration: int = 7) List[int][source]#

Remove spikes from signal due to pacing.

We assume that there is a spike starting at the time of pacing and the spike disappears after some duration. These points will be deleted from the signal

Parameters:
  • pacing (array) – The pacing amplitude of same length as y

  • spike_duration (int) – Duration of the spikes

Returns:

A list of indices containing the spikes

Return type:

np.ndarray

ap_features.filters.remove_points(x: ndarray | List[float] | Sequence[float], y: ndarray | List[float] | Sequence[float], t_start: float, t_end: float, normalize: bool = True) Tuple[ndarray | List[float] | Sequence[float], ndarray | List[float] | Sequence[float]][source]#

Remove points in x and y between start and end. Also make sure that the new x starts a zero if normalize = True

ap_features.filters.within_x_std(arr: ndarray | List[float] | Sequence[float], x: float = 1.0, center='mean') Sequence[int][source]#

Get the indices in the array that are within x standard deviations from the center value

Parameters:
  • arr (Array) – The array with values

  • x (float, optional) – Number of standard deviations, by default 1.0

  • center (str, optional) – Center value, Either “mean” or “median”, by default “mean”

Returns:

Indices of the values that are within x standard deviations from the center value

Return type:

Sequence[int]

ap_features.plot module#

ap_features.plot.has_matplotlib() bool[source]#
ap_features.plot.plot_beat(beat: Trace, include_pacing: bool = False, include_background: bool = False, ylabel: str = '', fname: str = '')[source]#
ap_features.plot.plot_beats(beats: List[Beat], ylabel: str = '', align: bool = False, fname: str = '')[source]#
ap_features.plot.plot_beats_from_beat(trace: Beats, ylabel: str = '', align: bool = False, fname: str = '')[source]#
ap_features.plot.poincare(trace: Beats, apds: List[int], fname: str = '')[source]#

Create poincare plots for given APDs

Parameters:
  • trace (beat.Beats) – The trace

  • apds (list) – List of APDs to be used, e.g [30, 50, 80] will plot the APS30, APD50 and APD80.

  • fname (str) – Path to filename to save the figure. If not provided plot will be showed and not saved

Notes

For more info see <http://doi.org/10.1371/journal.pcbi.1003202>

Returns:

A dictionary with the key being the \(x\) in APD:math:x and the value begin the points being plotted.

Return type:

dict

ap_features.plot.poincare_from_beats(beats: List[Beat], apds: List[int], fname: str = '')[source]#

Create poincare plots for given APDs

Parameters:
  • beats (List[_beat.Beat]) – List of beats

  • apds (list) – List of APDs to be used, e.g [30, 50, 80] will plot the APS30, APD50 and APD80.

  • fname (str) – Path to filename to save the figure. If not provided plot will be showed and not saved

Notes

For more info see <http://doi.org/10.1371/journal.pcbi.1003202>

Returns:

A dictionary with the key being the \(x\) in APD:math:x and the value begin the points being plotted.

Return type:

dict

ap_features.plot.require_matplotlib(f)[source]#
ap_features.plot.savefig(fig, fname: str) None[source]#

Save figure if fname is not an empty string

Parameters:
  • fig (matplotlib.Figure) – The figure

  • fname (str) – The path

ap_features.testing module#

ap_features.testing.ca_transient(t, tstart=0.05)[source]#
ap_features.testing.fitzhugh_nagumo(t, x, a=-0.3, b=1.4, tau=20.0, Iext=0.23)[source]#

Time derivative of the Fitzhugh-Nagumo neural model. Parameters

Parameters:
  • t (float) – Time (not used)

  • x (np.ndarray) – State of size 2 - (Membrane potential, Recovery variable)

  • a (float) – Parameter in the model, by default -0.3

  • b (float) – Parameter in the model, by default 1.4

  • tau (float) – Time scale, by default 20.0

  • Iext (float) – Constant stimulus current, by default 0.23

Returns:

dx/dt - size 2

Return type:

np.ndarray

ap_features.utils module#

class ap_features.utils.Backend(value)[source]#

Bases: str, Enum

An enumeration.

numba = 'numba'#
python = 'python'#
ap_features.utils.find_pacing_period(pacing_data, pacing_amp=5)[source]#

Find period of pacing in pacing data

Parameters:
  • pacing_data (array) – The pacing data

  • pacing_amp (float) – The stimulus amplitude

ap_features.utils.interpolate(t: ndarray, trace: ndarray, dt: float = 1.0)[source]#
ap_features.utils.intersection(data: Sequence[Sequence[int]] | Dict[Any, Sequence[int]]) Sequence[int][source]#

Get intersection of all values in a dictionary or a list of lists

Parameters:

data (Union[Sequence[Sequence[int]], Dict[str, Sequence[int]]]) – Input data

Returns:

The intersection

Return type:

Sequence[int]

ap_features.utils.list_cost_function_terms()[source]#
ap_features.utils.list_cost_function_terms_trace(key='')[source]#
ap_features.utils.normalize_signal(V, v_r: float | None = None, v_max: float | None = None)[source]#

Normalize signal to have maximum value 1 and zero being the value equal to v_r (resting value). If v_r is not provided the minimum value in V will be used as v_r

Parameters:
  • V (array) – The signal

  • v_r (Optional[float], optional) – The resting value, by default None. If None the minimum value is chosen

  • v_max (Optional[float], optional) – The maximum value, by default None. If None the maximum value is chosen

ap_features.utils.numpyfy(y) ndarray[source]#
ap_features.utils.time_unit(time_stamps)[source]#
ap_features.utils.valid_index(arr: ndarray | List[float] | Sequence[float], index: int) ndarray[source]#

Module contents#

ap_features.BC#

alias of BackgroundCorrection

class ap_features.Backend(value)[source]#

Bases: str, Enum

An enumeration.

numba = 'numba'#
python = 'python'#
class ap_features.Beat(y: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float], pacing: ndarray | List[float] | Sequence[float] | None = None, y_rest: float | None = None, y_max: float | None = None, parent: Beats | None = None, backend: Backend = Backend.numba, beat_number: int | None = None)[source]#

Bases: Trace

apd(factor: float, use_spline: bool = True) float[source]#

The action potential duration

Parameters:
  • factor (int) – Integer between 0 and 100

  • use_spline (bool, optional) – Use spline interpolation, by default True.

Returns:

action potential duration

Return type:

float

apd_point(factor: float, use_spline: bool = True, strategy: APDPointStrategy = APDPointStrategy.big_diff_plus_one) Tuple[float, float][source]#

Return the first and second intersection of the APD p line

Parameters:
  • factor (int) – The APD

  • use_spline (bool, optional) – Use spline interpolation or not, by default True

Returns:

Two points corresponding to the first and second intersection of the APD p line

Return type:

Tuple[float, float]

apd_points(factor: float, use_spline: bool = True) List[float][source]#

Return all intersections of the APD p line

Parameters:
  • factor (int) – The APD

  • use_spline (bool, optional) – Use spline interpolation or not, by default True

Returns:

Two points corresponding to the first and second intersection of the APD p line

Return type:

List[float]

apd_up_xy(low, high)[source]#

Find the duration between first intersection (i.e during the upstroke) of two APD lines

Parameters:
  • low (int) – First APD line (value between 0 and 100)

  • high (int) – Second APD line (value between 0 and 100)

Returns:

The time between low to high

Return type:

float

as_beats() Beats[source]#

Convert trace from Beat to Beats

capd(factor: float, beat_rate: float | None = None, formula: str = 'friderica', use_spline: bool = True, use_median_beat_rate: bool = False) float[source]#

Correct the given APD (or any QT measurement) for the beat rate. normally the faster the HR (or the shorter the RR interval), the shorter the QT interval, and vice versa

Parameters:
  • factor (int) – Integer between 0 and 100

  • beat_rate (float) – The beat rate (number of beats per minute)

  • formula (str, optional) – Formula for computing th corrected APD, either ‘friderica’ or ‘bazett’, by default ‘friderica’,

Returns:

The corrected APD

Return type:

float

Notes

Friderica formula (default):

\[APD (RR)^{-1/3}\]

Bazett formula:

\[APD (RR)^{-1/2}\]

where \(RR\) is the R-R interval in an ECG. For an action potential this would be equivalent to the inverse of the beating frequency (or 60 divided by the beat rate)

Luo, Shen, et al. “A comparison of commonly used QT correction formulae: the effect of heart rate on the QTc of normal ECGs.” Journal of electrocardiology 37 (2004): 81-90.

property cost_terms#
detect_ead(sigma: float = 1, prominence_level: float = 0.07) Tuple[bool, int | None][source]#

Detect (Early after depolarizations) EADs based on peak prominence.

Parameters:
  • y (Array) – The signal that you want to detect EADs

  • sigma (float) – Standard deviation in the gaussian smoothing kernel Default: 1.0

  • prominence_level (float) – How prominent a peak should be in order to be characterized as an EAD. This value should be between 0 and 1, with a greater value being more prominent. Default: 0.07

Returns:

  • bool – Flag indicating if an EAD is found or not

  • int or None – Index where we found the EAD. If no EAD is found then this will be None. I more than one peaks are found then only the first will be returned.

integrate_apd(factor: float, use_spline: bool = True, normalize: bool = False) float[source]#

Compute the integral of the signals above the APD p line

Parameters:
  • factor (float) – Which APD line

  • use_spline (bool, optional) – Use spline interpolation, by default True

  • normalize (bool, optional) – If true normalize signal first, so that max value is 1.0, and min value is zero before performing the computation, by default False

Returns:

Integral above the APD p line

Return type:

float

is_valid()[source]#

Check if intersection with APD50 line gives two points

maximum_relative_upstroke_velocity(upstroke_duration: int = 50, sigmoid_fit: bool = True)[source]#

Estimate maximum relative upstroke velocity

Parameters:
  • upstroke_duration (int) – Duration in milliseconds of upstroke (Default: 50). This does not have to be exact up should at least be longer than the upstroke.

  • sigmoid_fit (bool) – If True then use a sigmoid function to fit the data of the upstroke and report the maximum derivate of the sigmoid as the maximum upstroke.

maximum_upstroke_velocity(use_spline: bool = True, normalize: bool = False) float[source]#

Compute maximum upstroke velocity

Parameters:
  • use_spline (bool, optional) – Use spline interpolation, by default True

  • normalize (bool, optional) – If true normalize signal first, so that max value is 1.0, and min value is zero before performing the computation, by default False

Returns:

The maximum upstroke velocity

Return type:

float

property parent: Beats | None#

If the beat comes from several Beats object then this will return those Beats

Returns:

The parent Beats

Return type:

Beats

peaks(prominence_level: float = 0.1) List[int][source]#

Return the list of peak indices given a prominence level

tau(a: float) float[source]#

Decay time. Time for the signal amplitude to go from maximum to (1 - a) * 100 % of maximum

Parameters:

a (float) – The value for which you want to estimate the time decay

Returns:

Decay time

Return type:

float

time_above_apd_line(factor: float) float[source]#

Compute the amount of time spent above APD p line

triangulation(low: int = 30, high: int = 80, use_spline: bool = True) float[source]#

Compute the triangulation which is the last intersection of the \(\mathrm{APD} \; p_{\mathrm{high}}\) line minus the last intersection of the \(\mathrm{APD} \; p_{\mathrm{low}}\) line

Parameters:
  • low (int, optional) – Lower APD value, by default 30

  • high (int, optional) – Higher APD value, by default 80

  • use_spline (bool, optional) – Use spline interpolation, by default True.

Returns:

The triangulations

Return type:

float

ttp(use_pacing: bool = True) float[source]#

Computed the time to peak from pacing is triggered to maximum amplitude. Note, if pacing is not provided it will compute the time from the beginning of the trace (which might not be consistent) to the peak.

Parameters:

use_pacing (bool, optional) – If pacing is available compute time to peak from start of packing, by default True

Returns:

Time to peak

Return type:

float

upstroke(a: float) float[source]#

Compute the time from (1-a)*100 % signal amplitude to peak. For example if if a = 0.8 if will compute the time from the starting value of APD80 to the upstroke.

Parameters:

a (float) – Fraction of signal amplitude

Returns:

The upstroke value

Return type:

float

property y_max: float | None#

Return maximum value if specified, otherwise None

property y_normalized: ndarray#

Return normalized signal

property y_rest: float | None#

Return resting value if specified, otherwise None

class ap_features.BeatCollection(y: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float], pacing: ndarray | List[float] | Sequence[float] | None = None, mask: ndarray | List[float] | Sequence[float] | None = None, parent: BeatSeriesCollection | None = None, backend: Backend = Backend.numba)[source]#

Bases: Trace

property num_traces#
property parent: BeatSeriesCollection | None#

If the beat comes from a BeatSeries object then this will return that BeatSeries

Returns:

The parent BeatSeries

Return type:

BeatSeries

class ap_features.Beats(y: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float], pacing: ndarray | List[float] | Sequence[float] | None = None, background_correction_method: BackgroundCorrection = BackgroundCorrection.none, zero_index: int | None = None, background_correction_kernel: int = 0, backend: Backend = Backend.numba, intervals: List[Interval] | None = None, chopping_options: Dict[str, float] | None = None, force_positive: bool = False)[source]#

Bases: Trace

aligned_beats(N=200) List[Beat][source]#
apd_slope(factor: float, corrected_apd: bool = False) Tuple[float, float][source]#
as_beat() Beat[source]#

Convert trace from Beats to Beat

average_beat(filters: Sequence[Filters] | None = None, N: int = 200, x: float = 1.0, apd_point: float = 50) Beat[source]#

Compute an average beat based on aligning the individual beats

Parameters:
  • filters (Optional[Sequence[_filters.Filters]], optional) – A list of filters that should be used to decide which beats that should be included in the averaging, by default None

  • N (int, optional) – Length of output signal, by default 200. Note that the output signal will be interpolated so that it has this length. This is done because the different beats might have different lengths.

  • x (float, optional) – The number of standard deviations used in the filtering, by default 1.0

Returns:

An average beat.

Return type:

Beat

property background: ndarray#
property beat_rate: float#

The beat rate, i.e number of beats per minute, which is simply 60 divided by the beating frequency

property beat_rates: List[float]#

Beat rate for all beats

Returns:

List of beat rates

Return type:

List[float]

property beating_frequencies: Sequence[float]#

Get the frequency for each beat

Returns:

List of frequencies

Return type:

List[float]

property beating_frequency: float#

The median frequency of all beats

property beats: List[Beat]#

Chop signal into individual beats. You can also pass in any options that should be provided to the chopping algorithm.

Returns:

A list of chopped beats

Return type:

List[Beat]

chop_data(threshold_factor=0.5, min_window=50, max_window=5000, N=None, extend_front=None, extend_end=None, ignore_pacing=False, intervals=None)[source]#
property chopped_data: ChoppedData#
correct_background(background_correction_method: BackgroundCorrection, copy: bool = True) Beats[source]#
filter(kernel_size: int = 3, copy: bool = True) Beats[source]#
filter_beats(filters: Sequence[Filters], x: float = 1.0) List[Beat][source]#

Get a subset of the chopped beats based on similarities in different features.

Parameters:
  • filters (Sequence[_filters.Filters]) – A list of filters that should be used for filtering

  • x (float, optional) – How many standard deviations away from the mean the different beats should be to be included, by default 1.0

Returns:

A list of filtered beats

Return type:

List[Beat]

property intervals: List[Beat]#

A ist of time intervals for each beat

property num_beats: int#
property original_y: ndarray#
plot_beats(ylabel: str = '', align: bool = False, fname: str = '')[source]#
remove_points(t_start: float, t_end: float) Beats[source]#
remove_spikes(spike_duration: int) Beats[source]#
property y: ndarray#

The trace

class ap_features.State(y: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float] | None, pacing: ndarray | List[float] | Sequence[float] | None = None, backend: Backend = Backend.numba)[source]#

Bases: Trace

property cost_terms#
property num_states#
class ap_features.StateCollection(y: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float], pacing: ndarray | List[float] | Sequence[float] | None = None, mask: ndarray | List[float] | Sequence[float] | None = None, parent: StateSeriesCollection | None = None)[source]#

Bases: Trace

property cost_terms#
property mask: ndarray | List[float] | Sequence[float] | None#
property num_states#
property num_traces#
property parent: StateSeriesCollection | None#

If the beat comes from a BeatSeries object then this will return that BeatSeries

Returns:

The parent BeatSeries

Return type:

BeatSeries

class ap_features.Trace(y: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float] | None, pacing: ndarray | List[float] | Sequence[float] | None = None, backend: Backend = Backend.numba)[source]#

Bases: object

amp() float[source]#

Return the difference between the maximum and minimum value

as_spline(k: int = 3, s: int | None = None) UnivariateSpline[source]#

Convert trace to spline

Parameters:
  • k (int, optional) – Degree of the smoothing spline. Must be 1 <= k <= 5. Default is k = 3, a cubic spline, by default 3.

  • s (float or None, optional) – Positive smoothing factor used to choose the number of knots. If 0, spline will interpolate through all data points, by default 0

Returns:

A spline representation of the trace

Return type:

UnivariateSpline

copy(**kwargs)[source]#

Create a copy of the trace

property duration: float#

The duration of the trace, i.e last time point minus the first

ensure_time_unit(unit: str) None[source]#

Convert time to milliseconds or seconds

Parameters:

unit (str) – A string with ‘ms’ or ‘s’

max() float[source]#

Return the maximum value of the trace

min() float[source]#

Return the minimum value of the trace

property pacing: ndarray#

Array of pacing amplitudes. If no pacing info is available, then this will be an array of zeros with same length as the trace

plot(fname: str = '', include_pacing: bool = False, include_background: bool = False, ylabel: str = '')[source]#

Plot the trace with matplotlib

Parameters:
  • fname (str, optional) – Name of the figure to be saved. If not provided the figure will note be saved, but you can show by calling plt.show

  • include_pacing (bool, optional) – Whether to include pacing in the plot, by default False

  • include_background (bool, optional) – Whether to include the background, by default False

  • ylabel (str, optional) – Label on the y-axis, by default “”

Returns:

If matplotlib is installed it will return a tuple containing the figure and the axes.

Return type:

Tuple[plt.Figure, plt.Axes] | None

slice(start: float, end: float, copy: bool = True) Trace[source]#

Create a slice of the original trace

Parameters:
  • start (float) – Start time of slice

  • end (float) – End time of slice

  • copy (bool, optional) – If true create a copy of the original array otherwise return a slice of the original array, by default True

Returns:

A sliced trace

Return type:

Trace

property t: ndarray#

The time stamps

property time_unit: str#

The time unit ‘ms’ or ‘s’

property y: ndarray#

The trace

ap_features.all_cost_terms(arr: ndarray, t: ndarray, mask: ndarray | None = None, backend: Backend = Backend.numba, normalize_time: bool = True) ndarray[source]#
ap_features.apd(factor: float, V: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float], v_r: float | None = None, v_max: float | None = None, use_spline: bool = True, backend: Backend = Backend.python) float[source]#

Return the action potential duration at the given factor repolarization, so that factor = 0 would be zero, and factor = 1 given the time from triggering to potential is down to resting potential.

Parameters:
  • factor (int) – The APD factor between 0 and 100

  • V (Array) – The signal

  • t (Array) – The time stamps

  • v_r (Optional[float], optional) – The resting value, by default None. If None the minimum value is chosen

  • v_max (Optional[float], optional) – The maximum value, by default None. If None the maximum value is chosen

  • use_spline (bool, optional) – Use spline interpolation, by default True. Only applicable for python Backend.

  • backend (utils.Backend, optional) – Which backend to use by default Backend.python. Choices, ‘python’, ‘numba’

Returns:

  • float – The action potential duration

  • .. Note:: – If the signal has more intersection than two with the APX_X line, then the first and second occurrence will be used.

Raises:
  • ValueError – If factor is outside the range of (0, 100)

  • ValueError – If shape of x and y does not match

  • RunTimeError – In unable to compute APD

Notes

If the signal represent voltage, we would like to compute the action potential duration at a given factor of the signal. Formally, Let \(p \in (0, 100)\), and define

\[y_p = \tilde{y} - \left(1- \frac{p}{100} \right).\]

Now let \(\mathcal{T}\) denote the set of solutions of \(y_p = 0\), i.e

\[y_p(t) = 0, \;\; \forall t \in \mathcal{T}\]

Then there are three different scenarios; \(\mathcal{T}\) contains one, two or more than two elements. Note that \(\mathcal{T}\) cannot be empty (because of the intermediate value theorem). The only valid scenario is the case when \(\mathcal{T}\) contains two (or more) elements. In this case we define

\[\mathrm{APD} \; p = \max \mathcal{T} - \min \mathcal{T}\]

for \(p < 0.5\) and

\[\mathrm{APD} \; p = \min \mathcal{T} / \min \mathcal{T} - \min \mathcal{T}\]
ap_features.apd_up_xy(y: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float], low: int, high: int, backend: Backend = Backend.python) float[source]#

Find the duration between first intersection (i.e during the upstroke) of two APD lines

Parameters:
  • t (np.ndarray) – Time values

  • y (np.ndarray) – The trace

  • low (int) – First APD line (value between 0 and 100)

  • high (int) – Second APD line (value between 0 and 100)

  • backend (utils.Backend, optional) – Which backend to use by default Backend.python. Choices, ‘python’, ‘numba’

Returns:

The time between low to high

Return type:

float

ap_features.average_and_interpolate(ys: Sequence[ndarray | List[float] | Sequence[float]], xs: Sequence[ndarray | List[float] | Sequence[float]] | None = None, N: int = 200) Average[source]#

Get the average of list of signals assuming that they align at the same x value

Parameters:
  • ys (Array) – The signal values

  • xs (Array) – The x-values

  • N (int) – Length of output array (Default: 200)

Returns:

  • Y_avg (array) – The average y values

  • X (array) – The new x-values

ap_features.cost_terms(v: ndarray | List[float] | Sequence[float], ca: ndarray | List[float] | Sequence[float], t_v: ndarray | List[float] | Sequence[float], t_ca: ndarray | List[float] | Sequence[float], backend: Backend = Backend.numba) ndarray[source]#
ap_features.cost_terms_trace(y: ndarray | List[float] | Sequence[float], t: ndarray | List[float] | Sequence[float], backend: Backend = Backend.numba) ndarray[source]#
ap_features.list_cost_function_terms()[source]#
ap_features.list_cost_function_terms_trace(key='')[source]#
ap_features.transpose_trace_array(arr)[source]#