GEMC  2.3
Geant4 Monte-Carlo Framework
gdml_det_factory.cc
Go to the documentation of this file.
1 
2 // gemc headers
3 #include "gdml_det_factory.h"
4 #include "utils.h"
5 #include <cmath>
6 double verbosity;
7 map<string, detector> gdml_det_factory::loadDetectors()
8 {
9 
10  string hd_msg = " >> GDML Factory: >> ";
11  verbosity = gemcOpt.optMap["GEO_VERBOSITY"].arg;
12  map<string, detector> dets;
13 
14  // first check if there's at least one detector with GDML factory
16  return dets;
17 
18  // there is at least one build with this factory.
19  // building all detectors that are tagged with GDML factory
20  for(map<string, detectorCondition>::iterator it=RC.detectorConditionsMap.begin(); it != RC.detectorConditionsMap.end() ; it++)
21  {
22  if(it->second.get_factory() != factoryType )
23  continue;
24 
25  string dname = it->first;
26  string fname = dname + ".gdml";
27 
28  if(verbosity)
29  cout << hd_msg << " Importing Detector: " << dname << " with " << factoryType << " factory. " << endl;
30 
31  // If found, parse the gdml file
32  QFile gdet(fname.c_str());
33 
34  if( !gdet.exists() )
35  {
36  cout << hd_msg << " Failed to open geometry file " << fname << " for system: " << dname << ". Maybe the filename doesn't exist? Exiting." << endl;
37  exit(0);
38  }
39 
40  QDomDocument domDocument;
41  // opening gcard and filling domDocument
42  if(!domDocument.setContent(&gdet))
43  {
44  gdet.close();
45  cout << hd_msg << " Failed to open geometry file " << fname << " for system: " << dname << ". Wrong XML syntax. Exiting." << endl;
46  exit(0);
47  }
48  gdet.close();
49 
50 
51  // maps of various objects
52  map<string, double> gconstantMap;
53  map<string, gposition> gpositionsMap;
54  map<string, grotation> grotationsMap;
55  map<string, glogicV> glogicVMap;
56  map<string, gsolid> gsolidsMap;
57  map<string, gphysV> gphysVMap;
58  map<string, goperation> operationMap;
59  map<string, string> auxiliaryMap;
60  map<string, gposition> widthOffsetMap;
61 
62  //add "unity" as default value for position and rotation.
63  gpositionsMap["unity"] = gposition(0, 0, 0, "mm");
64  grotationsMap["unity"] = grotation("0", "0", "0", "deg");
65  //map<string, string> stringConstantMap;
66 
67  // fill with <quantity name="wextent" type="length" value="10000.0" unit="mm"/>
68 
69 
70  QDomElement docElem = domDocument.documentElement();
71  QDomNode n = docElem.firstChild();
72  while(!n.isNull())
73  {
74 
76  QDomElement e = n.toElement();
78 
79  // selecting "define" nodes for definitions of parameters
80  if(!e.isNull() && e.tagName().toStdString() == "define")
81  {
83  QDomNode nn= e.firstChild();
84 
85  while( !nn.isNull() )
86  {
87  QDomElement ee = nn.toElement();
88 
89  //parses constants and add to gconstantMap
90  if(ee.tagName().toStdString() == "constant")
91  {
93  string constant_name= assignAttribute(ee, "name", "noname");
94  string v = assignAttribute(ee, "value", "0");
95 
96  //call resolve_strings function to get double constant value
97  gconstantMap[constant_name] = resolve_strings(constant_name, v, gconstantMap);
98  if(verbosity>0) cout << "map value of " << constant_name << " " << gconstantMap[constant_name] << endl;
99 
100  }
101 
102  //calls resolve_string function for x, y and z respectively to get double values and add to gpositionsMap
103  if(ee.tagName().toStdString() == "position")
104  {
105 
106  string position_name= assignAttribute(ee, "name", "noname");
107 
108  if(verbosity>0) cout << "!!!!!!!!!!!!!! position name : " << position_name << " !!!!!!!!!!!!!!!!! " << endl;
109 
110  string x = assignAttribute(ee, "x", "0");
111  //resolve_string will calculate the string or change it into a double value
112  double x_p = resolve_string(x, gconstantMap);
113  if(verbosity>0) cout << "x_p is obtained " <<"x_p = " << x_p << endl;
114  string y = assignAttribute(ee, "y", "0");
115  double y_p = resolve_string(y, gconstantMap);
116  if(verbosity>0) cout << "y_p is obtained " <<"y_p = " << y_p << endl;
117  string z = assignAttribute(ee, "z", "0");
118  double z_p = resolve_string(z, gconstantMap);
119  if(verbosity>0) cout << "z_p is obtained " <<"z_p = " << z_p << endl;
120 
121  string lunit = assignAttribute(ee, "unit", "mm");
122 
123  gpositionsMap[position_name] = gposition(x_p, y_p, z_p, lunit);
124 
125  }
126  //calls resolve_string function for x, y and z respectively to get double values and add to grotationsMap
127  if(ee.tagName().toStdString() == "rotation")
128  {
129 
130  string rotation_name= assignAttribute(ee, "name", "noname");
131 
132  if(verbosity>0) cout << "!!!!!!!!!! rotation name : " << rotation_name << "!!!!!!!!!!!!!!!!! " << endl;
133 
134  string a = rad_to_deg(assignAttribute(ee, "x", "0"));
135  string a_r = stringify(resolve_string(a, gconstantMap));
136  if(verbosity>0) cout << "a_r is obtained " << a_r << endl;
137  string b = rad_to_deg(assignAttribute(ee, "y", "0"));
138  string b_r = stringify(resolve_string(b, gconstantMap));
139  if(verbosity>0) cout << "b_r is obtained " << b_r << endl;
140  string c = rad_to_deg(assignAttribute(ee, "z", "0"));
141  string c_r = stringify(resolve_string(c, gconstantMap));
142  if(verbosity>0) cout << "c_r is obtained " << c_r << endl;
143  string aunit = assignAttribute(ee, "unit", "deg");
144 
145  //changes unit according to the original value before resolve_string is called
146  rad_to_deg_u (a, aunit);
147  rad_to_deg_u (b, aunit);
148  rad_to_deg_u (c, aunit);
149 
150  grotationsMap[rotation_name] = grotation(a_r, b_r, c_r, aunit);
151 
152 
153  }
154 
155 
156  nn=nn.nextSibling();
157 
158  }
159 
160 
161 
162  }
163 
164 
166  if(!e.isNull() && e.tagName().toStdString() == "solids")
167  {
168 
169  QDomNode nn= e.firstChild();
170  vector<string> seconds;
171  while( !nn.isNull() )
172  {
173  QDomElement ee = nn.toElement();
174  //parses type and calls togType to get correct name of solids types
175  string type = togType(ee.tagName().toStdString());
176 
177  //discriminates operations with type
178  if(type == "union" || type == "subtraction")
179  {
180  string first, second;
181  //define default value of position and rotation reference as unity
182  string pos = "unity";
183  string rot = "unity";
184  string optype, renamed_second;
185 
186  string opname = assignAttribute(ee, "name", "noname");
187 
188  QDomNode nnn= ee.firstChild();
189  while( !nnn.isNull() )
190  {
191  QDomElement eee = nnn.toElement();
192 
193  if(eee.tagName().toStdString() == "first")
194  first = assignAttribute(eee, "ref", "noref");
195 
196  if(eee.tagName().toStdString() == "second")
197  {
198  second = assignAttribute(eee, "ref", "noref");
199  //add every seconds to seconds vector to compare with other seconds
200  seconds.push_back(second);
201  //reused indicates the number of repetition as a seconds
202  double reused = 0;
203  for(unsigned int i=0; i<seconds.size(); i++)
204  {
205 
206  if(seconds[i] == second)
207  reused++;
208  }
209  //if a second is reused rename it with the number of repetition(reused)
210  if(reused>1)
211  renamed_second = second + "_" + stringify(reused);
212  else
213  renamed_second = second;
214 
215 
216  }
217 
218  if(eee.tagName().toStdString() == "positionref")
219  pos = assignAttribute(eee, "ref", "noref");
220 
221  if(eee.tagName().toStdString() == "rotationref")
222  rot = assignAttribute(eee, "ref", "noref");
223 
224  nnn=nnn.nextSibling();
225  }
226  //defines types for union and subtraction with + and - respectively
227  if(type == "union")
228  optype = "Operation: " + first + "+" + second;
229 
230  if(type == "subtraction")
231  optype = "Operation: " + first + "-" + second;
232 
233  //adds operations to gsolidsMap (type will be optype and dimension is 0)
234  gsolidsMap[opname] = gsolid(optype, "0");
235  //adds operation information to the map so that it can be used to make gtables for components.
236  operationMap[opname] = goperation(first, second, renamed_second, pos, rot);
237 
238  }
239 
240  // not an operation
241  else
242  {
243  string name = assignAttribute(ee, "name", "unnamed");
244 
245  cout << " " << endl;
246  if(verbosity>0) cout << "-------solids name : " << name << " solids type : " <<type << "--------" << endl;
247  //get_dimensions will return each solid dimension which is defined in gdml_solids.cc.
248  gsolidsMap[name] = gsolid(type, get_dimensions(nn, gconstantMap));
249 
250  }
251 
252  nn=nn.nextSibling();
253  }
254  }
255  cout << " " << endl;
257  if(!e.isNull() && e.tagName().toStdString() == "structure")
258  {
259  QDomNode nn= e.firstChild();
260  while( !nn.isNull() )
261  {
262  QDomElement ee = nn.toElement();
263 
265  if(!ee.isNull() && ee.tagName().toStdString() == "volume")
266  {
267  string lvol_name= assignAttribute(ee, "name", "unnamed");
268 
269  // childs of volumes to look for phys volumes, volumeref
270  QDomNode nnn= ee.firstChild();
271  string matref;
272  string solidref;
273  string auxtype, auxvalue;
274  string replica_num;
275  while( !nnn.isNull() )
276  {
277  QDomElement eee = nnn.toElement();
278 
279  // I suspect physappear volumes are child of volumes only if volume is "World"
281  //lvol_name == "World" &&
282 
283  //selecting physical volume node
284  if(eee.tagName().toStdString() == "physvol")
285  {
286  string posref = "unity";
287  string rotref = "unity";
288  string physvol_name;
289 
290  QDomNode nnnn= eee.firstChild();
291  while( !nnnn.isNull() )
292  {
293  QDomElement eeee = nnnn.toElement();
294 
295  if(eeee.tagName().toStdString() == "volumeref")
296  physvol_name=eeee.attributeNode("ref").value().toStdString();
297 
298  if(eeee.tagName().toStdString() == "positionref")
299  posref=assignAttribute(eeee, "ref", "unity");
300 
301  if(eeee.tagName().toStdString() == "rotationref")
302  rotref=assignAttribute(eeee, "ref", "unity");
303 
304  nnnn=nnnn.nextSibling();
305  }
306  //adds position and rotation reference to gphysVMap
307  gphysVMap[physvol_name] = gphysV(posref, rotref);
308  }
309 
310 
311  if(eee.tagName().toStdString() == "materialref")
312  matref=assignAttribute(eee, "ref", "");
313 
314 
315  if(eee.tagName().toStdString() == "solidref")
316  solidref=assignAttribute(eee, "ref", "");
317 
318  //selecting replica node
319  if(eee.tagName().toStdString() == "replicavol")
320  {
321  //gets double replica value in gconstantMap with the string value
322  replica_num=assignAttribute(eee, "number", "0");
323  double j = gconstantMap[replica_num];
324 
325 
326  QDomNode nnnn= eee.firstChild();
327  string volume_ref;
328  while( !nnnn.isNull() )
329  {
330 
331  QDomElement eeee = nnnn.toElement();
332 
333  if(eeee.tagName().toStdString() == "volumeref")
334  volume_ref=eeee.attributeNode("ref").value().toStdString();
335 
336  if(eeee.tagName().toStdString() == "replicate_along_axis")
337  {
338  QDomNode n_5= eeee.firstChild();
339 
340  string x_s, y_s, z_s, direction;
341  double width = 0;
342  double offset = 0;
343  string width_ref, width_unit, offset_ref, offset_unit;
344 
345  while( !n_5.isNull() )
346  {
347 
348  QDomElement e_5 = n_5.toElement();
349  if(e_5.tagName().toStdString() == "direction")
350  {
351  x_s = assignAttribute(e_5, "x", "0");
352  y_s = assignAttribute(e_5, "y", "0");
353  z_s = assignAttribute(e_5, "z", "0");
354  }
355  if(e_5.tagName().toStdString() == "width")
356  {
357  width_ref = assignAttribute(e_5, "value", "no value");
358  width_unit = assignAttribute(e_5, "unit", "mm");
359  width = gconstantMap[width_ref];
360  }
361  if(e_5.tagName().toStdString() == "offset")
362  {
363  offset_ref = assignAttribute(e_5, "value", "no value");
364  offset_unit = assignAttribute(e_5, "unit", "mm");
365  offset = gconstantMap[offset_ref];
366  }
367  n_5 = n_5.nextSibling();
368  }
369 
370 
371  if(x_s == "1") direction = "1";
372  if(y_s == "1") direction = "2";
373  if(z_s == "1") direction = "3";
374 
375  //obtains replica type with all the replica information
376  string replica_type = "Replica "+ volume_ref + "," +"root" +","+ direction+ "," + stringify(j) + "," +stringify(width)+"*"+width_unit + "," + stringify(offset)+"*"+offset_unit;
377  //defines replica type with the string above
378  gsolidsMap[solidref].type = replica_type;
379 
380 
381  }
382  nnnn=nnnn.nextSibling();
383  }
384  }
385  //parese auxiliary node and fills the map with type and value
386  if(eee.tagName().toStdString() == "auxiliary")
387  {
388  auxtype=assignAttribute(eee, "auxtype", "");
389  auxvalue=assignAttribute(eee, "auxvalue", "");
390  }
391 
392  nnn=nnn.nextSibling();
393 
394  }
395  //fills glogicVMap with material and solid reference
396  glogicVMap[lvol_name] = glogicV(matref, solidref);
397  auxiliaryMap[auxtype] = auxvalue;
398  }
399  nn=nn.nextSibling();
400  }
401  }
402 
403  // selecting "define" nodes for definitions of parameters
404 
405 
406  n=n.nextSibling();
407 
408  }
409 
410  //makes gtable for every logical volume
411  for(map<string, glogicV>::iterator itt=glogicVMap.begin(); itt != glogicVMap.end(); itt++)
412  {
413  gtable gt;
414 
415  string a ="root";
416  string b = "no description";
417  string c = "9999ff";
418  string d = "no";
419  string e = "1";
420  string f = "0";
421 
422  gt.add_data(itt->first); // first item is name
423  gt.add_data(a); // second element is mother volume (not found for now)
424  gt.add_data(b);
425 
426  //position
427  //If an element which is same as logical volume name(itt->first) doesn't exist, add default value.
428  if(gphysVMap.find(itt->first) == gphysVMap.end())
429  {
430  if(verbosity>0)cout << " !! Attention: position ref doesn't exist. Defaulting to (0,0,0)" << endl;
431  gt.add_data((string) "0, 0, 0");
432  }
433 
434  else
435  {
436  string posref_name = gphysVMap[itt->first].positionRef;
437  //If there is no position value for a position reference, add a default value
438  if(gpositionsMap.find(posref_name) == gpositionsMap.end())
439  {
440  if(verbosity>0)cout << " !! Attention: position ref for " << posref_name << " not found. Defaulting to (0,0,0)" << endl;
441  gt.add_data((string) "0, 0, 0");
442  }
443 
444  else
445  gt.add_data(gpositionsMap[posref_name].get_dimensions()); // position is obtained by get_dimensions() like " x*unit y*unit z*unit"
446  if(verbosity>0)cout << "position get_dimensions() : " << gpositionsMap[posref_name].get_dimensions()<< endl;
447  }
448 
449  //rotation
450  //If an element which is same as logical volume name(itt->first) doesn't exist, add default value.
451  if(gphysVMap.find(itt->first) == gphysVMap.end())
452  {
453  if(verbosity>0)cout << " !! Attention: rotation ref doesn't exist. Defaulting to (0,0,0)" << endl;
454  gt.add_data((string) "0, 0, 0");
455  }
456  else
457  {
458  string rotref_name = gphysVMap[itt->first].rotationRef;
459  //If there is no rotation value for a rotation reference, add a default value
460  if(grotationsMap.find(rotref_name) == grotationsMap.end())
461  {
462  if(verbosity>0)cout << " !! Attention: rotation ref for " << rotref_name << " not found. Defaulting to (0,0,0)" << endl;
463  gt.add_data((string) "0, 0, 0");
464  }
465 
466  else
467  gt.add_data(grotationsMap[rotref_name].get_dimensions());// rotation is obtained by get_dimensions() like " x*unit y*unit z*unit"
468 
469  if(verbosity>0)cout << "rotation get_dimensions() : " << grotationsMap[rotref_name].get_dimensions() << endl;
470  }
471  gt.add_data(c); // color
472 
473  string solid_type = gsolidsMap[itt->second.solidRef].type;
474  gt.add_data(solid_type); // type
475 
476  string solid_dimensions = gsolidsMap[itt->second.solidRef].dimension;
477  gt.add_data(solid_dimensions); // dimensions of solid
478 
479  gt.add_data(itt->second.materialRef); // material
480  gt.add_data(d); // magnetic field
481  gt.add_data(e); // copy number
482  gt.add_data(e); // pmany
483  gt.add_data(e); // 1 = active
484  if (itt->first == "World")
485  gt.add_data(f); // 0 = invisible (World)
486  else
487  gt.add_data(e);
488 
489  //gt.add_data(e); // 1 = solid style , 0 wirefeame
490  gt.add_data(string("0")); // 1 = solid style , 0 wirefeame
491  gt.add_data(d); // sensitivity
492  gt.add_data(d); // hitprocess
493  gt.add_data(f); // identity
494  gt.add_data(dname); //detector name
495  gt.add_data((string) "GDML"); //GDML
496 
497  dets[gt.data[0]] = get_detector(gt, gemcOpt, RC);
498 
499  if(verbosity>0)cout << dets[gt.data[0]] << endl;
500 
501 
502  }
503 
504  //makes gtable for every component of operations
505  for(map<string, goperation>::iterator itt=operationMap.begin(); itt != operationMap.end(); itt++)
506  {
507  //makes two gtables for every operation
508  //One is for first component, the other is for second component
509  for(unsigned int i=0; i<2; i++)
510  {
511  gtable gt;
512 
513  string a ="root";
514  string b = "no description";
515  string c = "9999ff";
516  string d = "no";
517  string e = "1";
518  string f = "0";
519  string g = "Component";
520 
521  string fs;
522 
523  // first item is name
524  //makes a gtable for first component and then second component
525  if(i == 0)
526  {
527  gt.add_data(itt->second.first);
528  fs = "first";
529  if(verbosity>0)cout << "-------------------first--------------------"<< endl;
530  }
531  else if(i == 1)
532  {
533  gt.add_data(itt->second.renamed_second);
534  fs = "second";
535  if(verbosity>0)cout << "--------------------second----------------------" << endl;
536  }
537  gt.add_data(a); // second element is mother volume (not found for now)
538  gt.add_data(b);
539 
540  //For position and rotation,
541  //If the gtable if for first component, position is "0"
542  //If it is for second component, get position from gpositionsMap and inline function get_dimensions()
543 
544  //position
545  string posref_name;
546  if(fs == "first")
547  gt.add_data((string) "0, 0, 0");
548  else if(fs == "second")
549  {
550  posref_name = itt->second.pos;
551  //If there is no position value for a position reference, add a default value
552  if(gpositionsMap.find(posref_name) == gpositionsMap.end())
553  {
554  if(verbosity>0)cout << " !! Attention: position ref for " << posref_name << " not found. Defaulting to (0,0,0)" << endl;
555  gt.add_data((string) "0, 0, 0");
556  }
557  else
558  gt.add_data(gpositionsMap[posref_name].get_dimensions());
559 
560  if(verbosity>0)cout << "position ref " << posref_name << " position " << gpositionsMap[posref_name].get_dimensions() << endl;
561  }
562 
563  //rotation
564  string rotref_name;
565  if(fs == "first")
566  gt.add_data((string) "0, 0, 0");
567  else if(fs == "second")
568  {
569  rotref_name = itt->second.rot;
570  //If there is no rotation value for a rotation reference, add a default value
571  if(grotationsMap.find(rotref_name) == grotationsMap.end())
572  {
573  if(verbosity>0)cout << " !! Attention: position ref for " << rotref_name << " not found. Defaulting to (0,0,0)" << endl;
574  gt.add_data((string) "0, 0, 0");
575  }
576 
577  else
578  gt.add_data(gpositionsMap[posref_name].get_dimensions());
579 
580 
581  if(verbosity>0)cout << "rotation ref " << rotref_name << " rotation " << grotationsMap[rotref_name].get_dimensions() << endl;
582  }
583 
584 
585  gt.add_data(c); // color
586 
587  //type
588  string lvol_name;
589  //finds solid reference for first and second from operationMap
590  //This solid reference(lvol_name) will be used to find type and dimension from gsolidsMap
591  if(fs == "first")
592  lvol_name = itt->second.first;
593  else if(fs == "second")
594  lvol_name = itt->second.second;
595 
596  string solid_type = gsolidsMap[lvol_name].type;
597  gt.add_data(solid_type);
598 
599  //dimensions of solid
600  string solid_dimensions = gsolidsMap[lvol_name].dimension;
601  gt.add_data(solid_dimensions);
602 
603  gt.add_data(g); // material
604  gt.add_data(d); // magnetic field
605  gt.add_data(e); // copy number
606  gt.add_data(e); // pmany
607  gt.add_data(e); // 1 = active
608  gt.add_data(e); // 1 = visible
609 
610  //gt.add_data(e); // 1 = solid style , 0 wirefeame
611  gt.add_data(string("0")); // 1 = solid style , 0 wirefeame
612  gt.add_data(d); // sensitivity
613  gt.add_data(d); // hitprocess
614  gt.add_data(f); // identity
615  gt.add_data(dname); //detector name
616  gt.add_data((string) "GDML"); //GDML
617 
618  dets[gt.data[0]] = get_detector(gt, gemcOpt, RC);
619  if(verbosity>0)cout << dets[gt.data[0]] << endl;
620 
621  }
622 
623  }
624 
625 
626 
627 
628  }
629 
630  return dets;
631 
632 }
633 
634 
635 ostream &operator<<(ostream &stream, map<string, glogicV> glogicVMap)
636 {
637  for(map<string, glogicV>::iterator it = glogicVMap.begin(); it != glogicVMap.end(); it++)
638  cout << " Logic Volume :" << it->first << " solidRef: " << it->second.solidRef << ", materialRef: " << it->second.materialRef << endl;
639 
640  return stream;
641 }
642 
643 
644 ostream &operator<<(ostream &stream, map<string, gposition> gpositionsMap)
645 {
646  for(map<string, gposition>::iterator it = gpositionsMap.begin(); it != gpositionsMap.end(); it++)
647  cout << " Position " << it->first << ": x: " << it->second.x << ", y: " << it->second.y << ", z: " << it->second.z << " lunit: " << it->second.unit << endl;
648 
649  return stream;
650 }
651 
652 
653 ostream &operator<<(ostream &stream,map<string, grotation> grotationsMap )
654 {
655  for(map<string,grotation>::iterator it = grotationsMap.begin(); it != grotationsMap.end(); it++)
656  cout << " Rotation " << it->first << ": x: " << it->second.x << ", y: " << it->second.y << ", z: " << it->second.z << " aunit: " << it->second.unit << endl;
657 
658  return stream;
659 }
660 
661 
662 ostream &operator<<(ostream &stream,map<string, gsolid> gsolidsMap )
663 {
664  for(map<string, gsolid>::iterator it = gsolidsMap.begin(); it != gsolidsMap.end(); it++)
665  cout << " Solid :" << it->first << " type: " << it->second.type << ", dimension: " << it->second.dimension << endl;
666 
667  return stream;
668 }
669 
670 
671 ostream &operator<<(ostream &stream,map<string, gphysV> gphysVMap )
672 {
673  for(map<string, gphysV>::iterator it = gphysVMap.begin(); it != gphysVMap.end(); it++)
674  cout << " Physical Volume :" << it->first << " positionRef: " << it->second.positionRef << ", rotationRef: " << it->second.rotationRef << endl;
675 
676  return stream;
677 }
678 
679 
680 
681 string togType(string type)
682 {
683  if(type == "para") return "Parallelepiped";
684  if(type == "cone") return "Cons";
685  if(type == "box") return "Box";
686  if(type == "sphere") return "Sphere";
687  if(type == "ellipsoid") return "Ellipsoid";
688  if(type == "paraboloid") return "Paroboloid";
689  if(type == "hype") return "Hype";
690  if(type == "tube") return "Tube";
691  if(type == "eltube") return "EllipticalTube";
692  if(type == "torus") return "Torus";
693  if(type == "trd") return "Trd";
694  if(type == "orb") return "Orb";
695  if(type == "tet") return "Tet";
696 
697  return type;
698 }
699 
700 double resolve_strings(string constant_name, string v, map<string, double> gconstantMap)
701 {
702 
703  double constantResult;
704 
705  // starts solving operations, and iteration will become smaller and smaller
706 
707  // If a string has "+","-","/" or "*", replace these to " + "," - "," / " and " * " so that it can be tokenized
708  string w("+");
709  string x("-");
710  string y("*");
711  string z("/");
712  v = replaceCharWithChars(v, w, " + ");
713  v = replaceCharWithChars(v, x, " - ");
714  v = replaceCharWithChars(v, y, " * ");
715  v = replaceCharWithChars(v, z, " / ");
716 
717  vector<string> operation;
718  vector<double> constant;
719  vector<string> constantName;
720 
721  //puts constant names that exist in the resultMap by now to compare with operand tokens and change them with double values
722 
723  for(map<string, double>::iterator it=gconstantMap.begin(); it != gconstantMap.end(); it++)
724  constantName.push_back(it->first);
725 
726  if (v == "0" || v == "0.0")
727  constantResult = 0.0;
728 
729  else if ( atof(v.c_str())== 0 && atoi(v.c_str()) == 0)
730  {
731  if(verbosity>0)cout << "----------constant calculation---------- "<< endl;
732  //tokenizes each constant value that needs to be substituted or calculated
733  int size = v.length();
734  char constantChar[size];
735  strcpy(constantChar, v.c_str());
736  char * pch;
737  //tokenizes a string by space and "\n"
738  pch = strtok (constantChar," \n");
739  string token;
740 
741  //adds operators in operation vector and operands in constant vector after tokenizing
742  while (pch != NULL)
743  {
744  token = pch;
745 
746  if(token == "+" || token == "-" || token == "*" || token == "/")
747  operation.push_back(token);
748 
749  //puts number tokens into the constant vector.
750  else if (atof(token.c_str()) != 0)
751  constant.push_back(atof(token.c_str()));
752 
753  else
754  constant.push_back(gconstantMap[token]);
755 
756 
757  if(verbosity>0) cout << "constant " << token << endl;
758 
759  pch = strtok (NULL, " \n");
760  }
761 
762 
763  //puts double constant value in the map if it doesn't include any operators
764  if (operation.size() == 0)
765  constantResult = constant[0];
766  //If calculation is needed.
767  else
768  {
769  //gets a string with changed values and operators.
770 
771  unsigned int calSize = constant.size()*2-1;
772 
773  vector<string> calculation;
774  calculation.resize(calSize);
775 
776  //make calculation vector in the same order of a formula (operand operator operand...)
777  for(unsigned int a=0;a<constant.size();a++)
778  calculation[2*a] = stringify(constant[a]);
779  for(unsigned int a=0;a<constant.size()-1;a++)
780  calculation[2*a+1] = operation[a];
781 
782  if(verbosity>0)
783  {
784  cout << " " << endl;
785  cout << "calculation" << endl;
786  cout << " " << endl;
787 
788  for(unsigned int a=0;a<calSize;a++)
789  cout << calculation[a] << endl;
790  }
791 
792  //calls p_calculation to get the result of calculation.
793  calculation[0] = p_calculation(calculation);
794 
795  if(verbosity>0) cout << "!!!!!calculated value!!!!! " << calculation[0] << endl;
796  constantResult = atof(calculation[0].c_str());
797 
798  }
799 
800  }
801  else
802  constantResult = atof(v.c_str());
803 
804  return constantResult;
805 
806 
807 }
808 
809 
810 double resolve_string(string constString, map<string, double> gconstantMap)
811 {
812 
813  double result;
814 
815  //When there are these characters in a string, add space before and after the string
816  string w("+");
817  string x("-");
818  string y("*");
819  string z("/");
820  string p1("(");
821  string p2(")");
822  string sine("sin");
823  string cosine("cos");
824 
825  //For one character, use replaceCharWithChars which is defined in string_utilities.h
826  constString = replaceCharWithChars(constString, w, " + ");
827  constString = replaceCharWithChars(constString, x, " - ");
828  constString = replaceCharWithChars(constString, y, " * ");
829  constString = replaceCharWithChars(constString, z, " / ");
830  constString = replaceCharWithChars(constString, p1, " ( ");
831  constString = replaceCharWithChars(constString, p2, " ) ");
832 
833  //If it has more than one character, use replaceCharsWithChars also defined in string_utilities.h
834  if(constString.size()>=sine.size())
835  constString = replaceCharsWithChars(constString, sine, " sin ");
836  if(constString.size()>=cosine.size())
837  constString = replaceCharsWithChars(constString, cosine, " cos ");
838 
839  if(verbosity>0)cout << "constString after replacing : " << constString << endl;
840 
841 
842  vector<string> calculation;
843 
844  vector<string> operation;
845  vector<double> constant;
846 
847  //If constString is "0", return double value 0
848  if (constString == "0" || constString == "0.0")
849  result = 0.0;
850  //If constString is not numbers and is a string,
851  else if ( atof(constString.c_str())== 0 && atoi(constString.c_str()) == 0)
852  {
853  int size = constString.length();
854  char constantChar[size];
855  strcpy(constantChar, constString.c_str());
856  char * pch;
857  pch = strtok (constantChar," \n");
858  string token;
859 
860  //tokenize the string and put values in gconstantMap
861  while (pch != NULL)
862  {
863  token = pch;
864 
865  //put each token to calculation vector
866  if(token == "+" || token == "-" ||token == "*" ||token == "/" || token == "(" || token == ")" || token == "sin" || token == "cos" )
867  calculation.push_back(token);
868  //If a token is number, add double value of the number
869  else if(atof(token.c_str()) != 0)
870  calculation.push_back(token);
871 
872  //If the token is "pi", put "3.14" instead of it
873  else if(token == "pi")
874  calculation.push_back("3.14");
875  //If the token is string, and gconstantMap has its value, put the value to calculation
876  else
877  calculation.push_back(stringify(gconstantMap[token]));
878 
879  pch = strtok (NULL, " \n");
880  }
881 
882  for(unsigned int i=0; i<calculation.size(); i++)
883  if(verbosity>0)cout << "calculation[" << i << "] = " << calculation[i] << endl;
884  //If calculation has only one token, return it as a result
885  if(calculation.size() == 1)
886  result = atof(calculation[0].c_str());
887  //If calculation vector has more than one element and needs calculation,
888  else
889  {
890 
891  vector<unsigned int> a;
892  vector<unsigned int> b;
893  unsigned int element_a, element_b;
894  //makes vector for parenthesis and find the number of parenthesis
895  for(unsigned int i=0; i<calculation.size();i++)
896  {
897  if(calculation[i] == "(")
898  a.push_back(i);
899  if(calculation[i] == ")")
900  b.push_back(i);
901  }
902  unsigned int size_a = a.size();
903 
904  //If parenthesis exists, check if there is double parenthesis and calculate inside of every parenthesis pair
905  if(size_a>0)
906  {
907  int doublep_count=0;
908  vector<unsigned int> c;
909  //finds double parenthesis by comparing the index of "(" and ")"
910  for(unsigned int i=0; i<a.size()-1; i++)
911  {
912  //If a ")[i]" which is a pair with "([i]" is located in ahead of "([i+1]", there is double parenthesis
913  if(b[i]>a[i+1])
914  {
915  c.push_back(i+1);
916  doublep_count++;
917  }
918  }
919  unsigned int size_c = c.size();
920 
921  //If the string has one pair of parenthesis, calculate inside the parenthesis once using p_calculation.
922  if(size_a>0 && doublep_count == 0)
923  {
924  element_a=a[0];
925  element_b=b[0];
926 
927  while(size_a>0)//iterates until there is no parenthesis left
928  {
929  vector<string> paren_calculation;
930  //puts calculation elements which are between a pair of parenthesis to paren_calculation
931  for(unsigned int i=element_a+1; i<element_b; i++)
932  paren_calculation.push_back(calculation[i]);
933  //calls p_calculation to calculate paren_calculation and add the result to the location of the corresponding "("
934  calculation[element_a] = p_calculation(paren_calculation);
935 
936  //reorganize calculation by shifting the next elements located after the parenthesis part and popping out as many times as the paren_calculation size+1
937  for(unsigned int i = element_b+1; i<calculation.size(); i++)
938  calculation[i-element_b+element_a] = calculation[i];
939  for(unsigned int i = 0; i<element_b-element_a; i++)
940  calculation.pop_back();
941  size_a--;
942  //find the location(index) of each parenthesis again in the modified calculation vector
943  for(unsigned int i=0; i<calculation.size();i++)
944  {
945  if(calculation[i] == "(")
946  element_a = i;
947  if(calculation[i] == ")")
948  element_b = i;
949  }
950  for(unsigned int j=0; j<calculation.size(); j++)
951  if(verbosity>0)cout << "calculation[" << j << "] = " << calculation[j] << endl;
952  }
953 
954  }
955  //If the string has double parenthesis, calculate twice using p_calculation.
956  else if(doublep_count>0)
957  {
958  unsigned int m = c[0];
959  //iterates calculation for double parenthesis until there is no double parenthesis.
960  //Same as single parenthesis calculation.
961  while(size_c>0)
962  {
963  vector<string> paren_calculation;
964 
965  for(unsigned int n=a[m]+1; n<b[m-1]; n++)
966  {
967  paren_calculation.push_back(calculation[n]);
968  }
969  for(unsigned int h=0; h<paren_calculation.size(); h++)
970  if(verbosity>0)cout << "double_paren_calculation[i] = " << paren_calculation[h] << endl;
971 
972  calculation[a[m]] = p_calculation(paren_calculation);
973 
974  for(unsigned int n=b[m-1]+1; n<calculation.size(); n++)
975  calculation[n-b[m-1]+a[m]] = calculation[n];
976  for(unsigned int n=0; n<b[m-1]-a[m]; n++)
977  calculation.pop_back();
978  size_c--;
979  size_a--;
980  if(size_c>0)
981  {
982  vector<unsigned int>aa;
983  vector<unsigned int>bb;
984 
985  for(unsigned int n=0;n<calculation.size();n++)
986  {
987  if(calculation[n] == "(")
988  aa.push_back(n);
989  if(calculation[n] == ")")
990  bb.push_back(n);
991  }
992  for(unsigned int n=0;n<calculation.size()-1;n++)
993  {
994  if(bb[n]>aa[n+1])
995  m=n;
996  }
997  }
998 
999  }
1000 
1001  //After removing double parenthesis, iterates again to remove single parenthesis
1002  vector<unsigned int> d;
1003  vector<unsigned int> e;
1004  unsigned int element_d, element_e;
1005  for(unsigned int i=0; i<calculation.size(); i++)
1006  {
1007  if(calculation[i] == "(")
1008  d.push_back(i);
1009  if(calculation[i] == ")")
1010  e.push_back(i);
1011  }
1012  element_d = d[0];
1013  element_e = e[0];
1014  unsigned int size_d = d.size();
1015  while(size_d>0)
1016  {
1017  vector<string>paren_calculation;
1018  for(unsigned int i=element_d+1; i<element_e; i++)
1019  paren_calculation.push_back(calculation[i]);
1020  for(unsigned int h=0; h<paren_calculation.size(); h++)
1021  if(verbosity>0)cout << "__paren_calculation[i] = " << paren_calculation[h] << endl;
1022  calculation[element_d] = p_calculation(paren_calculation);
1023 
1024  for(unsigned int i=element_e+1; i<calculation.size(); i++)
1025  calculation[i-element_e+element_d] = calculation[i];
1026  for(unsigned int i=0; i<element_e-element_d; i++)
1027  calculation.pop_back();
1028  size_d--;
1029  for(unsigned int i=0; i<calculation.size();i++)
1030  {
1031  if(calculation[i] == "(")
1032  element_d = i;
1033  if(calculation[i] == ")")
1034  element_e = i;
1035  }
1036  }
1037  }
1038  }
1039  //If there is no parenthesis, go to the next step
1040  else
1041  if(verbosity>0)cout << "There is no parenthesis in calculation[]" << endl;
1042  //looks for sin and cos
1043  for(unsigned int i=0; i<calculation.size();i++)
1044  {
1045  //If there is sine or cosine in the calculation, calculate this trigonometric function and reorganize calculation by moving elements and popping out
1046  if(calculation[i] == "sin")
1047  {
1048  calculation[i] = stringify(sin(atof(calculation[i+1].c_str())));
1049  for(unsigned int j=i+2; j<calculation.size();j++)
1050  calculation[j]=calculation[j-1];
1051  calculation.pop_back();
1052  }
1053 
1054  if(calculation[i] == "cos")
1055  {
1056  calculation[i] = stringify(cos(atof(calculation[i+1].c_str())));
1057  for(unsigned int j=i+2; j<calculation.size();j++)
1058  calculation[j]=calculation[j-1];
1059  calculation.pop_back();
1060  }
1061  }
1062  //If there is no parenthesis, sin and cos, calculate +-/* with p_calculation function
1063  result = atof(p_calculation(calculation).c_str());
1064  if(verbosity>0)cout << "return value result = " << result << endl;
1065 
1066 
1067  }
1068  }
1069  //If constString is composed of numbers, not "0"
1070  else
1071  result = atof(constString.c_str());
1072 
1073 return result;
1074 
1075 
1076 }
1077 
1078 //a function that calculates +, -, * and /
1079 string p_calculation(vector<string> paren_calculation)
1080 {
1081  string paren_result = paren_calculation[0];
1082 
1083  for(unsigned int m=0; m<paren_calculation.size(); m++)
1084  if(verbosity>0)cout << "calculation in p_calculation : " << paren_calculation[m] << endl;
1085 
1086  //If "-" is the first element, (If there is a negative number)
1087  if(paren_calculation[0] == "-")
1088  {
1089  //multiply -1 to the second element and reorganize calculation vector.
1090  paren_calculation[1] = stringify(-1*atof(paren_calculation[1].c_str()));
1091  if(verbosity>0)cout << "calculation[1] after multiplying -1 " << paren_calculation[1] << endl;
1092  for(unsigned int i =1;i<paren_calculation.size();i++)
1093  paren_calculation[i-1]=paren_calculation[i];
1094  paren_calculation.pop_back();
1095  }
1096 
1097  int count=0;
1098  unsigned int paren_calSize = paren_calculation.size();
1099 
1100  //counts the number of "*" and "/"
1101  for(unsigned int j=0;j<(paren_calSize-1)/2;j++)
1102  {
1103  if(paren_calculation[2*j+1] == "*" || paren_calculation[2*j+1] == "/")
1104  count++;
1105  }
1106  //If there is "*" or "/", calculate this operation first and reorganize calculation vector
1107  while(count>0)
1108  {
1109  for(unsigned int j=0;j<(paren_calculation.size()-1)/2;j++)
1110  {
1111 
1112  if(paren_calculation[2*j+1] == "*")
1113  {
1114 
1115  paren_calculation[2*j] = stringify(atof(paren_calculation[2*j].c_str())*atof(paren_calculation[2*j+2].c_str()));
1116  //remove paren_calculation[2*j+1], [2*j+2] and shift other values
1117  for(unsigned int l=2*j+3;l<paren_calculation.size();l++)
1118  paren_calculation[l-2]=paren_calculation[l];
1119  //remove paren_calculation[end], paren_calculation[end-1]
1120  paren_calculation.pop_back();
1121  paren_calculation.pop_back();
1122  count=count-1;
1123 
1124  }
1125  else if(paren_calculation[2*j+1] == "/")
1126  {
1127  paren_calculation[2*j] = stringify(atof(paren_calculation[2*j].c_str())/atof(paren_calculation[2*j+2].c_str()));
1128  //remove paren_calculation[2*j+1], [2*j+2] and shift other values
1129  for(unsigned int l=2*j+3;l<paren_calculation.size();l++)
1130  paren_calculation[l-2]=paren_calculation[l];
1131  //remove paren_calculation[end], paren_calculation[end-1]
1132  paren_calculation.pop_back();
1133  paren_calculation.pop_back();
1134  count=count-1;
1135 
1136  }
1137  }
1138  }
1139 
1140  //After "*" and "/" calculation, calculate "+" and "-", the final result will be stored in paren_calculation[0]
1141  while(paren_calculation.size()>1)
1142  {
1143  int m = 0;
1144  if(paren_calculation[2*m+1] == "+")
1145  {
1146  paren_calculation[2*m] = stringify(atof(paren_calculation[2*m].c_str())+atof(paren_calculation[2*m+2].c_str()));
1147  for(unsigned int l=2*m+3;l<paren_calculation.size();l++)
1148  paren_calculation[l-2]=paren_calculation[l];
1149  //remove paren_calculation[end], paren_calculation[end-1]
1150  paren_calculation.pop_back();
1151  paren_calculation.pop_back();
1152  }
1153  if(paren_calculation[2*m+1] == "-")
1154  {
1155  paren_calculation[2*m] = stringify(atof(paren_calculation[2*m].c_str())-atof(paren_calculation[2*m+2].c_str()));
1156  for(unsigned int l=2*m+3;l<paren_calculation.size();l++)
1157  paren_calculation[l-2]=paren_calculation[l];
1158  //remove paren_calculation[end], paren_calculation[end-1]
1159  paren_calculation.pop_back();
1160  paren_calculation.pop_back();
1161 
1162  }
1163 
1164 
1165  }
1166  paren_result = paren_calculation[0];
1167 
1168  return paren_result;
1169 
1170 }
1171 
int check_if_factory_is_needed(map< string, detectorCondition > dcon, string factory)
string rad_to_deg(string radValue)
Definition: gdml_solids.cc:13
vector< string > data
Definition: utils.h:76
Definition: utils.h:65
string get_dimensions(QDomNode solidNode, map< string, double > gconstantMap)
Definition: gdml_solids.cc:56
double verbosity
map< string, detector > loadDetectors()
string replaceCharsWithChars(string input, string x, string y)
void add_data(QVariant input)
Definition: utils.h:78
string replaceCharWithChars(string input, string x, string y)
map< string, detectorCondition > detectorConditionsMap
runConditions RC
string assignAttribute(QDomElement e, string attribute, string defaultValue)
Definition: utils.cc:294
string stringify(double x)
string rad_to_deg_u(string radValue, string radUnit)
converts the unit radian to degree if there is radian value.
Definition: gdml_solids.cc:38
double resolve_strings(string constant_name, string v, map< string, double > gconstantMap)
map< string, aopt > optMap
Options map.
Definition: options.h:75
string togType(string type)
double resolve_string(string constString, map< string, double > gconstantMap)
string p_calculation(vector< string > paren_calculation)
detector get_detector(gtable gt, goptions go, runConditions RC)