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 <G4PVReplica.hh>
17 #include <G4ThreeVector.hh>
18 #include <G4RotationMatrix.hh>
20 #include <g4std/iomanip>
21 #include <g4std/vector>
23 TG4XMLGeometryGenerator* TG4XMLGeometryGenerator::fgInstance = 0;
25 //_____________________________________________________________________________
26 TG4XMLGeometryGenerator::TG4XMLGeometryGenerator()
30 TG4Globals::Exception(
31 "TG4XMLGeometryGenerator: attempt to create two instances of singleton.");
34 fConvertor = new TG4XMLConvertor(fOutFile);
37 //_____________________________________________________________________________
38 TG4XMLGeometryGenerator::TG4XMLGeometryGenerator(const TG4XMLGeometryGenerator& right)
41 TG4Globals::Exception(
42 "TG4XMLGeometryGenerator: attempt to copy singleton.");
45 //_____________________________________________________________________________
46 TG4XMLGeometryGenerator::~TG4XMLGeometryGenerator() {
52 //_____________________________________________________________________________
53 TG4XMLGeometryGenerator&
54 TG4XMLGeometryGenerator::operator=(const TG4XMLGeometryGenerator& right)
56 // check assignement to self
57 if (this == &right) return *this;
59 TG4Globals::Exception(
60 "Attempt to assign TG4XMLGeometryGenerator singleton.");
68 //_____________________________________________________________________________
69 void TG4XMLGeometryGenerator::CutName(G4String& name) const
71 // Removes spaces after the name if present.
74 G4int i = name.length();
75 while (name(--i) == ' ') name = name(0,i);
78 //_____________________________________________________________________________
79 void TG4XMLGeometryGenerator::ProcessSolids(G4LogicalVolume* lv)
81 // Writes all solids of given logical volume.
84 G4VSolid* solid = lv->GetSolid();
85 G4String lvName = lv->GetName();
86 G4String material = lv->GetMaterial()->GetName();
87 fConvertor->WriteSolid(lvName, solid, material);
89 // store the name of logical volume in the set
90 fVolumeNames.insert(fVolumeNames.begin(), lvName);
93 G4int nofDaughters = lv->GetNoDaughters();
95 for (G4int i=0; i<nofDaughters; i++) {
96 //G4cout << "processing " << i << "th daughter of "
97 // << lv->GetName() << G4endl;
98 G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
99 G4String lvdName = lvd->GetName();
101 if (fVolumeNames.find(lvdName) == fVolumeNames.end()) {
102 // process lvd only if it was not yet processed
108 //_____________________________________________________________________________
109 void TG4XMLGeometryGenerator::ProcessMaterials(G4LogicalVolume* lv)
111 // Writes all materials of given logical volume.
114 G4Material* material = lv->GetMaterial();
116 // check if this material was already written
117 G4bool written = false;
118 G4String name = material->GetName();
120 if (fMaterialNames.find(name) != fMaterialNames.end()) written = true;
123 fConvertor->WriteMaterial(material);
124 fMaterialNames.insert(fMaterialNames.begin(), name);
127 // store the name of logical volume in the set
128 G4String lvName = lv->GetName();
129 fVolumeNames.insert(fVolumeNames.begin(), lvName);
131 G4int nofDaughters = lv->GetNoDaughters();
133 for (G4int i=0; i<nofDaughters; i++) {
134 G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
135 G4String lvdName = lvd->GetName();
137 if (fVolumeNames.find(lvdName) == fVolumeNames.end()) {
138 // process lvd only if it was not yet processed
139 ProcessMaterials(lvd);
144 //_____________________________________________________________________________
145 void TG4XMLGeometryGenerator::ProcessRotations(G4LogicalVolume* lv)
147 // Writes all rotation matrices of given logical volume.
150 G4String lvName = lv->GetName();
152 // store the name of logical volume in the set
153 fVolumeNames.insert(fVolumeNames.begin(), lvName);
155 G4int nofDaughters = lv->GetNoDaughters();
157 if (nofDaughters>0) {
159 for (i=0; i<nofDaughters; i++) {
161 G4VPhysicalVolume* pvd = lv->GetDaughter(i);
162 const G4RotationMatrix* kRotation = pvd->GetRotation();
164 fConvertor->WriteRotation(kRotation);
166 G4LogicalVolume* lvd = pvd->GetLogicalVolume();
167 G4String lvdName = lvd->GetName();
169 if (fVolumeNames.find(lvdName) == fVolumeNames.end()) {
170 // process lvd only if it was not yet processed
171 ProcessRotations(lvd);
177 //_____________________________________________________________________________
178 void TG4XMLGeometryGenerator::ProcessLogicalVolume(G4LogicalVolume* lv)
180 // Writes logical volume tree.
183 G4int nofDaughters = lv->GetNoDaughters();
184 if (nofDaughters == 0) return;
187 G4String lvName = lv->GetName();
188 G4String name = lvName;
189 name.append("_comp");
190 fConvertor->OpenComposition(name);
194 for (i=0; i<nofDaughters; i++) {
195 // G4cout << "processing " << i << "th daughter of "
196 // << lv->GetName() << G4endl;
198 G4VPhysicalVolume* vpvd = lv->GetDaughter(i);
199 G4LogicalVolume* lvd = vpvd->GetLogicalVolume();
202 G4String lvName = lvd->GetName();
203 G4String compName = lvd->GetName();
204 compName.append("_comp");
205 G4int nd = lvd->GetNoDaughters();
207 G4PVPlacement* pvd = dynamic_cast<G4PVPlacement*>(vpvd);
210 G4ThreeVector position = vpvd->GetTranslation();
212 if (!vpvd->GetRotation()) {
213 fConvertor->WritePosition(lvName, position);
214 // if volume is not leaf node place its logical volume
216 fConvertor->WritePosition(compName, position);
219 const G4RotationMatrix* kMatrix = vpvd->GetObjectRotation();
220 fConvertor->WritePositionWithRotation(lvName, position, kMatrix);
222 fConvertor->WritePositionWithRotation(compName, position, kMatrix);
226 G4PVReplica* pvr = dynamic_cast<G4PVReplica*>(vpvd);
229 fConvertor->WriteReplica(lvName, pvr);
230 // if volume is not leaf node place its logical volume
232 fConvertor->WriteReplica(compName, pvr);
235 G4String text = "TG4XMLGeometryGenerator::ProcessLogicalVolume: \n";
236 text = text + " Limitation: \n";
237 text = text + " Other physical volumes than PVPlacement and PVReplica";
238 text = text + " are not implemented.";
239 TG4Globals::Exception(text);
245 fConvertor->CloseComposition();
246 fConvertor->WriteEmptyLine();
248 // store the name of logical volume in the set
249 fVolumeNames.insert(fVolumeNames.begin(), lvName);
252 for (i=0; i<nofDaughters; i++) {
253 G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
254 G4String lvdName = lvd->GetName();
256 if (fVolumeNames.find(lvdName) == fVolumeNames.end()) {
257 // process lvd only if it was not yet processed
258 ProcessLogicalVolume(lvd);
263 //_____________________________________________________________________________
264 void TG4XMLGeometryGenerator::ClearMaterialNames()
266 // Clears the set of material names.
269 fMaterialNames.erase(fMaterialNames.begin(), fMaterialNames.end());
272 //_____________________________________________________________________________
273 void TG4XMLGeometryGenerator::ClearVolumeNames()
275 // Clears the set of volume names.
278 fVolumeNames.erase(fVolumeNames.begin(), fVolumeNames.end());
283 //_____________________________________________________________________________
284 void TG4XMLGeometryGenerator::GenerateMaterials(
285 const G4String& version, const G4String& date,
286 const G4String& author, const G4String dtdVersion,
289 // Generates the XML material element containing
290 // all materials present in given logical volume.
294 fConvertor->OpenMaterials(version, date, author, dtdVersion);
295 fConvertor->WriteEmptyLine();
298 ProcessMaterials(lv);
299 fConvertor->WriteEmptyLine();
300 ClearMaterialNames();
304 fConvertor->CloseMaterials();
305 fConvertor->WriteEmptyLine();
308 //_____________________________________________________________________________
309 void TG4XMLGeometryGenerator::GenerateSection(const G4String& name,
310 const G4String& version, const G4String& date,
311 const G4String& author, const G4String& topVolume,
314 // Generates the XML section element containing
315 // all geometry objects defined in given logical volume:
316 // rotation matrices, solids and volumes hierarchy.
320 fConvertor->OpenSection(name, version, date, author, topVolume);
321 fConvertor->WriteEmptyLine();
324 //ProcessRotations(lv);
325 //fConvertor->WriteEmptyLine();
327 //ClearVolumeNames();
331 fConvertor->WriteEmptyLine();
334 // process geometry tree
335 ProcessLogicalVolume(lv);
336 fConvertor->WriteEmptyLine();
340 fConvertor->CloseSection();
343 //_____________________________________________________________________________
344 void TG4XMLGeometryGenerator::OpenFile(G4String filePath)
346 // Opens output file.
349 fOutFile.open(filePath, G4std::ios::out);
352 G4String text = "Cannot open ";
353 text = text + filePath;
354 TG4Globals::Warning(text);
357 // use FORTRAN compatibility output
358 fOutFile.setf(G4std::ios::fixed, G4std::ios::floatfield);
362 //_____________________________________________________________________________
363 void TG4XMLGeometryGenerator::CloseFile()
365 // Closes output file.