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