psambit9791 / jdsp

A Java Library for Digital Signal Processing
https://jdsp.dev
MIT License
240 stars 45 forks source link

Filtering Peaks by multiple properties #8

Closed d-lowl closed 3 years ago

d-lowl commented 3 years ago

Is there a way to filter peaks by multiple properties (as done in scipy)?

Example in scipy:

find_peaks(x, distance=20, height=(50, None)

jDSP currently allows filtering by only one metric (i.e. find* methods return int[], and they cannot be filtered further). Unless I'm missing something

psambit9791 commented 3 years ago

At the moment, the Peak class only allows filtering by one metric at a time. I am planning to add the functionality of filtering by multiple parameters using a piping structure and this should be available in the next release.

psambit9791 commented 3 years ago

This functionality has been added in commit https://github.com/psambit9791/jDSP/commit/f6e0abbd68a23c28ba0661f6130d8416f9c8a25b

The process to do this as of now is as follows:

FindPeak fp = new FindPeak(signal);
Peak out = fp.detectPeaks();
int[] peaks = out.getPeaks();
int[] filteredPeaks = out.filterByHeight(peaks, 0.5, "lower");
filteredPeaks = out.filterByPeakDistance(filteredPeaks, 150);
filteredPeaks = out.filterByWidth(filteredPeaks, 20 ,"lower");

The output peaks can now be passed into the <filterByProperty()> functions alongside the arguments. Calling the functions without peaks will return the result of filtering on all the detected peaks.

This will be released as PATCH release - v0.5.1 accounting for the fact that this is an essential feature for Peak Filtering


The pipelining of filtering properties will be added in next release. (v0.6.0)

psambit9791 commented 3 years ago

Update to filtering method in v0.5.1

With the addition of the feature of filtering from a specific list of peaks, some new updates have also been made in the way the functions are called.

Unlike before, filtering for a lower or upper threshold does not require passing "lower" or "upper" as argument. In stead you can now pass null. All the filterBy*() methods are now structured as filterBy*(peaks, lower_threshold, upper_threshold) and you can pass null as an argument to ignore it.

So, code from https://github.com/psambit9791/jDSP/issues/8#issuecomment-719866920 will now be written as follows:

FindPeak fp = new FindPeak(signal);
Peak out = fp.detectPeaks();
int[] peaks = out.getPeaks();
int[] filteredPeaks = out.filterByHeight(peaks, 0.5, null);
filteredPeaks = out.filterByPeakDistance(filteredPeaks, 150);
filteredPeaks = out.filterByWidth(filteredPeaks, 20.0 , null);
d-lowl commented 3 years ago

Awesome. Cheers! I'll have a look.