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