9 #include <top/modules/TOPLaserCalibrator/LaserCalibratorFit.h>
11 #include <framework/logging/Logger.h>
13 #include <Math/PdfFuncMathCore.h>
14 #include <Math/MinimizerOptions.h>
25 double fcnCB(
double* x,
double* par)
31 double f1 = ROOT::Math::crystalball_pdf(x[0], a1, n1, s1, m1);
36 double fcnCB2(
double* x,
double* par)
42 double m2 = m1 - par[6];
47 double f1 = ROOT::Math::crystalball_pdf(x[0], a1, n1, s1, m1);
48 double f2 = ROOT::Math::crystalball_pdf(x[0], a2, n2, s2, m2);
49 return par[0] * f1 + par[5] * f2;
74 for (
unsigned i = 0; i < hist.size(); i++) {
84 return m_func[channel]->GetChisquare();
92 if (channel >
m_hist.size()) {
93 B2WARNING(
"Wrong channel!");
97 B2WARNING(
"No Evts. in channel " << channel);
101 if (
m_hist[channel]->GetEntries() < 10) {
102 B2WARNING(
"Too little Evts. for fitting (Evts. < 10)!");
106 m_maxpos[channel] =
m_hist[channel]->GetXaxis()->GetBinCenter(
m_hist[channel]->GetMaximumBin());
116 B2WARNING(
"No matched fit method!");
125 auto file =
new TFile(outfile.c_str(),
"RECREATE");
126 auto otree =
new TTree(
"fits",
"fitted times");
128 unsigned channel = 0;
131 otree->Branch(
"maxpos", &maxpos,
"maxpos/D");
136 otree->Branch(
"channel", &channel,
"channel/I");
137 otree->Branch(
"norm", &(parms[0]),
"norm/D");
138 otree->Branch(
"time", &(parms[1]),
"time/D");
139 otree->Branch(
"reso", &(parms[2]),
"reso/D");
140 otree->Branch(
"normErr", &(parmErrs[0]),
"normErr/D");
141 otree->Branch(
"timeErr", &(parmErrs[1]),
"timeErr/D");
142 otree->Branch(
"resoErr", &(parmErrs[2]),
"resoErr/D");
147 f->GetParameters(parms);
148 for (
int iPar = 0; iPar < 3; iPar++)
149 parmErrs[iPar] = f->GetParError(iPar);
159 otree->Branch(
"channel", &channel,
"channel/I");
160 otree->Branch(
"norm1", &(parms[0]),
"norm1/D");
161 otree->Branch(
"time1", &(parms[1]),
"time1/D");
162 otree->Branch(
"reso1", &(parms[2]),
"reso1/D");
163 otree->Branch(
"alpha_CB", &(parms[3]),
"alpha_CB/D");
164 otree->Branch(
"n_CB", &(parms[4]),
"n_CB/D");
165 otree->Branch(
"norm2", &(parms[5]),
"norm2/D");
166 otree->Branch(
"dt12", &(parms[6]),
"dt12/D");
167 otree->Branch(
"reso2", &(parms[7]),
"reso2/D");
168 otree->Branch(
"time2", &time2,
"time2/D");
170 otree->Branch(
"norm1Err", &(parmErrs[0]),
"norm1Err/D");
171 otree->Branch(
"time1Err", &(parmErrs[1]),
"time1Err/D");
172 otree->Branch(
"reso1Err", &(parmErrs[2]),
"reso1Err/D");
173 otree->Branch(
"alpha_CBErr", &(parmErrs[3]),
"alpha_CBErr/D");
174 otree->Branch(
"n_CBErr", &(parmErrs[4]),
"n_CBErr/D");
175 otree->Branch(
"norm2Err", &(parmErrs[5]),
"norm2Err/D");
176 otree->Branch(
"dt12Err", &(parmErrs[6]),
"dt12Err/D");
177 otree->Branch(
"reso2Err", &(parmErrs[7]),
"reso2Err/D");
183 f->GetParameters(parms);
184 for (
int iPar = 0; iPar < 8; iPar++)
185 parmErrs[iPar] = f->GetParError(iPar);
194 otree->Branch(
"channel", &channel,
"channel/I");
195 otree->Branch(
"norm", &(parms[0]),
"norm/D");
196 otree->Branch(
"time", &(parms[1]),
"time/D");
197 otree->Branch(
"reso", &(parms[2]),
"reso/D");
198 otree->Branch(
"alpha_CB", &(parms[3]),
"alpha_CB/D");
199 otree->Branch(
"n_CB", &(parms[4]),
"n_CB/D");
201 otree->Branch(
"normErr", &(parmErrs[0]),
"normErr/D");
202 otree->Branch(
"timeErr", &(parmErrs[1]),
"timeErr/D");
203 otree->Branch(
"resoErr", &(parmErrs[2]),
"resoErr/D");
204 otree->Branch(
"alpha_CBErr", &(parmErrs[3]),
"alpha_CBErr/D");
205 otree->Branch(
"n_CBErr", &(parmErrs[4]),
"n_CBErr/D");
210 f->GetParameters(parms);
211 for (
int iPar = 0; iPar < 5; iPar++)
212 parmErrs[iPar] = f->GetParError(iPar);
218 B2WARNING(
"Nothing be written to files!");
222 if (h && h->GetEntries() >= 10) {
235 TH1F* h =
m_hist[channel];
236 double m = h->GetMean();
237 double w = h->GetRMS();
238 h->Fit(
"gaus",
"Q",
"", m - 2.*w, m + 4.*w);
240 TF1* func = h->GetFunction(
"gaus");
241 func->GetParameters(parms);
243 h->Fit(
"gaus",
"Q",
"", m - w, m + w);
244 func = h->GetFunction(
"gaus");
253 TH1F* h =
m_hist[channel];
258 parms[1] = h->GetMean();
259 parms[2] = h->GetRMS();
263 func->SetParameters(parms);
266 func->SetParName(0,
"norm");
267 func->SetParName(1,
"time");
268 func->SetParName(2,
"sigma");
269 func->SetParName(3,
"alpha_CB");
270 func->SetParName(4,
"n_CB");
274 func->SetParLimits(3, -5, 0);
275 func->SetParLimits(4, 0, 10);
277 h->Fit(func,
"Q",
"");
278 if (fabs(
m_maxpos[channel] - parms[1]) < parms[2]) {
291 TH1F* h =
m_hist[channel];
292 auto func =
new TF1(
"fcnCB2", fcnCB2,
m_xmin,
m_xmax, 8);
294 double vdt[8] = {0.272, 0.242, 0.208, 0.178, 0.113, 0.082, 0.0485, 0.017};
303 parms[6] = vdt[(channel) / 64];
307 func->SetParameters(parms);
310 func->SetParName(0,
"norm1");
311 func->SetParName(1,
"time1");
312 func->SetParName(2,
"sigma1");
313 func->SetParName(3,
"alpha1_CB");
314 func->SetParName(4,
"n1_CB");
315 func->SetParName(5,
"norm2");
316 func->SetParName(6,
"dt12");
317 func->SetParName(7,
"sigma2");
318 func->SetParName(8,
"alpha2_CB");
319 func->SetParName(9,
"n2_CB");
321 func->SetParLimits(1, parms[1] - 0.25, parms[1] + 0.15);
323 func->SetParLimits(3, -5, 0);
324 func->SetParLimits(4, 0, 10);
325 func->SetParLimits(6, parms[6] * 0.7, parms[6] * 1.5);
326 func->SetParLimits(8, -5, 0);
327 func->SetParLimits(9, 0, 10);
329 ROOT::Math::MinimizerOptions::SetDefaultMaxFunctionCalls(50000);
331 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.