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