source: trunk/source/persistency/gdml/src/G4GDMLWrite.cc @ 1258

Last change on this file since 1258 was 1228, checked in by garnier, 14 years ago

update geant4.9.3 tag

File size: 10.2 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer                                           *
4// *                                                                  *
5// * The  Geant4 software  is  copyright of the Copyright Holders  of *
6// * the Geant4 Collaboration.  It is provided  under  the terms  and *
7// * conditions of the Geant4 Software License,  included in the file *
8// * LICENSE and available at  http://cern.ch/geant4/license .  These *
9// * include a list of copyright holders.                             *
10// *                                                                  *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work  make  any representation or  warranty, express or implied, *
14// * regarding  this  software system or assume any liability for its *
15// * use.  Please see the license in the file  LICENSE  and URL above *
16// * for the full disclaimer and the limitation of liability.         *
17// *                                                                  *
18// * This  code  implementation is the result of  the  scientific and *
19// * technical work of the GEANT4 collaboration.                      *
20// * By using,  copying,  modifying or  distributing the software (or *
21// * any work based  on the software)  you  agree  to acknowledge its *
22// * use  in  resulting  scientific  publications,  and indicate your *
23// * acceptance of all terms of the Geant4 Software license.          *
24// ********************************************************************
25//
26//
27// $Id: G4GDMLWrite.cc,v 1.55 2009/04/24 15:34:20 gcosmo Exp $
28// GEANT4 tag $Name: geant4-09-03 $
29//
30// class G4GDMLWrite Implementation
31//
32// Original author: Zoltan Torzsok, November 2007
33//
34// --------------------------------------------------------------------
35
36#include <sys/stat.h>
37#include <iostream>
38
39#include "G4GDMLWrite.hh"
40
41#include "G4LogicalVolume.hh"
42#include "G4Transform3D.hh"
43#include "G4PVDivision.hh"
44
45G4bool G4GDMLWrite::addPointerToName = true;
46
47G4GDMLWrite::G4GDMLWrite() : extElement(0)
48{
49}
50
51G4GDMLWrite::~G4GDMLWrite()
52{
53}
54
55G4bool G4GDMLWrite::FileExists(const G4String& fname) const
56{
57  struct stat FileInfo;
58  return (stat(fname.c_str(),&FileInfo) == 0); 
59}
60
61G4GDMLWrite::VolumeMapType& G4GDMLWrite::VolumeMap()
62{
63   static VolumeMapType instance;
64   return instance;
65}
66
67G4GDMLWrite::PhysVolumeMapType& G4GDMLWrite::PvolumeMap()
68{
69   static PhysVolumeMapType instance;
70   return instance;
71}
72
73G4GDMLWrite::DepthMapType& G4GDMLWrite::DepthMap()
74{
75   static DepthMapType instance;
76   return instance;
77}
78
79void G4GDMLWrite::AddExtension(xercesc::DOMElement*,
80                               const G4LogicalVolume* const)
81{
82   // Empty implementation. To be overwritten by user for specific extensions
83   // related to attributes associated to volumes
84}
85
86void G4GDMLWrite::ExtensionWrite(xercesc::DOMElement*)
87{
88   // Empty implementation. To be overwritten by user for specific extensions
89}
90
91G4String G4GDMLWrite::GenerateName(const G4String& name, const void* const ptr)
92{
93   G4String nameOut;
94   std::stringstream stream; stream << name;
95   if (addPointerToName) { stream << ptr; };
96
97   nameOut=G4String(stream.str());
98   if(nameOut.contains(' '))
99   nameOut.erase(std::remove(nameOut.begin(),nameOut.end(),' '),nameOut.end());
100
101   return nameOut;
102}
103
104xercesc::DOMAttr* G4GDMLWrite::NewAttribute(const G4String& name,
105                                            const G4String& value)
106{
107   xercesc::XMLString::transcode(name,tempStr,99);
108   xercesc::DOMAttr* att = doc->createAttribute(tempStr);
109   xercesc::XMLString::transcode(value,tempStr,99);
110   att->setValue(tempStr);
111   return att;
112}
113
114xercesc::DOMAttr* G4GDMLWrite::NewAttribute(const G4String& name,
115                                            const G4double& value)
116{
117   xercesc::XMLString::transcode(name,tempStr,99);
118   xercesc::DOMAttr* att = doc->createAttribute(tempStr);
119   std::ostringstream ostream;
120   ostream.precision(15);
121   ostream << value;
122   G4String str = ostream.str();
123   xercesc::XMLString::transcode(str,tempStr,99);
124   att->setValue(tempStr);
125   return att;
126}
127
128xercesc::DOMElement* G4GDMLWrite::NewElement(const G4String& name)
129{
130   xercesc::XMLString::transcode(name,tempStr,99);
131   return doc->createElement(tempStr);
132}
133
134G4Transform3D G4GDMLWrite::Write(const G4String& fname,
135                                 const G4LogicalVolume* const logvol,
136                                 const G4String& setSchemaLocation,
137                                 const G4int depth,
138                                       G4bool refs)
139{
140   SchemaLocation = setSchemaLocation;
141   addPointerToName = refs;
142
143   if (depth==0) { G4cout << "G4GDML: Writing '" << fname << "'..." << G4endl; }
144   else   { G4cout << "G4GDML: Writing module '" << fname << "'..." << G4endl; }
145   
146   if (FileExists(fname))
147   {
148     G4String ErrorMessage = "File '"+fname+"' already exists!";
149     G4Exception("G4GDMLWrite::Write()", "InvalidSetup",
150                 FatalException, ErrorMessage);
151   }
152   
153   VolumeMap().clear(); // The module map is global for all modules,
154                        // so clear it only at once!
155
156   xercesc::XMLString::transcode("LS", tempStr, 99);
157   xercesc::DOMImplementation* impl =
158     xercesc::DOMImplementationRegistry::getDOMImplementation(tempStr);
159   xercesc::XMLString::transcode("Range", tempStr, 99);
160   impl = xercesc::DOMImplementationRegistry::getDOMImplementation(tempStr);
161   xercesc::XMLString::transcode("gdml", tempStr, 99);
162   doc = impl->createDocument(0,tempStr,0);
163   xercesc::DOMElement* gdml = doc->getDocumentElement();
164
165#if XERCES_VERSION_MAJOR >= 3
166                                             // DOM L3 as per Xerces 3.0 API
167    xercesc::DOMLSSerializer* writer =
168      ((xercesc::DOMImplementationLS*)impl)->createLSSerializer();
169
170    xercesc::DOMConfiguration *dc = writer->getDomConfig();
171    dc->setParameter(xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true);
172
173#else
174
175   xercesc::DOMWriter* writer =
176     ((xercesc::DOMImplementationLS*)impl)->createDOMWriter();
177
178   if (writer->canSetFeature(xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true))
179       writer->setFeature(xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true);
180
181#endif
182
183   gdml->setAttributeNode(NewAttribute("xmlns:xsi",
184                          "http://www.w3.org/2001/XMLSchema-instance"));
185   gdml->setAttributeNode(NewAttribute("xsi:noNamespaceSchemaLocation",
186                          SchemaLocation));
187
188   ExtensionWrite(gdml);
189   DefineWrite(gdml);
190   MaterialsWrite(gdml);
191   SolidsWrite(gdml);
192   StructureWrite(gdml);
193   SetupWrite(gdml,logvol);
194
195   G4Transform3D R = TraverseVolumeTree(logvol,depth);
196
197   SurfacesWrite();
198   xercesc::XMLFormatTarget *myFormTarget =
199     new xercesc::LocalFileFormatTarget(fname.c_str());
200
201   try
202   {
203#if XERCES_VERSION_MAJOR >= 3
204                                            // DOM L3 as per Xerces 3.0 API
205      xercesc::DOMLSOutput *theOutput =
206        ((xercesc::DOMImplementationLS*)impl)->createLSOutput();
207      theOutput->setByteStream(myFormTarget);
208      writer->write(doc, theOutput);
209#else
210      writer->writeNode(myFormTarget, *doc);
211#endif
212   }
213   catch (const xercesc::XMLException& toCatch)
214   {
215      char* message = xercesc::XMLString::transcode(toCatch.getMessage());
216      G4cout << "G4GDML: Exception message is: " << message << G4endl;
217      xercesc::XMLString::release(&message);
218      return G4Transform3D::Identity;
219   }
220   catch (const xercesc::DOMException& toCatch)
221   {
222      char* message = xercesc::XMLString::transcode(toCatch.msg);
223      G4cout << "G4GDML: Exception message is: " << message << G4endl;
224      xercesc::XMLString::release(&message);
225      return G4Transform3D::Identity;
226   }
227   catch (...)
228   {   
229      G4cout << "G4GDML: Unexpected Exception!" << G4endl;
230      return G4Transform3D::Identity;
231   }       
232
233   delete myFormTarget;
234   writer->release();
235
236   if (depth==0)
237   {
238     G4cout << "G4GDML: Writing '" << fname << "' done !" << G4endl;
239   }
240   else
241   {
242     G4cout << "G4GDML: Writing module '" << fname << "' done !" << G4endl;
243   }
244
245   return R;
246}
247
248void G4GDMLWrite::AddModule(const G4VPhysicalVolume* const physvol)
249{
250   G4String fname = GenerateName(physvol->GetName(),physvol);
251   G4cout << "G4GDML: Adding module '" << fname << "'..." << G4endl;
252
253   if (physvol == 0)
254   {
255     G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
256                 "Invalid NULL pointer is specified for modularization!");
257   }
258   if (dynamic_cast<const G4PVDivision*>(physvol))
259   {
260     G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
261                 "It is not possible to modularize by divisionvol!");
262   }
263   if (physvol->IsParameterised())
264   {
265     G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
266                 "It is not possible to modularize by parameterised volume!");
267   }
268   if (physvol->IsReplicated())
269   {
270     G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
271                 "It is not possible to modularize by replicated volume!");
272   }
273
274   PvolumeMap()[physvol] = fname;
275}
276
277void G4GDMLWrite::AddModule(const G4int depth)
278{
279   if (depth<0)
280   {
281     G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
282                 "Depth must be a positive number!");
283   }
284   if (DepthMap().find(depth) != DepthMap().end())
285   {
286     G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
287                 "Adding module(s) at this depth is already requested!");
288   }
289   DepthMap()[depth] = 0;
290}
291
292G4String G4GDMLWrite::Modularize( const G4VPhysicalVolume* const physvol,
293                                  const G4int depth )
294{
295   if (PvolumeMap().find(physvol) != PvolumeMap().end())
296   {
297     return PvolumeMap()[physvol]; // Modularize via physvol
298   }
299
300   if (DepthMap().find(depth) != DepthMap().end()) // Modularize via depth
301   {
302     std::stringstream stream;
303     stream << "depth" << depth << "_module" << DepthMap()[depth] << ".gdml";
304     DepthMap()[depth]++;           // There can be more modules at this depth!
305     return G4String(stream.str());
306   }
307
308   return G4String(""); // Empty string for module name = no modularization
309                        // was requested at that level/physvol!
310}
311
312void G4GDMLWrite::SetAddPointerToName(G4bool set)
313{
314   addPointerToName = set;
315}
Note: See TracBrowser for help on using the repository browser.