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