]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TGeant4/TG4XMLGeometryGenerator.cxx
upgrade: added panels for viewing users limits (cuts, process controls) - D. Adamova
[u/mrichter/AliRoot.git] / TGeant4 / TG4XMLGeometryGenerator.cxx
1 // $Id$
2 // Category: geometry
3 //
4 // Author: I. Hrivnacova, 27.07.2000 
5 //
6 // Class TG4XMLGeometryGenerator
7 // -----------------------------
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>
19 #include <G4PVReplica.hh>
20 #include <G4ThreeVector.hh>
21 #include <G4RotationMatrix.hh>
22
23 #include <g4std/iomanip>
24 #include <g4std/vector>
25
26 TG4XMLGeometryGenerator* TG4XMLGeometryGenerator::fgInstance = 0;
27
28 //_____________________________________________________________________________
29 TG4XMLGeometryGenerator::TG4XMLGeometryGenerator()
30   : TG4Verbose("geometryGenerator") 
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
41 //_____________________________________________________________________________
42 TG4XMLGeometryGenerator::TG4XMLGeometryGenerator(
43                                        const TG4XMLGeometryGenerator& right) 
44   : TG4Verbose("geometryGenerator") 
45 {
46 // 
47   TG4Globals::Exception(
48     "TG4XMLGeometryGenerator: attempt to copy singleton.");
49 }
50
51 //_____________________________________________________________________________
52 TG4XMLGeometryGenerator::~TG4XMLGeometryGenerator() {
53 //
54 }
55
56 // operators
57
58 //_____________________________________________________________________________
59 TG4XMLGeometryGenerator& 
60 TG4XMLGeometryGenerator::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
74 //_____________________________________________________________________________
75 void 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
84 //_____________________________________________________________________________
85 void TG4XMLGeometryGenerator::ProcessSolids(G4LogicalVolume* lv) 
86 {
87 // Writes all solids of given logical volume.
88 // ---
89
90   G4VSolid* solid = lv->GetSolid();
91   G4String lvName = lv->GetName();
92   G4String material = lv->GetMaterial()->GetName();
93   fConvertor->WriteSolid(lvName, solid, material);
94   
95   // store the name of logical volume in the set
96   fVolumeNames.insert(fVolumeNames.begin(), lvName); 
97
98   // process daughters
99   G4int nofDaughters = lv->GetNoDaughters();
100   if (nofDaughters>0) 
101     for (G4int i=0; i<nofDaughters; i++) {
102
103       if (VerboseLevel() > 1) {
104         G4cout << "processing " << i << "th daughter of " 
105                << lv->GetName() << G4endl;
106       }
107               
108       G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
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       } 
115     }
116 }  
117
118 //_____________________________________________________________________________
119 void TG4XMLGeometryGenerator::ProcessMaterials(G4LogicalVolume* lv) 
120 {
121 // Writes all materials of given logical volume.
122 // ---
123
124   G4Material* material = lv->GetMaterial();
125   
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
141   G4int nofDaughters = lv->GetNoDaughters();
142   if (nofDaughters>0) 
143     for (G4int i=0; i<nofDaughters; i++) {
144       G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
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       } 
151     }
152 }  
153
154 //_____________________________________________________________________________
155 void TG4XMLGeometryGenerator::ProcessRotations(G4LogicalVolume* lv) 
156 {
157 // Writes all rotation matrices of given logical volume.
158 // ---
159
160   G4String lvName = lv->GetName();
161
162   // store the name of logical volume in the set
163   fVolumeNames.insert(fVolumeNames.begin(), lvName); 
164   
165   G4int nofDaughters = lv->GetNoDaughters();
166
167   if (nofDaughters>0) {
168     G4int i; 
169     for (i=0; i<nofDaughters; i++) {
170       
171       G4VPhysicalVolume* pvd = lv->GetDaughter(i);
172       const G4RotationMatrix* kRotation = pvd->GetRotation();
173       if (kRotation) 
174         fConvertor->WriteRotation(kRotation);
175
176       G4LogicalVolume* lvd = pvd->GetLogicalVolume();
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       } 
183     }
184   }  
185 }  
186
187 //_____________________________________________________________________________
188 void TG4XMLGeometryGenerator::ProcessLogicalVolume(G4LogicalVolume* lv) 
189 {
190 // Writes logical volume tree.
191 // ---
192   
193   G4int nofDaughters = lv->GetNoDaughters();
194   if (nofDaughters == 0) return;
195   
196   // open composition
197   G4String lvName = lv->GetName();
198   G4String name = lvName;
199   name.append("_comp");
200   fConvertor->OpenComposition(name);
201   
202   // write positions  
203   G4int i;
204   for (i=0; i<nofDaughters; i++) {
205
206     if (VerboseLevel() > 1) {
207       G4cout << "processing " << i << "th daughter of " 
208              << lv->GetName() << G4endl;
209     }        
210    
211     G4VPhysicalVolume* vpvd = lv->GetDaughter(i);
212     G4LogicalVolume* lvd = vpvd->GetLogicalVolume();
213       
214     // get parameters
215     G4String lvName = lvd->GetName();
216     G4String compName = lvd->GetName();
217     compName.append("_comp");      
218     G4int nd = lvd->GetNoDaughters(); 
219
220     G4PVPlacement* pvd = dynamic_cast<G4PVPlacement*>(vpvd);
221     if (pvd) {
222       // placement
223       G4ThreeVector  position = vpvd->GetTranslation();
224
225       if (!vpvd->GetRotation()) {
226         fConvertor->WritePosition(lvName, position);
227         // if volume is not leaf node place its logical volume
228         if (nd>0) 
229           fConvertor->WritePosition(compName, position);
230       }   
231       else {  
232         const G4RotationMatrix* kMatrix = vpvd->GetObjectRotation();      
233         fConvertor->WritePositionWithRotation(lvName, position, kMatrix);
234         if (nd>0) 
235            fConvertor->WritePositionWithRotation(compName, position, kMatrix);
236       }
237     }
238     else {
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     }  
255   }  
256
257   // close composition
258   fConvertor->CloseComposition();       
259   fConvertor->WriteEmptyLine();
260
261   // store the name of logical volume in the set
262   fVolumeNames.insert(fVolumeNames.begin(), lvName); 
263
264   // process daughters
265   for (i=0; i<nofDaughters; i++) {
266     G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
267     G4String lvdName = lvd->GetName();
268
269     if (fVolumeNames.find(lvdName) == fVolumeNames.end()) {
270       // process lvd only if it was not yet processed
271       ProcessLogicalVolume(lvd);
272     }
273   }    
274 }  
275
276 //_____________________________________________________________________________
277 void TG4XMLGeometryGenerator::ClearMaterialNames() 
278 {
279 // Clears the set of material names.
280 // ---
281
282   fMaterialNames.erase(fMaterialNames.begin(), fMaterialNames.end());
283 }  
284
285 //_____________________________________________________________________________
286 void TG4XMLGeometryGenerator::ClearVolumeNames() 
287 {
288 // Clears the set of volume names.
289 // ---
290
291   fVolumeNames.erase(fVolumeNames.begin(), fVolumeNames.end());
292 }  
293
294 // public methods
295
296 //_____________________________________________________________________________
297 void 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();
313   ClearMaterialNames();
314   ClearVolumeNames();
315
316   // close section
317   fConvertor->CloseMaterials();
318   fConvertor->WriteEmptyLine();
319 }   
320
321 //_____________________________________________________________________________
322 void TG4XMLGeometryGenerator::GenerateSection(const G4String& name, 
323                         const G4String& version, const G4String& date,
324                         const G4String& author, const G4String& topVolume,
325                         G4LogicalVolume* lv)
326 {
327 // Generates the XML section element containing
328 // all geometry objects defined in given logical volume:
329 // rotation matrices, solids and volumes hierarchy.
330 // ---
331
332   // create section
333   fConvertor->OpenSection(name, version, date, author, topVolume);  
334   fConvertor->WriteEmptyLine();
335   
336   // process rotations
337   //ProcessRotations(lv);
338   //fConvertor->WriteEmptyLine();
339   //ClearRotations();
340   //ClearVolumeNames();
341     
342   // process solids
343   ProcessSolids(lv);
344   fConvertor->WriteEmptyLine();
345   ClearVolumeNames();
346     
347   // process geometry tree
348   ProcessLogicalVolume(lv);
349   fConvertor->WriteEmptyLine();
350   ClearVolumeNames();
351   
352   // close section
353   fConvertor->CloseSection();
354 }   
355
356 //_____________________________________________________________________________
357 void TG4XMLGeometryGenerator::OpenFile(G4String filePath)
358
359 // Opens output file.
360 // ---
361
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
375 //_____________________________________________________________________________
376 void TG4XMLGeometryGenerator::CloseFile()
377
378 // Closes output file.
379 // ---
380
381   fOutFile.close(); 
382 }