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