Finding peaks
Peaks.argmaxima
— Functionargmaxima(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
Peaks.argminima
— Functionargminima(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
Peaks.maxima
— Functionmaxima(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
Peaks.minima
— Functionminima(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
Peaks.findmaxima
— Functionfindmaxima(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])
Peaks.findminima
— Functionfindminima(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])
Peaks.simplemaxima
— Functionsimplemaxima(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 missing
s 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)
Peaks.simpleminima
— Functionsimpleminima(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 missing
s 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)
Peak characteristics & filtering
Peaks.peakproms
— Functionpeakproms(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])
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])
Peaks.peakproms!
— Functionpeakproms!(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])
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])
Peaks.peakwidths
— Functionpeakwidths(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])
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)])
Peaks.peakwidths!
— Functionpeakwidths!(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])
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)])
Peaks.peakheights
— Functionpeakheights(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])
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])
Peaks.peakheights!
— Functionpeakheights!(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])
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])
Peaks.filterpeaks!
— Functionfilterpeaks!(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])
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])
Convenience functions
Peaks.findnextmaxima
— Functionfindnextmaxima(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
Peaks.findnextminima
— Functionfindnextminima(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
Peaks.ismaxima
— Functionismaxima(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
Peaks.isminima
— Functionisminima(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
Peaks.isplateau
— Functionisplateau(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
.