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 = "";
1314
1315 if (z == 1) {
1316 Double_t a = 0;
1317 Double_t d = 0;
1318
1319 name = gdml->GetAttr(node, "name");
1320 local_name = name;
1321 if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1322 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
1323 }
1324
1325 while (child != nullptr) {
1326 attr = gdml->GetFirstAttr(child);
1327
1328 if ((strcmp(gdml->GetNodeName(child), "property")) == 0) {
1329 TNamed *property = new TNamed();
1330 while (attr != nullptr) {
1331 tempattr = gdml->GetAttrName(attr);
1332 tempattr.ToLower();
1333
1334 if (tempattr == "name") {
1335 property->SetName(gdml->GetAttrValue(attr));
1336 } else if (tempattr == "ref") {
1337 property->SetTitle(gdml->GetAttrValue(attr));
1338 TGDMLMatrix *matrix = fmatrices[property->GetTitle()];
1339 if (matrix)
1340 properties.Add(property);
1341 else {
1342 Bool_t error = false;
1343 gGeoManager->GetProperty(property->GetTitle(), &error);
1344 if (error)
1345 Error("MatProcess", "Reference %s for material %s not found", property->GetTitle(),
1346 name.Data());
1347 else
1349 }
1350 }
1351 attr = gdml->GetNextAttr(attr);
1352 }
1353 }
1354
1355 if ((strcmp(gdml->GetNodeName(child), "atom")) == 0) {
1356 while (attr != nullptr) {
1357 tempattr = gdml->GetAttrName(attr);
1358 tempattr.ToLower();
1359
1360 if (tempattr == "value") {
1361 a = Value(gdml->GetAttrValue(attr));
1362 }
1363 attr = gdml->GetNextAttr(attr);
1364 }
1365 }
1366
1367 if ((strcmp(gdml->GetNodeName(child), "D")) == 0) {
1368 while (attr != nullptr) {
1369 tempattr = gdml->GetAttrName(attr);
1370 tempattr.ToLower();
1371
1372 if (tempattr == "value") {
1373 d = Value(gdml->GetAttrValue(attr));
1374 }
1375 attr = gdml->GetNextAttr(attr);
1376 }
1377 }
1378 child = gdml->GetNext(child);
1379 }
1380 // still in the is Z else...but not in the while..
1381 // CHECK FOR CONSTANTS
1382 tempconst = gdml->GetAttr(node, "Z");
1383
1385
1387 // deal with special case - Z of vacuum is always 0
1388 tmpname.ToLower();
1389 if (tmpname == "vacuum") {
1390 valZ = 0;
1391 }
1393 mat = mgr->GetMaterial(mat_name);
1394 if (!mat) {
1395 mat = new TGeoMaterial(mat_name, a, valZ, d);
1396 } else {
1397 Info("TGDMLParse", "Re-use existing material: %s", mat->GetName());
1398 }
1399 if (properties.GetSize()) {
1401 TIter next(&properties);
1402 while ((property = (TNamed *)next()))
1403 mat->AddProperty(property->GetName(), property->GetTitle());
1404 }
1405 if (constproperties.GetSize()) {
1407 TIter next(&constproperties);
1408 while ((property = (TNamed *)next()))
1409 mat->AddConstProperty(property->GetName(), property->GetTitle());
1410 }
1411 mixflag = 0;
1412 // Note: Object(name, title) corresponds to Element(formula, name)
1413 TGeoElement *mat_ele = tab_ele->FindElement(mat_name);
1414 // We cannot use elements with Z = 0, so we expect a user definition
1415 if (mat_ele && mat_ele->Z() == 0)
1416 mat_ele = nullptr;
1417
1418 if (!mat_ele) {
1420 } else if (gDebug >= 2) {
1421 Info("TGDMLParse", "Re-use existing material-element: %s", mat_ele->GetName());
1422 }
1423 felemap[local_name.Data()] = mat_ele;
1424 }
1425
1426 else if (z == 0) {
1427 while (child != nullptr) {
1428 attr = gdml->GetFirstAttr(child);
1429
1430 if ((strcmp(gdml->GetNodeName(child), "property")) == 0) {
1431 TNamed *property = new TNamed();
1432 while (attr != nullptr) {
1433 tempattr = gdml->GetAttrName(attr);
1434 tempattr.ToLower();
1435
1436 if (tempattr == "name") {
1437 property->SetName(gdml->GetAttrValue(attr));
1438 } else if (tempattr == "ref") {
1439 property->SetTitle(gdml->GetAttrValue(attr));
1440 TGDMLMatrix *matrix = fmatrices[property->GetTitle()];
1441 if (matrix)
1442 properties.Add(property);
1443 else {
1444 Bool_t error = false;
1445 gGeoManager->GetProperty(property->GetTitle(), &error);
1446 if (error)
1447 Error("MatProcess", "Reference %s for material %s not found", property->GetTitle(),
1448 name.Data());
1449 else
1451 }
1452 }
1453 attr = gdml->GetNextAttr(attr);
1454 }
1455 }
1456 if ((strcmp(gdml->GetNodeName(child), "fraction")) == 0) {
1457 Double_t n = 0;
1458 TString ref = "";
1459 ncompo = ncompo + 1;
1460
1461 while (attr != nullptr) {
1462 tempattr = gdml->GetAttrName(attr);
1463 tempattr.ToLower();
1464
1465 if (tempattr == "n") {
1466 n = Value(gdml->GetAttrValue(attr));
1467 } else if (tempattr == "ref") {
1468 ref = gdml->GetAttrValue(attr);
1469 if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1470 ref = TString::Format("%s_%s", ref.Data(), fCurrentFile);
1471 }
1472 }
1473 attr = gdml->GetNextAttr(attr);
1474 }
1475 fracmap[ref.Data()] = n;
1476 }
1477
1478 else if ((strcmp(gdml->GetNodeName(child), "composite")) == 0) {
1479 composite = kTRUE;
1480 Double_t n = 0;
1481 TString ref = "";
1482 ncompo = ncompo + 1;
1483
1484 while (attr != nullptr) {
1485 tempattr = gdml->GetAttrName(attr);
1486 tempattr.ToLower();
1487 if (tempattr == "n") {
1488 n = Value(gdml->GetAttrValue(attr));
1489 } else if (tempattr == "ref") {
1490 ref = gdml->GetAttrValue(attr);
1491 if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1492 ref = TString::Format("%s_%s", ref.Data(), fCurrentFile);
1493 }
1494 }
1495 attr = gdml->GetNextAttr(attr);
1496 }
1497 fracmap[ref.Data()] = n;
1498 } else if ((strcmp(gdml->GetNodeName(child), "D")) == 0) {
1499 while (attr != nullptr) {
1500 tempattr = gdml->GetAttrName(attr);
1501 tempattr.ToLower();
1502
1503 if (tempattr == "value") {
1504 density = Value(gdml->GetAttrValue(attr));
1505 }
1506 attr = gdml->GetNextAttr(attr);
1507 }
1508 }
1509 child = gdml->GetNext(child);
1510 }
1511 // still in the not Z else...but not in the while..
1512
1513 name = gdml->GetAttr(node, "name");
1514 local_name = name;
1515 if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1516 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
1517 }
1518 // mix = new TGeoMixture(NameShort(name), 0 /*ncompo*/, density);
1519 mixflag = 1;
1521 mat = mgr->GetMaterial(mat_name);
1522 if (!mat) {
1523 mix = new TGeoMixture(mat_name, ncompo, density);
1524 } else if (mat->IsMixture()) {
1525 mix = (TGeoMixture *)mat;
1526 if (gDebug >= 2)
1527 Info("TGDMLParse", "Re-use existing material-mixture: %s", mix->GetName());
1528 } else {
1529 Fatal("TGDMLParse", "WARNING! Inconsistent material definitions between GDML and TGeoManager");
1530 return child;
1531 }
1532 if (properties.GetSize()) {
1534 TIter next(&properties);
1535 while ((property = (TNamed *)next()))
1536 mix->AddProperty(property->GetName(), property->GetTitle());
1537 }
1538 if (constproperties.GetSize()) {
1540 TIter next(&constproperties);
1541 while ((property = (TNamed *)next()))
1542 mix->AddConstProperty(property->GetName(), property->GetTitle());
1543 }
1544 Int_t natoms;
1545 Double_t weight;
1546
1547 for (fractions f = fracmap.begin(); f != fracmap.end(); ++f) {
1548 TGeoMaterial *mattmp = nullptr;
1549 auto material = fmatmap.find(f->first);
1550 if (material != fmatmap.end())
1551 mattmp = (TGeoMaterial *)material->second;
1552 else {
1553 auto mixture = fmixmap.find(f->first);
1554 if (mixture != fmixmap.end())
1555 mattmp = (TGeoMixture *)mixture->second;
1556 }
1557 auto element = felemap.find(f->first);
1558
1559 if ((composite && element != felemap.end()) || (!composite && (mattmp || element != felemap.end()))) {
1560 if (composite) {
1561 natoms = (Int_t)f->second;
1562 mix->AddElement((TGeoElement *)element->second, natoms);
1563 }
1564
1565 else {
1566 weight = f->second;
1567 if (mattmp) {
1568 mix->AddElement(mattmp, weight);
1569 } else {
1570 mix->AddElement((TGeoElement *)element->second, weight);
1571 }
1572 }
1573 }
1574 }
1575 } // end of not Z else
1576
1577 medid = medid + 1;
1578
1579 if (mixflag == 1)
1580 fmixmap[local_name.Data()] = mix;
1581 else if (mixflag == 0)
1582 fmatmap[local_name.Data()] = mat;
1583
1584 TGeoMedium *med = mgr->GetMedium(NameShort(name));
1585 if (!med) {
1586 if (mixflag == 1) {
1587 med = new TGeoMedium(NameShort(name), medid, mix);
1588 } else if (mixflag == 0) {
1590 }
1591 } else if (gDebug >= 2) {
1592 Info("TGDMLParse", "Re-use existing medium: %s", med->GetName());
1593 }
1594 fmedmap[local_name.Data()] = med;
1595
1596 return child;
1597}
1598
1599////////////////////////////////////////////////////////////////////////////////
1600/// In the structure section of the GDML file, skin surfaces can be declared.
1601
1603{
1606
1607 while (attr != nullptr) {
1608 tempattr = gdml->GetAttrName(attr);
1609 tempattr.ToLower();
1610
1611 if (tempattr == "name") {
1612 name = gdml->GetAttrValue(attr);
1613 }
1614 if (tempattr == "surfaceproperty") {
1615 surfname = gdml->GetAttrValue(attr);
1616 }
1617 attr = gdml->GetNextAttr(attr);
1618 }
1619
1620 XMLNodePointer_t child = gdml->GetChild(node);
1621 while (child != nullptr) {
1622 attr = gdml->GetFirstAttr(child);
1623 if ((strcmp(gdml->GetNodeName(child), "volumeref")) == 0) {
1624 while (attr != nullptr) {
1625 tempattr = gdml->GetAttrName(attr);
1626 tempattr.ToLower();
1627 if (tempattr == "ref") {
1628 volname = gdml->GetAttrValue(attr);
1629 }
1630 attr = gdml->GetNextAttr(attr);
1631 }
1632 } // loop on child attributes
1633 child = gdml->GetNext(child);
1634 } // loop on children
1636 if (!surf)
1637 Fatal("SkinSurfaceProcess", "Skin surface %s: referenced optical surface %s not defined", name.Data(),
1638 surfname.Data());
1639 TGeoVolume *vol = GetVolume(volname.Data());
1642 return child;
1643}
1644
1645////////////////////////////////////////////////////////////////////////////////
1646/// In the structure section of the GDML file, border surfaces can be declared.
1647
1649{
1652
1653 while (attr != nullptr) {
1654 tempattr = gdml->GetAttrName(attr);
1655 tempattr.ToLower();
1656
1657 if (tempattr == "name") {
1658 name = gdml->GetAttrValue(attr);
1659 }
1660 if (tempattr == "surfaceproperty") {
1661 surfname = gdml->GetAttrValue(attr);
1662 }
1663 attr = gdml->GetNextAttr(attr);
1664 }
1665
1666 XMLNodePointer_t child = gdml->GetChild(node);
1667 Int_t inode = 0;
1668 while (child != nullptr) {
1669 attr = gdml->GetFirstAttr(child);
1670 if ((strcmp(gdml->GetNodeName(child), "physvolref")) == 0) {
1671 while (attr != nullptr) {
1672 tempattr = gdml->GetAttrName(attr);
1673 tempattr.ToLower();
1674 if (tempattr == "ref") {
1675 nodename[inode++] = gdml->GetAttrValue(attr);
1676 }
1677 attr = gdml->GetNextAttr(attr);
1678 }
1679 } // loop on child attributes
1680 child = gdml->GetNext(child);
1681 } // loop on children
1682 if (inode != 2)
1683 Fatal("BorderSurfaceProcess", "Border surface %s not referencing two nodes", name.Data());
1685 if (!surf)
1686 Fatal("BorderSurfaceProcess", "Border surface %s: referenced optical surface %s not defined", name.Data(),
1687 surfname.Data());
1688 TGeoNode *node1 = fpvolmap[nodename[0].Data()];
1689 TGeoNode *node2 = fpvolmap[nodename[1].Data()];
1690 if (!node1 || !node2)
1691 Fatal("BorderSurfaceProcess", "Border surface %s: not found nodes %s [%s] or %s [%s]", name.Data(),
1692 nodename[0].Data(), node1 ? "present" : "missing", nodename[1].Data(), node2 ? "present" : "missing");
1693
1696 return child;
1697}
1698
1700{
1701 // Get defined position by name, in local file scope.
1702 TGeoTranslation *pos = nullptr;
1703 if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1704 // Search local file namespace first
1706 if (fposmap.find(reftemp.Data()) != fposmap.end())
1707 pos = fposmap[reftemp.Data()];
1708 }
1709
1710 if (!pos && fposmap.find(name) != fposmap.end())
1711 pos = fposmap[name];
1712
1713 if (!pos)
1714 Error("GetPosition", "Position %s not defined", name);
1715 return pos;
1716}
1717
1719{
1720 // Get defined rotation by name.
1721 TGeoRotation *rot = nullptr;
1722 if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1723 // Search local file namespace first
1725 if (frotmap.find(reftemp.Data()) != frotmap.end())
1726 rot = frotmap[reftemp.Data()];
1727 }
1728
1729 if (!rot && frotmap.find(name) != frotmap.end())
1730 rot = frotmap[name];
1731
1732 if (!rot)
1733 Error("GetRotation", "Rotation %s not defined", name);
1734 return rot;
1735}
1736
1738{
1739 // Get defined scale by name.
1740 TGeoScale *scl = nullptr;
1741 if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1742 // Search local file namespace first
1744 if (fsclmap.find(reftemp.Data()) != fsclmap.end())
1745 scl = fsclmap[reftemp.Data()];
1746 }
1747
1748 if (!scl && fsclmap.find(name) != fsclmap.end())
1749 scl = fsclmap[name];
1750
1751 if (!scl)
1752 Error("GetScale", "Scale %s not defined", name);
1753 return scl;
1754}
1755
1757{
1758 // Get defined solid by name.
1759 TGeoShape *sol = nullptr;
1760 if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1761 // Search local file namespace first
1763 if (fsolmap.find(reftemp.Data()) != fsolmap.end())
1764 sol = fsolmap[reftemp.Data()];
1765 }
1766
1767 if (!sol && fsolmap.find(name) != fsolmap.end())
1768 sol = fsolmap[name];
1769
1770 if (!sol)
1771 Error("GetSolid", "Solid %s not defined", name);
1772 return sol;
1773}
1774
1776{
1777 // Get defined solid by name.
1778 TGeoVolume *vol = nullptr;
1779 if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1780 // Search local file namespace first
1782 if (fvolmap.find(reftemp.Data()) != fvolmap.end())
1783 vol = fvolmap[reftemp.Data()];
1784 }
1785
1786 if (!vol && fvolmap.find(name) != fvolmap.end())
1787 vol = fvolmap[name];
1788
1789 if (!vol)
1790 Error("GetVolume", "Volume %s not defined", name);
1791 return vol;
1792}
1793
1794////////////////////////////////////////////////////////////////////////////////
1795/// In the structure section of the GDML file, volumes can be declared.
1796/// when the volume keyword is found, this function is called, and the
1797/// name and values of the volume are converted into type TGeoVolume and
1798/// stored in fvolmap map using the name as its key. Volumes reference to
1799/// a solid declared higher up in the solids section of the GDML file.
1800/// Some volumes reference to other physical volumes to contain inside
1801/// that volume, declaring positions and rotations within that volume.
1802/// when each 'physvol' is declared, a matrix for its rotation and
1803/// translation is built and the 'physvol node' is added to the original
1804/// volume using TGeoVolume->AddNode.
1805/// volume division is also declared within the volume node, and once the
1806/// values for the division have been collected, using TGeoVolume->divide,
1807/// the division can be applied.
1808
1810{
1814
1815 XMLNodePointer_t child = gdml->GetChild(node);
1816 TString name;
1817 TString solidname = "";
1818 TString tempattr = "";
1819 TGeoShape *solid = nullptr;
1820 TGeoMedium *medium = nullptr;
1821 TGeoVolume *vol = nullptr;
1822 TGeoVolume *lv = nullptr;
1823 TGeoShape *reflex = nullptr;
1824 const Double_t *parentrot = nullptr;
1825 int yesrefl = 0;
1826 TString reftemp = "";
1827 TMap *auxmap = nullptr;
1828
1829 while (child != nullptr) {
1830 if ((strcmp(gdml->GetNodeName(child), "solidref")) == 0) {
1831
1832 reftemp = gdml->GetAttr(child, "ref");
1833 if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1834 reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
1835 }
1836 if (fsolmap.find(reftemp.Data()) != fsolmap.end()) {
1837 solid = fsolmap[reftemp.Data()];
1838 } else if (freflectmap.find(reftemp.Data()) != freflectmap.end()) {
1840 reflex = fsolmap[freflectmap[reftemp.Data()]];
1841 } else {
1842 printf("Solid: %s, Not Yet Defined!\n", reftemp.Data());
1843 }
1844 }
1845
1846 if ((strcmp(gdml->GetNodeName(child), "materialref")) == 0) {
1847 reftemp = gdml->GetAttr(child, "ref");
1848 if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1849 reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
1850 }
1851 if (fmedmap.find(reftemp.Data()) != fmedmap.end()) {
1852 medium = fmedmap[reftemp.Data()];
1853 } else {
1854 printf("Medium: %s, Not Yet Defined!\n", gdml->GetAttr(child, "ref"));
1855 }
1856 }
1857
1858 child = gdml->GetNext(child);
1859 }
1860
1861 name = gdml->GetAttr(node, "name");
1863 if ((strcmp(fCurrentFile, fStartFile)) != 0) {
1864 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
1865 }
1866
1867 if (reflex == nullptr) {
1868 vol = new TGeoVolume(NameShort(name), solid, medium);
1869 } else {
1870 vol = new TGeoVolume(NameShort(name), reflex, medium);
1871 freflvolmap[name.Data()] = solidname;
1873 parentrot = parentrefl->GetMatrix()->GetRotationMatrix();
1874 yesrefl = 1;
1875 }
1876
1877 fvolmap[local_name.Data()] = vol;
1878
1879 // PHYSVOL - run through child nodes of VOLUME again..
1880
1881 child = gdml->GetChild(node);
1882
1883 while (child != nullptr) {
1884 if ((strcmp(gdml->GetNodeName(child), "physvol")) == 0) {
1885
1886 TString volref = "";
1887
1888 TGeoTranslation *pos = nullptr;
1889 TGeoRotation *rot = nullptr;
1890 TGeoScale *scl = nullptr;
1891 TString pnodename = gdml->GetAttr(child, "name");
1892 TString scopynum = gdml->GetAttr(child, "copynumber");
1893 Int_t copynum = (scopynum.IsNull()) ? 0 : (Int_t)Value(scopynum);
1894
1895 subchild = gdml->GetChild(child);
1896
1897 while (subchild != nullptr) {
1898 tempattr = gdml->GetNodeName(subchild);
1899 tempattr.ToLower();
1900
1901 if (tempattr == "volumeref") {
1902 reftemp = gdml->GetAttr(subchild, "ref");
1903 lv = GetVolume(reftemp.Data());
1904 volref = reftemp;
1905 } else if (tempattr == "file") {
1906 const char *filevol;
1907 const char *prevfile = fCurrentFile;
1908
1909 fCurrentFile = gdml->GetAttr(subchild, "name");
1910 filevol = gdml->GetAttr(subchild, "volname");
1911
1913 gdml2->SetSkipComments(kTRUE);
1915 if (filedoc1 == nullptr) {
1916 Fatal("VolProcess", "Bad filename given %s", fCurrentFile);
1917 }
1918 // take access to main node
1919 XMLNodePointer_t mainnode2 = gdml2->DocGetRootElement(filedoc1);
1920 // increase depth counter + add DOM pointer
1921 fFILENO = fFILENO + 1;
1923
1924 if (ffilemap.find(fCurrentFile) != ffilemap.end()) {
1926 } else {
1929 }
1930
1931 if (filevol)
1932 volref = filevol;
1933 lv = GetVolume(volref.Data());
1934
1935 fFILENO = fFILENO - 1;
1938
1939 // File tree complete - Release memory before exit
1940
1941 gdml->FreeDoc(filedoc1);
1942 delete gdml2;
1943 } else if (tempattr == "position") {
1944 attr = gdml->GetFirstAttr(subchild);
1946 reftemp = gdml->GetAttr(subchild, "name");
1947 pos = GetPosition(reftemp.Data());
1948 } else if (tempattr == "positionref") {
1949 reftemp = gdml->GetAttr(subchild, "ref");
1950 pos = GetPosition(reftemp.Data());
1951 if (!pos)
1952 Fatal("VolProcess", "Physvol's position %s not found", reftemp.Data());
1953 } else if (tempattr == "rotation") {
1954 attr = gdml->GetFirstAttr(subchild);
1956 reftemp = gdml->GetAttr(subchild, "name");
1957 rot = GetRotation(reftemp.Data());
1958 } else if (tempattr == "rotationref") {
1959 reftemp = gdml->GetAttr(subchild, "ref");
1960 rot = GetRotation(reftemp.Data());
1961 if (!rot)
1962 Fatal("VolProcess", "Physvol's rotation %s not found", reftemp.Data());
1963 } else if (tempattr == "scale") {
1964 attr = gdml->GetFirstAttr(subchild);
1966 reftemp = gdml->GetAttr(subchild, "name");
1967 scl = GetScaleObj(reftemp.Data());
1968 } else if (tempattr == "scaleref") {
1969 reftemp = gdml->GetAttr(subchild, "ref");
1970 scl = GetScaleObj(reftemp.Data());
1971 if (!scl)
1972 Fatal("VolProcess", "Physvol's scale %s not found", reftemp.Data());
1973 }
1974
1975 subchild = gdml->GetNext(subchild);
1976 }
1977
1978 // ADD PHYSVOL TO GEOMETRY
1979 fVolID = fVolID + 1;
1980
1982
1983 if (pos != nullptr)
1984 transform->SetTranslation(pos->GetTranslation());
1985 if (rot != nullptr)
1986 transform->SetRotation(rot->GetRotationMatrix());
1987
1988 if (scl != nullptr) { // Scaling must be added to the rotation matrix!
1989
1990 Double_t scale3x3[9];
1991 memset(scale3x3, 0, 9 * sizeof(Double_t));
1992 const Double_t *diagonal = scl->GetScale();
1993
1994 scale3x3[0] = diagonal[0];
1995 scale3x3[4] = diagonal[1];
1996 scale3x3[8] = diagonal[2];
1997
1999 scaleMatrix.SetMatrix(scale3x3);
2000 transform->Multiply(&scaleMatrix);
2001 }
2002
2003 // BEGIN: reflectedSolid. Remove lines between if reflectedSolid will be removed from GDML!!!
2004
2005 if (freflvolmap.find(volref.Data()) != freflvolmap.end()) {
2006 // if the volume is a reflected volume the matrix needs to be CHANGED
2008 transform->Multiply(temprefl->GetMatrix());
2009 }
2010
2011 if (yesrefl == 1) {
2012 // reflection is done per solid so that we cancel it if exists in mother volume!!!
2014 prot.SetMatrix(parentrot);
2015 transform->MultiplyLeft(&prot);
2016 }
2017
2018 // END: reflectedSolid
2019
2020 vol->AddNode(lv, copynum, transform);
2021 TGeoNode *lastnode = (TGeoNode *)vol->GetNodes()->Last();
2022 if (!pnodename.IsNull())
2023 lastnode->SetName(pnodename);
2024 fpvolmap[lastnode->GetName()] = lastnode;
2025 } else if ((strcmp(gdml->GetNodeName(child), "divisionvol")) == 0) {
2026
2027 TString divVolref = "";
2028 Int_t axis = 0;
2029 TString number = "";
2030 TString width = "";
2031 TString offset = "";
2032 TString lunit = fDefault_lunit.c_str();
2033 bool unitless_l = true;
2034 reftemp = "";
2035 local_name = "";
2036
2037 attr = gdml->GetFirstAttr(child);
2038
2039 while (attr != nullptr) {
2040
2041 tempattr = gdml->GetAttrName(attr);
2042 tempattr.ToLower();
2043
2044 if (tempattr == "axis") {
2045 axis = SetAxis(gdml->GetAttrValue(attr));
2046 } else if (tempattr == "number") {
2047 number = gdml->GetAttrValue(attr);
2048 } else if (tempattr == "width") {
2049 width = gdml->GetAttrValue(attr);
2050 } else if (tempattr == "offset") {
2051 offset = gdml->GetAttrValue(attr);
2052 } else if (tempattr == "unit") {
2053 lunit = gdml->GetAttrValue(attr);
2054 unitless_l = false;
2055 }
2056
2057 attr = gdml->GetNextAttr(attr);
2058 }
2059
2060 subchild = gdml->GetChild(child);
2061
2062 while (subchild != nullptr) {
2063 tempattr = gdml->GetNodeName(subchild);
2064 tempattr.ToLower();
2065
2066 if (tempattr == "volumeref") {
2067 reftemp = gdml->GetAttr(subchild, "ref");
2069 if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2070 local_name = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
2071 }
2073 }
2074
2075 subchild = gdml->GetNext(subchild);
2076 }
2077
2078 Double_t numberline = Value(number);
2081 Double_t step = Value(width) * retunit;
2083
2084 fVolID = fVolID + 1;
2085 Double_t xlo, xhi;
2086 vol->GetShape()->GetAxisRange(axis, xlo, xhi);
2087
2088 Int_t ndiv = (Int_t)numberline;
2089 Double_t start = xlo + offsetline;
2090
2091 Int_t numed = 0;
2093 if (old) {
2094 // We need to recreate the content of the divided volume
2095 // medium id
2096 numed = old->GetMedium()->GetId();
2097 }
2098 TGeoVolume *divvol = vol->Divide(NameShort(reftemp), axis, ndiv, start, step, numed);
2099 if (!divvol) {
2100 Fatal("VolProcess", "Cannot divide volume %s", vol->GetName());
2101 return child;
2102 }
2103 if (old && old->GetNdaughters()) {
2104 divvol->ReplayCreation(old);
2105 }
2106 fvolmap[local_name.Data()] = divvol;
2107
2108 } // end of Division else if
2109
2110 else if ((strcmp(gdml->GetNodeName(child), "replicavol")) == 0) {
2111
2112 TString divVolref = "";
2113 Int_t axis = 0;
2114 TString number = "";
2115 TString width = "";
2116 TString offset = "";
2117 TString wunit = fDefault_lunit.c_str();
2118 TString ounit = fDefault_lunit.c_str();
2119 bool unitless_l = true;
2120 Double_t wvalue = 0;
2121 Double_t ovalue = 0;
2122 reftemp = "";
2123 local_name = "";
2124
2125 attr = gdml->GetFirstAttr(child);
2126
2127 while (attr != nullptr) {
2128
2129 tempattr = gdml->GetAttrName(attr);
2130 tempattr.ToLower();
2131
2132 if (tempattr == "number") {
2133 number = gdml->GetAttrValue(attr);
2134 }
2135 attr = gdml->GetNextAttr(attr);
2136 }
2137
2138 subchild = gdml->GetChild(child);
2139
2140 while (subchild != nullptr) {
2141 tempattr = gdml->GetNodeName(subchild);
2142 tempattr.ToLower();
2143
2144 if (tempattr == "volumeref") {
2145 reftemp = gdml->GetAttr(subchild, "ref");
2147 if ((strcmp(fCurrentFile, fStartFile)) != 0) {
2148 local_name = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
2149 }
2151 }
2152
2153 if (tempattr == "replicate_along_axis") {
2154 subsubchild = gdml->GetChild(subchild);
2155
2156 while (subsubchild != nullptr) {
2157 if ((strcmp(gdml->GetNodeName(subsubchild), "width")) == 0) {
2158 attr = gdml->GetFirstAttr(subsubchild);
2159 while (attr != nullptr) {
2160 tempattr = gdml->GetAttrName(attr);
2161 tempattr.ToLower();
2162 if (tempattr == "value") {
2163 wvalue = Value(gdml->GetAttrValue(attr));
2164 } else if (tempattr == "unit") {
2165 wunit = gdml->GetAttrValue(attr);
2166 unitless_l = false;
2167 }
2168
2169 attr = gdml->GetNextAttr(attr);
2170 }
2171 } else if ((strcmp(gdml->GetNodeName(subsubchild), "offset")) == 0) {
2172 attr = gdml->GetFirstAttr(subsubchild);
2173 while (attr != nullptr) {
2174 tempattr = gdml->GetAttrName(attr);
2175 tempattr.ToLower();
2176 if (tempattr == "value") {
2177 ovalue = Value(gdml->GetAttrValue(attr));
2178 } else if (tempattr == "unit") {
2179 ounit = gdml->GetAttrValue(attr);
2180 unitless_l = false;
2181 }
2182 attr = gdml->GetNextAttr(attr);
2183 }
2184 } else if ((strcmp(gdml->GetNodeName(subsubchild), "direction")) == 0) {
2185 attr = gdml->GetFirstAttr(subsubchild);
2186 while (attr != nullptr) {
2187 tempattr = gdml->GetAttrName(attr);
2188 tempattr.ToLower();
2189 if (tempattr == "x") {
2190 axis = 1;
2191 } else if (tempattr == "y") {
2192 axis = 2;
2193 } else if (tempattr == "z") {
2194 axis = 3;
2195 } else if (tempattr == "rho") {
2196 axis = 1;
2197 } else if (tempattr == "phi") {
2198 axis = 2;
2199 }
2200
2201 attr = gdml->GetNextAttr(attr);
2202 }
2203 }
2204
2205 subsubchild = gdml->GetNext(subsubchild);
2206 }
2207 }
2208
2209 subchild = gdml->GetNext(subchild);
2210 }
2211
2215
2216 Double_t numberline = Value(number);
2219
2220 fVolID = fVolID + 1;
2221 Double_t xlo, xhi;
2222 vol->GetShape()->GetAxisRange(axis, xlo, xhi);
2223
2224 Int_t ndiv = (Int_t)numberline;
2225 Double_t start = xlo + offsetline;
2226
2227 Double_t step = widthline;
2228 Int_t numed = 0;
2230 if (old) {
2231 // We need to recreate the content of the divided volume
2232 // medium id
2233 numed = old->GetMedium()->GetId();
2234 }
2235 TGeoVolume *divvol = vol->Divide(NameShort(reftemp), axis, ndiv, start, step, numed);
2236 if (!divvol) {
2237 Fatal("VolProcess", "Cannot divide volume %s", vol->GetName());
2238 return child;
2239 }
2240 if (old && old->GetNdaughters()) {
2241 divvol->ReplayCreation(old);
2242 }
2243 fvolmap[local_name.Data()] = divvol;
2244
2245 } // End of replicavol
2246 else if (strcmp(gdml->GetNodeName(child), "auxiliary") == 0) {
2248 if (!auxmap) {
2249 // printf("Auxiliary values for volume %s\n",vol->GetName());
2250 auxmap = new TMap();
2251 auto ext = new TGeoRCExtension(auxmap);
2252 vol->SetUserExtension(ext); // grabs a copy
2253 ext->Release();
2254 }
2255 attr = gdml->GetFirstAttr(child);
2256 while (attr) {
2257 if (!strcmp(gdml->GetAttrName(attr), "auxtype"))
2258 auxType = gdml->GetAttrValue(attr);
2259 else if (!strcmp(gdml->GetAttrName(attr), "auxvalue"))
2260 auxValue = gdml->GetAttrValue(attr);
2261 else if (!strcmp(gdml->GetAttrName(attr), "auxunit"))
2262 auxUnit = gdml->GetAttrValue(attr);
2263 attr = gdml->GetNextAttr(attr);
2264 }
2265 if (!auxUnit.IsNull())
2266 auxValue = TString::Format("%s*%s", auxValue.Data(), auxUnit.Data());
2267 auxmap->Add(new TObjString(auxType), new TObjString(auxValue));
2268 // printf(" %s: %s\n", auxType.Data(), auxValue.Data());
2269 }
2270
2271 child = gdml->GetNext(child);
2272 }
2273
2274 return child;
2275}
2276
2277////////////////////////////////////////////////////////////////////////////////
2278/// In the solid section of the GDML file, boolean solids can be
2279/// declared. when the subtraction, intersection or union keyword
2280/// is found, this function is called, and the values (rotation and
2281/// translation) of the solid are converted into type TGeoCompositeShape
2282/// and stored in fsolmap map using the name as its key.
2283///
2284/// - 1 = SUBTRACTION
2285/// - 2 = INTERSECTION
2286/// - 3 = UNION
2287
2289{
2290 TString reftemp = "";
2291 TString tempattr = "";
2292 XMLNodePointer_t child = gdml->GetChild(node);
2293
2294 TGeoShape *first = nullptr;
2295 TGeoShape *second = nullptr;
2296
2299
2302
2303 firstRot->RotateZ(0);
2304 firstRot->RotateY(0);
2305 firstRot->RotateX(0);
2306
2307 secondRot->RotateZ(0);
2308 secondRot->RotateY(0);
2309 secondRot->RotateX(0);
2310
2311 TString name = gdml->GetAttr(node, "name");
2313
2314 if ((strcmp(fCurrentFile, fStartFile)) != 0)
2315 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
2316
2317 while (child != nullptr) {
2318 tempattr = gdml->GetNodeName(child);
2319 tempattr.ToLower();
2320
2321 if (tempattr == "first") {
2322 reftemp = gdml->GetAttr(child, "ref");
2323 first = GetSolid(reftemp.Data());
2324 if (!first)
2325 Fatal("BooSolid", "First solid %s not found", reftemp.Data());
2326 } else if (tempattr == "second") {
2327 reftemp = gdml->GetAttr(child, "ref");
2328 second = GetSolid(reftemp.Data());
2329 if (!second)
2330 Fatal("BooSolid", "Second solid %s not found", reftemp.Data());
2331 } else if (tempattr == "position") {
2332 attr = gdml->GetFirstAttr(child);
2334 reftemp = gdml->GetAttr(child, "name");
2335 secondPos = GetPosition(reftemp.Data());
2336 } else if (tempattr == "positionref") {
2337 reftemp = gdml->GetAttr(child, "ref");
2338 secondPos = GetPosition(reftemp.Data());
2339 if (!secondPos)
2340 Fatal("BooSolid", "Second position %s not found", reftemp.Data());
2341 } else if (tempattr == "rotation") {
2342 attr = gdml->GetFirstAttr(child);
2344 reftemp = gdml->GetAttr(child, "name");
2345 secondRot = GetRotation(reftemp.Data());
2346 } else if (tempattr == "rotationref") {
2347 reftemp = gdml->GetAttr(child, "ref");
2348 secondRot = GetRotation(reftemp.Data());
2349 if (!secondRot)
2350 Fatal("BooSolid", "Second rotation %s not found", reftemp.Data());
2351 } else if (tempattr == "firstposition") {
2352 attr = gdml->GetFirstAttr(child);
2354 reftemp = gdml->GetAttr(child, "name");
2355 firstPos = GetPosition(reftemp.Data());
2356 } else if (tempattr == "firstpositionref") {
2357 reftemp = gdml->GetAttr(child, "ref");
2358 firstPos = GetPosition(reftemp.Data());
2359 if (!firstPos)
2360 Fatal("BooSolid", "First position %s not found", reftemp.Data());
2361 } else if (tempattr == "firstrotation") {
2362 attr = gdml->GetFirstAttr(child);
2364 reftemp = gdml->GetAttr(child, "name");
2365 firstRot = GetRotation(reftemp.Data());
2366 } else if (tempattr == "firstrotationref") {
2367 reftemp = gdml->GetAttr(child, "ref");
2368 firstRot = GetRotation(reftemp.Data());
2369 if (!firstRot)
2370 Fatal("BooSolid", "First rotation %s not found", reftemp.Data());
2371 }
2372 child = gdml->GetNext(child);
2373 }
2374
2377
2378 TGeoCompositeShape *boolean = nullptr;
2379 switch (num) {
2380 case 1:
2381 boolean = new TGeoCompositeShape(NameShort(name), new TGeoSubtraction(first, second, firstMatrix, secondMatrix));
2382 break; // SUBTRACTION
2383 case 2:
2384 boolean = new TGeoCompositeShape(NameShort(name), new TGeoIntersection(first, second, firstMatrix, secondMatrix));
2385 break; // INTERSECTION
2386 case 3:
2387 boolean = new TGeoCompositeShape(NameShort(name), new TGeoUnion(first, second, firstMatrix, secondMatrix));
2388 break; // UNION
2389 default: break;
2390 }
2391
2392 fsolmap[local_name.Data()] = boolean;
2393
2394 return child;
2395}
2396
2397////////////////////////////////////////////////////////////////////////////////
2398/// User data to be processed.
2399
2401{
2402 XMLNodePointer_t child = gdml->GetChild(node);
2404 double value = 0.;
2406 while (child) {
2407 region = nullptr;
2408 nodename = gdml->GetNodeName(child);
2409 if (nodename == "auxiliary") {
2410 auxtype = gdml->GetAttr(child, "auxtype");
2411 auxvalue = gdml->GetAttr(child, "auxvalue");
2412 if (auxtype == "Region") {
2414 region = new TGeoRegion(auxvalue);
2415 }
2416 }
2417 XMLNodePointer_t subchild = gdml->GetChild(child);
2418 while (subchild) {
2419 auxtypec = gdml->GetAttr(subchild, "auxtype");
2420 auxvaluec = gdml->GetAttr(subchild, "auxvalue");
2421 auxunitc = gdml->GetAttr(subchild, "auxunit");
2422 if (auxtypec == "volume") {
2424 if (region)
2425 region->AddVolume(auxvaluec);
2426 }
2427 if (auxtypec.Contains("cut")) {
2429 if (region)
2430 region->AddCut(auxtypec, value);
2431 }
2432 subchild = gdml->GetNext(subchild);
2433 }
2434 if (region) {
2436 // region->Print();
2437 }
2438 child = gdml->GetNext(child);
2439 }
2440 return child;
2441}
2442
2443////////////////////////////////////////////////////////////////////////////////
2444/// In the structure section of the GDML file, assembly volumes can be
2445/// declared. when the assembly keyword is found, this function is called,
2446/// and the name is converted into type TGeoVolumeAssembly and
2447/// stored in fvolmap map using the name as its key. Some assembly volumes
2448/// reference to other physical volumes to contain inside that assembly,
2449/// declaring positions and rotations within that volume. When each 'physvol'
2450/// is declared, a matrix for its rotation and translation is built and the
2451/// 'physvol node' is added to the original assembly using TGeoVolume->AddNode.
2452
2454{
2455 TString name = gdml->GetAttr(node, "name");
2457 TString reftemp = "";
2458
2459 if ((strcmp(fCurrentFile, fStartFile)) != 0)
2460 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
2461
2464 XMLNodePointer_t child = gdml->GetChild(node);
2465 TString tempattr = "";
2466 TGeoVolume *lv = nullptr;
2467 TGeoTranslation *pos = nullptr;
2468 TGeoRotation *rot = nullptr;
2469 TGeoCombiTrans *matr;
2470
2472
2473 // PHYSVOL - run through child nodes of VOLUME again..
2474
2475 // child = gdml->GetChild(node);
2476
2477 while (child != nullptr) {
2478 if ((strcmp(gdml->GetNodeName(child), "physvol")) == 0) {
2479 TString pnodename = gdml->GetAttr(child, "name");
2480 TString scopynum = gdml->GetAttr(child, "copynumber");
2481 Int_t copynum = (scopynum.IsNull()) ? 0 : (Int_t)Value(scopynum);
2482
2483 subchild = gdml->GetChild(child);
2484 pos = new TGeoTranslation(0, 0, 0);
2485 rot = new TGeoRotation();
2486
2487 while (subchild != nullptr) {
2488 tempattr = gdml->GetNodeName(subchild);
2489 tempattr.ToLower();
2490
2491 if (tempattr == "volumeref") {
2492 reftemp = gdml->GetAttr(subchild, "ref");
2493 lv = GetVolume(reftemp.Data());
2494 } else if (tempattr == "positionref") {
2495 reftemp = gdml->GetAttr(subchild, "ref");
2496 pos = GetPosition(reftemp.Data());
2497 if (!pos)
2498 Fatal("AssProcess", "Position %s not found", reftemp.Data());
2499 } else if (tempattr == "position") {
2500 attr = gdml->GetFirstAttr(subchild);
2502 reftemp = gdml->GetAttr(subchild, "name");
2503 pos = GetPosition(reftemp.Data());
2504 } else if (tempattr == "rotationref") {
2505 reftemp = gdml->GetAttr(subchild, "ref");
2506 rot = GetRotation(reftemp.Data());
2507 if (!rot)
2508 Fatal("AssProcess", "Rotation %s not found", reftemp.Data());
2509 } else if (tempattr == "rotation") {
2510 attr = gdml->GetFirstAttr(subchild);
2512 reftemp = gdml->GetAttr(subchild, "name");
2513 rot = GetRotation(reftemp.Data());
2514 }
2515
2516 subchild = gdml->GetNext(subchild);
2517 }
2518
2519 // ADD PHYSVOL TO GEOMETRY
2520 fVolID = fVolID + 1;
2521 matr = new TGeoCombiTrans(*pos, *rot);
2522 assem->AddNode(lv, copynum, matr);
2523 TGeoNode *lastnode = (TGeoNode *)assem->GetNodes()->Last();
2524 if (!pnodename.IsNull())
2525 lastnode->SetName(pnodename);
2526 fpvolmap[lastnode->GetName()] = lastnode;
2527 }
2528 child = gdml->GetNext(child);
2529 }
2530
2531 fvolmap[local_name.Data()] = assem;
2532 return child;
2533}
2534
2535////////////////////////////////////////////////////////////////////////////////
2536/// In the setup section of the GDML file, the top volume need to be
2537/// declared. when the setup keyword is found, this function is called,
2538/// and the top volume ref is taken and 'world' is set
2539
2541{
2542 const char *name = gdml->GetAttr(node, "name");
2544 XMLNodePointer_t child = gdml->GetChild(node);
2545 TString reftemp = "";
2546
2547 while (child != nullptr) {
2548
2549 if ((strcmp(gdml->GetNodeName(child), "world") == 0)) {
2550 // const char* reftemp;
2551 // TString reftemp = "";
2552 reftemp = gdml->GetAttr(child, "ref");
2553 fWorld = GetVolume(reftemp.Data());
2554 fWorldName = reftemp.Data();
2555 }
2556 child = gdml->GetNext(child);
2557 }
2558 return node;
2559}
2560
2561////////////////////////////////////////////////////////////////////////////////
2562/// In the solids section of the GDML file, a box may be declared.
2563/// when the box keyword is found, this function is called, and the
2564/// dimensions required are taken and stored, these are then bound and
2565/// converted to type TGeoBBox and stored in fsolmap map using the name
2566/// as its key.
2567
2569{
2570 TString lunit = fDefault_lunit.c_str();
2571 bool unitless_l = true;
2572 TString xpos = "0";
2573 TString ypos = "0";
2574 TString zpos = "0";
2575 TString name = "";
2577
2578 while (attr != nullptr) {
2579
2580 tempattr = gdml->GetAttrName(attr);
2581 tempattr.ToLower();
2582
2583 if (tempattr == "name") {
2584 name = gdml->GetAttrValue(attr);
2585 } else if (tempattr == "x") {
2586 xpos = gdml->GetAttrValue(attr);
2587 } else if (tempattr == "y") {
2588 ypos = gdml->GetAttrValue(attr);
2589 } else if (tempattr == "z") {
2590 zpos = gdml->GetAttrValue(attr);
2591 } else if (tempattr == "lunit") {
2592 lunit = gdml->GetAttrValue(attr);
2593 unitless_l = false;
2594 }
2595
2596 attr = gdml->GetNextAttr(attr);
2597 }
2598
2600 if ((strcmp(fCurrentFile, fStartFile)) != 0)
2601 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
2602
2605
2606 Double_t xline = 0.5 * Value(xpos) * retunit;
2607 Double_t yline = 0.5 * Value(ypos) * retunit;
2608 Double_t zline = 0.5 * Value(zpos) * retunit;
2609
2611
2612 fsolmap[local_name.Data()] = box;
2613
2614 return node;
2615}
2616
2617////////////////////////////////////////////////////////////////////////////////
2618/// In the solids section of the GDML file, an ellipsoid may be declared.
2619/// Unfortunately, the ellipsoid is not supported under ROOT so,
2620/// when the ellipsoid keyword is found, this function is called
2621/// to convert it to a simple box with similar dimensions, and the
2622/// dimensions required are taken and stored, these are then bound and
2623/// converted to type TGeoBBox and stored in fsolmap map using the name
2624/// as its key.
2625
2627{
2628 TString lunit = fDefault_lunit.c_str();
2629 bool unitless_l = true;
2630 TString ax = "0";
2631 TString by = "0";
2632 TString cz = "0";
2633 // initialization to empty string
2634 TString zcut1 = "";
2635 TString zcut2 = "";
2636 TString name = "";
2638
2639 while (attr != nullptr) {
2640
2641 tempattr = gdml->GetAttrName(attr);
2642 tempattr.ToLower();
2643
2644 if (tempattr == "name") {
2645 name = gdml->GetAttrValue(attr);
2646 } else if (tempattr == "ax") {
2647 ax = gdml->GetAttrValue(attr);
2648 } else if (tempattr == "by") {
2649 by = gdml->GetAttrValue(attr);
2650 } else if (tempattr == "cz") {
2651 cz = gdml->GetAttrValue(attr);
2652 } else if (tempattr == "zcut1") {
2653 zcut1 = gdml->GetAttrValue(attr);
2654 } else if (tempattr == "zcut2") {
2655 zcut2 = gdml->GetAttrValue(attr);
2656 } else if (tempattr == "lunit") {
2657 lunit = gdml->GetAttrValue(attr);
2658 unitless_l = false;
2659 }
2660
2661 attr = gdml->GetNextAttr(attr);
2662 }
2663
2665 if ((strcmp(fCurrentFile, fStartFile)) != 0)
2666 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
2667
2670
2671 Double_t dx = Value(ax) * retunit;
2672 Double_t dy = Value(by) * retunit;
2674 Double_t sx = dx / radius;
2675 Double_t sy = dy / radius;
2676 Double_t sz = 1.;
2677 Double_t z1, z2;
2678 // Initialization of cutting
2679 if (zcut1 == "") {
2680 z1 = -radius;
2681 } else {
2682 z1 = Value(zcut1) * retunit;
2683 }
2684 if (zcut2 == "") {
2685 z2 = radius;
2686 } else {
2687 z2 = Value(zcut2) * retunit;
2688 }
2689
2690 TGeoSphere *sph = new TGeoSphere(0, radius);
2691 TGeoScale *scl = new TGeoScale("", sx, sy, sz);
2693
2694 Double_t origin[3] = {0., 0., 0.};
2695 origin[2] = 0.5 * (z1 + z2);
2696 Double_t dz = 0.5 * (z2 - z1);
2697 TGeoBBox *pCutBox = new TGeoBBox("cutBox", dx, dy, dz, origin);
2698 TGeoBoolNode *pBoolNode = new TGeoIntersection(shape, pCutBox, nullptr, nullptr);
2700 fsolmap[local_name.Data()] = cs;
2701
2702 return node;
2703}
2704
2705////////////////////////////////////////////////////////////////////////////////
2706/// In the solids section of the GDML file, an elliptical cone may be declared.
2707/// Unfortunately, the elliptical cone is not supported under ROOT so,
2708/// when the elcone keyword is found, this function is called
2709/// to convert it to a simple box with similar dimensions, and the
2710/// dimensions required are taken and stored, these are then bound and
2711/// converted to type TGeoBBox and stored in fsolmap map using the name
2712/// as its key.
2713
2715{
2716 TString lunit = fDefault_lunit.c_str();
2717 bool unitless_l = true;
2718 TString dx = "0";
2719 TString dy = "0";
2720 TString zmax = "0";
2721 TString zcut = "0";
2722 TString name = "";
2724
2725 while (attr != nullptr) {
2726
2727 tempattr = gdml->GetAttrName(attr);
2728 tempattr.ToLower();
2729
2730 if (tempattr == "name") {
2731 name = gdml->GetAttrValue(attr);
2732 } else if (tempattr == "dx") {
2733 dx = gdml->GetAttrValue(attr);
2734 } else if (tempattr == "dy") {
2735 dy = gdml->GetAttrValue(attr);
2736 } else if (tempattr == "zmax") {
2737 zmax = gdml->GetAttrValue(attr);
2738 } else if (tempattr == "zcut") {
2739 zcut = gdml->GetAttrValue(attr);
2740 } else if (tempattr == "lunit") {
2741 lunit = gdml->GetAttrValue(attr);
2742 unitless_l = false;
2743 }
2744
2745 attr = gdml->GetNextAttr(attr);
2746 }
2747
2749 if ((strcmp(fCurrentFile, fStartFile)) != 0)
2750 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
2751
2752 // semiaxises of elliptical cone (elcone) are different then ellipsoid
2753
2756
2757 // dxline and dyline are without units because they are as a ration
2760 Double_t z = Value(zmax) * retunit;
2762
2763 if (z1 <= 0) {
2764 Info("ElCone", "ERROR! Parameter zcut = %.12g is not set properly, elcone will not be imported.", z1);
2765 return node;
2766 }
2767 if (z1 > z) {
2768 z1 = z;
2769 }
2770 Double_t rx1 = (z + z1) * dxratio;
2771 Double_t ry1 = (z + z1) * dyratio;
2772 Double_t rx2 = (z - z1) * dxratio;
2773 Double_t sx = 1.;
2774 Double_t sy = ry1 / rx1;
2775 Double_t sz = 1.;
2776
2777 TGeoCone *con = new TGeoCone(z1, 0, rx1, 0, rx2);
2778 TGeoScale *scl = new TGeoScale("", sx, sy, sz);
2780
2781 fsolmap[local_name.Data()] = shape;
2782
2783 return node;
2784}
2785
2786////////////////////////////////////////////////////////////////////////////////
2787/// In the solids section of the GDML file, a Paraboloid may be declared.
2788/// when the paraboloid keyword is found, this function is called, and the
2789/// dimensions required are taken and stored, these are then bound and
2790/// converted to type TGeoParaboloid and stored in fsolmap map using the name
2791/// as its key.
2792
2794{
2795 TString lunit = fDefault_lunit.c_str();
2796 bool unitless_l = true;
2797 TString rlopos = "0";
2798 TString rhipos = "0";
2799 TString dzpos = "0";
2800 TString name = "";
2802
2803 while (attr != nullptr) {
2804
2805 tempattr = gdml->GetAttrName(attr);
2806 tempattr.ToLower();
2807
2808 if (tempattr == "name") {
2809 name = gdml->GetAttrValue(attr);
2810 } else if (tempattr == "rlo") {
2811 rlopos = gdml->GetAttrValue(attr);
2812 } else if (tempattr == "rhi") {
2813 rhipos = gdml->GetAttrValue(attr);
2814 } else if (tempattr == "dz") {
2815 dzpos = gdml->GetAttrValue(attr);
2816 } else if (tempattr == "lunit") {
2817 lunit = gdml->GetAttrValue(attr);
2818 unitless_l = false;
2819 }
2820
2821 attr = gdml->GetNextAttr(attr);
2822 }
2823
2825 if ((strcmp(fCurrentFile, fStartFile)) != 0)
2826 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
2827
2830
2834
2836
2837 fsolmap[local_name.Data()] = paraboloid;
2838
2839 return node;
2840}
2841
2842////////////////////////////////////////////////////////////////////////////////
2843/// In the solids section of the GDML file, an Arb8 may be declared.
2844/// when the arb8 keyword is found, this function is called, and the
2845/// dimensions required are taken and stored, these are then bound and
2846/// converted to type TGeoArb8 and stored in fsolmap map using the name
2847/// as its key.
2848
2850{
2851 TString lunit = fDefault_lunit.c_str();
2852 bool unitless_l = true;
2853 TString v1xpos = "0";
2854 TString v1ypos = "0";
2855 TString v2xpos = "0";
2856 TString v2ypos = "0";
2857 TString v3xpos = "0";
2858 TString v3ypos = "0";
2859 TString v4xpos = "0";
2860 TString v4ypos = "0";
2861 TString v5xpos = "0";
2862 TString v5ypos = "0";
2863 TString v6xpos = "0";
2864 TString v6ypos = "0";
2865 TString v7xpos = "0";
2866 TString v7ypos = "0";
2867 TString v8xpos = "0";
2868 TString v8ypos = "0";
2869 TString dzpos = "0";
2870 TString name = "";
2872
2873 while (attr != nullptr) {
2874
2875 tempattr = gdml->GetAttrName(attr);
2876 tempattr.ToLower();
2877
2878 if (tempattr == "name") {
2879 name = gdml->GetAttrValue(attr);
2880 } else if (tempattr == "v1x") {
2881 v1xpos = gdml->GetAttrValue(attr);
2882 } else if (tempattr == "v1y") {
2883 v1ypos = gdml->GetAttrValue(attr);
2884 } else if (tempattr == "v2x") {
2885 v2xpos = gdml->GetAttrValue(attr);
2886 } else if (tempattr == "v2y") {
2887 v2ypos = gdml->GetAttrValue(attr);
2888 } else if (tempattr == "v3x") {
2889 v3xpos = gdml->GetAttrValue(attr);
2890 } else if (tempattr == "v3y") {
2891 v3ypos = gdml->GetAttrValue(attr);
2892 } else if (tempattr == "v4x") {
2893 v4xpos = gdml->GetAttrValue(attr);
2894 } else if (tempattr == "v4y") {
2895 v4ypos = gdml->GetAttrValue(attr);
2896 } else if (tempattr == "v5x") {
2897 v5xpos = gdml->GetAttrValue(attr);
2898 } else if (tempattr == "v5y") {
2899 v5ypos = gdml->GetAttrValue(attr);
2900 } else if (tempattr == "v6x") {
2901 v6xpos = gdml->GetAttrValue(attr);
2902 } else if (tempattr == "v6y") {
2903 v6ypos = gdml->GetAttrValue(attr);
2904 } else if (tempattr == "v7x") {
2905 v7xpos = gdml->GetAttrValue(attr);
2906 } else if (tempattr == "v7y") {
2907 v7ypos = gdml->GetAttrValue(attr);
2908 } else if (tempattr == "v8x") {
2909 v8xpos = gdml->GetAttrValue(attr);
2910 } else if (tempattr == "v8y") {
2911 v8ypos = gdml->GetAttrValue(attr);
2912 } else if (tempattr == "dz") {
2913 dzpos = gdml->GetAttrValue(attr);
2914 } else if (tempattr == "lunit") {
2915 lunit = gdml->GetAttrValue(attr);
2916 unitless_l = false;
2917 }
2918
2919 attr = gdml->GetNextAttr(attr);
2920 }
2921
2923 if ((strcmp(fCurrentFile, fStartFile)) != 0)
2924 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
2925
2928
2946
2948
2949 arb8->SetVertex(0, v1x, v1y);
2950 arb8->SetVertex(1, v2x, v2y);
2951 arb8->SetVertex(2, v3x, v3y);
2952 arb8->SetVertex(3, v4x, v4y);
2953 arb8->SetVertex(4, v5x, v5y);
2954 arb8->SetVertex(5, v6x, v6y);
2955 arb8->SetVertex(6, v7x, v7y);
2956 arb8->SetVertex(7, v8x, v8y);
2957
2958 fsolmap[local_name.Data()] = arb8;
2959
2960 return node;
2961}
2962
2963////////////////////////////////////////////////////////////////////////////////
2964/// In the solids section of the GDML file, a Tube may be declared.
2965/// when the tube keyword is found, this function is called, and the
2966/// dimensions required are taken and stored, these are then bound and
2967/// converted to type TGeoTubeSeg and stored in fsolmap map using the name
2968/// as its key.
2969
2971{
2972 TString lunit = fDefault_lunit.c_str();
2973 TString aunit = fDefault_aunit.c_str();
2974 bool unitless_l = true;
2975 bool unitless_a = true;
2976 TString rmin = "0";
2977 TString rmax = "0";
2978 TString z = "0";
2979 TString startphi = "0";
2980 TString deltaphi = "0";
2981 TString name = "";
2983
2984 while (attr != nullptr) {
2985
2986 tempattr = gdml->GetAttrName(attr);
2987 tempattr.ToLower();
2988
2989 if (tempattr == "name") {
2990 name = gdml->GetAttrValue(attr);
2991 } else if (tempattr == "rmin") {
2992 rmin = gdml->GetAttrValue(attr);
2993 } else if (tempattr == "rmax") {
2994 rmax = gdml->GetAttrValue(attr);
2995 } else if (tempattr == "z") {
2996 z = gdml->GetAttrValue(attr);
2997 } else if (tempattr == "lunit") {
2998 lunit = gdml->GetAttrValue(attr);
2999 unitless_l = false;
3000 } else if (tempattr == "aunit") {
3001 aunit = gdml->GetAttrValue(attr);
3002 unitless_a = false;
3003 } else if (tempattr == "startphi") {
3004 startphi = gdml->GetAttrValue(attr);
3005 } else if (tempattr == "deltaphi") {
3006 deltaphi = gdml->GetAttrValue(attr);
3007 }
3008
3009 attr = gdml->GetNextAttr(attr);
3010 }
3011
3013 if ((strcmp(fCurrentFile, fStartFile)) != 0)
3014 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3015
3019
3026
3027 TGeoShape *tube = nullptr;
3028 if (deltaphideg < 360.)
3030 else
3032 fsolmap[local_name.Data()] = tube;
3033
3034 return node;
3035}
3036
3037////////////////////////////////////////////////////////////////////////////////
3038/// In the solids section of the GDML file, a Cut Tube may be declared.
3039/// when the cutTube keyword is found, this function is called, and the
3040/// dimensions required are taken and stored, these are then bound and
3041/// converted to type TGeoCtub and stored in fsolmap map using the name
3042/// as its key.
3043
3045{
3046 TString lunit = fDefault_lunit.c_str();
3047 TString aunit = fDefault_aunit.c_str();
3048 bool unitless_l = true;
3049 bool unitless_a = true;
3050 TString rmin = "0";
3051 TString rmax = "0";
3052 TString z = "0";
3053 TString startphi = "0";
3054 TString deltaphi = "0";
3055 TString lowX = "0";
3056 TString lowY = "0";
3057 TString lowZ = "0";
3058 TString highX = "0";
3059 TString highY = "0";
3060 TString highZ = "0";
3061 TString name = "";
3063
3064 while (attr != nullptr) {
3065
3066 tempattr = gdml->GetAttrName(attr);
3067 tempattr.ToLower();
3068
3069 if (tempattr == "name") {
3070 name = gdml->GetAttrValue(attr);
3071 } else if (tempattr == "rmin") {
3072 rmin = gdml->GetAttrValue(attr);
3073 } else if (tempattr == "rmax") {
3074 rmax = gdml->GetAttrValue(attr);
3075 } else if (tempattr == "z") {
3076 z = gdml->GetAttrValue(attr);
3077 } else if (tempattr == "lunit") {
3078 lunit = gdml->GetAttrValue(attr);
3079 unitless_l = false;
3080 } else if (tempattr == "aunit") {
3081 aunit = gdml->GetAttrValue(attr);
3082 unitless_a = false;
3083 } else if (tempattr == "startphi") {
3084 startphi = gdml->GetAttrValue(attr);
3085 } else if (tempattr == "deltaphi") {
3086 deltaphi = gdml->GetAttrValue(attr);
3087 } else if (tempattr == "lowx") {
3088 lowX = gdml->GetAttrValue(attr);
3089 } else if (tempattr == "lowy") {
3090 lowY = gdml->GetAttrValue(attr);
3091 } else if (tempattr == "lowz") {
3092 lowZ = gdml->GetAttrValue(attr);
3093 } else if (tempattr == "highx") {
3094 highX = gdml->GetAttrValue(attr);
3095 } else if (tempattr == "highy") {
3096 highY = gdml->GetAttrValue(attr);
3097 } else if (tempattr == "highz") {
3098 highZ = gdml->GetAttrValue(attr);
3099 }
3100
3101 attr = gdml->GetNextAttr(attr);
3102 }
3103
3105 if ((strcmp(fCurrentFile, fStartFile)) != 0)
3106 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3107
3111
3123
3126
3127 fsolmap[local_name.Data()] = cuttube;
3128
3129 return node;
3130}
3131
3132////////////////////////////////////////////////////////////////////////////////
3133/// In the solids section of the GDML file, a cone may be declared.
3134/// when the cone keyword is found, this function is called, and the
3135/// dimensions required are taken and stored, these are then bound and
3136/// converted to type TGeoConSeg and stored in fsolmap map using the name
3137/// as its key.
3138
3140{
3141 TString lunit = fDefault_lunit.c_str();
3142 TString aunit = fDefault_aunit.c_str();
3143 bool unitless_l = true;
3144 bool unitless_a = true;
3145 TString rmin1 = "0";
3146 TString rmax1 = "0";
3147 TString rmin2 = "0";
3148 TString rmax2 = "0";
3149 TString z = "0";
3150 TString startphi = "0";
3151 TString deltaphi = "0";
3152 TString name = "";
3154
3155 while (attr != nullptr) {
3156
3157 tempattr = gdml->GetAttrName(attr);
3158 tempattr.ToLower();
3159
3160 if (tempattr == "name") {
3161 name = gdml->GetAttrValue(attr);
3162 } else if (tempattr == "rmin1") {
3163 rmin1 = gdml->GetAttrValue(attr);
3164 } else if (tempattr == "rmax1") {
3165 rmax1 = gdml->GetAttrValue(attr);
3166 } else if (tempattr == "rmin2") {
3167 rmin2 = gdml->GetAttrValue(attr);
3168 } else if (tempattr == "rmax2") {
3169 rmax2 = gdml->GetAttrValue(attr);
3170 } else if (tempattr == "z") {
3171 z = gdml->GetAttrValue(attr);
3172 } else if (tempattr == "lunit") {
3173 lunit = gdml->GetAttrValue(attr);
3174 unitless_l = false;
3175 } else if (tempattr == "aunit") {
3176 aunit = gdml->GetAttrValue(attr);
3177 unitless_a = false;
3178 } else if (tempattr == "startphi") {
3179 startphi = gdml->GetAttrValue(attr);
3180 } else if (tempattr == "deltaphi") {
3181 deltaphi = gdml->GetAttrValue(attr);
3182 }
3183
3184 attr = gdml->GetNextAttr(attr);
3185 }
3186
3188 if ((strcmp(fCurrentFile, fStartFile)) != 0)
3189 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3190
3194
3202 Double_t ephi = sphi + dphi;
3203
3204 TGeoShape *cone = nullptr;
3205 if (dphi < 360.)
3207 else
3209
3210 fsolmap[local_name.Data()] = cone;
3211
3212 return node;
3213}
3214
3215////////////////////////////////////////////////////////////////////////////////
3216/// In the solids section of the GDML file, a Trap may be declared.
3217/// when the trap keyword is found, this function is called, and the
3218/// dimensions required are taken and stored, these are then bound and
3219/// converted to type TGeoTrap and stored in fsolmap map using the name
3220/// as its key.
3221
3223{
3224 TString lunit = fDefault_lunit.c_str();
3225 TString aunit = fDefault_aunit.c_str();
3226 bool unitless_l = true;
3227 bool unitless_a = true;
3228 TString x1 = "0";
3229 TString x2 = "0";
3230 TString x3 = "0";
3231 TString x4 = "0";
3232 TString y1 = "0";
3233 TString y2 = "0";
3234 TString z = "0";
3235 TString phi = "0";
3236 TString theta = "0";
3237 TString alpha1 = "0";
3238 TString alpha2 = "0";
3239 TString name = "";
3241
3242 while (attr != nullptr) {
3243
3244 tempattr = gdml->GetAttrName(attr);
3245 tempattr.ToLower();
3246
3247 if (tempattr == "name") {
3248 name = gdml->GetAttrValue(attr);
3249 } else if (tempattr == "x1") {
3250 x1 = gdml->GetAttrValue(attr);
3251 } else if (tempattr == "x2") {
3252 x2 = gdml->GetAttrValue(attr);
3253 } else if (tempattr == "x3") {
3254 x3 = gdml->GetAttrValue(attr);
3255 } else if (tempattr == "x4") {
3256 x4 = gdml->GetAttrValue(attr);
3257 } else if (tempattr == "y1") {
3258 y1 = gdml->GetAttrValue(attr);
3259 } else if (tempattr == "y2") {
3260 y2 = gdml->GetAttrValue(attr);
3261 } else if (tempattr == "z") {
3262 z = gdml->GetAttrValue(attr);
3263 } else if (tempattr == "lunit") {
3264 lunit = gdml->GetAttrValue(attr);
3265 unitless_l = false;
3266 } else if (tempattr == "aunit") {
3267 aunit = gdml->GetAttrValue(attr);
3268 unitless_a = false;
3269 } else if (tempattr == "phi") {
3270 phi = gdml->GetAttrValue(attr);
3271 } else if (tempattr == "theta") {
3272 theta = gdml->GetAttrValue(attr);
3273 } else if (tempattr == "alpha1") {
3274 alpha1 = gdml->GetAttrValue(attr);
3275 } else if (tempattr == "alpha2") {
3276 alpha2 = gdml->GetAttrValue(attr);
3277 }
3278
3279 attr = gdml->GetNextAttr(attr);
3280 }
3281
3283 if ((strcmp(fCurrentFile, fStartFile)) != 0)
3284 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3285
3289
3297 Double_t philine = Value(phi) * retaunit;
3298 Double_t thetaline = Value(theta) * retaunit;
3301
3303 alpha1line, y2line / 2, x3line / 2, x4line / 2, alpha2line);
3304
3305 fsolmap[local_name.Data()] = trap;
3306
3307 return node;
3308}
3309
3310////////////////////////////////////////////////////////////////////////////////
3311/// In the solids section of the GDML file, a Trd may be declared.
3312/// when the trd keyword is found, this function is called, and the
3313/// dimensions required are taken and stored, these are then bound and
3314/// converted to type TGeoTrd2 and stored in fsolmap map using the name
3315/// as its key.
3316
3318{
3319 TString lunit = fDefault_lunit.c_str();
3320 bool unitless_l = true;
3321 TString x1 = "0";
3322 TString x2 = "0";
3323 TString y1 = "0";
3324 TString y2 = "0";
3325 TString z = "0";
3326 TString name = "";
3328
3329 while (attr != nullptr) {
3330
3331 tempattr = gdml->GetAttrName(attr);
3332 tempattr.ToLower();
3333
3334 if (tempattr == "name") {
3335 name = gdml->GetAttrValue(attr);
3336 } else if (tempattr == "x1") {
3337 x1 = gdml->GetAttrValue(attr);
3338 } else if (tempattr == "x2") {
3339 x2 = gdml->GetAttrValue(attr);
3340 } else if (tempattr == "y1") {
3341 y1 = gdml->GetAttrValue(attr);
3342 } else if (tempattr == "y2") {
3343 y2 = gdml->GetAttrValue(attr);
3344 } else if (tempattr == "z") {
3345 z = gdml->GetAttrValue(attr);
3346 } else if (tempattr == "lunit") {
3347 lunit = gdml->GetAttrValue(attr);
3348 unitless_l = false;
3349 }
3350
3351 attr = gdml->GetNextAttr(attr);
3352 }
3353
3355 if ((strcmp(fCurrentFile, fStartFile)) != 0)
3356 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3357
3360
3366
3367 TGeoTrd2 *trd = new TGeoTrd2(NameShort(name), x1line / 2, x2line / 2, y1line / 2, y2line / 2, zline / 2);
3368
3369 fsolmap[local_name.Data()] = trd;
3370
3371 return node;
3372}
3373
3374////////////////////////////////////////////////////////////////////////////////
3375/// In the solids section of the GDML file, a Polycone may be declared.
3376/// when the polycone keyword is found, this function is called, and the
3377/// dimensions required are taken and stored, these are then bound and
3378/// converted to type TGeoPCon and stored in fsolmap map using the name
3379/// as its key. Polycone has Zplanes, planes along the z axis specifying
3380/// the rmin, rmax dimensions at that point along z.
3381
3383{
3384 TString lunit = fDefault_lunit.c_str();
3385 TString aunit = fDefault_aunit.c_str();
3386 bool unitless_l = true;
3387 bool unitless_a = true;
3388 TString rmin = "0";
3389 TString rmax = "0";
3390 TString z = "0";
3391 TString startphi = "0";
3392 TString deltaphi = "0";
3393 TString name = "";
3395
3396 while (attr != nullptr) {
3397
3398 tempattr = gdml->GetAttrName(attr);
3399 tempattr.ToLower();
3400
3401 if (tempattr == "name") {
3402 name = gdml->GetAttrValue(attr);
3403 } else if (tempattr == "lunit") {
3404 lunit = gdml->GetAttrValue(attr);
3405 unitless_l = false;
3406 } else if (tempattr == "aunit") {
3407 aunit = gdml->GetAttrValue(attr);
3408 unitless_a = false;
3409 } else if (tempattr == "startphi") {
3410 startphi = gdml->GetAttrValue(attr);
3411 } else if (tempattr == "deltaphi") {
3412 deltaphi = gdml->GetAttrValue(attr);
3413 }
3414 attr = gdml->GetNextAttr(attr);
3415 }
3416
3418 if ((strcmp(fCurrentFile, fStartFile)) != 0)
3419 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3420
3424
3425 // START TO LOOK THRU CHILD (ZPLANE) NODES...
3426
3427 XMLNodePointer_t child = gdml->GetChild(node);
3428 int numplanes = 0;
3429
3430 while (child != nullptr) {
3431 numplanes = numplanes + 1;
3432 child = gdml->GetNext(child);
3433 }
3434 if (numplanes < 2) {
3435 Fatal("Polycone", "Found less than 2 planes for polycone %s", name.Data());
3436 return child;
3437 }
3438
3439 int cols;
3440 int i;
3441 cols = 3;
3442 double **table = new double *[numplanes];
3443 for (i = 0; i < numplanes; i++) {
3444 table[i] = new double[cols];
3445 }
3446
3447 child = gdml->GetChild(node);
3448 int planeno = 0;
3449
3450 while (child != nullptr) {
3451 if (strcmp(gdml->GetNodeName(child), "zplane") == 0) {
3452 // removed original dec
3453 Double_t rminline = 0;
3454 Double_t rmaxline = 0;
3455 Double_t zline = 0;
3456
3457 attr = gdml->GetFirstAttr(child);
3458
3459 while (attr != nullptr) {
3460 tempattr = gdml->GetAttrName(attr);
3461 tempattr.ToLower();
3462
3463 if (tempattr == "rmin") {
3464 rmin = gdml->GetAttrValue(attr);
3466 table[planeno][0] = rminline;
3467 } else if (tempattr == "rmax") {
3468 rmax = gdml->GetAttrValue(attr);
3470 table[planeno][1] = rmaxline;
3471 } else if (tempattr == "z") {
3472 z = gdml->GetAttrValue(attr);
3473 zline = Value(z) * retlunit;
3474 table[planeno][2] = zline;
3475 }
3476 attr = gdml->GetNextAttr(attr);
3477 }
3478 }
3479 planeno = planeno + 1;
3480 child = gdml->GetNext(child);
3481 }
3482
3485
3487 Int_t zno = 0;
3488
3489 for (int j = 0; j < numplanes; j++) {
3490 poly->DefineSection(zno, table[j][2], table[j][0], table[j][1]);
3491 zno = zno + 1;
3492 }
3493
3494 fsolmap[local_name.Data()] = poly;
3495 for (i = 0; i < numplanes; i++) {
3496 delete[] table[i];
3497 }
3498 delete[] table;
3499
3500 return node;
3501}
3502
3503////////////////////////////////////////////////////////////////////////////////
3504/// In the solids section of the GDML file, a Polyhedra may be declared.
3505/// when the polyhedra keyword is found, this function is called, and the
3506/// dimensions required are taken and stored, these are then bound and
3507/// converted to type TGeoPgon and stored in fsolmap map using the name
3508/// as its key. Polycone has Zplanes, planes along the z axis specifying
3509/// the rmin, rmax dimensions at that point along z.
3510
3512{
3513 TString lunit = fDefault_lunit.c_str();
3514 TString aunit = fDefault_aunit.c_str();
3515 bool unitless_l = true;
3516 bool unitless_a = true;
3517 TString rmin = "0";
3518 TString rmax = "0";
3519 TString z = "0";
3520 TString startphi = "0";
3521 TString deltaphi = "0";
3522 TString numsides = "1";
3523 TString name = "";
3525
3526 while (attr != nullptr) {
3527
3528 tempattr = gdml->GetAttrName(attr);
3529 tempattr.ToLower();
3530
3531 if (tempattr == "name") {
3532 name = gdml->GetAttrValue(attr);
3533 } else if (tempattr == "lunit") {
3534 lunit = gdml->GetAttrValue(attr);
3535 unitless_l = false;
3536 } else if (tempattr == "aunit") {
3537 aunit = gdml->GetAttrValue(attr);
3538 unitless_a = false;
3539 } else if (tempattr == "startphi") {
3540 startphi = gdml->GetAttrValue(attr);
3541 } else if (tempattr == "deltaphi") {
3542 deltaphi = gdml->GetAttrValue(attr);
3543 } else if (tempattr == "numsides") {
3544 numsides = gdml->GetAttrValue(attr);
3545 }
3546
3547 attr = gdml->GetNextAttr(attr);
3548 }
3549
3551 if ((strcmp(fCurrentFile, fStartFile)) != 0)
3552 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3553
3557
3558 // START TO LOOK THRU CHILD (ZPLANE) NODES...
3559
3560 XMLNodePointer_t child = gdml->GetChild(node);
3561 int numplanes = 0;
3562
3563 while (child != nullptr) {
3564 numplanes = numplanes + 1;
3565 child = gdml->GetNext(child);
3566 }
3567 if (numplanes < 2) {
3568 Fatal("Polyhedra", "Found less than 2 planes for polyhedra %s", name.Data());
3569 return child;
3570 }
3571
3572 int cols;
3573 int i;
3574 cols = 3;
3575 double **table = new double *[numplanes];
3576 for (i = 0; i < numplanes; i++) {
3577 table[i] = new double[cols];
3578 }
3579
3580 child = gdml->GetChild(node);
3581 int planeno = 0;
3582
3583 while (child != nullptr) {
3584 if (strcmp(gdml->GetNodeName(child), "zplane") == 0) {
3585
3586 Double_t rminline = 0;
3587 Double_t rmaxline = 0;
3588 Double_t zline = 0;
3589 attr = gdml->GetFirstAttr(child);
3590
3591 while (attr != nullptr) {
3592 tempattr = gdml->GetAttrName(attr);
3593 tempattr.ToLower();
3594
3595 if (tempattr == "rmin") {
3596 rmin = gdml->GetAttrValue(attr);
3598 table[planeno][0] = rminline;
3599 } else if (tempattr == "rmax") {
3600 rmax = gdml->GetAttrValue(attr);
3602 table[planeno][1] = rmaxline;
3603 } else if (tempattr == "z") {
3604 z = gdml->GetAttrValue(attr);
3605 zline = Value(z) * retlunit;
3606 table[planeno][2] = zline;
3607 }
3608
3609 attr = gdml->GetNextAttr(attr);
3610 }
3611 }
3612 planeno = planeno + 1;
3613 child = gdml->GetNext(child);
3614 }
3615
3619
3621 Int_t zno = 0;
3622
3623 for (int j = 0; j < numplanes; j++) {
3624 polyg->DefineSection(zno, table[j][2], table[j][0], table[j][1]);
3625 zno = zno + 1;
3626 }
3627
3628 fsolmap[local_name.Data()] = polyg;
3629 for (i = 0; i < numplanes; i++) {
3630 delete[] table[i];
3631 }
3632 delete[] table;
3633
3634 return node;
3635}
3636
3637////////////////////////////////////////////////////////////////////////////////
3638/// In the solids section of the GDML file, a Sphere may be declared.
3639/// when the sphere keyword is found, this function is called, and the
3640/// dimensions required are taken and stored, these are then bound and
3641/// converted to type TGeoSphere and stored in fsolmap map using the name
3642/// as its key.
3643
3645{
3646 TString lunit = fDefault_lunit.c_str();
3647 TString aunit = fDefault_aunit.c_str();
3648 bool unitless_l = true;
3649 bool unitless_a = true;
3650 TString rmin = "0";
3651 TString rmax = "0";
3652 TString startphi = "0";
3653 TString deltaphi = "0";
3654 TString starttheta = "0";
3655 TString deltatheta = "0";
3656 TString name = "";
3658
3659 while (attr != nullptr) {
3660 tempattr = gdml->GetAttrName(attr);
3661 tempattr.ToLower();
3662
3663 if (tempattr == "name") {
3664 name = gdml->GetAttrValue(attr);
3665 } else if (tempattr == "rmin") {
3666 rmin = gdml->GetAttrValue(attr);
3667 } else if (tempattr == "rmax") {
3668 rmax = gdml->GetAttrValue(attr);
3669 } else if (tempattr == "lunit") {
3670 lunit = gdml->GetAttrValue(attr);
3671 unitless_l = false;
3672 } else if (tempattr == "aunit") {
3673 aunit = gdml->GetAttrValue(attr);
3674 unitless_a = false;
3675 } else if (tempattr == "startphi") {
3676 startphi = gdml->GetAttrValue(attr);
3677 } else if (tempattr == "deltaphi") {
3678 deltaphi = gdml->GetAttrValue(attr);
3679 } else if (tempattr == "starttheta") {
3680 starttheta = gdml->GetAttrValue(attr);
3681 } else if (tempattr == "deltatheta") {
3682 deltatheta = gdml->GetAttrValue(attr);
3683 }
3684
3685 attr = gdml->GetNextAttr(attr);
3686 }
3687
3689 if ((strcmp(fCurrentFile, fStartFile)) != 0)
3690 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3691
3695
3702
3705
3706 fsolmap[local_name.Data()] = sphere;
3707
3708 return node;
3709}
3710
3711////////////////////////////////////////////////////////////////////////////////
3712/// In the solids section of the GDML file, a Torus may be declared.
3713/// when the torus keyword is found, this function is called, and the
3714/// dimensions required are taken and stored, these are then bound and
3715/// converted to type TGeoTorus and stored in fsolmap map using the name
3716/// as its key.
3717
3719{
3720 TString lunit = fDefault_lunit.c_str();
3721 TString aunit = fDefault_aunit.c_str();
3722 bool unitless_l = true;
3723 bool unitless_a = true;
3724 TString rmin = "0";
3725 TString rmax = "0";
3726 TString rtor = "0";
3727 TString startphi = "0";
3728 TString deltaphi = "0";
3729 TString name = "";
3731
3732 while (attr != nullptr) {
3733
3734 tempattr = gdml->GetAttrName(attr);
3735 tempattr.ToLower();
3736
3737 if (tempattr == "name") {
3738 name = gdml->GetAttrValue(attr);
3739 } else if (tempattr == "rmin") {
3740 rmin = gdml->GetAttrValue(attr);
3741 } else if (tempattr == "rmax") {
3742 rmax = gdml->GetAttrValue(attr);
3743 } else if (tempattr == "rtor") {
3744 rtor = gdml->GetAttrValue(attr);
3745 } else if (tempattr == "lunit") {
3746 lunit = gdml->GetAttrValue(attr);
3747 unitless_l = false;
3748 } else if (tempattr == "aunit") {
3749 aunit = gdml->GetAttrValue(attr);
3750 unitless_a = false;
3751 } else if (tempattr == "startphi") {
3752 startphi = gdml->GetAttrValue(attr);
3753 } else if (tempattr == "deltaphi") {
3754 deltaphi = gdml->GetAttrValue(attr);
3755 }
3756
3757 attr = gdml->GetNextAttr(attr);
3758 }
3759
3761 if ((strcmp(fCurrentFile, fStartFile)) != 0)
3762 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3763
3767
3773
3775
3776 fsolmap[local_name.Data()] = torus;
3777
3778 return node;
3779}
3780
3781////////////////////////////////////////////////////////////////////////////////
3782/// In the solids section of the GDML file, a Hype may be declared.
3783/// when the hype keyword is found, this function is called, and the
3784/// dimensions required are taken and stored, these are then bound and
3785/// converted to type TGeoHype and stored in fsolmap map using the name
3786/// as its key.
3787
3789{
3790 TString lunit = fDefault_lunit.c_str();
3791 TString aunit = fDefault_aunit.c_str();
3792 bool unitless_l = true;
3793 bool unitless_a = true;
3794 TString rmin = "0";
3795 TString rmax = "0";
3796 TString z = "0";
3797 TString inst = "0";
3798 TString outst = "0";
3799 TString name = "";
3801
3802 while (attr != nullptr) {
3803 tempattr = gdml->GetAttrName(attr);
3804 tempattr.ToLower();
3805
3806 if (tempattr == "name") {
3807 name = gdml->GetAttrValue(attr);
3808 } else if (tempattr == "rmin") {
3809 rmin = gdml->GetAttrValue(attr);
3810 } else if (tempattr == "rmax") {
3811 rmax = gdml->GetAttrValue(attr);
3812 } else if (tempattr == "z") {
3813 z = gdml->GetAttrValue(attr);
3814 } else if (tempattr == "lunit") {
3815 lunit = gdml->GetAttrValue(attr);
3816 unitless_l = false;
3817 } else if (tempattr == "aunit") {
3818 aunit = gdml->GetAttrValue(attr);
3819 unitless_a = false;
3820 } else if (tempattr == "inst") {
3821 inst = gdml->GetAttrValue(attr);
3822 } else if (tempattr == "outst") {
3823 outst = gdml->GetAttrValue(attr);
3824 }
3825
3826 attr = gdml->GetNextAttr(attr);
3827 }
3828
3830 if ((strcmp(fCurrentFile, fStartFile)) != 0)
3831 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3832
3836
3842
3844
3845 fsolmap[local_name.Data()] = hype;
3846
3847 return node;
3848}
3849
3850////////////////////////////////////////////////////////////////////////////////
3851/// In the solids section of the GDML file, a Para may be declared.
3852/// when the para keyword is found, this function is called, and the
3853/// dimensions required are taken and stored, these are then bound and
3854/// converted to type TGeoPara and stored in fsolmap map using the name
3855/// as its key.
3856
3858{
3859 TString lunit = fDefault_lunit.c_str();
3860 TString aunit = fDefault_aunit.c_str();
3861 bool unitless_l = true;
3862 bool unitless_a = true;
3863 TString x = "0";
3864 TString y = "0";
3865 TString z = "0";
3866 TString phi = "0";
3867 TString theta = "0";
3868 TString alpha = "0";
3869 TString name = "";
3871
3872 while (attr != nullptr) {
3873
3874 tempattr = gdml->GetAttrName(attr);
3875 tempattr.ToLower();
3876
3877 if (tempattr == "name") {
3878 name = gdml->GetAttrValue(attr);
3879 } else if (tempattr == "x") {
3880 x = gdml->GetAttrValue(attr);
3881 } else if (tempattr == "y") {
3882 y = gdml->GetAttrValue(attr);
3883 } else if (tempattr == "z") {
3884 z = gdml->GetAttrValue(attr);
3885 } else if (tempattr == "lunit") {
3886 lunit = gdml->GetAttrValue(attr);
3887 unitless_l = false;
3888 } else if (tempattr == "aunit") {
3889 aunit = gdml->GetAttrValue(attr);
3890 unitless_a = false;
3891 } else if (tempattr == "phi") {
3892 phi = gdml->GetAttrValue(attr);
3893 } else if (tempattr == "theta") {
3894 theta = gdml->GetAttrValue(attr);
3895 } else if (tempattr == "alpha") {
3896 alpha = gdml->GetAttrValue(attr);
3897 }
3898
3899 attr = gdml->GetNextAttr(attr);
3900 }
3901
3903 if ((strcmp(fCurrentFile, fStartFile)) != 0)
3904 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3905
3909
3913 Double_t philine = Value(phi) * retaunit;
3914 Double_t alphaline = Value(alpha) * retaunit;
3915 Double_t thetaline = Value(theta) * retaunit;
3916
3918
3919 fsolmap[local_name.Data()] = para;
3920
3921 return node;
3922}
3923
3924////////////////////////////////////////////////////////////////////////////////
3925/// In the solids section of the GDML file, a TwistTrap may be declared.
3926/// when the twistedtrap keyword is found, this function is called, and the
3927/// dimensions required are taken and stored, these are then bound and
3928/// converted to type TGeoGTra and stored in fsolmap map using the name
3929/// as its key.
3930
3932{
3933 TString lunit = fDefault_lunit.c_str();
3934 TString aunit = fDefault_aunit.c_str();
3935 bool unitless_l = true;
3936 bool unitless_a = true;
3937 TString x1 = "0";
3938 TString x2 = "0";
3939 TString x3 = "0";
3940 TString x4 = "0";
3941 TString y1 = "0";
3942 TString y2 = "0";
3943 TString z = "0";
3944 TString phi = "0";
3945 TString theta = "0";
3946 TString alpha1 = "0";
3947 TString alpha2 = "0";
3948 TString twist = "0";
3949 TString name = "";
3951
3952 while (attr != nullptr) {
3953
3954 tempattr = gdml->GetAttrName(attr);
3955 tempattr.ToLower();
3956
3957 if (tempattr == "name") {
3958 name = gdml->GetAttrValue(attr);
3959 } else if (tempattr == "x1") {
3960 x1 = gdml->GetAttrValue(attr);
3961 } else if (tempattr == "x2") {
3962 x2 = gdml->GetAttrValue(attr);
3963 } else if (tempattr == "x3") {
3964 x3 = gdml->GetAttrValue(attr);
3965 } else if (tempattr == "x4") {
3966 x4 = gdml->GetAttrValue(attr);
3967 } else if (tempattr == "y1") {
3968 y1 = gdml->GetAttrValue(attr);
3969 } else if (tempattr == "y2") {
3970 y2 = gdml->GetAttrValue(attr);
3971 } else if (tempattr == "z") {
3972 z = gdml->GetAttrValue(attr);
3973 } else if (tempattr == "lunit") {
3974 lunit = gdml->GetAttrValue(attr);
3975 unitless_l = false;
3976 } else if (tempattr == "aunit") {
3977 aunit = gdml->GetAttrValue(attr);
3978 unitless_a = false;
3979 } else if (tempattr == "phi") {
3980 phi = gdml->GetAttrValue(attr);
3981 } else if (tempattr == "theta") {
3982 theta = gdml->GetAttrValue(attr);
3983 } else if (tempattr == "alph") { // gdml schema knows only alph attribute
3984 alpha1 = gdml->GetAttrValue(attr);
3985 alpha2 = alpha1;
3986 //} else if (tempattr == "alpha2") {
3987 // alpha2 = gdml->GetAttrValue(attr);
3988 } else if (tempattr == "phitwist") {
3989 twist = gdml->GetAttrValue(attr);
3990 }
3991
3992 attr = gdml->GetNextAttr(attr);
3993 }
3994
3996 if ((strcmp(fCurrentFile, fStartFile)) != 0)
3997 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
3998
4002
4010 Double_t philine = Value(phi) * retaunit;
4011 Double_t thetaline = Value(theta) * retaunit;
4015
4017 x2line / 2, alpha1line, y2line / 2, x3line / 2, x4line / 2, alpha2line);
4018
4019 fsolmap[local_name.Data()] = twtrap;
4020
4021 return node;
4022}
4023
4024////////////////////////////////////////////////////////////////////////////////
4025/// In the solids section of the GDML file, a ElTube may be declared.
4026/// when the eltube keyword is found, this function is called, and the
4027/// dimensions required are taken and stored, these are then bound and
4028/// converted to type TGeoEltu and stored in fsolmap map using the name
4029/// as its key.
4030
4032{
4033 TString lunit = fDefault_lunit.c_str();
4034 bool unitless_l = true;
4035 TString xpos = "0";
4036 TString ypos = "0";
4037 TString zpos = "0";
4038 TString name = "";
4040
4041 while (attr != nullptr) {
4042
4043 tempattr = gdml->GetAttrName(attr);
4044 tempattr.ToLower();
4045
4046 if (tempattr == "name") {
4047 name = gdml->GetAttrValue(attr);
4048 } else if (tempattr == "dx") {
4049 xpos = gdml->GetAttrValue(attr);
4050 } else if (tempattr == "dy") {
4051 ypos = gdml->GetAttrValue(attr);
4052 } else if (tempattr == "dz") {
4053 zpos = gdml->GetAttrValue(attr);
4054 } else if (tempattr == "lunit") {
4055 lunit = gdml->GetAttrValue(attr);
4056 unitless_l = false;
4057 }
4058
4059 attr = gdml->GetNextAttr(attr);
4060 }
4061
4063 if ((strcmp(fCurrentFile, fStartFile)) != 0)
4064 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
4065
4068
4072
4074
4075 fsolmap[local_name.Data()] = eltu;
4076
4077 return node;
4078}
4079////////////////////////////////////////////////////////////////////////////////
4080/// In the solids section of the GDML file, an Orb may be declared.
4081/// when the orb keyword is found, this function is called, and the
4082/// dimensions required are taken and stored, these are then bound and
4083/// converted to type TGeoSphere and stored in fsolmap map using the name
4084/// as its key.
4085
4087{
4088 TString lunit = fDefault_lunit.c_str();
4089 bool unitless_l = true;
4090 TString r = "0";
4091 TString name = "";
4093
4094 while (attr != nullptr) {
4095
4096 tempattr = gdml->GetAttrName(attr);
4097 tempattr.ToLower();
4098
4099 if (tempattr == "name") {
4100 name = gdml->GetAttrValue(attr);
4101 } else if (tempattr == "r") {
4102 r = gdml->GetAttrValue(attr);
4103 } else if (tempattr == "lunit") {
4104 lunit = gdml->GetAttrValue(attr);
4105 unitless_l = false;
4106 }
4107
4108 attr = gdml->GetNextAttr(attr);
4109 }
4110
4112 if ((strcmp(fCurrentFile, fStartFile)) != 0)
4113 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
4114
4117
4119
4120 TGeoSphere *orb = new TGeoSphere(NameShort(name), 0, rline, 0, 180, 0, 360);
4121
4122 fsolmap[local_name.Data()] = orb;
4123
4124 return node;
4125}
4126
4127////////////////////////////////////////////////////////////////////////////////
4128/// In the solids section of the GDML file, an Xtru may be declared.
4129/// when the xtru keyword is found, this function is called, and the
4130/// dimensions required are taken and stored, these are then bound and
4131/// converted to type TGeoXtru and stored in fsolmap map using the name
4132/// as its key. The xtru has child nodes of either 'twoDimVertex'or
4133/// 'section'. These two nodes define the real structure of the shape.
4134/// The twoDimVertex's define the x,y sizes of a vertice. The section links
4135/// the vertice to a position within the xtru.
4136
4138{
4139 TString lunit = fDefault_lunit.c_str();
4140 bool unitless_l = true;
4141 TString x = "0";
4142 TString y = "0";
4143 TString zorder = "0";
4144 TString zpos = "0";
4145 TString xoff = "0";
4146 TString yoff = "0";
4147 TString scale = "0";
4148 TString name = "";
4150
4151 while (attr != nullptr) {
4152
4153 tempattr = gdml->GetAttrName(attr);
4154 tempattr.ToLower();
4155
4156 if (tempattr == "name") {
4157 name = gdml->GetAttrValue(attr);
4158 } else if (tempattr == "lunit") {
4159 lunit = gdml->GetAttrValue(attr);
4160 unitless_l = false;
4161 }
4162
4163 attr = gdml->GetNextAttr(attr);
4164 }
4165
4167 if ((strcmp(fCurrentFile, fStartFile)) != 0)
4168 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
4169
4172
4173 // START TO LOOK THRU CHILD NODES...
4174
4175 XMLNodePointer_t child = gdml->GetChild(node);
4176 int nosects = 0;
4177 int noverts = 0;
4178
4179 while (child != nullptr) {
4180 tempattr = gdml->GetNodeName(child);
4181
4182 if (tempattr == "twoDimVertex") {
4183 noverts = noverts + 1;
4184 } else if (tempattr == "section") {
4185 nosects = nosects + 1;
4186 }
4187
4188 child = gdml->GetNext(child);
4189 }
4190
4191 if (nosects < 2 || noverts < 3) {
4192 Fatal("Xtru", "Invalid number of sections/vertices found forxtru %s", name.Data());
4193 return child;
4194 }
4195
4196 // Build the dynamic arrays..
4197 int cols;
4198 int i;
4199 double *vertx = new double[noverts];
4200 double *verty = new double[noverts];
4201 cols = 5;
4202 double **section = new double *[nosects];
4203 for (i = 0; i < nosects; i++) {
4204 section[i] = new double[cols];
4205 }
4206
4207 child = gdml->GetChild(node);
4208 int sect = 0;
4209 int vert = 0;
4210
4211 while (child != nullptr) {
4212 if (strcmp(gdml->GetNodeName(child), "twoDimVertex") == 0) {
4213 Double_t xline = 0;
4214 Double_t yline = 0;
4215
4216 attr = gdml->GetFirstAttr(child);
4217
4218 while (attr != nullptr) {
4219 tempattr = gdml->GetAttrName(attr);
4220
4221 if (tempattr == "x") {
4222 x = gdml->GetAttrValue(attr);
4223 xline = Value(x) * retlunit;
4224 vertx[vert] = xline;
4225 } else if (tempattr == "y") {
4226 y = gdml->GetAttrValue(attr);
4227 yline = Value(y) * retlunit;
4228 verty[vert] = yline;
4229 }
4230
4231 attr = gdml->GetNextAttr(attr);
4232 }
4233
4234 vert = vert + 1;
4235 }
4236
4237 else if (strcmp(gdml->GetNodeName(child), "section") == 0) {
4238
4239 Double_t zposline = 0;
4240 Double_t xoffline = 0;
4241 Double_t yoffline = 0;
4242
4243 attr = gdml->GetFirstAttr(child);
4244
4245 while (attr != nullptr) {
4246 tempattr = gdml->GetAttrName(attr);
4247
4248 if (tempattr == "zOrder") {
4249 zorder = gdml->GetAttrValue(attr);
4250 section[sect][0] = Value(zorder);
4251 } else if (tempattr == "zPosition") {
4252 zpos = gdml->GetAttrValue(attr);
4254 section[sect][1] = zposline;
4255 } else if (tempattr == "xOffset") {
4256 xoff = gdml->GetAttrValue(attr);
4258 section[sect][2] = xoffline;
4259 } else if (tempattr == "yOffset") {
4260 yoff = gdml->GetAttrValue(attr);
4262 section[sect][3] = yoffline;
4263 } else if (tempattr == "scalingFactor") {
4264 scale = gdml->GetAttrValue(attr);
4265 section[sect][4] = Value(scale);
4266 }
4267
4268 attr = gdml->GetNextAttr(attr);
4269 }
4270
4271 sect = sect + 1;
4272 }
4273 child = gdml->GetNext(child);
4274 }
4275
4276 TGeoXtru *xtru = new TGeoXtru(nosects);
4277 xtru->SetName(NameShort(name));
4278 xtru->DefinePolygon(vert, vertx, verty);
4279
4280 for (int j = 0; j < sect; j++) {
4281 xtru->DefineSection((int)section[j][0], section[j][1], section[j][2], section[j][3], section[j][4]);
4282 }
4283
4284 fsolmap[local_name.Data()] = xtru;
4285 delete[] vertx;
4286 delete[] verty;
4287 for (i = 0; i < nosects; i++) {
4288 delete[] section[i];
4289 }
4290 delete[] section;
4291 return node;
4292}
4293
4294////////////////////////////////////////////////////////////////////////////////
4295/// In the solids section of the GDML file, a tessellated shape may be declared.
4296/// When the tessellated keyword is found, this function is called, and the
4297/// triangular/quadrangular facets are read, creating the corresponding
4298/// TGeoTessellated object stored in fsolmap map using the name
4299/// as its key.
4300
4302{
4305
4306 while (attr != nullptr) {
4307 tempattr = gdml->GetAttrName(attr);
4308 tempattr.ToLower();
4309 if (tempattr == "name") {
4310 name = gdml->GetAttrValue(attr);
4311 }
4312 attr = gdml->GetNextAttr(attr);
4313 }
4314
4316 if ((strcmp(fCurrentFile, fStartFile)) != 0)
4317 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
4318
4319 auto tsl = new TGeoTessellated(NameShort(name));
4320 TGeoTranslation *pos = nullptr;
4321 Tessellated::Vertex_t vertices[4];
4322
4323 auto SetVertex = [&](int i, TGeoTranslation *trans) {
4324 if (trans == nullptr)
4325 return;
4326 const double *tr = trans->GetTranslation();
4327 vertices[i].Set(tr[0], tr[1], tr[2]);
4328 };
4329
4330 auto AddTriangularFacet = [&](bool relative) {
4331 if (relative) {
4332 vertices[2] += vertices[0] + vertices[1];
4333 vertices[1] += vertices[0];
4334 }
4335 tsl->AddFacet(vertices[0], vertices[1], vertices[2]);
4336 };
4337
4338 auto AddQuadrangularFacet = [&](bool relative) {
4339 if (relative) {
4340 vertices[3] += vertices[0] + vertices[1] + vertices[2];
4341 vertices[2] += vertices[0] + vertices[1];
4342 vertices[1] += vertices[0];
4343 }
4344 tsl->AddFacet(vertices[0], vertices[1], vertices[2], vertices[3]);
4345 };
4346
4347 // Get facet attributes
4348 XMLNodePointer_t child = gdml->GetChild(node);
4349 while (child != nullptr) {
4350 tempattr = gdml->GetNodeName(child);
4351 tempattr.ToLower();
4352 if (tempattr == "triangular") {
4353 attr = gdml->GetFirstAttr(child);
4354 bool relative = false;
4355
4356 while (attr != nullptr) {
4357 tempattr = gdml->GetAttrName(attr);
4358
4359 if (tempattr == "vertex1") {
4360 vname = gdml->GetAttrValue(attr);
4361 pos = GetPosition(vname.Data());
4362 if (!pos)
4363 Fatal("Tessellated", "Vertex %s not defined", vname.Data());
4364 SetVertex(0, pos);
4365 }
4366
4367 else if (tempattr == "vertex2") {
4368 vname = gdml->GetAttrValue(attr);
4369 pos = GetPosition(vname.Data());
4370 if (!pos)
4371 Fatal("Tessellated", "Vertex %s not defined", vname.Data());
4372 SetVertex(1, pos);
4373 }
4374
4375 else if (tempattr == "vertex3") {
4376 vname = gdml->GetAttrValue(attr);
4377 pos = GetPosition(vname.Data());
4378 if (!pos)
4379 Fatal("Tessellated", "Vertex %s not defined", vname.Data());
4380 SetVertex(2, pos);
4381 }
4382
4383 else if (tempattr == "type") {
4384 type = gdml->GetAttrValue(attr);
4385 type.ToLower();
4386 relative = (type == "relative") ? true : false;
4387 }
4388
4389 attr = gdml->GetNextAttr(attr);
4390 }
4392 }
4393
4394 else if (tempattr == "quadrangular") {
4395 attr = gdml->GetFirstAttr(child);
4396 bool relative = false;
4397
4398 while (attr != nullptr) {
4399 tempattr = gdml->GetAttrName(attr);
4400
4401 if (tempattr == "vertex1") {
4402 vname = gdml->GetAttrValue(attr);
4403 pos = GetPosition(vname.Data());
4404 if (!pos)
4405 Fatal("Tessellated", "Vertex %s not defined", vname.Data());
4406 SetVertex(0, pos);
4407 }
4408
4409 else if (tempattr == "vertex2") {
4410 vname = gdml->GetAttrValue(attr);
4411 pos = GetPosition(vname.Data());
4412 if (!pos)
4413 Fatal("Tessellated", "Vertex %s not defined", vname.Data());
4414 SetVertex(1, pos);
4415 }
4416
4417 else if (tempattr == "vertex3") {
4418 vname = gdml->GetAttrValue(attr);
4419 pos = GetPosition(vname.Data());
4420 if (!pos)
4421 Fatal("Tessellated", "Vertex %s not defined", vname.Data());
4422 SetVertex(2, pos);
4423 }
4424
4425 else if (tempattr == "vertex4") {
4426 vname = gdml->GetAttrValue(attr);
4427 pos = GetPosition(vname.Data());
4428 if (!pos)
4429 Fatal("Tessellated", "Vertex %s not defined", vname.Data());
4430 SetVertex(3, pos);
4431 }
4432
4433 else if (tempattr == "type") {
4434 type = gdml->GetAttrValue(attr);
4435 type.ToLower();
4436 relative = (type == "relative") ? true : false;
4437 }
4438
4439 attr = gdml->GetNextAttr(attr);
4440 }
4442 }
4443 child = gdml->GetNext(child);
4444 }
4445 tsl->CloseShape(false);
4446
4447 fsolmap[local_name.Data()] = tsl;
4448
4449 return node;
4450}
4451
4452////////////////////////////////////////////////////////////////////////////////
4453/// In the solids section of the GDML file, a Scaled Solid may be
4454/// declared when the scaledSolid keyword is found, this function
4455/// is called. The scale transformation is used as internal matrix.
4456
4458{
4461
4462 XMLNodePointer_t child = gdml->GetChild(node);
4463 TString solidname = "";
4464 TGeoShape *solid = nullptr;
4465 TGeoScale *scl = nullptr;
4466
4467 TString name;
4468 while (attr != nullptr) {
4469 tempattr = gdml->GetAttrName(attr);
4470 tempattr.ToLower();
4471 if (tempattr == "name") {
4472 name = gdml->GetAttrValue(attr);
4473 }
4474 attr = gdml->GetNextAttr(attr);
4475 }
4477 if ((strcmp(fCurrentFile, fStartFile)) != 0) {
4478 local_name = TString::Format("%s_%s", name.Data(), fCurrentFile);
4479 }
4480
4481 while (child != nullptr) {
4482 tempattr = gdml->GetNodeName(child);
4483 tempattr.ToLower();
4484 if (tempattr == "solidref") {
4485 reftemp = gdml->GetAttr(child, "ref");
4486 if ((strcmp(fCurrentFile, fStartFile)) != 0) {
4487 reftemp = TString::Format("%s_%s", reftemp.Data(), fCurrentFile);
4488 }
4489 if (fsolmap.find(reftemp.Data()) != fsolmap.end()) {
4490 solid = fsolmap[reftemp.Data()];
4491 } else {
4492 printf("Solid: %s, Not Yet Defined!\n", reftemp.Data());
4493 }
4494 } else if (tempattr == "scale") {
4495 childattr = gdml->GetFirstAttr(child);
4497 reftemp = gdml->GetAttr(child, "name");
4498 scl = GetScaleObj(reftemp.Data());
4499 } else if (tempattr == "scaleref") {
4500 reftemp = gdml->GetAttr(child, "ref");
4501 scl = GetScaleObj(reftemp.Data());
4502 if (!scl)
4503 Fatal("ScaledSolid", "Solid's scale %s not found", reftemp.Data());
4504 }
4505
4506 child = gdml->GetNext(child);
4507 }
4508
4510 fsolmap[local_name.Data()] = scaled;
4511
4512 return child;
4513}
4514
4515////////////////////////////////////////////////////////////////////////////////
4516/// In the solids section of the GDML file, a Reflected Solid may be
4517/// declared when the ReflectedSolid keyword is found, this function
4518/// is called. The rotation, position and scale for the reflection are
4519/// applied to a matrix that is then stored in the class object
4520/// TGDMLRefl. This is then stored in the map freflsolidmap, with
4521/// the reflection name as a reference. also the name of the solid to
4522/// be reflected is stored in a map called freflectmap with the reflection
4523/// name as a reference.
4524
4526{
4527 std::cout << "WARNING! The reflectedSolid is obsolete! Use scale transformation instead!" << std::endl;
4528
4529 TString sx = "0";
4530 TString sy = "0";
4531 TString sz = "0";
4532 TString rx = "0";
4533 TString ry = "0";
4534 TString rz = "0";
4535 TString dx = "0";
4536 TString dy = "0";
4537 TString dz = "0";
4538 TString name = "0";
4539 TString solid = "0";
4541
4542 while (attr != nullptr) {
4543
4544 tempattr = gdml->GetAttrName(attr);
4545 tempattr.ToLower();
4546
4547 if (tempattr == "name") {
4548 name = gdml->GetAttrValue(attr);
4549 } else if (tempattr == "sx") {
4550 sx = gdml->GetAttrValue(attr);
4551 } else if (tempattr == "sy") {
4552 sy = gdml->GetAttrValue(attr);
4553 } else if (tempattr == "sz") {
4554 sz = gdml->GetAttrValue(attr);
4555 } else if (tempattr == "rx") {
4556 rx = gdml->GetAttrValue(attr);
4557 } else if (tempattr == "ry") {
4558 ry = gdml->GetAttrValue(attr);
4559 } else if (tempattr == "rz") {
4560 rz = gdml->GetAttrValue(attr);
4561 } else if (tempattr == "dx") {
4562 dx = gdml->GetAttrValue(attr);
4563 } else if (tempattr == "dy") {
4564 dy = gdml->GetAttrValue(attr);
4565 } else if (tempattr == "dz") {
4566 dz = gdml->GetAttrValue(attr);
4567 } else if (tempattr == "solid") {
4568 solid = gdml->GetAttrValue(attr);
4569 }
4570 attr = gdml->GetNextAttr(attr);
4571 }
4572
4573 if ((strcmp(fCurrentFile, fStartFile)) != 0) {
4574 name = TString::Format("%s_%s", name.Data(), fCurrentFile);
4575 }
4576 if ((strcmp(fCurrentFile, fStartFile)) != 0) {
4577 solid = TString::Format("%s_%s", solid.Data(), fCurrentFile);
4578 }
4579
4580 TGeoRotation *rot = new TGeoRotation();
4581 rot->RotateZ(-(Value(rz)));
4582 rot->RotateY(-(Value(ry)));
4583 rot->RotateX(-(Value(rx)));
4584
4585 if (atoi(sx) == -1) {
4586 rot->ReflectX(kTRUE);
4587 }
4588 if (atoi(sy) == -1) {
4589 rot->ReflectY(kTRUE);
4590 }
4591 if (atoi(sz) == -1) {
4592 rot->ReflectZ(kTRUE);
4593 }
4594
4596
4598 freflsolidmap[name.Data()] = reflsol;
4599 freflectmap[name.Data()] = solid;
4600
4601 return node;
4602}
4603
4604/** \class TGDMLRefl
4605\ingroup Geometry_gdml
4606
4607This class is a helper class for TGDMLParse. It assists in the
4608reflection process. This process takes a previously defined solid
4609and can reflect the matrix of it. This class stores the name of the
4610reflected solid, along with the name of the solid that is being
4611reflected, and finally the reflected solid's matrix. This is then
4612recalled when the volume is used in the structure part of the gdml
4613file.
4614
4615*/
4616
4617
4618////////////////////////////////////////////////////////////////////////////////
4619/// This constructor method stores the values brought in as params.
4620
4622{
4623 fNameS = name;
4624 fSolid = solid;
4625 fMatrix = matrix;
4626}
4627
4628////////////////////////////////////////////////////////////////////////////////
4629/// This accessor method returns the matrix.
4630
4632{
4633 return fMatrix;
4634}
#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:145
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:783
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:326
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 TGDMLRefl for it - containing refl matrix
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 files parsed during entire parsing, with their world volume name
Definition TGDMLParse.h:222
MatrixMap fmatrices
! Map containing matrices defined in the GDML 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 volume names and the TGeoVolume 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 rotation names and the TGeoRotation 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 reflected volume names and the solid ref for it
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 reflection names and the Solid name ir references to
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 material names and the TGeoMaterial for it
Definition TGDMLParse.h:213
SclMap fsclmap
! Map containing scale names and the TGeoScale 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 isotope names and the TGeoIsotope 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 placed volume names and the TGeoNode 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 medium names and the TGeoMedium 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 values of constants declared in the file
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 solid names and the TGeoShape for it
Definition TGDMLParse.h:216
EleMap felemap
! Map containing element names and the TGeoElement 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
! Map containing position names and the TGeoTranslation for it
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 mixture names and the TGeoMixture 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
! reflected solid name
Definition TGDMLParse.h:46
TGeoMatrix * fMatrix
! matrix of reflected solid
Definition TGDMLParse.h:48
TGeoMatrix * GetMatrix()
This accessor method returns the matrix.
const char * fSolid
! solid name being reflected
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:18
Base class for Boolean operations between two shapes.
Class describing rotation + translation.
Definition TGeoMatrix.h:318
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:174
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:153
Matrix class used for computing global transformations Should NOT be used for node definition.
Definition TGeoMatrix.h:459
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:46
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.
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:39
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:169
Class describing scale transformations.
Definition TGeoMatrix.h:254
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:117
const Double_t * GetTranslation() const override
Definition TGeoMatrix.h:155
A general trapezoid.
Definition TGeoArb8.h:99
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:317
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:176
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:363
TObjArray * GetNodes()
Definition TGeoVolume.h:170
TGeoShape * GetShape() const
Definition TGeoVolume.h:191
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
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:1081
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1095
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1123
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1069
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:2385
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