9#include <top/modules/TOPLaserCalibrator/LaserCalibratorFit.h>
11#include <framework/logging/Logger.h>
13#include <Math/PdfFuncMathCore.h>
14#include <Math/MinimizerOptions.h>
26 double fcnCB(
double* x,
double* par)
32 double f1 = ROOT::Math::crystalball_pdf(x[0], a1, n1, s1, m1);
38 double fcnCB2(
double* x,
double* par)
44 double m2 = m1 - par[6];
49 double f1 = ROOT::Math::crystalball_pdf(x[0], a1, n1, s1, m1);
50 double f2 = ROOT::Math::crystalball_pdf(x[0], a2, n2, s2, m2);
51 return par[0] * f1 + par[5] * f2;
76 for (
unsigned i = 0; i < hist.size(); i++) {
86 return m_func[channel]->GetChisquare();
94 if (channel >
m_hist.size()) {
95 B2WARNING(
"Wrong channel!");
99 B2WARNING(
"No Evts. in channel " << channel);
103 if (
m_hist[channel]->GetEntries() < 10) {
104 B2WARNING(
"Too little Evts. for fitting (Evts. < 10)!");
108 m_maxpos[channel] =
m_hist[channel]->GetXaxis()->GetBinCenter(
m_hist[channel]->GetMaximumBin());
118 B2WARNING(
"No matched fit method!");
127 auto file =
new TFile(outfile.c_str(),
"RECREATE");
128 auto otree =
new TTree(
"fits",
"fitted times");
130 unsigned channel = 0;
133 otree->Branch(
"maxpos", &maxpos,
"maxpos/D");
138 otree->Branch(
"channel", &channel,
"channel/I");
139 otree->Branch(
"norm", &(parms[0]),
"norm/D");
140 otree->Branch(
"time", &(parms[1]),
"time/D");
141 otree->Branch(
"reso", &(parms[2]),
"reso/D");
142 otree->Branch(
"normErr", &(parmErrs[0]),
"normErr/D");
143 otree->Branch(
"timeErr", &(parmErrs[1]),
"timeErr/D");
144 otree->Branch(
"resoErr", &(parmErrs[2]),
"resoErr/D");
149 f->GetParameters(parms);
150 for (
int iPar = 0; iPar < 3; iPar++)
151 parmErrs[iPar] = f->GetParError(iPar);
161 otree->Branch(
"channel", &channel,
"channel/I");
162 otree->Branch(
"norm1", &(parms[0]),
"norm1/D");
163 otree->Branch(
"time1", &(parms[1]),
"time1/D");
164 otree->Branch(
"reso1", &(parms[2]),
"reso1/D");
165 otree->Branch(
"alpha_CB", &(parms[3]),
"alpha_CB/D");
166 otree->Branch(
"n_CB", &(parms[4]),
"n_CB/D");
167 otree->Branch(
"norm2", &(parms[5]),
"norm2/D");
168 otree->Branch(
"dt12", &(parms[6]),
"dt12/D");
169 otree->Branch(
"reso2", &(parms[7]),
"reso2/D");
170 otree->Branch(
"time2", &time2,
"time2/D");
172 otree->Branch(
"norm1Err", &(parmErrs[0]),
"norm1Err/D");
173 otree->Branch(
"time1Err", &(parmErrs[1]),
"time1Err/D");
174 otree->Branch(
"reso1Err", &(parmErrs[2]),
"reso1Err/D");
175 otree->Branch(
"alpha_CBErr", &(parmErrs[3]),
"alpha_CBErr/D");
176 otree->Branch(
"n_CBErr", &(parmErrs[4]),
"n_CBErr/D");
177 otree->Branch(
"norm2Err", &(parmErrs[5]),
"norm2Err/D");
178 otree->Branch(
"dt12Err", &(parmErrs[6]),
"dt12Err/D");
179 otree->Branch(
"reso2Err", &(parmErrs[7]),
"reso2Err/D");
185 f->GetParameters(parms);
186 for (
int iPar = 0; iPar < 8; iPar++)
187 parmErrs[iPar] = f->GetParError(iPar);
196 otree->Branch(
"channel", &channel,
"channel/I");
197 otree->Branch(
"norm", &(parms[0]),
"norm/D");
198 otree->Branch(
"time", &(parms[1]),
"time/D");
199 otree->Branch(
"reso", &(parms[2]),
"reso/D");
200 otree->Branch(
"alpha_CB", &(parms[3]),
"alpha_CB/D");
201 otree->Branch(
"n_CB", &(parms[4]),
"n_CB/D");
203 otree->Branch(
"normErr", &(parmErrs[0]),
"normErr/D");
204 otree->Branch(
"timeErr", &(parmErrs[1]),
"timeErr/D");
205 otree->Branch(
"resoErr", &(parmErrs[2]),
"resoErr/D");
206 otree->Branch(
"alpha_CBErr", &(parmErrs[3]),
"alpha_CBErr/D");
207 otree->Branch(
"n_CBErr", &(parmErrs[4]),
"n_CBErr/D");
212 f->GetParameters(parms);
213 for (
int iPar = 0; iPar < 5; iPar++)
214 parmErrs[iPar] = f->GetParError(iPar);
220 B2WARNING(
"Nothing be written to files!");
224 if (h && h->GetEntries() >= 10) {
237 TH1F* h =
m_hist[channel];
238 double m = h->GetMean();
239 double w = h->GetRMS();
240 h->Fit(
"gaus",
"Q",
"", m - 2.*w, m + 4.*w);
242 TF1* func = h->GetFunction(
"gaus");
243 func->GetParameters(parms);
245 h->Fit(
"gaus",
"Q",
"", m - w, m + w);
246 func = h->GetFunction(
"gaus");
255 TH1F* h =
m_hist[channel];
260 parms[1] = h->GetMean();
261 parms[2] = h->GetRMS();
265 func->SetParameters(parms);
268 func->SetParName(0,
"norm");
269 func->SetParName(1,
"time");
270 func->SetParName(2,
"sigma");
271 func->SetParName(3,
"alpha_CB");
272 func->SetParName(4,
"n_CB");
276 func->SetParLimits(3, -5, 0);
277 func->SetParLimits(4, 0, 10);
279 h->Fit(func,
"Q",
"");
280 if (fabs(
m_maxpos[channel] - parms[1]) < parms[2]) {
293 TH1F* h =
m_hist[channel];
294 auto func =
new TF1(
"fcnCB2", fcnCB2,
m_xmin,
m_xmax, 8);
296 const double vdt[8] = {0.272, 0.242, 0.208, 0.178, 0.113, 0.082, 0.0485, 0.017};
305 parms[6] = vdt[(channel) / 64];
309 func->SetParameters(parms);
312 func->SetParName(0,
"norm1");
313 func->SetParName(1,
"time1");
314 func->SetParName(2,
"sigma1");
315 func->SetParName(3,
"alpha1_CB");
316 func->SetParName(4,
"n1_CB");
317 func->SetParName(5,
"norm2");
318 func->SetParName(6,
"dt12");
319 func->SetParName(7,
"sigma2");
320 func->SetParName(8,
"alpha2_CB");
321 func->SetParName(9,
"n2_CB");
323 func->SetParLimits(1, parms[1] - 0.25, parms[1] + 0.15);
325 func->SetParLimits(3, -5, 0);
326 func->SetParLimits(4, 0, 10);
327 func->SetParLimits(6, parms[6] * 0.7, parms[6] * 1.5);
328 func->SetParLimits(8, -5, 0);
329 func->SetParLimits(9, 0, 10);
331 ROOT::Math::MinimizerOptions::SetDefaultMaxFunctionCalls(50000);
333 h->Fit(func,
"Q",
"");
double m_xmin
fitting low-edge
TF1 * makeCB2Fit(unsigned channel, bool minOut)
Fit process using double Crystal Ball fuction.
void setHist(const std::vector< TH1F * > &hist)
set time hist of all channels in one moduleID
~LaserCalibratorFit()
Destructor.
std::vector< TH1F * > m_hist
time hist of 512 channels
TF1 * makeCBFit(unsigned channel)
Fit process using single Crystal Ball fuction.
std::vector< TF1 * > m_func
fitting function
double m_fitTErr
error on the mean position estimated by the fit
LaserCalibratorFit(unsigned moduleID)
Constructor.
double m_xmax
fitting upper-edge
std::vector< double > m_maxpos_error
error on the center positon of hist max bin
int fitChannel(unsigned channel)
fit for a specific channel
void writeFile(const std::string &outfile)
write fit result to a root file
double m_fitT
mean position after fit
std::string m_fitMethod
fitting method
TF1 * makeGFit(unsigned channel)
Fit process using single gaussian function.
std::vector< double > m_maxpos
center positon of hist max bin
double getFitChisq(unsigned channel)
get chi^2 in the fit
Abstract base class for different kinds of events.