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