16#include <TGraphErrors.h>
20#include <fmt/format.h>
28double CrystalBallSymmetric(
double* xx,
double* par)
38 double tp = fabs((xx[0] - par[1]) / par[2]);
40 double absAlpha = fabs(par[3]);
41 double ap = pow(par[4] / absAlpha, par[4]) *
exp(-0.5 * absAlpha * absAlpha);
42 double bp = par[4] / absAlpha - absAlpha;
45 return par[0] * (
exp(-0.5 * tp * tp));
47 return par[0] * (ap / pow(bp + tp, par[4]));
51std::pair<double, double> GetSigma(TH1*
h,
int color)
54 gStyle->SetOptFit(100);
56 static TF1* fCrystalBall =
new TF1(
"CrystalBall", CrystalBallSymmetric, -2., 2., 5);
57 fCrystalBall->SetLineColor(
color);
59 if (
h->GetEntries() < 10.) {
60 return std::make_pair(0., 0.);
63 double sigmaTrk = 0.2;
64 double sigmaTrkCut = 4.;
67 double xMin = -0.5 * sigmaTrkCut * sigmaTrk;
68 double xMax = 0.5 * sigmaTrkCut * sigmaTrk;
69 fCrystalBall->SetRange(xMin, xMax);
70 fCrystalBall->SetParameters(
h->GetEntries(), 0., 0.1, 2., 1.5);
71 fCrystalBall->SetParLimits(1, xMin, xMax);
72 fCrystalBall->SetParLimits(2, 0., 1.);
73 fCrystalBall->FixParameter(3, 1.e6);
74 h->Fit(fCrystalBall,
"RNQ");
81 fCrystalBall->SetParameter(0, fCrystalBall->GetParameter(0) * rebin);
82 fCrystalBall->ReleaseParameter(3);
83 fCrystalBall->SetParameter(3, 2.);
84 fCrystalBall->SetParameter(4, 1.5);
85 h->Fit(fCrystalBall,
"RQ");
87 return std::make_pair(fCrystalBall->GetParameter(2), fCrystalBall->GetParError(2));
98 int nPadsx(1), nPadsy(1);
99 while ((
int)histos.size() > nPadsx * nPadsy) {
100 if (nPadsx == nPadsy) {
106 return std::make_pair(nPadsx, nPadsy);
110 const std::vector<TH1*>& histos,
111 int* nPadsx,
int* nPadsy)
120 TCanvas*
c =
new TCanvas(
name, title, 10, 10, TMath::Max(nx * 300, 1200), TMath::Max(ny * 300, 900));
128 gStyle->SetOptStat(111111);
129 int nPadsx = (histos.size() + 2) / 3;
131 c =
new TCanvas(
"residuals",
"residuals", 10, 10, nPadsx * 300, 900);
133 c->Divide(nPadsx, 3);
135 for (
const auto&
h : histos) {
136 c->cd((
i % 3) * nPadsx +
i / 3 + 1);
137 if (
dynamic_cast<TH1F*
>(
h) ==
nullptr) {
162 gStyle->SetOptStat(1);
163 int nPadsx = (histos.size() + 1) / 2;
165 c =
new TCanvas(Form(
"residual%s", extension), Form(
"residual%s", extension), 10, 10, nPadsx * 300, 600);
167 c->Divide(nPadsx, 2);
169 for (
const auto&
h : histos) {
170 c->cd((
i % 2) * nPadsx +
i / 2 + 1);
173 h->GetXaxis()->SetRangeUser(-0.02, 0.02);
180 const std::vector<TH1*>& histos2,
const char* extension,
184 gStyle->SetOptStat(1);
185 int color[2] = {4, 2};
186 int nPadsx = (histos1.size() + 1) / 2;
188 c =
new TCanvas(Form(
"residual%s", extension), Form(
"residual%s", extension), 10, 10, nPadsx * 300, 600);
190 c->Divide(nPadsx, 2);
192 for (
const auto&
h : histos1) {
193 c->cd((
i % 2) * nPadsx +
i / 2 + 1);
195 h->SetLineColor(
color[0]);
197 histos2[
i]->SetLineColor(
color[1]);
198 histos2[
i]->Draw(
"sames");
202 TLegend* lHist =
new TLegend(0.2, 0.65, 0.4, 0.8);
203 lHist->SetFillStyle(0);
204 lHist->SetBorderSize(0);
205 lHist->AddEntry(histos1[0],
"file 1",
"l");
206 lHist->AddEntry(histos2[0],
"file 2",
"l");
212 const std::vector<TH1*>& histos2,
const char* extension,
213 TCanvas*
c1, TCanvas*
c2)
216 gStyle->SetOptStat(1);
218 TGraphErrors*
g[2][2] = {
nullptr};
219 const char* dir[2] = {
"X",
"Y"};
220 int color[2] = {4, 2};
221 for (
int i = 0;
i < 2; ++
i) {
222 for (
int j = 0;
j < 2; ++
j) {
223 g[
i][
j] =
new TGraphErrors(6);
224 g[
i][
j]->SetName(Form(
"sigma%s%s%d", dir[
i], extension,
j));
225 g[
i][
j]->SetTitle(Form(
"#sigma%s per station;station ID;#sigma%s (cm)", dir[
i], dir[
i]));
226 g[
i][
j]->SetMarkerStyle(kFullDotLarge);
232 int nPadsx = (histos1.size() + 1) / 2;
234 c1 =
new TCanvas(Form(
"residual%sFit", extension), Form(
"residual%sFit", extension), 10, 10, nPadsx * 300, 600);
236 c1->Divide(nPadsx, 2);
238 double ymax[2] = {0., 0.};
239 double ymin[2] = {std::numeric_limits<double>::max(), std::numeric_limits<double>::max()};
240 for (
auto h : histos1) {
241 c1->cd((
i % 2) * nPadsx +
i / 2 + 1);
243 auto h1 =
static_cast<TH1*
>(
h->Clone());
244 h1->SetLineColor(
color[0]);
246 auto res1 = GetSigma(h1,
color[0]);
247 g[
i % 2][0]->SetPoint(
i / 2,
i * 1. / 2 + 1., res1.first);
248 g[
i % 2][0]->SetPointError(
i / 2, 0., res1.second);
249 ymin[
i % 2] = std::min(ymin[
i % 2], res1.first - res1.second - 0.001);
250 ymax[
i % 2] = std::max(ymax[
i % 2], res1.first + res1.second + 0.001);
251 auto h2 =
static_cast<TH1*
>(histos2[
i]->Clone());
252 h2->SetLineColor(
color[1]);
254 auto res2 = GetSigma(h2,
color[1]);
255 g[
i % 2][1]->SetPoint(
i / 2,
i * 1. / 2 + 1., res2.first);
256 g[
i % 2][1]->SetPointError(
i / 2, 0., res2.second);
257 ymin[
i % 2] = std::min(ymin[
i % 2], res2.first - res2.second - 0.001);
258 ymax[
i % 2] = std::max(ymax[
i % 2], res2.first + res2.second + 0.001);
259 printf(
"%s: %f ± %f cm --> %f ± %f cm\n",
h->GetName(), res1.first, res1.second, res2.first, res2.second);
264 c2 =
new TCanvas(Form(
"sigma%s", extension), Form(
"sigma%s", extension), 10, 10, 600, 300);
269 g[0][0]->GetYaxis()->SetRangeUser(ymin[0], ymax[0]);
273 g[1][0]->GetYaxis()->SetRangeUser(ymin[1], ymax[1]);
277 TLegend* lHist =
new TLegend(0.2, 0.65, 0.4, 0.8);
278 lHist->SetFillStyle(0);
279 lHist->SetBorderSize(0);
280 lHist->AddEntry(histos1[0],
"file 1",
"l");
281 lHist->AddEntry(histos2[0],
"file 2",
"l");
292 for (
int i = 0;
i < (
int)histos[0].
size(); ++
i) {
295 histos[0][
i]->SetStats(
false);
296 histos[0][
i]->SetLineColor(4);
297 histos[0][
i]->Draw();
298 histos[1][
i]->SetLineColor(2);
299 histos[1][
i]->Draw(
"same");
303 TLegend* lHist =
new TLegend(0.5, 0.65, 0.9, 0.8);
304 lHist->SetFillStyle(0);
305 lHist->SetBorderSize(0);
306 lHist->AddEntry(histos[0][0], Form(
"%g tracks in file 1", histos[0][0]->GetEntries()),
"l");
307 lHist->AddEntry(histos[1][0], Form(
"%g tracks in file 2", histos[1][0]->GetEntries()),
"l");
315 c =
autoCanvas(
"differences",
"histos2 - histos1", histos[0]);
319 for (
int i = 0;
i < (
int)histos[0].
size(); ++
i) {
321 TH1F* hDiff =
static_cast<TH1F*
>(histos[1][
i]->Clone());
322 hDiff->Add(histos[0][
i], -1.);
323 hDiff->SetStats(
false);
324 hDiff->SetLineColor(2);
330 const std::vector<TH1*>& histos2,
331 const char* extension,
336 int nPadsx = (histos1.size() + 1) / 2;
338 c =
new TCanvas(Form(
"ratio%s", extension), Form(
"ratio%s", extension), 10, 10, nPadsx * 300, 600);
340 c->Divide(nPadsx, 2);
342 for (
const auto&
h : histos2) {
343 c->cd((
i % 2) * nPadsx +
i / 2 + 1);
344 TH1* hRat =
new TH1F(*
static_cast<TH1F*
>(
h));
346 auto h1 =
static_cast<TH1F*
>(histos1[
i]->Clone());
350 hRat->SetStats(
false);
351 hRat->SetLineColor(2);
353 hRat->GetXaxis()->SetRangeUser(-0.5, 0.5);
362 c =
autoCanvas(
"ratios",
"histos2 / histos1", histos[0]);
365 for (
int i = 0;
i < (
int)histos[0].
size(); ++
i) {
367 TH1F* hRat =
static_cast<TH1F*
>(histos[1][
i]->Clone());
368 hRat->Divide(histos[0][
i]);
369 hRat->SetStats(
false);
370 hRat->SetLineColor(2);
390 c =
autoCanvas(
"comparisons",
"comparisons", histos[0]);
392 for (
int i = 0;
i < (
int)histos[0].
size(); ++
i) {
395 histos[0][
i]->SetStats(
false);
396 histos[0][
i]->SetLineColor(1);
397 histos[0][
i]->SetMinimum(0.5);
398 histos[0][
i]->Draw();
399 histos[1][
i]->SetLineColor(4);
400 histos[1][
i]->Draw(
"same");
401 histos[2][
i]->SetLineColor(877);
402 histos[2][
i]->Draw(
"same");
403 histos[3][
i]->SetLineColor(3);
404 histos[3][
i]->Draw(
"same");
405 histos[4][
i]->SetLineColor(2);
406 histos[4][
i]->Draw(
"same");
410 TLegend* lHist =
new TLegend(0.5, 0.5, 0.9, 0.8);
411 lHist->SetFillStyle(0);
412 lHist->SetBorderSize(0);
413 lHist->AddEntry(histos[0][0], Form(
"%g tracks identical", histos[0][0]->GetEntries()),
"l");
414 lHist->AddEntry(histos[1][0], Form(
"%g tracks similar (1)", histos[1][0]->GetEntries()),
"l");
415 lHist->AddEntry(histos[2][0], Form(
"%g tracks similar (2)", histos[2][0]->GetEntries()),
"l");
416 lHist->AddEntry(histos[3][0], Form(
"%g tracks additional", histos[3][0]->GetEntries()),
"l");
417 lHist->AddEntry(histos[4][0], Form(
"%g tracks missing", histos[4][0]->GetEntries()),
"l");
428 std::vector<TH1*>* trackResidualsAtFirstCluster =
reinterpret_cast<std::vector<TH1*>*
>(
f->GetObjectUnchecked(
"trackResidualsAtFirstCluster"));
429 if (trackResidualsAtFirstCluster) {
432 std::cerr <<
"could not read trackResidualsAtFirstCluster vector of histogram from file\n";
435 std::array<std::vector<TH1*>, 5>* clusterResiduals =
reinterpret_cast<std::array<std::vector<TH1*>, 5
>*>(
f->GetObjectUnchecked(
"clusterResiduals"));
438 std::array<std::vector<TH1*>, 2>* histosAtVertex =
reinterpret_cast<std::array<std::vector<TH1*>, 2
>*>(
f->GetObjectUnchecked(
"histosAtVertex"));
441 std::array<std::vector<TH1*>, 5>* comparisonsAtVertex =
reinterpret_cast<std::array<std::vector<TH1*>, 5
>*>(
f->GetObjectUnchecked(
"comparisonsAtVertex"));
uint64_t exp(uint64_t base, uint8_t exp) noexcept
bool const GPUTPCGMMerger::trackCluster * c1
bool const GPUTPCGMMerger::trackCluster const clcomparestruct * c2
Class for time synchronization of RawReader instances.
GLuint const GLchar * name
void drawAll(const char *filename)
void drawPlainHistosAtVertex(const std::array< std::vector< TH1 * >, 2 > &histos, TCanvas *c=nullptr)
void drawClusterTrackResidualsSigma(const std::vector< TH1 * > &histos1, const std::vector< TH1 * > &histos2, const char *extension, TCanvas *c1=nullptr, TCanvas *c2=nullptr)
void drawClusterClusterResiduals(const std::vector< TH1 * > &histos, const char *extension, TCanvas *c=nullptr)
void drawClusterTrackResidualsRatio(const std::vector< TH1 * > &histos1, const std::vector< TH1 * > &histos2, const char *extension, TCanvas *c=nullptr)
auto padGridSize(const std::vector< TH1 * > &histos)
void drawRatioHistosAtVertex(const std::array< std::vector< TH1 * >, 2 > &histos, TCanvas *c=nullptr)
void drawDiffHistosAtVertex(const std::array< std::vector< TH1 * >, 2 > &histos, TCanvas *c=nullptr)
void drawTrackResiduals(std::vector< TH1 * > &histos, TCanvas *c=nullptr)
TCanvas * autoCanvas(const char *title, const char *name, const std::vector< TH1 * > &histos, int *nPadsx=nullptr, int *nPadsy=nullptr)
void drawClusterTrackResiduals(const std::vector< TH1 * > &histos1, const std::vector< TH1 * > &histos2, const char *extension, TCanvas *c=nullptr)
void drawClusterResiduals(const std::array< std::vector< TH1 * >, 5 > &histos, TCanvas *c=nullptr)
void drawComparisonsAtVertex(const std::array< std::vector< TH1 * >, 5 > histos, TCanvas *c=nullptr)
void drawHistosAtVertex(const std::array< std::vector< TH1 * >, 2 > &histos, TCanvas *c=nullptr)