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