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