LArSoft  v06_85_00
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 
138  if(fTQ == kTQ)
139  {
140  fRawHisto->Reset("ICEM");
141  fRecoHisto->Reset("ICEM");
142 
143  this->RawDataDraw()->FillTQHisto(*evt,
144  fPlane,
145  fWire,
146  fRawHisto);
147 
148  this->RecoBaseDraw()->FillTQHistoDP(*evt,
149  fPlane,
150  fWire,
151  fRecoHisto,
152  htau1,
153  htau2,
154  hamplitudes,
155  hpeaktimes,
156  hstartT,
157  hendT,
158  hNMultiHit);
159 
160 
161  // draw with histogram style, only (square) lines, no errors
162  static const std::string defaultDrawOptions = "HIST";
163 
164  switch (drawopt->fDrawRawDataOrCalibWires) {
165  case kRAW:
166  fRawHisto->Draw(defaultDrawOptions.c_str());
167  break;
168  case kCALIB:
169  fRecoHisto->Draw(defaultDrawOptions.c_str());
170  break;
171  case kRAWCALIB:
172  fRawHisto->SetMaximum(1.2*std::max(fRawHisto->GetMaximum(), fRecoHisto->GetMaximum()));
173  fRawHisto->SetMinimum(1.2*std::min(fRawHisto->GetMinimum(), fRecoHisto->GetMinimum()));
174  fRawHisto->Draw(defaultDrawOptions.c_str());
175  fRecoHisto->Draw((defaultDrawOptions + " same").c_str());
176  break;
177  } // switch
178 
179  // this loop draws the double-exponential shapes for identified hits in the reco histo
180  for (size_t i = 0; i < hamplitudes.size() && drawopt->fDrawRawDataOrCalibWires != kRAW; ++i) {
181  // If there is more than one peak in this fit, draw the sum of all peaks
182  if( (i==0 && hNMultiHit[i]>1) || (i>0 && hNMultiHit[i]>1 && hstartT[i] != hstartT[i-1]) )
183  {
184  // create TPolyLine that actually gets drawn
185  TPolyLine& p2 = fView->AddPolyLine(1001,kRed,3,1);
186 
187  // set coordinates of TPolyLine based fitted function
188  for(int j = 0; j<1001; ++j)
189  {
190  double x = hstartT[i]+j*(hendT[i]-hstartT[i])/1000;
191  double y = RecoBaseDraw()->EvalMultiExpoFit(x,i,hNMultiHit[i],htau1,htau2,hamplitudes,hpeaktimes);
192  p2.SetPoint(j, x, y);
193  }
194 
195  p2.Draw("same");
196  }
197 
198  // Always draw the single peaks in addition to the sum of all peaks
199  // create TPolyLine that actually gets drawn
200  TPolyLine& p1 = fView->AddPolyLine(1001,kOrange+7,3,1);
201 
202  // set coordinates of TPolyLine based fitted function
203  for(int j = 0; j<1001; ++j){
204  double x = hstartT[i]+j*(hendT[i]-hstartT[i])/1000;
205  double y = RecoBaseDraw()->EvalExpoFit(x,htau1[i],htau2[i],hamplitudes[i],hpeaktimes[i]);
206  p1.SetPoint(j, x, y);
207  }
208 
209  p1.Draw("same");
210  }
211 
212  if (drawopt->fDrawRawDataOrCalibWires == kCALIB) fRecoHisto->Draw((defaultDrawOptions + " same").c_str());
213  else if(drawopt->fDrawRawDataOrCalibWires == kRAWCALIB){
214  fRawHisto->Draw((defaultDrawOptions + " same").c_str());
215  fRecoHisto->Draw((defaultDrawOptions + " same").c_str());
216  }
217 
218  fRawHisto->SetLabelSize (0.15,"X");
219  fRawHisto->SetLabelOffset(0.01,"X");
220  fRawHisto->SetTitleSize (0.15,"X");
221  fRawHisto->SetTitleOffset(0.60,"X");
222 
223  fRawHisto->SetLabelSize (0.15,"Y");
224  fRawHisto->SetLabelOffset(0.002,"Y");
225  fRawHisto->SetTitleSize (0.15,"Y");
226  fRawHisto->SetTitleOffset(0.16,"Y");
227 
228  fRecoHisto->SetLabelSize (0.15,"X");
229  fRecoHisto->SetLabelOffset(0.01,"X");
230  fRecoHisto->SetTitleSize (0.15,"X");
231  fRecoHisto->SetTitleOffset(0.60,"X");
232 
233  fRecoHisto->SetLabelSize (0.15,"Y");
234  fRecoHisto->SetLabelOffset(0.002,"Y");
235  fRecoHisto->SetTitleSize (0.15,"Y");
236  fRecoHisto->SetTitleOffset(0.16,"Y");
237 
238  } // end if fTQ == kTQ
239 
240 
241  } //end raw waveform (dual phase)
242  else //deconvoluted waveform (single phase)
243  {
244  fPad->Clear();
245  fPad->cd();
246 
247  std::vector<double> hstart;
248  std::vector<double> hend;
249  std::vector<double> hamplitudes;
250  std::vector<double> hpeaktimes;
251 
252  if(fTQ == kTQ){
253  fRawHisto->Reset("ICEM");
254  fRecoHisto->Reset("ICEM");
255 
256  this->RawDataDraw()->FillTQHisto(*evt,
257  fPlane,
258  fWire,
259  fRawHisto);
260 
261  RecoBaseDrawer::HitParamsVec hitParamsVec;
262 
263  this->RecoBaseDraw()->FillTQHisto(*evt,
264  fPlane,
265  fWire,
266  fRecoHisto,
267  hitParamsVec);
268 
269  // draw with histogram style, only (square) lines, no errors
270  static const std::string defaultDrawOptions = "HIST";
271 
272  switch (drawopt->fDrawRawDataOrCalibWires) {
273  case kRAW:
274  fRawHisto->Draw(defaultDrawOptions.c_str());
275  break;
276  case kCALIB:
277  fRecoHisto->Draw(defaultDrawOptions.c_str());
278  break;
279  case kRAWCALIB:
280  fRawHisto->SetMaximum(1.1*std::max(fRawHisto->GetMaximum(), fRecoHisto->GetMaximum()));
281  fRawHisto->SetMinimum(1.1*std::min(fRawHisto->GetMinimum(), fRecoHisto->GetMinimum()));
282  fRawHisto->Draw(defaultDrawOptions.c_str());
283  fRecoHisto->Draw((defaultDrawOptions + " same").c_str());
284  break;
285  } // switch
286 
287  // this loop draws Gaussian shapes for identified hits in the reco histo
288  if (drawopt->fDrawRawDataOrCalibWires != kRAW)
289  {
290  for(const auto& roiHitParamsVec : hitParamsVec)
291  {
292  double roiStart = roiHitParamsVec.front().hitStart; //roiHitParamsVec.front().hitStart - 3. * roiHitParamsVec.front().hitSigma;
293  double roiStop = roiHitParamsVec.back().hitEnd; //roiHitParamsVec.back().hitEnd + 3. * roiHitParamsVec.back().hitSigma;
294  double width = roiStop - roiStart;
295 
296  std::string funcString = "gaus(0)";
297 
298  for(size_t idx = 1; idx < roiHitParamsVec.size(); idx++) funcString += "+gaus(" + std::to_string(3*idx) + ")";
299 
300  TF1 f1("hitshape",funcString.c_str(),roiStart,roiStop);
301 
302  size_t idx(0);
303  for(const auto& hitParams : roiHitParamsVec)
304  {
305  f1.SetParameter(idx + 0, hitParams.hitHeight);
306  f1.SetParameter(idx + 1, hitParams.hitCenter);
307  f1.SetParameter(idx + 2, hitParams.hitSigma);
308 
309  TPolyLine& hitHeight = fView->AddPolyLine(2, kBlack, 1, 1);
310 
311  hitHeight.SetPoint(0, hitParams.hitCenter, 0.);
312  hitHeight.SetPoint(1, hitParams.hitCenter, hitParams.hitHeight);
313 
314  hitHeight.Draw("same");
315 
316  TPolyLine& hitSigma = fView->AddPolyLine(2, kGray, 1, 1);
317 
318  hitSigma.SetPoint(0, hitParams.hitCenter - hitParams.hitSigma, 0.6 * hitParams.hitHeight);
319  hitSigma.SetPoint(1, hitParams.hitCenter + hitParams.hitSigma, 0.6 * hitParams.hitHeight);
320 
321  hitSigma.Draw("same");
322 
323  idx += 3;
324  }
325 
326  //create TPolyLine that actually gets drawn
327  TPolyLine& p1 = fView->AddPolyLine(1001, kOrange+7, 3, 1);
328 
329  //set coordinates of TPolyLine based on Gaussian function
330  for(int j = 0; j<1001; ++j)
331  {
332  double x = roiStart + j*width/1000;
333  double y = f1.Eval(x);
334  p1.SetPoint(j, x, y);
335  }
336  p1.Draw("same");
337  }
338  }
339 
340 /* This code needs additional work to draw the text on the pad
341  // BB: draw plane and wire number on the histogram
342  std::string pw = "P:W = " + std::to_string(this->fPlane) +
343  ":" + std::to_string(this->fWire);
344  char const* txt = pw.c_str();
345  std::cout<<" my text "<<txt<<"\n";
346  double xp = 0.1, yp = 0.9;
347  this->cd();
348  TText& plnwir = fView->AddText(xp, yp, txt);xxx
349  plnwir.SetTextColor(kBlack);
350  plnwir.Draw("same");
351 */
352  if (drawopt->fDrawRawDataOrCalibWires == kCALIB) fRecoHisto->Draw((defaultDrawOptions + " same").c_str());
353  else if(drawopt->fDrawRawDataOrCalibWires == kRAWCALIB){
354  fRawHisto->Draw((defaultDrawOptions + " same").c_str());
355  fRecoHisto->Draw((defaultDrawOptions + " same").c_str());
356  }
357 
358  fRawHisto->SetTitleOffset(0.2, "Y");
359  fRecoHisto->SetLabelSize(0.2, "Y");
360 
361  } // end if fTQ == kTQ
362 
363  if(fTQ == kQ){
364 
365  // figure out the signal type for this plane, assume that
366  // plane n in each TPC/cryostat has the same type
367  geo::PlaneID planeid(drawopt->CurrentTPC(), fPlane);
369  geo::SigType_t sigType = geo->SignalType(planeid);
370 
372 
373  TH1F *hist;
374 
375  int ndiv = 0;
376  if(drawopt->fDrawRawDataOrCalibWires != kCALIB){
377  hist = fRawHisto;
378  hist->SetMinimum(cst->fRawQLow [(size_t)sigType]);
379  hist->SetMaximum(cst->fRawQHigh[(size_t)sigType]);
380  ndiv = cst->fRawDiv[(size_t)sigType];
381  }
382  if(drawopt->fDrawRawDataOrCalibWires == kCALIB){
383  hist = fRecoHisto;
384  hist->SetMinimum(cst->fRecoQLow [(size_t)sigType]);
385  hist->SetMaximum(cst->fRecoQHigh[(size_t)sigType]);
386  ndiv = cst->fRecoDiv[(size_t)sigType];
387  }
388 
389  hist->SetLabelSize(0, "X");
390  hist->SetLabelSize(0, "Y");
391  hist->SetTickLength(0, "X");
392  hist->SetTickLength(0, "Y");
393  hist->Draw("pY+");
394 
395  //
396  // Use this to fill the histogram with colors from the color scale
397  //
398  double x1, x2, y1, y2;
399  x1 = 0.;
400  x2 = 1.;
401 
402  for(int i = 0; i < ndiv; ++i){
403  y1 = hist->GetMinimum() + i*(hist->GetMaximum()-hist->GetMinimum())/(1.*ndiv);
404  y2 = hist->GetMinimum() + (i + 1)*(hist->GetMaximum()-hist->GetMinimum())/(1.*ndiv);
405 
406  int c = 1;
407  if (drawopt->fDrawRawDataOrCalibWires==kRAW) {
408  c = cst->RawQ(sigType).GetColor(0.5*(y1+y2));
409  }
410  if (drawopt->fDrawRawDataOrCalibWires!=kRAW) {
411  c= cst->CalQ(sigType).GetColor(0.5*(y1+y2));
412  }
413 
414  TBox& b = fView->AddBox(x1,y1,x2,y2);
415  b.SetFillStyle(1001);
416  b.SetFillColor(c);
417  b.Draw();
418  } // end loop over Q histogram bins
419 
420 
421  hist->Draw("same");
422 
423  } // end if fTQ == kQ
424  } //if-else dual single phase
425  return;
426  }
427 
428 
429  //......................................................................
431  {
432 
433  if (fRawHisto) {
434  delete fRawHisto;
435  fRawHisto = 0;
436  }
437  if (fRecoHisto) {
438  delete fRecoHisto;
439  fRecoHisto = 0;
440  }
441 
444 
445  // figure out the signal type for this plane, assume that
446  // plane n in each TPC/cryostat has the same type
447  geo::PlaneID planeid(drawopt->CurrentTPC(), fPlane);
449  geo::SigType_t sigType = geo->SignalType(planeid);
450 
452  // int ndivraw = cst->fRawDiv;
453  // int ndivreco = cst->fRecoDiv;
454  double qxloraw = cst->fRawQLow[(size_t)sigType];
455  double qxhiraw = cst->fRawQHigh[(size_t)sigType];
456  double qxloreco = cst->fRecoQLow[(size_t)sigType];
457  double qxhireco = cst->fRecoQHigh[(size_t)sigType];
458  double tqxlo = 1.*this->RawDataDraw()->StartTick();
459  double tqxhi = 1.*this->RawDataDraw()->TotalClockTicks();
460 
461  switch (fTQ) {
462  case kQ:
463  fRawHisto = new TH1F("fRAWQHisto", ";;", 2,0.,1.);
464  fRawHisto->SetMaximum(qxhiraw);
465  fRawHisto->SetMinimum(qxloraw);
466 
467  fRecoHisto = new TH1F("fCALQHisto", ";;", 1,0.,1.);
468  fRecoHisto->SetMaximum(qxhireco);
469  fRecoHisto->SetMinimum(qxloreco);
470  break; // kQ
471  case kTQ:
472  fRawHisto = new TH1F("fRAWTQHisto", ";t [ticks];q [ADC]", (int)tqxhi,tqxlo,tqxhi+tqxlo);
473  fRecoHisto = new TH1F("fCALTQHisto", ";t [ticks];q [ADC]", (int)tqxhi,tqxlo,tqxhi+tqxlo);
474  fRecoHisto->SetLineColor(kBlue);
475  break;
476  default:
477  throw cet::exception("TQPad") << __func__ << ": unexpected quantity #" << fTQ << "\n";
478  }//end if fTQ == kTQ
479 
480  fRawHisto->SetLabelSize (0.15,"X");
481  fRawHisto->SetLabelOffset(0.00,"X");
482  fRawHisto->SetTitleSize (0.15,"X");
483  fRawHisto->SetTitleOffset(0.80,"X");
484 
485  fRawHisto->SetLabelSize (0.10,"Y");
486  fRawHisto->SetLabelOffset(0.01,"Y");
487  fRawHisto->SetTitleSize (0.15,"Y");
488  fRawHisto->SetTitleOffset(0.80,"Y");
489 
490  fRecoHisto->SetLabelSize (0.15,"X");
491  fRecoHisto->SetLabelOffset(0.00,"X");
492  fRecoHisto->SetTitleSize (0.15,"X");
493  fRecoHisto->SetTitleOffset(0.80,"X");
494 
495  fRecoHisto->SetLabelSize (0.15,"Y");
496  fRecoHisto->SetLabelOffset(0.00,"Y");
497  fRecoHisto->SetTitleSize (0.15,"Y");
498  fRecoHisto->SetTitleOffset(0.80,"Y");
499  }
500 
501 }
Float_t x
Definition: compare.C:6
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)
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:430
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.
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
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