Garfield++ 4.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
Garfield::ViewGeometry Class Reference

Visualize a geometry defined using the "native" shapes. More...

#include <ViewGeometry.hh>

+ Inheritance diagram for Garfield::ViewGeometry:

Public Member Functions

 ViewGeometry ()
 Constructor.
 
 ~ViewGeometry ()
 Destructor.
 
void SetGeometry (GeometrySimple *geo)
 Set the geometry to be drawn.
 
void Plot (const bool twod=false)
 Draw the geometry.
 
void Plot2d ()
 Draw a cut through the geometry at the current viewing plane.
 
void Plot3d ()
 Draw a three-dimensional view of the geometry.
 
- Public Member Functions inherited from Garfield::ViewBase
 ViewBase ()=delete
 Default constructor.
 
 ViewBase (const std::string &name)
 Constructor.
 
virtual ~ViewBase ()=default
 Destructor.
 
void SetCanvas (TPad *pad)
 Set the canvas to be painted on.
 
void SetCanvas ()
 Unset an external canvas.
 
TPad * GetCanvas ()
 Retrieve the canvas.
 
void SetArea (const double xmin, const double ymin, const double xmax, const double ymax)
 
virtual void SetArea (const double xmin, const double ymin, const double zmin, const double xmax, const double ymax, const double zmax)
 Set a bounding box (if applicable).
 
void SetArea ()
 
virtual void SetPlane (const double fx, const double fy, const double fz, const double x0, const double y0, const double z0)
 
virtual void SetPlane (const double fx, const double fy, const double fz, const double x0, const double y0, const double z0, const double hx, const double hy, const double hz)
 Set the projection plane specifying a hint for the in-plane x axis.
 
void Rotate (const double angle)
 Rotate the viewing plane (angle in radian).
 
void SetPlaneXY ()
 Set the viewing plane to x-y.
 
void SetPlaneXZ ()
 Set the viewing plane to x-z.
 
void SetPlaneYZ ()
 Set the viewing plane to y-z.
 
void EnableDebugging (const bool on=true)
 Switch on/off debugging output.
 

Additional Inherited Members

- Static Public Member Functions inherited from Garfield::ViewBase
static std::string FindUnusedFunctionName (const std::string &s)
 Find an unused function name.
 
static std::string FindUnusedHistogramName (const std::string &s)
 Find an unused histogram name.
 
static std::string FindUnusedCanvasName (const std::string &s)
 Find an unused canvas name.
 
- Protected Member Functions inherited from Garfield::ViewBase
void UpdateProjectionMatrix ()
 
template<typename T >
void ToPlane (const T x, const T y, const T z, T &xp, T &yp) const
 
template<typename T >
bool InBox (const std::array< T, 3 > &x) const
 
void Clip (const std::array< float, 3 > &x0, const std::array< float, 3 > &x1, std::array< float, 3 > &xc) const
 
void DrawLine (const std::vector< std::array< float, 3 > > &xl, const short col, const short lw)
 
std::string LabelX ()
 
std::string LabelY ()
 
std::string PlaneDescription ()
 
bool PlotLimits (Sensor *sensor, double &xmin, double &ymin, double &xmax, double &ymax) const
 
bool PlotLimits (Component *cmp, double &xmin, double &ymin, double &xmax, double &ymax) const
 
bool PlotLimitsFromUserBox (double &xmin, double &ymin, double &xmax, double &ymax) const
 
bool PlotLimits (std::array< double, 3 > &bbmin, std::array< double, 3 > &bbmax, double &xmin, double &ymin, double &xmax, double &ymax) const
 
bool RangeSet (TPad *)
 
void SetRange (TPad *pad, const double x0, const double y0, const double x1, const double y1)
 
- Protected Attributes inherited from Garfield::ViewBase
std::string m_className = "ViewBase"
 
bool m_debug = false
 
bool m_userPlotLimits = false
 
double m_xMinPlot = -1.
 
double m_xMaxPlot = 1.
 
double m_yMinPlot = -1.
 
double m_yMaxPlot = 1.
 
bool m_userBox = false
 
double m_xMinBox = -1.
 
double m_xMaxBox = 1.
 
double m_yMinBox = -1.
 
double m_yMaxBox = 1.
 
double m_zMinBox = -1.
 
double m_zMaxBox = 1.
 
std::array< std::array< double, 3 >, 3 > m_proj
 
std::array< double, 4 > m_plane {{0, 0, 1, 0}}
 
std::array< std::array< double, 3 >, 3 > m_prmat
 

Detailed Description

Visualize a geometry defined using the "native" shapes.

Definition at line 18 of file ViewGeometry.hh.

Constructor & Destructor Documentation

◆ ViewGeometry()

Garfield::ViewGeometry::ViewGeometry ( )

Constructor.

