File indexing completed on 2024-05-12 03:47:52

0001 /*
0002     File                 : nsl_peak.cpp
0003     Project              : LabPlot
0004     Description          : NSL peak detection and releated methods
0005     --------------------------------------------------------------------
0006     SPDX-FileCopyrightText: 2023 Stefan Gerlach <stefan.gerlach@uni.kn>
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include "nsl_peak.h"
0011 #include "backend/lib/macros.h"
0012 
0013 // simple peak detection
0014 template<typename T>
0015 size_t* nsl_peak_detect(T* data, size_t n, size_t& np, T height, size_t distance) {
0016     DEBUG(Q_FUNC_INFO << ", h = " << height << ", d = " << distance)
0017     if (n <= 1) // nothing to do
0018         return nullptr;
0019 
0020     size_t* peaks = (size_t*)malloc(n * sizeof(size_t));
0021     if (!peaks) {
0022         WARN("ERROR allocating memory for peak detection")
0023         return nullptr;
0024     }
0025 
0026     // find peaks
0027     np = 0;
0028     for (size_t i = 0; i < n; i++) {
0029         bool found = false;
0030         if (i == 0 && n > 1 && data[0] > data[1]) // start
0031             found = true;
0032         else if (i == n - 1 && n > 1 && data[n - 1] > data[n - 2]) // end
0033             found = true;
0034         else if (data[i - 1] < data[i] && data[i] > data[i + 1])
0035             found = true;
0036 
0037         // check minimum height and distance
0038         if (found && data[i] >= height && (np == 0 || i - peaks[np - 1] >= distance))
0039             peaks[np++] = i;
0040     }
0041     if (np == 0) { // nothing found
0042         printf("nothing found\n");
0043         return nullptr;
0044     }
0045 
0046     if (!(peaks = (size_t*)realloc(peaks, np * sizeof(size_t)))) { // should never happen since np <= n
0047         WARN("ERROR reallocating memory for peak detection")
0048         free(peaks);
0049         return nullptr;
0050     }
0051 
0052     return peaks;
0053 }
0054 
0055 // needs explicit instantiation
0056 template size_t* nsl_peak_detect<double>(double* data, size_t n, size_t& np, double height, size_t distance);
0057 template size_t* nsl_peak_detect<int>(int* data, size_t n, size_t& np, int height, size_t distance);
0058 template size_t* nsl_peak_detect<qint64>(qint64* data, size_t n, size_t& np, qint64 height, size_t distance);