Vespucci  1.0.0
macroparser.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 *******************************************************************************/
20 #include "macroparser.h"
21 
22 MacroParser::MacroParser(QSharedPointer<VespucciDataset> dataset)
23 {
24  dataset_ = dataset;
25 
26  valid_commands_["MinMaxNormalize"] = QStringList();
27  valid_commands_["MeanCenter"] = QStringList();
28  valid_commands_["ZScoreNormalize"] = QStringList();
29  valid_commands_["AbsoluteValue"] = QStringList();
30  valid_commands_["ShedZeroSpectra"] = QStringList();
31  valid_commands_["ShedZeroWavelengths"] = QStringList();
32  valid_commands_["VectorNormalize"] = QStringList({ "UInt" });
33  valid_commands_["SNVNormalize"] = QStringList({ "Double", "Bool" });
34  valid_commands_["PeakIntensityNormalize"] = QStringList({ "Double", "Double" });
35  valid_commands_["Booleanize"] = QStringList({ "Double" , "Double" , "Bool" , "Bool" });
36  valid_commands_["Clamp"] = QStringList({ "Double" , "Double" });
37  valid_commands_["MedianFilter"] = QStringList({ "UInt" });
38  valid_commands_["LinearMovingAverage"] = QStringList({ "UInt" });
39  valid_commands_["SavitzkyGolay"] = QStringList({ "UInt", "UInt", "UInt" });
40  valid_commands_["SingularValue"] = QStringList({ "UInt" });
41  valid_commands_["QUIC_SVD"] = QStringList({ "Double" });
42  valid_commands_["MFBaseline"] = QStringList({ "Int", "Int" });
43  valid_commands_["IModPolyBaseline"] = QStringList({ "UInt", "UInt", "Double" });
44  valid_commands_["RemoveClippedSpectra"] = QStringList({ "Double" });
45  valid_commands_["RemoveFlatSpectra"] = QStringList({ "Double" });
46  valid_commands_["ZeroClippedSpectra"] = QStringList({ "Double" });
47  valid_commands_["ZeroFlatSpectra"] = QStringList({ "Double" });
48  valid_commands_["Scale"] = QStringList({ "Double" });
49  valid_commands_["ShedSpectrum"] = QStringList({ "UInt" });
50  valid_commands_["ZeroSpectrum"] = QStringList({ "UInt" });
51  valid_commands_["Univariate"] = QStringList({ "String" , "Double" , "Double" , "UInt" });
52  valid_commands_["BandRatio"] = QStringList({ "String" , "Double" , "Double" , "Double" , "Double" , "UInt" });
53  valid_commands_["PartialLeastSquares"] = QStringList({ "String", "UInt" });
54  valid_commands_["VertexComponents"] = QStringList({ "String", "UInt" });
55  valid_commands_["KMeans"] = QStringList({ "String", "String", "String", "Bool", "UInt" });
56  valid_commands_["PrincipalComponents"] = QStringList({ "String" });
57  valid_commands_["ClassicalLeastSquares"] = QStringList({"String", "String", "String", "String"});
58  valid_commands_["RollingBallBaseline"] = QStringList({ "UInt", "UInt" });
59 }
60 
68 bool MacroParser::LoadMacro(QString macro)
69 {
70 
71  QStringList command_list = macro.split("\n");
72  //this regular expression is used to split the commands so that the first
73  //member of the list is the function name, and all subsequent entries are
74  //parameters of the function.
75  QRegExp sep("(\\(|\\)|,|\\s)");
76 
77  bool command_valid;
78  for (int i = 0; i < command_list.size(); ++i){
79  QStringList pieces = command_list[i].split(sep, QString::SkipEmptyParts);
80  if (!pieces.size()) continue;
81  QString function_name = pieces.first();
82  pieces.removeAt(0);
83  command_valid = ValidateCommand(function_name, pieces, error_param_);
84  if (!command_valid){
85  error_line_ = i;
86  return false;
87  }
88  else{
89  QPair<QString, QStringList> processed_command(function_name, pieces);
90  commands_.push_back(processed_command);
91  }
92  }
93 
94  return true;
95 }
96 
104 {
105  bool ok;
106  for (int i = 0; i < commands_.size(); ++i){
107  ok = ValidateCommand(commands_[i].first, commands_[i].second, error_param_);
108  if (!ok){
109  error_line_ = i + 1; //indexing starts at 1 here because to the user there is no line 0.
110  error_param_++; //indexing starts at 1 here because we count the name of the function as parameter 0.
111  return false;
112  }
113  }
114 
115  //if all commands are valid, execute each in order
116  for(auto command: commands_){
117  ExecuteCommand(command.first, command.second);
118  }
119  return true; //we've already handled the cases where it would return false
120 }
121 
122 void MacroParser::Error(int &error_line, int &error_param)
123 {
124  error_line = error_line_;
125  error_param = error_param_;
126 }
127 
135 void MacroParser::ExecuteCommand(QString command, QStringList params)
136 {
137  if (command == "MinMaxNormalize")
138  dataset_->MinMaxNormalize();
139  else if (command == "VectorNormalize")
140  dataset_->VectorNormalize(params[0].toInt());
141  else if (command == "MeanCenter")
142  dataset_->MeanCenter();
143  else if (command == "ZScoreNormalize")
144  dataset_->ZScoreNormalize();
145  else if (command == "AbsoluteValue")
146  dataset_->AbsoluteValue();
147  else if (command == "ShedZeroSpectra")
148  dataset_->ShedZeroSpectra();
149  else if (command == "ShedZeroWavelengths")
150  dataset_->ShedZeroWavelengths();
151  else if (command == "SNVNormalize")
152  dataset_->SNVNormalize(params[0].toDouble(), ToBool(params[1]));
153  else if (command == "PeakIntensityNormalize")
154  dataset_->PeakIntensityNormalize(params[0].toDouble(), params[1].toDouble());
155  else if (command == "Booleanize")
156  dataset_->Booleanize(params[0].toDouble(), params[1].toDouble(), ToBool(params[2]), ToBool(params[3]));
157  else if (command == "Clamp")
158  dataset_->Clamp(params[0].toDouble(), params[1].toDouble());
159  else if (command == "MedianFilter")
160  dataset_->MedianFilter(params[0].toInt());
161  else if (command == "LinearMovingAverage")
162  dataset_->LinearMovingAverage(params[0].toInt());
163  else if (command == "SavitzkyGolay")
164  dataset_->SavitzkyGolay(params[0].toInt(), params[1].toInt(), params[2].toInt());
165  else if (command == "SingularValue")
166  dataset_->SingularValue(params[0].toInt());
167  else if (command == "QUIC_SVD")
168  dataset_->QUIC_SVD(params[0].toDouble());
169  else if (command == "MFBaseline")
170  dataset_->MFBaseline(params[0].toInt(), params[1].toInt());
171  else if (command == "IModPolyBaseline")
172  dataset_->IModPolyBaseline(params[0].toInt(), params[1].toInt(), params[2].toDouble());
173  else if (command == "RemoveClippedSpectra")
174  dataset_->RemoveClippedSpectra(params[0].toDouble());
175  else if (command == "RemoveFlatSpectra")
176  dataset_->RemoveFlatSpectra(params[0].toDouble());
177  else if (command == "ZeroFlatSpectra")
178  dataset_->ZeroFlatSpectra(params[0].toDouble());
179  else if (command == "ZeroClippedSpectra")
180  dataset_->ZeroClippedSpectra(params[0].toDouble());
181  else if (command == "Scale")
182  dataset_->Scale(params[0].toDouble());
183  else if (command == "ShedSpectrum")
184  dataset_->ShedSpectrum(params[0].toInt());
185  else if (command == "ZeroSpectrum")
186  dataset_->ZeroSpectrum(params[0].toInt());
187  else if (command == "Univariate"){
188  double param1 = params[1].toDouble();
189  double param2 = params[2].toDouble();
190  dataset_->Univariate(params[0], param1, param2, params[3].toInt());
191  }
192  else if (command == "BandRatio"){
193  double param1 = params[1].toDouble();
194  double param2 = params[2].toDouble();
195  double param3 = params[3].toDouble();
196  double param4 = params[4].toDouble();
197  dataset_->BandRatio(params[0], param1, param2, param3, param4, params[5].toInt());
198  }
199  else if (command == "PartialLeastSquares")
200  dataset_->PartialLeastSquares(params[0], params[1].toInt());
201  else if (command == "VertexComponents")
202  dataset_->VertexComponents(params[0], params[1].toInt());
203  else if (command == "KMeans")
204  dataset_->KMeans(params[0], params[1], params[2], ToBool(params[3]), params[4].toInt());
205  else if (command == "PrincipalComponents")
206  dataset_->PrincipalComponents(params[0]);
207  else if (command == "ClassicalLeastSquares"){
208  QString name = params[0];
209  QStringList keys = params;
210  params.removeFirst();
211  dataset_->ClassicalLeastSquares(name, keys);
212  }
213  else if (command == "RollingBallBaseline")
214  dataset_->RollingBallBaseline(params[0].toInt(), params[1].toInt());
215  else; //Do nothing
216 }
217 
218 bool ToBool(const QString &param) {
219  return param.toLower() == "true";
220 }
221 
240 bool MacroParser::ValidateCommand(QString command, QStringList params, int &param_error)
241 {
242  QStringList expected_types = valid_commands_[command];
243  bool conversion_ok;
244 
245  if (expected_types.size() != params.size()) {
246  param_error = 0;
247  return false;
248  }
249  for (int i = 0; i < params.size(); ++i) {
250  if (expected_types[i] == "Bool")
251  conversion_ok = (params[i].toLower() == "true" || params[i].toLower() == "false");
252  else if (expected_types[i] == "Int")
253  params[i].toInt(&conversion_ok);
254  else if (expected_types[i] == "UInt") {
255  int val = params[i].toInt(&conversion_ok);
256  conversion_ok = (conversion_ok && val >= 0);
257  }
258  else if (expected_types[i] == "Double")
259  params[i].toDouble(&conversion_ok);
260  else conversion_ok = true; //Treating as String
261 
262  if (!conversion_ok) {
263  param_error = i + 1;
264  return false;
265  }
266  }
267  return true;
268 }
269 
270 bool MacroParser::ToBool(const QString &param)
271 {
272  return (param.toLower() == "true");
273 }
MacroParser(QSharedPointer< VespucciDataset > dataset)
Definition: macroparser.cpp:22
bool LoadMacro(QString macro)
MacroParser::LoadMacro.
Definition: macroparser.cpp:68
void Error(int &error_line, int &error_param)
bool ExecuteMacro()
MacroParser::ExecuteMacro Iteratively executes the commands in commands_. Each command is first valid...