Definition at line 21 of file ViewGeometry.cc.

21: ViewBase("ViewGeometry") {}
ViewBase()=delete
Default constructor.

◆ ~ViewGeometry()

Garfield::ViewGeometry::~ViewGeometry ( )

Destructor.

Definition at line 23 of file ViewGeometry.cc.

23 {
24 Reset();
25}

Member Function Documentation

◆ Plot()

void Garfield::ViewGeometry::Plot ( const bool  twod = false)

Draw the geometry.

Definition at line 36 of file ViewGeometry.cc.

36 {
37
38 if (twod) {
39 Plot2d();
40 } else {
41 Plot3d();
42 }
43}
void Plot3d()
Draw a three-dimensional view of the geometry.
Definition: ViewGeometry.cc:45
void Plot2d()
Draw a cut through the geometry at the current viewing plane.

◆ Plot2d()

void Garfield::ViewGeometry::Plot2d ( )

Draw a cut through the geometry at the current viewing plane.

Definition at line 194 of file ViewGeometry.cc.

194 {
195
196 if (!m_geometry) {
197 std::cerr << m_className << "::Plot2d: Geometry is not defined.\n";
198 return;
199 }
200
201 const unsigned int nSolids = m_geometry->GetNumberOfSolids();
202 if (nSolids == 0) {
203 std::cerr << m_className << "::Plot2d: Geometry is empty.\n";
204 return;
205 }
206
207 // Determine the plot limits.
208 double x0 = 0., y0 = 0.;
209 double x1 = 0., y1 = 0.;
210 if (m_userPlotLimits) {
211 x0 = m_xMinPlot;
212 y0 = m_yMinPlot;
213 x1 = m_xMaxPlot;
214 y1 = m_yMaxPlot;
215 } else if (m_userBox) {
216 PlotLimitsFromUserBox(x0, y0, x1, y1);
217 } else {
218 std::array<double, 3> bbmin;
219 std::array<double, 3> bbmax;
220 if (!m_geometry->GetBoundingBox(bbmin[0], bbmin[1], bbmin[2],
221 bbmax[0], bbmax[1], bbmax[2])) {
222 std::cerr << m_className << "::Plot2d: Cannot retrieve bounding box.\n";
223 return;
224 }
225 PlotLimits(bbmin, bbmax, x0, y0, x1, y1);
226 }
227
228 auto canvas = GetCanvas();
229 canvas->cd();
230 canvas->SetTitle("Geometry");
231
232 bool empty = false;
233 if (!gPad ||
234 (gPad->GetListOfPrimitives()->GetSize() == 0 && gPad->GetX1() == 0 &&
235 gPad->GetX2() == 1 && gPad->GetY1() == 0 && gPad->GetY2() == 1)) {
236 empty = true;
237 }
238 const double bm = canvas->GetBottomMargin();
239 const double lm = canvas->GetLeftMargin();
240 const double rm = canvas->GetRightMargin();
241 const double tm = canvas->GetTopMargin();
242 if (!empty) {
243 TPad* pad = new TPad("geo", "", 0, 0, 1, 1);
244 pad->SetFillStyle(0);
245 pad->SetFrameFillStyle(0);
246 pad->Draw();
247 pad->cd();
248 }
249 gPad->Range(x0 - (x1 - x0) * (lm / (1. - rm - lm)),
250 y0 - (y1 - y0) * (bm / (1. - tm - lm)),
251 x1 + (x1 - x0) * (rm / (1. - rm - lm)),
252 y1 + (y1 - y0) * (tm / (1. - tm - lm)));
253 TPolyLine pl;
254 pl.SetLineWidth(2);
255 for (unsigned int i = 0; i < nSolids; ++i) {
256 auto solid = m_geometry->GetSolid(i);
257 if (!solid) continue;
258 std::vector<Panel> panels;
259 solid->Cut(m_proj[2][0], m_proj[2][1], m_proj[2][2],
260 m_plane[0], m_plane[1], m_plane[2], panels);
261 for (const auto& panel : panels) {
262 const unsigned int nv = panel.xv.size();
263 if (nv < 3) continue;
264 std::vector<double> xpl;
265 std::vector<double> ypl;
266 for (unsigned int j = 0; j < nv; ++j) {
267 double u, v;
268 ToPlane(panel.xv[j], panel.yv[j], panel.zv[j], u, v);
269 xpl.push_back(u);
270 ypl.push_back(v);
271 }
272 xpl.push_back(xpl[0]);
273 ypl.push_back(ypl[0]);
274 if (panel.colour < 0) {
275 pl.SetLineColor(kBlack);
276 } else {
277 pl.SetLineColor(panel.colour);
278 }
279 pl.DrawPolyLine(nv + 1, xpl.data(), ypl.data(), "same");
280 }
281 }
282 gPad->Update();
283}
size_t GetNumberOfSolids() const override
Return the number of solids in the geometry.
Solid * GetSolid(const size_t i) const override
Get a solid from the list.
bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) override
Get the bounding box (envelope of the geometry).
virtual void Cut(const double x0, const double y0, const double z0, const double xn, const double yn, const double zn, std::vector< Panel > &panels)=0
std::array< double, 4 > m_plane
Definition: ViewBase.hh:99
std::string m_className
Definition: ViewBase.hh:78
std::array< std::array< double, 3 >, 3 > m_proj
Definition: ViewBase.hh:96
TPad * GetCanvas()
Retrieve the canvas.
Definition: ViewBase.cc:74
bool PlotLimits(Sensor *sensor, double &xmin, double &ymin, double &xmax, double &ymax) const
Definition: ViewBase.cc:608
void ToPlane(const T x, const T y, const T z, T &xp, T &yp) const
Definition: ViewBase.hh:109
bool PlotLimitsFromUserBox(double &xmin, double &ymin, double &xmax, double &ymax) const
Definition: ViewBase.cc:663

