VGM Version 5.4
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& name,
1201 const std::string& volumeName,
1202 const std::string& positionRef, const std::string& rotationRef,
1203 bool isReflection, int copyNo)
1204{
1206
1207 // Update name
1208 std::string newVolumeName = UpdateName(volumeName);
1209
1210 // Compose element strings
1211 //
1212 std::string element0 = "\"/>";
1213 std::string element1 = "<physvol copynumber=\"";
1214 std::string element1b = "\" name=\"";
1215 element1b.append(name);
1216 element1b.append("\">");
1217
1218 std::string element2 = "<volumeref ref=\"";
1219 element2.append(newVolumeName);
1220 element2.append(element0);
1221
1222 std::string element3 = "<positionref ref=\"";
1223 element3.append(positionRef);
1224 element3.append(element0);
1225
1226 std::string element4 = "<rotationref ref=\"";
1227 element4.append(rotationRef);
1228 element4.append(element0);
1229
1230 std::string element5 = "<scaleref ref=\"";
1231 element5.append(std::string("scale_0"));
1232 element5.append(element0);
1233
1234 std::string element6 = "</physvol>";
1235
1236 std::string indention1 = fIndention + fkBasicIndention;
1237 std::string indention2 = fIndention + fkBasicIndention + fkBasicIndention;
1238
1239 // Write element
1240 fOutFile << fIndention << element1 << copyNo << element1b << std::endl
1241 << indention1 << element2 << std::endl
1242 << indention2 << element3 << std::endl
1243 << indention2 << element4 << std::endl;
1244
1245 if (isReflection) fOutFile << indention2 << element5 << std::endl;
1246
1247 fOutFile << fIndention << element6 << std::endl;
1248}
1249
1250//_____________________________________________________________________________
1251void XmlVGM::GDMLWriter::WriteMultiplePlacement(const std::string& name,
1252 const std::string& volumeName,
1253 VGM::Axis axis, int nofReplicas, double width, double offset)
1254{
1256
1257 std::string axisName;
1258 switch (axis) {
1259 case VGM::kXAxis:
1260 axisName = "kXAxis";
1261 break;
1262 case VGM::kYAxis:
1263 axisName = "kYAxis";
1264 break;
1265 case VGM::kZAxis:
1266 axisName = "kZAxis";
1267 break;
1268 case VGM::kRho:
1269 axisName = "kRho";
1270 break;
1271 case VGM::kPhi:
1272 axisName = "kPhi";
1273 break;
1274 case VGM::kRadial3D:
1275 axisName = "Undefined";
1276 break; // ADD WARNING HERE
1277 case VGM::kSphTheta:
1278 axisName = "Undefined";
1279 break;
1280 case VGM::kUnknownAxis:
1281 axisName = "Undefined";
1282 break;
1283 }
1284
1285 // set units
1286 double width2;
1287 double offset2;
1288 std::string unit;
1289 if (axis != VGM::kPhi && axis != VGM::kSphTheta) {
1290 width2 = width / LengthUnit();
1291 offset2 = offset / LengthUnit();
1292 unit = "cm";
1293 }
1294 else {
1295 width2 = width / AngleUnit();
1296 offset2 = offset / AngleUnit();
1297 unit = "degree";
1298 }
1299
1300 // Update name
1301 std::string newVolumeName = UpdateName(volumeName);
1302
1303 // Compose element strings
1304 //
1305 // compose element string template
1306 std::string quota = "\"";
1307 std::string element1 = "<divisionvol name=\"";
1308 element1.append(name);
1309 element1.append("\" unit=\"");
1310 std::string element2 = "axis=\"";
1311 std::string element3 = "number=\"";
1312 std::string element4 = "offset=\"";
1313 std::string element5 = "width=\"";
1314 std::string element6 = "\">";
1315
1316 std::string element7 = "<volumeref ref=\"";
1317 std::string element8 = "\"/>";
1318 std::string element9 = "</divisionvol>";
1319
1320 std::string indention1 = fIndention + fkBasicIndention;
1321
1322 // write element
1323 fOutFile << fIndention << element1 << unit << quota << std::endl
1324 << indention1 << element2 << axisName + quota << " " << element3
1325 << nofReplicas << quota << " " << element4 << std::setw(fNW + 1)
1326 << std::setprecision(fNP) << offset2 << quota << " " << element5
1327 << std::setw(fNW + 1) << std::setprecision(fNP) << width2 << element6
1328 << std::endl
1329 << indention1 << element7 << newVolumeName << element8 << std::endl
1330 << fIndention << element9 << std::endl;
1331}
1332
1333//
1334// public methods
1335//
1336
1337//_____________________________________________________________________________
1338void XmlVGM::GDMLWriter::OpenFile(std::string filePath)
1339{
1340 // Opens output file
1341
1342 fOutFile.open(filePath.data(), std::ios::out);
1343
1344 if (!fOutFile) {
1345 std::cerr << " Cannot open " << filePath << std::endl;
1346 std::cerr << "** Exception: Aborting execution **" << std::endl;
1347 exit(1);
1348 }
1349
1350 // use FORTRAN compatibility output
1351 fOutFile.setf(std::ios::fixed, std::ios::floatfield);
1352}
1353
1354//_____________________________________________________________________________
1356{
1357 // Write document opening;
1358 // Could be made customizable in future
1359
1360 fOutFile << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" \?>"
1361 << std::endl
1362 << "<gdml xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
1363 "xsi:noNamespaceSchemaLocation=\""
1364 << std::endl
1365 << "http://service-spi.web.cern.ch/service-spi/app/releases/GDML/"
1366 "schema/gdml.xsd\">"
1367 << std::endl;
1368}
1369
1370//_____________________________________________________________________________
1371void XmlVGM::GDMLWriter::OpenSection(const std::string& /*topVolume*/)
1372{
1373 // Write section opening
1374
1375 // nothing to be done in GDML
1376}
1377
1378//_____________________________________________________________________________
1380{
1381 // Open element for general definitions
1382 // (positions and rotations for generated XML files.)
1383
1384 std::string element1 = "<define>";
1385
1386 // write element
1387 fOutFile << fIndention << element1 << std::endl;
1388
1389 // increase indention
1391}
1392
1393//_____________________________________________________________________________
1395{
1396 // Rotations are written in the same element as positions.
1397 // The element is already open.
1398}
1399
1400//_____________________________________________________________________________
1402{
1403 // Write materials opening
1404
1405 std::string element = "<materials>";
1406
1407 // write element
1408 fOutFile << fIndention << element << std::endl;
1409
1410 // increase indention
1412}
1413
1414//_____________________________________________________________________________
1416{
1417 // Write solids opening
1418
1419 std::string element = "<solids>";
1420
1421 // write element
1422 fOutFile << fIndention << element << std::endl;
1423
1424 // increase indention
1426}
1427
1428//_____________________________________________________________________________
1430{
1431 // Write structure opening.
1432
1433 std::string element = "<structure>";
1434
1435 // Write element
1436 fOutFile << fIndention << element << std::endl;
1437
1438 // increase indention
1440}
1441
1442//_____________________________________________________________________________
1444 const std::string& name, const std::string& materialName)
1445{
1446 // Write composition opening.
1447
1448 // Update names
1449 std::string volName = UpdateName(name);
1450 std::string matName = UpdateName(materialName);
1451 std::string sldName = UpdateName(name, fgkSolidNameExtension);
1452
1453 // Register volume name
1454 RegisterName(volName);
1455
1456 std::string element1 = "<volume name=\"";
1457 element1.append(volName);
1458 element1.append("\">");
1459
1460 std::string element2 = "<materialref ref=\"";
1461 element2.append(matName);
1462 element2.append("\"/>");
1463
1464 std::string element3 = "<solidref ref=\"";
1465 element3.append(sldName);
1466 element3.append("\"/>");
1467
1468 std::string indention = fIndention + fkBasicIndention;
1469
1470 // write element
1471 fOutFile << fIndention << element1 << std::endl
1472 << indention << element2 << std::endl
1473 << indention << element3 << std::endl;
1474
1475 // increase indention
1477}
1478
1479//_____________________________________________________________________________
1481{
1482 // Closes output file
1483
1484 fOutFile.close();
1485}
1486
1487//_____________________________________________________________________________
1489{
1490 // Write document closing
1491
1492 fOutFile << "</gdml>" << std::endl;
1493}
1494
1495//_____________________________________________________________________________
1496void XmlVGM::GDMLWriter::CloseSection(const std::string& topVolume)
1497{
1498 // Write section closing
1499
1500 // Define element
1501 //
1502 std::string quota = "\"";
1503 std::string element2 = "<setup name=\"";
1504 element2.append(fUnitName);
1505 element2.append(quota);
1506
1507 std::string element3 = "version=\"";
1508 element3.append(fVersion);
1509 element3.append(quota);
1510
1511 std::string element4 = "<world ref=\"";
1512 element4.append(topVolume);
1513 element4.append(quota);
1514
1515 std::string element5 = "</setup>";
1516 std::string indention = fIndention + fkBasicIndention;
1517
1518 // Write element
1519 //
1520 fOutFile << fIndention << element2 << fkBasicIndention << element3 << ">"
1521 << std::endl
1522 << indention << element4 << "/>" << std::endl
1523 << fIndention << element5 << std::endl
1524 << std::endl;
1525}
1526
1527//_____________________________________________________________________________
1529{
1530 // Do not close the element.
1531 // Rotations will be written in the same element as positions.
1532}
1533
1534//_____________________________________________________________________________
1536{
1537 // Close element for general definitions
1538 // (positions and rotations for generated XML files.)
1539
1540 // decrease indention
1542
1543 std::string element1 = "</define>";
1544
1545 // write element
1546 fOutFile << fIndention << element1 << std::endl;
1547}
1548
1549//_____________________________________________________________________________
1551{
1552 // Write materials closing
1553
1554 // decrease indention
1556
1557 // define element
1558 std::string element = "</materials>";
1559
1560 // write element
1561 fOutFile << fIndention << element << std::endl;
1562}
1563
1564//_____________________________________________________________________________
1566{
1567 // Close element for solids
1568
1569 // decrease indention
1571
1572 std::string element1 = "</solids>";
1573
1574 // write element
1575 fOutFile << fIndention << element1 << std::endl;
1576}
1577
1578//_____________________________________________________________________________
1580{
1581 // Close element for structure
1582
1583 // decrease indention
1585
1586 std::string element = "</structure>";
1587
1588 // write element
1589 fOutFile << fIndention << element << std::endl;
1590}
1591
1592//_____________________________________________________________________________
1594{
1595 // Write composition closing
1596
1597 // decrease indention
1599
1600 // define element
1601 std::string element = "</volume>";
1602
1603 // write element
1604 fOutFile << fIndention << element << std::endl;
1605}
1606
1607//_____________________________________________________________________________
1609{
1610 // Write VGM::IElement
1611
1612 std::string name = IsotopeName(isotope);
1613 name.append(fgkIsotopeNameExtension);
1614 RegisterName(name);
1615
1616 // Get parameters
1617 int theZ = isotope->Z();
1618 int theN = isotope->N();
1619 double theA = isotope->A() / AtomicWeightUnit();
1620
1621 // GDML does not allow N=0
1622 // Let's put =1 in this case
1623 if (theN == 0) theN = 1;
1624
1625 // Compose element string template
1626 std::string quota1 = "\"";
1627 std::string quota2 = "\" ";
1628 std::string element1 = "<isotope name=\"";
1629
1630 std::string element2 = "Z=\"";
1631 std::string element3 = "N=\"";
1632 std::string element4 = "<atom type=\"A\" unit=\"g/mol\" value=\"";
1633 std::string element5 = "\" />";
1634 std::string element6 = "</isotope>";
1635
1636 std::string indention = fIndention + fkBasicIndention;
1637
1638 // Write isotope
1639 fOutFile << fIndention << element1 << name << quota1;
1640 for (int i = 0; i < 10 - int(name.size()); i++) fOutFile << " ";
1641
1642 SmartPut(fOutFile, fNW - 2, fNP, 0, element2, theZ, quota2);
1643
1644 // SmartPut(fOutFile, fNW-2, fNP, element3, theN, "\" >");
1645 // fOutFile << std::endl;
1646 fOutFile << element3 << std::setw(3) << theN << "\" >" << std::endl;
1647
1648 fOutFile << indention;
1649 SmartPut(fOutFile, fNW - 2, fNP, 0, element4, theA, element5);
1650 fOutFile << std::endl;
1651
1652 fOutFile << fIndention << element6 << std::endl;
1653}
1654
1655//_____________________________________________________________________________
1657{
1658 // Write VGM::IElement
1659
1660 std::string name = UpdateName(element->Name(), fgkElementNameExtension);
1661 RegisterName(name);
1662
1663 // Compose element string template
1664 std::string quota1 = "\"";
1665 std::string quota2 = "\" ";
1666 std::string element1 = "<element name=\"";
1667 std::string element6 = "\" />";
1668 std::string element7 = "</element>";
1669
1670 std::string indention = fIndention + fkBasicIndention;
1671
1672 // Write element name
1673 fOutFile << fIndention << element1 << name << quota2;
1674
1675 // Get parameters
1676 if (element->NofIsotopes() > 0) {
1677
1678 std::string element2 = ">";
1679 std::string element3 = "<fraction n=\"";
1680 std::string element4 = "ref=\"";
1681
1682 fOutFile << element2 << std::endl;
1683 for (int i = 0; i < element->NofIsotopes(); i++) {
1684 VGM::IIsotope* isotope = element->Isotope(i);
1685 std::string name2 = IsotopeName(isotope);
1686 name2.append(fgkIsotopeNameExtension);
1687 double natoms = element->RelAbundance(i);
1688
1689 fOutFile << indention;
1690 SmartPut(fOutFile, fNW - 2, fNP, 0, element3, natoms, quota2);
1691 fOutFile << element4 << name2 << element6 << std::endl;
1692 }
1693 }
1694 else {
1695 double theZ = element->Z();
1696 int theN = (int)ClhepVGM::Round(element->N());
1697 double theA = element->A() / AtomicWeightUnit();
1698
1699 // GDML does not allow Z=0, N=0
1700 // Let's put =1 in this case
1701 if (theZ == 0) theZ = 1;
1702 if (theN == 0) theN = 1;
1703
1704 std::string element3 = "Z=\"";
1705 std::string element4 = "N=\"";
1706 std::string element5 = "<atom type=\"A\" unit=\"g/mol\" value=\"";
1707
1708 SmartPut(fOutFile, fNW - 2, fNP, 0, element3, theZ, quota2);
1709 // SmartPut(fOutFile, fNW-2, fNP, element3, theN, "\" >");
1710 // fOutFile << std::endl;
1711 fOutFile << element4 << std::setw(3) << theN << "\" >" << std::endl;
1712
1713 fOutFile << indention;
1714 SmartPut(fOutFile, fNW - 2, fNP, 0, element5, theA, element6);
1715 fOutFile << std::endl;
1716 }
1717
1718 fOutFile << fIndention << element7 << std::endl;
1719}
1720
1721//_____________________________________________________________________________
1723{
1724 // Write VGM::IMaterial
1725
1726 std::string materialName = UpdateName(material->Name());
1727 RegisterName(materialName);
1728
1729 // Get parameters
1730 double density = material->Density() / MassDensityUnit();
1731 std::string state;
1732 switch (material->State()) {
1733 case VGM::kSolid:
1734 state = "solid";
1735 break;
1736 case VGM::kLiquid:
1737 state = "liquid";
1738 break;
1739 case VGM::kGas:
1740 state = "gas";
1741 break;
1742 case VGM::kUndefined:
1743 default:
1744 state = "undefined";
1745 }
1746 double temperature = material->Temperature() / TemperatureUnit();
1747 double pressure = material->Pressure() / PressureUnit();
1748
1749 // Compose material string template
1750 std::string quota = "\" ";
1751 std::string element1 = "<material name=\"";
1752 element1.append(materialName);
1753 element1.append(quota);
1754
1755 std::string element2 = "state=\"";
1756 element2.append(state);
1757 element2.append(quota);
1758 element2.append(">");
1759
1760 std::string element3 = "<D type=\"density\" unit=\"g/cm3\" value=\"";
1761 std::string element4 = "<T type=\"temperature\" unit=\"K\" value=\"";
1762 std::string element5 = "<P type=\"pressure\" unit=\"pascal\" value=\"";
1763 std::string element6 = "<fraction n=\"";
1764 std::string element7 = "ref=\"";
1765 std::string element8 = "\"/>";
1766 std::string element9 = "</material>";
1767
1768 std::string indention = fIndention + fkBasicIndention;
1769
1770 // Write element
1771 fOutFile << fIndention << element1 << element2 << std::endl;
1772
1773 fOutFile << indention;
1774 SmartPut(fOutFile, fNW + 1, fNP, 0, element3, density, element8);
1775 fOutFile << std::endl;
1776
1777 if (temperature != fgkSTPTemperature) {
1778 fOutFile << indention;
1779 SmartPut(fOutFile, fNW + 1, fNP, 0, element4, temperature, element8);
1780 fOutFile << std::endl;
1781 }
1782
1783 if (pressure != fgkSTPPressure) {
1784 fOutFile << indention;
1785 SmartPut(fOutFile, fNW + 1, fNP, 0, element5, pressure, element8);
1786 fOutFile << std::endl;
1787 }
1788
1789 for (int i = 0; i < int(material->NofElements()); i++) {
1790 double fraction = material->MassFraction(i);
1791 std::string elementName =
1792 UpdateName(material->Element(i)->Name(), fgkElementNameExtension);
1793
1794 fOutFile << indention;
1795 SmartPut(fOutFile, fNW, fNP, 0, element6, fraction, quota);
1796 fOutFile << element7 << elementName << element8 << std::endl;
1797 }
1798
1799 fOutFile << fIndention << element9 << std::endl;
1800}
1801
1802//_____________________________________________________________________________
1803void XmlVGM::GDMLWriter::WriteSolid(std::string volumeName,
1804 const VGM::ISolid* solid, std::string /*materialName*/)
1805{
1806 // Finds solid concrete type and calls writing function.
1807 // For not yet implemented solids, only XML comment element is written.
1808
1809 std::string solidName = UpdateName(volumeName, fgkSolidNameExtension);
1810 RegisterName(solidName);
1811
1812 VGM::SolidType solidType = solid->Type();
1813 if (solidType == VGM::kArb8) {
1814 const VGM::IArb8* arb8 = dynamic_cast<const VGM::IArb8*>(solid);
1815 WriteArb8(solidName, arb8);
1816 return;
1817 }
1818 else if (solidType == VGM::kBox) {
1819 const VGM::IBox* box = dynamic_cast<const VGM::IBox*>(solid);
1820 WriteBox(solidName, box);
1821 return;
1822 }
1823 else if (solidType == VGM::kCons) {
1824 const VGM::ICons* cons = dynamic_cast<const VGM::ICons*>(solid);
1825 WriteCons(solidName, cons);
1826 return;
1827 }
1828 else if (solidType == VGM::kCtubs) {
1829 const VGM::ICtubs* ctubs = dynamic_cast<const VGM::ICtubs*>(solid);
1830 WriteCtubs(solidName, ctubs);
1831 return;
1832 }
1833 else if (solidType == VGM::kEllipsoid) {
1834 const VGM::IEllipsoid* ellipsoid =
1835 dynamic_cast<const VGM::IEllipsoid*>(solid);
1836 WriteEllipsoid(solidName, ellipsoid);
1837 return;
1838 }
1839 else if (solidType == VGM::kEltu) {
1840 const VGM::IEllipticalTube* eltu =
1841 dynamic_cast<const VGM::IEllipticalTube*>(solid);
1842 WriteEllipticalTube(solidName, eltu);
1843 return;
1844 }
1845 else if (solidType == VGM::kExtruded) {
1846 const VGM::IExtrudedSolid* extruded =
1847 dynamic_cast<const VGM::IExtrudedSolid*>(solid);
1848 WriteExtrudedSolid(solidName, extruded);
1849 return;
1850 }
1851 else if (solidType == VGM::kHype) {
1852 const VGM::IHype* hype = dynamic_cast<const VGM::IHype*>(solid);
1853 WriteHype(solidName, hype);
1854 return;
1855 }
1856 else if (solidType == VGM::kPara) {
1857 const VGM::IPara* para = dynamic_cast<const VGM::IPara*>(solid);
1858 WritePara(solidName, para);
1859 return;
1860 }
1861 else if (solidType == VGM::kParaboloid) {
1862 const VGM::IParaboloid* paraboloid =
1863 dynamic_cast<const VGM::IParaboloid*>(solid);
1864 WriteParaboloid(solidName, paraboloid);
1865 return;
1866 }
1867 else if (solidType == VGM::kPolycone) {
1868 const VGM::IPolycone* polycone = dynamic_cast<const VGM::IPolycone*>(solid);
1869 WritePolycone(solidName, polycone);
1870 return;
1871 }
1872 else if (solidType == VGM::kPolyhedra) {
1873 const VGM::IPolyhedra* polyhedra =
1874 dynamic_cast<const VGM::IPolyhedra*>(solid);
1875 WritePolyhedra(solidName, polyhedra);
1876 return;
1877 }
1878 else if (solidType == VGM::kSphere) {
1879 const VGM::ISphere* sphere = dynamic_cast<const VGM::ISphere*>(solid);
1880 WriteSphere(solidName, sphere);
1881 return;
1882 }
1883 else if (solidType == VGM::kTessellated) {
1884 const VGM::ITessellatedSolid* tessellated =
1885 dynamic_cast<const VGM::ITessellatedSolid*>(solid);
1886 WriteTessellatedSolid(solidName, tessellated);
1887 return;
1888 }
1889 else if (solidType == VGM::kTorus) {
1890 const VGM::ITorus* torus = dynamic_cast<const VGM::ITorus*>(solid);
1891 WriteTorus(solidName, torus);
1892 return;
1893 }
1894 else if (solidType == VGM::kTrap) {
1895 const VGM::ITrap* trap = dynamic_cast<const VGM::ITrap*>(solid);
1896 WriteTrap(solidName, trap);
1897 return;
1898 }
1899 else if (solidType == VGM::kTrd) {
1900 const VGM::ITrd* trd = dynamic_cast<const VGM::ITrd*>(solid);
1901 WriteTrd(solidName, trd);
1902 return;
1903 }
1904 else if (solidType == VGM::kTubs) {
1905 const VGM::ITubs* tubs = dynamic_cast<const VGM::ITubs*>(solid);
1906 WriteTubs(solidName, tubs);
1907 return;
1908 }
1909 else if (solidType == VGM::kBoolean) {
1910 const VGM::IBooleanSolid* boolean =
1911 dynamic_cast<const VGM::IBooleanSolid*>(solid);
1912 WriteBooleanSolid(solidName, boolean);
1913 return;
1914 }
1915 else if (solidType == VGM::kMultiUnion) {
1916 const VGM::IMultiUnion* multiUnion =
1917 dynamic_cast<const VGM::IMultiUnion*>(solid);
1918 WriteMultiUnion(solidName, multiUnion);
1919 return;
1920 }
1921
1922 // Not supported solid
1923 WriteNotSupportedSolid(solidName);
1924}
1925
1926//_____________________________________________________________________________
1928 const std::string& name, const VGM::Transform& transform)
1929{
1930 // Write position element with a given name
1931
1932 // get parameters
1933 double x = transform[VGM::kDx] / LengthUnit();
1934 double y = transform[VGM::kDy] / LengthUnit();
1935 double z = transform[VGM::kDz] / LengthUnit();
1936
1937 // compose element string template
1938 std::string quota1 = "\"";
1939 std::string quota2 = "\" ";
1940 std::string element1 = "<position name=";
1941 std::string posName = AppendName(quota1 + name + quota1, 12);
1942
1943 std::string element2 = "x=\"";
1944 std::string element3 = "y=\"";
1945 std::string element4 = "z=\"";
1946 std::string element5 = "\" unit=\"cm\" />";
1947
1948 // write element
1949 fOutFile << fIndention << element1 << posName;
1950
1951 SmartPut(fOutFile, fNW + 1, fNP, fgkCarTolerance, element2, x, quota2);
1952 SmartPut(fOutFile, fNW + 1, fNP, fgkCarTolerance, element3, y, quota2);
1953 SmartPut(fOutFile, fNW + 1, fNP, fgkCarTolerance, element4, z, "");
1954
1955 fOutFile << element5 << std::endl;
1956}
1957
1958//_____________________________________________________________________________
1960 const std::string& name, const VGM::Transform& transform)
1961{
1962 // Write rotation element with a given name
1963
1964 VGM::Transform invTransform = ClhepVGM::Inverse(transform);
1965
1966 // Get parameters
1967 double angleX = invTransform[VGM::kAngleX] / AngleUnit();
1968 double angleY = invTransform[VGM::kAngleY] / AngleUnit();
1969 double angleZ = invTransform[VGM::kAngleZ] / AngleUnit();
1970
1971 // Compose element string template
1972 std::string quota1 = "\"";
1973 std::string quota2 = "\" ";
1974 std::string element1 = "<rotation name=";
1975 std::string rotName = AppendName(quota1 + name + quota1, 12);
1976
1977 std::string element2 = "x=\"";
1978 std::string element3 = "y=\"";
1979 std::string element4 = "z=\"";
1980 std::string element5 = "\" unit=\"degree\" />";
1981
1982 // Write element
1983 fOutFile << fIndention << element1 << rotName;
1984
1985 SmartPut(fOutFile, fNW + 1, fNP, fgkAngTolerance, element2, angleX, quota2);
1986 SmartPut(fOutFile, fNW + 1, fNP, fgkAngTolerance, element3, angleY, quota2);
1987 SmartPut(fOutFile, fNW + 1, fNP, fgkAngTolerance, element4, angleZ, "");
1988
1989 fOutFile << element5 << std::endl;
1990}
1991
1992//_____________________________________________________________________________
1993void XmlVGM::GDMLWriter::WriteScale(const std::string& name)
1994{
1995 // Write scale element with a given name with reflectionZ
1996
1997 // Get parameters
1998 double scaleX = 1.0;
1999 double scaleY = 1.0;
2000 double scaleZ = -1.0;
2001
2002 // Compose element string template
2003 std::string quota1 = "\"";
2004 std::string quota2 = "\" ";
2005 std::string element1 = "<scale name=";
2006 std::string rotName = AppendName(quota1 + name + quota1, 12);
2007
2008 std::string element2 = "x=\"";
2009 std::string element3 = "y=\"";
2010 std::string element4 = "z=\"";
2011 std::string element5 = "\" />";
2012
2013 // Write element
2014 fOutFile << fIndention << element1 << rotName;
2015
2016 SmartPut(fOutFile, fNW + 1, fNP, 0, element2, scaleX, quota2);
2017 SmartPut(fOutFile, fNW + 1, fNP, 0, element3, scaleY, quota2);
2018 SmartPut(fOutFile, fNW + 1, fNP, 0, element4, scaleZ, "");
2019
2020 fOutFile << element5 << std::endl;
2021}
2022
2023//_____________________________________________________________________________
2025{
2026
2027 VGM::PlacementType placementType = placement.Type();
2028
2029 if (placementType == VGM::kSimplePlacement) {
2030
2031 // simple placement
2032 VGM::Transform transform = placement.Transformation();
2033
2034 // Get position
2035 std::string positionRef = fMaps->FindPositionName(transform);
2036
2037 // Get rotation
2038 std::string rotationRef = fMaps->FindRotationName(transform);
2039
2040 // If boolean solid that have to be reflected
2041 // set reflection to the transformation
2042 VGM::IBooleanSolid* booleanSolid =
2043 dynamic_cast<VGM::IBooleanSolid*>(placement.Volume()->Solid());
2044 if (booleanSolid && booleanSolid->ToBeReflected())
2045 transform[VGM::kReflZ] = 1;
2046
2047 // If paraboloid that have to be reflected,
2048 // set reflection to the transformation
2049 VGM::IParaboloid* paraboloid =
2050 dynamic_cast<VGM::IParaboloid*>(placement.Volume()->Solid());
2051 if (paraboloid && paraboloid->RadiusPlusZ() <= paraboloid->RadiusMinusZ())
2052 transform[VGM::kReflZ] = 1;
2053
2054 // Get info about reflection
2055 bool isReflection = ClhepVGM::HasReflection(transform);
2056
2057 WriteSimplePlacement(
2058 placement.Name(), placement.Volume()->Name(), positionRef, rotationRef,
2059 isReflection, placement.CopyNo());
2060 }
2061 else if (placementType == VGM::kMultiplePlacement) {
2062
2063 // get parameters
2064 VGM::Axis axis;
2065 int nReplicas;
2066 double width;
2067 double offset;
2068 double halfGap; // not supported
2069 placement.MultiplePlacementData(axis, nReplicas, width, offset, halfGap);
2070
2071 if (halfGap != 0.) {
2072 std::cerr << "+++ Warning +++" << std::endl;
2073 std::cerr << " XmlVGM::Writer::WritePlacement: " << std::endl;
2074 std::cerr << " Multiple placement with a half gap is not supported. "
2075 << std::endl;
2076 std::cerr << " The half gap parameter will be ignored. " << std::endl;
2077 }
2078
2079 // write multiple position
2080 WriteMultiplePlacement(
2081 placement.Name(), placement.Volume()->Name(), axis, nReplicas, width,
2082 offset);
2083 }
2084 else if (placementType == VGM::kParameterised) {
2085
2086 // get parameters
2087 std::vector<VGM::Transform> transforms;
2088 std::vector<VGM::IVolume*> volumes;
2089 placement.ParameterisedPlacementData(transforms, volumes);
2090
2091
2092 for (size_t i=0; i<transforms.size(); ++i) {
2093
2094 auto transform = transforms[i];
2095
2096 // Get position & rotation
2097 std::string positionRef = fMaps->FindPositionName(transform);
2098 std::string rotationRef = fMaps->FindRotationName(transform);
2099
2100 bool isReflection = ClhepVGM::HasReflection(transform);
2101
2102 auto volumeName = volumes[i]->Name();
2103
2104 WriteSimplePlacement(
2105 placement.Name(), volumeName, positionRef, rotationRef,
2106 isReflection, i);
2107 }
2108 }
2109 else {
2110 std::cerr << "+++ Warning +++" << std::endl;
2111 std::cerr << " XmlVGM::GDMLExporter::ProcessVolume: " << std::endl;
2112 std::cerr << " Unknown placement type. " << std::endl;
2113 std::cerr << " Volume \"" << placement.Name() << "\" was not converted."
2114 << std::endl;
2115 }
2116}
2117
2118//_____________________________________________________________________________
2120{
2121 // Write empty line.
2122
2123 fOutFile << std::endl;
2124}
2125
2126//_____________________________________________________________________________
2128{
2129 // Increase indention
2130
2131 fIndention.append(fkBasicIndention);
2132}
2133
2134//_____________________________________________________________________________
2136{
2137 // Decrease indention
2138
2139 fIndention.replace(fIndention.find(fkBasicIndention), 3, "");
2140}
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 int CopyNo() const =0
Return the copy number of this placement.
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 std::string Name() const =0
Return the name of this volume.
virtual void CloseMaterials()
Write materials definitions closing.
virtual double MassDensityUnit() const
Return the default mass density unit.
Definition GDMLWriter.h:239
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 double LengthUnit() const
Return the default length unit.
Definition GDMLWriter.h:230
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 double TemperatureUnit() const
Definition GDMLWriter.h:244
virtual void WritePosition(const std::string &name, const VGM::Transform &transform)
Write position (from VGM transformation)
virtual void OpenMaterials()
Write materials definitions opening.
virtual double PressureUnit() const
Definition GDMLWriter.h:249
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 double AtomicWeightUnit() const
Return the default atomic weight unit.
Definition GDMLWriter.h:234
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 double AngleUnit() const
Return the default angle unit.
Definition GDMLWriter.h:232
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
Axis
Definition Axis.h:34
@ 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