VEMTraceView.cc
Go to the documentation of this file.
1 #include <algorithm>
2 #include <sstream>
3 
4 #include <boost/format.hpp>
5 
6 #include <TCanvas.h>
7 #include <TH1D.h>
8 #include <TGraph.h>
9 #include <TGraphErrors.h>
10 #include <TArrow.h>
11 #include <TBox.h>
12 
13 #include <sevt/PMT.h>
14 #include <sevt/Station.h>
15 
16 #include "AddText.h"
17 #include "VEMTraceView.h"
18 
19 using namespace utl;
20 using namespace sevt;
21 using namespace std;
22 using namespace boost;
23 using namespace SdCalibPlotterOG;
24 
25 
26 void
27 VEMTraceView::DividePage(TCanvas& c)
28 {
29  const double xmargin = 0.003;
30  const double ymargin = 0.003;
31  const double vertDivision = 0.2;
32 
33  TPad* const savePad = (TPad*)gPad;
34  c.cd();
35  const string name = c.GetName();
36  ostringstream os;
37  int n = 1;
38  os.str(""); os << name << "_1";
39  const double x1 = xmargin;
40  const double x2 = vertDivision - 0.5*xmargin;
41  const double x3 = vertDivision + 0.5*xmargin;
42  const double x4 = 1 - xmargin;
43  const double y11 = ymargin;
44  const double y12 = 1 - ymargin;
45  TPad* const pad1 = new TPad(os.str().c_str(), os.str().c_str(), x1, y11, x2, y12, 0);
46  pad1->SetNumber(n++);
47  pad1->Draw();
48  const int nRows = 4;
49  for (int row = 0; row < nRows; ++row) {
50  const double y1 = 1 - (row+1)*(1 - ymargin)/nRows;
51  const double y2 = 1 - ymargin - row*(1 - ymargin)/nRows;
52  os.str(""); os << name << '_' << n;
53  TPad* const pad = new TPad(os.str().c_str(), os.str().c_str(), x3, y1, x4, y2, 0);
54  pad->SetNumber(n++);
55  pad->SetLeftMargin(0.5*pad->GetLeftMargin());
56  pad->SetRightMargin(0);
57  pad->Draw();
58  }
59  savePad->cd();
60 }
61 
62 
63 void
64 PMTVEMTraceView::Draw(const PMT& pmt, const int stationStart, const int stationStop)
65 {
66  if (!pmt.HasRecData()) {
67  Missing("No Rec Data");
68  return;
69  }
70 
71  const PMTRecData& pmtRec = pmt.GetRecData();
72 
73  if (!pmtRec.HasVEMTrace()) {
74  Missing("No VEM Trace");
75  return;
76  }
77 
78  // vem trace
79  const TraceD& trace = pmtRec.GetVEMTrace();
80  const int traceLength = trace.GetSize();
81  ostringstream os;
82  os << "PMT" << pmt.GetId() << "_VEMTrace";
83  TH1D& th =
84  Add(new TH1D(os.str().c_str(), os.str().c_str(), traceLength, 0, traceLength));
85  for (int i = 0; i < traceLength; ++i)
86  th.SetBinContent(i+1, trace[i]);
87  th.SetStats(false);
88  th.SetLineColor(kRed);
89 
90  // peak amplitude
91  const double peak = pmtRec.GetPeakAmplitude();
92  const double xPeak[2] = { 0, double(traceLength) };
93  const double yPeak[2] = { peak, peak };
94  TGraph& pg = Add(new TGraph(2, xPeak, yPeak));
95  pg.SetTitle(os.str().c_str());
96  pg.SetLineStyle(kDashed);
97  pg.SetLineColor(17); // gray
98  pg.Draw("AL");
99  pg.GetXaxis()->SetLimits(0, traceLength);
100  pg.GetYaxis()->SetTitle("[VEM peak]");
101  pg.GetYaxis()->SetTitleOffset(0.3);
102  pg.GetYaxis()->SetTickLength(0.01);
103  TH1F& pgh = *pg.GetHistogram();
104  pgh.SetMinimum(th.GetMinimum());
105  pgh.SetMaximum(th.GetMaximum());
106 
107  // station start/stop
108  if (stationStart >= 0) {
109  const double x1[2] = { double(stationStart), double(stationStart) };
110  const double x2[2] = { double(stationStop), double(stationStop) };
111  const double y[2] = { -peak, 3*peak };
112  TGraph& ss1 = Add(new TGraph(2, x1, y));
113  ss1.SetLineColor(kBlue);
114  ss1.SetLineStyle(kDashed);
115  ss1.Draw("L same");
116  TGraph& ss2 = Add(new TGraph(2, x2, y));
117  ss2.SetLineColor(kBlue);
118  ss2.SetLineStyle(kDashed);
119  ss2.Draw("L same");
120  }
121 
122  // zero line
123  const double yZero[2] = { 0, 0 };
124  TGraph& zg = Add(new TGraph(2, xPeak, yZero));
125  zg.SetLineWidth(1);
126  zg.SetLineColor(17); // gray
127  zg.Draw("L same");
128 
129  // signals
130  const SignalSegmentCollection& signals = pmtRec.GetSignals();
131  {
132  for (unsigned int s = 0; s < signals.size(); ++s) {
133  double min = trace[signals[s].fStart];
134  double max = min;
135  for (int i = signals[s].fStart+1; i < signals[s].fStop; ++i) {
136  double val = trace[i];
137  if (val < min)
138  min = val;
139  if (val > max)
140  max = val;
141  }
142  const double eps = 0.1*(max - min);
143  const double y1 = min - eps;
144  const double y2 = max + eps;
145  if (y1 < pgh.GetMinimum())
146  pgh.SetMinimum(y1);
147  if (y2 > pgh.GetMaximum())
148  pgh.SetMaximum(y2);
149  }
150  const double plotSpan = pgh.GetMaximum() - pgh.GetMinimum();
151  for (unsigned int s = 0; s < signals.size(); ++s) {
152  double min = trace[signals[s].fStart];
153  double max = min;
154  for (int i = signals[s].fStart; i < signals[s].fStop; ++i) {
155  double val = trace[i];
156  if (val < min)
157  min = val;
158  if (val > max)
159  max = val;
160  }
161  const double diff = max - min;
162  const double eps = 0.05*diff;
163  const double y1 = min - eps;
164  const double y2 = max + eps;
165  TBox& sb = Add(new TBox(signals[s].fStart, y1, signals[s].fStop, y2));
166  sb.SetFillStyle(0);
167  sb.SetLineColor(8); // dark green
168  sb.Draw();
169  const string& chargeStr = (format("%.2f") % signals[s].fCharge).str();
170  if (diff < 0.35*plotSpan) {
171  const double x = 0.5*(signals[s].fStart + signals[s].fStop);
172  TArrow& a = Add(new TArrow(x, max + 0.3*plotSpan, x, max + 0.05*plotSpan, 0.01));
173  a.SetAngle(20);
174  a.SetLineColor(8); // dark green
175  a.Draw();
176  TText& t = Add(new TText(signals[s].fStart, max + 0.34*plotSpan, chargeStr.c_str()));
177  t.Draw();
178  } else {
179  TText& t = Add(new TText(signals[s].fStop + 3, 0.3*min + 0.7*max, chargeStr.c_str()));
180  t.Draw();
181  }
182  }
183  }
184 
185  th.Draw("same");
186 
187  const sdet::PMTConstants::PMTGain gainUsed = pmtRec.GetGainUsed();
188 
189  // gain used
190  {
191  TPaveText& pt = Add(new TPaveText(0.88,0.77,0.99,0.87, "ndc"));
192  pt.SetBorderSize(2);
193  pt.SetTextAlign(12);
194  if (gainUsed == sdet::PMTConstants::eHighGain) {
195  pt.SetFillColor(kWhite);
196  pt.AddText("From High Gain");
197  } else {
198  pt.SetFillColor(kCyan);
199  pt.AddText("From Low Gain");
200  }
201  pt.Draw();
202  }
203 
204  // sturated bins
205  {
206  const int satBins = pmtRec.GetFADCSaturatedBins(gainUsed);
207  if (satBins) {
208  TPaveText& pt = Add(new TPaveText(0.92,0.64,0.99,0.74, "ndc"));
209  pt.SetBorderSize(2);
210  pt.SetTextAlign(12);
211  pt.SetFillColor(kCyan);
212  pt.AddText((format("N_{sat} = %d ") % satBins).str().c_str());
213  pt.Draw();
214  }
215  }
216 
217  // total charge
218  {
219  TPaveText& pt = Add(new TPaveText(0.9,0.90,0.99,1, "ndc"));
220  pt.SetBorderSize(2);
221  pt.SetTextAlign(12);
222  pt.SetFillColor(kWhite);
223  pt.AddText((format("q = %.2f VEM") % pmtRec.GetTotalCharge()).str().c_str());
224  pt.Draw();
225  }
226 }
227 
228 
229 void
230 StationVEMTraceView::Draw(const Station& station)
231 {
232  if (!station.HasVEMTrace()) {
233  Missing("No VEM Trace");
234  return;
235  }
236 
237  const TraceD& trace = station.GetVEMTrace();
238  const int traceLength = trace.GetSize();
239  const string titleStr = (format("Station_%04d_VEMTrace") % station.GetId()).str();
240 
241  // zero line
242  const double xZero[2] = { 0., double(traceLength) };
243  const double yZero[2] = { 0, 0 };
244  TGraph& zg = Add(new TGraph(2, xZero, yZero));
245  zg.SetLineWidth(1);
246  zg.SetLineColor(17); // gray
247  zg.SetTitle(titleStr.c_str());
248  zg.Draw("AL");
249  zg.GetXaxis()->SetLimits(0, traceLength);
250  zg.GetYaxis()->SetTitle("[VEM peak]");
251  zg.GetYaxis()->SetTitleOffset(0.3);
252  zg.GetYaxis()->SetTickLength(0.01);
253 
254  TH1D& th =
255  Add(new TH1D(titleStr.c_str(), "", traceLength, 0, traceLength));
256  for (int i = 0; i < traceLength; ++i)
257  th.SetBinContent(i+1, trace[i]);
258  th.SetStats(false);
259  th.SetLineColor(kRed);
260 
261  TH1F& zgh = *zg.GetHistogram();
262  zgh.SetMinimum(th.GetMinimum());
263  zgh.SetMaximum(th.GetMaximum());
264 
265  // signals
266  const SignalSegmentCollection& signals = station.GetSignals();
267  {
268  for (unsigned int s = 0; s < signals.size(); ++s) {
269  double min = trace[signals[s].fStart];
270  double max = min;
271  for (int i = signals[s].fStart+1; i < signals[s].fStop; ++i) {
272  double val = trace[i];
273  if (val < min)
274  min = val;
275  if (val > max)
276  max = val;
277  }
278  const double eps = 0.1*(max - min);
279  const double y1 = min - eps;
280  const double y2 = max + eps;
281  if (y1 < zgh.GetMinimum())
282  zgh.SetMinimum(y1);
283  if (y2 > zgh.GetMaximum())
284  zgh.SetMaximum(y2);
285  }
286  const double plotSpan = zgh.GetMaximum() - zgh.GetMinimum();
287  for (unsigned int s = 0; s < signals.size(); ++s) {
288  double min = trace[signals[s].fStart];
289  double max = min;
290  for (int i = signals[s].fStart; i < signals[s].fStop; ++i) {
291  double val = trace[i];
292  if (val < min)
293  min = val;
294  if (val > max)
295  max = val;
296  }
297  const double diff = max - min;
298  const double eps = 0.05*diff;
299  const double y1 = min - eps;
300  const double y2 = max + eps;
301  TBox& sb = Add(new TBox(signals[s].fStart, y1, signals[s].fStop, y2));
302  sb.SetFillStyle(0);
303  sb.SetLineColor(8); // dark green
304  sb.Draw();
305  const string& chargeStr = (format("%.2f") % signals[s].fCharge).str();
306  if (diff < 0.35*plotSpan) {
307  const double x = 0.5*(signals[s].fStart + signals[s].fStop);
308  TArrow& a = Add(new TArrow(x, max + 0.3*plotSpan, x, max + 0.05*plotSpan, 0.01));
309  a.SetAngle(20);
310  a.SetLineColor(8); // dark green
311  a.Draw();
312  TText& t = Add(new TText(signals[s].fStart, max + 0.34*plotSpan, chargeStr.c_str()));
313  t.Draw();
314  } else {
315  TText& t = Add(new TText(signals[s].fStop + 3, 0.3*min + 0.7*max, chargeStr.c_str()));
316  t.Draw();
317  }
318  }
319  }
320 
321  if (!station.HasRecData()) {
322  Missing("No Rec Data");
323  th.Draw("same");
324  return;
325  }
326 
327  // final signal start/end time
328  const StationRecData& stRec = station.GetRecData();
329  const int start = stRec.GetSignalStartSlot();
330  const int stop = stRec.GetSignalEndSlot();
331  double min = trace[start];
332  double max = min;
333  for (int i = start; i < stop; ++i) {
334  double val = trace[i];
335  if (val < min)
336  min = val;
337  if (val > max)
338  max = val;
339  }
340  const double diff = max - min;
341  const double eps = 0.05*diff;
342  const double y1 = min - eps;
343  const double y2 = max + eps;
344  TBox& sb = Add(new TBox(start, y1, stop, y2));
345  sb.SetFillStyle(0);
346  sb.SetLineColor(kBlue);
347  sb.Draw();
348 
349  th.Draw("same");
350 
351  // total signal
352  {
353  TPaveText& pt = Add(new TPaveText(0.9,0.90,0.99,1, "ndc"));
354  pt.SetBorderSize(2);
355  pt.SetTextAlign(12);
356  pt.SetFillColor(kWhite);
357  pt.AddText((format("q = %.2f VEM") % stRec.GetTotalSignal()).str().c_str());
358  pt.Draw();
359  }
360 }
361 
362 
363 void
364 VEMTraceView::Missing(const string& what)
365 {
366  TPaveText& pt = Add(new TPaveText(0.3,0.4,0.7,0.6, "ndc"));
367  pt.SetBorderSize(2);
368  pt.SetFillColor(kRed);
369  pt.SetTextAlign(12);
370  pt.AddText(what.c_str());
371  pt.Draw();
372 }
373 
374 
375 // Configure (x)emacs for this file ...
376 // Local Variables:
377 // mode: c++
378 // End:
Class to access station level reconstructed data.
utl::TraceD & GetVEMTrace(const StationConstants::SignalComponent source=StationConstants::eTotal)
Traces calibrated in VEM Peak.
Definition: PMTRecData.h:46
double GetTotalCharge() const
Total charge.
Definition: PMTRecData.h:137
int GetId() const
Get the station Id.
bool HasRecData() const
Check for existenc of PMT reconstructed data object.
Definition: SEvent/PMT.h:53
class to hold data at PMT level
Definition: SEvent/PMT.h:28
PMTRecData & GetRecData()
Get object containing PMT reconstructed data.
Definition: SEvent/PMT.h:48
sevt::StationRecData & GetRecData()
Get station level reconstructed data.
int GetFADCSaturatedBins(const sdet::PMTConstants::PMTGain gain=sdet::PMTConstants::eHighGain) const
Definition: PMTRecData.h:161
unsigned int GetId() const
Return Id of the PMT.
Definition: SEvent/PMT.h:32
utl::TraceD & GetVEMTrace(const StationConstants::SignalComponent source=StationConstants::eTotal)
signal trace calibrated in [VEM charge]
#define max(a, b)
class to hold data at Station level
constexpr double s
Definition: AugerUnits.h:163
class to hold reconstructed data at PMT level
Definition: PMTRecData.h:38
double GetTotalSignal() const
Total integrated signal in VEM unit, averaged over pmts.
unsigned int GetSignalStartSlot() const
Start time of the signal in time slots from beginning of trace.
bool HasVEMTrace(const StationConstants::SignalComponent source=StationConstants::eTotal) const
Check whether VEM trace exists.
SizeType GetSize() const
Definition: Trace.h:156
double eps
unsigned int GetSignalEndSlot() const
End time of the signal in time slots from beginning of trace.
std::vector< SignalSegment > SignalSegmentCollection
Definition: SignalSegment.h:33
sdet::PMTConstants::PMTGain GetGainUsed() const
Definition: PMTRecData.h:164
bool HasRecData() const
Check whether station reconstructed data exists.
SignalSegmentCollection & GetSignals()
Definition: PMTRecData.h:169
SignalSegmentCollection & GetSignals()
double GetPeakAmplitude() const
Peak Amplitude.
Definition: PMTRecData.h:140
bool HasVEMTrace(const StationConstants::SignalComponent source=StationConstants::eTotal) const
Definition: PMTRecData.h:55

, generated on Tue Sep 26 2023.