Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHG4GDMLWriteSolids.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHG4GDMLWriteSolids.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id: PHG4GDMLWriteSolids.cc 81843 2014-06-06 09:11:11Z gcosmo $
28 //
29 // class PHG4GDMLWriteSolids Implementation
30 //
31 // Original author: Zoltan Torzsok, November 2007
32 //
33 // --------------------------------------------------------------------
34 
35 #include "PHG4GDMLWriteSolids.hh"
36 
37 #include <Geant4/G4SystemOfUnits.hh>
38 #include <Geant4/G4BooleanSolid.hh>
39 #include <Geant4/G4Box.hh>
40 #include <Geant4/G4Cons.hh>
41 #include <Geant4/G4Ellipsoid.hh>
42 #include <Geant4/G4EllipticalCone.hh>
43 #include <Geant4/G4EllipticalTube.hh>
44 #include <Geant4/G4ExtrudedSolid.hh>
45 #include <Geant4/G4Hype.hh>
46 #include <Geant4/G4Orb.hh>
47 #include <Geant4/G4Para.hh>
48 #include <Geant4/G4Paraboloid.hh>
49 #include <Geant4/G4IntersectionSolid.hh>
50 #include <Geant4/G4Polycone.hh>
51 #include <Geant4/G4GenericPolycone.hh>
52 #include <Geant4/G4Polyhedra.hh>
53 #include <Geant4/G4ReflectedSolid.hh>
54 #include <Geant4/G4Sphere.hh>
55 #include <Geant4/G4SubtractionSolid.hh>
56 #include <Geant4/G4GenericTrap.hh>
57 #include <Geant4/G4TessellatedSolid.hh>
58 #include <Geant4/G4Tet.hh>
59 #include <Geant4/G4Torus.hh>
60 #include <Geant4/G4Trap.hh>
61 #include <Geant4/G4Trd.hh>
62 #include <Geant4/G4Tubs.hh>
63 #include <Geant4/G4CutTubs.hh>
64 #include <Geant4/G4TwistedBox.hh>
65 #include <Geant4/G4TwistedTrap.hh>
66 #include <Geant4/G4TwistedTrd.hh>
67 #include <Geant4/G4TwistedTubs.hh>
68 #include <Geant4/G4UnionSolid.hh>
69 #include <Geant4/G4OpticalSurface.hh>
70 #include <Geant4/G4SurfaceProperty.hh>
71 
73  : PHG4GDMLWriteMaterials(), solidsElement(0)
74 {
75 }
76 
78 {
79 }
80 
81 #if !defined(G4GEOM_USE_USOLIDS)
83 MultiUnionWrite(xercesc::DOMElement*,
84  const G4MultiUnion* const)
85 {
86  G4Exception("PHG4GDMLWriteSolids::MultiUnionWrite()",
87  "InvalidSetup", FatalException,
88  "Installation with USolids primitives required!");
89  return;
90 }
91 #else
93 MultiUnionWrite(xercesc::DOMElement* solElement,
94  const G4MultiUnion* const munionSolid)
95 {
96  G4int numSolids=munionSolid->GetNumberOfSolids();
97  G4String tag("multiUnion");
98 
99  const G4String& name = GenerateName(munionSolid->GetName(),munionSolid);
100  xercesc::DOMElement* multiUnionElement = NewElement(tag);
101  multiUnionElement->setAttributeNode(NewAttribute("name",name));
102 
103  for (G4int i=0; i<numSolids; ++i)
104  {
105  G4VSolid* solid = munionSolid->GetSolid(i);
106  G4Transform3D* transform = munionSolid->GetTransformation(i);
107 
108  HepGeom::Rotate3D rot3d;
109  HepGeom::Translate3D transl ;
110  HepGeom::Scale3D scale;
111  transform->getDecomposition(scale,rot3d,transl);
112 
113  G4ThreeVector pos = transl.getTranslation();
114  G4RotationMatrix
115  rotm(CLHEP::HepRep3x3(rot3d.xx(), rot3d.xy(), rot3d.xz(),
116  rot3d.yx(), rot3d.yy(), rot3d.yz(),
117  rot3d.zx(), rot3d.zy(), rot3d.zz()));
118  G4ThreeVector rot = GetAngles(rotm);
119 
120  AddSolid(solid);
121  const G4String& solidref = GenerateName(solid->GetName(),solid);
122  std::ostringstream os; os << i+1;
123  const G4String& nodeName = "Node-" + G4String(os.str());
124  xercesc::DOMElement* solidElement = NewElement("solid");
125  solidElement->setAttributeNode(NewAttribute("ref",solidref));
126  xercesc::DOMElement* multiUnionNodeElement = NewElement("multiUnionNode");
127  multiUnionNodeElement->setAttributeNode(NewAttribute("name", nodeName));
128  multiUnionNodeElement->appendChild(solidElement); // Append solid to node
129  if ( (std::fabs(pos.x()) > kLinearPrecision)
130  || (std::fabs(pos.y()) > kLinearPrecision)
131  || (std::fabs(pos.z()) > kLinearPrecision) )
132  {
133  PositionWrite(multiUnionNodeElement,name+"_pos",pos);
134  }
135  if ( (std::fabs(rot.x()) > kAngularPrecision)
136  || (std::fabs(rot.y()) > kAngularPrecision)
137  || (std::fabs(rot.z()) > kAngularPrecision) )
138  {
139  RotationWrite(multiUnionNodeElement,name+"_rot",rot);
140  }
141  multiUnionElement->appendChild(multiUnionNodeElement); // Append node
142  }
143 
144  solElement->appendChild(multiUnionElement);
145  // Add the multiUnion solid AFTER the constituent nodes!
146 }
147 #endif
148 
150 BooleanWrite(xercesc::DOMElement* solElement,
151  const G4BooleanSolid* const boolean)
152 {
153  G4int displaced=0;
154 
155  G4String tag("undefined");
156  if (dynamic_cast<const G4IntersectionSolid*>(boolean))
157  { tag = "intersection"; } else
158  if (dynamic_cast<const G4SubtractionSolid*>(boolean))
159  { tag = "subtraction"; } else
160  if (dynamic_cast<const G4UnionSolid*>(boolean))
161  { tag = "union"; }
162 
163  G4VSolid* firstPtr = const_cast<G4VSolid*>(boolean->GetConstituentSolid(0));
164  G4VSolid* secondPtr = const_cast<G4VSolid*>(boolean->GetConstituentSolid(1));
165 
166  G4ThreeVector firstpos,firstrot,pos,rot;
167 
168  // Solve possible displacement of referenced solids!
169  //
170  while (true)
171  {
172  if ( displaced>8 )
173  {
174  G4String ErrorMessage = "The referenced solid '"
175  + firstPtr->GetName() +
176  + "in the Boolean shape '" +
177  + boolean->GetName() +
178  + "' was displaced too many times!";
179  G4Exception("PHG4GDMLWriteSolids::BooleanWrite()",
180  "InvalidSetup", FatalException, ErrorMessage);
181  }
182 
183  if (G4DisplacedSolid* disp = dynamic_cast<G4DisplacedSolid*>(firstPtr))
184  {
185  firstpos += disp->GetObjectTranslation();
186  firstrot += GetAngles(disp->GetObjectRotation());
187  firstPtr = disp->GetConstituentMovedSolid();
188  displaced++;
189  continue;
190  }
191  break;
192  }
193  displaced = 0;
194  while (true)
195  {
196  if ( displaced>maxTransforms )
197  {
198  G4String ErrorMessage = "The referenced solid '"
199  + secondPtr->GetName() +
200  + "in the Boolean shape '" +
201  + boolean->GetName() +
202  + "' was displaced too many times!";
203  G4Exception("PHG4GDMLWriteSolids::BooleanWrite()",
204  "InvalidSetup", FatalException, ErrorMessage);
205  }
206 
207  if (G4DisplacedSolid* disp = dynamic_cast<G4DisplacedSolid*>(secondPtr))
208  {
209  pos += disp->GetObjectTranslation();
210  rot += GetAngles(disp->GetObjectRotation());
211  secondPtr = disp->GetConstituentMovedSolid();
212  displaced++;
213  continue;
214  }
215  break;
216  }
217 
218  AddSolid(firstPtr); // At first add the constituent solids!
219  AddSolid(secondPtr);
220 
221  const G4String& name = GenerateName(boolean->GetName(),boolean);
222  const G4String& firstref = GenerateName(firstPtr->GetName(),firstPtr);
223  const G4String& secondref = GenerateName(secondPtr->GetName(),secondPtr);
224 
225  xercesc::DOMElement* booleanElement = NewElement(tag);
226  booleanElement->setAttributeNode(NewAttribute("name",name));
227  xercesc::DOMElement* firstElement = NewElement("first");
228  firstElement->setAttributeNode(NewAttribute("ref",firstref));
229  booleanElement->appendChild(firstElement);
230  xercesc::DOMElement* secondElement = NewElement("second");
231  secondElement->setAttributeNode(NewAttribute("ref",secondref));
232  booleanElement->appendChild(secondElement);
233  solElement->appendChild(booleanElement);
234  // Add the boolean solid AFTER the constituent solids!
235 
236  if ( (std::fabs(pos.x()) > kLinearPrecision)
237  || (std::fabs(pos.y()) > kLinearPrecision)
238  || (std::fabs(pos.z()) > kLinearPrecision) )
239  {
240  PositionWrite(booleanElement,name+"_pos",pos);
241  }
242 
243  if ( (std::fabs(rot.x()) > kAngularPrecision)
244  || (std::fabs(rot.y()) > kAngularPrecision)
245  || (std::fabs(rot.z()) > kAngularPrecision) )
246  {
247  RotationWrite(booleanElement,name+"_rot",rot);
248  }
249 
250  if ( (std::fabs(firstpos.x()) > kLinearPrecision)
251  || (std::fabs(firstpos.y()) > kLinearPrecision)
252  || (std::fabs(firstpos.z()) > kLinearPrecision) )
253  {
254  FirstpositionWrite(booleanElement,name+"_fpos",firstpos);
255  }
256 
257  if ( (std::fabs(firstrot.x()) > kAngularPrecision)
258  || (std::fabs(firstrot.y()) > kAngularPrecision)
259  || (std::fabs(firstrot.z()) > kAngularPrecision) )
260  {
261  FirstrotationWrite(booleanElement,name+"_frot",firstrot);
262  }
263 }
264 
266 BoxWrite(xercesc::DOMElement* solElement, const G4Box* const box)
267 {
268  const G4String& name = GenerateName(box->GetName(),box);
269 
270  xercesc::DOMElement* boxElement = NewElement("box");
271  boxElement->setAttributeNode(NewAttribute("name",name));
272  boxElement->setAttributeNode(NewAttribute("x",2.0*box->GetXHalfLength()/mm));
273  boxElement->setAttributeNode(NewAttribute("y",2.0*box->GetYHalfLength()/mm));
274  boxElement->setAttributeNode(NewAttribute("z",2.0*box->GetZHalfLength()/mm));
275  boxElement->setAttributeNode(NewAttribute("lunit","mm"));
276  solElement->appendChild(boxElement);
277 }
278 
280 ConeWrite(xercesc::DOMElement* solElement, const G4Cons* const cone)
281 {
282  const G4String& name = GenerateName(cone->GetName(),cone);
283 
284  xercesc::DOMElement* coneElement = NewElement("cone");
285  coneElement->setAttributeNode(NewAttribute("name",name));
286  coneElement->
287  setAttributeNode(NewAttribute("rmin1",cone->GetInnerRadiusMinusZ()/mm));
288  coneElement->
289  setAttributeNode(NewAttribute("rmax1",cone->GetOuterRadiusMinusZ()/mm));
290  coneElement->
291  setAttributeNode(NewAttribute("rmin2",cone->GetInnerRadiusPlusZ()/mm));
292  coneElement->
293  setAttributeNode(NewAttribute("rmax2",cone->GetOuterRadiusPlusZ()/mm));
294  coneElement->
295  setAttributeNode(NewAttribute("z",2.0*cone->GetZHalfLength()/mm));
296  coneElement->
297  setAttributeNode(NewAttribute("startphi",cone->GetStartPhiAngle()/degree));
298  coneElement->
299  setAttributeNode(NewAttribute("deltaphi",cone->GetDeltaPhiAngle()/degree));
300  coneElement->setAttributeNode(NewAttribute("aunit","deg"));
301  coneElement->setAttributeNode(NewAttribute("lunit","mm"));
302  solElement->appendChild(coneElement);
303 }
304 
306 ElconeWrite(xercesc::DOMElement* solElement,
307  const G4EllipticalCone* const elcone)
308 {
309  const G4String& name = GenerateName(elcone->GetName(),elcone);
310 
311  xercesc::DOMElement* elconeElement = NewElement("elcone");
312  elconeElement->setAttributeNode(NewAttribute("name",name));
313  elconeElement->setAttributeNode(NewAttribute("dx",elcone->GetSemiAxisX()/mm));
314  elconeElement->setAttributeNode(NewAttribute("dy",elcone->GetSemiAxisY()/mm));
315  elconeElement->setAttributeNode(NewAttribute("zmax",elcone->GetZMax()/mm));
316  elconeElement->setAttributeNode(NewAttribute("zcut",elcone->GetZTopCut()/mm));
317  elconeElement->setAttributeNode(NewAttribute("lunit","mm"));
318  solElement->appendChild(elconeElement);
319 }
320 
322 EllipsoidWrite(xercesc::DOMElement* solElement,
323  const G4Ellipsoid* const ellipsoid)
324 {
325  const G4String& name = GenerateName(ellipsoid->GetName(),ellipsoid);
326 
327  xercesc::DOMElement* ellipsoidElement = NewElement("ellipsoid");
328  ellipsoidElement->setAttributeNode(NewAttribute("name",name));
329  ellipsoidElement->
330  setAttributeNode(NewAttribute("ax",ellipsoid->GetSemiAxisMax(0)/mm));
331  ellipsoidElement->
332  setAttributeNode(NewAttribute("by",ellipsoid->GetSemiAxisMax(1)/mm));
333  ellipsoidElement->
334  setAttributeNode(NewAttribute("cz",ellipsoid->GetSemiAxisMax(2)/mm));
335  ellipsoidElement->
336  setAttributeNode(NewAttribute("zcut1",ellipsoid->GetZBottomCut()/mm));
337  ellipsoidElement->
338  setAttributeNode(NewAttribute("zcut2",ellipsoid->GetZTopCut()/mm));
339  ellipsoidElement->
340  setAttributeNode(NewAttribute("lunit","mm"));
341  solElement->appendChild(ellipsoidElement);
342 }
343 
345 EltubeWrite(xercesc::DOMElement* solElement,
346  const G4EllipticalTube* const eltube)
347 {
348  const G4String& name = GenerateName(eltube->GetName(),eltube);
349 
350  xercesc::DOMElement* eltubeElement = NewElement("eltube");
351  eltubeElement->setAttributeNode(NewAttribute("name",name));
352  eltubeElement->setAttributeNode(NewAttribute("dx",eltube->GetDx()/mm));
353  eltubeElement->setAttributeNode(NewAttribute("dy",eltube->GetDy()/mm));
354  eltubeElement->setAttributeNode(NewAttribute("dz",eltube->GetDz()/mm));
355  eltubeElement->setAttributeNode(NewAttribute("lunit","mm"));
356  solElement->appendChild(eltubeElement);
357 }
358 
360 XtruWrite(xercesc::DOMElement* solElement,
361  const G4ExtrudedSolid* const xtru)
362 {
363  const G4String& name = GenerateName(xtru->GetName(),xtru);
364 
365  xercesc::DOMElement* xtruElement = NewElement("xtru");
366  xtruElement->setAttributeNode(NewAttribute("name",name));
367  xtruElement->setAttributeNode(NewAttribute("lunit","mm"));
368  solElement->appendChild(xtruElement);
369 
370  const G4int NumVertex = xtru->GetNofVertices();
371 
372  for (G4int i=0;i<NumVertex;i++)
373  {
374  xercesc::DOMElement* twoDimVertexElement = NewElement("twoDimVertex");
375  xtruElement->appendChild(twoDimVertexElement);
376 
377  const G4TwoVector& vertex = xtru->GetVertex(i);
378 
379  twoDimVertexElement->setAttributeNode(NewAttribute("x",vertex.x()/mm));
380  twoDimVertexElement->setAttributeNode(NewAttribute("y",vertex.y()/mm));
381  }
382 
383  const G4int NumSection = xtru->GetNofZSections();
384 
385  for (G4int i=0;i<NumSection;i++)
386  {
387  xercesc::DOMElement* sectionElement = NewElement("section");
388  xtruElement->appendChild(sectionElement);
389 
390  const G4ExtrudedSolid::ZSection section = xtru->GetZSection(i);
391 
392  sectionElement->setAttributeNode(NewAttribute("zOrder",i));
393  sectionElement->setAttributeNode(NewAttribute("zPosition",section.fZ/mm));
394  sectionElement->
395  setAttributeNode(NewAttribute("xOffset",section.fOffset.x()/mm));
396  sectionElement->
397  setAttributeNode(NewAttribute("yOffset",section.fOffset.y()/mm));
398  sectionElement->
399  setAttributeNode(NewAttribute("scalingFactor",section.fScale));
400  }
401 }
402 
404 HypeWrite(xercesc::DOMElement* solElement, const G4Hype* const hype)
405 {
406  const G4String& name = GenerateName(hype->GetName(),hype);
407 
408  xercesc::DOMElement* hypeElement = NewElement("hype");
409  hypeElement->setAttributeNode(NewAttribute("name",name));
410  hypeElement->setAttributeNode(NewAttribute("rmin",
411  hype->GetInnerRadius()/mm));
412  hypeElement->setAttributeNode(NewAttribute("rmax",
413  hype->GetOuterRadius()/mm));
414  hypeElement->setAttributeNode(NewAttribute("inst",
415  hype->GetInnerStereo()/degree));
416  hypeElement->setAttributeNode(NewAttribute("outst",
417  hype->GetOuterStereo()/degree));
418  hypeElement->setAttributeNode(NewAttribute("z",
419  2.0*hype->GetZHalfLength()/mm));
420  hypeElement->setAttributeNode(NewAttribute("aunit","deg"));
421  hypeElement->setAttributeNode(NewAttribute("lunit","mm"));
422  solElement->appendChild(hypeElement);
423 }
424 
426 OrbWrite(xercesc::DOMElement* solElement, const G4Orb* const orb)
427 {
428  const G4String& name = GenerateName(orb->GetName(),orb);
429 
430  xercesc::DOMElement* orbElement = NewElement("orb");
431  orbElement->setAttributeNode(NewAttribute("name",name));
432  orbElement->setAttributeNode(NewAttribute("r",orb->GetRadius()/mm));
433  orbElement->setAttributeNode(NewAttribute("lunit","mm"));
434  solElement->appendChild(orbElement);
435 }
436 
438 ParaWrite(xercesc::DOMElement* solElement, const G4Para* const para)
439 {
440  const G4String& name = GenerateName(para->GetName(),para);
441 
442  const G4ThreeVector simaxis = para->GetSymAxis();
443  const G4double alpha = std::atan(para->GetTanAlpha());
444  const G4double phi = simaxis.phi();
445  const G4double theta = simaxis.theta();
446 
447  xercesc::DOMElement* paraElement = NewElement("para");
448  paraElement->setAttributeNode(NewAttribute("name",name));
449  paraElement->setAttributeNode(NewAttribute("x",
450  2.0*para->GetXHalfLength()/mm));
451  paraElement->setAttributeNode(NewAttribute("y",
452  2.0*para->GetYHalfLength()/mm));
453  paraElement->setAttributeNode(NewAttribute("z",
454  2.0*para->GetZHalfLength()/mm));
455  paraElement->setAttributeNode(NewAttribute("alpha",alpha/degree));
456  paraElement->setAttributeNode(NewAttribute("theta",theta/degree));
457  paraElement->setAttributeNode(NewAttribute("phi",phi/degree));
458  paraElement->setAttributeNode(NewAttribute("aunit","deg"));
459  paraElement->setAttributeNode(NewAttribute("lunit","mm"));
460  solElement->appendChild(paraElement);
461 }
462 
464 ParaboloidWrite(xercesc::DOMElement* solElement,
465  const G4Paraboloid* const paraboloid)
466 {
467  const G4String& name = GenerateName(paraboloid->GetName(),paraboloid);
468 
469  xercesc::DOMElement* paraboloidElement = NewElement("paraboloid");
470  paraboloidElement->setAttributeNode(NewAttribute("name",name));
471  paraboloidElement->setAttributeNode(NewAttribute("rlo",
472  paraboloid->GetRadiusMinusZ()/mm));
473  paraboloidElement->setAttributeNode(NewAttribute("rhi",
474  paraboloid->GetRadiusPlusZ()/mm));
475  paraboloidElement->setAttributeNode(NewAttribute("dz",
476  paraboloid->GetZHalfLength()/mm));
477  paraboloidElement->setAttributeNode(NewAttribute("lunit","mm"));
478  solElement->appendChild(paraboloidElement);
479 }
481 PolyconeWrite(xercesc::DOMElement* solElement,
482  const G4Polycone* const polycone)
483 {
484  const G4String& name = GenerateName(polycone->GetName(),polycone);
485 
486  xercesc::DOMElement* polyconeElement = NewElement("polycone");
487  polyconeElement->setAttributeNode(NewAttribute("name",name));
488  polyconeElement->setAttributeNode(NewAttribute("startphi",
489  polycone->GetOriginalParameters()->Start_angle/degree));
490  polyconeElement->setAttributeNode(NewAttribute("deltaphi",
491  polycone->GetOriginalParameters()->Opening_angle/degree));
492  polyconeElement->setAttributeNode(NewAttribute("aunit","deg"));
493  polyconeElement->setAttributeNode(NewAttribute("lunit","mm"));
494  solElement->appendChild(polyconeElement);
495 
496  const size_t num_zplanes = polycone->GetOriginalParameters()->Num_z_planes;
497  const G4double* z_array = polycone->GetOriginalParameters()->Z_values;
498  const G4double* rmin_array = polycone->GetOriginalParameters()->Rmin;
499  const G4double* rmax_array = polycone->GetOriginalParameters()->Rmax;
500 
501  for (size_t i=0; i<num_zplanes; i++)
502  {
503  ZplaneWrite(polyconeElement,z_array[i],rmin_array[i],rmax_array[i]);
504  }
505 
506 
507 }
508 
510 GenericPolyconeWrite(xercesc::DOMElement* solElement,
511  const G4GenericPolycone* const polycone)
512 {
513  const G4String& name = GenerateName(polycone->GetName(),polycone);
514  xercesc::DOMElement* polyconeElement = NewElement("genericPolycone");
515  const G4double startPhi=polycone->GetStartPhi();
516  polyconeElement->setAttributeNode(NewAttribute("name",name));
517  polyconeElement->setAttributeNode(NewAttribute("startphi",
518  startPhi/degree));
519  polyconeElement->setAttributeNode(NewAttribute("deltaphi",
520  (polycone->GetEndPhi()-startPhi)/degree));
521  polyconeElement->setAttributeNode(NewAttribute("aunit","deg"));
522  polyconeElement->setAttributeNode(NewAttribute("lunit","mm"));
523  solElement->appendChild(polyconeElement);
524 
525  const size_t num_rzpoints = polycone->GetNumRZCorner();
526  for (size_t i=0; i<num_rzpoints; i++)
527  {
528  const G4double r_point=polycone->GetCorner(i).r;
529  const G4double z_point=polycone->GetCorner(i).z;
530  RZPointWrite(polyconeElement,r_point,z_point);
531  }
532 
533 }
534 
536 PolyhedraWrite(xercesc::DOMElement* solElement,
537  const G4Polyhedra* const polyhedra)
538 {
539  const G4String& name = GenerateName(polyhedra->GetName(),polyhedra);
540  if(polyhedra->IsGeneric() == false){
541  xercesc::DOMElement* polyhedraElement = NewElement("polyhedra");
542  polyhedraElement->setAttributeNode(NewAttribute("name",name));
543  polyhedraElement->setAttributeNode(NewAttribute("startphi",
544  polyhedra->GetOriginalParameters()->Start_angle/degree));
545  polyhedraElement->setAttributeNode(NewAttribute("deltaphi",
546  polyhedra->GetOriginalParameters()->Opening_angle/degree));
547  polyhedraElement->setAttributeNode(NewAttribute("numsides",
548  polyhedra->GetOriginalParameters()->numSide));
549  polyhedraElement->setAttributeNode(NewAttribute("aunit","deg"));
550  polyhedraElement->setAttributeNode(NewAttribute("lunit","mm"));
551  solElement->appendChild(polyhedraElement);
552 
553  const size_t num_zplanes = polyhedra->GetOriginalParameters()->Num_z_planes;
554  const G4double* z_array = polyhedra->GetOriginalParameters()->Z_values;
555  const G4double* rmin_array = polyhedra->GetOriginalParameters()->Rmin;
556  const G4double* rmax_array = polyhedra->GetOriginalParameters()->Rmax;
557 
558  const G4double convertRad =
559  std::cos(0.5*polyhedra->GetOriginalParameters()->Opening_angle
560  / polyhedra->GetOriginalParameters()->numSide);
561 
562  for (size_t i=0;i<num_zplanes;i++)
563  {
564  ZplaneWrite(polyhedraElement,z_array[i],
565  rmin_array[i]*convertRad, rmax_array[i]*convertRad);
566  }
567  }else{//generic polyhedra
568 
569  xercesc::DOMElement* polyhedraElement = NewElement("genericPolyhedra");
570  polyhedraElement->setAttributeNode(NewAttribute("name",name));
571  polyhedraElement->setAttributeNode(NewAttribute("startphi",
572  polyhedra->GetOriginalParameters()->Start_angle/degree));
573  polyhedraElement->setAttributeNode(NewAttribute("deltaphi",
574  polyhedra->GetOriginalParameters()->Opening_angle/degree));
575  polyhedraElement->setAttributeNode(NewAttribute("numsides",
576  polyhedra->GetOriginalParameters()->numSide));
577  polyhedraElement->setAttributeNode(NewAttribute("aunit","deg"));
578  polyhedraElement->setAttributeNode(NewAttribute("lunit","mm"));
579  solElement->appendChild(polyhedraElement);
580 
581  const size_t num_rzpoints = polyhedra->GetNumRZCorner();
582 
583  for (size_t i=0;i<num_rzpoints;i++)
584  {
585  const G4double r_point = polyhedra->GetCorner(i).r;
586  const G4double z_point = polyhedra->GetCorner(i).z;
587  RZPointWrite(polyhedraElement,r_point,z_point);
588  }
589  }
590 }
591 
593 SphereWrite(xercesc::DOMElement* solElement, const G4Sphere* const sphere)
594 {
595  const G4String& name = GenerateName(sphere->GetName(),sphere);
596 
597  xercesc::DOMElement* sphereElement = NewElement("sphere");
598  sphereElement->setAttributeNode(NewAttribute("name",name));
599  sphereElement->setAttributeNode(NewAttribute("rmin",
600  sphere->GetInnerRadius()/mm));
601  sphereElement->setAttributeNode(NewAttribute("rmax",
602  sphere->GetOuterRadius()/mm));
603  sphereElement->setAttributeNode(NewAttribute("startphi",
604  sphere->GetStartPhiAngle()/degree));
605  sphereElement->setAttributeNode(NewAttribute("deltaphi",
606  sphere->GetDeltaPhiAngle()/degree));
607  sphereElement->setAttributeNode(NewAttribute("starttheta",
608  sphere->GetStartThetaAngle()/degree));
609  sphereElement->setAttributeNode(NewAttribute("deltatheta",
610  sphere->GetDeltaThetaAngle()/degree));
611  sphereElement->setAttributeNode(NewAttribute("aunit","deg"));
612  sphereElement->setAttributeNode(NewAttribute("lunit","mm"));
613  solElement->appendChild(sphereElement);
614 }
615 
617 TessellatedWrite(xercesc::DOMElement* solElement,
618  const G4TessellatedSolid* const tessellated)
619 {
620  const G4String& solid_name = tessellated->GetName();
621  const G4String& name = GenerateName(solid_name, tessellated);
622 
623  xercesc::DOMElement* tessellatedElement = NewElement("tessellated");
624  tessellatedElement->setAttributeNode(NewAttribute("name",name));
625  tessellatedElement->setAttributeNode(NewAttribute("aunit","deg"));
626  tessellatedElement->setAttributeNode(NewAttribute("lunit","mm"));
627  solElement->appendChild(tessellatedElement);
628 
629  std::map<G4ThreeVector, G4String, G4ThreeVectorCompare> vertexMap;
630 
631  const size_t NumFacets = tessellated->GetNumberOfFacets();
632  size_t NumVertex = 0;
633 
634  for (size_t i=0;i<NumFacets;i++)
635  {
636  const G4VFacet* facet = tessellated->GetFacet(i);
637  const size_t NumVertexPerFacet = facet->GetNumberOfVertices();
638 
639  G4String FacetTag;
640 
641  if (NumVertexPerFacet==3) { FacetTag="triangular"; } else
642  if (NumVertexPerFacet==4) { FacetTag="quadrangular"; }
643  else
644  {
645  G4Exception("PHG4GDMLWriteSolids::TessellatedWrite()", "InvalidSetup",
646  FatalException, "Facet should contain 3 or 4 vertices!");
647  }
648 
649  xercesc::DOMElement* facetElement = NewElement(FacetTag);
650  tessellatedElement->appendChild(facetElement);
651 
652  for (size_t j=0; j<NumVertexPerFacet; j++)
653  {
654  std::stringstream name_stream;
655  std::stringstream ref_stream;
656 
657  name_stream << "vertex" << (j+1);
658  ref_stream << solid_name << "_v" << NumVertex;
659 
660  const G4String& fname = name_stream.str(); // facet's tag variable
661  G4String ref = ref_stream.str(); // vertex tag to be associated
662 
663  // Now search for the existance of the current vertex in the
664  // map of cached vertices. If existing, do NOT store it as
665  // position in the GDML file, so avoiding duplication; otherwise
666  // cache it in the local map and add it as position in the
667  // "define" section of the GDML file.
668 
669  const G4ThreeVector& vertex = facet->GetVertex(j);
670 
671  if(vertexMap.find(vertex) != vertexMap.end()) // Vertex is cached
672  {
673  ref = vertexMap[vertex]; // Set the proper tag for it
674  }
675  else // Vertex not found
676  {
677  vertexMap.insert(std::make_pair(vertex,ref)); // Cache vertex and ...
678  AddPosition(ref, vertex); // ... add it to define section!
679  NumVertex++;
680  }
681 
682  // Now create association of the vertex with its facet
683  //
684  facetElement->setAttributeNode(NewAttribute(fname,ref));
685  }
686  }
687 }
688 
690 TetWrite(xercesc::DOMElement* solElement, const G4Tet* const tet)
691 {
692  const G4String& solid_name = tet->GetName();
693  const G4String& name = GenerateName(solid_name, tet);
694 
695  std::vector<G4ThreeVector> vertexList = tet->GetVertices();
696 
697  xercesc::DOMElement* tetElement = NewElement("tet");
698  tetElement->setAttributeNode(NewAttribute("name",name));
699  tetElement->setAttributeNode(NewAttribute("vertex1",solid_name+"_v1"));
700  tetElement->setAttributeNode(NewAttribute("vertex2",solid_name+"_v2"));
701  tetElement->setAttributeNode(NewAttribute("vertex3",solid_name+"_v3"));
702  tetElement->setAttributeNode(NewAttribute("vertex4",solid_name+"_v4"));
703  tetElement->setAttributeNode(NewAttribute("lunit","mm"));
704  solElement->appendChild(tetElement);
705 
706  AddPosition(solid_name+"_v1",vertexList[0]);
707  AddPosition(solid_name+"_v2",vertexList[1]);
708  AddPosition(solid_name+"_v3",vertexList[2]);
709  AddPosition(solid_name+"_v4",vertexList[3]);
710 }
711 
713 TorusWrite(xercesc::DOMElement* solElement, const G4Torus* const torus)
714 {
715  const G4String& name = GenerateName(torus->GetName(),torus);
716 
717  xercesc::DOMElement* torusElement = NewElement("torus");
718  torusElement->setAttributeNode(NewAttribute("name",name));
719  torusElement->setAttributeNode(NewAttribute("rmin",torus->GetRmin()/mm));
720  torusElement->setAttributeNode(NewAttribute("rmax",torus->GetRmax()/mm));
721  torusElement->setAttributeNode(NewAttribute("rtor",torus->GetRtor()/mm));
722  torusElement->
723  setAttributeNode(NewAttribute("startphi",torus->GetSPhi()/degree));
724  torusElement->
725  setAttributeNode(NewAttribute("deltaphi",torus->GetDPhi()/degree));
726  torusElement->setAttributeNode(NewAttribute("aunit","deg"));
727  torusElement->setAttributeNode(NewAttribute("lunit","mm"));
728  solElement->appendChild(torusElement);
729 }
730 
732 GenTrapWrite(xercesc::DOMElement* solElement,
733  const G4GenericTrap* const gtrap)
734 {
735  const G4String& name = GenerateName(gtrap->GetName(),gtrap);
736 
737  std::vector<G4TwoVector> vertices = gtrap->GetVertices();
738 
739  xercesc::DOMElement* gtrapElement = NewElement("arb8");
740  gtrapElement->setAttributeNode(NewAttribute("name",name));
741  gtrapElement->setAttributeNode(NewAttribute("dz",
742  gtrap->GetZHalfLength()/mm));
743  gtrapElement->setAttributeNode(NewAttribute("v1x", vertices[0].x()));
744  gtrapElement->setAttributeNode(NewAttribute("v1y", vertices[0].y()));
745  gtrapElement->setAttributeNode(NewAttribute("v2x", vertices[1].x()));
746  gtrapElement->setAttributeNode(NewAttribute("v2y", vertices[1].y()));
747  gtrapElement->setAttributeNode(NewAttribute("v3x", vertices[2].x()));
748  gtrapElement->setAttributeNode(NewAttribute("v3y", vertices[2].y()));
749  gtrapElement->setAttributeNode(NewAttribute("v4x", vertices[3].x()));
750  gtrapElement->setAttributeNode(NewAttribute("v4y", vertices[3].y()));
751  gtrapElement->setAttributeNode(NewAttribute("v5x", vertices[4].x()));
752  gtrapElement->setAttributeNode(NewAttribute("v5y", vertices[4].y()));
753  gtrapElement->setAttributeNode(NewAttribute("v6x", vertices[5].x()));
754  gtrapElement->setAttributeNode(NewAttribute("v6y", vertices[5].y()));
755  gtrapElement->setAttributeNode(NewAttribute("v7x", vertices[6].x()));
756  gtrapElement->setAttributeNode(NewAttribute("v7y", vertices[6].y()));
757  gtrapElement->setAttributeNode(NewAttribute("v8x", vertices[7].x()));
758  gtrapElement->setAttributeNode(NewAttribute("v8y", vertices[7].y()));
759  gtrapElement->setAttributeNode(NewAttribute("lunit","mm"));
760  solElement->appendChild(gtrapElement);
761 }
762 
764 TrapWrite(xercesc::DOMElement* solElement, const G4Trap* const trap)
765 {
766  const G4String& name = GenerateName(trap->GetName(),trap);
767 
768  const G4ThreeVector& simaxis = trap->GetSymAxis();
769  const G4double phi = simaxis.phi();
770  const G4double theta = simaxis.theta();
771  const G4double alpha1 = std::atan(trap->GetTanAlpha1());
772  const G4double alpha2 = std::atan(trap->GetTanAlpha2());
773 
774  xercesc::DOMElement* trapElement = NewElement("trap");
775  trapElement->setAttributeNode(NewAttribute("name",name));
776  trapElement->setAttributeNode(NewAttribute("z",
777  2.0*trap->GetZHalfLength()/mm));
778  trapElement->setAttributeNode(NewAttribute("theta",theta/degree));
779  trapElement->setAttributeNode(NewAttribute("phi",phi/degree));
780  trapElement->setAttributeNode(NewAttribute("y1",
781  2.0*trap->GetYHalfLength1()/mm));
782  trapElement->setAttributeNode(NewAttribute("x1",
783  2.0*trap->GetXHalfLength1()/mm));
784  trapElement->setAttributeNode(NewAttribute("x2",
785  2.0*trap->GetXHalfLength2()/mm));
786  trapElement->setAttributeNode(NewAttribute("alpha1",alpha1/degree));
787  trapElement->setAttributeNode(NewAttribute("y2",
788  2.0*trap->GetYHalfLength2()/mm));
789  trapElement->setAttributeNode(NewAttribute("x3",
790  2.0*trap->GetXHalfLength3()/mm));
791  trapElement->setAttributeNode(NewAttribute("x4",
792  2.0*trap->GetXHalfLength4()/mm));
793  trapElement->setAttributeNode(NewAttribute("alpha2",alpha2/degree));
794  trapElement->setAttributeNode(NewAttribute("aunit","deg"));
795  trapElement->setAttributeNode(NewAttribute("lunit","mm"));
796  solElement->appendChild(trapElement);
797 }
798 
800 TrdWrite(xercesc::DOMElement* solElement, const G4Trd* const trd)
801 {
802  const G4String& name = GenerateName(trd->GetName(),trd);
803 
804  xercesc::DOMElement* trdElement = NewElement("trd");
805  trdElement->setAttributeNode(NewAttribute("name",name));
806  trdElement->setAttributeNode(NewAttribute("x1",
807  2.0*trd->GetXHalfLength1()/mm));
808  trdElement->setAttributeNode(NewAttribute("x2",
809  2.0*trd->GetXHalfLength2()/mm));
810  trdElement->setAttributeNode(NewAttribute("y1",
811  2.0*trd->GetYHalfLength1()/mm));
812  trdElement->setAttributeNode(NewAttribute("y2",
813  2.0*trd->GetYHalfLength2()/mm));
814  trdElement->setAttributeNode(NewAttribute("z",
815  2.0*trd->GetZHalfLength()/mm));
816  trdElement->setAttributeNode(NewAttribute("lunit","mm"));
817  solElement->appendChild(trdElement);
818 }
819 
821 TubeWrite(xercesc::DOMElement* solElement, const G4Tubs* const tube)
822 {
823  const G4String& name = GenerateName(tube->GetName(),tube);
824 
825  xercesc::DOMElement* tubeElement = NewElement("tube");
826  tubeElement->setAttributeNode(NewAttribute("name",name));
827  tubeElement->setAttributeNode(NewAttribute("rmin",
828  tube->GetInnerRadius()/mm));
829  tubeElement->setAttributeNode(NewAttribute("rmax",
830  tube->GetOuterRadius()/mm));
831  tubeElement->setAttributeNode(NewAttribute("z",
832  2.0*tube->GetZHalfLength()/mm));
833  tubeElement->setAttributeNode(NewAttribute("startphi",
834  tube->GetStartPhiAngle()/degree));
835  tubeElement->setAttributeNode(NewAttribute("deltaphi",
836  tube->GetDeltaPhiAngle()/degree));
837  tubeElement->setAttributeNode(NewAttribute("aunit","deg"));
838  tubeElement->setAttributeNode(NewAttribute("lunit","mm"));
839  solElement->appendChild(tubeElement);
840 }
841 
843 CutTubeWrite(xercesc::DOMElement* solElement, const G4CutTubs* const cuttube)
844 {
845  const G4String& name = GenerateName(cuttube->GetName(),cuttube);
846 
847  xercesc::DOMElement* cuttubeElement = NewElement("cutTube");
848  cuttubeElement->setAttributeNode(NewAttribute("name",name));
849  cuttubeElement->setAttributeNode(NewAttribute("rmin",
850  cuttube->GetInnerRadius()/mm));
851  cuttubeElement->setAttributeNode(NewAttribute("rmax",
852  cuttube->GetOuterRadius()/mm));
853  cuttubeElement->setAttributeNode(NewAttribute("z",
854  2.0*cuttube->GetZHalfLength()/mm));
855  cuttubeElement->setAttributeNode(NewAttribute("startphi",
856  cuttube->GetStartPhiAngle()/degree));
857  cuttubeElement->setAttributeNode(NewAttribute("deltaphi",
858  cuttube->GetDeltaPhiAngle()/degree));
859  cuttubeElement->setAttributeNode(NewAttribute("lowX",
860  cuttube->GetLowNorm().getX()/mm));
861  cuttubeElement->setAttributeNode(NewAttribute("lowY",
862  cuttube->GetLowNorm().getY()/mm));
863  cuttubeElement->setAttributeNode(NewAttribute("lowZ",
864  cuttube->GetLowNorm().getZ()/mm));
865  cuttubeElement->setAttributeNode(NewAttribute("highX",
866  cuttube->GetHighNorm().getX()/mm));
867  cuttubeElement->setAttributeNode(NewAttribute("highY",
868  cuttube->GetHighNorm().getY()/mm));
869  cuttubeElement->setAttributeNode(NewAttribute("highZ",
870  cuttube->GetHighNorm().getZ()/mm));
871  cuttubeElement->setAttributeNode(NewAttribute("aunit","deg"));
872  cuttubeElement->setAttributeNode(NewAttribute("lunit","mm"));
873  solElement->appendChild(cuttubeElement);
874 }
875 
877 TwistedboxWrite(xercesc::DOMElement* solElement,
878  const G4TwistedBox* const twistedbox)
879 {
880  const G4String& name = GenerateName(twistedbox->GetName(),twistedbox);
881 
882  xercesc::DOMElement* twistedboxElement = NewElement("twistedbox");
883  twistedboxElement->setAttributeNode(NewAttribute("name",name));
884  twistedboxElement->setAttributeNode(NewAttribute("x",
885  2.0*twistedbox->GetXHalfLength()/mm));
886  twistedboxElement->setAttributeNode(NewAttribute("y",
887  2.0*twistedbox->GetYHalfLength()/mm));
888  twistedboxElement->setAttributeNode(NewAttribute("z",
889  2.0*twistedbox->GetZHalfLength()/mm));
890  twistedboxElement->setAttributeNode(NewAttribute("PhiTwist",
891  twistedbox->GetPhiTwist()/degree));
892  twistedboxElement->setAttributeNode(NewAttribute("aunit","deg"));
893  twistedboxElement->setAttributeNode(NewAttribute("lunit","mm"));
894  solElement->appendChild(twistedboxElement);
895 }
896 
898 TwistedtrapWrite(xercesc::DOMElement* solElement,
899  const G4TwistedTrap* const twistedtrap)
900 {
901  const G4String& name = GenerateName(twistedtrap->GetName(),twistedtrap);
902 
903  xercesc::DOMElement* twistedtrapElement = NewElement("twistedtrap");
904  twistedtrapElement->setAttributeNode(NewAttribute("name",name));
905  twistedtrapElement->setAttributeNode(NewAttribute("y1",
906  2.0*twistedtrap->GetY1HalfLength()/mm));
907  twistedtrapElement->setAttributeNode(NewAttribute("x1",
908  2.0*twistedtrap->GetX1HalfLength()/mm));
909  twistedtrapElement->setAttributeNode(NewAttribute("x2",
910  2.0*twistedtrap->GetX2HalfLength()/mm));
911  twistedtrapElement->setAttributeNode(NewAttribute("y2",
912  2.0*twistedtrap->GetY2HalfLength()/mm));
913  twistedtrapElement->setAttributeNode(NewAttribute("x3",
914  2.0*twistedtrap->GetX3HalfLength()/mm));
915  twistedtrapElement->setAttributeNode(NewAttribute("x4",
916  2.0*twistedtrap->GetX4HalfLength()/mm));
917  twistedtrapElement->setAttributeNode(NewAttribute("z",
918  2.0*twistedtrap->GetZHalfLength()/mm));
919  twistedtrapElement->setAttributeNode(NewAttribute("Alph",
920  twistedtrap->GetTiltAngleAlpha()/degree));
921  twistedtrapElement->setAttributeNode(NewAttribute("Theta",
922  twistedtrap->GetPolarAngleTheta()/degree));
923  twistedtrapElement->setAttributeNode(NewAttribute("Phi",
924  twistedtrap->GetAzimuthalAnglePhi()/degree));
925  twistedtrapElement->setAttributeNode(NewAttribute("PhiTwist",
926  twistedtrap->GetPhiTwist()/degree));
927  twistedtrapElement->setAttributeNode(NewAttribute("aunit","deg"));
928  twistedtrapElement->setAttributeNode(NewAttribute("lunit","mm"));
929 
930  solElement->appendChild(twistedtrapElement);
931 }
932 
934 TwistedtrdWrite(xercesc::DOMElement* solElement,
935  const G4TwistedTrd* const twistedtrd)
936 {
937  const G4String& name = GenerateName(twistedtrd->GetName(),twistedtrd);
938 
939  xercesc::DOMElement* twistedtrdElement = NewElement("twistedtrd");
940  twistedtrdElement->setAttributeNode(NewAttribute("name",name));
941  twistedtrdElement->setAttributeNode(NewAttribute("x1",
942  2.0*twistedtrd->GetX1HalfLength()/mm));
943  twistedtrdElement->setAttributeNode(NewAttribute("x2",
944  2.0*twistedtrd->GetX2HalfLength()/mm));
945  twistedtrdElement->setAttributeNode(NewAttribute("y1",
946  2.0*twistedtrd->GetY1HalfLength()/mm));
947  twistedtrdElement->setAttributeNode(NewAttribute("y2",
948  2.0*twistedtrd->GetY2HalfLength()/mm));
949  twistedtrdElement->setAttributeNode(NewAttribute("z",
950  2.0*twistedtrd->GetZHalfLength()/mm));
951  twistedtrdElement->setAttributeNode(NewAttribute("PhiTwist",
952  twistedtrd->GetPhiTwist()/degree));
953  twistedtrdElement->setAttributeNode(NewAttribute("aunit","deg"));
954  twistedtrdElement->setAttributeNode(NewAttribute("lunit","mm"));
955  solElement->appendChild(twistedtrdElement);
956 }
957 
959 TwistedtubsWrite(xercesc::DOMElement* solElement,
960  const G4TwistedTubs* const twistedtubs)
961 {
962  const G4String& name = GenerateName(twistedtubs->GetName(),twistedtubs);
963 
964  xercesc::DOMElement* twistedtubsElement = NewElement("twistedtubs");
965  twistedtubsElement->setAttributeNode(NewAttribute("name",name));
966  twistedtubsElement->setAttributeNode(NewAttribute("twistedangle",
967  twistedtubs->GetPhiTwist()/degree));
968  twistedtubsElement->setAttributeNode(NewAttribute("endinnerrad",
969  twistedtubs->GetInnerRadius()/mm));
970  twistedtubsElement->setAttributeNode(NewAttribute("endouterrad",
971  twistedtubs->GetOuterRadius()/mm));
972  twistedtubsElement->setAttributeNode(NewAttribute("zlen",
973  2.0*twistedtubs->GetZHalfLength()/mm));
974  twistedtubsElement->setAttributeNode(NewAttribute("phi",
975  twistedtubs->GetDPhi()/degree));
976  twistedtubsElement->setAttributeNode(NewAttribute("aunit","deg"));
977  twistedtubsElement->setAttributeNode(NewAttribute("lunit","mm"));
978  solElement->appendChild(twistedtubsElement);
979 }
980 
982 ZplaneWrite(xercesc::DOMElement* element, const G4double& z,
983  const G4double& rmin, const G4double& rmax)
984 {
985  xercesc::DOMElement* zplaneElement = NewElement("zplane");
986  zplaneElement->setAttributeNode(NewAttribute("z",z/mm));
987  zplaneElement->setAttributeNode(NewAttribute("rmin",rmin/mm));
988  zplaneElement->setAttributeNode(NewAttribute("rmax",rmax/mm));
989  element->appendChild(zplaneElement);
990 }
991 
993 RZPointWrite(xercesc::DOMElement* element, const G4double& r,
994  const G4double& z)
995 {
996  xercesc::DOMElement* rzpointElement = NewElement("rzpoint");
997  rzpointElement->setAttributeNode(NewAttribute("r",r/mm));
998  rzpointElement->setAttributeNode(NewAttribute("z",z/mm));
999  element->appendChild(rzpointElement);
1000 }
1001 
1003 OpticalSurfaceWrite(xercesc::DOMElement* solElement,
1004  const G4OpticalSurface* const surf)
1005 {
1006  xercesc::DOMElement* optElement = NewElement("opticalsurface");
1007  G4OpticalSurfaceModel smodel = surf->GetModel();
1008  G4double sval = (smodel==glisur) ? surf->GetPolish() : surf->GetSigmaAlpha();
1009 
1010  optElement->setAttributeNode(NewAttribute("name", surf->GetName()));
1011  optElement->setAttributeNode(NewAttribute("model", smodel));
1012  optElement->setAttributeNode(NewAttribute("finish", surf->GetFinish()));
1013  optElement->setAttributeNode(NewAttribute("type", surf->GetType()));
1014  optElement->setAttributeNode(NewAttribute("value", sval));
1015 
1016  solElement->appendChild(optElement);
1017 }
1018 
1019 void PHG4GDMLWriteSolids::SolidsWrite(xercesc::DOMElement* gdmlElement)
1020 {
1021  std::cout << "PHG4GDML: Writing solids..." << std::endl;
1022 
1023  solidsElement = NewElement("solids");
1024  gdmlElement->appendChild(solidsElement);
1025 
1026  solidList.clear();
1027 }
1028 
1029 void PHG4GDMLWriteSolids::AddSolid(const G4VSolid* const solidPtr)
1030 {
1031  for (size_t i=0; i<solidList.size(); i++) // Check if solid is
1032  { // already in the list!
1033  if (solidList[i] == solidPtr) { return; }
1034  }
1035 
1036  solidList.push_back(solidPtr);
1037 
1038  if (const G4BooleanSolid* const booleanPtr
1039  = dynamic_cast<const G4BooleanSolid*>(solidPtr))
1040  { BooleanWrite(solidsElement,booleanPtr); } else
1041  if (solidPtr->GetEntityType()=="G4MultiUnion")
1042  { const G4MultiUnion* const munionPtr
1043  = static_cast<const G4MultiUnion*>(solidPtr);
1044  MultiUnionWrite(solidsElement,munionPtr); } else
1045  if (solidPtr->GetEntityType()=="G4Box")
1046  { const G4Box* const boxPtr
1047  = static_cast<const G4Box*>(solidPtr);
1048  BoxWrite(solidsElement,boxPtr); } else
1049  if (solidPtr->GetEntityType()=="G4Cons")
1050  { const G4Cons* const conePtr
1051  = static_cast<const G4Cons*>(solidPtr);
1052  ConeWrite(solidsElement,conePtr); } else
1053  if (solidPtr->GetEntityType()=="G4EllipticalCone")
1054  { const G4EllipticalCone* const elconePtr
1055  = static_cast<const G4EllipticalCone*>(solidPtr);
1056  ElconeWrite(solidsElement,elconePtr); } else
1057  if (solidPtr->GetEntityType()=="G4Ellipsoid")
1058  { const G4Ellipsoid* const ellipsoidPtr
1059  = static_cast<const G4Ellipsoid*>(solidPtr);
1060  EllipsoidWrite(solidsElement,ellipsoidPtr); } else
1061  if (solidPtr->GetEntityType()=="G4EllipticalTube")
1062  { const G4EllipticalTube* const eltubePtr
1063  = static_cast<const G4EllipticalTube*>(solidPtr);
1064  EltubeWrite(solidsElement,eltubePtr); } else
1065  if (solidPtr->GetEntityType()=="G4ExtrudedSolid")
1066  { const G4ExtrudedSolid* const xtruPtr
1067  = static_cast<const G4ExtrudedSolid*>(solidPtr);
1068  XtruWrite(solidsElement,xtruPtr); } else
1069  if (solidPtr->GetEntityType()=="G4Hype")
1070  { const G4Hype* const hypePtr
1071  = static_cast<const G4Hype*>(solidPtr);
1072  HypeWrite(solidsElement,hypePtr); } else
1073  if (solidPtr->GetEntityType()=="G4Orb")
1074  { const G4Orb* const orbPtr
1075  = static_cast<const G4Orb*>(solidPtr);
1076  OrbWrite(solidsElement,orbPtr); } else
1077  if (solidPtr->GetEntityType()=="G4Para")
1078  { const G4Para* const paraPtr
1079  = static_cast<const G4Para*>(solidPtr);
1080  ParaWrite(solidsElement,paraPtr); } else
1081  if (solidPtr->GetEntityType()=="G4Paraboloid")
1082  { const G4Paraboloid* const paraboloidPtr
1083  = static_cast<const G4Paraboloid*>(solidPtr);
1084  ParaboloidWrite(solidsElement,paraboloidPtr); } else
1085  if (solidPtr->GetEntityType()=="G4Polycone")
1086  { const G4Polycone* const polyconePtr
1087  = static_cast<const G4Polycone*>(solidPtr);
1088  PolyconeWrite(solidsElement,polyconePtr); } else
1089  if (solidPtr->GetEntityType()=="G4GenericPolycone")
1090  { const G4GenericPolycone* const genpolyconePtr
1091  = static_cast<const G4GenericPolycone*>(solidPtr);
1092  GenericPolyconeWrite(solidsElement,genpolyconePtr); } else
1093  if (solidPtr->GetEntityType()=="G4Polyhedra")
1094  { const G4Polyhedra* const polyhedraPtr
1095  = static_cast<const G4Polyhedra*>(solidPtr);
1096  PolyhedraWrite(solidsElement,polyhedraPtr); } else
1097  if (solidPtr->GetEntityType()=="G4Sphere")
1098  { const G4Sphere* const spherePtr
1099  = static_cast<const G4Sphere*>(solidPtr);
1100  SphereWrite(solidsElement,spherePtr); } else
1101  if (solidPtr->GetEntityType()=="G4TessellatedSolid")
1102  { const G4TessellatedSolid* const tessellatedPtr
1103  = static_cast<const G4TessellatedSolid*>(solidPtr);
1104  TessellatedWrite(solidsElement,tessellatedPtr); } else
1105  if (solidPtr->GetEntityType()=="G4Tet")
1106  { const G4Tet* const tetPtr
1107  = static_cast<const G4Tet*>(solidPtr);
1108  TetWrite(solidsElement,tetPtr); } else
1109  if (solidPtr->GetEntityType()=="G4Torus")
1110  { const G4Torus* const torusPtr
1111  = static_cast<const G4Torus*>(solidPtr);
1112  TorusWrite(solidsElement,torusPtr); } else
1113  if (solidPtr->GetEntityType()=="G4GenericTrap")
1114  { const G4GenericTrap* const gtrapPtr
1115  = static_cast<const G4GenericTrap*>(solidPtr);
1116  GenTrapWrite(solidsElement,gtrapPtr); } else
1117  if (solidPtr->GetEntityType()=="G4Trap")
1118  { const G4Trap* const trapPtr
1119  = static_cast<const G4Trap*>(solidPtr);
1120  TrapWrite(solidsElement,trapPtr); } else
1121  if (solidPtr->GetEntityType()=="G4Trd")
1122  { const G4Trd* const trdPtr
1123  = static_cast<const G4Trd*>(solidPtr);
1124  TrdWrite(solidsElement,trdPtr); } else
1125  if (solidPtr->GetEntityType()=="G4Tubs")
1126  { const G4Tubs* const tubePtr
1127  = static_cast<const G4Tubs*>(solidPtr);
1128  TubeWrite(solidsElement,tubePtr); } else
1129  if (solidPtr->GetEntityType()=="G4CutTubs")
1130  { const G4CutTubs* const cuttubePtr
1131  = static_cast<const G4CutTubs*>(solidPtr);
1132  CutTubeWrite(solidsElement,cuttubePtr); } else
1133  if (solidPtr->GetEntityType()=="G4TwistedBox")
1134  { const G4TwistedBox* const twistedboxPtr
1135  = static_cast<const G4TwistedBox*>(solidPtr);
1136  TwistedboxWrite(solidsElement,twistedboxPtr); } else
1137  if (solidPtr->GetEntityType()=="G4TwistedTrap")
1138  { const G4TwistedTrap* const twistedtrapPtr
1139  = static_cast<const G4TwistedTrap*>(solidPtr);
1140  TwistedtrapWrite(solidsElement,twistedtrapPtr); } else
1141  if (solidPtr->GetEntityType()=="G4TwistedTrd")
1142  { const G4TwistedTrd* const twistedtrdPtr
1143  = static_cast<const G4TwistedTrd*>(solidPtr);
1144  TwistedtrdWrite(solidsElement,twistedtrdPtr); } else
1145  if (solidPtr->GetEntityType()=="G4TwistedTubs")
1146  { const G4TwistedTubs* const twistedtubsPtr
1147  = static_cast<const G4TwistedTubs*>(solidPtr);
1148  TwistedtubsWrite(solidsElement,twistedtubsPtr); }
1149  else
1150  {
1151  G4String error_msg = "Unknown solid: " + solidPtr->GetName()
1152  + "; Type: " + solidPtr->GetEntityType();
1153  G4Exception("PHG4GDMLWriteSolids::AddSolid()", "WriteError",
1154  FatalException, error_msg);
1155  }
1156 }