]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TGeant4/TG4XMLGeometryGenerator.cxx
1d85a98b804ab97824073df3ffd7e0637b74c99c
[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::ProcessLogicalVolume(G4LogicalVolume* lv) 
98 {
99 // Writes logical volume tree.
100 // ---
101   
102   G4int nofDaughters = lv->GetNoDaughters();
103   if (nofDaughters == 0) return;
104   
105   // make a vector of contained logical volumes
106   G4std::vector<G4LogicalVolume*> vect;
107   for (G4int i=0; i<nofDaughters; i++) {
108     G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
109     G4bool store = true;
110     for (G4int j=0; j<vect.size(); j++) 
111       if (vect[j] == lvd) store = false;
112     if (store) vect.push_back(lvd);
113   }   
114
115   // loop over contained logical volumes
116   for (G4int j=0; j<vect.size(); j++) {
117     G4LogicalVolume* lvd = vect[j];
118  
119     // open composition
120     if(lvd->GetNoDaughters()>0) {
121       G4String name = lvd->GetName();
122       name.append("_lv");
123       fConvertor->OpenComposition(name);
124     }   
125       
126     // write positions  
127     for (G4int i=0; i<nofDaughters; i++) {
128       G4VPhysicalVolume* vpvd = lv->GetDaughter(i);
129       G4LogicalVolume* lvdi = vpvd->GetLogicalVolume();
130       
131       if (lvdi == lvd) {
132         // only placements are processed
133         G4PVPlacement* pvd = dynamic_cast<G4PVPlacement*>(vpvd);
134         if (pvd) {
135           G4String solidName = lvd->GetSolid()->GetName();
136           G4ThreeVector  position = vpvd->GetFrameTranslation();
137           const G4RotationMatrix* kMatrix = vpvd->GetFrameRotation();      
138           if (!kMatrix)
139             fConvertor->WritePosition(solidName, position);
140           else  
141             fConvertor->WritePositionWithRotation(solidName, position, kMatrix);
142         }
143         else {
144           G4String text = "TG4XMLGeometryGenerator::ProcessLogicalVolume: \n";
145           text = text + "    Limitation: \n";
146           text = text + "    Other physical volumes than PVPlacement";
147           text = text + " are not implemented.";
148           TG4Globals::Warning(text);
149         }
150       } 
151     }
152
153     if(lvd->GetNoDaughters()>0) {
154       // process daughters recursively
155       ProcessLogicalVolume(lvd);
156       fConvertor->CloseComposition();   
157       fConvertor->WriteEmptyLine();
158     }
159   }
160 }  
161
162 // public methods
163
164 void TG4XMLGeometryGenerator::GenerateSection(const G4String& name, 
165                         const G4String& version, const G4String& date,
166                         const G4String& author, const G4String& topVolume,
167                         G4LogicalVolume* lv)
168 {
169 // Generates the XML section containing
170 // all geometry objects defined in given logical volume:
171 // materials, solids, rotation matrices and
172 // volumes hierarchy.
173 // ---
174
175   // create section
176   fConvertor->OpenSection(name, version, date, author, topVolume);  
177   fConvertor->WriteEmptyLine();
178   
179   // process materials
180   ProcessMaterials(lv);
181   fConvertor->WriteEmptyLine();
182
183   // process solids
184   ProcessSolids(lv);
185   fConvertor->WriteEmptyLine();
186     
187   // process geometry tree
188   G4String moduleName = name; moduleName.append("_module");
189   fConvertor->OpenComposition(moduleName);  
190   ProcessLogicalVolume(lv);
191   fConvertor->CloseComposition();
192   fConvertor->WriteEmptyLine();
193   
194   // close section
195   fConvertor->CloseSection();
196 }   
197
198 void TG4XMLGeometryGenerator::OpenFile(G4String filePath)
199
200 // Opens output file.
201 // ---
202
203   G4cout << "TG4XMLGeometryGenerator::OpenFile: " << filePath << G4endl;
204   
205   fOutFile.open(filePath, G4std::ios::out); 
206   
207   if (!fOutFile) {
208     G4String text = "Cannot open ";
209     text = text + filePath;
210     TG4Globals::Warning(text);  
211   }
212   
213   // use FORTRAN compatibility output
214   fOutFile.setf(G4std::ios::fixed, G4std::ios::floatfield);
215 }
216
217
218 void TG4XMLGeometryGenerator::CloseFile()
219
220 // Closes output file.
221 // ---
222
223   fOutFile.close(); 
224 }