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