LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
TQPad.cxx
Go to the documentation of this file.
7 
8 #include "TBox.h"
9 #include "TH1F.h"
10 #include "TF1.h"
11 #include "TPad.h"
12 #include "TPolyLine.h"
13 #include "TText.h"
14 
15 #include "cetlib_except/exception.h"
16 
29 
30 // C/C++ standard libraries
31 #include <algorithm> // std::min(), std::max()
32 
33 
34 namespace evd{
35 
36  static const int kRAW = 0;
37  static const int kCALIB = 1;
38  static const int kRAWCALIB = 2;
39  static const int kQ = 0;
40  static const int kTQ = 1;
41 
42  //......................................................................
43 
44  TQPad::TQPad(const char* nm, const char* ti,
45  double x1, double y1,
46  double x2, double y2,
47  const char *opt,
48  unsigned int plane,
49  unsigned int wire) :
50  DrawingPad(nm, ti, x1, y1, x2, y2),
51  fWire(wire),
52  fPlane(plane),
53  fRawHisto(0),
54  fRecoHisto(0)
55  {
56 
58  unsigned int planes = geo->Nplanes();
59 
60  this->Pad()->cd();
61 
62  this->Pad()->SetLeftMargin (0.050);
63  this->Pad()->SetRightMargin (0.050);
64 
65  this->Pad()->SetTopMargin (0.005);
66  this->Pad()->SetBottomMargin(0.110);
67 
68  // there has to be a better way of doing this that does
69  // not have a case for each number of planes in a detector
70  if(planes == 2 && fPlane > 0){
71  this->Pad()->SetTopMargin (0.110);
72  this->Pad()->SetBottomMargin(0.010);
73  }
74  else if(planes > 2){
75  if(fPlane == 1){
76  this->Pad()->SetTopMargin (0.005);
77  this->Pad()->SetBottomMargin(0.010);
78  }
79  else if(fPlane == 2){
80  this->Pad()->SetTopMargin (0.110);
81  this->Pad()->SetBottomMargin(0.010);
82  }
83  }
84 
85 
86  std::string opts(opt);
87  if(opts == "TQ") {
88  fTQ = kTQ;
89  // BB adjust the vertical spacing
90  this->Pad()->SetTopMargin (0);
91  this->Pad()->SetBottomMargin(0.2);
92  }
93  if(opts == "Q" ){
94  fTQ = kQ;
95  }
96 
97  this->BookHistogram();
98  fView = new evdb::View2D();
99  }
100 
101  //......................................................................
102 
104  {
105  if (fView) { delete fView; fView = 0; }
106  if (fRawHisto) { delete fRawHisto; fRawHisto = 0; }
107  if (fRecoHisto) { delete fRecoHisto; fRecoHisto = 0; }
108  }
109 
110  //......................................................................
111  void TQPad::Draw()
112  {
114 
115  if (!fRawHisto || !fRecoHisto) return;
116 
117  //grab the singleton with the event
119  if(!evt) return;
120 
121  //check if raw (dual phase) or deconvoluted (single phase) waveform was fitted
122  auto hitResults = anab::FVectorReader<recob::Hit, 4>::create(*evt, "dprawhit");
123 
124  if(hitResults) //raw waveform (dual phase)
125  {
126 
127  fPad->Clear();
128  fPad->cd();
129 
130  std::vector<double> htau1;
131  std::vector<double> htau2;
132  std::vector<double> hamplitudes;
133  std::vector<double> hpeaktimes;
134  std::vector<int> hstartT;
135  std::vector<int> hendT;
136  std::vector<int> hNMultiHit;
137  std::vector<int> hLocalHitIndex;
138 
139  if(fTQ == kTQ)
140  {
141  fRawHisto->Reset("ICEM");
142  fRecoHisto->Reset("ICEM");
143 
144  this->RawDataDraw()->FillTQHisto(*evt,
145  fPlane,
146  fWire,
147  fRawHisto);
148 
149  this->RecoBaseDraw()->FillTQHistoDP(*evt,
150  fPlane,
151  fWire,
152  fRecoHisto,
153  htau1,
154  htau2,
155  hamplitudes,
156  hpeaktimes,
157  hstartT,
158  hendT,
159  hNMultiHit,
160  hLocalHitIndex);
161 
162 
163  // draw with histogram style, only (square) lines, no errors
164  static const std::string defaultDrawOptions = "HIST";
165 
166  switch (drawopt->fDrawRawDataOrCalibWires) {
167  case kRAW:
168  fRawHisto->Draw(defaultDrawOptions.c_str());
169  break;
170  case kCALIB:
171  fRecoHisto->Draw(defaultDrawOptions.c_str());
172  break;
173  case kRAWCALIB:
174  fRawHisto->SetMaximum(1.2*std::max(fRawHisto->GetMaximum(), fRecoHisto->GetMaximum()));
175  fRawHisto->SetMinimum(1.2*std::min(fRawHisto->GetMinimum(), fRecoHisto->GetMinimum()));
176  fRawHisto->Draw(defaultDrawOptions.c_str());
177  fRecoHisto->Draw((defaultDrawOptions + " same").c_str());
178  break;
179  } // switch
180 
181  // this loop draws the double-exponential shapes for identified hits in the reco histo
182  for (size_t i = 0; i < hamplitudes.size() && drawopt->fDrawRawDataOrCalibWires != kRAW; ++i) {
183  // If there is more than one peak in this fit, draw the sum of all peaks
184  if( hNMultiHit[i] > 1 && hLocalHitIndex[i] == 0)
185  {
186  // create TPolyLine that actually gets drawn
187  TPolyLine& p2 = fView->AddPolyLine(1001,kRed,3,1);
188 
189  // set coordinates of TPolyLine based fitted function
190  for(int j = 0; j<1001; ++j)
191  {
192  double x = hstartT[i]+j*(hendT[i+hNMultiHit[i]-1]-hstartT[i])/1000;
193  double y = RecoBaseDraw()->EvalMultiExpoFit(x,i,hNMultiHit[i],htau1,htau2,hamplitudes,hpeaktimes);
194  p2.SetPoint(j, x, y);
195  }
196 
197  p2.Draw("same");
198  }
199 
200  // Always draw the single peaks in addition to the sum of all peaks
201  // create TPolyLine that actually gets drawn
202  TPolyLine& p1 = fView->AddPolyLine(1001,kOrange+7,3,1);
203 
204  // set coordinates of TPolyLine based fitted function
205  for(int j = 0; j<1001; ++j){
206  double x = hstartT[i-hLocalHitIndex[i]]+j*(hendT[i+hNMultiHit[i]-hLocalHitIndex[i]-1]-hstartT[i-hLocalHitIndex[i]])/1000;
207  double y = RecoBaseDraw()->EvalExpoFit(x,htau1[i],htau2[i],hamplitudes[i],hpeaktimes[i]);
208  p1.SetPoint(j, x, y);
209  }
210 
211  p1.Draw("same");
212  }
213 
214  if (drawopt->fDrawRawDataOrCalibWires == kCALIB) fRecoHisto->Draw((defaultDrawOptions + " same").c_str());
215  else if(drawopt->fDrawRawDataOrCalibWires == kRAWCALIB){
216  fRawHisto->Draw((defaultDrawOptions + " same").c_str());
217  fRecoHisto->Draw((defaultDrawOptions + " same").c_str());
218  }
219 
220  fRawHisto->SetLabelSize (0.15,"X");
221  fRawHisto->SetLabelOffset(0.01,"X");
222  fRawHisto->SetTitleSize (0.15,"X");
223  fRawHisto->SetTitleOffset(0.60,"X");
224 
225  fRawHisto->SetLabelSize (0.15,"Y");
226  fRawHisto->SetLabelOffset(0.002,"Y");
227  fRawHisto->SetTitleSize (0.15,"Y");
228  fRawHisto->SetTitleOffset(0.16,"Y");
229 
230  fRecoHisto->SetLabelSize (0.15,"X");
231  fRecoHisto->SetLabelOffset(0.01,"X");
232  fRecoHisto->SetTitleSize (0.15,"X");
233  fRecoHisto->SetTitleOffset(0.60,"X");
234 
235  fRecoHisto->SetLabelSize (0.15,"Y");
236  fRecoHisto->SetLabelOffset(0.002,"Y");
237  fRecoHisto->SetTitleSize (0.15,"Y");
238  fRecoHisto->SetTitleOffset(0.16,"Y");
239 
240  } // end if fTQ == kTQ
241 
242 
243  } //end raw waveform (dual phase)
244  else //deconvoluted waveform (single phase)
245  {
246  fPad->Clear();
247  fPad->cd();
248 
249  std::vector<double> hstart;
250  std::vector<double> hend;
251  std::vector<double> hamplitudes;
252  std::vector<double> hpeaktimes;
253 
254  if(fTQ == kTQ){
255  fRawHisto->Reset("ICEM");
256  fRecoHisto->Reset("ICEM");
257 
258  this->RawDataDraw()->FillTQHisto(*evt,
259  fPlane,
260  fWire,
261  fRawHisto);
262 
263  RecoBaseDrawer::HitParamsVec hitParamsVec;
264 
265  this->RecoBaseDraw()->FillTQHisto(*evt,
266  fPlane,
267  fWire,
268  fRecoHisto,
269  hitParamsVec);
270 
271  // draw with histogram style, only (square) lines, no errors
272  static const std::string defaultDrawOptions = "HIST";
273 
274  switch (drawopt->fDrawRawDataOrCalibWires) {
275  case kRAW:
276  fRawHisto->Draw(defaultDrawOptions.c_str());
277  break;
278  case kCALIB:
279  fRecoHisto->Draw(defaultDrawOptions.c_str());
280  break;
281  case kRAWCALIB:
282  fRawHisto->SetMaximum(1.1*std::max(fRawHisto->GetMaximum(), fRecoHisto->GetMaximum()));
283  fRawHisto->SetMinimum(1.1*std::min(fRawHisto->GetMinimum(), fRecoHisto->GetMinimum()));
284  fRawHisto->Draw(defaultDrawOptions.c_str());
285  fRecoHisto->Draw((defaultDrawOptions + " same").c_str());
286  break;
287  } // switch
288 
289  // this loop draws Gaussian shapes for identified hits in the reco histo
290  if (drawopt->fDrawRawDataOrCalibWires != kRAW)
291  {
292  for(const auto& roiHitParamsVec : hitParamsVec)
293  {
294  double roiStart = roiHitParamsVec.front().hitStart; //roiHitParamsVec.front().hitStart - 3. * roiHitParamsVec.front().hitSigma;
295  double roiStop = roiHitParamsVec.back().hitEnd; //roiHitParamsVec.back().hitEnd + 3. * roiHitParamsVec.back().hitSigma;
296  double width = roiStop - roiStart;
297 
298  std::string funcString = "gaus(0)";
299 
300  for(size_t idx = 1; idx < roiHitParamsVec.size(); idx++) funcString += "+gaus(" + std::to_string(3*idx) + ")";
301 
302  TF1 f1("hitshape",funcString.c_str(),roiStart,roiStop);
303 
304  size_t idx(0);
305  for(const auto& hitParams : roiHitParamsVec)
306  {
307  f1.SetParameter(idx + 0, hitParams.hitHeight);
308  f1.SetParameter(idx + 1, hitParams.hitCenter);
309  f1.SetParameter(idx + 2, hitParams.hitSigma);
310 
311  TPolyLine& hitHeight = fView->AddPolyLine(2, kBlack, 1, 1);
312 
313  hitHeight.SetPoint(0, hitParams.hitCenter, 0.);
314  hitHeight.SetPoint(1, hitParams.hitCenter, hitParams.hitHeight);
315 
316  hitHeight.Draw("same");
317 
318  TPolyLine& hitSigma = fView->AddPolyLine(2, kGray, 1, 1);
319 
320  hitSigma.SetPoint(0, hitParams.hitCenter - hitParams.hitSigma, 0.6 * hitParams.hitHeight);
321  hitSigma.SetPoint(1, hitParams.hitCenter + hitParams.hitSigma, 0.6 * hitParams.hitHeight);
322 
323  hitSigma.Draw("same");
324 
325  idx += 3;
326  }
327 
328  //create TPolyLine that actually gets drawn
329  TPolyLine& p1 = fView->AddPolyLine(1001, kOrange+7, 3, 1);
330 
331  //set coordinates of TPolyLine based on Gaussian function
332  for(int j = 0; j<1001; ++j)
333  {
334  double x = roiStart + j*width/1000;
335  double y = f1.Eval(x);
336  p1.SetPoint(j, x, y);
337  }
338  p1.Draw("same");
339  }
340  }
341 
342 /* This code needs additional work to draw the text on the pad
343  // BB: draw plane and wire number on the histogram
344  std::string pw = "P:W = " + std::to_string(this->fPlane) +
345  ":" + std::to_string(this->fWire);
346  char const* txt = pw.c_str();
347  std::cout<<" my text "<<txt<<"\n";
348  double xp = 0.1, yp = 0.9;
349  this->cd();
350  TText& plnwir = fView->AddText(xp, yp, txt);xxx
351  plnwir.SetTextColor(kBlack);
352  plnwir.Draw("same");
353 */
354  if (drawopt->fDrawRawDataOrCalibWires == kCALIB) fRecoHisto->Draw((defaultDrawOptions + " same").c_str());
355  else if(drawopt->fDrawRawDataOrCalibWires == kRAWCALIB){
356  fRawHisto->Draw((defaultDrawOptions + " same").c_str());
357  fRecoHisto->Draw((defaultDrawOptions + " same").c_str());
358  }
359 
360  fRawHisto->SetTitleOffset(0.2, "Y");
361  fRecoHisto->SetLabelSize(0.2, "Y");
362 
363  } // end if fTQ == kTQ
364 
365  if(fTQ == kQ){
366 
367  // figure out the signal type for this plane, assume that
368  // plane n in each TPC/cryostat has the same type
369  geo::PlaneID planeid(drawopt->CurrentTPC(), fPlane);
371  geo::SigType_t sigType = geo->SignalType(planeid);
372 
374 
375  TH1F *hist;
376 
377  int ndiv = 0;
378  if(drawopt->fDrawRawDataOrCalibWires != kCALIB){
379  hist = fRawHisto;
380  hist->SetMinimum(cst->fRawQLow [(size_t)sigType]);
381  hist->SetMaximum(cst->fRawQHigh[(size_t)sigType]);
382  ndiv = cst->fRawDiv[(size_t)sigType];
383  }
384  if(drawopt->fDrawRawDataOrCalibWires == kCALIB){
385  hist = fRecoHisto;
386  hist->SetMinimum(cst->fRecoQLow [(size_t)sigType]);
387  hist->SetMaximum(cst->fRecoQHigh[(size_t)sigType]);
388  ndiv = cst->fRecoDiv[(size_t)sigType];
389  }
390 
391  hist->SetLabelSize(0, "X");
392  hist->SetLabelSize(0, "Y");
393  hist->SetTickLength(0, "X");
394  hist->SetTickLength(0, "Y");
395  hist->Draw("pY+");
396 
397  //
398  // Use this to fill the histogram with colors from the color scale
399  //
400  double x1, x2, y1, y2;
401  x1 = 0.;
402  x2 = 1.;
403 
404  for(int i = 0; i < ndiv; ++i){
405  y1 = hist->GetMinimum() + i*(hist->GetMaximum()-hist->GetMinimum())/(1.*ndiv);
406  y2 = hist->GetMinimum() + (i + 1)*(hist->GetMaximum()-hist->GetMinimum())/(1.*ndiv);
407 
408  int c = 1;
409  if (drawopt->fDrawRawDataOrCalibWires==kRAW) {
410  c = cst->RawQ(sigType).GetColor(0.5*(y1+y2));
411  }
412  if (drawopt->fDrawRawDataOrCalibWires!=kRAW) {
413  c= cst->CalQ(sigType).GetColor(0.5*(y1+y2));
414  }
415 
416  TBox& b = fView->AddBox(x1,y1,x2,y2);
417  b.SetFillStyle(1001);
418  b.SetFillColor(c);
419  b.Draw();
420  } // end loop over Q histogram bins
421 
422 
423  hist->Draw("same");
424 
425  } // end if fTQ == kQ
426  } //if-else dual single phase
427  return;
428  }
429 
430 
431  //......................................................................
433  {
434 
435  if (fRawHisto) {
436  delete fRawHisto;
437  fRawHisto = 0;
438  }
439  if (fRecoHisto) {
440  delete fRecoHisto;
441  fRecoHisto = 0;
442  }
443 
446 
447  // figure out the signal type for this plane, assume that
448  // plane n in each TPC/cryostat has the same type
449  geo::PlaneID planeid(drawopt->CurrentTPC(), fPlane);
451  geo::SigType_t sigType = geo->SignalType(planeid);
452 
454  // int ndivraw = cst->fRawDiv;
455  // int ndivreco = cst->fRecoDiv;
456  double qxloraw = cst->fRawQLow[(size_t)sigType];
457  double qxhiraw = cst->fRawQHigh[(size_t)sigType];
458  double qxloreco = cst->fRecoQLow[(size_t)sigType];
459  double qxhireco = cst->fRecoQHigh[(size_t)sigType];
460  double tqxlo = 1.*this->RawDataDraw()->StartTick();
461  double tqxhi = 1.*this->RawDataDraw()->TotalClockTicks();
462 
463  switch (fTQ) {
464  case kQ:
465  fRawHisto = new TH1F("fRAWQHisto", ";;", 2,0.,1.);
466  fRawHisto->SetMaximum(qxhiraw);
467  fRawHisto->SetMinimum(qxloraw);
468 
469  fRecoHisto = new TH1F("fCALQHisto", ";;", 1,0.,1.);
470  fRecoHisto->SetMaximum(qxhireco);
471  fRecoHisto->SetMinimum(qxloreco);
472  break; // kQ
473  case kTQ:
474  fRawHisto = new TH1F("fRAWTQHisto", ";t [ticks];q [ADC]", (int)tqxhi,tqxlo,tqxhi+tqxlo);
475  fRecoHisto = new TH1F("fCALTQHisto", ";t [ticks];q [ADC]", (int)tqxhi,tqxlo,tqxhi+tqxlo);
476  fRecoHisto->SetLineColor(kBlue);
477  break;
478  default:
479  throw cet::exception("TQPad") << __func__ << ": unexpected quantity #" << fTQ << "\n";
480  }//end if fTQ == kTQ
481 
482  fRawHisto->SetLabelSize (0.15,"X");
483  fRawHisto->SetLabelOffset(0.00,"X");
484  fRawHisto->SetTitleSize (0.15,"X");
485  fRawHisto->SetTitleOffset(0.80,"X");
486 
487  fRawHisto->SetLabelSize (0.10,"Y");
488  fRawHisto->SetLabelOffset(0.01,"Y");
489  fRawHisto->SetTitleSize (0.15,"Y");
490  fRawHisto->SetTitleOffset(0.80,"Y");
491 
492  fRecoHisto->SetLabelSize (0.15,"X");
493  fRecoHisto->SetLabelOffset(0.00,"X");
494  fRecoHisto->SetTitleSize (0.15,"X");
495  fRecoHisto->SetTitleOffset(0.80,"X");
496 
497  fRecoHisto->SetLabelSize (0.15,"Y");
498  fRecoHisto->SetLabelOffset(0.00,"Y");
499  fRecoHisto->SetTitleSize (0.15,"Y");
500  fRecoHisto->SetTitleOffset(0.80,"Y");
501  }
502 
503 }
Float_t x
Definition: compare.C:6
const art::Event * GetEvent() const
Definition: EventHolder.cxx:45
std::vector< double > fRawQLow
low edge of ADC values for drawing raw digits
unsigned int fPlane
Which plane in the detector.
Definition: TQPad.h:30
void FillTQHisto(const art::Event &evt, unsigned int plane, unsigned int wire, TH1F *histo)
Encapsulate the construction of a single cyostat.
Float_t y1[n_points_granero]
Definition: compare.C:5
TPolyLine & AddPolyLine(int n, int c, int w, int s)
Definition: View2D.cxx:210
std::vector< int > fRawDiv
number of divisions in raw
void BookHistogram()
Definition: TQPad.cxx:432
int fDrawRawDataOrCalibWires
0 for raw
Float_t x1[n_points_granero]
Definition: compare.C:5
Declaration of signal hit object.
Float_t y
Definition: compare.C:6
void FillTQHisto(const art::Event &evt, unsigned int plane, unsigned int wire, TH1F *histo, HitParamsVec &hitParamsVec)
The data type to uniquely identify a Plane.
Definition: geo_types.h:250
Drawing pad for time or charge histograms.
static const int kRAW
Definition: TQPad.cxx:36
static std::unique_ptr< FVectorReader > create(const art::Event &evt, const art::InputTag &tag)
Definition: MVAReader.h:29
A collection of drawable 2-D objects.
int GetColor(double x) const
Definition: ColorScale.cxx:126
static const int kCALIB
Definition: TQPad.cxx:37
void Draw()
Definition: TQPad.cxx:111
std::vector< ROIHitParamsVec > HitParamsVec
Singleton to hold the current art::Event for the event display.
static const int kRAWCALIB
Definition: TQPad.cxx:38
std::vector< double > fRecoQHigh
high edge of ADC values for drawing raw digits
Float_t y2[n_points_geant4]
Definition: compare.C:26
std::vector< double > fRecoQLow
low edge of ADC values for drawing raw digits
unsigned int fWire
Definition: TQPad.h:29
The color scales used by the event display.
evdb::View2D * fView
Superimpose scale on 1D histo.
Definition: TQPad.h:34
TBox & AddBox(double x1, double y1, double x2, double y2)
Definition: View2D.cxx:263
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
Int_t max
Definition: plot.C:27
LArSoft includes.
void FillTQHistoDP(const art::Event &evt, unsigned int plane, unsigned int wire, TH1F *histo, std::vector< double > &htau1, std::vector< double > &htau2, std::vector< double > &hitamplitudes, std::vector< double > &hpeaktimes, std::vector< int > &hstartT, std::vector< int > &hendT, std::vector< int > &hNMultiHit, std::vector< int > &hLocalHitIndex)
RawDataDrawer * RawDataDraw()
Definition: DrawingPad.cxx:109
const evdb::ColorScale & RawQ(geo::SigType_t st) const
enum geo::_plane_sigtype SigType_t
Enumerate the possible plane projections.
static EventHolder * Instance()
Definition: EventHolder.cxx:15
EmPhysicsFactory f1
const evdb::ColorScale & CalQ(geo::SigType_t st) const
Base class for event display drawing pads.
Definition: DrawingPad.h:29
RecoBaseDrawer * RecoBaseDraw()
Definition: DrawingPad.cxx:120
TH1F * fRawHisto
1-D Histogram of charge or charge vs time
Definition: TQPad.h:32
TPad * Pad()
Definition: DrawingPad.h:37
geo::TPCID CurrentTPC() const
Returns the current TPC as a TPCID.
double TotalClockTicks() const
Definition: RawDataDrawer.h:85
static const int kQ
Definition: TQPad.cxx:39
Class to aid in the rendering of RecoBase objects.
Class to aid in the rendering of RawData objects.
double EvalExpoFit(double x, double tau1, double tau2, double amplitude, double peaktime)
static const int kTQ
Definition: TQPad.cxx:40
std::vector< double > fRawQHigh
high edge of ADC values for drawing raw digits
int fTQ
0 = plot shows charge only, 1 = plot shows charge vs time for a wire
Definition: TQPad.h:31
double StartTick() const
Definition: RawDataDrawer.h:84
std::string to_string(Flag_t< Storage > const flag)
Convert a flag into a stream (shows its index).
Definition: BitMask.h:187
Encapsulate the construction of a single detector plane.
TH2F * hist
Definition: plot.C:136
Int_t min
Definition: plot.C:26
double EvalMultiExpoFit(double x, int HitNumber, int NHits, std::vector< double > tau1, std::vector< double > tau2, std::vector< double > amplitude, std::vector< double > peaktime)
TPad * fPad
The ROOT graphics pad.
Definition: DrawingPad.h:53
TCEvent evt
Definition: DataStructs.cxx:5
std::vector< int > fRecoDiv
number of divisions in raw
Float_t x2[n_points_geant4]
Definition: compare.C:26
Namespace collecting geometry-related classes utilities.
TQPad(const char *nm, const char *ti, double x1, double y1, double x2, double y2, const char *opt, unsigned int plane, unsigned int wire)
Definition: TQPad.cxx:44
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
Encapsulate the construction of a single detector plane.
TH1F * fRecoHisto
1-D Histogram of charge or charge vs time
Definition: TQPad.h:33