VGM Version 5.3
Loading...
Searching...
No Matches
Factory.cxx
Go to the documentation of this file.
1// $Id$
2
3// -----------------------------------------------------------------------
4// The RootGM 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 Factory
14// ---------------
15// The interface to geometry factory.
16//
17// Author: Ivana Hrivnacova; IPN Orsay
18
20
21#include "RootGM/common/Units.h"
22#include "RootGM/common/axis.h"
25#include "RootGM/solids/Arb8.h"
27#include "RootGM/solids/Box.h"
28#include "RootGM/solids/Cons.h"
29#include "RootGM/solids/Ctubs.h"
34#include "RootGM/solids/Hype.h"
36#include "RootGM/solids/Para.h"
44#include "RootGM/solids/Torus.h"
45#include "RootGM/solids/Trap.h"
46#include "RootGM/solids/Trd.h"
47#include "RootGM/solids/Tubs.h"
53
54#include "RVersion.h"
55#include "TGeoArb8.h"
56#include "TGeoCompositeShape.h"
57#include "TGeoCone.h"
58#include "TGeoEltu.h"
59#include "TGeoHalfSpace.h"
60#include "TGeoHype.h"
61#include "TGeoManager.h"
62#include "TGeoPara.h"
63#include "TGeoParaboloid.h"
64#include "TGeoPcon.h"
65#include "TGeoPgon.h"
66#include "TGeoScaledShape.h"
67#include "TGeoShape.h"
68#include "TGeoShapeAssembly.h"
69#include "TGeoSphere.h"
70#include "TGeoTessellated.h"
71#include "TGeoTorus.h"
72#include "TGeoTrd1.h"
73#include "TGeoTrd2.h"
74#include "TGeoVolume.h"
75#include "TGeoXtru.h"
76#include "TObjArray.h"
77
78#include <algorithm>
79
80//_____________________________________________________________________________
82 : VGM::IFactory(),
83 BaseVGM::VFactory("Root_GM_Factory", new RootGM::MaterialFactory()),
84 fTop(0),
85 fSolid(0)
86{
88
89 if (!gGeoManager) new TGeoManager("VGM Root geometry", "VGM Root geometry");
90
91#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 22, 8)
92 // Set Root default units to TGeo
93 TGeoManager::LockDefaultUnits(false);
94 TGeoManager::SetDefaultUnits(TGeoManager::kRootUnits);
95 TGeoManager::LockDefaultUnits(true);
96#endif
97}
98
99//_____________________________________________________________________________
101 : VGM::IFactory(rhs), BaseVGM::VFactory(rhs)
102{
104}
105
106//_____________________________________________________________________________
108{
109 //
110
111 // delete map singletons
115 // There is inconsistence in using the singleton maps
116 // via a factory which is not a singleton
117 // TO DO: to be improved later
118}
119
120//
121// private functions
122//
123
124//_____________________________________________________________________________
125void RootGM::Factory::ImportConstituentSolid(
126 int index, TGeoCompositeShape* solid)
127{
129
130 TGeoShape* consSolid =
132
133 if (!RootGM::SolidMap::Instance()->GetSolid(consSolid)) {
134 VGM::ISolid* vgmSolid = ImportSolid(consSolid);
135 if (Debug()) {
137 if (vgmSolid)
138 std::cout << " Imported solid: " << *vgmSolid << std::endl;
139 else
140 std::cout << " Imported solid: "
141 << "0x0" << std::endl;
142 }
143 }
144}
145
146//_____________________________________________________________________________
147VGM::ISolid* RootGM::Factory::ImportSolid(TGeoShape* shape)
148{
150
151 // Do not import the same solid twice
152 //
153 VGM::ISolid* importedSolid = RootGM::SolidMap::Instance()->GetSolid(shape);
154 if (importedSolid) return importedSolid;
155
156 if (Debug() > 0) {
158 std::cout << "Importing shape: ";
159 if (Debug() > 1) std::cout << shape << " ";
160 std::cout << shape->GetName() << std::endl;
161 }
162
163 TGeoBBox* box = dynamic_cast<TGeoBBox*>(shape);
164 if (box && std::string(shape->ClassName()) == std::string("TGeoBBox")) {
165
166 // Import box if it has not offset defined
167 const Double_t* origin = box->GetOrigin();
168 if (!origin || (origin[0] == 0.0 && origin[1] == 0.0 && origin[2] == 0.0)) {
169
170 // Import box itself
171 return Register(new RootGM::Box(box));
172 }
173
174 // Import box with offset via displaced solid
175 return Register(new RootGM::DisplacedSolid(box));
176 }
177
178 TGeoConeSeg* cons = dynamic_cast<TGeoConeSeg*>(shape);
179 if (cons) {
180 return Register(new RootGM::Cons(cons));
181 }
182
183 TGeoEltu* eltu = dynamic_cast<TGeoEltu*>(shape);
184 if (eltu) {
185 return Register(new RootGM::EllipticalTube(eltu));
186 }
187
188 TGeoCone* cone = dynamic_cast<TGeoCone*>(shape);
189 if (cone) {
190 return Register(new RootGM::Cons(cone));
191 }
192
193 TGeoHalfSpace* halfSpace = dynamic_cast<TGeoHalfSpace*>(shape);
194 if (halfSpace) {
195 return Register(new RootGM::DisplacedSolid(halfSpace));
196 }
197
198 TGeoHype* hype = dynamic_cast<TGeoHype*>(shape);
199 if (hype) {
200 return Register(new RootGM::Hype(hype));
201 }
202
203 TGeoPara* para = dynamic_cast<TGeoPara*>(shape);
204 if (para) {
205 return Register(new RootGM::Para(para));
206 }
207
208 TGeoParaboloid* paraboloid = dynamic_cast<TGeoParaboloid*>(shape);
209 if (paraboloid) {
210 return Register(new RootGM::Paraboloid(paraboloid));
211 }
212
213 TGeoPgon* polyhedra = dynamic_cast<TGeoPgon*>(shape);
214 if (polyhedra) {
215 return Register(new RootGM::Polyhedra(polyhedra));
216 }
217
218 TGeoPcon* polycone = dynamic_cast<TGeoPcon*>(shape);
219 if (polycone) {
220 return Register(new RootGM::Polycone(polycone));
221 }
222
223 TGeoSphere* sphere = dynamic_cast<TGeoSphere*>(shape);
224 if (sphere) {
225 return Register(new RootGM::Sphere(sphere));
226 }
227
228 TGeoTorus* torus = dynamic_cast<TGeoTorus*>(shape);
229 if (torus) {
230 return Register(new RootGM::Torus(torus));
231 }
232
233 TGeoTrap* trap = dynamic_cast<TGeoTrap*>(shape);
234 if (trap) {
235 return Register(new RootGM::Trap(trap));
236 }
237
238 TGeoTrd1* trd1 = dynamic_cast<TGeoTrd1*>(shape);
239 if (trd1) {
240 return Register(new RootGM::Trd(trd1));
241 }
242
243 TGeoTrd2* trd2 = dynamic_cast<TGeoTrd2*>(shape);
244 if (trd2) {
245 return Register(new RootGM::Trd(trd2));
246 }
247
248 TGeoArb8* arb8 = dynamic_cast<TGeoArb8*>(shape);
249 if (arb8) {
250 return Register(new RootGM::Arb8(arb8));
251 }
252
253 TGeoCtub* ctubs = dynamic_cast<TGeoCtub*>(shape);
254 if (ctubs) {
255 return Register(new RootGM::Ctubs(ctubs));
256 }
257
258 TGeoTubeSeg* tubs = dynamic_cast<TGeoTubeSeg*>(shape);
259 if (tubs) {
260 return Register(new RootGM::Tubs(tubs));
261 }
262
263 TGeoTube* tube = dynamic_cast<TGeoTube*>(shape);
264 if (tube) {
265 return Register(new RootGM::Tubs(tube));
266 }
267
268 TGeoXtru* xtru = dynamic_cast<TGeoXtru*>(shape);
269 if (xtru) {
270 return Register(new RootGM::ExtrudedSolid(xtru));
271 }
272
273 TGeoTessellated* tessellated = dynamic_cast<TGeoTessellated*>(shape);
274 if (tessellated) {
275 return Register(new RootGM::TessellatedSolid(tessellated));
276 }
277
278 TGeoShapeAssembly* assembly = dynamic_cast<TGeoShapeAssembly*>(shape);
279 if (assembly) {
280 return 0;
281 }
282
283 TGeoScaledShape* scaled = dynamic_cast<TGeoScaledShape*>(shape);
284 if (scaled) {
285 ImportSolid(scaled->GetShape());
286 return Register(new RootGM::ScaledSolid(scaled));
287 }
288
289 TGeoCompositeShape* composite = dynamic_cast<TGeoCompositeShape*>(shape);
290 if (composite) {
291 ImportConstituentSolid(0, composite);
292 ImportConstituentSolid(1, composite);
293 VGM::IBooleanSolid* vgmBoolean = new RootGM::BooleanSolid(composite);
294 Register(vgmBoolean);
295
296 if (Debug() > 0) {
298 std::cout << "Imported Boolean solid: ";
299 if (Debug() > 1) std::cout << vgmBoolean;
300 std::cout << std::endl;
302 std::cout << *vgmBoolean << std::endl;
303 }
304 return vgmBoolean;
305 }
306
307 std::cerr << " RootGM::Factory::ImportSolid: " << std::endl;
308 std::cerr << " Unsupported solid type (solid \"" << shape->GetName()
309 << "\""
310 << " type \"" << shape->ClassName() << "\")" << std::endl;
311
312 if (Ignore()) {
313 std::cerr << "*** Warning: Using a box instead ***" << std::endl;
314 return Register(new RootGM::Box(shape->GetName(),
315 DummyBoxDimensions() / RootGM::Units::Length(),
316 DummyBoxDimensions() / RootGM::Units::Length(),
317 DummyBoxDimensions() / RootGM::Units::Length()));
318 }
319 else {
320 std::cerr << "*** Error: Aborting execution ***" << std::endl;
321 exit(1);
322 }
323}
324
325//_____________________________________________________________________________
326VGM::IVolume* RootGM::Factory::ImportVolume(TGeoVolume* rootVolume)
327{
328 if (Debug()) {
330 std::cout << "Importing volume: " << rootVolume->GetName() << std::endl;
331 }
332
333 // Import solid
334 VGM::ISolid* solid = ImportSolid(rootVolume->GetShape());
335
336 if (Debug()) {
338 if (solid)
339 std::cout << " Imported solid: " << *solid << std::endl;
340 else
341 std::cout << " Imported solid: "
342 << "0x0" << std::endl;
343 }
344
345 // Do not import assembly volumes
346 if (dynamic_cast<TGeoVolumeAssembly*>(rootVolume)) return 0;
347
348 // Create vgm volume
349 VGM::IVolume* volume = new RootGM::Volume(solid, rootVolume);
350 VolumeStore().push_back(volume);
351 return volume;
352}
353
354//_____________________________________________________________________________
355void RootGM::Factory::ImportDaughters(TGeoVolume* rootVolume)
356{
358
359 if (Debug()) {
361 std::cout << "ImportDaughters for " << rootVolume->GetName() << std::endl;
362 }
363
364 for (int i = 0; i < rootVolume->GetNdaughters(); i++) {
365
366 TGeoVolume* rootDVolume = rootVolume->GetNode(i)->GetVolume();
367
368 VGM::IVolume* dVolume =
370
371 if (!dVolume) {
372 // Import logical volume
373 dVolume = ImportVolume(rootDVolume);
374
375 // Process its daughters
376 ImportDaughters(rootDVolume);
377 }
378 }
379}
380
381//_____________________________________________________________________________
382void RootGM::Factory::ImportAssembly(const TGeoVolume* rootVolume,
383 VGM::IVolume* volume, const TGeoNode* rootAssemblyNode,
384 std::vector<const TGeoNode*>& assemblyNodes)
385{
388
389 TGeoVolume* rootAssemblyVolume = rootAssemblyNode->GetVolume();
390
391 if (!rootAssemblyVolume->IsAssembly()) return;
392
393 assemblyNodes.push_back(rootAssemblyNode);
394
395 for (int i = 0; i < rootAssemblyVolume->GetNdaughters(); i++) {
396
397 TGeoNode* dNode = rootAssemblyVolume->GetNode(i);
398 TGeoVolume* dRootVolume = dNode->GetVolume();
399
400 if (!dRootVolume->IsAssembly()) {
401 VGM::IVolume* dVolume =
403
404 if (Debug() > 0) {
406 std::cout << " " << i << "th assembly daughter rtVol = ";
407 if (Debug() > 1) std::cout << dRootVolume << " ";
408 std::cout << dRootVolume->GetName() << " vgmVol = ";
409 if (Debug() > 1) std::cout << dVolume << " ";
410 std::cout << dVolume->Name() << std::endl;
411 }
412 // Create placement
413 new RootGM::Placement(dVolume, volume, dNode, assemblyNodes);
414 }
415 else {
416 std::vector<const TGeoNode*> assemblyNodes2(assemblyNodes.size());
417 copy(assemblyNodes.begin(), assemblyNodes.end(), assemblyNodes2.begin());
418
419 ImportAssembly(rootVolume, volume, dNode, assemblyNodes2);
420 }
421 }
422}
423
424//_____________________________________________________________________________
425void RootGM::Factory::ImportPlacements(
426 const TGeoVolume* rootVolume, VGM::IVolume* volume)
427{
429
430 for (int i = 0; i < rootVolume->GetNdaughters(); i++) {
431
432 TGeoNode* dNode = rootVolume->GetNode(i);
433 TGeoVolume* dRootVolume = dNode->GetVolume();
434
435 if (Debug() > 0) {
437 std::cout << " " << i << "th daughter rtNode = ";
438 if (Debug() > 1) std::cout << dNode << " ";
439 std::cout << dNode->GetName() << " rtVol = ";
440 if (Debug() > 1) std::cout << dRootVolume << " ";
441 std::cout << dRootVolume->GetName();
442 }
443
444 if (!dRootVolume->IsAssembly()) {
445
446 VGM::IVolume* dVolume =
448
449 // Create placement
450 VGM::IPlacement* dPlacement =
451 new RootGM::Placement(dVolume, volume, dNode);
452
453 if (Debug() > 0) {
454 std::cout << " vgmPl = ";
455 if (Debug() > 1) std::cout << dPlacement << " ";
456 std::cout << dPlacement->Name() << " vgmVol = ";
457 if (Debug() > 1) std::cout << dVolume << " ";
458 std::cout << dVolume->Name() << std::endl;
459 }
460 }
461 else {
462 std::vector<const TGeoNode*> assemblyNodes;
463 ImportAssembly(rootVolume, volume, dNode, assemblyNodes);
464 }
465 }
466}
467
468//_____________________________________________________________________________
469void RootGM::Factory::ImportDivision(
470 const TGeoVolume* rootVolume, VGM::IVolume* volume)
471{
473
474 // Get pattern finder
475 TGeoPatternFinder* finderNonConst = rootVolume->GetFinder();
476
477 // Get the first division volume
478 TGeoNode* dNode = finderNonConst->GetNodeOffset(0);
479 TGeoVolume* dRootVolume = dNode->GetVolume();
480 VGM::IVolume* dVolume = RootGM::VolumeMap::Instance()->GetVolume(dRootVolume);
481
482 if (Debug() > 0) {
484 std::cout << " "
485 << "0th daughter (division) rtNode = ";
486 if (Debug() > 1) std::cout << dNode << " ";
487 std::cout << dNode->GetName() << " rtVol = ";
488 if (Debug() > 1) std::cout << dRootVolume << " ";
489 std::cout << dRootVolume->GetName();
490 }
491
492 // Create placement
493 VGM::IPlacement* placement = new RootGM::Placement(dVolume, volume, dNode);
494
495 if (Debug() > 0) {
496 std::cout << " vgmPl = ";
497 if (Debug() > 1) std::cout << placement << " ";
498 std::cout << placement->Name() << " vgmVol = ";
499 if (Debug() > 1) std::cout << volume << " ";
500 std::cout << volume->Name() << std::endl;
501 }
502}
503
504//_____________________________________________________________________________
505void RootGM::Factory::ImportPositions()
506{
508
509 if (Debug() > 0) {
511 std::cout << "Import positions: " << std::endl;
512 }
513
514 TObjArray* rootVolumes = gGeoManager->GetListOfVolumes();
515
516 for (int i = 0; i < rootVolumes->GetEntriesFast(); i++) {
517
518 TGeoVolume* rootVolume = (TGeoVolume*)rootVolumes->At(i);
519 if (rootVolume->IsAssembly()) continue;
520
521 VGM::IVolume* volume = RootGM::VolumeMap::Instance()->GetVolume(rootVolume);
522
523 if (!volume) continue;
524 // There may be defined volumes which are placed
525 // or not placed withing this top volume
526 // Hence they were not imported and we skip them
527
528 if (Debug() > 0) {
530 std::cout << i << "th volume: " << rootVolume->GetName() << " ";
531 if (Debug() > 1)
532 std::cout << " rt : " << rootVolume << " "
533 << " vgm: " << volume;
534 std::cout << std::endl;
535 }
536
537 if (IsDivided(rootVolume))
538 ImportDivision(rootVolume, volume);
539 else
540 ImportPlacements(rootVolume, volume);
541 }
542}
543
544//_____________________________________________________________________________
545bool RootGM::Factory::Import(void* topNode)
546{
547 //
548 TGeoNode* rootNode = static_cast<TGeoNode*>(topNode);
549
550 return Import(rootNode);
551}
552
553//_____________________________________________________________________________
554bool RootGM::Factory::ImportSolid(void* solid)
555{
556 //
557 TGeoShape* rootSolid = static_cast<TGeoShape*>(solid);
558
559 return Import(rootSolid);
560}
561
562//_____________________________________________________________________________
563bool RootGM::Factory::IsDivided(const TGeoVolume* volume) const
564{
567
568 // Check if division is present
569 const TGeoPatternFinder* finder = volume->GetFinder();
570 if (!finder) return false;
571
572 // Get division axis
573 VGM::Axis axis = Axis(finder);
574 if (axis == VGM::kUnknownAxis) return false;
575
576 // Volume can be processed as VGM division
577 return true;
578}
579
580//_____________________________________________________________________________
581VGM::ISolid* RootGM::Factory::Register(VGM::ISolid* vgmSolid)
582{
584
585 SolidStore().push_back(vgmSolid);
586 return vgmSolid;
587}
588
589//_____________________________________________________________________________
590void RootGM::Factory::EmulateReplicatedSlice(const std::string& name,
591 VGM::IVolume* volume, VGM::IVolume* motherVolume, VGM::Axis axis,
592 int nofItems, double width, double offset, double halfGap)
593{
594 // Only box shape is supported
595 if (motherVolume->Solid()->Type() != VGM::kBox) {
596 std::cerr << " RootGM::Factory:::EmulateReplicatedSlice " << std::endl;
597 std::cerr << " Unsupported solid type \""
598 << VGM::SolidTypeName(motherVolume->Solid()->Type()) << "\", "
599 << "mother volume: \"" << motherVolume->Name() << "\""
600 << std::endl;
601 return;
602 }
603
604 // Compute slice dimensions
605 VGM::IBox* motherBox = dynamic_cast<VGM::IBox*>(motherVolume->Solid());
606 double hx = motherBox->XHalfLength();
607 double hy = motherBox->YHalfLength();
608 double hz = motherBox->ZHalfLength();
609
610 if (axis == VGM::kXAxis) {
611 hx = (width - 2. * halfGap) / 2.;
612 }
613 else if (axis == VGM::kYAxis) {
614 hy = (width - 2. * halfGap) / 2.;
615 }
616 else if (axis == VGM::kZAxis) {
617 hz = (width - 2. * halfGap) / 2.;
618 }
619
620 // Create the cell solid
621 // (Should not be needed if the slice solid is correct- check)
622 VGM::IBox* sliceBox = dynamic_cast<VGM::IBox*>(volume->Solid());
623 VGM::IVolume* sliceVolume = volume;
624
625 // Check dimensions
626 if (sliceBox->XHalfLength() != hx || sliceBox->YHalfLength() != hy ||
627 sliceBox->ZHalfLength() != hz) {
628 std::cerr << " RootGM::Factory:::EmulateReplicatedSlice " << std::endl;
629 std::cerr << " Slice solid dimensions do not respect multiple placement "
630 "parameters."
631 << std::endl;
632 std::cerr << " Solid dimensions: " << sliceBox->XHalfLength() << ","
633 << sliceBox->YHalfLength() << "," << sliceBox->ZHalfLength()
634 << "," << std::endl;
635 std::cerr << " Expected: " << hx << "," << hy << "," << hz << ","
636 << std::endl;
637 std::cerr << " New solid and volume will be created." << std::endl;
638
639 VGM::ISolid* newSolid = CreateBox(volume->Solid()->Name(), hx, hy, hz);
640 sliceVolume = CreateVolume(volume->Name(), newSolid, volume->MediumName());
641 }
642
643 if (BestMatch()) {
644 // Compute start position and its delta for a=each copy
645 std::vector<double> start = { 0., 0., 0. };
646 std::vector<double> delta = { 0., 0., 0. };
647
648 if (axis == VGM::kXAxis) {
649 delta[0] = width;
650 start[0] = -motherBox->XHalfLength() + offset + width / 2.;
651 }
652 else if (axis == VGM::kYAxis) {
653 delta[1] = width;
654 start[1] = -motherBox->YHalfLength() + offset + width / 2.;
655 }
656 else if (axis == VGM::kZAxis) {
657 delta[2] = width;
658 start[2] = -motherBox->ZHalfLength() + offset + width / 2.;
659 }
660
661 // Place the slice multiple times
662 for (int i = 0; i < nofItems; ++i) {
663 // Define trasformation
664 std::cout << i << "th position: " << start[0] + i * delta[0] << ",";
665 std::cout << start[1] + i * delta[1] << ",";
666 std::cout << start[2] + i * delta[2] << std::endl;
667
668 VGM::Transform transform = { start[0] + i * delta[0],
669 start[1] + i * delta[1], start[2] + i * delta[2], 0., 0., 0., 0. };
670
671 CreatePlacement(name, i, sliceVolume, motherVolume, transform);
672 }
673 }
674 else {
675 // Create an interim volume (envelope) by division and place the slice
676 // inside it
677 std::string nameBis = name + "bis";
678 VGM::IVolume* volumeBis =
679 CreateVolume(nameBis, volume->Solid(), motherVolume->MediumName());
680
681 // Create TGeo division without gaps
682 BaseVGM::VPlacement* placement = new RootGM::Placement(
683 nameBis, volumeBis, motherVolume, axis, nofItems, width, offset);
684
685 // Import divison volume
686 // (The VGM::IVolume* volume is ignored)
687 TGeoNode* node = RootGM::PlacementMap::Instance()->GetPlacement(placement);
688 TGeoVolume* rootVolume = node->GetVolume();
689 rootVolume->SetName(volumeBis->Name().data());
690 (dynamic_cast<RootGM::Volume*>(volumeBis))->ResetVolume(rootVolume);
691
692 // Place the slice volume in the created division
693 VGM::Transform transform = { 0, 0, 0, 0, 0, 0, 0 };
694 CreatePlacement(name, 0, sliceVolume, volumeBis, transform);
695 }
696}
697
698//
699// protected functions
700//
701
702//_____________________________________________________________________________
704{
706
707 fSolid = solid;
708}
709
710//
711// public functions
712//
713
714//_____________________________________________________________________________
716 const std::string& name, double hz, std::vector<VGM::TwoVector> vertices)
717{
718 //
719 return Register(new RootGM::Arb8(name, hz, vertices));
720}
721
722//_____________________________________________________________________________
724 const std::string& name, double hx, double hy, double hz)
725{
726 //
727 return Register(new RootGM::Box(name, hx, hy, hz));
728}
729
730//_____________________________________________________________________________
731VGM::ISolid* RootGM::Factory::CreateCons(const std::string& name, double rin1,
732 double rout1, double rin2, double rout2, double hz, double sphi, double dphi)
733{
734 //
735 return Register(
736 new RootGM::Cons(name, rin1, rout1, rin2, rout2, hz, sphi, dphi));
737}
738
739//_____________________________________________________________________________
740VGM::ISolid* RootGM::Factory::CreateCtubs(const std::string& name, double rin,
741 double rout, double hz, double sphi, double dphi, double nxlow, double nylow,
742 double nzlow, double nxhigh, double nyhigh, double nzhigh)
743{
744 //
745 return Register(new RootGM::Ctubs(name, rin, rout, hz, sphi, dphi, nxlow,
746 nylow, nzlow, nxhigh, nyhigh, nzhigh));
747}
748
749//_____________________________________________________________________________
751 double dx, double dy, double dz, double zBottomCut, double zTopCut)
752{
753 //
754 return Register(new RootGM::Ellipsoid(name, dx, dy, dz, zBottomCut, zTopCut));
755}
756
757//_____________________________________________________________________________
759 const std::string& name, double dx, double dy, double hz)
760{
761 //
762 return Register(new RootGM::EllipticalTube(name, dx, dy, hz));
763}
764
765//_____________________________________________________________________________
766VGM::ISolid* RootGM::Factory::CreateHype(const std::string& name, double r1,
767 double r2, double stereo1, double stereo2, double hz)
768{
769 //
770 return Register(new RootGM::Hype(name, r1, r2, stereo1, stereo2, hz));
771}
772
773//_____________________________________________________________________________
774VGM::ISolid* RootGM::Factory::CreatePara(const std::string& name, double dx,
775 double dy, double dz, double alpha, double theta, double phi)
776{
777 //
778 return Register(new RootGM::Para(name, dx, dy, dz, alpha, theta, phi));
779}
780
781//_____________________________________________________________________________
783 const std::string& name, double r1, double r2, double hz)
784{
785 //
786 return Register(new RootGM::Paraboloid(name, r1, r2, hz));
787}
788
789//_____________________________________________________________________________
791 double sphi, double dphi, int nofZplanes, double* z, double* rin,
792 double* rout)
793{
794 //
795 return Register(
796 new RootGM::Polycone(name, sphi, dphi, nofZplanes, z, rin, rout));
797}
798
799//_____________________________________________________________________________
801 double sphi, double dphi, int nofSides, int nofZplanes, double* z,
802 double* rin, double* rout)
803{
804 //
805 return Register(new RootGM::Polyhedra(
806 name, sphi, dphi, nofSides, nofZplanes, z, rin, rout));
807}
808
809//_____________________________________________________________________________
810VGM::ISolid* RootGM::Factory::CreateSphere(const std::string& name, double rin,
811 double rout, double sphi, double dphi, double stheta, double dtheta)
812{
813 //
814 return Register(
815 new RootGM::Sphere(name, rin, rout, sphi, dphi, stheta, dtheta));
816}
817
818//_____________________________________________________________________________
820 const std::string& name, std::vector<std::vector<VGM::ThreeVector> > facets)
821{
822 //
823 return Register(new RootGM::TessellatedSolid(name, facets));
824}
825
826//_____________________________________________________________________________
827VGM::ISolid* RootGM::Factory::CreateTorus(const std::string& name, double rin,
828 double rout, double rax, double sphi, double dphi)
829{
830 //
831 return Register(new RootGM::Torus(name, rin, rout, rax, sphi, dphi));
832}
833
834//_____________________________________________________________________________
835VGM::ISolid* RootGM::Factory::CreateTrap(const std::string& name, double hz,
836 double theta, double phi, double dy1, double dx1, double dx2, double alpha1,
837 double dy2, double dx3, double dx4, double alpha2)
838{
839 //
840 return Register(new RootGM::Trap(
841 name, hz, theta, phi, dy1, dx1, dx2, alpha1, dy2, dx3, dx4, alpha2));
842}
843
844//_____________________________________________________________________________
845VGM::ISolid* RootGM::Factory::CreateTrd(const std::string& name, double hx1,
846 double hx2, double hy1, double hy2, double hz)
847{
848 //
849 return Register(new RootGM::Trd(name, hx1, hx2, hy1, hy2, hz));
850}
851
852//_____________________________________________________________________________
853VGM::ISolid* RootGM::Factory::CreateTubs(const std::string& name, double rin,
854 double rout, double hz, double sphi, double dphi)
855{
856 //
857 return Register(new RootGM::Tubs(name, rin, rout, hz, sphi, dphi));
858}
859
860//_____________________________________________________________________________
862 std::vector<VGM::TwoVector> polygon,
863 std::vector<std::vector<double> > zsections)
864{
865 //
866 return Register(new RootGM::ExtrudedSolid(name, polygon, zsections));
867}
868
869//_____________________________________________________________________________
871 VGM::ISolid* solidA, VGM::ISolid* solidB, const VGM::Transform& transform)
872{
873 //
874 return Register(new RootGM::BooleanSolid(
875 name, VGM::kIntersection, solidA, solidB, CreateTransform(transform)));
876}
877
878//_____________________________________________________________________________
880 VGM::ISolid* solidA, VGM::ISolid* solidB, const VGM::Transform& transform)
881{
882 //
883 return Register(new RootGM::BooleanSolid(
884 name, VGM::kSubtraction, solidA, solidB, CreateTransform(transform)));
885}
886
887//_____________________________________________________________________________
889 VGM::ISolid* solidA, VGM::ISolid* solidB, const VGM::Transform& transform)
890{
891 //
892 return Register(new RootGM::BooleanSolid(
893 name, VGM::kUnion, solidA, solidB, CreateTransform(transform)));
894}
895
896//_____________________________________________________________________________
898 const std::string& name, VGM::ISolid* solid, const VGM::Transform& transform)
899{
900 //
901 return Register(
902 new RootGM::DisplacedSolid(name, solid, CreateTransform(transform)));
903}
904
905//_____________________________________________________________________________
907 const std::string& name, VGM::ISolid* solid, const VGM::Transform& transform)
908{
909 //
910 return Register(new RootGM::ScaledSolid(name, solid, CreateScale(transform)));
911}
912
913//_____________________________________________________________________________
915 std::vector<VGM::ISolid*> constituents,
916 std::vector<VGM::Transform> transforms)
917{
918 //
919 std::vector<TGeoMatrix*> rootTransforms;
920 for (auto transform : transforms) {
921 rootTransforms.push_back(CreateTransform(transform));
922 }
923
924 return Register(new RootGM::MultiUnion(name, constituents, rootTransforms));
925}
926
927//_____________________________________________________________________________
929 const std::string& name, VGM::ISolid* solid, const std::string& mediumName)
930{
931 //
932 VGM::IVolume* volume = new RootGM::Volume(name, solid, mediumName);
933
934 VolumeStore().push_back(volume);
935 return volume;
936}
937
938//_____________________________________________________________________________
940 int copyNo, VGM::IVolume* volume, VGM::IVolume* motherVolume,
941 const VGM::Transform& transform)
942{
943 //
944 VGM::IPlacement* placement = new RootGM::Placement(
945 name, copyNo, volume, motherVolume, CreateTransform(transform));
946
947 // Top volume
948 if (!motherVolume) {
949 if (!fTop)
950 fTop = placement;
951 else {
952 std::cerr << " RootGM::Factory::CreatePlacement:" << std::endl;
953 std::cerr << " Top volume defided twice!" << std::endl;
954 std::cerr << "*** Error: Aborting execution ***" << std::endl;
955 exit(1);
956 }
957 }
958
959 return placement;
960}
961
962//_____________________________________________________________________________
964 const std::string& name, VGM::IVolume* volume, VGM::IVolume* motherVolume,
965 VGM::Axis axis, int nofItems, double width, double offset, double halfGap)
966{
967 //
968 // Cannot be top volume
969 if (!motherVolume) {
970 std::cerr << " RootGM::Factory::CreateMultiplePlacement:" << std::endl;
971 std::cerr << " Mother volume not defined!" << std::endl;
972 std::cerr << "*** Error: Aborting execution ***" << std::endl;
973 exit(1);
974 }
975
976 if (halfGap != 0) {
977 EmulateReplicatedSlice(
978 name, volume, motherVolume, axis, nofItems, width, offset, halfGap);
979 return 0;
980 }
981 else {
982
983 // Create TGeo division
984 BaseVGM::VPlacement* placement = new RootGM::Placement(
985 name, volume, motherVolume, axis, nofItems, width, offset);
986
987 // Import divison volume
988 // (The VGM::IVolume* volume is ignored)
989 TGeoNode* node = RootGM::PlacementMap::Instance()->GetPlacement(placement);
990 TGeoVolume* rootVolume = node->GetVolume();
991 rootVolume->SetName(volume->Name().data());
992 // Now we should copy old root volume daughters to this new one
993 // but there is no way to do it
994 // For the time being only check if it happens
995
996 TGeoVolume* oldVolume = RootGM::VolumeMap::Instance()->GetVolume(volume);
997 oldVolume->SetName("volumeNotPlacedInGeometry");
998 if (oldVolume->GetNdaughters() > 0) {
999 std::cerr << "*** Limitation ***" << std::endl;
1000 std::cerr << " RootGM::Factory::CreateMultiplePlacement: "
1001 << std::endl;
1002 std::cerr << " Daughters of divided volume can be set " << std::endl
1003 << " only after multiple placement definition." << std::endl
1004 << " Geometry would be incomplete." << std::endl;
1005 exit(1);
1006 }
1007
1008 (dynamic_cast<RootGM::Volume*>(volume))->ResetVolume(rootVolume);
1009
1010 return placement;
1011 }
1012}
1013
1014//_____________________________________________________________________________
1016 const std::string& name, VGM::IVolume* motherVolume,
1017 const std::vector<VGM::Transform>& transforms,
1018 const std::vector<VGM::IVolume*>& volumes)
1019{
1020 //
1021 // Cannot be top volume
1022 if (!motherVolume) {
1023 std::cerr << " RootGM::Factory::CreateParameterisedPlacement:"
1024 << std::endl;
1025 std::cerr << " Mother volume not defined!" << std::endl;
1026 std::cerr << "*** Error: Aborting execution ***" << std::endl;
1027 exit(1);
1028 }
1029
1030 // the vector sizes cannot be different
1031 if (transforms.size() != volumes.size()) {
1032 std::cerr << " RootGM::Factory::CreateParameterisedPlacement:"
1033 << std::endl;
1034 std::cerr << " Transformations and Volumes vector sizes cannot be different!"
1035 << std::endl;
1036 std::cerr << "*** Error: Aborting execution ***" << std::endl;
1037 exit(1);
1038 }
1039
1040 for (size_t i = 0; i < transforms.size(); ++i) {
1041 CreatePlacement(name, i, volumes[i], motherVolume, transforms[i]);
1042 }
1043
1044 return 0;
1045}
1046
1047//_____________________________________________________________________________
1049{
1051
1052 return fTop;
1053}
1054
1055//_____________________________________________________________________________
1057{
1059
1060 return fSolid;
1061}
1062
1063//_____________________________________________________________________________
1064TGeoNode* RootGM::Factory::World() const
1065{
1067
1069}
1070
1071//_____________________________________________________________________________
1072TGeoShape* RootGM::Factory::Solid() const
1073{
1075
1076 return RootGM::SolidMap::Instance()->GetSolid(fSolid);
1077}
1078
1079//_____________________________________________________________________________
1080bool RootGM::Factory::Import(TGeoNode* topNode)
1081{
1083
1084 if (Debug() > 0) {
1086 std::cout << "RootGM::Factory::Import started ...";
1087 if (Debug() > 1) std::cout << topNode;
1088 std::cout << std::endl;
1089 }
1090
1091 // Inactivate single mode (if it was switch previously)
1092 //
1093 SetSingleMode(false);
1094
1095 // Import materials
1096 //
1098
1099 // Get top volume
1100 TGeoVolume* topVolume = topNode->GetVolume();
1101
1102 // Import the top volume
1103 VGM::IVolume* worldVolume = ImportVolume(topVolume);
1104
1105 // Import recursively all daughters
1106 ImportDaughters(topVolume);
1107
1108 // Import positions
1109 ImportPositions();
1110
1111 if (Debug() > 0) {
1113 std::cout << std::endl;
1114 PrintSolids();
1115 PrintVolumes();
1116 if (Debug() > 1) RootGM::VolumeMap::Instance()->Print();
1117 }
1118
1119 // Position the top volume
1120 fTop = new RootGM::Placement(worldVolume, 0, topNode);
1121
1122 if (Debug() > 0) {
1124 std::cout << "RootGM::Factory::Import finished." << std::endl;
1125 }
1126
1127 return true;
1128}
1129
1130//_____________________________________________________________________________
1131bool RootGM::Factory::Import(TGeoShape* shape)
1132{
1135
1136 if (Debug() > 0) {
1138 std::cout << "RootGM::Factory::Import of one solid started ...";
1139 if (Debug() > 1) std::cout << shape;
1140 std::cout << std::endl;
1141 }
1142
1143 // Clear solid store
1144 // (Do not delete objects as they are also referenced in a singleton mao)
1145 SolidStore().clear();
1146
1147 // Activate single mode
1148 //
1149 SetSingleMode(true);
1150
1151 // Import shape
1152 fSolid = ImportSolid(shape);
1153
1154 if (Debug() > 0) {
1156 std::cout << "RootGM::Factory::Import of one solid finished." << std::endl;
1157 }
1158
1159 return (fSolid != 0);
1160}
The abstract base class to positions of volumes.
Definition VPlacement.h:32
VGM implementation for Root Arb8 solid.
Definition Arb8.h:33
VGM implementation for Root Boolean solid.
static TGeoShape * GetConstituentSolid(int index, TGeoCompositeShape *compositeShape)
VGM implementation for Root box solid.
Definition Box.h:32
VGM implementation for Root cons solid.
Definition Cons.h:32
VGM implementation for Root cut tubs solid.
Definition Ctubs.h:32
VGM implementation for Root displaced solid.
VGM implementation for Root ellipsoid solid.
Definition Ellipsoid.h:33
VGM implementation for Root elliptical tube solid.
VGM implementation for Root extruded solid.
VGM factory for Root.
Definition Factory.h:44
virtual VGM::ISolid * CreateTubs(const std::string &name, double rin, double rout, double hz, double sphi, double dphi)
Create the trd solid = phi segment of a tube.
Definition Factory.cxx:853
TGeoNode * World() const
Definition Factory.cxx:1064
virtual VGM::ISolid * CreatePara(const std::string &name, double dx, double dy, double dz, double alpha, double theta, double phi)
Create the para solid = parallelepiped.
Definition Factory.cxx:774
virtual VGM::ISolid * CreateCons(const std::string &name, double rin1, double rout1, double rin2, double rout2, double hz, double sphi, double dphi)
Create the cons solid = phi segment of a conical tube.
Definition Factory.cxx:731
virtual VGM::ISolid * CreateMultiUnion(const std::string &name, std::vector< VGM::ISolid * > constituents, std::vector< VGM::Transform > transforms)
Create the multi union of solids.
Definition Factory.cxx:914
virtual VGM::ISolid * CreateHype(const std::string &name, double r1, double r2, double stereo1, double stereo2, double hz)
Create the hyperboloid solid.
Definition Factory.cxx:766
virtual VGM::ISolid * CreateSubtractionSolid(const std::string &name, VGM::ISolid *solidA, VGM::ISolid *solidB, const VGM::Transform &transform)
Create the subtraction of two solids.
Definition Factory.cxx:879
virtual VGM::IPlacement * Top() const
Return the top volume placement.
Definition Factory.cxx:1048
virtual VGM::IPlacement * CreateMultiplePlacement(const std::string &name, VGM::IVolume *volume, VGM::IVolume *motherVolume, VGM::Axis axis, int nofItems, double width, double offset, double halfGap)
Create the multiple volume placement.
Definition Factory.cxx:963
virtual VGM::IPlacement * CreatePlacement(const std::string &name, int copyNo, VGM::IVolume *volume, VGM::IVolume *motherVolume, const VGM::Transform &transform)
Create the simple volume placement.
Definition Factory.cxx:939
virtual VGM::ISolid * CreateEllipsoid(const std::string &name, double dx, double dy, double dz, double zBottomCut, double zTopCut)
Create the ellipsoid solid.
Definition Factory.cxx:750
virtual VGM::ISolid * CreateTrd(const std::string &name, double hx1, double hx2, double hy1, double hy2, double hz)
Create the trd solid = a trapezoid with the x and y dimensions varying along z.
Definition Factory.cxx:845
virtual VGM::ISolid * CreatePolycone(const std::string &name, double sphi, double dphi, int nofZplanes, double *z, double *rin, double *rout)
Create the polycone solid = phi segment of a polycone.
Definition Factory.cxx:790
virtual VGM::ISolid * CreateScaledSolid(const std::string &name, VGM::ISolid *solid, const VGM::Transform &transform)
Create scaled solid.
Definition Factory.cxx:906
virtual VGM::ISolid * CreateEllipticalTube(const std::string &name, double dx, double dy, double hz)
Create the elliptical tube solid.
Definition Factory.cxx:758
virtual VGM::ISolid * CreateBox(const std::string &name, double hx, double hy, double hz)
Create the box solid.
Definition Factory.cxx:723
virtual VGM::IVolume * CreateVolume(const std::string &name, VGM::ISolid *solid, const std::string &mediumName)
Create the volume.
Definition Factory.cxx:928
TGeoShape * Solid() const
Definition Factory.cxx:1072
virtual VGM::ISolid * CreateTrap(const std::string &name, double hz, double theta, double phi, double dy1, double dx1, double dx2, double alpha1, double dy2, double dx3, double dx4, double alpha2)
Create the trap solid = general trapezoid ( Note that of the 11 parameters described below,...
Definition Factory.cxx:835
virtual VGM::IPlacement * CreateParameterisedPlacement(const std::string &name, VGM::IVolume *motherVolume, const std::vector< VGM::Transform > &transforms, const std::vector< VGM::IVolume * > &volumes)
Create the parameterised volume placement.
Definition Factory.cxx:1015
virtual VGM::ISolid * CreateArb8(const std::string &name, double hz, std::vector< VGM::TwoVector > vertices)
Create the arbitrary trapezoid with 8 vertices standing on two paralel planes perpendicular to Z axis...
Definition Factory.cxx:715
virtual VGM::ISolid * CreateTessellatedSolid(const std::string &name, std::vector< std::vector< VGM::ThreeVector > > facets)
Create tessellated solid = solid composed from triangular and rectangular facets.
Definition Factory.cxx:819
virtual VGM::ISolid * CreateTorus(const std::string &name, double rin, double rout, double rax, double sphi, double dphi)
Create the torus solid = phi segment of a torus.
Definition Factory.cxx:827
virtual ~Factory()
Definition Factory.cxx:107
virtual VGM::ISolid * CreateCtubs(const std::string &name, double rin, double rout, double hz, double sphi, double dphi, double nxlow, double nylow, double nzlow, double nxhigh, double nyhigh, double nzhigh)
Create the cut tubs solid = phi segment of a tube cut with two planes.
Definition Factory.cxx:740
virtual VGM::ISolid * CreateParaboloid(const std::string &name, double r1, double r2, double hz)
Create the paraboloid solid.
Definition Factory.cxx:782
virtual VGM::ISolid * CreatePolyhedra(const std::string &name, double sphi, double dphi, int nofSides, int nofZplanes, double *z, double *rin, double *rout)
Create the polyhedra solid = phi segment of a polyhedra (polygone)
Definition Factory.cxx:800
virtual VGM::ISolid * SingleSolid() const
Return solid (if in one solid conversion mode)
Definition Factory.cxx:1056
virtual void SetSolid(VGM::ISolid *solid)
Set solid (in single mode)
Definition Factory.cxx:703
virtual VGM::ISolid * CreateIntersectionSolid(const std::string &name, VGM::ISolid *solidA, VGM::ISolid *solidB, const VGM::Transform &transform)
Create the intersection of two solids.
Definition Factory.cxx:870
virtual VGM::ISolid * CreateExtrudedSolid(const std::string &name, std::vector< VGM::TwoVector > polygon, std::vector< std::vector< double > > zsections)
Create the extruded solid.
Definition Factory.cxx:861
virtual VGM::ISolid * CreateUnionSolid(const std::string &name, VGM::ISolid *solidA, VGM::ISolid *solidB, const VGM::Transform &transform)
Create the union of two solids.
Definition Factory.cxx:888
virtual VGM::ISolid * CreateSphere(const std::string &name, double rin, double rout, double sphi, double dphi, double stheta, double dtheta)
Create the sphere solid = phi segment of a spherical shell.
Definition Factory.cxx:810
virtual VGM::ISolid * CreateDisplacedSolid(const std::string &name, VGM::ISolid *solid, const VGM::Transform &transform)
Create displaced solid.
Definition Factory.cxx:897
bool Import(TGeoNode *topNode)
Definition Factory.cxx:1080
VGM implementation for Root hyperboloid solid.
Definition Hype.h:32
VGM material factory for Root.
virtual bool Import()
Import native materials.
VGM implementation for Root Boolean solid.
Definition MultiUnion.h:36
VGM implementation for Root para solid.
Definition Para.h:32
VGM implementation for Root paraboloid solid.
Definition Paraboloid.h:32
TGeoNode * GetPlacement(VGM::IPlacement *iPlacement) const
static PlacementMap * Instance()
VGM implementation for Root positions of volumes.
Definition Placement.h:41
VGM implementation for Root polycone solid.
Definition Polycone.h:32
VGM implementation for Root polyhedra solid.
Definition Polyhedra.h:32
VGM implementation for Root Scaled solid.
Definition ScaledSolid.h:34
TGeoShape * GetSolid(VGM::ISolid *iSolid) const
Definition SolidMap.cxx:86
static SolidMap * Instance()
Definition SolidMap.cxx:28
VGM implementation for Root sphere solid.
Definition Sphere.h:32
VGM implementation for Root tessellated solid.
VGM implementation for Root torus solid.
Definition Torus.h:32
VGM implementation for Root trap solid.
Definition Trap.h:32
VGM implementation for Root trd solid.
Definition Trd.h:33
VGM implementation for Root tubs solid.
Definition Tubs.h:32
static double Length()
Return Root length unit in VGM units.
Definition Units.h:84
static VolumeMap * Instance()
Definition VolumeMap.cxx:28
void Print() const
Definition VolumeMap.cxx:72
TGeoVolume * GetVolume(VGM::IVolume *iVolume) const
Definition VolumeMap.cxx:92
VGM implementation for Root volume.
Definition Volume.h:36
VGM Axis enumeration.
The VGM interface to Boolean solids.
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 positions of volumes.
Definition IPlacement.h:44
virtual std::string Name() const =0
Return the name of this placement.
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 volumes.
Definition IVolume.h:32
virtual ISolid * Solid() const =0
Return the associated solid.
virtual std::string Name() const =0
Return the name of this volume.
virtual std::string MediumName() const =0
Return the name of the associated medium.
BaseVGM utilities.
Definition utilities.h:23
void DebugInfo()
Debug printing.
Definition utilities.cxx:27
VGM implementation for Root.
Definition axis.h:28
TGeoScale * CreateScale(const VGM::Transform &transform)
TGeoMatrix * CreateTransform(const VGM::Transform &transform)
VGM::Axis Axis(const TGeoPatternFinder *finder)
Definition axis.cxx:33
VGM interfaces.
Definition VMedium.h:28
std::vector< double > Transform
Definition Transform.h:40
std::string SolidTypeName(VGM::SolidType typeId)
Definition solid.cxx:27
@ kIntersection
@ kSubtraction
std::vector< IVolume * > VolumeStore
Definition IFactory.h:43
@ kYAxis
Definition Axis.h:36
@ kXAxis
Definition Axis.h:35
@ kUnknownAxis
Definition Axis.h:42
@ kZAxis
Definition Axis.h:37
std::vector< ISolid * > SolidStore
Definition IFactory.h:42
@ kBox
Definition ISolid.h:31