XZYZProjectionsView.cxx
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////
2 /// \file XZYZProjectionsView.cxx
3 /// \brief The "main" event display view that most people will want to use
4 /// \author messier@indiana.edu
5 /// \version $Id: XZYZProjectionsView.cxx,v 1.13 2012-03-10 02:09:41 bckhouse Exp $
6 /////////////////////////////////////////////////////////////////////////////
7 #include <cmath>
8 #include <iostream>
9 
10 #include "TAxis.h"
11 #include "TCanvas.h"
12 #include "TH2F.h"
13 #include "TTimer.h"
14 
15 #include "EventDisplay/HeaderPad.h"
18 #include "EventDisplay/TZProjPad.h"
19 #include "EventDisplay/TQPad.h"
21 
22 #include "TRootEmbeddedCanvas.h"
23 
24 namespace evd
25 {
26  //...................................................................
28  evdb::Canvas(mf),
29  fX0(0.0),
30  fX1(0.135),
31  fX3(1.0),
32  fX2(0.5*(fX1+fX3)),
33  fY0(0.0),
34  fY1(0.14),
35  fY2(0.17),
36  fY4(1.0),
37  fY3(0.5*(fY2+fY4))
38  {
40  fHeaderPad = new HeaderPad("fHeaderPad","Header",fX0,fY0,fX1,fY2,"");
41  fHeaderPad->Draw();
42 
44  fRawT = new TQPad("fTPad", "Hit Times",fX1,fY0,fX2,fY1,"T");
45  fRawT->Draw();
46 
48  fRawQ = new TQPad("fQPad", "Hit Charges",fX2,fY0,fX3,fY1,"Q");
49  fRawQ->Draw();
50 
52  fMC = new MCBriefPad("fMCPad","MC Info.",fX1,fY1,fX3,fY2,"");
53  fMC->Draw();
54 
56  fXview = new TZProjPad("fXView","xz view",fX0,fY3,fX3,fY4,"x");
57  fXview->Draw();
58 
60  fYview = new TZProjPad("fYView","yz view",fX0,fY2,fX3,fY3,"y");
61  fYview->Draw();
62 
63  fXview->Pad()->Connect("RangeChanged()",
64  "evd::XZYZProjectionsView",
65  this,
66  "RangeChanged()");
67  fYview->Pad()->Connect("RangeChanged()",
68  "evd::XZYZProjectionsView",
69  this,
70  "RangeChanged()");
71 
72  // Want the slice bar top, but the canvas got there first. Remove it...
73  mf->RemoveFrame(fEmbCanvas);
74  // ...add the bar...
76  mf->AddFrame(fSliceButtonBar,
77  new TGLayoutHints(kLHintsTop | kLHintsExpandX,
78  0, 0, 1, 0));
79  // ...and put the canvas back
80  mf->AddFrame(fEmbCanvas, fLayout);
81 
82  fCanvas->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)", "evd::XZYZProjectionsView",
83  this, "AspectRatioHandler(int, int, int, TObject*)");
84 
85  evdb::Canvas::fCanvas->Update();
86  }
87 
88  //......................................................................
89 
91  {
92  if (fRawT) { delete fRawT; fRawT = 0; }
93  if (fRawQ) { delete fRawQ; fRawQ = 0; }
94  if (fMC) { delete fMC; fMC = 0; }
95  if (fXview) { delete fXview; fXview = 0; }
96  if (fYview) { delete fYview; fYview = 0; }
97  if (fSliceButtonBar) { delete fSliceButtonBar; fSliceButtonBar = 0; }
98  }
99 
100  //......................................................................
101  //
102  // Adjust the aspect ratios of the x and y views to reflect the size
103  // of the detector
104  //
106  {
107  if(!fXview->fHisto || !fYview->fHisto) return;
108 
109  static double lastnx = 0.0;
110  static double lastny = 0.0;
111 
112  double nx =
113  fXview->fHisto->GetYaxis()->GetXmax()-
114  fXview->fHisto->GetYaxis()->GetXmin();
115  double ny =
116  fYview->fHisto->GetYaxis()->GetXmax()-
117  fYview->fHisto->GetYaxis()->GetXmin();
118 
119  //
120  // Is the current aspect ratio correct?
121  //
122  if (lastnx == nx && lastny==ny) return;
123  static const double tol = 0.001;
124  if (fabs(lastnx-nx)<tol && fabs(lastny-ny)<tol) return;
125 
126  lastnx = nx;
127  lastny = ny;
128 
129  //
130  // Reposition the boundary (fY3) between the X and Y views so that
131  // the distance between y3 and y4 scales with nx and the distance
132  // between y2 and y3 scales with ny
133  //
134  fY3 = (nx*fY2+ny*fY4)/(nx+ny);
135 
136  fXview->Pad()->SetPad(fX0,fY3,fX3,fY4);
137  fYview->Pad()->SetPad(fX0,fY2,fX3,fY3);
138 
139  //
140  // Along with scaling the views, we need to rescale the fonts sizes
141  // and offsets to keep them lined up
142  //
143  double sfx = (fY3-fY2)/(fY4-fY2);
144  double sfy = (fY4-fY3)/(fY4-fY2);
145 
146  TAxis* xvx = fXview->fHisto->GetXaxis();
147  TAxis* xvy = fXview->fHisto->GetYaxis();
148  xvx->SetTickLength(0.01);
149  xvy->SetTickLength(0.01);
150 
151  xvx->SetTitleSize(0.15*sfx);
152  xvy->SetTitleSize(0.15*sfx);
153 
154  xvx->SetTitleOffset(0.8);
155  xvy->SetTitleOffset(0.65*sfy);
156  xvx->SetLabelSize(0.12*sfx);
157  xvy->SetLabelSize(0.12*sfx);
158  xvx->SetLabelOffset(0.025*sfx);
159 
160  TAxis* yvx = fYview->fHisto->GetXaxis();
161  TAxis* yvy = fYview->fHisto->GetYaxis();
162 
163  yvx->SetTickLength(0.01);
164  yvy->SetTickLength(0.01);
165  yvx->SetTitleSize(0.15*sfy);
166  yvy->SetTitleSize(0.15*sfy);
167  yvx->SetTitleOffset(0.8);
168  yvy->SetTitleOffset(0.65*sfx);
169 
170  yvx->SetLabelSize(0.12*sfy);
171  yvy->SetLabelSize(0.12*sfy);
172  yvx->SetLabelOffset(0.025*sfy);
173  }
174 
175  //......................................................................
176 
177  void XZYZProjectionsView::Draw(const char* opt)
178  {
179  evdb::Canvas::fCanvas->cd();
180 
181  fHeaderPad->Draw();
182 
183  fRawT->Draw();
184  fRawQ->Draw();
185  fMC->Draw();
186 
187  bool rezoom = false;
188 
189  fXview->Draw(opt, &rezoom);
190  fYview->Draw(opt, &rezoom);
191 
192  // Any auto-zooming should always wind up in a state with correct aspect
193  // ratio.
194  if(rezoom) FixAspectRatio();
195 
197 
198  this->SetAspectRatio();
199 
200  evdb::Canvas::fCanvas->Update();
201  }
202 
203  //......................................................................
204 
205  class Refresher: public TTimer
206  {
207  public:
208  Refresher() : TTimer(0, kTRUE) {}
209  virtual Bool_t Notify()
210  {
211  gPad->Update();
212  TurnOff();
213  return kFALSE;
214  }
215  } gRefresher;
216 
217  //......................................................................
218 
220  {
221  static int ilolast = -1;
222  static int ihilast = -1;
223 
224  int i1lo, i1hi;
225  int i2lo, i2hi;
226 
227  fXview->GetZrange(&i1lo, &i1hi);
228  fYview->GetZrange(&i2lo, &i2hi);
229 
230  bool axis1changed = (i1lo!=ilolast)||(i1hi!=ihilast);
231  bool axis2changed = (i2lo!=ilolast)||(i2hi!=ihilast);
232 
233  if (axis1changed==true) {
234  fYview->SetZrange(i1lo, i1hi);
235  fYview->Pad()->Modified();
236 
237  ilolast = i1lo;
238  ihilast = i1hi;
239  }
240  if (axis2changed==true) {
241  fXview->SetZrange(i2lo, i2hi);
242  fXview->Pad()->Modified();
243 
244  ilolast = i2lo;
245  ihilast = i2hi;
246  }
247 
248  if(axis1changed || axis2changed){
249  // We need to call gPad->Update() to get these new axis ranges
250  // drawn. Unfortunately, this function is called in the middle of another
251  // gPad->Update(), and ROOT prevents two calls from happening at
252  // once. Instead, arrange matters so that it will be called just as soon
253  // as we return to the event loop. This is the neatest way I could figure
254  // out to get a one-short timer (I can't make TTimer::SingleShot() work
255  // right).
256  gRefresher.TurnOn();
257  }
258  }
259 
260  //......................................................................
261 
262  void XZYZProjectionsView::AspectRatioHandler( int event, int key, int py, TObject *sel)
263  {
264 
265  if (event != kKeyPress || key != '=' )
266  return;
267 
268  FixAspectRatio();
269  }
270 
271  //......................................................................
272 
274  {
275  float xmin, xmax, ymin, ymax, zmin, zmax;
276  fXview->GetWrangeCm(&xmin, &xmax);
277  fYview->GetWrangeCm(&ymin, &ymax);
278  fXview->GetZrangeCm(&zmin, &zmax);
279 
280  float xcm = xmax - xmin;
281  float ycm = ymax - ymin;
282  float zcm = zmax - zmin;
283 
284  int xpix = fXview->Pad()->GetWh()*fXview->Pad()->GetHNDC();
285  int ypix = fYview->Pad()->GetWh()*fYview->Pad()->GetHNDC();
286  int zpix = fXview->Pad()->GetWw()*fXview->Pad()->GetWNDC();
287 
288  float xpixcm = xpix/xcm;
289  float ypixcm = ypix/ycm;
290  float zpixcm = zpix/zcm;
291 
292  float xboundmin, xboundmax, yboundmin, yboundmax, zboundmin, zboundmax;
293 
294  fXview->GetZBoundCm( &zboundmin, &zboundmax);
295  fXview->GetWBoundCm( &xboundmin, &xboundmax);
296  fYview->GetWBoundCm( &yboundmin, &yboundmax);
297 
298  if( xpixcm < ypixcm && xpixcm < zpixcm ){
299  // x is more zoomed out, zoom out on y,z as well.
300 
301  std::vector<float> zrange = GetRightAxesRange( zpix, zcm, zmin, zmax,
302  zboundmin, zboundmax,
303  xpix, xcm);
304 
305  std::vector<float> yrange = GetRightAxesRange( ypix, ycm, ymin, ymax,
306  yboundmin, yboundmax,
307  xpix, xcm);
308  fXview->SetZrangeCm( zrange[0], zrange[1]);
309  fYview->SetZrangeCm( zrange[0], zrange[1]);
310  fYview->SetWrangeCm( yrange[0], yrange[1]);
311  fXview->Pad()->Modified();
312  fYview->Pad()->Modified();
313  }
314 
315  else if( ypixcm < xpixcm && ypixcm < zpixcm ){
316 
317  // y is more zoomed out, zoom out on x,z as well.
318 
319  std::vector<float> zrange = GetRightAxesRange( zpix, zcm, zmin, zmax,
320  zboundmin, zboundmax,
321  ypix, ycm);
322 
323  std::vector<float> xrange = GetRightAxesRange( xpix, xcm, xmin, xmax,
324  xboundmin, xboundmax,
325  ypix, ycm);
326 
327  fXview->SetZrangeCm( zrange[0], zrange[1]);
328  fYview->SetZrangeCm( zrange[0], zrange[1]);
329  fXview->SetWrangeCm( xrange[0], xrange[1]);
330  fXview->Pad()->Modified();
331  fYview->Pad()->Modified();
332  }
333 
334  else if( zpixcm < ypixcm && zpixcm < xpixcm ){
335 
336  // x is more zoomed out, zoom out on y,z as well.
337 
338  std::vector<float> xrange = GetRightAxesRange( xpix, xcm, xmin, xmax,
339  xboundmin, xboundmax,
340  zpix, zcm);
341 
342  std::vector<float> yrange = GetRightAxesRange( ypix, ycm, ymin, ymax,
343  yboundmin, yboundmax,
344  zpix, zcm);
345 
346  fXview->SetWrangeCm( xrange[0], xrange[1]);
347  fYview->SetWrangeCm( yrange[0], yrange[1]);
348  fXview->Pad()->Modified();
349  fYview->Pad()->Modified();
350  }
351 
352  else if( ypixcm == xpixcm && ypixcm < zpixcm ){
353  // y,x are more zoomed out, zoom out on z as well.
354 
355  std::vector<float> zrange = GetRightAxesRange( zpix, zcm, zmin, zmax,
356  zboundmin, zboundmax,
357  ypix, ycm);
358 
359  fXview->SetZrangeCm( zrange[0], zrange[1]);
360  fYview->SetZrangeCm( zrange[0], zrange[1]);
361  fXview->Pad()->Modified();
362  fYview->Pad()->Modified();
363  }
364 
365  else if( zpixcm == xpixcm && zpixcm < ypixcm ){
366  // y,x are more zoomed out, zoom out on z as well.
367 
368  std::vector<float> yrange = GetRightAxesRange( ypix, ycm, ymin, ymax,
369  yboundmin, yboundmax,
370  zpix, zcm);
371 
372  fYview->SetWrangeCm( yrange[0], yrange[1]);
373  fYview->Pad()->Modified();
374  }
375 
376  else if( zpixcm == ypixcm && zpixcm < xpixcm ){
377  // y,x are more zoomed out, zoom out on z as well.
378 
379  std::vector<float> xrange = GetRightAxesRange( xpix, xcm, xmin, xmax,
380  xboundmin, xboundmax,
381  zpix, zcm);
382  fXview->SetWrangeCm( xrange[0], xrange[1]);
383  fXview->Pad()->Modified();
384  }
385 
386  fCanvas->Update();
387  }
388 
389  //......................................................................
390 
391  std::vector<float> XZYZProjectionsView::GetRightAxesRange( int pix, float cm, float min,
392  float max, float boundmin,
393  float boundmax, int tpix, float tcm)
394  {
395  std::vector<float> range;
396 
397  float zoom = (tcm * pix / tpix ) -cm;
398  float lo = min - (zoom/2);
399  float hi = max + (zoom/2);
400 
401  if( lo < boundmin ){
402  float shift = boundmin - lo;
403  lo = boundmin;
404  hi = hi + shift;
405  }
406 
407  if( hi > boundmax ){
408  float shift = hi - boundmax;
409  lo = lo - shift;
410  hi = boundmax;
411  }
412  range.push_back( lo );
413  range.push_back( hi );
414 
415  return range;
416  }
417 
418 } // end namespace evd
419 ////////////////////////////////////////////////////////////////////////
void SetZrange(int i1, int i2)
Definition: TZProjPad.cxx:406
TSpline3 lo("lo", xlo, ylo, 12,"0")
void GetWBoundCm(float *i1, float *i2) const
Definition: TZProjPad.cxx:396
HeaderPad * fHeaderPad
Show header information.
A view showing XZ and YZ readout planes.
std::map< std::string, double > xmax
Definition: Canvas.py:1
fvar< T > fabs(const fvar< T > &x)
Definition: fabs.hpp:15
Drawing pad for short summary of an MC event.
Controls for navigating between slices.
TZProjPad * fYview
Y - Z projection of the event.
MCBriefPad * fMC
Short summary of MC event.
Drawing pad for time or charge histograms.
void Draw(const char *opt=0, bool *rezoom=0)
Definition: TZProjPad.cxx:116
void GetZBoundCm(float *i1, float *i2) const
Definition: TZProjPad.cxx:387
TCanvas * fCanvas
The ROOT drawing canvas.
Definition: Canvas.h:42
void Draw()
Definition: TQPad.cxx:123
TGLayoutHints * fLayout
Layout hints for frame.
Definition: Canvas.h:40
Manage all things related to colors for the event display.
Definition: Display3DPad.h:11
void GetWrangeCm(float *i1, float *i2) const
Definition: TZProjPad.cxx:369
Double_t ymax
Definition: plot.C:25
void SetWrangeCm(float i1, float i2)
Definition: TZProjPad.cxx:428
Drawing pad for time or charge histograms.
TSpline3 hi("hi", xhi, yhi, 18,"0")
std::vector< float > GetRightAxesRange(int pix, float cm, float min, float max, float boundmin, float boundmax, int tpix, float tcm)
virtual Bool_t Notify()
A drawing pad for an XZ or ZY.
Definition: TZProjPad.h:32
nova event display
void SetZrangeCm(float i1, float i2)
Definition: TZProjPad.cxx:413
TPad * Pad()
Definition: DrawingPad.h:27
static float min(const float a, const float b, const float c)
Definition: absgeo.cxx:45
void Draw(const char *opt="")
Definition: HeaderPad.cxx:40
TH2F * fHisto
Histogram to draw objects on.
Definition: TZProjPad.h:73
XZYZProjectionsView(TGMainFrame *mf)
void AspectRatioHandler(int event, int key, int py, TObject *sel)
Double_t ymin
Definition: plot.C:24
evd::Refresher gRefresher
SliceButtonBar * fSliceButtonBar
Bar with slice controls.
void GetZrangeCm(float *i1, float *i2) const
Definition: TZProjPad.cxx:378
void GetZrange(int *i1, int *i2) const
Definition: TZProjPad.cxx:362
void Draw(const char *opt="")
T max(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:68
TZProjPad * fXview
X - Z projection of the event.
TRootEmbeddedCanvas * fEmbCanvas
Embedded canvas.
Definition: Canvas.h:41
static constexpr Double_t cm
Definition: Munits.h:140
TQPad * fRawT
Histogram of raw times.
TQPad * fRawQ
Histogram of raw charges.