]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TGeant4/TG4XMLConvertor.cxx
More exact rounding function, but also much slower.
[u/mrichter/AliRoot.git] / TGeant4 / TG4XMLConvertor.cxx
1 // $Id$
2 // Category: geometry
3 //
4 // Author: I. Hrivnacova, 27.07.2000 
5 //
6 // Class TG4XMLConvertor 
7 // ---------------------
8 // See the class description in the header file.
9
10 #include "TG4XMLConvertor.h"
11 #include "TG4Polycone.h"
12 #include "TG4Polyhedra.h"
13 #include "TG4G3Units.h"
14
15 #include <G4PVReplica.hh>
16 #include <G4Material.hh>
17 #include <G4VSolid.hh>
18 #include <G4ReflectedSolid.hh>
19 #include <G4Box.hh>
20 #include <G4Tubs.hh>
21 #include <G4Cons.hh>
22 #include <G4Trd.hh>
23 #include <G4Trap.hh>
24 #include <G4Para.hh>
25 #include <G4Polycone.hh>
26 #include <G4Polyhedra.hh>
27
28 #include <g4std/iostream>
29 #include <g4std/iomanip>
30
31 const G4int TG4XMLConvertor::fgkMaxVolumeNameLength   = 10;
32 const G4int TG4XMLConvertor::fgkMaxMaterialNameLength = 20;
33 const G4int TG4XMLConvertor::fgkDefaultNumWidth = 7;
34 const G4int TG4XMLConvertor::fgkDefaultNumPrecision = 4;
35
36 //_____________________________________________________________________________
37 TG4XMLConvertor::TG4XMLConvertor(G4std::ofstream& outFile) 
38   : fOutFile(outFile),
39     fkBasicIndention("   "),
40     fNW(fgkDefaultNumWidth),
41     fNP(fgkDefaultNumPrecision),
42     fIndention(fkBasicIndention),
43     fRotationCounter(0)
44 {
45   fOutFile.width(fgkDefaultNumWidth);
46   fOutFile.precision(fgkDefaultNumPrecision);
47 }
48
49 //_____________________________________________________________________________
50 TG4XMLConvertor::~TG4XMLConvertor() {
51 //
52 }
53
54 // private methods
55
56 //_____________________________________________________________________________
57 void TG4XMLConvertor::CutName(G4String& name) const
58 {
59 // Removes spaces after the name if present.
60 // ---
61
62   G4int i = name.length();
63   while (name(--i) == ' ') name = name(0,i);
64 }  
65
66 //_____________________________________________________________________________
67 void TG4XMLConvertor::CutName(G4String& name, G4int size) const
68 {
69 // Cuts name to given size.
70 // ---
71
72   if (name.length() > size) name = name(0, size);
73 }  
74
75 //_____________________________________________________________________________
76 void TG4XMLConvertor::PutName(G4String& element, G4String name, 
77                               G4String templ) const
78 {
79 // Replaces given template in string element with a give name.
80 // ---
81
82   CutName(name);
83   // make better
84   if (templ == "#") 
85     CutName(name, fgkMaxVolumeNameLength);
86   else if (templ == "!")  
87     CutName(name, fgkMaxMaterialNameLength);
88   
89   element.replace(element.find(templ), name.size(), name);
90   element.replace(element.find(templ), 1, "\"");
91   while (element.contains(templ)) element.replace(element.find(templ), 1 , " ");
92 }    
93   
94 //_____________________________________________________________________________
95 void TG4XMLConvertor::WriteBox(G4String lvName, const G4Box* box, 
96                                G4String materialName)
97 {
98 // Writes G4box solid.
99 // ---
100
101   // get parameters
102   G4double x = box->GetXHalfLength()/TG4G3Units::Length()*2.;
103   G4double y = box->GetYHalfLength()/TG4G3Units::Length()*2.;
104   G4double z = box->GetZHalfLength()/TG4G3Units::Length()*2.;
105
106   // compose element string template
107   G4String quota = "\"";
108   G4String element1 = "<box    name=\"" + lvName + quota;
109   G4String element2 = "material=\"" + materialName + quota;
110   G4String element3 = "X_Y_Z=\"";
111   G4String element4 = "\" />";
112   G4String indention = fkBasicIndention + fkBasicIndention;
113   
114   // write element
115   fOutFile << fkBasicIndention << element1 << G4endl  
116            << indention        << element2 << G4endl
117            << indention        << element3
118            << G4std::setw(fNW) << G4std::setprecision(fNP) << x << "  "
119            << G4std::setw(fNW) << G4std::setprecision(fNP) << y << "  "
120            << G4std::setw(fNW) << G4std::setprecision(fNP) << z 
121            << element4 << G4endl << G4endl;
122 }
123  
124 //_____________________________________________________________________________
125 void TG4XMLConvertor::WriteTubs(G4String lvName, const G4Tubs* tubs, 
126                                 G4String materialName)
127 {
128 // Writes G4tubs solid.
129 // ---
130
131   // get parameters
132   G4double rmin = tubs->GetInnerRadius()/TG4G3Units::Length();
133   G4double rmax = tubs->GetOuterRadius()/TG4G3Units::Length();
134   G4double hz   = tubs->GetZHalfLength()/TG4G3Units::Length()*2.;
135   G4double sphi = tubs->GetStartPhiAngle()/TG4G3Units::Angle();
136   G4double dphi = tubs->GetDeltaPhiAngle()/TG4G3Units::Angle();
137
138   // compose element string template
139   G4String quota = "\"";
140   G4String element1 = "<tubs   name=\"" + lvName + quota; 
141   G4String element2 = "material=\"" + materialName + quota;
142   G4String element3 = "profile=\"";
143   G4String element4 = "Rio_Z  =\"";
144   G4String element5 = "\" />";
145   G4String indention = fkBasicIndention + fkBasicIndention;
146   
147   // write element
148   fOutFile << fkBasicIndention << element1 << G4endl
149            << indention        << element2 << G4endl
150            << indention        << element3
151            << G4std::setw(fNW)   << G4std::setprecision(fNP) << sphi << "  "
152            << G4std::setw(fNW)   << G4std::setprecision(fNP) << sphi+dphi
153            << quota << G4endl              
154            << indention        << element4
155            << G4std::setw(fNW) << G4std::setprecision(fNP) << rmin << "  "
156            << G4std::setw(fNW) << G4std::setprecision(fNP) << rmax << "  "
157            << G4std::setw(fNW) << G4std::setprecision(fNP) << hz 
158            << element5 << G4endl << G4endl;
159 }  
160
161 //_____________________________________________________________________________
162 void TG4XMLConvertor::WriteCons(G4String lvName, const G4Cons* cons, 
163                                 G4String materialName)
164 {
165 // Writes G4cons solid.
166 // ---
167
168   // get parameters
169   G4double rmin1 = cons->GetInnerRadiusMinusZ()/TG4G3Units::Length();
170   G4double rmax1 = cons->GetOuterRadiusMinusZ()/TG4G3Units::Length();
171   G4double rmin2 = cons->GetInnerRadiusPlusZ()/TG4G3Units::Length();
172   G4double rmax2 = cons->GetOuterRadiusPlusZ()/TG4G3Units::Length();
173   G4double hz   = cons->GetZHalfLength()/TG4G3Units::Length()*2.;
174   G4double sphi = cons->GetStartPhiAngle()/TG4G3Units::Angle();
175   G4double dphi = cons->GetDeltaPhiAngle()/TG4G3Units::Angle();
176
177   // compose element string template
178   G4String quota = "\"";
179   G4String element1 = "<cons   name=\"" + lvName + quota; 
180   G4String element2 = "material=\"" + materialName + quota;
181   G4String element3 = "profile=\"";
182   G4String element4 = "Rio1_Rio2_Z  =\"";
183   G4String element5 = "\" />";
184   G4String indention = fkBasicIndention + fkBasicIndention;
185   
186   // write element
187   fOutFile << fkBasicIndention << element1 << G4endl
188            << indention        << element2 << G4endl
189            << indention        << element3
190            << G4std::setw(fNW)   << G4std::setprecision(fNP) << sphi << "  "
191            << G4std::setw(fNW)   << G4std::setprecision(fNP) << sphi+dphi
192            << quota << G4endl              
193            << indention        << element4
194            << G4std::setw(fNW) << G4std::setprecision(fNP) << rmin1 << "  "
195            << G4std::setw(fNW) << G4std::setprecision(fNP) << rmin2 << "  "
196            << G4std::setw(fNW) << G4std::setprecision(fNP) << rmax1 << "  "
197            << G4std::setw(fNW) << G4std::setprecision(fNP) << rmax2 << "  "
198            << G4std::setw(fNW) << G4std::setprecision(fNP) << hz 
199            << element5 << G4endl << G4endl;
200 }  
201
202 //_____________________________________________________________________________
203 void TG4XMLConvertor::WriteTrd(G4String lvName, const G4Trd* trd, 
204                                G4String materialName)
205 {
206 // Writes G4Trd solid.
207 // ---
208
209   // get parameters
210   G4double x1 = trd->GetXHalfLength1()/TG4G3Units::Length()*2;
211   G4double x2 = trd->GetXHalfLength2()/TG4G3Units::Length()*2;
212   G4double y1 = trd->GetYHalfLength1()/TG4G3Units::Length()*2;
213   G4double y2 = trd->GetYHalfLength2()/TG4G3Units::Length()*2;
214   G4double hz = trd->GetZHalfLength()/TG4G3Units::Length()*2;
215
216   // compose element string template
217   G4String quota = "\"";
218   G4String element1 = "<trd    name=\"" + lvName + quota; 
219   G4String element2 = "material=\"" + materialName + quota;
220   G4String element3 = "Xmp_Ymp_Z=\"";
221   G4String element4 = "\" />";
222   G4String indention = fkBasicIndention + fkBasicIndention;
223   
224   // write element
225   fOutFile << fkBasicIndention << element1 << G4endl
226            << indention        << element2 << G4endl
227            << indention        << element3
228            << G4std::setw(fNW) << G4std::setprecision(fNP) << x1 << "  "
229            << G4std::setw(fNW) << G4std::setprecision(fNP) << x2 << "  "
230            << G4std::setw(fNW) << G4std::setprecision(fNP) << y1 << "  "
231            << G4std::setw(fNW) << G4std::setprecision(fNP) << y2 << "  "
232            << G4std::setw(fNW) << G4std::setprecision(fNP) << hz
233            << element4 << G4endl << G4endl;
234 }  
235
236 //_____________________________________________________________________________
237 void TG4XMLConvertor::WriteTrap(G4String lvName, const G4Trap* trap, 
238                                 G4String materialName)
239 {
240 // Writes G4Trap solid.
241 // ---
242
243   // get parameters
244   G4double dz = trap->GetZHalfLength()/TG4G3Units::Length()*2.;
245   G4ThreeVector symAxis = trap->GetSymAxis();
246   G4double y1 = trap->GetYHalfLength1()/TG4G3Units::Length()*2.;
247   G4double x1 = trap->GetXHalfLength1()/TG4G3Units::Length()*2.;
248   G4double x2 = trap->GetXHalfLength2()/TG4G3Units::Length()*2.;
249   G4double tanAlpha1 = trap->GetTanAlpha1();
250   G4double y2 = trap->GetYHalfLength2()/TG4G3Units::Length()*2.;
251   G4double x3 = trap->GetXHalfLength3()/TG4G3Units::Length()*2.;
252   G4double x4 = trap->GetXHalfLength4()/TG4G3Units::Length()*2.;
253   G4double tanAlpha2 = trap->GetTanAlpha2();
254
255   // ordering of parameters in XML element
256   // Xmumdpupd_Ymp_Z: 2x2 2x1 2x4 2x3 2y2 2y1 2dz
257   // inclination: atan(symAxis.x/symAxis.z), atan(symAxis.y/symAxis.z)
258   // declination: alpha1, alpha2
259
260   // get angles
261   G4double inc1 = atan(symAxis.x()/symAxis.z()) / deg;
262   G4double inc2 = atan(symAxis.y()/symAxis.z()) / deg;
263   G4double alpha1 = atan(tanAlpha1) / deg;
264   G4double alpha2 = atan(tanAlpha2) / deg;
265
266   // compose element string template
267   G4String quota = "\"";
268   G4String element1 = "<trap   name=\"" + lvName + quota; 
269   G4String element2 = "material=\"" + materialName + quota;
270   G4String element3 = "Xmumdpupd_Ymp_Z=\"";
271   G4String element4 = "inclination=\""; 
272   G4String element5 = "declination=\""; 
273   G4String element6 = "\" />";
274   G4String indention = fkBasicIndention + fkBasicIndention;
275
276   // write element
277   fOutFile << fkBasicIndention << element1 << G4endl
278            << indention        << element2 << G4endl
279            << indention        << element3
280            << G4std::setw(fNW) << G4std::setprecision(fNP) << x2 << "  "
281            << G4std::setw(fNW) << G4std::setprecision(fNP) << x1 << "  "
282            << G4std::setw(fNW) << G4std::setprecision(fNP) << x4 << "  "
283            << G4std::setw(fNW) << G4std::setprecision(fNP) << x3 << "  "
284            << G4std::setw(fNW) << G4std::setprecision(fNP) << y2 << "  "
285            << G4std::setw(fNW) << G4std::setprecision(fNP) << y1 << "  "
286            << G4std::setw(fNW) << G4std::setprecision(fNP) << dz 
287            << quota << G4endl
288            << indention       << element4
289            << G4std::setw(fNW) << G4std::setprecision(fNP) << inc1 << "  "
290            << G4std::setw(fNW) << G4std::setprecision(fNP) << inc2 
291            << quota << G4endl
292            << indention       << element5
293            << G4std::setw(fNW) << G4std::setprecision(fNP) << alpha1 << "  "
294            << G4std::setw(fNW) << G4std::setprecision(fNP) << alpha2 
295            << element6 << G4endl << G4endl;
296 }  
297
298 //_____________________________________________________________________________
299 void TG4XMLConvertor::WritePara(G4String lvName, const G4Para* para, 
300                                 G4String materialName)
301 {
302 // Writes G4Para solid.
303 // ---
304
305   // get parameters
306   G4double dx = para->GetXHalfLength()/TG4G3Units::Length()*2.;
307   G4double dy = para->GetYHalfLength()/TG4G3Units::Length()*2.;
308   G4double dz = para->GetZHalfLength()/TG4G3Units::Length()*2.;
309   G4double tanAlpha     = para->GetTanAlpha();
310   G4ThreeVector symAxis = para->GetSymAxis();
311   
312   G4double alpha = atan(tanAlpha) / deg;
313   G4double theta = acos(symAxis.z()) / deg;
314   G4double phi;
315   if (theta == 0.)
316     phi = 0;
317   else        
318     phi = atan(symAxis.y()/symAxis.x()) / deg;
319
320   // compose element string template
321   G4String quota = "\"";
322   G4String element1 = "<para   name=\"" + lvName + quota;
323   G4String element2 = "material=\"" + materialName + quota;
324   G4String element3 = "X_Y_Z=\"";
325   G4String element4 = "alpha=\"";
326   G4String element5 = "theta=\"";
327   G4String element6 = "phi=  \"";
328   G4String element7 = "\" />";
329   G4String indention = fkBasicIndention + fkBasicIndention;
330   
331   // write element
332   fOutFile << fkBasicIndention << element1 << G4endl  
333            << indention        << element2 << G4endl
334            << indention        << element3
335            << G4std::setw(fNW) << G4std::setprecision(fNP) << dx << "  "
336            << G4std::setw(fNW) << G4std::setprecision(fNP) << dy << "  "
337            << G4std::setw(fNW) << G4std::setprecision(fNP) << dz 
338            << quota << G4endl
339            << indention        << element4
340            << G4std::setw(fNW) << G4std::setprecision(fNP) << alpha 
341            << quota << G4endl
342            << indention        << element5
343            << G4std::setw(fNW) << G4std::setprecision(fNP) << theta
344            << quota << G4endl
345            << indention        << element6
346            << G4std::setw(fNW) << G4std::setprecision(fNP) << phi          
347            << element7 << G4endl << G4endl;
348 }
349  
350 //_____________________________________________________________________________
351 void TG4XMLConvertor::WritePolycone(G4String lvName, const G4Polycone* polycone, 
352                                     G4String materialName)
353 {
354 // Writes G4Polycone solid.
355 // ---
356
357   // get profile parameters
358   G4double sphi = polycone->GetStartPhi()/TG4G3Units::Angle();
359   G4double ephi = polycone->GetEndPhi()/TG4G3Units::Angle();
360   
361   // get polycone Z planes parameters
362   TG4Polycone historicalPolycone = TG4Polycone(*polycone);
363
364   G4int nofZPlanes = historicalPolycone.GetNofZPlanes();
365   G4double* rminArray = historicalPolycone.GetRmin();
366   G4double* rmaxArray = historicalPolycone.GetRmax();
367   G4double* zArray    = historicalPolycone.GetZ();
368
369   // compose element string template
370   G4String quota = "\"";
371   G4String element1 = "<pcon   name=\"" + lvName + quota; 
372   G4String element2 = "material=\"" + materialName + quota;
373   G4String element3 = "profile=\"";
374   G4String element4 = "\" >";
375   G4String element5 = "<polyplane Rio_Z=\"";
376   G4String element6 = "\" />";
377   G4String element7 = "</pcon>";
378   G4String indention = fkBasicIndention + fkBasicIndention;
379   
380   // write pcon element
381   fOutFile << fkBasicIndention << element1 << G4endl
382            << indention        << element2 << G4endl
383            << indention        << element3
384            << G4std::setw(fNW) << G4std::setprecision(fNP) << sphi << "  "
385            << G4std::setw(fNW) << G4std::setprecision(fNP) << ephi
386            << element4 << G4endl;
387
388   // write polyplane elements
389   for (G4int i=0; i<nofZPlanes; i++) {
390   
391     // set units
392     G4double rmin = rminArray[i]/TG4G3Units::Length();
393     G4double rmax = rmaxArray[i]/TG4G3Units::Length();
394     G4double z    = zArray[i]/TG4G3Units::Length();
395
396     fOutFile << indention << element5
397              << G4std::setw(fNW) << G4std::setprecision(fNP) << rmin << "  "
398              << G4std::setw(fNW) << G4std::setprecision(fNP) << rmax << "  " 
399              << G4std::setw(fNW) << G4std::setprecision(fNP) << z 
400              << element6
401              << G4endl;
402   }
403   
404   // close pcon element
405   fOutFile << fkBasicIndention
406            << element7 << G4endl << G4endl;          
407 }  
408
409 //_____________________________________________________________________________
410 void TG4XMLConvertor::WritePolyhedra(G4String lvName, const G4Polyhedra* polyhedra, 
411                                     G4String materialName)
412 {
413 // Writes G4Polycone solid.
414 // ---
415
416   // get parameters
417   G4int nofSides = polyhedra->GetNumSide();
418   G4double sphi = polyhedra->GetStartPhi()/TG4G3Units::Angle();
419   G4double ephi = polyhedra->GetEndPhi()/TG4G3Units::Angle();
420   
421   // get polyhedra Z planes parameters
422   TG4Polyhedra historicalPolyhedra = TG4Polyhedra(*polyhedra);
423
424   G4int nofZPlanes = historicalPolyhedra.GetNofZPlanes();
425   G4double* rminArray = historicalPolyhedra.GetRmin();
426   G4double* rmaxArray = historicalPolyhedra.GetRmax();
427   G4double* zArray    = historicalPolyhedra.GetZ();
428
429   // compose element string template
430   G4String quota = "\"";
431   G4String element1 = "<phedra name=\"" + lvName + quota; 
432   G4String element2 = "material=\"" + materialName + quota;
433   G4String element3 = "profile=\"";
434   G4String element4 = "sides =\"";
435   G4String element5 = "Ris=\"";
436   G4String element6 = "Ros=\"";
437   G4String element7 = "Zs =\"";
438   G4String element8 = "\" />";
439   G4String indention = fkBasicIndention + fkBasicIndention;
440   
441   // write element
442   fOutFile << fkBasicIndention << element1 << G4endl
443            << indention        << element2 << G4endl
444            << indention        << element3
445            << G4std::setw(fNW) << G4std::setprecision(fNP) << sphi << "  "
446            << G4std::setw(fNW) << G4std::setprecision(fNP) << ephi
447            << quota << G4endl
448            << indention       << element4 
449            << nofSides
450            << quota << G4endl;
451
452   fOutFile << indention << element5;
453   G4int i;
454   for (i=0; i<nofZPlanes; i++) {  
455     // set units    
456     G4double rmin = rminArray[i]/TG4G3Units::Length();
457     if (i>0) fOutFile << "  ";
458     fOutFile << G4std::setw(fNW) << G4std::setprecision(fNP) << rmin;
459   };
460   fOutFile << quota << G4endl;
461
462   fOutFile << indention << element6;
463   for (i=0; i<nofZPlanes; i++) {  
464     // set units
465     G4double rmax = rmaxArray[i]/TG4G3Units::Length();
466     if (i>0) fOutFile << "  ";
467     fOutFile << G4std::setw(fNW) << G4std::setprecision(fNP) << rmax;
468   };
469   fOutFile << quota << G4endl;
470
471   fOutFile << indention << element7;
472   for (i=0; i<nofZPlanes; i++) {  
473     // set units
474     G4double z = zArray[i]/TG4G3Units::Length();
475     if (i>0) fOutFile << "  ";
476     fOutFile << G4std::setw(fNW) << G4std::setprecision(fNP) << z;
477   };
478   fOutFile << element8 << G4endl << G4endl;
479 }  
480
481
482 // public methods
483
484 //_____________________________________________________________________________
485 void TG4XMLConvertor::OpenMaterials(const G4String& version, 
486                          const G4String& date, const G4String& author,
487                          const G4String dtdVersion)
488 {
489 // Writes section opening.
490 // ---
491                          
492   G4String element1 = "<materials  version = \"";
493   G4String element2 = "            date    = \"";
494   G4String element3 = "            author  = \"";
495   G4String element4 = "            DTD_version=\"";
496   G4String element5 = "  >";
497   G4String quota = "\"";   
498   
499   // write element
500   fOutFile << element1 << version << quota << G4endl
501            << element2 << date    << quota << G4endl
502            << element3 << author  << quota << G4endl
503            << element4 << dtdVersion << quota
504            << element5 << G4endl;
505 }  
506
507 //_____________________________________________________________________________
508 void TG4XMLConvertor::OpenSection(const G4String& name, const G4String& version,
509                          const G4String& date, const G4String& author,
510                          const G4String& topVolume)
511 {
512 // Writes section opening.
513 // ---
514                          
515   G4String element1 = "<section name       = \"";
516   G4String element2 = "         version    = \"";
517   G4String element3 = "         date       = \"";
518   G4String element4 = "         author     = \"";
519   G4String element5 = "         topVolume  = \"";
520   G4String element6 = "  >";
521   G4String quota = "\"";   
522   
523   // write element
524   fOutFile << element1 << name    << quota << G4endl
525            << element2 << version << quota << G4endl
526            << element3 << date    << quota << G4endl
527            << element4 << author  << quota << G4endl
528            << element5 << topVolume << quota
529            << element6 << G4endl;
530 }  
531
532 void TG4XMLConvertor::OpenComposition(const G4String& name)
533 {
534 // Writes composition opening.
535 // ---
536                          
537   G4String element = "<composition name=\"";
538   element.append(name);
539   element.append("\">");
540
541   // write element
542   fOutFile << fIndention
543            << element
544            << G4endl;
545
546   // increase indention
547   IncreaseIndention();     
548 }  
549
550 //_____________________________________________________________________________
551 void TG4XMLConvertor::CloseMaterials()
552 {
553 // Writes materials closing.
554 // ---
555
556   // define element
557   G4String element = "</materials>";
558
559   // write element
560   fOutFile << element
561            << G4endl;
562 }  
563
564 //_____________________________________________________________________________
565 void TG4XMLConvertor::CloseSection()
566 {
567 // Writes section closing.
568 // ---
569
570   // define element
571   G4String element = "</section>";
572
573   // write element
574   fOutFile << element
575            << G4endl;
576 }  
577
578 //_____________________________________________________________________________
579 void TG4XMLConvertor::CloseComposition()
580 {
581 // Writes composition closing.
582 // ---
583
584   // decrease indention
585   DecreaseIndention();
586
587   // define element
588   G4String element = "</composition>";
589
590   // write element
591   fOutFile << fIndention
592            << element
593            << G4endl;
594 }  
595
596 //_____________________________________________________________________________
597 void TG4XMLConvertor::WriteMaterial(const G4Material* material) 
598 {
599 // Writes G4Material. 
600 // Not yet implemented, only XML comment element is written.
601 // ---
602
603   G4String name = material->GetName();
604   CutName(name);
605
606   // only comment line
607   G4String element1 = "<!-- material = \""; 
608   G4String element2 = "\" -->";
609   
610   // write element
611   fOutFile << fkBasicIndention
612            << element1 << name
613            << element2
614            << G4endl;
615 }  
616
617 //_____________________________________________________________________________
618 void TG4XMLConvertor::WriteSolid(G4String lvName, const G4VSolid* solid, 
619                                  G4String materialName) 
620 {
621 // Finds G4Solid concrete type and calls writing function. 
622 // For not yet implemented solids, only XML comment element is written.
623 // ---
624
625   // to be removed when materials are supported
626   materialName = "Hydrogen";
627   
628   const G4ReflectedSolid* reflSolid
629     = dynamic_cast<const G4ReflectedSolid*>(solid);
630
631   const G4VSolid* consSolid;
632   if (reflSolid) 
633     consSolid = reflSolid->GetConstituentMovedSolid();
634   else  
635     consSolid = solid;  
636   
637   const G4Box* box = dynamic_cast<const G4Box*>(consSolid);
638   if (box) { 
639     WriteBox(lvName, box, materialName); 
640     return;
641   }
642   
643   const G4Tubs* tubs = dynamic_cast<const G4Tubs*>(consSolid);
644   if (tubs) { 
645     WriteTubs(lvName, tubs, materialName); 
646     return;
647   }
648   
649   const G4Cons* cons = dynamic_cast<const G4Cons*>(consSolid);
650   if (cons) { 
651     WriteCons(lvName, cons, materialName); 
652     return;
653   }
654   
655   const G4Trd* trd = dynamic_cast<const G4Trd*>(consSolid);
656   if (trd) { 
657     WriteTrd(lvName, trd, materialName); 
658     return;
659   }
660   
661   const G4Trap* trap = dynamic_cast<const G4Trap*>(consSolid);
662   if (trap) { 
663     WriteTrap(lvName, trap, materialName); 
664     return;
665   }
666   
667   const G4Para* para = dynamic_cast<const G4Para*>(consSolid);
668   if (para) { 
669     WritePara(lvName, para, materialName); 
670     return;
671   }
672   
673   const G4Polycone* polycone = dynamic_cast<const G4Polycone*>(consSolid);
674   if (polycone) { 
675     WritePolycone(lvName, polycone, materialName); 
676     return;
677   }
678   
679   const G4Polyhedra* polyhedra = dynamic_cast<const G4Polyhedra*>(consSolid);
680   if (polyhedra) { 
681     WritePolyhedra(lvName, polyhedra, materialName); 
682     return;
683   }
684   
685   // write comment line in case of unsupported
686   // shape
687
688   // only comment line
689   G4String element1 = "<!-- unsupported shape   name= \""; 
690   G4String element2 = "\" -->";
691   
692   // write element
693   fOutFile << fkBasicIndention
694            << element1 << lvName
695            << element2
696            << G4endl;
697 }  
698
699 //_____________________________________________________________________________
700 void TG4XMLConvertor::WriteRotation(const G4RotationMatrix* rotation)
701 {
702 // Writes G4RotationMatrix. 
703 // Not yet implemented, only XML comment element is written.
704 // ---
705
706   // return if this rotation was already written
707   G4int nofRotations = fRotations.size();
708   if (nofRotations>0)
709     for (G4int i=0; i<nofRotations; i++) 
710       if (fRotations[i] == rotation) return;
711
712   fRotations.push_back(rotation);  
713
714
715   // get parameters
716   G4double xx = rotation->xx();
717   G4double xy = rotation->xy();
718   G4double xz = rotation->xz();
719   G4double yx = rotation->yx();
720   G4double yy = rotation->yy();
721   G4double yz = rotation->yz();
722   G4double zx = rotation->zx();
723   G4double zy = rotation->zy();
724   G4double zz = rotation->zz();
725   G4String id = "RM";
726   TG4Globals::AppendNumberToString(id, ++fRotationCounter);
727  
728   // compose element string template
729   G4String quota = "\"\n";
730   G4String element1 = "<rot_matrix   id=\"#######  XX_XY_XZ=\"";
731   G4String element2 = "                           YX_YY_YZ=\"";
732   G4String element3 = "                           ZX_ZY_ZZ=\"";
733   G4String element4 = "\" />";
734   
735   // put identifier
736   PutName(element1, id, "#");
737
738   // write element
739   fOutFile << fkBasicIndention
740            << element1
741            << G4std::setw(8) << G4std::setprecision(5) << xx << "  "  
742            << G4std::setw(8) << G4std::setprecision(5) << xy << "  "  
743            << G4std::setw(8) << G4std::setprecision(5) << xz << quota
744            << fkBasicIndention
745            << element2
746            << G4std::setw(8) << G4std::setprecision(5) << yx << "  "  
747            << G4std::setw(8) << G4std::setprecision(5) << yy << "  "  
748            << G4std::setw(8) << G4std::setprecision(5) << yz << quota
749            << fkBasicIndention
750            << element3
751            << G4std::setw(8) << G4std::setprecision(5) << zx << "  "  
752            << G4std::setw(8) << G4std::setprecision(5) << zy << "  "  
753            << G4std::setw(8) << G4std::setprecision(5) << zz 
754            << element4     
755            << G4endl;
756 }  
757
758 //_____________________________________________________________________________
759 void TG4XMLConvertor::WritePosition(G4String lvName, G4ThreeVector position) 
760 {
761 // Writes position without rotation with a given solid name. 
762 // ---
763
764   // get parameters
765   G4double x = position.x()/TG4G3Units::Length();
766   G4double y = position.y()/TG4G3Units::Length();
767   G4double z = position.z()/TG4G3Units::Length();
768
769   // compose element string template
770   G4String element1 = "<posXYZ      volume=\"###########   X_Y_Z=\"";
771   G4String element2 = "\" />";
772   
773   // put solid name
774   PutName(element1, lvName, "#");
775   
776   // write element
777   fOutFile << fIndention
778            << element1
779            << G4std::setw(fNW+1) << G4std::setprecision(fNP) << x << "  "
780            << G4std::setw(fNW+1) << G4std::setprecision(fNP) << y << "  "
781            << G4std::setw(fNW+1) << G4std::setprecision(fNP) << z
782            << element2
783            << G4endl;
784 }  
785
786 //_____________________________________________________________________________
787 void TG4XMLConvertor::WritePositionWithRotation(
788                            G4String lvName, G4ThreeVector position, 
789                            const G4RotationMatrix* rotation)
790 {
791 // Writes position with rotation with a given solid name. 
792 // Not yet implemented, only XML comment element is written.
793 // ---
794
795   // get parameters
796   G4double x = position.x()/TG4G3Units::Length();
797   G4double y = position.y()/TG4G3Units::Length();
798   G4double z = position.z()/TG4G3Units::Length();
799   G4double xx = rotation->xx();
800   G4double xy = rotation->xy();
801   G4double xz = rotation->xz();
802   G4double yx = rotation->yx();
803   G4double yy = rotation->yy();
804   G4double yz = rotation->yz();
805   G4double zx = rotation->zx();
806   G4double zy = rotation->zy();
807   G4double zz = rotation->zz();
808   
809 /*
810   // find rotation
811   G4int i=0;
812   while (i<fRotations.size() && fRotations[i] != rotation) i++; 
813   if (i==fRotations.size()) {
814     G4String text = "TG4XMLConvertor::WritePositionWithRotation: ";
815     text = text + "    Unknown rotation - fatal error.";    
816     TG4Globals::Exception(text);
817   }  
818   G4String id = "RM";
819   TG4Globals::AppendNumberToString(id, i); 
820 */  
821
822   // compose element string template
823   G4String quota = "\"\n";
824   G4String element1 = "<transform   volume=\"###########     pos=\"";
825   G4String element2 = "                                     rot=\"";
826   G4String element3 = "                                          ";
827   G4String element4 = "\" />";
828   
829   // put solid name
830   PutName(element1, lvName, "#");
831   
832   // write element
833   fOutFile << fIndention
834            << element1
835            << G4std::setw(fNW+1) << G4std::setprecision(fNP) << x << "  "
836            << G4std::setw(fNW+1) << G4std::setprecision(fNP) << y << "  "
837            << G4std::setw(fNW+1) << G4std::setprecision(fNP) << z << quota
838            << fIndention
839            << element2 
840            << G4std::setw(8) << G4std::setprecision(5) << xx << "  "  
841            << G4std::setw(8) << G4std::setprecision(5) << xy << "  "  
842            << G4std::setw(8) << G4std::setprecision(5) << xz << G4endl
843            << fIndention
844            << element3
845            << G4std::setw(8) << G4std::setprecision(5) << yx << "  "  
846            << G4std::setw(8) << G4std::setprecision(5) << yy << "  "  
847            << G4std::setw(8) << G4std::setprecision(5) << yz << G4endl
848            << fIndention
849            << element3
850            << G4std::setw(8) << G4std::setprecision(5) << zx << "  "  
851            << G4std::setw(8) << G4std::setprecision(5) << zy << "  "  
852            << G4std::setw(8) << G4std::setprecision(5) << zz 
853            << element4
854            << G4endl;
855 }  
856
857 //_____________________________________________________________________________
858 void TG4XMLConvertor::WriteReplica(G4String lvName, G4PVReplica* pvr) 
859 {
860 // Writes position without rotation with a given solid name. 
861 // ---
862
863   // get parameters
864   EAxis axis;
865   G4int nReplicas;
866   G4double width;
867   G4double offset;
868   G4bool consuming;
869   pvr->GetReplicationData(axis, nReplicas, width, offset, consuming);
870   
871   G4String tag;
872   switch (axis) {
873     case kXAxis: tag = "X"; break;
874     case kYAxis: tag = "Y"; break;
875     case kZAxis: tag = "Z"; break;
876     case kRho:   tag = "R"; break;
877     case kPhi:   tag = "Phi"; break;
878   }  
879
880   // set units
881   G4double value0 = offset;
882   G4double dValue = width;
883   if (axis != kPhi) {
884     value0 = value0/TG4G3Units::Length();
885     dValue = dValue/TG4G3Units::Length();
886   }  
887   else  {
888     value0 = value0/TG4G3Units::Angle();
889     dValue = dValue/TG4G3Units::Angle();
890   }  
891   
892   // set tag and attributes names
893   G4String a0 = "mpos"; a0 = a0 + tag;
894   G4String a1 = tag;  a1 = a1 + "0";
895   G4String a2 = "d";  a2 = a2 + tag; 
896
897   // compose element string template
898   G4String element1 = "<" + a0 + "      volume=\"###########   ncopy=\"";
899   G4String element2 = "\"   " + a1 + "=\"";
900   G4String element3 = "\"   " + a2 + "=\"";
901   G4String element4 = "\" />";
902   
903   // put solid name
904   PutName(element1, lvName, "#");
905   
906   // write element
907   fOutFile << fIndention
908            << element1
909            << G4std::setw(fNW+1) << G4std::setprecision(fNP) << nReplicas
910            << element2
911            << G4std::setw(fNW+1) << G4std::setprecision(fNP) << value0
912            << element3     
913            << G4std::setw(fNW+1) << G4std::setprecision(fNP) << dValue
914            << element4
915            << G4endl;
916 }  
917
918 //_____________________________________________________________________________
919 void TG4XMLConvertor::WriteEmptyLine()
920 {
921 // Writes empty line.
922 // ---
923
924   fOutFile << G4endl;
925 }  
926
927 //_____________________________________________________________________________
928 void TG4XMLConvertor::IncreaseIndention()
929 {
930   // increase indention
931   fIndention.append(fkBasicIndention);     
932 }
933
934 //_____________________________________________________________________________
935 void TG4XMLConvertor::DecreaseIndention()
936 {
937   // decrease indention
938   fIndention.replace(fIndention.find(fkBasicIndention), 3 , "");
939 }