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