VGM Version 5.3
Loading...
Searching...
No Matches
AGDDWriter.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// Class AGDDWriter
14// ---------------------
15// The implementation of the interface for the XML convertor that
16// converts VGM geometry objects to XML defined by AGDD.dtd
17// (ATLAS Generic Detector Description)
18//
19// Author: I. Hrivnacova, 16.01.2004
20
25#include <VGM/solids/IBox.h>
26#include <VGM/solids/ICons.h>
27#include <VGM/solids/IPara.h>
30#include <VGM/solids/ISolid.h>
31#include <VGM/solids/ISphere.h>
32#include <VGM/solids/ITrap.h>
33#include <VGM/solids/ITrd.h>
34#include <VGM/solids/ITubs.h>
36#include <VGM/volumes/IVolume.h>
37
38#include <ClhepVGM/transform.h>
39
40#include "XmlVGM/AGDDWriter.h"
41#include "XmlVGM/utilities.h"
42
43#include "CLHEP/Geometry/Transform3D.h"
44#include "CLHEP/Units/SystemOfUnits.h"
45#include "CLHEP/Vector/Rotation.h"
46#include "CLHEP/Vector/ThreeVector.h"
47
48#include <cstdlib>
49#include <iomanip>
50#include <iostream>
51#include <math.h>
52#include <sstream>
53#include <time.h>
54
55using CLHEP::deg;
56
57const int XmlVGM::AGDDWriter::fgkDefaultNumWidth = 7;
58const int XmlVGM::AGDDWriter::fgkDefaultNumPrecision = 4;
59const std::string XmlVGM::AGDDWriter::fgkCompNameExtension = "_comp";
60const std::string XmlVGM::AGDDWriter::fgkElementNameExtension = "_e";
61const std::string XmlVGM::AGDDWriter::fgkMaterialNameExtension = "_mat";
62const double XmlVGM::AGDDWriter::fgkCarTolerance = 1e-10;
63const double XmlVGM::AGDDWriter::fgkAngTolerance = 1e-8;
64
65//_____________________________________________________________________________
66XmlVGM::AGDDWriter::AGDDWriter(const std::string& version,
67 const std::string& author, const std::string dtdVersion)
68 : IWriter(),
69 fOutFile(),
70 fVersion(version),
71 fAuthor(author),
72 fDtdVersion(dtdVersion),
73 fkBasicIndention(" "),
74 fIndention(fkBasicIndention),
75 fNW(fgkDefaultNumWidth),
76 fNP(fgkDefaultNumPrecision)
77{
82
83 fOutFile.width(fgkDefaultNumWidth);
84 fOutFile.precision(fgkDefaultNumPrecision);
85}
86
87//_____________________________________________________________________________
92
93//_____________________________________________________________________________
98
99//
100// private methods
101//
102
103//_____________________________________________________________________________
104std::string XmlVGM::AGDDWriter::ElementSymbol(
105 const VGM::IElement* element) const
106{
109
110 std::string symbol = element->Symbol();
111 if (symbol == " ") {
112 symbol = element->Name();
113 symbol.append(fgkElementNameExtension);
114 }
115
116 return symbol;
117}
118
119//_____________________________________________________________________________
120void XmlVGM::AGDDWriter::RegisterName(const std::string& name, bool warning)
121{
124
125 // Check if the name is unique
126 if (fAGDDNames.find(name) == fAGDDNames.end())
127 fAGDDNames.insert(name);
128 else if (warning) {
129 std::cerr << "+++ Warning +++: " << std::endl;
130 std::cerr << " Duplicated name has occured: \"" << name << "\""
131 << " in geometry." << std::endl;
132 std::cerr << " Duplicated names are not allowed in AGDD." << std::endl;
133 }
134}
135
136//_____________________________________________________________________________
137double XmlVGM::AGDDWriter::Round2(double number) const
138{
141
142 double precision = fNP;
143 return ClhepVGM::Round(number * pow(10., precision)) / pow(10., precision);
144}
145
146//_____________________________________________________________________________
147bool XmlVGM::AGDDWriter::IsIdentity(const VGM::ThreeVector& rotation) const
148{
150
151 VGM::ThreeVector roundedRotation(3);
152 roundedRotation[0] = Round2(rotation[0] / AngleUnit());
153 roundedRotation[1] = Round2(rotation[1] / AngleUnit());
154 roundedRotation[2] = Round2(rotation[2] / AngleUnit());
155
156 if (roundedRotation[0] == 0. && roundedRotation[1] == 0. &&
157 roundedRotation[2] == 0.)
158
159 return true;
160 else
161 return false;
162}
163
164//_____________________________________________________________________________
165void XmlVGM::AGDDWriter::WriteBooleanSolid(std::string volumeName,
166 const VGM::IBooleanSolid* booleanSolid, std::string mediumName)
167{
169
170 // Get constituent solids
171 VGM::ISolid* solidA = booleanSolid->ConstituentSolidA();
172 VGM::ISolid* solidB = booleanSolid->ConstituentSolidB();
173
174 // Write constituent solids
175 std::string nameA = volumeName + "_constA";
176 std::string nameB = volumeName + "_constB";
177 WriteSolid(nameA, solidA, mediumName);
178 WriteSolid(nameB, solidB, mediumName);
179
180 // Zero position
181 VGM::ThreeVector position0(3);
182 position0[0] = 0.0;
183 position0[1] = 0.0;
184 position0[2] = 0.0;
185
186 // Get displacement
187 VGM::Transform transform = booleanSolid->Displacement();
188
189 // position
190 VGM::ThreeVector position(3);
191 position[0] = transform[VGM::kDx];
192 position[1] = transform[VGM::kDy];
193 position[2] = transform[VGM::kDz];
194
195 // rotation
196 VGM::ThreeVector rotation(3);
197 rotation[0] = transform[VGM::kAngleX];
198 rotation[1] = transform[VGM::kAngleY];
199 rotation[2] = transform[VGM::kAngleZ];
200
201 // Get boolean type
202 VGM::BooleanType boolType = booleanSolid->BoolType();
203
204 // compose element string template
205 //
206 std::string element1;
207 std::string element3;
208 switch (boolType) {
210 element1 = "<intersection name=\"";
211 element3 = "</intersection>";
212 break;
214 element1 = "<subtraction name=\"";
215 element3 = "</subtraction>";
216 break;
217 case VGM::kUnion:
218 element1 = "<union name=\"";
219 element3 = "</union>";
220 break;
222 break;
223 }
224 std::string element2 = "\" >";
225 std::string indention = fIndention;
226
227 // write element
228 fOutFile << fIndention << element1 << volumeName << element2 << std::endl;
229
230 // write first constituent
231 fIndention = fIndention + fkBasicIndention;
232 WritePlacement(nameA, position0);
233
234 // write second constituent
235 if (ClhepVGM::HasReflection(transform))
236 WritePlacementWithRotationAndReflection(nameB, position, rotation);
237 else if (IsIdentity(rotation))
238 WritePlacement(nameB, position);
239 else
240 WritePlacementWithRotation(nameB, position, rotation);
241
242 fIndention = indention;
243
244 fOutFile << fIndention << element3 << std::endl << std::endl;
245}
246
247//_____________________________________________________________________________
248void XmlVGM::AGDDWriter::WriteBox(std::string volumeName, double hx, double hy,
249 double hz, std::string mediumName)
250{
252
253 // get parameters
254 double x = hx / LengthUnit() * 2.;
255 double y = hy / LengthUnit() * 2.;
256 double z = hz / LengthUnit() * 2.;
257
258 // compose element string template
259 std::string quota = "\"";
260 std::string element1 = "<box name=\"" + volumeName + quota;
261 std::string element2 = "medium=\"" + mediumName + quota;
262 std::string element3 = "X_Y_Z=\"";
263 std::string element4 = "\" />";
264 std::string indention = fkBasicIndention + fkBasicIndention;
265
266 // write element
267 fOutFile << fkBasicIndention << element1 << std::endl
268 << indention << element2 << std::endl
269 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
270 << x << "; " << std::setw(fNW) << std::setprecision(fNP) << y << "; "
271 << std::setw(fNW) << std::setprecision(fNP) << z << element4
272 << std::endl
273 << std::endl;
274}
275
276//_____________________________________________________________________________
277void XmlVGM::AGDDWriter::WriteBox(
278 std::string volumeName, const VGM::IBox* box, std::string mediumName)
279{
281
282 WriteBox(volumeName, box->XHalfLength(), box->YHalfLength(),
283 box->ZHalfLength(), mediumName);
284}
285
286//_____________________________________________________________________________
287void XmlVGM::AGDDWriter::WriteTubs(
288 std::string volumeName, const VGM::ITubs* tubs, std::string mediumName)
289{
291
292 // get parameters
293 double rmin = tubs->InnerRadius() / LengthUnit();
294 double rmax = tubs->OuterRadius() / LengthUnit();
295 double hz = tubs->ZHalfLength() / LengthUnit() * 2.;
296 double sphi = tubs->StartPhi() / AngleUnit();
297 double dphi = tubs->DeltaPhi() / AngleUnit();
298
299 // compose element string template
300 std::string quota = "\"";
301 std::string element1 = "<tubs name=\"" + volumeName + quota;
302 std::string element2 = "medium=\"" + mediumName + quota;
303 std::string element3 = "profile=\"";
304 std::string element4 = "Rio_Z =\"";
305 std::string element5 = "\" />";
306 std::string indention = fkBasicIndention + fkBasicIndention;
307
308 // write element
309 fOutFile << fkBasicIndention << element1 << std::endl
310 << indention << element2 << std::endl
311 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
312 << sphi << "; " << std::setw(fNW) << std::setprecision(fNP) << dphi
313 << quota << std::endl
314 << indention << element4 << std::setw(fNW) << std::setprecision(fNP)
315 << rmin << "; " << std::setw(fNW) << std::setprecision(fNP) << rmax
316 << "; " << std::setw(fNW) << std::setprecision(fNP) << hz << element5
317 << std::endl
318 << std::endl;
319}
320
321//_____________________________________________________________________________
322void XmlVGM::AGDDWriter::WriteCons(
323 std::string volumeName, const VGM::ICons* cons, std::string mediumName)
324{
326
327 // get parameters
328 double rmin1 = cons->InnerRadiusMinusZ() / LengthUnit();
329 double rmax1 = cons->OuterRadiusMinusZ() / LengthUnit();
330 double rmin2 = cons->InnerRadiusPlusZ() / LengthUnit();
331 double rmax2 = cons->OuterRadiusPlusZ() / LengthUnit();
332 double hz = cons->ZHalfLength() / LengthUnit() * 2.;
333 double sphi = cons->StartPhi() / AngleUnit();
334 double dphi = cons->DeltaPhi() / AngleUnit();
335
336 // compose element string template
337 std::string quota = "\"";
338 std::string element1 = "<cons name=\"" + volumeName + quota;
339 std::string element2 = "medium=\"" + mediumName + quota;
340 std::string element3 = "profile=\"";
341 std::string element4 = "Rio1_Rio2_Z =\"";
342 std::string element5 = "\" />";
343 std::string indention = fkBasicIndention + fkBasicIndention;
344
345 // write element
346 fOutFile << fkBasicIndention << element1 << std::endl
347 << indention << element2 << std::endl
348 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
349 << sphi << "; " << std::setw(fNW) << std::setprecision(fNP) << dphi
350 << quota << std::endl
351 << indention << element4 << std::setw(fNW) << std::setprecision(fNP)
352 << rmin1 << "; " << std::setw(fNW) << std::setprecision(fNP) << rmin2
353 << "; " << std::setw(fNW) << std::setprecision(fNP) << rmax1 << "; "
354 << std::setw(fNW) << std::setprecision(fNP) << rmax2 << "; "
355 << std::setw(fNW) << std::setprecision(fNP) << hz << element5
356 << std::endl
357 << std::endl;
358}
359
360//_____________________________________________________________________________
361void XmlVGM::AGDDWriter::WriteTrd(
362 std::string volumeName, const VGM::ITrd* trd, std::string mediumName)
363{
365
366 // get parameters
367 double x1 = trd->XHalfLengthMinusZ() / LengthUnit() * 2;
368 double x2 = trd->XHalfLengthPlusZ() / LengthUnit() * 2;
369 double y1 = trd->YHalfLengthMinusZ() / LengthUnit() * 2;
370 double y2 = trd->YHalfLengthPlusZ() / LengthUnit() * 2;
371 double hz = trd->ZHalfLength() / LengthUnit() * 2;
372
373 // compose element string template
374 std::string quota = "\"";
375 std::string element1 = "<trd name=\"" + volumeName + quota;
376 std::string element2 = "medium=\"" + mediumName + quota;
377 std::string element3 = "Xmp_Ymp_Z=\"";
378 std::string element4 = "\" />";
379 std::string indention = fkBasicIndention + fkBasicIndention;
380
381 // write element
382 fOutFile << fkBasicIndention << element1 << std::endl
383 << indention << element2 << std::endl
384 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
385 << x1 << "; " << std::setw(fNW) << std::setprecision(fNP) << x2
386 << "; " << std::setw(fNW) << std::setprecision(fNP) << y1 << "; "
387 << std::setw(fNW) << std::setprecision(fNP) << y2 << "; "
388 << std::setw(fNW) << std::setprecision(fNP) << hz << element4
389 << std::endl
390 << std::endl;
391}
392
393//_____________________________________________________________________________
394void XmlVGM::AGDDWriter::WriteTrap(
395 std::string volumeName, const VGM::ITrap* trap, std::string mediumName)
396{
398
399 // get parameters
400 double dz = trap->ZHalfLength() / LengthUnit() * 2.;
401 double theta = trap->Theta() / AngleUnit();
402 double phi = trap->Phi() / AngleUnit();
403 double y1 = trap->YHalfLengthMinusZ() / LengthUnit() * 2.;
404 double x1 = trap->XHalfLengthMinusZMinusY() / LengthUnit() * 2.;
405 double x2 = trap->XHalfLengthMinusZPlusY() / LengthUnit() * 2.;
406 double alpha1 = trap->AlphaMinusZ() / AngleUnit();
407 double y2 = trap->YHalfLengthPlusZ() / LengthUnit() * 2.;
408 double x3 = trap->XHalfLengthPlusZMinusY() / LengthUnit() * 2.;
409 double x4 = trap->XHalfLengthPlusZPlusY() / LengthUnit() * 2.;
410 double alpha2 = trap->AlphaPlusZ() / AngleUnit();
411
412 // ordering of parameters in XML element
413 // Xmumdpupd_Ymp_Z: 2x2 2x1 2x4 2x3 2y2 2y1 2dz
414 // inclination: atan(symAxis.x/symAxis.z), atan(symAxis.y/symAxis.z)
415 // declination: alpha1, alpha2
416
417 // get inclination angles
418 double thetaCphi = tan(theta * deg) * cos(phi * deg);
419 double thetaSphi = tan(theta * deg) * sin(phi * deg);
420 double cosTheta =
421 1.0 / sqrt(1 + thetaCphi * thetaCphi + thetaSphi * thetaSphi);
422
423 CLHEP::Hep3Vector symAxis(
424 thetaCphi * cosTheta, thetaSphi * cosTheta, cosTheta);
425 double inc1 = atan(symAxis.x() / symAxis.z()) / deg;
426 double inc2 = atan(symAxis.y() / symAxis.z()) / deg;
427
428 // compose element string template
429 std::string quota = "\"";
430 std::string element1 = "<trap name=\"" + volumeName + quota;
431 std::string element2 = "medium=\"" + mediumName + quota;
432 std::string element3 = "Xmumdpupd_Ymp_Z=\"";
433 std::string element4 = "inclination=\"";
434 std::string element5 = "declination=\"";
435 std::string element6 = "\" />";
436 std::string indention = fkBasicIndention + fkBasicIndention;
437
438 // write element
439 fOutFile << fkBasicIndention << element1 << std::endl
440 << indention << element2 << std::endl
441 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
442 << x2 << "; " << std::setw(fNW) << std::setprecision(fNP) << x1
443 << "; " << std::setw(fNW) << std::setprecision(fNP) << x4 << "; "
444 << std::setw(fNW) << std::setprecision(fNP) << x3 << "; "
445 << std::setw(fNW) << std::setprecision(fNP) << y2 << "; "
446 << std::setw(fNW) << std::setprecision(fNP) << y1 << "; "
447 << std::setw(fNW) << std::setprecision(fNP) << dz << quota
448 << std::endl
449 << indention << element4 << std::setw(fNW) << std::setprecision(fNP)
450 << inc1 << "; " << std::setw(fNW) << std::setprecision(fNP) << inc2
451 << quota << std::endl
452 << indention << element5 << std::setw(fNW) << std::setprecision(fNP)
453 << alpha1 << "; " << std::setw(fNW) << std::setprecision(fNP)
454 << alpha2 << element6 << std::endl
455 << std::endl;
456}
457
458//_____________________________________________________________________________
459void XmlVGM::AGDDWriter::WritePara(
460 std::string volumeName, const VGM::IPara* para, std::string mediumName)
461{
463
464 // get parameters
465 double dx = para->XHalfLength() / LengthUnit() * 2.;
466 double dy = para->YHalfLength() / LengthUnit() * 2.;
467 double dz = para->ZHalfLength() / LengthUnit() * 2.;
468 double alpha = para->Alpha() / AngleUnit();
469 double theta = para->Theta() / AngleUnit();
470 double phi = para->Phi() / AngleUnit();
471
472 // compose element string template
473 std::string quota = "\"";
474 std::string element1 = "<para name=\"" + volumeName + quota;
475 std::string element2 = "medium=\"" + mediumName + quota;
476 std::string element3 = "X_Y_Z=\"";
477 std::string element4 = "alpha=\"";
478 std::string element5 = "theta=\"";
479 std::string element6 = "phi= \"";
480 std::string element7 = "\" />";
481 std::string indention = fkBasicIndention + fkBasicIndention;
482
483 // write element
484 fOutFile << fkBasicIndention << element1 << std::endl
485 << indention << element2 << std::endl
486 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
487 << dx << "; " << std::setw(fNW) << std::setprecision(fNP) << dy
488 << "; " << std::setw(fNW) << std::setprecision(fNP) << dz << quota
489 << std::endl
490 << indention << element4 << std::setw(fNW) << std::setprecision(fNP)
491 << alpha << quota << std::endl
492 << indention << element5 << std::setw(fNW) << std::setprecision(fNP)
493 << theta << quota << std::endl
494 << indention << element6 << std::setw(fNW) << std::setprecision(fNP)
495 << phi << element7 << std::endl
496 << std::endl;
497}
498
499//_____________________________________________________________________________
500void XmlVGM::AGDDWriter::WritePolycone(std::string volumeName,
501 const VGM::IPolycone* polycone, std::string mediumName)
502{
504
505 // get profile parameters
506 double sphi = polycone->StartPhi() / AngleUnit();
507 double dphi = polycone->DeltaPhi() / AngleUnit();
508
509 // get polycone Z planes parameters
510 int nofZPlanes = polycone->NofZPlanes();
511 double* rminArray = polycone->InnerRadiusValues();
512 double* rmaxArray = polycone->OuterRadiusValues();
513 double* zArray = polycone->ZValues();
514
515 // compose element string template
516 std::string quota = "\"";
517 std::string element1 = "<pcon name=\"" + volumeName + quota;
518 std::string element2 = "medium=\"" + mediumName + quota;
519 std::string element3 = "profile=\"";
520 std::string element4 = "\" >";
521 std::string element5 = "<polyplane Rio_Z=\"";
522 std::string element6 = "\" />";
523 std::string element7 = "</pcon>";
524 std::string indention = fkBasicIndention + fkBasicIndention;
525
526 // write pcon element
527 fOutFile << fkBasicIndention << element1 << std::endl
528 << indention << element2 << std::endl
529 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
530 << sphi << "; " << std::setw(fNW) << std::setprecision(fNP) << dphi
531 << element4 << std::endl;
532
533 // write polyplane elements
534 for (int i = 0; i < nofZPlanes; i++) {
535
536 // set units
537 double rmin = rminArray[i] / LengthUnit();
538 double rmax = rmaxArray[i] / LengthUnit();
539 double z = zArray[i] / LengthUnit();
540
541 fOutFile << indention << element5 << std::setw(fNW)
542 << std::setprecision(fNP) << rmin << "; " << std::setw(fNW)
543 << std::setprecision(fNP) << rmax << "; " << std::setw(fNW)
544 << std::setprecision(fNP) << z << element6 << std::endl;
545 }
546
547 // close pcon element
548 fOutFile << fkBasicIndention << element7 << std::endl << std::endl;
549}
550
551//_____________________________________________________________________________
552void XmlVGM::AGDDWriter::WritePolyhedra(std::string volumeName,
553 const VGM::IPolyhedra* polyhedra, std::string mediumName)
554{
556
557 // get parameters
558 int nofSides = polyhedra->NofSides();
559 double sphi = polyhedra->StartPhi() / AngleUnit();
560 double dphi = polyhedra->DeltaPhi() / AngleUnit();
561
562 // get polyhedra Z planes parameters
563 int nofZPlanes = polyhedra->NofZPlanes();
564 double* rminArray = polyhedra->InnerRadiusValues();
565 double* rmaxArray = polyhedra->OuterRadiusValues();
566 double* zArray = polyhedra->ZValues();
567
568 // compose element string template
569 std::string quota = "\"";
570 std::string element1 = "<phedra name=\"" + volumeName + quota;
571 std::string element2 = "medium=\"" + mediumName + quota;
572 std::string element3 = "profile=\"";
573 std::string element4 = "sides =\"";
574 std::string element5 = "Ris=\"";
575 std::string element6 = "Ros=\"";
576 std::string element7 = "Zs =\"";
577 std::string element8 = "\" />";
578 std::string indention = fkBasicIndention + fkBasicIndention;
579
580 // write element
581 fOutFile << fkBasicIndention << element1 << std::endl
582 << indention << element2 << std::endl
583 << indention << element3 << std::setw(fNW) << std::setprecision(fNP)
584 << sphi << "; " << std::setw(fNW) << std::setprecision(fNP) << dphi
585 << quota << std::endl
586 << indention << element4 << nofSides << quota << std::endl;
587
588 fOutFile << indention << element5;
589 int i;
590 for (i = 0; i < nofZPlanes; i++) {
591 // set units
592 double rmin = rminArray[i] / LengthUnit();
593 if (i > 0) fOutFile << "; ";
594 fOutFile << std::setw(fNW) << std::setprecision(fNP) << rmin;
595 };
596 fOutFile << quota << std::endl;
597
598 fOutFile << indention << element6;
599 for (i = 0; i < nofZPlanes; i++) {
600 // set units
601 double rmax = rmaxArray[i] / LengthUnit();
602 if (i > 0) fOutFile << "; ";
603 fOutFile << std::setw(fNW) << std::setprecision(fNP) << rmax;
604 };
605 fOutFile << quota << std::endl;
606
607 fOutFile << indention << element7;
608 for (i = 0; i < nofZPlanes; i++) {
609 // set units
610 double z = zArray[i] / LengthUnit();
611 if (i > 0) fOutFile << "; ";
612 fOutFile << std::setw(fNW) << std::setprecision(fNP) << z;
613 };
614 fOutFile << element8 << std::endl << std::endl;
615}
616
617//_____________________________________________________________________________
618void XmlVGM::AGDDWriter::WriteNotSupportedSolid(
619 std::string name, std::string mediumName)
620{
623
624 // Compose comment
625 std::string element1 = "<!-- !!! unsupported shape !!! name= \"";
626 std::string element2 = "\" -->";
627 std::string element3 = "<!-- dummy box is written instead -->";
628
629 // Write element with warning
630 fOutFile << fIndention << element1 << name << element2 << std::endl
631 << fIndention << element3 << std::endl;
632
633 // Write dummy box element
634 WriteBox(name, 1.0, 1.0, 1.0, mediumName);
635}
636
637//_____________________________________________________________________________
638void XmlVGM::AGDDWriter::WritePlacementWithRotation(std::string volumeName,
639 const VGM::ThreeVector& position, const VGM::ThreeVector& rotation)
640{
642
643 // get parameters
644 double x = position[0] / LengthUnit();
645 double y = position[1] / LengthUnit();
646 double z = position[2] / LengthUnit();
647
648 // convert object rotation to frame rotation
649 CLHEP::HepRotation hepRotation;
650 hepRotation.rotateX(rotation[0] * deg);
651 hepRotation.rotateY(rotation[1] * deg);
652 hepRotation.rotateZ(rotation[2] * deg);
653
654 double xx = hepRotation.xx();
655 double xy = hepRotation.xy();
656 double xz = hepRotation.xz();
657 double yx = hepRotation.yx();
658 double yy = hepRotation.yy();
659 double yz = hepRotation.yz();
660 double zx = hepRotation.zx();
661 double zy = hepRotation.zy();
662 double zz = hepRotation.zz();
663
664 // compose element string template
665 std::string quota = "\"\n";
666 std::string element1 = "<transform pos=\"";
667 std::string element2 = " matrix=\"";
668 std::string element3 = " ";
669 std::string element4 = "\"> <volume name=\"";
670 std::string element5 = "\"/>";
671 std::string element6 = "</transform>";
672
673 // write element
674 fOutFile << fIndention << element1;
675
676 SmartPut(fOutFile, fNW + 1, fNP, fgkCarTolerance, x, "; ");
677 SmartPut(fOutFile, fNW + 1, fNP, fgkCarTolerance, y, "; ");
678 SmartPut(fOutFile, fNW + 1, fNP, fgkCarTolerance, z, quota);
679
680 fOutFile << fIndention << element2;
681
682 SmartPut(fOutFile, 8, 5, 0, xx, "; ");
683 SmartPut(fOutFile, 8, 5, 0, xy, "; ");
684 SmartPut(fOutFile, 8, 5, 0, xz, "; ");
685
686 fOutFile << std::endl << fIndention << element3;
687
688 SmartPut(fOutFile, 8, 5, 0, yx, "; ");
689 SmartPut(fOutFile, 8, 5, 0, yy, "; ");
690 SmartPut(fOutFile, 8, 5, 0, yz, "; ");
691
692 fOutFile << std::endl << fIndention << element3;
693
694 SmartPut(fOutFile, 8, 5, 0, zx, "; ");
695 SmartPut(fOutFile, 8, 5, 0, zy, "; ");
696 SmartPut(fOutFile, 8, 5, 0, zz, "");
697
698 fOutFile << element4 << volumeName << element5 << std::endl
699 << fIndention << element6 << std::endl;
700}
701
702//_____________________________________________________________________________
703void XmlVGM::AGDDWriter::WritePlacementWithRotationAndReflection(
704 std::string volumeName, const VGM::ThreeVector& position,
705 const VGM::ThreeVector& rotation)
706{
707 // Write position with rotation and reflection with a given volume name
708
709 // get parameters
710 //
711 HepGeom::Translate3D translate3D(position[0], position[1], position[2]);
712
713 // rotation
714 CLHEP::HepRotation hepRotation;
715 hepRotation.rotateX(rotation[0] * deg);
716 hepRotation.rotateY(rotation[1] * deg);
717 hepRotation.rotateZ(rotation[2] * deg);
718 HepGeom::Rotate3D rotate3D(hepRotation);
719
720 HepGeom::ScaleZ3D scale3D(-1.0);
721
722 HepGeom::Transform3D transform3D = translate3D * rotate3D * scale3D;
723
724 CLHEP::Hep3Vector translation = transform3D.getTranslation();
725 double x = translation.x() / LengthUnit();
726 double y = translation.y() / LengthUnit();
727 double z = translation.z() / LengthUnit();
728
729 double xx = transform3D(0, 0);
730 double xy = transform3D(0, 1);
731 double xz = transform3D(0, 2);
732 double yx = transform3D(1, 0);
733 double yy = transform3D(1, 1);
734 double yz = transform3D(1, 2);
735 double zx = transform3D(2, 0);
736 double zy = transform3D(2, 1);
737 double zz = transform3D(2, 2);
738
739 // compose element string template
740 std::string quota = "\"\n";
741 std::string element1 = "<transform pos=\"";
742 std::string element2 = " matrix=\"";
743 std::string element3 = " ";
744 std::string element4 = "\"> <volume name=\"";
745 std::string element5 = "\"/>";
746 std::string element6 = "</transform>";
747
748 // write element
749 fOutFile << fIndention << element1;
750
751 SmartPut(fOutFile, fNW + 1, fNP, fgkCarTolerance, x, "; ");
752 SmartPut(fOutFile, fNW + 1, fNP, fgkCarTolerance, y, "; ");
753 SmartPut(fOutFile, fNW + 1, fNP, fgkCarTolerance, z, quota);
754
755 fOutFile << fIndention << element2;
756
757 SmartPut(fOutFile, 8, 5, 0, xx, "; ");
758 SmartPut(fOutFile, 8, 5, 0, xy, "; ");
759 SmartPut(fOutFile, 8, 5, 0, xz, "; ");
760
761 fOutFile << std::endl << fIndention << element3;
762
763 SmartPut(fOutFile, 8, 5, 0, yx, "; ");
764 SmartPut(fOutFile, 8, 5, 0, yy, "; ");
765 SmartPut(fOutFile, 8, 5, 0, yz, "; ");
766
767 fOutFile << std::endl << fIndention << element3;
768
769 SmartPut(fOutFile, 8, 5, 0, zx, "; ");
770 SmartPut(fOutFile, 8, 5, 0, zy, "; ");
771 SmartPut(fOutFile, 8, 5, 0, zz, "");
772
773 fOutFile << element4 << volumeName << element5 << std::endl
774 << fIndention << element6 << std::endl;
775}
776
777//_____________________________________________________________________________
778void XmlVGM::AGDDWriter::WriteMultiplePlacement(const std::string& volumeName,
779 VGM::Axis axis, int nofReplicas, double width, double offset)
780
781{
782 // Write multiple position
783
784 std::string tag;
785 switch (axis) {
786 case VGM::kXAxis:
787 tag = "X";
788 break;
789 case VGM::kYAxis:
790 tag = "Y";
791 break;
792 case VGM::kZAxis:
793 tag = "Z";
794 break;
795 case VGM::kRho:
796 tag = "R";
797 break;
798 case VGM::kPhi:
799 tag = "Phi";
800 break;
801 case VGM::kRadial3D:
802 tag = "R3D";
803 break; // CHECK
804 case VGM::kSphTheta:
805 tag = "Undefined";
806 break; // CHECK
808 tag = "Undefined";
809 break;
810 }
811
812 // set units
813 double value0 = -width * (nofReplicas - 1) * 0.5 + offset;
814 double dValue = width;
815 if (axis != VGM::kPhi) {
816 value0 = value0 / LengthUnit();
817 dValue = dValue / LengthUnit();
818 }
819 else {
820 value0 = value0 / AngleUnit();
821 dValue = dValue / AngleUnit();
822 }
823
824 // set tag and attributes names
825 std::string a0 = "mpos";
826 a0 = a0 + tag;
827 std::string a1 = tag;
828 a1 = a1 + "0";
829 std::string a2 = "d";
830 a2 = a2 + tag;
831
832 // compose element string template
833 std::string element1 = "<" + a0 + " ncopy=\"";
834 std::string element2 = "\" " + a1 + "=\"";
835 std::string element3 = "\" " + a2 + "=\"";
836 std::string element4 = "\"> <volume name=\"";
837 std::string element5 = "\"/>";
838 std::string element6 = "</" + a0 + ">";
839
840 // write element
841 fOutFile << fIndention << element1 << std::setw(fNW + 1 - fNP) << nofReplicas
842 << element2 << std::setw(fNW + 1) << std::setprecision(fNP) << value0
843 << element3 << std::setw(fNW + 1) << std::setprecision(fNP) << dValue
844 << element4 << volumeName << element5 << std::endl
845 << fIndention << element6 << std::endl;
846}
847
848//
849// public methods
850//
851
852//_____________________________________________________________________________
853void XmlVGM::AGDDWriter::OpenFile(std::string filePath)
854{
855 // Open output file
856
857 fOutFile.open(filePath.data(), std::ios::out);
858
859 if (!fOutFile) {
860 std::cerr << " Cannot open " << filePath << std::endl;
861 std::cerr << "** Exception: Aborting execution **" << std::endl;
862 exit(1);
863 }
864
865 // use FORTRAN compatibility output
866 fOutFile.setf(std::ios::fixed, std::ios::floatfield);
867}
868
869//_____________________________________________________________________________
871{
872 // Write document opening.
873 // Could be made customizable in future.
874
875 // Opening xml document
876 fOutFile << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl
877 << std::endl
878 << "<AGDD DTD_version = \"v7\"" << std::endl
879 << " xmlns:xi=\"http://www.w3.org/2001/XInclude\">" << std::endl
880 << std::endl
881 << "<xi:include href=\"StandardColors.agdd\"/>" << std::endl
882 << std::endl;
883}
884
885//_____________________________________________________________________________
886void XmlVGM::AGDDWriter::OpenSection(const std::string& topVolume)
887{
888 // Write section opening.
889 // Could be made customizable in future.
890
891 // Define section element
892
893 std::string element1 = "<section DTD_version = \"";
894 std::string element2 = " name = \"";
895 std::string element3 = " version = \"";
896 std::string element4 = " date = \"";
897 std::string element5 = " author = \"";
898 std::string element6 = " top_volume = \"";
899 std::string element7 = " >";
900 std::string quota = "\"";
901
902 std::string version = fVersion;
903 if (version == "Undefined") {
904 version = "$Id$";
905 // strip $ from the string
906 version = version.substr(1, version.size() - 2);
907 }
908
909 std::string name = topVolume;
910 name.append(fgkCompNameExtension);
911
912 std::string date = Date();
913
914 // write element
915 fOutFile << element1 << fDtdVersion << quota << std::endl
916 << element2 << topVolume << quota << std::endl
917 << element3 << version << quota << std::endl
918 << element4 << date << quota << std::endl
919 << element5 << fAuthor << quota << std::endl
920 << element6 << name << quota << element7 << std::endl;
921}
922
923//_____________________________________________________________________________
925{
926 // Write materials opening.
927
928 std::string element1 = "<materials version = \"";
929 std::string element2 = " date = \"";
930 std::string element3 = " author = \"";
931 std::string element4 = " DTD_version=\"";
932 std::string element5 = " >";
933 std::string quota = "\"";
934
935 std::string version = fVersion;
936 if (version == "Undefined") {
937 version = "$Id$";
938 // strip $ from the string
939 version = version.substr(1, version.size() - 2);
940 }
941
942 std::string date = Date();
943
944 // write element
945 fOutFile << element1 << version << quota << std::endl
946 << element2 << date << quota << std::endl
947 << element3 << fAuthor << quota << std::endl
948 << element4 << fDtdVersion << quota << element5 << std::endl
949 << std::endl;
950}
951
952//_____________________________________________________________________________
954{
955 // Write materials opening.
956
957 std::string element1 = "<media version = \"";
958 std::string element2 = " date = \"";
959 std::string element3 = " author = \"";
960 std::string element4 = " DTD_version=\"";
961 std::string element5 = " >";
962 std::string quota = "\"";
963
964 std::string version = fVersion;
965 if (version == "Undefined") {
966 version = "$Id$";
967 // strip $ from the string
968 version = version.substr(1, version.size() - 2);
969 }
970
971 std::string date = Date();
972
973 // write element
974 fOutFile << element1 << version << quota << std::endl
975 << element2 << date << quota << std::endl
976 << element3 << fAuthor << quota << std::endl
977 << element4 << fDtdVersion << quota << element5 << std::endl
978 << std::endl;
979}
980
981//_____________________________________________________________________________
983 const std::string& name, const std::string& /*materialName*/)
984{
985 // Write composition opening.
986
987 std::string compName = name;
988 compName.append(fgkCompNameExtension);
989
990 std::string element = "<composition name=\"";
991 element.append(compName);
992 element.append("\">");
993
994 // write element
995 fOutFile << fIndention << element << std::endl;
996
997 // increase indention
998 IncreaseIndention();
999}
1000
1001//_____________________________________________________________________________
1003{
1004 // Close output file.
1005
1006 fOutFile.close();
1007}
1008
1009//_____________________________________________________________________________
1011{
1012 // Write document closing
1013
1014 // define element
1015 std::string element = "</AGDD>";
1016
1017 // write element
1018 fOutFile << element << std::endl;
1019}
1020
1021//_____________________________________________________________________________
1022void XmlVGM::AGDDWriter::CloseSection(const std::string& /*topVolume*/)
1023{
1024 // Write section closing
1025
1026 // define element
1027 std::string element = "</section>";
1028
1029 // write element
1030 fOutFile << element << std::endl << std::endl;
1031}
1032
1033//_____________________________________________________________________________
1035{
1036 // Write materials closing
1037
1038 // define element
1039 std::string element = "</materials>";
1040
1041 // write element
1042 fOutFile << element << std::endl;
1043}
1044
1045//_____________________________________________________________________________
1047{
1048 // Write materials closing
1049
1050 // define element
1051 std::string element = "</media>";
1052
1053 // write element
1054 fOutFile << element << std::endl;
1055}
1056
1057//_____________________________________________________________________________
1059{
1060 // Write composition closing
1061
1062 // decrease indention
1063 DecreaseIndention();
1064
1065 // define element
1066 std::string element = "</composition>";
1067
1068 // write element
1069 fOutFile << fIndention << element << std::endl;
1070}
1071
1072//_____________________________________________________________________________
1074{
1075 // Write VGM::IElement
1076
1077 // Get parameters
1078 int theZ = isotope->Z();
1079 int theN = isotope->N();
1080 int theA = isotope->N();
1081 // double theA = isotope->A()/ AtomicWeightUnit();
1083
1084 // Compose name as name_N
1085 std::string name = IsotopeName(isotope);
1086 RegisterName(name);
1087
1088 // AGDD does not allow N=0
1089 // Let's put =1 in this case
1090 if (theN == 0) theN = 1;
1091
1092 // Compose element string template
1093 std::string quota1 = "\"";
1094 std::string quota2 = "\" ";
1095 std::string element1 = "<isotope name=\"";
1096 std::string element2 = "z=\"";
1097 std::string element3 = "n=\"";
1098 std::string element4 = "a=\"";
1099 std::string element5 = "\"/>";
1100
1101 std::string indention = fIndention + fkBasicIndention;
1102
1103 // Write element
1104 fOutFile << fIndention << element1 << name << quota1;
1105 for (int i = 0; i < 8 - int(name.size()); i++) fOutFile << " ";
1106
1107 fOutFile << element2 << std::setw(3) << theZ << quota2;
1108 // SmartPut(fOutFile, fNW, fNP, theZ, quota2);
1109
1110 fOutFile << element3 << std::setw(3) << theN << quota2;
1111 // SmartPut(fOutFile, fNW, fNP, theN, quota2);
1112
1113 fOutFile << element4 << std::setw(3) << theA << element5;
1114 // SmartPut(fOutFile, fNW, fNP, theA, element5);
1115 fOutFile << std::endl;
1116}
1117
1118//_____________________________________________________________________________
1120{
1121 // Write VGM::IElement
1122
1123 std::string symbol = ElementSymbol(element);
1124 RegisterName(symbol);
1125
1126 // Compose element string template
1127 std::string quota1 = "\"";
1128 std::string quota2 = "\" ";
1129 std::string element1 = "<element symbol=\"";
1130 std::string element2 = "\">";
1131 std::string element6 = "</element>";
1132
1133 std::string indention = fIndention + fkBasicIndention;
1134
1135 // Write element name
1136 fOutFile << fIndention << element1 << symbol << element2 << std::endl;
1137
1138 // Get parameters
1139 if (element->NofIsotopes() > 0) {
1140 for (int i = 0; i < element->NofIsotopes(); i++) {
1141 VGM::IIsotope* isotope = element->Isotope(i);
1142 std::string name = IsotopeName(isotope);
1143 double natoms = element->RelAbundance(i);
1144 int natomsInt = (int)(Round2(natoms * 100));
1145
1146 std::string element3 = "<addisotope name=\"";
1147 std::string element4 = "natoms=\"";
1148 std::string element5 = "\" />";
1149
1150 fOutFile << indention << element3 << name << quota2;
1151 fOutFile << element4;
1152 // SmartPut(fOutFile, fNW-2, fNP, natoms, element5);
1153 fOutFile << std::setw(3) << natomsInt << element5;
1154 fOutFile << std::endl;
1155 }
1156 }
1157 else {
1158 double theZ = element->Z();
1159 int theN = (int)ClhepVGM::Round(element->N());
1160 double theA = element->A() / AtomicWeightUnit();
1161
1162 // AGDD does not allow N=0
1163 // Let's put =1 in this case
1164 if (theN == 0) theN = 1;
1165
1166 std::string element3 = "<atom zeff=\"";
1167 std::string element4 = "aweight=\"";
1168 std::string element5 = "\" />";
1169
1170 fOutFile << indention << element3;
1171 SmartPut(fOutFile, fNW - 2, fNP, 0, theZ, quota2);
1172
1173 fOutFile << element4;
1174 SmartPut(fOutFile, fNW - 2, fNP, 0, theA, element5);
1175 fOutFile << std::endl;
1176 }
1177
1178 fOutFile << fIndention << element6 << std::endl;
1179}
1180
1181//_____________________________________________________________________________
1183{
1184 // Write material.
1185
1186 std::string materialName =
1187 UpdateName(material->Name(), fgkMaterialNameExtension);
1188 RegisterName(materialName);
1189
1190 // Get parameters
1191 double density = material->Density() / MassDensityUnit();
1192
1193 // Compose material string template
1194 std::string quota = "\" ";
1195 std::string element1 = "<material name=\"";
1196 std::string element2 = "density=\"";
1197 std::string element3 = "\">";
1198 std::string element4 = "<addelement name=\"";
1199 std::string element5 = "natoms=\"";
1200 std::string element6 = "\"/>";
1201 std::string element7 = "</material>";
1202
1203 std::string indention = fIndention + fkBasicIndention;
1204
1205 // Write element
1206 fOutFile << fIndention;
1207 fOutFile << element1 << materialName << quota;
1208
1209 fOutFile << element2;
1210 SmartPut(fOutFile, fNW + 1, fNP, 0, density, element3);
1211 fOutFile << std::endl;
1212
1213 for (int i = 0; i < int(material->NofElements()); i++) {
1214 double atomCount = material->AtomCount(i);
1215 std::string elementSymbol = ElementSymbol(material->Element(i));
1216
1217 fOutFile << indention << element4 << elementSymbol << quota;
1218 fOutFile << element5;
1219 SmartPut(fOutFile, fNW, fNP, 0, atomCount, element6);
1220 fOutFile << std::endl;
1221 }
1222
1223 fOutFile << fIndention << element7 << std::endl;
1224}
1225
1226//_____________________________________________________________________________
1228{
1229 // Write medium.
1230
1231 std::string mediumName = UpdateName(medium->Name());
1232 RegisterName(mediumName);
1233
1234 // Get parameters
1235 std::string materialName =
1236 UpdateName(medium->Material()->Name(), fgkMaterialNameExtension);
1237
1238 // Compose material string template
1239 std::string quota = "\" ";
1240 std::string element1 = "<medium name=\"";
1241 std::string element2 = "material=\"";
1242 std::string element3 = "color=\"random\"";
1243 std::string element4 = "sensitive=\"true\"";
1244 std::string element5 = "parameters=\"";
1245 std::string element6 = "; ";
1246 std::string element7 = "\"/>";
1247
1248 std::string indention = fIndention + fkBasicIndention;
1249
1250 // Write element
1251 fOutFile << fIndention;
1252 fOutFile << element1 << mediumName << quota << std::endl;
1253
1254 fOutFile << indention << element2 << materialName << quota << std::endl;
1255 fOutFile << indention << element3 << std::endl;
1256 fOutFile << indention << element4 << std::endl;
1257 fOutFile << indention << element5;
1258
1259 for (int i = 0; i < medium->NofParameters(); i++) {
1260 double parameter = medium->Parameter(i);
1261 std::string separator = element6;
1262 if (i == medium->NofParameters() - 1) separator = element7;
1263 SmartPut(fOutFile, fNW, fNP, 0, parameter, separator);
1264 }
1265 fOutFile << std::endl;
1266}
1267
1268//_____________________________________________________________________________
1270{
1271 // Write medium element from material.
1272
1273 std::string mediumName = UpdateName(material->Name());
1274 RegisterName(mediumName);
1275
1276 // Get parameters
1277 std::string materialName =
1278 UpdateName(material->Name(), fgkMaterialNameExtension);
1279
1280 // Compose material string template
1281 std::string quota = "\" ";
1282 std::string element1 = "<medium name=\"";
1283 std::string element2 = "material=\"";
1284 std::string element3 = "color=\"random\"";
1285 std::string element4 = "sensitive=\"true\"";
1286 std::string element5 = "parameters=\"\"/>";
1287
1288 std::string indention = fIndention + fkBasicIndention;
1289
1290 // Write element
1291 fOutFile << fIndention;
1292 fOutFile << element1 << mediumName << quota << std::endl;
1293
1294 fOutFile << indention << element2 << materialName << quota << std::endl;
1295 fOutFile << indention << element3 << std::endl;
1296 fOutFile << indention << element4 << std::endl;
1297 fOutFile << indention << element5 << std::endl;
1298}
1299
1300//_____________________________________________________________________________
1302 std::string volumeName, const VGM::ISolid* solid, std::string mediumName)
1303{
1304 // Get VGM::ISolid concrete type and calls writing function
1305
1306 VGM::SolidType solidType = solid->Type();
1307
1308 if (solidType == VGM::kBox) {
1309 const VGM::IBox* box = dynamic_cast<const VGM::IBox*>(solid);
1310 WriteBox(volumeName, box, UpdateName(mediumName));
1311 return;
1312 }
1313 else if (solidType == VGM::kCons) {
1314 const VGM::ICons* cons = dynamic_cast<const VGM::ICons*>(solid);
1315 WriteCons(volumeName, cons, UpdateName(mediumName));
1316 return;
1317 }
1318 /*
1319 else if (solidType == VGM::kEltu) {
1320 const VGM::IEllipticalTube* eltu
1321 = dynamic_cast<const VGM::IEllipticalTube*>(solid);
1322 WriteEllipticalTube(solidName, eltu);
1323 return;
1324 }
1325 */
1326 else if (solidType == VGM::kPara) {
1327 const VGM::IPara* para = dynamic_cast<const VGM::IPara*>(solid);
1328 WritePara(volumeName, para, UpdateName(mediumName));
1329 return;
1330 }
1331 else if (solidType == VGM::kPolycone) {
1332 const VGM::IPolycone* polycone = dynamic_cast<const VGM::IPolycone*>(solid);
1333 WritePolycone(volumeName, polycone, UpdateName(mediumName));
1334 return;
1335 }
1336 else if (solidType == VGM::kPolyhedra) {
1337 const VGM::IPolyhedra* polyhedra =
1338 dynamic_cast<const VGM::IPolyhedra*>(solid);
1339 WritePolyhedra(volumeName, polyhedra, UpdateName(mediumName));
1340 return;
1341 }
1342 /*
1343 else if (solidType == VGM::kSphere) {
1344 const VGM::ISphere* sphere = dynamic_cast<const VGM::ISphere*>(solid);
1345 WriteSphere(volumeName, sphere, UpdateName(mediumName));
1346 return;
1347 }
1348 else if (solidType == VGM::kTorus) {
1349 const VGM::ITorus* torus = dynamic_cast<const VGM::ITorus*>(solid);
1350 WriteTorus(volumeName, torus, UpdateName(mediumName));
1351 return;
1352 }
1353 */
1354 else if (solidType == VGM::kTrap) {
1355 const VGM::ITrap* trap = dynamic_cast<const VGM::ITrap*>(solid);
1356 WriteTrap(volumeName, trap, UpdateName(mediumName));
1357 return;
1358 }
1359 else if (solidType == VGM::kTrd) {
1360 const VGM::ITrd* trd = dynamic_cast<const VGM::ITrd*>(solid);
1361 WriteTrd(volumeName, trd, UpdateName(mediumName));
1362 return;
1363 }
1364 else if (solidType == VGM::kTubs) {
1365 const VGM::ITubs* tubs = dynamic_cast<const VGM::ITubs*>(solid);
1366 WriteTubs(volumeName, tubs, UpdateName(mediumName));
1367 return;
1368 }
1369 else if (solidType == VGM::kBoolean) {
1370 const VGM::IBooleanSolid* boolean =
1371 dynamic_cast<const VGM::IBooleanSolid*>(solid);
1372 WriteBooleanSolid(volumeName, boolean, UpdateName(mediumName));
1373 return;
1374 }
1375
1376 // Not supported solid
1377 WriteNotSupportedSolid(volumeName, UpdateName(mediumName));
1378}
1379
1380//_____________________________________________________________________________
1382 const std::string& volumeName, const VGM::ThreeVector& position)
1383{
1385
1386 // get parameters
1387 double x = position[0] / LengthUnit();
1388 double y = position[1] / LengthUnit();
1389 double z = position[2] / LengthUnit();
1390
1391 // compose element string template
1392 std::string element1 = "<posXYZ X_Y_Z=\"";
1393 std::string element2 = "\"> <volume name=\"";
1394 std::string element3 = "\"/>";
1395 std::string element4 = "</posXYZ>";
1396
1397 // write element
1398 fOutFile << fIndention << element1;
1399
1400 SmartPut(fOutFile, fNW + 1, fNP, fgkCarTolerance, x, "; ");
1401 SmartPut(fOutFile, fNW + 1, fNP, fgkCarTolerance, y, "; ");
1402 SmartPut(fOutFile, fNW + 1, fNP, fgkCarTolerance, z, "");
1403
1404 fOutFile << element2 << volumeName << element3 << std::endl
1405 << fIndention << element4 << std::endl;
1406}
1407
1408//_____________________________________________________________________________
1410{
1411 // get parameters
1412 std::string volumeName = placement.Volume()->Name();
1413 std::string compName = volumeName;
1414 compName.append(fgkCompNameExtension);
1415 int nd = placement.Volume()->NofDaughters();
1416
1417 VGM::PlacementType placementType = placement.Type();
1418
1419 if (placementType == VGM::kSimplePlacement) {
1420
1421 VGM::Transform transform = placement.Transformation();
1422
1423 // If boolean solid that have to be reflected
1424 // set reflection to the transformation
1425 VGM::IBooleanSolid* booleanSolid =
1426 dynamic_cast<VGM::IBooleanSolid*>(placement.Volume()->Solid());
1427 if (booleanSolid && booleanSolid->ToBeReflected())
1428 transform[VGM::kReflZ] = 1;
1429
1430 // position
1431 VGM::ThreeVector position(3);
1432 position[0] = transform[VGM::kDx];
1433 position[1] = transform[VGM::kDy];
1434 position[2] = transform[VGM::kDz];
1435
1436 // rotation
1437 VGM::ThreeVector rotation(3);
1438 rotation[0] = transform[VGM::kAngleX];
1439 rotation[1] = transform[VGM::kAngleY];
1440 rotation[2] = transform[VGM::kAngleZ];
1441
1442 if (ClhepVGM::HasReflection(transform)) {
1443 WritePlacementWithRotationAndReflection(volumeName, position, rotation);
1444
1445 if (nd > 0)
1446 WritePlacementWithRotationAndReflection(compName, position, rotation);
1447 }
1448 else {
1449 if (IsIdentity(rotation)) {
1450 WritePlacement(volumeName, position);
1451 // if volume is not leaf node place its logical volume
1452 if (nd > 0) WritePlacement(compName, position);
1453 }
1454 else {
1455 WritePlacementWithRotation(volumeName, position, rotation);
1456 if (nd > 0) WritePlacementWithRotation(compName, position, rotation);
1457 }
1458 }
1459 }
1460 else if (placementType == VGM::kMultiplePlacement) {
1461
1462 // get parameters
1463 VGM::Axis axis;
1464 int nReplicas;
1465 double width;
1466 double offset;
1467 double halfGap; // not supported
1468 placement.MultiplePlacementData(axis, nReplicas, width, offset, halfGap);
1469
1470 if (halfGap != 0.) {
1471 std::cerr << "+++ Warning +++" << std::endl;
1472 std::cerr << " XmlVGM::Writer::WritePlacement: " << std::endl;
1473 std::cerr << " Multiple placement with a half gap is not supported. "
1474 << std::endl;
1475 std::cerr << " The half gap parameter will be ignored. " << std::endl;
1476 }
1477
1478 // write multiple position
1479 WriteMultiplePlacement(volumeName, axis, nReplicas, width, offset);
1480
1481 // if volume is not leaf node place its logical volume
1482 if (nd > 0)
1483 WriteMultiplePlacement(compName, axis, nReplicas, width, offset);
1484 }
1485 else if (placementType == VGM::kParameterised) {
1486
1487 // get parameters
1488 std::vector<VGM::Transform> transforms;
1489 std::vector<VGM::IVolume*> volumes;
1490 placement.ParameterisedPlacementData(transforms, volumes);
1491
1492
1493 for (size_t i=0; i<transforms.size(); ++i) {
1494
1495 auto transform = transforms[i];
1496 auto volumeName = volumes[i]->Name();
1497
1498 // position
1499 VGM::ThreeVector position(3);
1500 position[0] = transform[VGM::kDx];
1501 position[1] = transform[VGM::kDy];
1502 position[2] = transform[VGM::kDz];
1503
1504 // rotation
1505 VGM::ThreeVector rotation(3);
1506 rotation[0] = transform[VGM::kAngleX];
1507 rotation[1] = transform[VGM::kAngleY];
1508 rotation[2] = transform[VGM::kAngleZ];
1509
1510 if (IsIdentity(rotation)) {
1511 WritePlacement(volumeName, position);
1512 if (nd > 0) {
1513 WritePlacement(compName, position);
1514 }
1515 }
1516 else {
1517 WritePlacementWithRotation(volumeName, position, rotation);
1518 if (nd > 0) {
1519 WritePlacementWithRotation(compName, position, rotation);
1520 }
1521 }
1522 }
1523 }
1524 else {
1525 std::cerr << "+++ Warning +++" << std::endl;
1526 std::cerr << " XmlVGM::Writer::WritePlacement: " << std::endl;
1527 std::cerr << " Unknown placement type. " << std::endl;
1528 std::cerr << " Volume \"" << placement.Name() << "\" was not converted."
1529 << std::endl;
1530 }
1531}
1532
1533//_____________________________________________________________________________
1535{
1536 // Write empty line
1537
1538 fOutFile << std::endl;
1539}
1540
1541//_____________________________________________________________________________
1543{
1544 // Increase indention
1545
1546 fIndention.append(fkBasicIndention);
1547}
1548
1549//_____________________________________________________________________________
1551{
1552 // Decrease indention
1553
1554 fIndention.replace(fIndention.find(fkBasicIndention), 3, "");
1555}
VGM Axis enumeration.
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 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 std::string Symbol() const =0
Return the symbol 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 elements.
Definition IIsotope.h:28
virtual int N() const =0
Return the effective number of nucleons.
virtual int Z() const =0
Return the effective atomic number.
The VGM interface to materials.
Definition IMaterial.h:44
virtual IElement * Element(int iel) const =0
Return the i-th element constituing this material.
virtual double AtomCount(int iel) const =0
Return the atom count of the i-th element constituing this material.
virtual double Density() const =0
Return the density in g/cm3.
virtual std::string Name() const =0
Return the name of this element.
virtual int NofElements() const =0
Return the number of elements constituing this material.
The VGM interface to tracking medium.
Definition IMedium.h:31
virtual IMaterial * Material() const =0
Return its associated material.
virtual int NofParameters() const =0
Return the number of defined parameters.
virtual double Parameter(int i) const =0
Return the i-th parameter.
virtual std::string Name() const =0
Return its name.
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 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.
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.
virtual int NofDaughters() const =0
Return the number of volume daughters.
The implementation of the interface for the XML writer that writes VGM geometry objects to XML define...
Definition AGDDWriter.h:57
virtual void CloseMedia()
Write media definitions closing.
virtual void WriteMaterial(const VGM::IMaterial *material)
Write VGM material.
virtual void CloseSection(const std::string &)
Write the section closing (if present)
virtual void WriteMedium(const VGM::IMedium *medium)
Write VGM medium.
virtual ~AGDDWriter()
virtual void IncreaseIndention()
Increase indention.
virtual void OpenMaterials()
Write materials definitions opening.
virtual void CloseFile()
Close output file.
virtual void WriteSolid(std::string lvName, const VGM::ISolid *solid, std::string mediumName)
Write VGM solid.
virtual void CloseDocument()
Write XML document closing.
virtual void WriteElement(const VGM::IElement *element)
Write VGM element.
virtual void DecreaseIndention()
Decrease indention.
virtual void WriteEmptyLine()
Write empty line.
virtual void OpenMedia()
Write media definitions opening.
void WritePlacement(const std::string &lvName, const VGM::ThreeVector &position)
virtual void CloseComposition()
Write composition definition closing (if present)
AGDDWriter(const std::string &version="Undefined", const std::string &author="VGM AGGD Writer", const std::string dtdVersion="v7")
virtual void CloseMaterials()
Write materials definitions closing.
virtual void OpenDocument()
Write XML document opening.
virtual void OpenSection(const std::string &topVolume)
Write the section opening (if present)
virtual void WriteIsotope(const VGM::IIsotope *isotope)
Write VGM isotope.
virtual void OpenComposition(const std::string &name, const std::string &)
Write composition definition opening (if present)
virtual void OpenFile(std::string filePath)
Open output file.
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)
std::vector< double > Transform
Definition Transform.h:40
@ 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
@ kTrd
Definition ISolid.h:46
@ kCons
Definition ISolid.h:32
@ kTubs
Definition ISolid.h:47
@ kPara
Definition ISolid.h:38
@ kPolycone
Definition ISolid.h:40
@ kTrap
Definition ISolid.h:45
@ kPolyhedra
Definition ISolid.h:41
@ kBoolean
Definition ISolid.h:48
@ kBox
Definition ISolid.h:31
std::string IsotopeName(const VGM::IIsotope *isotope)
Definition utilities.cxx:86
std::string Date()
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