Logo ROOT   6.21/01
Reference Guide
TGDMLParse.cxx
Go to the documentation of this file.
1 /* @(#)root/gdml:$Id$ */
2 // Author: Ben Lloyd 09/11/06
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2006, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TGDMLParse
13 \ingroup Geometry_gdml
14 
15  This class contains the implementation of the GDML parser associated to
16  all the supported GDML elements. User should never need to explicitly
17  instaciate this class. It is internally used by the TGeoManager.
18 
19  Each element process has a 'Binding' to ROOT. The 'binding' is specific
20  mapping of GDML elements (materials, solids, etc) to specific objects which
21  should be instanciated by the converted. In the present case (ROOT) the
22  binding is implemented at the near the end of each process function. Most
23  bindings follow similar format, dependent on what is being added to the
24  geometry.
25 
26  This file also contains the implementation of the TGDMLRefl class. This is
27  just a small helper class used internally by the 'reflection' method (for
28  reflected solids).
29 
30  The presently supported list of TGeo classes is the following:
31 
32 #### Materials:
33  - TGeoElement
34  - TGeoMaterial
35  - TGeoMixture
36 
37 #### Solids:
38  - TGeoBBox
39  - TGeoArb8
40  - TGeoTubeSeg
41  - TGeoConeSeg
42  - TGeoCtub
43  - TGeoPcon
44  - TGeoTrap
45  - TGeoGtra
46  - TGeoTrd2
47  - TGeoSphere
48  - TGeoPara
49  - TGeoTorus
50  - TGeoHype
51  - TGeoPgon
52  - TGeoXtru
53  - TGeoEltu
54  - TGeoParaboloid
55  - TGeoCompositeShape (subtraction, union, intersection)
56 
57 #### Approximated Solids:
58  - Ellipsoid (approximated to a TGeoBBox)
59  - Elliptical cone (approximated to a TGeoCone)
60 
61 #### Geometry:
62  - TGeoVolume
63  - TGeoVolumeAssembly
64  - divisions
65  - reflection
66 
67 When most solids or volumes are added to the geometry they
68 
69 
70  Whenever a new element is added to GDML schema, this class needs to be extended.
71  The appropriate method (process) needs to be implemented, as well as the new
72  element process then needs to be linked thru the function TGDMLParse
73 
74  For any question or remarks concerning this code, please send an email to
75  ben.lloyd@cern.ch
76 
77 */
78 
79 #include "TGDMLParse.h"
80 #include "TGDMLMatrix.h"
81 
82 #include "TGeoManager.h"
83 #include "TGeoMatrix.h"
84 #include "TXMLEngine.h"
85 #include "TGeoVolume.h"
86 #include "TGeoBBox.h"
87 #include "TGeoParaboloid.h"
88 #include "TGeoArb8.h"
89 #include "TGeoTube.h"
90 #include "TGeoCone.h"
91 #include "TGeoTrd2.h"
92 #include "TGeoPcon.h"
93 #include "TGeoPgon.h"
94 #include "TGeoSphere.h"
95 #include "TGeoTorus.h"
96 #include "TGeoPara.h"
97 #include "TGeoHype.h"
98 #include "TGeoEltu.h"
99 #include "TGeoXtru.h"
100 #include "TGeoScaledShape.h"
101 #include "TGeoTessellated.h"
102 #include "TGeoVolume.h"
103 #include "TROOT.h"
104 #include "TMath.h"
105 #include "TMap.h"
106 #include "TObjString.h"
107 #include "TGeoExtension.h"
108 #include "TGeoMaterial.h"
109 #include "TGeoBoolNode.h"
110 #include "TGeoMedium.h"
111 #include "TGeoElement.h"
112 #include "TGeoShape.h"
113 #include "TGeoCompositeShape.h"
114 #include "TGeoRegion.h"
115 #include "TGeoOpticalSurface.h"
116 #include "TGeoSystemOfUnits.h"
117 
118 #include <stdlib.h>
119 #include <string>
120 #include <sstream>
121 #include <locale>
122 
124 
125 ////////////////////////////////////////////////////////////////////////////////
126 /// Constructor
127 
129 {
130  fWorldName = "";
131  fWorld = 0;
132  fVolID = 0;
133  fFILENO = 0;
134  for (Int_t i = 0; i < 20; i++)
135  fFileEngine[i] = 0;
136  fStartFile = 0;
137  fCurrentFile = 0;
138  auto def_units = TGeoManager::GetDefaultUnits();
139  switch (def_units) {
141  fDefault_lunit = "mm";
142  fDefault_aunit = "rad";
143  break;
145  fDefault_lunit = "cm";
146  fDefault_aunit = "deg";
147  break;
148  default: // G4 units
149  fDefault_lunit = "mm";
150  fDefault_aunit = "rad";
151  }
152 }
153 
154 ////////////////////////////////////////////////////////////////////////////////
155 /// Creates the new instance of the XMLEngine called 'gdml', using the filename >>
156 /// then parses the file and creates the DOM tree. Then passes the DOM to the
157 /// next function to translate it.
158 
159 TGeoVolume *TGDMLParse::GDMLReadFile(const char *filename)
160 {
161  // First create engine
162  TXMLEngine *gdml = new TXMLEngine;
163  gdml->SetSkipComments(kTRUE);
164 
165  // Now try to parse xml file
166  XMLDocPointer_t gdmldoc = gdml->ParseFile(filename);
167  if (gdmldoc == 0) {
168  delete gdml;
169  return 0;
170  } else {
171 
172  // take access to main node
173  XMLNodePointer_t mainnode = gdml->DocGetRootElement(gdmldoc);
174 
175  fFileEngine[fFILENO] = gdml;
176  fStartFile = filename;
177  fCurrentFile = filename;
178 
179  // display recursively all nodes and subnodes
180  ParseGDML(gdml, mainnode);
181 
182  // Release memory before exit
183  gdml->FreeDoc(gdmldoc);
184  delete gdml;
185  }
186  return fWorld;
187 }
188 
189 ////////////////////////////////////////////////////////////////////////////////
190 /// This function recursively moves thru the DOM tree of the GDML file. It checks for
191 /// key words along the way and if a key word is found it calls the corresponding
192 /// function to interpret the node.
193 
195 {
196  DefineConstants();
197  XMLAttrPointer_t attr = gdml->GetFirstAttr(node);
198  const char *name = gdml->GetNodeName(node);
199  XMLNodePointer_t parentn = gdml->GetParent(node);
200  const char *parent = gdml->GetNodeName(parentn);
201  XMLNodePointer_t childtmp = 0;
202 
203  const char *posistr = "position";
204  const char *setustr = "setup";
205  const char *consstr = "constant";
206  const char *varistr = "variable";
207  const char *quanstr = "quantity";
208  const char *matrstr = "matrix";
209  const char *rotastr = "rotation";
210  const char *scalstr = "scale";
211  const char *elemstr = "element";
212  const char *istpstr = "isotope";
213  const char *matestr = "material";
214  const char *volustr = "volume";
215  const char *assestr = "assembly";
216  const char *twtrstr = "twistedtrap";
217  const char *cutTstr = "cutTube";
218  const char *bboxstr = "box";
219  const char *xtrustr = "xtru";
220  const char *arb8str = "arb8";
221  const char *tubestr = "tube";
222  const char *conestr = "cone";
223  const char *polystr = "polycone";
224  const char *hypestr = "hype";
225  const char *trapstr = "trap";
226  const char *trdstr = "trd";
227  const char *sphestr = "sphere";
228  const char *orbstr = "orb";
229  const char *parastr = "para";
230  const char *torustr = "torus";
231  const char *hedrstr = "polyhedra";
232  const char *eltustr = "eltube";
233  const char *subtstr = "subtraction";
234  const char *uniostr = "union";
235  const char *parbstr = "paraboloid";
236  const char *intestr = "intersection";
237  const char *reflstr = "reflectedSolid";
238  const char *ellistr = "ellipsoid";
239  const char *elcnstr = "elcone";
240  const char *optsstr = "opticalsurface";
241  const char *skinstr = "skinsurface";
242  const char *bordstr = "bordersurface";
243  const char *usrstr = "userinfo";
244  const char *tslstr = "tessellated";
245  Bool_t hasIsotopes;
246  Bool_t hasIsotopesExtended;
247 
248  if ((strcmp(name, posistr)) == 0) {
249  node = PosProcess(gdml, node, attr);
250  } else if ((strcmp(name, rotastr)) == 0) {
251  node = RotProcess(gdml, node, attr);
252  } else if ((strcmp(name, scalstr)) == 0) {
253  node = SclProcess(gdml, node, attr);
254  } else if ((strcmp(name, setustr)) == 0) {
255  node = TopProcess(gdml, node);
256  } else if ((strcmp(name, consstr)) == 0) {
257  node = ConProcess(gdml, node, attr);
258  } else if ((strcmp(name, varistr)) == 0) {
259  node = ConProcess(gdml, node, attr);
260  } else if ((strcmp(name, quanstr)) == 0) {
261  node = QuantityProcess(gdml, node, attr);
262  } else if ((strcmp(name, matrstr)) == 0) {
263  node = MatrixProcess(gdml, node, attr);
264  } else if ((strcmp(name, optsstr)) == 0) {
265  node = OpticalSurfaceProcess(gdml, node, attr);
266  } else if ((strcmp(name, skinstr)) == 0) {
267  node = SkinSurfaceProcess(gdml, node, attr);
268  } else if ((strcmp(name, bordstr)) == 0) {
269  node = BorderSurfaceProcess(gdml, node, attr);
270  }
271  //*************eleprocess********************************
272 
273  else if (((strcmp(name, "atom")) == 0) && ((strcmp(parent, elemstr)) == 0)) {
274  hasIsotopes = kFALSE;
275  hasIsotopesExtended = kFALSE;
276  node = EleProcess(gdml, node, parentn, hasIsotopes, hasIsotopesExtended);
277  } else if ((strcmp(name, elemstr) == 0) && !gdml->HasAttr(node, "Z")) {
278  hasIsotopes = kTRUE;
279  hasIsotopesExtended = kFALSE;
280  node = EleProcess(gdml, node, parentn, hasIsotopes, hasIsotopesExtended);
281  }
282 
283  else if ((strcmp(name, elemstr) == 0) && gdml->HasAttr(node, "Z")) {
284  childtmp = gdml->GetChild(node);
285  if ((strcmp(gdml->GetNodeName(childtmp), "fraction") == 0)) {
286  hasIsotopes = kFALSE;
287  hasIsotopesExtended = kTRUE;
288  node = EleProcess(gdml, node, parentn, hasIsotopes, hasIsotopesExtended);
289  }
290  }
291 
292  //********isoprocess******************************
293 
294  else if (((strcmp(name, "atom")) == 0) && ((strcmp(parent, istpstr)) == 0)) {
295  node = IsoProcess(gdml, node, parentn);
296  }
297 
298  //********matprocess***********************************
299  else if ((strcmp(name, matestr)) == 0 && gdml->HasAttr(node, "Z")) {
300  childtmp = gdml->GetChild(node);
301  // if ((strcmp(gdml->GetNodeName(childtmp), "fraction") == 0) || (strcmp(gdml->GetNodeName(childtmp), "D") ==
302  // 0)){
303  // Bool_t frac = kFALSE;
304  Bool_t atom = kFALSE;
305  while (childtmp) {
306  // frac = strcmp(gdml->GetNodeName(childtmp),"fraction")==0;
307  atom = strcmp(gdml->GetNodeName(childtmp), "atom") == 0;
308  gdml->ShiftToNext(childtmp);
309  }
310  int z = (atom) ? 1 : 0;
311  node = MatProcess(gdml, node, attr, z);
312  } else if ((strcmp(name, matestr)) == 0 && !gdml->HasAttr(node, "Z")) {
313  int z = 0;
314  node = MatProcess(gdml, node, attr, z);
315  }
316 
317  //*********************************************
318  else if ((strcmp(name, volustr)) == 0) {
319  node = VolProcess(gdml, node);
320  } else if ((strcmp(name, bboxstr)) == 0) {
321  node = Box(gdml, node, attr);
322  } else if ((strcmp(name, ellistr)) == 0) {
323  node = Ellipsoid(gdml, node, attr);
324  } else if ((strcmp(name, elcnstr)) == 0) {
325  node = ElCone(gdml, node, attr);
326  } else if ((strcmp(name, cutTstr)) == 0) {
327  node = CutTube(gdml, node, attr);
328  } else if ((strcmp(name, arb8str)) == 0) {
329  node = Arb8(gdml, node, attr);
330  } else if ((strcmp(name, tubestr)) == 0) {
331  node = Tube(gdml, node, attr);
332  } else if ((strcmp(name, conestr)) == 0) {
333  node = Cone(gdml, node, attr);
334  } else if ((strcmp(name, polystr)) == 0) {
335  node = Polycone(gdml, node, attr);
336  } else if ((strcmp(name, trapstr)) == 0) {
337  node = Trap(gdml, node, attr);
338  } else if ((strcmp(name, trdstr)) == 0) {
339  node = Trd(gdml, node, attr);
340  } else if ((strcmp(name, sphestr)) == 0) {
341  node = Sphere(gdml, node, attr);
342  } else if ((strcmp(name, xtrustr)) == 0) {
343  node = Xtru(gdml, node, attr);
344  } else if ((strcmp(name, twtrstr)) == 0) {
345  node = TwistTrap(gdml, node, attr);
346  } else if ((strcmp(name, hypestr)) == 0) {
347  node = Hype(gdml, node, attr);
348  } else if ((strcmp(name, orbstr)) == 0) {
349  node = Orb(gdml, node, attr);
350  } else if ((strcmp(name, parastr)) == 0) {
351  node = Para(gdml, node, attr);
352  } else if ((strcmp(name, torustr)) == 0) {
353  node = Torus(gdml, node, attr);
354  } else if ((strcmp(name, eltustr)) == 0) {
355  node = ElTube(gdml, node, attr);
356  } else if ((strcmp(name, hedrstr)) == 0) {
357  node = Polyhedra(gdml, node, attr);
358  } else if ((strcmp(name, tslstr)) == 0) {
359  node = Tessellated(gdml, node, attr);
360  } else if ((strcmp(name, parbstr)) == 0) {
361  node = Paraboloid(gdml, node, attr);
362  } else if ((strcmp(name, subtstr)) == 0) {
363  node = BooSolid(gdml, node, attr, 1);
364  } else if ((strcmp(name, intestr)) == 0) {
365  node = BooSolid(gdml, node, attr, 2);
366  } else if ((strcmp(name, uniostr)) == 0) {
367  node = BooSolid(gdml, node, attr, 3);
368  } else if ((strcmp(name, reflstr)) == 0) {
369  node = Reflection(gdml, node, attr);
370  } else if ((strcmp(name, assestr)) == 0) {
371  node = AssProcess(gdml, node);
372  } else if ((strcmp(name, usrstr)) == 0) {
373  node = UsrProcess(gdml, node);
374  // CHECK FOR TAGS NOT SUPPORTED
375  } else if (((strcmp(name, "gdml")) != 0) && ((strcmp(name, "define")) != 0) && ((strcmp(name, "element")) != 0) &&
376  ((strcmp(name, "materials")) != 0) && ((strcmp(name, "solids")) != 0) &&
377  ((strcmp(name, "structure")) != 0) && ((strcmp(name, "zplane")) != 0) && ((strcmp(name, "first")) != 0) &&
378  ((strcmp(name, "second")) != 0) && ((strcmp(name, "twoDimVertex")) != 0) &&
379  ((strcmp(name, "firstposition")) != 0) && ((strcmp(name, "firstpositionref")) != 0) &&
380  ((strcmp(name, "firstrotation")) != 0) && ((strcmp(name, "firstrotationref")) != 0) &&
381  ((strcmp(name, "section")) != 0) && ((strcmp(name, "world")) != 0) && ((strcmp(name, "isotope")) != 0) &&
382  ((strcmp(name, "triangular")) != 0) && ((strcmp(name, "quadrangular")) != 0)) {
383  std::cout << "Error: Unsupported GDML Tag Used :" << name << ". Please Check Geometry/Schema." << std::endl;
384  }
385 
386  // Check for Child node - if present call this funct. recursively until no more
387 
388  XMLNodePointer_t child = gdml->GetChild(node);
389  while (child != 0) {
390  ParseGDML(gdml, child);
391  child = gdml->GetNext(child);
392  }
393 
394  return fWorldName;
395 }
396 
397 ////////////////////////////////////////////////////////////////////////////////
398 /// Takes a string containing a mathematical expression and returns the value of
399 /// the expression
400 
401 double TGDMLParse::Evaluate(const char *evalline)
402 {
403 
404  return TFormula("TFormula", evalline).Eval(0);
405 }
406 
407 ////////////////////////////////////////////////////////////////////////////////
408 /// When using the 'divide' process in the geometry this function
409 /// sets the variable 'axis' depending on what is specified.
410 
411 Int_t TGDMLParse::SetAxis(const char *axisString)
412 {
413  Int_t axis = 0;
414 
415  if ((strcmp(axisString, "kXAxis")) == 0) {
416  axis = 1;
417  } else if ((strcmp(axisString, "kYAxis")) == 0) {
418  axis = 2;
419  } else if ((strcmp(axisString, "kZAxis")) == 0) {
420  axis = 3;
421  } else if ((strcmp(axisString, "kRho")) == 0) {
422  axis = 1;
423  } else if ((strcmp(axisString, "kPhi")) == 0) {
424  axis = 2;
425  }
426 
427  return axis;
428 }
429 
430 ////////////////////////////////////////////////////////////////////////////////
431 /// This function looks thru a string for the chars '0x' next to
432 /// each other, when it finds this, it calls another function to strip
433 /// the hex address. It does this recursively until the end of the
434 /// string is reached, returning a string without any hex addresses.
435 
436 const char *TGDMLParse::NameShort(const char *name)
437 {
438  static TString stripped;
439  stripped = name;
440  Int_t index = stripped.Index("0x");
441  if (index >= 0)
442  stripped = stripped(0, index);
443  return stripped.Data();
444 }
445 
446 ////////////////////////////////////////////////////////////////////////////////
447 /// In the define section of the GDML file, constants can be declared.
448 /// when the constant keyword is found, this function is called, and the
449 /// name and value of the constant is stored in the "fformvec" vector as
450 /// a TFormula class, representing a constant function
451 
453 {
454  TString name = "";
455  TString value = "";
456  TString tempattr;
457 
458  while (attr != 0) {
459  tempattr = gdml->GetAttrName(attr);
460  tempattr.ToLower();
461 
462  if (tempattr == "name") {
463  name = gdml->GetAttrValue(attr);
464  }
465  if (tempattr == "value") {
466  value = gdml->GetAttrValue(attr);
467  }
468  attr = gdml->GetNextAttr(attr);
469  }
470 
471  // if ((strcmp(fCurrentFile, fStartFile)) != 0) {
472  // name = TString::Format("%s_%s", name.Data(), fCurrentFile);
473  //}
474 
475  Double_t val = Value(value);
476  fconsts[name.Data()] = val;
477  gGeoManager->AddProperty(name.Data(), val);
478 
479  return node;
480 }
481 
482 ////////////////////////////////////////////////////////////////////////////////
483 /// Define constant expressions used.
485 {
486  // Units used in TGeo. Note that they are based on cm/degree/GeV and they are different from Geant4
487  fconsts["mm"] = TGeoUnit::mm;
488  fconsts["millimeter"] = TGeoUnit::mm;
489  fconsts["cm"] = TGeoUnit::cm;
490  fconsts["centimeter"] = TGeoUnit::cm;
491  fconsts["m"] = TGeoUnit::m;
492  fconsts["meter"] = TGeoUnit::m;
493  fconsts["km"] = TGeoUnit::km;
494  fconsts["kilometer"] = TGeoUnit::km;
495  fconsts["rad"] = TGeoUnit::rad;
496  fconsts["radian"] = TGeoUnit::rad;
497  fconsts["deg"] = TGeoUnit::deg;
498  fconsts["degree"] = TGeoUnit::deg;
499  fconsts["pi"] = TGeoUnit::pi;
500  fconsts["twopi"] = TGeoUnit::twopi;
501  fconsts["avogadro"] = TMath::Na();
502  fconsts["gev"] = TGeoUnit::GeV;
503  fconsts["GeV"] = TGeoUnit::GeV;
504  fconsts["mev"] = TGeoUnit::MeV;
505  fconsts["MeV"] = TGeoUnit::MeV;
506  fconsts["kev"] = TGeoUnit::keV;
507  fconsts["keV"] = TGeoUnit::keV;
508  fconsts["ev"] = TGeoUnit::eV;
509  fconsts["eV"] = TGeoUnit::eV;
510  fconsts["s"] = TGeoUnit::s;
511  fconsts["ms"] = TGeoUnit::ms;
512  fconsts["ns"] = TGeoUnit::ns;
513  fconsts["us"] = TGeoUnit::us;
514  fconsts["kg"] = TGeoUnit::kg;
515  fconsts["g"] = TGeoUnit::g;
516  fconsts["mg"] = TGeoUnit::mg;
517 }
518 
519 ////////////////////////////////////////////////////////////////////////////////
520 /// In the define section of the GDML file, quantities can be declared.
521 /// These are treated the same as constants, but the unit has to be multiplied
522 
524 {
525  TString name = "";
526  TString value = "";
527  TString unit = "1.0";
528  TString tempattr;
529 
530  while (attr != 0) {
531  tempattr = gdml->GetAttrName(attr);
532  tempattr.ToLower();
533 
534  if (tempattr == "name") {
535  name = gdml->GetAttrValue(attr);
536  }
537  if (tempattr == "value") {
538  value = gdml->GetAttrValue(attr);
539  }
540  if (tempattr == "unit") {
541  unit = gdml->GetAttrValue(attr);
542  }
543  attr = gdml->GetNextAttr(attr);
544  }
545 
546  fconsts[name.Data()] = GetScaleVal(unit) * Value(value);
547 
548  return node;
549 }
550 
551 ////////////////////////////////////////////////////////////////////////////////
552 /// In the define section of the GDML file, matrices
553 /// These are referenced by other GDML tags, such as optical surfaces
555 {
556  TString name = "";
557  Int_t coldim = 1;
558  std::string values;
559  TString tempattr;
560 
561  while (attr != 0) {
562  tempattr = gdml->GetAttrName(attr);
563  tempattr.ToLower();
564 
565  if (tempattr == "name") {
566  name = gdml->GetAttrValue(attr);
567  }
568  if (tempattr == "coldim") {
569  coldim = (Int_t)Value(gdml->GetAttrValue(attr));
570  }
571  if (tempattr == "values") {
572  values = gdml->GetAttrValue(attr);
573  }
574  attr = gdml->GetNextAttr(attr);
575  }
576 
577  // Parse the values and create the matrix
578  std::stringstream valueStream(values);
579  std::vector<Double_t> valueList;
580  while (!valueStream.eof()) {
581  std::string matrixValue;
582  valueStream >> matrixValue;
583  // protect against trailing '\n' and other white spaces
584  if (matrixValue.empty())
585  continue;
586  valueList.push_back(Value(matrixValue.c_str()));
587  }
588 
589  TGDMLMatrix *matrix = new TGDMLMatrix(name, valueList.size() / coldim, coldim);
590  matrix->SetMatrixAsString(values.c_str());
591  for (size_t i = 0; i < valueList.size(); ++i)
592  matrix->Set(i / coldim, i % coldim, valueList[i]);
593 
594  gGeoManager->AddGDMLMatrix(matrix);
595  fmatrices[name.Data()] = matrix;
596 
597  return node;
598 }
599 
600 ////////////////////////////////////////////////////////////////////////////////
601 /// In the solids section of the GDML file, optical surfaces can be defined
602 ///
604 {
605  TString name, propname, ref;
609  Double_t value = 0;
610  TString tempattr;
611 
612  while (attr != 0) {
613  tempattr = gdml->GetAttrName(attr);
614  tempattr.ToLower();
615 
616  if (tempattr == "name") {
617  name = gdml->GetAttrValue(attr);
618  }
619  if (tempattr == "model") {
620  model = TGeoOpticalSurface::StringToModel(gdml->GetAttrValue(attr));
621  }
622  if (tempattr == "finish") {
623  finish = TGeoOpticalSurface::StringToFinish(gdml->GetAttrValue(attr));
624  }
625  if (tempattr == "type") {
627  }
628  if (tempattr == "value") {
629  value = Value(gdml->GetAttrValue(attr));
630  }
631  attr = gdml->GetNextAttr(attr);
632  }
633 
634  TGeoOpticalSurface *surf = new TGeoOpticalSurface(name, model, finish, type, value);
635 
636  XMLNodePointer_t child = gdml->GetChild(node);
637  while (child != 0) {
638  attr = gdml->GetFirstAttr(child);
639  if ((strcmp(gdml->GetNodeName(child), "property")) == 0) {
640  while (attr != 0) {
641  tempattr = gdml->GetAttrName(attr);
642  tempattr.ToLower();
643  if (tempattr == "name") {
644  propname = gdml->GetAttrValue(attr);
645  } else if (tempattr == "ref") {
646  ref = gdml->GetAttrValue(attr);
647  TGDMLMatrix *matrix = fmatrices[ref.Data()];
648  if (!matrix)
649  Error("OpticalSurfaceProcess", "Reference matrix %s for optical surface %s not found", ref.Data(),
650  name.Data());
651  surf->AddProperty(propname, ref);
652  }
653  attr = gdml->GetNextAttr(attr);
654  }
655  } // loop on child attributes
656  child = gdml->GetNext(child);
657  } // loop on children
659  return child;
660 }
661 
662 ////////////////////////////////////////////////////////////////////////////////
663 /// Throughout the GDML file, a unit can de specified. Whether it be
664 /// angular or linear, values can be used as well as abbreviations such as
665 /// 'mm' or 'deg'. This function is passed the specified unit and if it is
666 /// found, replaces it with the appropriate value.
667 
668 TString TGDMLParse::GetScale(const char *unit)
669 {
670  TString retunit = "";
671 
672  if (strcmp(unit, "mm") == 0) {
673  retunit = "0.1";
674  } else if (strcmp(unit, "milimeter") == 0) {
675  retunit = "0.1";
676  } else if (strcmp(unit, "cm") == 0) {
677  retunit = "1.0";
678  } else if (strcmp(unit, "centimeter") == 0) {
679  retunit = "1.0";
680  } else if (strcmp(unit, "m") == 0) {
681  retunit = "100.0";
682  } else if (strcmp(unit, "meter") == 0) {
683  retunit = "100.0";
684  } else if (strcmp(unit, "km") == 0) {
685  retunit = "100000.0";
686  } else if (strcmp(unit, "kilometer") == 0) {
687  retunit = "100000.0";
688  } else if (strcmp(unit, "rad") == 0) {
689  retunit = TString::Format("%.12f", TMath::RadToDeg());
690  } else if (strcmp(unit, "radian") == 0) {
691  retunit = TString::Format("%.12f", TMath::RadToDeg());
692  } else if (strcmp(unit, "deg") == 0) {
693  retunit = "1.0";
694  } else if (strcmp(unit, "degree") == 0) {
695  retunit = "1.0";
696  } else if (strcmp(unit, "pi") == 0) {
697  retunit = "pi";
698  } else if (strcmp(unit, "avogadro") == 0) {
699  retunit = TString::Format("%.12g", TMath::Na());
700  } else {
701  Fatal("GetScale", "Unit <%s> not known", unit);
702  retunit = "0";
703  }
704  return retunit;
705 }
706 
707 ////////////////////////////////////////////////////////////////////////////////
708 /// Throughout the GDML file, a unit can de specified. Whether it be
709 /// angular or linear, values can be used as well as abbreviations such as
710 /// 'mm' or 'deg'. This function is passed the specified unit and if it is
711 /// found, replaces it with the appropriate value.
712 
714 {
715  Double_t retunit = 0.;
716  TString unit(sunit);
717  unit.ToLower();
718 
719  if ((unit == "mm") || (unit == "milimeter")) {
720  retunit = 0.1;
721  } else if ((unit == "cm") || (unit == "centimeter")) {
722  retunit = 1.0;
723  } else if ((unit == "m") || (unit == "meter")) {
724  retunit = 100.0;
725  } else if ((unit == "km") || (unit == "kilometer")) {
726  retunit = 100000.0;
727  } else if ((unit == "rad") || (unit == "radian")) {
728  retunit = TMath::RadToDeg();
729  } else if ((unit == "deg") || (unit == "degree")) {
730  retunit = 1.0;
731  } else if ((unit == "ev") || (unit == "electronvolt")) {
732  retunit = 0.000000001;
733  } else if ((unit == "kev") || (unit == "kiloelectronvolt")) {
734  retunit = 0.000001;
735  } else if ((unit == "mev") || (unit == "megaelectronvolt")) {
736  retunit = 0.001;
737  } else if ((unit == "gev") || (unit == "gigaelectronvolt")) {
738  retunit = 1;
739  } else if (unit == "pi") {
740  retunit = TMath::Pi();
741  } else if (unit == "avogadro") {
742  retunit = TMath::Na();
743  } else {
744  Fatal("GetScaleVal", "Unit <%s> not known", sunit);
745  retunit = 0;
746  }
747  return retunit;
748 }
749 
750 ////////////////////////////////////////////////////////////////////////////////
751 /// Convert number in string format to double value.
752 
753 Double_t TGDMLParse::Value(const char *svalue) const
754 {
755  char *end;
756  double val = strtod(svalue, &end);
757 
758  // ignore white spaces.
759  while (*end != 0 && isspace(*end))
760  ++end;
761 
762  // Successfully parsed all the characters up to the ending NULL, so svalue
763  // was a simple number.
764  if (*end == 0)
765  return val;
766 
767  // Otherwise we'll use TFormula to evaluate the string, having first found
768  // all the GDML variable names in it and marked them with [] so that
769  // TFormula will recognize them as parameters.
770 
771  std::string expanded;
772  expanded.reserve(strlen(svalue) * 2);
773 
774  // Be careful about locale so we always mean the same thing by
775  // "alphanumeric"
776  const std::locale &loc = std::locale::classic(); // "C" locale
777 
778  // Walk through the string inserting '[' and ']' where necessary
779  const char *p = svalue;
780  while (*p) {
781  // Find a site for a '['. Just before the first alphabetic character
782  for (; *p != 0; ++p) {
783  if (std::isalpha(*p, loc) || *p == '_') {
784  const char *pe = p + 1;
785  // Now look for the position of the following ']'. Straight before the
786  // first non-alphanumeric character
787  for (; *pe != 0; ++pe) {
788  if (!isalnum(*pe, loc) && *pe != '_') {
789  if (*pe == '(') {
790  // The string represents a function, so no brackets needed: copy chars and advance
791  for (; p < pe; ++p)
792  expanded += *p;
793  break;
794  } else {
795  expanded += '[';
796  for (; p < pe; ++p)
797  expanded += *p;
798  expanded += ']';
799  break;
800  }
801  }
802  }
803  if (*pe == 0) {
804  expanded += '[';
805  for (; p < pe; ++p)
806  expanded += *p;
807  expanded += ']';
808  }
809  }
810  expanded += *p;
811  }
812  } // end loop over svalue
813 
814  TFormula f("TFormula", expanded.c_str());
815 
816  // Tell the TFormula about every parameter we know about
817  for (auto it : fconsts)
818  f.SetParameter(it.first.c_str(), it.second);
819 
820  val = f.Eval(0);
821 
822  if (std::isnan(val) || std::isinf(val)) {
823  Fatal("Value", "Got bad value %lf from string '%s'", val, svalue);
824  }
825 
826  return val;
827 }
828 
829 ////////////////////////////////////////////////////////////////////////////////
830 /// In the define section of the GDML file, positions can be declared.
831 /// when the position keyword is found, this function is called, and the
832 /// name and values of the position are converted into type TGeoPosition
833 /// and stored in fposmap map using the name as its key. This function
834 /// can also be called when declaring solids.
835 
837 {
838  TString lunit = fDefault_lunit.c_str();
839  TString xpos = "0";
840  TString ypos = "0";
841  TString zpos = "0";
842  TString name = "0";
843  TString tempattr;
844 
845  while (attr != 0) {
846 
847  tempattr = gdml->GetAttrName(attr);
848  tempattr.ToLower();
849 
850  if (tempattr == "name") {
851  name = gdml->GetAttrValue(attr);
852  } else if (tempattr == "x") {
853  xpos = gdml->GetAttrValue(attr);
854  } else if (tempattr == "y") {
855  ypos = gdml->GetAttrValue(attr);
856  } else if (tempattr == "z") {
857  zpos = gdml->GetAttrValue(attr);
858  } else if (tempattr == "unit") {
859  lunit = gdml->GetAttrValue(attr);
860  }
861 
862  attr = gdml->GetNextAttr(attr);
863  }
864 
865  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
866  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
867  }
868 
869  Double_t retunit = GetScaleVal(lunit);
870  Double_t xline = Value(xpos) * retunit;
871  Double_t yline = Value(ypos) * retunit;
872  Double_t zline = Value(zpos) * retunit;
873 
874  TGeoTranslation *pos = new TGeoTranslation(xline, yline, zline);
875 
876  fposmap[name.Data()] = pos;
877 
878  return node;
879 }
880 
881 ////////////////////////////////////////////////////////////////////////////////
882 /// In the define section of the GDML file, rotations can be declared.
883 /// when the rotation keyword is found, this function is called, and the
884 /// name and values of the rotation are converted into type TGeoRotation
885 /// and stored in frotmap map using the name as its key. This function
886 /// can also be called when declaring solids.
887 
889 {
890  TString aunit = fDefault_aunit.c_str();
891  TString xpos = "0";
892  TString ypos = "0";
893  TString zpos = "0";
894  TString name = "";
895  TString tempattr;
896 
897  while (attr != 0) {
898 
899  tempattr = gdml->GetAttrName(attr);
900  tempattr.ToLower();
901 
902  if (tempattr == "name") {
903  name = gdml->GetAttrValue(attr);
904  } else if (tempattr == "x") {
905  xpos = gdml->GetAttrValue(attr);
906  } else if (tempattr == "y") {
907  ypos = gdml->GetAttrValue(attr);
908  } else if (tempattr == "z") {
909  zpos = gdml->GetAttrValue(attr);
910  } else if (tempattr == "unit") {
911  aunit = gdml->GetAttrValue(attr);
912  }
913 
914  attr = gdml->GetNextAttr(attr);
915  }
916 
917  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
918  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
919  }
920 
921  Double_t retunit = GetScaleVal(aunit);
922 
923  Double_t xline = Value(xpos) * retunit;
924  Double_t yline = Value(ypos) * retunit;
925  Double_t zline = Value(zpos) * retunit;
926 
927  TGeoRotation *rot = new TGeoRotation();
928 
929  rot->RotateZ(-zline);
930  rot->RotateY(-yline);
931  rot->RotateX(-xline);
932 
933  frotmap[name.Data()] = rot;
934 
935  return node;
936 }
937 
938 ////////////////////////////////////////////////////////////////////////////////
939 /// In the define section of the GDML file, rotations can be declared.
940 /// when the scale keyword is found, this function is called, and the
941 /// name and values of the scale are converted into type TGeoScale
942 /// and stored in fsclmap map using the name as its key. This function
943 /// can also be called when declaring solids.
944 
946 {
947  TString xpos = "0";
948  TString ypos = "0";
949  TString zpos = "0";
950  TString name = "";
951  TString tempattr;
952 
953  while (attr != 0) {
954 
955  tempattr = gdml->GetAttrName(attr);
956  tempattr.ToLower();
957 
958  if (tempattr == "name") {
959  name = gdml->GetAttrValue(attr);
960  } else if (tempattr == "x") {
961  xpos = gdml->GetAttrValue(attr);
962  } else if (tempattr == "y") {
963  ypos = gdml->GetAttrValue(attr);
964  } else if (tempattr == "z") {
965  zpos = gdml->GetAttrValue(attr);
966  }
967 
968  attr = gdml->GetNextAttr(attr);
969  }
970 
971  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
972  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
973  }
974 
975  TGeoScale *scl = new TGeoScale(Value(xpos), Value(ypos), Value(zpos));
976 
977  fsclmap[name.Data()] = scl;
978 
979  return node;
980 }
981 
982 ////////////////////////////////////////////////////////////////////////////////
983 /// In the material section of the GDML file, an isotope may be declared.
984 /// when the isotope keyword is found, this function is called, and the
985 /// required parameters are taken and stored, these are then bound and
986 /// converted to type TGeoIsotope and stored in fisomap map using the name
987 /// as its key.
988 
990 {
991  TString z = "0";
992  TString name = "";
993  TString n = "0";
994  TString atom = "0";
995  TString tempattr;
996 
997  // obtain attributes for the element
998 
999  XMLAttrPointer_t attr = gdml->GetFirstAttr(parentn);
1000 
1001  while (attr != 0) {
1002 
1003  tempattr = gdml->GetAttrName(attr);
1004  tempattr.ToLower();
1005 
1006  if (tempattr == "name") {
1007  name = gdml->GetAttrValue(attr);
1008  } else if (tempattr == "z") {
1009  z = gdml->GetAttrValue(attr);
1010  } else if (tempattr == "n") {
1011  n = gdml->GetAttrValue(attr);
1012  }
1013 
1014  attr = gdml->GetNextAttr(attr);
1015  }
1016 
1017  // get the atom value for the element
1018 
1019  attr = gdml->GetFirstAttr(node);
1020 
1021  while (attr != 0) {
1022 
1023  tempattr = gdml->GetAttrName(attr);
1024 
1025  if (tempattr == "value") {
1026  atom = gdml->GetAttrValue(attr);
1027  }
1028 
1029  attr = gdml->GetNextAttr(attr);
1030  }
1031 
1032  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1033  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
1034  }
1035 
1036  Int_t z2 = (Int_t)Value(z);
1037  Int_t n2 = (Int_t)Value(n);
1038  Double_t atom2 = Value(atom);
1039 
1040  TGeoManager *mgr = gGeoManager;
1041  TString iso_name = NameShort(name);
1042  TGeoElementTable *tab = mgr->GetElementTable();
1043  TGeoIsotope *iso = tab->FindIsotope(iso_name);
1044  if (!iso) {
1045  iso = new TGeoIsotope(iso_name, z2, n2, atom2);
1046  } else if (gDebug >= 2) {
1047  Info("TGDMLParse", "Re-use existing isotope: %s", iso->GetName());
1048  }
1049  fisomap[name.Data()] = iso;
1050 
1051  return node;
1052 }
1053 
1054 ////////////////////////////////////////////////////////////////////////////////
1055 /// When the element keyword is found, this function is called, and the
1056 /// name and values of the element are converted into type TGeoElement and
1057 /// stored in felemap map using the name as its key.
1058 
1060  Bool_t hasIsotopes, Bool_t hasIsotopesExtended)
1061 
1062 {
1063  TString z = "0";
1064  TString name = "";
1065  TString formula = "";
1066  TString atom = "0";
1067  TString tempattr;
1068  Int_t ncompo = 0;
1069  TGeoManager *mgr = gGeoManager;
1070  TGeoElementTable *tab = mgr->GetElementTable();
1071  typedef FracMap::iterator fractions;
1072  FracMap fracmap;
1073 
1074  XMLNodePointer_t child = 0;
1075 
1076  // obtain attributes for the element
1077 
1078  XMLAttrPointer_t attr = gdml->GetFirstAttr(node);
1079 
1080  if (hasIsotopes) {
1081 
1082  // Get the name of the element
1083  while (attr != 0) {
1084  tempattr = gdml->GetAttrName(attr);
1085  if (tempattr == "name") {
1086  name = gdml->GetAttrValue(attr);
1087 
1088  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1089  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
1090  }
1091  break;
1092  }
1093  attr = gdml->GetNextAttr(attr);
1094  }
1095  // Get component isotopes. Loop all children.
1096  child = gdml->GetChild(node);
1097  while (child != 0) {
1098 
1099  // Check for fraction node name
1100  if ((strcmp(gdml->GetNodeName(child), "fraction")) == 0) {
1101  Double_t n = 0;
1102  TString ref = "";
1103  ncompo = ncompo + 1;
1104  attr = gdml->GetFirstAttr(child);
1105  while (attr != 0) {
1106  tempattr = gdml->GetAttrName(attr);
1107  tempattr.ToLower();
1108  if (tempattr == "n") {
1109  n = Value(gdml->GetAttrValue(attr));
1110  } else if (tempattr == "ref") {
1111  ref = gdml->GetAttrValue(attr);
1112  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1113  ref = TString::Format("%s_%s", ref.Data(), fCurrentFile);
1114  }
1115  }
1116  attr = gdml->GetNextAttr(attr);
1117  } // loop on child attributes
1118  fracmap[ref.Data()] = n;
1119  }
1120  child = gdml->GetNext(child);
1121  } // loop on children
1122  // Create TGeoElement - note: Object(name, title) corresponds to Element(formula, name)
1123  TGeoElement *ele = tab->FindElement(NameShort(name));
1124  // We cannot use elements with Z = 0, so we expect a user definition
1125  if (ele && ele->Z() == 0)
1126  ele = nullptr;
1127  if (!ele) {
1128  ele = new TGeoElement(NameShort(name), NameShort(name), ncompo);
1129  for (fractions f = fracmap.begin(); f != fracmap.end(); ++f) {
1130  if (fisomap.find(f->first) != fisomap.end()) {
1131  ele->AddIsotope((TGeoIsotope *)fisomap[f->first], f->second);
1132  }
1133  }
1134  } else if (gDebug >= 2) {
1135  Info("TGDMLParse", "Re-use existing element: %s", ele->GetName());
1136  }
1137  felemap[name.Data()] = ele;
1138  return child;
1139  } // hasisotopes end loop
1140 
1141  //*************************
1142 
1143  if (hasIsotopesExtended) {
1144 
1145  while (attr != 0) {
1146  tempattr = gdml->GetAttrName(attr);
1147 
1148  if (tempattr == "name") {
1149  name = gdml->GetAttrValue(attr);
1150 
1151  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1152  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
1153  }
1154  break;
1155  }
1156  attr = gdml->GetNextAttr(attr);
1157  }
1158  // Get component isotopes. Loop all children.
1159  child = gdml->GetChild(node);
1160  while (child != 0) {
1161 
1162  // Check for fraction node name
1163  if ((strcmp(gdml->GetNodeName(child), "fraction")) == 0) {
1164  Double_t n = 0;
1165  TString ref = "";
1166  ncompo = ncompo + 1;
1167  attr = gdml->GetFirstAttr(child);
1168  while (attr != 0) {
1169  tempattr = gdml->GetAttrName(attr);
1170  tempattr.ToLower();
1171  if (tempattr == "n") {
1172  n = Value(gdml->GetAttrValue(attr));
1173  } else if (tempattr == "ref") {
1174  ref = gdml->GetAttrValue(attr);
1175  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1176  ref = TString::Format("%s_%s", ref.Data(), fCurrentFile);
1177  }
1178  }
1179  attr = gdml->GetNextAttr(attr);
1180  } // loop on child attributes
1181  fracmap[ref.Data()] = n;
1182  }
1183  child = gdml->GetNext(child);
1184  } // loop on children
1185  // Create TGeoElement - note: Object(name, title) corresponds to Element(formula, name)
1186  TGeoElement *ele = tab->FindElement(NameShort(name));
1187  // We cannot use elements with Z = 0, so we expect a user definition
1188  if (ele && ele->Z() == 0)
1189  ele = nullptr;
1190  if (!ele) {
1191  ele = new TGeoElement(NameShort(name), NameShort(name), ncompo);
1192  for (fractions f = fracmap.begin(); f != fracmap.end(); ++f) {
1193  if (fisomap.find(f->first) != fisomap.end()) {
1194  ele->AddIsotope((TGeoIsotope *)fisomap[f->first], f->second);
1195  }
1196  }
1197  } else if (gDebug >= 2) {
1198  Info("TGDMLParse", "Re-use existing element: %s", ele->GetName());
1199  }
1200  felemap[name.Data()] = ele;
1201  return child;
1202  } // hasisotopesExtended end loop
1203 
1204  //***************************
1205 
1206  attr = gdml->GetFirstAttr(parentn);
1207  while (attr != 0) {
1208 
1209  tempattr = gdml->GetAttrName(attr);
1210  tempattr.ToLower();
1211 
1212  if (tempattr == "name") {
1213  name = gdml->GetAttrValue(attr);
1214 
1215  } else if (tempattr == "z") {
1216  z = gdml->GetAttrValue(attr);
1217  } else if (tempattr == "formula") {
1218  formula = gdml->GetAttrValue(attr);
1219  }
1220 
1221  attr = gdml->GetNextAttr(attr);
1222  }
1223 
1224  // get the atom value for the element
1225 
1226  attr = gdml->GetFirstAttr(node);
1227 
1228  while (attr != 0) {
1229 
1230  tempattr = gdml->GetAttrName(attr);
1231  tempattr.ToLower();
1232 
1233  if (tempattr == "value") {
1234  atom = gdml->GetAttrValue(attr);
1235  }
1236 
1237  attr = gdml->GetNextAttr(attr);
1238  }
1239 
1240  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1241  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
1242  }
1243 
1244  Int_t z2 = (Int_t)Value(z);
1245  Double_t atom2 = Value(atom);
1246  TGeoElement *ele = tab->FindElement(formula);
1247  // We cannot use elements with Z = 0, so we expect a user definition
1248  if (ele && ele->Z() == 0)
1249  ele = nullptr;
1250 
1251  if (!ele) {
1252  ele = new TGeoElement(formula, NameShort(name), z2, atom2);
1253  } else if (gDebug >= 2) {
1254  Info("TGDMLParse", "Re-use existing element: %s", ele->GetName());
1255  }
1256  felemap[name.Data()] = ele;
1257  return node;
1258 }
1259 
1260 ////////////////////////////////////////////////////////////////////////////////
1261 /// In the materials section of the GDML file, materials can be declared.
1262 /// when the material keyword is found, this function is called, and the
1263 /// name and values of the material are converted into type TGeoMaterial
1264 /// and stored in fmatmap map using the name as its key. Mixtures can also
1265 /// be declared, and they are converted to TGeoMixture and stored in
1266 /// fmixmap. These mixtures and materials are then all converted into one
1267 /// common type - TGeoMedium. The map fmedmap is then built up of all the
1268 /// mixtures and materials.
1269 
1271 {
1272  //! Map to hold fractions while being processed
1273  typedef FracMap::iterator fractions;
1274  // typedef FracMap::iterator i;
1275  FracMap fracmap;
1276 
1277  TGeoManager *mgr = gGeoManager;
1278  TGeoElementTable *tab_ele = mgr->GetElementTable();
1279  TList properties, constproperties;
1280  properties.SetOwner();
1281  constproperties.SetOwner();
1282  // We have to assume the media are monotonic increasing starting with 1
1283  static int medid = mgr->GetListOfMedia()->GetSize() + 1;
1284  XMLNodePointer_t child = gdml->GetChild(node);
1285  TString tempattr = "";
1286  Int_t ncompo = 0, mixflag = 2;
1287  Double_t density = 0;
1288  TString name = "";
1289  TGeoMixture *mix = 0;
1290  TGeoMaterial *mat = 0;
1291  TString tempconst = "";
1292  TString matname;
1293  Bool_t composite = kFALSE;
1294 
1295  if (z == 1) {
1296  Double_t a = 0;
1297  Double_t d = 0;
1298 
1299  name = gdml->GetAttr(node, "name");
1300  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1301  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
1302  }
1303 
1304  while (child != 0) {
1305  attr = gdml->GetFirstAttr(child);
1306 
1307  if ((strcmp(gdml->GetNodeName(child), "property")) == 0) {
1308  TNamed *property = new TNamed();
1309  while (attr != 0) {
1310  tempattr = gdml->GetAttrName(attr);
1311  tempattr.ToLower();
1312 
1313  if (tempattr == "name") {
1314  property->SetName(gdml->GetAttrValue(attr));
1315  } else if (tempattr == "ref") {
1316  property->SetTitle(gdml->GetAttrValue(attr));
1317  TGDMLMatrix *matrix = fmatrices[property->GetTitle()];
1318  if (matrix)
1319  properties.Add(property);
1320  else {
1321  Bool_t error = 0;
1322  gGeoManager->GetProperty(property->GetTitle(), &error);
1323  if (error)
1324  Error("MatProcess", "Reference %s for material %s not found", property->GetTitle(),
1325  name.Data());
1326  else
1327  constproperties.Add(property);
1328  }
1329  }
1330  attr = gdml->GetNextAttr(attr);
1331  }
1332  }
1333 
1334  if ((strcmp(gdml->GetNodeName(child), "atom")) == 0) {
1335  while (attr != 0) {
1336  tempattr = gdml->GetAttrName(attr);
1337  tempattr.ToLower();
1338 
1339  if (tempattr == "value") {
1340  a = Value(gdml->GetAttrValue(attr));
1341  }
1342  attr = gdml->GetNextAttr(attr);
1343  }
1344  }
1345 
1346  if ((strcmp(gdml->GetNodeName(child), "D")) == 0) {
1347  while (attr != 0) {
1348  tempattr = gdml->GetAttrName(attr);
1349  tempattr.ToLower();
1350 
1351  if (tempattr == "value") {
1352  d = Value(gdml->GetAttrValue(attr));
1353  }
1354  attr = gdml->GetNextAttr(attr);
1355  }
1356  }
1357  child = gdml->GetNext(child);
1358  }
1359  // still in the is Z else...but not in the while..
1360  // CHECK FOR CONSTANTS
1361  tempconst = gdml->GetAttr(node, "Z");
1362 
1363  Double_t valZ = Value(tempconst);
1364 
1365  TString tmpname = name;
1366  // deal with special case - Z of vacuum is always 0
1367  tmpname.ToLower();
1368  if (tmpname == "vacuum") {
1369  valZ = 0;
1370  }
1371  TString mat_name = NameShort(name);
1372  mat = mgr->GetMaterial(mat_name);
1373  if (!mat) {
1374  mat = new TGeoMaterial(mat_name, a, valZ, d);
1375  } else {
1376  Info("TGDMLParse", "Re-use existing material: %s", mat->GetName());
1377  }
1378  if (properties.GetSize()) {
1379  TNamed *property;
1380  TIter next(&properties);
1381  while ((property = (TNamed *)next()))
1382  mat->AddProperty(property->GetName(), property->GetTitle());
1383  }
1384  if (constproperties.GetSize()) {
1385  TNamed *property;
1386  TIter next(&constproperties);
1387  while ((property = (TNamed *)next()))
1388  mat->AddConstProperty(property->GetName(), property->GetTitle());
1389  }
1390  mixflag = 0;
1391  // Note: Object(name, title) corresponds to Element(formula, name)
1392  TGeoElement *mat_ele = tab_ele->FindElement(mat_name);
1393  // We cannot use elements with Z = 0, so we expect a user definition
1394  if (mat_ele && mat_ele->Z() == 0)
1395  mat_ele = nullptr;
1396 
1397  if (!mat_ele) {
1398  mat_ele = new TGeoElement(mat_name, mat_name, atoi(tempconst), a);
1399  } else if (gDebug >= 2) {
1400  Info("TGDMLParse", "Re-use existing material-element: %s", mat_ele->GetName());
1401  }
1402  felemap[name.Data()] = mat_ele;
1403  }
1404 
1405  else if (z == 0) {
1406  while (child != 0) {
1407  attr = gdml->GetFirstAttr(child);
1408 
1409  if ((strcmp(gdml->GetNodeName(child), "property")) == 0) {
1410  TNamed *property = new TNamed();
1411  while (attr != 0) {
1412  tempattr = gdml->GetAttrName(attr);
1413  tempattr.ToLower();
1414 
1415  if (tempattr == "name") {
1416  property->SetName(gdml->GetAttrValue(attr));
1417  } else if (tempattr == "ref") {
1418  property->SetTitle(gdml->GetAttrValue(attr));
1419  TGDMLMatrix *matrix = fmatrices[property->GetTitle()];
1420  if (matrix)
1421  properties.Add(property);
1422  else {
1423  Bool_t error = 0;
1424  gGeoManager->GetProperty(property->GetTitle(), &error);
1425  if (error)
1426  Error("MatProcess", "Reference %s for material %s not found", property->GetTitle(),
1427  name.Data());
1428  else
1429  constproperties.Add(property);
1430  }
1431  }
1432  attr = gdml->GetNextAttr(attr);
1433  }
1434  }
1435  if ((strcmp(gdml->GetNodeName(child), "fraction")) == 0) {
1436  Double_t n = 0;
1437  TString ref = "";
1438  ncompo = ncompo + 1;
1439 
1440  while (attr != 0) {
1441  tempattr = gdml->GetAttrName(attr);
1442  tempattr.ToLower();
1443 
1444  if (tempattr == "n") {
1445  n = Value(gdml->GetAttrValue(attr));
1446  } else if (tempattr == "ref") {
1447  ref = gdml->GetAttrValue(attr);
1448  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1449  ref = TString::Format("%s_%s", ref.Data(), fCurrentFile);
1450  }
1451  }
1452  attr = gdml->GetNextAttr(attr);
1453  }
1454  fracmap[ref.Data()] = n;
1455  }
1456 
1457  else if ((strcmp(gdml->GetNodeName(child), "composite")) == 0) {
1458  composite = kTRUE;
1459  Double_t n = 0;
1460  TString ref = "";
1461  ncompo = ncompo + 1;
1462 
1463  while (attr != 0) {
1464  tempattr = gdml->GetAttrName(attr);
1465  tempattr.ToLower();
1466  if (tempattr == "n") {
1467  n = Value(gdml->GetAttrValue(attr));
1468  } else if (tempattr == "ref") {
1469  ref = gdml->GetAttrValue(attr);
1470  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1471  ref = TString::Format("%s_%s", ref.Data(), fCurrentFile);
1472  }
1473  }
1474  attr = gdml->GetNextAttr(attr);
1475  }
1476  fracmap[ref.Data()] = n;
1477  } else if ((strcmp(gdml->GetNodeName(child), "D")) == 0) {
1478  while (attr != 0) {
1479  tempattr = gdml->GetAttrName(attr);
1480  tempattr.ToLower();
1481 
1482  if (tempattr == "value") {
1483  density = Value(gdml->GetAttrValue(attr));
1484  }
1485  attr = gdml->GetNextAttr(attr);
1486  }
1487  }
1488  child = gdml->GetNext(child);
1489  }
1490  // still in the not Z else...but not in the while..
1491 
1492  name = gdml->GetAttr(node, "name");
1493  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1494  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
1495  }
1496  // mix = new TGeoMixture(NameShort(name), 0 /*ncompo*/, density);
1497  mixflag = 1;
1498  TString mat_name = NameShort(name);
1499  mat = mgr->GetMaterial(mat_name);
1500  if (!mat) {
1501  mix = new TGeoMixture(mat_name, ncompo, density);
1502  } else if (mat->IsMixture()) {
1503  mix = (TGeoMixture *)mat;
1504  if (gDebug >= 2)
1505  Info("TGDMLParse", "Re-use existing material-mixture: %s", mix->GetName());
1506  } else {
1507  Fatal("TGDMLParse", "WARNING! Inconsistent material definitions between GDML and TGeoManager");
1508  return child;
1509  }
1510  if (properties.GetSize()) {
1511  TNamed *property;
1512  TIter next(&properties);
1513  while ((property = (TNamed *)next()))
1514  mix->AddProperty(property->GetName(), property->GetTitle());
1515  }
1516  if (constproperties.GetSize()) {
1517  TNamed *property;
1518  TIter next(&constproperties);
1519  while ((property = (TNamed *)next()))
1520  mix->AddConstProperty(property->GetName(), property->GetTitle());
1521  }
1522  Int_t natoms;
1523  Double_t weight;
1524 
1525  for (fractions f = fracmap.begin(); f != fracmap.end(); ++f) {
1526  matname = f->first;
1527  matname = NameShort(matname);
1528 
1530 
1531  if (mattmp || (felemap.find(f->first) != felemap.end())) {
1532  if (composite) {
1533  natoms = (Int_t)f->second;
1534 
1535  mix->AddElement(felemap[f->first], natoms);
1536 
1537  }
1538 
1539  else {
1540  weight = f->second;
1541  if (mattmp) {
1542  mix->AddElement(mattmp, weight);
1543  } else {
1544  mix->AddElement(felemap[f->first], weight);
1545  }
1546  }
1547  }
1548  }
1549  } // end of not Z else
1550 
1551  medid = medid + 1;
1552 
1553  TGeoMedium *med = mgr->GetMedium(NameShort(name));
1554  if (!med) {
1555  if (mixflag == 1) {
1556  fmixmap[name.Data()] = mix;
1557  med = new TGeoMedium(NameShort(name), medid, mix);
1558  } else if (mixflag == 0) {
1559  fmatmap[name.Data()] = mat;
1560  med = new TGeoMedium(NameShort(name), medid, mat);
1561  }
1562  } else if (gDebug >= 2) {
1563  Info("TGDMLParse", "Re-use existing medium: %s", med->GetName());
1564  }
1565  fmedmap[name.Data()] = med;
1566 
1567  return child;
1568 }
1569 
1570 ////////////////////////////////////////////////////////////////////////////////
1571 /// In the structure section of the GDML file, skin surfaces can be declared.
1572 
1574 {
1575  TString name, surfname, volname;
1576  TString tempattr;
1577 
1578  while (attr != 0) {
1579  tempattr = gdml->GetAttrName(attr);
1580  tempattr.ToLower();
1581 
1582  if (tempattr == "name") {
1583  name = gdml->GetAttrValue(attr);
1584  }
1585  if (tempattr == "surfaceproperty") {
1586  surfname = gdml->GetAttrValue(attr);
1587  }
1588  attr = gdml->GetNextAttr(attr);
1589  }
1590 
1591  XMLNodePointer_t child = gdml->GetChild(node);
1592  while (child != 0) {
1593  attr = gdml->GetFirstAttr(child);
1594  if ((strcmp(gdml->GetNodeName(child), "volumeref")) == 0) {
1595  while (attr != 0) {
1596  tempattr = gdml->GetAttrName(attr);
1597  tempattr.ToLower();
1598  if (tempattr == "ref") {
1599  volname = gdml->GetAttrValue(attr);
1600  }
1601  attr = gdml->GetNextAttr(attr);
1602  }
1603  } // loop on child attributes
1604  child = gdml->GetNext(child);
1605  } // loop on children
1607  if (!surf)
1608  Fatal("SkinSurfaceProcess", "Skin surface %s: referenced optical surface %s not defined", name.Data(),
1609  surfname.Data());
1610  TGeoVolume *vol = fvolmap[volname.Data()];
1611  TGeoSkinSurface *skin = new TGeoSkinSurface(name, surfname, surf, vol);
1612  gGeoManager->AddSkinSurface(skin);
1613  return child;
1614 }
1615 
1616 ////////////////////////////////////////////////////////////////////////////////
1617 /// In the structure section of the GDML file, border surfaces can be declared.
1618 
1620 {
1621  TString name, surfname, nodename[2];
1622  TString tempattr;
1623 
1624  while (attr != 0) {
1625  tempattr = gdml->GetAttrName(attr);
1626  tempattr.ToLower();
1627 
1628  if (tempattr == "name") {
1629  name = gdml->GetAttrValue(attr);
1630  }
1631  if (tempattr == "surfaceproperty") {
1632  surfname = gdml->GetAttrValue(attr);
1633  }
1634  attr = gdml->GetNextAttr(attr);
1635  }
1636 
1637  XMLNodePointer_t child = gdml->GetChild(node);
1638  Int_t inode = 0;
1639  while (child != 0) {
1640  attr = gdml->GetFirstAttr(child);
1641  if ((strcmp(gdml->GetNodeName(child), "physvolref")) == 0) {
1642  while (attr != 0) {
1643  tempattr = gdml->GetAttrName(attr);
1644  tempattr.ToLower();
1645  if (tempattr == "ref") {
1646  nodename[inode++] = gdml->GetAttrValue(attr);
1647  }
1648  attr = gdml->GetNextAttr(attr);
1649  }
1650  } // loop on child attributes
1651  child = gdml->GetNext(child);
1652  } // loop on children
1653  if (inode != 2)
1654  Fatal("BorderSurfaceProcess", "Border surface %s not referencing two nodes", name.Data());
1656  if (!surf)
1657  Fatal("BorderSurfaceProcess", "Border surface %s: referenced optical surface %s not defined", name.Data(),
1658  surfname.Data());
1659  TGeoNode *node1 = fpvolmap[nodename[0].Data()];
1660  TGeoNode *node2 = fpvolmap[nodename[1].Data()];
1661  if (!node1 || !node2)
1662  Fatal("BorderSurfaceProcess", "Border surface %s: not found nodes %s [%s] or %s [%s]", name.Data(),
1663  nodename[0].Data(), node1 ? "present" : "missing", nodename[1].Data(), node2 ? "present" : "missing");
1664 
1665  TGeoBorderSurface *border = new TGeoBorderSurface(name, surfname, surf, node1, node2);
1666  gGeoManager->AddBorderSurface(border);
1667  return child;
1668 }
1669 
1670 ////////////////////////////////////////////////////////////////////////////////
1671 /// In the structure section of the GDML file, volumes can be declared.
1672 /// when the volume keyword is found, this function is called, and the
1673 /// name and values of the volume are converted into type TGeoVolume and
1674 /// stored in fvolmap map using the name as its key. Volumes reference to
1675 /// a solid declared higher up in the solids section of the GDML file.
1676 /// Some volumes reference to other physical volumes to contain inside
1677 /// that volume, declaring positions and rotations within that volume.
1678 /// when each 'physvol' is declared, a matrix for its rotation and
1679 /// translation is built and the 'physvol node' is added to the original
1680 /// volume using TGeoVolume->AddNode.
1681 /// volume division is also declared within the volume node, and once the
1682 /// values for the division have been collected, using TGeoVolume->divide,
1683 /// the division can be applied.
1684 
1686 {
1687  XMLAttrPointer_t attr;
1688  XMLNodePointer_t subchild;
1689  XMLNodePointer_t subsubchild;
1690 
1691  XMLNodePointer_t child = gdml->GetChild(node);
1692  TString name;
1693  TString solidname = "";
1694  TString tempattr = "";
1695  TGeoShape *solid = 0;
1696  TGeoMedium *medium = 0;
1697  TGeoVolume *vol = 0;
1698  TGeoVolume *lv = 0;
1699  TGeoShape *reflex = 0;
1700  const Double_t *parentrot = 0;
1701  int yesrefl = 0;
1702  TString reftemp = "";
1703  TMap *auxmap = 0;
1704 
1705  while (child != 0) {
1706  if ((strcmp(gdml->GetNodeName(child), "solidref")) == 0) {
1707 
1708  reftemp = gdml->GetAttr(child, "ref");
1709  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1710  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
1711  }
1712  if (fsolmap.find(reftemp.Data()) != fsolmap.end()) {
1713  solid = fsolmap[reftemp.Data()];
1714  } else if (freflectmap.find(reftemp.Data()) != freflectmap.end()) {
1715  solidname = reftemp;
1716  reflex = fsolmap[freflectmap[reftemp.Data()]];
1717  } else {
1718  printf("Solid: %s, Not Yet Defined!\n", reftemp.Data());
1719  }
1720  }
1721 
1722  if ((strcmp(gdml->GetNodeName(child), "materialref")) == 0) {
1723  reftemp = gdml->GetAttr(child, "ref");
1724  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1725  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
1726  }
1727  if (fmedmap.find(reftemp.Data()) != fmedmap.end()) {
1728  medium = fmedmap[reftemp.Data()];
1729  } else {
1730  printf("Medium: %s, Not Yet Defined!\n", gdml->GetAttr(child, "ref"));
1731  }
1732  }
1733 
1734  child = gdml->GetNext(child);
1735  }
1736 
1737  name = gdml->GetAttr(node, "name");
1738 
1739  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1740  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
1741  }
1742 
1743  if (reflex == 0) {
1744  vol = new TGeoVolume(NameShort(name), solid, medium);
1745  } else {
1746  vol = new TGeoVolume(NameShort(name), reflex, medium);
1747  freflvolmap[name.Data()] = solidname;
1748  TGDMLRefl *parentrefl = freflsolidmap[solidname.Data()];
1749  parentrot = parentrefl->GetMatrix()->GetRotationMatrix();
1750  yesrefl = 1;
1751  }
1752 
1753  fvolmap[name.Data()] = vol;
1754 
1755  // PHYSVOL - run through child nodes of VOLUME again..
1756 
1757  child = gdml->GetChild(node);
1758 
1759  while (child != 0) {
1760  if ((strcmp(gdml->GetNodeName(child), "physvol")) == 0) {
1761 
1762  TString volref = "";
1763 
1764  TGeoTranslation *pos = 0;
1765  TGeoRotation *rot = 0;
1766  TGeoScale *scl = 0;
1767  TString pnodename = gdml->GetAttr(child, "name");
1768  TString scopynum = gdml->GetAttr(child, "copynumber");
1769  Int_t copynum = (scopynum.IsNull()) ? 0 : (Int_t)Value(scopynum);
1770 
1771  subchild = gdml->GetChild(child);
1772 
1773  while (subchild != 0) {
1774  tempattr = gdml->GetNodeName(subchild);
1775  tempattr.ToLower();
1776 
1777  if (tempattr == "volumeref") {
1778  reftemp = gdml->GetAttr(subchild, "ref");
1779  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1780  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
1781  }
1782  lv = fvolmap[reftemp.Data()];
1783  volref = reftemp;
1784  } else if (tempattr == "file") {
1785  const char *filevol;
1786  const char *prevfile = fCurrentFile;
1787 
1788  fCurrentFile = gdml->GetAttr(subchild, "name");
1789  filevol = gdml->GetAttr(subchild, "volname");
1790 
1791  TXMLEngine *gdml2 = new TXMLEngine;
1792  gdml2->SetSkipComments(kTRUE);
1793  XMLDocPointer_t filedoc1 = gdml2->ParseFile(fCurrentFile);
1794  if (filedoc1 == 0) {
1795  Fatal("VolProcess", "Bad filename given %s", fCurrentFile);
1796  }
1797  // take access to main node
1798  XMLNodePointer_t mainnode2 = gdml2->DocGetRootElement(filedoc1);
1799  // increase depth counter + add DOM pointer
1800  fFILENO = fFILENO + 1;
1801  fFileEngine[fFILENO] = gdml2;
1802 
1803  if (ffilemap.find(fCurrentFile) != ffilemap.end()) {
1804  volref = ffilemap[fCurrentFile];
1805  } else {
1806  volref = ParseGDML(gdml2, mainnode2);
1807  ffilemap[fCurrentFile] = volref;
1808  }
1809 
1810  if (filevol) {
1811  volref = filevol;
1812  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1813  volref = TString::Format("%s_%s", volref.Data(), fCurrentFile);
1814  }
1815  }
1816 
1817  fFILENO = fFILENO - 1;
1818  gdml = fFileEngine[fFILENO];
1819  fCurrentFile = prevfile;
1820 
1821  lv = fvolmap[volref.Data()];
1822  // File tree complete - Release memory before exit
1823 
1824  gdml->FreeDoc(filedoc1);
1825  delete gdml2;
1826  } else if (tempattr == "position") {
1827  attr = gdml->GetFirstAttr(subchild);
1828  PosProcess(gdml, subchild, attr);
1829  reftemp = gdml->GetAttr(subchild, "name");
1830  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1831  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
1832  }
1833  pos = fposmap[reftemp.Data()];
1834  } else if (tempattr == "positionref") {
1835  reftemp = gdml->GetAttr(subchild, "ref");
1836  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1837  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
1838  }
1839  if (fposmap.find(reftemp.Data()) != fposmap.end())
1840  pos = fposmap[reftemp.Data()];
1841  else
1842  std::cout << "ERROR! Physvol's position " << reftemp << " not found!" << std::endl;
1843  } else if (tempattr == "rotation") {
1844  attr = gdml->GetFirstAttr(subchild);
1845  RotProcess(gdml, subchild, attr);
1846  reftemp = gdml->GetAttr(subchild, "name");
1847  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1848  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
1849  }
1850  rot = frotmap[reftemp.Data()];
1851  } else if (tempattr == "rotationref") {
1852  reftemp = gdml->GetAttr(subchild, "ref");
1853  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1854  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
1855  }
1856  if (frotmap.find(reftemp.Data()) != frotmap.end())
1857  rot = frotmap[reftemp.Data()];
1858  else
1859  std::cout << "ERROR! Physvol's rotation " << reftemp << " not found!" << std::endl;
1860  } else if (tempattr == "scale") {
1861  attr = gdml->GetFirstAttr(subchild);
1862  SclProcess(gdml, subchild, attr);
1863  reftemp = gdml->GetAttr(subchild, "name");
1864  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1865  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
1866  }
1867  scl = fsclmap[reftemp.Data()];
1868  } else if (tempattr == "scaleref") {
1869  reftemp = gdml->GetAttr(subchild, "ref");
1870  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1871  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
1872  }
1873  if (fsclmap.find(reftemp.Data()) != fsclmap.end())
1874  scl = fsclmap[reftemp.Data()];
1875  else
1876  std::cout << "ERROR! Physvol's scale " << reftemp << " not found!" << std::endl;
1877  }
1878 
1879  subchild = gdml->GetNext(subchild);
1880  }
1881 
1882  // ADD PHYSVOL TO GEOMETRY
1883  fVolID = fVolID + 1;
1884 
1885  TGeoHMatrix *transform = new TGeoHMatrix();
1886 
1887  if (pos != 0)
1888  transform->SetTranslation(pos->GetTranslation());
1889  if (rot != 0)
1890  transform->SetRotation(rot->GetRotationMatrix());
1891 
1892  if (scl != 0) { // Scaling must be added to the rotation matrix!
1893 
1894  Double_t scale3x3[9];
1895  memset(scale3x3, 0, 9 * sizeof(Double_t));
1896  const Double_t *diagonal = scl->GetScale();
1897 
1898  scale3x3[0] = diagonal[0];
1899  scale3x3[4] = diagonal[1];
1900  scale3x3[8] = diagonal[2];
1901 
1902  TGeoRotation scaleMatrix;
1903  scaleMatrix.SetMatrix(scale3x3);
1904  transform->Multiply(&scaleMatrix);
1905  }
1906 
1907  // BEGIN: reflectedSolid. Remove lines between if reflectedSolid will be removed from GDML!!!
1908 
1909  if (freflvolmap.find(volref.Data()) != freflvolmap.end()) {
1910  // if the volume is a reflected volume the matrix needs to be CHANGED
1911  TGDMLRefl *temprefl = freflsolidmap[freflvolmap[volref.Data()]];
1912  transform->Multiply(temprefl->GetMatrix());
1913  }
1914 
1915  if (yesrefl == 1) {
1916  // reflection is done per solid so that we cancel it if exists in mother volume!!!
1917  TGeoRotation prot;
1918  prot.SetMatrix(parentrot);
1919  transform->MultiplyLeft(&prot);
1920  }
1921 
1922  // END: reflectedSolid
1923 
1924  vol->AddNode(lv, copynum, transform);
1925  TGeoNode *lastnode = (TGeoNode *)vol->GetNodes()->Last();
1926  if (!pnodename.IsNull())
1927  lastnode->SetName(pnodename);
1928  fpvolmap[lastnode->GetName()] = lastnode;
1929  } else if ((strcmp(gdml->GetNodeName(child), "divisionvol")) == 0) {
1930 
1931  TString divVolref = "";
1932  Int_t axis = 0;
1933  TString number = "";
1934  TString width = "";
1935  TString offset = "";
1936  TString lunit = fDefault_lunit.c_str();
1937 
1938  attr = gdml->GetFirstAttr(child);
1939 
1940  while (attr != 0) {
1941 
1942  tempattr = gdml->GetAttrName(attr);
1943  tempattr.ToLower();
1944 
1945  if (tempattr == "axis") {
1946  axis = SetAxis(gdml->GetAttrValue(attr));
1947  } else if (tempattr == "number") {
1948  number = gdml->GetAttrValue(attr);
1949  } else if (tempattr == "width") {
1950  width = gdml->GetAttrValue(attr);
1951  } else if (tempattr == "offset") {
1952  offset = gdml->GetAttrValue(attr);
1953  } else if (tempattr == "unit") {
1954  lunit = gdml->GetAttrValue(attr);
1955  }
1956 
1957  attr = gdml->GetNextAttr(attr);
1958  }
1959 
1960  subchild = gdml->GetChild(child);
1961 
1962  while (subchild != 0) {
1963  tempattr = gdml->GetNodeName(subchild);
1964  tempattr.ToLower();
1965 
1966  if (tempattr == "volumeref") {
1967  reftemp = gdml->GetAttr(subchild, "ref");
1968  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1969  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
1970  }
1971  divVolref = reftemp;
1972  }
1973 
1974  subchild = gdml->GetNext(subchild);
1975  }
1976 
1977  Double_t numberline = Value(number);
1978  Double_t retunit = GetScaleVal(lunit);
1979  Double_t step = Value(width) * retunit;
1980  Double_t offsetline = Value(offset) * retunit;
1981 
1982  fVolID = fVolID + 1;
1983  Double_t xlo, xhi;
1984  vol->GetShape()->GetAxisRange(axis, xlo, xhi);
1985 
1986  Int_t ndiv = (Int_t)numberline;
1987  Double_t start = xlo + offsetline;
1988 
1989  Int_t numed = 0;
1990  TGeoVolume *old = fvolmap[NameShort(reftemp)];
1991  if (old) {
1992  // We need to recreate the content of the divided volume
1993  old = fvolmap[NameShort(reftemp)];
1994  // medium id
1995  numed = old->GetMedium()->GetId();
1996  }
1997  TGeoVolume *divvol = vol->Divide(NameShort(reftemp), axis, ndiv, start, step, numed);
1998  if (!divvol) {
1999  Fatal("VolProcess", "Cannot divide volume %s", vol->GetName());
2000  return child;
2001  }
2002  if (old && old->GetNdaughters()) {
2003  divvol->ReplayCreation(old);
2004  }
2005  fvolmap[NameShort(reftemp)] = divvol;
2006 
2007  } // end of Division else if
2008 
2009  else if ((strcmp(gdml->GetNodeName(child), "replicavol")) == 0) {
2010 
2011  TString divVolref = "";
2012  Int_t axis = 0;
2013  TString number = "";
2014  TString width = "";
2015  TString offset = "";
2016  TString wunit = fDefault_lunit.c_str();
2017  TString ounit = fDefault_lunit.c_str();
2018  Double_t wvalue = 0;
2019  Double_t ovalue = 0;
2020 
2021  attr = gdml->GetFirstAttr(child);
2022 
2023  while (attr != 0) {
2024 
2025  tempattr = gdml->GetAttrName(attr);
2026  tempattr.ToLower();
2027 
2028  if (tempattr == "number") {
2029  number = gdml->GetAttrValue(attr);
2030  }
2031  attr = gdml->GetNextAttr(attr);
2032  }
2033 
2034  subchild = gdml->GetChild(child);
2035 
2036  while (subchild != 0) {
2037  tempattr = gdml->GetNodeName(subchild);
2038  tempattr.ToLower();
2039 
2040  if (tempattr == "volumeref") {
2041  reftemp = gdml->GetAttr(subchild, "ref");
2042  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2043  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
2044  }
2045  divVolref = reftemp;
2046  }
2047 
2048  if (tempattr == "replicate_along_axis") {
2049  subsubchild = gdml->GetChild(subchild);
2050 
2051  while (subsubchild != 0) {
2052  if ((strcmp(gdml->GetNodeName(subsubchild), "width")) == 0) {
2053  attr = gdml->GetFirstAttr(subsubchild);
2054  while (attr != 0) {
2055  tempattr = gdml->GetAttrName(attr);
2056  tempattr.ToLower();
2057  if (tempattr == "value") {
2058  wvalue = Value(gdml->GetAttrValue(attr));
2059  } else if (tempattr == "unit") {
2060  wunit = gdml->GetAttrValue(attr);
2061  }
2062 
2063  attr = gdml->GetNextAttr(attr);
2064  }
2065  } else if ((strcmp(gdml->GetNodeName(subsubchild), "offset")) == 0) {
2066  attr = gdml->GetFirstAttr(subsubchild);
2067  while (attr != 0) {
2068  tempattr = gdml->GetAttrName(attr);
2069  tempattr.ToLower();
2070  if (tempattr == "value") {
2071  ovalue = Value(gdml->GetAttrValue(attr));
2072  } else if (tempattr == "unit") {
2073  ounit = gdml->GetAttrValue(attr);
2074  }
2075  attr = gdml->GetNextAttr(attr);
2076  }
2077  } else if ((strcmp(gdml->GetNodeName(subsubchild), "direction")) == 0) {
2078  attr = gdml->GetFirstAttr(subsubchild);
2079  while (attr != 0) {
2080  tempattr = gdml->GetAttrName(attr);
2081  tempattr.ToLower();
2082  if (tempattr == "x") {
2083  axis = 1;
2084  } else if (tempattr == "y") {
2085  axis = 2;
2086  } else if (tempattr == "z") {
2087  axis = 3;
2088  } else if (tempattr == "rho") {
2089  axis = 1;
2090  } else if (tempattr == "phi") {
2091  axis = 2;
2092  }
2093 
2094  attr = gdml->GetNextAttr(attr);
2095  }
2096  }
2097 
2098  subsubchild = gdml->GetNext(subsubchild);
2099  }
2100  }
2101 
2102  subchild = gdml->GetNext(subchild);
2103  }
2104 
2105  Double_t retwunit = GetScaleVal(wunit);
2106  Double_t retounit = GetScaleVal(ounit);
2107 
2108  Double_t numberline = Value(number);
2109  Double_t widthline = wvalue * retwunit;
2110  Double_t offsetline = ovalue * retounit;
2111 
2112  fVolID = fVolID + 1;
2113  Double_t xlo, xhi;
2114  vol->GetShape()->GetAxisRange(axis, xlo, xhi);
2115 
2116  Int_t ndiv = (Int_t)numberline;
2117  Double_t start = xlo + offsetline;
2118 
2119  Double_t step = widthline;
2120  Int_t numed = 0;
2121  TGeoVolume *old = fvolmap[NameShort(reftemp)];
2122  if (old) {
2123  // We need to recreate the content of the divided volume
2124  old = fvolmap[NameShort(reftemp)];
2125  // medium id
2126  numed = old->GetMedium()->GetId();
2127  }
2128  TGeoVolume *divvol = vol->Divide(NameShort(reftemp), axis, ndiv, start, step, numed);
2129  if (!divvol) {
2130  Fatal("VolProcess", "Cannot divide volume %s", vol->GetName());
2131  return child;
2132  }
2133  if (old && old->GetNdaughters()) {
2134  divvol->ReplayCreation(old);
2135  }
2136  fvolmap[NameShort(reftemp)] = divvol;
2137 
2138  } // End of replicavol
2139  else if (strcmp(gdml->GetNodeName(child), "auxiliary") == 0) {
2140  TString auxType, auxUnit, auxValue;
2141  if (!auxmap) {
2142  // printf("Auxiliary values for volume %s\n",vol->GetName());
2143  auxmap = new TMap();
2144  vol->SetUserExtension(new TGeoRCExtension(auxmap));
2145  }
2146  attr = gdml->GetFirstAttr(child);
2147  while (attr) {
2148  if (!strcmp(gdml->GetAttrName(attr), "auxtype"))
2149  auxType = gdml->GetAttrValue(attr);
2150  else if (!strcmp(gdml->GetAttrName(attr), "auxvalue"))
2151  auxValue = gdml->GetAttrValue(attr);
2152  else if (!strcmp(gdml->GetAttrName(attr), "auxunit"))
2153  auxUnit = gdml->GetAttrValue(attr);
2154  attr = gdml->GetNextAttr(attr);
2155  }
2156  if (!auxUnit.IsNull())
2157  auxValue = TString::Format("%s*%s", auxValue.Data(), auxUnit.Data());
2158  auxmap->Add(new TObjString(auxType), new TObjString(auxValue));
2159  // printf(" %s: %s\n", auxType.Data(), auxValue.Data());
2160  }
2161 
2162  child = gdml->GetNext(child);
2163  }
2164 
2165  return child;
2166 }
2167 
2168 ////////////////////////////////////////////////////////////////////////////////
2169 /// In the solid section of the GDML file, boolean solids can be
2170 /// declared. when the subtraction, intersection or union keyword
2171 /// is found, this function is called, and the values (rotation and
2172 /// translation) of the solid are converted into type TGeoCompositeShape
2173 /// and stored in fsolmap map using the name as its key.
2174 ///
2175 /// - 1 = SUBTRACTION
2176 /// - 2 = INTERSECTION
2177 /// - 3 = UNION
2178 
2180 {
2181  TString reftemp = "";
2182  TString tempattr = "";
2183  XMLNodePointer_t child = gdml->GetChild(node);
2184 
2185  TGeoShape *first = 0;
2186  TGeoShape *second = 0;
2187 
2188  TGeoTranslation *firstPos = new TGeoTranslation(0, 0, 0);
2189  TGeoTranslation *secondPos = new TGeoTranslation(0, 0, 0);
2190 
2191  TGeoRotation *firstRot = new TGeoRotation();
2192  TGeoRotation *secondRot = new TGeoRotation();
2193 
2194  firstRot->RotateZ(0);
2195  firstRot->RotateY(0);
2196  firstRot->RotateX(0);
2197 
2198  secondRot->RotateZ(0);
2199  secondRot->RotateY(0);
2200  secondRot->RotateX(0);
2201 
2202  TString name = gdml->GetAttr(node, "name");
2203 
2204  if ((strcmp(fCurrentFile, fStartFile)) != 0)
2205  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
2206 
2207  while (child != 0) {
2208  tempattr = gdml->GetNodeName(child);
2209  tempattr.ToLower();
2210 
2211  if (tempattr == "first") {
2212  reftemp = gdml->GetAttr(child, "ref");
2213  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2214  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
2215  }
2216  if (fsolmap.find(reftemp.Data()) != fsolmap.end()) {
2217  first = fsolmap[reftemp.Data()];
2218  }
2219  } else if (tempattr == "second") {
2220  reftemp = gdml->GetAttr(child, "ref");
2221  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2222  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
2223  }
2224  if (fsolmap.find(reftemp.Data()) != fsolmap.end()) {
2225  second = fsolmap[reftemp.Data()];
2226  }
2227  } else if (tempattr == "position") {
2228  attr = gdml->GetFirstAttr(child);
2229  PosProcess(gdml, child, attr);
2230  reftemp = gdml->GetAttr(child, "name");
2231  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2232  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
2233  }
2234  secondPos = fposmap[reftemp.Data()];
2235  } else if (tempattr == "positionref") {
2236  reftemp = gdml->GetAttr(child, "ref");
2237  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2238  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
2239  }
2240  if (fposmap.find(reftemp.Data()) != fposmap.end()) {
2241  secondPos = fposmap[reftemp.Data()];
2242  }
2243  } else if (tempattr == "rotation") {
2244  attr = gdml->GetFirstAttr(child);
2245  RotProcess(gdml, child, attr);
2246  reftemp = gdml->GetAttr(child, "name");
2247  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2248  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
2249  }
2250  secondRot = frotmap[reftemp.Data()];
2251  } else if (tempattr == "rotationref") {
2252  reftemp = gdml->GetAttr(child, "ref");
2253  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2254  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
2255  }
2256  if (frotmap.find(reftemp.Data()) != frotmap.end()) {
2257  secondRot = frotmap[reftemp.Data()];
2258  }
2259  } else if (tempattr == "firstposition") {
2260  attr = gdml->GetFirstAttr(child);
2261  PosProcess(gdml, child, attr);
2262  reftemp = gdml->GetAttr(child, "name");
2263  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2264  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
2265  }
2266  firstPos = fposmap[reftemp.Data()];
2267  } else if (tempattr == "firstpositionref") {
2268  reftemp = gdml->GetAttr(child, "ref");
2269  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2270  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
2271  }
2272  if (fposmap.find(reftemp.Data()) != fposmap.end()) {
2273  firstPos = fposmap[reftemp.Data()];
2274  }
2275  } else if (tempattr == "firstrotation") {
2276  attr = gdml->GetFirstAttr(child);
2277  RotProcess(gdml, child, attr);
2278  reftemp = gdml->GetAttr(child, "name");
2279  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2280  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
2281  }
2282  firstRot = frotmap[reftemp.Data()];
2283  } else if (tempattr == "firstrotationref") {
2284  reftemp = gdml->GetAttr(child, "ref");
2285  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2286  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
2287  }
2288  if (frotmap.find(reftemp.Data()) != frotmap.end()) {
2289  firstRot = frotmap[reftemp.Data()];
2290  }
2291  }
2292  child = gdml->GetNext(child);
2293  }
2294 
2295  TGeoMatrix *firstMatrix = new TGeoCombiTrans(*firstPos, firstRot->Inverse());
2296  TGeoMatrix *secondMatrix = new TGeoCombiTrans(*secondPos, secondRot->Inverse());
2297 
2298  TGeoCompositeShape *boolean = 0;
2299  if (!first || !second) {
2300  Fatal("BooSolid", "Incomplete solid %s, missing shape components", name.Data());
2301  return child;
2302  }
2303  switch (num) {
2304  case 1:
2305  boolean = new TGeoCompositeShape(NameShort(name), new TGeoSubtraction(first, second, firstMatrix, secondMatrix));
2306  break; // SUBTRACTION
2307  case 2:
2308  boolean = new TGeoCompositeShape(NameShort(name), new TGeoIntersection(first, second, firstMatrix, secondMatrix));
2309  break; // INTERSECTION
2310  case 3:
2311  boolean = new TGeoCompositeShape(NameShort(name), new TGeoUnion(first, second, firstMatrix, secondMatrix));
2312  break; // UNION
2313  default: break;
2314  }
2315 
2316  fsolmap[name.Data()] = boolean;
2317 
2318  return child;
2319 }
2320 
2321 ////////////////////////////////////////////////////////////////////////////////
2322 /// User data to be processed.
2323 
2325 {
2326  XMLNodePointer_t child = gdml->GetChild(node);
2327  TString nodename, auxtype, auxtypec, auxvalue, auxvaluec, auxunit, auxunitc;
2328  double value = 0.;
2329  TGeoRegion *region;
2330  while (child) {
2331  region = nullptr;
2332  nodename = gdml->GetNodeName(child);
2333  if (nodename == "auxiliary") {
2334  auxtype = gdml->GetAttr(child, "auxtype");
2335  auxvalue = gdml->GetAttr(child, "auxvalue");
2336  if (auxtype == "Region") {
2337  auxvalue = NameShort(auxvalue);
2338  region = new TGeoRegion(auxvalue);
2339  }
2340  }
2341  XMLNodePointer_t subchild = gdml->GetChild(child);
2342  while (subchild) {
2343  auxtypec = gdml->GetAttr(subchild, "auxtype");
2344  auxvaluec = gdml->GetAttr(subchild, "auxvalue");
2345  auxunitc = gdml->GetAttr(subchild, "auxunit");
2346  if (auxtypec == "volume") {
2347  auxvaluec = NameShort(auxvaluec);
2348  if (region)
2349  region->AddVolume(auxvaluec);
2350  }
2351  if (auxtypec.Contains("cut")) {
2352  value = Value(auxvaluec) * GetScaleVal(auxunitc);
2353  if (region)
2354  region->AddCut(auxtypec, value);
2355  }
2356  subchild = gdml->GetNext(subchild);
2357  }
2358  if (region) {
2359  gGeoManager->AddRegion(region);
2360  // region->Print();
2361  }
2362  child = gdml->GetNext(child);
2363  }
2364  return child;
2365 }
2366 
2367 ////////////////////////////////////////////////////////////////////////////////
2368 /// In the structure section of the GDML file, assembly volumes can be
2369 /// declared. when the assembly keyword is found, this function is called,
2370 /// and the name is converted into type TGeoVolumeAssembly and
2371 /// stored in fvolmap map using the name as its key. Some assembly volumes
2372 /// reference to other physical volumes to contain inside that assembly,
2373 /// declaring positions and rotations within that volume. When each 'physvol'
2374 /// is declared, a matrix for its rotation and translation is built and the
2375 /// 'physvol node' is added to the original assembly using TGeoVolume->AddNode.
2376 
2378 {
2379  TString name = gdml->GetAttr(node, "name");
2380  TString reftemp = "";
2381 
2382  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2383  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
2384  }
2385 
2386  XMLAttrPointer_t attr;
2387  XMLNodePointer_t subchild;
2388  XMLNodePointer_t child = gdml->GetChild(node);
2389  TString tempattr = "";
2390  TGeoVolume *lv = 0;
2391  TGeoTranslation *pos = 0;
2392  TGeoRotation *rot = 0;
2393  TGeoCombiTrans *matr;
2394 
2396 
2397  // PHYSVOL - run through child nodes of VOLUME again..
2398 
2399  // child = gdml->GetChild(node);
2400 
2401  while (child != 0) {
2402  if ((strcmp(gdml->GetNodeName(child), "physvol")) == 0) {
2403  TString pnodename = gdml->GetAttr(child, "name");
2404  TString scopynum = gdml->GetAttr(child, "copynumber");
2405  Int_t copynum = (scopynum.IsNull()) ? 0 : (Int_t)Value(scopynum);
2406 
2407  subchild = gdml->GetChild(child);
2408  pos = new TGeoTranslation(0, 0, 0);
2409  rot = new TGeoRotation();
2410 
2411  while (subchild != 0) {
2412  tempattr = gdml->GetNodeName(subchild);
2413  tempattr.ToLower();
2414 
2415  if (tempattr == "volumeref") {
2416  reftemp = gdml->GetAttr(subchild, "ref");
2417  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2418  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
2419  }
2420  lv = fvolmap[reftemp.Data()];
2421  } else if (tempattr == "positionref") {
2422  reftemp = gdml->GetAttr(subchild, "ref");
2423  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2424  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
2425  }
2426  if (fposmap.find(reftemp.Data()) != fposmap.end()) {
2427  pos = fposmap[reftemp.Data()];
2428  }
2429  } else if (tempattr == "position") {
2430  attr = gdml->GetFirstAttr(subchild);
2431  PosProcess(gdml, subchild, attr);
2432  reftemp = gdml->GetAttr(subchild, "name");
2433  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2434  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
2435  }
2436  pos = fposmap[reftemp.Data()];
2437  } else if (tempattr == "rotationref") {
2438  reftemp = gdml->GetAttr(subchild, "ref");
2439  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2440  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
2441  }
2442  if (frotmap.find(reftemp.Data()) != frotmap.end()) {
2443  rot = frotmap[reftemp.Data()];
2444  }
2445  } else if (tempattr == "rotation") {
2446  attr = gdml->GetFirstAttr(subchild);
2447  RotProcess(gdml, subchild, attr);
2448  reftemp = gdml->GetAttr(subchild, "name");
2449  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2450  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
2451  }
2452  rot = frotmap[reftemp.Data()];
2453  }
2454 
2455  subchild = gdml->GetNext(subchild);
2456  }
2457 
2458  // ADD PHYSVOL TO GEOMETRY
2459  fVolID = fVolID + 1;
2460  matr = new TGeoCombiTrans(*pos, *rot);
2461  assem->AddNode(lv, copynum, matr);
2462  TGeoNode *lastnode = (TGeoNode *)assem->GetNodes()->Last();
2463  if (!pnodename.IsNull())
2464  lastnode->SetName(pnodename);
2465  fpvolmap[lastnode->GetName()] = lastnode;
2466  }
2467  child = gdml->GetNext(child);
2468  }
2469 
2470  fvolmap[name.Data()] = assem;
2471  return child;
2472 }
2473 
2474 ////////////////////////////////////////////////////////////////////////////////
2475 /// In the setup section of the GDML file, the top volume need to be
2476 /// declared. when the setup keyword is found, this function is called,
2477 /// and the top volume ref is taken and 'world' is set
2478 
2480 {
2481  const char *name = gdml->GetAttr(node, "name");
2483  XMLNodePointer_t child = gdml->GetChild(node);
2484  TString reftemp = "";
2485 
2486  while (child != 0) {
2487 
2488  if ((strcmp(gdml->GetNodeName(child), "world") == 0)) {
2489  // const char* reftemp;
2490  // TString reftemp = "";
2491  reftemp = gdml->GetAttr(child, "ref");
2492 
2493  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2494  reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
2495  }
2496  fWorld = fvolmap[reftemp.Data()];
2497  fWorldName = reftemp.Data();
2498  }
2499  child = gdml->GetNext(child);
2500  }
2501  return node;
2502 }
2503 
2504 ////////////////////////////////////////////////////////////////////////////////
2505 /// In the solids section of the GDML file, a box may be declared.
2506 /// when the box keyword is found, this function is called, and the
2507 /// dimensions required are taken and stored, these are then bound and
2508 /// converted to type TGeoBBox and stored in fsolmap map using the name
2509 /// as its key.
2510 
2512 {
2513  TString lunit = fDefault_lunit.c_str();
2514  TString xpos = "0";
2515  TString ypos = "0";
2516  TString zpos = "0";
2517  TString name = "";
2518  TString tempattr;
2519 
2520  while (attr != 0) {
2521 
2522  tempattr = gdml->GetAttrName(attr);
2523  tempattr.ToLower();
2524 
2525  if (tempattr == "name") {
2526  name = gdml->GetAttrValue(attr);
2527  } else if (tempattr == "x") {
2528  xpos = gdml->GetAttrValue(attr);
2529  } else if (tempattr == "y") {
2530  ypos = gdml->GetAttrValue(attr);
2531  } else if (tempattr == "z") {
2532  zpos = gdml->GetAttrValue(attr);
2533  } else if (tempattr == "lunit") {
2534  lunit = gdml->GetAttrValue(attr);
2535  }
2536 
2537  attr = gdml->GetNextAttr(attr);
2538  }
2539 
2540  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2541  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
2542  }
2543 
2544  Double_t retunit = GetScaleVal(lunit);
2545 
2546  Double_t xline = 0.5 * Value(xpos) * retunit;
2547  Double_t yline = 0.5 * Value(ypos) * retunit;
2548  Double_t zline = 0.5 * Value(zpos) * retunit;
2549 
2550  TGeoBBox *box = new TGeoBBox(NameShort(name), xline, yline, zline);
2551 
2552  fsolmap[name.Data()] = box;
2553 
2554  return node;
2555 }
2556 
2557 ////////////////////////////////////////////////////////////////////////////////
2558 /// In the solids section of the GDML file, an ellipsoid may be declared.
2559 /// Unfortunately, the ellipsoid is not supported under ROOT so,
2560 /// when the ellipsoid keyword is found, this function is called
2561 /// to convert it to a simple box with similar dimensions, and the
2562 /// dimensions required are taken and stored, these are then bound and
2563 /// converted to type TGeoBBox and stored in fsolmap map using the name
2564 /// as its key.
2565 
2567 {
2568  TString lunit = fDefault_lunit.c_str();
2569  TString ax = "0";
2570  TString by = "0";
2571  TString cz = "0";
2572  // initialization to empty string
2573  TString zcut1 = "";
2574  TString zcut2 = "";
2575  TString name = "";
2576  TString tempattr;
2577 
2578  while (attr != 0) {
2579 
2580  tempattr = gdml->GetAttrName(attr);
2581  tempattr.ToLower();
2582 
2583  if (tempattr == "name") {
2584  name = gdml->GetAttrValue(attr);
2585  } else if (tempattr == "ax") {
2586  ax = gdml->GetAttrValue(attr);
2587  } else if (tempattr == "by") {
2588  by = gdml->GetAttrValue(attr);
2589  } else if (tempattr == "cz") {
2590  cz = gdml->GetAttrValue(attr);
2591  } else if (tempattr == "zcut1") {
2592  zcut1 = gdml->GetAttrValue(attr);
2593  } else if (tempattr == "zcut2") {
2594  zcut2 = gdml->GetAttrValue(attr);
2595  } else if (tempattr == "lunit") {
2596  lunit = gdml->GetAttrValue(attr);
2597  }
2598 
2599  attr = gdml->GetNextAttr(attr);
2600  }
2601 
2602  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2603  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
2604  }
2605 
2606  Double_t retunit = GetScaleVal(lunit);
2607 
2608  Double_t dx = Value(ax) * retunit;
2609  Double_t dy = Value(by) * retunit;
2610  Double_t radius = Value(cz) * retunit;
2611  Double_t sx = dx / radius;
2612  Double_t sy = dy / radius;
2613  Double_t sz = 1.;
2614  Double_t z1, z2;
2615  // Initialization of cutting
2616  if (zcut1 == "") {
2617  z1 = -radius;
2618  } else {
2619  z1 = Value(zcut1) * retunit;
2620  }
2621  if (zcut2 == "") {
2622  z2 = radius;
2623  } else {
2624  z2 = Value(zcut2) * retunit;
2625  }
2626 
2627  TGeoSphere *sph = new TGeoSphere(0, radius);
2628  TGeoScale *scl = new TGeoScale("", sx, sy, sz);
2629  TGeoScaledShape *shape = new TGeoScaledShape(NameShort(name), sph, scl);
2630 
2631  Double_t origin[3] = {0., 0., 0.};
2632  origin[2] = 0.5 * (z1 + z2);
2633  Double_t dz = 0.5 * (z2 - z1);
2634  TGeoBBox *pCutBox = new TGeoBBox("cutBox", dx, dy, dz, origin);
2635  TGeoBoolNode *pBoolNode = new TGeoIntersection(shape, pCutBox, 0, 0);
2636  TGeoCompositeShape *cs = new TGeoCompositeShape(NameShort(name), pBoolNode);
2637  fsolmap[name.Data()] = cs;
2638 
2639  return node;
2640 }
2641 
2642 ////////////////////////////////////////////////////////////////////////////////
2643 /// In the solids section of the GDML file, an elliptical cone may be declared.
2644 /// Unfortunately, the elliptical cone is not supported under ROOT so,
2645 /// when the elcone keyword is found, this function is called
2646 /// to convert it to a simple box with similar dimensions, and the
2647 /// dimensions required are taken and stored, these are then bound and
2648 /// converted to type TGeoBBox and stored in fsolmap map using the name
2649 /// as its key.
2650 
2652 {
2653  TString lunit = fDefault_lunit.c_str();
2654  TString dx = "0";
2655  TString dy = "0";
2656  TString zmax = "0";
2657  TString zcut = "0";
2658  TString name = "";
2659  TString tempattr;
2660 
2661  while (attr != 0) {
2662 
2663  tempattr = gdml->GetAttrName(attr);
2664  tempattr.ToLower();
2665 
2666  if (tempattr == "name") {
2667  name = gdml->GetAttrValue(attr);
2668  } else if (tempattr == "dx") {
2669  dx = gdml->GetAttrValue(attr);
2670  } else if (tempattr == "dy") {
2671  dy = gdml->GetAttrValue(attr);
2672  } else if (tempattr == "zmax") {
2673  zmax = gdml->GetAttrValue(attr);
2674  } else if (tempattr == "zcut") {
2675  zcut = gdml->GetAttrValue(attr);
2676  } else if (tempattr == "lunit") {
2677  lunit = gdml->GetAttrValue(attr);
2678  }
2679 
2680  attr = gdml->GetNextAttr(attr);
2681  }
2682 
2683  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2684  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
2685  }
2686 
2687  // semiaxises of elliptical cone (elcone) are different then ellipsoid
2688 
2689  Double_t retunit = GetScaleVal(lunit);
2690 
2691  // dxline and dyline are without units because they are as a ration
2692  Double_t dxratio = Value(dx);
2693  Double_t dyratio = Value(dy);
2694  Double_t z = Value(zmax) * retunit;
2695  Double_t z1 = Value(zcut) * retunit;
2696 
2697  if (z1 <= 0) {
2698  Info("ElCone", "ERROR! Parameter zcut = %.12g is not set properly, elcone will not be imported.", z1);
2699  return node;
2700  }
2701  if (z1 > z) {
2702  z1 = z;
2703  }
2704  Double_t rx1 = (z + z1) * dxratio;
2705  Double_t ry1 = (z + z1) * dyratio;
2706  Double_t rx2 = (z - z1) * dxratio;
2707  Double_t sx = 1.;
2708  Double_t sy = ry1 / rx1;
2709  Double_t sz = 1.;
2710 
2711  TGeoCone *con = new TGeoCone(z1, 0, rx1, 0, rx2);
2712  TGeoScale *scl = new TGeoScale("", sx, sy, sz);
2713  TGeoScaledShape *shape = new TGeoScaledShape(NameShort(name), con, scl);
2714 
2715  fsolmap[name.Data()] = shape;
2716 
2717  return node;
2718 }
2719 
2720 ////////////////////////////////////////////////////////////////////////////////
2721 /// In the solids section of the GDML file, a Paraboloid may be declared.
2722 /// when the paraboloid keyword is found, this function is called, and the
2723 /// dimensions required are taken and stored, these are then bound and
2724 /// converted to type TGeoParaboloid and stored in fsolmap map using the name
2725 /// as its key.
2726 
2728 {
2729  TString lunit = fDefault_lunit.c_str();
2730  TString rlopos = "0";
2731  TString rhipos = "0";
2732  TString dzpos = "0";
2733  TString name = "";
2734  TString tempattr;
2735 
2736  while (attr != 0) {
2737 
2738  tempattr = gdml->GetAttrName(attr);
2739  tempattr.ToLower();
2740 
2741  if (tempattr == "name") {
2742  name = gdml->GetAttrValue(attr);
2743  } else if (tempattr == "rlo") {
2744  rlopos = gdml->GetAttrValue(attr);
2745  } else if (tempattr == "rhi") {
2746  rhipos = gdml->GetAttrValue(attr);
2747  } else if (tempattr == "dz") {
2748  dzpos = gdml->GetAttrValue(attr);
2749  } else if (tempattr == "lunit") {
2750  lunit = gdml->GetAttrValue(attr);
2751  }
2752 
2753  attr = gdml->GetNextAttr(attr);
2754  }
2755 
2756  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2757  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
2758  }
2759 
2760  Double_t retunit = GetScaleVal(lunit);
2761 
2762  Double_t rlo = Value(rlopos) * retunit;
2763  Double_t rhi = Value(rhipos) * retunit;
2764  Double_t dz = Value(dzpos) * retunit;
2765 
2766  TGeoParaboloid *paraboloid = new TGeoParaboloid(NameShort(name), rlo, rhi, dz);
2767 
2768  fsolmap[name.Data()] = paraboloid;
2769 
2770  return node;
2771 }
2772 
2773 ////////////////////////////////////////////////////////////////////////////////
2774 /// In the solids section of the GDML file, an Arb8 may be declared.
2775 /// when the arb8 keyword is found, this function is called, and the
2776 /// dimensions required are taken and stored, these are then bound and
2777 /// converted to type TGeoArb8 and stored in fsolmap map using the name
2778 /// as its key.
2779 
2781 {
2782  TString lunit = fDefault_lunit.c_str();
2783  TString v1xpos = "0";
2784  TString v1ypos = "0";
2785  TString v2xpos = "0";
2786  TString v2ypos = "0";
2787  TString v3xpos = "0";
2788  TString v3ypos = "0";
2789  TString v4xpos = "0";
2790  TString v4ypos = "0";
2791  TString v5xpos = "0";
2792  TString v5ypos = "0";
2793  TString v6xpos = "0";
2794  TString v6ypos = "0";
2795  TString v7xpos = "0";
2796  TString v7ypos = "0";
2797  TString v8xpos = "0";
2798  TString v8ypos = "0";
2799  TString dzpos = "0";
2800  TString name = "";
2801  TString tempattr;
2802 
2803  while (attr != 0) {
2804 
2805  tempattr = gdml->GetAttrName(attr);
2806  tempattr.ToLower();
2807 
2808  if (tempattr == "name") {
2809  name = gdml->GetAttrValue(attr);
2810  } else if (tempattr == "v1x") {
2811  v1xpos = gdml->GetAttrValue(attr);
2812  } else if (tempattr == "v1y") {
2813  v1ypos = gdml->GetAttrValue(attr);
2814  } else if (tempattr == "v2x") {
2815  v2xpos = gdml->GetAttrValue(attr);
2816  } else if (tempattr == "v2y") {
2817  v2ypos = gdml->GetAttrValue(attr);
2818  } else if (tempattr == "v3x") {
2819  v3xpos = gdml->GetAttrValue(attr);
2820  } else if (tempattr == "v3y") {
2821  v3ypos = gdml->GetAttrValue(attr);
2822  } else if (tempattr == "v4x") {
2823  v4xpos = gdml->GetAttrValue(attr);
2824  } else if (tempattr == "v4y") {
2825  v4ypos = gdml->GetAttrValue(attr);
2826  } else if (tempattr == "v5x") {
2827  v5xpos = gdml->GetAttrValue(attr);
2828  } else if (tempattr == "v5y") {
2829  v5ypos = gdml->GetAttrValue(attr);
2830  } else if (tempattr == "v6x") {
2831  v6xpos = gdml->GetAttrValue(attr);
2832  } else if (tempattr == "v6y") {
2833  v6ypos = gdml->GetAttrValue(attr);
2834  } else if (tempattr == "v7x") {
2835  v7xpos = gdml->GetAttrValue(attr);
2836  } else if (tempattr == "v7y") {
2837  v7ypos = gdml->GetAttrValue(attr);
2838  } else if (tempattr == "v8x") {
2839  v8xpos = gdml->GetAttrValue(attr);
2840  } else if (tempattr == "v8y") {
2841  v8ypos = gdml->GetAttrValue(attr);
2842  } else if (tempattr == "dz") {
2843  dzpos = gdml->GetAttrValue(attr);
2844  } else if (tempattr == "lunit") {
2845  lunit = gdml->GetAttrValue(attr);
2846  }
2847 
2848  attr = gdml->GetNextAttr(attr);
2849  }
2850 
2851  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2852  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
2853  }
2854 
2855  Double_t retunit = GetScaleVal(lunit);
2856 
2857  Double_t v1x = Value(v1xpos) * retunit;
2858  Double_t v1y = Value(v1ypos) * retunit;
2859  Double_t v2x = Value(v2xpos) * retunit;
2860  Double_t v2y = Value(v2ypos) * retunit;
2861  Double_t v3x = Value(v3xpos) * retunit;
2862  Double_t v3y = Value(v3ypos) * retunit;
2863  Double_t v4x = Value(v4xpos) * retunit;
2864  Double_t v4y = Value(v4ypos) * retunit;
2865  Double_t v5x = Value(v5xpos) * retunit;
2866  Double_t v5y = Value(v5ypos) * retunit;
2867  Double_t v6x = Value(v6xpos) * retunit;
2868  Double_t v6y = Value(v6ypos) * retunit;
2869  Double_t v7x = Value(v7xpos) * retunit;
2870  Double_t v7y = Value(v7ypos) * retunit;
2871  Double_t v8x = Value(v8xpos) * retunit;
2872  Double_t v8y = Value(v8ypos) * retunit;
2873  Double_t dz = Value(dzpos) * retunit;
2874 
2875  TGeoArb8 *arb8 = new TGeoArb8(NameShort(name), dz);
2876 
2877  arb8->SetVertex(0, v1x, v1y);
2878  arb8->SetVertex(1, v2x, v2y);
2879  arb8->SetVertex(2, v3x, v3y);
2880  arb8->SetVertex(3, v4x, v4y);
2881  arb8->SetVertex(4, v5x, v5y);
2882  arb8->SetVertex(5, v6x, v6y);
2883  arb8->SetVertex(6, v7x, v7y);
2884  arb8->SetVertex(7, v8x, v8y);
2885 
2886  fsolmap[name.Data()] = arb8;
2887 
2888  return node;
2889 }
2890 
2891 ////////////////////////////////////////////////////////////////////////////////
2892 /// In the solids section of the GDML file, a Tube may be declared.
2893 /// when the tube keyword is found, this function is called, and the
2894 /// dimensions required are taken and stored, these are then bound and
2895 /// converted to type TGeoTubeSeg and stored in fsolmap map using the name
2896 /// as its key.
2897 
2899 {
2900  TString lunit = fDefault_lunit.c_str();
2901  TString aunit = fDefault_aunit.c_str();
2902  TString rmin = "0";
2903  TString rmax = "0";
2904  TString z = "0";
2905  TString startphi = "0";
2906  TString deltaphi = "0";
2907  TString name = "";
2908  TString tempattr;
2909 
2910  while (attr != 0) {
2911 
2912  tempattr = gdml->GetAttrName(attr);
2913  tempattr.ToLower();
2914 
2915  if (tempattr == "name") {
2916  name = gdml->GetAttrValue(attr);
2917  } else if (tempattr == "rmin") {
2918  rmin = gdml->GetAttrValue(attr);
2919  } else if (tempattr == "rmax") {
2920  rmax = gdml->GetAttrValue(attr);
2921  } else if (tempattr == "z") {
2922  z = gdml->GetAttrValue(attr);
2923  } else if (tempattr == "lunit") {
2924  lunit = gdml->GetAttrValue(attr);
2925  } else if (tempattr == "aunit") {
2926  aunit = gdml->GetAttrValue(attr);
2927  } else if (tempattr == "startphi") {
2928  startphi = gdml->GetAttrValue(attr);
2929  } else if (tempattr == "deltaphi") {
2930  deltaphi = gdml->GetAttrValue(attr);
2931  }
2932 
2933  attr = gdml->GetNextAttr(attr);
2934  }
2935 
2936  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2937  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
2938  }
2939 
2940  Double_t retlunit = GetScaleVal(lunit);
2941  Double_t retaunit = GetScaleVal(aunit);
2942 
2943  Double_t rminline = Value(rmin) * retlunit;
2944  Double_t rmaxline = Value(rmax) * retlunit;
2945  Double_t zline = Value(z) * retlunit;
2946  Double_t startphideg = Value(startphi) * retaunit;
2947  Double_t deltaphideg = Value(deltaphi) * retaunit;
2948  Double_t endphideg = startphideg + deltaphideg;
2949 
2950  TGeoShape *tube = 0;
2951  if (deltaphideg < 360.)
2952  tube = new TGeoTubeSeg(NameShort(name), rminline, rmaxline, zline / 2, startphideg, endphideg);
2953  else
2954  tube = new TGeoTube(NameShort(name), rminline, rmaxline, zline / 2);
2955  fsolmap[name.Data()] = tube;
2956 
2957  return node;
2958 }
2959 
2960 ////////////////////////////////////////////////////////////////////////////////
2961 /// In the solids section of the GDML file, a Cut Tube may be declared.
2962 /// when the cutTube keyword is found, this function is called, and the
2963 /// dimensions required are taken and stored, these are then bound and
2964 /// converted to type TGeoCtub and stored in fsolmap map using the name
2965 /// as its key.
2966 
2968 {
2969  TString lunit = fDefault_lunit.c_str();
2970  TString aunit = fDefault_aunit.c_str();
2971  TString rmin = "0";
2972  TString rmax = "0";
2973  TString z = "0";
2974  TString startphi = "0";
2975  TString deltaphi = "0";
2976  TString lowX = "0";
2977  TString lowY = "0";
2978  TString lowZ = "0";
2979  TString highX = "0";
2980  TString highY = "0";
2981  TString highZ = "0";
2982  TString name = "";
2983  TString tempattr;
2984 
2985  while (attr != 0) {
2986 
2987  tempattr = gdml->GetAttrName(attr);
2988  tempattr.ToLower();
2989 
2990  if (tempattr == "name") {
2991  name = gdml->GetAttrValue(attr);
2992  } else if (tempattr == "rmin") {
2993  rmin = gdml->GetAttrValue(attr);
2994  } else if (tempattr == "rmax") {
2995  rmax = gdml->GetAttrValue(attr);
2996  } else if (tempattr == "z") {
2997  z = gdml->GetAttrValue(attr);
2998  } else if (tempattr == "lunit") {
2999  lunit = gdml->GetAttrValue(attr);
3000  } else if (tempattr == "aunit") {
3001  aunit = gdml->GetAttrValue(attr);
3002  } else if (tempattr == "startphi") {
3003  startphi = gdml->GetAttrValue(attr);
3004  } else if (tempattr == "deltaphi") {
3005  deltaphi = gdml->GetAttrValue(attr);
3006  } else if (tempattr == "lowx") {
3007  lowX = gdml->GetAttrValue(attr);
3008  } else if (tempattr == "lowy") {
3009  lowY = gdml->GetAttrValue(attr);
3010  } else if (tempattr == "lowz") {
3011  lowZ = gdml->GetAttrValue(attr);
3012  } else if (tempattr == "highx") {
3013  highX = gdml->GetAttrValue(attr);
3014  } else if (tempattr == "highy") {
3015  highY = gdml->GetAttrValue(attr);
3016  } else if (tempattr == "highz") {
3017  highZ = gdml->GetAttrValue(attr);
3018  }
3019 
3020  attr = gdml->GetNextAttr(attr);
3021  }
3022 
3023  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
3024  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3025  }
3026 
3027  Double_t retlunit = GetScaleVal(lunit);
3028  Double_t retaunit = GetScaleVal(aunit);
3029 
3030  Double_t rminline = Value(rmin) * retlunit;
3031  Double_t rmaxline = Value(rmax) * retlunit;
3032  Double_t zline = Value(z) * retlunit;
3033  Double_t startphiline = Value(startphi) * retaunit;
3034  Double_t deltaphiline = Value(deltaphi) * retaunit + startphiline;
3035  Double_t lowXline = Value(lowX) * retlunit;
3036  Double_t lowYline = Value(lowY) * retlunit;
3037  Double_t lowZline = Value(lowZ) * retlunit;
3038  Double_t highXline = Value(highX) * retlunit;
3039  Double_t highYline = Value(highY) * retlunit;
3040  Double_t highZline = Value(highZ) * retlunit;
3041 
3042  TGeoCtub *cuttube = new TGeoCtub(NameShort(name), rminline, rmaxline, zline / 2, startphiline, deltaphiline,
3043  lowXline, lowYline, lowZline, highXline, highYline, highZline);
3044 
3045  fsolmap[name.Data()] = cuttube;
3046 
3047  return node;
3048 }
3049 
3050 ////////////////////////////////////////////////////////////////////////////////
3051 /// In the solids section of the GDML file, a cone may be declared.
3052 /// when the cone keyword is found, this function is called, and the
3053 /// dimensions required are taken and stored, these are then bound and
3054 /// converted to type TGeoConSeg and stored in fsolmap map using the name
3055 /// as its key.
3056 
3058 {
3059  TString lunit = fDefault_lunit.c_str();
3060  TString aunit = fDefault_aunit.c_str();
3061  TString rmin1 = "0";
3062  TString rmax1 = "0";
3063  TString rmin2 = "0";
3064  TString rmax2 = "0";
3065  TString z = "0";
3066  TString startphi = "0";
3067  TString deltaphi = "0";
3068  TString name = "";
3069  TString tempattr;
3070 
3071  while (attr != 0) {
3072 
3073  tempattr = gdml->GetAttrName(attr);
3074  tempattr.ToLower();
3075 
3076  if (tempattr == "name") {
3077  name = gdml->GetAttrValue(attr);
3078  } else if (tempattr == "rmin1") {
3079  rmin1 = gdml->GetAttrValue(attr);
3080  } else if (tempattr == "rmax1") {
3081  rmax1 = gdml->GetAttrValue(attr);
3082  } else if (tempattr == "rmin2") {
3083  rmin2 = gdml->GetAttrValue(attr);
3084  } else if (tempattr == "rmax2") {
3085  rmax2 = gdml->GetAttrValue(attr);
3086  } else if (tempattr == "z") {
3087  z = gdml->GetAttrValue(attr);
3088  } else if (tempattr == "lunit") {
3089  lunit = gdml->GetAttrValue(attr);
3090  } else if (tempattr == "aunit") {
3091  aunit = gdml->GetAttrValue(attr);
3092  } else if (tempattr == "startphi") {
3093  startphi = gdml->GetAttrValue(attr);
3094  } else if (tempattr == "deltaphi") {
3095  deltaphi = gdml->GetAttrValue(attr);
3096  }
3097 
3098  attr = gdml->GetNextAttr(attr);
3099  }
3100 
3101  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
3102  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3103  }
3104 
3105  Double_t retlunit = GetScaleVal(lunit);
3106  Double_t retaunit = GetScaleVal(aunit);
3107 
3108  Double_t rmin1line = Value(rmin1) * retlunit;
3109  Double_t rmax1line = Value(rmax1) * retlunit;
3110  Double_t rmin2line = Value(rmin2) * retlunit;
3111  Double_t rmax2line = Value(rmax2) * retlunit;
3112  Double_t zline = Value(z) * retlunit;
3113  Double_t sphi = Value(startphi) * retaunit;
3114  Double_t dphi = Value(deltaphi) * retaunit;
3115  Double_t ephi = sphi + dphi;
3116 
3117  TGeoShape *cone = 0;
3118  if (dphi < 360.)
3119  cone = new TGeoConeSeg(NameShort(name), zline / 2, rmin1line, rmax1line, rmin2line, rmax2line, sphi, ephi);
3120  else
3121  cone = new TGeoCone(NameShort(name), zline / 2, rmin1line, rmax1line, rmin2line, rmax2line);
3122 
3123  fsolmap[name.Data()] = cone;
3124 
3125  return node;
3126 }
3127 
3128 ////////////////////////////////////////////////////////////////////////////////
3129 /// In the solids section of the GDML file, a Trap may be declared.
3130 /// when the trap keyword is found, this function is called, and the
3131 /// dimensions required are taken and stored, these are then bound and
3132 /// converted to type TGeoTrap and stored in fsolmap map using the name
3133 /// as its key.
3134 
3136 {
3137  TString lunit = fDefault_lunit.c_str();
3138  TString aunit = fDefault_aunit.c_str();
3139  TString x1 = "0";
3140  TString x2 = "0";
3141  TString x3 = "0";
3142  TString x4 = "0";
3143  TString y1 = "0";
3144  TString y2 = "0";
3145  TString z = "0";
3146  TString phi = "0";
3147  TString theta = "0";
3148  TString alpha1 = "0";
3149  TString alpha2 = "0";
3150  TString name = "";
3151  TString tempattr;
3152 
3153  while (attr != 0) {
3154 
3155  tempattr = gdml->GetAttrName(attr);
3156  tempattr.ToLower();
3157 
3158  if (tempattr == "name") {
3159  name = gdml->GetAttrValue(attr);
3160  } else if (tempattr == "x1") {
3161  x1 = gdml->GetAttrValue(attr);
3162  } else if (tempattr == "x2") {
3163  x2 = gdml->GetAttrValue(attr);
3164  } else if (tempattr == "x3") {
3165  x3 = gdml->GetAttrValue(attr);
3166  } else if (tempattr == "x4") {
3167  x4 = gdml->GetAttrValue(attr);
3168  } else if (tempattr == "y1") {
3169  y1 = gdml->GetAttrValue(attr);
3170  } else if (tempattr == "y2") {
3171  y2 = gdml->GetAttrValue(attr);
3172  } else if (tempattr == "z") {
3173  z = gdml->GetAttrValue(attr);
3174  } else if (tempattr == "lunit") {
3175  lunit = gdml->GetAttrValue(attr);
3176  } else if (tempattr == "aunit") {
3177  aunit = gdml->GetAttrValue(attr);
3178  } else if (tempattr == "phi") {
3179  phi = gdml->GetAttrValue(attr);
3180  } else if (tempattr == "theta") {
3181  theta = gdml->GetAttrValue(attr);
3182  } else if (tempattr == "alpha1") {
3183  alpha1 = gdml->GetAttrValue(attr);
3184  } else if (tempattr == "alpha2") {
3185  alpha2 = gdml->GetAttrValue(attr);
3186  }
3187 
3188  attr = gdml->GetNextAttr(attr);
3189  }
3190 
3191  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
3192  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3193  }
3194 
3195  Double_t retlunit = GetScaleVal(lunit);
3196  Double_t retaunit = GetScaleVal(aunit);
3197 
3198  Double_t x1line = Value(x1) * retlunit;
3199  Double_t x2line = Value(x2) * retlunit;
3200  Double_t x3line = Value(x3) * retlunit;
3201  Double_t x4line = Value(x4) * retlunit;
3202  Double_t y1line = Value(y1) * retlunit;
3203  Double_t y2line = Value(y2) * retlunit;
3204  Double_t zline = Value(z) * retlunit;
3205  Double_t philine = Value(phi) * retaunit;
3206  Double_t thetaline = Value(theta) * retaunit;
3207  Double_t alpha1line = Value(alpha1) * retaunit;
3208  Double_t alpha2line = Value(alpha2) * retaunit;
3209 
3210  TGeoTrap *trap = new TGeoTrap(NameShort(name), zline / 2, thetaline, philine, y1line / 2, x1line / 2, x2line / 2,
3211  alpha1line, y2line / 2, x3line / 2, x4line / 2, alpha2line);
3212 
3213  fsolmap[name.Data()] = trap;
3214 
3215  return node;
3216 }
3217 
3218 ////////////////////////////////////////////////////////////////////////////////
3219 /// In the solids section of the GDML file, a Trd may be declared.
3220 /// when the trd keyword is found, this function is called, and the
3221 /// dimensions required are taken and stored, these are then bound and
3222 /// converted to type TGeoTrd2 and stored in fsolmap map using the name
3223 /// as its key.
3224 
3226 {
3227  TString lunit = fDefault_lunit.c_str();
3228  TString x1 = "0";
3229  TString x2 = "0";
3230  TString y1 = "0";
3231  TString y2 = "0";
3232  TString z = "0";
3233  TString name = "";
3234  TString tempattr;
3235 
3236  while (attr != 0) {
3237 
3238  tempattr = gdml->GetAttrName(attr);
3239  tempattr.ToLower();
3240 
3241  if (tempattr == "name") {
3242  name = gdml->GetAttrValue(attr);
3243  } else if (tempattr == "x1") {
3244  x1 = gdml->GetAttrValue(attr);
3245  } else if (tempattr == "x2") {
3246  x2 = gdml->GetAttrValue(attr);
3247  } else if (tempattr == "y1") {
3248  y1 = gdml->GetAttrValue(attr);
3249  } else if (tempattr == "y2") {
3250  y2 = gdml->GetAttrValue(attr);
3251  } else if (tempattr == "z") {
3252  z = gdml->GetAttrValue(attr);
3253  } else if (tempattr == "lunit") {
3254  lunit = gdml->GetAttrValue(attr);
3255  }
3256 
3257  attr = gdml->GetNextAttr(attr);
3258  }
3259 
3260  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
3261  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3262  }
3263 
3264  Double_t retlunit = GetScaleVal(lunit);
3265 
3266  Double_t x1line = Value(x1) * retlunit;
3267  Double_t x2line = Value(x2) * retlunit;
3268  Double_t y1line = Value(y1) * retlunit;
3269  Double_t y2line = Value(y2) * retlunit;
3270  Double_t zline = Value(z) * retlunit;
3271 
3272  TGeoTrd2 *trd = new TGeoTrd2(NameShort(name), x1line / 2, x2line / 2, y1line / 2, y2line / 2, zline / 2);
3273 
3274  fsolmap[name.Data()] = trd;
3275 
3276  return node;
3277 }
3278 
3279 ////////////////////////////////////////////////////////////////////////////////
3280 /// In the solids section of the GDML file, a Polycone may be declared.
3281 /// when the polycone keyword is found, this function is called, and the
3282 /// dimensions required are taken and stored, these are then bound and
3283 /// converted to type TGeoPCon and stored in fsolmap map using the name
3284 /// as its key. Polycone has Zplanes, planes along the z axis specifying
3285 /// the rmin, rmax dimensions at that point along z.
3286 
3288 {
3289  TString lunit = fDefault_lunit.c_str();
3290  TString aunit = fDefault_aunit.c_str();
3291  TString rmin = "0";
3292  TString rmax = "0";
3293  TString z = "0";
3294  TString startphi = "0";
3295  TString deltaphi = "0";
3296  TString name = "";
3297  TString tempattr;
3298 
3299  while (attr != 0) {
3300 
3301  tempattr = gdml->GetAttrName(attr);
3302  tempattr.ToLower();
3303 
3304  if (tempattr == "name") {
3305  name = gdml->GetAttrValue(attr);
3306  } else if (tempattr == "lunit") {
3307  lunit = gdml->GetAttrValue(attr);
3308  } else if (tempattr == "aunit") {
3309  aunit = gdml->GetAttrValue(attr);
3310  } else if (tempattr == "startphi") {
3311  startphi = gdml->GetAttrValue(attr);
3312  } else if (tempattr == "deltaphi") {
3313  deltaphi = gdml->GetAttrValue(attr);
3314  }
3315  attr = gdml->GetNextAttr(attr);
3316  }
3317 
3318  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
3319  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3320  }
3321 
3322  Double_t retlunit = GetScaleVal(lunit);
3323  Double_t retaunit = GetScaleVal(aunit);
3324 
3325  // START TO LOOK THRU CHILD (ZPLANE) NODES...
3326 
3327  XMLNodePointer_t child = gdml->GetChild(node);
3328  int numplanes = 0;
3329 
3330  while (child != 0) {
3331  numplanes = numplanes + 1;
3332  child = gdml->GetNext(child);
3333  }
3334  if (numplanes < 2) {
3335  Fatal("Polycone", "Found less than 2 planes for polycone %s", name.Data());
3336  return child;
3337  }
3338 
3339  int cols;
3340  int i;
3341  cols = 3;
3342  double **table = new double *[numplanes];
3343  for (i = 0; i < numplanes; i++) {
3344  table[i] = new double[cols];
3345  }
3346 
3347  child = gdml->GetChild(node);
3348  int planeno = 0;
3349 
3350  while (child != 0) {
3351  if (strcmp(gdml->GetNodeName(child), "zplane") == 0) {
3352  // removed original dec
3353  Double_t rminline = 0;
3354  Double_t rmaxline = 0;
3355  Double_t zline = 0;
3356 
3357  attr = gdml->GetFirstAttr(child);
3358 
3359  while (attr != 0) {
3360  tempattr = gdml->GetAttrName(attr);
3361  tempattr.ToLower();
3362 
3363  if (tempattr == "rmin") {
3364  rmin = gdml->GetAttrValue(attr);
3365  rminline = Value(rmin) * retlunit;
3366  table[planeno][0] = rminline;
3367  } else if (tempattr == "rmax") {
3368  rmax = gdml->GetAttrValue(attr);
3369  rmaxline = Value(rmax) * retlunit;
3370  table[planeno][1] = rmaxline;
3371  } else if (tempattr == "z") {
3372  z = gdml->GetAttrValue(attr);
3373  zline = Value(z) * retlunit;
3374  table[planeno][2] = zline;
3375  }
3376  attr = gdml->GetNextAttr(attr);
3377  }
3378  }
3379  planeno = planeno + 1;
3380  child = gdml->GetNext(child);
3381  }
3382 
3383  Double_t startphiline = Value(startphi) * retaunit;
3384  Double_t deltaphiline = Value(deltaphi) * retaunit;
3385 
3386  TGeoPcon *poly = new TGeoPcon(NameShort(name), startphiline, deltaphiline, numplanes);
3387  Int_t zno = 0;
3388 
3389  for (int j = 0; j < numplanes; j++) {
3390  poly->DefineSection(zno, table[j][2], table[j][0], table[j][1]);
3391  zno = zno + 1;
3392  }
3393 
3394  fsolmap[name.Data()] = poly;
3395  for (i = 0; i < numplanes; i++) {
3396  delete[] table[i];
3397  }
3398  delete[] table;
3399 
3400  return node;
3401 }
3402 
3403 ////////////////////////////////////////////////////////////////////////////////
3404 /// In the solids section of the GDML file, a Polyhedra may be declared.
3405 /// when the polyhedra keyword is found, this function is called, and the
3406 /// dimensions required are taken and stored, these are then bound and
3407 /// converted to type TGeoPgon and stored in fsolmap map using the name
3408 /// as its key. Polycone has Zplanes, planes along the z axis specifying
3409 /// the rmin, rmax dimensions at that point along z.
3410 
3412 {
3413  TString lunit = fDefault_lunit.c_str();
3414  TString aunit = fDefault_aunit.c_str();
3415  TString rmin = "0";
3416  TString rmax = "0";
3417  TString z = "0";
3418  TString startphi = "0";
3419  TString deltaphi = "0";
3420  TString numsides = "1";
3421  TString name = "";
3422  TString tempattr;
3423 
3424  while (attr != 0) {
3425 
3426  tempattr = gdml->GetAttrName(attr);
3427  tempattr.ToLower();
3428 
3429  if (tempattr == "name") {
3430  name = gdml->GetAttrValue(attr);
3431  } else if (tempattr == "lunit") {
3432  lunit = gdml->GetAttrValue(attr);
3433  } else if (tempattr == "aunit") {
3434  aunit = gdml->GetAttrValue(attr);
3435  } else if (tempattr == "startphi") {
3436  startphi = gdml->GetAttrValue(attr);
3437  } else if (tempattr == "deltaphi") {
3438  deltaphi = gdml->GetAttrValue(attr);
3439  } else if (tempattr == "numsides") {
3440  numsides = gdml->GetAttrValue(attr);
3441  }
3442 
3443  attr = gdml->GetNextAttr(attr);
3444  }
3445 
3446  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
3447  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3448  }
3449 
3450  Double_t retlunit = GetScaleVal(lunit);
3451  Double_t retaunit = GetScaleVal(aunit);
3452 
3453  // START TO LOOK THRU CHILD (ZPLANE) NODES...
3454 
3455  XMLNodePointer_t child = gdml->GetChild(node);
3456  int numplanes = 0;
3457 
3458  while (child != 0) {
3459  numplanes = numplanes + 1;
3460  child = gdml->GetNext(child);
3461  }
3462  if (numplanes < 2) {
3463  Fatal("Polyhedra", "Found less than 2 planes for polyhedra %s", name.Data());
3464  return child;
3465  }
3466 
3467  int cols;
3468  int i;
3469  cols = 3;
3470  double **table = new double *[numplanes];
3471  for (i = 0; i < numplanes; i++) {
3472  table[i] = new double[cols];
3473  }
3474 
3475  child = gdml->GetChild(node);
3476  int planeno = 0;
3477 
3478  while (child != 0) {
3479  if (strcmp(gdml->GetNodeName(child), "zplane") == 0) {
3480 
3481  Double_t rminline = 0;
3482  Double_t rmaxline = 0;
3483  Double_t zline = 0;
3484  attr = gdml->GetFirstAttr(child);
3485 
3486  while (attr != 0) {
3487  tempattr = gdml->GetAttrName(attr);
3488  tempattr.ToLower();
3489 
3490  if (tempattr == "rmin") {
3491  rmin = gdml->GetAttrValue(attr);
3492  rminline = Value(rmin) * retlunit;
3493  table[planeno][0] = rminline;
3494  } else if (tempattr == "rmax") {
3495  rmax = gdml->GetAttrValue(attr);
3496  rmaxline = Value(rmax) * retlunit;
3497  table[planeno][1] = rmaxline;
3498  } else if (tempattr == "z") {
3499  z = gdml->GetAttrValue(attr);
3500  zline = Value(z) * retlunit;
3501  table[planeno][2] = zline;
3502  }
3503 
3504  attr = gdml->GetNextAttr(attr);
3505  }
3506  }
3507  planeno = planeno + 1;
3508  child = gdml->GetNext(child);
3509  }
3510 
3511  Double_t startphiline = Value(startphi) * retaunit;
3512  Double_t deltaphiline = Value(deltaphi) * retaunit;
3513  Int_t numsidesline = (int)Value(numsides);
3514 
3515  TGeoPgon *polyg = new TGeoPgon(NameShort(name), startphiline, deltaphiline, numsidesline, numplanes);
3516  Int_t zno = 0;
3517 
3518  for (int j = 0; j < numplanes; j++) {
3519  polyg->DefineSection(zno, table[j][2], table[j][0], table[j][1]);
3520  zno = zno + 1;
3521  }
3522 
3523  fsolmap[name.Data()] = polyg;
3524  for (i = 0; i < numplanes; i++) {
3525  delete[] table[i];
3526  }
3527  delete[] table;
3528 
3529  return node;
3530 }
3531 
3532 ////////////////////////////////////////////////////////////////////////////////
3533 /// In the solids section of the GDML file, a Sphere may be declared.
3534 /// when the sphere keyword is found, this function is called, and the
3535 /// dimensions required are taken and stored, these are then bound and
3536 /// converted to type TGeoSphere and stored in fsolmap map using the name
3537 /// as its key.
3538 
3540 {
3541  TString lunit = fDefault_lunit.c_str();
3542  TString aunit = fDefault_aunit.c_str();
3543  TString rmin = "0";
3544  TString rmax = "0";
3545  TString startphi = "0";
3546  TString deltaphi = "0";
3547  TString starttheta = "0";
3548  TString deltatheta = "0";
3549  TString name = "";
3550  TString tempattr;
3551 
3552  while (attr != 0) {
3553  tempattr = gdml->GetAttrName(attr);
3554  tempattr.ToLower();
3555 
3556  if (tempattr == "name") {
3557  name = gdml->GetAttrValue(attr);
3558  } else if (tempattr == "rmin") {
3559  rmin = gdml->GetAttrValue(attr);
3560  } else if (tempattr == "rmax") {
3561  rmax = gdml->GetAttrValue(attr);
3562  } else if (tempattr == "lunit") {
3563  lunit = gdml->GetAttrValue(attr);
3564  } else if (tempattr == "aunit") {
3565  aunit = gdml->GetAttrValue(attr);
3566  } else if (tempattr == "startphi") {
3567  startphi = gdml->GetAttrValue(attr);
3568  } else if (tempattr == "deltaphi") {
3569  deltaphi = gdml->GetAttrValue(attr);
3570  } else if (tempattr == "starttheta") {
3571  starttheta = gdml->GetAttrValue(attr);
3572  } else if (tempattr == "deltatheta") {
3573  deltatheta = gdml->GetAttrValue(attr);
3574  }
3575 
3576  attr = gdml->GetNextAttr(attr);
3577  }
3578 
3579  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
3580  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3581  }
3582 
3583  Double_t retlunit = GetScaleVal(lunit);
3584  Double_t retaunit = GetScaleVal(aunit);
3585 
3586  Double_t rminline = Value(rmin) * retlunit;
3587  Double_t rmaxline = Value(rmax) * retlunit;
3588  Double_t startphiline = Value(startphi) * retaunit;
3589  Double_t deltaphiline = startphiline + Value(deltaphi) * retaunit;
3590  Double_t startthetaline = Value(starttheta) * retaunit;
3591  Double_t deltathetaline = startthetaline + Value(deltatheta) * retaunit;
3592 
3593  TGeoSphere *sphere =
3594  new TGeoSphere(NameShort(name), rminline, rmaxline, startthetaline, deltathetaline, startphiline, deltaphiline);
3595 
3596  fsolmap[name.Data()] = sphere;
3597 
3598  return node;
3599 }
3600 
3601 ////////////////////////////////////////////////////////////////////////////////
3602 /// In the solids section of the GDML file, a Torus may be declared.
3603 /// when the torus keyword is found, this function is called, and the
3604 /// dimensions required are taken and stored, these are then bound and
3605 /// converted to type TGeoTorus and stored in fsolmap map using the name
3606 /// as its key.
3607 
3609 {
3610  TString lunit = fDefault_lunit.c_str();
3611  TString aunit = fDefault_aunit.c_str();
3612  TString rmin = "0";
3613  TString rmax = "0";
3614  TString rtor = "0";
3615  TString startphi = "0";
3616  TString deltaphi = "0";
3617  TString name = "";
3618  TString tempattr;
3619 
3620  while (attr != 0) {
3621 
3622  tempattr = gdml->GetAttrName(attr);
3623  tempattr.ToLower();
3624 
3625  if (tempattr == "name") {
3626  name = gdml->GetAttrValue(attr);
3627  } else if (tempattr == "rmin") {
3628  rmin = gdml->GetAttrValue(attr);
3629  } else if (tempattr == "rmax") {
3630  rmax = gdml->GetAttrValue(attr);
3631  } else if (tempattr == "rtor") {
3632  rtor = gdml->GetAttrValue(attr);
3633  } else if (tempattr == "lunit") {
3634  lunit = gdml->GetAttrValue(attr);
3635  } else if (tempattr == "aunit") {
3636  aunit = gdml->GetAttrValue(attr);
3637  } else if (tempattr == "startphi") {
3638  startphi = gdml->GetAttrValue(attr);
3639  } else if (tempattr == "deltaphi") {
3640  deltaphi = gdml->GetAttrValue(attr);
3641  }
3642 
3643  attr = gdml->GetNextAttr(attr);
3644  }
3645 
3646  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
3647  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3648  }
3649 
3650  Double_t retlunit = GetScaleVal(lunit);
3651  Double_t retaunit = GetScaleVal(aunit);
3652 
3653  Double_t rminline = Value(rmin) * retlunit;
3654  Double_t rmaxline = Value(rmax) * retlunit;
3655  Double_t rtorline = Value(rtor) * retlunit;
3656  Double_t startphiline = Value(startphi) * retaunit;
3657  Double_t deltaphiline = Value(deltaphi) * retaunit;
3658 
3659  TGeoTorus *torus = new TGeoTorus(NameShort(name), rtorline, rminline, rmaxline, startphiline, deltaphiline);
3660 
3661  fsolmap[name.Data()] = torus;
3662 
3663  return node;
3664 }
3665 
3666 ////////////////////////////////////////////////////////////////////////////////
3667 /// In the solids section of the GDML file, a Hype may be declared.
3668 /// when the hype keyword is found, this function is called, and the
3669 /// dimensions required are taken and stored, these are then bound and
3670 /// converted to type TGeoHype and stored in fsolmap map using the name
3671 /// as its key.
3672 
3674 {
3675  TString lunit = fDefault_lunit.c_str();
3676  TString aunit = fDefault_aunit.c_str();
3677  TString rmin = "0";
3678  TString rmax = "0";
3679  TString z = "0";
3680  TString inst = "0";
3681  TString outst = "0";
3682  TString name = "";
3683  TString tempattr;
3684 
3685  while (attr != 0) {
3686  tempattr = gdml->GetAttrName(attr);
3687  tempattr.ToLower();
3688 
3689  if (tempattr == "name") {
3690  name = gdml->GetAttrValue(attr);
3691  } else if (tempattr == "rmin") {
3692  rmin = gdml->GetAttrValue(attr);
3693  } else if (tempattr == "rmax") {
3694  rmax = gdml->GetAttrValue(attr);
3695  } else if (tempattr == "z") {
3696  z = gdml->GetAttrValue(attr);
3697  } else if (tempattr == "lunit") {
3698  lunit = gdml->GetAttrValue(attr);
3699  } else if (tempattr == "aunit") {
3700  aunit = gdml->GetAttrValue(attr);
3701  } else if (tempattr == "inst") {
3702  inst = gdml->GetAttrValue(attr);
3703  } else if (tempattr == "outst") {
3704  outst = gdml->GetAttrValue(attr);
3705  }
3706 
3707  attr = gdml->GetNextAttr(attr);
3708  }
3709 
3710  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
3711  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3712  }
3713 
3714  Double_t retlunit = GetScaleVal(lunit);
3715  Double_t retaunit = GetScaleVal(aunit);
3716 
3717  Double_t rminline = Value(rmin) * retlunit;
3718  Double_t rmaxline = Value(rmax) * retlunit;
3719  Double_t zline = Value(z) * retlunit;
3720  Double_t instline = Value(inst) * retaunit;
3721  Double_t outstline = Value(outst) * retaunit;
3722 
3723  TGeoHype *hype = new TGeoHype(NameShort(name), rminline, instline, rmaxline, outstline, zline / 2);
3724 
3725  fsolmap[name.Data()] = hype;
3726 
3727  return node;
3728 }
3729 
3730 ////////////////////////////////////////////////////////////////////////////////
3731 /// In the solids section of the GDML file, a Para may be declared.
3732 /// when the para keyword is found, this function is called, and the
3733 /// dimensions required are taken and stored, these are then bound and
3734 /// converted to type TGeoPara and stored in fsolmap map using the name
3735 /// as its key.
3736 
3738 {
3739  TString lunit = fDefault_lunit.c_str();
3740  TString aunit = fDefault_aunit.c_str();
3741  TString x = "0";
3742  TString y = "0";
3743  TString z = "0";
3744  TString phi = "0";
3745  TString theta = "0";
3746  TString alpha = "0";
3747  TString name = "";
3748  TString tempattr;
3749 
3750  while (attr != 0) {
3751 
3752  tempattr = gdml->GetAttrName(attr);
3753  tempattr.ToLower();
3754 
3755  if (tempattr == "name") {
3756  name = gdml->GetAttrValue(attr);
3757  } else if (tempattr == "x") {
3758  x = gdml->GetAttrValue(attr);
3759  } else if (tempattr == "y") {
3760  y = gdml->GetAttrValue(attr);
3761  } else if (tempattr == "z") {
3762  z = gdml->GetAttrValue(attr);
3763  } else if (tempattr == "lunit") {
3764  lunit = gdml->GetAttrValue(attr);
3765  } else if (tempattr == "aunit") {
3766  aunit = gdml->GetAttrValue(attr);
3767  } else if (tempattr == "phi") {
3768  phi = gdml->GetAttrValue(attr);
3769  } else if (tempattr == "theta") {
3770  theta = gdml->GetAttrValue(attr);
3771  } else if (tempattr == "alpha") {
3772  alpha = gdml->GetAttrValue(attr);
3773  }
3774 
3775  attr = gdml->GetNextAttr(attr);
3776  }
3777 
3778  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
3779  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3780  }
3781 
3782  Double_t retlunit = GetScaleVal(lunit);
3783  Double_t retaunit = GetScaleVal(aunit);
3784 
3785  Double_t xline = Value(x) * retlunit;
3786  Double_t yline = Value(y) * retlunit;
3787  Double_t zline = Value(z) * retlunit;
3788  Double_t philine = Value(phi) * retaunit;
3789  Double_t alphaline = Value(alpha) * retaunit;
3790  Double_t thetaline = Value(theta) * retaunit;
3791 
3792  TGeoPara *para = new TGeoPara(NameShort(name), xline / 2, yline / 2, zline / 2, alphaline, thetaline, philine);
3793 
3794  fsolmap[name.Data()] = para;
3795 
3796  return node;
3797 }
3798 
3799 ////////////////////////////////////////////////////////////////////////////////
3800 /// In the solids section of the GDML file, a TwistTrap may be declared.
3801 /// when the twistedtrap keyword is found, this function is called, and the
3802 /// dimensions required are taken and stored, these are then bound and
3803 /// converted to type TGeoGTra and stored in fsolmap map using the name
3804 /// as its key.
3805 
3807 {
3808  TString lunit = fDefault_lunit.c_str();
3809  TString aunit = fDefault_aunit.c_str();
3810  TString x1 = "0";
3811  TString x2 = "0";
3812  TString x3 = "0";
3813  TString x4 = "0";
3814  TString y1 = "0";
3815  TString y2 = "0";
3816  TString z = "0";
3817  TString phi = "0";
3818  TString theta = "0";
3819  TString alpha1 = "0";
3820  TString alpha2 = "0";
3821  TString twist = "0";
3822  TString name = "";
3823  TString tempattr;
3824 
3825  while (attr != 0) {
3826 
3827  tempattr = gdml->GetAttrName(attr);
3828  tempattr.ToLower();
3829 
3830  if (tempattr == "name") {
3831  name = gdml->GetAttrValue(attr);
3832  } else if (tempattr == "x1") {
3833  x1 = gdml->GetAttrValue(attr);
3834  } else if (tempattr == "x2") {
3835  x2 = gdml->GetAttrValue(attr);
3836  } else if (tempattr == "x3") {
3837  x3 = gdml->GetAttrValue(attr);
3838  } else if (tempattr == "x4") {
3839  x4 = gdml->GetAttrValue(attr);
3840  } else if (tempattr == "y1") {
3841  y1 = gdml->GetAttrValue(attr);
3842  } else if (tempattr == "y2") {
3843  y2 = gdml->GetAttrValue(attr);
3844  } else if (tempattr == "z") {
3845  z = gdml->GetAttrValue(attr);
3846  } else if (tempattr == "lunit") {
3847  lunit = gdml->GetAttrValue(attr);
3848  } else if (tempattr == "aunit") {
3849  aunit = gdml->GetAttrValue(attr);
3850  } else if (tempattr == "phi") {
3851  phi = gdml->GetAttrValue(attr);
3852  } else if (tempattr == "theta") {
3853  theta = gdml->GetAttrValue(attr);
3854  } else if (tempattr == "alph") { // gdml schema knows only alph attribute
3855  alpha1 = gdml->GetAttrValue(attr);
3856  alpha2 = alpha1;
3857  //} else if (tempattr == "alpha2") {
3858  // alpha2 = gdml->GetAttrValue(attr);
3859  } else if (tempattr == "phitwist") {
3860  twist = gdml->GetAttrValue(attr);
3861  }
3862 
3863  attr = gdml->GetNextAttr(attr);
3864  }
3865 
3866  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
3867  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3868  }
3869 
3870  Double_t retlunit = GetScaleVal(lunit);
3871  Double_t retaunit = GetScaleVal(aunit);
3872 
3873  Double_t x1line = Value(x1) * retlunit;
3874  Double_t x2line = Value(x2) * retlunit;
3875  Double_t x3line = Value(x3) * retlunit;
3876  Double_t x4line = Value(x4) * retlunit;
3877  Double_t y1line = Value(y1) * retlunit;
3878  Double_t y2line = Value(y2) * retlunit;
3879  Double_t zline = Value(z) * retlunit;
3880  Double_t philine = Value(phi) * retaunit;
3881  Double_t thetaline = Value(theta) * retaunit;
3882  Double_t alpha1line = Value(alpha1) * retaunit;
3883  Double_t alpha2line = Value(alpha2) * retaunit;
3884  Double_t twistline = Value(twist) * retaunit;
3885 
3886  TGeoGtra *twtrap = new TGeoGtra(NameShort(name), zline / 2, thetaline, philine, twistline, y1line / 2, x1line / 2,
3887  x2line / 2, alpha1line, y2line / 2, x3line / 2, x4line / 2, alpha2line);
3888 
3889  fsolmap[name.Data()] = twtrap;
3890 
3891  return node;
3892 }
3893 
3894 ////////////////////////////////////////////////////////////////////////////////
3895 /// In the solids section of the GDML file, a ElTube may be declared.
3896 /// when the eltube keyword is found, this function is called, and the
3897 /// dimensions required are taken and stored, these are then bound and
3898 /// converted to type TGeoEltu and stored in fsolmap map using the name
3899 /// as its key.
3900 
3902 {
3903  TString lunit = fDefault_lunit.c_str();
3904  TString xpos = "0";
3905  TString ypos = "0";
3906  TString zpos = "0";
3907  TString name = "";
3908  TString tempattr;
3909 
3910  while (attr != 0) {
3911 
3912  tempattr = gdml->GetAttrName(attr);
3913  tempattr.ToLower();
3914 
3915  if (tempattr == "name") {
3916  name = gdml->GetAttrValue(attr);
3917  } else if (tempattr == "dx") {
3918  xpos = gdml->GetAttrValue(attr);
3919  } else if (tempattr == "dy") {
3920  ypos = gdml->GetAttrValue(attr);
3921  } else if (tempattr == "dz") {
3922  zpos = gdml->GetAttrValue(attr);
3923  } else if (tempattr == "lunit") {
3924  lunit = gdml->GetAttrValue(attr);
3925  }
3926 
3927  attr = gdml->GetNextAttr(attr);
3928  }
3929 
3930  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
3931  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3932  }
3933 
3934  Double_t retunit = GetScaleVal(lunit);
3935 
3936  Double_t xline = Value(xpos) * retunit;
3937  Double_t yline = Value(ypos) * retunit;
3938  Double_t zline = Value(zpos) * retunit;
3939 
3940  TGeoEltu *eltu = new TGeoEltu(NameShort(name), xline, yline, zline);
3941 
3942  fsolmap[name.Data()] = eltu;
3943 
3944  return node;
3945 }
3946 ////////////////////////////////////////////////////////////////////////////////
3947 /// In the solids section of the GDML file, an Orb may be declared.
3948 /// when the orb keyword is found, this function is called, and the
3949 /// dimensions required are taken and stored, these are then bound and
3950 /// converted to type TGeoSphere and stored in fsolmap map using the name
3951 /// as its key.
3952 
3954 {
3955  TString lunit = fDefault_lunit.c_str();
3956  TString r = "0";
3957  TString name = "";
3958  TString tempattr;
3959 
3960  while (attr != 0) {
3961 
3962  tempattr = gdml->GetAttrName(attr);
3963  tempattr.ToLower();
3964 
3965  if (tempattr == "name") {
3966  name = gdml->GetAttrValue(attr);
3967  } else if (tempattr == "r") {
3968  r = gdml->GetAttrValue(attr);
3969  } else if (tempattr == "lunit") {
3970  lunit = gdml->GetAttrValue(attr);
3971  }
3972 
3973  attr = gdml->GetNextAttr(attr);
3974  }
3975 
3976  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
3977  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3978  }
3979 
3980  Double_t retunit = GetScaleVal(lunit);
3981 
3982  Double_t rline = Value(r) * retunit;
3983 
3984  TGeoSphere *orb = new TGeoSphere(NameShort(name), 0, rline, 0, 180, 0, 360);
3985 
3986  fsolmap[name.Data()] = orb;
3987 
3988  return node;
3989 }
3990 
3991 ////////////////////////////////////////////////////////////////////////////////
3992 /// In the solids section of the GDML file, an Xtru may be declared.
3993 /// when the xtru keyword is found, this function is called, and the
3994 /// dimensions required are taken and stored, these are then bound and
3995 /// converted to type TGeoXtru and stored in fsolmap map using the name
3996 /// as its key. The xtru has child nodes of either 'twoDimVertex'or
3997 /// 'section'. These two nodes define the real structure of the shape.
3998 /// The twoDimVertex's define the x,y sizes of a vertice. The section links
3999 /// the vertice to a position within the xtru.
4000 
4002 {
4003  TString lunit = fDefault_lunit.c_str();
4004  // TString aunit = "rad";
4005  TString x = "0";
4006  TString y = "0";
4007  TString zorder = "0";
4008  TString zpos = "0";
4009  TString xoff = "0";
4010  TString yoff = "0";
4011  TString scale = "0";
4012  TString name = "";
4013  TString tempattr;
4014 
4015  while (attr != 0) {
4016 
4017  tempattr = gdml->GetAttrName(attr);
4018  tempattr.ToLower();
4019 
4020  if (tempattr == "name") {
4021  name = gdml->GetAttrValue(attr);
4022  } else if (tempattr == "lunit") {
4023  lunit = gdml->GetAttrValue(attr);
4024  }
4025 
4026  attr = gdml->GetNextAttr(attr);
4027  }
4028 
4029  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
4030  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
4031  }
4032 
4033  Double_t retlunit = GetScaleVal(lunit);
4034 
4035  // START TO LOOK THRU CHILD NODES...
4036 
4037  XMLNodePointer_t child = gdml->GetChild(node);
4038  int nosects = 0;
4039  int noverts = 0;
4040 
4041  while (child != 0) {
4042  tempattr = gdml->GetNodeName(child);
4043 
4044  if (tempattr == "twoDimVertex") {
4045  noverts = noverts + 1;
4046  } else if (tempattr == "section") {
4047  nosects = nosects + 1;
4048  }
4049 
4050  child = gdml->GetNext(child);
4051  }
4052 
4053  if (nosects < 2 || noverts < 3) {
4054  Fatal("Xtru", "Invalid number of sections/vertices found forxtru %s", name.Data());
4055  return child;
4056  }
4057 
4058  // Build the dynamic arrays..
4059  int cols;
4060  int i;
4061  double *vertx = new double[noverts];
4062  double *verty = new double[noverts];
4063  cols = 5;
4064  double **section = new double *[nosects];
4065  for (i = 0; i < nosects; i++) {
4066  section[i] = new double[cols];
4067  }
4068 
4069  child = gdml->GetChild(node);
4070  int sect = 0;
4071  int vert = 0;
4072 
4073  while (child != 0) {
4074  if (strcmp(gdml->GetNodeName(child), "twoDimVertex") == 0) {
4075  Double_t xline = 0;
4076  Double_t yline = 0;
4077 
4078  attr = gdml->GetFirstAttr(child);
4079 
4080  while (attr != 0) {
4081  tempattr = gdml->GetAttrName(attr);
4082 
4083  if (tempattr == "x") {
4084  x = gdml->GetAttrValue(attr);
4085  xline = Value(x) * retlunit;
4086  vertx[vert] = xline;
4087  } else if (tempattr == "y") {
4088  y = gdml->GetAttrValue(attr);
4089  yline = Value(y) * retlunit;
4090  verty[vert] = yline;
4091  }
4092 
4093  attr = gdml->GetNextAttr(attr);
4094  }
4095 
4096  vert = vert + 1;
4097  }
4098 
4099  else if (strcmp(gdml->GetNodeName(child), "section") == 0) {
4100 
4101  Double_t zposline = 0;
4102  Double_t xoffline = 0;
4103  Double_t yoffline = 0;
4104 
4105  attr = gdml->GetFirstAttr(child);
4106 
4107  while (attr != 0) {
4108  tempattr = gdml->GetAttrName(attr);
4109 
4110  if (tempattr == "zOrder") {
4111  zorder = gdml->GetAttrValue(attr);
4112  section[sect][0] = Value(zorder);
4113  } else if (tempattr == "zPosition") {
4114  zpos = gdml->GetAttrValue(attr);
4115  zposline = Value(zpos) * retlunit;
4116  section[sect][1] = zposline;
4117  } else if (tempattr == "xOffset") {
4118  xoff = gdml->GetAttrValue(attr);
4119  xoffline = Value(xoff) * retlunit;
4120  section[sect][2] = xoffline;
4121  } else if (tempattr == "yOffset") {
4122  yoff = gdml->GetAttrValue(attr);
4123  yoffline = Value(yoff) * retlunit;
4124  section[sect][3] = yoffline;
4125  } else if (tempattr == "scalingFactor") {
4126  scale = gdml->GetAttrValue(attr);
4127  section[sect][4] = Value(scale);
4128  }
4129 
4130  attr = gdml->GetNextAttr(attr);
4131  }
4132 
4133  sect = sect + 1;
4134  }
4135  child = gdml->GetNext(child);
4136  }
4137 
4138  TGeoXtru *xtru = new TGeoXtru(nosects);
4139  xtru->SetName(NameShort(name));
4140  xtru->DefinePolygon(vert, vertx, verty);
4141 
4142  for (int j = 0; j < sect; j++) {
4143  xtru->DefineSection((int)section[j][0], section[j][1], section[j][2], section[j][3], section[j][4]);
4144  }
4145 
4146  fsolmap[name.Data()] = xtru;
4147  delete[] vertx;
4148  delete[] verty;
4149  for (i = 0; i < nosects; i++) {
4150  delete[] section[i];
4151  }
4152  delete[] section;
4153  return node;
4154 }
4155 
4156 ////////////////////////////////////////////////////////////////////////////////
4157 /// In the solids section of the GDML file, a tessellated shape may be declared.
4158 /// When the tessellated keyword is found, this function is called, and the
4159 /// triangular/quadrangular facets are read, creating the corresponding
4160 /// TGeoTessellated object stored in fsolmap map using the name
4161 /// as its key.
4162 
4164 {
4165  TString lunit = fDefault_lunit.c_str();
4166  TString name, vname, type;
4167  TString tempattr;
4168 
4169  while (attr != nullptr) {
4170  tempattr = gdml->GetAttrName(attr);
4171  tempattr.ToLower();
4172  if (tempattr == "name") {
4173  name = gdml->GetAttrValue(attr);
4174  }
4175  attr = gdml->GetNextAttr(attr);
4176  }
4177 
4178  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
4179  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
4180  }
4181 
4182  auto tsl = new TGeoTessellated(NameShort(name));
4183  TGeoTranslation *pos = nullptr;
4184  Tessellated::Vertex_t vertices[4];
4185 
4186  auto SetVertex = [&](int i, TGeoTranslation *trans) {
4187  if (trans == nullptr)
4188  return;
4189  const double *tr = trans->GetTranslation();
4190  vertices[i].Set(tr[0], tr[1], tr[2]);
4191  };
4192 
4193  auto AddTriangularFacet = [&](bool relative) {
4194  if (relative) {
4195  vertices[2] += vertices[0] + vertices[1];
4196  vertices[1] += vertices[0];
4197  }
4198  tsl->AddFacet(vertices[0], vertices[1], vertices[2]);
4199  };
4200 
4201  auto AddQuadrangularFacet = [&](bool relative) {
4202  if (relative) {
4203  vertices[3] += vertices[0] + vertices[1] + vertices[2];
4204  vertices[2] += vertices[0] + vertices[1];
4205  vertices[1] += vertices[0];
4206  }
4207  tsl->AddFacet(vertices[0], vertices[1], vertices[2], vertices[3]);
4208  };
4209 
4210  // Get facet attributes
4211  XMLNodePointer_t child = gdml->GetChild(node);
4212  while (child != nullptr) {
4213  tempattr = gdml->GetNodeName(child);
4214  tempattr.ToLower();
4215  if (tempattr == "triangular") {
4216  attr = gdml->GetFirstAttr(child);
4217 
4218  while (attr != nullptr) {
4219  tempattr = gdml->GetAttrName(attr);
4220 
4221  if (tempattr == "vertex1") {
4222  vname = gdml->GetAttrValue(attr);
4223  if (fposmap.find(vname.Data()) != fposmap.end())
4224  pos = fposmap[vname.Data()];
4225  else
4226  Fatal("Tessellated", "Vertex %s not defined", vname.Data());
4227  SetVertex(0, pos);
4228  }
4229 
4230  else if (tempattr == "vertex2") {
4231  vname = gdml->GetAttrValue(attr);
4232  if (fposmap.find(vname.Data()) != fposmap.end())
4233  pos = fposmap[vname.Data()];
4234  else
4235  Fatal("Tessellated", "Vertex %s not defined", vname.Data());
4236  SetVertex(1, pos);
4237  }
4238 
4239  else if (tempattr == "vertex3") {
4240  vname = gdml->GetAttrValue(attr);
4241  if (fposmap.find(vname.Data()) != fposmap.end())
4242  pos = fposmap[vname.Data()];
4243  else
4244  Fatal("Tessellated", "Vertex %s not defined", vname.Data());
4245  SetVertex(2, pos);
4246  }
4247 
4248  else if (tempattr == "type") {
4249  type = gdml->GetAttrValue(attr);
4250  type.ToLower();
4251  bool relative = (type == "relative") ? true : false;
4252  AddTriangularFacet(relative);
4253  }
4254 
4255  attr = gdml->GetNextAttr(attr);
4256  }
4257 
4258  }
4259 
4260  else if (tempattr == "quadrangular") {
4261  attr = gdml->GetFirstAttr(child);
4262 
4263  while (attr != nullptr) {
4264  tempattr = gdml->GetAttrName(attr);
4265 
4266  if (tempattr == "vertex1") {
4267  vname = gdml->GetAttrValue(attr);
4268  if (fposmap.find(vname.Data()) != fposmap.end())
4269  pos = fposmap[vname.Data()];
4270  else
4271  Fatal("Tessellated", "Vertex %s not defined", vname.Data());
4272  SetVertex(0, pos);
4273  }
4274 
4275  else if (tempattr == "vertex2") {
4276  vname = gdml->GetAttrValue(attr);
4277  if (fposmap.find(vname.Data()) != fposmap.end())
4278  pos = fposmap[vname.Data()];
4279  else
4280  Fatal("Tessellated", "Vertex %s not defined", vname.Data());
4281  SetVertex(1, pos);
4282  }
4283 
4284  else if (tempattr == "vertex3") {
4285  vname = gdml->GetAttrValue(attr);
4286  if (fposmap.find(vname.Data()) != fposmap.end())
4287  pos = fposmap[vname.Data()];
4288  else
4289  Fatal("Tessellated", "Vertex %s not defined", vname.Data());
4290  SetVertex(2, pos);
4291  }
4292 
4293  else if (tempattr == "vertex4") {
4294  vname = gdml->GetAttrValue(attr);
4295  if (fposmap.find(vname.Data()) != fposmap.end())
4296  pos = fposmap[vname.Data()];
4297  else
4298  Fatal("Tessellated", "Vertex %s not defined", vname.Data());
4299  SetVertex(3, pos);
4300  }
4301 
4302  else if (tempattr == "type") {
4303  type = gdml->GetAttrValue(attr);
4304  type.ToLower();
4305  bool relative = (type == "relative") ? true : false;
4306  AddQuadrangularFacet(relative);
4307  }
4308 
4309  attr = gdml->GetNextAttr(attr);
4310  }
4311  }
4312  child = gdml->GetNext(child);
4313  }
4314  tsl->CloseShape(false);
4315 
4316  fsolmap[name.Data()] = tsl;
4317 
4318  return node;
4319 }
4320 
4321 ////////////////////////////////////////////////////////////////////////////////
4322 /// In the solids section of the GDML file, a Reflected Solid may be
4323 /// declared when the ReflectedSolid keyword is found, this function
4324 /// is called. The rotation, position and scale for the reflection are
4325 /// applied to a matrix that is then stored in the class object
4326 /// TGDMLRefl. This is then stored in the map freflsolidmap, with
4327 /// the reflection name as a reference. also the name of the solid to
4328 /// be reflected is stored in a map called freflectmap with the reflection
4329 /// name as a reference.
4330 
4332 {
4333  std::cout << "WARNING! The reflectedSolid is obsolete! Use scale transformation instead!" << std::endl;
4334 
4335  TString sx = "0";
4336  TString sy = "0";
4337  TString sz = "0";
4338  TString rx = "0";
4339  TString ry = "0";
4340  TString rz = "0";
4341  TString dx = "0";
4342  TString dy = "0";
4343  TString dz = "0";
4344  TString name = "0";
4345  TString solid = "0";
4346  TString tempattr;
4347 
4348  while (attr != 0) {
4349 
4350  tempattr = gdml->GetAttrName(attr);
4351  tempattr.ToLower();
4352 
4353  if (tempattr == "name") {
4354  name = gdml->GetAttrValue(attr);
4355  } else if (tempattr == "sx") {
4356  sx = gdml->GetAttrValue(attr);
4357  } else if (tempattr == "sy") {
4358  sy = gdml->GetAttrValue(attr);
4359  } else if (tempattr == "sz") {
4360  sz = gdml->GetAttrValue(attr);
4361  } else if (tempattr == "rx") {
4362  rx = gdml->GetAttrValue(attr);
4363  } else if (tempattr == "ry") {
4364  ry = gdml->GetAttrValue(attr);
4365  } else if (tempattr == "rz") {
4366  rz = gdml->GetAttrValue(attr);
4367  } else if (tempattr == "dx") {
4368  dx = gdml->GetAttrValue(attr);
4369  } else if (tempattr == "dy") {
4370  dy = gdml->GetAttrValue(attr);
4371  } else if (tempattr == "dz") {
4372  dz = gdml->GetAttrValue(attr);
4373  } else if (tempattr == "solid") {
4374  solid = gdml->GetAttrValue(attr);
4375  }
4376  attr = gdml->GetNextAttr(attr);
4377  }
4378 
4379  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
4380  name = TString::Format("%s_%s", name.Data(), fCurrentFile);
4381  }
4382  if ((strcmp(fCurrentFile, fStartFile)) != 0) {
4383  solid = TString::Format("%s_%s", solid.Data(), fCurrentFile);
4384  }
4385 
4386  TGeoRotation *rot = new TGeoRotation();
4387  rot->RotateZ(-(Value(rz)));
4388  rot->RotateY(-(Value(ry)));
4389  rot->RotateX(-(Value(rx)));
4390 
4391  if (atoi(sx) == -1) {
4392  rot->ReflectX(kTRUE);
4393  }
4394  if (atoi(sy) == -1) {
4395  rot->ReflectY(kTRUE);
4396  }
4397  if (atoi(sz) == -1) {
4398  rot->ReflectZ(kTRUE);
4399  }
4400 
4401  TGeoCombiTrans *relf_matx = new TGeoCombiTrans(Value(dx), Value(dy), Value(dz), rot);
4402 
4403  TGDMLRefl *reflsol = new TGDMLRefl(NameShort(name), solid, relf_matx);
4404  freflsolidmap[name.Data()] = reflsol;
4405  freflectmap[name.Data()] = solid;
4406 
4407  return node;
4408 }
4409 
4410 /** \class TGDMLRefl
4411 \ingroup Geometry_gdml
4412 
4413 This class is a helper class for TGDMLParse. It assists in the
4414 reflection process. This process takes a previously defined solid
4415 and can reflect the matrix of it. This class stores the name of the
4416 reflected solid, along with the name of the solid that is being
4417 reflected, and finally the reflected solid's matrix. This is then
4418 recalled when the volume is used in the structure part of the gdml
4419 file.
4420 
4421 */
4422 
4424 
4425 ////////////////////////////////////////////////////////////////////////////////
4426 /// This constructor method stores the values brought in as params.
4427 
4428 TGDMLRefl::TGDMLRefl(const char *name, const char *solid, TGeoMatrix *matrix)
4429 {
4430  fNameS = name;
4431  fSolid = solid;
4432  fMatrix = matrix;
4433 }
4434 
4435 ////////////////////////////////////////////////////////////////////////////////
4436 /// This accessor method returns the matrix.
4437 
4439 {
4440  return fMatrix;
4441 }
static constexpr double us
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
XMLNodePointer_t UsrProcess(TXMLEngine *gdml, XMLNodePointer_t node)
User data to be processed.
XMLNodePointer_t ConProcess(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the define section of the GDML file, constants can be declared.
Definition: TGDMLParse.cxx:452
Mixtures of elements.
Definition: TGeoMaterial.h:150
Spherical shell class.
Definition: TGeoSphere.h:17
static constexpr double cm
Cylindrical tube class.
Definition: TGeoTube.h:17
MatrixMap fmatrices
Map containing values of constants declared in the file.
Definition: TGDMLParse.h:215
XMLNodePointer_t TwistTrap(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, a TwistTrap may be declared.
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
Double_t Eval(Double_t x) const
The manager class for any TGeo geometry.
Definition: TGeoManager.h:42
RotMap frotmap
Map containing position names and the TGeoTranslation for it.
Definition: TGDMLParse.h:200
Box class.
Definition: TGeoBBox.h:17
auto * m
Definition: textangle.C:8
Volume assemblies.
Definition: TGeoVolume.h:300
static constexpr double mm
XMLNodePointer_t Trd(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, a Trd may be declared.
Table of elements.
Definition: TGeoElement.h:369
MatMap fmatmap
Map containing element names and the TGeoElement for it.
Definition: TGDMLParse.h:204
TGeoVolume * fWorld
Definition: TGDMLParse.h:99
Collectable string class.
Definition: TObjString.h:28
void MultiplyLeft(const TGeoMatrix *left)
multiply to the left with an other transformation if right is identity matrix, just return ...
Gtra is a twisted trapezoid.
Definition: TGeoArb8.h:145
Geometrical transformation package.
Definition: TGeoMatrix.h:40
XMLNodePointer_t Paraboloid(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, a Paraboloid may be declared.
void AddBorderSurface(TGeoBorderSurface *surf)
Add border surface;.
#define g(i)
Definition: RSha256.hxx:105
static constexpr double rad
Int_t Z() const
Definition: TGeoElement.h:73
XMLNodePointer_t Xtru(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, an Xtru may be declared.
A polycone.
Definition: TGeoPcon.h:17
virtual const Double_t * GetRotationMatrix() const =0
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
A polygone.
Definition: TGeoPgon.h:19
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
XMLNodePointer_t Reflection(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, a Reflected Solid may be declared when the ReflectedSolid key...
EleMap felemap
Map containing isotope names and the TGeoIsotope for it.
Definition: TGDMLParse.h:203
PvolMap fpvolmap
Map containing volume names and the TGeoVolume for it.
Definition: TGDMLParse.h:209
TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
Definition: TGeoVolume.h:42
TGeoElementTable * GetElementTable()
Returns material table. Creates it if not existing.
Tessellated solid class.
virtual void RotateX(Double_t angle)
Rotate about X axis of the master frame with angle expressed in degrees.
XMLNodePointer_t Cone(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, a cone may be declared.
void SetTranslation(const Double_t *vect)
Definition: TGeoMatrix.h:462
void Add(TObject *obj)
This function may not be used (but we need to provide it since it is a pure virtual in TCollection)...
Definition: TMap.cxx:53
Torus segment class.
Definition: TGeoTorus.h:17
Class describing translations.
Definition: TGeoMatrix.h:121
virtual void DefineSection(Int_t snum, Double_t z, Double_t x0=0., Double_t y0=0., Double_t scale=1.)
defines z position of a section plane, rmin and rmax at this z.
Definition: TGeoXtru.cxx:691
Int_t AddRegion(TGeoRegion *region)
Add a new region of volumes.
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
Int_t GetId() const
Definition: TGeoMedium.h:48
TString GetScale(const char *unit)
Throughout the GDML file, a unit can de specified.
Definition: TGDMLParse.cxx:668
XMLNodePointer_t GetNext(XMLNodePointer_t xmlnode, Bool_t realnode=kTRUE)
return next to xmlnode node if realnode==kTRUE, any special nodes in between will be skipped ...
Basic string class.
Definition: TString.h:131
Matrix class used for computing global transformations Should NOT be used for node definition...
Definition: TGeoMatrix.h:420
Base class describing materials.
Definition: TGeoMaterial.h:29
void Multiply(const TGeoMatrix *right)
multiply to the right with an other transformation if right is identity matrix, just return ...
XMLNodePointer_t IsoProcess(TXMLEngine *gdml, XMLNodePointer_t node, XMLNodePointer_t parentn)
In the material section of the GDML file, an isotope may be declared.
Definition: TGDMLParse.cxx:989
#define f(i)
Definition: RSha256.hxx:104
XMLNodePointer_t Polycone(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, a Polycone may be declared.
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1125
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
void SetSkipComments(Bool_t on=kTRUE)
Definition: TXMLEngine.h:48
void ReplayCreation(const TGeoVolume *other)
Recreate the content of the other volume without pointer copying.
TGeoIsotope * FindIsotope(const char *name) const
Find existing isotope by name. Not optimized for a big number of isotopes.
A shape scaled by a TGeoScale transformation.
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition: fillpatterns.C:1
XMLNodePointer_t MatrixProcess(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the define section of the GDML file, matrices These are referenced by other GDML tags...
Definition: TGDMLParse.cxx:554
virtual const Double_t * GetScale() const
Definition: TGeoMatrix.h:279
XMLAttrPointer_t GetNextAttr(XMLAttrPointer_t xmlattr)
return next attribute in the list
Definition: TXMLEngine.cxx:675
TGeoHMatrix Inverse() const
Return a temporary inverse of this.
Definition: TGeoMatrix.cxx:976
void FreeDoc(XMLDocPointer_t xmldoc)
frees allocated document data and deletes document itself
Paraboloid class.
std::string fDefault_lunit
Definition: TGDMLParse.h:105
static ESurfaceModel StringToModel(const char *model)
static constexpr double km
double GetScaleVal(const char *unit)
Throughout the GDML file, a unit can de specified.
Definition: TGDMLParse.cxx:713
TList * GetListOfMaterials() const
Definition: TGeoManager.h:490
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:575
TObjArray * GetNodes()
Definition: TGeoVolume.h:165
ReflectionsMap freflectmap
Map containing placed volume names and the TGeoNode for it.
Definition: TGDMLParse.h:210
Int_t GetNdaughters() const
Definition: TGeoVolume.h:347
TGeoMaterial * GetMaterial(const char *matname) const
Search for a named material. All trailing blanks stripped.
TList * GetListOfMedia() const
Definition: TGeoManager.h:491
const char * fCurrentFile
Definition: TGDMLParse.h:104
XMLNodePointer_t SclProcess(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the define section of the GDML file, rotations can be declared.
Definition: TGDMLParse.cxx:945
This class contains the implementation of the GDML parser associated to all the supported GDML elemen...
Definition: TGDMLParse.h:95
TObject * Last() const
Return the object in the last filled slot. Returns 0 if no entries.
Definition: TObjArray.cxx:505
bool AddProperty(const char *property, const char *ref)
TGeoMatrix * fMatrix
solid name being reflected
Definition: TGDMLParse.h:49
static const double x2[5]
XMLNodePointer_t BooSolid(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr, int num)
In the solid section of the GDML file, boolean solids can be declared.
virtual void ReflectY(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to ZX.
Double_t x[n]
Definition: legend1.C:17
double Evaluate(const char *evalline)
Takes a string containing a mathematical expression and returns the value of the expression.
Definition: TGDMLParse.cxx:401
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2311
A phi segment of a conical tube.
Definition: TGeoCone.h:98
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
void * XMLDocPointer_t
Definition: TXMLEngine.h:20
TGeoMatrix * GetMatrix()
This accessor method returns the matrix.
TCanvas * fractions()
Definition: fractions.C:1
TGeoVolume * GDMLReadFile(const char *filename="test.gdml")
Creates the new instance of the XMLEngine called &#39;gdml&#39;, using the filename >> then parses the file a...
Definition: TGDMLParse.cxx:159
This class is used in the process of reading and writing the GDML "matrix" tag.
Definition: TGDMLMatrix.h:34
static constexpr double twopi
void AddIsotope(TGeoIsotope *isotope, Double_t relativeAbundance)
Add an isotope for this element. All isotopes have to be isotopes of the same element.
Base class for chemical elements.
Definition: TGeoElement.h:36
void DefineConstants()
Define constant expressions used.
Definition: TGDMLParse.cxx:484
static const double x4[22]
XMLNodePointer_t Arb8(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, an Arb8 may be declared.
TGeoMedium * GetMedium() const
Definition: TGeoVolume.h:171
double Value(const char *svalue) const
Convert number in string format to double value.
Definition: TGDMLParse.cxx:753
XMLNodePointer_t BorderSurfaceProcess(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the structure section of the GDML file, border surfaces can be declared.
virtual void SetVertex(Int_t vnum, Double_t x, Double_t y)
Set values for a given vertex.
Definition: TGeoArb8.cxx:1255
TRAP is a general trapezoid, i.e.
Definition: TGeoArb8.h:91
static constexpr double s
void AddSkinSurface(TGeoSkinSurface *surf)
Add skin surface;.
virtual void RotateY(Double_t angle)
Rotate about Y axis of the master frame with angle expressed in degrees.
FileMap ffilemap
Map containing reflected volume names and the solid ref for it.
Definition: TGDMLParse.h:213
constexpr Double_t Pi()
Definition: TMath.h:38
ConstMap fconsts
Map containing files parsed during entire parsing, with their world volume name.
Definition: TGDMLParse.h:214
XMLNodePointer_t Tessellated(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, a tessellated shape may be declared.
virtual const Double_t * GetTranslation() const
Definition: TGeoMatrix.h:160
virtual TGeoVolume * Divide(const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step, Int_t numed=0, Option_t *option="")
Division a la G3.
auto * lv
Definition: textalign.C:5
This class is a helper class for TGDMLParse.
Definition: TGDMLParse.h:30
const char * GetNodeName(XMLNodePointer_t xmlnode)
returns name of xmlnode
XMLNodePointer_t CutTube(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, a Cut Tube may be declared.
virtual void AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat=0, Option_t *option="")
Add a TGeoNode to the list of nodes.
Definition: TGeoVolume.cxx:931
A doubly linked list.
Definition: TList.h:44
XMLNodePointer_t Sphere(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, a Sphere may be declared.
virtual const Double_t * GetRotationMatrix() const
Definition: TGeoMatrix.h:230
XMLNodePointer_t Orb(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, an Orb may be declared.
Class handling Boolean composition of shapes.
void AddElement(Double_t a, Double_t z, Double_t weight)
add an element to the mixture using fraction by weight Check if the element is already defined ...
A trapezoid with both x and y lengths varying with z.
Definition: TGeoTrd2.h:17
XMLNodePointer_t PosProcess(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the define section of the GDML file, positions can be declared.
Definition: TGDMLParse.cxx:836
Parallelepiped class.
Definition: TGeoPara.h:17
XMLNodePointer_t Torus(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, a Torus may be declared.
int isnan(double)
TGDMLParse()
Constructor.
Definition: TGDMLParse.cxx:128
XMLNodePointer_t Box(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, a box may be declared.
XMLNodePointer_t Ellipsoid(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, an ellipsoid may be declared.
Base abstract class for all shapes.
Definition: TGeoShape.h:25
void ShiftToNext(XMLNodePointer_t &xmlnode, Bool_t realnode=kTRUE)
shifts specified node to next if realnode==kTRUE, any special nodes in between will be skipped ...
ROOT::R::TRInterface & r
Definition: Object.C:4
static constexpr double MeV
void Set(size_t r, size_t c, Double_t a)
Definition: TGDMLMatrix.cxx:71
std::map< std::string, double > FracMap
Definition: TGDMLParse.h:196
Class describing rotation + translation.
Definition: TGeoMatrix.h:291
XMLNodePointer_t Para(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, a Para may be declared.
XMLNodePointer_t Trap(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, a Trap may be declared.
auto * a
Definition: textangle.C:12
Bool_t AddProperty(const char *property, Double_t value)
Add a user-defined property. Returns true if added, false if existing.
const char * fStartFile
Definition: TGDMLParse.h:103
The Formula class.
Definition: TFormula.h:83
static constexpr double ms
Regions are groups of volumes having a common set of user tracking cuts.
Definition: TGeoRegion.h:36
static constexpr double mg
Hyperboloid class defined by 5 parameters.
Definition: TGeoHype.h:17
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
const char * fSolid
reflected solid name
Definition: TGDMLParse.h:48
const char * GetAttrValue(XMLAttrPointer_t xmlattr)
return value of attribute
Definition: TXMLEngine.cxx:697
Double_t GetProperty(const char *name, Bool_t *error=nullptr) const
Get a user-defined property.
TGeoElement * FindElement(const char *name) const
Search an element by symbol or full name Exact matching.
XMLNodePointer_t RotProcess(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the define section of the GDML file, rotations can be declared.
Definition: TGDMLParse.cxx:888
XMLAttrPointer_t GetFirstAttr(XMLNodePointer_t xmlnode)
return first attribute in the list, namespace (if exists) will be skipped
Definition: TXMLEngine.cxx:659
TXMLEngine * fFileEngine[20]
Definition: TGDMLParse.h:102
XMLNodePointer_t Hype(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, a Hype may be declared.
void * XMLNodePointer_t
Definition: TXMLEngine.h:17
IsoMap fisomap
Map containing scale names and the TGeoScale for it.
Definition: TGDMLParse.h:202
constexpr Double_t Na()
Avogadro constant (Avogadro&#39;s Number) in .
Definition: TMath.h:283
virtual void AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat=0, Option_t *option="")
Add a component to the assembly.
static constexpr double keV
bool AddProperty(const char *property, const char *ref)
void SetUserExtension(TGeoExtension *ext)
Connect user-defined extension to the volume.
virtual void RotateZ(Double_t angle)
Rotate about Z axis of the master frame with angle expressed in degrees.
XMLNodePointer_t TopProcess(TXMLEngine *gdml, XMLNodePointer_t node)
In the setup section of the GDML file, the top volume need to be declared.
Class describing rotations.
Definition: TGeoMatrix.h:174
const Bool_t kFALSE
Definition: RtypesCore.h:88
XMLNodePointer_t OpticalSurfaceProcess(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, optical surfaces can be defined.
Definition: TGDMLParse.cxx:603
Bool_t HasAttr(XMLNodePointer_t xmlnode, const char *name)
checks if node has attribute of specified name
Definition: TXMLEngine.cxx:533
static constexpr double kg
TGeoMedium * GetMedium(const char *medium) const
Search for a named tracking medium. All trailing blanks stripped.
include TDocParser_001 C image html pict1_TDocParser_001 png width
Definition: TDocParser.cxx:121
A tube segment cut with 2 planes.
Definition: TGeoTube.h:168
const char * fNameS
Definition: TGDMLParse.h:47
#define d(i)
Definition: RSha256.hxx:102
XMLDocPointer_t ParseFile(const char *filename, Int_t maxbuf=100000)
Parses content of file and tries to produce xml structures.
An extrusion with fixed outline shape in x-y and a sequence of z extents (segments).
Definition: TGeoXtru.h:21
void * XMLAttrPointer_t
Definition: TXMLEngine.h:19
Class describing scale transformations.
Definition: TGeoMatrix.h:244
static const double x1[5]
XMLNodePointer_t Polyhedra(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, a Polyhedra may be declared.
#define ClassImp(name)
Definition: Rtypes.h:365
static ESurfaceFinish StringToFinish(const char *finish)
bool AddConstProperty(const char *property, const char *ref)
virtual void ReflectX(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to YZ.
R__EXTERN TGeoManager * gGeoManager
Definition: TGeoManager.h:601
virtual Bool_t IsMixture() const
Definition: TGeoMaterial.h:124
double Double_t
Definition: RtypesCore.h:55
const char * GetAttr(XMLNodePointer_t xmlnode, const char *name)
returns value of attribute for xmlnode
Definition: TXMLEngine.cxx:549
virtual void ReflectZ(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to XY.
TMap implements an associative array of (key,value) pairs using a THashTable for efficient retrieval ...
Definition: TMap.h:40
int type
Definition: TGX11.cxx:120
Conical tube class.
Definition: TGeoCone.h:17
MixMap fmixmap
Map containing medium names and the TGeoMedium for it.
Definition: TGDMLParse.h:206
std::string fDefault_aunit
Definition: TGDMLParse.h:106
Double_t y[n]
Definition: legend1.C:17
XMLNodePointer_t QuantityProcess(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the define section of the GDML file, quantities can be declared.
Definition: TGDMLParse.cxx:523
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
void AddVolume(TGeoVolume *vol)
Definition: TGeoRegion.h:49
Reference counted extension which has a pointer to and owns a user defined TObject.
Definition: TGeoExtension.h:36
Int_t SetAxis(const char *axisString)
When using the &#39;divide&#39; process in the geometry this function sets the variable &#39;axis&#39; depending on w...
Definition: TGDMLParse.cxx:411
An arbitrary trapezoid with less than 8 vertices standing on two parallel planes perpendicular to Z a...
Definition: TGeoArb8.h:17
TGeoOpticalSurface * GetOpticalSurface(const char *name) const
Get optical surface with a given name;.
Media are used to store properties related to tracking and which are useful only when using geometry ...
Definition: TGeoMedium.h:23
Bool_t IsNull() const
Definition: TString.h:402
const char * NameShort(const char *name)
This function looks thru a string for the chars &#39;0x&#39; next to each other, when it finds this...
Definition: TGDMLParse.cxx:436
void SetMatrix(const Double_t *rot)
Definition: TGeoMatrix.h:225
MedMap fmedmap
Map containing material names and the TGeoMaterial for it.
Definition: TGDMLParse.h:205
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
constexpr Double_t RadToDeg()
Conversion from radian to degree: .
Definition: TMath.h:74
SclMap fsclmap
Map containing rotation names and the TGeoRotation for it.
Definition: TGDMLParse.h:201
SolMap fsolmap
Map containing mixture names and the TGeoMixture for it.
Definition: TGDMLParse.h:207
const char * ParseGDML(TXMLEngine *gdml, XMLNodePointer_t node)
This function recursively moves thru the DOM tree of the GDML file.
Definition: TGDMLParse.cxx:194
A node represent a volume positioned inside another.They store links to both volumes and to the TGeoM...
Definition: TGeoNode.h:39
ReflVolMap freflvolmap
Map containing reflection names and the TGDMLRefl for it - containing refl matrix.
Definition: TGDMLParse.h:212
XMLNodePointer_t SkinSurfaceProcess(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the structure section of the GDML file, skin surfaces can be declared.
VolMap fvolmap
Map containing solid names and the TGeoShape for it.
Definition: TGDMLParse.h:208
virtual void Add(TObject *obj)
Definition: TList.h:87
XMLNodePointer_t GetChild(XMLNodePointer_t xmlnode, Bool_t realnode=kTRUE)
returns first child of xmlnode
Base class for Boolean operations between two shapes.
Definition: TGeoBoolNode.h:24
Elliptical tube class.
Definition: TGeoEltu.h:17
XMLNodePointer_t GetParent(XMLNodePointer_t xmlnode)
returns parent of xmlnode
static constexpr double pi
void SetRotation(const Double_t *matrix)
Definition: TGeoMatrix.h:463
XMLNodePointer_t DocGetRootElement(XMLDocPointer_t xmldoc)
returns root node of document
XMLNodePointer_t ElTube(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, a ElTube may be declared.
static constexpr double eV
static constexpr double ns
virtual void DefineSection(Int_t snum, Double_t z, Double_t rmin, Double_t rmax)
Defines z position of a section plane, rmin and rmax at this z.
Definition: TGeoPcon.cxx:618
virtual Double_t GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi) const =0
R__EXTERN Int_t gDebug
Definition: Rtypes.h:91
ReflSolidMap freflsolidmap
Map containing reflection names and the Solid name ir references to.
Definition: TGDMLParse.h:211
Definition: first.py:1
XMLNodePointer_t MatProcess(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr, int z)
In the materials section of the GDML file, materials can be declared.
XMLNodePointer_t EleProcess(TXMLEngine *gdml, XMLNodePointer_t node, XMLNodePointer_t parentn, Bool_t hasIsotopes, Bool_t hasIsotopesExtended)
When the element keyword is found, this function is called, and the name and values of the element ar...
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:908
TGeoShape * GetShape() const
Definition: TGeoVolume.h:186
XMLNodePointer_t Tube(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, a Tube may be declared.
void AddCut(const char *name, Double_t cut)
Add cut to the region.
Definition: TGeoRegion.cxx:75
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
XMLNodePointer_t AssProcess(TXMLEngine *gdml, XMLNodePointer_t node)
In the structure section of the GDML file, assembly volumes can be declared.
XMLNodePointer_t VolProcess(TXMLEngine *gdml, XMLNodePointer_t node)
In the structure section of the GDML file, volumes can be declared.
static constexpr double deg
static constexpr double GeV
const char * GetAttrName(XMLAttrPointer_t xmlattr)
return name of the attribute
Definition: TXMLEngine.cxx:686
const Bool_t kTRUE
Definition: RtypesCore.h:87
const Int_t n
Definition: legend1.C:16
static ESurfaceType StringToType(const char *type)
TString fWorldName
Definition: TGDMLParse.h:98
void AddGDMLMatrix(TGDMLMatrix *mat)
Add GDML matrix;.
char name[80]
Definition: TGX11.cxx:109
XMLNodePointer_t ElCone(TXMLEngine *gdml, XMLNodePointer_t node, XMLAttrPointer_t attr)
In the solids section of the GDML file, an elliptical cone may be declared.
void AddOpticalSurface(TGeoOpticalSurface *optsurf)
Add optical surface;.
static EDefaultUnits GetDefaultUnits()
Bool_t DefinePolygon(Int_t nvert, const Double_t *xv, const Double_t *yv)
Creates the polygon representing the blueprint of any Xtru section.
Definition: TGeoXtru.cxx:658
void SetMatrixAsString(const char *mat)
Definition: TGDMLMatrix.h:46
PosMap fposmap
Definition: TGDMLParse.h:199
static const double x3[11]
static constexpr double second
const char * Data() const
Definition: TString.h:364
A phi segment of a tube.
Definition: TGeoTube.h:88