--- /dev/null
+// $Id$
+// Category: geometry
+// by I. Hrivnacova, 27.07.2000
+//
+// See the class description in the header file.
+
+#include "TG4VXMLConvertor.h"
+
+TG4VXMLConvertor::TG4VXMLConvertor() {
+//
+}
+
+TG4VXMLConvertor::~TG4VXMLConvertor() {
+//
+}
+
--- /dev/null
+// $Id$
+// Category: geometry
+// by I. Hrivnacova, 27.07.2000
+//
+// The interface for XML convertor that
+// converts G4 basic geometry objects to XML.
+
+#ifndef TG4_V_XML_CONVERTOR_H
+#define TG4_V_XML_CONVERTOR_H
+
+#include <G4ThreeVector.hh>
+#include <G4RotationMatrix.hh>
+
+class G4Material;
+class G4VSolid;
+class G4LogicalVolume;
+
+class TG4VXMLConvertor
+{
+ public:
+ TG4VXMLConvertor();
+ virtual ~TG4VXMLConvertor();
+
+ // methods
+ virtual void OpenSection(const G4String& name, const G4String& version,
+ const G4String& date, const G4String& author,
+ const G4String& topVolume) = 0;
+ virtual void OpenComposition(const G4String& name) = 0;
+ virtual void CloseSection() = 0;
+ virtual void CloseComposition() = 0;
+
+ virtual void WriteMaterial(const G4Material* material) = 0;
+ virtual void WriteSolid(const G4VSolid* solid, G4String materialName) = 0;
+ virtual void WritePosition(G4String solidName, G4ThreeVector position) = 0;
+ virtual void WritePositionWithRotation(
+ G4String solidName, G4ThreeVector position,
+ const G4RotationMatrix* rotation) = 0;
+ virtual void WriteEmptyLine() = 0;
+};
+
+#endif //TG4_V_XML_CONVERTOR_H
+
--- /dev/null
+// $Id$
+// Category: geometry
+//
+// See the class description in the header file.
+
+#include "TG4XMLConvertor.h"
+#include "TG3Units.h"
+
+#include <G4LogicalVolume.hh>
+#include <G4Material.hh>
+#include <G4VSolid.hh>
+#include <G4Box.hh>
+#include <G4Tubs.hh>
+#include <G4Trd.hh>
+#include <globals.hh>
+
+#include <g4std/iostream>
+#include <g4std/iomanip>
+
+const G4int TG4XMLConvertor::fgkMaxVolumeNameLength = 10;
+const G4int TG4XMLConvertor::fgkMaxMaterialNameLength = 20;
+
+TG4XMLConvertor::TG4XMLConvertor(G4std::ofstream& outFile)
+ : fOutFile(outFile),
+ fIndention("")
+{
+//
+}
+
+TG4XMLConvertor::~TG4XMLConvertor() {
+//
+}
+
+// private methods
+
+void TG4XMLConvertor::CutName(G4String& name) const
+{
+// Removes spaces after the name if present.
+// ---
+
+ G4int i = name.length();
+ while (name(--i) == ' ') name = name(0,i);
+}
+
+void TG4XMLConvertor::CutName(G4String& name, G4int size) const
+{
+// Cuts name to given size.
+// ---
+
+ if (name.length() > size) name = name(0, size);
+}
+
+void TG4XMLConvertor::PutName(G4String& element, G4String name,
+ G4String templ) const
+{
+// Replaces given template in string element with a give name.
+// ---
+
+ CutName(name);
+ // make better
+ if (templ == "#")
+ CutName(name, fgkMaxVolumeNameLength);
+ else if (templ == "!")
+ CutName(name, fgkMaxMaterialNameLength);
+
+ element.replace(element.find(templ), name.size(), name);
+ element.replace(element.find(templ), 1, "\"");
+ while (element.contains(templ)) element.replace(element.find(templ), 1 , " ");
+}
+
+void TG4XMLConvertor::WriteBox(const G4Box* box, G4String materialName)
+{
+// Writes G4box solid.
+// ---
+
+ // get parameters
+ G4String solidName = box->GetName();
+ G4double x = box->GetXHalfLength()/TG3Units::Length();
+ G4double y = box->GetYHalfLength()/TG3Units::Length();
+ G4double z = box->GetZHalfLength()/TG3Units::Length();
+
+ // compose element string template
+ G4String element1
+ = "<box name=\"########### material=\"!!!!!!!!!!!!!!!!!!!!! X_Y_Z=\"";
+ G4String element2 = "\" />";
+
+ // put solid and material names
+ PutName(element1, solidName, "#");
+ PutName(element1, materialName, "!");
+
+ // write element
+ //fOutFile.setf(G4std::ios::fixed, G4std::ios::floatfield);
+ fOutFile << element1
+ << G4std::setw(7) << G4std::setprecision(2) << x << " "
+ << G4std::setw(7) << G4std::setprecision(2) << y << " "
+ << G4std::setw(7) << G4std::setprecision(2) << z
+ << element2
+ << G4endl;
+}
+
+void TG4XMLConvertor::WriteTubs(const G4Tubs* tubs, G4String materialName)
+{
+// Writes G4tubs solid.
+// ---
+
+ // get parameters
+ G4String solidName = tubs->GetName();
+ G4double rmin = tubs->GetInnerRadius()/TG3Units::Length();
+ G4double rmax = tubs->GetOuterRadius()/TG3Units::Length();
+ G4double hz = tubs->GetZHalfLength()/TG3Units::Length();
+ G4double sphi = tubs->GetStartPhiAngle()/TG3Units::Angle();
+ G4double dphi = tubs->GetDeltaPhiAngle()/TG3Units::Angle();
+
+ // compose element string template
+ G4String element1
+ = "<tubs name=\"########### material=\"!!!!!!!!!!!!!!!!!!!!! Rio_Z=\"";
+ G4String element2 = "\" profile=\"";
+ G4String element3 = "\" />";
+
+ // put solid and material names
+ PutName(element1, solidName, "#");
+ PutName(element1, materialName, "!");
+
+ // write element
+ fOutFile << element1
+ << G4std::setw(7) << G4std::setprecision(2) << rmin << " "
+ << G4std::setw(7) << G4std::setprecision(2) << rmax << " "
+ << G4std::setw(7) << G4std::setprecision(2) << hz
+ << element2
+ << G4std::setw(7) << G4std::setprecision(2) << sphi << " "
+ << G4std::setw(7) << G4std::setprecision(2) << dphi
+ << element3
+ << G4endl;
+}
+
+
+void TG4XMLConvertor::WriteTrd(const G4Trd* trd, G4String materialName)
+{
+// Writes G4Trd solid.
+// ---
+
+ // get parameters
+ G4String solidName = trd->GetName();
+ G4double x1 = trd->GetXHalfLength1()/TG3Units::Length();
+ G4double x2 = trd->GetXHalfLength2()/TG3Units::Length();
+ G4double y1 = trd->GetYHalfLength1()/TG3Units::Length();
+ G4double y2 = trd->GetYHalfLength2()/TG3Units::Length();
+ G4double hz = trd->GetZHalfLength()/TG3Units::Length();
+
+ // compose element string template
+ G4String element1
+ = "<trd name=\"########### material=\"!!!!!!!!!!!!!!!!!!!!! Xmp_Ymp_Z=\"";
+ G4String element2 = "\" />";
+
+ // put solid and material names
+ // put solid and material names
+ PutName(element1, solidName, "#");
+ PutName(element1, materialName, "!");
+
+ // write element
+ fOutFile << element1
+ << G4std::setw(7) << G4std::setprecision(2) << x1 << " "
+ << G4std::setw(7) << G4std::setprecision(2) << x2 << " "
+ << G4std::setw(7) << G4std::setprecision(2) << y1 << " "
+ << G4std::setw(7) << G4std::setprecision(2) << y2 << " "
+ << G4std::setw(7) << G4std::setprecision(2) << hz
+ << element2
+ << G4endl;
+}
+
+
+// public methods
+
+void TG4XMLConvertor::OpenSection(const G4String& name, const G4String& version,
+ const G4String& date, const G4String& author,
+ const G4String& topVolume)
+{
+// Writes section opening.
+// ---
+
+ G4String element1 = "<section name = \"";
+ G4String element2 = " version = \"";
+ G4String element3 = " date = \"";
+ G4String element4 = " author = \"";
+ G4String element5 = " topVolume = \"";
+ G4String element6 = " >";
+ G4String quota = "\"";
+
+ // write element
+ fOutFile << element1 << name << quota << G4endl
+ << element2 << version << quota << G4endl
+ << element3 << date << quota << G4endl
+ << element4 << author << quota << G4endl
+ << element5 << topVolume << quota
+ << element6 << G4endl;
+}
+
+void TG4XMLConvertor::OpenComposition(const G4String& name)
+{
+// Writes composition opening.
+// ---
+
+ G4String element = "<composition name=\"";
+ element.append(name);
+ element.append(">");
+
+ // write element
+ fOutFile << fIndention
+ << element
+ << G4endl;
+
+ // increase indention
+ fIndention.append(" ");
+}
+
+void TG4XMLConvertor::CloseSection()
+{
+// Writes section closing.
+// ---
+
+ // define element
+ G4String element = "</section>";
+
+ // write element
+ fOutFile << element
+ << G4endl;
+}
+
+void TG4XMLConvertor::CloseComposition()
+{
+// Writes composition closing.
+// ---
+
+ // decrease indention
+ fIndention.replace(fIndention.find(" "), 3 , "");
+
+ // define element
+ G4String element = "</composition>";
+
+ // write element
+ fOutFile << fIndention
+ << element
+ << G4endl;
+}
+
+void TG4XMLConvertor::WriteMaterial(const G4Material* material)
+{
+// Writes G4Material.
+// Not yet implemented, only XML comment element is written.
+// ---
+
+ G4String name = material->GetName();
+ CutName(name);
+
+ // return if material of this name was already written
+ if (fMaterialNames.find(name) != fMaterialNames.end()) return;
+
+ fMaterialNames.insert(fMaterialNames.begin(), name);
+
+ // only comment line
+ G4String element1 = "<!-- material = \"";
+ G4String element2 = "\" -->";
+
+ // write element
+ fOutFile << element1 << name
+ << element2
+ << G4endl;
+}
+
+void TG4XMLConvertor::WriteSolid(const G4VSolid* solid, G4String materialName)
+{
+// Finds G4Solid concrete type and calls writing function.
+// For not yet implemented solids, only XML comment element is written.
+// ---
+
+ G4String name = solid->GetName();
+
+ // return if solid of this name was already written
+ if (fSolidNames.find(name) != fSolidNames.end()) return;
+
+ fSolidNames.insert(fSolidNames.begin(), name);
+
+ // find concrete solid type and write it
+
+ const G4Box* box = dynamic_cast<const G4Box*>(solid);
+ if (box) {
+ WriteBox(box, materialName);
+ return;
+ }
+
+ const G4Tubs* tubs = dynamic_cast<const G4Tubs*>(solid);
+ if (tubs) {
+ WriteTubs(tubs, materialName);
+ return;
+ }
+
+ const G4Trd* trd = dynamic_cast<const G4Trd*>(solid);
+ if (trd) {
+ WriteTrd(trd, materialName);
+ return;
+ }
+
+ // write comment line in case of unsupported
+ // shape
+
+ // only comment line
+ G4String element1 = "<!-- unsupported shape name= \"";
+ G4String element2 = "\" -->";
+
+ // write element
+ fOutFile << element1 << name
+ << element2
+ << G4endl;
+}
+
+void TG4XMLConvertor::WriteRotation(const G4RotationMatrix* rotation)
+{
+// Writes G4RotationMatrix.
+// Not yet implemented, only XML comment element is written.
+// ---
+
+ // only comment line
+ G4String element = "<!-- rotation matrix-->";
+
+ // write element
+ fOutFile << element
+ << G4endl;
+}
+
+void TG4XMLConvertor::WritePosition(G4String solidName, G4ThreeVector position)
+{
+// Writes position without rotation with a given solid name.
+// ---
+
+ // get parameters
+ G4double x = position.x()/TG3Units::Length();
+ G4double y = position.y()/TG3Units::Length();
+ G4double z = position.z()/TG3Units::Length();
+
+ // compose element string template
+ G4String element1 = "<posXYZ volume=\"########### X_Y_Z=\"";
+ G4String element2 = "\" />";
+
+ // put solid name
+ PutName(element1, solidName, "#");
+
+ // write element
+ fOutFile << fIndention
+ << element1
+ << G4std::setw(7) << G4std::setprecision(2) << x << " "
+ << G4std::setw(7) << G4std::setprecision(2) << y << " "
+ << G4std::setw(7) << G4std::setprecision(2) << z
+ << element2
+ << G4endl;
+}
+
+void TG4XMLConvertor::WritePositionWithRotation(
+ G4String solidName, G4ThreeVector position,
+ const G4RotationMatrix* rotation)
+{
+// Writes position with rotation with a given solid name.
+// Not yet implemented, only XML comment element is written.
+// ---
+
+ // only comment line
+ G4String element = "<!-- position with rotation -->";
+
+ // write element
+ fOutFile << fIndention
+ << element
+ << G4endl;
+}
+
+void TG4XMLConvertor::WriteEmptyLine()
+{
+// Writes empty line.
+// ---
+
+ fOutFile << G4endl;
+}
+
+
--- /dev/null
+// $Id$
+// Category: geometry
+// by I. Hrivnacova, 27.07.2000
+//
+// XML convertor that converts G4 basic geometry objects
+// to XML defined by AGDD.dtd
+// (ATLAS Generic Detector Description)
+
+#ifndef TG4_XML_CONVERTOR_H
+#define TG4_XML_CONVERTOR_H
+
+#include "TG4VXMLConvertor.h"
+#include "TG4Globals.h"
+
+#include <globals.hh>
+#include <g4std/fstream>
+
+class G4Material;
+class G4VSolid;
+class G4LogicalVolume;
+class G4Box;
+class G4Tubs;
+class G4Trd;
+
+class TG4XMLConvertor : public TG4VXMLConvertor
+{
+ public:
+ TG4XMLConvertor(G4std::ofstream& outFile);
+ virtual ~TG4XMLConvertor();
+
+ // methods
+ virtual void OpenSection(const G4String& name, const G4String& version,
+ const G4String& date, const G4String& author,
+ const G4String& topVolume);
+ virtual void OpenComposition(const G4String& name);
+ virtual void CloseSection();
+ virtual void CloseComposition();
+
+ virtual void WriteMaterial(const G4Material* material);
+ virtual void WriteSolid(const G4VSolid* solid, G4String materialName);
+ virtual void WriteRotation(const G4RotationMatrix* rotation);
+ virtual void WritePosition(G4String solidName, G4ThreeVector position);
+ virtual void WritePositionWithRotation(
+ G4String solidName, G4ThreeVector position,
+ const G4RotationMatrix* rotation);
+ virtual void WriteEmptyLine();
+
+ private:
+ //methods
+ void CutName(G4String& name) const;
+ void CutName(G4String& name, G4int size) const;
+ void PutName(G4String& element, G4String name, G4String templ) const;
+ void WriteBox (const G4Box* box, G4String materialName);
+ void WriteTubs(const G4Tubs* tubs, G4String materialName);
+ void WriteTrd (const G4Trd* trd, G4String materialName);
+
+ // static data members
+ static const G4int fgkMaxVolumeNameLength;
+ static const G4int fgkMaxMaterialNameLength;
+
+ // data members
+ G4std::ofstream& fOutFile; //output file
+ TG4StringSet fMaterialNames; //set of names of materials
+ TG4StringSet fSolidNames; //set of names of solids
+ G4String fIndention; //indention string
+};
+
+#endif //TG4_XML_CONVERTOR_H
+
--- /dev/null
+// $Id$
+// Category: geometry
+// by I. Hrivnacova, 27.07.2000
+//
+// See the class description in the header file.
+
+#include "TG4XMLGeometryGenerator.h"
+#include "TG4XMLConvertor.h"
+#include "TG4Globals.h"
+
+#include <G4Material.hh>
+#include <G4VSolid.hh>
+#include <G4LogicalVolume.hh>
+#include <G4VPhysicalVolume.hh>
+#include <G4PVPlacement.hh>
+#include <G4ThreeVector.hh>
+#include <G4RotationMatrix.hh>
+
+#include <g4std/iomanip>
+#include <g4std/vector>
+
+TG4XMLGeometryGenerator* TG4XMLGeometryGenerator::fgInstance = 0;
+
+TG4XMLGeometryGenerator::TG4XMLGeometryGenerator()
+{
+//
+ if (fgInstance) {
+ TG4Globals::Exception(
+ "TG4XMLGeometryGenerator: attempt to create two instances of singleton.");
+ }
+
+ fConvertor = new TG4XMLConvertor(fOutFile);
+}
+
+TG4XMLGeometryGenerator::TG4XMLGeometryGenerator(const TG4XMLGeometryGenerator& right)
+{
+//
+ TG4Globals::Exception(
+ "TG4XMLGeometryGenerator: attempt to copy singleton.");
+}
+
+
+TG4XMLGeometryGenerator::~TG4XMLGeometryGenerator() {
+//
+}
+
+// operators
+
+TG4XMLGeometryGenerator&
+TG4XMLGeometryGenerator::operator=(const TG4XMLGeometryGenerator& right)
+{
+ // check assignement to self
+ if (this == &right) return *this;
+
+ TG4Globals::Exception(
+ "Attempt to assign TG4XMLGeometryGenerator singleton.");
+
+ return *this;
+}
+
+
+// private methods
+
+void TG4XMLGeometryGenerator::ProcessSolids(G4LogicalVolume* lv)
+{
+// Writes all solids of given logical volume.
+// ---
+
+ G4VSolid* solid = lv->GetSolid();
+ G4String material = lv->GetMaterial()->GetName();
+ fConvertor->WriteSolid(solid, material);
+
+ G4int nofDaughters = lv->GetNoDaughters();
+ if (nofDaughters>0)
+ for (G4int i=0; i<nofDaughters; i++) {
+ G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
+ ProcessSolids(lvd);
+ }
+}
+
+void TG4XMLGeometryGenerator::ProcessMaterials(G4LogicalVolume* lv)
+{
+// Writes all materials of given logical volume.
+// ---
+
+ G4Material* material = lv->GetMaterial();
+ fConvertor->WriteMaterial(material);
+
+ G4int nofDaughters = lv->GetNoDaughters();
+ if (nofDaughters>0)
+ for (G4int i=0; i<nofDaughters; i++) {
+ G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
+ ProcessMaterials(lvd);
+ }
+}
+
+void TG4XMLGeometryGenerator::ProcessLogicalVolume(G4LogicalVolume* lv)
+{
+// Writes logical volume tree.
+// ---
+
+ G4int nofDaughters = lv->GetNoDaughters();
+ if (nofDaughters == 0) return;
+
+ // make a vector of contained logical volumes
+ G4std::vector<G4LogicalVolume*> vect;
+ for (G4int i=0; i<nofDaughters; i++) {
+ G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
+ G4bool store = true;
+ for (G4int j=0; j<vect.size(); j++)
+ if (vect[j] == lvd) store = false;
+ if (store) vect.push_back(lvd);
+ }
+
+ // loop over contained logical volumes
+ for (G4int j=0; j<vect.size(); j++) {
+ G4LogicalVolume* lvd = vect[j];
+
+ // open composition
+ if(lvd->GetNoDaughters()>0) {
+ G4String name = lvd->GetName();
+ name.append("_lv");
+ fConvertor->OpenComposition(name);
+ }
+
+ // write positions
+ for (G4int i=0; i<nofDaughters; i++) {
+ G4VPhysicalVolume* vpvd = lv->GetDaughter(i);
+ G4LogicalVolume* lvdi = vpvd->GetLogicalVolume();
+
+ if (lvdi == lvd) {
+ // only placements are processed
+ G4PVPlacement* pvd = dynamic_cast<G4PVPlacement*>(vpvd);
+ if (pvd) {
+ G4String solidName = lvd->GetSolid()->GetName();
+ G4ThreeVector position = vpvd->GetFrameTranslation();
+ const G4RotationMatrix* kMatrix = vpvd->GetFrameRotation();
+ if (!kMatrix)
+ fConvertor->WritePosition(solidName, position);
+ else
+ fConvertor->WritePositionWithRotation(solidName, position, kMatrix);
+ }
+ else {
+ G4String text = "TG4XMLGeometryGenerator::ProcessLogicalVolume: \n";
+ text = text + " Limitation: \n";
+ text = text + " Other physical volumes than PVPlacement";
+ text = text + " are not implemented.";
+ TG4Globals::Warning(text);
+ }
+ }
+ }
+
+ if(lvd->GetNoDaughters()>0) {
+ // process daughters recursively
+ ProcessLogicalVolume(lvd);
+ fConvertor->CloseComposition();
+ fConvertor->WriteEmptyLine();
+ }
+ }
+}
+
+// public methods
+
+void TG4XMLGeometryGenerator::GenerateSection(const G4String& name,
+ const G4String& version, const G4String& date,
+ const G4String& author, const G4String& topVolume,
+ G4LogicalVolume* lv)
+{
+// Generates the XML section containing
+// all geometry objects defined in given logical volume:
+// materials, solids, rotation matrices and
+// volumes hierarchy.
+// ---
+
+ // create section
+ fConvertor->OpenSection(name, version, date, author, topVolume);
+ fConvertor->WriteEmptyLine();
+
+ // process materials
+ ProcessMaterials(lv);
+ fConvertor->WriteEmptyLine();
+
+ // process solids
+ ProcessSolids(lv);
+ fConvertor->WriteEmptyLine();
+
+ // process geometry tree
+ G4String moduleName = name; moduleName.append("_module");
+ fConvertor->OpenComposition(moduleName);
+ ProcessLogicalVolume(lv);
+ fConvertor->CloseComposition();
+ fConvertor->WriteEmptyLine();
+
+ // close section
+ fConvertor->CloseSection();
+}
+
+void TG4XMLGeometryGenerator::OpenFile(G4String filePath)
+{
+// Opens output file.
+// ---
+
+ G4cout << "TG4XMLGeometryGenerator::OpenFile: " << filePath << G4endl;
+
+ fOutFile.open(filePath, G4std::ios::out);
+
+ if (!fOutFile) {
+ G4String text = "Cannot open ";
+ text = text + filePath;
+ TG4Globals::Warning(text);
+ }
+
+ // use FORTRAN compatibility output
+ fOutFile.setf(G4std::ios::fixed, G4std::ios::floatfield);
+}
+
+
+void TG4XMLGeometryGenerator::CloseFile()
+{
+// Closes output file.
+// ---
+
+ fOutFile.close();
+}
--- /dev/null
+// $Id$
+// Category: geometry
+// by I. Hrivnacova, 27.07.2000
+//
+// Singleton class for generation of geometry data files in XML,
+// the XML format is independent from G4 geometry
+// object model.
+
+#ifndef TG4_XML_GEOMETRY_GENERATOR_H
+#define TG4_XML_GEOMETRY_GENERATOR_H
+
+#include <globals.hh>
+#include <g4std/fstream>
+
+class TG4VXMLConvertor;
+
+class G4LogicalVolume;
+
+class TG4XMLGeometryGenerator
+{
+ public:
+ TG4XMLGeometryGenerator();
+ // --> protected
+ // TG4XMLGeometryGenerator(const TG4XMLGeometryGenerator& right);
+ virtual ~TG4XMLGeometryGenerator();
+
+ // static access method
+ static TG4XMLGeometryGenerator* Instance();
+
+ // methods
+ void GenerateSection(const G4String& name, const G4String& version,
+ const G4String& date, const G4String& author,
+ const G4String& topVolume, G4LogicalVolume* lv);
+ void OpenFile(G4String filePath);
+ void CloseFile();
+
+ protected:
+ TG4XMLGeometryGenerator(const TG4XMLGeometryGenerator& right);
+
+ // operators
+ TG4XMLGeometryGenerator& operator=(const TG4XMLGeometryGenerator& right);
+
+ private:
+ // methods
+ void ProcessLogicalVolume(G4LogicalVolume* lv);
+ void ProcessMaterials(G4LogicalVolume* lv);
+ void ProcessSolids(G4LogicalVolume* lv);
+
+ // static data members
+ static TG4XMLGeometryGenerator* fgInstance; //this instance
+
+ // data members
+ TG4VXMLConvertor* fConvertor; //interface to XML convertor
+ G4std::ofstream fOutFile; //output file
+};
+
+
+// inline methods
+inline TG4XMLGeometryGenerator* TG4XMLGeometryGenerator::Instance()
+{ return fgInstance; }
+
+#endif //TG4_GEOMETRY_XML_MANAGER_H
+