]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TGeant4/TG4XMLConvertor.cxx
applied corrections of first implementation; separated materials from section (added...
[u/mrichter/AliRoot.git] / TGeant4 / TG4XMLConvertor.cxx
1 // $Id$
2 // Category: geometry
3 //
4 // See the class description in the header file.
5
6 #include "TG4XMLConvertor.h"
7 #include "TG3Units.h"
8
9 #include <G4LogicalVolume.hh>
10 #include <G4Material.hh>
11 #include <G4VSolid.hh>
12 #include <G4Box.hh>
13 #include <G4Tubs.hh>
14 #include <G4Trd.hh>
15 #include <globals.hh>
16
17 #include <g4std/iostream>
18 #include <g4std/iomanip>
19
20 const G4int TG4XMLConvertor::fgkMaxVolumeNameLength   = 10;
21 const G4int TG4XMLConvertor::fgkMaxMaterialNameLength = 20;
22
23 TG4XMLConvertor::TG4XMLConvertor(G4std::ofstream& outFile) 
24   : fOutFile(outFile),
25     fBasicIndention("   "),
26     fIndention(fBasicIndention)
27 {
28 //
29 }
30
31 TG4XMLConvertor::~TG4XMLConvertor() {
32 //
33 }
34
35 // private methods
36
37 void TG4XMLConvertor::CutName(G4String& name) const
38 {
39 // Removes spaces after the name if present.
40 // ---
41
42   G4int i = name.length();
43   while (name(--i) == ' ') name = name(0,i);
44 }  
45
46 void TG4XMLConvertor::CutName(G4String& name, G4int size) const
47 {
48 // Cuts name to given size.
49 // ---
50
51   if (name.length() > size) name = name(0, size);
52 }  
53
54 void TG4XMLConvertor::PutName(G4String& element, G4String name, 
55                               G4String templ) const
56 {
57 // Replaces given template in string element with a give name.
58 // ---
59
60   CutName(name);
61   // make better
62   if (templ == "#") 
63     CutName(name, fgkMaxVolumeNameLength);
64   else if (templ == "!")  
65     CutName(name, fgkMaxMaterialNameLength);
66   
67   element.replace(element.find(templ), name.size(), name);
68   element.replace(element.find(templ), 1, "\"");
69   while (element.contains(templ)) element.replace(element.find(templ), 1 , " ");
70 }    
71   
72 void TG4XMLConvertor::WriteBox(const G4Box* box, G4String materialName)
73 {
74 // Writes G4box solid.
75 // ---
76
77   // get parameters
78   G4String solidName = box->GetName();
79   G4double x = box->GetXHalfLength()/TG3Units::Length();
80   G4double y = box->GetYHalfLength()/TG3Units::Length();
81   G4double z = box->GetZHalfLength()/TG3Units::Length();
82
83   // compose element string template
84   G4String element1 
85     = "<box   name=\"###########   material=\"!!!!!!!!!!!!!!!!!!!!!   X_Y_Z=\"";
86   G4String element2 = "\" />";
87   
88   // put solid and material names
89   PutName(element1, solidName, "#");
90   PutName(element1, materialName, "!");
91   
92   // write element
93   fOutFile << fBasicIndention
94            << element1
95            << G4std::setw(7) << G4std::setprecision(2) << x << "  "
96            << G4std::setw(7) << G4std::setprecision(2) << y << "  "
97            << G4std::setw(7) << G4std::setprecision(2) << z
98            << element2
99            << G4endl;
100 }
101  
102 void TG4XMLConvertor::WriteTubs(const G4Tubs* tubs, G4String materialName)
103 {
104 // Writes G4tubs solid.
105 // ---
106
107   // get parameters
108   G4String solidName = tubs->GetName();
109   G4double rmin = tubs->GetInnerRadius()/TG3Units::Length();
110   G4double rmax = tubs->GetOuterRadius()/TG3Units::Length();
111   G4double hz   = tubs->GetZHalfLength()/TG3Units::Length();
112   G4double sphi = tubs->GetStartPhiAngle()/TG3Units::Angle();
113   G4double dphi = tubs->GetDeltaPhiAngle()/TG3Units::Angle();
114
115   // compose element string template
116   G4String element1 
117     = "<tubs  name=\"###########   material=\"!!!!!!!!!!!!!!!!!!!!!   Rio_Z=\"";
118   G4String element2 = "\"  profile=\"";
119   G4String element3 = "\" />";
120   
121   // put solid and material names
122   PutName(element1, solidName, "#");
123   PutName(element1, materialName, "!");
124   
125   // write element
126   fOutFile << fBasicIndention
127            << element1
128            << G4std::setw(7) << G4std::setprecision(2) << rmin << "  "
129            << G4std::setw(7) << G4std::setprecision(2) << rmax << "  "
130            << G4std::setw(7) << G4std::setprecision(2) << hz
131            << element2
132            << G4std::setw(7) << G4std::setprecision(2) << sphi << "  "
133            << G4std::setw(7) << G4std::setprecision(2) << dphi
134            << element3
135            << G4endl;
136 }  
137
138
139 void TG4XMLConvertor::WriteTrd(const G4Trd* trd, G4String materialName)
140 {
141 // Writes G4Trd solid.
142 // ---
143
144   // get parameters
145   G4String solidName = trd->GetName();
146   G4double x1 = trd->GetXHalfLength1()/TG3Units::Length();
147   G4double x2 = trd->GetXHalfLength2()/TG3Units::Length();
148   G4double y1 = trd->GetYHalfLength1()/TG3Units::Length();
149   G4double y2 = trd->GetYHalfLength2()/TG3Units::Length();
150   G4double hz = trd->GetZHalfLength()/TG3Units::Length();
151
152   // compose element string template
153   G4String element1 
154     = "<trd   name=\"###########   material=\"!!!!!!!!!!!!!!!!!!!!!   Xmp_Ymp_Z=\"";
155   G4String element2 = "\" />";
156   
157   // put solid and material names
158   // put solid and material names
159   PutName(element1, solidName, "#");
160   PutName(element1, materialName, "!");
161   
162   // write element
163   fOutFile << fBasicIndention
164            << element1
165            << G4std::setw(7) << G4std::setprecision(2) << x1 << "  "
166            << G4std::setw(7) << G4std::setprecision(2) << x2 << "  "
167            << G4std::setw(7) << G4std::setprecision(2) << y1 << "  "
168            << G4std::setw(7) << G4std::setprecision(2) << y2 << "  "
169            << G4std::setw(7) << G4std::setprecision(2) << hz
170            << element2
171            << G4endl;
172 }  
173
174
175 // public methods
176
177 void TG4XMLConvertor::OpenMaterials(const G4String& version, 
178                          const G4String& date, const G4String& author,
179                          const G4String dtdVersion)
180 {
181 // Writes section opening.
182 // ---
183                          
184   G4String element1 = "<materials  version = \"";
185   G4String element2 = "            date    = \"";
186   G4String element3 = "            author  = \"";
187   G4String element4 = "            DTD_version=\"";
188   G4String element5 = "  >";
189   G4String quota = "\"";   
190   
191   // write element
192   fOutFile << element1 << version << quota << G4endl
193            << element2 << date    << quota << G4endl
194            << element3 << author  << quota << G4endl
195            << element4 << dtdVersion << quota
196            << element5 << G4endl;
197 }  
198
199 void TG4XMLConvertor::OpenSection(const G4String& name, const G4String& version,
200                          const G4String& date, const G4String& author,
201                          const G4String& topVolume)
202 {
203 // Writes section opening.
204 // ---
205                          
206   G4String element1 = "<section name       = \"";
207   G4String element2 = "         version    = \"";
208   G4String element3 = "         date       = \"";
209   G4String element4 = "         author     = \"";
210   G4String element5 = "         topVolume  = \"";
211   G4String element6 = "  >";
212   G4String quota = "\"";   
213   
214   // write element
215   fOutFile << element1 << name    << quota << G4endl
216            << element2 << version << quota << G4endl
217            << element3 << date    << quota << G4endl
218            << element4 << author  << quota << G4endl
219            << element5 << topVolume << quota
220            << element6 << G4endl;
221 }  
222
223 void TG4XMLConvertor::OpenComposition(const G4String& name)
224 {
225 // Writes composition opening.
226 // ---
227                          
228   G4String element = "<composition name=\"";
229   element.append(name);
230   element.append(">");
231
232   // write element
233   fOutFile << fIndention
234            << element
235            << G4endl;
236
237   // increase indention
238   IncreaseIndention();     
239 }  
240
241 void TG4XMLConvertor::CloseMaterials()
242 {
243 // Writes materials closing.
244 // ---
245
246   // define element
247   G4String element = "</materials>";
248
249   // write element
250   fOutFile << element
251            << G4endl;
252 }  
253
254 void TG4XMLConvertor::CloseSection()
255 {
256 // Writes section closing.
257 // ---
258
259   // define element
260   G4String element = "</section>";
261
262   // write element
263   fOutFile << element
264            << G4endl;
265 }  
266
267 void TG4XMLConvertor::CloseComposition()
268 {
269 // Writes composition closing.
270 // ---
271
272   // decrease indention
273   DecreaseIndention();
274
275   // define element
276   G4String element = "</composition>";
277
278   // write element
279   fOutFile << fIndention
280            << element
281            << G4endl;
282 }  
283
284 void TG4XMLConvertor::WriteMaterial(const G4Material* material) 
285 {
286 // Writes G4Material. 
287 // Not yet implemented, only XML comment element is written.
288 // ---
289
290   G4String name = material->GetName();
291   CutName(name);
292
293   // return if material of this name was already written
294   if (fMaterialNames.find(name) != fMaterialNames.end()) return;
295     
296   fMaterialNames.insert(fMaterialNames.begin(), name); 
297
298   // only comment line
299   G4String element1 = "<!-- material = \""; 
300   G4String element2 = "\" -->";
301   
302   // write element
303   fOutFile << fBasicIndention
304            << element1 << name
305            << element2
306            << G4endl;
307 }  
308
309 void TG4XMLConvertor::WriteSolid(const G4VSolid* solid, G4String materialName) 
310 {
311 // Finds G4Solid concrete type and calls writing function. 
312 // For not yet implemented solids, only XML comment element is written.
313 // ---
314
315   G4String name = solid->GetName();
316
317   // return if solid of this name was already written
318   if (fSolidNames.find(name) != fSolidNames.end()) return;
319     
320   fSolidNames.insert(fSolidNames.begin(), name); 
321
322   // find concrete solid type and write it
323
324   const G4Box* box = dynamic_cast<const G4Box*>(solid);
325   if (box) { 
326     WriteBox(box, materialName); 
327     return;
328   }
329   
330   const G4Tubs* tubs = dynamic_cast<const G4Tubs*>(solid);
331   if (tubs) { 
332     WriteTubs(tubs, materialName); 
333     return;
334   }
335   
336   const G4Trd* trd = dynamic_cast<const G4Trd*>(solid);
337   if (trd) { 
338     WriteTrd(trd, materialName); 
339     return;
340   }
341   
342   // write comment line in case of unsupported
343   // shape
344
345   // only comment line
346   G4String element1 = "<!-- unsupported shape   name= \""; 
347   G4String element2 = "\" -->";
348   
349   // write element
350   fOutFile << fBasicIndention
351            << element1 << name
352            << element2
353            << G4endl;
354 }  
355
356 void TG4XMLConvertor::WriteRotation(const G4RotationMatrix* rotation)
357 {
358 // Writes G4RotationMatrix. 
359 // Not yet implemented, only XML comment element is written.
360 // ---
361
362   // return if this rotation was already written
363   G4int nofRotations = fRotations.size();
364   if (nofRotations>0)
365     for (G4int i=0; i<nofRotations; i++) 
366       if (fRotations[i] == rotation) return;
367
368   fRotations.push_back(rotation);  
369
370   // get parameters
371   G4double xx = rotation->xx();
372   G4double xy = rotation->xy();
373   G4double xz = rotation->xz();
374   G4double yx = rotation->yx();
375   G4double yy = rotation->yy();
376   G4double yz = rotation->yz();
377   G4double zx = rotation->zx();
378   G4double zy = rotation->zy();
379   G4double zz = rotation->zz();
380   G4String id = "RM";
381   TG4Globals::AppendNumberToString(id, nofRotations);
382  
383   // compose element string template
384   G4String quota = "\"\n";
385   G4String element1 = "<rot_matrix   id=\"#######  XX_XY_XZ=\"";
386   G4String element2 = "                           YX_YY_YZ=\"";
387   G4String element3 = "                           ZX_ZY_ZZ=\"";
388   G4String element4 = "\" />";
389   
390   // put identifier
391   PutName(element1, id, "#");
392
393   // write element
394   fOutFile << fBasicIndention
395            << element1
396            << G4std::setw(8) << G4std::setprecision(5) << xx << "  "  
397            << G4std::setw(8) << G4std::setprecision(5) << xy << "  "  
398            << G4std::setw(8) << G4std::setprecision(5) << xz << quota
399            << fBasicIndention
400            << element2
401            << G4std::setw(8) << G4std::setprecision(5) << yx << "  "  
402            << G4std::setw(8) << G4std::setprecision(5) << yy << "  "  
403            << G4std::setw(8) << G4std::setprecision(5) << yz << quota
404            << fBasicIndention
405            << element3
406            << G4std::setw(8) << G4std::setprecision(5) << zx << "  "  
407            << G4std::setw(8) << G4std::setprecision(5) << zy << "  "  
408            << G4std::setw(8) << G4std::setprecision(5) << zz 
409            << element4     
410            << G4endl;
411 }  
412
413 void TG4XMLConvertor::WritePosition(G4String solidName, G4ThreeVector position) 
414 {
415 // Writes position without rotation with a given solid name. 
416 // ---
417
418   // get parameters
419   G4double x = position.x()/TG3Units::Length();
420   G4double y = position.y()/TG3Units::Length();
421   G4double z = position.z()/TG3Units::Length();
422
423   // compose element string template
424   G4String element1 = "<posXYZ      volume=\"###########   X_Y_Z=\"";
425   G4String element2 = "\" />";
426   
427   // put solid name
428   PutName(element1, solidName, "#");
429   
430   // write element
431   fOutFile << fIndention
432            << element1
433            << G4std::setw(8) << G4std::setprecision(2) << x << "  "
434            << G4std::setw(8) << G4std::setprecision(2) << y << "  "
435            << G4std::setw(8) << G4std::setprecision(2) << z
436            << element2
437            << G4endl;
438 }  
439
440 void TG4XMLConvertor::WritePositionWithRotation(
441                            G4String solidName, G4ThreeVector position, 
442                            const G4RotationMatrix* rotation)
443 {
444 // Writes position with rotation with a given solid name. 
445 // Not yet implemented, only XML comment element is written.
446 // ---
447
448   // get parameters
449   G4double x = position.x()/TG3Units::Length();
450   G4double y = position.y()/TG3Units::Length();
451   G4double z = position.z()/TG3Units::Length();
452   
453   // find rotation
454   G4int i=0;
455   while (i<fRotations.size() && fRotations[i] != rotation) i++; 
456   if (i==fRotations.size()) {
457     G4String text = "TG4XMLConvertor::WritePositionWithRotation: ";
458     text = text + "    Unknown rotation - fatal error.";    
459     TG4Globals::Exception(text);
460   }  
461   G4String id = "RM";
462   TG4Globals::AppendNumberToString(id, i); 
463
464   // compose element string template
465   G4String element1 = "<posXYZRot   volume=\"###########   X_Y_Z=\"";
466   G4String element2 = "\"   rot=\"";
467   G4String element3 = "\" />";
468   
469   // put solid name
470   PutName(element1, solidName, "#");
471   
472   // write element
473   fOutFile << fIndention
474            << element1
475            << G4std::setw(8) << G4std::setprecision(2) << x << "  "
476            << G4std::setw(8) << G4std::setprecision(2) << y << "  "
477            << G4std::setw(8) << G4std::setprecision(2) << z
478            << element2
479            << id
480            << element3
481            << G4endl;
482 }  
483
484 void TG4XMLConvertor::WriteEmptyLine()
485 {
486 // Writes empty line.
487 // ---
488
489   fOutFile << G4endl;
490 }  
491
492 void TG4XMLConvertor::IncreaseIndention()
493 {
494   // increase indention
495   fIndention.append(fBasicIndention);      
496 }
497
498 void TG4XMLConvertor::DecreaseIndention()
499 {
500   // decrease indention
501   fIndention.replace(fIndention.find(fBasicIndention), 3 , "");
502 }