Logo ROOT  
Reference Guide
TGDMLWrite.cxx
Go to the documentation of this file.
1 // @(#)root/gdml:$Id$
2 // Author: Anton Pytel 15/9/2011
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2011, 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 TGDMLWrite
13 \ingroup Geometry_gdml
14 
15  This class contains implementation of converting ROOT's gGeoManager
16 geometry to GDML file. gGeoManager is the instance of TGeoManager class
17 containing tree of geometries creating resulting geometry. GDML is xml
18 based format of file mirroring the tree of geometries according to GDML
19 schema rules. For more information about GDML see http://gdml.web.cern.ch.
20 Each object in ROOT is represented by xml tag (=xml node/element) in GDML.
21 
22  This class is not needed to be instanciated. It should always be called
23 by gGeoManager->Export("xyz.gdml") method. Export is driven by extenstion
24 that is why ".gdml" is important in resulting name.
25 
26  Whenever a new ROOT geometry object is implemented or there is a change
27 in GDML schema this class is needed to be updated to ensure proper mapping
28 between ROOT objects and GDML elements.
29 
30  Current status of mapping ROOT -> GDML is implemented in method called
31 TGDMLWrite::ChooseObject and it contains following "map":
32 
33 #### Solids:
34 
35 ~~~
36 TGeoBBox -> <box ... >
37 TGeoParaboloid -> <paraboloid ...>
38 TGeoSphere -> <sphere ...>
39 TGeoArb8 -> <arb8 ...>
40 TGeoConeSeg -> <cone ...>
41 TGeoCone -> <cone ...>
42 TGeoPara -> <para ...>
43 TGeoTrap -> <trap ...> or
44 - -> <arb8 ...>
45 TGeoGtra -> <twistedtrap ...> or
46 - -> <trap ...> or
47 - -> <arb8 ...>
48 TGeoTrd1 -> <trd ...>
49 TGeoTrd2 -> <trd ...>
50 TGeoTubeSeg -> <tube ...>
51 TGeoCtub -> <cutTube ...>
52 TGeoTube -> <tube ...>
53 TGeoPcon -> <polycone ...>
54 TGeoTorus -> <torus ...>
55 TGeoPgon -> <polyhedra ...>
56 TGeoEltu -> <eltube ...>
57 TGeoHype -> <hype ...>
58 TGeoXtru -> <xtru ...>
59 TGeoTessellated -> <tessellated ...>
60 TGeoCompositeShape -> <union ...> or
61 - -> <subtraction ...> or
62 - -> <intersection ...>
63 
64 Special cases of solids:
65 TGeoScaledShape -> <elcone ...> if scaled TGeoCone or
66 - -> element without scale
67 TGeoCompositeShape -> <ellipsoid ...>
68 - intersection of:
69 - scaled TGeoSphere and TGeoBBox
70 ~~~
71 
72 #### Materials:
73 
74 ~~~
75 TGeoIsotope -> <isotope ...>
76 TGeoElement -> <element ...>
77 TGeoMaterial -> <material ...>
78 TGeoMixture -> <material ...>
79 ~~~
80 
81 #### Structure
82 
83 ~~~
84 TGeoVolume -> <volume ...> or
85 - -> <assembly ...>
86 TGeoNode -> <physvol ...>
87 TGeoPatternFinder -> <divisionvol ...>
88 ~~~
89 
90 There are options that can be set to change resulting document
91 
92 ##### Options:
93 
94 ~~~
95 g - is set by default in gGeoManager, this option ensures compatibility
96 - with Geant4. It means:
97 - -> atomic number of material will be changed if <1 to 1
98 - -> if polycone is set badly it will try to export it correctly
99 - -> if widht * ndiv + offset is more then width of object being divided
100 - (in divisions) then it will be rounded so it will not exceed or
101 - if kPhi divsion then it will keep range of offset in -360 -> 0
102 f - if this option is set then names of volumes and solids will have
103 - pointer as a suffix to ensure uniqness of names
104 n - if this option is set then names will not have suffix, but uniqness is
105 - of names is not secured
106 - - if none of this two options (f,n) is set then default behaviour is so
107 - that incremental suffix is added to the names.
108 - (eg. TGeoBBox_0x1, TGeoBBox_0x2 ...)
109 ~~~
110 
111 #### USAGE:
112 
113 ~~~
114 gGeoManager->Export("output.gdml");
115 gGeoManager->Export("output.gdml","","vg"); //the same as previous just
116  //options are set explicitly
117 gGeoManager->Export("output.gdml","","vgf");
118 gGeoManager->Export("output.gdml","","gn");
119 gGeoManager->Export("output.gdml","","f");
120 ...
121 ~~~
122 
123 #### Note:
124  Options discussed above are used only for TGDMLWrite class. There are
125 other options in the TGeoManager::Export(...) method that can be used.
126 See that function for details.
127 
128 */
129 
130 #include "TGDMLWrite.h"
131 
132 #include "TGeoManager.h"
133 #include "TGeoMaterial.h"
134 #include "TGeoMatrix.h"
135 #include "TXMLEngine.h"
136 #include "TGeoVolume.h"
137 #include "TGeoBBox.h"
138 #include "TGeoParaboloid.h"
139 #include "TGeoArb8.h"
140 #include "TGeoTube.h"
141 #include "TGeoCone.h"
142 #include "TGeoTrd1.h"
143 #include "TGeoTrd2.h"
144 #include "TGeoPcon.h"
145 #include "TGeoPgon.h"
146 #include "TGeoSphere.h"
147 #include "TGeoTorus.h"
148 #include "TGeoPara.h"
149 #include "TGeoHype.h"
150 #include "TGeoEltu.h"
151 #include "TGeoXtru.h"
152 #include "TGeoScaledShape.h"
153 #include "TMath.h"
154 #include "TGeoBoolNode.h"
155 #include "TGeoMedium.h"
156 #include "TGeoElement.h"
157 #include "TGeoShape.h"
158 #include "TGeoCompositeShape.h"
159 #include "TGeoOpticalSurface.h"
160 #include <cstdlib>
161 #include <string>
162 #include <map>
163 #include <set>
164 #include <ctime>
165 #include <sstream>
166 
168 
170 
171 namespace {
172  struct MaterialExtractor {
173  std::set<TGeoMaterial*> materials;
174  void operator() (const TGeoVolume* v) {
175  materials.insert(v->GetMaterial());
176  for(Int_t i=0; i<v->GetNdaughters(); ++i)
177  (*this)(v->GetNode(i)->GetVolume());
178  }
179  };
180 }
181 
182 ////////////////////////////////////////////////////////////////////////////////
183 /// Default constructor.
184 
186  : TObject(),
187  fIsotopeList(0),
188  fElementList(0),
189  fAccPatt(0),
190  fRejShape(0),
191  fNameList(0),
192  fgNamingSpeed(0),
193  fgG4Compatibility(0),
194  fGdmlFile(0),
195  fTopVolumeName(0),
196  fGdmlE(0),
197  fDefineNode(0),
198  fMaterialsNode(0),
199  fSolidsNode(0),
200  fStructureNode(0),
201  fVolCnt(0),
202  fPhysVolCnt(0),
203  fActNameErr(0),
204  fSolCnt(0),
205  fFltPrecision(17) // %.17g
206 {
207  if (fgGDMLWrite) delete fgGDMLWrite;
208  fgGDMLWrite = this;
209 }
210 
211 ////////////////////////////////////////////////////////////////////////////////
212 /// Destructor.
213 
215 {
216  delete fIsotopeList;
217  delete fElementList;
218  delete fAccPatt;
219  delete fRejShape;
220  delete fNameList;
221 
222  fgGDMLWrite = 0;
223 }
224 
225 ////////////////////////////////////////////////////////////////////////////////
226 /// Set convention of naming solids and volumes
227 
229 {
230  fgNamingSpeed = naming;
231 }
232 
233 ////////////////////////////////////////////////////////////////////////////////
234 //wrapper of all main methods for extraction
235 void TGDMLWrite::WriteGDMLfile(TGeoManager * geomanager, const char* filename, TString option)
236 {
237  TList* materials = geomanager->GetListOfMaterials();
238  TGeoNode* node = geomanager->GetTopNode();
239  if ( !node ) {
240  Info("WriteGDMLfile", "Top volume does not exist!");
241  return;
242  }
243  fTopVolumeName = "";
244  WriteGDMLfile(geomanager, node, materials, filename, option);
245 }
246 
247 ////////////////////////////////////////////////////////////////////////////////
248 // Wrapper to only selectively write one branch of the volume hierarchy to file
249 void TGDMLWrite::WriteGDMLfile(TGeoManager * geomanager, TGeoNode* node, const char* filename, TString option)
250 {
251  TGeoVolume* volume = node->GetVolume();
252  TList materials, volumes, nodes;
253  MaterialExtractor extract;
254  if ( !volume ) {
255  Info("WriteGDMLfile", "Invalid Volume reference to extract GDML information!");
256  return;
257  }
258  extract(volume);
259  for(TGeoMaterial* m : extract.materials)
260  materials.Add(m);
261  fTopVolumeName = volume->GetName();
262  fSurfaceList.clear();
263  fVolumeList.clear();
264  fNodeList.clear();
265  WriteGDMLfile(geomanager, node, &materials, filename, option);
266  materials.Clear("nodelete");
267  volumes.Clear("nodelete");
268  nodes.Clear("nodelete");
269 }
270 
271 ////////////////////////////////////////////////////////////////////////////////
272 /// Wrapper of all exporting methods
273 /// Creates blank GDML file and fills it with gGeoManager structure converted
274 /// to GDML structure of xml nodes
275 
277  TGeoNode* node,
278  TList* materialsLst,
279  const char* filename,
280  TString option)
281 {
282  //option processing
283  option.ToLower();
284  if (option.Contains("g")) {
286  Info("WriteGDMLfile", "Geant4 compatibility mode set");
287  } else {
289  }
290  if (option.Contains("f")) {
292  Info("WriteGDMLfile", "Fast naming convention with pointer suffix set");
293  } else if (option.Contains("n")) {
295  Info("WriteGDMLfile", "Naming without prefix set - be careful uniqness of name is not ensured");
296  } else {
298  Info("WriteGDMLfile", "Potentially slow with incremental suffix naming convention set");
299  }
300 
301  //local variables
302  Int_t outputLayout = 1;
303  const char * krootNodeName = "gdml";
304  const char * knsRefGeneral = "http://www.w3.org/2001/XMLSchema-instance";
305  const char * knsNameGeneral = "xsi";
306  const char * knsRefGdml = "http://service-spi.web.cern.ch/service-spi/app/releases/GDML/schema/gdml.xsd";
307  const char * knsNameGdml = "xsi:noNamespaceSchemaLocation";
308 
309  // First create engine
310  fGdmlE = new TXMLEngine;
312 
313  //create blank GDML file
314  fGdmlFile = fGdmlE->NewDoc();
315 
316  //create root node and add it to blank GDML file
317  XMLNodePointer_t rootNode = fGdmlE->NewChild(nullptr, nullptr, krootNodeName, nullptr);
318  fGdmlE->DocSetRootElement(fGdmlFile, rootNode);
319 
320  //add namespaces to root node
321  fGdmlE->NewNS(rootNode, knsRefGeneral, knsNameGeneral);
322  fGdmlE->NewAttr(rootNode, nullptr, knsNameGdml, knsRefGdml);
323 
324  //initialize general lists and <define>, <solids>, <structure> nodes
325  fIsotopeList = new StructLst;
326  fElementList = new StructLst;
327 
328  fNameList = new NameLst;
329 
330  fDefineNode = fGdmlE->NewChild(nullptr, nullptr, "define", nullptr);
331  fSolidsNode = fGdmlE->NewChild(nullptr, nullptr, "solids", nullptr);
332  fStructureNode = fGdmlE->NewChild(nullptr, nullptr, "structure", nullptr);
333  //========================
334 
335  //initialize list of accepted patterns for divisions (in ExtractVolumes)
336  fAccPatt = new StructLst;
337  fAccPatt->fLst["TGeoPatternX"] = kTRUE;
338  fAccPatt->fLst["TGeoPatternY"] = kTRUE;
339  fAccPatt->fLst["TGeoPatternZ"] = kTRUE;
340  fAccPatt->fLst["TGeoPatternCylR"] = kTRUE;
341  fAccPatt->fLst["TGeoPatternCylPhi"] = kTRUE;
342  //========================
343 
344  //initialize list of rejected shapes for divisions (in ExtractVolumes)
345  fRejShape = new StructLst;
346  //this shapes are rejected because, it is not possible to divide trd2
347  //in Y axis and while only trd2 object is imported from GDML
348  //it causes a problem when TGeoTrd1 is divided in Y axis
349  fRejShape->fLst["TGeoTrd1"] = kTRUE;
350  fRejShape->fLst["TGeoTrd2"] = kTRUE;
351  //=========================
352 
353  //Initialize global counters
354  fActNameErr = 0;
355  fVolCnt = 0;
356  fPhysVolCnt = 0;
357  fSolCnt = 0;
358 
359  //calling main extraction functions (with measuring time)
360  time_t startT, endT;
361  startT = time(nullptr);
362  ExtractMatrices(geomanager->GetListOfGDMLMatrices());
363  ExtractConstants(geomanager);
364  fMaterialsNode = ExtractMaterials(materialsLst);
365 
366  Info("WriteGDMLfile", "Extracting volumes");
367  ExtractVolumes(node);
368  Info("WriteGDMLfile", "%i solids added", fSolCnt);
369  Info("WriteGDMLfile", "%i volumes added", fVolCnt);
370  Info("WriteGDMLfile", "%i physvolumes added", fPhysVolCnt);
374  endT = time(nullptr);
375  //<gdml>
376  fGdmlE->AddChild(rootNode, fDefineNode); // <define>...</define>
377  fGdmlE->AddChild(rootNode, fMaterialsNode); // <materials>...</materials>
378  fGdmlE->AddChild(rootNode, fSolidsNode); // <solids>...</solids>
379  fGdmlE->AddChild(rootNode, fStructureNode); // <structure>...</structure>
380  fGdmlE->AddChild(rootNode, CreateSetupN(fTopVolumeName.Data())); // <setup>...</setup>
381  //</gdml>
382  Double_t tdiffI = difftime(endT, startT);
383  TString tdiffS = (tdiffI == 0 ? TString("< 1 s") : TString::Format("%.0lf s", tdiffI));
384  Info("WriteGDMLfile", "Exporting time: %s", tdiffS.Data());
385  //=========================
386 
387  //Saving document
388  fGdmlE->SaveDoc(fGdmlFile, filename, outputLayout);
389  Info("WriteGDMLfile", "File %s saved", filename);
390  //cleaning
392  //unset processing bits:
393  UnsetTemporaryBits(geomanager);
394  delete fGdmlE;
395 }
396 
397 ////////////////////////////////////////////////////////////////////////////////
398 /// Method exporting GDML matrices
399 
401 {
402  if (!matrixList->GetEntriesFast()) return;
403  XMLNodePointer_t matrixN;
404  TIter next(matrixList);
405  TGDMLMatrix *matrix;
406  while ((matrix = (TGDMLMatrix*)next())) {
407  matrixN = CreateMatrixN(matrix);
408  fGdmlE->AddChild(fDefineNode, matrixN);
409  }
410 }
411 
412 ////////////////////////////////////////////////////////////////////////////////
413 /// Method exporting GDML matrices
414 
416 {
417  if (!geom->GetNproperties()) return;
418  XMLNodePointer_t constantN;
419  TString property;
420  Double_t value;
421  for (Int_t i = 0; i < geom->GetNproperties(); ++i) {
422  value = geom->GetProperty(i, property);
423  constantN = CreateConstantN(property.Data(), value);
424  fGdmlE->AddChild(fDefineNode, constantN);
425  }
426 }
427 
428 ////////////////////////////////////////////////////////////////////////////////
429 /// Method exporting optical surfaces
430 
432 {
433  if (!surfaces->GetEntriesFast()) return;
434  XMLNodePointer_t surfaceN;
435  TIter next(surfaces);
436  TGeoOpticalSurface *surf;
437  while ((surf = (TGeoOpticalSurface*)next())) {
438  if ( fSurfaceList.find(surf) == fSurfaceList.end() ) continue;
439  surfaceN = CreateOpticalSurfaceN(surf);
440  fGdmlE->AddChild(fSolidsNode, surfaceN);
441  // Info("ExtractSkinSurfaces", "Extracted optical surface: %s",surf->GetName());
442  }
443 }
444 
445 ////////////////////////////////////////////////////////////////////////////////
446 /// Method exporting skin surfaces
447 
449 {
450  if (!surfaces->GetEntriesFast()) return;
451  XMLNodePointer_t surfaceN;
452  TIter next(surfaces);
453  TGeoSkinSurface *surf;
454  while ((surf = (TGeoSkinSurface*)next())) {
455  if ( fVolumeList.find(surf->GetVolume()) == fVolumeList.end() ) continue;
456  surfaceN = CreateSkinSurfaceN(surf);
457  fGdmlE->AddChild(fStructureNode, surfaceN);
458  fSurfaceList.insert(surf->GetSurface());
459  // Info("ExtractSkinSurfaces", "Extracted skin surface: %s",surf->GetName());
460  }
461 }
462 
463 ////////////////////////////////////////////////////////////////////////////////
464 /// Method exporting border surfaces
465 
467 {
468  if (!surfaces->GetEntriesFast()) return;
469  XMLNodePointer_t surfaceN;
470  TIter next(surfaces);
471  TGeoBorderSurface *surf;
472  while ((surf = (TGeoBorderSurface*)next())) {
473  auto ia = fNodeList.find(surf->GetNode1());
474  auto ib = fNodeList.find(surf->GetNode2());
475  if ( ia == fNodeList.end() && ib == fNodeList.end() ) {
476  continue;
477  }
478  else if ( ia == fNodeList.end() && ib != fNodeList.end() ) {
479  Warning("ExtractBorderSurfaces", "Inconsistent border surface extraction %s: Node %s"
480  " is not part of GDML!",surf->GetName(), surf->GetNode1()->GetName());
481  continue;
482  }
483  else if ( ia != fNodeList.end() && ib == fNodeList.end() ) {
484  Warning("ExtractBorderSurfaces", "Inconsistent border surface extraction %s: Node %s"
485  " is not part of GDML!",surf->GetName(), surf->GetNode2()->GetName());
486  continue;
487  }
488  surfaceN = CreateBorderSurfaceN(surf);
489  fGdmlE->AddChild(fStructureNode, surfaceN);
490  fSurfaceList.insert(surf->GetSurface());
491  // Info("ExtractBorderSurfaces", "Extracted border surface: %s",surf->GetName());
492  }
493 }
494 
495 ////////////////////////////////////////////////////////////////////////////////
496 /// Method exporting materials
497 
499 {
500  Info("ExtractMaterials", "Extracting materials");
501  //crate main <materials> node
502  XMLNodePointer_t materialsN = fGdmlE->NewChild(nullptr, nullptr, "materials", nullptr);
503  Int_t matcnt = 0;
504 
505  //go through materials - iterator and object declaration
506  TIter next(materialsLst);
507  TGeoMaterial *lmaterial;
508 
509  while ((lmaterial = (TGeoMaterial *)next())) {
510  //generate uniq name
511  TString lname = GenName(lmaterial->GetName(), TString::Format("%p", lmaterial));
512 
513  if (lmaterial->IsMixture()) {
514  TGeoMixture *lmixture = (TGeoMixture *)lmaterial;
515  XMLNodePointer_t mixtureN = CreateMixtureN(lmixture, materialsN, lname);
516  fGdmlE->AddChild(materialsN, mixtureN);
517  } else {
518  XMLNodePointer_t materialN = CreateMaterialN(lmaterial, lname);
519  fGdmlE->AddChild(materialsN, materialN);
520  }
521  matcnt++;
522  }
523  Info("ExtractMaterials", "%i materials added", matcnt);
524  return materialsN;
525 }
526 
527 ////////////////////////////////////////////////////////////////////////////////
528 /// Method creating solid to xml file and returning its name
529 
531 {
532  XMLNodePointer_t solidN;
533  TString solname = "";
534  solidN = ChooseObject(volShape); //volume->GetShape()
535  fGdmlE->AddChild(fSolidsNode, solidN);
536  if (solidN != nullptr) fSolCnt++;
537  solname = fNameList->fLst[TString::Format("%p", volShape)];
538  if (solname.Contains("missing_")) {
539  solname = "-1";
540  }
541  return solname;
542 }
543 
544 
545 ////////////////////////////////////////////////////////////////////////////////
546 /// Method extracting geometry structure recursively
547 
549 {
550  XMLNodePointer_t volumeN, childN;
551  TGeoVolume * volume = node->GetVolume();
552  TString volname, matname, solname, pattClsName, nodeVolNameBak;
553  TGeoPatternFinder *pattFinder = 0;
554  Bool_t isPattern = kFALSE;
555  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
556 
557  fNodeList.insert(node);
558  fVolumeList.insert(volume);
559  //create the name for volume/assembly
560  if (volume->IsTopVolume()) {
561  //not needed a special function for generating name
562  volname = volume->GetName();
563  fTopVolumeName = volname;
564  //register name to the pointer
565  fNameList->fLst[TString::Format("%p", volume)] = volname;
566  } else {
567  volname = GenName(volume->GetName(), TString::Format("%p", volume));
568  }
569 
570  //start to create main volume/assembly node
571  if (volume->IsAssembly()) {
572  volumeN = StartAssemblyN(volname);
573  } else {
574  //get reference material and add solid to <solids> + get name
575  matname = fNameList->fLst[TString::Format("%p", volume->GetMaterial())];
576  solname = ExtractSolid(volume->GetShape());
577  //If solid is not supported or corrupted
578  if (solname == "-1") {
579  Info("ExtractVolumes", "ERROR! %s volume was not added, because solid is either not supported or corrupted",
580  volname.Data());
581  //set volume as missing volume
582  fNameList->fLst[TString::Format("%p", volume)] = "missing_" + volname;
583  return;
584  }
585  volumeN = StartVolumeN(volname, solname, matname);
586 
587  //divisionvol can't be in assembly
588  pattFinder = volume->GetFinder();
589  //if found pattern
590  if (pattFinder) {
591  pattClsName = TString::Format("%s", pattFinder->ClassName());
592  TString shapeCls = TString::Format("%s", volume->GetShape()->ClassName());
593  //if pattern in accepted pattern list and not in shape rejected list
594  if ((fAccPatt->fLst[pattClsName] == kTRUE) &&
595  (fRejShape->fLst[shapeCls] != kTRUE)) {
596  isPattern = kTRUE;
597  }
598  }
599  }
600  //get all nodes in volume
601  TObjArray *nodeLst = volume->GetNodes();
602  TIter next(nodeLst);
603  TGeoNode *geoNode;
604  Int_t nCnt = 0;
605  //loop through all nodes
606  while ((geoNode = (TGeoNode *) next())) {
607  //get volume of current node and if not processed then process it
608  TGeoVolume * subvol = geoNode->GetVolume();
609  fNodeList.insert(geoNode);
610  if (subvol->TestAttBit(fgkProcBitVol) == kFALSE) {
611  subvol->SetAttBit(fgkProcBitVol);
612  ExtractVolumes(geoNode);
613  }
614 
615  //volume of this node has to exist because it was processed recursively
616  TString nodevolname = fNameList->fLst[TString::Format("%p", geoNode->GetVolume())];
617  if (nodevolname.Contains("missing_")) {
618  continue;
619  }
620  if (nCnt == 0) { //save name of the first node for divisionvol
621  nodeVolNameBak = nodevolname;
622  }
623 
624  if (isPattern == kFALSE) {
625  //create name for node
626  TString nodename, posname, rotname;
627  nodename = GenName(geoNode->GetName(), TString::Format("%p", geoNode));
628  nodename = nodename + "in" + volname;
629 
630  //create name for position and clear rotation
631  posname = nodename + "pos";
632  rotname = "";
633 
634  //position
635  const Double_t * pos = geoNode->GetMatrix()->GetTranslation();
636  Xyz nodPos;
637  nodPos.x = pos[0];
638  nodPos.y = pos[1];
639  nodPos.z = pos[2];
640  childN = CreatePositionN(posname.Data(), nodPos);
641  fGdmlE->AddChild(fDefineNode, childN); //adding node to <define> node
642  //Deal with reflection
643  XMLNodePointer_t scaleN = nullptr;
644  Double_t lx, ly, lz;
645  Double_t xangle = 0;
646  Double_t zangle = 0;
647  lx = geoNode->GetMatrix()->GetRotationMatrix()[0];
648  ly = geoNode->GetMatrix()->GetRotationMatrix()[4];
649  lz = geoNode->GetMatrix()->GetRotationMatrix()[8];
650  if (geoNode->GetMatrix()->IsReflection()
651  && TMath::Abs(lx) == 1 && TMath::Abs(ly) == 1 && TMath::Abs(lz) == 1) {
652  scaleN = fGdmlE->NewChild(nullptr, nullptr, "scale", nullptr);
653  fGdmlE->NewAttr(scaleN, nullptr, "name", (nodename + "scl").Data());
654  fGdmlE->NewAttr(scaleN, nullptr, "x", TString::Format(fltPrecision.Data(), lx));
655  fGdmlE->NewAttr(scaleN, nullptr, "y", TString::Format(fltPrecision.Data(), ly));
656  fGdmlE->NewAttr(scaleN, nullptr, "z", TString::Format(fltPrecision.Data(), lz));
657  //experimentally found out, that rotation should be updated like this
658  if (lx == -1) {
659  zangle = 180;
660  }
661  if (lz == -1) {
662  xangle = 180;
663  }
664  }
665 
666  //rotation
668  lxyz.x -= xangle;
669  lxyz.z -= zangle;
670  if ((lxyz.x != 0.0) || (lxyz.y != 0.0) || (lxyz.z != 0.0)) {
671  rotname = nodename + "rot";
672  childN = CreateRotationN(rotname.Data(), lxyz);
673  fGdmlE->AddChild(fDefineNode, childN); //adding node to <define> node
674  }
675 
676  //create physvol for main volume/assembly node
677  childN = CreatePhysVolN(geoNode->GetName(), geoNode->GetNumber(), nodevolname.Data(), posname.Data(), rotname.Data(), scaleN);
678  fGdmlE->AddChild(volumeN, childN);
679  }
680  nCnt++;
681  }
682  //create only one divisionvol node
683  if (isPattern && pattFinder) {
684  //retrieve attributes of division
685  Int_t ndiv, divaxis;
686  Double_t offset, width, xlo, xhi;
687  TString axis, unit;
688 
689  ndiv = pattFinder->GetNdiv();
690  width = pattFinder->GetStep();
691 
692  divaxis = pattFinder->GetDivAxis();
693  volume->GetShape()->GetAxisRange(divaxis, xlo, xhi);
694 
695  //compute relative start (not positional)
696  offset = pattFinder->GetStart() - xlo;
697  axis = GetPattAxis(divaxis, pattClsName, unit);
698 
699  //create division node
700  childN = CreateDivisionN(offset, width, ndiv, axis.Data(), unit.Data(), nodeVolNameBak.Data());
701  fGdmlE->AddChild(volumeN, childN);
702  }
703 
704  fVolCnt++;
705  //add volume/assembly node into the <structure> node
706  fGdmlE->AddChild(fStructureNode, volumeN);
707 
708 }
709 
710 ////////////////////////////////////////////////////////////////////////////////
711 /// Creates "atom" node for GDML
712 
714 {
715  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
716  XMLNodePointer_t atomN = fGdmlE->NewChild(nullptr, nullptr, "atom", nullptr);
717  fGdmlE->NewAttr(atomN, nullptr, "unit", unit);
718  fGdmlE->NewAttr(atomN, nullptr, "value", TString::Format(fltPrecision.Data(), atom));
719  return atomN;
720 }
721 
722 ////////////////////////////////////////////////////////////////////////////////
723 /// Creates "D" density node for GDML
724 
725 XMLNodePointer_t TGDMLWrite::CreateDN(Double_t density, const char * unit)
726 {
727  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
728  XMLNodePointer_t densN = fGdmlE->NewChild(nullptr, nullptr, "D", nullptr);
729  fGdmlE->NewAttr(densN, nullptr, "unit", unit);
730  fGdmlE->NewAttr(densN, nullptr, "value", TString::Format(fltPrecision.Data(), density));
731  return densN;
732 }
733 
734 ////////////////////////////////////////////////////////////////////////////////
735 /// Creates "fraction" node for GDML
736 
737 XMLNodePointer_t TGDMLWrite::CreateFractionN(Double_t percentage, const char * refName)
738 {
739  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
740  XMLNodePointer_t fractN = fGdmlE->NewChild(nullptr, nullptr, "fraction", nullptr);
741  fGdmlE->NewAttr(fractN, nullptr, "n", TString::Format(fltPrecision.Data(), percentage));
742  fGdmlE->NewAttr(fractN, nullptr, "ref", refName);
743  return fractN;
744 }
745 
746 ////////////////////////////////////////////////////////////////////////////////
747 /// Creates "property" node for GDML
748 
750 {
751  XMLNodePointer_t propertyN = fGdmlE->NewChild(nullptr, nullptr, "property", nullptr);
752  fGdmlE->NewAttr(propertyN, nullptr, "name", property.GetName());
753  fGdmlE->NewAttr(propertyN, nullptr, "ref", property.GetTitle());
754  return propertyN;
755 }
756 
757 ////////////////////////////////////////////////////////////////////////////////
758 /// Creates "isotope" node for GDML
759 
761 {
762  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "isotope", nullptr);
763  fGdmlE->NewAttr(mainN, nullptr, "name", name);
764  fGdmlE->NewAttr(mainN, nullptr, "N", TString::Format("%i", isotope->GetN()));
765  fGdmlE->NewAttr(mainN, nullptr, "Z", TString::Format("%i", isotope->GetZ()));
766  fGdmlE->AddChild(mainN, CreateAtomN(isotope->GetA()));
767  return mainN;
768 }
769 
770 ////////////////////////////////////////////////////////////////////////////////
771 /// Creates "element" node for GDML
772 ///element node and attribute
773 
775 {
776  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "element", nullptr);
777  fGdmlE->NewAttr(mainN, nullptr, "name", name);
778  //local associative arrays for saving isotopes and their weight
779  //inside element
780  NameListF wPercentage;
781  NameListI wCounter;
782 
783  if (element->HasIsotopes()) {
784  Int_t nOfIso = element->GetNisotopes();
785  //go through isotopes
786  for (Int_t idx = 0; idx < nOfIso; idx++) {
787  TGeoIsotope *myIsotope = element->GetIsotope(idx);
788  if (!myIsotope) {
789  Fatal("CreateElementN", "Missing isotopes for element %s", element->GetName());
790  return mainN;
791  }
792 
793  //Get name of the Isotope (
794  TString lname = myIsotope->GetName();
795  //_iso suffix is added to avoid problems with same names
796  //for material, element and isotopes
797  lname = TString::Format("%s_iso", lname.Data());
798 
799  //cumulates abundance, in case 2 isotopes with same names
800  //within one element
801  wPercentage[lname] += element->GetRelativeAbundance(idx);
802  wCounter[lname]++;
803 
804  //check whether isotope name is not in list of isotopes
805  if (IsInList(fIsotopeList->fLst, lname)) {
806  continue;
807  }
808  //add isotope to list of isotopes and to main <materials> node
809  fIsotopeList->fLst[lname] = kTRUE;
810  XMLNodePointer_t isoNode = CreateIsotopN(myIsotope, lname);
811  fGdmlE->AddChild(materials, isoNode);
812  }
813  //loop through asoc array of isotopes
814  for (NameListI::iterator itr = wCounter.begin(); itr != wCounter.end(); ++itr) {
815  if (itr->second > 1) {
816  Info("CreateMixtureN", "WARNING! 2 equal isotopes in one element. Check: %s isotope of %s element",
817  itr->first.Data(), name);
818  }
819  //add fraction child to element with reference to isotope
820  fGdmlE->AddChild(mainN, CreateFractionN(wPercentage[itr->first], itr->first.Data()));
821  }
822  } else {
823  fGdmlE->NewAttr(mainN, nullptr, "formula", element->GetName());
824  Int_t valZ = element->Z();
825  // Z can't be <1 in Geant4 and Z is optional parameter
826  if (valZ >= 1) {
827  fGdmlE->NewAttr(mainN, nullptr, "Z", TString::Format("%i", valZ));
828  }
829  fGdmlE->AddChild(mainN, CreateAtomN(element->A()));
830  }
831  return mainN;
832 }
833 
834 ////////////////////////////////////////////////////////////////////////////////
835 /// Creates "material" node for GDML with references to other sub elements
836 
838 {
839  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "material", nullptr);
840  fGdmlE->NewAttr(mainN, nullptr, "name", mname);
841  fGdmlE->AddChild(mainN, CreateDN(mixture->GetDensity()));
842  //local associative arrays for saving elements and their weight
843  //inside mixture
844  NameListF wPercentage;
845  NameListI wCounter;
846 
847  Int_t nOfElm = mixture->GetNelements();
848  //go through elements
849  for (Int_t idx = 0; idx < nOfElm; idx++) {
850  TGeoElement *myElement = mixture->GetElement(idx);
851 
852  //Get name of the element
853  //NOTE: that for element - GetTitle() returns the "name" tag
854  //and GetName() returns "formula" tag (see createElementN)
855  TString lname = myElement->GetTitle();
856  //_elm suffix is added to avoid problems with same names
857  //for material and element
858  lname = TString::Format("%s_elm", lname.Data());
859 
860  //cumulates percentage, in case 2 elements with same names within one mixture
861  wPercentage[lname] += mixture->GetWmixt()[idx];
862  wCounter[lname]++;
863 
864  //check whether element name is not in list of elements already created
865  if (IsInList(fElementList->fLst, lname)) {
866  continue;
867  }
868 
869  //add element to list of elements and to main <materials> node
870  fElementList->fLst[lname] = kTRUE;
871  XMLNodePointer_t elmNode = CreateElementN(myElement, materials, lname);
872  fGdmlE->AddChild(materials, elmNode);
873  }
874  //loop through asoc array
875  for (NameListI::iterator itr = wCounter.begin(); itr != wCounter.end(); ++itr) {
876  if (itr->second > 1) {
877  Info("CreateMixtureN", "WARNING! 2 equal elements in one material. Check: %s element of %s material",
878  itr->first.Data(), mname.Data());
879  }
880  //add fraction child to material with reference to element
881  fGdmlE->AddChild(mainN, CreateFractionN(wPercentage[itr->first], itr->first.Data()));
882  }
883 
884  // Write properties
885  TList const &properties = mixture->GetProperties();
886  if (properties.GetSize()) {
887  TIter next(&properties);
888  TNamed *property;
889  while ((property = (TNamed*)next()))
890  fGdmlE->AddChild(mainN, CreatePropertyN(*property));
891  }
892  // Write CONST properties
893  TList const &const_properties = mixture->GetConstProperties();
894  if (const_properties.GetSize()) {
895  TIter next(&const_properties);
896  TNamed *property;
897  while ((property = (TNamed*)next()))
898  fGdmlE->AddChild(mainN, CreatePropertyN(*property));
899  }
900 
901  return mainN;
902 }
903 
904 ////////////////////////////////////////////////////////////////////////////////
905 /// Creates "material" node for GDML
906 
908 {
909  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "material", nullptr);
910  fGdmlE->NewAttr(mainN, nullptr, "name", mname);
911  Double_t valZ = material->GetZ();
912  //Z can't be zero in Geant4 so this is workaround for vacuum
913  TString tmpname = mname;
914  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
915  tmpname.ToLower();
916  if (valZ < 1) {
917  if (tmpname == "vacuum") {
918  valZ = 1;
919  } else {
920  if (fgG4Compatibility == kTRUE) {
921  Info("CreateMaterialN", "WARNING! value of Z in %s material can't be < 1 in Geant4, that is why it was changed to 1, please check it manually! ",
922  mname.Data());
923  valZ = 1;
924  } else {
925  Info("CreateMaterialN", "WARNING! value of Z in %s material can't be < 1 in Geant4", mname.Data());
926  }
927  }
928  }
929  fGdmlE->NewAttr(mainN, nullptr, "Z", TString::Format(fltPrecision.Data(), valZ)); //material->GetZ()));
930  fGdmlE->AddChild(mainN, CreateDN(material->GetDensity()));
931  fGdmlE->AddChild(mainN, CreateAtomN(material->GetA()));
932  // Create properties if any
933  TList const &properties = material->GetProperties();
934  if (properties.GetSize()) {
935  TIter next(&properties);
936  TNamed *property;
937  while ((property = (TNamed*)next()))
938  fGdmlE->AddChild(mainN, CreatePropertyN(*property));
939  }
940  // Write CONST properties
941  TList const &const_properties = material->GetConstProperties();
942  if (const_properties.GetSize()) {
943  TIter next(&const_properties);
944  TNamed *property;
945  while ((property = (TNamed*)next()))
946  fGdmlE->AddChild(mainN, CreatePropertyN(*property));
947  }
948  return mainN;
949 }
950 
951 ////////////////////////////////////////////////////////////////////////////////
952 /// Creates "box" node for GDML
953 
955 {
956  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "box", nullptr);
957  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
958  TString lname = GenName(geoShape->GetName(), TString::Format("%p", geoShape));
959  fGdmlE->NewAttr(mainN, nullptr, "name", lname);
960  if (IsNullParam(geoShape->GetDX(), "DX", lname) ||
961  IsNullParam(geoShape->GetDY(), "DY", lname) ||
962  IsNullParam(geoShape->GetDZ(), "DZ", lname)) {
963  return nullptr;
964  }
965  fGdmlE->NewAttr(mainN, nullptr, "x", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDX()));
966  fGdmlE->NewAttr(mainN, nullptr, "y", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDY()));
967  fGdmlE->NewAttr(mainN, nullptr, "z", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDZ()));
968 
969  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
970  return mainN;
971 }
972 
973 ////////////////////////////////////////////////////////////////////////////////
974 /// Creates "paraboloid" node for GDML
975 
977 {
978  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "paraboloid", nullptr);
979  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
980  TString lname = GenName(geoShape->GetName(), TString::Format("%p", geoShape));
981  fGdmlE->NewAttr(mainN, nullptr, "name", lname);
982  if (IsNullParam(geoShape->GetRhi(), "Rhi", lname) ||
983  IsNullParam(geoShape->GetDz(), "Dz", lname)) {
984  return nullptr;
985  }
986  fGdmlE->NewAttr(mainN, nullptr, "rlo", TString::Format(fltPrecision.Data(), geoShape->GetRlo()));
987  fGdmlE->NewAttr(mainN, nullptr, "rhi", TString::Format(fltPrecision.Data(), geoShape->GetRhi()));
988  fGdmlE->NewAttr(mainN, nullptr, "dz", TString::Format(fltPrecision.Data(), geoShape->GetDz()));
989 
990  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
991  return mainN;
992 }
993 
994 ////////////////////////////////////////////////////////////////////////////////
995 /// Creates "sphere" node for GDML
996 
998 {
999  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "sphere", nullptr);
1000  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1001  TString lname = GenName(geoShape->GetName(), TString::Format("%p", geoShape));
1002  fGdmlE->NewAttr(mainN, nullptr, "name", lname);
1003  if (IsNullParam(geoShape->GetRmax(), "Rmax", lname)) {
1004  return nullptr;
1005  }
1006 
1007  fGdmlE->NewAttr(mainN, nullptr, "rmin", TString::Format(fltPrecision.Data(), geoShape->GetRmin()));
1008  fGdmlE->NewAttr(mainN, nullptr, "rmax", TString::Format(fltPrecision.Data(), geoShape->GetRmax()));
1009  fGdmlE->NewAttr(mainN, nullptr, "startphi", TString::Format(fltPrecision.Data(), geoShape->GetPhi1()));
1010  fGdmlE->NewAttr(mainN, nullptr, "deltaphi", TString::Format(fltPrecision.Data(), geoShape->GetPhi2() - geoShape->GetPhi1()));
1011  fGdmlE->NewAttr(mainN, nullptr, "starttheta", TString::Format(fltPrecision.Data(), geoShape->GetTheta1()));
1012  fGdmlE->NewAttr(mainN, nullptr, "deltatheta", TString::Format(fltPrecision.Data(), geoShape->GetTheta2() - geoShape->GetTheta1()));
1013 
1014  fGdmlE->NewAttr(mainN, nullptr, "aunit", "deg");
1015  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
1016  return mainN;
1017 }
1018 
1019 ////////////////////////////////////////////////////////////////////////////////
1020 /// Creates "arb8" node for GDML
1021 
1023 {
1024  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "arb8", nullptr);
1025  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1026  TString lname = GenName(geoShape->GetName(), TString::Format("%p", geoShape));
1027  fGdmlE->NewAttr(mainN, nullptr, "name", lname);
1028  if (IsNullParam(geoShape->GetDz(), "Dz", lname)) {
1029  return nullptr;
1030  }
1031 
1032  fGdmlE->NewAttr(mainN, nullptr, "v1x", TString::Format(fltPrecision.Data(), geoShape->GetVertices()[0]));
1033  fGdmlE->NewAttr(mainN, nullptr, "v1y", TString::Format(fltPrecision.Data(), geoShape->GetVertices()[1]));
1034  fGdmlE->NewAttr(mainN, nullptr, "v2x", TString::Format(fltPrecision.Data(), geoShape->GetVertices()[2]));
1035  fGdmlE->NewAttr(mainN, nullptr, "v2y", TString::Format(fltPrecision.Data(), geoShape->GetVertices()[3]));
1036  fGdmlE->NewAttr(mainN, nullptr, "v3x", TString::Format(fltPrecision.Data(), geoShape->GetVertices()[4]));
1037  fGdmlE->NewAttr(mainN, nullptr, "v3y", TString::Format(fltPrecision.Data(), geoShape->GetVertices()[5]));
1038  fGdmlE->NewAttr(mainN, nullptr, "v4x", TString::Format(fltPrecision.Data(), geoShape->GetVertices()[6]));
1039  fGdmlE->NewAttr(mainN, nullptr, "v4y", TString::Format(fltPrecision.Data(), geoShape->GetVertices()[7]));
1040  fGdmlE->NewAttr(mainN, nullptr, "v5x", TString::Format(fltPrecision.Data(), geoShape->GetVertices()[8]));
1041  fGdmlE->NewAttr(mainN, nullptr, "v5y", TString::Format(fltPrecision.Data(), geoShape->GetVertices()[9]));
1042  fGdmlE->NewAttr(mainN, nullptr, "v6x", TString::Format(fltPrecision.Data(), geoShape->GetVertices()[10]));
1043  fGdmlE->NewAttr(mainN, nullptr, "v6y", TString::Format(fltPrecision.Data(), geoShape->GetVertices()[11]));
1044  fGdmlE->NewAttr(mainN, nullptr, "v7x", TString::Format(fltPrecision.Data(), geoShape->GetVertices()[12]));
1045  fGdmlE->NewAttr(mainN, nullptr, "v7y", TString::Format(fltPrecision.Data(), geoShape->GetVertices()[13]));
1046  fGdmlE->NewAttr(mainN, nullptr, "v8x", TString::Format(fltPrecision.Data(), geoShape->GetVertices()[14]));
1047  fGdmlE->NewAttr(mainN, nullptr, "v8y", TString::Format(fltPrecision.Data(), geoShape->GetVertices()[15]));
1048  fGdmlE->NewAttr(mainN, nullptr, "dz", TString::Format(fltPrecision.Data(), geoShape->GetDz()));
1049 
1050  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
1051  return mainN;
1052 }
1053 
1054 ////////////////////////////////////////////////////////////////////////////////
1055 /// Creates "cone" node for GDML from TGeoConeSeg object
1056 
1058 {
1059  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "cone", nullptr);
1060  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1061  TString lname = GenName(geoShape->GetName(), TString::Format("%p", geoShape));
1062  fGdmlE->NewAttr(mainN, nullptr, "name", lname);
1063  if (IsNullParam(geoShape->GetDz(), "Dz", lname)) {
1064  return nullptr;
1065  }
1066 
1067  fGdmlE->NewAttr(mainN, nullptr, "z", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDz()));
1068  fGdmlE->NewAttr(mainN, nullptr, "rmin1", TString::Format(fltPrecision.Data(), geoShape->GetRmin1()));
1069  fGdmlE->NewAttr(mainN, nullptr, "rmin2", TString::Format(fltPrecision.Data(), geoShape->GetRmin2()));
1070  fGdmlE->NewAttr(mainN, nullptr, "rmax1", TString::Format(fltPrecision.Data(), geoShape->GetRmax1()));
1071  fGdmlE->NewAttr(mainN, nullptr, "rmax2", TString::Format(fltPrecision.Data(), geoShape->GetRmax2()));
1072  fGdmlE->NewAttr(mainN, nullptr, "startphi", TString::Format(fltPrecision.Data(), geoShape->GetPhi1()));
1073  fGdmlE->NewAttr(mainN, nullptr, "deltaphi", TString::Format(fltPrecision.Data(), geoShape->GetPhi2() - geoShape->GetPhi1()));
1074 
1075  fGdmlE->NewAttr(mainN, nullptr, "aunit", "deg");
1076  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
1077  return mainN;
1078 }
1079 
1080 ////////////////////////////////////////////////////////////////////////////////
1081 /// Creates "cone" node for GDML from TGeoCone object
1082 
1084 {
1085  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "cone", nullptr);
1086  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1087  TString lname = GenName(geoShape->GetName(), TString::Format("%p", geoShape));
1088  fGdmlE->NewAttr(mainN, nullptr, "name", lname);
1089  if (IsNullParam(geoShape->GetDz(), "Dz", lname)) {
1090  return nullptr;
1091  }
1092 
1093  fGdmlE->NewAttr(mainN, nullptr, "z", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDz()));
1094  fGdmlE->NewAttr(mainN, nullptr, "rmin1", TString::Format(fltPrecision.Data(), geoShape->GetRmin1()));
1095  fGdmlE->NewAttr(mainN, nullptr, "rmin2", TString::Format(fltPrecision.Data(), geoShape->GetRmin2()));
1096  fGdmlE->NewAttr(mainN, nullptr, "rmax1", TString::Format(fltPrecision.Data(), geoShape->GetRmax1()));
1097  fGdmlE->NewAttr(mainN, nullptr, "rmax2", TString::Format(fltPrecision.Data(), geoShape->GetRmax2()));
1098  fGdmlE->NewAttr(mainN, nullptr, "startphi", TString::Format("%i", 0));
1099  fGdmlE->NewAttr(mainN, nullptr, "deltaphi", TString::Format("%i", 360));
1100 
1101  fGdmlE->NewAttr(mainN, nullptr, "aunit", "deg");
1102  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
1103  return mainN;
1104 }
1105 
1106 ////////////////////////////////////////////////////////////////////////////////
1107 /// Creates "para" node for GDML
1108 
1110 {
1111  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "para", nullptr);
1112  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1113  fGdmlE->NewAttr(mainN, nullptr, "name", GenName(geoShape->GetName(), TString::Format("%p", geoShape)));
1114 
1115  fGdmlE->NewAttr(mainN, nullptr, "x", TString::Format(fltPrecision.Data(), 2 * geoShape->GetX()));
1116  fGdmlE->NewAttr(mainN, nullptr, "y", TString::Format(fltPrecision.Data(), 2 * geoShape->GetY()));
1117  fGdmlE->NewAttr(mainN, nullptr, "z", TString::Format(fltPrecision.Data(), 2 * geoShape->GetZ()));
1118  fGdmlE->NewAttr(mainN, nullptr, "alpha", TString::Format(fltPrecision.Data(), geoShape->GetAlpha()));
1119  fGdmlE->NewAttr(mainN, nullptr, "theta", TString::Format(fltPrecision.Data(), geoShape->GetTheta()));
1120  fGdmlE->NewAttr(mainN, nullptr, "phi", TString::Format(fltPrecision.Data(), geoShape->GetPhi()));
1121 
1122  fGdmlE->NewAttr(mainN, nullptr, "aunit", "deg");
1123  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
1124  return mainN;
1125 }
1126 
1127 ////////////////////////////////////////////////////////////////////////////////
1128 /// Creates "trap" node for GDML
1129 
1131 {
1132  XMLNodePointer_t mainN;
1133  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1134 
1135  //if one base equals 0 create Arb8 instead of trap
1136  if ((geoShape->GetBl1() == 0 || geoShape->GetTl1() == 0 || geoShape->GetH1() == 0) ||
1137  (geoShape->GetBl2() == 0 || geoShape->GetTl2() == 0 || geoShape->GetH2() == 0)) {
1138  mainN = CreateArb8N(geoShape);
1139  return mainN;
1140  }
1141 
1142  //if is twisted then create arb8
1143  if (geoShape->IsTwisted()) {
1144  mainN = CreateArb8N((TGeoArb8 *) geoShape);
1145  return mainN;
1146  }
1147 
1148  mainN = fGdmlE->NewChild(nullptr, nullptr, "trap", nullptr);
1149  TString lname = GenName(geoShape->GetName(), TString::Format("%p", geoShape));
1150  fGdmlE->NewAttr(mainN, nullptr, "name", lname);
1151  if (IsNullParam(geoShape->GetDz(), "Dz", lname)) {
1152  return nullptr;
1153  }
1154 
1155  fGdmlE->NewAttr(mainN, nullptr, "z", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDz()));
1156  fGdmlE->NewAttr(mainN, nullptr, "theta", TString::Format(fltPrecision.Data(), geoShape->GetTheta()));
1157  fGdmlE->NewAttr(mainN, nullptr, "phi", TString::Format(fltPrecision.Data(), geoShape->GetPhi()));
1158  fGdmlE->NewAttr(mainN, nullptr, "x1", TString::Format(fltPrecision.Data(), 2 * geoShape->GetBl1()));
1159  fGdmlE->NewAttr(mainN, nullptr, "x2", TString::Format(fltPrecision.Data(), 2 * geoShape->GetTl1()));
1160  fGdmlE->NewAttr(mainN, nullptr, "x3", TString::Format(fltPrecision.Data(), 2 * geoShape->GetBl2()));
1161  fGdmlE->NewAttr(mainN, nullptr, "x4", TString::Format(fltPrecision.Data(), 2 * geoShape->GetTl2()));
1162  fGdmlE->NewAttr(mainN, nullptr, "y1", TString::Format(fltPrecision.Data(), 2 * geoShape->GetH1()));
1163  fGdmlE->NewAttr(mainN, nullptr, "y2", TString::Format(fltPrecision.Data(), 2 * geoShape->GetH2()));
1164 
1165  fGdmlE->NewAttr(mainN, nullptr, "alpha1", TString::Format(fltPrecision.Data(), geoShape->GetAlpha1()));
1166  fGdmlE->NewAttr(mainN, nullptr, "alpha2", TString::Format(fltPrecision.Data(), geoShape->GetAlpha2()));
1167 
1168  fGdmlE->NewAttr(mainN, nullptr, "aunit", "deg");
1169  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
1170  return mainN;
1171 }
1172 
1173 ////////////////////////////////////////////////////////////////////////////////
1174 /// Creates "twistedtrap" node for GDML
1175 
1177 {
1178  XMLNodePointer_t mainN;
1179  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1180 
1181  //if one base equals 0 create Arb8 instead of twisted trap
1182  if ((geoShape->GetBl1() == 0 && geoShape->GetTl1() == 0 && geoShape->GetH1() == 0) ||
1183  (geoShape->GetBl2() == 0 && geoShape->GetTl2() == 0 && geoShape->GetH2() == 0)) {
1184  mainN = CreateArb8N((TGeoArb8 *) geoShape);
1185  return mainN;
1186  }
1187 
1188  //if is twisted then create arb8
1189  if (geoShape->IsTwisted()) {
1190  mainN = CreateArb8N((TGeoArb8 *) geoShape);
1191  return mainN;
1192  }
1193 
1194  //if parameter twistAngle (PhiTwist) equals zero create trap node
1195  if (geoShape->GetTwistAngle() == 0) {
1196  mainN = CreateTrapN((TGeoTrap *) geoShape);
1197  return mainN;
1198  }
1199 
1200  mainN = fGdmlE->NewChild(nullptr, nullptr, "twistedtrap", nullptr);
1201  TString lname = GenName(geoShape->GetName(), TString::Format("%p", geoShape));
1202  fGdmlE->NewAttr(mainN, nullptr, "name", lname);
1203  if (IsNullParam(geoShape->GetDz(), "Dz", lname)) {
1204  return nullptr;
1205  }
1206 
1207  fGdmlE->NewAttr(mainN, nullptr, "z", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDz()));
1208  fGdmlE->NewAttr(mainN, nullptr, "Theta", TString::Format(fltPrecision.Data(), geoShape->GetTheta()));
1209  fGdmlE->NewAttr(mainN, nullptr, "Phi", TString::Format(fltPrecision.Data(), geoShape->GetPhi()));
1210  fGdmlE->NewAttr(mainN, nullptr, "x1", TString::Format(fltPrecision.Data(), 2 * geoShape->GetBl1()));
1211  fGdmlE->NewAttr(mainN, nullptr, "x2", TString::Format(fltPrecision.Data(), 2 * geoShape->GetTl1()));
1212  fGdmlE->NewAttr(mainN, nullptr, "x3", TString::Format(fltPrecision.Data(), 2 * geoShape->GetBl2()));
1213  fGdmlE->NewAttr(mainN, nullptr, "x4", TString::Format(fltPrecision.Data(), 2 * geoShape->GetTl2()));
1214  fGdmlE->NewAttr(mainN, nullptr, "y1", TString::Format(fltPrecision.Data(), 2 * geoShape->GetH1()));
1215  fGdmlE->NewAttr(mainN, nullptr, "y2", TString::Format(fltPrecision.Data(), 2 * geoShape->GetH2()));
1216 
1217  fGdmlE->NewAttr(mainN, nullptr, "Alph", TString::Format(fltPrecision.Data(), geoShape->GetAlpha1()));
1218 
1219  //check if alpha1 equals to alpha2 (converting to string - to avoid problems with floats)
1220  if (TString::Format(fltPrecision.Data(), geoShape->GetAlpha1()) != TString::Format(fltPrecision.Data(), geoShape->GetAlpha2())) {
1221  Info("CreateTwistedTrapN",
1222  "ERROR! Object %s is not exported correctly because parameter Alpha2 is not declared in GDML schema",
1223  lname.Data());
1224  }
1225  //fGdmlE->NewAttr(mainN,0, "alpha2", TString::Format(fltPrecision.Data(), geoShape->GetAlpha2()));
1226  fGdmlE->NewAttr(mainN, nullptr, "PhiTwist", TString::Format(fltPrecision.Data(), geoShape->GetTwistAngle()));
1227 
1228  fGdmlE->NewAttr(mainN, nullptr, "aunit", "deg");
1229  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
1230  return mainN;
1231 }
1232 
1233 ////////////////////////////////////////////////////////////////////////////////
1234 /// Creates "trd" node for GDML from object TGeoTrd1
1235 
1237 {
1238  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "trd", nullptr);
1239  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1240  TString lname = GenName(geoShape->GetName(), TString::Format("%p", geoShape));
1241  fGdmlE->NewAttr(mainN, nullptr, "name", lname);
1242  if (IsNullParam(geoShape->GetDz(), "Dz", lname)) {
1243  return nullptr;
1244  }
1245 
1246  fGdmlE->NewAttr(mainN, nullptr, "x1", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDx1()));
1247  fGdmlE->NewAttr(mainN, nullptr, "x2", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDx2()));
1248  fGdmlE->NewAttr(mainN, nullptr, "y1", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDy()));
1249  fGdmlE->NewAttr(mainN, nullptr, "y2", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDy()));
1250  fGdmlE->NewAttr(mainN, nullptr, "z", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDz()));
1251 
1252  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
1253  return mainN;
1254 }
1255 
1256 ////////////////////////////////////////////////////////////////////////////////
1257 /// Creates "trd" node for GDML from object TGeoTrd2
1258 
1260 {
1261  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "trd", nullptr);
1262  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1263  TString lname = GenName(geoShape->GetName(), TString::Format("%p", geoShape));
1264  fGdmlE->NewAttr(mainN, nullptr, "name", lname);
1265  if (IsNullParam(geoShape->GetDz(), "Dz", lname)) {
1266  return nullptr;
1267  }
1268 
1269  fGdmlE->NewAttr(mainN, nullptr, "x1", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDx1()));
1270  fGdmlE->NewAttr(mainN, nullptr, "x2", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDx2()));
1271  fGdmlE->NewAttr(mainN, nullptr, "y1", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDy1()));
1272  fGdmlE->NewAttr(mainN, nullptr, "y2", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDy2()));
1273  fGdmlE->NewAttr(mainN, nullptr, "z", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDz()));
1274 
1275  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
1276  return mainN;
1277 }
1278 
1279 ////////////////////////////////////////////////////////////////////////////////
1280 /// Creates "tube" node for GDML from object TGeoTubeSeg
1281 
1283 {
1284  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "tube", nullptr);
1285  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1286  TString lname = GenName(geoShape->GetName(), TString::Format("%p", geoShape));
1287  fGdmlE->NewAttr(mainN, nullptr, "name", lname);
1288  if (IsNullParam(geoShape->GetRmax(), "Rmax", lname) ||
1289  IsNullParam(geoShape->GetDz(), "Dz", lname)) {
1290  return nullptr;
1291  }
1292 
1293  fGdmlE->NewAttr(mainN, nullptr, "rmin", TString::Format(fltPrecision.Data(), geoShape->GetRmin()));
1294  fGdmlE->NewAttr(mainN, nullptr, "rmax", TString::Format(fltPrecision.Data(), geoShape->GetRmax()));
1295  fGdmlE->NewAttr(mainN, nullptr, "z", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDz()));
1296  fGdmlE->NewAttr(mainN, nullptr, "startphi", TString::Format(fltPrecision.Data(), geoShape->GetPhi1()));
1297  fGdmlE->NewAttr(mainN, nullptr, "deltaphi", TString::Format(fltPrecision.Data(), geoShape->GetPhi2() - geoShape->GetPhi1()));
1298 
1299  fGdmlE->NewAttr(mainN, nullptr, "aunit", "deg");
1300  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
1301  return mainN;
1302 }
1303 
1304 ////////////////////////////////////////////////////////////////////////////////
1305 /// Creates "cutTube" node for GDML
1306 
1308 {
1309  XMLNodePointer_t mainN;
1310  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1311 
1312  mainN = fGdmlE->NewChild(nullptr, nullptr, "cutTube", nullptr);
1313  TString lname = GenName(geoShape->GetName(), TString::Format("%p", geoShape));
1314  fGdmlE->NewAttr(mainN, nullptr, "name", lname);
1315  if (IsNullParam(geoShape->GetRmax(), "Rmax", lname) ||
1316  IsNullParam(geoShape->GetDz(), "Dz", lname)) {
1317  return nullptr;
1318  }
1319  //This is not needed, because cutTube is already supported by Geant4 9.5
1320  if (fgG4Compatibility == kTRUE && kFALSE) {
1321  TGeoShape * fakeCtub = CreateFakeCtub(geoShape);
1322  mainN = ChooseObject(fakeCtub);
1323 
1324  //register name for cuttube shape (so it will be found during volume export)
1325  lname = fNameList->fLst[TString::Format("%p", fakeCtub)];
1326  fNameList->fLst[TString::Format("%p", geoShape)] = lname;
1327  Info("CreateCutTubeN", "WARNING! %s - CutTube was replaced by intersection of TGeoTubSeg and two TGeoBBoxes",
1328  lname.Data());
1329  return mainN;
1330  }
1331  fGdmlE->NewAttr(mainN, nullptr, "rmin", TString::Format(fltPrecision.Data(), geoShape->GetRmin()));
1332  fGdmlE->NewAttr(mainN, nullptr, "rmax", TString::Format(fltPrecision.Data(), geoShape->GetRmax()));
1333  fGdmlE->NewAttr(mainN, nullptr, "z", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDz()));
1334  fGdmlE->NewAttr(mainN, nullptr, "startphi", TString::Format(fltPrecision.Data(), geoShape->GetPhi1()));
1335  fGdmlE->NewAttr(mainN, nullptr, "deltaphi", TString::Format(fltPrecision.Data(), geoShape->GetPhi2() - geoShape->GetPhi1()));
1336  fGdmlE->NewAttr(mainN, nullptr, "lowX", TString::Format(fltPrecision.Data(), geoShape->GetNlow()[0]));
1337  fGdmlE->NewAttr(mainN, nullptr, "lowY", TString::Format(fltPrecision.Data(), geoShape->GetNlow()[1]));
1338  fGdmlE->NewAttr(mainN, nullptr, "lowZ", TString::Format(fltPrecision.Data(), geoShape->GetNlow()[2]));
1339  fGdmlE->NewAttr(mainN, nullptr, "highX", TString::Format(fltPrecision.Data(), geoShape->GetNhigh()[0]));
1340  fGdmlE->NewAttr(mainN, nullptr, "highY", TString::Format(fltPrecision.Data(), geoShape->GetNhigh()[1]));
1341  fGdmlE->NewAttr(mainN, nullptr, "highZ", TString::Format(fltPrecision.Data(), geoShape->GetNhigh()[2]));
1342 
1343  fGdmlE->NewAttr(mainN, nullptr, "aunit", "deg");
1344  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
1345 
1346  return mainN;
1347 }
1348 
1349 ////////////////////////////////////////////////////////////////////////////////
1350 /// Creates "tube" node for GDML from object TGeoTube
1351 
1353 {
1354  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "tube", nullptr);
1355  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1356  TString lname = GenName(geoShape->GetName(), TString::Format("%p", geoShape));
1357  fGdmlE->NewAttr(mainN, nullptr, "name", lname);
1358  if (IsNullParam(geoShape->GetRmax(), "Rmax", lname) ||
1359  IsNullParam(geoShape->GetDz(), "Dz", lname)) {
1360  return nullptr;
1361  }
1362 
1363  fGdmlE->NewAttr(mainN, nullptr, "rmin", TString::Format(fltPrecision.Data(), geoShape->GetRmin()));
1364  fGdmlE->NewAttr(mainN, nullptr, "rmax", TString::Format(fltPrecision.Data(), geoShape->GetRmax()));
1365  fGdmlE->NewAttr(mainN, nullptr, "z", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDz()));
1366  fGdmlE->NewAttr(mainN, nullptr, "startphi", TString::Format("%i", 0));
1367  fGdmlE->NewAttr(mainN, nullptr, "deltaphi", TString::Format("%i", 360));
1368 
1369  fGdmlE->NewAttr(mainN, nullptr, "aunit", "deg");
1370  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
1371  return mainN;
1372 }
1373 
1374 ////////////////////////////////////////////////////////////////////////////////
1375 /// Creates "zplane" node for GDML
1376 
1378 {
1379  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "zplane", nullptr);
1380  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1381 
1382  fGdmlE->NewAttr(mainN, nullptr, "z", TString::Format(fltPrecision.Data(), z));
1383  fGdmlE->NewAttr(mainN, nullptr, "rmin", TString::Format(fltPrecision.Data(), rmin));
1384  fGdmlE->NewAttr(mainN, nullptr, "rmax", TString::Format(fltPrecision.Data(), rmax));
1385 
1386  return mainN;
1387 }
1388 
1389 ////////////////////////////////////////////////////////////////////////////////
1390 /// Creates "polycone" node for GDML
1391 
1393 {
1394  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "polycone", nullptr);
1395  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1396  TString lname = GenName(geoShape->GetName(), TString::Format("%p", geoShape));
1397  fGdmlE->NewAttr(mainN, nullptr, "name", lname);
1398 
1399  fGdmlE->NewAttr(mainN, nullptr, "startphi", TString::Format(fltPrecision.Data(), geoShape->GetPhi1()));
1400  fGdmlE->NewAttr(mainN, nullptr, "deltaphi", TString::Format(fltPrecision.Data(), geoShape->GetDphi()));
1401 
1402  fGdmlE->NewAttr(mainN, nullptr, "aunit", "deg");
1403  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
1404  Int_t nZPlns = geoShape->GetNz();
1405  for (Int_t it = 0; it < nZPlns; it++) {
1406  //add zplane child node
1407  fGdmlE->AddChild(mainN, CreateZplaneN(geoShape->GetZ(it), geoShape->GetRmin(it), geoShape->GetRmax(it)));
1408  //compare actual plane and next plane
1409  if ((it < nZPlns - 1) && (geoShape->GetZ(it) == geoShape->GetZ(it + 1))) {
1410  //rmin of actual is greater then rmax of next one
1411  // | |rmax next
1412  // __ ...| |... __ < rmin actual
1413  // | | | |
1414  if (geoShape->GetRmin(it) > geoShape->GetRmax(it + 1)) {
1415  //adding plane from rmax next to rmin actual at the same z position
1416  if (fgG4Compatibility == kTRUE) {
1417  fGdmlE->AddChild(mainN, CreateZplaneN(geoShape->GetZ(it), geoShape->GetRmax(it + 1), geoShape->GetRmin(it)));
1418  Info("CreatePolyconeN", "WARNING! One plane was added to %s solid to be compatible with Geant4", lname.Data());
1419  } else {
1420  Info("CreatePolyconeN", "WARNING! Solid %s definition seems not contiguous may cause problems in Geant4", lname.Data());
1421  }
1422 
1423  }
1424  //rmin of next is greater then rmax of actual
1425  // | | | |
1426  // | |...___...| | rmin next
1427  // | | > rmax act
1428  if (geoShape->GetRmin(it + 1) > geoShape->GetRmax(it)) {
1429  //adding plane from rmax act to rmin next at the same z position
1430  if (fgG4Compatibility == kTRUE) {
1431  fGdmlE->AddChild(mainN, CreateZplaneN(geoShape->GetZ(it), geoShape->GetRmax(it), geoShape->GetRmin(it + 1)));
1432  Info("CreatePolyconeN", "WARNING! One plane was added to %s solid to be compatible with Geant4", lname.Data());
1433  } else {
1434  Info("CreatePolyconeN", "WARNING! Solid %s definition seems not contiguous may cause problems in Geant4", lname.Data());
1435  }
1436  }
1437  }
1438  }
1439  return mainN;
1440 }
1441 
1442 ////////////////////////////////////////////////////////////////////////////////
1443 /// Creates "torus" node for GDML
1444 
1446 {
1447  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "torus", nullptr);
1448  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1449  TString lname = GenName(geoShape->GetName(), TString::Format("%p", geoShape));
1450  fGdmlE->NewAttr(mainN, nullptr, "name", lname);
1451  if (IsNullParam(geoShape->GetRmax(), "Rmax", lname)) {
1452  return nullptr;
1453  }
1454 
1455  fGdmlE->NewAttr(mainN, nullptr, "rtor", TString::Format(fltPrecision.Data(), geoShape->GetR()));
1456  fGdmlE->NewAttr(mainN, nullptr, "rmin", TString::Format(fltPrecision.Data(), geoShape->GetRmin()));
1457  fGdmlE->NewAttr(mainN, nullptr, "rmax", TString::Format(fltPrecision.Data(), geoShape->GetRmax()));
1458  fGdmlE->NewAttr(mainN, nullptr, "startphi", TString::Format(fltPrecision.Data(), geoShape->GetPhi1()));
1459  fGdmlE->NewAttr(mainN, nullptr, "deltaphi", TString::Format(fltPrecision.Data(), geoShape->GetDphi()));
1460 
1461  fGdmlE->NewAttr(mainN, nullptr, "aunit", "deg");
1462  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
1463 
1464  return mainN;
1465 }
1466 
1467 ////////////////////////////////////////////////////////////////////////////////
1468 /// Creates "polyhedra" node for GDML
1469 
1471 {
1472  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "polyhedra", nullptr);
1473  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1474  fGdmlE->NewAttr(mainN, nullptr, "name", GenName(geoShape->GetName(), TString::Format("%p", geoShape)));
1475 
1476  fGdmlE->NewAttr(mainN, nullptr, "startphi", TString::Format(fltPrecision.Data(), geoShape->GetPhi1()));
1477  fGdmlE->NewAttr(mainN, nullptr, "deltaphi", TString::Format(fltPrecision.Data(), geoShape->GetDphi()));
1478  fGdmlE->NewAttr(mainN, nullptr, "numsides", TString::Format("%i", geoShape->GetNedges()));
1479 
1480  fGdmlE->NewAttr(mainN, nullptr, "aunit", "deg");
1481  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
1482  for (Int_t it = 0; it < geoShape->GetNz(); it++) {
1483  //add zplane child node
1484  fGdmlE->AddChild(mainN, CreateZplaneN(geoShape->GetZ(it), geoShape->GetRmin(it), geoShape->GetRmax(it)));
1485  }
1486  return mainN;
1487 }
1488 
1489 ////////////////////////////////////////////////////////////////////////////////
1490 /// Creates "eltube" node for GDML
1491 
1493 {
1494  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "eltube", nullptr);
1495  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1496  TString lname = GenName(geoShape->GetName(), TString::Format("%p", geoShape));
1497  fGdmlE->NewAttr(mainN, nullptr, "name", lname);
1498  if (IsNullParam(geoShape->GetA(), "A", lname) ||
1499  IsNullParam(geoShape->GetB(), "B", lname) ||
1500  IsNullParam(geoShape->GetDz(), "Dz", lname)) {
1501  return nullptr;
1502  }
1503 
1504  fGdmlE->NewAttr(mainN, nullptr, "dx", TString::Format(fltPrecision.Data(), geoShape->GetA()));
1505  fGdmlE->NewAttr(mainN, nullptr, "dy", TString::Format(fltPrecision.Data(), geoShape->GetB()));
1506  fGdmlE->NewAttr(mainN, nullptr, "dz", TString::Format(fltPrecision.Data(), geoShape->GetDz()));
1507 
1508  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
1509 
1510  return mainN;
1511 }
1512 
1513 ////////////////////////////////////////////////////////////////////////////////
1514 /// Creates "hype" node for GDML
1515 
1517 {
1518  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "hype", nullptr);
1519  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1520  TString lname = GenName(geoShape->GetName(), TString::Format("%p", geoShape));
1521  fGdmlE->NewAttr(mainN, nullptr, "name", lname);
1522  if (IsNullParam(geoShape->GetDz(), "Dz", lname)) {
1523  return nullptr;
1524  }
1525 
1526 
1527  fGdmlE->NewAttr(mainN, nullptr, "rmin", TString::Format(fltPrecision.Data(), geoShape->GetRmin()));
1528  fGdmlE->NewAttr(mainN, nullptr, "rmax", TString::Format(fltPrecision.Data(), geoShape->GetRmax()));
1529  fGdmlE->NewAttr(mainN, nullptr, "inst", TString::Format(fltPrecision.Data(), geoShape->GetStIn()));
1530  fGdmlE->NewAttr(mainN, nullptr, "outst", TString::Format(fltPrecision.Data(), geoShape->GetStOut()));
1531  fGdmlE->NewAttr(mainN, nullptr, "z", TString::Format(fltPrecision.Data(), 2 * geoShape->GetDz()));
1532 
1533  fGdmlE->NewAttr(mainN, nullptr, "aunit", "deg");
1534  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
1535 
1536  return mainN;
1537 }
1538 
1539 ////////////////////////////////////////////////////////////////////////////////
1540 /// Creates "xtru" node for GDML
1541 
1543 {
1544  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "xtru", nullptr);
1545  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1546  TString lname = GenName(geoShape->GetName(), TString::Format("%p", geoShape));
1547  fGdmlE->NewAttr(mainN, nullptr, "name", lname);
1548 
1549  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
1550  XMLNodePointer_t childN;
1551  Int_t vertNum = geoShape->GetNvert();
1552  Int_t secNum = geoShape->GetNz();
1553  if (vertNum < 3 || secNum < 2) {
1554  Info("CreateXtrusionN", "ERROR! TGeoXtru %s has only %i vertices and %i sections. It was not exported",
1555  lname.Data(), vertNum, secNum);
1556  mainN = nullptr;
1557  return mainN;
1558  }
1559  for (Int_t it = 0; it < vertNum; it++) {
1560  //add twoDimVertex child node
1561  childN = fGdmlE->NewChild(nullptr, nullptr, "twoDimVertex", nullptr);
1562  fGdmlE->NewAttr(childN, nullptr, "x", TString::Format(fltPrecision.Data(), geoShape->GetX(it)));
1563  fGdmlE->NewAttr(childN, nullptr, "y", TString::Format(fltPrecision.Data(), geoShape->GetY(it)));
1564  fGdmlE->AddChild(mainN, childN);
1565  }
1566  for (Int_t it = 0; it < secNum; it++) {
1567  //add section child node
1568  childN = fGdmlE->NewChild(nullptr, nullptr, "section", nullptr);
1569  fGdmlE->NewAttr(childN, nullptr, "zOrder", TString::Format("%i", it));
1570  fGdmlE->NewAttr(childN, nullptr, "zPosition", TString::Format(fltPrecision.Data(), geoShape->GetZ(it)));
1571  fGdmlE->NewAttr(childN, nullptr, "xOffset", TString::Format(fltPrecision.Data(), geoShape->GetXOffset(it)));
1572  fGdmlE->NewAttr(childN, nullptr, "yOffset", TString::Format(fltPrecision.Data(), geoShape->GetYOffset(it)));
1573  fGdmlE->NewAttr(childN, nullptr, "scalingFactor", TString::Format(fltPrecision.Data(), geoShape->GetScale(it)));
1574  fGdmlE->AddChild(mainN, childN);
1575  }
1576  return mainN;
1577 }
1578 
1579 ////////////////////////////////////////////////////////////////////////////////
1580 /// Creates "ellipsoid" node for GDML
1581 /// this is a special case, because ellipsoid is not defined in ROOT
1582 /// so when intersection of scaled sphere and TGeoBBox is found,
1583 /// it is considered as an ellipsoid
1584 
1586 {
1587  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "ellipsoid", nullptr);
1588  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1589  TGeoScaledShape *leftS = (TGeoScaledShape *)geoShape->GetBoolNode()->GetLeftShape(); //ScaledShape
1590  TGeoBBox *rightS = (TGeoBBox *)geoShape->GetBoolNode()->GetRightShape(); //BBox
1591 
1592 
1593  fGdmlE->NewAttr(mainN, nullptr, "name", elName.Data());
1594  Double_t sx = leftS->GetScale()->GetScale()[0];
1595  Double_t sy = leftS->GetScale()->GetScale()[1];
1596  Double_t radius = ((TGeoSphere *) leftS->GetShape())->GetRmax();
1597 
1598  Double_t ax, by, cz;
1599  cz = radius;
1600  ax = sx * radius;
1601  by = sy * radius;
1602 
1603  Double_t dz = rightS->GetDZ();
1604  Double_t zorig = rightS->GetOrigin()[2];
1605  Double_t zcut2 = dz + zorig;
1606  Double_t zcut1 = 2 * zorig - zcut2;
1607 
1608 
1609  fGdmlE->NewAttr(mainN, nullptr, "ax", TString::Format(fltPrecision.Data(), ax));
1610  fGdmlE->NewAttr(mainN, nullptr, "by", TString::Format(fltPrecision.Data(), by));
1611  fGdmlE->NewAttr(mainN, nullptr, "cz", TString::Format(fltPrecision.Data(), cz));
1612  fGdmlE->NewAttr(mainN, nullptr, "zcut1", TString::Format(fltPrecision.Data(), zcut1));
1613  fGdmlE->NewAttr(mainN, nullptr, "zcut2", TString::Format(fltPrecision.Data(), zcut2));
1614  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
1615 
1616  return mainN;
1617 }
1618 
1619 ////////////////////////////////////////////////////////////////////////////////
1620 /// Creates "elcone" (elliptical cone) node for GDML
1621 /// this is a special case, because elliptical cone is not defined in ROOT
1622 /// so when scaled cone is found, it is considered as a elliptical cone
1623 
1625 {
1626  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "elcone", nullptr);
1627  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1628  fGdmlE->NewAttr(mainN, nullptr, "name", GenName(geoShape->GetName(), TString::Format("%p", geoShape)));
1629  Double_t zcut = ((TGeoCone *) geoShape->GetShape())->GetDz();
1630  Double_t rx1 = ((TGeoCone *) geoShape->GetShape())->GetRmax1();
1631  Double_t rx2 = ((TGeoCone *) geoShape->GetShape())->GetRmax2();
1632  Double_t zmax = zcut * ((rx1 + rx2) / (rx1 - rx2));
1633  Double_t z = zcut + zmax;
1634 
1635  Double_t sy = geoShape->GetScale()->GetScale()[1];
1636  Double_t ry1 = sy * rx1;
1637 
1638  std::string format(TString::Format("%s/%s", fltPrecision.Data(), fltPrecision.Data()).Data());
1639  fGdmlE->NewAttr(mainN, nullptr, "dx", TString::Format(format.c_str(), rx1, z));
1640  fGdmlE->NewAttr(mainN, nullptr, "dy", TString::Format(format.c_str(), ry1, z));
1641  fGdmlE->NewAttr(mainN, nullptr, "zmax", TString::Format(fltPrecision.Data(), zmax));
1642  fGdmlE->NewAttr(mainN, nullptr, "zcut", TString::Format(fltPrecision.Data(), zcut));
1643  fGdmlE->NewAttr(mainN, nullptr, "lunit", "cm");
1644 
1645  return mainN;
1646 }
1647 
1648 ////////////////////////////////////////////////////////////////////////////////
1649 /// Creates "tessellated" (tessellated shape) node for GDML
1650 
1652 {
1653  // add all vertices to the define section
1654  TString genname = GenName(geoShape->GetName(), TString::Format("%p", geoShape));
1655  for (int i = 0; i < geoShape->GetNvertices(); ++i) {
1656  auto vertex = geoShape->GetVertex(i);
1657  TString posName = TString::Format("%s_%d", genname.Data(), i);
1658  Xyz nodPos;
1659  nodPos.x = vertex[0];
1660  nodPos.y = vertex[1];
1661  nodPos.z = vertex[2];
1662  auto childN = CreatePositionN(posName.Data(), nodPos);
1663  fGdmlE->AddChild(fDefineNode, childN); //adding node to <define> node
1664  }
1665  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "tessellated", nullptr);
1666  fGdmlE->NewAttr(mainN, nullptr, "name", genname.Data());
1667 
1668  XMLNodePointer_t childN;
1669  for (Int_t it = 0; it < geoShape->GetNfacets(); it++) {
1670  //add section child node
1671  auto facet = geoShape->GetFacet(it);
1672  bool triangular = facet.GetNvert() == 3;
1673  TString ntype = (triangular) ? "triangular" : "quadrangular";
1674  childN = fGdmlE->NewChild(nullptr, nullptr, ntype.Data(), nullptr);
1675  fGdmlE->NewAttr(childN, nullptr, "vertex1", TString::Format("%s_%d", genname.Data(), facet.GetVertexIndex(0)));
1676  fGdmlE->NewAttr(childN, nullptr, "vertex2", TString::Format("%s_%d", genname.Data(), facet.GetVertexIndex(1)));
1677  fGdmlE->NewAttr(childN, nullptr, "vertex3", TString::Format("%s_%d", genname.Data(), facet.GetVertexIndex(2)));
1678  if (!triangular)
1679  fGdmlE->NewAttr(childN, nullptr, "vertex4", TString::Format("%s_%d", genname.Data(), facet.GetVertexIndex(3)));
1680  fGdmlE->NewAttr(childN, nullptr, "type", "ABSOLUTE");
1681  fGdmlE->AddChild(mainN, childN);
1682  }
1683  return mainN;
1684 }
1685 
1686 ////////////////////////////////////////////////////////////////////////////////
1687 /// Creates common part of union intersection and subtraction nodes
1688 
1690 {
1691  XMLNodePointer_t mainN, ndR, ndL, childN;
1692  TString nodeName = GenName(geoShape->GetName(), TString::Format("%p", geoShape));
1693  TString lboolType;
1694  TGeoBoolNode::EGeoBoolType boolType = geoShape->GetBoolNode()->GetBooleanOperator();
1695  switch (boolType) {
1697  lboolType = "union";
1698  break;
1700  lboolType = "subtraction";
1701  break;
1703  lboolType = "intersection";
1704  break;
1705  }
1706 
1708  const Double_t *ltr = geoShape->GetBoolNode()->GetLeftMatrix()->GetTranslation();
1710  const Double_t *rtr = geoShape->GetBoolNode()->GetRightMatrix()->GetTranslation();
1711 
1712  //specific case!
1713  //Ellipsoid tag preparing
1714  //if left == TGeoScaledShape AND right == TGeoBBox
1715  // AND if TGeoScaledShape->GetShape == TGeoSphere
1716  TGeoShape *leftS = geoShape->GetBoolNode()->GetLeftShape();
1717  TGeoShape *rightS = geoShape->GetBoolNode()->GetRightShape();
1718  if (strcmp(leftS->ClassName(), "TGeoScaledShape") == 0 &&
1719  strcmp(rightS->ClassName(), "TGeoBBox") == 0) {
1720  if (strcmp(((TGeoScaledShape *)leftS)->GetShape()->ClassName(), "TGeoSphere") == 0) {
1721  if (lboolType == "intersection") {
1722  mainN = CreateEllipsoidN(geoShape, nodeName);
1723  return mainN;
1724  }
1725  }
1726  }
1727 
1728  Xyz translL, translR;
1729  //translation
1730  translL.x = ltr[0];
1731  translL.y = ltr[1];
1732  translL.z = ltr[2];
1733  translR.x = rtr[0];
1734  translR.y = rtr[1];
1735  translR.z = rtr[2];
1736 
1737  //left and right nodes are created here also their names are created
1738  ndL = ChooseObject(geoShape->GetBoolNode()->GetLeftShape());
1739  ndR = ChooseObject(geoShape->GetBoolNode()->GetRightShape());
1740 
1741  //retrieve left and right node names by their pointer to make reference
1742  TString lname = fNameList->fLst[TString::Format("%p", geoShape->GetBoolNode()->GetLeftShape())];
1743  TString rname = fNameList->fLst[TString::Format("%p", geoShape->GetBoolNode()->GetRightShape())];
1744 
1745  //left and right nodes appended to main structure of nodes (if they are not already there)
1746  if (ndL != nullptr) {
1747  fGdmlE->AddChild(fSolidsNode, ndL);
1748  fSolCnt++;
1749  } else {
1750  if (lname.Contains("missing_") || lname == "") {
1751  Info("CreateCommonBoolN", "ERROR! Left node is NULL - Boolean Shape will be skipped");
1752  return nullptr;
1753  }
1754  }
1755  if (ndR != nullptr) {
1756  fGdmlE->AddChild(fSolidsNode, ndR);
1757  fSolCnt++;
1758  } else {
1759  if (rname.Contains("missing_") || rname == "") {
1760  Info("CreateCommonBoolN", "ERROR! Right node is NULL - Boolean Shape will be skipped");
1761  return nullptr;
1762  }
1763  }
1764 
1765  //create union node and its child nodes (or intersection or subtraction)
1766  /* <union name="...">
1767  * <first ref="left name" />
1768  * <second ref="right name" />
1769  * <firstposition .../>
1770  * <firstrotation .../>
1771  * <position .../>
1772  * <rotation .../>
1773  * </union>
1774  */
1775  mainN = fGdmlE->NewChild(nullptr, nullptr, lboolType.Data(), nullptr);
1776  fGdmlE->NewAttr(mainN, nullptr, "name", nodeName);
1777 
1778  //<first> (left)
1779  childN = fGdmlE->NewChild(nullptr, nullptr, "first", nullptr);
1780  fGdmlE->NewAttr(childN, nullptr, "ref", lname);
1781  fGdmlE->AddChild(mainN, childN);
1782 
1783  //<second> (right)
1784  childN = fGdmlE->NewChild(nullptr, nullptr, "second", nullptr);
1785  fGdmlE->NewAttr(childN, nullptr, "ref", rname);
1786  fGdmlE->AddChild(mainN, childN);
1787 
1788  //<firstposition> (left)
1789  if ((translL.x != 0.0) || (translL.y != 0.0) || (translL.z != 0.0)) {
1790  childN = CreatePositionN((nodeName + lname + "pos").Data(), translL, "firstposition");
1791  fGdmlE->AddChild(mainN, childN);
1792  }
1793  //<firstrotation> (left)
1794  if ((lrot.x != 0.0) || (lrot.y != 0.0) || (lrot.z != 0.0)) {
1795  childN = CreateRotationN((nodeName + lname + "rot").Data(), lrot, "firstrotation");
1796  fGdmlE->AddChild(mainN, childN);
1797  }
1798  //<position> (right)
1799  if ((translR.x != 0.0) || (translR.y != 0.0) || (translR.z != 0.0)) {
1800  childN = CreatePositionN((nodeName + rname + "pos").Data(), translR, "position");
1801  fGdmlE->AddChild(mainN, childN);
1802  }
1803  //<rotation> (right)
1804  if ((rrot.x != 0.0) || (rrot.y != 0.0) || (rrot.z != 0.0)) {
1805  childN = CreateRotationN((nodeName + rname + "rot").Data(), rrot, "rotation");
1806  fGdmlE->AddChild(mainN, childN);
1807  }
1808 
1809  return mainN;
1810 }
1811 
1812 ////////////////////////////////////////////////////////////////////////////////
1813 /// Creates "opticalsurface" node for GDML
1814 
1816 {
1817  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "opticalsurface", nullptr);
1818  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1819  fGdmlE->NewAttr(mainN, nullptr, "name", geoSurf->GetName());
1820  fGdmlE->NewAttr(mainN, nullptr, "model", TGeoOpticalSurface::ModelToString(geoSurf->GetModel()));
1821  fGdmlE->NewAttr(mainN, nullptr, "finish", TGeoOpticalSurface::FinishToString(geoSurf->GetFinish()));
1822  fGdmlE->NewAttr(mainN, nullptr, "type", TGeoOpticalSurface::TypeToString(geoSurf->GetType()));
1823  fGdmlE->NewAttr(mainN, nullptr, "value", TString::Format(fltPrecision.Data(), geoSurf->GetValue()));
1824 
1825  // Write properties
1826  TList const &properties = geoSurf->GetProperties();
1827  if (properties.GetSize()) {
1828  TIter next(&properties);
1829  TNamed *property;
1830  while ((property = (TNamed*)next()))
1831  fGdmlE->AddChild(mainN, CreatePropertyN(*property));
1832  }
1833  return mainN;
1834 }
1835 
1836 ////////////////////////////////////////////////////////////////////////////////
1837 /// Creates "skinsurface" node for GDML
1838 
1840 {
1841  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "skinsurface", nullptr);
1842  fGdmlE->NewAttr(mainN, nullptr, "name", geoSurf->GetName());
1843  fGdmlE->NewAttr(mainN, nullptr, "surfaceproperty", geoSurf->GetTitle());
1844  // Cretate the logical volume reference node
1845  auto childN = fGdmlE->NewChild(nullptr, nullptr, "volumeref", nullptr);
1846  fGdmlE->NewAttr(childN, nullptr, "ref", geoSurf->GetVolume()->GetName());
1847  fGdmlE->AddChild(mainN, childN);
1848  return mainN;
1849 }
1850 
1851 ////////////////////////////////////////////////////////////////////////////////
1852 /// Creates "bordersurface" node for GDML
1853 
1855 {
1856  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "bordersurface", nullptr);
1857  fGdmlE->NewAttr(mainN, nullptr, "name", geoSurf->GetName());
1858  fGdmlE->NewAttr(mainN, nullptr, "surfaceproperty", geoSurf->GetTitle());
1859  // Cretate the logical volume reference node
1860  auto childN = fGdmlE->NewChild(nullptr, nullptr, "physvolref", nullptr);
1861  fGdmlE->NewAttr(childN, nullptr, "ref", geoSurf->GetNode1()->GetName());
1862  fGdmlE->NewAttr(childN, nullptr, "ref", geoSurf->GetNode2()->GetName());
1863  fGdmlE->AddChild(mainN, childN);
1864  return mainN;
1865 }
1866 
1867 ////////////////////////////////////////////////////////////////////////////////
1868 /// Creates "position" kind of node for GDML
1869 
1870 XMLNodePointer_t TGDMLWrite::CreatePositionN(const char * name, Xyz position, const char * type, const char * unit)
1871 {
1872  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, type, nullptr);
1873  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1874  fGdmlE->NewAttr(mainN, nullptr, "name", name);
1875  fGdmlE->NewAttr(mainN, nullptr, "x", TString::Format(fltPrecision.Data(), position.x));
1876  fGdmlE->NewAttr(mainN, nullptr, "y", TString::Format(fltPrecision.Data(), position.y));
1877  fGdmlE->NewAttr(mainN, nullptr, "z", TString::Format(fltPrecision.Data(), position.z));
1878  fGdmlE->NewAttr(mainN, nullptr, "unit", unit);
1879  return mainN;
1880 }
1881 
1882 ////////////////////////////////////////////////////////////////////////////////
1883 /// Creates "rotation" kind of node for GDML
1884 
1885 XMLNodePointer_t TGDMLWrite::CreateRotationN(const char * name, Xyz rotation, const char * type, const char * unit)
1886 {
1887  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, type, nullptr);
1888  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1889  fGdmlE->NewAttr(mainN, nullptr, "name", name);
1890  fGdmlE->NewAttr(mainN, nullptr, "x", TString::Format(fltPrecision.Data(), rotation.x));
1891  fGdmlE->NewAttr(mainN, nullptr, "y", TString::Format(fltPrecision.Data(), rotation.y));
1892  fGdmlE->NewAttr(mainN, nullptr, "z", TString::Format(fltPrecision.Data(), rotation.z));
1893  fGdmlE->NewAttr(mainN, nullptr, "unit", unit);
1894  return mainN;
1895 }
1896 
1897 ////////////////////////////////////////////////////////////////////////////////
1898 /// Creates "matrix" kind of node for GDML
1899 
1901 {
1902  std::stringstream vals;
1903  size_t cols = matrix->GetCols();
1904  size_t rows = matrix->GetRows();
1905  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "matrix", nullptr);
1906  fGdmlE->NewAttr(mainN, nullptr, "name", matrix->GetName());
1907  fGdmlE->NewAttr(mainN, nullptr, "coldim", TString::Format("%zu", cols));
1908  for(size_t i=0; i<rows; ++i) {
1909  for(size_t j=0; j<cols; ++j) {
1910  vals << matrix->Get(i,j);
1911  if ( j < cols-1 ) vals << ' ';
1912  }
1913  if ( i < rows-1 ) vals << '\n';
1914  }
1915  fGdmlE->NewAttr(mainN, nullptr, "values", vals.str().c_str());
1916  return mainN;
1917 }
1918 
1919 ////////////////////////////////////////////////////////////////////////////////
1920 /// Creates "constant" kind of node for GDML
1921 
1923 {
1924  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "constant", nullptr);
1925  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
1926  fGdmlE->NewAttr(mainN, nullptr, "name", name);
1927  fGdmlE->NewAttr(mainN, nullptr, "value", TString::Format(fltPrecision.Data(), value));
1928  return mainN;
1929 }
1930 
1931 ////////////////////////////////////////////////////////////////////////////////
1932 /// Creates "setup" node for GDML
1933 
1934 XMLNodePointer_t TGDMLWrite::CreateSetupN(const char * topVolName, const char * name, const char * version)
1935 {
1936  XMLNodePointer_t setupN = fGdmlE->NewChild(nullptr, nullptr, "setup", nullptr);
1937  fGdmlE->NewAttr(setupN, nullptr, "name", name);
1938  fGdmlE->NewAttr(setupN, nullptr, "version", version);
1939  XMLNodePointer_t fworldN = fGdmlE->NewChild(setupN, nullptr, "world", nullptr);
1940  fGdmlE->NewAttr(fworldN, nullptr, "ref", topVolName);
1941  return setupN;
1942 }
1943 
1944 ////////////////////////////////////////////////////////////////////////////////
1945 /// Creates "volume" node for GDML
1946 
1947 XMLNodePointer_t TGDMLWrite::StartVolumeN(const char * name, const char * solid, const char * material)
1948 {
1949  XMLNodePointer_t childN;
1950  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "volume", nullptr);
1951  fGdmlE->NewAttr(mainN, nullptr, "name", name);
1952 
1953  childN = fGdmlE->NewChild(nullptr, nullptr, "materialref", nullptr);
1954  fGdmlE->NewAttr(childN, nullptr, "ref", material);
1955  fGdmlE->AddChild(mainN, childN);
1956 
1957  childN = fGdmlE->NewChild(nullptr, nullptr, "solidref", nullptr);
1958  fGdmlE->NewAttr(childN, nullptr, "ref", solid);
1959  fGdmlE->AddChild(mainN, childN);
1960 
1961  return mainN;
1962 }
1963 
1964 ////////////////////////////////////////////////////////////////////////////////
1965 /// Creates "assembly" node for GDML
1966 
1968 {
1969  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "assembly", nullptr);
1970  fGdmlE->NewAttr(mainN, nullptr, "name", name);
1971 
1972  return mainN;
1973 }
1974 
1975 ////////////////////////////////////////////////////////////////////////////////
1976 /// Creates "physvol" node for GDML
1977 
1978 XMLNodePointer_t TGDMLWrite::CreatePhysVolN(const char *name, Int_t copyno, const char * volref, const char * posref, const char * rotref, XMLNodePointer_t scaleN)
1979 {
1980  fPhysVolCnt++;
1981  XMLNodePointer_t childN;
1982  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "physvol", nullptr);
1983  fGdmlE->NewAttr(mainN, nullptr, "name", name);
1984  fGdmlE->NewAttr(mainN, nullptr, "copynumber", TString::Format("%d",copyno));
1985 
1986  childN = fGdmlE->NewChild(nullptr, nullptr, "volumeref", nullptr);
1987  fGdmlE->NewAttr(childN, nullptr, "ref", volref);
1988  fGdmlE->AddChild(mainN, childN);
1989 
1990  childN = fGdmlE->NewChild(nullptr, nullptr, "positionref", nullptr);
1991  fGdmlE->NewAttr(childN, nullptr, "ref", posref);
1992  fGdmlE->AddChild(mainN, childN);
1993 
1994  //if is not empty string add this node
1995  if (strcmp(rotref, "") != 0) {
1996  childN = fGdmlE->NewChild(nullptr, nullptr, "rotationref", nullptr);
1997  fGdmlE->NewAttr(childN, nullptr, "ref", rotref);
1998  fGdmlE->AddChild(mainN, childN);
1999  }
2000  if (scaleN != nullptr) {
2001  fGdmlE->AddChild(mainN, scaleN);
2002  }
2003 
2004  return mainN;
2005 }
2006 
2007 ////////////////////////////////////////////////////////////////////////////////
2008 /// Creates "divisionvol" node for GDML
2009 
2010 XMLNodePointer_t TGDMLWrite::CreateDivisionN(Double_t offset, Double_t width, Int_t number, const char * axis, const char * unit, const char * volref)
2011 {
2012  XMLNodePointer_t childN = 0;
2013  XMLNodePointer_t mainN = fGdmlE->NewChild(nullptr, nullptr, "divisionvol", nullptr);
2014  fGdmlE->NewAttr(mainN, nullptr, "axis", axis);
2015  fGdmlE->NewAttr(mainN, nullptr, "number", TString::Format("%i", number));
2016  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
2017  if (fgG4Compatibility == kTRUE) {
2018  //if eg. full length is 20 and width * number = 20,0001 problem in geant4
2019  //unit is either in cm or degrees nothing else
2020  width = (floor(width * 1E4)) * 1E-4;
2021  if ((offset >= 0.) && (strcmp(axis, "kPhi") == 0)) {
2022  Int_t offsetI = (Int_t) offset;
2023  Double_t decimals = offset - offsetI;
2024  //put to range from 0 to 360 add decimals and then put to range 0 -> -360
2025  offset = (offsetI % 360) + decimals - 360;
2026  }
2027  }
2028  fGdmlE->NewAttr(mainN, nullptr, "width", TString::Format(fltPrecision.Data(), width));
2029 
2030  fGdmlE->NewAttr(mainN, nullptr, "offset", TString::Format(fltPrecision.Data(), offset));
2031  fGdmlE->NewAttr(mainN, nullptr, "unit", unit);
2032  if (strcmp(volref, "") != 0) {
2033  childN = fGdmlE->NewChild(nullptr, nullptr, "volumeref", nullptr);
2034  fGdmlE->NewAttr(childN, nullptr, "ref", volref);
2035  }
2036  fGdmlE->AddChild(mainN, childN);
2037 
2038 
2039  return mainN;
2040 }
2041 
2042 ////////////////////////////////////////////////////////////////////////////////
2043 /// Chooses the object and method that should be used for processing object
2044 
2046 {
2047  const char * clsname = geoShape->ClassName();
2048  XMLNodePointer_t solidN;
2049 
2050  if (CanProcess((TObject *)geoShape) == kFALSE) {
2051  return nullptr;
2052  }
2053 
2054  //process different shapes
2055  if (strcmp(clsname, "TGeoBBox") == 0) {
2056  solidN = CreateBoxN((TGeoBBox*) geoShape);
2057  } else if (strcmp(clsname, "TGeoParaboloid") == 0) {
2058  solidN = CreateParaboloidN((TGeoParaboloid*) geoShape);
2059  } else if (strcmp(clsname, "TGeoSphere") == 0) {
2060  solidN = CreateSphereN((TGeoSphere*) geoShape);
2061  } else if (strcmp(clsname, "TGeoArb8") == 0) {
2062  solidN = CreateArb8N((TGeoArb8*) geoShape);
2063  } else if (strcmp(clsname, "TGeoConeSeg") == 0) {
2064  solidN = CreateConeN((TGeoConeSeg*) geoShape);
2065  } else if (strcmp(clsname, "TGeoCone") == 0) {
2066  solidN = CreateConeN((TGeoCone*) geoShape);
2067  } else if (strcmp(clsname, "TGeoPara") == 0) {
2068  solidN = CreateParaN((TGeoPara*) geoShape);
2069  } else if (strcmp(clsname, "TGeoTrap") == 0) {
2070  solidN = CreateTrapN((TGeoTrap*) geoShape);
2071  } else if (strcmp(clsname, "TGeoGtra") == 0) {
2072  solidN = CreateTwistedTrapN((TGeoGtra*) geoShape);
2073  } else if (strcmp(clsname, "TGeoTrd1") == 0) {
2074  solidN = CreateTrdN((TGeoTrd1*) geoShape);
2075  } else if (strcmp(clsname, "TGeoTrd2") == 0) {
2076  solidN = CreateTrdN((TGeoTrd2*) geoShape);
2077  } else if (strcmp(clsname, "TGeoTubeSeg") == 0) {
2078  solidN = CreateTubeN((TGeoTubeSeg*) geoShape);
2079  } else if (strcmp(clsname, "TGeoCtub") == 0) {
2080  solidN = CreateCutTubeN((TGeoCtub*) geoShape);
2081  } else if (strcmp(clsname, "TGeoTube") == 0) {
2082  solidN = CreateTubeN((TGeoTube*) geoShape);
2083  } else if (strcmp(clsname, "TGeoPcon") == 0) {
2084  solidN = CreatePolyconeN((TGeoPcon*) geoShape);
2085  } else if (strcmp(clsname, "TGeoTorus") == 0) {
2086  solidN = CreateTorusN((TGeoTorus*) geoShape);
2087  } else if (strcmp(clsname, "TGeoPgon") == 0) {
2088  solidN = CreatePolyhedraN((TGeoPgon*) geoShape);
2089  } else if (strcmp(clsname, "TGeoEltu") == 0) {
2090  solidN = CreateEltubeN((TGeoEltu*) geoShape);
2091  } else if (strcmp(clsname, "TGeoHype") == 0) {
2092  solidN = CreateHypeN((TGeoHype*) geoShape);
2093  } else if (strcmp(clsname, "TGeoXtru") == 0) {
2094  solidN = CreateXtrusionN((TGeoXtru*) geoShape);
2095  } else if (strcmp(clsname, "TGeoTessellated") == 0) {
2096  solidN = CreateTessellatedN((TGeoTessellated*) geoShape);
2097  } else if (strcmp(clsname, "TGeoScaledShape") == 0) {
2098  TGeoScaledShape * geoscale = (TGeoScaledShape *) geoShape;
2099  TString scaleObjClsName = geoscale->GetShape()->ClassName();
2100  if (scaleObjClsName == "TGeoCone") {
2101  solidN = CreateElConeN((TGeoScaledShape*) geoShape);
2102  } else {
2103  Info("ChooseObject",
2104  "ERROR! TGeoScaledShape object is not possible to process correctly. %s object is processed without scale",
2105  scaleObjClsName.Data());
2106  solidN = ChooseObject(geoscale->GetShape());
2107  //Name has to be propagated to geoscale level pointer
2108  fNameList->fLst[TString::Format("%p", geoscale)] =
2109  fNameList->fLst[TString::Format("%p", geoscale->GetShape())];
2110  }
2111  } else if (strcmp(clsname, "TGeoCompositeShape") == 0) {
2112  solidN = CreateCommonBoolN((TGeoCompositeShape*) geoShape);
2113  } else if (strcmp(clsname, "TGeoUnion") == 0) {
2114  solidN = CreateCommonBoolN((TGeoCompositeShape*) geoShape);
2115  } else if (strcmp(clsname, "TGeoIntersection") == 0) {
2116  solidN = CreateCommonBoolN((TGeoCompositeShape*) geoShape);
2117  } else if (strcmp(clsname, "TGeoSubtraction") == 0) {
2118  solidN = CreateCommonBoolN((TGeoCompositeShape*) geoShape);
2119  } else {
2120  Info("ChooseObject", "ERROR! %s Solid CANNOT be processed, solid is NOT supported",
2121  clsname);
2122  solidN = nullptr;
2123  }
2124  if (solidN == nullptr) {
2125  if (fNameList->fLst[TString::Format("%p", geoShape)] == "") {
2126  TString missingName = geoShape->GetName();
2127  GenName("missing_" + missingName, TString::Format("%p", geoShape));
2128  } else {
2129  fNameList->fLst[TString::Format("%p", geoShape)] = "missing_" + fNameList->fLst[TString::Format("%p", geoShape)];
2130  }
2131  }
2132 
2133  return solidN;
2134 }
2135 
2136 ////////////////////////////////////////////////////////////////////////////////
2137 /// Retrieves X Y Z angles from rotation matrix
2138 
2140 {
2141  TGDMLWrite::Xyz lxyz;
2142  Double_t a, b, c;
2143  Double_t rad = 180.0 / TMath::ACos(-1.0);
2144  const Double_t *r = rotationMatrix;
2145  Double_t cosb = TMath::Sqrt(r[0] * r[0] + r[1] * r[1]);
2146  if (cosb > 0.00001) {
2147  a = TMath::ATan2(r[5], r[8]) * rad;
2148  b = TMath::ATan2(-r[2], cosb) * rad;
2149  c = TMath::ATan2(r[1], r[0]) * rad;
2150  } else {
2151  a = TMath::ATan2(-r[7], r[4]) * rad;
2152  b = TMath::ATan2(-r[2], cosb) * rad;
2153  c = 0;
2154  }
2155  lxyz.x = a;
2156  lxyz.y = b;
2157  lxyz.z = c;
2158  return lxyz;
2159 }
2160 
2161 ////////////////////////////////////////////////////////////////////////////////
2162 /// Method creating cutTube as an intersection of tube and two boxes
2163 /// - not used anymore because cutube is supported in Geant4 9.5
2164 
2166 {
2167  Double_t rmin = geoShape->GetRmin();
2168  Double_t rmax = geoShape->GetRmax();
2169  Double_t z = geoShape->GetDz();
2170  Double_t startphi = geoShape->GetPhi1();
2171  Double_t deltaphi = geoShape->GetPhi2();
2172  Double_t x1 = geoShape->GetNlow()[0];
2173  Double_t y1 = geoShape->GetNlow()[1];
2174  Double_t z1 = geoShape->GetNlow()[2];
2175  Double_t x2 = geoShape->GetNhigh()[0];
2176  Double_t y2 = geoShape->GetNhigh()[1];
2177  Double_t z2 = geoShape->GetNhigh()[2];
2178  TString xname = geoShape->GetName();
2179 
2180 
2181  Double_t h0 = 2.*((TGeoBBox*)geoShape)->GetDZ();
2182  Double_t h1 = 2 * z;
2183  Double_t h2 = 2 * z;
2184  Double_t boxdx = 1E8 * (2 * rmax) + (2 * z);
2185 
2186  TGeoTubeSeg *T = new TGeoTubeSeg((xname + "T").Data(), rmin, rmax, h0, startphi, deltaphi);
2187  TGeoBBox *B1 = new TGeoBBox((xname + "B1").Data(), boxdx, boxdx, h1);
2188  TGeoBBox *B2 = new TGeoBBox((xname + "B2").Data(), boxdx, boxdx, h2);
2189 
2190 
2191  //first box position parameters
2192  Double_t phi1 = 360 - TMath::ATan2(x1, y1) * TMath::RadToDeg();
2193  Double_t theta1 = 360 - TMath::ATan2(sqrt(x1 * x1 + y1 * y1), z1) * TMath::RadToDeg();
2194 
2195  Double_t phi11 = TMath::ATan2(y1, x1) * TMath::RadToDeg() ;
2196  Double_t theta11 = TMath::ATan2(z1, sqrt(x1 * x1 + y1 * y1)) * TMath::RadToDeg() ;
2197 
2198  Double_t xpos1 = h1 * TMath::Cos((theta11) * TMath::DegToRad()) * TMath::Cos((phi11) * TMath::DegToRad()) * (-1);
2199  Double_t ypos1 = h1 * TMath::Cos((theta11) * TMath::DegToRad()) * TMath::Sin((phi11) * TMath::DegToRad()) * (-1);
2200  Double_t zpos1 = h1 * TMath::Sin((theta11) * TMath::DegToRad()) * (-1);
2201 
2202  //second box position parameters
2203  Double_t phi2 = 360 - TMath::ATan2(x2, y2) * TMath::RadToDeg();
2204  Double_t theta2 = 360 - TMath::ATan2(sqrt(x2 * x2 + y2 * y2), z2) * TMath::RadToDeg();
2205 
2206  Double_t phi21 = TMath::ATan2(y2, x2) * TMath::RadToDeg() ;
2207  Double_t theta21 = TMath::ATan2(z2, sqrt(x2 * x2 + y2 * y2)) * TMath::RadToDeg() ;
2208 
2209  Double_t xpos2 = h2 * TMath::Cos((theta21) * TMath::DegToRad()) * TMath::Cos((phi21) * TMath::DegToRad()) * (-1);
2210  Double_t ypos2 = h2 * TMath::Cos((theta21) * TMath::DegToRad()) * TMath::Sin((phi21) * TMath::DegToRad()) * (-1);
2211  Double_t zpos2 = h2 * TMath::Sin((theta21) * TMath::DegToRad()) * (-1);
2212 
2213 
2214  //positioning
2215  TGeoTranslation *t0 = new TGeoTranslation(0, 0, 0);
2216  TGeoTranslation *t1 = new TGeoTranslation(0 + xpos1, 0 + ypos1, 0 + (zpos1 - z));
2217  TGeoTranslation *t2 = new TGeoTranslation(0 + xpos2, 0 + ypos2, 0 + (zpos2 + z));
2218  TGeoRotation *r0 = new TGeoRotation((xname + "r0").Data());
2219  TGeoRotation *r1 = new TGeoRotation((xname + "r1").Data());
2220  TGeoRotation *r2 = new TGeoRotation((xname + "r2").Data());
2221 
2222  r1->SetAngles(phi1, theta1, 0);
2223  r2->SetAngles(phi2, theta2, 0);
2224 
2225  TGeoMatrix* m0 = new TGeoCombiTrans(*t0, *r0);
2226  TGeoMatrix* m1 = new TGeoCombiTrans(*t1, *r1);
2227  TGeoMatrix* m2 = new TGeoCombiTrans(*t2, *r2);
2228 
2229  TGeoCompositeShape *CS1 = new TGeoCompositeShape((xname + "CS1").Data(), new TGeoIntersection(T, B1, m0, m1));
2230  TGeoCompositeShape *cs = new TGeoCompositeShape((xname + "CS").Data(), new TGeoIntersection(CS1, B2, m0, m2));
2231  delete t0;
2232  delete t1;
2233  delete t2;
2234  delete r0;
2235  delete r1;
2236  delete r2;
2237  return cs;
2238 }
2239 
2240 ////////////////////////////////////////////////////////////////////////////////
2241 /// Checks whether name2check is in (NameList) list
2242 
2244 {
2245  Bool_t isIN = list[name2check];
2246  return isIN;
2247 }
2248 
2249 ////////////////////////////////////////////////////////////////////////////////
2250 ///NCNAME basic restrictions
2251 ///Replace "$" character with empty character etc.
2252 
2254 {
2255  TString newname = oldname.ReplaceAll("$", "");
2256  newname = newname.ReplaceAll(" ", "_");
2257  // :, @, $, %, &, /, +, ,, ;, whitespace characters or different parenthesis
2258  newname = newname.ReplaceAll(":", "");
2259  newname = newname.ReplaceAll("@", "");
2260  newname = newname.ReplaceAll("%", "");
2261  newname = newname.ReplaceAll("&", "");
2262  newname = newname.ReplaceAll("/", "");
2263  newname = newname.ReplaceAll("+", "");
2264  newname = newname.ReplaceAll(";", "");
2265  newname = newname.ReplaceAll("{", "");
2266  newname = newname.ReplaceAll("}", "");
2267  newname = newname.ReplaceAll("(", "");
2268  newname = newname.ReplaceAll(")", "");
2269  newname = newname.ReplaceAll("[", "");
2270  newname = newname.ReplaceAll("]", "");
2271  newname = newname.ReplaceAll("_refl", "");
2272  //workaround if first letter is digit than replace it to "O" (ou character)
2273  TString fstLet = newname(0, 1);
2274  if (fstLet.IsDigit()) {
2275  newname = "O" + newname(1, newname.Length());
2276  }
2277  return newname;
2278 }
2279 
2280 ////////////////////////////////////////////////////////////////////////////////
2281 /// Important function which is responsible for naming volumes, solids and materials
2282 
2284 {
2285  TString newname = GenName(oldname);
2286  if (newname != oldname) {
2287  if (fgkMaxNameErr > fActNameErr) {
2288  Info("GenName",
2289  "WARNING! Name of the object was changed because it failed to comply with NCNAME xml datatype restrictions.");
2290  } else if ((fgkMaxNameErr == fActNameErr)) {
2291  Info("GenName",
2292  "WARNING! Probably more names are going to be changed to comply with NCNAME xml datatype restriction, but it will not be displayed on the screen.");
2293  }
2294  fActNameErr++;
2295  }
2296  TString nameIter;
2297  Int_t iter = 0;
2298  switch (fgNamingSpeed) {
2299  case kfastButUglySufix:
2300  newname = newname + "0x" + objPointer;
2301  break;
2302  case kelegantButSlow:
2303  //0 means not in the list
2304  iter = fNameList->fLstIter[newname];
2305  if (iter == 0) {
2306  nameIter = "";
2307  } else {
2308  nameIter = TString::Format("0x%i", iter);
2309  }
2310  fNameList->fLstIter[newname]++;
2311  newname = newname + nameIter;
2312  break;
2313  case kwithoutSufixNotUniq:
2314  //no change
2315  break;
2316  }
2317  //store the name (mapped to pointer)
2318  fNameList->fLst[objPointer] = newname;
2319  return newname;
2320 }
2321 
2322 
2323 ////////////////////////////////////////////////////////////////////////////////
2324 /// Method which tests whether solids can be processed
2325 
2327 {
2328  Bool_t isProcessed = kFALSE;
2329  isProcessed = pointer->TestBit(fgkProcBit);
2330  pointer->SetBit(fgkProcBit, kTRUE);
2331  return !(isProcessed);
2332 }
2333 
2334 ////////////////////////////////////////////////////////////////////////////////
2335 /// Method that retrieves axis and unit along which object is divided
2336 
2337 TString TGDMLWrite::GetPattAxis(Int_t divAxis, const char * pattName, TString& unit)
2338 {
2339  TString resaxis;
2340  unit = "cm";
2341  switch (divAxis) {
2342  case 1:
2343  if (strcmp(pattName, "TGeoPatternX") == 0) {
2344  return "kXAxis";
2345  } else if (strcmp(pattName, "TGeoPatternCylR") == 0) {
2346  return "kRho";
2347  }
2348  break;
2349  case 2:
2350  if (strcmp(pattName, "TGeoPatternY") == 0) {
2351  return "kYAxis";
2352  } else if (strcmp(pattName, "TGeoPatternCylPhi") == 0) {
2353  unit = "deg";
2354  return "kPhi";
2355  }
2356  break;
2357  case 3:
2358  if (strcmp(pattName, "TGeoPatternZ") == 0) {
2359  return "kZAxis";
2360  }
2361  break;
2362  default:
2363  return "kUndefined";
2364  break;
2365  }
2366  return "kUndefined";
2367 }
2368 
2369 ////////////////////////////////////////////////////////////////////////////////
2370 /// Check for null parameter to skip the NULL objects
2371 
2373 {
2374  if (parValue == 0.) {
2375  Info("IsNullParam", "ERROR! %s is NULL due to %s = %.12g, Volume based on this shape will be skipped",
2376  objName.Data(),
2377  parName.Data(),
2378  parValue);
2379  return kTRUE;
2380  }
2381  return kFALSE;
2382 }
2383 
2384 ////////////////////////////////////////////////////////////////////////////////
2385 /// Unsetting bits that were changed in gGeoManager during export so that export
2386 /// can be run more times with the same instance of gGeoManager.
2387 
2389 {
2390  TIter next(geoMng->GetListOfVolumes());
2391  TGeoVolume *vol;
2392  while ((vol = (TGeoVolume *)next())) {
2393  ((TObject *)vol->GetShape())->SetBit(fgkProcBit, kFALSE);
2395  }
2396 
2397 }
2398 
2399 
2400 ////////////////////////////////////////////////////////////////////////////////
2401 //
2402 // Backwards compatibility for old DD4hep version (to be removed in the future)
2403 //
2404 ////////////////////////////////////////////////////////////////////////////////
2405 
2406 ////////////////////////////////////////////////////////////////////////////////
2407 // Backwards compatibility (to be removed in the future): Wrapper to only selectively write one branch
2408 void TGDMLWrite::WriteGDMLfile(TGeoManager * geomanager, TGeoVolume* volume, const char* filename, TString option)
2409 {
2410  TList materials, volumes, nodes;
2411  MaterialExtractor extract;
2412  if ( !volume ) {
2413  Info("WriteGDMLfile", "Invalid Volume reference to extract GDML information!");
2414  return;
2415  }
2416  extract(volume);
2417  for(TGeoMaterial* m : extract.materials)
2418  materials.Add(m);
2419  fTopVolumeName = volume->GetName();
2420  fSurfaceList.clear();
2421  fVolumeList.clear();
2422  fNodeList.clear();
2423  WriteGDMLfile(geomanager, volume, &materials, filename, option);
2424  materials.Clear("nodelete");
2425  volumes.Clear("nodelete");
2426  nodes.Clear("nodelete");
2427 }
2428 
2429 
2430 ////////////////////////////////////////////////////////////////////////////////
2431 /// Wrapper of all exporting methods
2432 /// Creates blank GDML file and fills it with gGeoManager structure converted
2433 /// to GDML structure of xml nodes
2434 
2436  TGeoVolume* volume,
2437  TList* materialsLst,
2438  const char* filename,
2439  TString option)
2440 {
2441  //option processing
2442  option.ToLower();
2443  if (option.Contains("g")) {
2445  Info("WriteGDMLfile", "Geant4 compatibility mode set");
2446  } else {
2448  }
2449  if (option.Contains("f")) {
2451  Info("WriteGDMLfile", "Fast naming convention with pointer suffix set");
2452  } else if (option.Contains("n")) {
2454  Info("WriteGDMLfile", "Naming without prefix set - be careful uniqness of name is not ensured");
2455  } else {
2457  Info("WriteGDMLfile", "Potentially slow with incremental suffix naming convention set");
2458  }
2459 
2460  //local variables
2461  Int_t outputLayout = 1;
2462  const char * krootNodeName = "gdml";
2463  const char * knsRefGeneral = "http://www.w3.org/2001/XMLSchema-instance";
2464  const char * knsNameGeneral = "xsi";
2465  const char * knsRefGdml = "http://service-spi.web.cern.ch/service-spi/app/releases/GDML/schema/gdml.xsd";
2466  const char * knsNameGdml = "xsi:noNamespaceSchemaLocation";
2467 
2468  // First create engine
2469  fGdmlE = new TXMLEngine;
2471 
2472  //create blank GDML file
2473  fGdmlFile = fGdmlE->NewDoc();
2474 
2475  //create root node and add it to blank GDML file
2476  XMLNodePointer_t rootNode = fGdmlE->NewChild(nullptr, nullptr, krootNodeName, nullptr);
2477  fGdmlE->DocSetRootElement(fGdmlFile, rootNode);
2478 
2479  //add namespaces to root node
2480  fGdmlE->NewNS(rootNode, knsRefGeneral, knsNameGeneral);
2481  fGdmlE->NewAttr(rootNode, nullptr, knsNameGdml, knsRefGdml);
2482 
2483  //initialize general lists and <define>, <solids>, <structure> nodes
2484  fIsotopeList = new StructLst;
2485  fElementList = new StructLst;
2486 
2487  fNameList = new NameLst;
2488 
2489  fDefineNode = fGdmlE->NewChild(nullptr, nullptr, "define", nullptr);
2490  fSolidsNode = fGdmlE->NewChild(nullptr, nullptr, "solids", nullptr);
2491  fStructureNode = fGdmlE->NewChild(nullptr, nullptr, "structure", nullptr);
2492  //========================
2493 
2494  //initialize list of accepted patterns for divisions (in ExtractVolumes)
2495  fAccPatt = new StructLst;
2496  fAccPatt->fLst["TGeoPatternX"] = kTRUE;
2497  fAccPatt->fLst["TGeoPatternY"] = kTRUE;
2498  fAccPatt->fLst["TGeoPatternZ"] = kTRUE;
2499  fAccPatt->fLst["TGeoPatternCylR"] = kTRUE;
2500  fAccPatt->fLst["TGeoPatternCylPhi"] = kTRUE;
2501  //========================
2502 
2503  //initialize list of rejected shapes for divisions (in ExtractVolumes)
2504  fRejShape = new StructLst;
2505  //this shapes are rejected because, it is not possible to divide trd2
2506  //in Y axis and while only trd2 object is imported from GDML
2507  //it causes a problem when TGeoTrd1 is divided in Y axis
2508  fRejShape->fLst["TGeoTrd1"] = kTRUE;
2509  fRejShape->fLst["TGeoTrd2"] = kTRUE;
2510  //=========================
2511 
2512  //Initialize global counters
2513  fActNameErr = 0;
2514  fVolCnt = 0;
2515  fPhysVolCnt = 0;
2516  fSolCnt = 0;
2517 
2518  //calling main extraction functions (with measuring time)
2519  time_t startT, endT;
2520  startT = time(nullptr);
2521  ExtractMatrices(geomanager->GetListOfGDMLMatrices());
2522  ExtractConstants(geomanager);
2523  fMaterialsNode = ExtractMaterials(materialsLst);
2524 
2525  Info("WriteGDMLfile", "Extracting volumes");
2526  ExtractVolumes(volume);
2527  Info("WriteGDMLfile", "%i solids added", fSolCnt);
2528  Info("WriteGDMLfile", "%i volumes added", fVolCnt);
2529  Info("WriteGDMLfile", "%i physvolumes added", fPhysVolCnt);
2533  endT = time(nullptr);
2534  //<gdml>
2535  fGdmlE->AddChild(rootNode, fDefineNode); // <define>...</define>
2536  fGdmlE->AddChild(rootNode, fMaterialsNode); // <materials>...</materials>
2537  fGdmlE->AddChild(rootNode, fSolidsNode); // <solids>...</solids>
2538  fGdmlE->AddChild(rootNode, fStructureNode); // <structure>...</structure>
2539  fGdmlE->AddChild(rootNode, CreateSetupN(fTopVolumeName.Data())); // <setup>...</setup>
2540  //</gdml>
2541  Double_t tdiffI = difftime(endT, startT);
2542  TString tdiffS = (tdiffI == 0 ? TString("< 1 s") : TString::Format("%.0lf s", tdiffI));
2543  Info("WriteGDMLfile", "Exporting time: %s", tdiffS.Data());
2544  //=========================
2545 
2546  //Saving document
2547  fGdmlE->SaveDoc(fGdmlFile, filename, outputLayout);
2548  Info("WriteGDMLfile", "File %s saved", filename);
2549  //cleaning
2551  //unset processing bits:
2552  UnsetTemporaryBits(geomanager);
2553  delete fGdmlE;
2554 }
2555 
2556 
2557 
2558 
2559 ////////////////////////////////////////////////////////////////////////////////
2560 /// Method extracting geometry structure recursively
2561 
2563 {
2564  XMLNodePointer_t volumeN, childN;
2565  TString volname, matname, solname, pattClsName, nodeVolNameBak;
2566  TGeoPatternFinder *pattFinder = nullptr;
2567  Bool_t isPattern = kFALSE;
2568  const TString fltPrecision = TString::Format("%%.%dg", fFltPrecision);
2569 
2570  //create the name for volume/assembly
2571  if (volume->IsTopVolume()) {
2572  //not needed a special function for generating name
2573  volname = volume->GetName();
2574  fTopVolumeName = volname;
2575  //register name to the pointer
2576  fNameList->fLst[TString::Format("%p", volume)] = volname;
2577  } else {
2578  volname = GenName(volume->GetName(), TString::Format("%p", volume));
2579  }
2580 
2581  //start to create main volume/assembly node
2582  if (volume->IsAssembly()) {
2583  volumeN = StartAssemblyN(volname);
2584  } else {
2585  //get reference material and add solid to <solids> + get name
2586  matname = fNameList->fLst[TString::Format("%p", volume->GetMaterial())];
2587  solname = ExtractSolid(volume->GetShape());
2588  //If solid is not supported or corrupted
2589  if (solname == "-1") {
2590  Info("ExtractVolumes", "ERROR! %s volume was not added, because solid is either not supported or corrupted",
2591  volname.Data());
2592  //set volume as missing volume
2593  fNameList->fLst[TString::Format("%p", volume)] = "missing_" + volname;
2594  return;
2595  }
2596  volumeN = StartVolumeN(volname, solname, matname);
2597 
2598  //divisionvol can't be in assembly
2599  pattFinder = volume->GetFinder();
2600  //if found pattern
2601  if (pattFinder) {
2602  pattClsName = TString::Format("%s", pattFinder->ClassName());
2603  TString shapeCls = TString::Format("%s", volume->GetShape()->ClassName());
2604  //if pattern in accepted pattern list and not in shape rejected list
2605  if ((fAccPatt->fLst[pattClsName] == kTRUE) &&
2606  (fRejShape->fLst[shapeCls] != kTRUE)) {
2607  isPattern = kTRUE;
2608  }
2609  }
2610  }
2611  //get all nodes in volume
2612  TObjArray *nodeLst = volume->GetNodes();
2613  TIter next(nodeLst);
2614  TGeoNode *geoNode;
2615  Int_t nCnt = 0;
2616  //loop through all nodes
2617  while ((geoNode = (TGeoNode *) next())) {
2618  //get volume of current node and if not processed then process it
2619  TGeoVolume * subvol = geoNode->GetVolume();
2620  if (subvol->TestAttBit(fgkProcBitVol) == kFALSE) {
2621  subvol->SetAttBit(fgkProcBitVol);
2622  ExtractVolumes(subvol);
2623  }
2624 
2625  //volume of this node has to exist because it was processed recursively
2626  TString nodevolname = fNameList->fLst[TString::Format("%p", geoNode->GetVolume())];
2627  if (nodevolname.Contains("missing_")) {
2628  continue;
2629  }
2630  if (nCnt == 0) { //save name of the first node for divisionvol
2631  nodeVolNameBak = nodevolname;
2632  }
2633 
2634  if (isPattern == kFALSE) {
2635  //create name for node
2636  TString nodename, posname, rotname;
2637  nodename = GenName(geoNode->GetName(), TString::Format("%p", geoNode));
2638  nodename = nodename + "in" + volname;
2639 
2640  //create name for position and clear rotation
2641  posname = nodename + "pos";
2642  rotname = "";
2643 
2644  //position
2645  const Double_t * pos = geoNode->GetMatrix()->GetTranslation();
2646  Xyz nodPos;
2647  nodPos.x = pos[0];
2648  nodPos.y = pos[1];
2649  nodPos.z = pos[2];
2650  childN = CreatePositionN(posname.Data(), nodPos);
2651  fGdmlE->AddChild(fDefineNode, childN); //adding node to <define> node
2652  //Deal with reflection
2653  XMLNodePointer_t scaleN = nullptr;
2654  Double_t lx, ly, lz;
2655  Double_t xangle = 0;
2656  Double_t zangle = 0;
2657  lx = geoNode->GetMatrix()->GetRotationMatrix()[0];
2658  ly = geoNode->GetMatrix()->GetRotationMatrix()[4];
2659  lz = geoNode->GetMatrix()->GetRotationMatrix()[8];
2660  if (geoNode->GetMatrix()->IsReflection()
2661  && TMath::Abs(lx) == 1 && TMath::Abs(ly) == 1 && TMath::Abs(lz) == 1) {
2662  scaleN = fGdmlE->NewChild(nullptr, nullptr, "scale", nullptr);
2663  fGdmlE->NewAttr(scaleN, nullptr, "name", (nodename + "scl").Data());
2664  fGdmlE->NewAttr(scaleN, nullptr, "x", TString::Format(fltPrecision.Data(), lx));
2665  fGdmlE->NewAttr(scaleN, nullptr, "y", TString::Format(fltPrecision.Data(), ly));
2666  fGdmlE->NewAttr(scaleN, nullptr, "z", TString::Format(fltPrecision.Data(), lz));
2667  //experimentally found out, that rotation should be updated like this
2668  if (lx == -1) {
2669  zangle = 180;
2670  }
2671  if (lz == -1) {
2672  xangle = 180;
2673  }
2674  }
2675 
2676  //rotation
2678  lxyz.x -= xangle;
2679  lxyz.z -= zangle;
2680  if ((lxyz.x != 0.0) || (lxyz.y != 0.0) || (lxyz.z != 0.0)) {
2681  rotname = nodename + "rot";
2682  childN = CreateRotationN(rotname.Data(), lxyz);
2683  fGdmlE->AddChild(fDefineNode, childN); //adding node to <define> node
2684  }
2685 
2686  //create physvol for main volume/assembly node
2687  childN = CreatePhysVolN(geoNode->GetName(), geoNode->GetNumber(), nodevolname.Data(), posname.Data(), rotname.Data(), scaleN);
2688  fGdmlE->AddChild(volumeN, childN);
2689  }
2690  nCnt++;
2691  }
2692  //create only one divisionvol node
2693  if (isPattern && pattFinder) {
2694  //retrieve attributes of division
2695  Int_t ndiv, divaxis;
2696  Double_t offset, width, xlo, xhi;
2697  TString axis, unit;
2698 
2699  ndiv = pattFinder->GetNdiv();
2700  width = pattFinder->GetStep();
2701 
2702  divaxis = pattFinder->GetDivAxis();
2703  volume->GetShape()->GetAxisRange(divaxis, xlo, xhi);
2704 
2705  //compute relative start (not positional)
2706  offset = pattFinder->GetStart() - xlo;
2707  axis = GetPattAxis(divaxis, pattClsName, unit);
2708 
2709  //create division node
2710  childN = CreateDivisionN(offset, width, ndiv, axis.Data(), unit.Data(), nodeVolNameBak.Data());
2711  fGdmlE->AddChild(volumeN, childN);
2712  }
2713 
2714  fVolCnt++;
2715  //add volume/assembly node into the <structure> node
2716  fGdmlE->AddChild(fStructureNode, volumeN);
2717 }
TGDMLWrite::ExtractVolumes
void ExtractVolumes(TGeoNode *topNode)
Method extracting geometry structure recursively.
Definition: TGDMLWrite.cxx:548
TGeoShape.h
TGDMLWrite::fgG4Compatibility
Bool_t fgG4Compatibility
Definition: TGDMLWrite.h:125
c
#define c(i)
Definition: RSha256.hxx:119
TGeoAtt::SetAttBit
void SetAttBit(UInt_t f)
Definition: TGeoAtt.h:71
TGeoPcon.h
vertex
REAL * vertex
Definition: triangle.c:512
TGeoTrd1::GetDz
Double_t GetDz() const
Definition: TGeoTrd1.h:64
TGeoTessellated::GetFacet
const TGeoFacet & GetFacet(int i)
Definition: TGeoTessellated.h:141
TGDMLWrite::fAccPatt
StructLst * fAccPatt
Definition: TGDMLWrite.h:114
TGeoTessellated
Definition: TGeoTessellated.h:105
TGeoTrap::GetTheta
Double_t GetTheta() const
Definition: TGeoArb8.h:126
TGeoCone::GetRmax1
virtual Double_t GetRmax1() const
Definition: TGeoCone.h:80
TGeoIsotope
Definition: TGeoElement.h:108
TGeoXtru::GetY
Double_t GetY(Int_t i) const
Definition: TGeoXtru.h:97
TGDMLMatrix::GetRows
size_t GetRows() const
Definition: TGDMLMatrix.h:44
m
auto * m
Definition: textangle.C:8
TGeoPara::GetY
Double_t GetY() const
Definition: TGeoPara.h:68
TGDMLWrite::fGdmlE
TXMLEngine * fGdmlE
Definition: TGDMLWrite.h:128
TGeoMedium.h
TGDMLWrite::fFltPrecision
UInt_t fFltPrecision
Definition: TGDMLWrite.h:138
TXMLEngine::NewAttr
XMLAttrPointer_t NewAttr(XMLNodePointer_t xmlnode, XMLNsPointer_t, const char *name, const char *value)
creates new attribute for xmlnode, namespaces are not supported for attributes
Definition: TXMLEngine.cxx:583
TGDMLWrite::CreatePolyhedraN
XMLNodePointer_t CreatePolyhedraN(TGeoPgon *geoShape)
Creates "polyhedra" node for GDML.
Definition: TGDMLWrite.cxx:1470
TGDMLWrite::CreateMixtureN
XMLNodePointer_t CreateMixtureN(TGeoMixture *mixture, XMLNodePointer_t materials, TString mname)
Creates "material" node for GDML with references to other sub elements.
Definition: TGDMLWrite.cxx:837
TGeoMaterial::GetDensity
virtual Double_t GetDensity() const
Definition: TGeoMaterial.h:108
TGeoElement::A
Double_t A() const
Definition: TGeoElement.h:76
TGDMLWrite::CreateFractionN
XMLNodePointer_t CreateFractionN(Double_t percentage, const char *refName)
Creates "fraction" node for GDML.
Definition: TGDMLWrite.cxx:737
TGeoPara
Definition: TGeoPara.h:17
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:91
TGeoTrap::GetBl1
Double_t GetBl1() const
Definition: TGeoArb8.h:129
TGeoElement::GetRelativeAbundance
Double_t GetRelativeAbundance(Int_t i) const
Return relative abundance of i-th isotope in this element.
Definition: TGeoElement.cxx:315
TObject::TestBit
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
TGDMLWrite::SetG4Compatibility
void SetG4Compatibility(Bool_t G4Compatible)
Definition: TGDMLWrite.h:85
TGDMLWrite::CreateArb8N
XMLNodePointer_t CreateArb8N(TGeoArb8 *geoShape)
Creates "arb8" node for GDML.
Definition: TGDMLWrite.cxx:1022
TMath::ATan2
Double_t ATan2(Double_t y, Double_t x)
Definition: TMath.h:668
TGDMLWrite::CreateZplaneN
XMLNodePointer_t CreateZplaneN(Double_t z, Double_t rmin, Double_t rmax)
Creates "zplane" node for GDML.
Definition: TGDMLWrite.cxx:1377
TGDMLWrite::CreateSetupN
XMLNodePointer_t CreateSetupN(const char *topVolName, const char *name="default", const char *version="1.0")
Creates "setup" node for GDML.
Definition: TGDMLWrite.cxx:1934
TGeoVolume::GetShape
TGeoShape * GetShape() const
Definition: TGeoVolume.h:188
TObjArray
Definition: TObjArray.h:37
TGeoElement::Z
Int_t Z() const
Definition: TGeoElement.h:73
TGDMLWrite::CreateParaN
XMLNodePointer_t CreateParaN(TGeoPara *geoShape)
Creates "para" node for GDML.
Definition: TGDMLWrite.cxx:1109
TGeoPatternFinder::GetNdiv
Int_t GetNdiv() const
Definition: TGeoPatternFinder.h:86
TGeoVolume::GetFinder
TGeoPatternFinder * GetFinder() const
Definition: TGeoVolume.h:175
TGeoPara::GetPhi
Double_t GetPhi() const
Definition: TGeoPara.h:72
TGDMLWrite::CreateHypeN
XMLNodePointer_t CreateHypeN(TGeoHype *geoShape)
Creates "hype" node for GDML.
Definition: TGDMLWrite.cxx:1516
TGDMLWrite::CreateMatrixN
XMLNodePointer_t CreateMatrixN(TGDMLMatrix const *matrix)
Creates "matrix" kind of node for GDML.
Definition: TGDMLWrite.cxx:1900
TGeoBoolNode::EGeoBoolType
EGeoBoolType
Definition: TGeoBoolNode.h:28
TGeoTessellated::GetVertex
const Vertex_t & GetVertex(int i)
Definition: TGeoTessellated.h:142
TMath::RadToDeg
constexpr Double_t RadToDeg()
Conversion from radian to degree:
Definition: TMath.h:79
TGeoCombiTrans
Definition: TGeoMatrix.h:291
TGDMLWrite::fVolumeList
VolList fVolumeList
Definition: TGDMLWrite.h:117
TXMLEngine::NewChild
XMLNodePointer_t NewChild(XMLNodePointer_t parent, XMLNsPointer_t ns, const char *name, const char *content=nullptr)
create new child element for parent node
Definition: TXMLEngine.cxx:712
TGeoHype::GetStOut
Double_t GetStOut() const
Definition: TGeoHype.h:75
TGeoManager::GetListOfVolumes
TObjArray * GetListOfVolumes() const
Definition: TGeoManager.h:493
TGeoRotation::SetAngles
void SetAngles(Double_t phi, Double_t theta, Double_t psi)
Set matrix elements according to Euler angles.
Definition: TGeoMatrix.cxx:1238
TGDMLWrite::fActNameErr
UInt_t fActNameErr
Definition: TGDMLWrite.h:136
TGeoPara::GetTheta
Double_t GetTheta() const
Definition: TGeoPara.h:71
TGDMLWrite::CreateDN
XMLNodePointer_t CreateDN(Double_t density, const char *unit="g/cm3")
Creates "D" density node for GDML.
Definition: TGDMLWrite.cxx:725
TGeoBoolNode::GetLeftShape
TGeoShape * GetLeftShape() const
Definition: TGeoBoolNode.h:83
TMath::Cos
Double_t Cos(Double_t)
Definition: TMath.h:630
floor
double floor(double)
TGeoSphere::GetRmin
virtual Double_t GetRmin() const
Definition: TGeoSphere.h:73
TGeoTorus
Definition: TGeoTorus.h:17
TGeoHype
Definition: TGeoHype.h:17
TString::Data
const char * Data() const
Definition: TString.h:369
TGDMLWrite::fSolCnt
UInt_t fSolCnt
Definition: TGDMLWrite.h:137
TGeoCtub
Definition: TGeoTube.h:168
TGeoCompositeShape::GetBoolNode
TGeoBoolNode * GetBoolNode() const
Definition: TGeoCompositeShape.h:65
TGDMLWrite::fgGDMLWrite
static TGDMLWrite * fgGDMLWrite
Definition: TGDMLWrite.h:123
TGDMLWrite::CreateTessellatedN
XMLNodePointer_t CreateTessellatedN(TGeoTessellated *geoShape)
Creates "tessellated" (tessellated shape) node for GDML.
Definition: TGDMLWrite.cxx:1651
TXMLEngine::SaveDoc
void SaveDoc(XMLDocPointer_t xmldoc, const char *filename, Int_t layout=1)
store document content to file if layout<=0, no any spaces or newlines will be placed between xmlnode...
Definition: TXMLEngine.cxx:1303
TGeoXtru
Definition: TGeoXtru.h:22
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
TGeoIsotope::GetZ
Int_t GetZ() const
Definition: TGeoElement.h:120
TNamed::GetTitle
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:54
TGDMLWrite::CreateMaterialN
XMLNodePointer_t CreateMaterialN(TGeoMaterial *material, TString mname)
Creates "material" node for GDML.
Definition: TGDMLWrite.cxx:907
TGDMLWrite::fRejShape
StructLst * fRejShape
Definition: TGDMLWrite.h:115
TGDMLWrite::ExtractMatrices
void ExtractMatrices(TObjArray *matrices)
Method exporting GDML matrices.
Definition: TGDMLWrite.cxx:400
TXMLEngine::AddChild
void AddChild(XMLNodePointer_t parent, XMLNodePointer_t child)
add child element to xmlnode
Definition: TXMLEngine.cxx:796
r
ROOT::R::TRInterface & r
Definition: Object.C:4
TGeoTrd1::GetDx2
Double_t GetDx2() const
Definition: TGeoTrd1.h:62
TGDMLWrite::fMaterialsNode
XMLNodePointer_t fMaterialsNode
Definition: TGDMLWrite.h:131
TObject::Info
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:864
TGeoAtt::TestAttBit
Bool_t TestAttBit(UInt_t f) const
Definition: TGeoAtt.h:74
TGeoScaledShape::GetShape
TGeoShape * GetShape() const
Definition: TGeoScaledShape.h:54
TGeoMaterial::IsMixture
virtual Bool_t IsMixture() const
Definition: TGeoMaterial.h:129
TGeoEltu::GetB
virtual Double_t GetB() const
Definition: TGeoEltu.h:50
TGeoTrap::GetTl2
Double_t GetTl2() const
Definition: TGeoArb8.h:134
TGDMLWrite.h
TGDMLWrite::WriteGDMLfile
void WriteGDMLfile(TGeoManager *geomanager, const char *filename="test.gdml", TString option="")
Definition: TGDMLWrite.cxx:235
TMath::Sqrt
Double_t Sqrt(Double_t x)
Definition: TMath.h:680
TGeoVolume::GetMaterial
TGeoMaterial * GetMaterial() const
Definition: TGeoVolume.h:172
TGeoIsotope::GetN
Int_t GetN() const
Definition: TGeoElement.h:121
TGeoNode::GetVolume
TGeoVolume * GetVolume() const
Definition: TGeoNode.h:97
TGeoScaledShape
Definition: TGeoScaledShape.h:20
TGDMLWrite::fDefineNode
XMLNodePointer_t fDefineNode
Definition: TGDMLWrite.h:130
TGDMLWrite::IsNullParam
Bool_t IsNullParam(Double_t parValue, TString parName, TString objName)
Check for null parameter to skip the NULL objects.
Definition: TGDMLWrite.cxx:2372
TGeoTorus::GetR
Double_t GetR() const
Definition: TGeoTorus.h:75
TMath::DegToRad
constexpr Double_t DegToRad()
Conversion from degree to radian:
Definition: TMath.h:87
TGDMLWrite::GetPattAxis
TString GetPattAxis(Int_t divAxis, const char *pattName, TString &unit)
Method that retrieves axis and unit along which object is divided.
Definition: TGDMLWrite.cxx:2337
TGeoEltu::GetA
virtual Double_t GetA() const
Definition: TGeoEltu.h:49
TGeoArb8
Definition: TGeoArb8.h:17
TGDMLWrite::fIsotopeList
StructLst * fIsotopeList
Definition: TGDMLWrite.h:112
width
include TDocParser_001 C image html pict1_TDocParser_001 png width
Definition: TDocParser.cxx:121
TGDMLWrite::StartVolumeN
XMLNodePointer_t StartVolumeN(const char *name, const char *solid, const char *material)
Creates "volume" node for GDML.
Definition: TGDMLWrite.cxx:1947
TGDMLWrite::CreateBorderSurfaceN
XMLNodePointer_t CreateBorderSurfaceN(TGeoBorderSurface *geoSurf)
Creates "bordersurface" node for GDML.
Definition: TGDMLWrite.cxx:1854
TGDMLWrite::CreateEllipsoidN
XMLNodePointer_t CreateEllipsoidN(TGeoCompositeShape *geoShape, TString elName)
Creates "ellipsoid" node for GDML this is a special case, because ellipsoid is not defined in ROOT so...
Definition: TGDMLWrite.cxx:1585
TObject::Fatal
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:918
TGDMLWrite::fPhysVolCnt
Int_t fPhysVolCnt
Definition: TGDMLWrite.h:135
Int_t
int Int_t
Definition: RtypesCore.h:45
TGeoVolume.h
TGDMLWrite
Definition: TGDMLWrite.h:56
TGeoArb8::GetDz
Double_t GetDz() const
Definition: TGeoArb8.h:71
TGeoManager::GetListOfGDMLMatrices
TObjArray * GetListOfGDMLMatrices() const
Definition: TGeoManager.h:499
TGeoPcon::GetZ
Double_t * GetZ() const
Definition: TGeoPcon.h:89
TGeoBBox::GetDZ
virtual Double_t GetDZ() const
Definition: TGeoBBox.h:78
TGeoTubeSeg::GetPhi1
Double_t GetPhi1() const
Definition: TGeoTube.h:148
TGeoBoolNode::GetBooleanOperator
virtual EGeoBoolType GetBooleanOperator() const =0
TGeoBorderSurface::GetNode2
const TGeoNode * GetNode2() const
Definition: TGeoOpticalSurface.h:207
TString::Contains
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:624
TGeoTrap::GetAlpha2
Double_t GetAlpha2() const
Definition: TGeoArb8.h:135
TGDMLWrite::CreateOpticalSurfaceN
XMLNodePointer_t CreateOpticalSurfaceN(TGeoOpticalSurface *geoSurf)
Creates "opticalsurface" node for GDML.
Definition: TGDMLWrite.cxx:1815
TString::Length
Ssiz_t Length() const
Definition: TString.h:410
operator()
TRObject operator()(const T1 &t1) const
Definition: TRFunctionImport__oprtr.h:14
TGeoEltu.h
TGeoConeSeg::GetPhi1
Double_t GetPhi1() const
Definition: TGeoCone.h:160
TGeoElement::HasIsotopes
Bool_t HasIsotopes() const
Definition: TGeoElement.h:85
TGeoPara::GetAlpha
Double_t GetAlpha() const
Definition: TGeoPara.h:70
TGeoOpticalSurface::GetType
ESurfaceType GetType() const
Definition: TGeoOpticalSurface.h:127
TGeoCone
Definition: TGeoCone.h:17
TGDMLWrite::CreateElConeN
XMLNodePointer_t CreateElConeN(TGeoScaledShape *geoShape)
Creates "elcone" (elliptical cone) node for GDML this is a special case, because elliptical cone is n...
Definition: TGDMLWrite.cxx:1624
TGeoTubeSeg
Definition: TGeoTube.h:88
TGDMLWrite::NameListI
std::map< TString, Int_t > NameListI
Definition: TGDMLWrite.h:101
TMath::Abs
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
TGeoEltu
Definition: TGeoEltu.h:17
TGDMLWrite::NameLst::fLstIter
NameListI fLstIter
Definition: TGDMLWrite.h:108
TGeoElement::GetIsotope
TGeoIsotope * GetIsotope(Int_t i) const
Return i-th isotope in the element.
Definition: TGeoElement.cxx:304
TString::Format
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition: TString.cxx:2311
TGeoTrd2::GetDx2
Double_t GetDx2() const
Definition: TGeoTrd2.h:63
TGeoShape::GetAxisRange
virtual Double_t GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi) const =0
TString
Definition: TString.h:136
TGDMLWrite::CanProcess
Bool_t CanProcess(TObject *pointer)
Method which tests whether solids can be processed.
Definition: TGDMLWrite.cxx:2326
TGeoBBox.h
TGeoCone.h
TGeoMixture::GetElement
virtual TGeoElement * GetElement(Int_t i=0) const
Retrieve the pointer to the element corresponding to component I.
Definition: TGeoMaterial.cxx:988
TGeoMixture::GetWmixt
Double_t * GetWmixt() const
Definition: TGeoMaterial.h:196
TGeoSkinSurface::GetVolume
const TGeoVolume * GetVolume() const
Definition: TGeoOpticalSurface.h:175
TGeoNode::GetMatrix
virtual TGeoMatrix * GetMatrix() const =0
TGeoTranslation
Definition: TGeoMatrix.h:121
TGeoBoolNode::kGeoUnion
@ kGeoUnion
Definition: TGeoBoolNode.h:29
TGeoMixture
Definition: TGeoMaterial.h:155
v
@ v
Definition: rootcling_impl.cxx:3635
TGeoNode
Definition: TGeoNode.h:39
TGeoTessellated::GetNfacets
int GetNfacets() const
Definition: TGeoTessellated.h:135
TGDMLWrite::kwithoutSufixNotUniq
@ kwithoutSufixNotUniq
Definition: TGDMLWrite.h:81
b
#define b(i)
Definition: RSha256.hxx:118
TGDMLWrite::CreatePositionN
XMLNodePointer_t CreatePositionN(const char *name, Xyz position, const char *type="position", const char *unit="cm")
Creates "position" kind of node for GDML.
Definition: TGDMLWrite.cxx:1870
TGeoTrd2::GetDz
Double_t GetDz() const
Definition: TGeoTrd2.h:66
h1
TH1F * h1
Definition: legend1.C:5
TGDMLWrite::fVolCnt
Int_t fVolCnt
Definition: TGDMLWrite.h:134
TGeoMaterial
Definition: TGeoMaterial.h:34
TGeoPatternFinder
Definition: TGeoPatternFinder.h:31
TGeoIsotope::GetA
Double_t GetA() const
Definition: TGeoElement.h:122
bool
TGeoConeSeg::GetPhi2
Double_t GetPhi2() const
Definition: TGeoCone.h:161
TString::ReplaceAll
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:692
TGeoCompositeShape
Definition: TGeoCompositeShape.h:27
TGeoTrap::GetAlpha1
Double_t GetAlpha1() const
Definition: TGeoArb8.h:131
TGDMLWrite::fSolidsNode
XMLNodePointer_t fSolidsNode
Definition: TGDMLWrite.h:132
TGDMLWrite::TGDMLWrite
TGDMLWrite()
Default constructor.
Definition: TGDMLWrite.cxx:185
TGDMLWrite::CreateXtrusionN
XMLNodePointer_t CreateXtrusionN(TGeoXtru *geoShape)
Creates "xtru" node for GDML.
Definition: TGDMLWrite.cxx:1542
TGeoTrd2.h
TGeoTrap::GetH1
Double_t GetH1() const
Definition: TGeoArb8.h:128
TGDMLWrite::GetXYZangles
Xyz GetXYZangles(const Double_t *rotationMatrix)
Retrieves X Y Z angles from rotation matrix.
Definition: TGDMLWrite.cxx:2139
TXMLEngine::NewNS
XMLNsPointer_t NewNS(XMLNodePointer_t xmlnode, const char *reference, const char *name=nullptr)
create namespace attribute for xmlnode.
Definition: TXMLEngine.cxx:738
TGDMLWrite::StartAssemblyN
XMLNodePointer_t StartAssemblyN(const char *name)
Creates "assembly" node for GDML.
Definition: TGDMLWrite.cxx:1967
x1
static const double x1[5]
Definition: RooGaussKronrodIntegrator1D.cxx:346
TGeoScale::GetScale
virtual const Double_t * GetScale() const
Definition: TGeoMatrix.h:279
TGeoElement::GetNisotopes
Int_t GetNisotopes() const
Definition: TGeoElement.h:78
TGDMLWrite::ExtractConstants
void ExtractConstants(TGeoManager *geom)
Method exporting GDML matrices.
Definition: TGDMLWrite.cxx:415
TGDMLWrite::CreateTwistedTrapN
XMLNodePointer_t CreateTwistedTrapN(TGeoGtra *geoShape)
Creates "twistedtrap" node for GDML.
Definition: TGDMLWrite.cxx:1176
TGeoCone::GetRmin2
virtual Double_t GetRmin2() const
Definition: TGeoCone.h:81
TGeoTrap::GetBl2
Double_t GetBl2() const
Definition: TGeoArb8.h:133
TGeoMatrix::GetRotationMatrix
virtual const Double_t * GetRotationMatrix() const =0
TGDMLWrite::Xyz::z
Double_t z
Definition: TGDMLWrite.h:93
TGeoTube::GetDz
virtual Double_t GetDz() const
Definition: TGeoTube.h:74
TGeoParaboloid.h
TGDMLWrite::fNodeList
NodeList fNodeList
Definition: TGDMLWrite.h:118
TObject::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:359
TGeoParaboloid::GetDz
Double_t GetDz() const
Definition: TGeoParaboloid.h:59
TGDMLWrite::CreateTorusN
XMLNodePointer_t CreateTorusN(TGeoTorus *geoShape)
Creates "torus" node for GDML.
Definition: TGDMLWrite.cxx:1445
TGDMLWrite::kfastButUglySufix
@ kfastButUglySufix
Definition: TGDMLWrite.h:82
TGeoTorus::GetPhi1
Double_t GetPhi1() const
Definition: TGeoTorus.h:78
TGeoSphere::GetRmax
virtual Double_t GetRmax() const
Definition: TGeoSphere.h:74
TGDMLWrite::CreateSphereN
XMLNodePointer_t CreateSphereN(TGeoSphere *geoShape)
Creates "sphere" node for GDML.
Definition: TGDMLWrite.cxx:997
TGeoManager::GetListOfMaterials
TList * GetListOfMaterials() const
Definition: TGeoManager.h:491
TGDMLWrite::CreateParaboloidN
XMLNodePointer_t CreateParaboloidN(TGeoParaboloid *geoShape)
Creates "paraboloid" node for GDML.
Definition: TGDMLWrite.cxx:976
TGeoArb8.h
TGeant4Unit::m2
static constexpr double m2
Definition: TGeant4SystemOfUnits.h:129
TGeoBBox::GetDX
virtual Double_t GetDX() const
Definition: TGeoBBox.h:76
TGeoXtru::GetScale
Double_t GetScale(Int_t i) const
Definition: TGeoXtru.h:100
TGeoCone::GetRmin1
virtual Double_t GetRmin1() const
Definition: TGeoCone.h:79
TGeoPcon::GetPhi1
Double_t GetPhi1() const
Definition: TGeoPcon.h:81
TGDMLWrite::StructLst
Definition: TGDMLWrite.h:103
TGeoCone::GetDz
virtual Double_t GetDz() const
Definition: TGeoCone.h:74
TGeoBoolNode::GetLeftMatrix
TGeoMatrix * GetLeftMatrix() const
Definition: TGeoBoolNode.h:81
TXMLEngine.h
TGeoShape
Definition: TGeoShape.h:25
TGeoScaledShape::GetScale
TGeoScale * GetScale() const
Definition: TGeoScaledShape.h:55
TGeoCone::GetRmax2
virtual Double_t GetRmax2() const
Definition: TGeoCone.h:82
TGeoSkinSurface::GetSurface
const TGeoOpticalSurface * GetSurface() const
Definition: TGeoOpticalSurface.h:174
TGDMLWrite::CreateTrapN
XMLNodePointer_t CreateTrapN(TGeoTrap *geoShape)
Creates "trap" node for GDML.
Definition: TGDMLWrite.cxx:1130
TGeoMaterial::GetProperties
const TList & GetProperties() const
Definition: TGeoMaterial.h:100
TGeoOpticalSurface::ModelToString
static const char * ModelToString(ESurfaceModel model)
Definition: TGeoOpticalSurface.cxx:109
TGDMLWrite::CreateIsotopN
XMLNodePointer_t CreateIsotopN(TGeoIsotope *isotope, const char *name)
Creates "isotope" node for GDML.
Definition: TGDMLWrite.cxx:760
TGDMLWrite::Xyz::x
Double_t x
Definition: TGDMLWrite.h:91
TGDMLWrite::~TGDMLWrite
virtual ~TGDMLWrite()
Destructor.
Definition: TGDMLWrite.cxx:214
TGeoXtru::GetNvert
Int_t GetNvert() const
Definition: TGeoXtru.h:95
TGDMLWrite::fElementList
StructLst * fElementList
Definition: TGDMLWrite.h:113
TGeoOpticalSurface::GetFinish
ESurfaceFinish GetFinish() const
Definition: TGeoOpticalSurface.h:129
TGeoElement
Definition: TGeoElement.h:36
TGDMLWrite::CreateConstantN
XMLNodePointer_t CreateConstantN(const char *name, Double_t value)
Creates "constant" kind of node for GDML.
Definition: TGDMLWrite.cxx:1922
TGeoTrd1.h
TGDMLWrite::fgkProcBitVol
static const UInt_t fgkProcBitVol
Definition: TGDMLWrite.h:141
TGDMLWrite::fgkMaxNameErr
static const UInt_t fgkMaxNameErr
Definition: TGDMLWrite.h:142
TGDMLWrite::CreateCommonBoolN
XMLNodePointer_t CreateCommonBoolN(TGeoCompositeShape *geoShape)
Creates common part of union intersection and subtraction nodes.
Definition: TGDMLWrite.cxx:1689
TObject::SetBit
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:696
TXMLEngine
Definition: TXMLEngine.h:26
TGeoSphere
Definition: TGeoSphere.h:17
TGDMLWrite::fTopVolumeName
TString fTopVolumeName
Definition: TGDMLWrite.h:127
TGeoElement.h
TGeoMatrix::IsReflection
Bool_t IsReflection() const
Definition: TGeoMatrix.h:69
surfaces
Definition: surfaces.py:1
TGeoOpticalSurface.h
TGeoXtru::GetNz
Int_t GetNz() const
Definition: TGeoXtru.h:94
TGeoVolume::GetNodes
TObjArray * GetNodes()
Definition: TGeoVolume.h:167
TObjArray::GetEntriesFast
Int_t GetEntriesFast() const
Definition: TObjArray.h:64
TGeoMaterial::GetZ
virtual Double_t GetZ() const
Definition: TGeoMaterial.h:106
a
auto * a
Definition: textangle.C:12
TNamed
Definition: TNamed.h:29
TGeoMaterial.h
TGeoBoolNode::kGeoSubtraction
@ kGeoSubtraction
Definition: TGeoBoolNode.h:31
TGeoRotation
Definition: TGeoMatrix.h:174
TGeoPatternFinder::GetStep
Double_t GetStep() const
Definition: TGeoPatternFinder.h:90
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:92
TGDMLWrite::fGdmlFile
XMLDocPointer_t fGdmlFile
Definition: TGDMLWrite.h:126
TGDMLWrite::StructLst::fLst
NameList fLst
Definition: TGDMLWrite.h:104
TGeoHype.h
TGDMLWrite::NameLst
Definition: TGDMLWrite.h:106
TGDMLWrite::UnsetTemporaryBits
void UnsetTemporaryBits(TGeoManager *geoMng)
Unsetting bits that were changed in gGeoManager during export so that export can be run more times wi...
Definition: TGDMLWrite.cxx:2388
TGeoBoolNode::GetRightMatrix
TGeoMatrix * GetRightMatrix() const
Definition: TGeoBoolNode.h:82
TGeoPcon::GetNz
Int_t GetNz() const
Definition: TGeoPcon.h:83
TGDMLWrite::CreateTubeN
XMLNodePointer_t CreateTubeN(TGeoTubeSeg *geoShape)
Creates "tube" node for GDML from object TGeoTubeSeg.
Definition: TGDMLWrite.cxx:1282
TGDMLWrite::NameList
std::map< TString, Bool_t > NameList
Definition: TGDMLWrite.h:99
TGeoNode::GetNumber
Int_t GetNumber() const
Definition: TGeoNode.h:95
TGeoPcon::GetRmin
Double_t * GetRmin() const
Definition: TGeoPcon.h:85
TGeoTube
Definition: TGeoTube.h:17
TMath::Sin
Double_t Sin(Double_t)
Definition: TMath.h:626
TGeoPara::GetZ
Double_t GetZ() const
Definition: TGeoPara.h:69
TGeoPgon
Definition: TGeoPgon.h:20
TGeoShape::GetName
virtual const char * GetName() const
Get the shape name.
Definition: TGeoShape.cxx:248
TGeoPcon
Definition: TGeoPcon.h:17
TGeoManager::GetListOfSkinSurfaces
TObjArray * GetListOfSkinSurfaces() const
Definition: TGeoManager.h:501
XMLNodePointer_t
void * XMLNodePointer_t
Definition: TXMLEngine.h:17
TGeoBBox::GetOrigin
virtual const Double_t * GetOrigin() const
Definition: TGeoBBox.h:79
TGeoCtub::GetNhigh
const Double_t * GetNhigh() const
Definition: TGeoTube.h:208
TGeoBBox
Definition: TGeoBBox.h:17
sqrt
double sqrt(double)
TGeoXtru.h
TGeoCompositeShape.h
TGeoGtra::GetTwistAngle
Double_t GetTwistAngle() const
Definition: TGeoArb8.h:168
TGDMLWrite::IsInList
Bool_t IsInList(NameList list, TString name2check)
Checks whether name2check is in (NameList) list.
Definition: TGDMLWrite.cxx:2243
TGDMLWrite::ExtractMaterials
XMLNodePointer_t ExtractMaterials(TList *materialsLst)
Method exporting materials.
Definition: TGDMLWrite.cxx:498
TGeoVolume::IsAssembly
virtual Bool_t IsAssembly() const
Returns true if the volume is an assembly or a scaled assembly.
Definition: TGeoVolume.cxx:1705
TGeoSphere::GetPhi2
Double_t GetPhi2() const
Definition: TGeoSphere.h:78
TGeant4Unit::rad
static constexpr double rad
Definition: TGeant4SystemOfUnits.h:148
TGDMLWrite::CreateFakeCtub
TGeoCompositeShape * CreateFakeCtub(TGeoCtub *geoShape)
Method creating cutTube as an intersection of tube and two boxes.
Definition: TGDMLWrite.cxx:2165
TGeoOpticalSurface::GetValue
Double_t GetValue() const
Definition: TGeoOpticalSurface.h:131
TGDMLWrite::CreateTrdN
XMLNodePointer_t CreateTrdN(TGeoTrd1 *geoShape)
Creates "trd" node for GDML from object TGeoTrd1.
Definition: TGDMLWrite.cxx:1236
TGeoXtru::GetXOffset
Double_t GetXOffset(Int_t i) const
Definition: TGeoXtru.h:98
TGeoOpticalSurface::GetProperties
const TList & GetProperties() const
Definition: TGeoOpticalSurface.h:123
TGDMLWrite::GenName
TString GenName(TString oldname)
NCNAME basic restrictions Replace "$" character with empty character etc.
Definition: TGDMLWrite.cxx:2253
TObject::Warning
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:876
TGeoPgon::GetNedges
Int_t GetNedges() const
Definition: TGeoPgon.h:89
TGeoTrap::GetTl1
Double_t GetTl1() const
Definition: TGeoArb8.h:130
TString::IsDigit
Bool_t IsDigit() const
Returns true if all characters in string are digits (0-9) or white spaces, i.e.
Definition: TString.cxx:1763
TGDMLWrite::CreatePropertyN
XMLNodePointer_t CreatePropertyN(TNamed const &property)
Creates "property" node for GDML.
Definition: TGDMLWrite.cxx:749
TGeoGtra
Definition: TGeoArb8.h:145
TGeoMatrix.h
TGeoBorderSurface::GetNode1
const TGeoNode * GetNode1() const
Definition: TGeoOpticalSurface.h:206
TGeoPcon::GetRmax
Double_t * GetRmax() const
Definition: TGeoPcon.h:87
TGDMLMatrix
Definition: TGDMLMatrix.h:34
TGeoArb8::GetVertices
Double_t * GetVertices()
Definition: TGeoArb8.h:75
TGeoBorderSurface::GetSurface
const TGeoOpticalSurface * GetSurface() const
Definition: TGeoOpticalSurface.h:205
TGeoFacet::GetNvert
int GetNvert() const
Definition: TGeoTessellated.h:92
TGDMLWrite::CreateConeN
XMLNodePointer_t CreateConeN(TGeoConeSeg *geoShape)
Creates "cone" node for GDML from TGeoConeSeg object.
Definition: TGDMLWrite.cxx:1057
TGeoManager::GetListOfBorderSurfaces
TObjArray * GetListOfBorderSurfaces() const
Definition: TGeoManager.h:502
TGeoTrap::GetPhi
Double_t GetPhi() const
Definition: TGeoArb8.h:127
TGeoIntersection
Definition: TGeoBoolNode.h:144
TXMLEngine::NewDoc
XMLDocPointer_t NewDoc(const char *version="1.0")
creates new xml document with provided version
Definition: TXMLEngine.cxx:1252
TGeoManager.h
TGeoXtru::GetYOffset
Double_t GetYOffset(Int_t i) const
Definition: TGeoXtru.h:99
TGeoScaledShape.h
TGDMLWrite::CreateEltubeN
XMLNodePointer_t CreateEltubeN(TGeoEltu *geoShape)
Creates "eltube" node for GDML.
Definition: TGDMLWrite.cxx:1492
TMath::ACos
Double_t ACos(Double_t)
Definition: TMath.h:657
TGeoParaboloid
Definition: TGeoParaboloid.h:17
TGDMLWrite::NameLst::fLst
NameListS fLst
Definition: TGDMLWrite.h:107
TGeoMixture::GetNelements
virtual Int_t GetNelements() const
Definition: TGeoMaterial.h:193
TGeoPatternFinder::GetStart
Double_t GetStart() const
Definition: TGeoPatternFinder.h:89
TGeoTrd1
Definition: TGeoTrd1.h:17
TGeoBoolNode::kGeoIntersection
@ kGeoIntersection
Definition: TGeoBoolNode.h:30
Double_t
double Double_t
Definition: RtypesCore.h:59
TGeoSphere::GetTheta2
Double_t GetTheta2() const
Definition: TGeoSphere.h:76
TGeoXtru::GetZ
Double_t * GetZ() const
Definition: TGeoXtru.h:101
TGeoMatrix
Definition: TGeoMatrix.h:40
TGeoBorderSurface
Definition: TGeoOpticalSurface.h:191
TGDMLWrite::ExtractBorderSurfaces
void ExtractBorderSurfaces(TObjArray *surfaces)
Method exporting border surfaces.
Definition: TGDMLWrite.cxx:466
TGDMLWrite::CreateAtomN
XMLNodePointer_t CreateAtomN(Double_t atom, const char *unit="g/mole")
Creates "atom" node for GDML.
Definition: TGDMLWrite.cxx:713
TGeoArb8::IsTwisted
Bool_t IsTwisted() const
Definition: TGeoArb8.h:81
TGDMLWrite::fStructureNode
XMLNodePointer_t fStructureNode
Definition: TGDMLWrite.h:133
TGeoTorus::GetRmax
Double_t GetRmax() const
Definition: TGeoTorus.h:77
TGeoBBox::GetDY
virtual Double_t GetDY() const
Definition: TGeoBBox.h:77
t1
auto * t1
Definition: textangle.C:20
TGeoTessellated::GetNvertices
int GetNvertices() const
Definition: TGeoTessellated.h:137
TCollection::GetSize
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
TGeoManager::GetListOfOpticalSurfaces
TObjArray * GetListOfOpticalSurfaces() const
Definition: TGeoManager.h:500
TGeoOpticalSurface::GetModel
ESurfaceModel GetModel() const
Definition: TGeoOpticalSurface.h:128
TGeoTrd2::GetDx1
Double_t GetDx1() const
Definition: TGeoTrd2.h:62
TXMLEngine::SetSkipComments
void SetSkipComments(Bool_t on=kTRUE)
Definition: TXMLEngine.h:48
TGeoTube::GetRmin
virtual Double_t GetRmin() const
Definition: TGeoTube.h:72
TGeoSphere::GetTheta1
Double_t GetTheta1() const
Definition: TGeoSphere.h:75
TGDMLWrite::CreatePhysVolN
XMLNodePointer_t CreatePhysVolN(const char *name, Int_t copyno, const char *volref, const char *posref, const char *rotref, XMLNodePointer_t scaleN)
Creates "physvol" node for GDML.
Definition: TGDMLWrite.cxx:1978
TGeoTorus::GetDphi
Double_t GetDphi() const
Definition: TGeoTorus.h:79
TList::Add
virtual void Add(TObject *obj)
Definition: TList.h:87
TObject
Definition: TObject.h:37
TGeoTrd2::GetDy2
Double_t GetDy2() const
Definition: TGeoTrd2.h:65
TGDMLMatrix::GetCols
size_t GetCols() const
Definition: TGDMLMatrix.h:45
TXMLEngine::DocSetRootElement
void DocSetRootElement(XMLDocPointer_t xmldoc, XMLNodePointer_t xmlnode)
set main (root) node for document
Definition: TXMLEngine.cxx:1323
TGeoManager::GetNproperties
Int_t GetNproperties() const
Definition: TGeoManager.h:182
TList::Clear
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:401
TGDMLWrite::SetNamingSpeed
void SetNamingSpeed(ENamingType naming)
Set convention of naming solids and volumes.
Definition: TGDMLWrite.cxx:228
name
char name[80]
Definition: TGX11.cxx:110
TGDMLWrite::CreateDivisionN
XMLNodePointer_t CreateDivisionN(Double_t offset, Double_t width, Int_t number, const char *axis, const char *unit, const char *volref)
Creates "divisionvol" node for GDML.
Definition: TGDMLWrite.cxx:2010
TGDMLWrite::CreatePolyconeN
XMLNodePointer_t CreatePolyconeN(TGeoPcon *geoShape)
Creates "polycone" node for GDML.
Definition: TGDMLWrite.cxx:1392
ROOT::Math::Chebyshev::T
double T(double x)
Definition: ChebyshevPol.h:52
TGeoParaboloid::GetRhi
Double_t GetRhi() const
Definition: TGeoParaboloid.h:58
TGeoTrd2::GetDy1
Double_t GetDy1() const
Definition: TGeoTrd2.h:64
TGDMLWrite::CreateElementN
XMLNodePointer_t CreateElementN(TGeoElement *element, XMLNodePointer_t materials, const char *name)
Creates "element" node for GDML element node and attribute.
Definition: TGDMLWrite.cxx:774
TGeoBoolNode::GetRightShape
TGeoShape * GetRightShape() const
Definition: TGeoBoolNode.h:84
TGDMLWrite::CreateSkinSurfaceN
XMLNodePointer_t CreateSkinSurfaceN(TGeoSkinSurface *geoSurf)
Creates "skinsurface" node for GDML.
Definition: TGDMLWrite.cxx:1839
x2
static const double x2[5]
Definition: RooGaussKronrodIntegrator1D.cxx:364
TGeoPara.h
TGeoBoolNode.h
TGeoConeSeg
Definition: TGeoCone.h:98
TIter
Definition: TCollection.h:233
TGeoPatternFinder::GetDivAxis
virtual Int_t GetDivAxis()
Definition: TGeoPatternFinder.h:84
TGeoPcon::GetDphi
Double_t GetDphi() const
Definition: TGeoPcon.h:82
TGDMLWrite::ExtractOpticalSurfaces
void ExtractOpticalSurfaces(TObjArray *surfaces)
Method exporting optical surfaces.
Definition: TGDMLWrite.cxx:431
TGDMLWrite::fSurfaceList
SurfaceList fSurfaceList
Definition: TGDMLWrite.h:116
TGeoTorus::GetRmin
Double_t GetRmin() const
Definition: TGeoTorus.h:76
TGeoManager::GetTopNode
TGeoNode * GetTopNode() const
Definition: TGeoManager.h:533
TGDMLWrite::Xyz::y
Double_t y
Definition: TGDMLWrite.h:92
TNamed::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:53
TGDMLWrite::NameListF
std::map< TString, Float_t > NameListF
Definition: TGDMLWrite.h:102
TGeoParaboloid::GetRlo
Double_t GetRlo() const
Definition: TGeoParaboloid.h:57
TGeoOpticalSurface::TypeToString
static const char * TypeToString(ESurfaceType type)
Definition: TGeoOpticalSurface.cxx:73
type
int type
Definition: TGX11.cxx:121
TGeoTube.h
TGeoTrd1::GetDy
Double_t GetDy() const
Definition: TGeoTrd1.h:63
TGDMLWrite::CreateBoxN
XMLNodePointer_t CreateBoxN(TGeoBBox *geoShape)
Creates "box" node for GDML.
Definition: TGDMLWrite.cxx:954
TString::ToLower
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1125
TGeoXtru::GetX
Double_t GetX(Int_t i) const
Definition: TGeoXtru.h:96
TGDMLWrite::ExtractSolid
TString ExtractSolid(TGeoShape *volShape)
Method creating solid to xml file and returning its name.
Definition: TGDMLWrite.cxx:530
TGDMLWrite::kelegantButSlow
@ kelegantButSlow
Definition: TGDMLWrite.h:80
TGeoMaterial::GetA
virtual Double_t GetA() const
Definition: TGeoMaterial.h:105
TGeoMatrix::GetTranslation
virtual const Double_t * GetTranslation() const =0
TGDMLWrite::Xyz
Definition: TGDMLWrite.h:90
TGDMLWrite::ExtractSkinSurfaces
void ExtractSkinSurfaces(TObjArray *surfaces)
Method exporting skin surfaces.
Definition: TGDMLWrite.cxx:448
TGeoManager
Definition: TGeoManager.h:44
TXMLEngine::FreeDoc
void FreeDoc(XMLDocPointer_t xmldoc)
frees allocated document data and deletes document itself
Definition: TXMLEngine.cxx:1285
TGeoOpticalSurface
Definition: TGeoOpticalSurface.h:27
TObject::ClassName
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:130
TGeoMatrix::Inverse
virtual TGeoHMatrix Inverse() const =0
TGeoTrap::GetH2
Double_t GetH2() const
Definition: TGeoArb8.h:132
TGeoManager::GetProperty
Double_t GetProperty(const char *name, Bool_t *error=nullptr) const
Get a user-defined property.
Definition: TGeoManager.cxx:592
TGDMLWrite::ChooseObject
XMLNodePointer_t ChooseObject(TGeoShape *geoShape)
Chooses the object and method that should be used for processing object.
Definition: TGDMLWrite.cxx:2045
TGeoPara::GetX
Double_t GetX() const
Definition: TGeoPara.h:67
TGDMLWrite::ENamingType
ENamingType
Definition: TGDMLWrite.h:79
TGeoTrd1::GetDx1
Double_t GetDx1() const
Definition: TGeoTrd1.h:61
TGeoVolume::IsTopVolume
Bool_t IsTopVolume() const
True if this is the top volume of the geometry.
Definition: TGeoVolume.cxx:812
TGDMLWrite::CreateRotationN
XMLNodePointer_t CreateRotationN(const char *name, Xyz rotation, const char *type="rotation", const char *unit="deg")
Creates "rotation" kind of node for GDML.
Definition: TGDMLWrite.cxx:1885
TMath::E
constexpr Double_t E()
Base of natural log:
Definition: TMath.h:102
TGeoTrd2
Definition: TGeoTrd2.h:17
TGeoVolume
Definition: TGeoVolume.h:44
TGeoTubeSeg::GetPhi2
Double_t GetPhi2() const
Definition: TGeoTube.h:149
TGeoSphere.h
TGeoSphere::GetPhi1
Double_t GetPhi1() const
Definition: TGeoSphere.h:77
TGDMLWrite::fgkProcBit
static const UInt_t fgkProcBit
floating point precision when writing
Definition: TGDMLWrite.h:140
TGeoOpticalSurface::FinishToString
static const char * FinishToString(ESurfaceFinish finish)
Definition: TGeoOpticalSurface.cxx:195
TList
Definition: TList.h:44
TGeoTrap
Definition: TGeoArb8.h:91
TGeoTorus.h
TGDMLMatrix::Get
Double_t Get(size_t r, size_t c) const
Definition: TGDMLMatrix.cxx:78
TGeoCtub::GetNlow
const Double_t * GetNlow() const
Definition: TGeoTube.h:207
TGeoTube::GetRmax
virtual Double_t GetRmax() const
Definition: TGeoTube.h:73
TGeoHMatrix::GetRotationMatrix
virtual const Double_t * GetRotationMatrix() const
Definition: TGeoMatrix.h:468
TMath.h
TGeoHype::GetStIn
Double_t GetStIn() const
Definition: TGeoHype.h:74
TGDMLWrite::fNameList
NameLst * fNameList
Definition: TGDMLWrite.h:120
TGDMLWrite::CreateCutTubeN
XMLNodePointer_t CreateCutTubeN(TGeoCtub *geoShape)
Creates "cutTube" node for GDML.
Definition: TGDMLWrite.cxx:1307
TGeoPgon.h
int
TGDMLWrite::fgNamingSpeed
Int_t fgNamingSpeed
Definition: TGDMLWrite.h:124
TGeoMaterial::GetConstProperties
const TList & GetConstProperties() const
Definition: TGeoMaterial.h:101
TGeoSkinSurface
Definition: TGeoOpticalSurface.h:162