11#include "TPaveLabel.h"
19 std::cerr <<
m_className <<
"::SetSensor: Null pointer.\n";
26 if (fabs(xmax - xmin) < Small) {
27 std::cerr <<
m_className <<
"::SetRangeX: Invalid range.\n";
30 m_xmin = std::min(xmin, xmax);
31 m_xmax = std::max(xmin, xmax);
36 if (fabs(ymax - ymin) < Small) {
37 std::cerr <<
m_className <<
"::SetRangeY: Invalid range.\n";
40 m_ymin = std::min(ymin, ymax);
41 m_ymax = std::max(ymin, ymax);
46 const bool electron,
const bool ion,
47 const bool delayed,
const bool same) {
49 std::cerr <<
m_className <<
"::PlotSignal: Sensor is not defined.\n";
55 canvas->SetTitle(
"Signal");
57 unsigned int nBins = 100;
58 double t0 = 0., dt = 1.;
60 const double t1 = t0 + nBins * dt;
62 std::string xlabel =
"time [ns]";
63 std::string ylabel = m_labelY;
65 ylabel = m_sensor->
IsIntegrated(label) ?
"signal [fC]" :
"signal [fC / ns]";
67 unsigned int nPlots = same ? 1 : 0;
70 m_hSignal.reset(
new TH1D(hname.c_str(),
"", nBins, t0, t1));
71 m_hSignal->SetLineColor(m_colTotal);
72 m_hSignal->GetXaxis()->SetTitle(xlabel.c_str());
73 m_hSignal->GetYaxis()->SetTitle(ylabel.c_str());
74 m_hSignal->SetStats(0);
75 for (
unsigned int i = 0; i < nBins; ++i) {
76 const double sig = m_sensor->
GetSignal(label, i);
77 m_hSignal->SetBinContent(i + 1, sig);
79 const std::string opt = nPlots > 0 ?
"same" :
"";
80 m_hSignal->DrawCopy(opt.c_str());
82 if (m_userRangeX) m_hSignal->SetAxisRange(m_xmin, m_xmax,
"X");
83 if (m_userRangeY) m_hSignal->SetAxisRange(m_ymin, m_ymax,
"Y");
89 gCrossings.SetMarkerStyle(20);
90 gCrossings.SetMarkerColor(m_colTotal);
91 std::vector<double> xp;
92 std::vector<double> yp;
93 double time = 0., level = 0.;
95 for (
unsigned int i = 0; i < nCrossings; ++i) {
101 gCrossings.DrawGraph(xp.size(), xp.data(), yp.data(),
"psame");
106 m_hDelayedSignal.reset(
new TH1D(hnamed.c_str(),
"", nBins, t0, t1));
107 m_hDelayedSignal->SetLineColor(m_colDelayed[0]);
108 m_hDelayedSignal->SetLineStyle(2);
109 m_hDelayedSignal->SetStats(0);
110 for (
unsigned int i = 0; i < nBins; ++i) {
113 m_hDelayedSignal->SetBinContent(i + 1, sig);
115 m_hDelayedSignal->DrawCopy(
"same");
123 m_hSignalElectrons.reset(
new TH1D(hname.c_str(),
"", nBins, t0, t1));
124 m_hSignalElectrons->SetLineColor(m_colElectrons);
125 m_hSignalElectrons->GetXaxis()->SetTitle(xlabel.c_str());
126 m_hSignalElectrons->GetYaxis()->SetTitle(ylabel.c_str());
127 m_hSignalElectrons->SetStats(0);
128 for (
unsigned int i = 0; i < nBins; ++i) {
130 m_hSignalElectrons->SetBinContent(i + 1, sig);
132 const std::string opt = nPlots > 0 ?
"same" :
"";
133 m_hSignalElectrons->DrawCopy(opt.c_str());
136 if (m_userRangeX) m_hSignalElectrons->SetAxisRange(m_xmin, m_xmax,
"X");
137 if (m_userRangeY) m_hSignalElectrons->SetAxisRange(m_ymin, m_ymax,
"Y");
141 m_hDelayedSignalElectrons.reset(
new TH1D(hnamed.c_str(),
"", nBins, t0, t1));
142 m_hDelayedSignalElectrons->SetLineColor(m_colDelayed[1]);
143 m_hDelayedSignalElectrons->SetLineStyle(2);
144 m_hDelayedSignalElectrons->SetStats(0);
145 for (
unsigned int i = 0; i < nBins; ++i) {
147 m_hDelayedSignalElectrons->SetBinContent(i + 1, sig);
149 m_hDelayedSignalElectrons->DrawCopy(
"same");
155 m_hSignalIons.reset(
new TH1D(hname.c_str(),
"", nBins, t0, t1));
156 m_hSignalIons->SetLineColor(m_colIons);
157 m_hSignalIons->GetXaxis()->SetTitle(xlabel.c_str());
158 m_hSignalIons->GetYaxis()->SetTitle(ylabel.c_str());
159 m_hSignalIons->SetStats(0);
160 for (
unsigned int i = 0; i < nBins; ++i) {
162 m_hSignalIons->SetBinContent(i + 1, sig);
164 const std::string opt = nPlots > 0 ?
"same" :
"";
165 m_hSignalIons->DrawCopy(opt.c_str());
167 if (!(total || electron)) {
168 if (m_userRangeX) m_hSignalIons->SetAxisRange(m_xmin, m_xmax,
"X");
169 if (m_userRangeY) m_hSignalIons->SetAxisRange(m_ymin, m_ymax,
"Y");
173 m_hDelayedSignalIons.reset(
new TH1D(hnamed.c_str(),
"", nBins, t0, t1));
174 m_hDelayedSignalIons->SetLineColor(m_colDelayed[2]);
175 m_hDelayedSignalIons->SetLineStyle(2);
176 m_hDelayedSignalIons->SetStats(0);
177 for (
unsigned int i = 0; i < nBins; ++i) {
179 m_hDelayedSignalIons->SetBinContent(i + 1, sig);
181 m_hDelayedSignalIons->DrawCopy(
"same");
188 const bool total,
const bool delayed,
const bool same) {
193 std::cerr <<
m_className <<
"::PlotSignal: Sensor is not defined.\n";
196 const double pres = 1e-50;
200 canvas->SetTitle(
"Signal");
202 unsigned int nBins = 100;
203 double t0 = 0., dt = 1.;
205 const double t1 = t0 + nBins * dt;
207 std::string xlabel =
"time [ns]";
208 std::string ylabel = m_labelY;
209 if (ylabel.empty()) {
210 ylabel = getsignal ?
"signal [fC / ns]" :
"charge [fC]";
214 unsigned int nPlots = same ? 1 : 0;
218 m_hSignal.reset(
new TH1D(hname.c_str(),
"", nBins, t0, t1));
219 m_hSignal->SetLineColor(m_colTotal);
221 m_hSignal->GetXaxis()->SetTitle(xlabel.c_str());
222 m_hSignal->GetYaxis()->SetTitle(ylabel.c_str());
223 m_hSignal->SetStats(0);
225 for (
unsigned int i = 0; i < nBins; ++i) {
226 const double sig = m_sensor->
GetSignal(label, i, 0);
227 if(!std::isnan(sig) && std::abs(sig) < pres) {
228 m_hSignal->SetBinContent(i + 1, 0.);
230 m_hSignal->SetBinContent(i + 1, sig);
233 m_hSignal->SetLineWidth(6);
234 const std::string opt = nPlots > 0 ?
"same" :
"";
235 m_hSignal->DrawCopy(opt.c_str());
237 if (m_userRangeX) m_hSignal->SetAxisRange(m_xmin, m_xmax,
"X");
238 if (m_userRangeY) m_hSignal->SetAxisRange(m_ymin, m_ymax,
"Y");
241 if (nCrossings > 0) {
243 gCrossings.SetMarkerStyle(20);
244 gCrossings.SetMarkerColor(m_colTotal);
245 std::vector<double> xp;
246 std::vector<double> yp;
247 double time = 0., level = 0.;
249 for (
unsigned int i = 0; i < nCrossings; ++i) {
255 gCrossings.DrawGraph(xp.size(), xp.data(), yp.data(),
"psame");
260 m_hDelayedSignal.reset(
new TH1D(hnamed.c_str(),
"", nBins, t0, t1));
261 m_hDelayedSignal->SetLineColor(m_colDelayed[0]);
262 m_hDelayedSignal->SetLineStyle(2);
263 m_hDelayedSignal->SetStats(0);
264 for (
unsigned int i = 0; i < nBins; ++i) {
265 const double sig = m_sensor->
GetSignal(label, i, 2);
266 if (!std::isnan(sig) && std::abs(sig) < pres) {
267 m_hDelayedSignal->SetBinContent(i + 1, 0.);
269 m_hDelayedSignal->SetBinContent(i + 1, sig);
272 m_hDelayedSignal->SetFillStyle(3001);
273 m_hDelayedSignal->SetFillColor(m_colDelayed[0]);
277 m_hPromptSignal.reset(
new TH1D(dnamed.c_str(),
"", nBins, t0, t1));
278 m_hPromptSignal->SetLineColor(m_colDelayed[2]);
279 m_hPromptSignal->SetLineStyle(2);
280 m_hPromptSignal->SetStats(0);
281 for (
unsigned int i = 0; i < nBins; ++i) {
282 const double sig = m_sensor->
GetSignal(label, i, 1);
283 if (!std::isnan(sig) && std::abs(sig) < pres) {
284 m_hPromptSignal->SetBinContent(i + 1, 0.);
286 m_hPromptSignal->SetBinContent(i + 1, sig);
289 m_hPromptSignal->SetFillStyle(3001);
290 m_hPromptSignal->SetFillColor(m_colDelayed[2]);
291 m_hPromptSignal->DrawCopy(
"same");
292 if (delayed) m_hDelayedSignal->DrawCopy(
"same");
294 TPaveLabel *label1 =
new TPaveLabel(-3.5, 700, -1, 800,
"Default option");
297 TH1D *g0 =
new TH1D(
"g0",
"g0", nBins, 0, 1);
298 g0->SetFillColor(m_colTotal);
299 TH1D *g1 =
new TH1D(
"g1",
"g1", nBins, 0, 1);
300 g1->SetFillStyle(3001);
301 g1->SetFillColor(m_colDelayed[0]);
303 TH1D *g2 =
new TH1D(
"g2",
"g2", nBins, 0, 1);
304 g2->SetFillStyle(3001);
305 g2->SetFillColor(m_colDelayed[2]);
307 TLegend *leg =
new TLegend(0.7, 0.7, 0.9, 0.9);
309 leg->SetHeader(
"Induced charge as a function of time");
310 leg->AddEntry(g0,
"Total induced charge",
"f");
311 leg->AddEntry(g2,
"Prompt induced charge",
"f");
312 if (delayed) leg->AddEntry(g1,
"Delayed induced charge",
"f");
315 leg->SetHeader(
"Induced current as a function of time");
316 leg->AddEntry(g0,
"Total induced current",
"f");
317 leg->AddEntry(g2,
"Prompt induced current",
"f");
318 if (delayed) leg->AddEntry(g1,
"Delayed induced current",
"f");
324 if (delayed)
delete g1;
double GetElectronSignal(const std::string &label, const unsigned int bin)
Retrieve the electron signal for a given electrode and time bin.
double GetDelayedIonSignal(const std::string &label, const unsigned int bin)
Retrieve the delayed ion/hole signal for a given electrode and time bin.
void GetTimeWindow(double &tstart, double &tstep, unsigned int &nsteps) const
Retrieve the time window and binning.
bool IntegrateSignal(const std::string &label)
Replace the signal on a given electrode by its integral.
double GetSignal(const std::string &label, const unsigned int bin)
Retrieve the total signal for a given electrode and time bin.
bool GetThresholdCrossing(const unsigned int i, double &time, double &level, bool &rise) const
size_t GetNumberOfThresholdCrossings() const
double GetDelayedElectronSignal(const std::string &label, const unsigned int bin)
Retrieve the delayed electron signal for a given electrode and time bin.
double GetIonSignal(const std::string &label, const unsigned int bin)
Retrieve the ion or hole signal for a given electrode and time bin.
bool IsIntegrated(const std::string &label) const
Return whether the signal has been integrated/convoluted.
Base class for visualization classes.
static std::string FindUnusedHistogramName(const std::string &s)
Find an unused histogram name.
TPad * GetCanvas()
Retrieve the canvas.
void SetSensor(Sensor *s)
Set the sensor from which to retrieve the signal.
void SetRangeY(const double ymin, const double ymax)
Set the y-axis limits explicitly.
void SetRangeX(const double xmin, const double xmax)
Set the x-axis limits explicitly.
void PlotSignal(const std::string &label, const bool total=true, const bool electron=false, const bool ion=false, const bool delayed=false, const bool same=false)
void Plot(const std::string &label, const bool getsignal, const bool total=true, const bool delayed=true, const bool same=false)