TWireProjPad.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 ///
3 /// \file TWireProjPad.cxx
4 /// \brief Drawing pad for X-Z or Y-Z projections of events
5 /// \author messier@indiana.edu
6 ///
7 ////////////////////////////////////////////////////////////////////////
8 
9 #include <algorithm>
10 
11 #include "TCanvas.h"
12 #include "TClass.h"
13 #include "TFrame.h"
14 #include "TH1F.h"
15 #include "TList.h"
16 #include "TPad.h"
17 #include "TString.h"
18 #include "TVirtualPad.h"
19 
32 #include "nuevdb/EventDisplayBase/EventHolder.h"
33 #include "nuevdb/EventDisplayBase/View2D.h"
34 
38 
39 namespace {
40 
41  template <typename Stream>
42  void
43  DumpPad(Stream&& log, TVirtualPad* pPad)
44  {
45  if (!pPad) {
46  log << "pad not available";
47  return;
48  }
49 
50  log << pPad->IsA()->GetName() << "[" << ((void*)pPad) << "](\"" << pPad->GetName() << "\")";
51  TFrame const* pFrame = pPad->GetFrame();
52  if (pFrame) {
53  double const low_wire = pFrame->GetX1(), high_wire = pFrame->GetX2();
54  double const low_tdc = pFrame->GetY1(), high_tdc = pFrame->GetY2();
55  double const wire_pixels = pPad->XtoAbsPixel(high_wire) - pPad->XtoAbsPixel(low_wire);
56  double const tdc_pixels = -(pPad->YtoAbsPixel(high_tdc) - pPad->YtoAbsPixel(low_tdc));
57  log << " has frame spanning wires " << low_wire << "-" << high_wire << " and TDC " << low_tdc
58  << "-" << high_tdc << " in a window " << wire_pixels << "x" << tdc_pixels << " pixel big";
59  }
60  else {
61  log << " has no frame";
62  }
63 
64  } // DumpPad()
65 
66  [[maybe_unused]] void
67  DumpPadsInCanvas(TVirtualPad* pPad, std::string caller, std::string msg = "")
68  {
69  mf::LogDebug log(caller);
70  if (!msg.empty()) log << msg << ": ";
71  if (!pPad) {
72  log << "pad not available";
73  return;
74  }
75 
76  DumpPad(log, pPad);
77 
78  TCanvas const* pCanvas = pPad->GetCanvas();
79  log << "\nCanvas is: (TCanvas*) (" << ((void*)pPad->GetCanvas()) << ") with "
80  << pCanvas->GetListOfPrimitives()->GetSize() << " primitives and the following pads:";
81  TIterator* pIter = pCanvas->GetListOfPrimitives()->MakeIterator();
82  TObject const* pObject;
83  while ((pObject = pIter->Next())) {
84  if (!pObject->InheritsFrom(TVirtualPad::Class())) continue;
85  log << "\n " << ((pObject == pPad) ? '*' : '-') << " ";
86  DumpPad(log, (TVirtualPad*)pObject);
87  }
88  log << "\n";
89  delete pIter;
90  } // DumpPadsInCanvas()
91 
92 } // local namespace
93 
94 namespace evd {
95 
96  ///
97  /// Create a pad showing a single X-Z or Y-Z projection of the detector
98  /// \param nm : Name of the pad
99  /// \param ti : Title of the pad
100  /// \param x1 : Location of left edge of pad (0-1)
101  /// \param x2 : Location of right edge of pad (0-1)
102  /// \param y1 : Location of bottom edge of pad (0-1)
103  /// \param y2 : Location of top edge of pad (0-1)
104  /// \param plane : plane number of view
105  ///
107  const char* ti,
108  double x1,
109  double x2,
110  double y1,
111  double y2,
112  unsigned int plane)
113  : DrawingPad(nm, ti, x1, x2, y1, y2), fPlane(plane)
114  {
115  fCurrentZoom.resize(4);
116 
118 
119  this->Pad()->cd();
120 
121  this->Pad()->SetLeftMargin(0.070);
122  this->Pad()->SetRightMargin(0.010);
123 
124  // how many planes in the detector and
125  // which plane is this one?
126 
127  unsigned int planes = geo->Nplanes();
128  this->Pad()->SetTopMargin(0.005);
129  this->Pad()->SetBottomMargin(0.110);
130 
131  // there has to be a better way of doing this that does
132  // not have a case for each number of planes in a detector
133  if (planes == 2 && fPlane > 0) {
134  this->Pad()->SetTopMargin(0.110);
135  this->Pad()->SetBottomMargin(0.005);
136  }
137  else if (planes > 2) {
138  if (fPlane == 1) {
139  this->Pad()->SetTopMargin(0.055);
140  this->Pad()->SetBottomMargin(0.055);
141  }
142  else if (fPlane == 2) {
143  this->Pad()->SetTopMargin(0.110);
144  this->Pad()->SetBottomMargin(0.005);
145  }
146  }
147 
148  TString planeNo = "fTWirePlane";
149  planeNo += fPlane;
150 
151  // picking the information from the current TPC
153  auto const signalType = geo->SignalType({rawopt->CurrentTPC(), fPlane});
154  TString xtitle = ";Induction Wire;t (tdc)";
155  if (signalType == geo::kCollection) xtitle = ";Collection Wire;t (tdc)";
156 
157  unsigned int const nWires = geo->Nwires(fPlane);
158  unsigned int const nTicks = RawDataDraw()->TotalClockTicks();
159 
160  fXLo = -0.005 * (nWires - 1);
161  fXHi = 1.005 * (nWires - 1);
162  fYLo = 0.990 * (unsigned int)(this->RawDataDraw()->StartTick());
163  fYHi = 1.005 * std::min((unsigned int)(this->RawDataDraw()->StartTick() + nTicks), nTicks);
164 
165  fOri = rawopt->fAxisOrientation;
166  if (fOri > 0) {
167  fYLo = -0.005 * (nWires - 1);
168  fYHi = 1.005 * (nWires - 1);
169  fYLo = 0.990 * (unsigned int)(this->RawDataDraw()->StartTick());
170  fYHi = 1.005 * std::min((unsigned int)(this->RawDataDraw()->StartTick() + nTicks), nTicks);
171  fXLo = -0.005 * nTicks;
172  fXHi = 1.010 * nTicks;
173  xtitle = ";t (tdc);InductionWire";
174  if (signalType == geo::kCollection) xtitle = ";t (tdc);Collection Wire";
175  }
176 
177  // make the range of the histogram be the biggest extent
178  // in both directions and then use SetRangeUser() to shrink it down
179  // that will allow us to change the axes on the fly
180  double min = std::min(fXLo, fYLo);
181  double max = std::max(fXHi, fYHi);
182 
183  fHisto = new TH1F(*(fPad->DrawFrame(min, min, max, max)));
184 
185  fHisto->SetTitleOffset(0.5, "Y");
186  fHisto->SetTitleOffset(0.75, "X");
188  fHisto->GetYaxis()->SetLabelSize(0.05);
189  fHisto->GetYaxis()->CenterTitle();
190  fHisto->GetXaxis()->SetLabelSize(0.05);
191  fHisto->GetXaxis()->CenterTitle();
192  fHisto->Draw("AB");
193 
194  fView = new evdb::View2D();
195  }
196 
197  //......................................................................
199  {
200  if (fHisto) {
201  delete fHisto;
202  fHisto = 0;
203  }
204  if (fView) {
205  delete fView;
206  fView = 0;
207  }
208  }
209 
210  //......................................................................
211  void
212  TWireProjPad::Draw(const char* opt)
213  {
214  // DumpPadsInCanvas(fPad, "TWireProjPad", "Draw()");
215  MF_LOG_DEBUG("TWireProjPad") << "Started to draw plane " << fPlane;
216 
217  ///\todo: Why is kSelectedColor hard coded?
218  int kSelectedColor = 4;
219  fView->Clear();
220 
221  // grab the singleton holding the art::Event
222  art::Event const* evtPtr = evdb::EventHolder::Instance()->GetEvent();
223  if (evtPtr) {
224  auto const& evt = *evtPtr;
225  auto const clockData =
227  auto const detProp =
230 
232 
233  // the 2D pads have too much detail to be rendered on screen;
234  // to act smarter, RawDataDrawer needs to know the range being plotted
236  this->RawDataDraw()->RawDigit2D(
237  evt, detProp, fView, fPlane, GetDrawOptions().bZoom2DdrawToRoI);
238 
239  this->RecoBaseDraw()->Wire2D(evt, fView, fPlane);
240  this->RecoBaseDraw()->Hit2D(evt, detProp, fView, fPlane);
241 
242  if (recoOpt->fUseHitSelector)
243  this->RecoBaseDraw()->Hit2D(
244  this->HitSelectorGet()->GetSelectedHits(fPlane), kSelectedColor, fView, true);
245 
246  this->RecoBaseDraw()->Slice2D(evt, detProp, fView, fPlane);
247  this->RecoBaseDraw()->Cluster2D(evt, clockData, detProp, fView, fPlane);
248  this->RecoBaseDraw()->EndPoint2D(evt, fView, fPlane);
249  this->RecoBaseDraw()->Prong2D(evt, clockData, detProp, fView, fPlane);
250  this->RecoBaseDraw()->Vertex2D(evt, detProp, fView, fPlane);
251  this->RecoBaseDraw()->Seed2D(evt, detProp, fView, fPlane);
252  this->RecoBaseDraw()->OpFlash2D(evt, clockData, detProp, fView, fPlane);
253  this->RecoBaseDraw()->Event2D(evt, fView, fPlane);
254  this->RecoBaseDraw()->DrawTrackVertexAssns2D(evt, clockData, detProp, fView, fPlane);
255 
256  UpdatePad();
257  } // if (evt)
258 
260 
261  // check if we need to swap the axis ranges
263  if (fOri != rawopt->fAxisOrientation) {
264  fOri = rawopt->fAxisOrientation;
265  double max = fXHi;
266  double min = fXLo;
267  fXHi = fYHi;
268  fXLo = fYLo;
269  fYHi = max;
270  fYLo = min;
271 
273 
274  TString xtitle = fHisto->GetXaxis()->GetTitle();
275  fHisto->GetXaxis()->SetTitle(fHisto->GetYaxis()->GetTitle());
276  fHisto->GetYaxis()->SetTitle(xtitle);
277  }
278 
279  if (fPlane > 0)
280  fHisto->Draw("X+");
281  else
282  fHisto->Draw("");
283 
284  // Check if we should zoom the displays;
285  // if there is no event, we have no clue about the region of interest
286  // and therefore we don't touch anything
287  if (opt == 0 && evtPtr) { this->ShowFull(); }
288 
289  MF_LOG_DEBUG("TWireProjPad") << "Started rendering plane " << fPlane;
290 
291  fView->Draw();
292 
293  MF_LOG_DEBUG("TWireProjPad") << "Drawing of plane " << fPlane << " completed";
294  }
295 
296  //......................................................................
297  void
299  {
301  if (recoOpt->fUseHitSelector) {
303  this->Draw();
304  }
305  }
306 
307  //......................................................................
308  // the override parameter is needed to unzoom to full range when the fAutoZoomInterest is on.
309 
310  void
312  {
313  // x values are wire numbers, y values are ticks of the clock
314  int xmin = fXLo;
315  int xmax = fXHi;
316  int ymax = fYHi;
317  int ymin = fYLo;
318 
321 
322  if (GetDrawOptions().bZoom2DdrawToRoI && !override) {
323  int test = 0;
324  if (rawopt->fDrawRawDataOrCalibWires == 0)
325  test = RawDataDraw()->GetRegionOfInterest((int)fPlane, xmin, xmax, ymin, ymax);
326  else
327  test = RecoBaseDraw()->GetRegionOfInterest((int)fPlane, xmin, xmax, ymin, ymax);
328 
329  if (test != 0) return;
330  }
331 
332  SetZoomRange(xmin, xmax, ymin, ymax);
333  }
334 
335  //......................................................................
336  void
337  TWireProjPad::GetWireRange(int* i1, int* i2) const
338  {
339  if (fOri < 1) {
340  *i1 = fHisto->GetXaxis()->GetFirst();
341  *i2 = fHisto->GetXaxis()->GetLast();
342  }
343  else {
344  *i1 = fHisto->GetYaxis()->GetFirst();
345  *i2 = fHisto->GetYaxis()->GetLast();
346  }
347  }
348 
349  //......................................................................
350  // Set the X axis range only
351  //
352  void
354  {
355  if (fOri < 1) { fHisto->GetXaxis()->SetRange(i1, i2); }
356  else {
357  fHisto->GetYaxis()->SetRange(i1, i2);
358  }
359  fCurrentZoom[0] = i1;
360  fCurrentZoom[1] = i2;
361  }
362 
363  //......................................................................
364  // Set the visible range of the wire / time view
365  //
366  void
367  TWireProjPad::SetZoomRange(int i1, int i2, int y1, int y2)
368  {
369  MF_LOG_DEBUG("TWireProjPad") << "SetZoomRange(" << i1 << ", " << i2 << ", " << y1 << ", " << y2
370  << ") on plane #" << fPlane;
371 
372  fHisto->GetXaxis()->SetRangeUser(i1, i2);
373  fHisto->GetYaxis()->SetRangeUser(y1, y2);
374  fCurrentZoom[0] = i1;
375  fCurrentZoom[1] = i2;
376  fCurrentZoom[2] = y1;
377  fCurrentZoom[3] = y2;
378  }
379 
380  //......................................................................
381  // Set the visible range of the wire / time view from the view
382  //
383  void
385  {
386  TAxis const& xaxis = *(fHisto->GetXaxis());
387  fCurrentZoom[0] = xaxis.GetBinLowEdge(xaxis.GetFirst());
388  fCurrentZoom[1] = xaxis.GetBinUpEdge(xaxis.GetLast());
389  fCurrentZoom[2] = fHisto->GetMinimum();
390  fCurrentZoom[3] = fHisto->GetMaximum();
391  MF_LOG_DEBUG("TWireProjPad") << "Zoom set to wires (" << fCurrentZoom[0] << "; "
392  << fCurrentZoom[1] << " ), tick (" << fCurrentZoom[2] << "; "
393  << fCurrentZoom[3] << ") for plane #" << fPlane;
394  } // TWireProjPad::SetZoomFromView()
395  //......................................................................
396  void
398  double i2,
399  double y1,
400  double y2,
401  double distance,
402  const char* zoom_opt,
403  bool good_plane)
404  {
405  const art::Event* evtPtr = evdb::EventHolder::Instance()->GetEvent();
406  if (evtPtr) {
407  auto const& evt = *evtPtr;
409  if (recoopt->fUseHitSelector) {
410  this->HitSelectorGet()->SaveHits(evt, fPlane, i1, i2, y1, y2, distance, good_plane);
411  this->Draw(zoom_opt);
412  }
413  }
414  }
415 
416  /////////////////////////////////////////////////
417  // Pass the seed list onwards to InfoTransfer
418  //
419  double
420  TWireProjPad::SaveSeedList(std::vector<util::PxLine> seedlines, double distance)
421  {
422  double KineticEnergy = util::kBogusD;
423  const art::Event* evt = evdb::EventHolder::Instance()->GetEvent();
424  if (evt) {
426  if (recoopt->fUseHitSelector)
427  KineticEnergy = this->HitSelectorGet()->SaveSeedLines(*evt, seedlines, distance);
428  }
429  return KineticEnergy;
430  }
431 
432  //......................................................................
433  void
434  TWireProjPad::SelectOneHit(double x, double y, const char* zoom_opt)
435  {
436 
437  const art::Event* evt = evdb::EventHolder::Instance()->GetEvent();
438  if (evt) {
440  if (recoopt->fUseHitSelector) {
441  this->HitSelectorGet()->ChangeHit(*evt, fPlane, x, y);
442  this->Draw(zoom_opt);
443  }
444  }
445  }
446 
447  //......................................................................
448  void
450  {
451  fPad->Clear();
452  this->UpdatePad();
453 
454  return;
455  }
456 
457  //......................................................................
458  void
460  {
461  fPad->cd();
462  fPad->Modified();
463  fPad->Update();
464  fPad->GetFrame()->SetBit(TPad::kCannotMove, true);
465  fPad->SetBit(TPad::kCannotMove, true);
466 
467  return;
468  }
469 
470  //......................................................................
471  void
472  TWireProjPad::DrawLinesinView(std::vector<util::PxLine> lines,
473  bool deleting,
474  const char* zoom_opt)
475  {
476  fPad->cd();
477  if (deleting) {
478  fPad->Clear();
479  this->Draw(zoom_opt);
480  }
481  else {
482  fView->Clear();
483  fView->Draw();
484  }
485 
486  mf::LogVerbatim("TWireProjPad") << "Drawing " << lines.size() << " lines";
487 
488  for (size_t is = 0; is < lines.size(); ++is) {
489  if (fPlane != lines[is].plane) continue;
490 
491  TLine& l = fView->AddLine(lines[is].w0, lines[is].t0, lines[is].w1, lines[is].t1);
492 
493  fView->Draw();
494  evd::Style::FromPDG(l, 11);
495  }
496 
497  fView->Draw();
498  UpdatePad();
499  fView->Draw();
500 
501  return;
502  }
503 
504 } // namespace
505 ////////////////////////////////////////////////////////////////////////
int GetRegionOfInterest(int plane, int &minw, int &maxw, int &mint, int &maxt)
code to link reconstructed objects back to the MC truth information
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
void SaveHits(const art::Event &evt, unsigned int plane, double x, double y, double x1, double y1, double distance, bool good_plane=true)
Definition: HitSelector.cxx:88
void msg(const char *fmt,...)
Definition: message.cpp:107
Drawing pad showing a single X-Z or Y-Z projection of an event.
std::string string
Definition: nybbler.cc:12
int fDrawRawDataOrCalibWires
0 for raw
unsigned int fPlane
Which plane in the detector.
Definition: TWireProjPad.h:84
opt
Definition: train.py:196
double SaveSeedList(std::vector< util::PxLine > seedlines, double distance)
void Draw(const char *opt=0)
void ShowFull(int override=0)
double fXLo
Low value of x axis.
Definition: TWireProjPad.h:88
void RawDigit2D(art::Event const &evt, detinfo::DetectorPropertiesData const &detProp, evdb::View2D *view, unsigned int plane, bool bZoomToRoI=false)
Draws raw digit content in 2D wire plane representation.
static void FromPDG(TLine &line, int pdgcode)
Definition: Style.cxx:139
SigType_t SignalType(geo::PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
void Prong2D(const art::Event &evt, detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, evdb::View2D *view, unsigned int plane)
static QStrList * l
Definition: config.cpp:1044
unsigned int Nwires(unsigned int p, unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wires in the specified plane.
art framework interface to geometry description
void Slice2D(const art::Event &evt, detinfo::DetectorPropertiesData const &detProp, evdb::View2D *view, unsigned int plane)
void Cluster2D(const art::Event &evt, detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, evdb::View2D *view, unsigned int plane)
void DrawTrackVertexAssns2D(const art::Event &evt, detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, evdb::View2D *view, unsigned int plane)
std::vector< double > const & GetCurrentZoom() const
Definition: TWireProjPad.h:72
void SaveHitList(double i1, double i2, double y1, double y2, double distance, const char *zoom_opt, bool good_plane=true)
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
void ClearHitList(unsigned int plane)
void Seed2D(const art::Event &evt, detinfo::DetectorPropertiesData const &detProp, evdb::View2D *view, unsigned int plane)
void SelectOneHit(double x, double y, const char *zoom_opt)
LArSoft includes.
Definition: InfoTransfer.h:33
RawDataDrawer * RawDataDraw()
Definition: DrawingPad.cxx:106
int fOri
Orientation of the axes - see RawDrawingOptions for values.
Definition: TWireProjPad.h:92
Class to perform operations needed to select hits and pass them to a cluster.
double fXHi
High value of x axis.
Definition: TWireProjPad.h:89
DrawOptions_t const & GetDrawOptions() const
Return the current draw options.
Definition: TWireProjPad.h:44
Base class for event display drawing pads.
Definition: DrawingPad.h:29
RecoBaseDrawer * RecoBaseDraw()
Definition: DrawingPad.cxx:117
int Hit2D(const art::Event &evt, detinfo::DetectorPropertiesData const &detProp, evdb::View2D *view, unsigned int plane)
TPad * Pad()
Definition: DrawingPad.h:37
geo::TPCID CurrentTPC() const
Returns the current TPC as a TPCID.
double TotalClockTicks() const
Definition: RawDataDrawer.h:82
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
double fYLo
Low value of y axis.
Definition: TWireProjPad.h:90
static int max(int a, int b)
SimulationDrawer * SimulationDraw()
Definition: DrawingPad.cxx:96
TH1F * fHisto
Histogram to draw object on.
Definition: TWireProjPad.h:85
void DrawLinesinView(std::vector< util::PxLine > lines, bool deleting=false, const char *zoom_opt=0)
void SetWireRange(int i1, int i2)
double StartTick() const
Definition: RawDataDrawer.h:77
void ChangeHit(const art::Event &evt, unsigned int plane, double x, double y)
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
void SetZoomRange(int i1, int i2, int y1, int y2)
void EndPoint2D(const art::Event &evt, evdb::View2D *view, unsigned int plane)
void Wire2D(const art::Event &evt, evdb::View2D *view, unsigned int plane)
#define MF_LOG_DEBUG(id)
HitSelector * HitSelectorGet()
Definition: DrawingPad.cxx:141
int fAxisOrientation
0 = TDC values on y-axis, wire number on x-axis, 1 = swapped
static const char * zoom_opt
void OpFlash2D(const art::Event &evt, detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, evdb::View2D *view, unsigned int plane)
double SaveSeedLines(const art::Event &evt, std::vector< util::PxLine > seedline, double distance)
Definition: HitSelector.cxx:50
int GetRegionOfInterest(int plane, int &minw, int &maxw, int &mint, int &maxt)
void MCTruthVectors2D(const art::Event &evt, evdb::View2D *view, unsigned int plane)
list x
Definition: train.py:276
void Event2D(const art::Event &evt, evdb::View2D *view, unsigned int plane)
constexpr double kBogusD
obviously bogus double value
TPad * fPad
The ROOT graphics pad.
Definition: DrawingPad.h:52
void SetZoomFromView()
Sets the zoom parameters from the current histogram view.
TCEvent evt
Definition: DataStructs.cxx:7
void Vertex2D(const art::Event &evt, detinfo::DetectorPropertiesData const &detProp, evdb::View2D *view, unsigned int plane)
void GetWireRange(int *i1, int *i2) const
std::vector< double > fCurrentZoom
Definition: TWireProjPad.h:80
LArSoft geometry interface.
Definition: ChannelGeo.h:16
double fYHi
High value of y axis.
Definition: TWireProjPad.h:91
evdb::View2D * fView
Collection of graphics objects to render.
Definition: TWireProjPad.h:86
Signal from collection planes.
Definition: geo_types.h:146
TWireProjPad(const char *nm, const char *ti, double x1, double y1, double x2, double y2, unsigned int plane)
void ExtractRange(TVirtualPad *pPad, std::vector< double > const *zoom=nullptr)
Fills the viewport information from the specified pad.