bpp-core3  3.0.0
ApplicationTools.cpp
Go to the documentation of this file.
1 //
2 // File: ApplicationTools.cpp
3 // Authors:
4 // Julien Dutheil
5 // Created: 2005-10-21 16:19:00
6 //
7 
8 /*
9  Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
10 
11  This software is a computer program whose purpose is to provide basal and
12  utilitary classes. This file belongs to the Bio++ Project.
13 
14  This software is governed by the CeCILL license under French law and
15  abiding by the rules of distribution of free software. You can use,
16  modify and/ or redistribute the software under the terms of the CeCILL
17  license as circulated by CEA, CNRS and INRIA at the following URL
18  "http://www.cecill.info".
19 
20  As a counterpart to the access to the source code and rights to copy,
21  modify and redistribute granted by the license, users are provided only
22  with a limited warranty and the software's author, the holder of the
23  economic rights, and the successive licensors have only limited
24  liability.
25 
26  In this respect, the user's attention is drawn to the risks associated
27  with loading, using, modifying and/or developing or reproducing the
28  software by the user in light of its specific status of free software,
29  that may mean that it is complicated to manipulate, and that also
30  therefore means that it is reserved for developers and experienced
31  professionals having in-depth computer knowledge. Users are therefore
32  encouraged to load and test the software's suitability as regards their
33  requirements in conditions enabling the security of their systems and/or
34  data to be ensured and, more generally, to use and operate it in the
35  same conditions as regards security.
36 
37  The fact that you are presently reading this means that you have had
38  knowledge of the CeCILL license and that you accept its terms.
39 */
40 
41 
42 #include "ApplicationTools.h"
43 
44 using namespace bpp;
45 
46 // From the STL:
47 #include <cmath>
48 
49 using namespace std;
50 
51 /******************************************************************************/
52 
53 std::shared_ptr<OutputStream> ApplicationTools::error(new StdErr());
54 std::shared_ptr<OutputStream> ApplicationTools::message(new StdOut());
55 std::shared_ptr<OutputStream> ApplicationTools::warning(new StdOut());
61 
62 
63 /******************************************************************************/
64 
65 vector<string> ApplicationTools::matchingParameters(const string& pattern, const map<string, string>& params)
66 {
67  vector<string> retv;
68 
69  for (const auto& it : params)
70  {
71  StringTokenizer stj(pattern, "*", true, false);
72  size_t pos1, pos2;
73  string parn = it.first;
74  bool flag(true);
75  string g = stj.nextToken();
76  pos1 = parn.find(g);
77  if (pos1 != 0)
78  flag = false;
79  pos1 += g.length();
80  while (flag && stj.hasMoreToken())
81  {
82  g = stj.nextToken();
83  pos2 = parn.find(g, pos1);
84  if (pos2 == string::npos)
85  {
86  flag = false;
87  break;
88  }
89  pos1 = pos2 + g.length();
90  }
91  if (flag &&
92  ((g.length() == 0) || (pos1 == parn.length()) || (parn.rfind(g) == parn.length() - g.length())))
93  retv.push_back(parn);
94  }
95 
96  return retv;
97 }
98 
99 vector<string> ApplicationTools::matchingParameters(const string& pattern, vector<string>& params)
100 {
101  vector<string> retv;
102 
103  for (size_t i = 0; i < params.size(); i++)
104  {
105  StringTokenizer stj(pattern, "*", true, false);
106  size_t pos1, pos2;
107  string parn = params.at(i);
108  bool flag(true);
109  string g = stj.nextToken();
110  pos1 = parn.find(g);
111  if (pos1 != 0)
112  flag = false;
113  pos1 += g.length();
114  while (flag && stj.hasMoreToken())
115  {
116  g = stj.nextToken();
117  pos2 = parn.find(g, pos1);
118  if (pos2 == string::npos)
119  {
120  flag = false;
121  break;
122  }
123  pos1 = pos2 + g.length();
124  }
125  if (flag &&
126  ((g.length() == 0) || (pos1 == parn.length()) || (parn.rfind(g) == parn.length() - g.length())))
127  retv.push_back(parn);
128  }
129 
130  return retv;
131 }
132 
133 /******************************************************************************/
134 
136  const string& parameter,
137  const map<string, string>& params,
138  bool isRequired,
139  bool mustExist,
140  const string& suffix,
141  bool suffixIsOptional,
142  const string& defaultPath,
143  int warn)
144 {
145  string filePath = getStringParameter(parameter, params, defaultPath, suffix, suffixIsOptional, warn);
146  if (filePath == "")
147  filePath = "none";
148  if (filePath == "none" && isRequired)
149  {
150  throw Exception("You must specify a file for this parameter: " + parameter + (suffixIsOptional ? "" : suffix));
151  }
152  if (filePath == "none")
153  return filePath;
154  if (mustExist && !FileTools::fileExists(filePath))
155  {
156  throw Exception("File does not exists: " + filePath);
157  }
158  return filePath;
159 }
160 
161 /******************************************************************************/
162 
164  const string& parameterName,
165  const map<string, string>& params,
166  double defaultValue,
167  const string& suffix,
168  bool suffixIsOptional,
169  int warn)
170 {
171  double dParam = defaultValue;
172  if (parameterExists(parameterName + suffix, params))
173  {
174  dParam = TextTools::toDouble(params.at(parameterName + suffix));
175  }
176  else if (suffixIsOptional && parameterExists(parameterName, params))
177  {
178  dParam = TextTools::toDouble(params.at(parameterName));
179  }
180  else if (warn <= warningLevel)
181  {
182  displayWarning("Parameter " + parameterName + suffix + " not specified. Default used instead: " + TextTools::toString(defaultValue));
183  }
184  return dParam;
185 }
186 
187 /******************************************************************************/
188 
190  const string& parameterName,
191  const map<string, string>& params,
192  int defaultValue,
193  const string& suffix,
194  bool suffixIsOptional,
195  int warn)
196 {
197  int iParam = defaultValue;
198  if (parameterExists(parameterName + suffix, params))
199  {
200  iParam = TextTools::toInt(params.at(parameterName + suffix));
201  }
202  else if (suffixIsOptional && parameterExists(parameterName, params))
203  {
204  iParam = TextTools::toInt(params.at(parameterName));
205  }
206  else if (warn <= warningLevel)
207  {
208  displayWarning("Parameter " + parameterName + suffix + " not specified. Default used instead: " + TextTools::toString(defaultValue));
209  }
210  return iParam;
211 }
212 
213 /******************************************************************************/
214 
215 
217  const string& parameterName,
218  const map<string, string>& params,
219  bool defaultValue,
220  const string& suffix,
221  bool suffixIsOptional,
222  int warn)
223 {
224  string sParam;
225  bool bParam = defaultValue;
226  if (parameterExists(parameterName + suffix, params))
227  {
228  sParam = params.at(parameterName + suffix);
229  }
230  else if (suffixIsOptional && parameterExists(parameterName, params))
231  {
232  sParam = params.at(parameterName);
233  }
234  else
235  {
236  if (warn <= warningLevel)
237  {
238  displayWarning("Parameter " + parameterName + " not specified. Default used instead: " + TextTools::toString(defaultValue));
239  }
240  return bParam;
241  }
242  if ((sParam == "true")
243  || (sParam == "TRUE")
244  || (sParam == "t")
245  || (sParam == "T")
246  || (sParam == "yes")
247  || (sParam == "YES")
248  || (sParam == "y")
249  || (sParam == "Y")
250  || (sParam == "1"))
251  bParam = true;
252  else if ((sParam == "false")
253  || (sParam == "FALSE")
254  || (sParam == "f")
255  || (sParam == "F")
256  || (sParam == "no")
257  || (sParam == "NO")
258  || (sParam == "n")
259  || (sParam == "N")
260  || (sParam == "0"))
261  bParam = false;
262  else
263  throw Exception("ApplicationTools::getBooleanParameter. Wrong description:" + sParam);
264 
265  return bParam;
266 }
267 
268 /******************************************************************************/
269 
270 void ApplicationTools::displayMessage(const string& text)
271 {
272  if (message)
273  (*message << text).endLine();
274 }
275 
276 void ApplicationTools::displayError(const string& text)
277 {
278  if (error)
279  (*error << "ERROR!!! " << text).endLine();
280 }
281 
282 void ApplicationTools::displayWarning(const string& text)
283 {
284  if (warning)
285  (*warning << "WARNING!!! " << text).endLine();
286 }
287 
288 void ApplicationTools::displayTask(const string& text, bool eof)
289 {
290  if (message)
291  {
292  *message << TextTools::resizeRight(text, static_cast<size_t>(static_cast<float>(terminalWidth) * terminalSplit - 1), '.') << ": ";
293  if (eof)
294  message->endLine();
295  else
296  message->flush();
297  }
298 }
299 
301 {
302  if (message)
303  (*message << "Done.").endLine();
304 }
305 
306 /******************************************************************************/
307 
308 void ApplicationTools::displayGauge(size_t iter, size_t total, char symbol, const string& mes)
309 {
310  if (!message)
311  return;
312  if (total == 0)
313  return; // We do not display anything in that case.
314  size_t width = static_cast<size_t>(static_cast<float>(terminalWidth) * terminalSplit - 2);
315  string gauge = string(static_cast<size_t>((1. * static_cast<double>(iter) / static_cast<double>(total)) * static_cast<double>(width)), symbol);
316  string info = mes;
317  size_t step = static_cast<size_t>(ceil(1. * static_cast<double>(total) / static_cast<double>(width)));
318  size_t x = iter % step;
319  if (interactive)
320  {
321  string fill = string(width - gauge.length(), ' ');
322  gauge = "[" + gauge + fill + "] " + TextTools::resizeLeft(TextTools::toString(100 * iter / total), 3) + "%";
323  if (mes.size() > terminalWidth - gauge.size())
324  info = TextTools::resizeRight(mes, terminalWidth - gauge.size());
325  if (x == 0 || iter == total)
326  {
327  *message << '\r' + info + gauge; message->flush();
328  }
329  }
330  else
331  {
332  if (iter == 0)
333  {
334  *message << "[";
335  message->flush();
336  return;
337  }
338  if (iter >= total)
339  {
340  size_t fill = static_cast<size_t>(static_cast<float>(terminalWidth) * terminalSplit) - (total - 1) / step - 1;
341  *message << TextTools::resizeLeft("]", fill, symbol);
342  message->flush();
343  return;
344  }
345  if (x == 0)
346  {
347  *message << symbol; message->flush();
348  }
349  }
350 }
351 
352 /******************************************************************************/
353 
354 void ApplicationTools::displayUnlimitedGauge(size_t iter, const string& mes)
355 {
356  if (!message)
357  return;
358  string chars = "-/-\\";
359  string info = mes;
360  if (interactive)
361  {
362  unsigned int i = iter % 4;
363  *message << '\r' << info << chars[i] << " " << TextTools::toString(iter);
364  message->flush();
365  }
366  else
367  {
368  if (iter == 0)
369  *message << info;
370  *message << "*";
371  message->flush();
372  return;
373  }
374 }
375 
376 /******************************************************************************/
377 
378 void ApplicationTools::displayTime(const string& msg)
379 {
380  time_t endTime;
381  time(&endTime);
382  if (message)
383  {
384  double nsec = difftime(endTime, startTime);
385  double nmin = floor(nsec / 60.);
386  double nhou = floor(nmin / 60.);
387  double nday = floor(nhou / 24.);
388  nhou = nhou - nday * 24;
389  nmin = nmin - (nday * 24 + nhou) * 60;
390  nsec = nsec - ((nday * 24 + nhou) * 60 + nmin) * 60;
391  *message << msg << " ";
392  *message << nday << "d, ";
393  *message << nhou << "h, ";
394  *message << nmin << "m, ";
395  *message << nsec << "s.";
396  message->endLine();
397  }
398 }
399 
400 /******************************************************************************/
401 
403 {
404  time_t endTime;
405  time(&endTime);
406  return difftime(endTime, startTime);
407 }
408 
409 /******************************************************************************/
static int warningLevel
Specify the amount of warning to display.
static void displayMessage(const std::string &text)
Print a message.
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.
static std::shared_ptr< OutputStream > warning
The output stream where warnings have to be displayed.
static float terminalSplit
The fraction of terminal width dedicated to messages.
static void displayTask(const std::string &text, bool eof=false)
Print a task message.
static std::shared_ptr< OutputStream > error
The output stream where errors have to be displayed.
static std::shared_ptr< OutputStream > message
The output stream where messages have to be displayed.
static void displayUnlimitedGauge(size_t iter, const std::string &mes="")
Display a gauge for unefined amount of iterations.
static void displayError(const std::string &text)
Print an error message.
static size_t terminalWidth
The width of the output terminal (in character).
static void displayTaskDone()
Print a task ended message.
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 double getTime()
Get the current timer value.
static void displayWarning(const std::string &text)
Print a warning message.
static bool interactive
Tell if the program is interactive (typically run in foreground). Default to yes.
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 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::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 void displayTime(const std::string &msg)
Display the current timer value to the 'message' stream.
static void displayGauge(size_t iter, size_t total, char symbol='>', const std::string &mes="")
Display a gauge.
static time_t startTime
Timer variable.
Exception base class. Overload exception constructor (to control the exceptions mechanism)....
Definition: Exceptions.h:59
static bool fileExists(const std::string &filename)
Tells if a file exist.
Definition: FileTools.cpp:56
Standard error stream.
Definition: OutputStream.h:284
Standard output stream.
Definition: OutputStream.h:250
A tokenizer for strings.
const std::string & nextToken()
Get the next available token. If no token is availbale, throw an Exception.
bool hasMoreToken() const
Tell if some tokens are still available.
int toInt(const std::string &s, char scientificNotation)
Convert from string to int.
Definition: TextTools.cpp:246
double toDouble(const std::string &s, char dec, char scientificNotation)
Convert from string to double.
Definition: TextTools.cpp:255
std::string resizeLeft(const std::string &s, std::size_t newSize, char fill)
Definition: TextTools.cpp:282
std::string toString(T t)
General template method to convert to a string.
Definition: TextTools.h:153
std::string resizeRight(const std::string &s, std::size_t newSize, char fill)
Definition: TextTools.cpp:264