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