8#include <svd/calibration/SVDClusterTimeShifterAlgorithm.h>
10#include <svd/dbobjects/SVDClusterTimeShifter.h>
19#include "TPaveStats.h"
20#include <framework/logging/Logger.h>
23#include <TFitResult.h>
37 gROOT->SetBatch(
true);
39 gStyle->SetFillColor(0);
40 gStyle->SetFillStyle(0);
41 gStyle->SetOptStat(0);
46 while (gSystem->GetPathInfo(Form(
"algorithm_svdClusterTimeShifter_%s_output_rev_%d.root",
m_timeAlgorithms[0].Data(), cal_rev),
53 TF1* fn_singleGaus =
new TF1(
"fn_singleGaus",
singleGaus, -50., 50., 4);
54 fn_singleGaus->SetLineColor(kGreen + 2);
55 fn_singleGaus->SetParName(0,
"N");
56 fn_singleGaus->SetParName(1,
"#mu");
57 fn_singleGaus->SetParName(2,
"#sigma");
58 fn_singleGaus->SetParName(3,
"C");
61 TF1* fn_doubleGaus =
new TF1(
"fn_doubleGaus",
doubleGaus, -50., 50., 7);
62 fn_doubleGaus->SetLineColor(kRed + 2);
63 fn_doubleGaus->SetParName(0,
"N");
64 fn_doubleGaus->SetParName(1,
"f");
65 fn_doubleGaus->SetParName(2,
"#mu_{1}");
66 fn_doubleGaus->SetParName(3,
"#sigma_{1}");
67 fn_doubleGaus->SetParName(4,
"#mu_{2}");
68 fn_doubleGaus->SetParName(5,
"#sigma_{2}");
69 fn_doubleGaus->SetParName(6,
"C");
70 fn_doubleGaus->SetParLimits(1, 0.01, 0.99);
71 fn_doubleGaus->SetParLimits(3, 0.5, 25.);
72 fn_doubleGaus->SetParLimits(5, 0.5, 25.);
75 auto __hBinToSensorMap__ = getObjectPtr<TH1F>(
"__hBinToSensorMap__");
79 B2INFO(
"Calculating shift for algorithm " << alg);
81 auto __hClusterSizeVsTimeResidual__ = getObjectPtr<TH3F>((
"__hClusterSizeVsTimeResidual__" + alg).Data());
83 int nSensors = __hClusterSizeVsTimeResidual__->GetNbinsZ();
84 int maxClsSize = __hClusterSizeVsTimeResidual__->GetNbinsY();
87 std::map< TString, std::vector<double> > shiftValues;
90 TH2F* hDrawShift =
new TH2F((
"hDrawShift_" + alg).Data(),
91 (
"Cluster time shift in " + alg).Data(),
92 nSensors, +0.5, nSensors + 0.5, maxClsSize, +0.5, maxClsSize + 0.5);
93 hDrawShift->GetZaxis()->SetTitle(
"Cluster Time Shift (in ns)");
94 hDrawShift->GetYaxis()->SetTitle(
"Cluster Size");
95 hDrawShift->GetXaxis()->SetTitle(
"Sensor");
97 std::unique_ptr<TFile> f(
new TFile(Form(
"algorithm_svdClusterTimeShifter_%s_output_rev_%d.root", alg.Data(), cal_rev),
"RECREATE"));
99 TString outPDF = Form(
"algorithm_svdClusterTimeShifter_%s_output_rev_%d.pdf", alg.Data(), cal_rev);
100 TCanvas c1(
"c1",
"c1", 640, 480);
101 c1.Print(outPDF +
"[");
102 TPad onePad(
"onePad",
"onePad", 0, 0, 1, 1, kWhite);
103 onePad.SetFillColor(0);
104 onePad.SetBorderMode(0);
105 onePad.SetBorderSize(2);
106 onePad.SetRightMargin(0.1339713);
107 onePad.SetBottomMargin(0.15);
108 onePad.SetFrameBorderMode(0);
109 onePad.SetFrameBorderMode(0);
113 for (
int ij = 0; ij < nSensors; ij++) {
115 auto binLabel = __hBinToSensorMap__->GetXaxis()->GetBinLabel(ij + 1);
117 int layer_num, sensor_num;
118 std::sscanf(binLabel,
"L%dS%dS%c", &layer_num, &sensor_num, &side);
120 B2INFO(
"Projecting for Sensor: " << binLabel <<
" with Bin Number: " << ij + 1);
122 __hClusterSizeVsTimeResidual__->GetZaxis()->SetRange(ij + 1, ij + 1);
123 TH2D* hClusterSizeVsTimeResidual = (TH2D*)__hClusterSizeVsTimeResidual__->Project3D(
"yxe");
124 hClusterSizeVsTimeResidual->SetName(Form(
"clusterSizeVsTimeResidual__L%dS%dS%c", layer_num, sensor_num, side));
125 char sidePN = (side ==
'U' ?
'P' :
'N');
126 hClusterSizeVsTimeResidual->SetTitle(Form(
"ClusterSize vs Time Residual in L%d.S%d %c/%c", layer_num, sensor_num, side, sidePN));
127 hClusterSizeVsTimeResidual->SetDirectory(0);
129 for (
int clSize = 1; clSize <= maxClsSize; clSize++) {
131 TH1D* hist = (TH1D*)hClusterSizeVsTimeResidual->ProjectionX(
"tmp", clSize, clSize,
"");
132 hist->SetName(Form(
"clusterTimeResidual__L%dS%dS%c_Sz%d", layer_num, sensor_num, side, clSize));
133 hist->SetTitle(Form(
"Cluster Time Residual for Size %d in L%d.S%d %c/%c", clSize, layer_num, sensor_num, side, sidePN));
134 hist->SetDirectory(0);
136 B2INFO(
"Histogram: " << hist->GetName() <<
137 " Entries (n. clusters): " << hist->GetEntries());
139 B2INFO(
"Histogram: " << hist->GetName() <<
140 " Entries (n. clusters): " << hist->GetEntries() <<
142 B2WARNING(
"Not enough data, adding one run to the collector");
144 c1.Print(outPDF +
"]");
146 gSystem->Unlink(Form(
"algorithm_svdClusterTimeShifter_%s_output_rev_%d.root",
m_timeAlgorithms[0].Data(), cal_rev));
154 if (hist->GetMaximum() < 200.) {
155 int rebinValue = 200. / hist->GetMaximum() + 1.;
156 while ((hist->GetNbinsX()) % rebinValue != 0) rebinValue++;
157 hist->Rebin(rebinValue);
161 bool isSingleGausFitValid, isDoubleGausFitValid;
162 while (fitCount++ < 5) {
163 double histMean = hist->GetMean();
164 double histStd = hist->GetStdDev();
165 fn_singleGaus->SetParameter(0, hist->GetSumOfWeights() * hist->GetBinWidth(1));
166 fn_singleGaus->SetParameter(1, histMean);
167 fn_singleGaus->SetParameter(2, histStd * 0.75);
168 fn_singleGaus->SetParameter(3, 1.);
169 fn_singleGaus->SetParLimits(1, histMean - histStd, histMean + histStd);
170 auto singleGausFitStatus = hist->Fit(
"fn_singleGaus",
"SQ",
"",
171 histMean - 2. * histStd, histMean + 2. * histStd);
172 isSingleGausFitValid = singleGausFitStatus->IsValid();
174 fn_doubleGaus->SetParameter(0, hist->GetSumOfWeights() * hist->GetBinWidth(1));
175 fn_doubleGaus->SetParameter(1, 0.95);
176 fn_doubleGaus->SetParameter(2, fn_singleGaus->GetParameter(1));
177 fn_doubleGaus->SetParameter(3, std::fabs(fn_singleGaus->GetParameter(2)));
178 fn_doubleGaus->SetParameter(4, fn_singleGaus->GetParameter(1) - 3.);
179 fn_doubleGaus->SetParameter(5, std::fabs(fn_singleGaus->GetParameter(2)) + 5.);
180 fn_doubleGaus->SetParameter(6, 10.);
181 fn_doubleGaus->SetParLimits(2,
184 fn_doubleGaus->SetParLimits(4,
188 auto doubleGausFitStatus = hist->Fit(
"fn_doubleGaus",
"SQ+");
189 isDoubleGausFitValid = doubleGausFitStatus->IsValid();
190 if (isDoubleGausFitValid)
break;
192 while ((hist->GetNbinsX()) % rebinValue != 0) rebinValue++;
193 hist->Rebin(rebinValue);
196 TPaveStats* ptstats =
new TPaveStats(0.55, 0.73, 0.85, 0.88,
"brNDC");
197 ptstats->SetName(
"stats1");
198 ptstats->SetBorderSize(1);
199 ptstats->SetFillColor(0);
200 ptstats->SetTextAlign(12);
201 ptstats->SetTextFont(42);
202 ptstats->SetTextColor(kGreen + 2);
203 ptstats->SetOptStat(11);
204 ptstats->SetParent(hist);
206 ptstats->AddText(
"Single Gaus");
207 for (
int npar = 0; npar < (fn_singleGaus->GetNpar()); npar++)
208 ptstats->AddText(TString::Format(
"%s = %.3f #pm %.4f",
209 fn_singleGaus->GetParName(npar),
210 fn_singleGaus->GetParameter(npar),
211 fn_singleGaus->GetParError(npar)));
212 ptstats =
new TPaveStats(0.55, 0.49, 0.85, 0.73,
"brNDC");
213 ptstats->SetName(
"stats2");
214 ptstats->SetBorderSize(1);
215 ptstats->SetFillColor(0);
216 ptstats->SetTextAlign(12);
217 ptstats->SetTextFont(42);
218 ptstats->SetTextColor(kRed + 2);
219 ptstats->SetOptStat(11);
220 ptstats->SetParent(hist);
222 ptstats->AddText(
"Double Gaus");
223 for (
int npar = 0; npar < (fn_doubleGaus->GetNpar()); npar++)
224 ptstats->AddText(TString::Format(
"%s = %.3f #pm %.4f",
225 fn_doubleGaus->GetParName(npar),
226 fn_doubleGaus->GetParameter(npar),
227 fn_doubleGaus->GetParError(npar)));
228 ptstats =
new TPaveStats(0.55, 0.43, 0.85, 0.49,
"brNDC");
229 ptstats->SetName(
"stats3");
230 ptstats->SetBorderSize(1);
231 ptstats->SetFillColor(0);
232 ptstats->SetTextAlign(12);
233 ptstats->SetTextFont(42);
234 ptstats->SetTextColor(kBlue + 2);
235 ptstats->SetOptStat(11);
236 ptstats->SetParent(hist);
243 if (isDoubleGausFitValid) {
244 fillShiftVal = (fn_doubleGaus->GetParameter(1) > 0.5 ?
245 fn_doubleGaus->GetParameter(2) : fn_doubleGaus->GetParameter(4));
246 ptstats->AddText(TString::Format(
"#splitline{Shift Value from Double Gaus}{%.3f}", fillShiftVal));
247 }
else if (isSingleGausFitValid) {
248 fillShiftVal = fn_singleGaus->GetParameter(1);
249 B2WARNING(
"Fit failed for " << hist->GetName() <<
250 "; using mean from single gaus fit. ");
251 ptstats->AddText(TString::Format(
"#splitline{Shift Value from Single Gaus}{%.3f}", fillShiftVal));
255 B2WARNING(
"Shift value is more than allowed or fit failed in " <<
256 hist->GetName() <<
" : " <<
257 shiftValues[binLabel].back() <<
258 "; using mean of the histogram.");
259 fillShiftVal = hist->GetMean();
260 ptstats->AddText(TString::Format(
"#splitline{Shift Value from Histogram Mean}{%.3f}", fillShiftVal));
263 shiftValues[binLabel].push_back(1. *
int(1000. * fillShiftVal) / 1000.);
264 hDrawShift->SetBinContent(ij + 1, clSize, shiftValues[binLabel].back());
265 hDrawShift->GetXaxis()->SetBinLabel(ij + 1, binLabel);
267 c1.Print(outPDF, TString(
"Title:") + hist->GetName());
275 hClusterSizeVsTimeResidual->Write();
276 delete hClusterSizeVsTimeResidual;
279 for (
auto item : shiftValues)
280 payload->setClusterTimeShift(alg, item.first, item.second);
283 hDrawShift->GetXaxis()->LabelsOption(
"v");
284 hDrawShift->SetStats(0);
285 hDrawShift->Draw(
"colz");
286 c1.Print(outPDF, TString(
"Title:") + hDrawShift->GetName());
292 c1.Print(outPDF +
"]");
Base class for calibration algorithms.
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
void setDescription(const std::string &description)
Set algorithm description (in constructor)
EResult
The result of calibration.
@ c_OK
Finished successfully =0 in Python.
@ c_NotEnoughData
Needs more data =2 in Python.
int m_minEntries
Set the minimun number of entries required in the histograms.
std::vector< TString > m_timeAlgorithms
List of time algorithms to calibrate.
std::string m_id
Parameter given to set the UniqueID of the payload.
float m_maximumAllowedShift
Allowed deviation of clsOnTracks histo wrt EventT0 histo.
SVDClusterTimeShifterAlgorithm(const std::string &str)
Constructor set the prefix to SVDTimeCalibrationCollector.
virtual EResult calibrate() override
Run algo on data.
This class store the shift in svd time w.r.t.
double singleGaus(const double *x, const double *par)
Single gaus function, where N is a normalization constant, a is the mean of the Gaus distribution,...
double doubleGaus(const double *x, const double *par)
Double gaus function, where N is a normalization constant, f is the fractional contribution of the fi...
Abstract base class for different kinds of events.