]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TGeant4/TG4XMLGeometryGenerator.cxx
Add ResetDecayTable() and SsetDecayTable() methods.
[u/mrichter/AliRoot.git] / TGeant4 / TG4XMLGeometryGenerator.cxx
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>
16 #include <G4PVReplica.hh>
17 #include <G4ThreeVector.hh>
18 #include <G4RotationMatrix.hh>
19
20 #include <g4std/iomanip>
21 #include <g4std/vector>
22
23 TG4XMLGeometryGenerator* TG4XMLGeometryGenerator::fgInstance = 0;
24
25 TG4XMLGeometryGenerator::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
36 TG4XMLGeometryGenerator::TG4XMLGeometryGenerator(const TG4XMLGeometryGenerator& right) 
37 {
38 // 
39   TG4Globals::Exception(
40     "TG4XMLGeometryGenerator: attempt to copy singleton.");
41 }
42
43
44 TG4XMLGeometryGenerator::~TG4XMLGeometryGenerator() {
45 //
46 }
47
48 // operators
49
50 TG4XMLGeometryGenerator& 
51 TG4XMLGeometryGenerator::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
65 void 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
74 void TG4XMLGeometryGenerator::ProcessSolids(G4LogicalVolume* lv) 
75 {
76 // Writes all solids of given logical volume.
77 // ---
78
79   G4VSolid* solid = lv->GetSolid();
80   G4String lvName = lv->GetName();
81   G4String material = lv->GetMaterial()->GetName();
82   fConvertor->WriteSolid(lvName, solid, material);
83   
84   // store the name of logical volume in the set
85   fVolumeNames.insert(fVolumeNames.begin(), lvName); 
86
87   // process daughters
88   G4int nofDaughters = lv->GetNoDaughters();
89   if (nofDaughters>0) 
90     for (G4int i=0; i<nofDaughters; i++) {
91       //G4cout << "processing " << i << "th daughter of " 
92       //       << lv->GetName() << G4endl;
93       G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
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       } 
100     }
101 }  
102
103 void TG4XMLGeometryGenerator::ProcessMaterials(G4LogicalVolume* lv) 
104 {
105 // Writes all materials of given logical volume.
106 // ---
107
108   G4Material* material = lv->GetMaterial();
109   
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
125   G4int nofDaughters = lv->GetNoDaughters();
126   if (nofDaughters>0) 
127     for (G4int i=0; i<nofDaughters; i++) {
128       G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
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       } 
135     }
136 }  
137
138 void TG4XMLGeometryGenerator::ProcessRotations(G4LogicalVolume* lv) 
139 {
140 // Writes all rotation matrices of given logical volume.
141 // ---
142
143   G4String lvName = lv->GetName();
144
145   // store the name of logical volume in the set
146   fVolumeNames.insert(fVolumeNames.begin(), lvName); 
147   
148   G4int nofDaughters = lv->GetNoDaughters();
149
150   if (nofDaughters>0) {
151     G4int i; 
152     for (i=0; i<nofDaughters; i++) {
153       
154       G4VPhysicalVolume* pvd = lv->GetDaughter(i);
155       const G4RotationMatrix* kRotation = pvd->GetRotation();
156       if (kRotation) 
157         fConvertor->WriteRotation(kRotation);
158
159       G4LogicalVolume* lvd = pvd->GetLogicalVolume();
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       } 
166     }
167   }  
168 }  
169
170 void TG4XMLGeometryGenerator::ProcessLogicalVolume(G4LogicalVolume* lv) 
171 {
172 // Writes logical volume tree.
173 // ---
174   
175   G4int nofDaughters = lv->GetNoDaughters();
176   if (nofDaughters == 0) return;
177   
178   // open composition
179   G4String lvName = lv->GetName();
180   G4String name = lvName;
181   name.append("_comp");
182   fConvertor->OpenComposition(name);
183   
184   // write positions  
185   G4int i;
186   for (i=0; i<nofDaughters; i++) {
187    // G4cout << "processing " << i << "th daughter of " 
188    //        << lv->GetName() << G4endl;
189    
190     G4VPhysicalVolume* vpvd = lv->GetDaughter(i);
191     G4LogicalVolume* lvd = vpvd->GetLogicalVolume();
192       
193     // get parameters
194     G4String lvName = lvd->GetName();
195     G4String compName = lvd->GetName();
196     compName.append("_comp");      
197     G4int nd = lvd->GetNoDaughters(); 
198
199     G4PVPlacement* pvd = dynamic_cast<G4PVPlacement*>(vpvd);
200     if (pvd) {
201       // placement
202       G4ThreeVector  position = vpvd->GetTranslation();
203
204       if (!vpvd->GetRotation()) {
205         fConvertor->WritePosition(lvName, position);
206         // if volume is not leaf node place its logical volume
207         if (nd>0) 
208           fConvertor->WritePosition(compName, position);
209       }   
210       else {  
211         const G4RotationMatrix* kMatrix = vpvd->GetObjectRotation();      
212         fConvertor->WritePositionWithRotation(lvName, position, kMatrix);
213         if (nd>0) 
214            fConvertor->WritePositionWithRotation(compName, position, kMatrix);
215       }
216     }
217     else {
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     }  
234   }  
235
236   // close composition
237   fConvertor->CloseComposition();       
238   fConvertor->WriteEmptyLine();
239
240   // store the name of logical volume in the set
241   fVolumeNames.insert(fVolumeNames.begin(), lvName); 
242
243   // process daughters
244   for (i=0; i<nofDaughters; i++) {
245     G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
246     G4String lvdName = lvd->GetName();
247
248     if (fVolumeNames.find(lvdName) == fVolumeNames.end()) {
249       // process lvd only if it was not yet processed
250       ProcessLogicalVolume(lvd);
251     }
252   }    
253 }  
254
255 void TG4XMLGeometryGenerator::ClearMaterialNames() 
256 {
257 // Clears the set of material names.
258 // ---
259
260   fMaterialNames.erase(fMaterialNames.begin(), fMaterialNames.end());
261 }  
262
263 void TG4XMLGeometryGenerator::ClearVolumeNames() 
264 {
265 // Clears the set of volume names.
266 // ---
267
268   fVolumeNames.erase(fVolumeNames.begin(), fVolumeNames.end());
269 }  
270
271 // public methods
272
273 void 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();
289   ClearMaterialNames();
290   ClearVolumeNames();
291
292   // close section
293   fConvertor->CloseMaterials();
294   fConvertor->WriteEmptyLine();
295 }   
296
297 void TG4XMLGeometryGenerator::GenerateSection(const G4String& name, 
298                         const G4String& version, const G4String& date,
299                         const G4String& author, const G4String& topVolume,
300                         G4LogicalVolume* lv)
301 {
302 // Generates the XML section element containing
303 // all geometry objects defined in given logical volume:
304 // rotation matrices, solids and volumes hierarchy.
305 // ---
306
307   // create section
308   fConvertor->OpenSection(name, version, date, author, topVolume);  
309   fConvertor->WriteEmptyLine();
310   
311   // process rotations
312   //ProcessRotations(lv);
313   //fConvertor->WriteEmptyLine();
314   //ClearRotations();
315   //ClearVolumeNames();
316     
317   // process solids
318   ProcessSolids(lv);
319   fConvertor->WriteEmptyLine();
320   ClearVolumeNames();
321     
322   // process geometry tree
323   ProcessLogicalVolume(lv);
324   fConvertor->WriteEmptyLine();
325   ClearVolumeNames();
326   
327   // close section
328   fConvertor->CloseSection();
329 }   
330
331 void TG4XMLGeometryGenerator::OpenFile(G4String filePath)
332
333 // Opens output file.
334 // ---
335
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
349 void TG4XMLGeometryGenerator::CloseFile()
350
351 // Closes output file.
352 // ---
353
354   fOutFile.close(); 
355 }