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::ProcessRotations(G4LogicalVolume* lv)
99 // Writes all rotation matrices of given logical volume.
102 G4int nofDaughters = lv->GetNoDaughters();
104 for (G4int i=0; i<nofDaughters; i++) {
105 G4VPhysicalVolume* pvd = lv->GetDaughter(i);
106 const G4RotationMatrix* kRotation = pvd->GetRotation();
107 if (kRotation) fConvertor->WriteRotation(kRotation);
108 G4LogicalVolume* lvd = pvd->GetLogicalVolume();
109 ProcessRotations(lvd);
113 void TG4XMLGeometryGenerator::ProcessLogicalVolume(G4LogicalVolume* lv)
115 // Writes logical volume tree.
118 G4int nofDaughters = lv->GetNoDaughters();
119 if (nofDaughters == 0) return;
122 G4String name = lv->GetName();
123 name.append("_comp");
124 fConvertor->OpenComposition(name);
128 for (i=0; i<nofDaughters; i++) {
129 G4VPhysicalVolume* vpvd = lv->GetDaughter(i);
130 G4LogicalVolume* lvd = vpvd->GetLogicalVolume();
132 // only placements are processed
133 G4PVPlacement* pvd = dynamic_cast<G4PVPlacement*>(vpvd);
135 G4String solidName = lvd->GetSolid()->GetName();
136 G4String compName = lvd->GetName();
137 compName.append("_comp");
138 G4int nd = lvd->GetNoDaughters();
139 G4ThreeVector position = vpvd->GetFrameTranslation();
140 const G4RotationMatrix* kMatrix = vpvd->GetFrameRotation();
143 fConvertor->WritePosition(solidName, position);
144 // if volume is not leaf node place its logical volume
146 fConvertor->WritePosition(compName, position);
149 fConvertor->WritePositionWithRotation(solidName, position, kMatrix);
151 fConvertor->WritePositionWithRotation(compName, position, kMatrix);
156 G4String text = "TG4XMLGeometryGenerator::ProcessLogicalVolume: \n";
157 text = text + " Limitation: \n";
158 text = text + " Other physical volumes than PVPlacement";
159 text = text + " are not implemented.";
160 TG4Globals::Warning(text);
165 fConvertor->CloseComposition();
166 fConvertor->WriteEmptyLine();
168 // make a vector of contained logical volumes
170 // -> change to a global map of names of written compositions
171 // and test against this map
172 G4std::vector<G4LogicalVolume*> vect;
173 for (i=0; i<nofDaughters; i++) {
174 G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
176 for (G4int j=0; j<vect.size(); j++)
177 if (vect[j] == lvd || lvd->GetNoDaughters()==0) store = false;
178 if (store) vect.push_back(lvd);
181 // process contained logical volumes with daughters
182 fConvertor->IncreaseIndention();
183 for (G4int j=0; j<vect.size(); j++)
184 ProcessLogicalVolume(vect[j]);
185 fConvertor->DecreaseIndention();
189 void TG4XMLGeometryGenerator::ProcessLogicalVolumeOld(G4LogicalVolume* lv)
191 // Writes logical volume tree.
194 G4int nofDaughters = lv->GetNoDaughters();
195 if (nofDaughters == 0) return;
197 // make a vector of contained logical volumes
198 G4std::vector<G4LogicalVolume*> vect;
199 for (G4int i=0; i<nofDaughters; i++) {
200 G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
202 for (G4int j=0; j<vect.size(); j++)
203 if (vect[j] == lvd) store = false;
204 if (store) vect.push_back(lvd);
207 // loop over contained logical volumes
208 for (G4int j=0; j<vect.size(); j++) {
209 G4LogicalVolume* lvd = vect[j];
212 if(lvd->GetNoDaughters()>0) {
213 G4String name = lvd->GetName();
215 fConvertor->OpenComposition(name);
219 for (G4int i=0; i<nofDaughters; i++) {
220 G4VPhysicalVolume* vpvd = lv->GetDaughter(i);
221 G4LogicalVolume* lvdi = vpvd->GetLogicalVolume();
224 // only placements are processed
225 G4PVPlacement* pvd = dynamic_cast<G4PVPlacement*>(vpvd);
227 G4String solidName = lvd->GetSolid()->GetName();
228 G4ThreeVector position = vpvd->GetFrameTranslation();
229 const G4RotationMatrix* kMatrix = vpvd->GetFrameRotation();
231 fConvertor->WritePosition(solidName, position);
233 fConvertor->WritePositionWithRotation(solidName, position, kMatrix);
236 G4String text = "TG4XMLGeometryGenerator::ProcessLogicalVolume: \n";
237 text = text + " Limitation: \n";
238 text = text + " Other physical volumes than PVPlacement";
239 text = text + " are not implemented.";
240 TG4Globals::Warning(text);
245 if(lvd->GetNoDaughters()>0) {
246 // process daughters recursively
247 ProcessLogicalVolume(lvd);
248 fConvertor->CloseComposition();
249 fConvertor->WriteEmptyLine();
257 void TG4XMLGeometryGenerator::GenerateMaterials(
258 const G4String& version, const G4String& date,
259 const G4String& author, const G4String dtdVersion,
262 // Generates the XML material element containing
263 // all materials present in given logical volume.
267 fConvertor->OpenMaterials(version, date, author, dtdVersion);
268 fConvertor->WriteEmptyLine();
271 ProcessMaterials(lv);
272 fConvertor->WriteEmptyLine();
275 fConvertor->CloseMaterials();
276 fConvertor->WriteEmptyLine();
279 void TG4XMLGeometryGenerator::GenerateSection(const G4String& name,
280 const G4String& version, const G4String& date,
281 const G4String& author, const G4String& topVolume,
284 // Generates the XML section element containing
285 // all geometry objects defined in given logical volume:
286 // rotation matrices, solids and volumes hierarchy.
290 fConvertor->OpenSection(name, version, date, author, topVolume);
291 fConvertor->WriteEmptyLine();
294 ProcessRotations(lv);
295 fConvertor->WriteEmptyLine();
299 fConvertor->WriteEmptyLine();
301 // process geometry tree
302 ProcessLogicalVolume(lv);
303 fConvertor->WriteEmptyLine();
306 fConvertor->CloseSection();
309 void TG4XMLGeometryGenerator::OpenFile(G4String filePath)
311 // Opens output file.
314 G4cout << "TG4XMLGeometryGenerator::OpenFile: " << filePath << G4endl;
316 fOutFile.open(filePath, G4std::ios::out);
319 G4String text = "Cannot open ";
320 text = text + filePath;
321 TG4Globals::Warning(text);
324 // use FORTRAN compatibility output
325 fOutFile.setf(G4std::ios::fixed, G4std::ios::floatfield);
329 void TG4XMLGeometryGenerator::CloseFile()
331 // Closes output file.