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