18 : m_className(
"ViewCell"),
20 m_useWireMarker(true),
21 m_label(
"Cell Layout"),
23 m_hasExternalCanvas(false),
39 if (!m_hasExternalCanvas && m_canvas)
delete m_canvas;
40 if (m_geo)
delete m_geo;
47 std::cerr << m_className <<
"::SetComponent: Null pointer.\n";
57 if (!m_hasExternalCanvas && m_canvas) {
62 m_hasExternalCanvas =
true;
67 const double xmax,
const double ymax,
71 if (xmin == xmax || ymin == ymax || zmin == zmax) {
72 std::cerr << m_className <<
"::SetArea: Null area range not permitted.\n";
75 m_xMin = std::min(xmin, xmax);
76 m_yMin = std::min(ymin, ymax);
77 m_zMin = std::min(zmin, zmax);
78 m_xMax = std::max(xmin, xmax);
79 m_yMax = std::max(ymin, ymax);
80 m_zMax = std::max(zmin, zmax);
87 std::cerr << m_className <<
"::Plot2d: Error creating plot.\n";
94 std::cerr << m_className <<
"::Plot3d: Error creating plot.\n";
98bool ViewCell::Plot(
const bool use3d) {
101 std::cerr << m_className <<
"::Plot: Component is not defined.\n";
105 double pmin = 0., pmax = 0.;
107 std::cerr << m_className <<
"::Plot: Component ist not ready.\n";
112 double x0 = m_xMin, y0 = m_yMin, z0 = m_zMin;
113 double x1 = m_xMax, y1 = m_yMax, z1 = m_zMax;
114 if (!m_hasUserArea) {
116 std::cerr << m_className <<
"::Plot:\n"
117 <<
" Bounding box cannot be determined.\n"
118 <<
" Call SetArea first.\n";
123 const double dx = std::max(
fabs(x0),
fabs(x1));
124 const double dy = std::max(
fabs(y0),
fabs(y1));
125 const double dz = std::max(
fabs(z0),
fabs(z1));
128 m_canvas =
new TCanvas();
129 if (!use3d) m_canvas->SetTitle(m_label.c_str());
130 if (m_hasExternalCanvas) m_hasExternalCanvas =
false;
136 if (!gPad || (gPad->GetListOfPrimitives()->GetSize() == 0 &&
137 gPad->GetX1() == 0 && gPad->GetX2() == 1 &&
138 gPad->GetY1() == 0 && gPad->GetY2() == 1)) {
141 const double bm = m_canvas->GetBottomMargin();
142 const double lm = m_canvas->GetLeftMargin();
143 const double rm = m_canvas->GetRightMargin();
144 const double tm = m_canvas->GetTopMargin();
146 TPad* pad =
new TPad(
"cell",
"", 0, 0, 1, 1);
147 pad->SetFillStyle(0);
148 pad->SetFrameFillStyle(0);
152 gPad->Range(x0 - (x1 - x0) * (lm / (1. - rm - lm)),
153 y0 - (y1 - y0) * (bm / (1. - tm - lm)),
154 x1 + (x1 - x0) * (rm / (1. - rm - lm)),
155 y1 + (y1 - y0) * (tm / (1. - tm - lm)));
159 const std::string cellType = m_component->
GetCellType();
162 double sx = 0., sy = 0.;
166 const int nMinX = perX ? int(x0 / sx) - 1 : 0;
167 const int nMaxX = perX ? int(x1 / sx) + 1 : 0;
168 const int nMinY = perY ? int(y0 / sy) - 1 : 0;
169 const int nMaxY = perY ? int(y1 / sy) + 1 : 0;
173 m_geo =
new TGeoManager(
"ViewCellGeoManager", m_label.c_str());
174 TGeoMaterial* matVacuum =
new TGeoMaterial(
"Vacuum", 0., 0., 0.);
175 TGeoMaterial* matMetal =
new TGeoMaterial(
"Metal", 63.546, 29., 8.92);
176 TGeoMedium* medVacuum =
new TGeoMedium(
"Vacuum", 0, matVacuum);
177 TGeoMedium* medMetal =
new TGeoMedium(
"Metal", 1, matMetal);
178 m_geo->AddMaterial(matVacuum);
179 m_geo->AddMaterial(medMetal->GetMaterial());
180 TGeoVolume* world = m_geo->MakeBox(
"World", medVacuum,
181 1.05 * dx, 1.05 * dy, 1.05 * dz);
182 m_geo->SetTopVolume(world);
184 TGeoVolume* top = m_geo->GetTopVolume();
185 TGeoBBox* box =
dynamic_cast<TGeoBBox*
>(top);
186 double halfLenghts[3] = {1.05 * dx, 1.05 * dy, 1.05 * dz};
187 if (box) box->SetDimensions(halfLenghts);
193 std::vector<std::string> wireTypes;
195 for (
unsigned int i = 0; i < nWires; ++i) {
196 double xw = 0., yw = 0., dw = 0., vw = 0., lw = 0., qw = 0.;
200 m_component->
GetWire(i, xw, yw, dw, vw, lbl, lw, qw, nTrap);
202 if (wireTypes.empty()) {
203 wireTypes.push_back(lbl);
206 const unsigned int nWireTypes = wireTypes.size();
207 for (
unsigned int j = 0; j < nWireTypes; ++j) {
208 if (lbl == wireTypes[j]) {
214 type = wireTypes.size();
215 wireTypes.push_back(lbl);
218 for (
int nx = nMinX; nx <= nMaxX; ++nx) {
219 const double x = xw + nx * sx;
220 if (x + 0.5 * dw <= x0 || x - 0.5 * dw >= x1)
continue;
221 for (
int ny = nMinY; ny <= nMaxY; ++ny) {
222 const double y = yw + ny * sy;
223 if (y + 0.5 * dw <= y0 || y - 0.5 * dw >= y1)
continue;
225 TGeoVolume* wire = m_geo->MakeTube(
"Wire", m_geo->GetMedium(
"Metal"),
227 std::min(0.5 * lw, dz));
230 wire->SetLineColor(kGray + 2);
233 wire->SetLineColor(kRed + 2);
236 wire->SetLineColor(kPink + 3);
239 wire->SetLineColor(kCyan + 3);
242 wire->SetLineColor(kBlue + type);
245 m_geo->GetTopVolume()->AddNode(wire, 1,
246 new TGeoTranslation(x, y, 0.));
248 PlotWire(x, y, dw, type);
256 for (
unsigned int i = 0; i < nPlanesX; ++i) {
257 double xp = 0., vp = 0.;
260 for (
int nx = nMinX; nx <= nMaxX; ++nx) {
261 const double x = xp + nx * sx;
262 if (x < x0 || x > x1)
continue;
264 const double width = std::min(0.01 * dx, 0.01 * dy);
265 TGeoVolume* plane = m_geo->MakeBox(
"PlaneX", m_geo->GetMedium(
"Metal"),
267 plane->SetLineColor(kGreen - 5);
268 plane->SetTransparency(75);
269 m_geo->GetTopVolume()->AddNode(plane, 1,
270 new TGeoTranslation(x, 0., 0.));
273 line.SetDrawOption(
"same");
274 line.DrawLine(x, y0, x, y1);
281 for (
unsigned int i = 0; i < nPlanesY; ++i) {
282 double yp = 0., vp = 0.;
285 for (
int ny = nMinY; ny <= nMaxY; ++ny) {
286 const double y = yp + ny * sy;
287 if (y < y0 || y > y1)
continue;
289 const double width = std::min(0.01 * dx, 0.01 * dy);
290 TGeoVolume* plane = m_geo->MakeBox(
"PlaneY", m_geo->GetMedium(
"Metal"),
292 plane->SetLineColor(kGreen - 5);
293 plane->SetTransparency(75);
294 m_geo->GetTopVolume()->AddNode(plane, 1,
295 new TGeoTranslation(0., y, 0.));
298 line.SetDrawOption(
"same");
299 line.DrawLine(x0, y, x1, y);
304 double rt = 0., vt = 0.;
307 if (m_component->
GetTube(rt, vt, nt, lbl)) {
311 TGeoVolume* tube = m_geo->MakeTube(
"Tube", m_geo->GetMedium(
"Metal"),
312 0.98 * rt, 1.02 * rt, dz);
313 tube->SetLineColor(kGreen + 2);
314 m_geo->GetTopVolume()->AddNode(tube, 1,
315 new TGeoTranslation(0., 0., 0.));
317 TGeoVolume* tube = m_geo->MakePgon(
"Tube", m_geo->GetMedium(
"Metal"),
319 TGeoPgon* pgon =
dynamic_cast<TGeoPgon*
>(tube->GetShape());
320 pgon->DefineSection(0, -dz, 0.98 * rt, 1.02 * rt);
321 pgon->DefineSection(1, +dz, 0.98 * rt, 1.02 * rt);
322 tube->SetLineColor(kGreen + 2);
323 m_geo->GetTopVolume()->AddNode(tube, 1,
324 new TGeoTranslation(0., 0., 0.));
327 PlotTube(0., 0., rt, nt);
332 m_geo->CloseGeometry();
333 m_geo->GetTopNode()->Draw(
"ogl");
341void ViewCell::PlotWire(
const double x,
const double y,
const double d,
344 if (m_useWireMarker) {
347 markerStyle = kFullCircle;
348 }
else if (type == 1) {
349 markerStyle = kOpenCircle;
350 }
else if (type == 2) {
351 markerStyle = kFullSquare;
352 }
else if (type == 3) {
353 markerStyle = kOpenSquare;
355 markerStyle = 26 + type;
358 marker.SetMarkerStyle(markerStyle);
359 marker.SetDrawOption(
"Psame");
360 marker.DrawMarker(x, y);
365 circle.SetDrawOption(
"same");
366 circle.DrawEllipse(x, y, 0.5 * d, 0.5 * d, 0, 0, 360);
369void ViewCell::PlotTube(
const double x0,
const double y0,
const double r,
374 circle.SetDrawOption(
"same");
375 circle.SetFillStyle(0);
376 circle.DrawEllipse(x0, y0, r, r, 0, 0, 360);
380 double* x =
new double[n + 1];
381 double* y =
new double[n + 1];
382 for (
int i = 0; i <= n; ++i) {
383 const double phi = i * TwoPi / double(n);
384 x[i] = x0 + r *
cos(phi);
385 y[i] = y0 + r *
sin(phi);
388 pline.SetDrawOption(
"same");
389 pline.DrawPolyLine(n + 1, x, y);
bool GetVoltageRange(double &pmin, double &pmax)
Calculate the voltage range [V].
bool GetPeriodicityY(double &s)
unsigned int GetNumberOfWires() const
std::string GetCellType()
bool GetWire(const unsigned int i, double &x, double &y, double &diameter, double &voltage, std::string &label, double &length, double &charge, int &ntrap) const
unsigned int GetNumberOfPlanesY() const
unsigned int GetNumberOfPlanesX() const
bool GetPeriodicityX(double &s)
bool GetTube(double &r, double &voltage, int &nEdges, std::string &label) const
bool GetPlaneX(const unsigned int i, double &x, double &voltage, std::string &label) const
bool GetBoundingBox(double &x0, double &y0, double &z0, double &x1, double &y1, double &z1)
Get the bounding box coordinates.
bool GetPlaneY(const unsigned int i, double &y, double &voltage, std::string &label) const
void Plot3d()
Make a three-dimensional drawing of the cell geometry (using TGeo).
void SetArea()
Take the plot range from the bounding box of the component class.
void SetCanvas(TCanvas *c)
Set the canvas on which to draw the cell geometry.
void SetComponent(ComponentAnalyticField *comp)
Set the component for which to draw the cell geometry.
void Plot2d()
Make a two-dimensional drawing of the cell geometry.
PlottingEngineRoot plottingEngine
DoubleAc cos(const DoubleAc &f)
DoubleAc fabs(const DoubleAc &f)
DoubleAc sin(const DoubleAc &f)