LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
Ortho3DPad.cxx
Go to the documentation of this file.
1 
8 #include "TPad.h"
9 #include "TFrame.h"
10 #include "TPadPainter.h"
11 #include "TH1F.h"
12 #include "TBox.h"
13 #include "TPolyMarker.h"
14 #include "TGNumberEntry.h"
15 #include "TLatex.h"
16 
17 #include "cetlib_except/exception.h"
19 
27 
29 
31 
42 evd::Ortho3DPad::Ortho3DPad(const char* name, const char* title,
44  double x1, double y1,
45  double x2, double y2) :
46  DrawingPad(name, title, x1, y1, x2, y2),
47  fHisto(0),
48  fProj(proj),
49  fXLo(0.),
50  fXHi(0.),
51  fYLo(0.),
52  fYHi(0.),
53  fMSize(0.25),
54  fMSizeEntry(0),
55  fPress(false),
56  fBoxDrawn(false),
57  fPressPx(0),
58  fPressPy(0),
59  fCurrentPx(0),
60  fCurrentPy(0),
61  fPressX(0.),
62  fPressY(0.),
63  fReleaseX(0.),
64  fReleaseY(0.)
65 {
66  // Get services.
67 
69 
70  // Set up pad.
71 
72 // Pad()->SetBit(kCannotPick); // workaround for issue #16169
73  Pad()->SetBit(TPad::kCannotMove);
74  Pad()->Draw();
75  Pad()->cd();
76  Pad()->SetLeftMargin (0.080);
77  Pad()->SetRightMargin (0.010);
78  Pad()->SetTopMargin (0.010);
79  Pad()->SetBottomMargin (0.10);
80 
81  // Define histogram boundaries (cm).
82  // For now only draw cryostat=0.
83  double minx = 1e9;
84  double maxx = -1e9;
85  double miny = 1e9;
86  double maxy = -1e9;
87  double minz = 1e9;
88  double maxz = -1e9;
89  for (size_t i = 0; i<geo->NTPC(); ++i){
90  double local[3] = {0.,0.,0.};
91  double world[3] = {0.,0.,0.};
92  const geo::TPCGeo &tpc = geo->TPC(i);
93  tpc.LocalToWorld(local,world);
94  if (minx>world[0]-geo->DetHalfWidth(i))
95  minx = world[0]-geo->DetHalfWidth(i);
96  if (maxx<world[0]+geo->DetHalfWidth(i))
97  maxx = world[0]+geo->DetHalfWidth(i);
98  if (miny>world[1]-geo->DetHalfHeight(i))
99  miny = world[1]-geo->DetHalfHeight(i);
100  if (maxy<world[1]+geo->DetHalfHeight(i))
101  maxy = world[1]+geo->DetHalfHeight(i);
102  if (minz>world[2]-geo->DetLength(i)/2.)
103  minz = world[2]-geo->DetLength(i)/2.;
104  if (maxz<world[2]+geo->DetLength(i)/2.)
105  maxz = world[2]+geo->DetLength(i)/2.;
106 
107  switch (proj) {
108  case evd::kXY:
109  TPCBox.push_back(TBox(world[0]-geo->DetHalfWidth(i),
110  world[1]-geo->DetHalfHeight(i),
111  world[0]+geo->DetHalfWidth(i),
112  world[1]+geo->DetHalfHeight(i)));
113  break;
114  case evd::kXZ:
115  TPCBox.push_back(TBox(world[2]-geo->DetLength(i)/2.,
116  world[0]-geo->DetHalfWidth(i),
117  world[2]+geo->DetLength(i)/2.,
118  world[0]+geo->DetHalfWidth(i)));
119  break;
120  case evd::kYZ:
121  TPCBox.push_back(TBox(world[2]-geo->DetLength(i)/2.,
122  world[1]-geo->DetHalfHeight(i),
123  world[2]+geo->DetLength(i)/2.,
124  world[1]+geo->DetHalfHeight(i)));
125  break;
126  default:
127  throw cet::exception("Ortho3DPad")
128  << __func__ << ": unwknow projection " << ((int) proj) << "\n";
129  } // switch
130  TPCBox.back().SetFillStyle(0);
131  TPCBox.back().SetLineStyle(2);
132  TPCBox.back().SetLineWidth(2);
133  TPCBox.back().SetLineColor(16);
134  }
135 
136  switch (proj) {
137  case evd::kXY:
138  fXLo = minx;
139  fXHi = maxx;
140  fYLo = miny;
141  fYHi = maxy;
142  break;
143  case evd::kXZ:
144  fXLo = minz;
145  fXHi = maxz;
146  fYLo = minx;
147  fYHi = maxx;
148  break;
149  case evd::kYZ:
150  fXLo = minz;
151  fXHi = maxz;
152  fYLo = miny;
153  fYHi = maxy;
154  break;
155  default:
156  throw cet::exception("Ortho3DPad")
157  << __func__ << ": unwknow projection " << ((int) proj) << "\n";
158  } // switch
159 
160  // Make enclosing histogram.
161 
162  fHisto = new TH1F(*(Pad()->DrawFrame(fXLo, fYLo, fXHi, fYHi)));
163  fHisto->SetBit(kCannotPick);
164  fHisto->SetBit(TPad::kCannotMove);
165  fHisto->SetTitleOffset(1.,"Y");
166  fHisto->SetTitleOffset(1.,"X");
167  fHisto->GetXaxis()->SetLabelSize(0.04);
168  fHisto->GetXaxis()->SetTitleSize(0.04);
169  switch (proj) {
170  case evd::kXY:
171  fHisto->GetXaxis()->SetTitle("x (cm)");
172  fHisto->GetYaxis()->SetTitle("y (cm)");
173  break;
174  case evd::kXZ:
175  fHisto->GetXaxis()->SetTitle("z (cm)");
176  fHisto->GetYaxis()->SetTitle("x (cm)");
177  break;
178  case evd::kYZ:
179  fHisto->GetXaxis()->SetTitle("z (cm)");
180  fHisto->GetYaxis()->SetTitle("y (cm)");
181  break;
182  default:
183  throw cet::exception("Ortho3DPad")
184  << __func__ << ": unexpected flow (projection: " << ((int) proj) << ")\n";
185  } // switch
186 
187  fHisto->GetXaxis()->CenterTitle();
188  fHisto->GetYaxis()->SetLabelSize(0.04);
189  fHisto->GetYaxis()->SetTitleSize(0.04);
190  fHisto->GetYaxis()->CenterTitle();
191  fHisto->SetFillColor(18);
192  fHisto->Draw("AB");
193 
194  fView = new evdb::View2D();
195 
196  // Set pad fill color
197  Pad()->SetFillColor(18);
198  Pad()->SetFrameFillColor(18);
199  Pad()->GetPainter()->SetFillColor(18);
200  Pad()->Modified();
201  Pad()->Update();
202 
203  // Install mouse event handler.
204 
205  std::ostringstream ostr;
206  ostr << "evd::Ortho3DPad::MouseEvent((evd::Ortho3DPad*)" << this << ")";
207  fPad->AddExec("getmousezoom", ostr.str().c_str());
208 }
209 
210 //......................................................................
211 // Destructor.
212 
214 {
215  if (fHisto) { delete fHisto; fHisto = nullptr; }
216  if (fView) { delete fView; fView = nullptr; }
217 }
218 
219 //......................................................................
220 // Draw selected objects.
221 
222 void evd::Ortho3DPad::Draw(const char* /*opt*/)
223 {
224  fPad->Clear();
225  fView->Clear();
226 
227  // Remove zoom.
228 
229  UnZoom(false);
230 
231  // grab the event from the singleton
232 
234 
235  // Insert graphic objects into fView collection.
236 
237  if(evt)
238  {
243  RecoBaseDraw()->SeedOrtho(*evt, fProj, fView);
245  RecoBaseDraw()->VertexOrtho(*evt, fProj, fView);
246  }
247  // Draw objects on pad.
248 
249  fPad->cd();
250  fPad->GetPainter()->SetFillColor(18);
251  fHisto->Draw("X-");
252  fView->Draw();
253  TLatex latex;
254  latex.SetTextColor(16);
255  latex.SetTextSize(0.05);
256  for (size_t i = 0; i<TPCBox.size(); ++i){
257  TPCBox[i].Draw();
258  double x1 = TPCBox[i].GetX2() - 0.02*(fXHi-fXLo);
259  double y1 = TPCBox[i].GetY2() - 0.05*(fYHi-fYLo);
260  for (size_t j = 0; j<i; ++j){
261  if (std::abs(x1-(TPCBox[j].GetX2() - 0.02*(fXHi-fXLo)))<1e-6&&
262  std::abs(y1-(TPCBox[j].GetY2() - 0.05*(fYHi-fYLo)))<1e-6){
263  y1 -= 0.05*(fYHi-fYLo);
264  }
265  }
266  latex.DrawLatex(x1,y1,Form("%lu",i));
267  }
268  fPad->Modified();
269  fPad->Update();
270  fBoxDrawn = false;
271 }
272 
273 //......................................................................
274 // Set zoom region. Limits are specified in user coordinates.
275 
276 void evd::Ortho3DPad::SetZoom(double xlo, double ylo,
277  double xhi, double yhi,
278  bool update)
279 {
280  fHisto->GetXaxis()->SetRangeUser(xlo, xhi);
281  fHisto->GetYaxis()->SetRangeUser(ylo, yhi);
282  fPad->Modified();
283  if(update) {
284  fPad->Update();
285  fBoxDrawn = false;
286  }
287 }
288 
289 //......................................................................
290 // Set zoom region to full range.
291 
292 void evd::Ortho3DPad::UnZoom(bool update)
293 {
294  fHisto->GetXaxis()->SetRangeUser(fXLo, fXHi);
295  fHisto->GetYaxis()->SetRangeUser(fYLo, fYHi);
296  fPad->Modified();
297 
298  // Also set marker size to default one pixel.
299 
300  SetMarkerSize(1., false);
301 
302  if(update) {
303  fPad->Update();
304  fBoxDrawn = false;
305  }
306 }
307 
308 //......................................................................
309 // Set the marker size (measured in pixels).
310 
311 void evd::Ortho3DPad::SetMarkerSize(double size, bool update)
312 {
313  // Update marker size.
314 
315  if(fMSize != size/4.) {
316 
317  // Update marker size attribute.
318 
319  fMSize = size/4.; // Scale to pixels.
320 
321  // Update widget.
322 
323  if(fMSizeEntry)
324  fMSizeEntry->SetNumber(size);
325 
326  // Loop over graphic objects that are currently drawn on
327  // pad, and update any that are polymarkers.
328 
329  TIter next(fPad->GetListOfPrimitives());
330  while(TObject* obj = next()) {
331  if(obj->InheritsFrom(TPolyMarker::Class())) {
332  TPolyMarker* pm = (TPolyMarker*)obj;
333  pm->SetMarkerSize(fMSize);
334  }
335  }
336 
337  fPad->Modified();
338  if(update) {
339  fPad->Update();
340  fBoxDrawn = false;
341  }
342  }
343 }
344 
345 //......................................................................
346 // Save a reference to the marker size number entry widget.
347 // This class gets the marker size from the widget if it is changed
348 // via the gui. It also sets the number in the widget if it is changed
349 // not from the gui.
350 
351 void evd::Ortho3DPad::SetMSizeEntry(TGNumberEntry* p)
352 {
353  fMSizeEntry = p;
354  if(fMSizeEntry)
355  fMSizeEntry->SetNumber(4.*fMSize);
356 }
357 
358 //......................................................................
359 // Slot method for marker size number entry widget.
360 // This method is called when the user changes the marker size via the gui.
361 
363 {
364 
365  // Get marker size from number entry widget.
366 
367  if (!fMSizeEntry)
368  throw cet::exception("Ortho3DPad") << __func__ << ": no MSize entry\n";
369  double val = fMSizeEntry->GetNumber();
370 
371  // Scale the marker size such that the displayed marker size
372  // is measured in pixels.
373 
374  SetMarkerSize(val, true);
375 }
376 
377 //......................................................................
378 // Static mouse event handler.
379 // This method is called by the gui for mouse events in the graphics pad.
380 
382 {
383  TObject *select = gPad->GetSelected();
384  if(!select)
385  return;
386  if(!select->InheritsFrom("TBox"))
387  return;
388  ((TBox*)select)->SetBit(TBox::kCannotMove);
389 
390  // This line is a workaround for a root bug that sends mouse events
391  // to the wrong pad.
392 
393  if(fMousePad != 0)
394  p = fMousePad;
395 
396  p->MouseEvent();
397 }
398 
399 //......................................................................
400 // Mouse event handler (called from static handler).
401 
403 {
404  // Get event type and location.
405 
406  int event = gPad->GetEvent();
407  int px = gPad->GetEventX(); // pixels.
408  int py = gPad->GetEventY(); // pixels.
409  double x = gPad->AbsPixeltoX(px); // User coordinates.
410  double y = gPad->AbsPixeltoY(py); // User coordinates.
411 
412  // Handle different events.
413 
414  switch(event) {
415  case kMouseEnter:
416 
417  // Main purpose of this case is to set the cursor shape.
418 
419  gPad->SetCursor(kCross);
420  fCurrentPx = px;
421  fCurrentPy = py;
422  fMousePad = this;
423  break;
424 
425  case kMouseMotion:
426 
427  // Not really needed...
428 
429  gPad->SetCursor(kCross);
430  fCurrentPx = px;
431  fCurrentPy = py;
432  break;
433 
434  case kMouseLeave:
435 
436  // Undraw box.
437 
438  //if(fBoxDrawn) {
439  // double pxlo = std::min(fPressPx, fCurrentPx);
440  // double pxhi = std::max(fPressPx, fCurrentPx);
441  // double pylo = std::min(fPressPy, fCurrentPy);
442  // double pyhi = std::max(fPressPy, fCurrentPy);
443  // gVirtualX->DrawBox(pxlo, pylo, pxhi, pyhi, TVirtualX::kHollow);
444  // fBoxDrawn = false;
445  //}
446 
447  // Set everything to default.
448 
449  fPress = false;
450  fPressPx = 0;
451  fPressPy = 0;
452  fCurrentPx = 0;
453  fCurrentPy = 0;
454  fPressX = 0.;
455  fPressY = 0.;
456  fReleaseX = 0.;
457  fReleaseY = 0.;
458  fMousePad = 0;
459  break;
460 
461  case kButton1Motion:
462 
463  // Undraw old selection box.
464 
465  //if(fBoxDrawn) {
466  // double pxlo = std::min(fPressPx, fCurrentPx);
467  // double pxhi = std::max(fPressPx, fCurrentPx);
468  // double pylo = std::min(fPressPy, fCurrentPy);
469  // double pyhi = std::max(fPressPy, fCurrentPy);
470  // gVirtualX->DrawBox(pxlo, pylo, pxhi, pyhi, TVirtualX::kHollow);
471  // fBoxDrawn = false;
472  //}
473 
474  // Update cursor location.
475 
476  gPad->SetCursor(kCross);
477  fCurrentPx = px;
478  fCurrentPy = py;
479 
480  // Draw new selection box.
481 
482  {
483  double pxlo = std::min(fPressPx, fCurrentPx);
484  double pxhi = std::max(fPressPx, fCurrentPx);
485  double pylo = std::min(fPressPy, fCurrentPy);
486  double pyhi = std::max(fPressPy, fCurrentPy);
487  gVirtualX->DrawBox(pxlo, pylo, pxhi, pyhi, TVirtualX::kHollow);
488  fBoxDrawn = true;
489  }
490  break;
491 
492  case kButton1Down:
493  gVirtualX->SetLineColor(-1);
494  gVirtualX->SetLineStyle(0);
495  gVirtualX->SetLineWidth(1);
496 
497  // Record the location of the button press event, which will be
498  // one corner of zoom region.
499 
500  gPad->SetCursor(kCross);
501  fPress = true;
502  fPressPx = px;
503  fPressPy = py;
504  fCurrentPx = px;
505  fCurrentPy = py;
506  fPressX = x;
507  fPressY = y;
508  fReleaseX = 0.;
509  fReleaseY = 0.;
510  fMousePad = this;
511  break;
512 
513  case kButton1Up:
514 
515  // Get the location of button release event, then zoom.
516 
517  gPad->SetCursor(kCross);
518  fPress = false;
519  fCurrentPx = px;
520  fCurrentPy = py;
521  fReleaseX = x;
522  fReleaseY = y;
523  {
524  double xlo = std::min(fPressX, fReleaseX);
525  double xhi = std::max(fPressX, fReleaseX);
526  double ylo = std::min(fPressY, fReleaseY);
527  double yhi = std::max(fPressY, fReleaseY);
528  SetZoom(xlo, ylo, xhi, yhi, true);
529  }
530  fMousePad = 0;
531  break;
532  }
533 }
534 
Float_t x
Definition: compare.C:6
void OpFlashOrtho(const art::Event &evt, evd::OrthoProj_t proj, evdb::View2D *view)
void SpacePointOrtho(const art::Event &evt, evd::OrthoProj_t proj, double msize, evdb::View2D *view)
void SetZoom(double xlo, double ylo, double xhi, double yhi, bool update)
Definition: Ortho3DPad.cxx:276
double fXHi
High x value.
Definition: Ortho3DPad.h:74
const art::Event * GetEvent() const
Definition: EventHolder.cxx:45
void PFParticleOrtho(const art::Event &evt, evd::OrthoProj_t proj, double msize, evdb::View2D *view)
int fPressPy
Poxel location where button 1 was pressed.
Definition: Ortho3DPad.h:90
void UnZoom(bool update)
Definition: Ortho3DPad.cxx:292
geo::Length_t DetHalfWidth(geo::TPCID const &tpcid) const
Returns the half width of the active volume of the specified TPC.
Float_t y1[n_points_granero]
Definition: compare.C:5
double fReleaseX
User location where button 1 was released.
Definition: Ortho3DPad.h:95
void SetMarkerSize(double size, bool update)
Definition: Ortho3DPad.cxx:311
Float_t x1[n_points_granero]
Definition: compare.C:5
void SetMSizeEntry(TGNumberEntry *p)
Definition: Ortho3DPad.cxx:351
void SeedOrtho(const art::Event &evt, evd::OrthoProj_t proj, evdb::View2D *view)
Float_t y
Definition: compare.C:6
double fYHi
High y value.
Definition: Ortho3DPad.h:76
Geometry information for a single TPC.
Definition: TPCGeo.h:37
void ProngOrtho(const art::Event &evt, evd::OrthoProj_t proj, double msize, evdb::View2D *view)
A drawing pad showing an orthographic rendering of 3D objects.
Definition: Ortho3DPad.h:25
int fCurrentPy
Current pixel location of mouse.
Definition: Ortho3DPad.h:92
A collection of drawable 2-D objects.
int fPressPx
Pixel location where button 1 was pressed.
Definition: Ortho3DPad.h:89
OrthoProj_t
Definition: OrthoProj.h:12
double fXLo
Low x value.
Definition: Ortho3DPad.h:73
void Clear()
Definition: View2D.cxx:109
Singleton to hold the current art::Event for the event display.
Float_t y2[n_points_geant4]
Definition: compare.C:26
Int_t max
Definition: plot.C:27
geo::Length_t DetHalfHeight(geo::TPCID const &tpcid) const
Returns the half height of the active volume of the specified TPC.
double fReleaseY
User location where button 1 was released.
Definition: Ortho3DPad.h:96
void Draw()
Definition: View2D.cxx:89
evd::OrthoProj_t fProj
Projection.
Definition: Ortho3DPad.h:72
static EventHolder * Instance()
Definition: EventHolder.cxx:15
bool fBoxDrawn
Is selection box drawn?
Definition: Ortho3DPad.h:88
double fYLo
Low y value.
Definition: Ortho3DPad.h:75
Base class for event display drawing pads.
Definition: DrawingPad.h:29
RecoBaseDrawer * RecoBaseDraw()
Definition: DrawingPad.cxx:120
geo::Length_t DetLength(geo::TPCID const &tpcid) const
Returns the length of the active volume of the specified TPC.
TPad * Pad()
Definition: DrawingPad.h:37
SimulationDrawer * SimulationDraw()
Definition: DrawingPad.cxx:99
Drawing pad showing an orthographic projection of 3D objects in the detector.
Ortho3DPad(const char *nm, const char *ti, evd::OrthoProj_t proj, double x1, double y1, double x2, double y2)
Definition: Ortho3DPad.cxx:42
Class to aid in the rendering of RecoBase objects.
double fPressX
User location where button 1 was pressed.
Definition: Ortho3DPad.h:93
double fPressY
User location where button 1 was pressed.
Definition: Ortho3DPad.h:94
int fCurrentPx
Current pixel location of mouse.
Definition: Ortho3DPad.h:91
unsigned int NTPC(unsigned int cstat=0) const
Returns the total number of TPCs in the specified cryostat.
std::vector< TBox > TPCBox
TPC box.
Definition: Ortho3DPad.h:78
Int_t min
Definition: plot.C:26
Float_t proj
Definition: plot.C:34
Render the objects from the Simulation package.
void MCTruthOrtho(const art::Event &evt, evd::OrthoProj_t proj, double msize, evdb::View2D *view)
TH1F * fHisto
Enclosing histogram.
Definition: Ortho3DPad.h:71
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
TPad * fPad
The ROOT graphics pad.
Definition: DrawingPad.h:53
bool fPress
Is button 1 pressed?
Definition: Ortho3DPad.h:87
Float_t x2[n_points_geant4]
Definition: compare.C:26
Float_t e
Definition: plot.C:34
static void MouseEvent(evd::Ortho3DPad *p)
Definition: Ortho3DPad.cxx:381
Namespace collecting geometry-related classes utilities.
static Ortho3DPad * fMousePad
Selected pad for mouse action.
Definition: Ortho3DPad.h:67
TGNumberEntry * fMSizeEntry
For changing marker size.
Definition: Ortho3DPad.h:83
void LocalToWorld(const double *tpc, double *world) const
Transform point from local TPC frame to world frame.
Definition: TPCGeo.h:490
evdb::View2D * fView
Collection of graphics objects to render.
Definition: Ortho3DPad.h:79
art framework interface to geometry description
void Draw(const char *opt=0)
Definition: Ortho3DPad.cxx:222
void VertexOrtho(const art::PtrVector< recob::Vertex > &vertex, evd::OrthoProj_t proj, evdb::View2D *view, int marker)
double fMSize
Marker size.
Definition: Ortho3DPad.h:77
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
Event finding and building.
Encapsulate the construction of a single detector plane.