Finding peaks

Peaks.argmaximaFunction
argmaxima(x[, w=1; strict=true]) -> Vector{Int}

Find the indices of local maxima in x, where each maxima i is either the maximum of x[i-w:i+w] or the first index of a plateau.

A plateau is defined as a maxima with consecutive equal (==) maximal values which are bounded by lesser values immediately before and after the consecutive maximal values.

When strict == true, no elements in x[i-w:i+w] may be missing or NaN, and the bounds of a plateau must exist. For strict == false, a maxima is the maximum of all non-NaN or missing elements in x[i-w:i+w], and plateau bounds are assumed to exist (i.e. missing, NaN, or either end of the array, x[begin-1] or x[end+1], may be treated as the bounds of a plateau).

See also: findmaxima, findnextmaxima, argminima

Examples

julia> argmaxima([0,2,0,1,1,0])
2-element Vector{Int64}:
 2
 4

julia> argmaxima([2,0,1,1])
Int64[]

julia> argmaxima([2,0,1,1]; strict=false)
2-element Vector{Int64}:
 1
 3
source
Peaks.argminimaFunction
argminima(x[, w=1; strict=false]) -> Vector{Int}

Find the indices of local minima in x, where each minima i is either the minimum of x[i-w:i+w] or the first index of a plateau.

A plateau is defined as a minima with consecutive equal (==) minimal values which are bounded by greater values immediately before and after the consecutive minimal values.

When strict == true, no elements in x[i-w:i+w] may be missing or NaN, and the bounds of a plateau must exist. For strict == false, a minima is the minimum of all non-NaN or missing elements in x[i-w:i+w], and plateau bounds are assumed to exist (i.e. missing, NaN, or either end of the array, x[begin-1] or x[end+1], may be treated as the bounds of a plateau).

See also: findminima, findnextminima

Examples

julia> argminima([3,2,3,1,1,3])
2-element Vector{Int64}:
 2
 4

julia> argminima([2,3,1,1])
Int64[]

julia> argminima([2,3,1,1]; strict=false)
2-element Vector{Int64}:
 1
 3
source
Peaks.maximaFunction
maxima(x[, w=1; strict=true]) -> Vector{eltype(x)}

Find the values of local maxima in x, where each maxima i is either the maximum of x[i-w:i+w] or the first index of a plateau.

A plateau is defined as a maxima with consecutive equal (==) maximal values which are bounded by lesser values immediately before and after the consecutive maximal values.

See also: argmaxima, findnextmaxima, minima

source
Peaks.minimaFunction
minima(x[, w=1; strict=true]) -> Vector{eltype(x)}

Find the values of local minima in x, where each minima i is either the minimum of x[i-w:i+w] or the first index of a plateau.

A plateau is defined as a minima with consecutive equal (==) minimal values which are bounded by greater values immediately before and after the consecutive minimal values.

See also: argminima, findnextminima

source
Peaks.findmaximaFunction
findmaxima(x[, w=1; strict=true]) -> (;indices, heights, data)

Find the indices and values of local maxima in x, where each maxima i is either the maximum of x[i-w:i+w] or the first index of a plateau.

Returns a NamedTuple contains the fields indices, heights, data, which are equivalent to heights = data[indices]. The data field is a reference (not a copy) to the argument x.

A plateau is defined as a maxima with consecutive equal (==) maximal values which are bounded by lesser values immediately before and after the consecutive maximal values.

See also: argmaxima, findnextmaxima, findminima

Examples

julia> data = [1, 5, 1, 3, 2];

julia> pks = findmaxima(data)
(indices = [2, 4], heights = [5, 3], data = [1, 5, 1, 3, 2])
source
Peaks.findminimaFunction
findminima(x[, w=1; strict=true]) -> (;indices, heights, data)

Find the indices and values of local minima in x, where each minima i is either the minimum of x[i-w:i+w] or the first index of a plateau.

Returns a NamedTuple contains the fields indices, heights, data, which are equivalent to heights = data[indices]. The data field is a reference (not a copy) to the argument x.

A plateau is defined as a minima with consecutive equal (==) minimal values which are bounded by greater values immediately before and after the consecutive minimal values.

See also: argminima, findnextminima

Examples

julia> data = [1, 5, 1, 3, 2];

julia> valleys = findminima(data)
(indices = [3], heights = [1], data = [1, 5, 1, 3, 2])
source
Peaks.simplemaximaFunction
simplemaxima(x) -> Vector{Int}

Find the indices of local maxima in x, where each maxima i is greater than both adjacent elements or is the first index of a plateau.

