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