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