A plateau is defined as a maxima with consecutive equal (==) maximal values which are bounded by lesser values immediately before and after the plateau.

This function is semantically equivalent to argmaxima(x, w=1; strict=true), but is faster because of its simplified set of features. (The difference in speed scales with length(x); for input arrays longer than 5k elements, argmaxima is roughly 7x slower.)

Vectors with missings are not supported by simplemaxima, use argmaxima if this is needed.

See also: argmaxima

Examples

julia> simplemaxima([0,2,0,1,1,0])
2-element Vector{Int64}:
 2
 4

julia> argmaxima([0,2,0,1,1,0])
2-element Vector{Int64}:
 2
 4

julia> simplemaxima([2,0,1,1])
Int64[]

julia> @btime simplemaxima(x) setup=(x = repeat([0,1]; outer=100));
  269.865 ns (3 allocations: 1.00 KiB)

julia> @btime argmaxima(x) setup=(x = repeat([0,1]; outer=100));
  748.780 ns (3 allocations: 1.00 KiB)
source
Peaks.simpleminimaFunction
simpleminima(x) -> Vector{Int}

Find the indices of local minima in x, where each minima i is less than both adjacent elements or is the first index of a plateau.

A plateau is defined as a minima with consecutive equal (==) minimal values which are bounded by greater values immediately before and after the plateau.

This function is semantically equivalent to argminima(x, w=1; strict=true), but is faster because of its simplified set of features. (The difference in speed scales with length(x); for input arrays longer than 5k elements, argmaxima is roughly 7x slower.)

Vectors with missings are not supported by simpleminima, use argminima if this is needed.

See also: argminima

Examples

julia> simpleminima([3,2,3,1,1,3])
2-element Vector{Int64}:
 2
 4

julia> argminima([3,2,3,1,1,3])
2-element Vector{Int64}:
 2
 4

julia> simpleminima([2,3,1,1])
Int64[]

julia> @btime simpleminima(x) setup=(x = repeat([0,1]; outer=100));
  280.362 ns (3 allocations: 1.00 KiB)

julia> @btime argminima(x) setup=(x = repeat([0,1]; outer=100));
  823.634 ns (3 allocations: 1.00 KiB)
source

Peak characteristics & filtering

Peaks.peakpromsFunction
peakproms(indices, x; [strict=true, min, max]) -> (indices, proms)
peakproms(pks::NamedTuple; [strict=true, min, max]) -> NamedTuple

Calculate the prominences of peak indices in x, and remove peaks with prominences less than min and/or greater than max.

Peak prominence is the absolute height (value) difference between the current peak and the larger of the two adjacent smallest magnitude points between the current peak and adjacent larger peaks or signal ends.

If a NamedTuple pks is given, a new NamedTuple is returned with filtered copies of fields from pks. pks must have :indices and :heights fields. If pks has a :proms field, prominences will only be filtered, and not be recalculated. The fields :widths and :edges will also be filtered if present, and any remaining fields will be copied unmodified.

If strict == true, the prominence for a peak with a NaN or missing between the current peak and either adjacent larger peaks will be NaN or missing, otherwise, it will be the larger of the smallest non-NaN or missing values between the current peak and adjacent larger peaks for strict == false.

See also: peakproms!, findmaxima

Examples

julia> pks = findmaxima([0,5,2,3,3,1,4,0]);

julia> pks = peakproms(pks; min=2)
(indices = [2, 7], heights = [5, 4], data = [0, 5, 2, 3, 3, 1, 4, 0], proms = Union{Missing, Int64}[5, 3])

julia> inds, proms = peakproms(pks.indices, pks.data; max=4)
([7], Union{Missing, Int64}[3])
source
peakproms(; [strict, min, max]) -> Function

Create a function, f(pks::NamedTuple), that calculates and filters the peak prominences of a copy of its argument, pks, using any given keyword arguments.

Examples

julia> findmaxima([0,5,2,3,3,1,4,0]) |> peakproms(; min=2)
(indices = [2, 7], heights = [5, 4], data = [0, 5, 2, 3, 3, 1, 4, 0], proms = Union{Missing, Int64}[5, 3])
source
Peaks.peakproms!Function
peakproms!(indices, x; [strict=true, min, max]) -> (indices, proms)
peakproms!(pks::NamedTuple; [strict=true, min, max]) -> NamedTuple

Calculate the prominences of peak indices in x, and remove peaks with prominences less than min and/or greater than max.

If a NamedTuple pks is given, a new NamedTuple is returned with the same fields (references) from pks. pks must have :indices and :heights fields. If pks has a :proms field, prominences will only be filtered, and not be recalculated. The fields :widths and :edges will also be filtered (mutated) if present, and any remaining fields will be copied unmodified.

