HistoView.cc
Go to the documentation of this file.
1 #include "AddText.h"
2 #include "HistoView.h"
3 
4 #include <utl/Histogram.h>
5 #include <utl/Math.h>
6 #include <sdet/Station.h>
7 #include <sevt/Station.h>
8 #include <sevt/PMT.h>
9 #include <sevt/PMTCalibData.h>
10 #include <utl/QuadraticFitData.h>
11 #include <utl/ExponentialFitData.h>
12 
13 #include <TCanvas.h>
14 #include <TH1D.h>
15 #include <TF1.h>
16 #include <TGraphErrors.h>
17 #include <TPaveText.h>
18 #include <TArrow.h>
19 
20 #include <vector>
21 #include <iomanip>
22 
23 using namespace utl;
24 using namespace sevt;
25 using namespace std;
26 using namespace SdCalibPlotterOG;
27 
28 
29 void
30 MuonPeakView::Draw(const sdet::Station& dStation, const sevt::Station& sStation, const PMT& pmt, const int pmtId)
31 {
32  if (HasNoCalib(pmt))
33  return;
34  ostringstream os;
35  os << "MuPeak PMT " << pmtId;
36  const auto& peakBinning = dStation.GetMuonPeakHistogramBinning<double>(pmt.GetType(), sStation.GetCalibData().GetVersion());
37  auto& peak = Add(new TH1D(os.str().c_str(), os.str().c_str(), peakBinning.size()-1, &peakBinning[0]));
38  const auto& pmtCalib = pmt.GetCalibData();
39  SetContent(peak, peakBinning, pmtCalib.GetMuonPeakHisto(), "peak");
40  peak.SetLineColor(kRed);
41  peak.SetStats(false);
42  peak.Draw();
43  const int offset = pmtCalib.GetMuonPeakHistoOffset();
44  const double lsValue = pmtCalib.GetOnlinePeak() + pmtCalib.GetBaseline() - offset;
45  if (pmt.HasRecData())
46  DrawQuadraticFit(pmt.GetRecData().GetMuonPeakFitData(), peak, lsValue);
47  else
48  DrawQuadraticFit(peak, lsValue);
49  const double peakMax = peak.GetMaximum();
50  DrawBaseline(pmtCalib, peakMax);
51  DrawOffset(offset, peakMax);
52  IsNotOK(pmt);
53 }
54 
55 
56 void
57 MuonChargeView::Draw(const sdet::Station& dStation, const sevt::Station& sStation, const PMT& pmt, const int pmtId)
58 {
59  if (HasNoCalib(pmt))
60  return;
61  ostringstream os;
62  os << "MuCharge PMT" << pmtId;
63  const auto& chargeBinning = dStation.GetMuonChargeHistogramBinning<double>(pmt.GetType(), sStation.GetCalibData().GetVersion());
64  const auto& pmtCalib = pmt.GetCalibData();
65  auto& charge = Add(new TH1D(os.str().c_str(), os.str().c_str(), chargeBinning.size()-1, &chargeBinning[0]));
66  SetContent(charge, chargeBinning, pmtCalib.GetMuonChargeHisto(), "charge");
67  charge.SetLineColor(kRed);
68  charge.SetStats(false);
69  charge.Draw();
70  const int offset = pmtCalib.GetMuonChargeHistoOffset();
71  const int baseFact = pmtCalib.GetMuonShapeHisto().size();
72  const double lsValue = pmtCalib.GetOnlineCharge()*1.045 + pmtCalib.GetBaseline() * baseFact - offset;
73  // ^^^^^ hump magic
74  if (pmt.HasRecData()) {
75  DrawQuadraticFit(pmt.GetRecData().GetMuonChargeFitData(), charge, lsValue);
76  DrawExponentialFit(charge, pmt.GetRecData().GetMuonChargeSlopeFitData());
77  } else
78  DrawQuadraticFit(charge, lsValue);
79  const double chargeMax = charge.GetMaximum();
80  DrawBaseline(pmtCalib, chargeMax);
81  DrawOffset(double(offset) / baseFact, chargeMax);
82  IsNotOK(pmt);
83 }
84 
85 
86 void
87 MuonShapeView::Draw(const sdet::Station& dStation, const PMT& pmt, const int pmtId, const int calibVersion)
88 {
89  if (HasNoCalib(pmt))
90  return;
91  gPad->SetLogy();
92  ostringstream os;
93  os << "MuShape PMT" << pmtId;
94  const auto& shapeBinning = dStation.GetMuonShapeHistogramBinning(calibVersion);
95  auto& shape = Add(new TH1D(os.str().c_str(), os.str().c_str(), shapeBinning.size()-1, &shapeBinning[0]));
96  const auto& pmtCalib = pmt.GetCalibData();
97  SetContent(shape, shapeBinning, pmtCalib.GetMuonShapeHisto(), "shape", 0);
98  shape.SetLineColor(kRed);
99  shape.SetStats(false);
100  shape.Draw();
101  if (pmt.HasRecData()) {
102  const auto& pmtRec = pmt.GetRecData();
103  DrawExponentialFit(shape, pmtRec.GetMuonShapeFitData());
104  DrawDecay(pmtRec.GetMuonPulseDecayTime());
105  }
106  IsNotOK(pmt);
107 }
108 
109 
110 void
111 PMTBaselineView::Draw(const sdet::Station& dStation, const PMT& pmt, const int pmtId)
112 {
113  if (HasNoCalib(pmt))
114  return;
115  gPad->SetLogy();
116  ostringstream os;
117  os << "MuBase PMT" << pmtId;
118  const auto& baseBinning = dStation.GetBaselineHistogramBinning<double>();
119  auto& base = Add(new TH1D(os.str().c_str(), os.str().c_str(), baseBinning.size()-1, &baseBinning[0]));
120  const auto& pmtCalib = pmt.GetCalibData();
121  SetContent(base, baseBinning, pmtCalib.GetMuonBaseHisto(), "base");
122  base.SetLineColor(kRed);
123  base.SetStats(false);
124  base.Draw();
125  DrawAverage(base);
126  IsNotOK(pmt);
127 }
128 
129 
130 void
131 HistoView::DividePage(TCanvas& c, const double xmargin, const double ymargin)
132 {
133  const auto savePad = (TPad*)gPad;
134  c.cd();
135  const string name = c.GetName();
136  ostringstream os;
137  const int nRows = 6;
138  int n = 1;
139  for (int row = 0; row < nRows; ++row) {
140  const double y1 = 1 - (row+1)*(1 - ymargin)/nRows;
141  const double y2 = 1 - ymargin - row*(1 - ymargin)/nRows;
142  const int nColumns = (row ? (row < 4 ? 2 : 3) : 1);
143  for (int column = 0; column < nColumns; ++column) {
144  const double x1 = xmargin + column*(1 - xmargin)/nColumns;
145  const double x2 = (column+1)*(1 - xmargin)/nColumns;
146  os.str(""); os << name << '_' << row+1 << column+1;
147  const auto pad = new TPad(os.str().c_str(), os.str().c_str(), x1, y1, x2, y2, 0);
148  pad->SetNumber(n++);
149  pad->Draw();
150  }
151  }
152  savePad->cd();
153 }
154 
155 
156 bool
157 HistoView::HasNoCalib(const PMT& pmt)
158 {
159  if (!pmt.HasCalibData()) {
160  auto& pt = Add(new TPaveText(0.3,0.4,0.7,0.6, "ndc"));
161  pt.SetBorderSize(2);
162  pt.SetFillColor(kRed);
163  pt.SetTextAlign(12);
164  pt.AddText("No Calibration Data");
165  pt.Draw();
166  return true;
167  }
168  return false;
169 }
170 
171 
172 bool
173 HistoView::IsNotOK(const PMT& pmt)
174 {
175  if (!pmt.GetCalibData().IsTubeOk()) {
176  auto& pt = Add(new TPaveText(0.5,0.43,0.8,0.57, "ndc"));
177  pt.SetBorderSize(2);
178  pt.SetFillColor(kRed);
179  pt.SetTextAlign(12);
180  pt.AddText("Tube not OK");
181  pt.Draw();
182  return true;
183  }
184  return false;
185 }
186 
187 
188 void
189 HistoView::SetContent(TH1D& rh,
190  const vector<double>& bins, const vector<int>& hist,
191  const string& what,
192  const int subtractBin)
193  const
194 {
195  if (bins.size()-1 != hist.size()) {
196  ostringstream warn;
197  warn << "Mismatch in PMT " << what << " histogram: " << bins.size()-1 << " bin intervals "
198  "but " << hist.size() << " values!";
199  WARNING(warn);
200  return;
201  }
202 
203  const VariableBinHistogramWrap<double, int> h(bins, hist);
204  const double sub = (subtractBin >= 0 ? h.GetBinAverage(subtractBin) : 0);
205  const int n = h.GetNBins();
206  for (int i = 0; i < n; ++i) {
207  const double val = h.GetBinAverage(i) - sub;
208  rh.SetBinContent(i+1, (val > 0 ? val : 0));
209  }
210 }
211 
212 
213 void
214 HistoView::DrawQuadraticFit(const QuadraticFitData& qf, TH1D& hist,
215  const double lsValue)
216 {
217  const string parabolaName = string(hist.GetName()) + "_parabola";
218  auto& par = Add(new TF1(parabolaName.c_str(),
219  [&qf](double* x, double*) { return qf(*x); }, qf.GetStart(), qf.GetStop(), 0));
220  par.SetLineWidth(1);
221  par.SetLineColor(kBlue);
222  par.Draw("same");
223  const double x = qf.GetExtremePosition();
224  const double yext = qf(x);
225  const double y = 1.15 * yext;
226  const double dx = qf.GetExtremePositionError();
227  // fit value with errorbar
228  auto& gfit = Add(new TGraphErrors(1, &x, &y, &dx, 0));
229  gfit.SetLineColor(kBlue);
230  gfit.SetMarkerStyle(kFullCircle);
231  gfit.SetMarkerColor(kBlue);
232  gfit.SetMarkerSize(0.5);
233  gfit.Draw("p same");
234  const double yy = 1.1 * y;
235  const double histMax = hist.GetMaximum();
236  if (yy > histMax)
237  hist.SetMaximum(yy);
238  DrawQuadraticFit(hist, lsValue, y);
239 }
240 
241 
242 void
243 HistoView::DrawQuadraticFit(TH1D& hist, const double lsValue, const double fitValue)
244 {
245  const double hMax = hist.GetMaximum();
246  const double hValue = hist.GetBinContent(hist.FindBin(lsValue));
247  const bool up = (hValue > 0.5*hMax);
248  const double y2 = up ? 0.82*hValue : max(hValue + 0.15*hMax, 1.15*fitValue);
249  const double y1 = up ? 0.5*y2 : y2 + 0.5*(hMax-y2);
250  // ls reported value
251  auto& als = Add(new TArrow(lsValue, y1, lsValue, y2, 0.01));
252  als.SetAngle(20);
253  als.SetLineColor(8);
254  als.Draw();
255 }
256 
257 
258 void
259 HistoView::DrawExponentialFit(TH1D& hist, const ExponentialFitData& ef)
260 {
261  const string exponentialName = string(hist.GetName()) + "_exponential";
262  auto& ex = Add(new TF1(exponentialName.c_str(),
263  [&ef](double* x, double*) { return ef(*x); }, ef.GetStart(), ef.GetStop(), 0));
264  ex.SetParameter(0, ef.GetAmplitude());
265  ex.SetParameter(1, ef.GetSlope());
266  ex.SetLineWidth(1);
267  ex.SetLineColor(kBlue);
268  ex.Draw("same");
269 }
270 
271 
272 void
273 HistoView::DrawBaseline(const PMTCalibData& pmtCalib, const double max)
274 {
275  const double x = pmtCalib.GetBaseline();
276  const double y = 0.19*max;
277  const double dx = pmtCalib.GetBaselineRMS();
278  auto& g = Add(new TGraphErrors(1, &x, &y, &dx, 0));
279  g.SetLineColor(46);
280  g.SetMarkerColor(46);
281  g.Draw("same");
282 }
283 
284 
285 void
286 HistoView::DrawOffset(const double x, const double max)
287 {
288  const double y = 0.15*max;
289  auto& a = Add(new TArrow(x, y, x, 0, 0.01));
290  a.SetAngle(20);
291  a.SetLineColor(kBlack);
292  a.Draw();
293 }
294 
295 
296 void
297 HistoView::DrawAverage(TH1D& h)
298 {
299  const double x = h.GetMean();
300  const double dx = sqrt(Sqr(h.GetMeanError()) + Sqr(h.GetBinWidth(1))/12);
301  const double y = 0.01*h.GetMaximum();
302  auto& g = Add(new TGraphErrors(1, &x, &y, &dx, &y));
303  g.SetLineColor(kBlack);
304  g.SetMarkerColor(kBlack);
305  g.DrawClone("same");
306  const double y2 = 0.1*y;
307  const double dx2 = h.GetRMS();
308  auto& g2 = Add(new TGraphErrors(1, &x, &y2, &dx2, 0));
309  g2.SetLineColor(kBlack);
310  g2.SetMarkerColor(kBlack);
311  g2.Draw("same");
312 }
313 
314 
315 void
316 HistoView::DrawDecay(const double time)
317 {
318  ostringstream os;
319  os << "#tau = " << setprecision(4) << time/nanosecond << " ns";
320  auto& pt = Add(new TPaveText(0.58,0.77,0.87,0.85, "ndc"));
321  pt.SetBorderSize(1);
322  pt.SetFillColor(kWhite);
323  pt.SetTextAlign(22);
324  pt.AddText(os.str().c_str());
325  pt.Draw();
326 }
bool HasRecData() const
Check for existenc of PMT reconstructed data object.
Definition: SEvent/PMT.h:53
constexpr T Sqr(const T &x)
Holds result of the quadratic fit.
class to hold data at PMT level
Definition: SEvent/PMT.h:28
double GetBaselineRMS(const sdet::PMTConstants::PMTGain gain=sdet::PMTConstants::eHighGain) const
Definition: PMTCalibData.h:44
Detector description interface for Station-related data.
bool IsTubeOk() const
Definition: PMTCalibData.h:29
PMTCalibData & GetCalibData()
Get object containing PMT calibration data.
Definition: SEvent/PMT.h:56
sdet::PMTConstants::PMTType GetType() const
Definition: SEvent/PMT.h:35
double GetExtremePositionError() const
int GetMuonPeakHistoOffset() const
x-axis offset of the muon peak histogram
Definition: PMTCalibData.h:66
PMTRecData & GetRecData()
Get object containing PMT reconstructed data.
Definition: SEvent/PMT.h:48
bool HasCalibData() const
Check for existence of PMT calibration data object.
Definition: SEvent/PMT.h:61
utl::ExponentialFitData & GetMuonChargeSlopeFitData()
Definition: PMTRecData.h:155
double GetAmplitude() const
double GetStart() const
#define max(a, b)
class to hold data at Station level
utl::QuadraticFitData & GetMuonChargeFitData()
Definition: PMTRecData.h:152
utl::QuadraticFitData & GetMuonPeakFitData()
Definition: PMTRecData.h:149
double GetStop() const
constexpr double nanosecond
Definition: AugerUnits.h:143
const std::vector< double > & GetMuonShapeHistogramBinning(const int calibrationVersion) const
Online Calibration data.
Definition: PMTCalibData.h:27
constexpr double g
Definition: AugerUnits.h:200
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
sevt::StationCalibData & GetCalibData()
Get calibration data for the station.
double GetBaseline(const sdet::PMTConstants::PMTGain gain=sdet::PMTConstants::eHighGain) const
Definition: PMTCalibData.h:41
double GetExtremePosition() const
int GetVersion() const
version of the onboard calibration

, generated on Tue Sep 26 2023.