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