bpp-core3  3.0.0
ApplicationTools.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
5 #include "ApplicationTools.h"
6 
7 using namespace bpp;
8 
9 // From the STL:
10 #include <cmath>
11 
12 using namespace std;
13 
14 /******************************************************************************/
15 
16 std::shared_ptr<OutputStream> ApplicationTools::error(new StdErr());
17 std::shared_ptr<OutputStream> ApplicationTools::message(new StdOut());
18 std::shared_ptr<OutputStream> ApplicationTools::warning(new StdOut());
24 
25 
26 /******************************************************************************/
27 
28 vector<string> ApplicationTools::matchingParameters(const string& pattern, const map<string, string>& params)
29 {
30  vector<string> retv;
31 
32  for (const auto& it : params)
33  {
34  StringTokenizer stj(pattern, "*", true, false);
35  size_t pos1, pos2;
36  string parn = it.first;
37  bool flag(true);
38  string g = stj.nextToken();
39  pos1 = parn.find(g);
40  if (pos1 != 0)
41  flag = false;
42  pos1 += g.length();
43  while (flag && stj.hasMoreToken())
44  {
45  g = stj.nextToken();
46  pos2 = parn.find(g, pos1);
47  if (pos2 == string::npos)
48  {
49  flag = false;
50  break;
51  }
52  pos1 = pos2 + g.length();
53  }
54  if (flag &&
55  ((g.length() == 0) || (pos1 == parn.length()) || (parn.rfind(g) == parn.length() - g.length())))
56  retv.push_back(parn);
57  }
58 
59  return retv;
60 }
61 
62 vector<string> ApplicationTools::matchingParameters(const string& pattern, vector<string>& params)
63 {
64  vector<string> retv;
65 
66  for (size_t i = 0; i < params.size(); i++)
67  {
68  StringTokenizer stj(pattern, "*", true, false);
69  size_t pos1, pos2;
70  string parn = params.at(i);
71  bool flag(true);
72  string g = stj.nextToken();
73  pos1 = parn.find(g);
74  if (pos1 != 0)
75  flag = false;
76  pos1 += g.length();
77  while (flag && stj.hasMoreToken())
78  {
79  g = stj.nextToken();
80  pos2 = parn.find(g, pos1);
81  if (pos2 == string::npos)
82  {
83  flag = false;
84  break;
85  }
86  pos1 = pos2 + g.length();
87  }
88  if (flag &&
89  ((g.length() == 0) || (pos1 == parn.length()) || (parn.rfind(g) == parn.length() - g.length())))
90  retv.push_back(parn);
91  }
92 
93  return retv;
94 }
95 
96 /******************************************************************************/
97 
99  const string& parameter,
100  const map<string, string>& params,
101  bool isRequired,
102  bool mustExist,
103  const string& suffix,
104  bool suffixIsOptional,
105  const string& defaultPath,
106  int warn)
107 {
108  string filePath = getStringParameter(parameter, params, defaultPath, suffix, suffixIsOptional, warn);
109  if (filePath == "")
110  filePath = "none";
111  if (filePath == "none" && isRequired)
112  {
113  throw Exception("You must specify a file for this parameter: " + parameter + (suffixIsOptional ? "" : suffix));
114  }
115  if (filePath == "none")
116  return filePath;
117  if (mustExist && !FileTools::fileExists(filePath))
118  {
119  throw Exception("File does not exists: " + filePath);
120  }
121  return filePath;
122 }
123 
124 /******************************************************************************/
125 
127  const string& parameterName,
128  const map<string, string>& params,
129  double defaultValue,
130  const string& suffix,
131  bool suffixIsOptional,
132  int warn)
133 {
134  double dParam = defaultValue;
135  if (parameterExists(parameterName + suffix, params))
136  {
137  dParam = TextTools::toDouble(params.at(parameterName + suffix));
138  }
139  else if (suffixIsOptional && parameterExists(parameterName, params))
140  {
141  dParam = TextTools::toDouble(params.at(parameterName));
142  }
143  else if (warn <= warningLevel)
144  {
145  displayWarning("Parameter " + parameterName + suffix + " not specified. Default used instead: " + TextTools::toString(defaultValue));
146  }
147  return dParam;
148 }
149 
150 /******************************************************************************/
151 
153  const string& parameterName,
154  const map<string, string>& params,
155  int defaultValue,
156  const string& suffix,
157  bool suffixIsOptional,
158  int warn)
159 {
160  int iParam = defaultValue;
161  if (parameterExists(parameterName + suffix, params))
162  {
163  iParam = TextTools::toInt(params.at(parameterName + suffix));
164  }
165  else if (suffixIsOptional && parameterExists(parameterName, params))
166  {
167  iParam = TextTools::toInt(params.at(parameterName));
168  }
169  else if (warn <= warningLevel)
170  {
171  displayWarning("Parameter " + parameterName + suffix + " not specified. Default used instead: " + TextTools::toString(defaultValue));
172  }
173  return iParam;
174 }
175 
176 /******************************************************************************/
177 
178 
180  const string& parameterName,
181  const map<string, string>& params,
182  bool defaultValue,
183  const string& suffix,
184  bool suffixIsOptional,
185  int warn)
186 {
187  string sParam;
188  bool bParam = defaultValue;
189  if (parameterExists(parameterName + suffix, params))
190  {
191  sParam = params.at(parameterName + suffix);
192  }
193  else if (suffixIsOptional && parameterExists(parameterName, params))
194  {
195  sParam = params.at(parameterName);
196  }
197  else
198  {
199  if (warn <= warningLevel)
200  {
201  displayWarning("Parameter " + parameterName + " not specified. Default used instead: " + TextTools::toString(defaultValue));
202  }
203  return bParam;
204  }
205  if ((sParam == "true")
206  || (sParam == "TRUE")
207  || (sParam == "t")
208  || (sParam == "T")
209  || (sParam == "yes")
210  || (sParam == "YES")
211  || (sParam == "y")
212  || (sParam == "Y")
213  || (sParam == "1"))
214  bParam = true;
215  else if ((sParam == "false")
216  || (sParam == "FALSE")
217  || (sParam == "f")
218  || (sParam == "F")
219  || (sParam == "no")
220  || (sParam == "NO")
221  || (sParam == "n")
222  || (sParam == "N")
223  || (sParam == "0"))
224  bParam = false;
225  else
226  throw Exception("ApplicationTools::getBooleanParameter. Wrong description:" + sParam);
227 
228  return bParam;
229 }
230 
231 /******************************************************************************/
232 
233 void ApplicationTools::displayMessage(const string& text)
234 {
235  if (message)
236  (*message << text).endLine();
237 }
238 
239 void ApplicationTools::displayError(const string& text)
240 {
241  if (error)
242  (*error << "ERROR!!! " << text).endLine();
243 }
244 
245 void ApplicationTools::displayWarning(const string& text)
246 {
247  if (warning)
248  (*warning << "WARNING!!! " << text).endLine();
249 }
250 
251 void ApplicationTools::displayTask(const string& text, bool eof)
252 {
253  if (message)
254  {
255  *message << TextTools::resizeRight(text, static_cast<size_t>(static_cast<float>(terminalWidth) * terminalSplit - 1), '.') << ": ";
256  if (eof)
257  message->endLine();
258  else
259  message->flush();
260  }
261 }
262 
264 {
265  if (message)
266  (*message << "Done.").endLine();
267 }
268 
269 /******************************************************************************/
270 
271 void ApplicationTools::displayGauge(size_t iter, size_t total, char symbol, const string& mes)
272 {
273  if (!message)
274  return;
275  if (total == 0)
276  return; // We do not display anything in that case.
277  size_t width = static_cast<size_t>(static_cast<float>(terminalWidth) * terminalSplit - 2);
278  string gauge = string(static_cast<size_t>((1. * static_cast<double>(iter) / static_cast<double>(total)) * static_cast<double>(width)), symbol);
279  string info = mes;
280  size_t step = static_cast<size_t>(ceil(1. * static_cast<double>(total) / static_cast<double>(width)));
281  size_t x = iter % step;
282  if (interactive)
283  {
284  string fill = string(width - gauge.length(), ' ');
285  gauge = "[" + gauge + fill + "] " + TextTools::resizeLeft(TextTools::toString(100 * iter / total), 3) + "%";
286  if (mes.size() > terminalWidth - gauge.size())
287  info = TextTools::resizeRight(mes, terminalWidth - gauge.size());
288  if (x == 0 || iter == total)
289  {
290  *message << '\r' + info + gauge; message->flush();
291  }
292  }
293  else
294  {
295  if (iter == 0)
296  {
297  *message << "[";
298  message->flush();
299  return;
300  }
301  if (iter >= total)
302  {
303  size_t fill = static_cast<size_t>(static_cast<float>(terminalWidth) * terminalSplit) - (total - 1) / step - 1;
304  *message << TextTools::resizeLeft("]", fill, symbol);
305  message->flush();
306  return;
307  }
308  if (x == 0)
309  {
310  *message << symbol; message->flush();
311  }
312  }
313 }
314 
315 /******************************************************************************/
316 
317 void ApplicationTools::displayUnlimitedGauge(size_t iter, const string& mes)
318 {
319  if (!message)
320  return;
321  string chars = "-/-\\";
322  string info = mes;
323  if (interactive)
324  {
325  unsigned int i = iter % 4;
326  *message << '\r' << info << chars[i] << " " << TextTools::toString(iter);
327  message->flush();
328  }
329  else
330  {
331  if (iter == 0)
332  *message << info;
333  *message << "*";
334  message->flush();
335  return;
336  }
337 }
338 
339 /******************************************************************************/
340 
341 void ApplicationTools::displayTime(const string& msg)
342 {
343  time_t endTime;
344  time(&endTime);
345  if (message)
346  {
347  double nsec = difftime(endTime, startTime);
348  double nmin = floor(nsec / 60.);
349  double nhou = floor(nmin / 60.);
350  double nday = floor(nhou / 24.);
351  nhou = nhou - nday * 24;
352  nmin = nmin - (nday * 24 + nhou) * 60;
353  nsec = nsec - ((nday * 24 + nhou) * 60 + nmin) * 60;
354  *message << msg << " ";
355  *message << nday << "d, ";
356  *message << nhou << "h, ";
357  *message << nmin << "m, ";
358  *message << nsec << "s.";
359  message->endLine();
360  }
361 }
362 
363 /******************************************************************************/
364 
366 {
367  time_t endTime;
368  time(&endTime);
369  return difftime(endTime, startTime);
370 }
371 
372 /******************************************************************************/
std::string resizeRight(const std::string &s, std::size_t newSize, char fill)
Definition: TextTools.cpp:226
static void displayTaskDone()
Print a task ended message.
static void displayWarning(const std::string &text)
Print a warning message.
A tokenizer for strings.
static std::vector< std::string > matchingParameters(const std::string &pattern, const std::map< std::string, std::string > &params)
Returns a vector of parameter names that match a given pattern.
double toDouble(const std::string &s, char dec, char scientificNotation)
Convert from string to double.
Definition: TextTools.cpp:217
const std::string & nextToken()
Get the next available token. If no token is availbale, throw an Exception.
static int warningLevel
Specify the amount of warning to display.
static void displayTime(const std::string &msg)
Display the current timer value to the &#39;message&#39; stream.
bool hasMoreToken() const
Tell if some tokens are still available.
static void displayTask(const std::string &text, bool eof=false)
Print a task message.
STL namespace.
static size_t terminalWidth
The width of the output terminal (in character).
Standard output stream.
Definition: OutputStream.h:212
static double getDoubleParameter(const std::string &parameterName, const std::map< std::string, std::string > &params, double defaultValue, const std::string &suffix="", bool suffixIsOptional=true, int warn=0)
Get a double parameter.
static std::shared_ptr< OutputStream > warning
The output stream where warnings have to be displayed.
static time_t startTime
Timer variable.
Standard error stream.
Definition: OutputStream.h:246
std::string resizeLeft(const std::string &s, std::size_t newSize, char fill)
Definition: TextTools.cpp:244
static std::shared_ptr< OutputStream > message
The output stream where messages have to be displayed.
static bool interactive
Tell if the program is interactive (typically run in foreground). Default to yes. ...
static int getIntParameter(const std::string &parameterName, const std::map< std::string, std::string > &params, int defaultValue, const std::string &suffix="", bool suffixIsOptional=true, int warn=0)
Get an integer parameter.
static std::shared_ptr< OutputStream > error
The output stream where errors have to be displayed.
static void displayMessage(const std::string &text)
Print a message.
static std::string getAFilePath(const std::string &parameter, const std::map< std::string, std::string > &params, bool isRequired=true, bool mustExist=true, const std::string &suffix="", bool suffixIsOptional=false, const std::string &defaultPath="none", int warn=0)
Get a file path.
static bool getBooleanParameter(const std::string &parameterName, const std::map< std::string, std::string > &params, bool defaultValue, const std::string &suffix="", bool suffixIsOptional=true, int warn=0)
Get a boolean parameter.
static float terminalSplit
The fraction of terminal width dedicated to messages.
Exception base class. Overload exception constructor (to control the exceptions mechanism). Destructor is already virtual (from std::exception)
Definition: Exceptions.h:20
static void displayGauge(size_t iter, size_t total, char symbol='>', const std::string &mes="")
Display a gauge.
int toInt(const std::string &s, char scientificNotation)
Convert from string to int.
Definition: TextTools.cpp:208
static bool fileExists(const std::string &filename)
Tells if a file exist.
Definition: FileTools.cpp:19
static void displayUnlimitedGauge(size_t iter, const std::string &mes="")
Display a gauge for unefined amount of iterations.
std::string toString(T t)
General template method to convert to a string.
Definition: TextTools.h:115
static void displayError(const std::string &text)
Print an error message.
static double getTime()
Get the current timer value.