TZProjPad.cxx
Go to the documentation of this file.
1 ///
2 /// \file TZProjPad.cxx
3 /// \brief Drawing pad for X-Z or Y-Z projections of events
4 /// \author messier@indiana.edu
5 /// \version $Id: TZProjPad.cxx,v 1.25 2012-12-05 02:43:06 bckhouse Exp $
6 ///
7 #include "TH2F.h"
8 #include "TPad.h"
9 
12 
13 #include "EventDisplay/TZProjPad.h"
23 #include "Geometry/Geometry.h"
25 #include "RecoBase/CellHit.h"
26 
27 namespace evd
28 {
29 
30  //......................................................................
31 
32  THUnZoomable::THUnZoomable(const char* a, const char* b,
33  int nx, double x0, double x1,
34  int ny, double y0, double y1)
35  : TH2F(a, b, nx, x0, x1, ny, y0, y1)
36  {
37  }
38 
39  //......................................................................
40 
42  {
43  GetXaxis()->UnZoom();
44  GetYaxis()->UnZoom();
45  }
46 
47  //......................................................................
48 
49  // Numeric flags for the XZ or ZY views
50  static const int kX = 0;
51  static const int kY = 1;
52 
53  static const double kZsf = 1.015; // Show z range larger than detector
54  static const double kTsf = 1.035; // Show x/y range larger than detector
55 
56  ///
57  /// Create a pad showing a single X-Z or Y-Z projection of the detector
58  /// \param nm : Name of the pad
59  /// \param ti : Title of the pad
60  /// \param x1 : Location of left edge of pad (0-1)
61  /// \param x2 : Location of right edge of pad (0-1)
62  /// \param y1 : Location of bottom edge of pad (0-1)
63  /// \param y2 : Location of top edge of pad (0-1)
64  /// \param opt : Options. Include 'x', 'y' for xz or yz projections
65  ///
66  TZProjPad::TZProjPad(const char* nm,
67  const char* ti,
68  double x1, double x2,
69  double y1, double y2,
70  const char* opt) :
71  DrawingPad(nm, ti, x1, x2, y1, y2),
72  fLastRun(999999),
73  fLastEvt(999999),
74  fLastSlice(999999),
75  fLastZoom(999999)
76  {
77 
79 
80  fDetId = geo->DetId();
81 
82  this->Pad()->SetBit(TPad::kCannotMove);
83  this->Pad()->cd();
84 
85  if (std::string(opt)=="x") fXorY = kX;
86  if (std::string(opt)=="y") fXorY = kY;
87  if (fXorY==kX) {
88  this->Pad()->SetLeftMargin (0.050);
89  this->Pad()->SetRightMargin (0.010);
90  this->Pad()->SetTopMargin (0.110);
91  this->Pad()->SetBottomMargin(0.005);
92  }
93  if (fXorY==kY) {
94  this->Pad()->SetLeftMargin (0.050);
95  this->Pad()->SetRightMargin (0.010);
96  this->Pad()->SetTopMargin (0.005);
97  this->Pad()->SetBottomMargin(0.120);
98  }
99 
100  fHisto = 0; // Force function to create us a new histogram
101  this->LayoutHisto();
102 
103  fView = new evdb::View2D();
104  }
105 
106  //......................................................................
107 
109  {
110  if (fHisto) { delete fHisto; fHisto = 0; }
111  if (fView) { delete fView; fView = 0; }
112  }
113 
114  //......................................................................
115 
116  void TZProjPad::Draw(const char* opt, bool* rezoom)
117  {
118  bool temp;
119  if(!rezoom) rezoom = &temp;
120 
121  fView->Clear();
122 
123  evdb::View2D* vx = 0;
124  evdb::View2D* vy = 0;
125  if (fXorY==kX) vx = fView; // fView is an XZ projection
126  if (fXorY==kY) vy = fView; // fView is a YZ projection
127 
128  // grab the singleton holding the art::Event
130  this->LayoutHisto();
131 
132  if (evt) {
133  this->GeometryDraw()-> DetOutline2D (*evt, vx, vy);
134  this->GeometryDraw()-> DrawCells2D (*evt, vx, vy);
135  this->GeometryDraw()-> DrawDCMBoxes (*evt, vx, vy);
136  this->GeometryDraw()-> FiducialVolumeUser2D (*evt, vx, vy);
137  this->GeometryDraw()-> DrawBadBoxesPretty (*evt, vx, vy); // nice looking badboxes but not quite exact
138  // this->GeometryDraw()-> DrawBadBoxesExact (*evt, vx, vy); // switch in to see exactly where the bad boxes are
139  this->SimulationDraw()->FLSHit2D (*evt, vx, vy);
140  this->SimulationDraw()->MCTruthVertices2D (*evt, vx, vy);
141  this->SimulationDraw()->MCTruthVectors2D (*evt, vx, vy);
142  this->SimulationDraw()->MCTruthTrajectories2D(*evt, vx, vy);
143  this->RawDataDraw()-> RawDigit2D (*evt, vx, vy);
144  this->RecoBaseDraw()-> CellHit2D (*evt, vx, vy);
145  this->GeometryDraw()-> DrawHighlightCell (*evt, vx, vy);
146  this->RecoBaseDraw()-> Cluster2D (*evt, vx, vy);
147  this->RecoBaseDraw()-> OfflineChans2D (*evt, vx, vy);
148  this->RecoBaseDraw()-> HoughResult2D (*evt, vx, vy);
149  this->RecoBaseDraw()-> Prong2D (*evt, vx, vy);
150  this->RecoBaseDraw()-> Track2D (*evt, vx, vy);
151  this->RecoBaseDraw()-> Vertex2D (*evt, vx, vy);
152  }
153 
156  fPad->cd();
157  fPad->Clear();
158 
159  int grid = ((drawopt->fOutline &
161  fPad->SetGridx(grid);
162  fPad->SetGridy(grid);
163 
164  this->LayoutHisto();
165  if (!fHisto) return;
166 
167  if (fXorY==kX) fHisto->Draw("X+");
168  else fHisto->Draw("");
169 
170  // Check if we should zoom the displays
171  *rezoom = false;
172  if(evt){
173  if (fLastRun != evt->run()) *rezoom = true;
174  if (fLastEvt != evt->id().event()) *rezoom = true;
175  if (fLastSlice != nav->CurrentSlice()) *rezoom = true;
176  }
177  if (fLastZoom != drawopt->fZoom) *rezoom = true;
179  int(fLastSlice) != nav->CurrentSlice())
180  *rezoom = true;
181 
182  if (*rezoom) {
183  switch (drawopt->fZoom) {
185  if (evt) AutoZoomTruth(evt);
186  break;
188  if (evt) AutoZoomSlice(evt);
189  break;
191  AutoZoom();
192  break;
194  ShowPartial();
195  break;
197  AutoZoomBox(evt);
198  break;
199  default:
200  ShowFull();
201  }
202  }
203 
204  if(evt){
205  fLastRun = evt->run();
206  fLastEvt = evt->id().event();
207  }
208  fLastSlice = nav->CurrentSlice();
209  fLastZoom = drawopt->fZoom;
210 
211  fView->Draw();
212  // Axes can get overdrawn by pad objects
213  // This somehow causes an infinite loop in the FD, comment out for now.
214  // fHisto->Draw("axis same");
215  }
216 
217  //......................................................................
218 
219  ///
220  /// Automatically zoom the view to a size just larger than the
221  /// events. Also ensures that the aspect ratio is the same for the XZ
222  /// and YZ projections.
223  ///
225  {
226  double xmin, ymin, zmin;
227  double xmax, ymax, zmax;
228  this->RawDataDraw()->GetLimits(&xmin, &xmax,
229  &ymin, &ymax,
230  &zmin, &zmax);
231 
232  AutoZoomHelper(xmin, xmax, ymin, ymax, zmin, zmax, .1);
233  }
234 
235  //......................................................................
236 
238  {
239  assert(evt);
240 
241  std::vector<art::Handle<std::vector<rb::CellHit>>> chits;
242  evt->getManyByType(chits);
243 
244  std::set<geo::OfflineChan> hmap;
245  for(unsigned int i = 0; i < chits.size(); ++i){
246  for(unsigned int j = 0; j < chits[i]->size(); ++j){
247  const art::Ptr<rb::CellHit> chit(chits[i], j);
248  hmap.insert(geo::OfflineChan(chit->Plane(), chit->Cell()));
249  }
250  }
251 
252  double xmin, xmax, ymin, ymax, zmin, zmax;
253  SimulationDraw()->GetLimits(evt, xmin, xmax, ymin, ymax, zmin, zmax, hmap);
254 
255  AutoZoomHelper(xmin, xmax, ymin, ymax, zmin, zmax, .05);
256  }
257 
258  //......................................................................
259 
261  {
262  assert(evt);
263 
265  double xmin, xmax, ymin, ymax, zmin, zmax;
266  // Drop 10% of outlier hits from each axis
267  nav->GetBounds(*evt, xmin, xmax, ymin, ymax, zmin, zmax, .1);
268 
269  // But then add in 20% of padding to compensate
270  AutoZoomHelper(xmin, xmax, ymin, ymax, zmin, zmax, .2);
271  }
272 
274  {
275  assert(evt);
276 
278  double xmin, xmax, ymin, ymax, zmin, zmax;
279  // Drop 10% of outlier hits from each axis
280  nav->GetBox(*evt, xmin, xmax, ymin, ymax, zmin, zmax, .1);
281 
282  // But then add in 20% of padding to compensate
283  AutoZoomHelper(xmin, xmax, ymin, ymax, zmin, zmax, .2);
284  }
285 
286  //......................................................................
287 
288  void TZProjPad::AutoZoomHelper(double xmin, double xmax,
289  double ymin, double ymax,
290  double zmin, double zmax, double safety)
291  {
292  const double dxy = std::max(xmax-xmin, ymax-ymin);
293  const double dz = zmax-zmin;
294 
295  const double xavg = (xmin+xmax)/2;
296  const double yavg = (ymin+ymax)/2;
297 
298  xmin = xavg-(.5+safety)*dxy;
299  xmax = xavg+(.5+safety)*dxy;
300  ymin = yavg-(.5+safety)*dxy;
301  ymax = yavg+(.5+safety)*dxy;
302  zmin -= safety*dz;
303  zmax += safety*dz;
304 
305  fHisto->GetXaxis()->SetRangeUser(zmin, zmax);
306  if(fXorY == kX) fHisto->GetYaxis()->SetRangeUser(xmin, xmax);
307  else fHisto->GetYaxis()->SetRangeUser(ymin, ymax);
308  }
309 
310  //......................................................................
311 
313  {
316 
317  double xmin = -kTsf*g->DetHalfWidth();
318  double xmax = +kTsf*g->DetHalfWidth();
319  double ymin = -kTsf*g->DetHalfHeight();
320  double ymax = +kTsf*g->DetHalfHeight();
321  double zmin = -(kZsf-1.0)*g->DetLength();
322  double zmax = +(kZsf )* drawopt->fZRange;
323 
324  GeoTransform::XYZ(&xmin, &ymin, &zmin);
325  GeoTransform::XYZ(&xmax, &ymax, &zmax);
326 
327  fHisto->GetXaxis()->SetRangeUser(zmin,zmax);
328  if (fXorY==kX) fHisto->GetYaxis()->SetRangeUser(xmin,xmax);
329  else fHisto->GetYaxis()->SetRangeUser(ymin,ymax);
330  }
331 
332  //......................................................................
333 
335  {
337 
338  double xmin = -kTsf*g->DetHalfWidth();
339  double xmax = +kTsf*g->DetHalfWidth();
340  double ymin = -kTsf*g->DetHalfHeight();
341  double ymax = +kTsf*g->DetHalfHeight();
342  double zmin = -(kZsf-1.0)*g->DetLength();
343  double zmax = +(kZsf )*g->DetLength();
344 
345  GeoTransform::XYZ(&xmin, &ymin, &zmin);
346  GeoTransform::XYZ(&xmax, &ymax, &zmax);
347 
348  fHisto->GetXaxis()->SetRangeUser(zmin,zmax);
349  if (fXorY==kX) fHisto->GetYaxis()->SetRangeUser(xmin,xmax);
350  else fHisto->GetYaxis()->SetRangeUser(ymin,ymax);
351  }
352 
353  //......................................................................
354  void TZProjPad::GetWrange(int* i1, int* i2) const
355  {
356  *i1 = fHisto->GetYaxis()->GetFirst();
357  *i2 = fHisto->GetYaxis()->GetLast();
358  }
359 
360  //......................................................................
361 
362  void TZProjPad::GetZrange(int* i1, int* i2) const
363  {
364  *i1 = fHisto->GetXaxis()->GetFirst();
365  *i2 = fHisto->GetXaxis()->GetLast();
366  }
367 
368  //......................................................................
369  void TZProjPad::GetWrangeCm(float* i1, float* i2) const
370  {
371  TAxis *axis = fHisto->GetYaxis();
372  *i1 = axis->GetBinCenter( axis->GetFirst() );
373  *i2 = axis->GetBinCenter( axis->GetLast() );
374  }
375 
376  //......................................................................
377 
378  void TZProjPad::GetZrangeCm(float* i1, float* i2) const
379  {
380  TAxis *axis = fHisto->GetXaxis();
381  *i1 = axis->GetBinCenter( axis->GetFirst() );
382  *i2 = axis->GetBinCenter( axis->GetLast() );
383  }
384 
385  //......................................................................
386 
387  void TZProjPad::GetZBoundCm(float* i1, float* i2) const
388  {
389  TAxis *axis = fHisto->GetXaxis();
390  *i1 = axis->GetXmin();
391  *i2 = axis->GetXmax();
392  }
393 
394  //......................................................................
395 
396  void TZProjPad::GetWBoundCm(float* i1, float* i2) const
397  {
398  TAxis *axis = fHisto->GetYaxis();
399  *i1 = axis->GetXmin();
400  *i2 = axis->GetXmax();
401  }
402 
403  //......................................................................
404 
405 
406  void TZProjPad::SetZrange(int i1, int i2)
407  {
408  fHisto->GetXaxis()->SetRange(i1,i2);
409  }
410 
411  //......................................................................
412 
413  void TZProjPad::SetZrangeCm(float i1, float i2)
414  {
415  TAxis *axis = fHisto->GetXaxis();
416  axis->SetRange( axis->FindBin(i1) , axis->FindBin(i2) );
417  }
418 
419  //......................................................................
420 
421  void TZProjPad::SetWrange(int i1, int i2)
422  {
423  fHisto->GetYaxis()->SetRange(i1,i2);
424  }
425 
426  //......................................................................
427 
428  void TZProjPad::SetWrangeCm(float i1, float i2)
429  {
430  TAxis *axis = fHisto->GetYaxis();
431  axis->SetRange( axis->FindBin(i1) , axis->FindBin(i2) );
432  }
433 
434  //......................................................................
435 
437  {
438  //
439  // Check if the current layout is correct. That is, we have a
440  // histogram and the detector ID matches the detector ID for the
441  // current geometry.
442  //
444  if (fHisto && geo->DetId() == fDetId) return;
445  fDetId = geo->DetId();
446 
447  if (geo->DetId() == novadaq::cnv::kUNKNOWN_DET) return;
448 
449  //
450  // Figure out the z range for axis. The z-range may optionally run
451  // from north to south or from south to north.
452  //
453  double zlo = -(kZsf-1.0)*geo->DetLength();
454  double zhi = (kZsf )*geo->DetLength();
455  GeoTransform::Z(&zlo);
456  GeoTransform::Z(&zhi);
457  if (zlo>zhi) { double ztmp = zlo; zlo = zhi; zhi = ztmp; }
458 
459  //
460  // Figure out how to label the axes. We may be asked to label
461  // compass directions and have to account for axis flips
462  //
464  bool flipx = geoopt->fFlip & evd::GeometryDrawingOptions::kFLIP_X;
465  bool flipz = geoopt->fFlip & evd::GeometryDrawingOptions::kFLIP_Z;
466  const char* xlabel = ";;x (cm)";
467  const char* ylabel = ";z (cm);y (cm)";
469  if (flipx) xlabel = ";;#leftarrow west x (cm) east #rightarrow";
470  else xlabel = ";;#leftarrow east x (cm) west #rightarrow";
471  if (flipz) ylabel = ";#leftarrow north z (cm) south #rightarrow;y (cm)";
472  else ylabel = ";#leftarrow south z (cm) north #rightarrow;y (cm)";
473  }
474 
475  delete fHisto; fHisto = 0;
476  if (fXorY == kX){
477  fHisto = new THUnZoomable("fTZXHisto",
478  xlabel,
479  2000,
480  zlo,
481  zhi,
482  1000,
483  -kTsf*geo->DetHalfWidth(),
484  +kTsf*geo->DetHalfWidth());
485  }
486  if (fXorY == kY){
487  fHisto = new THUnZoomable("fTZYHisto",
488  ylabel,
489  2000,
490  zlo,
491  zhi,
492  1000,
493  -kTsf*geo->DetHalfHeight(),
494  +kTsf*geo->DetHalfHeight());
495  }
496 
497  fHisto->GetYaxis()->CenterTitle();
498  fHisto->GetYaxis()->SetNdivisions(505);
499  fHisto->SetTitleOffset(0.5, "Y");
500 
501  fHisto->GetXaxis()->SetNoExponent();
502  }
503 
504 } // end namespace evd
505 ////////////////////////////////////////////////////////////////////////
void LayoutHisto()
Definition: TZProjPad.cxx:436
static const double kTsf
Definition: TZProjPad.cxx:54
T max(const caf::Proxy< T > &a, T b)
void SetZrange(int i1, int i2)
Definition: TZProjPad.cxx:406
void GetWBoundCm(float *i1, float *i2) const
Definition: TZProjPad.cxx:396
const art::Event * GetEvent() const
Definition: EventHolder.cxx:45
int fLabel
Which labels to draw?
std::map< std::string, double > xmax
void FLSHit2D(const art::Event &evt, evdb::View2D *xzview, evdb::View2D *yzview)
void GetBounds(const art::Event &evt, double &xmin, double &xmax, double &ymin, double &ymax, double &zmin, double &zmax, double trimfrac=0)
Float_t y1[n_points_granero]
Definition: compare.C:5
correl_xv GetYaxis() -> SetDecimals()
Implement an UnZoom menu item.
Definition: TZProjPad.h:22
unsigned int fLastRun
Last run number shown.
Definition: TZProjPad.h:67
unsigned short Plane() const
Definition: CellHit.h:39
void GetLimits(double *xmin, double *xmax, double *ymin, double *ymax, double *zmin, double *zmax)
Float_t x1[n_points_granero]
Definition: compare.C:5
static const double kZsf
Definition: TZProjPad.cxx:53
void GetBox(const art::Event &evt, double &xmin, double &xmax, double &ymin, double &ymax, double &zmin, double &zmax, double trimfrac=0)
static constexpr Double_t nm
Definition: Munits.h:133
void Draw(const char *opt=0, bool *rezoom=0)
Definition: TZProjPad.cxx:116
double DetLength() const
GeometryDrawer * GeometryDraw()
Definition: DrawingPad.cxx:73
void GetZBoundCm(float *i1, float *i2) const
Definition: TZProjPad.cxx:387
void SetWrange(int i1, int i2)
Definition: TZProjPad.cxx:421
void AutoZoomSlice(const art::Event *evt)
Definition: TZProjPad.cxx:260
void GetWrange(int *i1, int *i2) const
Definition: TZProjPad.cxx:354
A collection of drawable 2-D objects.
void ShowPartial()
Definition: TZProjPad.cxx:312
TZProjPad(const char *nm, const char *ti, double x1, double y1, double x2, double y2, const char *opt)
Definition: TZProjPad.cxx:66
void MCTruthVectors2D(const art::Event &evt, evdb::View2D *xzview, evdb::View2D *yzview)
void AutoZoomHelper(double xmin, double xmax, double ymin, double ymax, double zmin, double zmax, double safety)
Definition: TZProjPad.cxx:288
void GetWrangeCm(float *i1, float *i2) const
Definition: TZProjPad.cxx:369
void Clear()
Definition: View2D.cxx:109
Singleton to hold the current art::Event for the event display.
Double_t ymax
Definition: plot.C:25
int fXorY
Which view? 0 = X vs. Z, 1 = Y vs. Z.
Definition: TZProjPad.h:72
void SetWrangeCm(float i1, float i2)
Definition: TZProjPad.cxx:428
unsigned short Cell() const
Definition: CellHit.h:40
nova event display
double dz[NP][NC]
void MCTruthTrajectories2D(const art::Event &evt, evdb::View2D *xzview, evdb::View2D *yzview)
RawDataDrawer * RawDataDraw()
Definition: DrawingPad.cxx:91
void Draw()
Definition: View2D.cxx:89
static EventHolder * Instance()
Definition: EventHolder.cxx:15
const double a
correl_xv GetXaxis() -> SetDecimals()
void SetZrangeCm(float i1, float i2)
Definition: TZProjPad.cxx:413
novadaq::cnv::DetId DetId() const
Prefer ds::DetectorService::DetId() instead.
Definition: GeometryBase.h:243
int evt
Base class for event display drawing pads.
Definition: DrawingPad.h:20
RecoBaseDrawer * RecoBaseDraw()
Definition: DrawingPad.cxx:101
int fZoom
How to zoom the display.
void MCTruthVertices2D(const art::Event &evt, evdb::View2D *xzview, evdb::View2D *yzview)
void getManyByType(std::vector< Handle< PROD >> &results) const
Definition: DataViewImpl.h:446
TPad * Pad()
Definition: DrawingPad.h:27
const double j
Definition: BetheBloch.cxx:29
double DetHalfHeight() const
SimulationDrawer * SimulationDraw()
Definition: DrawingPad.cxx:82
Class to aid in the rendering of RecoBase objects.
void GetLimits(const art::Event *evt, double &xmin, double &xmax, double &ymin, double &ymax, double &zmin, double &zmax, const std::set< geo::OfflineChan > &hmap={})
Class to aid in the rendering of RawData objects.
unsigned int fLastEvt
Last event number shown.
Definition: TZProjPad.h:68
Class to aid in the rendering of Geometry objects.
static const int kX
Definition: TZProjPad.cxx:50
EventNumber_t event() const
Definition: EventID.h:116
double DetHalfWidth() const
TH2F * fHisto
Histogram to draw objects on.
Definition: TZProjPad.h:73
int fLastSlice
Last slice number shown.
Definition: TZProjPad.h:69
static void Z(double *z)
void AutoZoomTruth(const art::Event *evt)
Definition: TZProjPad.cxx:237
A (plane, cell) pair.
Definition: OfflineChan.h:17
static const int kY
Definition: TZProjPad.cxx:51
int fLastZoom
Last zoom option applied.
Definition: TZProjPad.h:70
Render the objects from the Simulation package.
const hit & b
Definition: hits.cxx:21
assert(nhit_max >=nhit_nbins)
Double_t ymin
Definition: plot.C:24
void GetZrangeCm(float *i1, float *i2) const
Definition: TZProjPad.cxx:378
TPad * fPad
The ROOT graphics pad.
Definition: DrawingPad.h:37
THUnZoomable(const char *a, const char *b, int nx, double x0, double x1, int ny, double y0, double y1)
Definition: TZProjPad.cxx:32
void GetZrange(int *i1, int *i2) const
Definition: TZProjPad.cxx:362
evdb::View2D * fView
Collection of graphics objects to render.
Definition: TZProjPad.h:74
RunNumber_t run() const
Definition: Event.h:77
Helper for AttenCurve.
Definition: Path.h:10
int fFlip
Reverse the sense of any of the coordinate axes?
EventID id() const
Definition: Event.h:56
Encapsulate the geometry of one entire detector (near, far, ndos)
static void XYZ(double *xyz)
void AutoZoomBox(const art::Event *evt)
Definition: TZProjPad.cxx:273
int fDetId
Detector display is configured for.
Definition: TZProjPad.h:71
int fOutline
Which outlines to draw.
Global drawing options that apply to all displays.
enum BeamMode string