G4GDMLWrite.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id$
00028 //
00029 // class G4GDMLWrite Implementation
00030 //
00031 // Original author: Zoltan Torzsok, November 2007
00032 //
00033 // --------------------------------------------------------------------
00034 
00035 #include <sys/stat.h>
00036 #include <iostream>
00037 
00038 #include "G4GDMLWrite.hh"
00039 
00040 #include "G4LogicalVolume.hh"
00041 #include "G4Transform3D.hh"
00042 #include "G4PVDivision.hh"
00043 
00044 G4bool G4GDMLWrite::addPointerToName = true;
00045 
00046 G4GDMLWrite::G4GDMLWrite() : doc(0), extElement(0)
00047 {
00048 }
00049 
00050 G4GDMLWrite::~G4GDMLWrite()
00051 {
00052 }
00053 
00054 G4bool G4GDMLWrite::FileExists(const G4String& fname) const
00055 {
00056   struct stat FileInfo;
00057   return (stat(fname.c_str(),&FileInfo) == 0); 
00058 }
00059 
00060 G4GDMLWrite::VolumeMapType& G4GDMLWrite::VolumeMap()
00061 {
00062    static VolumeMapType instance;
00063    return instance;
00064 }
00065 
00066 G4GDMLWrite::PhysVolumeMapType& G4GDMLWrite::PvolumeMap()
00067 {
00068    static PhysVolumeMapType instance;
00069    return instance;
00070 }
00071 
00072 G4GDMLWrite::DepthMapType& G4GDMLWrite::DepthMap()
00073 {
00074    static DepthMapType instance;
00075    return instance;
00076 }
00077 
00078 void G4GDMLWrite::AddExtension(xercesc::DOMElement*,
00079                                const G4LogicalVolume* const)
00080 {
00081    // Empty implementation. To be overwritten by user for specific extensions
00082    // related to attributes associated to volumes
00083 }
00084 
00085 void G4GDMLWrite::ExtensionWrite(xercesc::DOMElement*)
00086 {
00087    // Empty implementation. To be overwritten by user for specific extensions
00088 }
00089 
00090 G4String G4GDMLWrite::GenerateName(const G4String& name, const void* const ptr)
00091 {
00092    G4String nameOut;
00093    std::stringstream stream; stream << name;
00094    if (addPointerToName) { stream << ptr; };
00095 
00096    nameOut=G4String(stream.str());
00097    if(nameOut.contains(' '))
00098    nameOut.erase(std::remove(nameOut.begin(),nameOut.end(),' '),nameOut.end());
00099 
00100    return nameOut;
00101 }
00102 
00103 xercesc::DOMAttr* G4GDMLWrite::NewAttribute(const G4String& name,
00104                                             const G4String& value)
00105 {
00106    xercesc::XMLString::transcode(name,tempStr,99);
00107    xercesc::DOMAttr* att = doc->createAttribute(tempStr);
00108    xercesc::XMLString::transcode(value,tempStr,99);
00109    att->setValue(tempStr);
00110    return att;
00111 }
00112 
00113 xercesc::DOMAttr* G4GDMLWrite::NewAttribute(const G4String& name,
00114                                             const G4double& value)
00115 {
00116    xercesc::XMLString::transcode(name,tempStr,99);
00117    xercesc::DOMAttr* att = doc->createAttribute(tempStr);
00118    std::ostringstream ostream;
00119    ostream.precision(15);
00120    ostream << value;
00121    G4String str = ostream.str();
00122    xercesc::XMLString::transcode(str,tempStr,99);
00123    att->setValue(tempStr);
00124    return att;
00125 }
00126 
00127 xercesc::DOMElement* G4GDMLWrite::NewElement(const G4String& name)
00128 {
00129    xercesc::XMLString::transcode(name,tempStr,99);
00130    return doc->createElement(tempStr);
00131 }
00132 
00133 G4Transform3D G4GDMLWrite::Write(const G4String& fname,
00134                                  const G4LogicalVolume* const logvol,
00135                                  const G4String& setSchemaLocation,
00136                                  const G4int depth,
00137                                        G4bool refs)
00138 {
00139    SchemaLocation = setSchemaLocation;
00140    addPointerToName = refs;
00141 
00142    if (depth==0) { G4cout << "G4GDML: Writing '" << fname << "'..." << G4endl; }
00143    else   { G4cout << "G4GDML: Writing module '" << fname << "'..." << G4endl; }
00144    
00145    if (FileExists(fname))
00146    {
00147      G4String ErrorMessage = "File '"+fname+"' already exists!";
00148      G4Exception("G4GDMLWrite::Write()", "InvalidSetup",
00149                  FatalException, ErrorMessage);
00150    }
00151    
00152    VolumeMap().clear(); // The module map is global for all modules,
00153                         // so clear it only at once!
00154 
00155    xercesc::XMLString::transcode("LS", tempStr, 99);
00156      xercesc::DOMImplementationRegistry::getDOMImplementation(tempStr);
00157    xercesc::XMLString::transcode("Range", tempStr, 99);
00158    xercesc::DOMImplementation* impl =
00159      xercesc::DOMImplementationRegistry::getDOMImplementation(tempStr);
00160    xercesc::XMLString::transcode("gdml", tempStr, 99);
00161    doc = impl->createDocument(0,tempStr,0);
00162    xercesc::DOMElement* gdml = doc->getDocumentElement();
00163 
00164 #if XERCES_VERSION_MAJOR >= 3
00165                                              // DOM L3 as per Xerces 3.0 API
00166     xercesc::DOMLSSerializer* writer =
00167       ((xercesc::DOMImplementationLS*)impl)->createLSSerializer();
00168 
00169     xercesc::DOMConfiguration *dc = writer->getDomConfig();
00170     dc->setParameter(xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true);
00171 
00172 #else
00173 
00174    xercesc::DOMWriter* writer =
00175      ((xercesc::DOMImplementationLS*)impl)->createDOMWriter();
00176 
00177    if (writer->canSetFeature(xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true))
00178        writer->setFeature(xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true);
00179 
00180 #endif
00181 
00182    gdml->setAttributeNode(NewAttribute("xmlns:xsi",
00183                           "http://www.w3.org/2001/XMLSchema-instance"));
00184    gdml->setAttributeNode(NewAttribute("xsi:noNamespaceSchemaLocation",
00185                           SchemaLocation));
00186 
00187    ExtensionWrite(gdml);
00188    DefineWrite(gdml);
00189    MaterialsWrite(gdml);
00190    SolidsWrite(gdml);
00191    StructureWrite(gdml);
00192    SetupWrite(gdml,logvol);
00193 
00194    G4Transform3D R = TraverseVolumeTree(logvol,depth);
00195 
00196    SurfacesWrite();
00197    xercesc::XMLFormatTarget *myFormTarget =
00198      new xercesc::LocalFileFormatTarget(fname.c_str());
00199 
00200    try
00201    {
00202 #if XERCES_VERSION_MAJOR >= 3
00203                                             // DOM L3 as per Xerces 3.0 API
00204       xercesc::DOMLSOutput *theOutput =
00205         ((xercesc::DOMImplementationLS*)impl)->createLSOutput();
00206       theOutput->setByteStream(myFormTarget);
00207       writer->write(doc, theOutput);
00208 #else
00209       writer->writeNode(myFormTarget, *doc);
00210 #endif
00211    }
00212    catch (const xercesc::XMLException& toCatch)
00213    {
00214       char* message = xercesc::XMLString::transcode(toCatch.getMessage());
00215       G4cout << "G4GDML: Exception message is: " << message << G4endl;
00216       xercesc::XMLString::release(&message);
00217       return G4Transform3D::Identity;
00218    }
00219    catch (const xercesc::DOMException& toCatch)
00220    {
00221       char* message = xercesc::XMLString::transcode(toCatch.msg);
00222       G4cout << "G4GDML: Exception message is: " << message << G4endl;
00223       xercesc::XMLString::release(&message);
00224       return G4Transform3D::Identity;
00225    }
00226    catch (...)
00227    {   
00228       G4cout << "G4GDML: Unexpected Exception!" << G4endl;
00229       return G4Transform3D::Identity;
00230    }        
00231 
00232    delete myFormTarget;
00233    writer->release();
00234 
00235    if (depth==0)
00236    {
00237      G4cout << "G4GDML: Writing '" << fname << "' done !" << G4endl;
00238    }
00239    else
00240    {
00241      G4cout << "G4GDML: Writing module '" << fname << "' done !" << G4endl;
00242    }
00243 
00244    return R;
00245 }
00246 
00247 void G4GDMLWrite::AddModule(const G4VPhysicalVolume* const physvol)
00248 {
00249    G4String fname = GenerateName(physvol->GetName(),physvol);
00250    G4cout << "G4GDML: Adding module '" << fname << "'..." << G4endl;
00251 
00252    if (physvol == 0)
00253    {
00254      G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
00255                  "Invalid NULL pointer is specified for modularization!");
00256      return;
00257    }
00258    if (dynamic_cast<const G4PVDivision*>(physvol))
00259    {
00260      G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
00261                  "It is not possible to modularize by divisionvol!");
00262      return;
00263    }
00264    if (physvol->IsParameterised())
00265    {
00266      G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
00267                  "It is not possible to modularize by parameterised volume!");
00268      return;
00269    }
00270    if (physvol->IsReplicated())
00271    {
00272      G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
00273                  "It is not possible to modularize by replicated volume!");
00274      return;
00275    }
00276 
00277    PvolumeMap()[physvol] = fname;
00278 }
00279 
00280 void G4GDMLWrite::AddModule(const G4int depth)
00281 {
00282    if (depth<0)
00283    {
00284      G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
00285                  "Depth must be a positive number!");
00286    }
00287    if (DepthMap().find(depth) != DepthMap().end())
00288    {
00289      G4Exception("G4GDMLWrite::AddModule()", "InvalidSetup", FatalException,
00290                  "Adding module(s) at this depth is already requested!");
00291    }
00292    DepthMap()[depth] = 0;
00293 }
00294 
00295 G4String G4GDMLWrite::Modularize( const G4VPhysicalVolume* const physvol,
00296                                   const G4int depth )
00297 {
00298    if (PvolumeMap().find(physvol) != PvolumeMap().end())
00299    {
00300      return PvolumeMap()[physvol]; // Modularize via physvol
00301    }
00302 
00303    if (DepthMap().find(depth) != DepthMap().end()) // Modularize via depth
00304    {
00305      std::stringstream stream;
00306      stream << "depth" << depth << "_module" << DepthMap()[depth] << ".gdml";
00307      DepthMap()[depth]++;           // There can be more modules at this depth!
00308      return G4String(stream.str());
00309    }
00310 
00311    return G4String(""); // Empty string for module name = no modularization
00312                         // was requested at that level/physvol!
00313 }
00314 
00315 void G4GDMLWrite::SetAddPointerToName(G4bool set)
00316 {
00317    addPointerToName = set;
00318 }

Generated on Mon May 27 17:48:20 2013 for Geant4 by  doxygen 1.4.7