See also: peakproms, findmaxima

Examples

julia> pks = findmaxima([0,5,2,3,3,1,4,0]);

julia> pks = peakproms!(pks; min=2)
(indices = [2, 7], heights = [5, 4], data = [0, 5, 2, 3, 3, 1, 4, 0], proms = Union{Missing, Int64}[5, 3])

julia> inds, proms = peakproms!(pks.indices, pks.data; max=4)
([7], Union{Missing, Int64}[3])
source
peakproms!(; [strict, min, max]) -> Function

Create a function, f(pks::NamedTuple), that calculates and filters (mutates) the peak prominences and other fields of its argument, pks, using any given keyword arguments.

Examples

julia> findmaxima([0,5,2,3,3,1,4,0]) |> peakproms!(; min=2)
(indices = [2, 7], heights = [5, 4], data = [0, 5, 2, 3, 3, 1, 4, 0], proms = Union{Missing, Int64}[5, 3])
source
Peaks.peakwidthsFunction
peakwidths(indices, x, proms; [strict=true, relheight=0.5, min, max]) -> (indices, widths, ledge, redge)
peakwidths(pks::NamedTuple; [strict=true, relheight=0.5, min, max]) -> NamedTuple

Calculate the widths of peak indices in x at a reference level based on proms and relheight, and removing peaks with widths less than min and/or greater than max. Returns the peaks, widths, and the left and right edges at the reference level.

Peak width is the distance between the signal crossing a reference level before and after the peak. Signal crossings are linearly interpolated between indices. The reference level is the difference between the peak height and relheight times the peak prominence. Width cannot be calculated for a NaN or missing prominence.

If a NamedTuple pks is given, a new NamedTuple is returned with filtered copies of fields from pks. pks must have :indices, :heights, and :proms fields. If pks has :widths and :edges fields, they will not be recalculated, but filtered only. Any remaining fields will be copied unmodified.

If strict == true, the width for a peak with a gap in the signal (e.g. NaN, missing) at the reference level will match the gap (e.g. NaN for NaN, etc.). Otherwise, the signal crossing will be linearly interpolated between the edges of the gap.

See also: peakwidths!, peakproms, findmaxima

Examples

julia> x = Float64[0,5,2,2,3,3,1,4,0];

julia> pks = findmaxima(x) |> peakproms!(;max=2);

julia> peakwidths(pks)
(indices = [5], heights = [3.0], data = [0.0, 5.0, 2.0, 2.0, 3.0, 3.0, 1.0, 4.0, 0.0], proms = [1.0], widths = [1.75], edges = [(4.5, 6.25)])

julia> x[4] = NaN;

julia> peakwidths(pks.indices, x, pks.proms)
([5], [NaN], [NaN], [6.25])

julia> peakwidths(pks.indices, x, pks.proms; strict=false)
([5], [2.25], [4.0], [6.25])
source
peakwidths(; [strict, relheight, min, max]) -> Function

Create a function, f(pks::NamedTuple), that calculates and filters the peak widths of a copy of its argument, pks, using any given keyword arguments.

Examples

julia> findmaxima([0,5,2,3,3,1,4,0]) |> peakproms() |> peakwidths(; min=1.5)
(indices = [4], heights = [3], data = [0, 5, 2, 3, 3, 1, 4, 0], proms = Union{Missing, Int64}[1], widths = Union{Missing, Float64}[1.75], edges = Tuple{Union{Missing, Float64}, Union{Missing, Float64}}[(3.5, 5.25)])
source
Peaks.peakwidths!Function
peakwidths!(indices, x; [strict=true, relheight=0.5, min, max]) -> (indices, widths, ledge, redge)
peakwidths!(pks::NamedTuple; [strict=true, relheight=0.5, min, max]) -> NamedTuple

Calculate the widths of peak indices in x at a reference level based on proms and relheight, removing peaks with widths less than min and/or greater than max. Returns the modified peaks, widths, and the left and right edges at the reference level.

If a NamedTuple pks is given, a new NamedTuple is returned with the same fields (references) from pks. pks must have :indices, :heights, and :proms fields. If pks has :widths and :edges fields, they will not be recalculated, but filtered only. Any remaining fields will be copied unmodified.

See also: peakwidths, peakproms, findmaxima

Examples

julia> x = Float64[0,5,2,2,3,3,1,4,0];

julia> pks = findmaxima(x) |> peakproms!();

