VGM Version 5.3
Loading...
Searching...
No Matches
GDMLWriter.cxx
Go to the documentation of this file.
1// $Id$
2
3// -----------------------------------------------------------------------
4// The XmlVGM package of the Virtual Geometry Model
5// Copyright (C) 2007, Ivana Hrivnacova
6// All rights reserved.
7//
8// For the licensing terms see vgm/LICENSE.
9// Contact: ivana@ipno.in2p3.fr
10// -----------------------------------------------------------------------
11
12//
13// Author: I. Hrivnacova, 31.03.2004
14//
15// Class GDMLWriter
16// ----------------------
17// See the class description in the header file.
18
21#include "VGM/solids/IArb8.h"
23#include "VGM/solids/IBox.h"
24#include "VGM/solids/ICons.h"
25#include "VGM/solids/ICtubs.h"
29#include "VGM/solids/IHype.h"
31#include "VGM/solids/IPara.h"
35#include "VGM/solids/ISolid.h"
36#include "VGM/solids/ISphere.h"
38#include "VGM/solids/ITorus.h"
39#include "VGM/solids/ITrap.h"
40#include "VGM/solids/ITrd.h"
41#include "VGM/solids/ITubs.h"
43#include "VGM/volumes/IVolume.h"
44
45#include "ClhepVGM/transform.h"
46
47#include "XmlVGM/GDMLWriter.h"
48#include "XmlVGM/Maps.h"
49#include "XmlVGM/utilities.h"
50
51#include <cstdlib>
52#include <float.h>
53#include <iomanip>
54#include <iostream>
55#include <math.h>
56#include <sstream>
57
58const int XmlVGM::GDMLWriter::fgkDefaultNumWidth = 10;
59const int XmlVGM::GDMLWriter::fgkDefaultNumPrecision = 4;
60const std::string XmlVGM::GDMLWriter::fgkSolidNameExtension = "_s";
61const std::string XmlVGM::GDMLWriter::fgkIsotopeNameExtension = "_i";
62const std::string XmlVGM::GDMLWriter::fgkElementNameExtension = "_e";
63const char XmlVGM::GDMLWriter::fgkCharReplacement = '_';
64const std::string XmlVGM::GDMLWriter::fgkNotAllowedChars = " +-*/&<>%^";
65const std::string XmlVGM::GDMLWriter::fgkNotAllowedChars1 = "0123456789";
66const double XmlVGM::GDMLWriter::fgkSTPTemperature = 273.15; // in kelvin
67const double XmlVGM::GDMLWriter::fgkSTPPressure = 101325; // in pascal
68const double XmlVGM::GDMLWriter::fgkCarTolerance = 1e-10;
69const double XmlVGM::GDMLWriter::fgkAngTolerance = 1e-8;
70
71//_____________________________________________________________________________
73 const std::string& unitName, const std::string& version)
74 : IWriter(),
75 fOutFile(),
76 fUnitName(unitName),
77 fVersion(version),
78 fkBasicIndention(" "),
79 fIndention(fkBasicIndention),
80 fNW(fgkDefaultNumWidth),
81 fNP(fgkDefaultNumPrecision),
82 fGDMLNames(),
83 fMaps(0),
84 fFullLengths(true)
85{
89
90 fOutFile.width(fgkDefaultNumWidth);
91 fOutFile.precision(fgkDefaultNumPrecision);
92}
93
94//_____________________________________________________________________________
99
100//_____________________________________________________________________________
105
106//
107// private methods
108//
109
110//_____________________________________________________________________________
111double XmlVGM::GDMLWriter::UpdateAngle(double angle) const
112{
115
116 if (angle < -360. || angle > 360.) {
117 std::cerr << "+++ Warning +++: " << std::endl;
118 std::cerr << " XmlVGM::GDMLWriter::UpdateAngle:" << std::endl;
119 std::cerr << " Angle " << angle / AngleUnit()
120 << " is outside <-360., 360.>" << std::endl;
121 std::cerr << " It was converted to 0." << std::endl;
122 return 0.;
123 }
124
125 if (angle < 0.) return angle + 360.;
126
127 return angle;
128}
129
130//_____________________________________________________________________________
131void XmlVGM::GDMLWriter::RegisterName(const std::string& name, bool warning)
132{
135
136 // Check if the name is unique
137 if (fGDMLNames.find(name) == fGDMLNames.end())
138 fGDMLNames.insert(name);
139 else if (warning) {
140 std::cerr << "+++ Warning +++: " << std::endl;
141 std::cerr << " Duplicated name has occured: \"" << name << "\""
142 << " in geometry." << std::endl;
143 std::cerr << " Duplicated names are not allowed in GDML." << std::endl;
144 }
145}
146
147//_____________________________________________________________________________
148void XmlVGM::GDMLWriter::WriteBooleanSolid(
149 std::string lvName, const VGM::IBooleanSolid* booleanSolid)
150{
152
153 // Get constituent solids
154 VGM::ISolid* solidA = booleanSolid->ConstituentSolidA();
155 VGM::ISolid* solidB = booleanSolid->ConstituentSolidB();
156
157 // Write constituent solids
158 std::string nameA = StripName(lvName, fgkSolidNameExtension) + "_constA";
159 std::string nameB = StripName(lvName, fgkSolidNameExtension) + "_constB";
160 WriteSolid(nameA, solidA, "");
161 WriteSolid(nameB, solidB, "");
162
163 // Update names
164 nameA = UpdateName(nameA, fgkSolidNameExtension);
165 nameB = UpdateName(nameB, fgkSolidNameExtension);
166
167 // Get displacement
168 VGM::Transform transform = booleanSolid->Displacement();
169 VGM::Transform invTransform = ClhepVGM::Inverse(transform);
170 std::string positionName = fMaps->AddBooleanPosition();
171 std::string rotationName = fMaps->AddBooleanRotation();
172
173 // Get boolean type
174 VGM::BooleanType boolType = booleanSolid->BoolType();
175
176 // compose element string template
177 //
178 std::string element1;
179 std::string element6;
180 switch (boolType) {
182 element1 = "<intersection name=\"";
183 element6 = "</intersection>";
184 break;
186 element1 = "<subtraction name=\"";
187 element6 = "</subtraction>";
188 break;
189 case VGM::kUnion:
190 element1 = "<union name=\"";
191 element6 = "</union>";
192 break;
194 break;
195 }
196 std::string element2 = "\" >";
197 std::string element3 = "<first ref=\"";
198 std::string element4 = "\" />";
199 std::string element5 = "<second ref=\"";
200 std::string indention = fIndention + fkBasicIndention;
201
202 // write element
203 fOutFile << fIndention << element1 << lvName << element2 << std::endl
204 << indention << element3 << nameA << element4 << std::endl
205 << indention << element5 << nameB << element4 << std::endl;
206
207 fOutFile << fkBasicIndention;
208 WritePosition(positionName, transform);
209
210 fOutFile << fkBasicIndention;
211 WriteRotation(rotationName, invTransform);
212
213 fOutFile << fIndention << element6 << std::endl << std::endl;
214}
215
216//_____________________________________________________________________________
217void XmlVGM::GDMLWriter::WriteBox(
218 std::string name, double hx, double hy, double hz)
219{
221
222 // get parameters
223 double x = hx / LengthUnit();
224 double y = hy / LengthUnit();
225 double z = hz / LengthUnit();
226
227 // convert half lengths to full lengths
228 if (fFullLengths) {
229 x *= 2.;
230 y *= 2.;
231 z *= 2.;
232 }
233
234 // compose element string template
235 std::string quota = "\"";
236 std::string element1 = "<box lunit=\"cm\" aunit=\"degree\"";
237 std::string element2 = "name=\"" + name + quota;
238 std::string element3 = "x=\"";
239 std::string element4 = "y=\"";
240 std::string element5 = "z=\"";
241 std::string element6 = "\" />";
242 std::string indention = fIndention + fkBasicIndention;
243
244 // write element
245 fOutFile << fIndention << element1 << std::endl
246 << indention << element2 << std::endl
247 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
248 << x << quota << " " << element4 << std::setw(fNW)
249 << std::setprecision(fNP) << y << quota << " " << element5
250 << std::setw(fNW) << std::setprecision(fNP) << z << element6
251 << std::endl
252 << std::endl;
253}
254
255//_____________________________________________________________________________
256void XmlVGM::GDMLWriter::WriteArb8(std::string name, const VGM::IArb8* arb8)
257{
259
260 // get parameters
261 double hz = arb8->ZHalfLength() / LengthUnit();
262
263 // convert half lengths to full lengths
264 if (fFullLengths) {
265 hz *= 2.;
266 }
267
268 // compose element string template
269 std::string quota = "\"";
270 std::string element1 = "<arb8 lunit=\"cm\"";
271 std::string element2 = "name=\"" + name + quota;
272 std::string element3 = "dz=\"";
273 std::string element4 = "v";
274 std::string element5 = "x=\"";
275 std::string element6 = "y=\"";
276 std::string element7 = " />";
277 std::string indention = fIndention + fkBasicIndention;
278
279 // write openning element
280 fOutFile << fIndention << element1 << std::endl
281 << indention << element2 << std::endl
282 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
283 << hz << quota;
284
285 // write vertices
286 for (int i = 0; i < arb8->NofVertices(); ++i) {
287 VGM::TwoVector vertex = arb8->Vertex(i);
288 double dx = vertex.first / LengthUnit();
289 double dy = vertex.second / LengthUnit();
290
291 fOutFile << std::endl
292 << indention << element4 << std::setw(1) << i + 1 << element5
293 << std::setw(fNW) << std::setprecision(fNP) << dx << quota << " "
294 << element4 << std::setw(1) << i + 1 << element6 << std::setw(fNW)
295 << std::setprecision(fNP) << dy << quota;
296 }
297 fOutFile << element7 << std::endl << std::endl;
298}
299
300//_____________________________________________________________________________
301void XmlVGM::GDMLWriter::WriteBox(std::string name, const VGM::IBox* box)
302{
304
305 WriteBox(name, box->XHalfLength(), box->YHalfLength(), box->ZHalfLength());
306}
307
308//_____________________________________________________________________________
309void XmlVGM::GDMLWriter::WriteCons(std::string name, const VGM::ICons* cons)
310{
312
313 // get parameters
314 double rmin1 = cons->InnerRadiusMinusZ() / LengthUnit();
315 double rmax1 = cons->OuterRadiusMinusZ() / LengthUnit();
316 double rmin2 = cons->InnerRadiusPlusZ() / LengthUnit();
317 double rmax2 = cons->OuterRadiusPlusZ() / LengthUnit();
318 double hz = cons->ZHalfLength() / LengthUnit();
319 double sphi = UpdateAngle(cons->StartPhi()) / AngleUnit();
320 double dphi = UpdateAngle(cons->DeltaPhi()) / AngleUnit();
321
322 // convert half lengths to full lengths
323 if (fFullLengths) {
324 hz *= 2.;
325 }
326
327 // compose element string template
328 std::string quota = "\"";
329 std::string element1 = "<cone lunit=\"cm\" aunit=\"degree\"";
330 std::string element2 = "name=\"" + name + quota;
331 std::string element3 = "z=\"";
332 std::string element4 = "rmin1=\"";
333 std::string element5 = "rmin2=\"";
334 std::string element6 = "rmax1=\"";
335 std::string element7 = "rmax2=\"";
336 std::string element8 = "startphi=\"";
337 std::string element9 = "deltaphi=\"";
338 std::string element10 = "\" />";
339 std::string indention = fIndention + fkBasicIndention;
340
341 // write element
342 fOutFile << fIndention << element1 << std::endl
343 << indention << element2 << std::endl
344 << indention << element4 << std::setw(fNW) << std::setprecision(fNP)
345 << rmin1 << quota << " " << element5 << std::setw(fNW)
346 << std::setprecision(fNP) << rmin2 << quota << " " << element6
347 << std::setw(fNW) << std::setprecision(fNP) << rmax1 << quota << " "
348 << element7 << std::setw(fNW) << std::setprecision(fNP) << rmax2
349 << quota << std::endl
350 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
351 << hz << quota << std::endl
352 << indention << element8 << std::setw(fNW) << std::setprecision(fNP)
353 << sphi << quota << " " << element9 << std::setw(fNW)
354 << std::setprecision(fNP) << dphi << element10 << std::endl
355 << std::endl;
356}
357
358//_____________________________________________________________________________
359void XmlVGM::GDMLWriter::WriteCtubs(std::string name, const VGM::ICtubs* ctubs)
360{
362
363 // get parameters
364 double rmin = ctubs->InnerRadius() / LengthUnit();
365 double rmax = ctubs->OuterRadius() / LengthUnit();
366 double hz = ctubs->ZHalfLength() / LengthUnit() * 2.;
367 double sphi = ctubs->StartPhi() / AngleUnit();
368 double dphi = ctubs->DeltaPhi() / AngleUnit();
369 double nxl = ctubs->NxLow();
370 double nyl = ctubs->NyLow();
371 double nzl = ctubs->NzLow();
372 double nxh = ctubs->NxHigh();
373 double nyh = ctubs->NyHigh();
374 double nzh = ctubs->NzHigh();
375
376 // compose element string template
377 std::string quota = "\"";
378 std::string element1 = "<cutTube lunit=\"cm\" aunit=\"degree\"";
379 std::string element2 = "name=\"" + name + quota;
380 std::string element3 = "z=\"";
381 std::string element4 = "rmin=\"";
382 std::string element5 = "rmax=\"";
383 std::string element6 = "startphi=\"";
384 std::string element7 = "deltaphi=\"";
385 std::string element8 = "lowX=\"";
386 std::string element9 = "lowY=\"";
387 std::string element10 = "lowZ=\"";
388 std::string element11 = "highX=\"";
389 std::string element12 = "highY=\"";
390 std::string element13 = "highZ=\"";
391 std::string element14 = "\" />";
392 std::string indention = fIndention + fkBasicIndention;
393
394 // write element
395 fOutFile << fIndention << element1 << std::endl
396 << indention << element2 << std::endl
397 << indention << element4 << std::setw(fNW) << std::setprecision(fNP)
398 << rmin << quota << " " << element5 << std::setw(fNW)
399 << std::setprecision(fNP) << rmax << quota << " " << element3
400 << std::setw(fNW) << std::setprecision(fNP) << hz << quota
401 << std::endl
402 << indention << element6 << std::setw(fNW) << std::setprecision(fNP)
403 << sphi << quota << " " << element7 << std::setw(fNW)
404 << std::setprecision(fNP) << dphi << quota << std::endl
405 << indention << element8 << std::setw(fNW) << std::setprecision(fNP)
406 << nxl << quota << " " << element9 << std::setw(fNW)
407 << std::setprecision(fNP) << nyl << quota << " " << element10
408 << std::setw(fNW) << std::setprecision(fNP) << nzl << quota
409 << std::endl
410 << indention << element11 << std::setw(fNW) << std::setprecision(fNP)
411 << nxh << quota << " " << element12 << std::setw(fNW)
412 << std::setprecision(fNP) << nyh << quota << " " << element13
413 << std::setw(fNW) << std::setprecision(fNP) << nzh << element14
414 << std::endl
415 << std::endl;
416}
417
418//_____________________________________________________________________________
419void XmlVGM::GDMLWriter::WriteEllipsoid(
420 std::string name, const VGM::IEllipsoid* ellipsoid)
421{
423
424 // get parameters
425 double dx = ellipsoid->XSemiAxis() / LengthUnit();
426 double dy = ellipsoid->YSemiAxis() / LengthUnit();
427 double dz = ellipsoid->ZSemiAxis() / LengthUnit();
428 double zbCut = ellipsoid->ZBottomCut() / LengthUnit();
429 double ztCut = ellipsoid->ZTopCut() / LengthUnit();
430
431 // compose element string template
432 std::string quota = "\"";
433 std::string element1 = "<ellipsoid lunit=\"cm\" aunit=\"degree\"";
434 std::string element2 = "name=\"" + name + quota;
435 std::string element3 = "ax=\"";
436 std::string element4 = "by=\"";
437 std::string element5 = "cz=\"";
438 std::string element6 = "zcut1=\"";
439 std::string element7 = "zcut2=\"";
440 std::string element8 = "\" />";
441 std::string indention = fIndention + fkBasicIndention;
442
443 // write element
444 fOutFile << fIndention << element1 << std::endl
445 << indention << element2 << std::endl
446 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
447 << dx << quota << " " << element4 << std::setw(fNW)
448 << std::setprecision(fNP) << dy << quota << " " << element5
449 << std::setw(fNW) << std::setprecision(fNP) << dz << quota << " "
450 << element6 << std::setw(fNW) << std::setprecision(fNP) << zbCut
451 << quota << " " << element7 << std::setw(fNW)
452 << std::setprecision(fNP) << ztCut << element8 << std::endl
453 << std::endl;
454}
455
456//_____________________________________________________________________________
457void XmlVGM::GDMLWriter::WriteEllipticalTube(
458 std::string name, const VGM::IEllipticalTube* eltu)
459{
461
462 // get parameters
463 double dx = eltu->Dx() / LengthUnit();
464 double dy = eltu->Dy() / LengthUnit();
465 double hz = eltu->ZHalfLength() / LengthUnit();
466
467 // convert half lengths to full lengths
468 /*
469 if (fFullLengths) {
470 hz *= 2.;
471 }
472 */
473 // compose element string template
474 std::string quota = "\"";
475 std::string element1 = "<eltube lunit=\"cm\" aunit=\"degree\"";
476 std::string element2 = "name=\"" + name + quota;
477 std::string element3 = "dx=\"";
478 std::string element4 = "dy=\"";
479 std::string element5 = "dz=\"";
480 std::string element6 = "\" />";
481 std::string indention = fIndention + fkBasicIndention;
482
483 // write element
484 fOutFile << fIndention << element1 << std::endl
485 << indention << element2 << std::endl
486 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
487 << dx << quota << " " << element4 << std::setw(fNW)
488 << std::setprecision(fNP) << dy << quota << " " << element5
489 << std::setw(fNW) << std::setprecision(fNP) << hz << element6
490 << std::endl
491 << std::endl;
492}
493
494//_____________________________________________________________________________
495void XmlVGM::GDMLWriter::WriteExtrudedSolid(
496 std::string name, const VGM::IExtrudedSolid* extruded)
497{
499
500 // get vertices
501 int nofVertices = extruded->NofVertices();
502 double* xvertArray = new double[nofVertices];
503 double* yvertArray = new double[nofVertices];
504 for (int i = 0; i < nofVertices; i++) {
505 xvertArray[i] = extruded->Vertex(i).first / LengthUnit();
506 yvertArray[i] = extruded->Vertex(i).second / LengthUnit();
507 }
508
509 // get Z sections parameters
510 int nofZSections = extruded->NofZSections();
511 double* zArray = new double[nofZSections];
512 double* xoffsetArray = new double[nofZSections];
513 double* yoffsetArray = new double[nofZSections];
514 double* scaleArray = new double[nofZSections];
515 for (int i = 0; i < nofZSections; i++) {
516 zArray[i] = extruded->ZPosition(i) / LengthUnit();
517 xoffsetArray[i] = extruded->Offset(i).first / LengthUnit();
518 yoffsetArray[i] = extruded->Offset(i).second / LengthUnit();
519 scaleArray[i] = extruded->Scale(i);
520 }
521
522 // compose element string template
523 std::string quota = "\"";
524 std::string element1 = "<xtru lunit=\"cm\" aunit=\"degree\"";
525 std::string element2 = "name=\"" + name + quota;
526 std::string element3 = " >";
527 std::string element4 = "<twoDimVertex x=\"";
528 std::string element5 = "y=\"";
529 std::string element6 = "\" />";
530 std::string element7 = "<section zPosition=\"";
531 std::string element8 = "zOrder=\"";
532 std::string element9 = "xOffset=\"";
533 std::string element10 = "yOffset=\"";
534 std::string element11 = "scalingFactor=\"";
535 std::string element12 = "</xtru>";
536 std::string indention = fIndention + fkBasicIndention;
537
538 // write xtru element
539 fOutFile << fIndention << element1 << std::endl
540 << indention << element2 << element3 << std::endl;
541
542 // write vertices
543 for (int i = 0; i < nofVertices; i++) {
544 fOutFile << indention << element4 << std::setw(fNW)
545 << std::setprecision(fNP) << xvertArray[i] << quota << " "
546 << element5 << std::setw(fNW) << std::setprecision(fNP)
547 << yvertArray[i] << element6 << std::endl;
548 }
549
550 // write polyplane elements
551 for (int i = 0; i < nofZSections; i++) {
552 fOutFile << indention << element7 << std::setw(fNW)
553 << std::setprecision(fNP) << zArray[i] << quota << " " << element8
554 << std::setw(3) << i << quota << " " << element9 << std::setw(fNW)
555 << std::setprecision(fNP) << xoffsetArray[i] << quota << " "
556 << element10 << std::setw(fNW) << std::setprecision(fNP)
557 << yoffsetArray[i] << quota << " " << element11 << std::setw(fNW)
558 << std::setprecision(fNP) << scaleArray[i] << element6
559 << std::endl;
560 }
561
562 // close pcon element
563 fOutFile << fIndention << element12 << std::endl << std::endl;
564
565 delete[] xvertArray;
566 delete[] yvertArray;
567 delete[] zArray;
568 delete[] xoffsetArray;
569 delete[] yoffsetArray;
570 delete[] scaleArray;
571}
572
573//_____________________________________________________________________________
574void XmlVGM::GDMLWriter::WriteHype(std::string name, const VGM::IHype* hype)
575{
577
578 // get parameters
579 double rin = hype->InnerRadius() / LengthUnit();
580 double rout = hype->OuterRadius() / LengthUnit();
581 double dz = hype->ZHalfLength() / LengthUnit();
582 double stereoin = hype->InnerStereoAngle() / AngleUnit();
583 double stereoout = hype->OuterStereoAngle() / AngleUnit();
584
585 // convert half lengths to full lengths
586 if (fFullLengths) {
587 dz *= 2.;
588 }
589
590 // compose element string template
591 std::string quota = "\"";
592 std::string element1 = "<hype lunit=\"cm\" aunit=\"degree\"";
593 std::string element2 = "name=\"" + name + quota;
594 std::string element3 = "rmin=\"";
595 std::string element4 = "rmax=\"";
596 std::string element5 = "inst=\"";
597 std::string element6 = "outst=\"";
598 std::string element7 = "z=\"";
599 std::string element8 = "\" />";
600 std::string indention = fIndention + fkBasicIndention;
601
602 // write element
603 fOutFile << fIndention << element1 << std::endl
604 << indention << element2 << std::endl
605 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
606 << rin << quota << " " << element4 << std::setw(fNW)
607 << std::setprecision(fNP) << rout << quota << std::endl
608 << indention << element5 << std::setw(fNW) << std::setprecision(fNP)
609 << stereoin << quota << " " << element6 << std::setw(fNW)
610 << std::setprecision(fNP) << stereoout << quota << std::endl
611 << indention << element7 << std::setw(fNW) << std::setprecision(fNP)
612 << dz << element8 << std::endl
613 << std::endl;
614}
615
616//_____________________________________________________________________________
617void XmlVGM::GDMLWriter::WriteMultiUnion(
618 std::string name, const VGM::IMultiUnion* multiUnion)
619{
621
622 // Write constituent solids
623 std::vector<std::string> constNames;
624 for (int i = 0; i < multiUnion->NofSolids(); ++i) {
625 VGM::ISolid* constSolid = multiUnion->ConstituentSolid(i);
626 // write solid
627 std::string constName =
628 StripName(constSolid->Name(), fgkSolidNameExtension);
629 WriteSolid(constName, constSolid, "");
630 constName = UpdateName(constName, fgkSolidNameExtension);
631 constNames.push_back(constName);
632 }
633
634 // compose element
635 //
636 std::string element1 = "<multiUnion name=\"";
637 std::string element2 = "\">";
638 std::string element3 = "<multiUnionNode name=\"node-";
639 std::string element4 = "<solid ref=\"";
640 std::string element5 = "\" />";
641 std::string element6 = "<positionref ref=\"";
642 std::string element7 = "<rotationref ref=\"";
643 std::string element8 = "</multiUnionNode>";
644 std::string element9 = "</multiUnion>";
645
646 // write opening element
647 fOutFile << fIndention << element1 << name << element2 << std::endl;
648
649 std::string indention = fIndention + fkBasicIndention;
650 std::string indention2 = indention + fkBasicIndention;
651
652 // write nodes
653 for (int i = 0; i < multiUnion->NofSolids(); ++i) {
654 fOutFile << indention << element3 << i << element2 << std::endl
655 << indention2 << element4 << constNames[i] << element5
656 << std::endl;
657
658 // Displacement
659 std::string positionRef =
660 fMaps->FindPositionName(multiUnion->Transformation(i));
661 std::string rotationRef =
662 fMaps->FindRotationName(multiUnion->Transformation(i));
663
664 if (positionRef.size()) {
665 fOutFile << indention2 << element6 << positionRef << element5
666 << std::endl;
667 }
668
669 if (rotationRef.size()) {
670 fOutFile << indention2 << element7 << rotationRef << element5
671 << std::endl;
672 }
673 fOutFile << indention << element8 << std::endl;
674 }
675 fOutFile << fIndention << element9 << std::endl << std::endl;
676}
677
678//_____________________________________________________________________________
679void XmlVGM::GDMLWriter::WritePara(std::string name, const VGM::IPara* para)
680{
682
683 // get parameters
684 double dx = para->XHalfLength() / LengthUnit();
685 double dy = para->YHalfLength() / LengthUnit();
686 double dz = para->ZHalfLength() / LengthUnit();
687 double alpha = para->Alpha() / AngleUnit();
688 double theta = UpdateAngle(para->Theta()) / AngleUnit();
689 double phi = UpdateAngle(para->Phi()) / AngleUnit();
690
691 // convert half lengths to full lengths
692 if (fFullLengths) {
693 dx *= 2.;
694 dy *= 2.;
695 dz *= 2.;
696 }
697
698 // compose element string template
699 std::string quota = "\"";
700 std::string element1 = "<para lunit=\"cm\" aunit=\"degree\"";
701 std::string element2 = "name=\"" + name + quota;
702 std::string element3 = "x=\"";
703 std::string element4 = "y=\"";
704 std::string element5 = "z=\"";
705 std::string element6 = "alpha=\"";
706 std::string element7 = "theta=\"";
707 std::string element8 = "phi=\"";
708 std::string element9 = "\" />";
709 std::string indention = fIndention + fkBasicIndention;
710
711 // write element
712 fOutFile << fIndention << element1 << std::endl
713 << indention << element2 << std::endl
714 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
715 << dx << quota << " " << element4 << std::setw(fNW)
716 << std::setprecision(fNP) << dy << quota << " " << element5
717 << std::setw(fNW) << std::setprecision(fNP) << dz << quota
718 << std::endl
719 << indention << element6 << std::setw(fNW) << std::setprecision(fNP)
720 << alpha << quota << " " << element7 << std::setw(fNW)
721 << std::setprecision(fNP) << theta << quota << " " << element8
722 << std::setw(fNW) << std::setprecision(fNP) << phi << element9
723 << std::endl
724 << std::endl;
725}
726
727//_____________________________________________________________________________
728void XmlVGM::GDMLWriter::WriteParaboloid(
729 std::string name, const VGM::IParaboloid* paraboloid)
730{
732
733 // get parameters
734 double rlo = paraboloid->RadiusMinusZ() / LengthUnit();
735 double rhi = paraboloid->RadiusPlusZ() / LengthUnit();
736 double dz = paraboloid->ZHalfLength() / LengthUnit();
737
738 // switch rlo, rhi if rhi < rlo
739 // to make sure that GDML can be loaded by Geant4, which does not allow rhi <
740 // rlo
741 if (rhi < rlo) {
742 double tmp = rlo;
743 rlo = rhi;
744 rhi = tmp;
745 }
746
747 // convert half lengths to full lengths
748 // if (fFullLengths) {
749 // dz *= 2.;
750 //}
751
752 // compose element string template
753 std::string quota = "\"";
754 std::string element1 = "<paraboloid lunit=\"cm\" aunit=\"degree\"";
755 std::string element2 = "name=\"" + name + quota;
756 std::string element3 = "rlo=\"";
757 std::string element4 = "rhi=\"";
758 std::string element5 = "dz=\"";
759 std::string element6 = "\" />";
760 std::string indention = fIndention + fkBasicIndention;
761
762 // write element
763 fOutFile << fIndention << element1 << std::endl
764 << indention << element2 << std::endl
765 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
766 << rlo << quota << " " << element4 << std::setw(fNW)
767 << std::setprecision(fNP) << rhi << quota << " " << element5
768 << std::setw(fNW) << std::setprecision(fNP) << dz << element6
769 << std::endl
770 << std::endl;
771}
772
773//_____________________________________________________________________________
774void XmlVGM::GDMLWriter::WritePolycone(
775 std::string name, const VGM::IPolycone* polycone)
776{
778
779 // get profile parameters
780 double sphi = polycone->StartPhi() / AngleUnit();
781 double dphi = polycone->DeltaPhi() / AngleUnit();
782
783 // get polycone Z planes parameters
784 int nofZPlanes = polycone->NofZPlanes();
785 double* rminArray = new double[nofZPlanes];
786 double* rmaxArray = new double[nofZPlanes];
787 double* zArray = new double[nofZPlanes];
788 for (int i = 0; i < nofZPlanes; i++) {
789 rminArray[i] = polycone->InnerRadiusValues()[i] / LengthUnit();
790 rmaxArray[i] = polycone->OuterRadiusValues()[i] / LengthUnit();
791 zArray[i] = polycone->ZValues()[i] / LengthUnit();
792 }
793
794 // compose element string template
795 std::string quota = "\"";
796 std::string element1 = "<polycone lunit=\"cm\" aunit=\"degree\"";
797 std::string element2 = "name=\"" + name + quota;
798 std::string element3 = "startphi=\"";
799 std::string element4 = "deltaphi=\"";
800 std::string element5 = "\" >";
801 std::string element6 = "<zplane z=\"";
802 std::string element7 = "rmin=\"";
803 std::string element8 = "rmax=\"";
804 std::string element9 = "\" />";
805 std::string element10 = "</polycone>";
806 std::string indention = fIndention + fkBasicIndention;
807
808 // write pcon element
809 fOutFile << fIndention << element1 << std::endl
810 << indention << element2 << std::endl
811 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
812 << sphi << quota << " " << element4 << std::setw(fNW)
813 << std::setprecision(fNP) << dphi << element5 << std::endl;
814
815 // write polyplane elements
816 for (int j = 0; j < nofZPlanes; j++) {
817
818 fOutFile << indention << element6 << std::setw(fNW)
819 << std::setprecision(fNP) << zArray[j] << quota << " " << element7
820 << std::setw(fNW) << std::setprecision(fNP) << rminArray[j]
821 << quota << " " << element8 << std::setw(fNW)
822 << std::setprecision(fNP) << rmaxArray[j] << element9 << std::endl;
823 }
824
825 // close pcon element
826 fOutFile << fIndention << element10 << std::endl << std::endl;
827
828 delete[] rminArray;
829 delete[] rmaxArray;
830 delete[] zArray;
831}
832
833//_____________________________________________________________________________
834void XmlVGM::GDMLWriter::WritePolyhedra(
835 std::string name, const VGM::IPolyhedra* polyhedra)
836{
838
839 // get profile parameters
840 double sphi = UpdateAngle(polyhedra->StartPhi()) / AngleUnit();
841 double dphi = UpdateAngle(polyhedra->DeltaPhi()) / AngleUnit();
842
843 // get polyhedra Z planes parameters
844 int nofZPlanes = polyhedra->NofZPlanes();
845 int nofSides = polyhedra->NofSides();
846 double* rminArray = new double[nofZPlanes];
847 double* rmaxArray = new double[nofZPlanes];
848 double* zArray = new double[nofZPlanes];
849 for (int i = 0; i < nofZPlanes; i++) {
850 rminArray[i] = polyhedra->InnerRadiusValues()[i] / LengthUnit();
851 rmaxArray[i] = polyhedra->OuterRadiusValues()[i] / LengthUnit();
852 zArray[i] = polyhedra->ZValues()[i] / LengthUnit();
853 }
854
855 // compose element string template
856 std::string quota = "\"";
857 std::string element1 = "<polyhedra lunit=\"cm\" aunit=\"degree\"";
858 std::string element2 = "name=\"" + name + quota;
859 std::string element3 = "numsides=\"";
860 std::string element4 = "startphi=\"";
861 std::string element5 = "deltaphi=\"";
862 std::string element6 = "\" >";
863 std::string element7 = "<zplane z=\"";
864 std::string element8 = "rmin=\"";
865 std::string element9 = "rmax=\"";
866 std::string element10 = "\" />";
867 std::string element11 = "</polyhedra>";
868 std::string indention = fIndention + fkBasicIndention;
869
870 // write polyhedra element
871 fOutFile << fIndention << element1 << std::endl
872 << indention << element2 << std::endl
873 << indention << element3 << nofSides << quota << std::endl
874 << indention << element4 << std::setw(fNW) << std::setprecision(fNP)
875 << sphi << quota << " " << element5 << std::setw(fNW)
876 << std::setprecision(fNP) << dphi << element6 << std::endl;
877
878 // write polyplane elements
879 for (int j = 0; j < nofZPlanes; j++) {
880
881 fOutFile << indention << element7 << std::setw(fNW)
882 << std::setprecision(fNP) << zArray[j] << quota << " " << element8
883 << std::setw(fNW) << std::setprecision(fNP) << rminArray[j]
884 << quota << " " << element9 << std::setw(fNW)
885 << std::setprecision(fNP) << rmaxArray[j] << element10
886 << std::endl;
887 }
888
889 // close pcon element
890 fOutFile << fIndention << element11 << std::endl << std::endl;
891
892 delete[] rminArray;
893 delete[] rmaxArray;
894 delete[] zArray;
895}
896
897//_____________________________________________________________________________
898void XmlVGM::GDMLWriter::WriteSphere(
899 std::string name, const VGM::ISphere* sphere)
900{
902
903 // get parameters
904 double rmin = sphere->InnerRadius() / LengthUnit();
905 double rmax = sphere->OuterRadius() / LengthUnit();
906 double sphi = UpdateAngle(sphere->StartPhi()) / AngleUnit();
907 double dphi = UpdateAngle(sphere->DeltaPhi()) / AngleUnit();
908 double stheta = UpdateAngle(sphere->StartTheta()) / AngleUnit();
909 double dtheta = UpdateAngle(sphere->DeltaTheta()) / AngleUnit();
910
911 // compose element string template
912 std::string quota = "\"";
913 std::string element1 = "<sphere lunit=\"cm\" aunit=\"degree\"";
914 std::string element2 = "name=\"" + name + quota;
915 std::string element3 = "rmin=\"";
916 std::string element4 = "rmax=\"";
917 std::string element5 = "startphi=\"";
918 std::string element6 = "deltaphi=\"";
919 std::string element7 = "starttheta=\"";
920 std::string element8 = "deltatheta=\"";
921 std::string element9 = "\" />";
922 std::string indention = fIndention + fkBasicIndention;
923
924 // write element
925 fOutFile << fIndention << element1 << std::endl
926 << indention << element2 << std::endl
927 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
928 << rmin << quota << " " << element4 << std::setw(fNW)
929 << std::setprecision(fNP) << rmax << quota << std::endl
930 << indention << element5 << std::setw(fNW) << std::setprecision(fNP)
931 << sphi << quota << " " << element6 << std::setw(fNW)
932 << std::setprecision(fNP) << dphi << quota << " " << element7
933 << std::setw(fNW) << std::setprecision(fNP) << stheta << quota
934 << " " << element8 << std::setw(fNW) << std::setprecision(fNP)
935 << dtheta << element9 << std::endl
936 << std::endl;
937}
938
939//_____________________________________________________________________________
940void XmlVGM::GDMLWriter::WriteTessellatedSolid(
941 std::string name, const VGM::ITessellatedSolid* tessellated)
942{
944
945 // compose element string template
946 std::string quota = "\"";
947 std::string element1 = "<tessellated name=\"" + name + "\">";
948 std::string element2 = "<triangular ";
949 std::string element3 = "<quadrangular ";
950 std::string element4 = " vertex";
951 std::string element5 = "=\"";
952 std::string element6 = "/>";
953 std::string element8 = "</tessellated>";
954 std::string indention = fIndention + fkBasicIndention;
955
956 // write openning element
957 fOutFile << fIndention << element1 << std::endl;
958
959 // write triangular facets
960 for (int i = 0; i < tessellated->NofFacets(); ++i) {
961 int nofVertices = tessellated->NofVertices(i);
962 if (nofVertices == 3)
963 fOutFile << indention << element2;
964 else
965 fOutFile << indention << element3;
966
967 for (int j = 0; j < nofVertices; ++j) {
968 // Vertex position
969 VGM::ThreeVector vertex = tessellated->Vertex(i, j);
970 std::string positionRef = fMaps->FindPositionName(vertex);
971
972 fOutFile << element4 << std::setw(1) << j + 1 << element5 << positionRef
973 << quota;
974 }
975 fOutFile << element6 << std::endl;
976 }
977
978 // write closing element
979 fOutFile << fIndention << element8 << std::endl << std::endl;
980}
981
982//_____________________________________________________________________________
983void XmlVGM::GDMLWriter::WriteTorus(std::string name, const VGM::ITorus* torus)
984{
986
987 // get parameters
988 double rmin = torus->InnerRadius() / LengthUnit();
989 double rmax = torus->OuterRadius() / LengthUnit();
990 double rax = torus->AxialRadius() / LengthUnit();
991 double sphi = UpdateAngle(torus->StartPhi()) / AngleUnit();
992 double dphi = UpdateAngle(torus->DeltaPhi()) / AngleUnit();
993
994 // compose element string template
995 std::string quota = "\"";
996 std::string element1 = "<torus lunit=\"cm\" aunit=\"degree\"";
997 std::string element2 = "name=\"" + name + quota;
998 std::string element3 = "rmin=\"";
999 std::string element4 = "rmax=\"";
1000 std::string element5 = "rtor=\"";
1001 std::string element6 = "startphi=\"";
1002 std::string element7 = "deltaphi=\"";
1003 std::string element8 = "\" />";
1004 std::string indention = fIndention + fkBasicIndention;
1005
1006 // write element
1007 fOutFile << fIndention << element1 << std::endl
1008 << indention << element2 << std::endl
1009 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
1010 << rmin << quota << " " << element4 << std::setw(fNW)
1011 << std::setprecision(fNP) << rmax << quota << " " << element5
1012 << std::setw(fNW) << std::setprecision(fNP) << rax << quota
1013 << std::endl
1014 << indention << element6 << std::setw(fNW) << std::setprecision(fNP)
1015 << sphi << quota << " " << element7 << std::setw(fNW)
1016 << std::setprecision(fNP) << dphi << element8 << std::endl
1017 << std::endl;
1018}
1019
1020//_____________________________________________________________________________
1021void XmlVGM::GDMLWriter::WriteTrap(std::string name, const VGM::ITrap* trap)
1022{
1024
1025 // get parameters
1026 double dz = trap->ZHalfLength() / LengthUnit();
1027 double theta = UpdateAngle(trap->Theta()) / AngleUnit();
1028 double phi = UpdateAngle(trap->Phi()) / AngleUnit();
1029 double y1 = trap->YHalfLengthMinusZ() / LengthUnit();
1030 double x1 = trap->XHalfLengthMinusZMinusY() / LengthUnit();
1031 double x2 = trap->XHalfLengthMinusZPlusY() / LengthUnit();
1032 double alpha1 = trap->AlphaMinusZ() / AngleUnit();
1033 double y2 = trap->YHalfLengthPlusZ() / LengthUnit();
1034 double x3 = trap->XHalfLengthPlusZMinusY() / LengthUnit();
1035 double x4 = trap->XHalfLengthPlusZPlusY() / LengthUnit();
1036 double alpha2 = trap->AlphaPlusZ() / AngleUnit();
1037
1038 // convert half lengths to full lengths
1039 if (fFullLengths) {
1040 dz *= 2.;
1041 y1 *= 2.;
1042 x1 *= 2.;
1043 x2 *= 2.;
1044 y2 *= 2.;
1045 x3 *= 2.;
1046 x4 *= 2.;
1047 }
1048
1049 // compose element string template
1050 std::string quota = "\"";
1051 std::string element1 = "<trap lunit=\"cm\" aunit=\"degree\"";
1052 std::string element2 = "name=\"" + name + quota;
1053 std::string element3 = "z=\"";
1054 std::string element4 = "theta=\"";
1055 std::string element5 = "phi=\"";
1056 std::string element6 = "y1=\"";
1057 std::string element7 = "x1=\"";
1058 std::string element8 = "x2=\"";
1059 std::string element9 = "alpha1=\"";
1060 std::string element10 = "y2=\"";
1061 std::string element11 = "x3=\"";
1062 std::string element12 = "x4=\"";
1063 std::string element13 = "alpha2=\"";
1064 std::string element14 = "\" />";
1065 std::string indention = fIndention + fkBasicIndention;
1066
1067 // write element
1068 fOutFile << fIndention << element1 << std::endl
1069 << indention << element2 << std::endl
1070 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
1071 << dz << quota << std::endl
1072 << indention << element4 << std::setw(fNW) << std::setprecision(fNP)
1073 << theta << quota << " " << element5 << std::setw(fNW)
1074 << std::setprecision(fNP) << phi << quota << std::endl
1075 << indention << element6 << std::setw(fNW) << std::setprecision(fNP)
1076 << y1 << quota << " " << element7 << std::setw(fNW)
1077 << std::setprecision(fNP) << x1 << quota << " " << element8
1078 << std::setw(fNW) << std::setprecision(fNP) << x2 << quota << " "
1079 << element9 << std::setw(fNW) << std::setprecision(fNP) << alpha1
1080 << quota << std::endl
1081 << indention << element10 << std::setw(fNW) << std::setprecision(fNP)
1082 << y2 << quota << " " << element11 << std::setw(fNW)
1083 << std::setprecision(fNP) << x3 << quota << " " << element12
1084 << std::setw(fNW) << std::setprecision(fNP) << x4 << quota << " "
1085 << element13 << std::setw(fNW) << std::setprecision(fNP) << alpha2
1086 << element14 << std::endl
1087 << std::endl;
1088}
1089
1090//_____________________________________________________________________________
1091void XmlVGM::GDMLWriter::WriteTrd(std::string name, const VGM::ITrd* trd)
1092{
1094
1095 // get parameters
1096 double x1 = trd->XHalfLengthMinusZ() / LengthUnit();
1097 double x2 = trd->XHalfLengthPlusZ() / LengthUnit();
1098 double y1 = trd->YHalfLengthMinusZ() / LengthUnit();
1099 double y2 = trd->YHalfLengthPlusZ() / LengthUnit();
1100 double hz = trd->ZHalfLength() / LengthUnit();
1101
1102 // convert half lengths to full lengths
1103 if (fFullLengths) {
1104 x1 *= 2.;
1105 x2 *= 2.;
1106 y1 *= 2.;
1107 y2 *= 2.;
1108 hz *= 2.;
1109 }
1110
1111 // compose element string template
1112 std::string quota = "\"";
1113 std::string element1 = "<trd lunit=\"cm\" aunit=\"degree\"";
1114 std::string element2 = "name=\"" + name + quota;
1115 std::string element3 = "x1=\"";
1116 std::string element4 = "x2=\"";
1117 std::string element5 = "y1=\"";
1118 std::string element6 = "y2=\"";
1119 std::string element7 = "z=\"";
1120 std::string element8 = "\" />";
1121 std::string indention = fIndention + fkBasicIndention;
1122
1123 // write element
1124 fOutFile << fIndention << element1 << std::endl
1125 << indention << element2 << std::endl
1126 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
1127 << x1 << quota << " " << element4 << std::setw(fNW)
1128 << std::setprecision(fNP) << x2 << quota << " " << element5
1129 << std::setw(fNW) << std::setprecision(fNP) << y1 << quota << " "
1130 << element6 << std::setw(fNW) << std::setprecision(fNP) << y2
1131 << quota << std::endl
1132 << indention << element7 << std::setw(fNW) << std::setprecision(fNP)
1133 << hz << element8 << std::endl
1134 << std::endl;
1135}
1136
1137//_____________________________________________________________________________
1138void XmlVGM::GDMLWriter::WriteTubs(std::string name, const VGM::ITubs* tubs)
1139{
1141
1142 // get parameters
1143 double rmin = tubs->InnerRadius() / LengthUnit();
1144 double rmax = tubs->OuterRadius() / LengthUnit();
1145 double hz = tubs->ZHalfLength() / LengthUnit();
1146 double sphi = UpdateAngle(tubs->StartPhi()) / AngleUnit();
1147 double dphi = UpdateAngle(tubs->DeltaPhi()) / AngleUnit();
1148
1149 // convert half lengths to full lengths
1150 if (fFullLengths) {
1151 hz *= 2.;
1152 }
1153
1154 // compose element string template
1155 std::string quota = "\"";
1156 std::string element1 = "<tube lunit=\"cm\" aunit=\"degree\"";
1157 std::string element2 = "name=\"" + name + quota;
1158 std::string element3 = "z=\"";
1159 std::string element4 = "rmin=\"";
1160 std::string element5 = "rmax=\"";
1161 std::string element6 = "startphi=\"";
1162 std::string element7 = "deltaphi=\"";
1163 std::string element8 = "\" />";
1164 std::string indention = fIndention + fkBasicIndention;
1165
1166 // write element
1167 fOutFile << fIndention << element1 << std::endl
1168 << indention << element2 << std::endl
1169 << indention << element4 << std::setw(fNW) << std::setprecision(fNP)
1170 << rmin << quota << " " << element5 << std::setw(fNW)
1171 << std::setprecision(fNP) << rmax << quota << " " << element3
1172 << std::setw(fNW) << std::setprecision(fNP) << hz << quota
1173 << std::endl
1174 << indention << element6 << std::setw(fNW) << std::setprecision(fNP)
1175 << sphi << quota << " " << element7 << std::setw(fNW)
1176 << std::setprecision(fNP) << dphi << element8 << std::endl
1177 << std::endl;
1178}
1179
1180//_____________________________________________________________________________
1181void XmlVGM::GDMLWriter::WriteNotSupportedSolid(std::string name)
1182{
1185
1186 // Compose comment
1187 std::string element1 = "<!-- !!! unsupported shape !!! name= \"";
1188 std::string element2 = "\" -->";
1189 std::string element3 = "<!-- dummy box is written instead -->";
1190
1191 // Write element with warning
1192 fOutFile << fIndention << element1 << name << element2 << std::endl
1193 << fIndention << element3 << std::endl;
1194
1195 // Write dummy box element
1196 WriteBox(name, 1.0, 1.0, 1.0);
1197}
1198
1199//_____________________________________________________________________________
1200void XmlVGM::GDMLWriter::WriteSimplePlacement(const std::string& volumeName,
1201 const std::string& positionRef, const std::string& rotationRef,
1202 bool isReflection)
1203{
1205
1206 // Update name
1207 std::string name = UpdateName(volumeName);
1208
1209 // Compose element strings
1210 //
1211 std::string element0 = "\"/>";
1212 std::string element1 = "<physvol>";
1213
1214 std::string element2 = "<volumeref ref=\"";
1215 element2.append(name);
1216 element2.append(element0);
1217
1218 std::string element3 = "<positionref ref=\"";
1219 element3.append(positionRef);
1220 element3.append(element0);
1221
1222 std::string element4 = "<rotationref ref=\"";
1223 element4.append(rotationRef);
1224 element4.append(element0);
1225
1226 std::string element5 = "<scaleref ref=\"";
1227 element5.append(std::string("scale_0"));
1228 element5.append(element0);
1229
1230 std::string element6 = "</physvol>";
1231
1232 std::string indention1 = fIndention + fkBasicIndention;
1233 std::string indention2 = fIndention + fkBasicIndention + fkBasicIndention;
1234
1235 // Write element
1236 fOutFile << fIndention << element1 << std::endl
1237 << indention1 << element2 << std::endl
1238 << indention2 << element3 << std::endl
1239 << indention2 << element4 << std::endl;
1240
1241 if (isReflection) fOutFile << indention2 << element5 << std::endl;
1242
1243 fOutFile << fIndention << element6 << std::endl;
1244}
1245
1246//_____________________________________________________________________________
1247void XmlVGM::GDMLWriter::WriteMultiplePlacement(const std::string& volumeName,
1248 VGM::Axis axis, int nofReplicas, double width, double offset)
1249{
1251
1252 std::string axisName;
1253 switch (axis) {
1254 case VGM::kXAxis:
1255 axisName = "kXAxis";
1256 break;
1257 case VGM::kYAxis:
1258 axisName = "kYAxis";
1259 break;
1260 case VGM::kZAxis:
1261 axisName = "kZAxis";
1262 break;
1263 case VGM::kRho:
1264 axisName = "kRho";
1265 break;
1266 case VGM::kPhi:
1267 axisName = "kPhi";
1268 break;
1269 case VGM::kRadial3D:
1270 axisName = "Undefined";
1271 break; // ADD WARNING HERE
1272 case VGM::kSphTheta:
1273 axisName = "Undefined";
1274 break;
1275 case VGM::kUnknownAxis:
1276 axisName = "Undefined";
1277 break;
1278 }
1279
1280 // set units
1281 double width2;
1282 double offset2;
1283 std::string unit;
1284 if (axis != VGM::kPhi && axis != VGM::kSphTheta) {
1285 width2 = width / LengthUnit();
1286 offset2 = offset / LengthUnit();
1287 unit = "cm";
1288 }
1289 else {
1290 width2 = width / AngleUnit();
1291 offset2 = offset / AngleUnit();
1292 unit = "degree";
1293 }
1294
1295 // Compose element strings
1296 //
1297 // compose element string template
1298 std::string quota = "\"";
1299 std::string element1 = "<divisionvol unit=\"";
1300 std::string element2 = "axis=\"";
1301 std::string element3 = "number=\"";
1302 std::string element4 = "offset=\"";
1303 std::string element5 = "width=\"";
1304 std::string element6 = "\">";
1305
1306 std::string element7 = "<volumeref ref=\"";
1307 std::string element8 = "\"/>";
1308 std::string element9 = "</divisionvol>";
1309
1310 std::string indention1 = fIndention + fkBasicIndention;
1311
1312 // write element
1313 fOutFile << fIndention << element1 << unit << quota << std::endl
1314 << indention1 << element2 << axisName + quota << " " << element3
1315 << nofReplicas << quota << " " << element4 << std::setw(fNW + 1)
1316 << std::setprecision(fNP) << offset2 << quota << " " << element5
1317 << std::setw(fNW + 1) << std::setprecision(fNP) << width2 << element6
1318 << std::endl
1319 << indention1 << element7 << volumeName << element8 << std::endl
1320 << fIndention << element9 << std::endl;
1321}
1322
1323//
1324// public methods
1325//
1326
1327//_____________________________________________________________________________
1328void XmlVGM::GDMLWriter::OpenFile(std::string filePath)
1329{
1330 // Opens output file
1331
1332 fOutFile.open(filePath.data(), std::ios::out);
1333
1334 if (!fOutFile) {
1335 std::cerr << " Cannot open " << filePath << std::endl;
1336 std::cerr << "** Exception: Aborting execution **" << std::endl;
1337 exit(1);
1338 }
1339
1340 // use FORTRAN compatibility output
1341 fOutFile.setf(std::ios::fixed, std::ios::floatfield);
1342}
1343
1344//_____________________________________________________________________________
1346{
1347 // Write document opening;
1348 // Could be made customizable in future
1349
1350 fOutFile << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" \?>"
1351 << std::endl
1352 << "<gdml xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
1353 "xsi:noNamespaceSchemaLocation=\""
1354 << std::endl
1355 << "http://service-spi.web.cern.ch/service-spi/app/releases/GDML/"
1356 "schema/gdml.xsd\">"
1357 << std::endl;
1358}
1359
1360//_____________________________________________________________________________
1361void XmlVGM::GDMLWriter::OpenSection(const std::string& /*topVolume*/)
1362{
1363 // Write section opening
1364
1365 // nothing to be done in GDML
1366}
1367
1368//_____________________________________________________________________________
1370{
1371 // Open element for general definitions
1372 // (positions and rotations for generated XML files.)
1373
1374 std::string element1 = "<define>";
1375
1376 // write element
1377 fOutFile << fIndention << element1 << std::endl;
1378
1379 // increase indention
1380 IncreaseIndention();
1381}
1382
1383//_____________________________________________________________________________
1385{
1386 // Rotations are written in the same element as positions.
1387 // The element is already open.
1388}
1389
1390//_____________________________________________________________________________
1392{
1393 // Write materials opening
1394
1395 std::string element = "<materials>";
1396
1397 // write element
1398 fOutFile << fIndention << element << std::endl;
1399
1400 // increase indention
1401 IncreaseIndention();
1402}
1403
1404//_____________________________________________________________________________
1406{
1407 // Write solids opening
1408
1409 std::string element = "<solids>";
1410
1411 // write element
1412 fOutFile << fIndention << element << std::endl;
1413
1414 // increase indention
1415 IncreaseIndention();
1416}
1417
1418//_____________________________________________________________________________
1420{
1421 // Write structure opening.
1422
1423 std::string element = "<structure>";
1424
1425 // Write element
1426 fOutFile << fIndention << element << std::endl;
1427
1428 // increase indention
1429 IncreaseIndention();
1430}
1431
1432//_____________________________________________________________________________
1434 const std::string& name, const std::string& materialName)
1435{
1436 // Write composition opening.
1437
1438 // Update names
1439 std::string volName = UpdateName(name);
1440 std::string matName = UpdateName(materialName);
1441 std::string sldName = UpdateName(name, fgkSolidNameExtension);
1442
1443 // Register volume name
1444 RegisterName(volName);
1445
1446 std::string element1 = "<volume name=\"";
1447 element1.append(volName);
1448 element1.append("\">");
1449
1450 std::string element2 = "<materialref ref=\"";
1451 element2.append(matName);
1452 element2.append("\"/>");
1453
1454 std::string element3 = "<solidref ref=\"";
1455 element3.append(sldName);
1456 element3.append("\"/>");
1457
1458 std::string indention = fIndention + fkBasicIndention;
1459
1460 // write element
1461 fOutFile << fIndention << element1 << std::endl
1462 << indention << element2 << std::endl
1463 << indention << element3 << std::endl;
1464
1465 // increase indention
1466 IncreaseIndention();
1467}
1468
1469//_____________________________________________________________________________
1471{
1472 // Closes output file
1473
1474 fOutFile.close();
1475}
1476
1477//_____________________________________________________________________________
1479{
1480 // Write document closing
1481
1482 fOutFile << "</gdml>" << std::endl;
1483}
1484
1485//_____________________________________________________________________________
1486void XmlVGM::GDMLWriter::CloseSection(const std::string& topVolume)
1487{
1488 // Write section closing
1489
1490 // Define element
1491 //
1492 std::string quota = "\"";
1493 std::string element2 = "<setup name=\"";
1494 element2.append(fUnitName);
1495 element2.append(quota);
1496
1497 std::string element3 = "version=\"";
1498 element3.append(fVersion);
1499 element3.append(quota);
1500
1501 std::string element4 = "<world ref=\"";
1502 element4.append(topVolume);
1503 element4.append(quota);
1504
1505 std::string element5 = "</setup>";
1506 std::string indention = fIndention + fkBasicIndention;
1507
1508 // Write element
1509 //
1510 fOutFile << fIndention << element2 << fkBasicIndention << element3 << ">"
1511 << std::endl
1512 << indention << element4 << "/>" << std::endl
1513 << fIndention << element5 << std::endl
1514 << std::endl;
1515}
1516
1517//_____________________________________________________________________________
1519{
1520 // Do not close the element.
1521 // Rotations will be written in the same element as positions.
1522}
1523
1524//_____________________________________________________________________________
1526{
1527 // Close element for general definitions
1528 // (positions and rotations for generated XML files.)
1529
1530 // decrease indention
1531 DecreaseIndention();
1532
1533 std::string element1 = "</define>";
1534
1535 // write element
1536 fOutFile << fIndention << element1 << std::endl;
1537}
1538
1539//_____________________________________________________________________________
1541{
1542 // Write materials closing
1543
1544 // decrease indention
1545 DecreaseIndention();
1546
1547 // define element
1548 std::string element = "</materials>";
1549
1550 // write element
1551 fOutFile << fIndention << element << std::endl;
1552}
1553
1554//_____________________________________________________________________________
1556{
1557 // Close element for solids
1558
1559 // decrease indention
1560 DecreaseIndention();
1561
1562 std::string element1 = "</solids>";
1563
1564 // write element
1565 fOutFile << fIndention << element1 << std::endl;
1566}
1567
1568//_____________________________________________________________________________
1570{
1571 // Close element for structure
1572
1573 // decrease indention
1574 DecreaseIndention();
1575
1576 std::string element = "</structure>";
1577
1578 // write element
1579 fOutFile << fIndention << element << std::endl;
1580}
1581
1582//_____________________________________________________________________________
1584{
1585 // Write composition closing
1586
1587 // decrease indention
1588 DecreaseIndention();
1589
1590 // define element
1591 std::string element = "</volume>";
1592
1593 // write element
1594 fOutFile << fIndention << element << std::endl;
1595}
1596
1597//_____________________________________________________________________________
1599{
1600 // Write VGM::IElement
1601
1602 std::string name = IsotopeName(isotope);
1603 name.append(fgkIsotopeNameExtension);
1604 RegisterName(name);
1605
1606 // Get parameters
1607 int theZ = isotope->Z();
1608 int theN = isotope->N();
1609 double theA = isotope->A() / AtomicWeightUnit();
1610
1611 // GDML does not allow N=0
1612 // Let's put =1 in this case
1613 if (theN == 0) theN = 1;
1614
1615 // Compose element string template
1616 std::string quota1 = "\"";
1617 std::string quota2 = "\" ";
1618 std::string element1 = "<isotope name=\"";
1619
1620 std::string element2 = "Z=\"";
1621 std::string element3 = "N=\"";
1622 std::string element4 = "<atom type=\"A\" unit=\"g/mol\" value=\"";
1623 std::string element5 = "\" />";
1624 std::string element6 = "</isotope>";
1625
1626 std::string indention = fIndention + fkBasicIndention;
1627
1628 // Write isotope
1629 fOutFile << fIndention << element1 << name << quota1;
1630 for (int i = 0; i < 10 - int(name.size()); i++) fOutFile << " ";
1631
1632 SmartPut(fOutFile, fNW - 2, fNP, 0, element2, theZ, quota2);
1633
1634 // SmartPut(fOutFile, fNW-2, fNP, element3, theN, "\" >");
1635 // fOutFile << std::endl;
1636 fOutFile << element3 << std::setw(3) << theN << "\" >" << std::endl;
1637
1638 fOutFile << indention;
1639 SmartPut(fOutFile, fNW - 2, fNP, 0, element4, theA, element5);
1640 fOutFile << std::endl;
1641
1642 fOutFile << fIndention << element6 << std::endl;
1643}
1644
1645//_____________________________________________________________________________
1647{
1648 // Write VGM::IElement
1649
1650 std::string name = UpdateName(element->Name(), fgkElementNameExtension);
1651 RegisterName(name);
1652
1653 // Compose element string template
1654 std::string quota1 = "\"";
1655 std::string quota2 = "\" ";
1656 std::string element1 = "<element name=\"";
1657 std::string element6 = "\" />";
1658 std::string element7 = "</element>";
1659
1660 std::string indention = fIndention + fkBasicIndention;
1661
1662 // Write element name
1663 fOutFile << fIndention << element1 << name << quota2;
1664
1665 // Get parameters
1666 if (element->NofIsotopes() > 0) {
1667
1668 std::string element2 = ">";
1669 std::string element3 = "<fraction n=\"";
1670 std::string element4 = "ref=\"";
1671
1672 fOutFile << element2 << std::endl;
1673 for (int i = 0; i < element->NofIsotopes(); i++) {
1674 VGM::IIsotope* isotope = element->Isotope(i);
1675 std::string name2 = IsotopeName(isotope);
1676 name2.append(fgkIsotopeNameExtension);
1677 double natoms = element->RelAbundance(i);
1678
1679 fOutFile << indention;
1680 SmartPut(fOutFile, fNW - 2, fNP, 0, element3, natoms, quota2);
1681 fOutFile << element4 << name2 << element6 << std::endl;
1682 }
1683 }
1684 else {
1685 double theZ = element->Z();
1686 int theN = (int)ClhepVGM::Round(element->N());
1687 double theA = element->A() / AtomicWeightUnit();
1688
1689 // GDML does not allow Z=0, N=0
1690 // Let's put =1 in this case
1691 if (theZ == 0) theZ = 1;
1692 if (theN == 0) theN = 1;
1693
1694 std::string element3 = "Z=\"";
1695 std::string element4 = "N=\"";
1696 std::string element5 = "<atom type=\"A\" unit=\"g/mol\" value=\"";
1697
1698 SmartPut(fOutFile, fNW - 2, fNP, 0, element3, theZ, quota2);
1699 // SmartPut(fOutFile, fNW-2, fNP, element3, theN, "\" >");
1700 // fOutFile << std::endl;
1701 fOutFile << element4 << std::setw(3) << theN << "\" >" << std::endl;
1702
1703 fOutFile << indention;
1704 SmartPut(fOutFile, fNW - 2, fNP, 0, element5, theA, element6);
1705 fOutFile << std::endl;
1706 }
1707
1708 fOutFile << fIndention << element7 << std::endl;
1709}
1710
1711//_____________________________________________________________________________
1713{
1714 // Write VGM::IMaterial
1715
1716 std::string materialName = UpdateName(material->Name());
1717 RegisterName(materialName);
1718
1719 // Get parameters
1720 double density = material->Density() / MassDensityUnit();
1721 std::string state;
1722 switch (material->State()) {
1723 case VGM::kSolid:
1724 state = "solid";
1725 break;
1726 case VGM::kLiquid:
1727 state = "liquid";
1728 break;
1729 case VGM::kGas:
1730 state = "gas";
1731 break;
1732 case VGM::kUndefined:
1733 default:
1734 state = "undefined";
1735 }
1736 double temperature = material->Temperature() / TemperatureUnit();
1737 double pressure = material->Pressure() / PressureUnit();
1738
1739 // Compose material string template
1740 std::string quota = "\" ";
1741 std::string element1 = "<material name=\"";
1742 element1.append(materialName);
1743 element1.append(quota);
1744
1745 std::string element2 = "state=\"";
1746 element2.append(state);
1747 element2.append(quota);
1748 element2.append(">");
1749
1750 std::string element3 = "<D type=\"density\" unit=\"g/cm3\" value=\"";
1751 std::string element4 = "<T type=\"temperature\" unit=\"K\" value=\"";
1752 std::string element5 = "<P type=\"pressure\" unit=\"pascal\" value=\"";
1753 std::string element6 = "<fraction n=\"";
1754 std::string element7 = "ref=\"";
1755 std::string element8 = "\"/>";
1756 std::string element9 = "</material>";
1757
1758 std::string indention = fIndention + fkBasicIndention;
1759
1760 // Write element
1761 fOutFile << fIndention << element1 << element2 << std::endl;
1762
1763 fOutFile << indention;
1764 SmartPut(fOutFile, fNW + 1, fNP, 0, element3, density, element8);
1765 fOutFile << std::endl;
1766
1767 if (temperature != fgkSTPTemperature) {
1768 fOutFile << indention;
1769 SmartPut(fOutFile, fNW + 1, fNP, 0, element4, temperature, element8);
1770 fOutFile << std::endl;
1771 }
1772
1773 if (pressure != fgkSTPPressure) {
1774 fOutFile << indention;
1775 SmartPut(fOutFile, fNW + 1, fNP, 0, element5, pressure, element8);
1776 fOutFile << std::endl;
1777 }
1778
1779 for (int i = 0; i < int(material->NofElements()); i++) {
1780 double fraction = material->MassFraction(i);
1781 std::string elementName =
1782 UpdateName(material->Element(i)->Name(), fgkElementNameExtension);
1783
1784 fOutFile << indention;
1785 SmartPut(fOutFile, fNW, fNP, 0, element6, fraction, quota);
1786 fOutFile << element7 << elementName << element8 << std::endl;
1787 }
1788
1789 fOutFile << fIndention << element9 << std::endl;
1790}
1791
1792//_____________________________________________________________________________
1793void XmlVGM::GDMLWriter::WriteSolid(std::string volumeName,
1794 const VGM::ISolid* solid, std::string /*materialName*/)
1795{
1796 // Finds solid concrete type and calls writing function.
1797 // For not yet implemented solids, only XML comment element is written.
1798
1799 std::string solidName = UpdateName(volumeName, fgkSolidNameExtension);
1800 RegisterName(solidName);
1801
1802 VGM::SolidType solidType = solid->Type();
1803 if (solidType == VGM::kArb8) {
1804 const VGM::IArb8* arb8 = dynamic_cast<const VGM::IArb8*>(solid);
1805 WriteArb8(solidName, arb8);
1806 return;
1807 }
1808 else if (solidType == VGM::kBox) {
1809 const VGM::IBox* box = dynamic_cast<const VGM::IBox*>(solid);
1810 WriteBox(solidName, box);
1811 return;
1812 }
1813 else if (solidType == VGM::kCons) {
1814 const VGM::ICons* cons = dynamic_cast<const VGM::ICons*>(solid);
1815 WriteCons(solidName, cons);
1816 return;
1817 }
1818 else if (solidType == VGM::kCtubs) {
1819 const VGM::ICtubs* ctubs = dynamic_cast<const VGM::ICtubs*>(solid);
1820 WriteCtubs(solidName, ctubs);
1821 return;
1822 }
1823 else if (solidType == VGM::kEllipsoid) {
1824 const VGM::IEllipsoid* ellipsoid =
1825 dynamic_cast<const VGM::IEllipsoid*>(solid);
1826 WriteEllipsoid(solidName, ellipsoid);
1827 return;
1828 }
1829 else if (solidType == VGM::kEltu) {
1830 const VGM::IEllipticalTube* eltu =
1831 dynamic_cast<const VGM::IEllipticalTube*>(solid);
1832 WriteEllipticalTube(solidName, eltu);
1833 return;
1834 }
1835 else if (solidType == VGM::kExtruded) {
1836 const VGM::IExtrudedSolid* extruded =
1837 dynamic_cast<const VGM::IExtrudedSolid*>(solid);
1838 WriteExtrudedSolid(solidName, extruded);
1839 return;
1840 }
1841 else if (solidType == VGM::kHype) {
1842 const VGM::IHype* hype = dynamic_cast<const VGM::IHype*>(solid);
1843 WriteHype(solidName, hype);
1844 return;
1845 }
1846 else if (solidType == VGM::kPara) {
1847 const VGM::IPara* para = dynamic_cast<const VGM::IPara*>(solid);
1848 WritePara(solidName, para);
1849 return;
1850 }
1851 else if (solidType == VGM::kParaboloid) {
1852 const VGM::IParaboloid* paraboloid =
1853 dynamic_cast<const VGM::IParaboloid*>(solid);
1854 WriteParaboloid(solidName, paraboloid);
1855 return;
1856 }
1857 else if (solidType == VGM::kPolycone) {
1858 const VGM::IPolycone* polycone = dynamic_cast<const VGM::IPolycone*>(solid);
1859 WritePolycone(solidName, polycone);
1860 return;
1861 }
1862 else if (solidType == VGM::kPolyhedra) {
1863 const VGM::IPolyhedra* polyhedra =
1864 dynamic_cast<const VGM::IPolyhedra*>(solid);
1865 WritePolyhedra(solidName, polyhedra);
1866 return;
1867 }
1868 else if (solidType == VGM::kSphere) {
1869 const VGM::ISphere* sphere = dynamic_cast<const VGM::ISphere*>(solid);
1870 WriteSphere(solidName, sphere);
1871 return;
1872 }
1873 else if (solidType == VGM::kTessellated) {
1874 const VGM::ITessellatedSolid* tessellated =
1875 dynamic_cast<const VGM::ITessellatedSolid*>(solid);
1876 WriteTessellatedSolid(solidName, tessellated);
1877 return;
1878 }
1879 else if (solidType == VGM::kTorus) {
1880 const VGM::ITorus* torus = dynamic_cast<const VGM::ITorus*>(solid);
1881 WriteTorus(solidName, torus);
1882 return;
1883 }
1884 else if (solidType == VGM::kTrap) {
1885 const VGM::ITrap* trap = dynamic_cast<const VGM::ITrap*>(solid);
1886 WriteTrap(solidName, trap);
1887 return;
1888 }
1889 else if (solidType == VGM::kTrd) {
1890 const VGM::ITrd* trd = dynamic_cast<const VGM::ITrd*>(solid);
1891 WriteTrd(solidName, trd);
1892 return;
1893 }
1894 else if (solidType == VGM::kTubs) {
1895 const VGM::ITubs* tubs = dynamic_cast<const VGM::ITubs*>(solid);
1896 WriteTubs(solidName, tubs);
1897 return;
1898 }
1899 else if (solidType == VGM::kBoolean) {
1900 const VGM::IBooleanSolid* boolean =
1901 dynamic_cast<const VGM::IBooleanSolid*>(solid);
1902 WriteBooleanSolid(solidName, boolean);
1903 return;
1904 }
1905 else if (solidType == VGM::kMultiUnion) {
1906 const VGM::IMultiUnion* multiUnion =
1907 dynamic_cast<const VGM::IMultiUnion*>(solid);
1908 WriteMultiUnion(solidName, multiUnion);
1909 return;
1910 }
1911
1912 // Not supported solid
1913 WriteNotSupportedSolid(solidName);
1914}
1915
1916//_____________________________________________________________________________
1918 const std::string& name, const VGM::Transform& transform)
1919{
1920 // Write position element with a given name
1921
1922 // get parameters
1923 double x = transform[VGM::kDx] / LengthUnit();
1924 double y = transform[VGM::kDy] / LengthUnit();
1925 double z = transform[VGM::kDz] / LengthUnit();
1926
1927 // compose element string template
1928 std::string quota1 = "\"";
1929 std::string quota2 = "\" ";
1930 std::string element1 = "<position name=";
1931 std::string posName = AppendName(quota1 + name + quota1, 12);
1932
1933 std::string element2 = "x=\"";
1934 std::string element3 = "y=\"";
1935 std::string element4 = "z=\"";
1936 std::string element5 = "\" unit=\"cm\" />";
1937
1938 // write element
1939 fOutFile << fIndention << element1 << posName;
1940
1941 SmartPut(fOutFile, fNW + 1, fNP, fgkCarTolerance, element2, x, quota2);
1942 SmartPut(fOutFile, fNW + 1, fNP, fgkCarTolerance, element3, y, quota2);
1943 SmartPut(fOutFile, fNW + 1, fNP, fgkCarTolerance, element4, z, "");
1944
1945 fOutFile << element5 << std::endl;
1946}
1947
1948//_____________________________________________________________________________
1950 const std::string& name, const VGM::Transform& transform)
1951{
1952 // Write rotation element with a given name
1953
1954 VGM::Transform invTransform = ClhepVGM::Inverse(transform);
1955
1956 // Get parameters
1957 double angleX = invTransform[VGM::kAngleX] / AngleUnit();
1958 double angleY = invTransform[VGM::kAngleY] / AngleUnit();
1959 double angleZ = invTransform[VGM::kAngleZ] / AngleUnit();
1960
1961 // Compose element string template
1962 std::string quota1 = "\"";
1963 std::string quota2 = "\" ";
1964 std::string element1 = "<rotation name=";
1965 std::string rotName = AppendName(quota1 + name + quota1, 12);
1966
1967 std::string element2 = "x=\"";
1968 std::string element3 = "y=\"";
1969 std::string element4 = "z=\"";
1970 std::string element5 = "\" unit=\"degree\" />";
1971
1972 // Write element
1973 fOutFile << fIndention << element1 << rotName;
1974
1975 SmartPut(fOutFile, fNW + 1, fNP, fgkAngTolerance, element2, angleX, quota2);
1976 SmartPut(fOutFile, fNW + 1, fNP, fgkAngTolerance, element3, angleY, quota2);
1977 SmartPut(fOutFile, fNW + 1, fNP, fgkAngTolerance, element4, angleZ, "");
1978
1979 fOutFile << element5 << std::endl;
1980}
1981
1982//_____________________________________________________________________________
1983void XmlVGM::GDMLWriter::WriteScale(const std::string& name)
1984{
1985 // Write scale element with a given name with reflectionZ
1986
1987 // Get parameters
1988 double scaleX = 1.0;
1989 double scaleY = 1.0;
1990 double scaleZ = -1.0;
1991
1992 // Compose element string template
1993 std::string quota1 = "\"";
1994 std::string quota2 = "\" ";
1995 std::string element1 = "<scale name=";
1996 std::string rotName = AppendName(quota1 + name + quota1, 12);
1997
1998 std::string element2 = "x=\"";
1999 std::string element3 = "y=\"";
2000 std::string element4 = "z=\"";
2001 std::string element5 = "\" />";
2002
2003 // Write element
2004 fOutFile << fIndention << element1 << rotName;
2005
2006 SmartPut(fOutFile, fNW + 1, fNP, 0, element2, scaleX, quota2);
2007 SmartPut(fOutFile, fNW + 1, fNP, 0, element3, scaleY, quota2);
2008 SmartPut(fOutFile, fNW + 1, fNP, 0, element4, scaleZ, "");
2009
2010 fOutFile << element5 << std::endl;
2011}
2012
2013//_____________________________________________________________________________
2015{
2016
2017 VGM::PlacementType placementType = placement.Type();
2018
2019 if (placementType == VGM::kSimplePlacement) {
2020
2021 // simple placement
2022 VGM::Transform transform = placement.Transformation();
2023
2024 // Get position
2025 std::string positionRef = fMaps->FindPositionName(transform);
2026
2027 // Get rotation
2028 std::string rotationRef = fMaps->FindRotationName(transform);
2029
2030 // If boolean solid that have to be reflected
2031 // set reflection to the transformation
2032 VGM::IBooleanSolid* booleanSolid =
2033 dynamic_cast<VGM::IBooleanSolid*>(placement.Volume()->Solid());
2034 if (booleanSolid && booleanSolid->ToBeReflected())
2035 transform[VGM::kReflZ] = 1;
2036
2037 // If paraboloid that have to be reflected,
2038 // set reflection to the transformation
2039 VGM::IParaboloid* paraboloid =
2040 dynamic_cast<VGM::IParaboloid*>(placement.Volume()->Solid());
2041 if (paraboloid && paraboloid->RadiusPlusZ() <= paraboloid->RadiusMinusZ())
2042 transform[VGM::kReflZ] = 1;
2043
2044 // Get info about reflection
2045 bool isReflection = ClhepVGM::HasReflection(transform);
2046
2047 WriteSimplePlacement(
2048 placement.Volume()->Name(), positionRef, rotationRef, isReflection);
2049 }
2050 else if (placementType == VGM::kMultiplePlacement) {
2051
2052 // get parameters
2053 VGM::Axis axis;
2054 int nReplicas;
2055 double width;
2056 double offset;
2057 double halfGap; // not supported
2058 placement.MultiplePlacementData(axis, nReplicas, width, offset, halfGap);
2059
2060 if (halfGap != 0.) {
2061 std::cerr << "+++ Warning +++" << std::endl;
2062 std::cerr << " XmlVGM::Writer::WritePlacement: " << std::endl;
2063 std::cerr << " Multiple placement with a half gap is not supported. "
2064 << std::endl;
2065 std::cerr << " The half gap parameter will be ignored. " << std::endl;
2066 }
2067
2068 // write multiple position
2069 WriteMultiplePlacement(
2070 placement.Volume()->Name(), axis, nReplicas, width, offset);
2071 }
2072 else if (placementType == VGM::kParameterised) {
2073
2074 // get parameters
2075 std::vector<VGM::Transform> transforms;
2076 std::vector<VGM::IVolume*> volumes;
2077 placement.ParameterisedPlacementData(transforms, volumes);
2078
2079
2080 for (size_t i=0; i<transforms.size(); ++i) {
2081
2082 auto transform = transforms[i];
2083
2084 // Get position & rotation
2085 std::string positionRef = fMaps->FindPositionName(transform);
2086 std::string rotationRef = fMaps->FindRotationName(transform);
2087
2088 bool isReflection = ClhepVGM::HasReflection(transform);
2089
2090 auto volumeName = volumes[i]->Name();
2091
2092 WriteSimplePlacement(
2093 volumeName, positionRef, rotationRef, isReflection);
2094 }
2095 }
2096 else {
2097 std::cerr << "+++ Warning +++" << std::endl;
2098 std::cerr << " XmlVGM::GDMLExporter::ProcessVolume: " << std::endl;
2099 std::cerr << " Unknown placement type. " << std::endl;
2100 std::cerr << " Volume \"" << placement.Name() << "\" was not converted."
2101 << std::endl;
2102 }
2103}
2104
2105//_____________________________________________________________________________
2107{
2108 // Write empty line.
2109
2110 fOutFile << std::endl;
2111}
2112
2113//_____________________________________________________________________________
2115{
2116 // Increase indention
2117
2118 fIndention.append(fkBasicIndention);
2119}
2120
2121//_____________________________________________________________________________
2123{
2124 // Decrease indention
2125
2126 fIndention.replace(fIndention.find(fkBasicIndention), 3, "");
2127}
VGM Axis enumeration.
The VGM interface to Arb8 solids.
Definition IArb8.h:31
virtual double ZHalfLength() const =0
Return the half-length along the z axis in mm.
virtual int NofVertices() const =0
Return the number of vertices.
virtual TwoVector Vertex(int index) const =0
Return the index-th vertex.
The VGM interface to Boolean solids.
virtual ISolid * ConstituentSolidB() const =0
Return the second constituent solid.
virtual bool ToBeReflected() const =0
Return true if the solid has to be first reflected before being placed.
virtual ISolid * ConstituentSolidA() const =0
Return the first constituent solid.
virtual BooleanType BoolType() const =0
Return the Boolean type of this solid.
virtual Transform Displacement() const =0
Return the 3D displacement of the second constituent solid with respect to the first one.
The VGM interface to box solids.
Definition IBox.h:30
virtual double ZHalfLength() const =0
Return the half-length along the z axis in mm.
virtual double YHalfLength() const =0
Return the half-length along the y axis in mm.
virtual double XHalfLength() const =0
Return the half-length along the x axis in mm.
The VGM interface to cons solids.
Definition ICons.h:30
virtual double DeltaPhi() const =0
Return the opening phi angle of the segment in deg.
virtual double OuterRadiusPlusZ() const =0
Return the outer radius at -z in mm.
virtual double OuterRadiusMinusZ() const =0
Return the outer radius at -z in mm.
virtual double ZHalfLength() const =0
Return the half-length along the z axis in mm.
virtual double InnerRadiusMinusZ() const =0
Return the innner radius at -z in mm.
virtual double InnerRadiusPlusZ() const =0
Return the innner radius at +z in mm.
virtual double StartPhi() const =0
Return the starting phi angle of the segment in deg.
The VGM interface to cut tubs solids.
Definition ICtubs.h:30
virtual double OuterRadius() const =0
Return the outside radius in mm.
virtual double NxHigh() const =0
X-component of the normal unit vector to the cut plane in +z.
virtual double ZHalfLength() const =0
Return the half-length along the z axis in m.
virtual double DeltaPhi() const =0
Return the opening angle of the segment in deg.
virtual double NyLow() const =0
Y-component of the normal unit vector to the cut plane in -z.
virtual double NzLow() const =0
Z-component of the normal unit vector to the cut plane in -z.
virtual double NzHigh() const =0
Z-component of the normal unit vector to the cut plane in +z.
virtual double InnerRadius() const =0
Return the inside radius in mm.
virtual double StartPhi() const =0
Return the starting angle of the segment in deg.
virtual double NxLow() const =0
X-component of the normal unit vector to the cut plane in -z.
virtual double NyHigh() const =0
Y-component of the normal unit vector to the cut plane in +z.
The VGM interface to elements.
Definition IElement.h:34
virtual IIsotope * Isotope(int i) const =0
Return the i-th isotope constituing this element.
virtual int NofIsotopes() const =0
Return the number of isotopes constituing this element.
virtual double Z() const =0
Return the effective atomic number.
virtual double RelAbundance(int i) const =0
Return the relative abundance (the fraction of nb of atomes per volume) of the i-th isotope constitui...
virtual std::string Name() const =0
Return the name of this element.
virtual double A() const =0
Return the effective effective mass of a mole in g/mole.
virtual double N() const =0
Return the effective number of nucleons.
The VGM interface to ellipsoid solids.
Definition IEllipsoid.h:30
virtual double ZBottomCut() const =0
Return the z bottom cut in mm.
virtual double ZSemiAxis() const =0
Return the semi-axis of the ellipse along z in mm.
virtual double ZTopCut() const =0
Return the z top cut in mm.
virtual double XSemiAxis() const =0
Return the semi-axis of the ellipse along x in mm.
virtual double YSemiAxis() const =0
Return the semi-axis of the ellipse along y in mm.
The VGM interface to elliptical tube solids.
virtual double Dx() const =0
Return the semi-axis of the ellipse along x in mm.
virtual double ZHalfLength() const =0
Return the half-length along the z axis in mm.
virtual double Dy() const =0
Return the semi-axis of the ellipse along y in mm.
The VGM interface to extruded solids.
virtual TwoVector Offset(int iz) const =0
Return the polygon offset in iz-th side.
virtual int NofZSections() const =0
Return the number of planes perpendicular to the z axis.
virtual double ZPosition(int iz) const =0
Return the z position of the iz-th plane in mm.
virtual int NofVertices() const =0
Return the number of vertices of outline polygon.
virtual TwoVector Vertex(int index) const =0
Return the index-th vertex of outline polygon.
virtual double Scale(int iz) const =0
Return the polygon scale in iz-th side.
The VGM interface to hyperboloid solids.
Definition IHype.h:30
virtual double ZHalfLength() const =0
Return the half-length along the z axis in mm.
virtual double OuterStereoAngle() const =0
Return the inner stereo angle.
virtual double OuterRadius() const =0
Return the outer radius in mm.
virtual double InnerStereoAngle() const =0
Return the inner stereo angle.
virtual double InnerRadius() const =0
Return the inner radius in mm.
The VGM interface to elements.
Definition IIsotope.h:28
virtual int N() const =0
Return the effective number of nucleons.
virtual double A() const =0
Return the effective effective mass of a mole in g/mole.
virtual int Z() const =0
Return the effective atomic number.
The VGM interface to materials.
Definition IMaterial.h:44
virtual double Pressure() const =0
Return the density in atmosphere.
virtual IElement * Element(int iel) const =0
Return the i-th element constituing this material.
virtual double Density() const =0
Return the density in g/cm3.
virtual double Temperature() const =0
Return the temperature in kelvins.
virtual std::string Name() const =0
Return the name of this element.
virtual MaterialState State() const =0
Return the material state.
virtual double MassFraction(int iel) const =0
Return the mass fraction of the i-th element constituing this material.
virtual int NofElements() const =0
Return the number of elements constituing this material.
The VGM interface to Boolean solids.
Definition IMultiUnion.h:31
virtual Transform Transformation(int index) const =0
Return the displacement of the ith constituent solid.
virtual int NofSolids() const =0
Return the number of constituent solids.
virtual ISolid * ConstituentSolid(int index) const =0
Return the i-th constituent solid.
The VGM interface to para solids.
Definition IPara.h:30
virtual double Alpha() const =0
Return angle formed by the y axis and by the plane joining the centre of the faces parallel to the z-...
virtual double Theta() const =0
Return polar angle of the line joining the centres of the faces at -hz and +hz in deg.
virtual double YHalfLength() const =0
Return half-length along the y axis in mm.
virtual double ZHalfLength() const =0
Return half-length along the z axis in mm.
virtual double XHalfLength() const =0
Return half-length along the x axis in mm.
virtual double Phi() const =0
Return azimuthal angle of the line joining the centres of the faces at -hz and +hz in deg.
The VGM interface to paraboloid solids.
Definition IParaboloid.h:30
virtual double RadiusMinusZ() const =0
Return the radius at -z in mm.
virtual double RadiusPlusZ() const =0
Return the radius at +z in mm.
virtual double ZHalfLength() const =0
Return the half-length along the z axis in mm.
The VGM interface to positions of volumes.
Definition IPlacement.h:44
virtual PlacementType Type() const =0
Return the type of this placement.
virtual Transform Transformation() const =0
Return the 3D transformation (if simple placement)
virtual bool MultiplePlacementData(VGM::Axis &axis, int &nofItems, double &width, double &offset, double &halfGap) const =0
Fill the multiple placement data if relevant and return true; return false if not multiple placement.
virtual bool ParameterisedPlacementData(std::vector< VGM::Transform > &transforms, std::vector< VGM::IVolume * > &volumes) const =0
Fill the parameterised placement data if relevant and return true; return false if not parameterised ...
virtual std::string Name() const =0
Return the name of this placement.
virtual IVolume * Volume() const =0
Return the associated volume.
The VGM interface to polycone solids.
Definition IPolycone.h:30
virtual double StartPhi() const =0
Return starting phi angle of the segment in deg.
virtual int NofZPlanes() const =0
Return number of planes perpendicular to the z axis.
virtual double * ZValues() const =0
Return the array of z positions of the planes in mm.
virtual double DeltaPhi() const =0
Return opening phi angle of the segment in deg.
virtual double * InnerRadiusValues() const =0
Return the array of inner radius of the planes in mm.
virtual double * OuterRadiusValues() const =0
Return the array of outer radius of the planes in mm.
The VGM interface to polyhedra solids.
Definition IPolyhedra.h:30
virtual double * OuterRadiusValues() const =0
Return the array of outer radius of the planes in mm.
virtual int NofSides() const =0
Return number of sides of the cross section between the given phi limits.
virtual double StartPhi() const =0
Return starting phi angle of the segment in deg.
virtual double * InnerRadiusValues() const =0
Return the array of innner radius of the planes in mm.
virtual double * ZValues() const =0
Return the array of z positions of the planes in mm.
virtual double DeltaPhi() const =0
Return opening phi angle of the segment in deg.
virtual int NofZPlanes() const =0
Return number of planes perpendicular to the z axis.
The VGM interface to solids.
Definition ISolid.h:58
virtual SolidType Type() const =0
Return the type of this solid.
virtual std::string Name() const =0
Return the name of this solid.
The VGM interface to sphere solids.
Definition ISphere.h:30
virtual double StartPhi() const =0
Return the starting azimuthal angle of the segment in deg.
virtual double DeltaPhi() const =0
Return the opening azimuthal angle of the segment in deg.
virtual double StartTheta() const =0
Return the starting polar angle of the segment in deg.
virtual double DeltaTheta() const =0
Return the opening polar angle of the segment in deg.
virtual double OuterRadius() const =0
Return the outside radius of the shell in mm.
virtual double InnerRadius() const =0
Return the inside radius of the shell in mm.
The VGM interface to extruded solids.
virtual int NofVertices(int ifacet) const =0
Return the number of vertices in the the ifacet-th facet.
virtual ThreeVector Vertex(int ifacet, int index) const =0
Return the index-th vertex in the ifacet-th facet.
virtual int NofFacets() const =0
Return the number of facets.
The VGM interface to torus solids.
Definition ITorus.h:30
virtual double OuterRadius() const =0
Return the outside radius of the torus in mm.
virtual double StartPhi() const =0
Return the starting phi angle of the segment in deg (with 0 being the +x axis)
virtual double AxialRadius() const =0
Return the axial (swept) radius of the torus in mm.
virtual double DeltaPhi() const =0
Return the opening phi angle of the segment in deg.
virtual double InnerRadius() const =0
Return the inside radius of the torus in mm.
The VGM interface to trap solids.
Definition ITrap.h:30
virtual double Phi() const =0
Return the azimuthal angle of the line joining the centres of the faces at -hz and +hz in deg.
virtual double XHalfLengthPlusZMinusY() const =0
Return the half-length along x of the side at -hy of the face at +hz in m.
virtual double AlphaPlusZ() const =0
Return the angle with respect to the y axis from the centre of the side at -hy to the centre at +hy o...
virtual double ZHalfLength() const =0
Return the half-length along the z axis in mm.
virtual double YHalfLengthMinusZ() const =0
Return the half-length along y of the face at -hz in mm.
virtual double XHalfLengthMinusZMinusY() const =0
Return the half-length along x of the side at -hy of the face at -hz in mm.
virtual double YHalfLengthPlusZ() const =0
Return the half-length along y of the face at +hz in m.
virtual double XHalfLengthPlusZPlusY() const =0
Return the half-length along x of the side at +hy of the face at +hz in m.
virtual double Theta() const =0
Return the polar angle of the line joining the centres of the faces at -hz and +hz in deg.
virtual double AlphaMinusZ() const =0
Return the angle with respect to the y axis from the centre of the side at -hy to the centre at +hy o...
virtual double XHalfLengthMinusZPlusY() const =0
Return the half-length along x of the side at +hy of the face at +hz in mm.
The VGM interface to trd solids.
Definition ITrd.h:30
virtual double XHalfLengthPlusZ() const =0
Return the half-length along x at the surface positioned at +hz in mm.
virtual double YHalfLengthPlusZ() const =0
Return thehalf-length along y at the surface positioned at +hz in mm.
virtual double XHalfLengthMinusZ() const =0
Return the half-length along x at the surface positioned at -hz in mm.
virtual double ZHalfLength() const =0
Return the half-length along the z axis in mm.
virtual double YHalfLengthMinusZ() const =0
Return the half-length along y at the surface positioned at -hz in mm.
The VGM interface to tubs solids.
Definition ITubs.h:30
virtual double ZHalfLength() const =0
Return the half-length along the z axis in m.
virtual double StartPhi() const =0
Return the starting angle of the segment in deg.
virtual double DeltaPhi() const =0
Return the opening angle of the segment in deg.
virtual double InnerRadius() const =0
Return the inside radius in mm.
virtual double OuterRadius() const =0
Return the outside radius in mm.
virtual ISolid * Solid() const =0
Return the associated solid.
virtual std::string Name() const =0
Return the name of this volume.
The implementation of the interface for the XML writer that writes VGM geometry objects to XML define...
Definition GDMLWriter.h:64
virtual void CloseMaterials()
Write materials definitions closing.
virtual void WriteRotation(const std::string &name, const VGM::Transform &transform)
Write rotation (from VGM transformation)
virtual void CloseStructure()
Write structure definition closing (if present)
virtual void OpenSolids()
Write solids definitions opening.
virtual void OpenPositions()
Write positions definitions opening.
virtual void WriteEmptyLine()
Write empty line.
virtual void CloseSolids()
Write materials definitions closing.
virtual void CloseFile()
Close output file.
virtual void OpenStructure()
Write structure definition opening (if present)
GDMLWriter(const std::string &unitName="unit1", const std::string &version="1.0")
virtual void WriteMaterial(const VGM::IMaterial *material)
Write VGM material.
virtual void WritePosition(const std::string &name, const VGM::Transform &transform)
Write position (from VGM transformation)
virtual void OpenMaterials()
Write materials definitions opening.
virtual void OpenComposition(const std::string &name, const std::string &materialName)
Write composition definition opening (if present)
virtual void IncreaseIndention()
Increase indention.
virtual void OpenRotations()
Write rotations definitions opening.
virtual void WritePlacement(const VGM::IPlacement &placement)
Write VGM placement.
virtual void DecreaseIndention()
Decrease indention.
virtual void CloseComposition()
Write composition definition closing (if present)
virtual void OpenSection(const std::string &topVolume)
Write the section opening (if present)
virtual void ClosePositions()
Write positions definitions closing.
virtual void OpenFile(std::string filePath)
Open output file.
virtual void WriteSolid(std::string lvName, const VGM::ISolid *solid, std::string)
Write VGM solid.
virtual void WriteScale(const std::string &name)
Write scale (from VGM transformation)
virtual void CloseDocument()
Write XML document closing.
virtual void OpenDocument()
Write XML document opening.
virtual void WriteElement(const VGM::IElement *element)
Write VGM element.
virtual void CloseSection(const std::string &topVolume)
Write the section closing (if present)
virtual void CloseRotations()
Write rotations definitions closing.
virtual void WriteIsotope(const VGM::IIsotope *isotope)
Write VGM isotope.
The interface for the XML writer that writes VGM geometry objects to XML:
Definition IWriter.h:43
double Round(double x)
bool HasReflection(const HepGeom::Transform3D &transform)
VGM::Transform Inverse(const VGM::Transform &transform)
std::vector< double > Transform
Definition Transform.h:40
std::pair< double, double > TwoVector
Definition TwoVector.h:28
@ kUnknownBoolean
@ kIntersection
@ kSubtraction
std::vector< double > ThreeVector
Definition ThreeVector.h:27
@ kRho
Definition Axis.h:38
@ kPhi
Definition Axis.h:40
@ kYAxis
Definition Axis.h:36
@ kRadial3D
Definition Axis.h:39
@ kXAxis
Definition Axis.h:35
@ kUnknownAxis
Definition Axis.h:42
@ kZAxis
Definition Axis.h:37
@ kSphTheta
Definition Axis.h:41
@ kAngleZ
Definition Transform.h:49
@ kDx
Definition Transform.h:44
@ kReflZ
Definition Transform.h:50
@ kAngleY
Definition Transform.h:48
@ kDz
Definition Transform.h:46
@ kAngleX
Definition Transform.h:47
@ kDy
Definition Transform.h:45
PlacementType
Definition IPlacement.h:32
@ kParameterised
Definition IPlacement.h:35
@ kSimplePlacement
Definition IPlacement.h:33
@ kMultiplePlacement
Definition IPlacement.h:34
SolidType
Definition ISolid.h:29
@ kTessellated
Definition ISolid.h:43
@ kEllipsoid
Definition ISolid.h:34
@ kTorus
Definition ISolid.h:44
@ kTrd
Definition ISolid.h:46
@ kCons
Definition ISolid.h:32
@ kTubs
Definition ISolid.h:47
@ kExtruded
Definition ISolid.h:36
@ kPara
Definition ISolid.h:38
@ kSphere
Definition ISolid.h:42
@ kPolycone
Definition ISolid.h:40
@ kTrap
Definition ISolid.h:45
@ kMultiUnion
Definition ISolid.h:50
@ kPolyhedra
Definition ISolid.h:41
@ kEltu
Definition ISolid.h:35
@ kParaboloid
Definition ISolid.h:39
@ kHype
Definition ISolid.h:37
@ kBoolean
Definition ISolid.h:48
@ kArb8
Definition ISolid.h:30
@ kCtubs
Definition ISolid.h:33
@ kBox
Definition ISolid.h:31
@ kGas
Gas materila.
Definition IMaterial.h:40
@ kLiquid
Liquid material.
Definition IMaterial.h:39
@ kSolid
Solid material.
Definition IMaterial.h:38
@ kUndefined
Undefined material state.
Definition IMaterial.h:37
std::string IsotopeName(const VGM::IIsotope *isotope)
Definition utilities.cxx:86
std::string AppendName(const std::string &name, int size)
Definition utilities.cxx:71
std::string StripName(const std::string &name, const std::string &extension="")
Definition utilities.cxx:62
std::ostream & SmartPut(std::ostream &out, int size, int precision, double tolerance, double number, const std::string &separator)
std::string UpdateName(const std::string &name, const std::string &extension="")
Definition utilities.cxx:31