pub use crate::err::SpikefitError;
use num_traits::float::FloatCore;
use std::fmt::{Debug, Display};
use std::ops::{Mul, Sub};
mod err;
mod prominence;
mod searcher;
mod widths;
pub struct PeakWidthsOptions<'a, T> {
x: &'a [T],
peaks: Option<&'a [usize]>,
rel_height: Option<T>,
}
impl<'a, T> PeakWidthsOptions<'a, T> {
pub fn new(x: &'a [T]) -> Self {
Self {
x,
peaks: None,
rel_height: None,
}
}
pub fn peaks(mut self, peaks: &'a [usize]) -> Self {
self.peaks = Some(peaks);
self
}
pub fn rel_height(mut self, rh: T) -> Self {
self.rel_height = Some(rh);
self
}
}
impl<'a> PeakWidthsOptions<'a, f32> {
pub fn find(&self) -> Result<SpikefitWidths<f32>, SpikefitError> {
peak_widths_f32(self)
}
}
pub struct FindPeaksOptions<'a, T> {
x: &'a [T],
height: Option<f64>,
threshold: Option<f64>,
distance: Option<usize>,
prominence: Option<f64>,
width: Option<f64>,
}
impl<'a, T> FindPeaksOptions<'a, T> {
pub fn new(x: &'a [T]) -> Self {
Self {
x,
height: None,
threshold: None,
distance: None,
prominence: None,
width: None,
}
}
pub fn height(mut self, h: f64) -> Self {
self.height = Some(h);
self
}
pub fn threshold(mut self, t: f64) -> Self {
self.threshold = Some(t);
self
}
pub fn distance(mut self, d: usize) -> Self {
self.distance = Some(d);
self
}
pub fn prominence(mut self, p: f64) -> Self {
self.prominence = Some(p);
self
}
pub fn width(mut self, w: f64) -> Self {
self.width = Some(w);
self
}
}
impl FindPeaksOptions<'_, f32> {
pub fn find(self) -> Result<Vec<usize>, SpikefitError> {
find_peaks_impl(
self.x,
self.height,
self.threshold,
self.distance,
self.prominence,
self.width,
)
}
}
impl FindPeaksOptions<'_, f64> {
pub fn find(self) -> Result<Vec<usize>, SpikefitError> {
find_peaks_impl(
self.x,
self.height,
self.threshold,
self.distance,
self.prominence,
self.width,
)
}
}
pub(crate) trait SpikefitSample:
Debug
+ 'static
+ PartialOrd
+ PartialEq
+ Sub<Self, Output = Self>
+ Sized
+ Copy
+ Mul<Self, Output = Self>
+ FloatCore
+ Display
+ Default
{
const HALF: Self;
const TWO: Self;
}
impl SpikefitSample for f64 {
const HALF: Self = 0.5;
const TWO: Self = 2.0;
}
impl SpikefitSample for f32 {
const HALF: Self = 0.5;
const TWO: Self = 2.0;
}
pub fn peak_prominences(x: &[f64], peaks: &[usize]) -> Result<Vec<f64>, SpikefitError> {
peak_prominences_impl(x, peaks)
}
pub fn peak_prominences_f32(x: &[f32], peaks: &[usize]) -> Result<Vec<f32>, SpikefitError> {
peak_prominences_impl(x, peaks)
}
use crate::prominence::peak_prominences_impl;
use crate::searcher::find_peaks_impl;
use crate::widths::peak_widths_impl;
pub use widths::SpikefitWidths;
pub fn peak_widths(
options: &PeakWidthsOptions<'_, f64>,
) -> Result<SpikefitWidths<f64>, SpikefitError> {
if let Some(peaks) = options.peaks {
peak_widths_impl(options.x, peaks, options.rel_height)
} else {
Err(SpikefitError::SignalTooShort { len: 0 })
}
}
pub fn peak_widths_f32(
options: &PeakWidthsOptions<'_, f32>,
) -> Result<SpikefitWidths<f32>, SpikefitError> {
if let Some(peaks) = options.peaks {
peak_widths_impl(options.x, peaks, options.rel_height)
} else {
Err(SpikefitError::SignalTooShort { len: 0 })
}
}
pub fn find_peaks(options: FindPeaksOptions<'_, f64>) -> Result<Vec<usize>, SpikefitError> {
find_peaks_impl(
options.x,
options.height,
options.threshold,
options.distance,
options.prominence,
options.width,
)
}
pub fn find_peaks_f32(options: FindPeaksOptions<'_, f32>) -> Result<Vec<usize>, SpikefitError> {
find_peaks_impl(
options.x,
options.height,
options.threshold,
options.distance,
options.prominence,
options.width,
)
}