julia> peakwidths!(pks; min=1)
(indices = [2, 5], heights = [5.0, 3.0], data = [0.0, 5.0, 2.0, 2.0, 3.0, 3.0, 1.0, 4.0, 0.0], proms = [5.0, 1.0], widths = [1.333, 1.75], edges = [(1.5, 2.833), (4.5, 6.25)])

julia> peakwidths!(pks.indices, pks.data, pks.proms; min=1)
([2, 5], [1.333, 1.75], [1.5, 4.5], [2.833, 6.25])
source
peakwidths!(; [strict, relheight, min, max]) -> Function

Create a function, f(pks::NamedTuple), that calculates and filters (mutates) the peak widths and other fields of its argument, pks, using any given keyword arguments.

Examples

julia> findmaxima([0,5,2,3,3,1,4,0]) |> peakproms!() |> peakwidths!(; min=1.5)
(indices = [4], heights = [3], data = [0, 5, 2, 3, 3, 1, 4, 0], proms = Union{Missing, Int64}[1], widths = Union{Missing, Float64}[1.75], edges = Tuple{Union{Missing, Float64}, Union{Missing, Float64}}[(3.5, 5.25)])
source
Peaks.peakheightsFunction
peakheights(indices, heights; [min, max]) -> (indices, heights)
peakheights(pks::NamedTuple; [min, max]) -> NamedTuple

Return a copy of indices and heights where peaks are removed if their height is less than min and/or greater than max.

If a NamedTuple pks is given, a new NamedTuple is returned with filtered copies of fields from pks. pks must have :indices and :heights fields. The fields :proms, :widths, and :edges will be filtered if present, and any remaining fields will be copied unmodified.

See also: peakproms, peakwidths, findmaxima

Examples

julia> x = [0,5,2,3,3,1,4,0];

julia> pks = findmaxima(x)
(indices = [2, 4, 7], heights = [5, 3, 4], data = [0, 5, 2, 3, 3, 1, 4, 0])

julia> peakheights(pks; max=4)
(indices = [4, 7], heights = [3, 4], data = [0, 5, 2, 3, 3, 1, 4, 0])

julia> inds, heights = peakheights(pks.indices, pks.heights; max=4)
([4, 7], [3, 4])
source
peakheights(; [min, max]) -> Function

Create a function, f(pks::NamedTuple), that copies and filters the peak heights of its argument, pks, using any given keyword arguments.

Examples

julia> findmaxima([0, 5, 2, 3, 3, 1, 4, 0]) |> peakheights(; max=4)
(indices = [4, 7], heights = [3, 4], data = [0, 5, 2, 3, 3, 1, 4, 0])
source
Peaks.peakheights!Function
peakheights!(indices, heights; [min, max]) -> (indices, heights)
peakheights!(pks::NamedTuple; [min, max]) -> NamedTuple

Filter (mutate) and return indices and heights by removing peaks that are less than min and/or greater than max.

If a NamedTuple pks is given, a new NamedTuple is returned with the same fields (references) from pks. pks must have :indices and :heights fields. The fields :proms, :widths, and :edges will be filtered (mutated) if present, and any remaining fields will be referenced unmodified.

See also: peakproms, peakwidths, findmaxima filterpeaks!

Examples

julia> x = [0,5,2,3,3,1,4,0];

julia> pks = findmaxima(x)
(indices = [2, 4, 7], heights = [5, 3, 4], data = [0, 5, 2, 3, 3, 1, 4, 0])

julia> peakheights!(pks; max=4)
(indices = [4, 7], heights = [3, 4], data = [0, 5, 2, 3, 3, 1, 4, 0])

julia> inds, heights = peakheights!(pks.indices, pks.heights; min=3.5)
([7], [4])
source
peakheights!(; [min, max]) -> Function

Create a function, f(pks::NamedTuple), that calculates peak heights and then filters (mutates) the fields of its argument, pks, using any given keyword arguments.

Examples

julia> findmaxima([0, 5, 2, 3, 3, 1, 4, 0]) |> peakheights!(; max=4)
(indices = [4, 7], heights = [3, 4], data = [0, 5, 2, 3, 3, 1, 4, 0])
source
Peaks.filterpeaks!Function
filterpeaks!(pks::NT, feature; [min, max]) where {NT<:NamedTuple} -> pks::NT
filterpeaks!(pks::NT, mask) -> pks::NT

Filter the standard pks fields where peaks are removed if pks.$feature is less than min and/or greater than max. If a mask is given, a given peak i is filtered (removed) if mask[i] is false.

Standard Peaks.jl fields of pks are :indices, :proms, :heights, :widths, :edges.

