4 // Author: I. Hrivnacova, 27.07.2000
6 // Class TG4XMLGeometryGenerator
7 // -----------------------------
8 // See the class description in the header file.
10 #include "TG4XMLGeometryGenerator.h"
11 #include "TG4XMLConvertor.h"
12 #include "TG4Globals.h"
14 #include <G4Material.hh>
15 #include <G4VSolid.hh>
16 #include <G4LogicalVolume.hh>
17 #include <G4VPhysicalVolume.hh>
18 #include <G4PVPlacement.hh>
19 #include <G4PVReplica.hh>
20 #include <G4ThreeVector.hh>
21 #include <G4RotationMatrix.hh>
23 #include <g4std/iomanip>
24 #include <g4std/vector>
26 TG4XMLGeometryGenerator* TG4XMLGeometryGenerator::fgInstance = 0;
28 //_____________________________________________________________________________
29 TG4XMLGeometryGenerator::TG4XMLGeometryGenerator()
30 : TG4Verbose("geometryGenerator")
34 TG4Globals::Exception(
35 "TG4XMLGeometryGenerator: attempt to create two instances of singleton.");
38 fConvertor = new TG4XMLConvertor(fOutFile);
41 //_____________________________________________________________________________
42 TG4XMLGeometryGenerator::TG4XMLGeometryGenerator(
43 const TG4XMLGeometryGenerator& right)
44 : TG4Verbose("geometryGenerator")
47 TG4Globals::Exception(
48 "TG4XMLGeometryGenerator: attempt to copy singleton.");
51 //_____________________________________________________________________________
52 TG4XMLGeometryGenerator::~TG4XMLGeometryGenerator() {
58 //_____________________________________________________________________________
59 TG4XMLGeometryGenerator&
60 TG4XMLGeometryGenerator::operator=(const TG4XMLGeometryGenerator& right)
62 // check assignement to self
63 if (this == &right) return *this;
65 TG4Globals::Exception(
66 "Attempt to assign TG4XMLGeometryGenerator singleton.");
74 //_____________________________________________________________________________
75 void TG4XMLGeometryGenerator::CutName(G4String& name) const
77 // Removes spaces after the name if present.
80 G4int i = name.length();
81 while (name(--i) == ' ') name = name(0,i);
84 //_____________________________________________________________________________
85 void TG4XMLGeometryGenerator::ProcessSolids(G4LogicalVolume* lv)
87 // Writes all solids of given logical volume.
90 G4VSolid* solid = lv->GetSolid();
91 G4String lvName = lv->GetName();
92 G4String material = lv->GetMaterial()->GetName();
93 fConvertor->WriteSolid(lvName, solid, material);
95 // store the name of logical volume in the set
96 fVolumeNames.insert(fVolumeNames.begin(), lvName);
99 G4int nofDaughters = lv->GetNoDaughters();
101 for (G4int i=0; i<nofDaughters; i++) {
103 if (VerboseLevel() > 1) {
104 G4cout << "processing " << i << "th daughter of "
105 << lv->GetName() << G4endl;
108 G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
109 G4String lvdName = lvd->GetName();
111 if (fVolumeNames.find(lvdName) == fVolumeNames.end()) {
112 // process lvd only if it was not yet processed
118 //_____________________________________________________________________________
119 void TG4XMLGeometryGenerator::ProcessMaterials(G4LogicalVolume* lv)
121 // Writes all materials of given logical volume.
124 G4Material* material = lv->GetMaterial();
126 // check if this material was already written
127 G4bool written = false;
128 G4String name = material->GetName();
130 if (fMaterialNames.find(name) != fMaterialNames.end()) written = true;
133 fConvertor->WriteMaterial(material);
134 fMaterialNames.insert(fMaterialNames.begin(), name);
137 // store the name of logical volume in the set
138 G4String lvName = lv->GetName();
139 fVolumeNames.insert(fVolumeNames.begin(), lvName);
141 G4int nofDaughters = lv->GetNoDaughters();
143 for (G4int i=0; i<nofDaughters; i++) {
144 G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
145 G4String lvdName = lvd->GetName();
147 if (fVolumeNames.find(lvdName) == fVolumeNames.end()) {
148 // process lvd only if it was not yet processed
149 ProcessMaterials(lvd);
154 //_____________________________________________________________________________
155 void TG4XMLGeometryGenerator::ProcessRotations(G4LogicalVolume* lv)
157 // Writes all rotation matrices of given logical volume.
160 G4String lvName = lv->GetName();
162 // store the name of logical volume in the set
163 fVolumeNames.insert(fVolumeNames.begin(), lvName);
165 G4int nofDaughters = lv->GetNoDaughters();
167 if (nofDaughters>0) {
169 for (i=0; i<nofDaughters; i++) {
171 G4VPhysicalVolume* pvd = lv->GetDaughter(i);
172 const G4RotationMatrix* kRotation = pvd->GetRotation();
174 fConvertor->WriteRotation(kRotation);
176 G4LogicalVolume* lvd = pvd->GetLogicalVolume();
177 G4String lvdName = lvd->GetName();
179 if (fVolumeNames.find(lvdName) == fVolumeNames.end()) {
180 // process lvd only if it was not yet processed
181 ProcessRotations(lvd);
187 //_____________________________________________________________________________
188 void TG4XMLGeometryGenerator::ProcessLogicalVolume(G4LogicalVolume* lv)
190 // Writes logical volume tree.
193 G4int nofDaughters = lv->GetNoDaughters();
194 if (nofDaughters == 0) return;
197 G4String lvName = lv->GetName();
198 G4String name = lvName;
199 name.append("_comp");
200 fConvertor->OpenComposition(name);
204 for (i=0; i<nofDaughters; i++) {
206 if (VerboseLevel() > 1) {
207 G4cout << "processing " << i << "th daughter of "
208 << lv->GetName() << G4endl;
211 G4VPhysicalVolume* vpvd = lv->GetDaughter(i);
212 G4LogicalVolume* lvd = vpvd->GetLogicalVolume();
215 G4String lvName = lvd->GetName();
216 G4String compName = lvd->GetName();
217 compName.append("_comp");
218 G4int nd = lvd->GetNoDaughters();
220 G4PVPlacement* pvd = dynamic_cast<G4PVPlacement*>(vpvd);
223 G4ThreeVector position = vpvd->GetTranslation();
225 if (!vpvd->GetRotation()) {
226 fConvertor->WritePosition(lvName, position);
227 // if volume is not leaf node place its logical volume
229 fConvertor->WritePosition(compName, position);
232 const G4RotationMatrix* kMatrix = vpvd->GetObjectRotation();
233 fConvertor->WritePositionWithRotation(lvName, position, kMatrix);
235 fConvertor->WritePositionWithRotation(compName, position, kMatrix);
239 G4PVReplica* pvr = dynamic_cast<G4PVReplica*>(vpvd);
242 fConvertor->WriteReplica(lvName, pvr);
243 // if volume is not leaf node place its logical volume
245 fConvertor->WriteReplica(compName, pvr);
248 G4String text = "TG4XMLGeometryGenerator::ProcessLogicalVolume: \n";
249 text = text + " Limitation: \n";
250 text = text + " Other physical volumes than PVPlacement and PVReplica";
251 text = text + " are not implemented.";
252 TG4Globals::Exception(text);
258 fConvertor->CloseComposition();
259 fConvertor->WriteEmptyLine();
261 // store the name of logical volume in the set
262 fVolumeNames.insert(fVolumeNames.begin(), lvName);
265 for (i=0; i<nofDaughters; i++) {
266 G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
267 G4String lvdName = lvd->GetName();
269 if (fVolumeNames.find(lvdName) == fVolumeNames.end()) {
270 // process lvd only if it was not yet processed
271 ProcessLogicalVolume(lvd);
276 //_____________________________________________________________________________
277 void TG4XMLGeometryGenerator::ClearMaterialNames()
279 // Clears the set of material names.
282 fMaterialNames.erase(fMaterialNames.begin(), fMaterialNames.end());
285 //_____________________________________________________________________________
286 void TG4XMLGeometryGenerator::ClearVolumeNames()
288 // Clears the set of volume names.
291 fVolumeNames.erase(fVolumeNames.begin(), fVolumeNames.end());
296 //_____________________________________________________________________________
297 void TG4XMLGeometryGenerator::GenerateMaterials(
298 const G4String& version, const G4String& date,
299 const G4String& author, const G4String dtdVersion,
302 // Generates the XML material element containing
303 // all materials present in given logical volume.
307 fConvertor->OpenMaterials(version, date, author, dtdVersion);
308 fConvertor->WriteEmptyLine();
311 ProcessMaterials(lv);
312 fConvertor->WriteEmptyLine();
313 ClearMaterialNames();
317 fConvertor->CloseMaterials();
318 fConvertor->WriteEmptyLine();
321 //_____________________________________________________________________________
322 void TG4XMLGeometryGenerator::GenerateSection(const G4String& name,
323 const G4String& version, const G4String& date,
324 const G4String& author, const G4String& topVolume,
327 // Generates the XML section element containing
328 // all geometry objects defined in given logical volume:
329 // rotation matrices, solids and volumes hierarchy.
333 fConvertor->OpenSection(name, version, date, author, topVolume);
334 fConvertor->WriteEmptyLine();
337 //ProcessRotations(lv);
338 //fConvertor->WriteEmptyLine();
340 //ClearVolumeNames();
344 fConvertor->WriteEmptyLine();
347 // process geometry tree
348 ProcessLogicalVolume(lv);
349 fConvertor->WriteEmptyLine();
353 fConvertor->CloseSection();
356 //_____________________________________________________________________________
357 void TG4XMLGeometryGenerator::OpenFile(G4String filePath)
359 // Opens output file.
362 fOutFile.open(filePath, G4std::ios::out);
365 G4String text = "Cannot open ";
366 text = text + filePath;
367 TG4Globals::Warning(text);
370 // use FORTRAN compatibility output
371 fOutFile.setf(G4std::ios::fixed, G4std::ios::floatfield);
375 //_____________________________________________________________________________
376 void TG4XMLGeometryGenerator::CloseFile()
378 // Closes output file.