smart_arrays_peaks 2.0.8 smart_arrays_peaks: ^2.0.8 copied to clipboard
Provides functions to detect (search, pick) peaks (maximum values) in one- or two-dimensional arrays, also suitable for noisy data.
// Copyright (c) 2019, Dr. Bruno Guigas. All rights reserved. Use of this source
// code is governed by a BSD-style license that can be found in the LICENSE file.
import 'package:smart_arrays_peaks/smart_arrays_peaks.dart';
import 'dart:typed_data';
import 'dart:math' as math;
/// Demonstrates peak picking for 1D and 2D arrays.
main() {
// generate noisy sine wave ([noise] is a fraction of [ampl])
Float64List genSine(
double ampl, double phase, int nperiods, int nxvalues, double noise) {
math.Random rand = math.Random();
double xmax = 2 * math.pi * nperiods, x, y;
Float64List sine = new Float64List(nxvalues);
for (int i = 0; i < nxvalues; i++) {
x = (i * xmax) / nxvalues;
y = ampl * math.sin(x + phase);
// add noise between -1 and 1
sine[i] = y + noise * ampl * (2 * rand.nextDouble() - 1.0).sign;
}
return sine;
}
// Example 1D peak picking
Float64List array = genSine(100.0, 0.0, 10, 1000, 0.005); // sine with noise
// pick peaks: use noise discriminator 2.0 to suppress "noise peaks".
List<int> peakIndices = PeakPicker1D.detectPeaks(
array, 0, array.length, 2.0, 0.001, PeakPicker1D.PICK_POSNEG, 0);
// print result: we expect 10 minima with values around -100 and 10 maxima
// around +100.
for (int i = 0; i < peakIndices.length; i++) {
int ipeak = peakIndices[i];
print("Peak # / index / value: " +
"${i + 1} / $ipeak / ${array[ipeak].toStringAsFixed(2)}");
}
print("");
// Example 2D peak picking
final List<List<double>> PEAK_2D = [
[70, 80, 75, 73],
[80, 85, 90, 91],
[83, 100, 90, 80],
[81, 95, 93, 92]
]; // a sample 2D peak
// Create a matrix with 2 peaks at row/col positions 10/20 and 20/15
final int NROWS = 32, NCOLS = 41;
List<Float64List> matrix = List(NROWS);
for (int i = 0; i < NROWS; i++) {
matrix[i] = Float64List(NCOLS);
if (i == 8 || i == 9 || i == 10 || i == 11)
matrix[i].setRange(19, 19 + PEAK_2D[0].length - 1, PEAK_2D[i - 8]);
if (i == 18 || i == 19 || i == 20 || i == 21)
matrix[i].setRange(14, 14 + PEAK_2D[0].length - 1, PEAK_2D[i - 18]);
}
// pick peaks
List<List<int>> peakIndices2D = PeakPicker2D().detectPeaks(
matrix, 0, NROWS, 0, NCOLS, 0.0, 0.0, PeakPicker1D.PICK_POSNEG, 0);
// print result: we expect 2 maxima with value 100 at positions 10/20 and 20/15
for (int i = 0; i < peakIndices2D.length; i++) {
int row = peakIndices2D[i][0];
int col = peakIndices2D[i][1];
print("2D Peak # / row /col / value: " +
"${i + 1} / $row / $col / ${matrix[row][col].toStringAsFixed(2)}");
}
}