Vespucci  1.0.0
baselinedialog.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 *******************************************************************************/
22 #include "ui_baselinedialog.h"
23 
30 BaselineDialog::BaselineDialog(QWidget *parent, QSharedPointer<VespucciWorkspace> ws, const QString &dataset_key) :
31  QDialog(parent),
32  ui(new Ui::BaselineDialog)
33 {
34  ui->setupUi(this);
35  workspace_ = ws;
36  dataset_ = workspace_->GetDataset(dataset_key);
37 
38  ui->param_0Label->setText("Window Size");
39  ui->param_1Label->setText("Iterations");
40  ui->param_0Label->setVisible(true);
41  ui->param_1Label->setVisible(true);
42  ui->param_0SpinBox->setVisible(true);
43  ui->param_1SpinBox->setVisible(true);
44 
45  ui->param_2DoubleSpinBox->setVisible(false);
46  ui->param_3DoubleSpinBox->setVisible(false);
47  ui->param_2Label->setVisible(false);
48  ui->param_3Label->setVisible(false);
49 
50  spectrum_q_ = Vespucci::FromArmaVec(dataset_->PointSpectrum(0));
51  abscissa_q_ = Vespucci::FromArmaVec(dataset_->abscissa());
52  arma::uvec ind = {0};
53  spectrum_ = dataset_->spectra(ind);
54  abscissa_ = dataset_->abscissa();
55 
56  ui->spectrumPlot->setInteraction(QCP::iRangeDrag, true);
57  ui->spectrumPlot->setInteraction(QCP::iRangeZoom, true);
58  ui->spectrumPlot->addGraph();
59  ui->spectrumPlot->graph(0)->setData(abscissa_q_, spectrum_q_);
60  ui->spectrumPlot->xAxis->setRange(dataset_->WavelengthRange());
61  ui->spectrumPlot->yAxis->setRange(0, spectrum_.max());
62  ui->spectrumPlot->replot();
63 }
64 
66 {
67  delete ui;
68 }
69 
74 void BaselineDialog::on_buttonBox_accepted()
75 {
76 
77  close();
78  QString method = ui->methodComboBox->currentText();
79 
80  if (method == "Median Filter"){
81  int window_size = ui->param_0SpinBox->value();
82  int iterations = ui->param_1SpinBox->value();
83  try{
84  dataset_->MFBaseline(window_size, iterations);
85  }
86  catch(exception e){
87  workspace_->main_window()->DisplayExceptionWarning(e);
88  }
89  }
90  else if (method == "Rolling Ball"){
91  size_t wm = ui->param_0SpinBox->value();
92  size_t ws = ui->param_1SpinBox->value();
93  try{
94  dataset_->RollingBallBaseline(wm, ws);
95  }catch(exception e){
96  workspace_->main_window()->DisplayExceptionWarning(e);
97  }
98  }
99  else if (method == "Vancouver Raman Algorithm (IModPoly)"){
100  int poly_order = ui->param_0SpinBox->value();
101  int max_it = ui->param_1SpinBox->value();
102  double threshold = ui->param_2DoubleSpinBox->value();
103  try{
104  dataset_->IModPolyBaseline(poly_order, max_it, threshold);
105  }catch(exception e){
106  workspace_->main_window()->DisplayExceptionWarning(e);
107  }
108  }
109  else if (method == "CWT"){
110  int lambda = ui->param_0SpinBox->value();
111  int penalty_order = ui->param_1SpinBox->value();
112  double SNR_threshold = ui->param_2DoubleSpinBox->value();
113  double peak_shape_threshold = ui->param_3DoubleSpinBox->value();
114  try{
115  dataset_->CWTBaseline(lambda, penalty_order, SNR_threshold, peak_shape_threshold);
116  }catch(exception e){
117  workspace_->main_window()->DisplayExceptionWarning(e);
118  }
119  }
120  else{
121  QMessageBox::warning(this, "Error", "An Error Occurred in BaselineDialog");
122  }
123 
124  dataset_.clear();
125 }
126 
130 void BaselineDialog::on_buttonBox_rejected()
131 {
132  close();
133  dataset_.clear();
134 }
135 
136 void BaselineDialog::on_methodComboBox_currentTextChanged(const QString &arg1)
137 {
138  if (arg1 == "Median Filter"){
139  ui->param_0Label->setText("Window Size");
140  ui->param_1Label->setText("Iterations");
141  ui->param_0Label->setVisible(true);
142  ui->param_1Label->setVisible(true);
143  ui->param_0SpinBox->setVisible(true);
144  ui->param_1SpinBox->setVisible(true);
145  ui->param_1SpinBox->setValue(1);
146  ui->param_0SpinBox->setValue(35);
147  ui->param_0SpinBox->setSingleStep(2);
148  ui->param_0SpinBox->setToolTip("Only odd window sizes are allowed. "
149  "If you enter an even number, "
150  "it will be rounded up.");
151  ui->param_0SpinBox->setMinimum(3);
152 
153  ui->param_2DoubleSpinBox->setVisible(false);
154  ui->param_3DoubleSpinBox->setVisible(false);
155  ui->param_2Label->setVisible(false);
156  ui->param_3Label->setVisible(false);
157  }
158  else if (arg1 == "Rolling Ball"){
159  ui->param_0Label->setText("Min/Max Window Size");
160  ui->param_1Label->setText("Smoothing Window Size");
161  ui->param_0Label->setVisible(true);
162  ui->param_1Label->setVisible(true);
163  ui->param_0SpinBox->setVisible(true);
164  ui->param_1SpinBox->setVisible(true);
165  ui->param_1SpinBox->setValue(25);
166  ui->param_0SpinBox->setValue(25);
167  ui->param_0SpinBox->setSingleStep(2);
168  ui->param_0SpinBox->setToolTip("Only odd window sizes are allowed. "
169  "If you enter an even number, "
170  "it will be rounded up.");
171  ui->param_0SpinBox->setMinimum(3);
172  ui->param_1SpinBox->setMinimum(3);
173  ui->param_1SpinBox->setSingleStep(2);
174 
175  ui->param_2DoubleSpinBox->setVisible(false);
176  ui->param_3DoubleSpinBox->setVisible(false);
177  ui->param_2Label->setVisible(false);
178  ui->param_3Label->setVisible(false);
179  }
180  else if (arg1 == "Vancouver Raman Algorithm (IModPoly)"){
181  ui->param_0Label->setText("Polynomial Order");
182  ui->param_0Label->setVisible(true);
183  ui->param_0SpinBox->setVisible(true);
184  ui->param_0SpinBox->setValue(5);
185  ui->param_0SpinBox->setSingleStep(1);
186  ui->param_0SpinBox->setMinimum(1);
187 
188  ui->param_1Label->setText("Maximum Iterations");
189  ui->param_1Label->setVisible(true);
190  ui->param_1SpinBox->setVisible(true);
191  ui->param_1SpinBox->setRange(1, 1000);
192  ui->param_1SpinBox->setValue(100);
193 
194  ui->param_2Label->setText("Threshold");
195  ui->param_2Label->setVisible(true);
196  ui->param_2DoubleSpinBox->setVisible(true);
197  ui->param_2DoubleSpinBox->setRange(0, 1);
198  ui->param_2DoubleSpinBox->setValue(0.005);
199 
200  ui->param_3Label->setVisible(false);
201  ui->param_3DoubleSpinBox->setVisible(false);
202 
203  ui->param_1SpinBox->setMinimum(1);
204  ui->param_1SpinBox->setSingleStep(1);
205 
206  }
207  else if (arg1 == "CWT"){
208  ui->param_0Label->setText("Whittaker Lambda");
209  ui->param_0Label->setVisible(true);
210  ui->param_0SpinBox->setVisible(true);
211 
212  ui->param_1Label->setText("Whittaker Penalty Order");
213  ui->param_1Label->setVisible(true);
214  ui->param_1SpinBox->setVisible(true);
215 
216  ui->param_2Label->setText("Peak SNR Threshold");
217  ui->param_2Label->setVisible(true);
218  ui->param_2DoubleSpinBox->setVisible(true);
219  ui->param_2DoubleSpinBox->setValue(3.0);
220  ui->param_2DoubleSpinBox->setRange(0, 10000);
221 
222  ui->param_3Label->setText("Peak Shape Threshold");
223  ui->param_3Label->setVisible(false);
224  ui->param_3DoubleSpinBox->setVisible(false);
225  ui->param_3DoubleSpinBox->setValue(0.50);
226  ui->param_3DoubleSpinBox->setRange(0, 1);
227 
228  ui->param_1SpinBox->setMinimum(1);
229  ui->param_1SpinBox->setSingleStep(1);
230 
231  }
232 }
233 
234 void BaselineDialog::on_pushButton_clicked()
235 {
236  using namespace arma;
237  QString method = ui->methodComboBox->currentText();
238  if (ui->spectrumPlot->graph(1))
239  ui->spectrumPlot->graph(1)->clearData();
240  else
241  ui->spectrumPlot->addGraph(ui->spectrumPlot->graph(0)->keyAxis(), ui->spectrumPlot->graph(0)->valueAxis());
242  if (ui->spectrumPlot->graph(2))
243  ui->spectrumPlot->graph(2)->clearData();
244  else
245  ui->spectrumPlot->addGraph(ui->spectrumPlot->graph(0)->keyAxis(), ui->spectrumPlot->graph(0)->valueAxis());
246 
247 
248  if (method == "Median Filter"){
249  int window_size = ui->param_0SpinBox->value();
250  if (!(window_size % 2)){window_size += 1;} //round up if even.
251  int iterations = ui->param_1SpinBox->value();
252  vec baseline = spectrum_;
253 
254  try{
255  for (uword i = 0; i < uword(iterations); ++i){
256 
257  baseline = Vespucci::Math::Smoothing::MedianFilter(baseline, window_size);
258  }
259  vec corrected = spectrum_ - baseline;
260  QVector<double> baseline_q = Vespucci::FromArmaVec(baseline);
261  QVector<double> corrected_q = Vespucci::FromArmaVec(corrected);
262  ui->spectrumPlot->graph(1)->setPen(QColor("black"));
263  ui->spectrumPlot->graph(1)->setData(abscissa_q_, baseline_q);
264  ui->spectrumPlot->graph(2)->setPen(QColor("red"));
265  ui->spectrumPlot->graph(2)->setData(abscissa_q_, corrected_q);
266  }
267  catch(exception e){
268  workspace_->main_window()->DisplayExceptionWarning(e);
269  }
270  }
271  else if (method == "Rolling Ball"){
272  size_t wm = ui->param_0SpinBox->value();
273  size_t ws = ui->param_1SpinBox->value();
274  if (wm % 2 == 0) wm++;
275  if (ws % 2 == 0) ws++;
276  vec baseline, corrected;
277  try{
278  corrected = Vespucci::Math::Baseline::RollingBallBaseline(spectrum_,
279  baseline,
280  wm,
281  ws);
282  QVector<double> corrected_q = Vespucci::FromArmaVec(corrected);
283  QVector<double> baseline_q = Vespucci::FromArmaVec(baseline);
284  ui->spectrumPlot->graph(1)->setPen(QColor("black"));
285  ui->spectrumPlot->graph(1)->setData(abscissa_q_, baseline_q);
286  ui->spectrumPlot->graph(2)->setPen(QColor("red"));
287  ui->spectrumPlot->graph(2)->setData(abscissa_q_, corrected_q);
288  }catch(exception e){
289  workspace_->main_window()->DisplayExceptionWarning(e);
290  }
291  }
292  else if (method == "Vancouver Raman Algorithm (IModPoly)"){
293  int poly_order = ui->param_0SpinBox->value();
294  int max_it = ui->param_1SpinBox->value();
295  double threshold = ui->param_2DoubleSpinBox->value();
296  vec baseline, corrected;
297  double err;
298  try{
299  corrected = Vespucci::Math::LinLeastSq::IModPoly(spectrum_, abscissa_,
300  baseline, corrected,
301  err, poly_order,
302  max_it, threshold);
303  QVector<double> baseline_q = Vespucci::FromArmaVec(baseline);
304  QVector<double> corrected_q = Vespucci::FromArmaVec(corrected);
305  ui->spectrumPlot->graph(1)->setPen(QColor("black"));
306  ui->spectrumPlot->graph(1)->setData(abscissa_q_, baseline_q);
307  ui->spectrumPlot->graph(2)->setPen(QColor("red"));
308  ui->spectrumPlot->graph(2)->setData(abscissa_q_, corrected_q);
309  }catch(exception e){
310  workspace_->main_window()->DisplayExceptionWarning(e);
311  }
312  }
313  else if (method == "CWT"){
314  //not implemented yet
315 
316  /*
317  int lambda = ui->param_0SpinBox->value();
318  int penalty_order = ui->param_1SpinBox->value();
319  double SNR_threshold = ui->param_2DoubleSpinBox->value();
320  double peak_shape_threshold = ui->param_3DoubleSpinBox->value();
321  try{
322  dataset_->CWTBaseline(lambda, penalty_order, SNR_threshold, peak_shape_threshold);
323  }catch(exception e){
324  workspace_->main_window()->DisplayExceptionWarning(e);
325  }
326  */
327  }
328  else{
329  QMessageBox::warning(this, "Error", "An Error Occurred in BaselineDialog");
330  }
331  ui->spectrumPlot->replot();
332 }
0x001 Axis ranges are draggable (see QCPAxisRect::setRangeDrag, QCPAxisRect::setRangeDragAxes) ...
Definition: qcustomplot.h:160
Definition: ahcadialog.h:26
VESPUCCI_EXPORT arma::uword IModPoly(const arma::vec &spectrum, const arma::vec &abscissa, arma::vec &baseline, arma::vec &corrected, double &err, const arma::uword poly_order, const arma::uword max_it, const double threshold)
Vespucci::Math::LinLeastSq::IModPoly Perform the Vancouver Raman Algorithm to correct baseline...
Definition: linleastsq.cpp:35
VESPUCCI_EXPORT arma::vec MedianFilter(const arma::vec &X, arma::uword window_size)
Vespucci::Math::Smoothing::MedianFilter.
Definition: nonlinear.cpp:30
BaselineDialog(QWidget *parent, QSharedPointer< VespucciWorkspace > ws, const QString &dataset_key)
BaselineDialog::BaselineDialog.
QVector< double > FromArmaVec(const arma::vec &data)
Definition: global.cpp:180
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
0x002 Axis ranges are zoomable with the mouse wheel (see QCPAxisRect::setRangeZoom, QCPAxisRect::setRangeZoomAxes)
Definition: qcustomplot.h:161
The BaselineDialog class The dialog that allows the user to baseline-correct the data.