33 std::array<double, 8> params{};
42 m_settings =
new T0ClassicSettings(0., 300., 100, -100., 900., 1000, 1, 1000, 1, 8, params, 10., 4);
46 if (log.level() <= MSG::INFO) log << MSG::INFO <<
"T0CalibrationClassic::T0CalibrationClassic" <<
m_name <<
" " <<
name <<
endmsg;
49 std::string HistoFileName =
"T0Classic_" +
m_name +
".root";
50 if (log.level() <= MSG::INFO)
51 log << MSG::INFO <<
"T0CalibrationClassic::T0CalibrationClassic" <<
m_name <<
" " <<
name <<
" " << HistoFileName <<
endmsg;
52 m_file = std::make_unique<TFile>(HistoFileName.c_str(),
"recreate");
161 std::unique_ptr<TMinuit> gMinuit = std::make_unique<TMinuit>();
165 std::vector<double> pfit(np, 0), errfit(np, 0);
166 Double_t **matrix =
new Double_t *[np];
168 for (
int i = 0; i < np; i++) {
169 matrix[i] =
new Double_t[np];
170 for (
int j = 0; j < np; j++) matrix[i][j] = 0.;
172 const std::array<double, 8> &pdefault =
m_settings->params();
179 if (T0h.
id == 1 || T0h.
id == 2 || (T0h.
id > 10 && T0h.
id <= 23)) isMultilayer = 1;
183 if (log.level() <= MSG::INFO) log << MSG::INFO <<
" STARTING doTimeFit " <<
endmsg;
187 if (log.level() <= MSG::DEBUG) log << MSG::DEBUG << T0h.
id <<
endmsg;
191 if (fitMezz == 1 && !isMultilayer) {
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;
199 TH1F *timeHis = (TH1F *)
m_regiondir->Get(HistoId.c_str());
201 for (
int i = 0; i < np; i++)
delete[] matrix[i];
207 h = histosMezz->
time.get();
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;
220 std::unique_ptr<TF1> FitFunction{
h->GetFunction(
"TimeSpectrum")};
222 for (
int i = 0; i < np; i++) {
223 pfit[i] = FitFunction->GetParameter(i);
224 errfit[i] = FitFunction->GetParError(i);
226 chi2 = FitFunction->GetChisquare();
227 ndof = FitFunction->GetNDF();
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;
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; }
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.);
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");
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");
259 TimeSpectrum->SetParLimits(6, 4., 30.);
260 h->Fit(
"TimeSpectrum",
"QLB");
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);
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);
273 chi2 = TimeSpectrum->GetChisquare();
274 ndof = TimeSpectrum->GetNDF();
277 if (ndof == 0.) ndof = -1;
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()) {
288 for (
int i = 0; i < np; i++) fi.
par[i] = pfit[i];
295 for (
int i = 0; i < np; i++) fi.
cov[i] = errfit[i];
321 for (
int i = 0; i < np; i++)
delete[] matrix[i];
324 if (log.level() <= MSG::DEBUG) log << MSG::DEBUG <<
" ENDING doTimeFit " <<
endmsg;
336 std::array<double, 4> par{0}, errpar{0};
341 if (log.level() <= MSG::DEBUG) log << MSG::DEBUG <<
" doAdcFit : checking Single tube entries" <<
endmsg;
342 double adcThreshold = 50.;
343 TH1 *hcheck = T0h.
adc.get();
344 int nhits =
static_cast<int>(hcheck->GetEntries());
346 int adcBinThreshold = (int)((adcThreshold - hcheck->GetBinLowEdge(1)) / (hcheck->GetBinWidth(1)) + 1);
347 int nhitsAboveAdcCut = (int)hcheck->Integral(adcBinThreshold, hcheck->GetNbinsX());
348 if (log.level() <= MSG::DEBUG)
349 log << MSG::DEBUG <<
" doAdcFit : TotHits, nhitsAboveAdcCut " << nhits <<
" " << nhitsAboveAdcCut <<
endmsg;
352 fi.
cov[21] = nhitsAboveAdcCut;
354 if (log.level() <= MSG::DEBUG) log << MSG::DEBUG <<
" STARTING doAdcFit " <<
endmsg;
360 std::string HistoId = std::format(
"charge_mezz_{:}", (hIdMezz) % (900000000));
361 if (log.level() <= MSG::DEBUG) {
362 log << MSG::DEBUG <<
" doAdcFit HistogramId : " << T0h.
id <<
endmsg;
363 log << MSG::DEBUG <<
" doAdcFit Histogram : " << HistoId <<
endmsg;
365 TH1F *adcHis = (TH1F *)
m_regiondir->Get(HistoId.c_str());
369 h = histosMezz->
adc.get();
372 if (log.level() <= MSG::VERBOSE)
373 log << MSG::VERBOSE <<
" histogram " <<
h->GetName() <<
" " <<
h->GetTitle() <<
" entries=" <<
h->GetEntries() <<
endmsg;
379 TF1 *FitFunction =
h->GetFunction(
"AdcSpectrum");
381 chi2 = FitFunction->GetChisquare();
382 ndof = FitFunction->GetNDF();
383 for (
int i = 0; i < 4; i++) {
384 par[i] = FitFunction->GetParameter(i);
385 errpar[i] = FitFunction->GetParError(i);
389 double m =
h->GetMean();
390 double r =
h->GetRMS();
391 double maxval =
h->GetMaximum();
392 std::array<double, 4> adcpar{};
393 adcpar[0] = maxval * 2.;
398 std::unique_ptr<TF1> AdcSpectrum = std::make_unique<TF1>(
399 "AdcSpectrum",
" ([0]*exp((x-[1])/[2]))/ (1.+exp((x-[1])/[3])) ",
m_settings->minAdc(),
m_settings->maxAdc());
400 AdcSpectrum->SetParameters(adcpar.data());
401 double fitMin = m - (3 *
r);
402 double fitMax = m + (3 *
r);
403 if (fitMin < adcThreshold) fitMin = adcThreshold;
404 if (fitMax > 300) fitMax = 300.;
405 h->Fit(
"AdcSpectrum",
"Q",
" ", fitMin, fitMax);
406 chi2 = AdcSpectrum->GetChisquare();
407 ndof = AdcSpectrum->GetNDF();
408 for (
int i = 0; i < 4; i++) {
409 par[i] = AdcSpectrum->GetParameter(i);
410 errpar[i] = AdcSpectrum->GetParError(i);
412 if (log.level() <= MSG::VERBOSE)
413 log << MSG::VERBOSE <<
"chi2/ndof=" <<
chi2 / ndof <<
" "
414 <<
"Mean=" << m <<
" "
415 <<
"RMS=" <<
r <<
" par 0 1 2 3 " << par[0] <<
" " << par[1] <<
" " << par[2] <<
" " << par[3] <<
endmsg;
425 if (std::abs(ndof) == 0) {
434 int nbinsX =
h->GetNbinsX();
435 double sizeX =
h->GetBinWidth(1);
436 double oldSizeX = sizeX;
437 int RebinFactor =
static_cast<int>(10. / sizeX);
439 std::unique_ptr<TH1> hnew{
h->Rebin(RebinFactor,
"hnew")};
442 if (log.level() <= MSG::DEBUG)
443 log << MSG::DEBUG <<
"nbinsx,sizex,rebinfactor=" << nbinsX <<
" " << sizeX <<
" " << RebinFactor <<
endmsg;
444 float minDeriv(9999.);
446 sizeX = hnew->GetBinWidth(1);
447 int newbins = hnew->GetNbinsX();
448 for (
int i = 0; i < np; ++i) {
449 if (log.level() <= MSG::DEBUG) log << MSG::DEBUG <<
"i,p(i) " << i <<
" " << p[i] <<
endmsg;
451 for (
int i = 0; i < newbins - 1; ++i) {
452 if (hnew->GetBinContent(i) - hnew->GetBinContent(i + 1) < minDeriv) {
453 minDeriv = hnew->GetBinContent(i) - hnew->GetBinContent(i + 1);
457 float t0guess = hnew->GetBinCenter(minDerivBin);
458 if (minDerivBin < newbins - 1) { t0guess += (hnew->GetBinCenter(minDerivBin + 1) - hnew->GetBinCenter(minDerivBin)) / 2.; }
459 if (log.level() <= MSG::DEBUG) log << MSG::DEBUG <<
" t0guess is " << t0guess <<
endmsg;
464 int numOfBins(10), numOfBinsOffset(3);
466 if (minDerivBin > numOfBins + numOfBinsOffset) {
467 imin = minDerivBin - numOfBins - numOfBinsOffset;
468 imax = minDerivBin - numOfBinsOffset;
471 if (minDerivBin > numOfBinsOffset) {
472 imax = minDerivBin - numOfBinsOffset;
478 for (
int i = imin; i <=
imax; ++i) {
479 noise += hnew->GetBinContent(i);
483 noise = noise / (float)(icount);
484 if (log.level() <= MSG::DEBUG) log << MSG::DEBUG <<
" noise is " << noise <<
endmsg;
488 int t0bin = minDerivBin;
489 int ix1 = t0bin + (int)(50 / sizeX);
490 int ix2 = t0bin + (int)(500 / sizeX);
491 if (log.level() <= MSG::DEBUG) log << MSG::DEBUG <<
"t0bin,ix1,ix2 " << t0bin <<
" " << ix1 <<
" " << ix2 <<
endmsg;
495 if (log.level() <= MSG::DEBUG) log << MSG::DEBUG <<
"P1,P2,P3 start are " << P1 <<
" " << P2 <<
" " << P3 <<
endmsg;
501 if (0 < ix1 && ix1 < newbins && 0 < ix2 && ix2 < newbins) {
502 float a1 = hnew->GetBinCenter(ix1);
503 float a2 = hnew->GetBinCenter(ix2);
504 float cont1 = hnew->GetBinContent(ix1);
505 float cont2 = hnew->GetBinContent(ix2);
506 if (cont1 > 0. && cont2 > 0.) {
507 float A1 = std::exp(-(a1 - t0guess) / P3);
508 float A2 = std::exp(-(a2 - t0guess) / P3);
510 P2 = (cont1 / cont2 - 1.) / (A1 - cont1 / cont2 * A2);
511 P1 = cont1 / (1 + P2 * A1);
512 P1 = P1 * oldSizeX / sizeX;
513 P2 = P2 * oldSizeX / sizeX;
514 if (log.level() <= MSG::DEBUG) {
515 log << MSG::DEBUG <<
"a1,a2 " << a1 <<
" " << a2 <<
" cont1,cont2 " << cont1 <<
" " << cont2 <<
" A1,A2 " << A1 <<
" "
517 log << MSG::DEBUG <<
" t0Guess .... P1, P2 " << P1 <<
" " << P2 <<
endmsg;
582 std::unique_ptr<T0ClassicHistos> histos = std::make_unique<T0ClassicHistos>();
583 std::string histonametdc{}, histonameadc{};
587 if ((
int)(idtube / 100000000) == 9) {
588 int mezz = (idtube) % (900000000);
589 histonametdc = std::format(
"time_mezz_{:}", mezz);
590 histonameadc = std::format(
"charge_mezz_{:}", mezz);
591 }
else if (idtube == 0) {
592 histonametdc =
"time";
593 histonameadc =
"charge";
594 }
else if (idtube == 1) {
595 histonametdc =
"time_ML1";
596 histonameadc =
"charge_ML1";
597 }
else if (idtube == 2) {
598 histonametdc =
"time_ML2";
599 histonameadc =
"charge_ML2";
600 }
else if (idtube == 11) {
601 histonametdc =
"time_ML1_series1";
602 histonameadc =
"charge_ML1_series1";
603 }
else if (idtube == 12) {
604 histonametdc =
"time_ML1_series2";
605 histonameadc =
"charge_ML1_series2";
606 }
else if (idtube == 13) {
607 histonametdc =
"time_ML1_series3";
608 histonameadc =
"charge_ML1_series3";
609 }
else if (idtube == 21) {
610 histonametdc =
"time_ML2_series1";
611 histonameadc =
"charge_ML2_series1";
612 }
else if (idtube == 22) {
613 histonametdc =
"time_ML2_series2";
614 histonameadc =
"charge_ML2_series2";
615 }
else if (idtube == 23) {
616 histonametdc =
"time_ML2_series3";
617 histonameadc =
"charge_ML2_series3";
624 int tubeid = (nML * 1000) + (nL * 100) + nT;
628 histonametdc = std::format(
"time_{:}_{:}_{:}_{:}", stationName,
eta,
phi, tubeid);
629 histonameadc = std::format(
"charge_{:}_{:}_{:}_{:}", stationName,
eta,
phi, tubeid);
636 m_histos.emplace_back(std::move(histos));