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