Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:18:03

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 //
0027 // $Id: PHG4GDMLWriteSolids.cc 81843 2014-06-06 09:11:11Z gcosmo $
0028 //
0029 // class PHG4GDMLWriteSolids Implementation
0030 //
0031 // Original author: Zoltan Torzsok, November 2007
0032 //
0033 // --------------------------------------------------------------------
0034 
0035 #include "PHG4GDMLWriteSolids.hh"
0036 
0037 #include <Geant4/G4SystemOfUnits.hh>
0038 #include <Geant4/G4BooleanSolid.hh>
0039 #include <Geant4/G4Box.hh>
0040 #include <Geant4/G4Cons.hh>
0041 #include <Geant4/G4Ellipsoid.hh>
0042 #include <Geant4/G4EllipticalCone.hh>
0043 #include <Geant4/G4EllipticalTube.hh>
0044 #include <Geant4/G4ExtrudedSolid.hh>
0045 #include <Geant4/G4Hype.hh>
0046 #include <Geant4/G4Orb.hh>
0047 #include <Geant4/G4Para.hh>
0048 #include <Geant4/G4Paraboloid.hh>
0049 #include <Geant4/G4IntersectionSolid.hh>
0050 #include <Geant4/G4Polycone.hh>
0051 #include <Geant4/G4GenericPolycone.hh>
0052 #include <Geant4/G4Polyhedra.hh>
0053 #include <Geant4/G4ReflectedSolid.hh>
0054 #include <Geant4/G4Sphere.hh>
0055 #include <Geant4/G4SubtractionSolid.hh>
0056 #include <Geant4/G4GenericTrap.hh>
0057 #include <Geant4/G4TessellatedSolid.hh>
0058 #include <Geant4/G4Tet.hh>
0059 #include <Geant4/G4Torus.hh>
0060 #include <Geant4/G4Trap.hh>
0061 #include <Geant4/G4Trd.hh>
0062 #include <Geant4/G4Tubs.hh>
0063 #include <Geant4/G4CutTubs.hh>
0064 #include <Geant4/G4TwistedBox.hh>
0065 #include <Geant4/G4TwistedTrap.hh>
0066 #include <Geant4/G4TwistedTrd.hh>
0067 #include <Geant4/G4TwistedTubs.hh>
0068 #include <Geant4/G4UnionSolid.hh>
0069 #include <Geant4/G4OpticalSurface.hh>
0070 #include <Geant4/G4SurfaceProperty.hh>
0071 
0072 PHG4GDMLWriteSolids::PHG4GDMLWriteSolids()
0073   : PHG4GDMLWriteMaterials(), solidsElement(0)
0074 {
0075 }
0076 
0077 PHG4GDMLWriteSolids::~PHG4GDMLWriteSolids()
0078 {
0079 }
0080 
0081 #if !defined(G4GEOM_USE_USOLIDS)
0082 void PHG4GDMLWriteSolids::
0083 MultiUnionWrite(xercesc::DOMElement*,
0084                 const G4MultiUnion* const)
0085 {
0086    G4Exception("PHG4GDMLWriteSolids::MultiUnionWrite()",
0087                "InvalidSetup", FatalException,
0088                "Installation with USolids primitives required!");
0089    return;
0090 }
0091 #else
0092 void PHG4GDMLWriteSolids::
0093 MultiUnionWrite(xercesc::DOMElement* solElement,
0094                 const G4MultiUnion* const munionSolid)
0095 {
0096    G4int numSolids=munionSolid->GetNumberOfSolids();
0097    G4String tag("multiUnion");
0098 
0099    const G4String& name = GenerateName(munionSolid->GetName(),munionSolid);
0100    xercesc::DOMElement* multiUnionElement = NewElement(tag);
0101    multiUnionElement->setAttributeNode(NewAttribute("name",name));
0102 
0103    for (G4int i=0; i<numSolids; ++i)
0104    {
0105       G4VSolid* solid = munionSolid->GetSolid(i);
0106       G4Transform3D* transform = munionSolid->GetTransformation(i);
0107 
0108       HepGeom::Rotate3D rot3d;
0109       HepGeom::Translate3D transl ;
0110       HepGeom::Scale3D scale;
0111       transform->getDecomposition(scale,rot3d,transl);
0112 
0113       G4ThreeVector pos = transl.getTranslation();
0114       G4RotationMatrix
0115         rotm(CLHEP::HepRep3x3(rot3d.xx(), rot3d.xy(), rot3d.xz(),
0116                               rot3d.yx(), rot3d.yy(), rot3d.yz(),
0117                               rot3d.zx(), rot3d.zy(), rot3d.zz()));
0118       G4ThreeVector rot = GetAngles(rotm);
0119 
0120       AddSolid(solid);
0121       const G4String& solidref = GenerateName(solid->GetName(),solid);
0122       std::ostringstream os; os << i+1;
0123       const G4String& nodeName = "Node-" + G4String(os.str());
0124       xercesc::DOMElement* solidElement = NewElement("solid");
0125       solidElement->setAttributeNode(NewAttribute("ref",solidref));
0126       xercesc::DOMElement* multiUnionNodeElement = NewElement("multiUnionNode");
0127       multiUnionNodeElement->setAttributeNode(NewAttribute("name", nodeName));
0128       multiUnionNodeElement->appendChild(solidElement); // Append solid to node
0129       if ( (std::fabs(pos.x()) > kLinearPrecision)
0130         || (std::fabs(pos.y()) > kLinearPrecision)
0131         || (std::fabs(pos.z()) > kLinearPrecision) )
0132       {
0133         PositionWrite(multiUnionNodeElement,name+"_pos",pos);
0134       }
0135       if ( (std::fabs(rot.x()) > kAngularPrecision)
0136         || (std::fabs(rot.y()) > kAngularPrecision)
0137         || (std::fabs(rot.z()) > kAngularPrecision) )
0138       {
0139         RotationWrite(multiUnionNodeElement,name+"_rot",rot);
0140       }
0141       multiUnionElement->appendChild(multiUnionNodeElement); // Append node
0142    }
0143 
0144    solElement->appendChild(multiUnionElement);
0145      // Add the multiUnion solid AFTER the constituent nodes!
0146 }
0147 #endif
0148 
0149 void PHG4GDMLWriteSolids::
0150 BooleanWrite(xercesc::DOMElement* solElement,
0151              const G4BooleanSolid* const boolean)
0152 {
0153    G4int displaced=0;
0154 
0155    G4String tag("undefined");
0156    if (dynamic_cast<const G4IntersectionSolid*>(boolean))
0157      { tag = "intersection"; } else
0158    if (dynamic_cast<const G4SubtractionSolid*>(boolean))
0159      { tag = "subtraction"; } else
0160    if (dynamic_cast<const G4UnionSolid*>(boolean))
0161      { tag = "union"; }
0162    
0163    G4VSolid* firstPtr = const_cast<G4VSolid*>(boolean->GetConstituentSolid(0));
0164    G4VSolid* secondPtr = const_cast<G4VSolid*>(boolean->GetConstituentSolid(1));
0165    
0166    G4ThreeVector firstpos,firstrot,pos,rot;
0167 
0168    // Solve possible displacement of referenced solids!
0169    //
0170    while (true)
0171    {
0172       if ( displaced>8 )
0173       {
0174         G4String ErrorMessage = "The referenced solid '"
0175                               + firstPtr->GetName() +
0176                               + "in the Boolean shape '" +
0177                               + boolean->GetName() +
0178                               + "' was displaced too many times!";
0179         G4Exception("PHG4GDMLWriteSolids::BooleanWrite()",
0180                     "InvalidSetup", FatalException, ErrorMessage);
0181       }
0182 
0183       if (G4DisplacedSolid* disp = dynamic_cast<G4DisplacedSolid*>(firstPtr))
0184       {
0185          firstpos += disp->GetObjectTranslation();
0186          firstrot += GetAngles(disp->GetObjectRotation());
0187          firstPtr = disp->GetConstituentMovedSolid();
0188          displaced++;
0189          continue;
0190       }
0191       break;
0192    }
0193    displaced = 0;
0194    while (true)
0195    {
0196       if ( displaced>maxTransforms )
0197       {
0198         G4String ErrorMessage = "The referenced solid '"
0199                               + secondPtr->GetName() +
0200                               + "in the Boolean shape '" +
0201                               + boolean->GetName() +
0202                               + "' was displaced too many times!";
0203         G4Exception("PHG4GDMLWriteSolids::BooleanWrite()",
0204                     "InvalidSetup", FatalException, ErrorMessage);
0205       }
0206 
0207       if (G4DisplacedSolid* disp = dynamic_cast<G4DisplacedSolid*>(secondPtr))
0208       {
0209          pos += disp->GetObjectTranslation();
0210          rot += GetAngles(disp->GetObjectRotation());
0211          secondPtr = disp->GetConstituentMovedSolid();
0212          displaced++;
0213          continue;
0214       }
0215       break;
0216    }
0217 
0218    AddSolid(firstPtr);   // At first add the constituent solids!
0219    AddSolid(secondPtr);
0220 
0221    const G4String& name = GenerateName(boolean->GetName(),boolean);
0222    const G4String& firstref = GenerateName(firstPtr->GetName(),firstPtr);
0223    const G4String& secondref = GenerateName(secondPtr->GetName(),secondPtr);
0224 
0225    xercesc::DOMElement* booleanElement = NewElement(tag);
0226    booleanElement->setAttributeNode(NewAttribute("name",name));
0227    xercesc::DOMElement* firstElement = NewElement("first");
0228    firstElement->setAttributeNode(NewAttribute("ref",firstref));
0229    booleanElement->appendChild(firstElement);
0230    xercesc::DOMElement* secondElement = NewElement("second");
0231    secondElement->setAttributeNode(NewAttribute("ref",secondref));
0232    booleanElement->appendChild(secondElement);
0233    solElement->appendChild(booleanElement);
0234      // Add the boolean solid AFTER the constituent solids!
0235 
0236    if ( (std::fabs(pos.x()) > kLinearPrecision)
0237      || (std::fabs(pos.y()) > kLinearPrecision)
0238      || (std::fabs(pos.z()) > kLinearPrecision) )
0239    {
0240      PositionWrite(booleanElement,name+"_pos",pos);
0241    }
0242 
0243    if ( (std::fabs(rot.x()) > kAngularPrecision)
0244      || (std::fabs(rot.y()) > kAngularPrecision)
0245      || (std::fabs(rot.z()) > kAngularPrecision) )
0246    {
0247      RotationWrite(booleanElement,name+"_rot",rot);
0248    }
0249 
0250    if ( (std::fabs(firstpos.x()) > kLinearPrecision)
0251      || (std::fabs(firstpos.y()) > kLinearPrecision)
0252      || (std::fabs(firstpos.z()) > kLinearPrecision) )
0253    {
0254      FirstpositionWrite(booleanElement,name+"_fpos",firstpos);
0255    }
0256 
0257    if ( (std::fabs(firstrot.x()) > kAngularPrecision)
0258      || (std::fabs(firstrot.y()) > kAngularPrecision)
0259      || (std::fabs(firstrot.z()) > kAngularPrecision) )
0260    {
0261      FirstrotationWrite(booleanElement,name+"_frot",firstrot);
0262    }
0263 }
0264 
0265 void PHG4GDMLWriteSolids::
0266 BoxWrite(xercesc::DOMElement* solElement, const G4Box* const box)
0267 {
0268    const G4String& name = GenerateName(box->GetName(),box);
0269 
0270    xercesc::DOMElement* boxElement = NewElement("box");
0271    boxElement->setAttributeNode(NewAttribute("name",name));
0272    boxElement->setAttributeNode(NewAttribute("x",2.0*box->GetXHalfLength()/mm));
0273    boxElement->setAttributeNode(NewAttribute("y",2.0*box->GetYHalfLength()/mm));
0274    boxElement->setAttributeNode(NewAttribute("z",2.0*box->GetZHalfLength()/mm));
0275    boxElement->setAttributeNode(NewAttribute("lunit","mm"));
0276    solElement->appendChild(boxElement);
0277 }
0278 
0279 void PHG4GDMLWriteSolids::
0280 ConeWrite(xercesc::DOMElement* solElement, const G4Cons* const cone)
0281 {
0282    const G4String& name = GenerateName(cone->GetName(),cone);
0283 
0284    xercesc::DOMElement* coneElement = NewElement("cone");
0285    coneElement->setAttributeNode(NewAttribute("name",name));
0286    coneElement->
0287      setAttributeNode(NewAttribute("rmin1",cone->GetInnerRadiusMinusZ()/mm));
0288    coneElement->
0289      setAttributeNode(NewAttribute("rmax1",cone->GetOuterRadiusMinusZ()/mm));
0290    coneElement->
0291      setAttributeNode(NewAttribute("rmin2",cone->GetInnerRadiusPlusZ()/mm));
0292    coneElement->
0293      setAttributeNode(NewAttribute("rmax2",cone->GetOuterRadiusPlusZ()/mm));
0294    coneElement->
0295      setAttributeNode(NewAttribute("z",2.0*cone->GetZHalfLength()/mm));
0296    coneElement->
0297      setAttributeNode(NewAttribute("startphi",cone->GetStartPhiAngle()/degree));
0298    coneElement->
0299      setAttributeNode(NewAttribute("deltaphi",cone->GetDeltaPhiAngle()/degree));
0300    coneElement->setAttributeNode(NewAttribute("aunit","deg"));
0301    coneElement->setAttributeNode(NewAttribute("lunit","mm"));
0302    solElement->appendChild(coneElement);
0303 }
0304 
0305 void PHG4GDMLWriteSolids::
0306 ElconeWrite(xercesc::DOMElement* solElement,
0307             const G4EllipticalCone* const elcone)
0308 {
0309    const G4String& name = GenerateName(elcone->GetName(),elcone);
0310 
0311    xercesc::DOMElement* elconeElement = NewElement("elcone");
0312    elconeElement->setAttributeNode(NewAttribute("name",name));
0313    elconeElement->setAttributeNode(NewAttribute("dx",elcone->GetSemiAxisX()/mm));
0314    elconeElement->setAttributeNode(NewAttribute("dy",elcone->GetSemiAxisY()/mm));
0315    elconeElement->setAttributeNode(NewAttribute("zmax",elcone->GetZMax()/mm));
0316    elconeElement->setAttributeNode(NewAttribute("zcut",elcone->GetZTopCut()/mm));
0317    elconeElement->setAttributeNode(NewAttribute("lunit","mm"));
0318    solElement->appendChild(elconeElement);
0319 }
0320 
0321 void PHG4GDMLWriteSolids::
0322 EllipsoidWrite(xercesc::DOMElement* solElement,
0323                const G4Ellipsoid* const ellipsoid)
0324 {
0325    const G4String& name = GenerateName(ellipsoid->GetName(),ellipsoid);
0326 
0327    xercesc::DOMElement* ellipsoidElement = NewElement("ellipsoid");
0328    ellipsoidElement->setAttributeNode(NewAttribute("name",name));
0329    ellipsoidElement->
0330      setAttributeNode(NewAttribute("ax",ellipsoid->GetSemiAxisMax(0)/mm));
0331    ellipsoidElement->
0332      setAttributeNode(NewAttribute("by",ellipsoid->GetSemiAxisMax(1)/mm));
0333    ellipsoidElement->
0334      setAttributeNode(NewAttribute("cz",ellipsoid->GetSemiAxisMax(2)/mm));
0335    ellipsoidElement->
0336      setAttributeNode(NewAttribute("zcut1",ellipsoid->GetZBottomCut()/mm));
0337    ellipsoidElement->
0338      setAttributeNode(NewAttribute("zcut2",ellipsoid->GetZTopCut()/mm));
0339    ellipsoidElement->
0340      setAttributeNode(NewAttribute("lunit","mm"));
0341    solElement->appendChild(ellipsoidElement);
0342 }
0343 
0344 void PHG4GDMLWriteSolids::
0345 EltubeWrite(xercesc::DOMElement* solElement,
0346             const G4EllipticalTube* const eltube)
0347 {
0348    const G4String& name = GenerateName(eltube->GetName(),eltube);
0349 
0350    xercesc::DOMElement* eltubeElement = NewElement("eltube");
0351    eltubeElement->setAttributeNode(NewAttribute("name",name));
0352    eltubeElement->setAttributeNode(NewAttribute("dx",eltube->GetDx()/mm));
0353    eltubeElement->setAttributeNode(NewAttribute("dy",eltube->GetDy()/mm));
0354    eltubeElement->setAttributeNode(NewAttribute("dz",eltube->GetDz()/mm));
0355    eltubeElement->setAttributeNode(NewAttribute("lunit","mm"));
0356    solElement->appendChild(eltubeElement);
0357 }
0358 
0359 void PHG4GDMLWriteSolids::
0360 XtruWrite(xercesc::DOMElement* solElement,
0361           const G4ExtrudedSolid* const xtru)
0362 {
0363    const G4String& name = GenerateName(xtru->GetName(),xtru);
0364 
0365    xercesc::DOMElement* xtruElement = NewElement("xtru");
0366    xtruElement->setAttributeNode(NewAttribute("name",name));
0367    xtruElement->setAttributeNode(NewAttribute("lunit","mm"));
0368    solElement->appendChild(xtruElement);
0369 
0370    const G4int NumVertex = xtru->GetNofVertices();
0371    
0372    for (G4int i=0;i<NumVertex;i++)
0373    {
0374       xercesc::DOMElement* twoDimVertexElement = NewElement("twoDimVertex");
0375       xtruElement->appendChild(twoDimVertexElement);
0376 
0377       const G4TwoVector& vertex = xtru->GetVertex(i);
0378 
0379       twoDimVertexElement->setAttributeNode(NewAttribute("x",vertex.x()/mm));
0380       twoDimVertexElement->setAttributeNode(NewAttribute("y",vertex.y()/mm));
0381    }
0382 
0383    const G4int NumSection = xtru->GetNofZSections();
0384 
0385    for (G4int i=0;i<NumSection;i++)
0386    {
0387       xercesc::DOMElement* sectionElement = NewElement("section");
0388       xtruElement->appendChild(sectionElement);
0389 
0390       const G4ExtrudedSolid::ZSection section = xtru->GetZSection(i);
0391 
0392       sectionElement->setAttributeNode(NewAttribute("zOrder",i));
0393       sectionElement->setAttributeNode(NewAttribute("zPosition",section.fZ/mm));
0394       sectionElement->
0395         setAttributeNode(NewAttribute("xOffset",section.fOffset.x()/mm));
0396       sectionElement->
0397         setAttributeNode(NewAttribute("yOffset",section.fOffset.y()/mm));
0398       sectionElement->
0399         setAttributeNode(NewAttribute("scalingFactor",section.fScale));
0400    }
0401 }
0402 
0403 void PHG4GDMLWriteSolids::
0404 HypeWrite(xercesc::DOMElement* solElement, const G4Hype* const hype)
0405 {
0406    const G4String& name = GenerateName(hype->GetName(),hype);
0407 
0408    xercesc::DOMElement* hypeElement = NewElement("hype");
0409    hypeElement->setAttributeNode(NewAttribute("name",name));
0410    hypeElement->setAttributeNode(NewAttribute("rmin",
0411                 hype->GetInnerRadius()/mm));
0412    hypeElement->setAttributeNode(NewAttribute("rmax",
0413                 hype->GetOuterRadius()/mm));
0414    hypeElement->setAttributeNode(NewAttribute("inst",
0415                 hype->GetInnerStereo()/degree));
0416    hypeElement->setAttributeNode(NewAttribute("outst",
0417                 hype->GetOuterStereo()/degree));
0418    hypeElement->setAttributeNode(NewAttribute("z",
0419                 2.0*hype->GetZHalfLength()/mm));
0420    hypeElement->setAttributeNode(NewAttribute("aunit","deg"));
0421    hypeElement->setAttributeNode(NewAttribute("lunit","mm"));
0422    solElement->appendChild(hypeElement);
0423 }
0424 
0425 void PHG4GDMLWriteSolids::
0426 OrbWrite(xercesc::DOMElement* solElement, const G4Orb* const orb)
0427 {
0428    const G4String& name = GenerateName(orb->GetName(),orb);
0429 
0430    xercesc::DOMElement* orbElement = NewElement("orb");
0431    orbElement->setAttributeNode(NewAttribute("name",name));
0432    orbElement->setAttributeNode(NewAttribute("r",orb->GetRadius()/mm));
0433    orbElement->setAttributeNode(NewAttribute("lunit","mm"));
0434    solElement->appendChild(orbElement);
0435 }
0436 
0437 void PHG4GDMLWriteSolids::
0438 ParaWrite(xercesc::DOMElement* solElement, const G4Para* const para)
0439 {
0440    const G4String& name = GenerateName(para->GetName(),para);
0441 
0442    const G4ThreeVector simaxis = para->GetSymAxis();
0443    const G4double alpha = std::atan(para->GetTanAlpha());
0444    const G4double phi = simaxis.phi();
0445    const G4double theta = simaxis.theta();
0446 
0447    xercesc::DOMElement* paraElement = NewElement("para");
0448    paraElement->setAttributeNode(NewAttribute("name",name));
0449    paraElement->setAttributeNode(NewAttribute("x",
0450                 2.0*para->GetXHalfLength()/mm));
0451    paraElement->setAttributeNode(NewAttribute("y",
0452                 2.0*para->GetYHalfLength()/mm));
0453    paraElement->setAttributeNode(NewAttribute("z",
0454                 2.0*para->GetZHalfLength()/mm));
0455    paraElement->setAttributeNode(NewAttribute("alpha",alpha/degree));
0456    paraElement->setAttributeNode(NewAttribute("theta",theta/degree));
0457    paraElement->setAttributeNode(NewAttribute("phi",phi/degree));
0458    paraElement->setAttributeNode(NewAttribute("aunit","deg"));
0459    paraElement->setAttributeNode(NewAttribute("lunit","mm"));
0460    solElement->appendChild(paraElement);
0461 }
0462 
0463 void PHG4GDMLWriteSolids::
0464 ParaboloidWrite(xercesc::DOMElement* solElement,
0465                 const G4Paraboloid* const paraboloid)
0466 {
0467    const G4String& name = GenerateName(paraboloid->GetName(),paraboloid);
0468 
0469    xercesc::DOMElement* paraboloidElement = NewElement("paraboloid");
0470    paraboloidElement->setAttributeNode(NewAttribute("name",name));
0471    paraboloidElement->setAttributeNode(NewAttribute("rlo",
0472                       paraboloid->GetRadiusMinusZ()/mm));
0473    paraboloidElement->setAttributeNode(NewAttribute("rhi",
0474                       paraboloid->GetRadiusPlusZ()/mm));
0475    paraboloidElement->setAttributeNode(NewAttribute("dz",
0476                       paraboloid->GetZHalfLength()/mm));
0477    paraboloidElement->setAttributeNode(NewAttribute("lunit","mm"));
0478    solElement->appendChild(paraboloidElement);
0479 }
0480 void PHG4GDMLWriteSolids::
0481 PolyconeWrite(xercesc::DOMElement* solElement,
0482               const G4Polycone* const polycone)
0483 {
0484    const G4String& name = GenerateName(polycone->GetName(),polycone);
0485   
0486     xercesc::DOMElement* polyconeElement = NewElement("polycone");
0487     polyconeElement->setAttributeNode(NewAttribute("name",name));
0488     polyconeElement->setAttributeNode(NewAttribute("startphi",
0489                     polycone->GetOriginalParameters()->Start_angle/degree));
0490     polyconeElement->setAttributeNode(NewAttribute("deltaphi",
0491                     polycone->GetOriginalParameters()->Opening_angle/degree));
0492     polyconeElement->setAttributeNode(NewAttribute("aunit","deg"));
0493     polyconeElement->setAttributeNode(NewAttribute("lunit","mm"));
0494     solElement->appendChild(polyconeElement);
0495 
0496     const size_t num_zplanes = polycone->GetOriginalParameters()->Num_z_planes;
0497     const G4double* z_array = polycone->GetOriginalParameters()->Z_values;
0498     const G4double* rmin_array = polycone->GetOriginalParameters()->Rmin;
0499     const G4double* rmax_array = polycone->GetOriginalParameters()->Rmax;
0500 
0501     for (size_t i=0; i<num_zplanes; i++)
0502     {
0503       ZplaneWrite(polyconeElement,z_array[i],rmin_array[i],rmax_array[i]);
0504     }
0505    
0506   
0507 }
0508 
0509 void PHG4GDMLWriteSolids::
0510 GenericPolyconeWrite(xercesc::DOMElement* solElement,
0511               const G4GenericPolycone* const polycone)
0512 {
0513    const G4String& name = GenerateName(polycone->GetName(),polycone);
0514    xercesc::DOMElement* polyconeElement = NewElement("genericPolycone");
0515    const G4double startPhi=polycone->GetStartPhi();
0516     polyconeElement->setAttributeNode(NewAttribute("name",name));
0517     polyconeElement->setAttributeNode(NewAttribute("startphi",
0518             startPhi/degree));
0519     polyconeElement->setAttributeNode(NewAttribute("deltaphi",
0520             (polycone->GetEndPhi()-startPhi)/degree));
0521     polyconeElement->setAttributeNode(NewAttribute("aunit","deg"));
0522     polyconeElement->setAttributeNode(NewAttribute("lunit","mm"));
0523     solElement->appendChild(polyconeElement);
0524 
0525     const size_t num_rzpoints = polycone->GetNumRZCorner();
0526     for (size_t i=0; i<num_rzpoints; i++)
0527     {
0528       const G4double r_point=polycone->GetCorner(i).r;
0529       const G4double z_point=polycone->GetCorner(i).z;
0530       RZPointWrite(polyconeElement,r_point,z_point);
0531     }
0532    
0533 }
0534 
0535 void PHG4GDMLWriteSolids::
0536 PolyhedraWrite(xercesc::DOMElement* solElement,
0537                const G4Polyhedra* const polyhedra)
0538 {
0539    const G4String& name = GenerateName(polyhedra->GetName(),polyhedra);
0540    if(polyhedra->IsGeneric() == false){
0541     xercesc::DOMElement* polyhedraElement = NewElement("polyhedra");
0542     polyhedraElement->setAttributeNode(NewAttribute("name",name));
0543     polyhedraElement->setAttributeNode(NewAttribute("startphi",
0544                      polyhedra->GetOriginalParameters()->Start_angle/degree));
0545     polyhedraElement->setAttributeNode(NewAttribute("deltaphi",
0546                      polyhedra->GetOriginalParameters()->Opening_angle/degree));
0547     polyhedraElement->setAttributeNode(NewAttribute("numsides",
0548                      polyhedra->GetOriginalParameters()->numSide));
0549     polyhedraElement->setAttributeNode(NewAttribute("aunit","deg"));
0550     polyhedraElement->setAttributeNode(NewAttribute("lunit","mm"));
0551     solElement->appendChild(polyhedraElement);
0552 
0553     const size_t num_zplanes = polyhedra->GetOriginalParameters()->Num_z_planes;
0554     const G4double* z_array = polyhedra->GetOriginalParameters()->Z_values;
0555     const G4double* rmin_array = polyhedra->GetOriginalParameters()->Rmin;
0556     const G4double* rmax_array = polyhedra->GetOriginalParameters()->Rmax;
0557 
0558     const G4double convertRad =
0559          std::cos(0.5*polyhedra->GetOriginalParameters()->Opening_angle
0560        / polyhedra->GetOriginalParameters()->numSide);
0561 
0562     for (size_t i=0;i<num_zplanes;i++)
0563     {
0564       ZplaneWrite(polyhedraElement,z_array[i],
0565                   rmin_array[i]*convertRad, rmax_array[i]*convertRad);
0566     }
0567    }else{//generic polyhedra
0568    
0569     xercesc::DOMElement* polyhedraElement = NewElement("genericPolyhedra");
0570     polyhedraElement->setAttributeNode(NewAttribute("name",name));
0571     polyhedraElement->setAttributeNode(NewAttribute("startphi",
0572                      polyhedra->GetOriginalParameters()->Start_angle/degree));
0573     polyhedraElement->setAttributeNode(NewAttribute("deltaphi",
0574                      polyhedra->GetOriginalParameters()->Opening_angle/degree));
0575     polyhedraElement->setAttributeNode(NewAttribute("numsides",
0576                      polyhedra->GetOriginalParameters()->numSide));
0577     polyhedraElement->setAttributeNode(NewAttribute("aunit","deg"));
0578     polyhedraElement->setAttributeNode(NewAttribute("lunit","mm"));
0579     solElement->appendChild(polyhedraElement);
0580 
0581     const size_t num_rzpoints = polyhedra->GetNumRZCorner();
0582     
0583     for (size_t i=0;i<num_rzpoints;i++)
0584     {
0585       const G4double r_point = polyhedra->GetCorner(i).r;
0586       const G4double z_point = polyhedra->GetCorner(i).z;
0587       RZPointWrite(polyhedraElement,r_point,z_point);
0588     }
0589   }
0590 }
0591 
0592 void PHG4GDMLWriteSolids::
0593 SphereWrite(xercesc::DOMElement* solElement, const G4Sphere* const sphere)
0594 {
0595    const G4String& name = GenerateName(sphere->GetName(),sphere);
0596 
0597    xercesc::DOMElement* sphereElement = NewElement("sphere");
0598    sphereElement->setAttributeNode(NewAttribute("name",name));
0599    sphereElement->setAttributeNode(NewAttribute("rmin",
0600                   sphere->GetInnerRadius()/mm));
0601    sphereElement->setAttributeNode(NewAttribute("rmax",
0602                   sphere->GetOuterRadius()/mm));
0603    sphereElement->setAttributeNode(NewAttribute("startphi",
0604                   sphere->GetStartPhiAngle()/degree));
0605    sphereElement->setAttributeNode(NewAttribute("deltaphi",
0606                   sphere->GetDeltaPhiAngle()/degree));
0607    sphereElement->setAttributeNode(NewAttribute("starttheta",
0608                   sphere->GetStartThetaAngle()/degree));
0609    sphereElement->setAttributeNode(NewAttribute("deltatheta",
0610                   sphere->GetDeltaThetaAngle()/degree));
0611    sphereElement->setAttributeNode(NewAttribute("aunit","deg"));
0612    sphereElement->setAttributeNode(NewAttribute("lunit","mm"));
0613    solElement->appendChild(sphereElement);
0614 }
0615 
0616 void PHG4GDMLWriteSolids::
0617 TessellatedWrite(xercesc::DOMElement* solElement,
0618                  const G4TessellatedSolid* const tessellated)
0619 {
0620    const G4String& solid_name = tessellated->GetName();
0621    const G4String& name = GenerateName(solid_name, tessellated);
0622 
0623    xercesc::DOMElement* tessellatedElement = NewElement("tessellated");
0624    tessellatedElement->setAttributeNode(NewAttribute("name",name));
0625    tessellatedElement->setAttributeNode(NewAttribute("aunit","deg"));
0626    tessellatedElement->setAttributeNode(NewAttribute("lunit","mm"));
0627    solElement->appendChild(tessellatedElement);
0628 
0629    std::map<G4ThreeVector, G4String, G4ThreeVectorCompare> vertexMap;
0630 
0631    const size_t NumFacets = tessellated->GetNumberOfFacets();
0632    size_t NumVertex = 0;
0633    
0634    for (size_t i=0;i<NumFacets;i++)
0635    {
0636       const G4VFacet* facet = tessellated->GetFacet(i);
0637       const size_t NumVertexPerFacet = facet->GetNumberOfVertices();
0638 
0639       G4String FacetTag;
0640       
0641       if (NumVertexPerFacet==3) { FacetTag="triangular"; } else
0642       if (NumVertexPerFacet==4) { FacetTag="quadrangular"; }
0643       else
0644       {
0645         G4Exception("PHG4GDMLWriteSolids::TessellatedWrite()", "InvalidSetup",
0646                     FatalException, "Facet should contain 3 or 4 vertices!");
0647       }
0648 
0649       xercesc::DOMElement* facetElement = NewElement(FacetTag);
0650       tessellatedElement->appendChild(facetElement);
0651 
0652       for (size_t j=0; j<NumVertexPerFacet; j++)
0653       {
0654          std::stringstream name_stream;
0655          std::stringstream ref_stream;
0656 
0657          name_stream << "vertex" << (j+1);
0658          ref_stream << solid_name << "_v" << NumVertex;
0659 
0660          const G4String& fname = name_stream.str();  // facet's tag variable
0661          G4String ref = ref_stream.str();     // vertex tag to be associated
0662 
0663          // Now search for the existance of the current vertex in the
0664          // map of cached vertices. If existing, do NOT store it as
0665          // position in the GDML file, so avoiding duplication; otherwise
0666          // cache it in the local map and add it as position in the
0667          // "define" section of the GDML file.
0668 
0669          const G4ThreeVector& vertex = facet->GetVertex(j);
0670 
0671          if(vertexMap.find(vertex) != vertexMap.end())  // Vertex is cached
0672          {
0673            ref = vertexMap[vertex];     // Set the proper tag for it
0674          }
0675          else                                           // Vertex not found
0676          {
0677            vertexMap.insert(std::make_pair(vertex,ref)); // Cache vertex and ...
0678            AddPosition(ref, vertex);    // ... add it to define section!
0679            NumVertex++;
0680          }
0681 
0682          // Now create association of the vertex with its facet
0683          //
0684          facetElement->setAttributeNode(NewAttribute(fname,ref));
0685       }
0686    }
0687 }
0688 
0689 void PHG4GDMLWriteSolids::
0690 TetWrite(xercesc::DOMElement* solElement, const G4Tet* const tet)
0691 {
0692    const G4String& solid_name = tet->GetName();
0693    const G4String& name = GenerateName(solid_name, tet);
0694 
0695    std::vector<G4ThreeVector> vertexList = tet->GetVertices();
0696 
0697    xercesc::DOMElement* tetElement = NewElement("tet");
0698    tetElement->setAttributeNode(NewAttribute("name",name));
0699    tetElement->setAttributeNode(NewAttribute("vertex1",solid_name+"_v1"));
0700    tetElement->setAttributeNode(NewAttribute("vertex2",solid_name+"_v2"));
0701    tetElement->setAttributeNode(NewAttribute("vertex3",solid_name+"_v3"));
0702    tetElement->setAttributeNode(NewAttribute("vertex4",solid_name+"_v4"));
0703    tetElement->setAttributeNode(NewAttribute("lunit","mm"));
0704    solElement->appendChild(tetElement);
0705 
0706    AddPosition(solid_name+"_v1",vertexList[0]);
0707    AddPosition(solid_name+"_v2",vertexList[1]);
0708    AddPosition(solid_name+"_v3",vertexList[2]);
0709    AddPosition(solid_name+"_v4",vertexList[3]);
0710 }
0711 
0712 void PHG4GDMLWriteSolids::
0713 TorusWrite(xercesc::DOMElement* solElement, const G4Torus* const torus)
0714 {
0715    const G4String& name = GenerateName(torus->GetName(),torus);
0716 
0717    xercesc::DOMElement* torusElement = NewElement("torus");
0718    torusElement->setAttributeNode(NewAttribute("name",name));
0719    torusElement->setAttributeNode(NewAttribute("rmin",torus->GetRmin()/mm));
0720    torusElement->setAttributeNode(NewAttribute("rmax",torus->GetRmax()/mm));
0721    torusElement->setAttributeNode(NewAttribute("rtor",torus->GetRtor()/mm));
0722    torusElement->
0723      setAttributeNode(NewAttribute("startphi",torus->GetSPhi()/degree));
0724    torusElement->
0725      setAttributeNode(NewAttribute("deltaphi",torus->GetDPhi()/degree));
0726    torusElement->setAttributeNode(NewAttribute("aunit","deg"));
0727    torusElement->setAttributeNode(NewAttribute("lunit","mm"));
0728    solElement->appendChild(torusElement);
0729 }
0730 
0731 void PHG4GDMLWriteSolids::
0732 GenTrapWrite(xercesc::DOMElement* solElement,
0733              const G4GenericTrap* const gtrap)
0734 {
0735    const G4String& name = GenerateName(gtrap->GetName(),gtrap);
0736 
0737    std::vector<G4TwoVector> vertices = gtrap->GetVertices();
0738 
0739    xercesc::DOMElement* gtrapElement = NewElement("arb8");
0740    gtrapElement->setAttributeNode(NewAttribute("name",name));
0741    gtrapElement->setAttributeNode(NewAttribute("dz",
0742                                            gtrap->GetZHalfLength()/mm));
0743    gtrapElement->setAttributeNode(NewAttribute("v1x", vertices[0].x()));
0744    gtrapElement->setAttributeNode(NewAttribute("v1y", vertices[0].y()));
0745    gtrapElement->setAttributeNode(NewAttribute("v2x", vertices[1].x()));
0746    gtrapElement->setAttributeNode(NewAttribute("v2y", vertices[1].y()));
0747    gtrapElement->setAttributeNode(NewAttribute("v3x", vertices[2].x()));
0748    gtrapElement->setAttributeNode(NewAttribute("v3y", vertices[2].y()));
0749    gtrapElement->setAttributeNode(NewAttribute("v4x", vertices[3].x()));
0750    gtrapElement->setAttributeNode(NewAttribute("v4y", vertices[3].y()));
0751    gtrapElement->setAttributeNode(NewAttribute("v5x", vertices[4].x()));
0752    gtrapElement->setAttributeNode(NewAttribute("v5y", vertices[4].y()));
0753    gtrapElement->setAttributeNode(NewAttribute("v6x", vertices[5].x()));
0754    gtrapElement->setAttributeNode(NewAttribute("v6y", vertices[5].y()));
0755    gtrapElement->setAttributeNode(NewAttribute("v7x", vertices[6].x()));
0756    gtrapElement->setAttributeNode(NewAttribute("v7y", vertices[6].y()));
0757    gtrapElement->setAttributeNode(NewAttribute("v8x", vertices[7].x()));
0758    gtrapElement->setAttributeNode(NewAttribute("v8y", vertices[7].y()));
0759    gtrapElement->setAttributeNode(NewAttribute("lunit","mm"));
0760    solElement->appendChild(gtrapElement);
0761 }
0762 
0763 void PHG4GDMLWriteSolids::
0764 TrapWrite(xercesc::DOMElement* solElement, const G4Trap* const trap)
0765 {
0766    const G4String& name = GenerateName(trap->GetName(),trap);
0767 
0768    const G4ThreeVector& simaxis = trap->GetSymAxis();
0769    const G4double phi = simaxis.phi();
0770    const G4double theta = simaxis.theta();
0771    const G4double alpha1 = std::atan(trap->GetTanAlpha1());
0772    const G4double alpha2 = std::atan(trap->GetTanAlpha2());
0773 
0774    xercesc::DOMElement* trapElement = NewElement("trap");
0775    trapElement->setAttributeNode(NewAttribute("name",name));
0776    trapElement->setAttributeNode(NewAttribute("z",
0777                 2.0*trap->GetZHalfLength()/mm));
0778    trapElement->setAttributeNode(NewAttribute("theta",theta/degree));
0779    trapElement->setAttributeNode(NewAttribute("phi",phi/degree));
0780    trapElement->setAttributeNode(NewAttribute("y1",
0781                 2.0*trap->GetYHalfLength1()/mm));
0782    trapElement->setAttributeNode(NewAttribute("x1",
0783                 2.0*trap->GetXHalfLength1()/mm));
0784    trapElement->setAttributeNode(NewAttribute("x2",
0785                 2.0*trap->GetXHalfLength2()/mm));
0786    trapElement->setAttributeNode(NewAttribute("alpha1",alpha1/degree));
0787    trapElement->setAttributeNode(NewAttribute("y2",
0788                 2.0*trap->GetYHalfLength2()/mm));
0789    trapElement->setAttributeNode(NewAttribute("x3",
0790                 2.0*trap->GetXHalfLength3()/mm));
0791    trapElement->setAttributeNode(NewAttribute("x4",
0792                 2.0*trap->GetXHalfLength4()/mm));
0793    trapElement->setAttributeNode(NewAttribute("alpha2",alpha2/degree));
0794    trapElement->setAttributeNode(NewAttribute("aunit","deg"));
0795    trapElement->setAttributeNode(NewAttribute("lunit","mm"));
0796    solElement->appendChild(trapElement);
0797 }
0798 
0799 void PHG4GDMLWriteSolids::
0800 TrdWrite(xercesc::DOMElement* solElement, const G4Trd* const trd)
0801 {
0802    const G4String& name = GenerateName(trd->GetName(),trd);
0803 
0804    xercesc::DOMElement* trdElement = NewElement("trd");
0805    trdElement->setAttributeNode(NewAttribute("name",name));
0806    trdElement->setAttributeNode(NewAttribute("x1",
0807                2.0*trd->GetXHalfLength1()/mm));
0808    trdElement->setAttributeNode(NewAttribute("x2",
0809                2.0*trd->GetXHalfLength2()/mm));
0810    trdElement->setAttributeNode(NewAttribute("y1",
0811                2.0*trd->GetYHalfLength1()/mm));
0812    trdElement->setAttributeNode(NewAttribute("y2",
0813                2.0*trd->GetYHalfLength2()/mm));
0814    trdElement->setAttributeNode(NewAttribute("z",
0815                2.0*trd->GetZHalfLength()/mm));
0816    trdElement->setAttributeNode(NewAttribute("lunit","mm"));
0817    solElement->appendChild(trdElement);
0818 }
0819 
0820 void PHG4GDMLWriteSolids::
0821 TubeWrite(xercesc::DOMElement* solElement, const G4Tubs* const tube)
0822 {
0823    const G4String& name = GenerateName(tube->GetName(),tube);
0824 
0825    xercesc::DOMElement* tubeElement = NewElement("tube");
0826    tubeElement->setAttributeNode(NewAttribute("name",name));
0827    tubeElement->setAttributeNode(NewAttribute("rmin",
0828                 tube->GetInnerRadius()/mm));
0829    tubeElement->setAttributeNode(NewAttribute("rmax",
0830                 tube->GetOuterRadius()/mm));
0831    tubeElement->setAttributeNode(NewAttribute("z",
0832                 2.0*tube->GetZHalfLength()/mm));
0833    tubeElement->setAttributeNode(NewAttribute("startphi",
0834                 tube->GetStartPhiAngle()/degree));
0835    tubeElement->setAttributeNode(NewAttribute("deltaphi",
0836                 tube->GetDeltaPhiAngle()/degree));
0837    tubeElement->setAttributeNode(NewAttribute("aunit","deg"));
0838    tubeElement->setAttributeNode(NewAttribute("lunit","mm"));
0839    solElement->appendChild(tubeElement);
0840 }
0841 
0842 void PHG4GDMLWriteSolids::
0843 CutTubeWrite(xercesc::DOMElement* solElement, const G4CutTubs* const cuttube)
0844 {
0845    const G4String& name = GenerateName(cuttube->GetName(),cuttube);
0846 
0847    xercesc::DOMElement* cuttubeElement = NewElement("cutTube");
0848    cuttubeElement->setAttributeNode(NewAttribute("name",name));
0849    cuttubeElement->setAttributeNode(NewAttribute("rmin",
0850                 cuttube->GetInnerRadius()/mm));
0851    cuttubeElement->setAttributeNode(NewAttribute("rmax",
0852                 cuttube->GetOuterRadius()/mm));
0853    cuttubeElement->setAttributeNode(NewAttribute("z",
0854                 2.0*cuttube->GetZHalfLength()/mm));
0855    cuttubeElement->setAttributeNode(NewAttribute("startphi",
0856                 cuttube->GetStartPhiAngle()/degree));
0857    cuttubeElement->setAttributeNode(NewAttribute("deltaphi",
0858                 cuttube->GetDeltaPhiAngle()/degree));
0859    cuttubeElement->setAttributeNode(NewAttribute("lowX",
0860                 cuttube->GetLowNorm().getX()/mm));
0861    cuttubeElement->setAttributeNode(NewAttribute("lowY",
0862                 cuttube->GetLowNorm().getY()/mm));
0863    cuttubeElement->setAttributeNode(NewAttribute("lowZ",
0864                 cuttube->GetLowNorm().getZ()/mm));
0865    cuttubeElement->setAttributeNode(NewAttribute("highX",
0866                 cuttube->GetHighNorm().getX()/mm));
0867    cuttubeElement->setAttributeNode(NewAttribute("highY",
0868                 cuttube->GetHighNorm().getY()/mm));
0869    cuttubeElement->setAttributeNode(NewAttribute("highZ",
0870                 cuttube->GetHighNorm().getZ()/mm));
0871    cuttubeElement->setAttributeNode(NewAttribute("aunit","deg"));
0872    cuttubeElement->setAttributeNode(NewAttribute("lunit","mm"));
0873    solElement->appendChild(cuttubeElement);
0874 }
0875 
0876 void PHG4GDMLWriteSolids::
0877 TwistedboxWrite(xercesc::DOMElement* solElement,
0878                 const G4TwistedBox* const twistedbox)
0879 {
0880    const G4String& name = GenerateName(twistedbox->GetName(),twistedbox);
0881 
0882    xercesc::DOMElement* twistedboxElement = NewElement("twistedbox");
0883    twistedboxElement->setAttributeNode(NewAttribute("name",name));
0884    twistedboxElement->setAttributeNode(NewAttribute("x",
0885                       2.0*twistedbox->GetXHalfLength()/mm));
0886    twistedboxElement->setAttributeNode(NewAttribute("y",
0887                       2.0*twistedbox->GetYHalfLength()/mm));
0888    twistedboxElement->setAttributeNode(NewAttribute("z",
0889                       2.0*twistedbox->GetZHalfLength()/mm));
0890    twistedboxElement->setAttributeNode(NewAttribute("PhiTwist",
0891                       twistedbox->GetPhiTwist()/degree));
0892    twistedboxElement->setAttributeNode(NewAttribute("aunit","deg"));
0893    twistedboxElement->setAttributeNode(NewAttribute("lunit","mm"));
0894    solElement->appendChild(twistedboxElement);
0895 }
0896 
0897 void PHG4GDMLWriteSolids::
0898 TwistedtrapWrite(xercesc::DOMElement* solElement,
0899                  const G4TwistedTrap* const twistedtrap)
0900 {
0901    const G4String& name = GenerateName(twistedtrap->GetName(),twistedtrap);
0902 
0903    xercesc::DOMElement* twistedtrapElement = NewElement("twistedtrap");
0904    twistedtrapElement->setAttributeNode(NewAttribute("name",name));
0905    twistedtrapElement->setAttributeNode(NewAttribute("y1",
0906                        2.0*twistedtrap->GetY1HalfLength()/mm));
0907    twistedtrapElement->setAttributeNode(NewAttribute("x1",
0908                        2.0*twistedtrap->GetX1HalfLength()/mm));
0909    twistedtrapElement->setAttributeNode(NewAttribute("x2",
0910                        2.0*twistedtrap->GetX2HalfLength()/mm));
0911    twistedtrapElement->setAttributeNode(NewAttribute("y2",
0912                        2.0*twistedtrap->GetY2HalfLength()/mm));
0913    twistedtrapElement->setAttributeNode(NewAttribute("x3",
0914                        2.0*twistedtrap->GetX3HalfLength()/mm));
0915    twistedtrapElement->setAttributeNode(NewAttribute("x4",
0916                        2.0*twistedtrap->GetX4HalfLength()/mm));
0917    twistedtrapElement->setAttributeNode(NewAttribute("z",
0918                        2.0*twistedtrap->GetZHalfLength()/mm));
0919    twistedtrapElement->setAttributeNode(NewAttribute("Alph",
0920                        twistedtrap->GetTiltAngleAlpha()/degree));
0921    twistedtrapElement->setAttributeNode(NewAttribute("Theta",
0922                        twistedtrap->GetPolarAngleTheta()/degree));
0923    twistedtrapElement->setAttributeNode(NewAttribute("Phi",
0924                        twistedtrap->GetAzimuthalAnglePhi()/degree));
0925    twistedtrapElement->setAttributeNode(NewAttribute("PhiTwist",
0926                        twistedtrap->GetPhiTwist()/degree));
0927    twistedtrapElement->setAttributeNode(NewAttribute("aunit","deg"));
0928    twistedtrapElement->setAttributeNode(NewAttribute("lunit","mm"));
0929    
0930    solElement->appendChild(twistedtrapElement);
0931 }
0932 
0933 void PHG4GDMLWriteSolids::
0934 TwistedtrdWrite(xercesc::DOMElement* solElement,
0935                 const G4TwistedTrd* const twistedtrd)
0936 {
0937    const G4String& name = GenerateName(twistedtrd->GetName(),twistedtrd);
0938 
0939    xercesc::DOMElement* twistedtrdElement = NewElement("twistedtrd");
0940    twistedtrdElement->setAttributeNode(NewAttribute("name",name));
0941    twistedtrdElement->setAttributeNode(NewAttribute("x1",
0942                       2.0*twistedtrd->GetX1HalfLength()/mm));
0943    twistedtrdElement->setAttributeNode(NewAttribute("x2",
0944                       2.0*twistedtrd->GetX2HalfLength()/mm));
0945    twistedtrdElement->setAttributeNode(NewAttribute("y1",
0946                       2.0*twistedtrd->GetY1HalfLength()/mm));
0947    twistedtrdElement->setAttributeNode(NewAttribute("y2",
0948                       2.0*twistedtrd->GetY2HalfLength()/mm));
0949    twistedtrdElement->setAttributeNode(NewAttribute("z",
0950                       2.0*twistedtrd->GetZHalfLength()/mm));
0951    twistedtrdElement->setAttributeNode(NewAttribute("PhiTwist",
0952                       twistedtrd->GetPhiTwist()/degree));
0953    twistedtrdElement->setAttributeNode(NewAttribute("aunit","deg"));
0954    twistedtrdElement->setAttributeNode(NewAttribute("lunit","mm"));
0955    solElement->appendChild(twistedtrdElement);
0956 }
0957 
0958 void PHG4GDMLWriteSolids::
0959 TwistedtubsWrite(xercesc::DOMElement* solElement,
0960                  const G4TwistedTubs* const twistedtubs)
0961 {
0962    const G4String& name = GenerateName(twistedtubs->GetName(),twistedtubs);
0963 
0964    xercesc::DOMElement* twistedtubsElement = NewElement("twistedtubs");
0965    twistedtubsElement->setAttributeNode(NewAttribute("name",name));
0966    twistedtubsElement->setAttributeNode(NewAttribute("twistedangle",
0967                        twistedtubs->GetPhiTwist()/degree));
0968    twistedtubsElement->setAttributeNode(NewAttribute("endinnerrad",
0969                        twistedtubs->GetInnerRadius()/mm));
0970    twistedtubsElement->setAttributeNode(NewAttribute("endouterrad",
0971                        twistedtubs->GetOuterRadius()/mm));
0972    twistedtubsElement->setAttributeNode(NewAttribute("zlen",
0973                        2.0*twistedtubs->GetZHalfLength()/mm));
0974    twistedtubsElement->setAttributeNode(NewAttribute("phi",
0975                        twistedtubs->GetDPhi()/degree));
0976    twistedtubsElement->setAttributeNode(NewAttribute("aunit","deg"));
0977    twistedtubsElement->setAttributeNode(NewAttribute("lunit","mm"));
0978    solElement->appendChild(twistedtubsElement);
0979 }
0980 
0981 void PHG4GDMLWriteSolids::
0982 ZplaneWrite(xercesc::DOMElement* element, const G4double& z,
0983             const G4double& rmin, const G4double& rmax)
0984 {
0985    xercesc::DOMElement* zplaneElement = NewElement("zplane");
0986    zplaneElement->setAttributeNode(NewAttribute("z",z/mm));
0987    zplaneElement->setAttributeNode(NewAttribute("rmin",rmin/mm));
0988    zplaneElement->setAttributeNode(NewAttribute("rmax",rmax/mm));
0989    element->appendChild(zplaneElement);
0990 }
0991 
0992 void PHG4GDMLWriteSolids::
0993 RZPointWrite(xercesc::DOMElement* element, const G4double& r,
0994             const G4double& z)
0995 {
0996    xercesc::DOMElement* rzpointElement = NewElement("rzpoint");
0997    rzpointElement->setAttributeNode(NewAttribute("r",r/mm));
0998    rzpointElement->setAttributeNode(NewAttribute("z",z/mm));
0999    element->appendChild(rzpointElement);
1000 }
1001 
1002 void PHG4GDMLWriteSolids::
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 }