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);