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