160 {
161 std::unique_ptr<TMinuit> gMinuit = std::make_unique<TMinuit>();
162 int fitMezz(1);
163
165 std::vector<double> pfit(np, 0), errfit(np, 0);
166 Double_t **
matrix =
new Double_t *[
np];
167
168 for (
int i = 0;
i <
np;
i++) {
170 for (
int j = 0; j <
np; j++) matrix[i][j] = 0.;
171 }
172 const std::array<double, 8> &pdefault =
m_settings->params();
175
176 MuonFixedId fId(T0h.id);
177 int isMultilayer(0);
178
179 if (T0h.id == 1 || T0h.id == 2 || (T0h.id > 10 && T0h.id <= 23)) isMultilayer = 1;
180
182 if ((fId.isValid() && fId.is_mdt()) || isMultilayer) {
183 if (
log.level() <= MSG::INFO)
log << MSG::INFO <<
" STARTING doTimeFit " <<
endmsg;
185
186 if (isMultilayer) {
187 if (
log.level() <= MSG::DEBUG)
log << MSG::DEBUG << T0h.id <<
endmsg;
189 }
190
191 if (fitMezz == 1 && !isMultilayer) {
192 int hIdMezz = fId.mdtMezzanine();
193
194 std::string HistoId = std::format("time_mezz_{:}", (hIdMezz) % (900000000));
195 if (
log.level() <= MSG::DEBUG) {
196 log << MSG::DEBUG <<
" doTimeFit HistogramId : " << T0h.id <<
endmsg;
197 log << MSG::DEBUG <<
" doTimeFit Histogram : " << HistoId <<
endmsg;
198 }
200 if (!timeHis) {
201 for (
int i = 0;
i <
np;
i++)
delete[] matrix[i];
203 return;
204 }
205
206 T0ClassicHistos *histosMezz =
getHistos(fId.mdtMezzanine());
207 h = histosMezz->time.get();
208 }
209
212
213 if (
log.level() <= MSG::VERBOSE)
214 log << MSG::VERBOSE <<
" histogram " <<
h->GetName() <<
" " <<
h->GetTitle() <<
" entries=" <<
h->GetEntries()
215 <<
" min entries=" <<
m_settings->entries() << std::endl;
216
217
219
220 std::unique_ptr<TF1> FitFunction{
h->GetFunction(
"TimeSpectrum")};
221 if (FitFunction) {
222 for (
int i = 0;
i <
np;
i++) {
223 pfit[
i] = FitFunction->GetParameter(i);
224 errfit[
i] = FitFunction->GetParError(i);
225 }
226 chi2 = FitFunction->GetChisquare();
227 ndof = FitFunction->GetNDF();
228 } else {
229 std::unique_ptr<TF1> TimeSpectrum = std::make_unique<TF1>(
230 "TimeSpectrum", "[0]+([1]*(1+[2]*exp(-(x-[4])/[3])))/((1+exp((-x+[4])/[6]))*(1+exp((x-[5])/[7]))) ",
232 for (
int i = 0;
i <
np;
i++) {
233 pfit[
i] = pdefault[
i];
234 if (
log.level() <= MSG::DEBUG)
235 log << MSG::DEBUG <<
"T0CalibrationClassic::doTimeFit initial parameters" <<
i <<
"=" << pfit[
i] <<
endmsg;
236 }
238 if (
log.level() <= MSG::DEBUG) {
239 log << MSG::DEBUG <<
"T0CalibrationClassic::doTimeFit parameters after searchParams " <<
endmsg;
240 for (
int i = 0;
i <
np; ++
i) {
log << MSG::DEBUG <<
"i,pfit(i) " <<
i <<
" " << pfit[
i] <<
endmsg; }
241 }
242 TimeSpectrum->SetParameters(pfit.data());
243 TimeSpectrum->SetParLimits(0, 0., 5.);
244 TimeSpectrum->SetParLimits(1, 0., 1000.);
245 TimeSpectrum->SetParLimits(2, 0., 40.);
246 TimeSpectrum->SetParLimits(3, 50., 400.);
247 TimeSpectrum->SetParLimits(4, 0., 1000.);
248
249 TimeSpectrum->SetParLimits(5, pfit[5], pfit[5]);
250 TimeSpectrum->SetParLimits(6, pfit[6], pfit[6]);
251 TimeSpectrum->SetParLimits(7, pfit[7], pfit[7]);
252 h->Fit(
"TimeSpectrum",
"QLB");
253
254 TimeSpectrum->SetParLimits(5, 500., 2000.);
255 TimeSpectrum->SetParLimits(6, pfit[6], pfit[6]);
256 TimeSpectrum->SetParLimits(7, pfit[7], pfit[7]);
257 h->Fit(
"TimeSpectrum",
"QLB");
258
259 TimeSpectrum->SetParLimits(6, 4., 30.);
260 h->Fit(
"TimeSpectrum",
"QLB");
261
262 TimeSpectrum->SetParLimits(6, 4., 30.);
263 TimeSpectrum->SetParLimits(7, 4., 30.);
264 double xmin =
h->GetBinLowEdge(1);
265 double xmax = pfit[5] + 250.;
266 h->Fit(
"TimeSpectrum",
"QLB",
"",
xmin,
xmax);
267
268 gMinuit->mnemat(&matrix[0][0], np);
269 for (
int i = 0;
i <
np;
i++) {
270 pfit[
i] = TimeSpectrum->GetParameter(i);
271 errfit[
i] = TimeSpectrum->GetParError(i);
272 }
273 chi2 = TimeSpectrum->GetChisquare();
274 ndof = TimeSpectrum->GetNDF();
275 }
276
277 if (ndof == 0.)
ndof = -1;
278
279 if (
log.level() <= MSG::VERBOSE)
280 log << MSG::VERBOSE <<
" fit results chi2/ndof=" <<
chi2 /
ndof <<
" T0=" << pfit[4] <<
" err=" << errfit[4] <<
endmsg;
281 if (
chi2 / ndof < m_settings->chi2max()) {
282 stc.statusCode = 0;
283 } else {
284 stc.statusCode = 3;
285 }
286 stc.t0 = pfit[4];
288 for (
int i = 0;
i <
np;
i++) fi.par[i] = pfit[i];
289
290
291
292
293
294
295 for (
int i = 0;
i <
np;
i++) fi.cov[i] = errfit[i];
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317 } else {
318 stc.statusCode = 2;
319 }
320 }
321 for (
int i = 0;
i <
np;
i++)
delete[] matrix[i];
323
324 if (
log.level() <= MSG::DEBUG)
log << MSG::DEBUG <<
" ENDING doTimeFit " <<
endmsg;
325 }
void searchParams(TH1 *h, double *p, int np)
estimate initial parameters for time spectrum fit from the spectrum itself