3 // by I. Hrivnacova, 27.07.2000
5 // See the class description in the header file.
7 #include "TG4XMLGeometryGenerator.h"
8 #include "TG4XMLConvertor.h"
9 #include "TG4Globals.h"
11 #include <G4Material.hh>
12 #include <G4VSolid.hh>
13 #include <G4LogicalVolume.hh>
14 #include <G4VPhysicalVolume.hh>
15 #include <G4PVPlacement.hh>
16 #include <G4ThreeVector.hh>
17 #include <G4RotationMatrix.hh>
19 #include <g4std/iomanip>
20 #include <g4std/vector>
22 TG4XMLGeometryGenerator* TG4XMLGeometryGenerator::fgInstance = 0;
24 TG4XMLGeometryGenerator::TG4XMLGeometryGenerator()
28 TG4Globals::Exception(
29 "TG4XMLGeometryGenerator: attempt to create two instances of singleton.");
32 fConvertor = new TG4XMLConvertor(fOutFile);
35 TG4XMLGeometryGenerator::TG4XMLGeometryGenerator(const TG4XMLGeometryGenerator& right)
38 TG4Globals::Exception(
39 "TG4XMLGeometryGenerator: attempt to copy singleton.");
43 TG4XMLGeometryGenerator::~TG4XMLGeometryGenerator() {
49 TG4XMLGeometryGenerator&
50 TG4XMLGeometryGenerator::operator=(const TG4XMLGeometryGenerator& right)
52 // check assignement to self
53 if (this == &right) return *this;
55 TG4Globals::Exception(
56 "Attempt to assign TG4XMLGeometryGenerator singleton.");
64 void TG4XMLGeometryGenerator::ProcessSolids(G4LogicalVolume* lv)
66 // Writes all solids of given logical volume.
69 G4VSolid* solid = lv->GetSolid();
70 G4String material = lv->GetMaterial()->GetName();
71 fConvertor->WriteSolid(solid, material);
73 G4int nofDaughters = lv->GetNoDaughters();
75 for (G4int i=0; i<nofDaughters; i++) {
76 G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
81 void TG4XMLGeometryGenerator::ProcessMaterials(G4LogicalVolume* lv)
83 // Writes all materials of given logical volume.
86 G4Material* material = lv->GetMaterial();
87 fConvertor->WriteMaterial(material);
89 G4int nofDaughters = lv->GetNoDaughters();
91 for (G4int i=0; i<nofDaughters; i++) {
92 G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
93 ProcessMaterials(lvd);
97 void TG4XMLGeometryGenerator::ProcessLogicalVolume(G4LogicalVolume* lv)
99 // Writes logical volume tree.
102 G4int nofDaughters = lv->GetNoDaughters();
103 if (nofDaughters == 0) return;
105 // make a vector of contained logical volumes
106 G4std::vector<G4LogicalVolume*> vect;
107 for (G4int i=0; i<nofDaughters; i++) {
108 G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
110 for (G4int j=0; j<vect.size(); j++)
111 if (vect[j] == lvd) store = false;
112 if (store) vect.push_back(lvd);
115 // loop over contained logical volumes
116 for (G4int j=0; j<vect.size(); j++) {
117 G4LogicalVolume* lvd = vect[j];
120 if(lvd->GetNoDaughters()>0) {
121 G4String name = lvd->GetName();
123 fConvertor->OpenComposition(name);
127 for (G4int i=0; i<nofDaughters; i++) {
128 G4VPhysicalVolume* vpvd = lv->GetDaughter(i);
129 G4LogicalVolume* lvdi = vpvd->GetLogicalVolume();
132 // only placements are processed
133 G4PVPlacement* pvd = dynamic_cast<G4PVPlacement*>(vpvd);
135 G4String solidName = lvd->GetSolid()->GetName();
136 G4ThreeVector position = vpvd->GetFrameTranslation();
137 const G4RotationMatrix* kMatrix = vpvd->GetFrameRotation();
139 fConvertor->WritePosition(solidName, position);
141 fConvertor->WritePositionWithRotation(solidName, position, kMatrix);
144 G4String text = "TG4XMLGeometryGenerator::ProcessLogicalVolume: \n";
145 text = text + " Limitation: \n";
146 text = text + " Other physical volumes than PVPlacement";
147 text = text + " are not implemented.";
148 TG4Globals::Warning(text);
153 if(lvd->GetNoDaughters()>0) {
154 // process daughters recursively
155 ProcessLogicalVolume(lvd);
156 fConvertor->CloseComposition();
157 fConvertor->WriteEmptyLine();
164 void TG4XMLGeometryGenerator::GenerateSection(const G4String& name,
165 const G4String& version, const G4String& date,
166 const G4String& author, const G4String& topVolume,
169 // Generates the XML section containing
170 // all geometry objects defined in given logical volume:
171 // materials, solids, rotation matrices and
172 // volumes hierarchy.
176 fConvertor->OpenSection(name, version, date, author, topVolume);
177 fConvertor->WriteEmptyLine();
180 ProcessMaterials(lv);
181 fConvertor->WriteEmptyLine();
185 fConvertor->WriteEmptyLine();
187 // process geometry tree
188 G4String moduleName = name; moduleName.append("_module");
189 fConvertor->OpenComposition(moduleName);
190 ProcessLogicalVolume(lv);
191 fConvertor->CloseComposition();
192 fConvertor->WriteEmptyLine();
195 fConvertor->CloseSection();
198 void TG4XMLGeometryGenerator::OpenFile(G4String filePath)
200 // Opens output file.
203 G4cout << "TG4XMLGeometryGenerator::OpenFile: " << filePath << G4endl;
205 fOutFile.open(filePath, G4std::ios::out);
208 G4String text = "Cannot open ";
209 text = text + filePath;
210 TG4Globals::Warning(text);
213 // use FORTRAN compatibility output
214 fOutFile.setf(G4std::ios::fixed, G4std::ios::floatfield);
218 void TG4XMLGeometryGenerator::CloseFile()
220 // Closes output file.