32 IMdtCalibration(
name), m_settings(settings), m_converged(false), m_name(
name), m_result(nullptr), m_delete_settings(false) {
34 std::array<double, 8>
params{};
43 m_settings =
new T0ClassicSettings(0., 300., 100, -100., 900., 1000, 1, 1000, 1, 8,
params, 10., 4);
47 if (
log.level() <= MSG::INFO)
log << MSG::INFO <<
"T0CalibrationClassic::T0CalibrationClassic" <<
m_name <<
" " <<
name <<
endmsg;
50 std::string HistoFileName =
"T0Classic_" +
m_name +
".root";
51 if (
log.level() <= MSG::INFO)
52 log << MSG::INFO <<
"T0CalibrationClassic::T0CalibrationClassic" <<
m_name <<
" " <<
name <<
" " << HistoFileName <<
endmsg;
53 m_file = std::make_unique<TFile>(HistoFileName.c_str(),
"recreate");
65 float distanceToRO = hit->distanceToReadout();
67 bool ROside = distanceToRO < 130000.;
72 int nML =
id.mdtMultilayer();
73 int nL =
id.mdtTubeLayer();
74 int nT =
id.mdtTube();
75 const Identifier tubeId = idHelper.channelID(
id.stationNameString(),
id.
eta(),
id.
phi(),
80 log << MSG::WARNING <<
"no Single Tube Calib info found for ML=" << nML <<
" L=" << nL <<
" T=" << nT <<
endmsg;
92 float ttime = hit->driftTime();
95 histos->adc->Fill(hit->adcCount());
98 histosAll->
time->Fill(ttime);
99 histosAll->
adc->Fill(hit->adcCount());
103 histosML->
time->Fill(ttime);
104 histosML->
adc->Fill(hit->adcCount());
107 histosMezz->
time->Fill(ttime);
108 histosMezz->
adc->Fill(hit->adcCount());
111 int serialGas = nML * 10 + (nT - 1) % 3 + 1;
113 histosSerialGas->time->Fill(ttime);
114 histosSerialGas->adc->Fill(hit->adcCount());
126 for (std::unique_ptr<T0ClassicHistos> &
hist :
m_histos) {
130 int idtube =
hist->id;
131 if (idtube != 0 && (
int)(idtube / 100000000) != 9) {
141 bool setInfo =
m_result->setCalib(std::move(st), tubeId,
log);
142 if (!setInfo)
log << MSG::WARNING <<
"T0CalibrationClassic::PROBLEM! could not set SingleTubeCalib info " <<
endmsg;
144 if (!setInfo)
log << MSG::WARNING <<
"T0CalibrationClassic::PROBLEM! could not set SingleTubeFullInfo info " <<
endmsg;
162 std::unique_ptr<TMinuit> gMinuit = std::make_unique<TMinuit>();
166 std::vector<double> pfit(
np, 0), errfit(
np, 0);
167 Double_t **
matrix =
new Double_t *[
np];
169 for (
int i = 0;
i <
np;
i++) {
171 for (
int j = 0; j <
np; j++)
matrix[
i][j] = 0.;
180 if (T0h.
id == 1 || T0h.
id == 2 || (T0h.
id > 10 && T0h.
id <= 23)) isMultilayer = 1;
184 if (
log.level() <= MSG::INFO)
log << MSG::INFO <<
" STARTING doTimeFit " <<
endmsg;
192 if (fitMezz == 1 && !isMultilayer) {
196 std::string HistoId(std::string(
"time_mezz_") +
ts((hIdMezz) % (900000000)));
209 h = histosMezz->
time.get();
216 log <<
MSG::VERBOSE <<
" histogram " <<
h->GetName() <<
" " <<
h->GetTitle() <<
" entries=" <<
h->GetEntries()
222 std::unique_ptr<TF1> FitFunction{
h->GetFunction(
"TimeSpectrum")};
224 for (
int i = 0;
i <
np;
i++) {
225 pfit[
i] = FitFunction->GetParameter(
i);
226 errfit[
i] = FitFunction->GetParError(
i);
228 chi2 = FitFunction->GetChisquare();
229 ndof = FitFunction->GetNDF();
231 std::unique_ptr<TF1> TimeSpectrum = std::make_unique<TF1>(
232 "TimeSpectrum",
"[0]+([1]*(1+[2]*exp(-(x-[4])/[3])))/((1+exp((-x+[4])/[6]))*(1+exp((x-[5])/[7]))) ",
234 for (
int i = 0;
i <
np;
i++) {
235 pfit[
i] = pdefault[
i];
237 log <<
MSG::DEBUG <<
"T0CalibrationClassic::doTimeFit initial parameters" <<
i <<
"=" << pfit[
i] <<
endmsg;
241 log <<
MSG::DEBUG <<
"T0CalibrationClassic::doTimeFit parameters after searchParams " <<
endmsg;
244 TimeSpectrum->SetParameters(pfit.data());
245 TimeSpectrum->SetParLimits(0, 0., 5.);
246 TimeSpectrum->SetParLimits(1, 0., 1000.);
247 TimeSpectrum->SetParLimits(2, 0., 40.);
248 TimeSpectrum->SetParLimits(3, 50., 400.);
249 TimeSpectrum->SetParLimits(4, 0., 1000.);
251 TimeSpectrum->SetParLimits(5, pfit[5], pfit[5]);
252 TimeSpectrum->SetParLimits(6, pfit[6], pfit[6]);
253 TimeSpectrum->SetParLimits(7, pfit[7], pfit[7]);
254 h->Fit(
"TimeSpectrum",
"QLB");
256 TimeSpectrum->SetParLimits(5, 500., 2000.);
257 TimeSpectrum->SetParLimits(6, pfit[6], pfit[6]);
258 TimeSpectrum->SetParLimits(7, pfit[7], pfit[7]);
259 h->Fit(
"TimeSpectrum",
"QLB");
261 TimeSpectrum->SetParLimits(6, 4., 30.);
262 h->Fit(
"TimeSpectrum",
"QLB");
264 TimeSpectrum->SetParLimits(6, 4., 30.);
265 TimeSpectrum->SetParLimits(7, 4., 30.);
266 double xmin =
h->GetBinLowEdge(1);
267 double xmax = pfit[5] + 250.;
268 h->Fit(
"TimeSpectrum",
"QLB",
"",
xmin,
xmax);
271 for (
int i = 0;
i <
np;
i++) {
272 pfit[
i] = TimeSpectrum->GetParameter(
i);
273 errfit[
i] = TimeSpectrum->GetParError(
i);
275 chi2 = TimeSpectrum->GetChisquare();
276 ndof = TimeSpectrum->GetNDF();
283 if (
chi2 / ndof < m_settings->chi2max()) {
290 for (
int i = 0;
i <
np;
i++)
fi.par[
i] = pfit[
i];
297 for (
int i = 0;
i <
np;
i++)
fi.cov[
i] = errfit[
i];
338 std::array<double, 4>
par{0}, errpar{0};
344 double adcThreshold = 50.;
345 TH1 *hcheck = T0h.
adc.get();
346 int nhits =
static_cast<int>(hcheck->GetEntries());
348 int adcBinThreshold = (
int)((adcThreshold - hcheck->GetBinLowEdge(1)) / (hcheck->GetBinWidth(1)) + 1);
349 int nhitsAboveAdcCut = (
int)hcheck->Integral(adcBinThreshold, hcheck->GetNbinsX());
351 log <<
MSG::DEBUG <<
" doAdcFit : TotHits, nhitsAboveAdcCut " << nhits <<
" " << nhitsAboveAdcCut <<
endmsg;
354 fi.cov[21] = nhitsAboveAdcCut;
363 std::string HistoId(std::string(
"charge_mezz_") +
ts((hIdMezz) % (900000000)));
372 h = histosMezz->
adc.get();
376 log <<
MSG::VERBOSE <<
" histogram " <<
h->GetName() <<
" " <<
h->GetTitle() <<
" entries=" <<
h->GetEntries() <<
endmsg;
382 TF1 *FitFunction =
h->GetFunction(
"AdcSpectrum");
384 chi2 = FitFunction->GetChisquare();
385 ndof = FitFunction->GetNDF();
386 for (
int i = 0;
i < 4;
i++) {
387 par[
i] = FitFunction->GetParameter(
i);
388 errpar[
i] = FitFunction->GetParError(
i);
392 double m =
h->GetMean();
393 double r =
h->GetRMS();
394 double maxval =
h->GetMaximum();
395 std::array<double, 4> adcpar{};
396 adcpar[0] = maxval * 2.;
401 std::unique_ptr<TF1> AdcSpectrum = std::make_unique<TF1>(
403 AdcSpectrum->SetParameters(adcpar.data());
404 double fitMin =
m - (3 *
r);
405 double fitMax =
m + (3 *
r);
406 if (fitMin < adcThreshold) fitMin = adcThreshold;
407 if (fitMax > 300) fitMax = 300.;
408 h->Fit(
"AdcSpectrum",
"Q",
" ", fitMin, fitMax);
409 chi2 = AdcSpectrum->GetChisquare();
410 ndof = AdcSpectrum->GetNDF();
411 for (
int i = 0;
i < 4;
i++) {
412 par[
i] = AdcSpectrum->GetParameter(
i);
413 errpar[
i] = AdcSpectrum->GetParError(
i);
417 <<
"Mean=" <<
m <<
" "
418 <<
"RMS=" <<
r <<
" par 0 1 2 3 " <<
par[0] <<
" " <<
par[1] <<
" " <<
par[2] <<
" " <<
par[3] <<
endmsg;
424 fi.adc_par[0] =
par[1];
425 fi.adc_par[1] =
par[2];
426 fi.adc_err[0] = errpar[1];
427 fi.adc_err[1] = errpar[2];
428 if (std::abs(
ndof) == 0) {
431 fi.adc_chi2 =
chi2 /
static_cast<float>(
ndof);
437 int nbinsX =
h->GetNbinsX();
438 double sizeX =
h->GetBinWidth(1);
439 double oldSizeX = sizeX;
440 int RebinFactor =
static_cast<int>(10. / sizeX);
442 std::unique_ptr<TH1> hnew{
h->Rebin(RebinFactor,
"hnew")};
446 log <<
MSG::DEBUG <<
"nbinsx,sizex,rebinfactor=" << nbinsX <<
" " << sizeX <<
" " << RebinFactor <<
endmsg;
447 float minDeriv(9999.);
449 sizeX = hnew->GetBinWidth(1);
450 int newbins = hnew->GetNbinsX();
451 for (
int i = 0;
i <
np; ++
i) {
454 for (
int i = 0;
i < newbins - 1; ++
i) {
455 if (hnew->GetBinContent(
i) - hnew->GetBinContent(
i + 1) < minDeriv) {
456 minDeriv = hnew->GetBinContent(
i) - hnew->GetBinContent(
i + 1);
460 float t0guess = hnew->GetBinCenter(minDerivBin);
461 if (minDerivBin < newbins - 1) { t0guess += (hnew->GetBinCenter(minDerivBin + 1) - hnew->GetBinCenter(minDerivBin)) / 2.; }
467 int numOfBins(10), numOfBinsOffset(3);
469 if (minDerivBin > numOfBins + numOfBinsOffset) {
470 imin = minDerivBin - numOfBins - numOfBinsOffset;
471 imax = minDerivBin - numOfBinsOffset;
474 if (minDerivBin > numOfBinsOffset) {
475 imax = minDerivBin - numOfBinsOffset;
481 for (
int i = imin;
i <=
imax; ++
i) {
482 noise += hnew->GetBinContent(
i);
491 int t0bin = minDerivBin;
492 int ix1 = t0bin + (
int)(50 / sizeX);
493 int ix2 = t0bin + (
int)(500 / sizeX);
504 if (0 < ix1 && ix1 < newbins && 0 < ix2 && ix2 < newbins) {
505 float a1 = hnew->GetBinCenter(ix1);
506 float a2 = hnew->GetBinCenter(ix2);
507 float cont1 = hnew->GetBinContent(ix1);
508 float cont2 = hnew->GetBinContent(ix2);
509 if (cont1 > 0. && cont2 > 0.) {
510 float A1 =
std::exp(-(a1 - t0guess) / P3);
511 float A2 =
std::exp(-(a2 - t0guess) / P3);
513 P2 = (cont1 / cont2 - 1.) / (A1 - cont1 / cont2 * A2);
514 P1 = cont1 / (1 + P2 * A1);
515 P1 = P1 * oldSizeX / sizeX;
516 P2 = P2 * oldSizeX / sizeX;
518 log <<
MSG::DEBUG <<
"a1,a2 " << a1 <<
" " << a2 <<
" cont1,cont2 " << cont1 <<
" " << cont2 <<
" A1,A2 " << A1 <<
" "
530 return std::make_shared<T0CalibrationOutput>(
m_result.get());
536 if ((
int)(idtube / 100000000) == 9) {
537 int mezz = (idtube) % (900000000);
538 HistoId =
"time_mezz_" +
ts(mezz);
539 }
else if (idtube == 0) {
541 }
else if (idtube == 1) {
542 HistoId =
"time_ML1";
543 }
else if (idtube == 2) {
544 HistoId =
"time_ML2";
545 }
else if (idtube == 11) {
546 HistoId =
"time_ML1_series1";
547 }
else if (idtube == 12) {
548 HistoId =
"time_ML1_series2";
549 }
else if (idtube == 13) {
550 HistoId =
"time_ML1_series3";
551 }
else if (idtube == 21) {
552 HistoId =
"time_ML2_series1";
553 }
else if (idtube == 22) {
554 HistoId =
"time_ML2_series2";
555 }
else if (idtube == 23) {
556 HistoId =
"time_ML2_series3";
562 int tubeid = (nML * 1000) + (nL * 100) + nT;
575 for (
const std::unique_ptr<T0ClassicHistos> &
hist :
m_histos) {
576 if (
hist->time.get() == timeHis) {
586 std::unique_ptr<T0ClassicHistos>
histos = std::make_unique<T0ClassicHistos>();
588 std::string histonametdc;
589 std::string histonameadc;
593 if ((
int)(idtube / 100000000) == 9) {
594 int mezz = (idtube) % (900000000);
595 histonametdc =
"time_mezz_" +
ts(mezz);
596 histonameadc =
"charge_mezz_" +
ts(mezz);
597 }
else if (idtube == 0) {
598 histonametdc =
"time";
599 histonameadc =
"charge";
600 }
else if (idtube == 1) {
601 histonametdc =
"time_ML1";
602 histonameadc =
"charge_ML1";
603 }
else if (idtube == 2) {
604 histonametdc =
"time_ML2";
605 histonameadc =
"charge_ML2";
606 }
else if (idtube == 11) {
607 histonametdc =
"time_ML1_series1";
608 histonameadc =
"charge_ML1_series1";
609 }
else if (idtube == 12) {
610 histonametdc =
"time_ML1_series2";
611 histonameadc =
"charge_ML1_series2";
612 }
else if (idtube == 13) {
613 histonametdc =
"time_ML1_series3";
614 histonameadc =
"charge_ML1_series3";
615 }
else if (idtube == 21) {
616 histonametdc =
"time_ML2_series1";
617 histonameadc =
"charge_ML2_series1";
618 }
else if (idtube == 22) {
619 histonametdc =
"time_ML2_series2";
620 histonameadc =
"charge_ML2_series2";
621 }
else if (idtube == 23) {
622 histonametdc =
"time_ML2_series3";
623 histonameadc =
"charge_ML2_series3";
630 int tubeid = (nML * 1000) + (nL * 100) + nT;
655 m_result = std::make_unique<MdtTubeFitContainer>(*t0Input->
t0s());
656 m_result->setImplementation(
"T0CalibrationClassic");