Vespucci  1.0.0
cwt.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 *******************************************************************************/
21 #include <Math/Transform/cwt.h>
23 
24 
35 
41 
42 arma::mat Vespucci::Math::Transform::cwt(arma::vec X, std::string wavelet, arma::uvec scales)
43 {
44  arma::mat wcoeffs(X.n_rows, scales.n_elem);
45  arma::vec psi_xval(1024);
46  arma::vec psi(1024);
47 
48  arma::uword old_length = X.n_rows;
50 
51 
52  //calculate the wavelet:
53  try{
54  if (wavelet == "mexh"){
55  psi_xval = arma::linspace(-8, 8, 1024);
56  psi = (2/std::sqrt(3.0) * std::pow(arma::datum::pi, -0.25)) * (arma::ones(1024) - arma::pow(psi_xval, 2)) % arma::exp(-arma::pow(psi_xval, 2)/2);
57  }
58  else if (wavelet == "haar"){
59  psi_xval = arma::linspace(0, 1, 1024);
60  psi(0) = 0;
61  psi(1023) = 0;
62  psi.rows(1, 511) = arma::ones(511);
63  psi.rows(512, 1022) = -1*arma::ones(511);
64  }
65  }catch(std::exception e){
66  std::cerr << "Error calculating wavelet!" <<std::endl;
67  throw e;
68  }
69 
70 
71  psi_xval -= arma::ones(psi_xval.n_elem)*psi_xval(0);
72  double dxval = psi_xval(1);
73  double xmax = psi_xval(psi_xval.n_elem - 1);
74 
75  arma::vec f, j, w;
76  arma::uvec j_u;
77  arma::uword i, scale, shift_by;
78  try{
79  for (i = 0; i < scales.n_elem; ++i){
80  scale = scales(i);
81 
82  f = arma::zeros(X.n_elem);
83  j = arma::floor(arma::linspace(0, scale*xmax, scale*xmax + 1)/(scale*dxval));
84  j_u.set_size(j.n_elem);
85 
86 
87  for (arma::uword k = 0; k < j_u.n_elem; ++k){
88  j_u(k) = j(k);
89  }
90 
91  f.rows(0, j.n_elem-1) = arma::flipud(psi.elem(j_u)) - arma::mean(psi.elem(j_u));
92 
93  if (f.n_rows != X.n_rows){
94  std::cerr << "scale too large!" << std::endl;
95  }
96 
97  //convolve and scale
98  w = (1/std::sqrt(scale)) * Vespucci::Math::conv_fft(X, f, "filter");
99 
100 
101  //shift by half wavelet width + scale * xmax
102  shift_by = X.n_rows - std::floor((double) j.n_rows/2) + scale*xmax;
103 
104  w = Vespucci::Math::rotate(w, shift_by, true);
105 
106  //if signal had to be padded, remove padding
107  if (w.n_rows > old_length)
108  w.shed_rows(old_length, w.n_rows - 1);
109 
110  wcoeffs.col(i) = w;//rotate(w, scale*xmax, true);
111  }
112  }catch(std::exception e){
113  std::cerr << "error in CWT algorithm!" << std::endl;
114  std::cerr << "scale = " << scale;
115 
116  throw e;
117  }
118 
119  return wcoeffs;
120 }
121 
122 
123 arma::vec Vespucci::Math::Transform::cwt_spdbc(const arma::vec &X, std::string wavelet, arma::uword qscale, double threshold, std::string threshold_method, arma::uword window_size, arma::umat &peak_extrema, arma::vec &baseline)
124 {
125  arma::umat peaks;
126  arma::vec peak_magnitudes;
127  arma::uvec scales(1);
128  scales(0) = qscale;
129  try{
130  arma::vec X_transform = Vespucci::Math::Transform::cwt(X, wavelet, scales);
131  arma::vec dX_transform = Vespucci::Math::diff(X, 1);
132  dX_transform.insert_rows(0, 1, true); //buffer so that X and dX have same
133  //number of elements and dX(i) is the derivative of X at i.
134  peak_extrema = Vespucci::Math::PeakFinding::FindPeakPositions(X_transform, dX_transform,
135  threshold,
136  threshold_method,
137  peak_magnitudes);
138  baseline = Vespucci::Math::PeakFinding::EstimateBaseline(X, peak_extrema, window_size);
139  }catch(std::exception e){
140  std::cerr << std::endl << "exception! cwt_spdbc" << std::endl;
141  std::cerr << e.what();
142  throw(e);
143  }
144 
145  return X - baseline;
146 
147 }
148 
149 
150 arma::mat Vespucci::Math::Transform::cwt_spdbc_mat(const arma::mat &X, std::string wavelet, arma::uword qscale,
151  double threshold, std::string threshold_method,
152  arma::uword window_size, arma::field<arma::umat> &peak_positions,
153  arma::mat &baselines)
154 {
155  baselines.set_size(X.n_rows, X.n_cols);
156  arma::vec baseline;
157  arma::vec spectrum;
158  arma::vec current_corrected;
159  arma::mat corrected(X.n_rows, X.n_cols);
160  arma::umat current_peakpos;
161  peak_positions.set_size(X.n_cols);
162  arma::uword i;
163  try{
164  for (i = 0; i < X.n_cols; ++i){
165  spectrum = X.col(i);
166  current_corrected = Vespucci::Math::Transform::cwt_spdbc(spectrum, wavelet,
167  qscale, threshold,
168  threshold_method, window_size,
169  current_peakpos, baseline);
170 
171  peak_positions(i) = current_peakpos;
172  baselines.col(i) = baseline;
173  corrected.col(i) = current_corrected;
174  }
175  }catch(std::exception e){
176  std::cerr << std::endl << "exception! cwt_spdbc_mat" << std::endl;
177  std::cerr << "i = " << i << std::endl;
178  std::cerr << e.what();
179  throw(e);
180  }
181 
182  return corrected;
183 }
184 
185 
186 
187 
188 arma::mat Vespucci::Math::Transform::cwtPeakAnalysis(const arma::mat &X,
189  std::string wavelet, arma::uword qscale,
190  double threshold, std::string threshold_method,
191  arma::mat &transform)
192 {
193  transform.set_size(X.n_rows, X.n_cols);
194  arma::uvec scales(1);
195  scales(0) = qscale;
196  arma::uword i;
197  arma::umat peak_positions;
198  arma::mat peak_extrema(X.n_rows, X.n_cols);
199  arma::vec spectrum, current_transform, dtransform, peak_magnitudes;
200  try{
201  for (i = 0; i < X.n_cols; ++i){
202  spectrum = X.col(i);
203  current_transform = Vespucci::Math::Transform::cwt(spectrum, wavelet, scales);
204  transform.col(i) = current_transform;
205  dtransform = Vespucci::Math::diff(transform, 1);
206  dtransform.insert_rows(0, 1, true); //dtransform(i) is derivative at transform(i)
207  peak_positions = Vespucci::Math::PeakFinding::FindPeakPositions(transform, dtransform,
208  threshold, threshold_method,
209  peak_magnitudes);
210  peak_extrema.col(i) = Vespucci::Math::PeakFinding::PeakExtrema(X.n_elem, peak_positions);
211  }
212  }
213  catch(std::exception e){
214  std::cerr << "CWTPeakAnalysis" << std::endl;
215  std::cerr << "i = " << i << std::endl;
216  throw(e);
217  }
218  return peak_extrema;
219 }
227 arma::field<arma::mat> Vespucci::Math::Transform::cwt_multi(const arma::mat &X, std::string wavelet, arma::uvec scales)
228 {
229  arma::field<arma::mat> results(X.n_cols);
230  for (arma::uword i = 0; i < results.n_elem; ++i){
231  results(i) = Vespucci::Math::Transform::cwt(X.col(i), wavelet, scales);
232  }
233  return results;
234 }
235 
236 
VESPUCCI_EXPORT arma::vec ExtendToNextPow(arma::vec X, arma::uword n)
Definition: accessory.cpp:259
T diff(const T &X, arma::uword deriv_order=1)
Vespucci::Math::diff.
VESPUCCI_EXPORT arma::vec PeakExtrema(arma::uword vector_size, arma::umat peak_positions)
VESPUCCI_EXPORT arma::mat cwt_spdbc_mat(const arma::mat &X, std::string wavelet, arma::uword qscale, double threshold, std::string threshold_method, arma::uword window_size, arma::field< arma::umat > &peak_positions, arma::mat &baselines)
Definition: cwt.cpp:150
T conv_fft(const T &A, const T &B, std::string type)
T rotate(const T &X, arma::uword shift_by, bool slide_back=true)
VESPUCCI_EXPORT arma::mat cwtPeakAnalysis(const arma::mat &X, std::string wavelet, arma::uword qscale, double threshold, std::string threshold_method, arma::mat &transform)
Definition: cwt.cpp:188
VESPUCCI_EXPORT arma::mat cwt(arma::vec X, std::string wavelet, arma::uvec scales)
Vespucci::Math::Transform::cwt.
Definition: cwt.cpp:42
cmplx FADDEEVA() w(cmplx z, double relerr)
Definition: Faddeeva.cpp:680
VESPUCCI_EXPORT arma::vec cwt_spdbc(const arma::vec &X, std::string wavelet, arma::uword qscale, double threshold, std::string threshold_method, arma::uword window_size, arma::umat &peak_extrema, arma::vec &baseline)
Definition: cwt.cpp:123
VESPUCCI_EXPORT arma::vec EstimateBaseline(arma::vec X, arma::umat peaks, arma::uword window_size)
EstimateBaseline.
VESPUCCI_EXPORT arma::field< arma::mat > cwt_multi(const arma::mat &X, std::string wavelet, arma::uvec scales)
Vespucci::Math::Transform::cwt_multi.
Definition: cwt.cpp:227
VESPUCCI_EXPORT arma::uvec FindPeakPositions(arma::vec X, arma::vec dX, double sel, double threshold, arma::uvec &local_minima)