]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TGeant4/TG4XMLGeometryGenerator.cxx
Put vacuum in beam-pipe not air.
[u/mrichter/AliRoot.git] / TGeant4 / TG4XMLGeometryGenerator.cxx
CommitLineData
240601e9 1// $Id$
2// Category: geometry
3// by I. Hrivnacova, 27.07.2000
4//
5// See the class description in the header file.
6
7#include "TG4XMLGeometryGenerator.h"
8#include "TG4XMLConvertor.h"
9#include "TG4Globals.h"
10
11#include <G4Material.hh>
12#include <G4VSolid.hh>
13#include <G4LogicalVolume.hh>
14#include <G4VPhysicalVolume.hh>
15#include <G4PVPlacement.hh>
ee28e1fa 16#include <G4PVReplica.hh>
240601e9 17#include <G4ThreeVector.hh>
18#include <G4RotationMatrix.hh>
19
20#include <g4std/iomanip>
21#include <g4std/vector>
22
23TG4XMLGeometryGenerator* TG4XMLGeometryGenerator::fgInstance = 0;
24
25TG4XMLGeometryGenerator::TG4XMLGeometryGenerator()
26{
27//
28 if (fgInstance) {
29 TG4Globals::Exception(
30 "TG4XMLGeometryGenerator: attempt to create two instances of singleton.");
31 }
32
33 fConvertor = new TG4XMLConvertor(fOutFile);
34}
35
36TG4XMLGeometryGenerator::TG4XMLGeometryGenerator(const TG4XMLGeometryGenerator& right)
37{
38//
39 TG4Globals::Exception(
40 "TG4XMLGeometryGenerator: attempt to copy singleton.");
41}
42
43
44TG4XMLGeometryGenerator::~TG4XMLGeometryGenerator() {
45//
46}
47
48// operators
49
50TG4XMLGeometryGenerator&
51TG4XMLGeometryGenerator::operator=(const TG4XMLGeometryGenerator& right)
52{
53 // check assignement to self
54 if (this == &right) return *this;
55
56 TG4Globals::Exception(
57 "Attempt to assign TG4XMLGeometryGenerator singleton.");
58
59 return *this;
60}
61
62
63// private methods
64
4032dc03 65void TG4XMLGeometryGenerator::CutName(G4String& name) const
66{
67// Removes spaces after the name if present.
68// ---
69
70 G4int i = name.length();
71 while (name(--i) == ' ') name = name(0,i);
72}
73
240601e9 74void TG4XMLGeometryGenerator::ProcessSolids(G4LogicalVolume* lv)
75{
76// Writes all solids of given logical volume.
77// ---
78
79 G4VSolid* solid = lv->GetSolid();
4032dc03 80 G4String lvName = lv->GetName();
240601e9 81 G4String material = lv->GetMaterial()->GetName();
4032dc03 82 fConvertor->WriteSolid(lvName, solid, material);
240601e9 83
4032dc03 84 // store the name of logical volume in the set
85 fVolumeNames.insert(fVolumeNames.begin(), lvName);
86
87 // process daughters
240601e9 88 G4int nofDaughters = lv->GetNoDaughters();
89 if (nofDaughters>0)
90 for (G4int i=0; i<nofDaughters; i++) {
4032dc03 91 //G4cout << "processing " << i << "th daughter of "
92 // << lv->GetName() << G4endl;
240601e9 93 G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
4032dc03 94 G4String lvdName = lvd->GetName();
95
96 if (fVolumeNames.find(lvdName) == fVolumeNames.end()) {
97 // process lvd only if it was not yet processed
98 ProcessSolids(lvd);
99 }
240601e9 100 }
101}
102
103void TG4XMLGeometryGenerator::ProcessMaterials(G4LogicalVolume* lv)
104{
105// Writes all materials of given logical volume.
106// ---
107
108 G4Material* material = lv->GetMaterial();
240601e9 109
4032dc03 110 // check if this material was already written
111 G4bool written = false;
112 G4String name = material->GetName();
113 CutName(name);
114 if (fMaterialNames.find(name) != fMaterialNames.end()) written = true;
115
116 if (!written) {
117 fConvertor->WriteMaterial(material);
118 fMaterialNames.insert(fMaterialNames.begin(), name);
119 }
120
121 // store the name of logical volume in the set
122 G4String lvName = lv->GetName();
123 fVolumeNames.insert(fVolumeNames.begin(), lvName);
124
240601e9 125 G4int nofDaughters = lv->GetNoDaughters();
126 if (nofDaughters>0)
127 for (G4int i=0; i<nofDaughters; i++) {
128 G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
4032dc03 129 G4String lvdName = lvd->GetName();
130
131 if (fVolumeNames.find(lvdName) == fVolumeNames.end()) {
132 // process lvd only if it was not yet processed
133 ProcessMaterials(lvd);
134 }
240601e9 135 }
136}
137
9d37cb3b 138void TG4XMLGeometryGenerator::ProcessRotations(G4LogicalVolume* lv)
139{
140// Writes all rotation matrices of given logical volume.
141// ---
142
4032dc03 143 G4String lvName = lv->GetName();
144
145 // store the name of logical volume in the set
146 fVolumeNames.insert(fVolumeNames.begin(), lvName);
147
9d37cb3b 148 G4int nofDaughters = lv->GetNoDaughters();
4032dc03 149
150 if (nofDaughters>0) {
151 G4int i;
152 for (i=0; i<nofDaughters; i++) {
153
9d37cb3b 154 G4VPhysicalVolume* pvd = lv->GetDaughter(i);
155 const G4RotationMatrix* kRotation = pvd->GetRotation();
4032dc03 156 if (kRotation)
157 fConvertor->WriteRotation(kRotation);
158
9d37cb3b 159 G4LogicalVolume* lvd = pvd->GetLogicalVolume();
4032dc03 160 G4String lvdName = lvd->GetName();
161
162 if (fVolumeNames.find(lvdName) == fVolumeNames.end()) {
163 // process lvd only if it was not yet processed
164 ProcessRotations(lvd);
165 }
9d37cb3b 166 }
4032dc03 167 }
9d37cb3b 168}
169
240601e9 170void TG4XMLGeometryGenerator::ProcessLogicalVolume(G4LogicalVolume* lv)
171{
172// Writes logical volume tree.
173// ---
174
175 G4int nofDaughters = lv->GetNoDaughters();
176 if (nofDaughters == 0) return;
177
9d37cb3b 178 // open composition
4032dc03 179 G4String lvName = lv->GetName();
180 G4String name = lvName;
9d37cb3b 181 name.append("_comp");
182 fConvertor->OpenComposition(name);
4032dc03 183
9d37cb3b 184 // write positions
c7049a8c 185 G4int i;
186 for (i=0; i<nofDaughters; i++) {
4032dc03 187 // G4cout << "processing " << i << "th daughter of "
188 // << lv->GetName() << G4endl;
189
9d37cb3b 190 G4VPhysicalVolume* vpvd = lv->GetDaughter(i);
191 G4LogicalVolume* lvd = vpvd->GetLogicalVolume();
192
ee28e1fa 193 // get parameters
194 G4String lvName = lvd->GetName();
195 G4String compName = lvd->GetName();
196 compName.append("_comp");
197 G4int nd = lvd->GetNoDaughters();
4032dc03 198
9d37cb3b 199 G4PVPlacement* pvd = dynamic_cast<G4PVPlacement*>(vpvd);
200 if (pvd) {
ee28e1fa 201 // placement
4032dc03 202 G4ThreeVector position = vpvd->GetTranslation();
9d37cb3b 203
63c91916 204 if (!vpvd->GetRotation()) {
4032dc03 205 fConvertor->WritePosition(lvName, position);
9d37cb3b 206 // if volume is not leaf node place its logical volume
207 if (nd>0)
208 fConvertor->WritePosition(compName, position);
209 }
210 else {
63c91916 211 const G4RotationMatrix* kMatrix = vpvd->GetObjectRotation();
4032dc03 212 fConvertor->WritePositionWithRotation(lvName, position, kMatrix);
9d37cb3b 213 if (nd>0)
214 fConvertor->WritePositionWithRotation(compName, position, kMatrix);
ee28e1fa 215 }
9d37cb3b 216 }
217 else {
ee28e1fa 218 G4PVReplica* pvr = dynamic_cast<G4PVReplica*>(vpvd);
219 if (pvr) {
220 // replica
221 fConvertor->WriteReplica(lvName, pvr);
222 // if volume is not leaf node place its logical volume
223 if (nd>0)
224 fConvertor->WriteReplica(compName, pvr);
225 }
226 else {
227 G4String text = "TG4XMLGeometryGenerator::ProcessLogicalVolume: \n";
228 text = text + " Limitation: \n";
229 text = text + " Other physical volumes than PVPlacement and PVReplica";
230 text = text + " are not implemented.";
231 TG4Globals::Exception(text);
232 }
233 }
9d37cb3b 234 }
235
236 // close composition
237 fConvertor->CloseComposition();
238 fConvertor->WriteEmptyLine();
239
4032dc03 240 // store the name of logical volume in the set
241 fVolumeNames.insert(fVolumeNames.begin(), lvName);
242
243 // process daughters
c7049a8c 244 for (i=0; i<nofDaughters; i++) {
9d37cb3b 245 G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
4032dc03 246 G4String lvdName = lvd->GetName();
247
4032dc03 248 if (fVolumeNames.find(lvdName) == fVolumeNames.end()) {
249 // process lvd only if it was not yet processed
250 ProcessLogicalVolume(lvd);
251 }
252 }
9d37cb3b 253}
254
4032dc03 255void TG4XMLGeometryGenerator::ClearMaterialNames()
9d37cb3b 256{
4032dc03 257// Clears the set of material names.
9d37cb3b 258// ---
240601e9 259
4032dc03 260 fMaterialNames.erase(fMaterialNames.begin(), fMaterialNames.end());
261}
262
263void TG4XMLGeometryGenerator::ClearVolumeNames()
264{
265// Clears the set of volume names.
266// ---
267
268 fVolumeNames.erase(fVolumeNames.begin(), fVolumeNames.end());
240601e9 269}
270
271// public methods
272
9d37cb3b 273void TG4XMLGeometryGenerator::GenerateMaterials(
274 const G4String& version, const G4String& date,
275 const G4String& author, const G4String dtdVersion,
276 G4LogicalVolume* lv)
277{
278// Generates the XML material element containing
279// all materials present in given logical volume.
280// ---
281
282 // create section
283 fConvertor->OpenMaterials(version, date, author, dtdVersion);
284 fConvertor->WriteEmptyLine();
285
286 // process materials
287 ProcessMaterials(lv);
288 fConvertor->WriteEmptyLine();
4032dc03 289 ClearMaterialNames();
290 ClearVolumeNames();
9d37cb3b 291
292 // close section
293 fConvertor->CloseMaterials();
294 fConvertor->WriteEmptyLine();
295}
296
240601e9 297void TG4XMLGeometryGenerator::GenerateSection(const G4String& name,
298 const G4String& version, const G4String& date,
299 const G4String& author, const G4String& topVolume,
300 G4LogicalVolume* lv)
301{
9d37cb3b 302// Generates the XML section element containing
240601e9 303// all geometry objects defined in given logical volume:
9d37cb3b 304// rotation matrices, solids and volumes hierarchy.
240601e9 305// ---
306
307 // create section
308 fConvertor->OpenSection(name, version, date, author, topVolume);
309 fConvertor->WriteEmptyLine();
310
9d37cb3b 311 // process rotations
4032dc03 312 //ProcessRotations(lv);
313 //fConvertor->WriteEmptyLine();
314 //ClearRotations();
315 //ClearVolumeNames();
9d37cb3b 316
240601e9 317 // process solids
318 ProcessSolids(lv);
319 fConvertor->WriteEmptyLine();
4032dc03 320 ClearVolumeNames();
240601e9 321
322 // process geometry tree
240601e9 323 ProcessLogicalVolume(lv);
240601e9 324 fConvertor->WriteEmptyLine();
4032dc03 325 ClearVolumeNames();
240601e9 326
327 // close section
328 fConvertor->CloseSection();
329}
330
331void TG4XMLGeometryGenerator::OpenFile(G4String filePath)
332{
333// Opens output file.
334// ---
335
240601e9 336 fOutFile.open(filePath, G4std::ios::out);
337
338 if (!fOutFile) {
339 G4String text = "Cannot open ";
340 text = text + filePath;
341 TG4Globals::Warning(text);
342 }
343
344 // use FORTRAN compatibility output
345 fOutFile.setf(G4std::ios::fixed, G4std::ios::floatfield);
346}
347
348
349void TG4XMLGeometryGenerator::CloseFile()
350{
351// Closes output file.
352// ---
353
354 fOutFile.close();
355}