]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TGeant4/TG4XMLGeometryGenerator.cxx
corrected declaration of for-loop variable (required on HP-aCC)
[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 <G4ThreeVector.hh>
17 #include <G4RotationMatrix.hh>
18
19 #include <g4std/iomanip>
20 #include <g4std/vector>
21
22 TG4XMLGeometryGenerator* TG4XMLGeometryGenerator::fgInstance = 0;
23
24 TG4XMLGeometryGenerator::TG4XMLGeometryGenerator() 
25 {
26 //
27   if (fgInstance) {
28     TG4Globals::Exception(
29       "TG4XMLGeometryGenerator: attempt to create two instances of singleton.");
30   }
31
32   fConvertor = new TG4XMLConvertor(fOutFile);  
33 }
34
35 TG4XMLGeometryGenerator::TG4XMLGeometryGenerator(const TG4XMLGeometryGenerator& right) 
36 {
37 // 
38   TG4Globals::Exception(
39     "TG4XMLGeometryGenerator: attempt to copy singleton.");
40 }
41
42
43 TG4XMLGeometryGenerator::~TG4XMLGeometryGenerator() {
44 //
45 }
46
47 // operators
48
49 TG4XMLGeometryGenerator& 
50 TG4XMLGeometryGenerator::operator=(const TG4XMLGeometryGenerator& right)
51 {
52   // check assignement to self
53   if (this == &right) return *this;
54
55   TG4Globals::Exception(
56     "Attempt to assign TG4XMLGeometryGenerator singleton.");
57     
58   return *this;  
59 }    
60           
61
62 // private methods
63
64 void TG4XMLGeometryGenerator::ProcessSolids(G4LogicalVolume* lv) 
65 {
66 // Writes all solids of given logical volume.
67 // ---
68
69   G4VSolid* solid = lv->GetSolid();
70   G4String material = lv->GetMaterial()->GetName();
71   fConvertor->WriteSolid(solid, material);
72   
73   G4int nofDaughters = lv->GetNoDaughters();
74   if (nofDaughters>0) 
75     for (G4int i=0; i<nofDaughters; i++) {
76       G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
77       ProcessSolids(lvd);
78     }
79 }  
80
81 void TG4XMLGeometryGenerator::ProcessMaterials(G4LogicalVolume* lv) 
82 {
83 // Writes all materials of given logical volume.
84 // ---
85
86   G4Material* material = lv->GetMaterial();
87   fConvertor->WriteMaterial(material);
88   
89   G4int nofDaughters = lv->GetNoDaughters();
90   if (nofDaughters>0) 
91     for (G4int i=0; i<nofDaughters; i++) {
92       G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
93       ProcessMaterials(lvd);
94     }
95 }  
96
97 void TG4XMLGeometryGenerator::ProcessRotations(G4LogicalVolume* lv) 
98 {
99 // Writes all rotation matrices of given logical volume.
100 // ---
101
102   G4int nofDaughters = lv->GetNoDaughters();
103   if (nofDaughters>0) 
104     for (G4int i=0; i<nofDaughters; i++) {
105       G4VPhysicalVolume* pvd = lv->GetDaughter(i);
106       const G4RotationMatrix* kRotation = pvd->GetRotation();
107       if (kRotation) fConvertor->WriteRotation(kRotation);
108       G4LogicalVolume* lvd = pvd->GetLogicalVolume();
109       ProcessRotations(lvd);
110     }
111 }  
112
113 void TG4XMLGeometryGenerator::ProcessLogicalVolume(G4LogicalVolume* lv) 
114 {
115 // Writes logical volume tree.
116 // ---
117   
118   G4int nofDaughters = lv->GetNoDaughters();
119   if (nofDaughters == 0) return;
120   
121   // open composition
122   G4String name = lv->GetName();
123   name.append("_comp");
124   fConvertor->OpenComposition(name);
125       
126   // write positions  
127   G4int i;
128   for (i=0; i<nofDaughters; i++) {
129     G4VPhysicalVolume* vpvd = lv->GetDaughter(i);
130     G4LogicalVolume* lvd = vpvd->GetLogicalVolume();
131       
132     // only placements are processed
133     G4PVPlacement* pvd = dynamic_cast<G4PVPlacement*>(vpvd);
134     if (pvd) {
135       G4String solidName = lvd->GetSolid()->GetName();
136       G4String compName = lvd->GetName();
137       compName.append("_comp");      
138       G4int nd = lvd->GetNoDaughters(); 
139       G4ThreeVector  position = vpvd->GetFrameTranslation();
140       const G4RotationMatrix* kMatrix = vpvd->GetFrameRotation();      
141
142       if (!kMatrix) {
143         fConvertor->WritePosition(solidName, position);
144         // if volume is not leaf node place its logical volume
145         if (nd>0) 
146           fConvertor->WritePosition(compName, position);
147       }   
148       else {  
149         fConvertor->WritePositionWithRotation(solidName, position, kMatrix);
150         if (nd>0) 
151            fConvertor->WritePositionWithRotation(compName, position, kMatrix);
152       }   
153            
154     }
155     else {
156       G4String text = "TG4XMLGeometryGenerator::ProcessLogicalVolume: \n";
157       text = text + "    Limitation: \n";
158       text = text + "    Other physical volumes than PVPlacement";
159       text = text + " are not implemented.";
160       TG4Globals::Warning(text);
161     }
162   }  
163
164   // close composition
165   fConvertor->CloseComposition();       
166   fConvertor->WriteEmptyLine();
167
168   // make a vector of contained logical volumes
169   // with daughters
170   // -> change to a global map of names of written compositions 
171   //    and test against this map 
172   G4std::vector<G4LogicalVolume*> vect;
173   for (i=0; i<nofDaughters; i++) {
174     G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
175     G4bool store = true;
176     for (G4int j=0; j<vect.size(); j++) 
177       if (vect[j] == lvd || lvd->GetNoDaughters()==0) store = false;
178     if (store) vect.push_back(lvd);
179   }   
180
181   // process contained logical volumes with daughters  
182   fConvertor->IncreaseIndention();
183   for (G4int j=0; j<vect.size(); j++) 
184     ProcessLogicalVolume(vect[j]);
185   fConvertor->DecreaseIndention();
186 }  
187
188 /*
189 void TG4XMLGeometryGenerator::ProcessLogicalVolumeOld(G4LogicalVolume* lv) 
190 {
191 // Writes logical volume tree.
192 // ---
193   
194   G4int nofDaughters = lv->GetNoDaughters();
195   if (nofDaughters == 0) return;
196   
197   // make a vector of contained logical volumes
198   G4std::vector<G4LogicalVolume*> vect;
199   for (G4int i=0; i<nofDaughters; i++) {
200     G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
201     G4bool store = true;
202     for (G4int j=0; j<vect.size(); j++) 
203       if (vect[j] == lvd) store = false;
204     if (store) vect.push_back(lvd);
205   }   
206
207   // loop over contained logical volumes
208   for (G4int j=0; j<vect.size(); j++) {
209     G4LogicalVolume* lvd = vect[j];
210  
211     // open composition
212     if(lvd->GetNoDaughters()>0) {
213       G4String name = lvd->GetName();
214       name.append("_lv");
215       fConvertor->OpenComposition(name);
216     }   
217       
218     // write positions  
219     for (G4int i=0; i<nofDaughters; i++) {
220       G4VPhysicalVolume* vpvd = lv->GetDaughter(i);
221       G4LogicalVolume* lvdi = vpvd->GetLogicalVolume();
222       
223       if (lvdi == lvd) {
224         // only placements are processed
225         G4PVPlacement* pvd = dynamic_cast<G4PVPlacement*>(vpvd);
226         if (pvd) {
227           G4String solidName = lvd->GetSolid()->GetName();
228           G4ThreeVector  position = vpvd->GetFrameTranslation();
229           const G4RotationMatrix* kMatrix = vpvd->GetFrameRotation();      
230           if (!kMatrix)
231             fConvertor->WritePosition(solidName, position);
232           else  
233             fConvertor->WritePositionWithRotation(solidName, position, kMatrix);
234         }
235         else {
236           G4String text = "TG4XMLGeometryGenerator::ProcessLogicalVolume: \n";
237           text = text + "    Limitation: \n";
238           text = text + "    Other physical volumes than PVPlacement";
239           text = text + " are not implemented.";
240           TG4Globals::Warning(text);
241         }
242       } 
243     }
244
245     if(lvd->GetNoDaughters()>0) {
246       // process daughters recursively
247       ProcessLogicalVolume(lvd);
248       fConvertor->CloseComposition();   
249       fConvertor->WriteEmptyLine();
250     }
251   }
252 }  
253 */
254
255 // public methods
256
257 void TG4XMLGeometryGenerator::GenerateMaterials( 
258                         const G4String& version, const G4String& date,
259                         const G4String& author,  const G4String dtdVersion,
260                         G4LogicalVolume* lv)
261 {
262 // Generates the XML material element containing
263 // all materials present in given logical volume.
264 // ---
265
266   // create section
267   fConvertor->OpenMaterials(version, date, author, dtdVersion);  
268   fConvertor->WriteEmptyLine();
269   
270   // process materials
271   ProcessMaterials(lv);
272   fConvertor->WriteEmptyLine();
273
274   // close section
275   fConvertor->CloseMaterials();
276   fConvertor->WriteEmptyLine();
277 }   
278
279 void TG4XMLGeometryGenerator::GenerateSection(const G4String& name, 
280                         const G4String& version, const G4String& date,
281                         const G4String& author, const G4String& topVolume,
282                         G4LogicalVolume* lv)
283 {
284 // Generates the XML section element containing
285 // all geometry objects defined in given logical volume:
286 // rotation matrices, solids and volumes hierarchy.
287 // ---
288
289   // create section
290   fConvertor->OpenSection(name, version, date, author, topVolume);  
291   fConvertor->WriteEmptyLine();
292   
293   // process rotations
294   ProcessRotations(lv);
295   fConvertor->WriteEmptyLine();
296     
297   // process solids
298   ProcessSolids(lv);
299   fConvertor->WriteEmptyLine();
300     
301   // process geometry tree
302   ProcessLogicalVolume(lv);
303   fConvertor->WriteEmptyLine();
304   
305   // close section
306   fConvertor->CloseSection();
307 }   
308
309 void TG4XMLGeometryGenerator::OpenFile(G4String filePath)
310
311 // Opens output file.
312 // ---
313
314   G4cout << "TG4XMLGeometryGenerator::OpenFile: " << filePath << G4endl;
315   
316   fOutFile.open(filePath, G4std::ios::out); 
317   
318   if (!fOutFile) {
319     G4String text = "Cannot open ";
320     text = text + filePath;
321     TG4Globals::Warning(text);  
322   }
323   
324   // use FORTRAN compatibility output
325   fOutFile.setf(G4std::ios::fixed, G4std::ios::floatfield);
326 }
327
328
329 void TG4XMLGeometryGenerator::CloseFile()
330
331 // Closes output file.
332 // ---
333
334   fOutFile.close(); 
335 }