LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
ProtoDUNEDrawer_tool.cc
Go to the documentation of this file.
1 
7 
9 
10 #include "fhiclcpp/ParameterSet.h"
16 
17 #include "TPolyLine3D.h"
18 
19 #include <algorithm> // std::min()
20 #include <array>
21 #include <cmath> // std::abs()
22 
23 namespace evd_tool {
24 
26  public:
27  explicit ProtoDUNEDrawer(const fhicl::ParameterSet& pset);
28 
29  virtual void DetOutline3D(evdb::View3D* view) override;
30 
31  protected:
34  geo::BoxBoundedGeo const& bb,
35  Color_t color,
36  Width_t width,
37  Style_t style) const;
38 
41  geo::TPCGeo const& TPC,
42  Color_t color,
43  Width_t width,
44  Style_t style) const
45  {
46  DrawBoxBoundedGeoOutline(view, TPC, color, width, style);
47  }
48 
51  geo::TPCGeo const& TPC,
52  Color_t color,
53  Width_t width,
54  Style_t style) const;
55 
57  double const* coordsLo,
58  double const* coordsHi,
59  int color = kGray,
60  int width = 1,
61  int style = 1) const;
62  void DrawGrids(evdb::View3D* view,
63  double const* coordsLo,
64  double const* coordsHi,
65  int color = kGray,
66  int width = 1,
67  int style = 1) const;
68  void DrawAxes(evdb::View3D* view,
69  double const* coordsLo,
70  double const* coordsHi,
71  int color = kGray,
72  int width = 1,
73  int style = 1) const;
74 
75  private:
76  void configure(const fhicl::ParameterSet& pset);
77  // Member variables from the fhicl file
78  bool fDrawGrid;
80  bool fDrawAxes;
81  bool fDrawActive;
82  };
83 
84  //----------------------------------------------------------------------
85  // Constructor.
87  {
88  configure(pset);
89  }
90 
92  {
93  // Start by recovering the parameters
94  fDrawGrid = pset.get<bool>("DrawGrid", true);
95  fDrawAnodeGrid = pset.get<bool>("DrawAnodeGrid", false);
96  fDrawAxes = pset.get<bool>("DrawAxes", true);
97  fDrawActive = pset.get<bool>("DrawActive", true);
98 
99  return;
100  }
101 
102  //......................................................................
104  {
105  auto const& geom = *(lar::providerFrom<geo::Geometry>());
106 
107  // we compute the total volume of the detector, to be used for the axes;
108  // we do include the origin by choice
109  geo::BoxBoundedGeo detector({0.0, 0.0, 0.0}, {0.0, 0.0, 0.0});
110 
111  // Draw a box for each cryostat, and, within it, for each TPC;
112  // the outlined volumes are the ones from the geometry boxes
113  for (geo::CryostatGeo const& cryo : geom.Iterate<geo::CryostatGeo>()) {
114 
115  // include this cryostat in the detector volume
116  detector.ExtendToInclude(cryo);
117 
118  // draw the cryostat box
119  DrawBoxBoundedGeoOutline(view, cryo.Boundaries(), kRed + 2, 1, kSolid);
120 
121  // draw all TPC boxes
122  for (geo::TPCGeo const& TPC : cryo.IterateTPCs()) {
123 
124  DrawTPCoutline(view, TPC, kRed, 2, kSolid);
125 
126  // BUG the double brace syntax is required to work around clang bug 21629
127  // optionally draw the grid
128  if (fDrawGrid) {
129  std::array<double, 3U> const tpcLow{{TPC.MinX(), TPC.MinY(), TPC.MinZ()}},
130  tpcHigh{{TPC.MaxX(), TPC.MaxY(), TPC.MaxZ()}};
131  DrawGrids(view, tpcLow.data(), tpcHigh.data(), kGray + 2, 1, kSolid);
132  }
133 
134  // optionally draw the active volume
135  if (fDrawActive) DrawActiveTPCoutline(view, TPC, kCyan + 2, 1, kDotted);
136 
137  } // for TPCs in cryostat
138 
139  } // for cryostats
140 
141  // draw axes if requested
142  if (fDrawAxes) {
143  // BUG the double brace syntax is required to work around clang bug 21629
144  std::array<double, 3U> const detLow = {{detector.MinX(), detector.MinY(), detector.MinZ()}},
145  detHigh = {{detector.MaxX(), detector.MaxY(), detector.MaxZ()}};
146 
147  DrawAxes(view, detLow.data(), detHigh.data(), kBlue, 1, kSolid);
148  } // if draw axes
149  }
150 
152  geo::BoxBoundedGeo const& bb,
153  Color_t color,
154  Width_t width,
155  Style_t style) const
156  {
157  // BUG the double brace syntax is required to work around clang bug 21629
158  std::array<double, 3U> const low{{bb.MinX(), bb.MinY(), bb.MinZ()}},
159  high{{bb.MaxX(), bb.MaxY(), bb.MaxZ()}};
160  ;
161  DrawRectangularBox(view, low.data(), high.data(), color, width, style);
162  } // ProtoDUNEDrawer::DrawBoxBoundedGeoOutline()
163 
165  geo::TPCGeo const& TPC,
166  Color_t color,
167  Width_t width,
168  Style_t style) const
169  {
170  auto const& activeCenter = TPC.GetActiveVolumeCenter();
172  {{activeCenter.X() - TPC.ActiveHalfWidth(),
173  activeCenter.Y() - TPC.ActiveHalfHeight(),
174  activeCenter.Z() - TPC.ActiveHalfLength()},
175  {activeCenter.X() + TPC.ActiveHalfWidth(),
176  activeCenter.Y() + TPC.ActiveHalfHeight(),
177  activeCenter.Z() + TPC.ActiveHalfLength()}},
178  color,
179  width,
180  style);
181  }
182 
184  double const* coordsLo,
185  double const* coordsHi,
186  int color,
187  int width,
188  int style) const
189  {
190  TPolyLine3D& top = view->AddPolyLine3D(5, color, width, style);
191  top.SetPoint(0, coordsLo[0], coordsHi[1], coordsLo[2]);
192  top.SetPoint(1, coordsHi[0], coordsHi[1], coordsLo[2]);
193  top.SetPoint(2, coordsHi[0], coordsHi[1], coordsHi[2]);
194  top.SetPoint(3, coordsLo[0], coordsHi[1], coordsHi[2]);
195  top.SetPoint(4, coordsLo[0], coordsHi[1], coordsLo[2]);
196 
197  TPolyLine3D& side = view->AddPolyLine3D(5, color, width, style);
198  side.SetPoint(0, coordsHi[0], coordsHi[1], coordsLo[2]);
199  side.SetPoint(1, coordsHi[0], coordsLo[1], coordsLo[2]);
200  side.SetPoint(2, coordsHi[0], coordsLo[1], coordsHi[2]);
201  side.SetPoint(3, coordsHi[0], coordsHi[1], coordsHi[2]);
202  side.SetPoint(4, coordsHi[0], coordsHi[1], coordsLo[2]);
203 
204  TPolyLine3D& side2 = view->AddPolyLine3D(5, color, width, style);
205  side2.SetPoint(0, coordsLo[0], coordsHi[1], coordsLo[2]);
206  side2.SetPoint(1, coordsLo[0], coordsLo[1], coordsLo[2]);
207  side2.SetPoint(2, coordsLo[0], coordsLo[1], coordsHi[2]);
208  side2.SetPoint(3, coordsLo[0], coordsHi[1], coordsHi[2]);
209  side2.SetPoint(4, coordsLo[0], coordsHi[1], coordsLo[2]);
210 
211  TPolyLine3D& bottom = view->AddPolyLine3D(5, color, width, style);
212  bottom.SetPoint(0, coordsLo[0], coordsLo[1], coordsLo[2]);
213  bottom.SetPoint(1, coordsHi[0], coordsLo[1], coordsLo[2]);
214  bottom.SetPoint(2, coordsHi[0], coordsLo[1], coordsHi[2]);
215  bottom.SetPoint(3, coordsLo[0], coordsLo[1], coordsHi[2]);
216  bottom.SetPoint(4, coordsLo[0], coordsLo[1], coordsLo[2]);
217 
218  return;
219  }
220 
222  double const* coordsLo,
223  double const* coordsHi,
224  int color,
225  int width,
226  int style) const
227  {
228  // If the x distance is small then we are drawing an anode grid...
229  // Check to see if wanted
230  if (!fDrawAnodeGrid && std::abs(coordsHi[0] - coordsLo[0]) < 25.) return;
231 
232  // uniform step size, each 25 cm except that at least 5 per plane
233  double const gridStep = std::min(25.0,
234  std::max(10.,
235  std::min({std::abs(coordsHi[0] - coordsLo[0]),
236  std::abs(coordsHi[1] - coordsLo[1]),
237  std::abs(coordsHi[2] - coordsLo[2])})) /
238  5);
239 
240  // Grid running along x and y at constant z
241  for (double z = coordsLo[2]; z <= coordsHi[2]; z += gridStep) {
242 
243  // across x, on bottom plane, fixed z
244  TPolyLine3D& gridt = view->AddPolyLine3D(2, color, style, width);
245  gridt.SetPoint(0, coordsLo[0], coordsLo[1], z);
246  gridt.SetPoint(1, coordsHi[0], coordsLo[1], z);
247 
248  // on right plane, across y, fixed z
249  TPolyLine3D& grids = view->AddPolyLine3D(2, color, style, width);
250  grids.SetPoint(0, coordsHi[0], coordsLo[1], z);
251  grids.SetPoint(1, coordsHi[0], coordsHi[1], z);
252  }
253 
254  // Grid running along z at constant x
255  for (double x = coordsLo[0]; x <= coordsHi[0]; x += gridStep) {
256  // fixed x, on bottom plane, across z
257  TPolyLine3D& gridt = view->AddPolyLine3D(2, color, style, width);
258  gridt.SetPoint(0, x, coordsLo[1], coordsLo[2]);
259  gridt.SetPoint(1, x, coordsLo[1], coordsHi[2]);
260  }
261 
262  // Grid running along z at constant y
263  for (double y = coordsLo[1]; y <= coordsHi[1]; y += gridStep) {
264  // on right plane, fixed y, across z
265  TPolyLine3D& grids = view->AddPolyLine3D(2, color, style, width);
266  grids.SetPoint(0, coordsHi[0], y, coordsLo[2]);
267  grids.SetPoint(1, coordsHi[0], y, coordsHi[2]);
268  }
269 
270  return;
271  }
272 
274  double const* coordsLo,
275  double const* coordsHi,
276  int color,
277  int width,
278  int style) const
279  {
280  /*
281  * Axes are drawn encompassing the whole detector volume,
282  * the axis length being a fraction of the detector dimensions
283  */
284  double const vertexMargin = 0.06;
285  double const axisLength = 0.40; // 20% of the shortest
286 
287  double const dx = (coordsHi[0] - coordsLo[0]);
288  double const dy = (coordsHi[1] - coordsLo[1]);
289  double const dz = (coordsHi[2] - coordsLo[2]);
290 
291  // axes origin
292  double const x0 = coordsLo[0] - dx * vertexMargin;
293  double const y0 = coordsLo[1] - dy * vertexMargin;
294  double const z0 = coordsLo[2] - dz * vertexMargin;
295  // axis length
296  double const sz = axisLength * std::min({std::abs(dx), std::abs(dy), std::abs(dz)});
297 
298  TPolyLine3D& xaxis = view->AddPolyLine3D(2, color, style, width);
299  TPolyLine3D& yaxis = view->AddPolyLine3D(2, color, style, width);
300  TPolyLine3D& zaxis = view->AddPolyLine3D(2, color, style, width);
301  xaxis.SetPoint(0, x0, y0, z0);
302  xaxis.SetPoint(1, sz + x0, y0, z0);
303 
304  yaxis.SetPoint(0, x0, y0, z0);
305  yaxis.SetPoint(1, x0, y0 + sz, z0);
306 
307  zaxis.SetPoint(0, x0, y0, z0);
308  zaxis.SetPoint(1, x0, y0, z0 + sz);
309 
310  TPolyLine3D& xpoint = view->AddPolyLine3D(3, color, style, width);
311  TPolyLine3D& ypoint = view->AddPolyLine3D(3, color, style, width);
312  TPolyLine3D& zpoint = view->AddPolyLine3D(3, color, style, width);
313 
314  xpoint.SetPoint(0, 0.95 * sz + x0, y0, z0 - 0.05 * sz);
315  xpoint.SetPoint(1, 1.00 * sz + x0, y0, z0);
316  xpoint.SetPoint(2, 0.95 * sz + x0, y0, z0 + 0.05 * sz);
317 
318  ypoint.SetPoint(0, x0, 0.95 * sz + y0, z0 - 0.05 * sz);
319  ypoint.SetPoint(1, x0, 1.00 * sz + y0, z0);
320  ypoint.SetPoint(2, x0, 0.95 * sz + y0, z0 + 0.05 * sz);
321 
322  zpoint.SetPoint(0, x0 - 0.05 * sz, y0, 0.95 * sz + z0);
323  zpoint.SetPoint(1, x0 + 0.00 * sz, y0, 1.00 * sz + z0);
324  zpoint.SetPoint(2, x0 + 0.05 * sz, y0, 0.95 * sz + z0);
325 
326  TPolyLine3D& zleg = view->AddPolyLine3D(4, color, style, width);
327  zleg.SetPoint(0, x0 - 0.05 * sz, y0 + 0.05 * sz, z0 + 1.05 * sz);
328  zleg.SetPoint(1, x0 + 0.05 * sz, y0 + 0.05 * sz, z0 + 1.05 * sz);
329  zleg.SetPoint(2, x0 - 0.05 * sz, y0 - 0.05 * sz, z0 + 1.05 * sz);
330  zleg.SetPoint(3, x0 + 0.05 * sz, y0 - 0.05 * sz, z0 + 1.05 * sz);
331 
332  TPolyLine3D& yleg = view->AddPolyLine3D(5, color, style, width);
333  yleg.SetPoint(0, x0 - 0.05 * sz, y0 + 1.15 * sz, z0);
334  yleg.SetPoint(1, x0 + 0.00 * sz, y0 + 1.10 * sz, z0);
335  yleg.SetPoint(2, x0 + 0.00 * sz, y0 + 1.05 * sz, z0);
336  yleg.SetPoint(3, x0 + 0.00 * sz, y0 + 1.10 * sz, z0);
337  yleg.SetPoint(4, x0 + 0.05 * sz, y0 + 1.15 * sz, z0);
338 
339  TPolyLine3D& xleg = view->AddPolyLine3D(7, color, style, width);
340  xleg.SetPoint(0, x0 + 1.05 * sz, y0 + 0.05 * sz, z0 - 0.05 * sz);
341  xleg.SetPoint(1, x0 + 1.05 * sz, y0 + 0.00 * sz, z0 - 0.00 * sz);
342  xleg.SetPoint(2, x0 + 1.05 * sz, y0 + 0.05 * sz, z0 + 0.05 * sz);
343  xleg.SetPoint(3, x0 + 1.05 * sz, y0 + 0.00 * sz, z0 - 0.00 * sz);
344  xleg.SetPoint(4, x0 + 1.05 * sz, y0 - 0.05 * sz, z0 - 0.05 * sz);
345  xleg.SetPoint(5, x0 + 1.05 * sz, y0 + 0.00 * sz, z0 - 0.00 * sz);
346  xleg.SetPoint(6, x0 + 1.05 * sz, y0 - 0.05 * sz, z0 + 0.05 * sz);
347 
348  return;
349  }
350 
352 }
Float_t x
Definition: compare.C:6
bool fDrawAnodeGrid
Draws the grid on the anode plane.
bool fDrawAxes
true to draw coordinate axes
void DrawTPCoutline(evdb::View3D *view, geo::TPCGeo const &TPC, Color_t color, Width_t width, Style_t style) const
Draw the outline of the TPC volume.
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
Utilities related to art service access.
Encapsulate the construction of a single cyostat.
double ActiveHalfHeight() const
Half height (associated with y coordinate) of active TPC volume [cm].
Definition: TPCGeo.h:88
Float_t y
Definition: compare.C:6
Double_t z
Definition: plot.C:276
double MinX() const
Returns the world x coordinate of the start of the box.
Definition: BoxBoundedGeo.h:90
Geometry information for a single TPC.
Definition: TPCGeo.h:36
constexpr auto abs(T v)
Returns the absolute value of the argument.
double MaxX() const
Returns the world x coordinate of the end of the box.
Definition: BoxBoundedGeo.h:93
Geometry information for a single cryostat.
Definition: CryostatGeo.h:43
TGaxis * xaxis
Definition: plot_hist.C:61
void configure(const fhicl::ParameterSet &pset)
ProtoDUNEDrawer(const fhicl::ParameterSet &pset)
TPolyLine3D & AddPolyLine3D(int n, int c, int w, int s)
Definition: View3D.cxx:105
bool fDrawGrid
true to draw backing grid
double ActiveHalfLength() const
Length (associated with z coordinate) of active TPC volume [cm].
Definition: TPCGeo.h:94
void DrawGrids(evdb::View3D *view, double const *coordsLo, double const *coordsHi, int color=kGray, int width=1, int style=1) const
double ActiveHalfWidth() const
Half width (associated with x coordinate) of active TPC volume [cm].
Definition: TPCGeo.h:84
T get(std::string const &key) const
Definition: ParameterSet.h:314
double MinZ() const
Returns the world z coordinate of the start of the box.
virtual void DetOutline3D(evdb::View3D *view) override
Point_t GetActiveVolumeCenter() const
Returns the center of the TPC active volume in world coordinates [cm].
Definition: TPCGeo.h:250
double MaxY() const
Returns the world y coordinate of the end of the box.
void DrawRectangularBox(evdb::View3D *view, double const *coordsLo, double const *coordsHi, int color=kGray, int width=1, int style=1) const
std::size_t color(std::string const &procname)
void DrawActiveTPCoutline(evdb::View3D *view, geo::TPCGeo const &TPC, Color_t color, Width_t width, Style_t style) const
Draw the outline of the TPC active volume.
A base class aware of world box coordinatesAn object describing a simple shape can inherit from this ...
Definition: BoxBoundedGeo.h:33
void DrawAxes(evdb::View3D *view, double const *coordsLo, double const *coordsHi, int color=kGray, int width=1, int style=1) const
void DrawBoxBoundedGeoOutline(evdb::View3D *view, geo::BoxBoundedGeo const &bb, Color_t color, Width_t width, Style_t style) const
Draw the outline of an object bounded by a box.
double MaxZ() const
Returns the world z coordinate of the end of the box.
void ExtendToInclude(Coord_t x, Coord_t y, Coord_t z)
Extends the current box to also include the specified point.
A collection of 3D drawable objects.
This is the interface class for drawing 3D detector geometries.
double MinY() const
Returns the world y coordinate of the start of the box.
art framework interface to geometry description
bool fDrawActive
true to outline TPC sensitive volumes
Encapsulate the construction of a single detector plane.