Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/persistency/gdml/src/G4GDMLWriteStructure.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /persistency/gdml/src/G4GDMLWriteStructure.cc (Version 11.3.0) and /persistency/gdml/src/G4GDMLWriteStructure.cc (Version 10.2.p1)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // G4GDMLWriteStructure implementation         << 
 27 //                                                 26 //
 28 // Author: Zoltan Torzsok, November 2007       <<  27 // $Id: G4GDMLWriteStructure.cc 91789 2015-08-06 08:14:46Z gcosmo $
                                                   >>  28 //
                                                   >>  29 // class G4GDMLWriteStructure Implementation
                                                   >>  30 //
                                                   >>  31 // Original author: Zoltan Torzsok, November 2007
                                                   >>  32 //
 29 // -------------------------------------------     33 // --------------------------------------------------------------------
 30                                                    34 
 31 #include "G4GDMLWriteStructure.hh"                 35 #include "G4GDMLWriteStructure.hh"
 32 #include "G4GDMLEvaluator.hh"                      36 #include "G4GDMLEvaluator.hh"
 33                                                    37 
 34 #include "G4Material.hh"                           38 #include "G4Material.hh"
 35 #include "G4ReflectedSolid.hh"                     39 #include "G4ReflectedSolid.hh"
 36 #include "G4DisplacedSolid.hh"                     40 #include "G4DisplacedSolid.hh"
 37 #include "G4LogicalVolumeStore.hh"                 41 #include "G4LogicalVolumeStore.hh"
 38 #include "G4PhysicalVolumeStore.hh"                42 #include "G4PhysicalVolumeStore.hh"
 39 #include "G4ReflectionFactory.hh"                  43 #include "G4ReflectionFactory.hh"
 40 #include "G4PVDivision.hh"                         44 #include "G4PVDivision.hh"
 41 #include "G4PVReplica.hh"                          45 #include "G4PVReplica.hh"
 42 #include "G4Region.hh"                             46 #include "G4Region.hh"
 43 #include "G4OpticalSurface.hh"                     47 #include "G4OpticalSurface.hh"
 44 #include "G4LogicalSkinSurface.hh"                 48 #include "G4LogicalSkinSurface.hh"
 45 #include "G4LogicalBorderSurface.hh"               49 #include "G4LogicalBorderSurface.hh"
 46                                                    50 
 47 #include "G4ProductionCuts.hh"                     51 #include "G4ProductionCuts.hh"
 48 #include "G4ProductionCutsTable.hh"                52 #include "G4ProductionCutsTable.hh"
 49 #include "G4Gamma.hh"                              53 #include "G4Gamma.hh"
 50 #include "G4Electron.hh"                           54 #include "G4Electron.hh"
 51 #include "G4Positron.hh"                           55 #include "G4Positron.hh"
 52 #include "G4Proton.hh"                             56 #include "G4Proton.hh"
 53                                                    57 
 54 #include "G4VSensitiveDetector.hh"             << 
 55 #include "G4AssemblyStore.hh"                  << 
 56 #include "G4AssemblyVolume.hh"                 << 
 57                                                << 
 58 G4int G4GDMLWriteStructure::levelNo = 0;  // C << 
 59                                                << 
 60 // ------------------------------------------- << 
 61 G4GDMLWriteStructure::G4GDMLWriteStructure()       58 G4GDMLWriteStructure::G4GDMLWriteStructure()
 62   : G4GDMLWriteParamvol()                      <<  59   : G4GDMLWriteParamvol(), cexport(false)
 63   , maxLevel(INT_MAX)                          << 
 64 {                                                  60 {
 65   reflFactory = G4ReflectionFactory::Instance(     61   reflFactory = G4ReflectionFactory::Instance();
 66 }                                                  62 }
 67                                                    63 
 68 // ------------------------------------------- << 
 69 G4GDMLWriteStructure::~G4GDMLWriteStructure()      64 G4GDMLWriteStructure::~G4GDMLWriteStructure()
 70 {                                                  65 {
 71 }                                                  66 }
 72                                                    67 
 73 // ------------------------------------------- <<  68 void
 74 void G4GDMLWriteStructure::DivisionvolWrite(   <<  69 G4GDMLWriteStructure::DivisionvolWrite(xercesc::DOMElement* volumeElement,
 75   xercesc::DOMElement* volumeElement, const G4 <<  70                                        const G4PVDivision* const divisionvol)
 76 {                                              <<  71 {
 77   EAxis axis       = kUndefined;               <<  72    EAxis axis = kUndefined;
 78   G4int number     = 0;                        <<  73    G4int number = 0;
 79   G4double width   = 0.0;                      <<  74    G4double width = 0.0;
 80   G4double offset  = 0.0;                      <<  75    G4double offset = 0.0;
 81   G4bool consuming = false;                    <<  76    G4bool consuming = false;
 82                                                <<  77 
 83   divisionvol->GetReplicationData(axis, number <<  78    divisionvol->GetReplicationData(axis,number,width,offset,consuming);
 84   axis = divisionvol->GetDivisionAxis();       <<  79    axis = divisionvol->GetDivisionAxis();
 85                                                <<  80 
 86   G4String unitString("mm");                   <<  81    G4String unitString("mm");
 87   G4String axisString("kUndefined");           <<  82    G4String axisString("kUndefined");
 88   if(axis == kXAxis)                           <<  83    if (axis==kXAxis) { axisString = "kXAxis"; }
 89   {                                            <<  84    else if (axis==kYAxis) { axisString = "kYAxis"; }
 90     axisString = "kXAxis";                     <<  85    else if (axis==kZAxis) { axisString = "kZAxis"; }
 91   }                                            <<  86    else if (axis==kRho)   { axisString = "kRho";     }
 92   else if(axis == kYAxis)                      <<  87    else if (axis==kPhi)   { axisString = "kPhi"; unitString = "rad"; }
 93   {                                            <<  88 
 94     axisString = "kYAxis";                     <<  89    const G4String name
 95   }                                            <<  90          = GenerateName(divisionvol->GetName(),divisionvol);
 96   else if(axis == kZAxis)                      <<  91    const G4String volumeref
 97   {                                            <<  92          = GenerateName(divisionvol->GetLogicalVolume()->GetName(),
 98     axisString = "kZAxis";                     <<  93                         divisionvol->GetLogicalVolume());
 99   }                                            <<  94 
100   else if(axis == kRho)                        <<  95    xercesc::DOMElement* divisionvolElement = NewElement("divisionvol");
101   {                                            <<  96    divisionvolElement->setAttributeNode(NewAttribute("axis",axisString));
102     axisString = "kRho";                       <<  97    divisionvolElement->setAttributeNode(NewAttribute("number",number));
103   }                                            <<  98    divisionvolElement->setAttributeNode(NewAttribute("width",width));
104   else if(axis == kPhi)                        <<  99    divisionvolElement->setAttributeNode(NewAttribute("offset",offset));
105   {                                            << 100    divisionvolElement->setAttributeNode(NewAttribute("unit",unitString));
106     axisString = "kPhi";                       << 101    xercesc::DOMElement* volumerefElement = NewElement("volumeref");
107     unitString = "rad";                        << 102    volumerefElement->setAttributeNode(NewAttribute("ref",volumeref));
108   }                                            << 103    divisionvolElement->appendChild(volumerefElement);
109                                                << 104    volumeElement->appendChild(divisionvolElement);
110   const G4String name = GenerateName(divisionv << 
111   const G4String volumeref =                   << 
112     GenerateName(divisionvol->GetLogicalVolume << 
113                  divisionvol->GetLogicalVolume << 
114                                                << 
115   xercesc::DOMElement* divisionvolElement = Ne << 
116   divisionvolElement->setAttributeNode(NewAttr << 
117   divisionvolElement->setAttributeNode(NewAttr << 
118   divisionvolElement->setAttributeNode(NewAttr << 
119   divisionvolElement->setAttributeNode(NewAttr << 
120   divisionvolElement->setAttributeNode(NewAttr << 
121   xercesc::DOMElement* volumerefElement = NewE << 
122   volumerefElement->setAttributeNode(NewAttrib << 
123   divisionvolElement->appendChild(volumerefEle << 
124   volumeElement->appendChild(divisionvolElemen << 
125 }                                                 105 }
126                                                   106 
127 // ------------------------------------------- << 
128 void G4GDMLWriteStructure::PhysvolWrite(xerces    107 void G4GDMLWriteStructure::PhysvolWrite(xercesc::DOMElement* volumeElement,
129                                         const     108                                         const G4VPhysicalVolume* const physvol,
130                                         const     109                                         const G4Transform3D& T,
131                                         const     110                                         const G4String& ModuleName)
132 {                                                 111 {
133   HepGeom::Scale3D scale;                      << 112    HepGeom::Scale3D scale;
134   HepGeom::Rotate3D rotate;                    << 113    HepGeom::Rotate3D rotate;
135   HepGeom::Translate3D translate;              << 114    HepGeom::Translate3D translate;
136                                                << 115 
137   T.getDecomposition(scale, rotate, translate) << 116    T.getDecomposition(scale,rotate,translate);
138                                                << 117 
139   const G4ThreeVector scl(scale(0, 0), scale(1 << 118    const G4ThreeVector scl(scale(0,0),scale(1,1),scale(2,2));
140   const G4ThreeVector rot = GetAngles(rotate.g << 119    const G4ThreeVector rot = GetAngles(rotate.getRotation());
141   const G4ThreeVector pos = T.getTranslation() << 120    const G4ThreeVector pos = T.getTranslation();
142                                                << 121 
143   const G4String name    = GenerateName(physvo << 122    const G4String name = GenerateName(physvol->GetName(),physvol);
144   const G4int copynumber = physvol->GetCopyNo( << 123    const G4int copynumber = physvol->GetCopyNo();
145                                                << 124 
146   xercesc::DOMElement* physvolElement = NewEle << 125    xercesc::DOMElement* physvolElement = NewElement("physvol");
147   physvolElement->setAttributeNode(NewAttribut << 126    physvolElement->setAttributeNode(NewAttribute("name",name));
148   if(copynumber)                               << 127    if (copynumber) physvolElement->setAttributeNode(NewAttribute("copynumber", copynumber));
149   {                                            << 128 
150     physvolElement->setAttributeNode(NewAttrib << 129    volumeElement->appendChild(physvolElement);
151   }                                            << 130 
152                                                << 131    G4LogicalVolume* lv;
153   volumeElement->appendChild(physvolElement);  << 132    // Is it reflected?
154                                                << 133    if (reflFactory->IsReflected(physvol->GetLogicalVolume()))
155   G4LogicalVolume* lv;                         << 134      {
156   // Is it reflected?                          << 135        lv = reflFactory->GetConstituentLV(physvol->GetLogicalVolume());
157   if(reflFactory->IsReflected(physvol->GetLogi << 136      }
158   {                                            << 137    else
159     lv = reflFactory->GetConstituentLV(physvol << 138      {
160   }                                            << 139        lv = physvol->GetLogicalVolume();
161   else                                         << 140      }
162   {                                            << 141    
163     lv = physvol->GetLogicalVolume();          << 142    const G4String volumeref = GenerateName(lv->GetName(), lv);
164   }                                            << 143 
165                                                << 144    if (ModuleName.empty())
166   const G4String volumeref = GenerateName(lv-> << 145    {
167                                                << 146       xercesc::DOMElement* volumerefElement = NewElement("volumeref");
168   if(ModuleName.empty())                       << 147       volumerefElement->setAttributeNode(NewAttribute("ref",volumeref));
169   {                                            << 148       physvolElement->appendChild(volumerefElement);
170     xercesc::DOMElement* volumerefElement = Ne << 149    }
171     volumerefElement->setAttributeNode(NewAttr << 150    else
172     physvolElement->appendChild(volumerefEleme << 151    {
173   }                                            << 152       xercesc::DOMElement* fileElement = NewElement("file");
174   else                                         << 153       fileElement->setAttributeNode(NewAttribute("name",ModuleName));
175   {                                            << 154       fileElement->setAttributeNode(NewAttribute("volname",volumeref));
176     xercesc::DOMElement* fileElement = NewElem << 155       physvolElement->appendChild(fileElement);
177     fileElement->setAttributeNode(NewAttribute << 156    }
178     fileElement->setAttributeNode(NewAttribute << 157 
179     physvolElement->appendChild(fileElement);  << 158    if (std::fabs(pos.x()) > kLinearPrecision
180   }                                            << 159     || std::fabs(pos.y()) > kLinearPrecision
181                                                << 160     || std::fabs(pos.z()) > kLinearPrecision)
182   if(std::fabs(pos.x()) > kLinearPrecision ||  << 161    {
183      std::fabs(pos.y()) > kLinearPrecision ||  << 162      PositionWrite(physvolElement,name+"_pos",pos);
184      std::fabs(pos.z()) > kLinearPrecision)    << 163    }
185   {                                            << 164    if (std::fabs(rot.x()) > kAngularPrecision
186     PositionWrite(physvolElement, name + "_pos << 165     || std::fabs(rot.y()) > kAngularPrecision
187   }                                            << 166     || std::fabs(rot.z()) > kAngularPrecision)
188   if(std::fabs(rot.x()) > kAngularPrecision || << 167    {
189      std::fabs(rot.y()) > kAngularPrecision || << 168      RotationWrite(physvolElement,name+"_rot",rot);
190      std::fabs(rot.z()) > kAngularPrecision)   << 169    }
191   {                                            << 170    if (std::fabs(scl.x()-1.0) > kRelativePrecision
192     RotationWrite(physvolElement, name + "_rot << 171     || std::fabs(scl.y()-1.0) > kRelativePrecision
193   }                                            << 172     || std::fabs(scl.z()-1.0) > kRelativePrecision)
194   if(std::fabs(scl.x() - 1.0) > kRelativePreci << 173    {
195      std::fabs(scl.y() - 1.0) > kRelativePreci << 174      ScaleWrite(physvolElement,name+"_scl",scl);
196      std::fabs(scl.z() - 1.0) > kRelativePreci << 175    }
197   {                                            << 176 }
198     ScaleWrite(physvolElement, name + "_scl",  << 177 
199   }                                            << 178 void G4GDMLWriteStructure::ReplicavolWrite(xercesc::DOMElement* volumeElement,
200 }                                              << 179                                      const G4VPhysicalVolume* const replicavol)
201                                                << 180 {
202 // ------------------------------------------- << 181    EAxis axis = kUndefined;
203 void G4GDMLWriteStructure::ReplicavolWrite(    << 182    G4int number = 0;
204   xercesc::DOMElement* volumeElement, const G4 << 183    G4double width = 0.0;
205 {                                              << 184    G4double offset = 0.0;
206   EAxis axis       = kUndefined;               << 185    G4bool consuming = false;
207   G4int number     = 0;                        << 186    G4String unitString("mm");
208   G4double width   = 0.0;                      << 187 
209   G4double offset  = 0.0;                      << 188    replicavol->GetReplicationData(axis,number,width,offset,consuming);
210   G4bool consuming = false;                    << 189 
211   G4String unitString("mm");                   << 190    const G4String volumeref
212                                                << 191          = GenerateName(replicavol->GetLogicalVolume()->GetName(),
213   replicavol->GetReplicationData(axis, number, << 192                         replicavol->GetLogicalVolume());
214                                                << 193 
215   const G4String volumeref = GenerateName(     << 194    xercesc::DOMElement* replicavolElement = NewElement("replicavol");
216     replicavol->GetLogicalVolume()->GetName(), << 195    replicavolElement->setAttributeNode(NewAttribute("number",number));
217                                                << 196    xercesc::DOMElement* volumerefElement = NewElement("volumeref");
218   xercesc::DOMElement* replicavolElement = New << 197    volumerefElement->setAttributeNode(NewAttribute("ref",volumeref));
219   replicavolElement->setAttributeNode(NewAttri << 198    replicavolElement->appendChild(volumerefElement);
220   xercesc::DOMElement* volumerefElement = NewE << 199    xercesc::DOMElement* replicateElement = NewElement("replicate_along_axis");
221   volumerefElement->setAttributeNode(NewAttrib << 200    replicavolElement->appendChild(replicateElement);
222   replicavolElement->appendChild(volumerefElem << 201 
223   xercesc::DOMElement* replicateElement = NewE << 202    xercesc::DOMElement* dirElement = NewElement("direction");
224   replicavolElement->appendChild(replicateElem << 203    if(axis==kXAxis)
225                                                << 204      { dirElement->setAttributeNode(NewAttribute("x","1")); }
226   xercesc::DOMElement* dirElement = NewElement << 205    else if(axis==kYAxis)
227   if(axis == kXAxis)                           << 206      { dirElement->setAttributeNode(NewAttribute("y","1")); }
228   {                                            << 207    else if(axis==kZAxis)
229     dirElement->setAttributeNode(NewAttribute( << 208      { dirElement->setAttributeNode(NewAttribute("z","1")); }
230   }                                            << 209    else if(axis==kRho)
231   else if(axis == kYAxis)                      << 210      { dirElement->setAttributeNode(NewAttribute("rho","1")); }
232   {                                            << 211    else if(axis==kPhi)
233     dirElement->setAttributeNode(NewAttribute( << 212      { dirElement->setAttributeNode(NewAttribute("phi","1"));
234   }                                            << 213        unitString="rad"; }
235   else if(axis == kZAxis)                      << 214    replicateElement->appendChild(dirElement);
236   {                                            << 215 
237     dirElement->setAttributeNode(NewAttribute( << 216    xercesc::DOMElement* widthElement = NewElement("width");
238   }                                            << 217    widthElement->setAttributeNode(NewAttribute("value",width));
239   else if(axis == kRho)                        << 218    widthElement->setAttributeNode(NewAttribute("unit",unitString));
240   {                                            << 219    replicateElement->appendChild(widthElement);
241     dirElement->setAttributeNode(NewAttribute( << 220 
242   }                                            << 221    xercesc::DOMElement* offsetElement = NewElement("offset");
243   else if(axis == kPhi)                        << 222    offsetElement->setAttributeNode(NewAttribute("value",offset));
244   {                                            << 223    offsetElement->setAttributeNode(NewAttribute("unit",unitString));
245     dirElement->setAttributeNode(NewAttribute( << 224    replicateElement->appendChild(offsetElement);
246     unitString = "rad";                        << 225 
247   }                                            << 226    volumeElement->appendChild(replicavolElement);
248   replicateElement->appendChild(dirElement);   << 227 }
249                                                << 228 
250   xercesc::DOMElement* widthElement = NewEleme << 229 void G4GDMLWriteStructure::
251   widthElement->setAttributeNode(NewAttribute( << 230 BorderSurfaceCache(const G4LogicalBorderSurface* const bsurf)
252   widthElement->setAttributeNode(NewAttribute( << 231 {
253   replicateElement->appendChild(widthElement); << 232    if (!bsurf)  { return; }
254                                                << 233 
255   xercesc::DOMElement* offsetElement = NewElem << 234    const G4SurfaceProperty* psurf = bsurf->GetSurfaceProperty();
256   offsetElement->setAttributeNode(NewAttribute << 235 
257   offsetElement->setAttributeNode(NewAttribute << 236    // Generate the new element for border-surface
258   replicateElement->appendChild(offsetElement) << 237    //
                                                   >> 238    xercesc::DOMElement* borderElement = NewElement("bordersurface");
                                                   >> 239    borderElement->setAttributeNode(NewAttribute("name", bsurf->GetName()));
                                                   >> 240    borderElement->setAttributeNode(NewAttribute("surfaceproperty",
                                                   >> 241                                                 psurf->GetName()));
                                                   >> 242 
                                                   >> 243    const G4String volumeref1 = GenerateName(bsurf->GetVolume1()->GetName(),
                                                   >> 244                                             bsurf->GetVolume1());
                                                   >> 245    const G4String volumeref2 = GenerateName(bsurf->GetVolume2()->GetName(),
                                                   >> 246                                             bsurf->GetVolume2());
                                                   >> 247    xercesc::DOMElement* volumerefElement1 = NewElement("physvolref");
                                                   >> 248    xercesc::DOMElement* volumerefElement2 = NewElement("physvolref");
                                                   >> 249    volumerefElement1->setAttributeNode(NewAttribute("ref",volumeref1));
                                                   >> 250    volumerefElement2->setAttributeNode(NewAttribute("ref",volumeref2));
                                                   >> 251    borderElement->appendChild(volumerefElement1);
                                                   >> 252    borderElement->appendChild(volumerefElement2);
                                                   >> 253 
                                                   >> 254    if (FindOpticalSurface(psurf))
                                                   >> 255    {
                                                   >> 256      const G4OpticalSurface* opsurf =
                                                   >> 257        dynamic_cast<const G4OpticalSurface*>(psurf);
                                                   >> 258      if (!opsurf)
                                                   >> 259      {
                                                   >> 260        G4Exception("G4GDMLWriteStructure::BorderSurfaceCache()",
                                                   >> 261                    "InvalidSetup", FatalException, "No optical surface found!");
                                                   >> 262        return;
                                                   >> 263      }
                                                   >> 264      OpticalSurfaceWrite(solidsElement, opsurf);
                                                   >> 265    }
                                                   >> 266 
                                                   >> 267    borderElementVec.push_back(borderElement);
                                                   >> 268 }
                                                   >> 269 
                                                   >> 270 void G4GDMLWriteStructure::
                                                   >> 271 SkinSurfaceCache(const G4LogicalSkinSurface* const ssurf)
                                                   >> 272 {
                                                   >> 273    if (!ssurf)  { return; }
                                                   >> 274 
                                                   >> 275    const G4SurfaceProperty* psurf = ssurf->GetSurfaceProperty();
                                                   >> 276 
                                                   >> 277    // Generate the new element for border-surface
                                                   >> 278    //
                                                   >> 279    xercesc::DOMElement* skinElement = NewElement("skinsurface");
                                                   >> 280    skinElement->setAttributeNode(NewAttribute("name", ssurf->GetName()));
                                                   >> 281    skinElement->setAttributeNode(NewAttribute("surfaceproperty",
                                                   >> 282                                               psurf->GetName()));
                                                   >> 283 
                                                   >> 284    const G4String volumeref = GenerateName(ssurf->GetLogicalVolume()->GetName(),
                                                   >> 285                                            ssurf->GetLogicalVolume());
                                                   >> 286    xercesc::DOMElement* volumerefElement = NewElement("volumeref");
                                                   >> 287    volumerefElement->setAttributeNode(NewAttribute("ref",volumeref));
                                                   >> 288    skinElement->appendChild(volumerefElement);
                                                   >> 289 
                                                   >> 290    if (FindOpticalSurface(psurf))
                                                   >> 291    {
                                                   >> 292      const G4OpticalSurface* opsurf =
                                                   >> 293        dynamic_cast<const G4OpticalSurface*>(psurf);
                                                   >> 294      if (!opsurf)
                                                   >> 295      {
                                                   >> 296        G4Exception("G4GDMLWriteStructure::SkinSurfaceCache()",
                                                   >> 297                    "InvalidSetup", FatalException, "No optical surface found!");
                                                   >> 298        return;
                                                   >> 299      }
                                                   >> 300      OpticalSurfaceWrite(solidsElement, opsurf);
                                                   >> 301    }
259                                                   302 
260   volumeElement->appendChild(replicavolElement << 303    skinElementVec.push_back(skinElement);
261 }                                                 304 }
262                                                   305 
263 // ------------------------------------------- << 
264 void G4GDMLWriteStructure::AssemblyWrite(xerce << 
265                                          const << 
266 {                                              << 
267   G4AssemblyStore* assemblies  = G4AssemblySto << 
268   G4AssemblyVolume* myassembly = assemblies->G << 
269                                                << 
270   xercesc::DOMElement* assemblyElement = NewEl << 
271   G4String name = "Assembly_" + std::to_string << 
272                                                << 
273   assemblyElement->setAttributeNode(NewAttribu << 
274                                                << 
275   auto vit = myassembly->GetTripletsIterator() << 
276                                                << 
277   G4int depth = 0;                             << 
278   const G4String ModuleName;                   << 
279                                                << 
280   for(std::size_t i5 = 0; i5 < myassembly->Tot << 
281   {                                            << 
282     G4LogicalVolume* lvol = (*vit).GetVolume() << 
283     if (lvol == nullptr)                       << 
284     {                                          << 
285       G4String message = "Nested assemblies no << 
286       G4Exception("G4GDMLWriteStructure::Assem << 
287                   FatalException, message);    << 
288       return;                                  << 
289     }                                          << 
290     TraverseVolumeTree(lvol, depth + 1);       << 
291                                                << 
292     const G4ThreeVector rot = GetAngles((*vit) << 
293     const G4ThreeVector pos = (*vit).GetTransl << 
294                                                << 
295     const G4String pname =                     << 
296       GenerateName((*vit).GetVolume()->GetName << 
297                                                << 
298     xercesc::DOMElement* physvolElement = NewE << 
299     physvolElement->setAttributeNode(NewAttrib << 
300                                                << 
301     assemblyElement->appendChild(physvolElemen << 
302                                                << 
303     const G4String volumeref =                 << 
304       GenerateName((*vit).GetVolume()->GetName << 
305                                                << 
306     xercesc::DOMElement* volumerefElement = Ne << 
307     volumerefElement->setAttributeNode(NewAttr << 
308     physvolElement->appendChild(volumerefEleme << 
309                                                << 
310     if(std::fabs(pos.x()) > kLinearPrecision | << 
311        std::fabs(pos.y()) > kLinearPrecision | << 
312        std::fabs(pos.z()) > kLinearPrecision)  << 
313     {                                          << 
314       PositionWrite(physvolElement,name+"_posi << 
315     }                                          << 
316                                                << 
317     if(std::fabs(rot.x()) > kAngularPrecision  << 
318        std::fabs(rot.y()) > kAngularPrecision  << 
319        std::fabs(rot.z()) > kAngularPrecision) << 
320     {                                          << 
321       RotationWrite(physvolElement,name+"_rota << 
322     }                                          << 
323     ++vit;                                     << 
324   }                                            << 
325                                                << 
326   volumeElement->appendChild(assemblyElement); << 
327 }                                              << 
328                                                << 
329 // ------------------------------------------- << 
330 void G4GDMLWriteStructure::BorderSurfaceCache( << 
331   const G4LogicalBorderSurface* const bsurf)   << 
332 {                                              << 
333   if(bsurf == nullptr)                         << 
334   {                                            << 
335     return;                                    << 
336   }                                            << 
337                                                << 
338   const G4SurfaceProperty* psurf = bsurf->GetS << 
339                                                << 
340   // Generate the new element for border-surfa << 
341   //                                           << 
342   const G4String& bsname             = Generat << 
343   const G4String& psname             = Generat << 
344   xercesc::DOMElement* borderElement = NewElem << 
345   borderElement->setAttributeNode(NewAttribute << 
346   borderElement->setAttributeNode(NewAttribute << 
347                                                << 
348   const G4String volumeref1 =                  << 
349     GenerateName(bsurf->GetVolume1()->GetName( << 
350   const G4String volumeref2 =                  << 
351     GenerateName(bsurf->GetVolume2()->GetName( << 
352   xercesc::DOMElement* volumerefElement1 = New << 
353   xercesc::DOMElement* volumerefElement2 = New << 
354   volumerefElement1->setAttributeNode(NewAttri << 
355   volumerefElement2->setAttributeNode(NewAttri << 
356   borderElement->appendChild(volumerefElement1 << 
357   borderElement->appendChild(volumerefElement2 << 
358                                                << 
359   if(FindOpticalSurface(psurf))                << 
360   {                                            << 
361     const G4OpticalSurface* opsurf =           << 
362       dynamic_cast<const G4OpticalSurface*>(ps << 
363     if(opsurf == nullptr)                      << 
364     {                                          << 
365       G4Exception("G4GDMLWriteStructure::Borde << 
366                   FatalException, "No optical  << 
367       return;                                  << 
368     }                                          << 
369     OpticalSurfaceWrite(solidsElement, opsurf) << 
370   }                                            << 
371                                                << 
372   borderElementVec.push_back(borderElement);   << 
373 }                                              << 
374                                                << 
375 // ------------------------------------------- << 
376 void G4GDMLWriteStructure::SkinSurfaceCache(   << 
377   const G4LogicalSkinSurface* const ssurf)     << 
378 {                                              << 
379   if(ssurf == nullptr)                         << 
380   {                                            << 
381     return;                                    << 
382   }                                            << 
383                                                << 
384   const G4SurfaceProperty* psurf = ssurf->GetS << 
385                                                << 
386   // Generate the new element for border-surfa << 
387   //                                           << 
388   const G4String& ssname           = GenerateN << 
389   const G4String& psname           = GenerateN << 
390   xercesc::DOMElement* skinElement = NewElemen << 
391   skinElement->setAttributeNode(NewAttribute(" << 
392   skinElement->setAttributeNode(NewAttribute(" << 
393                                                << 
394   const G4String volumeref = GenerateName(ssur << 
395                                           ssur << 
396   xercesc::DOMElement* volumerefElement = NewE << 
397   volumerefElement->setAttributeNode(NewAttrib << 
398   skinElement->appendChild(volumerefElement);  << 
399                                                << 
400   if(FindOpticalSurface(psurf))                << 
401   {                                            << 
402     const G4OpticalSurface* opsurf =           << 
403       dynamic_cast<const G4OpticalSurface*>(ps << 
404     if(opsurf == nullptr)                      << 
405     {                                          << 
406       G4Exception("G4GDMLWriteStructure::SkinS << 
407                   FatalException, "No optical  << 
408       return;                                  << 
409     }                                          << 
410     OpticalSurfaceWrite(solidsElement, opsurf) << 
411   }                                            << 
412                                                << 
413   skinElementVec.push_back(skinElement);       << 
414 }                                              << 
415                                                << 
416 // ------------------------------------------- << 
417 G4bool G4GDMLWriteStructure::FindOpticalSurfac    306 G4bool G4GDMLWriteStructure::FindOpticalSurface(const G4SurfaceProperty* psurf)
418 {                                                 307 {
419   const G4OpticalSurface* osurf = dynamic_cast << 308    const G4OpticalSurface* osurf = dynamic_cast<const G4OpticalSurface*>(psurf);
420   auto pos = std::find(opt_vec.cbegin(), opt_v << 309    std::vector<const G4OpticalSurface*>::const_iterator pos;
421   if(pos != opt_vec.cend())                    << 310    pos = std::find(opt_vec.begin(), opt_vec.end(), osurf);
422   {                                            << 311    if (pos != opt_vec.end()) { return false; }  // item already created!
423     return false;                              << 
424   }  // item already created!                  << 
425                                                   312 
426   opt_vec.push_back(osurf);  // cache it for f << 313    opt_vec.push_back(osurf);              // cache it for future reference
427   return true;                                 << 314    return true;
428 }                                                 315 }
429                                                   316 
430 // ------------------------------------------- << 317 const G4LogicalSkinSurface*
431 const G4LogicalSkinSurface* G4GDMLWriteStructu << 318 G4GDMLWriteStructure::GetSkinSurface(const G4LogicalVolume* const lvol)
432   const G4LogicalVolume* const lvol)           << 
433 {                                                 319 {
434   G4LogicalSkinSurface* surf = nullptr;        << 320   G4LogicalSkinSurface* surf = 0;
435   std::size_t nsurf = G4LogicalSkinSurface::Ge << 321   G4int nsurf = G4LogicalSkinSurface::GetNumberOfSkinSurfaces();
436   if(nsurf)                                    << 322   if (nsurf)
437   {                                               323   {
438     const G4LogicalSkinSurfaceTable* stable =     324     const G4LogicalSkinSurfaceTable* stable =
439       G4LogicalSkinSurface::GetSurfaceTable(); << 325           G4LogicalSkinSurface::GetSurfaceTable();
440     auto pos = stable->find(lvol);             << 326     std::vector<G4LogicalSkinSurface*>::const_iterator pos;
441     if(pos != stable->cend())                  << 327     for (pos = stable->begin(); pos != stable->end(); pos++)
442     {                                             328     {
443       surf = pos->second;                      << 329       if (lvol == (*pos)->GetLogicalVolume())
                                                   >> 330       {
                                                   >> 331         surf = *pos; break;
                                                   >> 332       }
444     }                                             333     }
445   }                                               334   }
446   return surf;                                    335   return surf;
447 }                                                 336 }
448                                                   337 
449 // ------------------------------------------- << 338 const G4LogicalBorderSurface*
450 const G4LogicalBorderSurface* G4GDMLWriteStruc << 339 G4GDMLWriteStructure::GetBorderSurface(const G4VPhysicalVolume* const pvol)
451   const G4VPhysicalVolume* const pvol)         << 
452 {                                                 340 {
453   G4LogicalBorderSurface* surf = nullptr;      << 341   G4LogicalBorderSurface* surf = 0;
454   std::size_t nsurf = G4LogicalBorderSurface:: << 342   G4int nsurf = G4LogicalBorderSurface::GetNumberOfBorderSurfaces();
455   if(nsurf)                                    << 343   if (nsurf)
456   {                                               344   {
457     const G4LogicalBorderSurfaceTable* btable     345     const G4LogicalBorderSurfaceTable* btable =
458       G4LogicalBorderSurface::GetSurfaceTable( << 346           G4LogicalBorderSurface::GetSurfaceTable();
459     for(auto pos = btable->cbegin(); pos != bt << 347     std::vector<G4LogicalBorderSurface*>::const_iterator pos;
460     {                                          << 348     for (pos = btable->begin(); pos != btable->end(); pos++)
461       if(pvol == pos->first.first)  // just th << 349     {
462       {                             // could b << 350       if (pvol == (*pos)->GetVolume1())  // just the first in the couple 
463         surf = pos->second;         // break;  << 351       {                                  // is enough
464         BorderSurfaceCache(surf);              << 352         surf = *pos; break;
465       }                                           353       }
466     }                                             354     }
467   }                                               355   }
468   return surf;                                    356   return surf;
469 }                                                 357 }
470                                                   358 
471 // ------------------------------------------- << 
472 void G4GDMLWriteStructure::SurfacesWrite()        359 void G4GDMLWriteStructure::SurfacesWrite()
473 {                                                 360 {
474 #ifdef G4VERBOSE                               << 361    G4cout << "G4GDML: Writing surfaces..." << G4endl;
475   G4cout << "G4GDML: Writing surfaces..." << G << 362 
476 #endif                                         << 363    std::vector<xercesc::DOMElement*>::const_iterator pos;
477   for(auto pos = skinElementVec.cbegin();      << 364    for (pos = skinElementVec.begin(); pos != skinElementVec.end(); pos++)
478            pos != skinElementVec.cend(); ++pos << 365    {
479   {                                            << 366      structureElement->appendChild(*pos);
480     structureElement->appendChild(*pos);       << 367    }
481   }                                            << 368    for (pos = borderElementVec.begin(); pos != borderElementVec.end(); pos++)
482   for(auto pos = borderElementVec.cbegin();    << 369    {
483            pos != borderElementVec.cend(); ++p << 370      structureElement->appendChild(*pos);
484   {                                            << 371    }
485     structureElement->appendChild(*pos);       << 
486   }                                            << 
487 }                                                 372 }
488                                                   373 
489 // ------------------------------------------- << 
490 void G4GDMLWriteStructure::StructureWrite(xerc    374 void G4GDMLWriteStructure::StructureWrite(xercesc::DOMElement* gdmlElement)
491 {                                                 375 {
492 #ifdef G4VERBOSE                               << 376    G4cout << "G4GDML: Writing structure..." << G4endl;
493   G4cout << "G4GDML: Writing structure..." <<  << 
494 #endif                                         << 
495                                                << 
496   // filling the list of phys volumes that are << 
497                                                << 
498   G4AssemblyStore* assemblies = G4AssemblyStor << 
499                                                << 
500   for(auto it = assemblies->cbegin(); it != as << 
501   {                                            << 
502     auto vit = (*it)->GetVolumesIterator();    << 
503                                                   377 
504     for(std::size_t i5 = 0; i5 < (*it)->TotalI << 378    structureElement = NewElement("structure");
505     {                                          << 379    gdmlElement->appendChild(structureElement);
506       G4String pvname = (*vit)->GetName();     << 
507       std::size_t pos = pvname.find("_impr_")  << 
508       G4String impID  = pvname.substr(pos);    << 
509                                                << 
510       pos   = impID.find("_");                 << 
511       impID = impID.substr(0, pos);            << 
512                                                << 
513       assemblyVolMap[*vit] = (*it)->GetAssembl << 
514       imprintsMap[*vit]    = std::atoi(impID.c << 
515       ++vit;                                   << 
516     }                                          << 
517   }                                            << 
518                                                << 
519   structureElement = NewElement("structure");  << 
520   gdmlElement->appendChild(structureElement);  << 
521 }                                                 380 }
522                                                   381 
523 // ------------------------------------------- << 382 G4Transform3D G4GDMLWriteStructure::
524 G4Transform3D G4GDMLWriteStructure::TraverseVo << 383 TraverseVolumeTree(const G4LogicalVolume* const volumePtr, const G4int depth)
525   const G4LogicalVolume* const volumePtr, cons << 
526 {                                                 384 {
527   if(VolumeMap().find(volumePtr) != VolumeMap( << 385    if (VolumeMap().find(volumePtr) != VolumeMap().end())
528   {                                            << 386    {
529     return VolumeMap()[volumePtr];  // Volume  << 387      return VolumeMap()[volumePtr]; // Volume is already processed
530   }                                            << 388    }
531                                                << 389    
532   G4VSolid* solidPtr = volumePtr->GetSolid();  << 390    G4VSolid* solidPtr = volumePtr->GetSolid();
533   G4Transform3D R, invR;                       << 391    G4Transform3D R,invR;
534   G4int trans = 0;                             << 392    G4int trans=0;
535                                                << 
536   std::map<const G4LogicalVolume*, G4GDMLAuxLi << 
537                                                << 
538   ++levelNo;                                   << 
539                                                << 
540   while(true)  // Solve possible displacement/ << 
541   {            // of the referenced solid!     << 
542     if(trans > maxTransforms)                  << 
543     {                                          << 
544       G4String ErrorMessage = "Referenced soli << 
545                               volumePtr->GetNa << 
546                               "' was displaced << 
547       G4Exception("G4GDMLWriteStructure::Trave << 
548                   FatalException, ErrorMessage << 
549     }                                          << 
550                                                << 
551     if(G4ReflectedSolid* refl = dynamic_cast<G << 
552     {                                          << 
553       R        = R * refl->GetTransform3D();   << 
554       solidPtr = refl->GetConstituentMovedSoli << 
555       ++trans;                                 << 
556       continue;                                << 
557     }                                          << 
558                                                << 
559     if(G4DisplacedSolid* disp = dynamic_cast<G << 
560     {                                          << 
561       R        = R * G4Transform3D(disp->GetOb << 
562                             disp->GetObjectTra << 
563       solidPtr = disp->GetConstituentMovedSoli << 
564       ++trans;                                 << 
565       continue;                                << 
566     }                                          << 
567                                                << 
568     break;                                     << 
569   }                                            << 
570                                                << 
571   // check if it is a reflected volume         << 
572   G4LogicalVolume* tmplv = const_cast<G4Logica << 
573                                                << 
574   if(reflFactory->IsReflected(tmplv))          << 
575   {                                            << 
576     tmplv = reflFactory->GetConstituentLV(tmpl << 
577     if(VolumeMap().find(tmplv) != VolumeMap(). << 
578     {                                          << 
579       return R;  // Volume is already processe << 
580     }                                          << 
581   }                                            << 
582                                                << 
583   // Only compute the inverse when necessary!  << 
584   //                                           << 
585   if(trans > 0)                                << 
586   {                                            << 
587     invR = R.inverse();                        << 
588   }                                            << 
589                                                << 
590   const G4String name = GenerateName(tmplv->Ge << 
591                                                << 
592   G4String materialref = "NULL";               << 
593                                                << 
594   if(volumePtr->GetMaterial())                 << 
595   {                                            << 
596     materialref = GenerateName(volumePtr->GetM << 
597                                volumePtr->GetM << 
598   }                                            << 
599                                                << 
600   const G4String solidref = GenerateName(solid << 
601                                                << 
602   xercesc::DOMElement* volumeElement = NewElem << 
603   volumeElement->setAttributeNode(NewAttribute << 
604   xercesc::DOMElement* materialrefElement = Ne << 
605   materialrefElement->setAttributeNode(NewAttr << 
606   volumeElement->appendChild(materialrefElemen << 
607   xercesc::DOMElement* solidrefElement = NewEl << 
608   solidrefElement->setAttributeNode(NewAttribu << 
609   volumeElement->appendChild(solidrefElement); << 
610                                                << 
611   std::size_t daughterCount = volumePtr->GetNo << 
612                                                << 
613   if(levelNo == maxLevel)  // Stop exporting i << 
614   {                                            << 
615     daughterCount = 0;                         << 
616   }                                            << 
617                                                << 
618   std::map<G4int, std::vector<G4int> > assembl << 
619                                                   393 
620   for(std::size_t i = 0; i < daughterCount; ++ << 394    std::map<const G4LogicalVolume*, G4GDMLAuxListType>::iterator auxiter; 
621   {                                            << 
622     const G4VPhysicalVolume* const physvol = v << 
623     const G4String ModuleName              = M << 
624                                                << 
625     G4Transform3D daughterR;                   << 
626                                                << 
627     if(ModuleName.empty())  // Check if subtre << 
628     {                       // a separate modu << 
629       daughterR = TraverseVolumeTree(physvol-> << 
630     }                                          << 
631     else                                       << 
632     {                                          << 
633       G4GDMLWriteStructure writer;             << 
634       daughterR = writer.Write(ModuleName, phy << 
635                                SchemaLocation, << 
636     }                                          << 
637                                                   395 
638     if(const G4PVDivision* const divisionvol = << 396    while (true) // Solve possible displacement/reflection
639          dynamic_cast<const G4PVDivision*>(phy << 397    {            // of the referenced solid!
640     {                                          << 398       if (trans>maxTransforms)
641       if(!G4Transform3D::Identity.isNear(invR  << 
642       {                                           399       {
643         G4String ErrorMessage = "Division volu << 400         G4String ErrorMessage = "Referenced solid in volume '"
644                                 "' can not be  << 401                               + volumePtr->GetName()
                                                   >> 402                               + "' was displaced/reflected too many times!";
645         G4Exception("G4GDMLWriteStructure::Tra    403         G4Exception("G4GDMLWriteStructure::TraverseVolumeTree()",
646                     "InvalidSetup", FatalExcep    404                     "InvalidSetup", FatalException, ErrorMessage);
647       }                                           405       }
648       DivisionvolWrite(volumeElement, division << 406 
649     }                                          << 407       if (G4ReflectedSolid* refl = dynamic_cast<G4ReflectedSolid*>(solidPtr))
650     else                                       << 
651     {                                          << 
652       if(physvol->IsParameterised())  // Is it << 
653       {                                           408       {
654         if(!G4Transform3D::Identity.isNear(inv << 409          R = R*refl->GetTransform3D();
655                                            kRe << 410          solidPtr = refl->GetConstituentMovedSolid();
656         {                                      << 411          trans++;
657           G4String ErrorMessage = "Parameteris << 412          continue;
658                                   "' can not b << 
659           G4Exception("G4GDMLWriteStructure::T << 
660                       "InvalidSetup", FatalExc << 
661         }                                      << 
662         ParamvolWrite(volumeElement, physvol); << 
663       }                                           413       }
664       else                                     << 414 
                                                   >> 415       if (G4DisplacedSolid* disp = dynamic_cast<G4DisplacedSolid*>(solidPtr))
665       {                                           416       {
666         if(physvol->IsReplicated())  // Is it  << 417          R = R*G4Transform3D(disp->GetObjectRotation(),
667         {                                      << 418                              disp->GetObjectTranslation());
668           if(!G4Transform3D::Identity.isNear(i << 419          solidPtr = disp->GetConstituentMovedSolid();
669                                              k << 420          trans++;
670           {                                    << 421          continue;
671             G4String ErrorMessage = "Replica v << 
672                                     "' can not << 
673             G4Exception("G4GDMLWriteStructure: << 
674                         "InvalidSetup", FatalE << 
675           }                                    << 
676           ReplicavolWrite(volumeElement, physv << 
677         }                                      << 
678         else  // Is it a physvol or an assembl << 
679         {                                      << 
680           if(assemblyVolMap.find(physvol) != a << 
681           {                                    << 
682             G4int assemblyID = assemblyVolMap[ << 
683                                                << 
684             G4String assemblyref = "Assembly_" << 
685                                                << 
686             // here I need to retrieve the imp << 
687                                                << 
688             G4int imprintID = imprintsMap[phys << 
689                                                << 
690             // there are 2 steps:              << 
691             //                                 << 
692             // 1) add assembly to the structur << 
693             // (but after the constituents vol << 
694             //                                 << 
695                                                << 
696             if(std::find(addedAssemblies.cbegi << 
697                          assemblyID) == addedA << 
698             {                                  << 
699               AssemblyWrite(structureElement,  << 
700               addedAssemblies.push_back(assemb << 
701               assemblyIDToAddedImprints[assemb << 
702             }                                  << 
703                                                << 
704             // 2) add the assembly (as physica << 
705             // (but only once), using it's ori << 
706             //                                 << 
707                                                << 
708             // here I need a check if assembly << 
709             // mother volume                   << 
710             std::vector<G4int>& addedImprints  << 
711             if(std::find(addedImprints.cbegin( << 
712                          imprintID) == addedIm << 
713             {                                  << 
714               G4String imprintname = "Imprint_ << 
715               imprintname          = GenerateN << 
716                                                << 
717               // I need to get those two from  << 
718               // the assembly I have the impri << 
719               //                               << 
720               G4Transform3D& transf = G4Assemb << 
721                                         ->GetA << 
722                                         ->GetI << 
723                                                << 
724               HepGeom::Scale3D scale;          << 
725               HepGeom::Rotate3D rotate;        << 
726               HepGeom::Translate3D translate;  << 
727                                                << 
728               transf.getDecomposition(scale, r << 
729                                                << 
730               const G4ThreeVector scl(scale(0, << 
731               const G4ThreeVector rot = GetAng << 
732               const G4ThreeVector pos = transf << 
733                                                << 
734               // here I need a normal physvol  << 
735                                                << 
736               xercesc::DOMElement* physvolElem << 
737               physvolElement->setAttributeNode << 
738                                                << 
739               xercesc::DOMElement* volumerefEl << 
740               volumerefElement->setAttributeNo << 
741               physvolElement->appendChild(volu << 
742                                                << 
743               if(std::fabs(pos.x()) > kLinearP << 
744                  std::fabs(pos.y()) > kLinearP << 
745                  std::fabs(pos.z()) > kLinearP << 
746               {                                << 
747                 PositionWrite(physvolElement,  << 
748               }                                << 
749               if(std::fabs(rot.x()) > kAngular << 
750                  std::fabs(rot.y()) > kAngular << 
751                  std::fabs(rot.z()) > kAngular << 
752               {                                << 
753                 RotationWrite(physvolElement,  << 
754               }                                << 
755               if(std::fabs(scl.x() - 1.0) > kR << 
756                  std::fabs(scl.y() - 1.0) > kR << 
757                  std::fabs(scl.z() - 1.0) > kR << 
758               {                                << 
759                 ScaleWrite(physvolElement, nam << 
760               }                                << 
761                                                << 
762               volumeElement->appendChild(physv << 
763               //                               << 
764               addedImprints.push_back(imprintI << 
765             }                                  << 
766           }                                    << 
767           else  // not part of assembly, so a  << 
768           {                                    << 
769             G4RotationMatrix rot;              << 
770             if(physvol->GetFrameRotation() !=  << 
771             {                                  << 
772               rot = *(physvol->GetFrameRotatio << 
773             }                                  << 
774             G4Transform3D P(rot, physvol->GetO << 
775                                                << 
776             PhysvolWrite(volumeElement, physvo << 
777                          ModuleName);          << 
778           }                                    << 
779         }                                      << 
780       }                                           422       }
781     }                                          << 
782     // BorderSurfaceCache(GetBorderSurface(phy << 
783     GetBorderSurface(physvol);                 << 
784   }                                            << 
785                                                   423 
786   if(cexport)                                  << 424       break;
787   {                                            << 425    }
788     ExportEnergyCuts(volumePtr);               << 
789   }                                            << 
790   // Add optional energy cuts                  << 
791                                                << 
792   if(sdexport)                                 << 
793   {                                            << 
794     ExportSD(volumePtr);                       << 
795   }                                            << 
796   // Add optional SDs                          << 
797                                                << 
798   // Here write the auxiliary info             << 
799   //                                           << 
800   auxiter = auxmap.find(volumePtr);            << 
801   if(auxiter != auxmap.cend())                 << 
802   {                                            << 
803     AddAuxInfo(&(auxiter->second), volumeEleme << 
804   }                                            << 
805                                                << 
806   structureElement->appendChild(volumeElement) << 
807   // Append the volume AFTER traversing the ch << 
808   // the order of volumes will be correct!     << 
809                                                << 
810   VolumeMap()[tmplv] = R;                      << 
811                                                << 
812   AddExtension(volumeElement, volumePtr);      << 
813   // Add any possible user defined extension a << 
814                                                << 
815   AddMaterial(volumePtr->GetMaterial());       << 
816   // Add the involved materials and solids!    << 
817                                                << 
818   AddSolid(solidPtr);                          << 
819                                                << 
820   SkinSurfaceCache(GetSkinSurface(volumePtr)); << 
821                                                << 
822   return R;                                    << 
823 }                                              << 
824                                                   426 
825 // ------------------------------------------- << 427    //check if it is a reflected volume
826 void G4GDMLWriteStructure::AddVolumeAuxiliary( << 428    G4LogicalVolume* tmplv = const_cast<G4LogicalVolume*>(volumePtr);
827                                                << 429   
                                                   >> 430    if (reflFactory->IsReflected(tmplv))
                                                   >> 431      {
                                                   >> 432        tmplv = reflFactory->GetConstituentLV(tmplv);
                                                   >> 433        if (VolumeMap().find(tmplv) != VolumeMap().end())
                                                   >> 434    {
                                                   >> 435      return R; // Volume is already processed
                                                   >> 436    }    
                                                   >> 437      }
                                                   >> 438    
                                                   >> 439    // Only compute the inverse when necessary!
                                                   >> 440    //
                                                   >> 441    if (trans>0) { invR = R.inverse(); }
                                                   >> 442 
                                                   >> 443    const G4String name
                                                   >> 444      = GenerateName(tmplv->GetName(), tmplv);
                                                   >> 445    const G4String materialref
                                                   >> 446          = GenerateName(volumePtr->GetMaterial()->GetName(),
                                                   >> 447                         volumePtr->GetMaterial());
                                                   >> 448    const G4String solidref
                                                   >> 449          = GenerateName(solidPtr->GetName(),solidPtr);
                                                   >> 450 
                                                   >> 451    xercesc::DOMElement* volumeElement = NewElement("volume");
                                                   >> 452    volumeElement->setAttributeNode(NewAttribute("name",name));
                                                   >> 453    xercesc::DOMElement* materialrefElement = NewElement("materialref");
                                                   >> 454    materialrefElement->setAttributeNode(NewAttribute("ref",materialref));
                                                   >> 455    volumeElement->appendChild(materialrefElement);
                                                   >> 456    xercesc::DOMElement* solidrefElement = NewElement("solidref");
                                                   >> 457    solidrefElement->setAttributeNode(NewAttribute("ref",solidref));
                                                   >> 458    volumeElement->appendChild(solidrefElement);
                                                   >> 459 
                                                   >> 460    const G4int daughterCount = volumePtr->GetNoDaughters();
                                                   >> 461        
                                                   >> 462    for (G4int i=0;i<daughterCount;i++)   // Traverse all the children!
                                                   >> 463      {
                                                   >> 464        const G4VPhysicalVolume* const physvol = volumePtr->GetDaughter(i);
                                                   >> 465        const G4String ModuleName = Modularize(physvol,depth);
                                                   >> 466      
                                                   >> 467        G4Transform3D daughterR;
                                                   >> 468      
                                                   >> 469        if (ModuleName.empty())   // Check if subtree requested to be 
                                                   >> 470    {                         // a separate module!
                                                   >> 471      daughterR = TraverseVolumeTree(physvol->GetLogicalVolume(),depth+1);
                                                   >> 472    }
                                                   >> 473        else
                                                   >> 474    {   
                                                   >> 475      G4GDMLWriteStructure writer;
                                                   >> 476      daughterR = writer.Write(ModuleName,physvol->GetLogicalVolume(),
                                                   >> 477             SchemaLocation,depth+1);
                                                   >> 478    }     
                                                   >> 479      
                                                   >> 480        if (const G4PVDivision* const divisionvol
                                                   >> 481      = dynamic_cast<const G4PVDivision*>(physvol)) // Is it division?
                                                   >> 482    {
                                                   >> 483      if (!G4Transform3D::Identity.isNear(invR*daughterR,kRelativePrecision))
                                                   >> 484        {
                                                   >> 485          G4String ErrorMessage = "Division volume in '" + name
                                                   >> 486      + "' can not be related to reflected solid!";
                                                   >> 487          G4Exception("G4GDMLWriteStructure::TraverseVolumeTree()",
                                                   >> 488          "InvalidSetup", FatalException, ErrorMessage);
                                                   >> 489        }
                                                   >> 490      DivisionvolWrite(volumeElement,divisionvol); 
                                                   >> 491    } else 
                                                   >> 492    if (physvol->IsParameterised())   // Is it a paramvol?
                                                   >> 493      {
                                                   >> 494        if (!G4Transform3D::Identity.isNear(invR*daughterR,kRelativePrecision))
                                                   >> 495          {
                                                   >> 496      G4String ErrorMessage = "Parameterised volume in '" + name
                                                   >> 497        + "' can not be related to reflected solid!";
                                                   >> 498      G4Exception("G4GDMLWriteStructure::TraverseVolumeTree()",
                                                   >> 499            "InvalidSetup", FatalException, ErrorMessage);
                                                   >> 500          }
                                                   >> 501        ParamvolWrite(volumeElement,physvol);
                                                   >> 502      } else
                                                   >> 503      if (physvol->IsReplicated())   // Is it a replicavol?
                                                   >> 504        {
                                                   >> 505          if (!G4Transform3D::Identity.isNear(invR*daughterR,kRelativePrecision))
                                                   >> 506      {
                                                   >> 507        G4String ErrorMessage = "Replica volume in '" + name
                                                   >> 508          + "' can not be related to reflected solid!";
                                                   >> 509        G4Exception("G4GDMLWriteStructure::TraverseVolumeTree()",
                                                   >> 510              "InvalidSetup", FatalException, ErrorMessage);
                                                   >> 511      }
                                                   >> 512          ReplicavolWrite(volumeElement,physvol); 
                                                   >> 513        }
                                                   >> 514      else   // Is it a physvol?
                                                   >> 515        {
                                                   >> 516          G4RotationMatrix rot;
                                                   >> 517          if (physvol->GetFrameRotation() != 0)
                                                   >> 518      {
                                                   >> 519        rot = *(physvol->GetFrameRotation());
                                                   >> 520      }
                                                   >> 521          G4Transform3D P(rot,physvol->GetObjectTranslation());
                                                   >> 522                    
                                                   >> 523          PhysvolWrite(volumeElement,physvol,invR*P*daughterR,ModuleName);
                                                   >> 524        }
                                                   >> 525        BorderSurfaceCache(GetBorderSurface(physvol));
                                                   >> 526      }
                                                   >> 527 
                                                   >> 528    if (cexport)  { ExportEnergyCuts(volumePtr); }
                                                   >> 529    // Add optional energy cuts
                                                   >> 530        
                                                   >> 531    // Here write the auxiliary info
                                                   >> 532    //
                                                   >> 533    auxiter = auxmap.find(volumePtr);  
                                                   >> 534    if (auxiter != auxmap.end())
                                                   >> 535      {
                                                   >> 536        AddAuxInfo(&(auxiter->second), volumeElement);
                                                   >> 537      }
                                                   >> 538 
                                                   >> 539    structureElement->appendChild(volumeElement);
                                                   >> 540    // Append the volume AFTER traversing the children so that
                                                   >> 541    // the order of volumes will be correct!
                                                   >> 542        
                                                   >> 543    VolumeMap()[tmplv] = R;
                                                   >> 544        
                                                   >> 545    AddExtension(volumeElement, volumePtr);
                                                   >> 546    // Add any possible user defined extension attached to a volume
                                                   >> 547        
                                                   >> 548    AddMaterial(volumePtr->GetMaterial());
                                                   >> 549    // Add the involved materials and solids!
                                                   >> 550        
                                                   >> 551    AddSolid(solidPtr);
                                                   >> 552        
                                                   >> 553    SkinSurfaceCache(GetSkinSurface(volumePtr));
                                                   >> 554        
                                                   >> 555    return R;
                                                   >> 556 }
                                                   >> 557 
                                                   >> 558 void
                                                   >> 559 G4GDMLWriteStructure::AddVolumeAuxiliary(G4GDMLAuxStructType myaux,
                                                   >> 560                                          const G4LogicalVolume* const lvol)
828 {                                                 561 {
829   auto pos = auxmap.find(lvol);                << 562   std::map<const G4LogicalVolume*,
830                                                << 563            G4GDMLAuxListType>::iterator pos = auxmap.find(lvol);
831   if(pos == auxmap.cend())                     << 
832   {                                            << 
833     auxmap[lvol] = G4GDMLAuxListType();        << 
834   }                                            << 
835                                                   564 
                                                   >> 565   if (pos == auxmap.end())  { auxmap[lvol] = G4GDMLAuxListType(); }
                                                   >> 566   
836   auxmap[lvol].push_back(myaux);                  567   auxmap[lvol].push_back(myaux);
837 }                                                 568 }
838                                                   569 
839 // ------------------------------------------- << 570 void
840 void G4GDMLWriteStructure::SetEnergyCutsExport << 571 G4GDMLWriteStructure::SetEnergyCutsExport(G4bool fcuts)
841 {                                                 572 {
842   cexport = fcuts;                                573   cexport = fcuts;
843 }                                                 574 }
844                                                   575 
845 // ------------------------------------------- << 576 void
846 void G4GDMLWriteStructure::ExportEnergyCuts(co << 577 G4GDMLWriteStructure::ExportEnergyCuts(const G4LogicalVolume* const lvol)
847 {                                                 578 {
848   G4GDMLEvaluator eval;                           579   G4GDMLEvaluator eval;
849   G4ProductionCuts* pcuts     = lvol->GetRegio << 580   G4ProductionCuts* pcuts = lvol->GetRegion()->GetProductionCuts();
850   G4ProductionCutsTable* ctab = G4ProductionCu    581   G4ProductionCutsTable* ctab = G4ProductionCutsTable::GetProductionCutsTable();
851   G4Gamma* gamma              = G4Gamma::Gamma << 582   G4Gamma* gamma = G4Gamma::Gamma();
852   G4Electron* eminus          = G4Electron::El << 583   G4Electron* eminus = G4Electron::Electron();
853   G4Positron* eplus           = G4Positron::Po << 584   G4Positron* eplus = G4Positron::Positron();
854   G4Proton* proton            = G4Proton::Prot << 585   G4Proton* proton = G4Proton::Proton();
855                                                << 586 
856   G4double gamma_cut = ctab->ConvertRangeToEne << 587   G4double gamma_cut = ctab->ConvertRangeToEnergy(gamma, lvol->GetMaterial(),
857     gamma, lvol->GetMaterial(), pcuts->GetProd << 588                                             pcuts->GetProductionCut("gamma"));
858   G4double eminus_cut = ctab->ConvertRangeToEn << 589   G4double eminus_cut = ctab->ConvertRangeToEnergy(eminus, lvol->GetMaterial(),
859     eminus, lvol->GetMaterial(), pcuts->GetPro << 590                                             pcuts->GetProductionCut("e-"));
860   G4double eplus_cut = ctab->ConvertRangeToEne << 591   G4double eplus_cut = ctab->ConvertRangeToEnergy(eplus, lvol->GetMaterial(),
861     eplus, lvol->GetMaterial(), pcuts->GetProd << 592                                             pcuts->GetProductionCut("e+"));
862   G4double proton_cut = ctab->ConvertRangeToEn << 593   G4double proton_cut = ctab->ConvertRangeToEnergy(proton, lvol->GetMaterial(),
863     proton, lvol->GetMaterial(), pcuts->GetPro << 594                                             pcuts->GetProductionCut("proton"));
864                                                << 595 
865   G4GDMLAuxStructType gammainfo  = { "gammaECu << 596   G4GDMLAuxStructType gammainfo = {"gammaECut",
866                                     eval.Conve << 597                                    eval.ConvertToString(gamma_cut), "MeV", 0};
867   G4GDMLAuxStructType eminusinfo = { "electron << 598   G4GDMLAuxStructType eminusinfo = {"electronECut",
868                                      eval.Conv << 599                                   eval.ConvertToString(eminus_cut), "MeV", 0};
869                                      0 };      << 600   G4GDMLAuxStructType eplusinfo = {"positronECut",
870   G4GDMLAuxStructType eplusinfo  = { "positron << 601                                   eval.ConvertToString(eplus_cut), "MeV", 0};
871                                     eval.Conve << 602   G4GDMLAuxStructType protinfo = {"protonECut",
872   G4GDMLAuxStructType protinfo   = { "protonEC << 603                                   eval.ConvertToString(proton_cut), "MeV", 0};
873                                    eval.Conver << 
874                                                   604 
875   AddVolumeAuxiliary(gammainfo, lvol);            605   AddVolumeAuxiliary(gammainfo, lvol);
876   AddVolumeAuxiliary(eminusinfo, lvol);           606   AddVolumeAuxiliary(eminusinfo, lvol);
877   AddVolumeAuxiliary(eplusinfo, lvol);            607   AddVolumeAuxiliary(eplusinfo, lvol);
878   AddVolumeAuxiliary(protinfo, lvol);             608   AddVolumeAuxiliary(protinfo, lvol);
879 }                                              << 
880                                                << 
881 // ------------------------------------------- << 
882 void G4GDMLWriteStructure::SetSDExport(G4bool  << 
883 {                                              << 
884   sdexport = fsd;                              << 
885 }                                              << 
886                                                << 
887 // ------------------------------------------- << 
888 void G4GDMLWriteStructure::ExportSD(const G4Lo << 
889 {                                              << 
890   G4VSensitiveDetector* sd = lvol->GetMasterSe << 
891                                                << 
892   if(sd != nullptr)                            << 
893   {                                            << 
894     G4String SDname = sd->GetName();           << 
895                                                << 
896     G4GDMLAuxStructType SDinfo = { "SensDet",  << 
897     AddVolumeAuxiliary(SDinfo, lvol);          << 
898   }                                            << 
899 }                                              << 
900                                                << 
901 // ------------------------------------------- << 
902 G4int G4GDMLWriteStructure::GetMaxExportLevel( << 
903 {                                              << 
904   return maxLevel;                             << 
905 }                                              << 
906                                                << 
907 // ------------------------------------------- << 
908 void G4GDMLWriteStructure::SetMaxExportLevel(G << 
909 {                                              << 
910   if(level <= 0)                               << 
911   {                                            << 
912     G4Exception("G4GDMLWriteStructure::Travers << 
913                 FatalException, "Levels to exp << 
914     return;                                    << 
915   }                                            << 
916   maxLevel = level;                            << 
917   levelNo  = 0;                                << 
918 }                                                 609 }
919                                                   610