65 m_params.convolveWithNr = convolveWithNr;
123 if(parameters.startsWith(QString(
"%1|").arg(
name())))
125 QStringList params = parameters.split(
"|").back().split(
";");
131 m_params.convolveWithNr = (params.at(4) ==
"true" ?
true :
false);
136 QString(
"Building of FilterSavitzkyGolay from string '%1' failed").arg(parameters));
148 int data_point_count = data_points.size();
155 y_filtered_data_p =
dvector(1, 2 * data_point_count);
157 y_filtered_data_p =
dvector(1, data_point_count);
159 for(
int iter = 0; iter < data_point_count; ++iter)
161 x_data_p[iter] = data_points.at(iter).x;
162 y_initial_data_p[iter] = data_points.at(iter).y;
167 runFilter(y_initial_data_p, y_filtered_data_p, data_point_count);
170 auto iter_yf = y_filtered_data_p;
171 for(
auto &data_point : data_points)
173 data_point.y = *iter_yf;
192 return QString(
"%1|%2").arg(
name()).arg(
m_params.toString());
199 return "Savitzky-Golay";
207 v = (
int *)malloc((
size_t)((nh - nl + 2) *
sizeof(
int)));
210 qFatal(
"Error: Allocation failure.");
224 qFatal(
"Error: Allocation failure.");
226 for(k = nl; k <= nh; k++)
235 long i, nrow = nrh - nrl + 1, ncol = nch - ncl + 1;
240 qFatal(
"Error: Allocation failure.");
247 qFatal(
"Error: Allocation failure.");
251 for(i = nrl + 1; i <= nrh; i++)
252 m[i] = m[i - 1] + ncol;
260 free((
char *)(v + nl - 1));
267 free((
char *)(v + nl - 1));
273 pappso_double **m,
long nrl, [[maybe_unused]]
long nrh,
long ncl, [[maybe_unused]]
long nch)
const
275 free((
char *)(m[nrl] + ncl - 1));
276 free((
char *)(m + nrl - 1));
283 int i, ii = 0, ip, j;
286 for(i = 1; i <= n; i++)
292 for(j = ii; j <= i - 1; j++)
293 sum -=
a[i][j] *
b[j];
298 for(i = n; i >= 1; i--)
301 for(j = i + 1; j <= n; j++)
302 sum -=
a[i][j] *
b[j];
303 b[i] = sum /
a[i][i];
311 int i, imax = 0, j, k;
317 for(i = 1; i <= n; i++)
320 for(j = 1; j <= n; j++)
321 if((temp = fabs(
a[i][j])) > big)
325 qFatal(
"Error: Singular matrix found in routine ludcmp().");
329 for(j = 1; j <= n; j++)
331 for(i = 1; i < j; i++)
334 for(k = 1; k < i; k++)
335 sum -=
a[i][k] *
a[k][j];
339 for(i = j; i <= n; i++)
342 for(k = 1; k < j; k++)
343 sum -=
a[i][k] *
a[k][j];
345 if((dum = vv[i] * fabs(sum)) >= big)
353 for(k = 1; k <= n; k++)
356 a[imax][k] =
a[j][k];
364 a[j][j] = std::numeric_limits<pappso_double>::epsilon();
367 dum = 1.0 / (
a[j][j]);
368 for(i = j + 1; i <= n; i++)
379 unsigned long n, mmax, m, j, istep, i;
385 for(i = 1; i < n; i += 2)
389 SWAP(data[j], data[i]);
390 SWAP(data[j + 1], data[i + 1]);
393 while(m >= 2 && j > m)
404 theta = isign * (6.28318530717959 / mmax);
405 wtemp = sin(0.5 * theta);
406 wpr = -2.0 * wtemp * wtemp;
410 for(m = 1; m < mmax; m += 2)
412 for(i = m; i <= n; i += istep)
415 tempr = wr * data[j] - wi * data[j + 1];
416 tempi = wr * data[j + 1] + wi * data[j];
417 data[j] = data[i] - tempr;
418 data[j + 1] = data[i + 1] - tempi;
420 data[i + 1] += tempi;
422 wr = (wtemp = wr) * wpr - wi * wpi + wr;
423 wi = wi * wpr + wtemp * wpi + wi;
437 unsigned long nn3, nn2, jj, j;
440 nn3 = 1 + (nn2 = 2 + n + n);
441 for(j = 1, jj = 2; j <= n; j++, jj += 2)
443 fft1[jj - 1] = data1[j];
448 fft1[2] = fft2[2] = 0.0;
449 for(j = 3; j <= n + 1; j += 2)
451 rep = 0.5 * (fft1[j] + fft1[nn2 - j]);
452 rem = 0.5 * (fft1[j] - fft1[nn2 - j]);
453 aip = 0.5 * (fft1[j + 1] + fft1[nn3 - j]);
454 aim = 0.5 * (fft1[j + 1] - fft1[nn3 - j]);
458 fft1[nn3 - j] = -aim;
470 unsigned long i, i1, i2, i3, i4, np3;
478 four1(data, n >> 1, 1);
485 wtemp = sin(0.5 * theta);
486 wpr = -2.0 * wtemp * wtemp;
491 for(i = 2; i <= (n >> 2); i++)
493 i4 = 1 + (i3 = np3 - (i2 = 1 + (i1 = i + i - 1)));
494 h1r = c1 * (data[i1] + data[i3]);
495 h1i = c1 * (data[i2] - data[i4]);
496 h2r = -c2 * (data[i2] + data[i4]);
497 h2i = c2 * (data[i1] - data[i3]);
498 data[i1] = h1r + wr * h2r - wi * h2i;
499 data[i2] = h1i + wr * h2i + wi * h2r;
500 data[i3] = h1r - wr * h2r + wi * h2i;
501 data[i4] = -h1i + wr * h2i + wi * h2r;
502 wr = (wtemp = wr) * wpr - wi * wpi + wr;
503 wi = wi * wpr + wtemp * wpi + wi;
507 data[1] = (h1r = data[1]) + data[2];
508 data[2] = h1r - data[2];
512 data[1] = c1 * ((h1r = data[1]) + data[2]);
513 data[2] = c1 * (h1r - data[2]);
514 four1(data, n >> 1, -1);
527 unsigned long i, no2;
531 for(i = 1; i <= (m - 1) / 2; i++)
532 respns[n + 1 - i] = respns[m + 1 - i];
533 for(i = (m + 3) / 2; i <= n - (m - 1) / 2; i++)
535 twofft(data, respns, fft, ans, n);
537 for(i = 2; i <= n + 2; i += 2)
541 ans[i - 1] = (fft[i - 1] * (dum = ans[i - 1]) - fft[i] * ans[i]) / no2;
542 ans[i] = (fft[i] * dum + fft[i - 1] * ans[i]) / no2;
546 if((mag2 = ans[i - 1] * ans[i - 1] + ans[i] * ans[i]) == 0.0)
548 qDebug(
"Attempt of deconvolving at zero response in convlv().");
551 ans[i - 1] = (fft[i - 1] * (dum = ans[i - 1]) + fft[i] * ans[i]) / mag2 / no2;
552 ans[i] = (fft[i] * dum - fft[i - 1] * ans[i]) / mag2 / no2;
556 qDebug(
"No meaning for isign in convlv().");
570 int imj, ipj, j, k, kk, mm, *indx;
573 if(np < nl + nr + 1 || nl < 0 || nr < 0 || ld > m || nl + nr < m)
575 qDebug(
"Inconsistent arguments detected in routine sgcoeff.");
581 for(ipj = 0; ipj <= (m << 1); ipj++)
583 sum = (ipj ? 0.0 : 1.0);
584 for(k = 1; k <= nr; k++)
586 for(k = 1; k <= nl; k++)
588 mm = (ipj < 2 * m - ipj ? ipj : 2 * m - ipj);
589 for(imj = -mm; imj <= mm; imj += 2)
590 a[1 + (ipj + imj) / 2][1 + (ipj - imj) / 2] = sum;
593 for(j = 1; j <= m + 1; j++)
597 for(kk = 1; kk <= np; kk++)
599 for(k = -nl; k <= nr; k++)
603 for(mm = 1; mm <= m; mm++)
604 sum +=
b[mm + 1] * (fac *= k);
605 kk = ((np - k) % np) + 1;
622 double *y_filtered_data_p,
623 int data_point_count)
const
629#if CONVOLVE_WITH_NR_CONVLV
631 retval =
sgcoeff(
c, np, m_nL, m_nR, m_lD, m_m);
633 convlv(y_data_p, data_point_count,
c, np, 1, y_filtered_data_p);
642 qDebug() << __FILE__ << __LINE__ << __FUNCTION__ <<
"()"
651 y_filtered_data_p[k] +=
660 y_filtered_data_p[k] +=
664 for(k = data_point_count -
m_params.nR + 1; k <= data_point_count; k++)
668 if(k + j <= data_point_count)
670 y_filtered_data_p[k] +=
excetion to use when an item type is not recognized
uses Savitsky-Golay filter on trace
void free_dmatrix(pappso_double **m, long nrl, long nrh, long ncl, long nch) const
pappso_double * dvector(long nl, long nh) const
void buildFilterFromString(const QString &strBuildParams) override
build this filter using a string
void free_dvector(pappso_double *v, long nl, long nh) const
QString name() const override
pappso_double ** dmatrix(long nrl, long nrh, long ncl, long nch) const
QString toString() const override
Return a string with the textual representation of the configuration data.
virtual ~FilterSavitzkyGolay()
void twofft(pappso_double data1[], pappso_double data2[], pappso_double fft1[], pappso_double fft2[], unsigned long n)
void realft(pappso_double data[], unsigned long n, int isign)
void free_ivector(int *v, long nl, long nh) const
char convlv(pappso_double data[], unsigned long n, pappso_double respns[], unsigned long m, int isign, pappso_double ans[])
void lubksb(pappso_double **a, int n, int *indx, pappso_double b[]) const
int * ivector(long nl, long nh) const
void ludcmp(pappso_double **a, int n, int *indx, pappso_double *d) const
void four1(pappso_double data[], unsigned long nn, int isign)
FilterSavitzkyGolay & operator=(const FilterSavitzkyGolay &other)
Trace & filter(Trace &data_points) const override
char sgcoeff(pappso_double c[], int np, int nl, int nr, int ld, int m) const
char runFilter(double *y_data_p, double *y_filtered_data_p, int data_point_count) const
Perform the Savitzky-Golay filtering process.
SavGolParams getParameters() const
A simple container of DataPoint instances.
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...
double pappso_double
A type definition for doubles.
Parameters for the Savitzky-Golay filter.
int lD
specifies the order of the derivative to extract from the Savitzky-Golay smoothing algorithm (for reg...
int m
order of the polynomial to use in the regression analysis leading to the Savitzky-Golay coefficients ...
int nR
number of data points on the right of the filtered point
int nL
number of data points on the left of the filtered point
bool convolveWithNr
set to false for best results