Vespucci  1.0.0
rollingball.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright (C) 2014-2016 Wright State University - All Rights Reserved
3  Daniel P. Foose - Maintainer/Lead Developer
4 
5  This file is part of Vespucci.
6 
7  Vespucci is free software: you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation, either version 3 of the License, or
10  (at your option) any later version.
11 
12  Vespucci is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with Vespucci. If not, see <http://www.gnu.org/licenses/>.
19 *******************************************************************************/
33 arma::vec Vespucci::Math::Baseline::RollingBallBaseline(const arma::vec &spectrum,
34  arma::vec &baseline,
35  arma::uword wm,
36  arma::uword ws)
37 {
38  arma::uword u1; // placeholder 1
39  arma::uword u2; // placeholder 2
40  double v; // sum holder
41  baseline.clear();
42  baseline.set_size(spectrum.n_rows);
43  arma::vec T1 = spectrum; // minimizers
44  arma::vec T2 = spectrum; // maximizers
45 
46  // minimize
47  u1 = std::ceil((wm + 1) / 2) + 1;
48  T1(0) = Vespucci::Math::SafeRows(spectrum, 0, u1-1).min();
49  for (arma::uword i = 2; i <= wm; ++i){ // start of spectrum
50  u2 = u1 + 1 + (i % 2);
51  T1(i - 1) = std::min(Vespucci::Math::SafeRows(spectrum, u1, u2 - 1).min(), T1(i - 2));
52  u1 = u2;
53  }
54  for (arma::uword i = wm + 1; i <= spectrum.n_rows - wm; ++i){ // main part
55  if ((spectrum(u1) <= T1(i - 2)) && spectrum(u1 - wm - 1) != T1(i - 2))
56  T1(i) = spectrum(u1); // next smaller
57  else
58  T1(i) = Vespucci::Math::SafeRows(spectrum, i - wm - 1, i + wm - 1).min();
59  u1++;
60  }
61  u1 = spectrum.n_rows - 2*wm - 1;
62  for (arma::uword i = spectrum.n_rows - wm + 1; i <= spectrum.n_rows; ++i){ // end
63  u2 = u1 + 1 + ((i + 1) % 2);
64  if (Vespucci::Math::SafeRows(spectrum, u1 - 1, u2 - 2).min() > T1(i-2))
65  T1(i-1) = T1(i-2); // removed larger
66  else
67  T1(i-1) = Vespucci::Math::SafeRows(spectrum, u2, spectrum.n_rows - 1).min();
68  u1 = u2;
69  }
70 
71  // maximize
72  u1 = std::ceil((wm + 1) / 2.0) + 1;
73  T2(0) = Vespucci::Math::SafeRows(T1, 0, u1).max();
74  for (arma::uword i = 2; i <= wm; ++i){ // start
75  u2 = u1 + 1 + (i % 2);
76  T2(i - 1) = std::max(Vespucci::Math::SafeRows(T1, u1, u2 - 1).max(), T2(i - 1)); // check if new is larger
77  u1 = u2;
78  }
79  for (arma::uword i = wm + 1; i <= spectrum.n_rows - wm; ++i){ // main part
80  if ((T1(u1) >= T2(i - 2)) && (T1(u1 - wm - 1) != T2(i - 2)))
81  T2(i - 1) = T1(u1); // next is larger
82  else
83  T2(i - 1) = Vespucci::Math::SafeRows(T1, i - wm - 1, i + wm - 1).max();
84  u1++;
85  }
86  for (arma::uword i = spectrum.n_rows - wm + 1; i <= spectrum.n_rows; ++i){ // end
87  u2 = u1 + 1 + ((i + 1) % 2);
88  if (Vespucci::Math::SafeRows(T1, u1 - 1, u2 - 2).max() < T2(i - 2))
89  T2(i - 1) = T2(i - 2); //removed is smaller
90  else
91  T2(i - 1) = Vespucci::Math::SafeRows(T1, u2 - 1, spectrum.n_rows - 1).max();
92  u1 = u2;
93  }
94 
95  // smooth
96  u1 = std::ceil(ws / 2.0);
97  v = arma::accu(Vespucci::Math::SafeRows(T2, 0, u1 - 1));
98  for (arma::uword i = 1; i <= ws; ++i){ // start
99  u2 = u1 + 1 + (i % 2);
100  v += arma::accu(Vespucci::Math::SafeRows(T2, u1, u2 - 1));
101  baseline(i - 1) = v / double(u2);
102  u1 = u2;
103  }
104  v = arma::accu(Vespucci::Math::SafeRows(T2, 0, 2*ws));
105  baseline(ws) = v / (2*ws+1);
106  for (arma::uword i = ws + 2; i <= spectrum.n_rows - ws; ++i){
107  v = v - T2(i - ws - 2) + T2(i + ws - 1);
108  baseline(i - 1) = v / double(2*ws+1);
109  }
110  u1 = spectrum.n_rows - 2 * ws + 1;
111  v -= T2(u1 - 1);
112  baseline(spectrum.n_rows - ws) = v / double(2*ws);
113  for (arma::uword i = spectrum.n_rows - ws + 2; i <= spectrum.n_rows; ++i){
114  u2 = u1 + 1 + (i+1) % 2;
115  v -= arma::accu(Vespucci::Math::SafeRows(T2, u1 - 1, u2 - 2));
116  baseline(i - 1) = v / double(spectrum.n_rows - u2 + 1);
117  u1 = u2;
118  }
119 
120  return spectrum - baseline;
121 }
122 
123 arma::mat Vespucci::Math::Baseline::RollingBallBaselineMat(const arma::mat &spectra,
124  arma::mat &baselines,
125  arma::uword wm,
126  arma::uword ws)
127 {
128  arma::mat corrected(spectra.n_rows, spectra.n_cols);
129  baselines.clear();
130  baselines.set_size(spectra.n_rows, spectra.n_cols);
131  #ifdef _WIN32
132  #pragma omp parallel for default(none) \
133  shared(spectra, baselines, wm, ws, corrected)
134  for (intmax_t i = 0; i < (intmax_t) spectra.n_cols; ++i)
135  #else
136  #pragma omp parallel for default(none) \
137  shared(spectra, baselines, wm, ws, corrected)
138  for (size_t i = 0; i < spectra.n_cols; ++i)
139  #endif
140  {
141  arma::vec baseline;
142  corrected.col(i) = Vespucci::Math::Baseline::RollingBallBaseline(spectra.col(i), baseline, wm, ws);
143  baselines.col(i) = baseline;
144  }
145  return corrected;
146 }
VESPUCCI_EXPORT arma::uword max(arma::uword a, arma::uword b)
Vespucci::Math::max.
Definition: accessory.cpp:237
VESPUCCI_EXPORT arma::vec RollingBallBaseline(const arma::vec &spectrum, arma::vec &baseline, arma::uword wm, arma::uword ws)
Vespucci::Math::Baseline::RollingBallBaseline.
Definition: rollingball.cpp:33
VESPUCCI_EXPORT arma::mat SafeRows(const arma::mat &x, arma::uword a, arma::uword b)
Vespucci::Math::SafeRows.
Definition: accessory.cpp:1030
VESPUCCI_EXPORT arma::uword min(arma::uword a, arma::uword b)
Vespucci::Math::min.
Definition: accessory.cpp:249
VESPUCCI_EXPORT arma::mat RollingBallBaselineMat(const arma::mat &spectra, arma::mat &baselines, arma::uword wm, arma::uword ws)