Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/persistency/gdml/src/G4GDMLWrite.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 ]

  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 // G4GDMLWrite implementation
 27 //
 28 // Author: Zoltan Torzsok, November 2007
 29 // --------------------------------------------------------------------
 30 
 31 #include <sys/stat.h>
 32 #include <iostream>
 33 
 34 #include "G4GDMLWrite.hh"
 35 
 36 #include "G4LogicalVolume.hh"
 37 #include "G4Transform3D.hh"
 38 #include "G4PVDivision.hh"
 39 
 40 G4bool G4GDMLWrite::addPointerToName = true;
 41 
 42 // --------------------------------------------------------------------
 43 G4GDMLWrite::G4GDMLWrite()
 44 {
 45 }
 46 
 47 // --------------------------------------------------------------------
 48 G4GDMLWrite::~G4GDMLWrite()
 49 {
 50 }
 51 
 52 // --------------------------------------------------------------------
 53 G4bool G4GDMLWrite::FileExists(const G4String& fname) const
 54 {
 55   struct stat FileInfo;
 56   return (stat(fname.c_str(), &FileInfo) == 0);
 57 }
 58 
 59 // --------------------------------------------------------------------
 60 G4GDMLWrite::VolumeMapType& G4GDMLWrite::VolumeMap()
 61 {
 62   static VolumeMapType instance;
 63   return instance;
 64 }
 65 
 66 G4GDMLWrite::PhysVolumeMapType& G4GDMLWrite::PvolumeMap()
 67 {
 68   static PhysVolumeMapType instance;
 69   return instance;
 70 }
 71 
 72 // --------------------------------------------------------------------
 73 G4GDMLWrite::DepthMapType& G4GDMLWrite::DepthMap()
 74 {
 75   static DepthMapType instance;
 76   return instance;
 77 }
 78 
 79 // --------------------------------------------------------------------
 80 void G4GDMLWrite::AddExtension(xercesc::DOMElement*,
 81                                const G4LogicalVolume* const)
 82 {
 83   // Empty implementation. To be overwritten by user for specific extensions
 84   // related to attributes associated to volumes
 85 }
 86 
 87 // --------------------------------------------------------------------
 88 void G4GDMLWrite::ExtensionWrite(xercesc::DOMElement*)
 89 {
 90   // Empty implementation. To be overwritten by user for specific extensions
 91 }
 92 
 93 // --------------------------------------------------------------------
 94 void G4GDMLWrite::AddAuxInfo(G4GDMLAuxListType* auxInfoList,
 95                              xercesc::DOMElement* element)
 96 {
 97   for(auto iaux = auxInfoList->cbegin(); iaux != auxInfoList->cend(); ++iaux)
 98   {
 99     xercesc::DOMElement* auxiliaryElement = NewElement("auxiliary");
100     element->appendChild(auxiliaryElement);
101 
102     auxiliaryElement->setAttributeNode(NewAttribute("auxtype", (*iaux).type));
103     auxiliaryElement->setAttributeNode(NewAttribute("auxvalue", (*iaux).value));
104     if(((*iaux).unit) != "")
105     {
106       auxiliaryElement->setAttributeNode(NewAttribute("auxunit", (*iaux).unit));
107     }
108 
109     if(iaux->auxList)
110     {
111       AddAuxInfo(iaux->auxList, auxiliaryElement);
112     }
113   }
114   return;
115 }
116 
117 // --------------------------------------------------------------------
118 void G4GDMLWrite::UserinfoWrite(xercesc::DOMElement* gdmlElement)
119 {
120   if(auxList.size() > 0)
121   {
122 #ifdef G4VERBOSE
123     G4cout << "G4GDML: Writing userinfo..." << G4endl;
124 #endif
125     userinfoElement = NewElement("userinfo");
126     gdmlElement->appendChild(userinfoElement);
127     AddAuxInfo(&auxList, userinfoElement);
128   }
129 }
130 
131 // --------------------------------------------------------------------
132 G4String G4GDMLWrite::GenerateName(const G4String& name, const void* const ptr)
133 {
134   G4String nameOut;
135   std::stringstream stream;
136   stream << name;
137   if(addPointerToName)
138   {
139     stream << ptr;
140   };
141 
142   nameOut = G4String(stream.str());
143   std::vector<char> toremove = { ' ', '/', ':', '#', '+' };
144   for(auto c : toremove)
145   {
146     if(G4StrUtil::contains(nameOut, c))
147     {
148       std::replace(nameOut.begin(), nameOut.end(), c, '_');
149     }
150   }
151   return nameOut;
152 }
153 
154 // --------------------------------------------------------------------
155 xercesc::DOMAttr* G4GDMLWrite::NewAttribute(const G4String& name,
156                                             const G4String& value)
157 {
158   XMLCh* tempStr = NULL;
159   tempStr = xercesc::XMLString::transcode(name);
160   xercesc::DOMAttr* att = doc->createAttribute(tempStr);
161   xercesc::XMLString::release(&tempStr);
162 
163   tempStr = xercesc::XMLString::transcode(value);
164   att->setValue(tempStr);
165   xercesc::XMLString::release(&tempStr);
166 
167   return att;
168 }
169 
170 // --------------------------------------------------------------------
171 xercesc::DOMAttr* G4GDMLWrite::NewAttribute(const G4String& name,
172                                             const G4double& value)
173 {
174   XMLCh* tempStr = NULL;
175   tempStr = xercesc::XMLString::transcode(name);
176   xercesc::DOMAttr* att = doc->createAttribute(tempStr);
177   xercesc::XMLString::release(&tempStr);
178 
179   std::ostringstream ostream;
180   ostream.precision(15);
181   ostream << value;
182   G4String str = ostream.str();
183 
184   tempStr = xercesc::XMLString::transcode(str);
185   att->setValue(tempStr);
186   xercesc::XMLString::release(&tempStr);
187 
188   return att;
189 }
190 
191 // --------------------------------------------------------------------
192 xercesc::DOMElement* G4GDMLWrite::NewElement(const G4String& name)
193 {
194   XMLCh* tempStr = NULL;
195   tempStr = xercesc::XMLString::transcode(name);
196   xercesc::DOMElement* elem = doc->createElement(tempStr);
197   xercesc::XMLString::release(&tempStr);
198 
199   return elem;
200 }
201 
202 // --------------------------------------------------------------------
203 G4Transform3D G4GDMLWrite::Write(const G4String& fname,
204                                  const G4LogicalVolume* const logvol,
205                                  const G4String& setSchemaLocation,
206                                  const G4int depth, G4bool refs)
207 {
208   SchemaLocation   = setSchemaLocation;
209   addPointerToName = refs;
210 #ifdef G4VERBOSE
211   if(depth == 0)
212   {
213     G4cout << "G4GDML: Writing '" << fname << "'..." << G4endl;
214   }
215   else
216   {
217     G4cout << "G4GDML: Writing module '" << fname << "'..." << G4endl;
218   }
219 #endif
220   if(!overwriteOutputFile && FileExists(fname))
221   {
222     G4String ErrorMessage = "File '" + fname + "' already exists!";
223     G4Exception("G4GDMLWrite::Write()", "InvalidSetup", FatalException,
224                 ErrorMessage);
225   }
226 
227   VolumeMap().clear();  // The module map is global for all modules,
228                         // so clear it only at once!
229 
230   XMLCh* tempStr = NULL;
231   tempStr = xercesc::XMLString::transcode("LS");
232   xercesc::DOMImplementationRegistry::getDOMImplementation(tempStr);
233   xercesc::XMLString::release(&tempStr);
234   tempStr = xercesc::XMLString::transcode("Range");
235   xercesc::DOMImplementation* impl =
236     xercesc::DOMImplementationRegistry::getDOMImplementation(tempStr);
237   xercesc::XMLString::release(&tempStr);
238   tempStr = xercesc::XMLString::transcode("gdml");
239   doc                       = impl->createDocument(0, tempStr, 0);
240   xercesc::XMLString::release(&tempStr);
241   xercesc::DOMElement* gdml = doc->getDocumentElement();
242 
243 #if XERCES_VERSION_MAJOR >= 3
244   // DOM L3 as per Xerces 3.0 API
245   xercesc::DOMLSSerializer* writer =
246     ((xercesc::DOMImplementationLS*) impl)->createLSSerializer();
247 
248   xercesc::DOMConfiguration* dc = writer->getDomConfig();
249   dc->setParameter(xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true);
250 
251 #else
252 
253   xercesc::DOMWriter* writer =
254     ((xercesc::DOMImplementationLS*) impl)->createDOMWriter();
255 
256   if(writer->canSetFeature(xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true))
257     writer->setFeature(xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true);
258 
259 #endif
260 
261   gdml->setAttributeNode(
262     NewAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"));
263   gdml->setAttributeNode(
264     NewAttribute("xsi:noNamespaceSchemaLocation", SchemaLocation));
265 
266   ExtensionWrite(gdml);
267   DefineWrite(gdml);
268   MaterialsWrite(gdml);
269   SolidsWrite(gdml);
270   StructureWrite(gdml);
271   UserinfoWrite(gdml);
272   SetupWrite(gdml, logvol);
273 
274   G4Transform3D R = TraverseVolumeTree(logvol, depth);
275 
276   SurfacesWrite();
277   xercesc::XMLFormatTarget* myFormTarget =
278     new xercesc::LocalFileFormatTarget(fname.c_str());
279 
280   try
281   {
282 #if XERCES_VERSION_MAJOR >= 3
283     // DOM L3 as per Xerces 3.0 API
284     xercesc::DOMLSOutput* theOutput =
285       ((xercesc::DOMImplementationLS*) impl)->createLSOutput();
286     theOutput->setByteStream(myFormTarget);
287     writer->write(doc, theOutput);
288 #else
289     writer->writeNode(myFormTarget, *doc);
290 #endif
291   } catch(const xercesc::XMLException& toCatch)
292   {
293     char* message = xercesc::XMLString::transcode(toCatch.getMessage());
294     G4cout << "G4GDML: Exception message is: " << message << G4endl;
295     xercesc::XMLString::release(&message);
296     return G4Transform3D::Identity;
297   } catch(const xercesc::DOMException& toCatch)
298   {
299     char* message = xercesc::XMLString::transcode(toCatch.msg);
300     G4cout << "G4GDML: Exception message is: " << message << G4endl;
301     xercesc::XMLString::release(&message);
302     return G4Transform3D::Identity;
303   } catch(...)
304   {
305     G4cout << "G4GDML: Unexpected Exception!" << G4endl;
306     return G4Transform3D::Identity;
307   }
308 
309   delete myFormTarget;
310   writer->release();
311 
312   if(depth == 0)
313   {
314     G4cout << "G4GDML: Writing '" << fname << "' done !" << G4endl;
315   }
316   else
317   {
318 #ifdef G4VERBOSE
319     G4cout << "G4GDML: Writing module '" << fname << "' done !" << G4endl;
320 #endif
321   }
322 
323   return R;
324 }
325 
326 // --------------------------------------------------------------------
327 void G4GDMLWrite::AddModule(const G4VPhysicalVolume* const physvol)
328 {
329   G4String fname = GenerateName(physvol->GetName(), physvol);
330   G4cout << "G4GDML: Adding module '" << fname << "'..." << G4endl;
331 
332   if(physvol == nullptr)
333   {
334     G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
335                 "Invalid NULL pointer is specified for modularization!");
336     return;
337   }
338   if(dynamic_cast<const G4PVDivision*>(physvol))
339   {
340     G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
341                 "It is not possible to modularize by divisionvol!");
342     return;
343   }
344   if(physvol->IsParameterised())
345   {
346     G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
347                 "It is not possible to modularize by parameterised volume!");
348     return;
349   }
350   if(physvol->IsReplicated())
351   {
352     G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
353                 "It is not possible to modularize by replicated volume!");
354     return;
355   }
356 
357   PvolumeMap()[physvol] = fname;
358 }
359 
360 // --------------------------------------------------------------------
361 void G4GDMLWrite::AddModule(const G4int depth)
362 {
363   if(depth < 0)
364   {
365     G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
366                 "Depth must be a positive number!");
367   }
368   if(DepthMap().find(depth) != DepthMap().end())
369   {
370     G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
371                 "Adding module(s) at this depth is already requested!");
372   }
373   DepthMap()[depth] = 0;
374 }
375 
376 // --------------------------------------------------------------------
377 G4String G4GDMLWrite::Modularize(const G4VPhysicalVolume* const physvol,
378                                  const G4int depth)
379 {
380   if(PvolumeMap().find(physvol) != PvolumeMap().cend())
381   {
382     return PvolumeMap()[physvol];  // Modularize via physvol
383   }
384 
385   if(DepthMap().find(depth) != DepthMap().cend())  // Modularize via depth
386   {
387     std::stringstream stream;
388     stream << "depth" << depth << "_module" << DepthMap()[depth] << ".gdml";
389     DepthMap()[depth]++;  // There can be more modules at this depth!
390     return G4String(stream.str());
391   }
392 
393   return G4String("");  // Empty string for module name = no modularization
394                         // was requested at that level/physvol!
395 }
396 
397 // --------------------------------------------------------------------
398 void G4GDMLWrite::AddAuxiliary(G4GDMLAuxStructType myaux)
399 {
400   auxList.push_back(myaux);
401 }
402 
403 // --------------------------------------------------------------------
404 void G4GDMLWrite::SetOutputFileOverwrite(G4bool flag)
405 {
406   overwriteOutputFile = flag; 
407 }
408 
409 // --------------------------------------------------------------------
410 void G4GDMLWrite::SetAddPointerToName(G4bool set)
411 {
412   addPointerToName = set;
413 }
414