Xmipp  v3.23.11-Nereus
xmipp_program.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Authors: J.M. de la Rosa Trevin (josem@cnb.csic.es)
3  *
4  *
5  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
6  *
7  * This program 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 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program 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 this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  * 02111-1307 USA
21  *
22  * All comments concerning this program package may be sent to the
23  * e-mail address 'xmipp@cnb.csic.es'
24  ***************************************************************************/
25 
26 #include "xmipp_program.h"
27 #include "argsparser.h"
28 #include "xmipp_program_sql.h"
29 #include "argsprinter.h"
30 #include "xmipp_funcs.h"
31 #include "args.h"
32 
34 {
35  CommentList comments;
36  comments.addComment("Verbosity level, 0 means no output.");
37  defaultComments["-v"] = comments;
38 }
39 
40 void XmippProgram::processDefaultComment(const char *param, const char *left)
41 {
42  addParamsLine(((String)left+":"+defaultComments[param].comments[0]).c_str());
43  int imax=defaultComments[param].comments.size();
44  for (int i=1; i<imax; ++i)
45  addParamsLine(((String)":"+defaultComments[param].comments[i]).c_str());
46 }
47 
48 void XmippProgram::setDefaultComment(const char *param, const char *comment)
49 {
50  defaultComments[param].clear();
51  defaultComments[param].addComment(comment);
52 }
53 
55 {
57  addParamsLine("== Common options ==");
58  processDefaultComment("-v","[-v+ <verbose_level=1>]");
59  addParamsLine("alias --verbose;");
60  addParamsLine("[-h+* <param=\"\">] : If not param is supplied show this help message.");
61  addParamsLine(" : Otherwise, specific param help is showed,");
62  addParamsLine(" : param should be provided without the '-'");
63  addParamsLine("alias --help;");
64  addParamsLine("[--more*] : Show additional options.");
65 
68  addParamsLine("==+++++ Internal section ==");
69  addParamsLine("[--xmipp_write_definition* <dbname>] : Print metadata info about the program to sqlite database");
70  addParamsLine("[--xmipp_write_wiki* ] : Print metadata info about the program in wiki format");
71  addParamsLine("[--xmipp_write_autocomplete* <scriptfile>] : Add program autocomplete bash options to script file");
72  addParamsLine("[--xmipp_protocol_script <script>] : This is only meanful when execute throught protocols");
73  addParamsLine("[--xmipp_validate_params] : Validate input params");
74 }
75 
76 void XmippProgram::init()
77 {
78  initComments();
79  progDef = new ProgramDef();
80  this->defineParams();
81  this->defineCommons();
82  progDef->parse();
83 }
84 
85 bool XmippProgram::checkBuiltIns()
86 {
88  if (checkParam("--more"))
89  usage(1);
91  else if (checkParam("--help"))
92  {
93  String helpParam = getParam("-h");
94  if (helpParam != "")
95  {
96  String cmdHelp("-");
97  cmdHelp += helpParam;
98  if (existsParam(cmdHelp.c_str()))
99  usage(cmdHelp);
100  else
101  {
102  cmdHelp.insert(0, "-");
103  if (existsParam(cmdHelp.c_str()))
104  usage(cmdHelp);
105  else
106  {
107  if (verbose)
108  std::cerr << "Unrecognized param " << helpParam << " neither - or --" << std::endl;
109  usage();
110  }
111  }
112  }
113  else
114  usage();
115  }
116  else if (checkParam("--xmipp_write_definition"))
117  writeToDB();
118  else if (checkParam("--xmipp_write_wiki"))
119  createWiki();
120  else if (checkParam("--xmipp_write_autocomplete"))
121  writeToAutocomplete();
122  else
123  return false;
124  return true;
125 }
126 
127 void XmippProgram::writeToDB()
128 {
129  ProgramDb db;
130  db.printProgram(*progDef);
131 }
132 
133 void XmippProgram::writeToAutocomplete( )
134 {
135  String scriptfile = getParam("--xmipp_write_autocomplete");
136  AutocompletePrinter ap(scriptfile.c_str());
137  ap.printProgram(*progDef, 3);
138 }
139 
140 void XmippProgram::createWiki()
141 {
142  WikiPrinter wiki;
143  wiki.printProgram(*progDef, 3);
144 }
145 
147 {
148  //by defaul all programs have verbose = 1
149  // this can be changed on mpi slaves node for no output at all
150  verbose = 1;
151  progDef = NULL;
152  runWithoutArgs = doRun = false;
153  errorCode = 0;
154 }
155 
157 {
158  runWithoutArgs = doRun = false;
159  errorCode = 0;
160  init();
161  read(argc, argv);
162 }
163 
165 {
166  delete progDef;
167 }
168 
170 {
171  REPORT_ERROR(ERR_NOT_IMPLEMENTED, "function 'defineParams'");
172 }
173 
175 {
176  REPORT_ERROR(ERR_NOT_IMPLEMENTED, "function 'run'");
177 }
178 
179 void XmippProgram::quit(int exit_code) const
180 {
181  exit(exit_code);
182 }
183 
185 {
186  REPORT_ERROR(ERR_NOT_IMPLEMENTED, "function 'readParams'");
187 }
188 
189 
190 
191 void XmippProgram::read(int argc, const char ** argv, bool reportErrors)
192 {
193  if (progDef == NULL)
194  init();
195 
196  setProgramName(argv[0]);
197 
198  doRun = false;
199  errorCode = 0; //suppose no errors
201  //this behavior will be defined with environment variable XMIPP_BEHAVIOR
202  if (argc == 1)
203  {
204  if (runWithoutArgs) {
205  doRun = true;
206  } else {
207  usage();
208  }
209  }
210  else
211  {
212 
213  this->argc = argc;
214  this->argv = argv;
215  progDef->read(argc, argv, reportErrors);
216  if (!checkBuiltIns())
217  {
218  if (verbose) //if 0, ignore the parameter, useful for mpi programs
219  verbose = getIntParam("--verbose");
220  this->readParams();
221  doRun = !checkParam("--xmipp_validate_params"); //just validation, not run
222  }
223  }
224 }
225 
226 void XmippProgram::read(int argc, char ** argv, bool reportErrors)
227 {
228  read(argc,(const char **)argv,reportErrors);
229 }
230 
231 void XmippProgram::read(const String &argumentsLine)
232 {
233  int argc;
234  char ** argv=NULL;
235  char * copy=NULL;
236 
237  generateCommandLine(argumentsLine, argc, argv, copy);
238  read(argc, (const char **)argv);
239  delete[] copy;
240  delete[] argv[0]; // the only one allocated, the rest is pointing to 'copy'
241  delete[] argv;
242 }
243 
245 {
246  if (doRun)
247  this->run();
248  return errorCode;
249 }
251 void XmippProgram::initProgress(size_t total, size_t stepBin)
252 {
253  if (verbose)
254  {
255  progressTotal = total;
256  progressStep = XMIPP_MAX(1, total / stepBin);
257  progressLast = 0;
258  init_progress_bar(total);
259  }
260 }
261 
263 void XmippProgram::setProgress(size_t value)
264 {
265  progressLast = value ? value : progressLast + 1;
266  if (verbose && progressLast % progressStep == 0)
267  progress_bar(progressLast);
268 }
269 
272 {
273  if (verbose)
274  progress_bar(progressTotal);
275 }
276 
278 {
279  progDef->name = name;
280 }
281 
282 void XmippProgram::addUsageLine(const char * line, bool verbatim)
283 {
284  progDef->usageComments.addComment(line,verbatim);
285 }
286 void XmippProgram::addExampleLine(const char * example, bool verbatim)
287 {
288  progDef->examples.addComment(example, verbatim);
289 }
290 void XmippProgram::addSeeAlsoLine(const char * seeAlso)
291 {
292  if (progDef->seeAlso=="")
293  progDef->seeAlso = seeAlso;
294  else
295  {
296  progDef->seeAlso +=", ";
297  progDef->seeAlso +=seeAlso;
298  }
299 }
300 
302 {
304 }
306 {
307  progDef->pLexer->addLine(line);
308 }
309 
310 void XmippProgram::addParamsLine(const char * line)
311 {
312  progDef->pLexer->addLine((String)line);
313 }
314 
315 void XmippProgram::addKeywords(const char * keywords)
316 {
317  progDef->keywords += " ";
318  progDef->keywords += keywords;
319 }
320 
321 const char * XmippProgram::getParam(const char * param, int arg)
322 {
323  return progDef->getParam(param, arg);
324 }
325 
326 const char * XmippProgram::getParam(const char * param, const char * subparam, int arg)
327 {
328  return progDef->getParam(param, subparam, arg);
329 }
330 
331 int XmippProgram::getIntParam(const char * param, int arg)
332 {
333  return textToInteger(progDef->getParam(param, arg));
334 }
335 
336 int XmippProgram::getIntParam(const char * param, const char * subparam, int arg)
337 {
338  return textToInteger(progDef->getParam(param, subparam, arg));
339 }
340 
341 double XmippProgram::getDoubleParam(const char * param, int arg)
342 {
343  return textToFloat(progDef->getParam(param, arg));
344 }
345 
346 double XmippProgram::getDoubleParam(const char * param, const char * subparam, int arg)
347 {
348  return textToFloat(progDef->getParam(param, subparam, arg));
349 }
350 
351 float XmippProgram::getFloatParam(const char * param, int arg)
352 {
353  return textToFloat(progDef->getParam(param, arg));
354 }
355 
356 float XmippProgram::getFloatParam(const char * param, const char * subparam, int arg)
357 {
358  return textToFloat(progDef->getParam(param, subparam, arg));
359 }
360 
362 {
363  ParamDef * paramDef = progDef->findParam(param);
364  if (paramDef == NULL)
365  REPORT_ERROR(ERR_ARG_INCORRECT, ((String)"Doesn't exists param: " + param));
366  list.clear();
367  for (size_t i = 0; i < paramDef->cmdArguments.size(); ++i)
368  list.push_back(paramDef->cmdArguments[i]);
369 }
370 
372 {
373  ParamDef * paramDef = progDef->findParam(param);
374  if (paramDef == NULL)
375  REPORT_ERROR(ERR_ARG_INCORRECT, ((String)"Doesn't exists param: " + param));
376  return paramDef->cmdArguments.size();
377 }
378 
379 bool XmippProgram::checkParam(const char * param)
380 {
381  ParamDef * paramDef = progDef->findParam(param);
382  if (paramDef == NULL)
383  REPORT_ERROR(ERR_ARG_INCORRECT, ((String)"Doesn't exists param: " + param));
384  return paramDef->counter == 1;
385 }
386 
388 {
389  ParamDef * paramDef = progDef->findParam(param);
390  return paramDef != NULL;
391 }
392 
393 
395 {
396  return progDef->findParam(param);
397 }
398 
399 const char * XmippProgram::name() const
400 {
401  return progDef->name.c_str();
402 }
403 
404 void XmippProgram::usage(int verb) const
405 {
406  if (verbose)
407  {
408  ConsolePrinter cp;
409  char * var = getenv("XMIPP_COLOR_OFF");
410  if (var != NULL)
411  cp.color = false;
412  cp.printProgram(*progDef, verb);
413  }
414 }
415 
416 void XmippProgram::usage(const String & param, int verb)
417 {
418  if (verbose)
419  {
420  ConsolePrinter cp;
421  ParamDef * paramDef = progDef->findParam(param);
422  if (paramDef == NULL)
423  REPORT_ERROR(ERR_ARG_INCORRECT, ((String)"Doesn't exists param: " + param));
424  cp.printParam(*paramDef, verb);
425  }
426  quit(0);
427 }
428 
429 void XmippProgram::show() const
430 {}
431 
433 {
435 }
virtual void usage(int verb=0) const
void init_progress_bar(long total)
virtual void defineParams()
#define XMIPP_MAX(x, y)
Definition: xmipp_macros.h:193
Case or algorithm not implemented yet.
Definition: xmipp_error.h:177
double getDoubleParam(const char *param, int arg=0)
virtual void read(int argc, const char **argv, bool reportErrors=true)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
String name
Definition: argsparser.h:152
virtual int tryRun()
virtual void show() const
void setDefaultComment(const char *param, const char *comment)
ParamDef * findParam(const String &param)
Definition: argsparser.cpp:905
void defineCommons()
void initProgress(size_t total, size_t stepBin=60)
int version() const
void processDefaultComment(const char *param, const char *left)
void getListParam(const char *param, StringVector &list)
virtual void printParam(const ParamDef &param, int v=0)
virtual void quit(int exit_code=0) const
std::vector< String > StringVector
Definition: xmipp_strings.h:35
#define i
void read(int argc, const char **argv, bool reportErrors=true)
Read and validate commmand line.
Definition: argsparser.cpp:951
void addSeeAlsoLine(const char *seeAlso)
void addKeywords(const char *keywords)
ArgLexer * pLexer
Definition: argsparser.h:150
int argc
Original command line arguments.
Definition: xmipp_program.h:86
float getFloatParam(const char *param, int arg=0)
const char * getParam(const char *param, int arg=0)
virtual void printProgram(const ProgramDef &program, int v=0)
float textToFloat(const char *str)
bool runWithoutArgs
Definition: xmipp_program.h:95
Incorrect argument received.
Definition: xmipp_error.h:113
void setProgramName(const char *name)
String seeAlso
Definition: argsparser.h:247
void progress_bar(long rlen)
const char ** argv
Definition: xmipp_program.h:87
void addExampleLine(const char *example, bool verbatim=true)
std::vector< const char * > cmdArguments
Definition: argsparser.h:199
virtual ~XmippProgram()
int verbose
Verbosity level.
virtual void readParams()
virtual void run()
virtual void printProgram(const ProgramDef &program, int v=0)
const char * name() const
String keywords
Definition: argsparser.h:246
struct _parameter * param
int getCountParam(const char *param)
ParamDef * getParamDef(const char *param) const
void setProgress(size_t value=0)
CommentList examples
examples of use
Definition: argsparser.h:243
virtual bool parse()
Definition: argsparser.cpp:825
CommentList usageComments
comments of usage
Definition: argsparser.h:242
std::string String
Definition: xmipp_strings.h:34
int textToInteger(const char *str)
virtual void initComments()
const char * getParam(const char *paramName, size_t paramNumber=0)
bool checkParam(const char *param)
void addComment(const String &comment, int visible=0, bool wikiVerbatim=false)
void addUsageLine(const char *line, bool verbatim=false)
int counter
for count the number of times it appears in command line
Definition: argsparser.h:201
int getIntParam(const char *param, int arg=0)
bool existsParam(const char *param)
void addLine(const String &line)
Definition: argsparser.cpp:99
ProgramDef * progDef
Program definition and arguments parser.
Definition: xmipp_program.h:80
virtual void printProgram(const ProgramDef &program, int v=0)
void addParamsLine(const String &line)
void generateCommandLine(const std::string &command_line, int &argcp, char **&argvp, char *&copy)
Definition: args.cpp:238
virtual void printProgram(const ProgramDef &program, int v=0)
Definition: argsprinter.cpp:50
std::map< String, CommentList > defaultComments
Definition: xmipp_program.h:83