Examples

julia> pks = findmaxima([0,5,2,3,3,1,4,0])
(indices = [2, 4, 7], heights = [5, 3, 4], data = [0, 5, 2, 3, 3, 1, 4, 0])

julia> filterpeaks!(pks, :heights; max=4)
(indices = [4, 7], heights = [3, 4], data = [0, 5, 2, 3, 3, 1, 4, 0])

julia> pks = findmaxima([0,5,2,3,3,1,4,0]) |> peakproms!();

julia> mask = [pks.heights[i] < 5 &&  pks.proms[i] > 2 for i in eachindex(pks.indices)]
3-element Vector{Bool}:
 0
 0
 1

julia> filterpeaks!(pks, mask)
(indices = [7], heights = [4], data = [0, 5, 2, 3, 3, 1, 4, 0], proms = Union{Missing, Int64}[3])
source
filterpeaks!(pred, pks) -> NamedTuple

Apply a predicate function pred to NamedTuple slices (the scalar values related to each peak, e.g. (indices=5, heights=3, proms=2)) to and remove a peak if pred returns false.

Examples

julia> pks = findmaxima([0,5,2,3,3,1,4,0])
(indices = [2, 4, 7], heights = [5, 3, 4], data = [0, 5, 2, 3, 3, 1, 4, 0])

julia> filterpeaks!(pks) do nt
           return nt.heights ≥ 5 || nt.heights ≤ 3
       end
(indices = [2, 4], heights = [5, 3], data = [0, 5, 2, 3, 3, 1, 4, 0])
source

Convenience functions

Peaks.findnextmaximaFunction
findnextmaxima(x, i[, w=1; strict=true]) -> Int

Find the index of the next maxima in x after or including i, where the maxima i is either the maximum of x[i-w:i+w] or the first index of a plateau. Returns lastindex(x) + 1 if no maxima occur after i.

A plateau is defined as a maxima with consecutive equal (==) maximal values which are bounded by lesser values immediately before and after the consecutive maximal values.

When strict == true, no elements in x[i-w:i+w] may be missing or NaN, and the bounds of a plateau must exist. For strict == false, a maxima is the maximum of all non-NaN or missing elements in x[i-w:i+w], and plateau bounds are assumed to exist (i.e. missing, NaN, or either end of the array, x[begin-1] or x[end+1], may be treated as the bounds of a plateau).

See also: argmaxima

Examples

julia> findnextmaxima([0,2,0,1,1,0], 2)
2

julia> findnextmaxima([0,2,0,1,1,0], 3)
4
source
Peaks.findnextminimaFunction
findnextminima(x, i[, w=1, strict=true]) -> Int

Find the index of the next minima in x, after or including i, where the minima i is either the minimum of x[i-w:i+w] or the first index of a plateau. Returns lastindex(x) + 1 if no minima occur after i.

A plateau is defined as a minima with consecutive equal (==) minimal values which are bounded by greater values immediately before and after the consecutive minimal values.

When strict == true, no elements in x[i-w:i+w] may be missing or NaN, and the bounds of a plateau must exist. For strict == false, a minima is the minimum of all non-NaN or missing elements in x[i-w:i+w], and plateau bounds are assumed to exist (i.e. missing, NaN, or either end of the array, x[begin-1] or x[end+1], may be treated as the bounds of a plateau).

See also: argminima

Examples

julia> findnextminima([3,2,3,1,1,3], 2)
2

julia> findnextminima([3,2,3,1,1,3], 3)
4
source
Peaks.ismaximaFunction
ismaxima(i, x[, w=1; strict=true]) -> Bool

Test if i is a maxima in x, where the maxima i is either the maximum of x[i-w:i+w] or the first index of a plateau.

A plateau is defined as a maxima with consecutive equal (==) maximal values which are bounded by lesser values immediately before and after the consecutive maximal values.

See also: findnextmaxima

source
Peaks.isminimaFunction
isminima(i, x[, w=1; strict=true]) -> Bool

Test if i is a minima in x, where the minima i is either the minimum of x[i-w:i+w] or the first index of a plateau.

A plateau is defined as a minima with consecutive equal (==) minimal values which are bounded by greater values immediately before and after the consecutive minimal values.

See also: findnextminima

source
Peaks.isplateauFunction
isplateau(i, x[, w=1; strict=true]) -> Union{Missing,Bool}

Test if i is a plateau in x, where a plateau is defined as a maxima or minima with consecutive equal (==) extreme values which are bounded by lesser values immediately before and after the consecutive values. Returns false if i is the last index in x.

See also: ismaxima, isminima

source