ProtoDUNEDrawer_tool.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file ProtoDUNEDrawer.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 ProtoDUNEDrawer(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 fDrawAnodeGrid; ///< Draws the grid on the anode plane
53  bool fDrawAxes; ///< true to draw coordinate axes
54  bool fDrawActive; ///< true to outline TPC sensitive volumes
55 };
56 
57 //----------------------------------------------------------------------
58 // Constructor.
60 {
61  configure(pset);
62 }
63 
65 {
66  // Start by recovering the parameters
67  fDrawGrid = pset.get< bool >("DrawGrid", true);
68  fDrawAnodeGrid = pset.get< bool >("DrawAnodeGrid", false);
69  fDrawAxes = pset.get< bool >("DrawAxes", true);
70  fDrawActive = pset.get< bool >("DrawActive", true);
71 
72  return;
73 }
74 
75 //......................................................................
76 void ProtoDUNEDrawer::DetOutline3D(evdb::View3D* view)
77 {
78  auto const& geom = *(lar::providerFrom<geo::Geometry>());
79 
80  // we compute the total volume of the detector, to be used for the axes;
81  // we do include the origin by choice
82  geo::BoxBoundedGeo detector({ 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0 });
83 
84  // Draw a box for each cryostat, and, within it, for each TPC;
85  // the outlined volumes are the ones from the geometry boxes
86  for (geo::CryostatGeo const& cryo: geom.IterateCryostats()) {
87 
88  // include this cryostat in the detector volume
89  detector.ExtendToInclude(cryo);
90 
91  // draw the cryostat box
92  DrawBoxBoundedGeoOutline(view, cryo.Boundaries(), kRed + 2, 1, kSolid);
93 
94  // draw all TPC boxes
95  for (geo::TPCGeo const& TPC: cryo.TPCs()) {
96 
97  DrawTPCoutline(view, TPC, kRed, 2, kSolid);
98 
99  // BUG the double brace syntax is required to work around clang bug 21629
100  // optionally draw the grid
101  if (fDrawGrid) {
102  std::array<double, 3U> const
103  tpcLow {{ TPC.MinX(), TPC.MinY(), TPC.MinZ() }},
104  tpcHigh {{ TPC.MaxX(), TPC.MaxY(), TPC.MaxZ() }}
105  ;
106  DrawGrids(view, tpcLow.data(), tpcHigh.data(), kGray+2, 1, kSolid);
107  }
108 
109  // optionally draw the active volume
110  if (fDrawActive) DrawActiveTPCoutline(view, TPC, kCyan + 2, 1, kDotted);
111 
112  } // for TPCs in cryostat
113 
114  } // for cryostats
115 
116  // draw axes if requested
117  if (fDrawAxes) {
118  // BUG the double brace syntax is required to work around clang bug 21629
119  std::array<double, 3U> const
120  detLow = {{ detector.MinX(), detector.MinY(), detector.MinZ() }},
121  detHigh = {{ detector.MaxX(), detector.MaxY(), detector.MaxZ() }};
122 
123  DrawAxes(view, detLow.data(), detHigh.data(), kBlue, 1, kSolid);
124  } // if draw axes
125 
126 }
127 
128 
129 void ProtoDUNEDrawer::DrawBoxBoundedGeoOutline(evdb::View3D* view, geo::BoxBoundedGeo const& bb, Color_t color, Width_t width, Style_t style) const
130 {
131  // BUG the double brace syntax is required to work around clang bug 21629
132  std::array<double, 3U> const
133  low {{ bb.MinX(), bb.MinY(), bb.MinZ() }},
134  high {{ bb.MaxX(), bb.MaxY(), bb.MaxZ() }};
135  ;
136  DrawRectangularBox(view, low.data(), high.data(), color, width, style);
137 } // ProtoDUNEDrawer::DrawBoxBoundedGeoOutline()
138 
139 
140 void ProtoDUNEDrawer::DrawActiveTPCoutline(evdb::View3D* view, geo::TPCGeo const& TPC, Color_t color, Width_t width, Style_t style) const
141 {
142  auto const& activeCenter = TPC.GetActiveVolumeCenter();
144  {
145  {
146  activeCenter.X() - TPC.ActiveHalfWidth(),
147  activeCenter.Y() - TPC.ActiveHalfHeight(),
148  activeCenter.Z() - TPC.ActiveHalfLength()
149  },
150  {
151  activeCenter.X() + TPC.ActiveHalfWidth(),
152  activeCenter.Y() + TPC.ActiveHalfHeight(),
153  activeCenter.Z() + TPC.ActiveHalfLength()
154  }
155  },
156  color, width, style
157  );
158 }
159 
160 void ProtoDUNEDrawer::DrawRectangularBox(evdb::View3D* view, double const* coordsLo, double const* coordsHi, int color, int width, int style) const
161 {
162  TPolyLine3D& top = view->AddPolyLine3D(5, color, width, style);
163  top.SetPoint(0, coordsLo[0], coordsHi[1], coordsLo[2]);
164  top.SetPoint(1, coordsHi[0], coordsHi[1], coordsLo[2]);
165  top.SetPoint(2, coordsHi[0], coordsHi[1], coordsHi[2]);
166  top.SetPoint(3, coordsLo[0], coordsHi[1], coordsHi[2]);
167  top.SetPoint(4, coordsLo[0], coordsHi[1], coordsLo[2]);
168 
169  TPolyLine3D& side = view->AddPolyLine3D(5, color, width, style);
170  side.SetPoint(0, coordsHi[0], coordsHi[1], coordsLo[2]);
171  side.SetPoint(1, coordsHi[0], coordsLo[1], coordsLo[2]);
172  side.SetPoint(2, coordsHi[0], coordsLo[1], coordsHi[2]);
173  side.SetPoint(3, coordsHi[0], coordsHi[1], coordsHi[2]);
174  side.SetPoint(4, coordsHi[0], coordsHi[1], coordsLo[2]);
175 
176  TPolyLine3D& side2 = view->AddPolyLine3D(5, color, width, style);
177  side2.SetPoint(0, coordsLo[0], coordsHi[1], coordsLo[2]);
178  side2.SetPoint(1, coordsLo[0], coordsLo[1], coordsLo[2]);
179  side2.SetPoint(2, coordsLo[0], coordsLo[1], coordsHi[2]);
180  side2.SetPoint(3, coordsLo[0], coordsHi[1], coordsHi[2]);
181  side2.SetPoint(4, coordsLo[0], coordsHi[1], coordsLo[2]);
182 
183  TPolyLine3D& bottom = view->AddPolyLine3D(5, color, width, style);
184  bottom.SetPoint(0, coordsLo[0], coordsLo[1], coordsLo[2]);
185  bottom.SetPoint(1, coordsHi[0], coordsLo[1], coordsLo[2]);
186  bottom.SetPoint(2, coordsHi[0], coordsLo[1], coordsHi[2]);
187  bottom.SetPoint(3, coordsLo[0], coordsLo[1], coordsHi[2]);
188  bottom.SetPoint(4, coordsLo[0], coordsLo[1], coordsLo[2]);
189 
190  return;
191 }
192 
193 void ProtoDUNEDrawer::DrawGrids(evdb::View3D* view, double const* coordsLo, double const* coordsHi, int color, int width, int style) const
194 {
195  // If the x distance is small then we are drawing an anode grid...
196  // Check to see if wanted
197  if (!fDrawAnodeGrid && std::abs(coordsHi[0] - coordsLo[0]) < 25.) return;
198 
199  // uniform step size, each 25 cm except that at least 5 per plane
200  double const gridStep = std::min(25.0, std::max(10.,std::min({std::abs(coordsHi[0] - coordsLo[0]), std::abs(coordsHi[1] - coordsLo[1]), std::abs(coordsHi[2] - coordsLo[2])})) / 5);
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 ProtoDUNEDrawer::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 }
bool fDrawAnodeGrid
Draws the grid on the anode plane.
bool fDrawAxes
true to draw coordinate axes
Point GetActiveVolumeCenter() const
Returns the center of the TPC active volume in world coordinates [cm].
Definition: TPCGeo.h:288
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
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
void configure(const fhicl::ParameterSet &pset)
ProtoDUNEDrawer(const fhicl::ParameterSet &pset)
T abs(T value)
bool fDrawGrid
true to draw backing grid
double ActiveHalfLength() const
Length (associated with z coordinate) of active TPC volume [cm].
Definition: TPCGeo.h:105
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:95
T get(std::string const &key) const
Definition: ParameterSet.h:271
double MinZ() const
Returns the world z coordinate of the start of the box.
virtual void DetOutline3D(evdb::View3D *view) override
static int max(int a, int b)
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
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
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.
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.
bool fDrawActive
true to outline TPC sensitive volumes
Encapsulate the construction of a single detector plane.