Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
G4GDMLWrite.cc
Go to the documentation of this file.
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$
28//
29// class G4GDMLWrite Implementation
30//
31// Original author: Zoltan Torzsok, November 2007
32//
33// --------------------------------------------------------------------
34
35#include <sys/stat.h>
36#include <iostream>
37
38#include "G4GDMLWrite.hh"
39
40#include "G4LogicalVolume.hh"
41#include "G4Transform3D.hh"
42#include "G4PVDivision.hh"
43
45
46G4GDMLWrite::G4GDMLWrite() : doc(0), extElement(0)
47{
48}
49
51{
52}
53
55{
56 struct stat FileInfo;
57 return (stat(fname.c_str(),&FileInfo) == 0);
58}
59
60G4GDMLWrite::VolumeMapType& G4GDMLWrite::VolumeMap()
61{
62 static VolumeMapType instance;
63 return instance;
64}
65
66G4GDMLWrite::PhysVolumeMapType& G4GDMLWrite::PvolumeMap()
67{
68 static PhysVolumeMapType instance;
69 return instance;
70}
71
72G4GDMLWrite::DepthMapType& G4GDMLWrite::DepthMap()
73{
74 static DepthMapType instance;
75 return instance;
76}
77
78void G4GDMLWrite::AddExtension(xercesc::DOMElement*,
79 const G4LogicalVolume* const)
80{
81 // Empty implementation. To be overwritten by user for specific extensions
82 // related to attributes associated to volumes
83}
84
85void G4GDMLWrite::ExtensionWrite(xercesc::DOMElement*)
86{
87 // Empty implementation. To be overwritten by user for specific extensions
88}
89
90G4String G4GDMLWrite::GenerateName(const G4String& name, const void* const ptr)
91{
92 G4String nameOut;
93 std::stringstream stream; stream << name;
94 if (addPointerToName) { stream << ptr; };
95
96 nameOut=G4String(stream.str());
97 if(nameOut.contains(' '))
98 nameOut.erase(std::remove(nameOut.begin(),nameOut.end(),' '),nameOut.end());
99
100 return nameOut;
101}
102
103xercesc::DOMAttr* G4GDMLWrite::NewAttribute(const G4String& name,
104 const G4String& value)
105{
106 xercesc::XMLString::transcode(name,tempStr,99);
107 xercesc::DOMAttr* att = doc->createAttribute(tempStr);
108 xercesc::XMLString::transcode(value,tempStr,99);
109 att->setValue(tempStr);
110 return att;
111}
112
113xercesc::DOMAttr* G4GDMLWrite::NewAttribute(const G4String& name,
114 const G4double& value)
115{
116 xercesc::XMLString::transcode(name,tempStr,99);
117 xercesc::DOMAttr* att = doc->createAttribute(tempStr);
118 std::ostringstream ostream;
119 ostream.precision(15);
120 ostream << value;
121 G4String str = ostream.str();
122 xercesc::XMLString::transcode(str,tempStr,99);
123 att->setValue(tempStr);
124 return att;
125}
126
127xercesc::DOMElement* G4GDMLWrite::NewElement(const G4String& name)
128{
129 xercesc::XMLString::transcode(name,tempStr,99);
130 return doc->createElement(tempStr);
131}
132
134 const G4LogicalVolume* const logvol,
135 const G4String& setSchemaLocation,
136 const G4int depth,
137 G4bool refs)
138{
139 SchemaLocation = setSchemaLocation;
140 addPointerToName = refs;
141
142 if (depth==0) { G4cout << "G4GDML: Writing '" << fname << "'..." << G4endl; }
143 else { G4cout << "G4GDML: Writing module '" << fname << "'..." << G4endl; }
144
145 if (FileExists(fname))
146 {
147 G4String ErrorMessage = "File '"+fname+"' already exists!";
148 G4Exception("G4GDMLWrite::Write()", "InvalidSetup",
149 FatalException, ErrorMessage);
150 }
151
152 VolumeMap().clear(); // The module map is global for all modules,
153 // so clear it only at once!
154
155 xercesc::XMLString::transcode("LS", tempStr, 99);
156 xercesc::DOMImplementationRegistry::getDOMImplementation(tempStr);
157 xercesc::XMLString::transcode("Range", tempStr, 99);
158 xercesc::DOMImplementation* impl =
159 xercesc::DOMImplementationRegistry::getDOMImplementation(tempStr);
160 xercesc::XMLString::transcode("gdml", tempStr, 99);
161 doc = impl->createDocument(0,tempStr,0);
162 xercesc::DOMElement* gdml = doc->getDocumentElement();
163
164#if XERCES_VERSION_MAJOR >= 3
165 // DOM L3 as per Xerces 3.0 API
166 xercesc::DOMLSSerializer* writer =
167 ((xercesc::DOMImplementationLS*)impl)->createLSSerializer();
168
169 xercesc::DOMConfiguration *dc = writer->getDomConfig();
170 dc->setParameter(xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true);
171
172#else
173
174 xercesc::DOMWriter* writer =
175 ((xercesc::DOMImplementationLS*)impl)->createDOMWriter();
176
177 if (writer->canSetFeature(xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true))
178 writer->setFeature(xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true);
179
180#endif
181
182 gdml->setAttributeNode(NewAttribute("xmlns:xsi",
183 "http://www.w3.org/2001/XMLSchema-instance"));
184 gdml->setAttributeNode(NewAttribute("xsi:noNamespaceSchemaLocation",
186
187 ExtensionWrite(gdml);
188 DefineWrite(gdml);
189 MaterialsWrite(gdml);
190 SolidsWrite(gdml);
191 StructureWrite(gdml);
192 SetupWrite(gdml,logvol);
193
194 G4Transform3D R = TraverseVolumeTree(logvol,depth);
195
197 xercesc::XMLFormatTarget *myFormTarget =
198 new xercesc::LocalFileFormatTarget(fname.c_str());
199
200 try
201 {
202#if XERCES_VERSION_MAJOR >= 3
203 // DOM L3 as per Xerces 3.0 API
204 xercesc::DOMLSOutput *theOutput =
205 ((xercesc::DOMImplementationLS*)impl)->createLSOutput();
206 theOutput->setByteStream(myFormTarget);
207 writer->write(doc, theOutput);
208#else
209 writer->writeNode(myFormTarget, *doc);
210#endif
211 }
212 catch (const xercesc::XMLException& toCatch)
213 {
214 char* message = xercesc::XMLString::transcode(toCatch.getMessage());
215 G4cout << "G4GDML: Exception message is: " << message << G4endl;
216 xercesc::XMLString::release(&message);
218 }
219 catch (const xercesc::DOMException& toCatch)
220 {
221 char* message = xercesc::XMLString::transcode(toCatch.msg);
222 G4cout << "G4GDML: Exception message is: " << message << G4endl;
223 xercesc::XMLString::release(&message);
225 }
226 catch (...)
227 {
228 G4cout << "G4GDML: Unexpected Exception!" << G4endl;
230 }
231
232 delete myFormTarget;
233 writer->release();
234
235 if (depth==0)
236 {
237 G4cout << "G4GDML: Writing '" << fname << "' done !" << G4endl;
238 }
239 else
240 {
241 G4cout << "G4GDML: Writing module '" << fname << "' done !" << G4endl;
242 }
243
244 return R;
245}
246
248{
249 G4String fname = GenerateName(physvol->GetName(),physvol);
250 G4cout << "G4GDML: Adding module '" << fname << "'..." << G4endl;
251
252 if (physvol == 0)
253 {
254 G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
255 "Invalid NULL pointer is specified for modularization!");
256 return;
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 return;
263 }
264 if (physvol->IsParameterised())
265 {
266 G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
267 "It is not possible to modularize by parameterised volume!");
268 return;
269 }
270 if (physvol->IsReplicated())
271 {
272 G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
273 "It is not possible to modularize by replicated volume!");
274 return;
275 }
276
277 PvolumeMap()[physvol] = fname;
278}
279
281{
282 if (depth<0)
283 {
284 G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
285 "Depth must be a positive number!");
286 }
287 if (DepthMap().find(depth) != DepthMap().end())
288 {
289 G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
290 "Adding module(s) at this depth is already requested!");
291 }
292 DepthMap()[depth] = 0;
293}
294
296 const G4int depth )
297{
298 if (PvolumeMap().find(physvol) != PvolumeMap().end())
299 {
300 return PvolumeMap()[physvol]; // Modularize via physvol
301 }
302
303 if (DepthMap().find(depth) != DepthMap().end()) // Modularize via depth
304 {
305 std::stringstream stream;
306 stream << "depth" << depth << "_module" << DepthMap()[depth] << ".gdml";
307 DepthMap()[depth]++; // There can be more modules at this depth!
308 return G4String(stream.str());
309 }
310
311 return G4String(""); // Empty string for module name = no modularization
312 // was requested at that level/physvol!
313}
314
316{
317 addPointerToName = set;
318}
@ FatalException
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
virtual void SurfacesWrite()=0
virtual void MaterialsWrite(xercesc::DOMElement *)=0
DepthMapType & DepthMap()
Definition: G4GDMLWrite.cc:72
G4bool FileExists(const G4String &) const
Definition: G4GDMLWrite.cc:54
static void SetAddPointerToName(G4bool)
Definition: G4GDMLWrite.cc:315
void AddModule(const G4VPhysicalVolume *const topVol)
Definition: G4GDMLWrite.cc:247
xercesc::DOMElement * NewElement(const G4String &)
Definition: G4GDMLWrite.cc:127
G4String GenerateName(const G4String &, const void *const)
Definition: G4GDMLWrite.cc:90
G4String SchemaLocation
Definition: G4GDMLWrite.hh:121
G4String Modularize(const G4VPhysicalVolume *const topvol, const G4int depth)
Definition: G4GDMLWrite.cc:295
virtual void AddExtension(xercesc::DOMElement *, const G4LogicalVolume *const)
Definition: G4GDMLWrite.cc:78
virtual void SetupWrite(xercesc::DOMElement *, const G4LogicalVolume *const)=0
G4Transform3D Write(const G4String &filename, const G4LogicalVolume *const topLog, const G4String &schemaPath, const G4int depth, G4bool storeReferences=true)
Definition: G4GDMLWrite.cc:133
virtual G4Transform3D TraverseVolumeTree(const G4LogicalVolume *const, const G4int)=0
virtual ~G4GDMLWrite()
Definition: G4GDMLWrite.cc:50
virtual void DefineWrite(xercesc::DOMElement *)=0
xercesc::DOMDocument * doc
Definition: G4GDMLWrite.hh:123
xercesc::DOMAttr * NewAttribute(const G4String &, const G4String &)
Definition: G4GDMLWrite.cc:103
static G4bool addPointerToName
Definition: G4GDMLWrite.hh:122
virtual void ExtensionWrite(xercesc::DOMElement *)
Definition: G4GDMLWrite.cc:85
virtual void SolidsWrite(xercesc::DOMElement *)=0
VolumeMapType & VolumeMap()
Definition: G4GDMLWrite.cc:60
virtual void StructureWrite(xercesc::DOMElement *)=0
XMLCh tempStr[10000]
Definition: G4GDMLWrite.hh:125
PhysVolumeMapType & PvolumeMap()
Definition: G4GDMLWrite.cc:66
G4bool contains(const std::string &) const
virtual G4bool IsReplicated() const =0
const G4String & GetName() const
virtual G4bool IsParameterised() const =0
static const Transform3D Identity
Definition: Transform3D.h:197
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41