31 IMdtCalibration(
name), m_settings(settings), m_converged(false), m_name(
name), m_result(nullptr), m_delete_settings(false) {
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");
64 float distanceToRO = hit->distanceToReadout();
66 bool ROside = distanceToRO < 130000.;
71 int nML =
id.mdtMultilayer();
72 int nL =
id.mdtTubeLayer();
73 int nT =
id.mdtTube();
74 const Identifier tubeId = idHelper.channelID(
id.stationNameString(),
id.eta(),
id.phi(),
79 log << MSG::WARNING <<
"no Single Tube Calib info found for ML=" << nML <<
" L=" << nL <<
" T=" << nT <<
endmsg;
91 float ttime = hit->driftTime();
94 histos->adc->Fill(hit->adcCount());
97 histosAll->
time->Fill(ttime);
98 histosAll->
adc->Fill(hit->adcCount());
102 histosML->
time->Fill(ttime);
103 histosML->
adc->Fill(hit->adcCount());
106 histosMezz->
time->Fill(ttime);
107 histosMezz->
adc->Fill(hit->adcCount());
110 int serialGas = nML * 10 + (nT - 1) % 3 + 1;
112 histosSerialGas->time->Fill(ttime);
113 histosSerialGas->adc->Fill(hit->adcCount());
125 for (std::unique_ptr<T0ClassicHistos> &
hist :
m_histos) {
129 int idtube =
hist->id;
130 if (idtube != 0 && (
int)(idtube / 100000000) != 9) {
140 bool setInfo =
m_result->setCalib(std::make_unique<MdtTubeFitContainer::SingleTubeCalib>(st), tubeId,
log);
141 if (!setInfo)
log << MSG::WARNING <<
"T0CalibrationClassic::PROBLEM! could not set SingleTubeCalib info " <<
endmsg;
143 if (!setInfo)
log << MSG::WARNING <<
"T0CalibrationClassic::PROBLEM! could not set SingleTubeFullInfo info " <<
endmsg;
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++) {
170 for (
int j = 0; j <
np; j++)
matrix[
i][j] = 0.;
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;
191 if (fitMezz == 1 && !isMultilayer) {
194 std::string HistoId =
std::format(
"time_mezz_{:}", (hIdMezz) % (900000000));
207 h = histosMezz->
time.get();
214 log <<
MSG::VERBOSE <<
" histogram " <<
h->GetName() <<
" " <<
h->GetTitle() <<
" entries=" <<
h->GetEntries()
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];
235 log <<
MSG::DEBUG <<
"T0CalibrationClassic::doTimeFit initial parameters" <<
i <<
"=" << pfit[
i] <<
endmsg;
239 log <<
MSG::DEBUG <<
"T0CalibrationClassic::doTimeFit parameters after searchParams " <<
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);
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();
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];
336 std::array<double, 4>
par{0}, errpar{0};
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());
349 log <<
MSG::DEBUG <<
" doAdcFit : TotHits, nhitsAboveAdcCut " << nhits <<
" " << nhitsAboveAdcCut <<
endmsg;
352 fi.cov[21] = nhitsAboveAdcCut;
360 std::string HistoId =
std::format(
"charge_mezz_{:}", (hIdMezz) % (900000000));
369 h = histosMezz->
adc.get();
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>(
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);
414 <<
"Mean=" <<
m <<
" "
415 <<
"RMS=" <<
r <<
" par 0 1 2 3 " <<
par[0] <<
" " <<
par[1] <<
" " <<
par[2] <<
" " <<
par[3] <<
endmsg;
421 fi.adc_par[0] =
par[1];
422 fi.adc_par[1] =
par[2];
423 fi.adc_err[0] = errpar[1];
424 fi.adc_err[1] = errpar[2];
425 if (std::abs(
ndof) == 0) {
428 fi.adc_chi2 =
chi2 /
static_cast<float>(
ndof);
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")};
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) {
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.; }
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);
488 int t0bin = minDerivBin;
489 int ix1 = t0bin + (
int)(50 / sizeX);
490 int ix2 = t0bin + (
int)(500 / sizeX);
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;
515 log <<
MSG::DEBUG <<
"a1,a2 " << a1 <<
" " << a2 <<
" cont1,cont2 " << cont1 <<
" " << cont2 <<
" A1,A2 " << A1 <<
" "
527 return std::make_shared<T0CalibrationOutput>(
m_result.get());
532 if ((
int)(idtube / 100000000) == 9) {
533 int mezz = (idtube) % (900000000);
535 }
else if (idtube == 0) {
537 }
else if (idtube == 1) {
538 HistoId =
"time_ML1";
539 }
else if (idtube == 2) {
540 HistoId =
"time_ML2";
541 }
else if (idtube == 11) {
542 HistoId =
"time_ML1_series1";
543 }
else if (idtube == 12) {
544 HistoId =
"time_ML1_series2";
545 }
else if (idtube == 13) {
546 HistoId =
"time_ML1_series3";
547 }
else if (idtube == 21) {
548 HistoId =
"time_ML2_series1";
549 }
else if (idtube == 22) {
550 HistoId =
"time_ML2_series2";
551 }
else if (idtube == 23) {
552 HistoId =
"time_ML2_series3";
558 int tubeid = (nML * 1000) + (nL * 100) + nT;
571 for (
const std::unique_ptr<T0ClassicHistos> &
hist :
m_histos) {
572 if (
hist->time.get() == timeHis) {
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);
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;
649 m_result = std::make_unique<MdtTubeFitContainer>(*t0Input->
t0s());
650 m_result->setImplementation(
"T0CalibrationClassic");