Garfield++ 3.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
ViewGeometry.cc
Go to the documentation of this file.
1#include <cmath>
2#include <iostream>
3
4#include <TGeoBBox.h>
5#include <TGeoCone.h>
6#include <TGeoArb8.h>
7#include <TGeoBoolNode.h>
8#include <TGeoCompositeShape.h>
9
13#include "Garfield/Plotting.hh"
14#include "Garfield/Solid.hh"
16
17namespace Garfield {
18
21}
22
24 Reset();
25}
26
28 if (!geo) {
29 std::cerr << m_className << "::SetGeometry: Null pointer.\n";
30 return;
31 }
32
33 m_geometry = geo;
34}
35
37 if (!m_geometry) {
38 std::cerr << m_className << "::Plot: Geometry is not defined.\n";
39 return;
40 }
41
42 if (!m_canvas) {
43 m_canvas = new TCanvas();
45 }
46 m_canvas->cd();
47
48 const unsigned int nSolids = m_geometry->GetNumberOfSolids();
49 if (nSolids == 0) {
50 std::cerr << m_className << "::Plot: Geometry is empty.\n";
51 return;
52 }
53
54 // Get the bounding box.
55 double xMin = 0., yMin = 0., zMin = 0.;
56 double xMax = 0., yMax = 0., zMax = 0.;
57 if (!m_geometry->GetBoundingBox(xMin, yMin, zMin, xMax, yMax, zMax)) {
58 std::cerr << m_className << "::Plot: Cannot retrieve bounding box.\n";
59 return;
60 }
61 gGeoManager = nullptr;
62 m_geoManager.reset(new TGeoManager("ViewGeometryGeoManager", ""));
63 TGeoMaterial* matVacuum = new TGeoMaterial("Vacuum", 0., 0., 0.);
64 TGeoMedium* medVacuum = new TGeoMedium("Vacuum", 1, matVacuum);
65 m_media.push_back(medVacuum);
66 // Use silicon as "default" material.
67 TGeoMaterial* matDefault = new TGeoMaterial("Default", 28.085, 14., 2.329);
68 TGeoMedium* medDefault = new TGeoMedium("Default", 1, matDefault);
69 TGeoVolume* world = m_geoManager->MakeBox(
70 "World", medVacuum, std::max(fabs(xMin), fabs(xMax)),
71 std::max(fabs(yMin), fabs(yMax)), std::max(fabs(zMin), fabs(zMax)));
72 m_geoManager->SetTopVolume(world);
73 m_volumes.push_back(world);
74
75 for (unsigned int i = 0; i < nSolids; ++i) {
76 Solid* solid = m_geometry->GetSolid(i);
77 if (!solid) {
78 std::cerr << m_className << "::Plot:\n"
79 << " Could not get solid " << i << " from geometry.\n";
80 continue;
81 }
82 // Get the center coordinates.
83 double x0 = 0., y0 = 0., z0 = 0.;
84 if (!solid->GetCentre(x0, y0, z0)) {
85 std::cerr << m_className << "::Plot: Could not determine solid centre.\n";
86 continue;
87 }
88 // Get the rotation.
89 double ctheta = 1., stheta = 0.;
90 double cphi = 1., sphi = 0.;
91 if (!solid->GetOrientation(ctheta, stheta, cphi, sphi)) {
92 std::cerr << m_className << "::Plot:\n"
93 << " Could not determine solid orientation.\n";
94 continue;
95 }
96 double matrix[9] = {cphi * ctheta, -sphi, cphi * stheta,
97 sphi * ctheta, cphi, sphi * stheta,
98 -stheta, 0, ctheta};
99 TGeoVolume* volume = nullptr;
100 if (solid->IsTube()) {
101 const double rmin = solid->GetInnerRadius();
102 const double rmax = solid->GetOuterRadius();
103 const double lz = solid->GetHalfLengthZ();
104 volume = m_geoManager->MakeTube("Tube", medDefault, rmin, rmax, lz);
105 } else if (solid->IsBox()) {
106 const double dx = solid->GetHalfLengthX();
107 const double dy = solid->GetHalfLengthY();
108 const double dz = solid->GetHalfLengthZ();
109 volume = m_geoManager->MakeBox("Box", medDefault, dx, dy, dz);
110 } else if (solid->IsSphere()) {
111 const double r = solid->GetRadius();
112 volume = m_geoManager->MakeSphere("Sphere", medDefault, 0, r);
113 } else if (solid->IsHole()) {
114 const double r1 = solid->GetLowerRadius();
115 const double r2 = solid->GetUpperRadius();
116 const double rm = 0.5 * (r1 + r2);
117 const double dr = (r2 - r1);
118 const double dx = solid->GetHalfLengthX();
119 const double dy = solid->GetHalfLengthY();
120 const double dz = solid->GetHalfLengthZ();
121 TGeoBBox* box = new TGeoBBox("HoleBox", dx, dy, dz);
122 TGeoCone* cone = new TGeoCone("HoleCone", 2 * dz, 0, rm - dr, 0, rm + dr);
123 TGeoCompositeShape* hole = new TGeoCompositeShape("Hole",
124 new TGeoSubtraction(box, cone));
125 hole->RegisterYourself();
126 volume = new TGeoVolume("Hole", hole, medDefault);
127 } else if (solid->IsRidge()) {
128 const double dx = solid->GetHalfLengthX();
129 const double dy = solid->GetHalfLengthY();
130 const double dz = 0.5 * solid->GetRidgeHeight();
131 const double xr = solid->GetRidgeOffset();
132 volume = m_geoManager->MakeArb8("Ridge", medDefault, dz);
133 auto arb = (TGeoArb8*)volume->GetShape();
134 arb->SetVertex(0, -dx, -dy);
135 arb->SetVertex(1, -dx, +dy);
136 arb->SetVertex(2, +dx, +dy);
137 arb->SetVertex(3, +dx, -dy);
138 arb->SetVertex(4, xr, -dy);
139 arb->SetVertex(5, xr, +dy);
140 arb->SetVertex(6, xr, +dy);
141 arb->SetVertex(7, xr, -dy);
142 z0 += dz;
143 } else {
144 std::cerr << m_className << "::Plot: Unknown type of solid.\n";
145 continue;
146 }
147 Medium* medium = m_geometry->GetMedium(x0, y0, z0);
148 if (!medium) {
149 volume->SetLineColor(kGreen + 2);
150 volume->SetTransparency(50);
151 } else if (medium->IsGas()) {
152 volume->SetLineColor(kBlue + medium->GetId());
153 volume->SetTransparency(50);
154 } else if (medium->IsSemiconductor()) {
155 volume->SetLineColor(kRed + medium->GetId());
156 volume->SetTransparency(50);
157 } else {
158 volume->SetLineColor(kViolet + medium->GetId());
159 volume->SetTransparency(0);
160 }
161 TGeoRotation r;
162 r.SetMatrix(matrix);
163 TGeoTranslation t(x0, y0, z0);
164 TGeoCombiTrans* transform = new TGeoCombiTrans(t, r);
165 m_volumes.push_back(volume);
166 m_geoManager->GetTopVolume()->AddNode(volume, 1, transform);
167 }
168 m_geoManager->CloseGeometry();
169 m_geoManager->GetTopNode()->Draw("ogl");
170}
171
172void ViewGeometry::Reset() {
173 for (auto it = m_volumes.begin(), end = m_volumes.end(); it != end; ++it) {
174 if (*it) {
175 TGeoShape* shape = (*it)->GetShape();
176 if (shape) delete shape;
177 delete *it;
178 }
179 }
180 m_volumes.clear();
181 for (auto it = m_media.begin(), end = m_media.end(); it != end; ++it) {
182 if (*it) {
183 TGeoMaterial* material = (*it)->GetMaterial();
184 if (material) delete material;
185 delete *it;
186 }
187 }
188 m_media.clear();
189
190 m_geoManager.reset(nullptr);
191}
192}
"Native" geometry, using simple shapes.
Solid * GetSolid(const unsigned int i) const override
Get a solid from the list.
unsigned int GetNumberOfSolids() const override
Return the number of solids in the geometry.
Medium * GetMedium(const double x, const double y, const double z) const override
Retrieve the medium at a given point.
bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) override
Get the bounding box (envelope of the geometry).
Abstract base class for media.
Definition: Medium.hh:13
int GetId() const
Return the id number of the class instance.
Definition: Medium.hh:21
virtual bool IsSemiconductor() const
Is this medium a semiconductor?
Definition: Medium.hh:27
virtual bool IsGas() const
Is this medium a gas?
Definition: Medium.hh:25
void SetDefaultStyle()
Apply the default Garfield ROOT style.
Abstract base class for solids.
Definition: Solid.hh:28
virtual double GetUpperRadius() const
Return the upper radius (of a hole).
Definition: Solid.hh:104
virtual bool IsTube() const
Return true if the solid is a tube.
Definition: Solid.hh:52
virtual bool IsRidge() const
Return true if the solid is a ridge.
Definition: Solid.hh:58
virtual double GetHalfLengthX() const
Return the half-length along x.
Definition: Solid.hh:78
virtual bool IsHole() const
Return true if the solid is a hole.
Definition: Solid.hh:56
virtual double GetHalfLengthZ() const
Return the half-length along z.
Definition: Solid.hh:86
virtual bool IsBox() const
Return true if the solid is a box.
Definition: Solid.hh:50
virtual double GetHalfLengthY() const
Return the half-length along y.
Definition: Solid.hh:82
bool GetCentre(double &x, double &y, double &z) const
Retrieve the centre point of the solid.
Definition: Solid.hh:61
virtual double GetRidgeOffset() const
Return the x-offset of a ridge.
Definition: Solid.hh:108
virtual double GetLowerRadius() const
Return the lower radius (of a hole).
Definition: Solid.hh:100
virtual double GetOuterRadius() const
Return the outer radius.
Definition: Solid.hh:94
bool GetOrientation(double &ctheta, double &stheta, double &cphi, double &sphi) const
Retrieve the orientation (azimuthal and polar angles) of the solid.
Definition: Solid.hh:68
virtual double GetRadius() const
Return the radius.
Definition: Solid.hh:98
virtual bool IsSphere() const
Return true if the solid is a sphere.
Definition: Solid.hh:54
virtual double GetInnerRadius() const
Return the inner radius.
Definition: Solid.hh:90
virtual double GetRidgeHeight() const
Return the height of a ridge.
Definition: Solid.hh:112
Base class for visualization classes.
Definition: ViewBase.hh:10
std::string m_className
Definition: ViewBase.hh:28
bool m_hasExternalCanvas
Definition: ViewBase.hh:35
TCanvas * m_canvas
Definition: ViewBase.hh:34
void Plot()
Draw the geometry.
Definition: ViewGeometry.cc:36
void SetGeometry(GeometrySimple *geo)
Set the geometry to be drawn.
Definition: ViewGeometry.cc:27
~ViewGeometry()
Destructor.
Definition: ViewGeometry.cc:23
ViewGeometry()
Constructor.
Definition: ViewGeometry.cc:19
PlottingEngineRoot plottingEngine