All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
preparseGDML.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include "TList.h"
3 #include "TString.h"
4 #include "TFormula.h"
5 #include <vector>
6 #include <map>
7 #include <fstream>
8 #include <iostream>
9 #include <sstream>
10 #include <stdio.h>
11 #include <limits> // std::numeric_limits<>
12 #include <getopt.h> // getopt_long(), option
13 #include <stdexcept> // std::runtime_error
14 
15 bool sci = false;
16 bool setupChoice = false;
17 int debug = 0;
18 TString mySetup = "Default"; // Default volWorld
19 int prec = std::numeric_limits<double>::max_digits10;
20 
21 using namespace std;
22 
23 struct aLoop{
24  std::string varName;
25  double varTo;
26  double varStep;
27 };
28 
29 struct aSetup{
30  std::string stpName;
31  std::string stpWorldVolume;
32  std::string stpVersion;
33 };
34 
35 typedef std::map<std::string, double> Variables_t;
36 
37 bool isComment(TString key) {
38 
39  int pos1 = key.Index("<!--");
40  int pos2 = key.Index("-->");
41  bool k=0;
42  TString s1="X", s2="X";
43  if(pos1>=0 && pos2>pos1){
44  s1=key;
45  s1.Remove(pos1);
46  s2=key;
47  s2.Replace(0,pos2+3,"");
48  }
49  for(int i=0; i<s1.Length(); i++) if(s1[i]==char(9)) {s1.Replace(i,1," ");}
50  for(int i=0; i<s2.Length(); i++) if(s2[i]==char(9)) {s2.Replace(i,1," ");}
51  k = s1.IsWhitespace() && s2.IsWhitespace();
52  return k;
53 }
54 
55 void replaceVariable(TString &key, Variables_t const& variables ){
56 
57  Variables_t::const_iterator it;
58  std::stringstream stream;
59  TString varValue;
60  int i;
61  TString temp;
62  stream.precision(prec);
63  for (it=variables.begin(); it!=variables.end(); ++it) {
64  TString const& varName = it->first;
65  double value = it->second;
66  if (!key.Contains("=") || !key.Contains(varName) ) continue;
67  if (debug >= 3) {
68  std::cout.precision(prec);
69  std::cout << "REPLACING\t'" << varName << "'\t";
70  }
71  stream.str("");
72  stream.clear();
73 
74  if(0) { stream << scientific << value;} else {stream << value;}
75  stream >> varValue;
76 
77  if (debug >= 3) {
78  std::cout.precision(prec);
79  std::cout << "=> " << varValue << "\n";
80  }
81 
82  do {
83  i = key.Index(varName);
84  if (i>0) {
85  temp = key;
86  temp.Remove(i);
87  temp += varValue;
88  key.Replace(0,i+varName.Length(),"");
89  temp += key;
90  key = temp;
91  }
92  } while (i>0);
93  }
94 }
95 
96 void replaceKeyword(TString &key, TString word, TString keyword){
97 
98  int pos1 = key.Index(word);
99  if(pos1>=1){
100  int pos2 = word.Length();
101  TString delimiter1 = key[pos1-1];
102  TString delimiter2 = key[pos1+pos2];
103  if(delimiter1=="\"" && delimiter2=="\"") key.Replace(pos1,pos2,keyword);
104  }
105 
106 }
107 
108 void getVariable(TString key, Variables_t& variables){
109 
110  TString name;
111 
112  replaceVariable(key,variables);
113 
114  int pos = key.First("\"")+1;
115  key.Replace(0,pos,"");
116  pos = key.First("\"");
117  TString varName = key;
118  varName.Remove(pos);
119  pos = key.First("\"")+1;
120  key.Replace(0,pos,"");
121  pos = key.First("\"")+1;
122  key.Replace(0,pos,"");
123  pos = key.First("\"");
124  TString varValue = key;
125  varValue.Remove(pos);
126 
127  TFormula formula("formula",varValue);
128  name = varName;
129  double value = formula.Eval(0);
130 
131  if (debug >= 2) {
132  std::cout.precision(prec);
133  std::cout << "VARIABLE\t'" << name << "'=\"" << varValue << "\" => " << value << std::endl;
134  }
135  variables[name.Data()]=value;
136 
137 // if(varName.Length()==1) cout << varName << "\t"<< value<< endl;
138 }
139 
140 void evalFormulas(TString &key){
141 
142  TString storeKey;
143  int pos1,pos2;
144  const int n=66;
145  TString lookFor[n]={"x=\"","y=\"","z=\"","r=\"","rmax=\"","rmin=\"","rmax1=\"","rmin1=\"","rmax2=\"","rmin2=\"",
146  "startphi=\"","deltaphi=\"","starttheta=\"","deltatheta=\"","ax=\"","by=\"","cz=\"","dx=\"","dy=\"","dz=\"",
147  "zcut1=\"","zcut2=\"","rlo=\"","rhi=\"","alpha=\"","theta=\"","phi=\"","numsides=\"","x1=\"","x2=\"","y1=\"","y2=\"","x3=\"","x4=\"",
148  "alpha1=\"","alpha2=\"","inst=\"","outst=\"","lowX=\"","lowY=\"","lowZ=\"","highX=\"","highY=\"","highZ=\"","zOrder=\"","zPosition=\"",
149  "xOffset=\"","yOffset=\"","scalingFactor=\"","v1x=\"","v1y=\"","v2x=\"","v2y=\"","v3x=\"","v3y=\"","v4x=\"","v4y=\"","v5x=\"","v5y=\"",
150  "v6x=\"","v6y=\"","v7x=\"","v7y=\"","v8x=\"","v8y=\"","dz=\""};
151 
152 
153 
154  for(int i=0; i<n; i++)
155  if(key.Contains(lookFor[i])){
156  storeKey=key;
157  pos1 = key.Index(lookFor[i])+lookFor[i].Length();
158  key.Replace(0,pos1,"");
159  pos2 = key.First("\"");
160  TString varFormula = key;
161  varFormula.Remove(pos2);
162  TFormula formula("",varFormula);
163  double value = formula.Eval(0);
164  if (debug >= 2) {
165  std::cout.precision(prec);
166  std::cout << "FML " << lookFor[i] << "='" << varFormula << "' => " << value << std::endl;
167  }
168  TString varValue;
169  std::stringstream stream;
170  stream.precision(prec);
171  if(sci) { stream << scientific << value;} else {stream << value;}
172  stream << "\"";
173  stream >> varValue;
174  key = storeKey;
175  key.Replace(pos1,varFormula.Length()+1,varValue);
176  }
177 
178 
179 }
180 
181 void makeLoop(TString &key, aLoop &theLoop){
182  int pos = key.Index("for")+3;
183  key.Replace(0,pos,"");
184  pos = key.First("\"")+1;
185  key.Replace(0,pos,"");
186  pos = key.First("\"");
187  TString name = key;
188  name.Remove(pos);
189 
190  pos = key.Index("to")+2;
191  key.Replace(0,pos,"");
192  pos = key.First("\"")+1;
193  key.Replace(0,pos,"");
194  pos = key.First("\"");
195  TString value = key;
196  value.Remove(pos);
197 
198  pos = key.Index("step")+1;
199  key.Replace(0,pos,"");
200  pos = key.First("\"")+1;
201  key.Replace(0,pos,"");
202  pos = key.First("\"");
203  TString step = key;
204  step.Remove(pos);
205 
206  theLoop.varName = name;
207  theLoop.varTo = value.Atof();
208  theLoop.varStep = step.Atof();
209 }
210 
211 void getFileNames(TString inName, TString &outName1, TString &outName2){
212  int pos = inName.Index("_base");
213  TString temp = inName;
214  temp.Remove(pos);
215 
216  if (outName1.IsNull()) outName1 = temp+".gdml";
217  if (outName2.IsNull()) outName2 = temp+"_nowires.gdml";
218 }
219 
221 
222  variables["degree"] = M_PI / 180.0;
223 
224 } // SetDefaultVariables()
225 
226 
227 void getSetup(TString key, aSetup &theSetup){
228  int pos;
229  TString s;
230  pos = key.Index("name=");
231  if(pos>=0){
232  pos+=6;
233  s = key;
234  s.Replace(0,pos,"");
235  pos = s.Index("\"");
236  s.Replace(pos,s.Length()-pos,"");
237  theSetup.stpName = s;
238  }
239 
240  pos = key.Index("version=\"");
241  if(pos>=0){
242  pos+=9;
243  s = key;
244  s.Replace(0,pos,"");
245  pos = s.Index("\"");
246  s.Replace(pos,s.Length()-pos,"");
247  theSetup.stpVersion = s;
248  }
249 
250  pos = key.Index("ref=\"");
251  if(pos>=0 && key.Contains("world")){
252  pos+=5;
253  s = key;
254  s.Replace(0,pos,"");
255  pos = s.Index("\"");
256  s.Replace(pos,s.Length()-pos,"");
257  theSetup.stpWorldVolume = s;
258  }
259 
260 }
261 
262 int preparse(TString inName="sbnd_base.gdml", TString outName1="sbnd.gdml", TString outName2=""){
263 
264  std::cout << "Preparsing '" << inName << "'"
265  "\n => '" << outName1 << "' (complete description)";
266  if (!outName2.IsNull())
267  std::cout << "\n => '" << outName2 << "' (without TPC wires)";
268  std::cout << "\n" << std::endl;
269 
270 // cout << sci << "\t" << prec << endl;
271 
272  bool noWiresFiles = 1;
273  if(outName2!="") noWiresFiles = 0;
274 
275  ofstream output1, output2;
276  output1.open(outName1);
277  if(!noWiresFiles) output2.open(outName2);
278 
279 
280  ifstream input(inName);
281  TString key;
282  Variables_t variables;
283  SetDefaultVariables(variables);
284 
285  std::vector<std::string> loopLine;
286  aLoop theLoop;
287 
288  std::vector<aSetup> stpList;
289  aSetup theSetup;
290 
291  TString name, loopkey;
292  bool inLoop = 0;
293  bool inSetup = 0;
294  bool isWire = 0;
295  bool keepLoop = 1;
296  uint64_t lineCounter = 0;
297  do{
298  lineCounter++;
299  key.ReadLine(input,0);
300  if(debug>3) cout << lineCounter << "\t::\t" << key << "\n";
301  if ((key.Contains("<variable") && !key.Contains("<!--")) || (key.Contains("<constant") && !key.Contains("<!--"))) {
302  getVariable(key,variables);
303  } else if (key.Contains("<loop")) {
304  inLoop = 1;
305  if(key.Contains("#wire")) isWire=1;
306  makeLoop(key,theLoop);
307  } else if (key.Contains("</loop")) {
308  do{
309  for (std::vector<std::string>::iterator it = loopLine.begin() ; it != loopLine.end(); ++it){
310  loopkey = *it;
311  replaceVariable(loopkey,variables);
312  if(loopkey.Contains("--")) {
313  if (debug) {
314  std::cout << "checking double minus sign " << std::endl;
315  std::cout << loopkey << std::endl;
316  }
317  loopkey.ReplaceAll("--","+");
318  if (debug) std::cout << loopkey << std::endl;
319  }
320  evalFormulas(loopkey);
321  output1 << loopkey << endl;
322  if(!isWire && !noWiresFiles) output2 << loopkey << endl;
323  }
324  variables[theLoop.varName] += theLoop.varStep;
325  if(theLoop.varStep>0) {keepLoop = (variables[theLoop.varName] <= theLoop.varTo);}
326  else {keepLoop = (variables[theLoop.varName] >= theLoop.varTo);}
327  } while (keepLoop);
328  inLoop = 0;
329  isWire = 0;
330  loopLine.clear();
331  } else if (inLoop) {
332  loopLine.push_back(key.Data());
333  } else {
334  if( !( isComment(key) || key.IsWhitespace() ) ){
335  if(key.Contains("<setup")){
336  inSetup = 1;
337  getSetup(key,theSetup);
338  }
339  if(inSetup) getSetup(key,theSetup);
340  if(key.Contains("</setup")) {
341  stpList.push_back(theSetup);
342  theSetup.stpName="";
343  theSetup.stpVersion="";
344  theSetup.stpWorldVolume="";
345  inSetup = 0;
346  }
347  replaceVariable(key,variables);
348  evalFormulas(key);
349  output1 << key << endl;
350  if(!noWiresFiles) output2 << key << endl;
351  }
352  }
353 
354  }while(!input.eof());
355 
356 
357  output1.close();
358  if(!noWiresFiles) output2.close();
359  input.close();
360 
361  bool goAhead = true;
362  if (!setupChoice) mySetup = "Default";
363 
364  TString ver="1.0";
365  int pos=mySetup.Index(":");
366  if(pos>=0){
367  ver=mySetup;
368  ver.Replace(0,pos+1,"");
369  mySetup.Replace(pos,mySetup.Length()-pos,"");
370  }
371 
372  // is the indicated setup among the ones available?
373  for (std::vector<aSetup>::iterator itx = stpList.begin() ; itx != stpList.end(); ++itx){
374 
375  theSetup=(*itx);
376  if( theSetup.stpName==mySetup && theSetup.stpVersion==ver ){ goAhead = true; break; }
377  else {goAhead = false;}
378  }
379 
380  if (!goAhead) {
381  cout << "ERROR: Setup " << mySetup << " or its version not found." << endl;
382  } else {
383 
384  TString inName1, inName2, comm;
385  inName1 = outName1+"~";
386  inName2 = outName2+"~";
387  TString inNameVec[]={inName1,inName2};
388  TString outNameVec[]={outName1,outName2};
389 
390  const int kmax = 1+(!noWiresFiles);
391 
392  for(int k=0; k<kmax; k++){
393  errno = 0;
394  rename(outNameVec[k], inNameVec[k]);
395  if (errno != 0) {
396  std::cerr << "Error renaming '" << outNameVec[k] << "' into '" << inNameVec[k] << "': "
397  << strerror(errno) << std::endl;
398  return errno;
399  }
400  output1.open(outNameVec[k]);
401  ifstream input1(inNameVec[k]);
402 
403  inSetup=0;
404  do{
405  key.ReadLine(input1,0);
406  if((!key.Contains("<setup") && !inSetup) ){
407  if (theSetup.stpWorldVolume != "volWorld") {
408  replaceKeyword(key,"volWorld","volIgnoredOnThisSetup");
409  }
410  if(!key.Contains("volumeref")) replaceKeyword(key,theSetup.stpWorldVolume,"volWorld");
411  output1 << key << endl;
412  }else {inSetup=1;}
413  }while(!input1.eof());
414 
415  output1 << "\t<setup name=\"Default\" version=\"1.0\">" << endl;
416  output1 << "\t\t<world ref=\"volWorld\" />" << endl;
417  output1 << "\t</setup>" << endl;
418  output1 << "</gdml_simple_extension>" << endl;
419  output1.close();
420  input1.close();
421  remove(inNameVec[k]);
422  }
423  }
424  return 0;
425 } // preparse()
426 
427 
428 //---- Main program ------------------------------------------------------------
429 # ifndef __CINT__
430 
431 bool genNoWires = false, printHelp = false;
432 TString inFile="sbnd_base.gdml", outFile, outFile2, noWires, withWires;
433 
434 void parseArguments(unsigned int argc, char** argv) {
435 
436  static const option longopts[] = {
437  { "output", required_argument, NULL, 'o' },
438  { "nowires", optional_argument, NULL, 'w' },
439  { "sci", optional_argument, NULL, 's' },
440  { "prec", required_argument, NULL, 'p' },
441  { "setup", required_argument, NULL, 'S' },
442  { "debug", optional_argument, NULL, 'd' },
443  { "help", no_argument, NULL, 'h' },
444  { NULL, 0, NULL, 0 }
445  }; // longopts
446 
447  // automatically build the short option string from the long one
448  std::string shortopts = ":"; // this means no error printout
449  for (auto const& longopt: longopts) {
450  if (!longopt.name) break;
451  if (longopt.val == 0) continue;
452  shortopts += (char) longopt.val;
453  if (longopt.has_arg != no_argument) shortopts += ':';
454  if (longopt.has_arg == optional_argument) shortopts += ':';
455  } // for
456 
457  // ----------------------------------------------------------------------
458  // options
459  char ch;
460  optind = 1;
461  while
462  ((ch = getopt_long(argc, argv, shortopts.c_str(), longopts, NULL)) != -1)
463  {
464  switch (ch) {
465  case 'o': // -o, --output
466  outFile = optarg;
467  continue;
468  case 'w': // -w, --nowires
469  genNoWires = true;
470  if (optarg) outFile2 = optarg;
471  continue;
472  case 'S': // -S, --setup
473  setupChoice = true;
474  mySetup = optarg;
475  continue;
476  case 's': // -s, --sci
477  sci = true;
478  if (optarg) {
479  TString par = optarg;
480  if (!par.IsDigit())
481  throw std::runtime_error("Invalid precision in -s option.");
482  prec = par.Atoi();
483  }
484  continue;
485  case 'd': // -d, --debug
486  if (optarg) {
487  TString par = optarg;
488  if (!par.IsDigit())
489  throw std::runtime_error("Invalid debug level in -d option.");
490  debug = par.Atoi();
491  }
492  else debug = 1;
493  continue;
494  case 'p': // -p, --prec
495  {
496  TString par = optarg;
497  if (!par.IsDigit())
498  throw std::runtime_error("Invalid precision in -s option.");
499  prec = par.Atoi();
500  }
501  continue;
502  case 'h': // -h, --help
503  printHelp = true;
504  continue;
505  } // switch
506  } // while
507 
508  // ----------------------------------------------------------------------
509  // arguments
510  if (optind < (int) argc) inFile = argv[optind++];
511 
512  if (optind < (int) argc) {
513  std::cerr << "Spurious arguments: '" << argv[optind] << "'";
514  if (optind + 1 < (int) argc)
515  std::cerr << " and " << (argc - optind - 1) << " more";
516  std::cerr << "." << std::endl;
517  throw std::runtime_error("Too many arguments on the command line!");
518  }
519 
520 } // parseArguments()
521 
522 
523 
524 int main(int argc, char **argv)
525 {
526 
527  parseArguments(argc, argv);
528 
529  if (printHelp) {
530  std::string programName = argv[0];
531  if (programName.rfind('/') != std::string::npos) programName.erase(programName.rfind('/'));
532 
533  cout <<
534  "\nGDML Preparser v 1.0 (gustavo.valdiviesso@unifal-mg.edu.br)"
535  "\nBasic usage:"
536  "\n " << programName << " [file_base.gdml] [flags]"
537  "\n"
538  "\nGenerate file.gdml with the following configuration flags:"
539  "\n-w , --nowires[=nowirename]"
540  "\n Generate file_nowires.gdml, ignoring all <loop> with <!--wire--> comment."
541  "\n-p , --prec=precision"
542  "\n Set numerical output precision (current precision: " << prec << " digits)"
543  "\n-s , --sci[=precision]"
544  "\n Uses scientific notation for numbers (optionally alter numerical output precision)"
545  "\n-o , --output=outputname"
546  "\n Uses this file name as main output name"
547  "\n-S , --setup=setupname"
548  "\n Uses the specified setup name instead of default one"
549  "\n-d , --debug"
550  "\n Enable debugging messages"
551  "\n"
552  "\nExamples:"
553  "\n"
554  "\n " << programName << " geometry_base.gdml --nowires"
555  "\n Outputs geometry.gdml and geometry_nowires.gdml with standard numeric notation."
556  "\n"
557  "\n " << programName << " geometry_base.gdml -setup Cryostat:1.0"
558  "\n Outputs geometry.gdml making setup Cryostat (version 1.0) the volWorld required by LArSoft."
559  "\n"
560  << endl;
561  return 0;
562  }
563 
564  ifstream input(inFile);
565  if (!input.is_open()) {
566  std::cerr << "Error opening '" << inFile << "': " << strerror(errno) << std::endl;
567  return errno;
568  }
569 
570  if(inFile.Contains("_base.gdml")) {getFileNames(inFile,withWires,noWires);}
571  else {
572  withWires = inFile+"_preparsed.gdml";
573  noWires = inFile+"_nowires.gdml";
574  }
575  if(outFile!="") {
576  withWires = outFile;
577  noWires = outFile;
578  int pos = outFile.Index(".gdml");
579  noWires.Replace(pos,5,"_nowires.gdml");
580  }
581  if(outFile2!="") { noWires = outFile2; }
582  if(!genNoWires) noWires="";
583 
585 
586 } // main()
587 #endif // __CINT__
bool setupChoice
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
Definition: UtilFunc.cxx:42
bool printHelp
then if[["$THISISATEST"==1]]
Definition: neoSmazza.sh:95
bool sci
std::string varName
BEGIN_PROLOG could also be cerr
void makeLoop(TString &key, aLoop &theLoop)
std::map< std::string, double > Variables_t
void parseArguments(unsigned int argc, char **argv)
void getFileNames(TString inName, TString &outName1, TString &outName2)
void evalFormulas(TString &key)
bool isComment(TString key)
void getSetup(TString key, aSetup &theSetup)
TString outFile
void replaceKeyword(TString &key, TString word, TString keyword)
double varTo
TString inFile
double varStep
int preparse(TString inName="sbnd_base.gdml", TString outName1="sbnd.gdml", TString outName2="")
void SetDefaultVariables(Variables_t &variables)
std::string stpWorldVolume
TString withWires
TString noWires
TString outFile2
int prec
std::string stpVersion
then echo File list $list not found else cat $list while read file do echo $file sed s
Definition: file_to_url.sh:60
bool genNoWires
then echo fcl name
echo Invalid option
Definition: TrainMVA.sh:17
temporary value
void getVariable(TString key, Variables_t &variables)
pdgs k
Definition: selectors.fcl:22
int main(int argc, char **argv)
std::string stpName
void replaceVariable(TString &key, Variables_t const &variables)
BEGIN_PROLOG could also be cout
TString mySetup