GEMC  2.3
Geant4 Monte-Carlo Framework
options.cc
Go to the documentation of this file.
1 // gemc headers
2 #include "options.h"
3 #include "string_utilities.h"
4 
5 // C++ headers
6 #include <cstdio>
7 #include <set>
8 #include <cstdlib>
9 
10 // initialize general options
12 {
13  optMap["LOG_VERBOSITY"].arg = 0;
14  optMap["LOG_VERBOSITY"].help = "Controls General Log Verbosity.";
15  optMap["LOG_VERBOSITY"].name = "Log Verbosity";
16  optMap["LOG_VERBOSITY"].type = 0;
17  optMap["LOG_VERBOSITY"].ctgr = "verbosity";
18 }
19 
20 
21 void goptions::scanGcard(string file)
22 {
23  // If found, parse the <options> section of the file.
24  QDomDocument domDocument;
25 
26  cout << " >> Parsing " << file << " for options: \n";
27 
28  QFile gcard(file.c_str());
29 
30  if( !gcard.exists() )
31  {
32  cout << " >> gcard: " << file <<" not found. Exiting." << endl;
33  exit(0);
34  }
35 
36  // opening gcard and filling domDocument
37  if(!domDocument.setContent(&gcard))
38  {
39  gcard.close();
40  cout << " >> gcard format for file <" << file << "> is wrong - check XML syntax. Exiting." << endl;
41  exit(0);
42  }
43  gcard.close();
44 
45  // setting this gcard file as the one in the option
46  // this way the only gcard file with detectors in it
47  // is the last one in the command line
48  // however there should be only one anyway
49  optMap["gcard"].args = file;
50 
52  QDomElement docElem = domDocument.documentElement();
53  QDomNode n;
54 
55  map<string, int> count;
56  for(map<string, aopt>::iterator itm = optMap.begin(); itm != optMap.end(); itm++)
57  count[itm->first] = 0;
58 
60  n = docElem.firstChild();
61  while(!n.isNull())
62  {
63  QDomElement e = n.toElement();
64  if(!e.isNull())
65  if(e.tagName().toStdString() == "option")
66  {
67  int found = 0;
68  for(map<string, aopt>::iterator itm = optMap.begin();itm != optMap.end(); itm++)
69  {
70  // looking for a valid option. If a two instances of the same option exist
71  // the string __REPETITION__ will be appended
72  if(e.attributeNode("name").value().toStdString() == itm->first )
73  {
74 
75  found = 1;
76  count[itm->first] += 1;
77 
78  // first time it finds it
79  if(count[itm->first] == 1)
80  {
81  itm->second.args = e.attributeNode("value").value().toStdString();
82  itm->second.arg = stringToDouble(e.attributeNode("value").value().toStdString());
83 
84  itm->second.printSetting();
85  }
86 
87  else
88  {
89  string new_opt = itm->first + "__REPETITION__" + stringify(count[itm->first] - 1);
90  optMap[new_opt].args = e.attributeNode("value").value().toStdString();
91  optMap[new_opt].arg = stringToDouble(e.attributeNode("value").value().toStdString());
92  optMap[new_opt].name = itm->second.name;
93  optMap[new_opt].help = itm->second.help;
94  optMap[new_opt].type = itm->second.type;
95  optMap[new_opt].ctgr = itm->second.ctgr;
96  optMap[new_opt].repe = count[itm->first];
97  optMap[new_opt].printSetting();
98  }
99  break;
100  }
101  }
102  if( found == 0 )
103  {
104  cout << " !! Error: The option in the gcard file "
105  << e.attributeNode("name").value().toStdString()
106  << " is not known to this system. Please check your spelling." << endl;
107  exit(3);
108  }
109  }
110 
111  // now looking for child arguments
112  QDomNode nn= e.firstChild();
113  while( !nn.isNull() && e.tagName().toStdString() == "option")
114  {
115  QDomElement ee = nn.toElement();
116  int found=0;
117  for(map<string, aopt>::iterator itm = optMap.begin(); itm != optMap.end(); itm++)
118  {
119  if(ee.tagName().toStdString() == itm->first )
120  {
121  itm->second.args= ee.attributeNode("value").value().toStdString();
122  itm->second.arg = stringToDouble(ee.attributeNode("value").value().toStdString());
123  itm->second.printSetting();
124  found = 1;
125  }
126  }
127  if( found == 0 )
128  {
129  cout << " !! Error: The option in the gcard file "
130  << e.attributeNode("name").value().toStdString()
131  << " is not known to this system. Please check your spelling." << endl;
132  exit(3);
133  }
134  nn = nn.nextSibling();
135  }
136  n = n.nextSibling();
137  }
138 }
139 
140 
141 
142 int goptions::setOptMap(int argc, char **argv)
143 {
144  // Check the command line for the -gcard=file option.
145  // Then call the parser for the gcard file that reads all the options.
146  // This must be done BEFORE the commandline is parsed, so that command line
147  // options override the options in the file.
148 
149 
150  // Look for -gcard special option:
151  size_t pos;
152  for(int i=1;i<argc;i++)
153  {
154  string arg = argv[i];
155  pos = arg.find("gcard=");
156  if(pos != string::npos)
157  {
158  scanGcard(arg.substr(pos+6));
159  }
160  }
161 
162  // if no gcard option is passed, checking that one of the option is a gcard file
163  for(int i=1;i<argc;i++)
164  {
165  string arg = argv[i];
166  pos = arg.find(".gcard");
167  if(pos != string::npos)
168  {
169  ifstream my_file(argv[i]);
170  if(my_file)
171  {
172  scanGcard(argv[i]);
173  }
174  }
175  }
176 
177 
178  set<string> category;
179  // Filling Categories
180  for(map<string, aopt>::iterator itm = optMap.begin(); itm != optMap.end(); itm++)
181  if(category.find(itm->second.ctgr) == category.end()) category.insert(itm->second.ctgr);
182 
183 
184  // -help-all
185  cout << endl;
186  for(int i=1; i<argc; i++)
187  {
188  string arg = argv[i];
189  string com = "-help-all";
190  if(arg == com)
191  {
192  cout << " Usage: -Option=<option>" << endl << endl;
193  cout << " Options:" << endl << endl ;
194 
195  for(map<string, aopt>::iterator itm = optMap.begin(); itm != optMap.end(); itm++)
196  cout << " > Option " << itm->first << ": " << itm->second.help << endl;
197 
198  cout << endl << endl;
199  exit(0);
200  }
201  }
202 
203 
204  // -help
205  for(int i=1; i<argc; i++)
206  {
207  string arg = argv[i];
208  string com1 = "-help";
209  string com2 = "-h";
210  if(arg == com1 || arg == com2)
211  {
212  cout << endl << endl;
213  cout << " Help Options:" << endl << endl ;
214  cout << " > -help-all: all available options. " << endl << endl;
215  for(set<string>::iterator itcat = category.begin(); itcat != category.end(); itcat++)
216  {
217  cout << " > -help-" << *itcat << " ";
218  cout.width(15);
219  cout << *itcat << " options." << endl;
220  }
221  cout << endl << endl;
222  exit(0);
223  }
224  }
225 
226 
227  // -help-option
228  for(int i=1; i<argc; i++)
229  {
230  string arg = argv[i];
231  for(set<string>::iterator itcat = category.begin(); itcat != category.end(); itcat++)
232  {
233  string com = "-help-" + *itcat;
234  if(arg == com)
235  {
236  cout << endl << endl << " ## " << *itcat << " ## " << endl << endl;
237  cout << " Usage: -Option=<option>" << endl << endl;
238  for(map<string, aopt>::iterator itm = optMap.begin(); itm != optMap.end(); itm++)
239  if(itm->second.ctgr == *itcat)
240  cout << " > " << itm->first << ": " << itm->second.help << endl;
241  cout << endl << endl;
242  exit(0);
243  }
244  }
245  }
246 
247 
248  // -help-html
249  for(int i=1; i<argc; i++)
250  {
251  string arg = argv[i];
252  for(set<string>::iterator itcat = category.begin(); itcat != category.end(); itcat++)
253  {
254  string com = "-help-html";
255  if(arg == com)
256  {
257  ofstream hf;
258  hf.open("options.html");
259  hf << "<html>" << endl;
260  hf << " <STYLE TYPE=\"text/css\">" << endl;
261  hf << "<!--" << endl;
262  hf << ".pretty-table" << endl;
263  hf << "{" << endl;
264  hf << " padding: 0;" << endl;
265  hf << " margin: 0;" << endl;
266  hf << " border-collapse: collapse;" << endl;
267  hf << " border: 1px solid #333;" << endl;
268  hf << " font-family: \"Trebuchet MS\", Verdana, Arial, Helvetica, sans-serif;" << endl;
269  hf << " font-size: 0.8em;" << endl;
270  hf << " color: #000;" << endl;
271  hf << " background: #bcd0e4;" << endl;
272  hf << "}" << endl;
273  hf << ".pretty-table caption" << endl;
274  hf << "{" << endl;
275  hf << " caption-side: bottom;" << endl;
276  hf << " font-size: 0.9em;" << endl;
277  hf << " font-style: italic;" << endl;
278  hf << " text-align: right;" << endl;
279  hf << " padding: 0.5em 0;" << endl;
280  hf << "}" << endl;
281  hf << ".pretty-table th, .pretty-table td" << endl;
282  hf << "{" << endl;
283  hf << " border: 1px dotted #666;" << endl;
284  hf << " padding: 0.5em;" << endl;
285  hf << " text-align: left;" << endl;
286  hf << " color: #632a39;" << endl;
287  hf << "}" << endl;
288  hf << ".pretty-table th[scope=col]" << endl;
289  hf << "{" << endl;
290  hf << " color: #000;" << endl;
291  hf << " background-color: #8fadcc;" << endl;
292  hf << " text-transform: uppercase;" << endl;
293  hf << " font-size: 0.9em;" << endl;
294  hf << " border-bottom: 2px solid #333;" << endl;
295  hf << " border-right: 2px solid #333;" << endl;
296  hf << "}" << endl;
297  hf << ".pretty-table th+th[scope=col]" << endl;
298  hf << "{" << endl;
299  hf << " color: #009;" << endl;
300  hf << " background-color: #7d98b3;" << endl;
301  hf << " border-right: 1px dotted #666;" << endl;
302  hf << "}" << endl;
303  hf << ".pretty-table th[scope=row]" << endl;
304  hf << "{" << endl;
305  hf << " background-color: #b8cfe5;" << endl;
306  hf << " border-right: 2px solid #333;" << endl;
307  hf << "}" << endl;
308  hf << "pre{font-family:Helvetica;font-size:12pt}" << endl;
309 
310  hf << "--->" << endl;
311  hf << "</STYLE>" << endl;
312  hf << "</head>" << endl;
313  hf << "<body>" << endl;
314  hf << "<br><br>" << endl;
315  hf << "<center>" << endl;
316  hf << "<h1> GEMC options</h1>" << endl;
317  hf << "</center>" << endl;
318  hf << "<br><br><br>" << endl;
319  hf << "<table cellsize=20>" << endl;
320  hf << "<tr><td>" << endl;
321  hf << "<table class=\"pretty-table\">" << endl;
322  hf << "<caption>options. This table is produced with the option: -help-html </caption>" << endl;
323  hf << "<tr><th scope=\"col\" >Category</th>" << endl;
324  hf << " <th scope=\"col\" >Option</th>" << endl;
325  hf << " <th scope=\"col\" >Help</th></tr>" << endl;
326  for(set<string>::iterator itcat = category.begin(); itcat != category.end(); itcat++)
327  for(map<string, aopt>::iterator itm = optMap.begin(); itm != optMap.end(); itm++)
328  if(itm->second.ctgr == *itcat)
329  {
330  hf << "<tr><th scope=\"row\">";
331  hf << *itcat ;
332 
333  hf << "</th> <td>";
334  hf << itm->first;
335  hf << "</td><td><pre>" << endl;
336  hf << itm->second.help;
337  hf << "</pre></td></tr>" << endl;
338  }
339 
340  hf << "</table>" << endl;
341  hf << "</td>" << endl;
342  hf << "<td>" << endl;
343  hf << "</table>" << endl;
344  hf << " </body></html>";
345 
346  hf.close();
347  exit(0);
348  }
349  }
350  }
351 
352  // resetting option repetition if so directed
353  // if repe is 1, options can be accumulated from the gcard
354  map<string, int> count;
355  for(map<string, aopt>::iterator itm = optMap.begin(); itm != optMap.end(); itm++)
356  {
357  if(itm->second.repe == 0)
358  count[itm->first] = 0;
359  else
360  count[itm->first] = itm->second.repe;
361  }
362 
363  for(int i=1; i<argc; i++)
364  {
365  string arg = argv[i];
366  int found=0;
367  for(map<string, aopt>::iterator itm = optMap.begin(); itm != optMap.end(); itm++)
368  {
369  string com = "-" + itm->first + "=";
370 
371  string comp;
372  comp.assign(arg, 0, arg.find("=") + 1);
373 
374  // skip if argument is a file
375  ifstream my_file(argv[i]);
376  if(my_file)
377  found = 1;
378 
379  if(comp == com)
380  {
381  found=1;
382  count[itm->first] += 1;
383 
384  string opts;
385  opts.assign(arg, com.size(), arg.size()-com.size());
386 
387  // first time
388  if(count[itm->first] == 1)
389  {
390  itm->second.args = opts;
391  itm->second.arg = stringToDouble(opts);
392  itm->second.printSetting();
393  }
394 
395 
396  if(count[itm->first]>1)
397  {
398  string new_opt = itm->first + "__REPETITION__" + stringify(count[itm->first]-1);
399  optMap[new_opt].args = opts;
400  optMap[new_opt].arg = stringToDouble(opts);
401  optMap[new_opt].name = itm->second.name;
402  optMap[new_opt].help = itm->second.help;
403  optMap[new_opt].type = itm->second.type;
404  optMap[new_opt].ctgr = itm->second.ctgr;
405  optMap[new_opt].repe = count[itm->first];
406  optMap[new_opt].printSetting();
407  }
408  // why break here I forgot
409  // break;
410  }
411  }
412 
413  // For MAC OS X, we want to ignore the -psn_# type argument. This argument is added by
414  // the system when launching an application as an "app", and # contains the process id.
415  if( found == 0 && strncmp(argv[i],"-psn_", 4) !=0 && ignoreNotFound == 0)
416  {
417  cout << " The argument " << argv[i] << " is not known to this system / or file not found. Continuing anyway.\n\n";
418  // exit(2);
419  }
420  }
421 
422  cout << endl;
423 
424  return 1;
425 }
426 
427 vector<aopt> goptions::getArgs(string opt)
428 {
429  vector<aopt> options;
430  map<string, int> count;
431  for(map<string, aopt>::iterator itm = optMap.begin();itm != optMap.end(); itm++)
432  {
433  if(itm->first.find(opt) != string::npos)
434  {
435  options.push_back(itm->second);
436  }
437  }
438 
439  return options;
440 }
441 
442 
443 // Returns a map<string, string> with all options and values
444 map<string, string> goptions::getOptMap()
445 {
446  map<string, string> optmap;
447 
448  for(map<string, aopt>::iterator it = optMap.begin(); it != optMap.end(); it++)
449  {
450  string key = "option " + it->first;
451  if(it->second.type == 0) optmap[key] = stringify(it->second.arg);
452  else optmap[key] = it->second.args;
453  }
454 
455  return optmap;
456 }
457 
458 
459 
460 
461 // print the option setting
463 {
464  if(name.find("gemc card file") != string::npos) return;
465 
466 
467  cout << " > " << name << " set to: ";
468  if(type) cout << args;
469  else cout << arg;
470  cout << endl;
471 
472 }
473 
474 
475 
476 
477 
478 
479 
480 
481 
map< string, string > getOptMap()
Returns a map<string, string> with all options and values.
Definition: options.cc:444
void printSetting()
Definition: options.cc:462
vector< aopt > getArgs(string)
get a vector of arguments matching a string
Definition: options.cc:427
int setOptMap(int argc, char **args)
Sets map from command line arguments.
Definition: options.cc:142
string stringify(double x)
map< string, aopt > optMap
Options map.
Definition: options.h:75
goptions()
Definition: options.cc:11
double stringToDouble(string v)
void scanGcard(string file)
Scan option file for options.
Definition: options.cc:21
int ignoreNotFound
Definition: options.h:80