Referenced by Plot().

◆ Plot3d()

void Garfield::ViewGeometry::Plot3d ( )

Draw a three-dimensional view of the geometry.

Definition at line 45 of file ViewGeometry.cc.

45 {
46 if (!m_geometry) {
47 std::cerr << m_className << "::Plot3d: Geometry is not defined.\n";
48 return;
49 }
50
51 const unsigned int nSolids = m_geometry->GetNumberOfSolids();
52 if (nSolids == 0) {
53 std::cerr << m_className << "::Plot3d: Geometry is empty.\n";
54 return;
55 }
56
57 // Get the bounding box.
58 double xMin = 0., yMin = 0., zMin = 0.;
59 double xMax = 0., yMax = 0., zMax = 0.;
60 if (!m_geometry->GetBoundingBox(xMin, yMin, zMin, xMax, yMax, zMax)) {
61 std::cerr << m_className << "::Plot3d: Cannot retrieve bounding box.\n";
62 return;
63 }
64 auto canvas = GetCanvas();
65 canvas->cd();
66 gGeoManager = nullptr;
67 m_geoManager.reset(new TGeoManager("ViewGeometryGeoManager", ""));
68 TGeoMaterial* matVacuum = new TGeoMaterial("Vacuum", 0., 0., 0.);
69 TGeoMedium* medVacuum = new TGeoMedium("Vacuum", 1, matVacuum);
70 m_media.push_back(medVacuum);
71 // Use silicon as "default" material.
72 TGeoMaterial* matDefault = new TGeoMaterial("Default", 28.085, 14., 2.329);
73 TGeoMedium* medDefault = new TGeoMedium("Default", 1, matDefault);
74 TGeoVolume* world = m_geoManager->MakeBox(
75 "World", medVacuum, std::max(fabs(xMin), fabs(xMax)),
76 std::max(fabs(yMin), fabs(yMax)), std::max(fabs(zMin), fabs(zMax)));
77 m_geoManager->SetTopVolume(world);
78 m_volumes.push_back(world);
79
80 for (unsigned int i = 0; i < nSolids; ++i) {
81 Solid* solid = m_geometry->GetSolid(i);
82 if (!solid) {
83 std::cerr << m_className << "::Plot3d:\n"
84 << " Could not get solid " << i << " from geometry.\n";
85 continue;
86 }
87 // Get the center coordinates.
88 double x0 = 0., y0 = 0., z0 = 0.;
89 if (!solid->GetCentre(x0, y0, z0)) {
90 std::cerr << m_className << "::Plot3d: Could not determine solid centre.\n";
91 continue;
92 }
93 // Get the rotation.
94 double ctheta = 1., stheta = 0.;
95 double cphi = 1., sphi = 0.;
96 if (!solid->GetOrientation(ctheta, stheta, cphi, sphi)) {
97 std::cerr << m_className << "::Plot3d:\n"
98 << " Could not determine solid orientation.\n";
99 continue;
100 }
101 double matrix[9] = {cphi * ctheta, -sphi, cphi * stheta,
102 sphi * ctheta, cphi, sphi * stheta,
103 -stheta, 0, ctheta};
104 TGeoVolume* volume = nullptr;
105 if (solid->IsTube()) {
106 const double rt = solid->GetRadius();
107 const double lz = solid->GetHalfLengthZ();
108 volume = m_geoManager->MakeTube("Tube", medDefault, 0., rt, lz);
109 } else if (solid->IsWire()) {
110 const double rw = solid->GetRadius();
111 const double lz = solid->GetHalfLengthZ();
112 volume = m_geoManager->MakeTube("Wire", medDefault, 0., rw, lz);
113 } else if (solid->IsBox()) {
114 const double dx = solid->GetHalfLengthX();
115 const double dy = solid->GetHalfLengthY();
116 const double dz = solid->GetHalfLengthZ();
117 volume = m_geoManager->MakeBox("Box", medDefault, dx, dy, dz);
118 } else if (solid->IsSphere()) {
119 const double rmin = std::max(solid->GetInnerRadius(), 0.);
120 const double rmax = solid->GetOuterRadius();
121 volume = m_geoManager->MakeSphere("Sphere", medDefault, rmin, rmax);
122 } else if (solid->IsHole()) {
123 const double r1 = solid->GetLowerRadius();
124 const double r2 = solid->GetUpperRadius();
125 const double dx = solid->GetHalfLengthX();
126 const double dy = solid->GetHalfLengthY();
127 const double dz = solid->GetHalfLengthZ();
128 const double lz = 10 * std::max({dx, dy, dz});
129 const double rm = 0.5 * (r1 + r2);
130 const double dr = 0.5 * (r2 - r1) * lz / dz;
131 TGeoBBox* box = new TGeoBBox("HoleBox", dx, dy, dz);
132 TGeoCone* cone = new TGeoCone("HoleCone", lz, 0, rm - dr, 0, rm + dr);
133 TGeoCompositeShape* hole = new TGeoCompositeShape("Hole",
134 new TGeoSubtraction(box, cone));
135 hole->RegisterYourself();
136 volume = new TGeoVolume("Hole", hole, medDefault);
137 } else if (solid->IsRidge()) {
138 const double dx = solid->GetHalfLengthX();
139 const double dy = solid->GetHalfLengthY();
140 const double dz = 0.5 * solid->GetRidgeHeight();
141 const double xr = solid->GetRidgeOffset();
142 volume = m_geoManager->MakeArb8("Ridge", medDefault, dz);
143 auto arb = (TGeoArb8*)volume->GetShape();
144 arb->SetVertex(0, -dx, -dy);
145 arb->SetVertex(1, -dx, +dy);
146 arb->SetVertex(2, +dx, +dy);
147 arb->SetVertex(3, +dx, -dy);
148 arb->SetVertex(4, xr, -dy);
149 arb->SetVertex(5, xr, +dy);
150 arb->SetVertex(6, xr, +dy);
151 arb->SetVertex(7, xr, -dy);
152 z0 += dz;
153 } else if (solid->IsExtrusion()) {
154 const double dz = solid->GetHalfLengthZ();
155 std::vector<double> xp;
156 std::vector<double> yp;
157 if (!solid->GetProfile(xp, yp)) continue;
158 volume = m_geoManager->MakeXtru("Extrusion", medDefault, 2);
159 auto xtru = (TGeoXtru*)volume->GetShape();
160 xtru->DefinePolygon(xp.size(), xp.data(), yp.data());
161 xtru->DefineSection(0, -dz);
162 xtru->DefineSection(1, +dz);
163 } else {
164 std::cerr << m_className << "::Plot3d: Unknown type of solid.\n";
165 continue;
166 }
167 Medium* medium = m_geometry->GetMedium(x0, y0, z0);
168 if (solid->GetColour() >= 0) {
169 volume->SetLineColor(solid->GetColour());
170 } else if (!medium) {
171 volume->SetLineColor(kGreen + 2);
172 volume->SetTransparency(50);
173 } else if (medium->IsGas()) {
174 volume->SetLineColor(kBlue + medium->GetId());
175 volume->SetTransparency(50);
176 } else if (medium->IsSemiconductor()) {
177 volume->SetLineColor(kRed + medium->GetId());
178 volume->SetTransparency(50);
179 } else {
180 volume->SetLineColor(kViolet + medium->GetId());
181 volume->SetTransparency(0);
182 }
183 TGeoRotation r;
184 r.SetMatrix(matrix);
185 TGeoTranslation t(x0, y0, z0);
186 TGeoCombiTrans* transform = new TGeoCombiTrans(t, r);
187 m_volumes.push_back(volume);
188 m_geoManager->GetTopVolume()->AddNode(volume, 1, transform);
189 }
190 m_geoManager->CloseGeometry();
191 m_geoManager->GetTopNode()->Draw("ogl");
192}
Medium * GetMedium(const double x, const double y, const double z, const bool tesselated=false) const override
Retrieve the medium at a given point.
DoubleAc fabs(const DoubleAc &f)
Definition: DoubleAc.h:615

Referenced by Plot().

◆ SetGeometry()

void Garfield::ViewGeometry::SetGeometry ( GeometrySimple geo)

Set the geometry to be drawn.

Definition at line 27 of file ViewGeometry.cc.

27 {
28 if (!geo) {
29 std::cerr << m_className << "::SetGeometry: Null pointer.\n";
30 return;
31 }
32
33 m_geometry = geo;
34}

The documentation for this class was generated from the following files: