14#include <fairlogger/Logger.h>
40 mHistoChTimeSlewingAll =
new TH2F(
"hTOFchTimeSlewingAll",
";tot (ns);t - t_{exp} - t_{offset} (ps)", 5000, 0., 250., 1000, -24400., 24400.);
49 delete mHistoLHCphase;
51 delete mHistoChTimeSlewingAll;
54void CalibTOF::attachInputTrees()
58 if (!mTreeCollectedCalibInfoTOF) {
59 LOG(fatal) <<
"Input tree with collected TOF calib infos is not set";
62 if (!mTreeCollectedCalibInfoTOF->GetBranch(mCollectedCalibInfoTOFBranchName.data())) {
63 LOG(fatal) <<
"Did not find collected TOF calib info branch " << mCollectedCalibInfoTOFBranchName <<
" in the input tree";
77 LOG(error) <<
"Initialization was already done";
92 mInitialCalibChannelOffset[
i] = gRandom->Rndm() * 25000 - 12500;
102 mOutputTree->Branch(
"mLHCphaseObj", &mLHCphaseObj);
103 mOutputTree->Branch(
"mTimeSlewingObj", &mTimeSlewingObj);
108 LOG(error) <<
"Output tree is not attached, matched tracks will not be stored";
112 int nbinsLHCphase = TMath::Min(1000,
int((mMaxTimestamp - mMinTimestamp) / 300) + 1);
113 if (nbinsLHCphase < 1000) {
114 mMaxTimestamp = mMinTimestamp + nbinsLHCphase * 300;
116 mHistoLHCphase =
new TH2F(
"hLHCphase",
";clock offset (ps); timestamp (s)", 1000, -24400, 24400, nbinsLHCphase, mMinTimestamp, mMaxTimestamp);
119 mCalibTOFapi.
setURL(mCCDBpath.c_str());
130 Int_t currTOFInfoTreeEntry = -1;
132 std::vector<o2::dataformats::CalibInfoTOFshort>* localCalibInfoTOF =
nullptr;
133 TFile fOpenLocally(mTreeCollectedCalibInfoTOF->GetCurrentFile()->GetName());
134 TTree* localTree = (TTree*)fOpenLocally.Get(mTreeCollectedCalibInfoTOF->GetName());
137 LOG(fatal) <<
"tree " << mTreeCollectedCalibInfoTOF->GetName() <<
" not found in " << mTreeCollectedCalibInfoTOF->GetCurrentFile()->GetName();
140 localTree->SetBranchAddress(mCollectedCalibInfoTOFBranchName.data(), &localCalibInfoTOF);
143 LOG(fatal) <<
"init() was not done yet";
150 while (loadTOFCollectedCalibInfo(localTree, currTOFInfoTreeEntry)) {
151 fillLHCphaseCalibInput(localCalibInfoTOF);
158 std::vector<o2::dataformats::CalibInfoTOFshort>* calibTimePad[
NPADSPERSTEP];
160 histoChOffsetTemp[ipad] =
new TH1F(Form(
"OffsetTemp_Sec%02d_Pad%04d", sector, ipad), Form(
"Sector %02d (pad = %04d);channel offset (ps)", sector, ipad), 1000, -24400, 24400);
162 calibTimePad[ipad] =
new std::vector<o2::dataformats::CalibInfoTOFshort>;
164 calibTimePad[ipad] =
nullptr;
168 TF1* funcChOffset =
new TF1(Form(
"fTOFchOffset_%02d", sector),
"[0]*TMath::Gaus((x-[1])*(x-[1] < 12500 && x-[1] > -12500) + (x-[1]+25000)*(x-[1] < -12500) + (x-[1]-25000)*(x-[1] > 12500),0,[2])*(x > -12500 && x < 12500)", -12500, 12500);
169 funcChOffset->SetParLimits(1, -12500, 12500);
170 funcChOffset->SetParLimits(2, 50, 2000);
172 TH2F* histoChTimeSlewingTemp =
new TH2F(Form(
"hTOFchTimeSlewingTemp_%02d", sector), Form(
"Sector %02d;tot (ns);t - t_{exp} - t_{offset} (ps)", sector), 5000, 0., 250., 1000, -24400., 24400.);
180 for (
int ich = startLoop; ich < endLoop; ich +=
NPADSPERSTEP) {
184 resetChannelLevelHistos(histoChOffsetTemp, histoChTimeSlewingTemp, calibTimePad);
185 printf(
"strip %i\n", ich / 96);
186 currTOFInfoTreeEntry = ich - 1;
190 while (loadTOFCollectedCalibInfo(localTree, currTOFInfoTreeEntry)) {
193 fillChannelCalibInput(localCalibInfoTOF, mInitialCalibChannelOffset[ich + ipad], ipad, histoChOffsetTemp[ipad], calibTimePad[ipad]);
198 currTOFInfoTreeEntry = entryNext;
202 TFile* fout =
nullptr;
204 fout =
new TFile(Form(
"timeslewingTOF%06i.root", ich / 96),
"RECREATE");
208 if (histoChOffsetTemp[ipad]->GetEntries() > 30) {
209 float fractionUnderPeak = doChannelCalibration(ipad, histoChOffsetTemp[ipad], funcChOffset);
210 mCalibChannelOffset[ich + ipad] = funcChOffset->GetParameter(1) + mInitialCalibChannelOffset[ich + ipad];
215 mTimeSlewingObj->
setSigmaPeak(sector, channelInSector, std::abs(funcChOffset->GetParameter(2)));
220 histoChTimeSlewingTemp->Reset();
221 fillChannelTimeSlewingCalib(mCalibChannelOffset[ich + ipad], ipad, histoChTimeSlewingTemp, calibTimePad[ipad]);
223 histoChTimeSlewingTemp->SetName(Form(
"TimeSlewing_Sec%02d_Pad%04d", sector, channelInSector));
224 histoChTimeSlewingTemp->SetTitle(Form(
"Sector %02d (pad = %04d)", sector, channelInSector));
225 TGraphErrors* gTimeVsTot =
processSlewing(histoChTimeSlewingTemp, 1, funcChOffset);
227 if (gTimeVsTot && gTimeVsTot->GetN()) {
228 for (
int itot = 0; itot < gTimeVsTot->GetN(); itot++) {
229 mTimeSlewingObj->
addTimeSlewingInfo(ich + ipad, gTimeVsTot->GetX()[itot], gTimeVsTot->GetY()[itot] + mCalibChannelOffset[ich + ipad]);
235 if (mDebugMode && gTimeVsTot && gTimeVsTot->GetN() && fout) {
238 gTimeVsTot->SetName(Form(
"pad_%02d_%02d_%02d", sector, istrip, ipad %
o2::tof::Geo::NPADS));
254 delete histoChOffsetTemp[ipad];
255 if (calibTimePad[ipad]) {
256 delete calibTimePad[ipad];
259 delete histoChTimeSlewingTemp;
263 fOpenLocally.Close();
266 printf(
"Timing (%i):\n", sector);
278 std::map<std::string, std::string> metadataLHCphase;
279 mCalibTOFapi.
writeLHCphase(mLHCphaseObj, metadataLHCphase, (uint64_t)mMinTimestamp * 1000, (uint64_t)mMaxTimestamp * 1000);
282 std::map<std::string, std::string> metadataChannelCalib;
283 mCalibTOFapi.
writeTimeSlewingParam(mTimeSlewingObj, metadataChannelCalib, (uint64_t)mMinTimestamp * 1000);
293 LOG(info) <<
"****** component for calibration of TOF channels ******";
295 LOG(info) <<
"init is not done yet - nothing to print";
299 LOG(info) <<
"**********************************************************************";
303bool CalibTOF::loadTOFCollectedCalibInfo(TTree* localTree,
int& currententry,
int increment)
308 currententry += increment;
309 while (currententry < localTree->GetEntries()) {
312 localTree->GetEntry(currententry);
317 currententry -= increment;
324void CalibTOF::fillLHCphaseCalibInput(std::vector<o2::dataformats::CalibInfoTOFshort>* calibinfotof)
330 static double bc_inv = 1. /
bc;
332 for (
auto infotof = calibinfotof->begin(); infotof != calibinfotof->end(); infotof++) {
333 double dtime = infotof->getDeltaTimePi();
334 dtime -= (
int(dtime * bc_inv + 5.5) - 5) *
bc;
336 mHistoLHCphase->Fill(dtime, infotof->getTimestamp());
341void CalibTOF::doLHCPhaseCalib()
346 if (!mFuncLHCphase) {
347 mFuncLHCphase =
new TF1(
"fLHCphase",
"gaus");
351 for (
int ifit = ifit0; ifit <= mHistoLHCphase->GetNbinsY(); ifit++) {
352 TH1D* htemp = mHistoLHCphase->ProjectionX(
"htemp", ifit0, ifit);
353 if (htemp->GetEntries() < 300) {
359 int res =
FitPeak(mFuncLHCphase, htemp, 500., 3., 2.,
"LHCphase");
364 mLHCphaseObj->
addLHCphase(mHistoLHCphase->GetYaxis()->GetBinLowEdge(ifit0), mFuncLHCphase->GetParameter(1));
370void CalibTOF::fillChannelCalibInput(std::vector<o2::dataformats::CalibInfoTOFshort>* calibinfotof,
float offset,
int ipad, TH1F* histo, std::vector<o2::dataformats::CalibInfoTOFshort>* calibTimePad)
376 static double bc_inv = 1. /
bc;
378 for (
auto infotof = calibinfotof->begin(); infotof != calibinfotof->end(); infotof++) {
379 double dtime = infotof->getDeltaTimePi() -
offset;
380 dtime -= (
int(dtime * bc_inv + 5.5) - 5) *
bc;
384 calibTimePad->push_back(*infotof);
390void CalibTOF::fillChannelTimeSlewingCalib(
float offset,
int ipad, TH2F* histo, std::vector<o2::dataformats::CalibInfoTOFshort>* calibTimePad)
396 static double bc_inv = 1. /
bc;
398 for (
auto infotof = calibTimePad->begin(); infotof != calibTimePad->end(); infotof++) {
399 double dtime = infotof->getDeltaTimePi() -
offset;
401 dtime -= (
int(dtime * bc_inv + 5.5) - 5) *
bc;
403 histo->Fill(TMath::Min(
double(infotof->getTot()), 249.9), dtime);
404 mHistoChTimeSlewingAll->Fill(infotof->getTot(), dtime);
409float CalibTOF::doChannelCalibration(
int ipad, TH1F* histo,
TF1* funcChOffset)
413 float integral = histo->Integral();
418 int resfit =
FitPeak(funcChOffset, histo, 500., 3., 2.,
"ChannelOffset");
425 float mean = funcChOffset->GetParameter(1);
426 float sigma = funcChOffset->GetParameter(2);
427 float intmin =
mean - 5 * sigma;
428 float intmax =
mean + 5 * sigma;
434 float addduetoperiodicity = 0;
435 if (intmin < -12500) {
436 intmin2 = intmin + 25000;
439 if (intmin2 > intmax) {
440 int binmin2 = histo->FindBin(intmin2);
441 int binmax2 = histo->FindBin(intmax2);
442 addduetoperiodicity = histo->Integral(binmin2, binmax2);
444 }
else if (intmax > 12500) {
445 intmax2 = intmax - 25000;
448 if (intmax2 < intmin) {
449 int binmin2 = histo->FindBin(intmin2);
450 int binmax2 = histo->FindBin(intmax2);
451 addduetoperiodicity = histo->Integral(binmin2, binmax2);
455 int binmin = histo->FindBin(intmin);
456 int binmax = histo->FindBin(intmax);
461 if (binmax > histo->GetNbinsX()) {
462 binmax = histo->GetNbinsX();
465 return (histo->Integral(binmin, binmax) + addduetoperiodicity) / integral;
469void CalibTOF::resetChannelLevelHistos(TH1F* histoOffset[NPADSPERSTEP], TH2F* histoTimeSlewing, std::vector<o2::dataformats::CalibInfoTOFshort>* calibTimePad[NPADSPERSTEP])
475 histoOffset[ipad]->Reset();
476 if (calibTimePad[ipad]) {
477 calibTimePad[ipad]->clear();
480 histoTimeSlewing->Reset();
488 TH1D* hpx = histo->ProjectionX(
"hpx");
491 Int_t minBin = hpx->FindFirstBinAbove(0);
492 Int_t maxBin = hpx->FindLastBinAbove(0);
493 Float_t minTOT = hpx->GetBinLowEdge(minBin);
494 Float_t maxTOT = hpx->GetBinLowEdge(maxBin + 1);
499 Float_t tot[10000], toterr[10000];
500 Float_t mean[10000], meanerr[10000];
501 Float_t sigma[10000], vertexSigmaerr[10000];
502 for (Int_t ibin = minBin; ibin <= maxBin; ibin++) {
505 Int_t startBin = ibin;
507 while (hpx->Integral(startBin, endBin) < 300) {
508 if (startBin == 1 && forceZero) {
511 if (endBin < maxBin) {
513 }
else if (startBin > minBin) {
519 if (hpx->Integral(startBin, endBin) <= 0) {
525 TH1D* hpy = histo->ProjectionY(
"hpy", startBin, endBin);
528 hpx->GetXaxis()->SetRange(startBin, endBin);
529 tot[nPoints] = hpx->GetMean();
530 toterr[nPoints] = hpx->GetMeanError();
533 if (
FitPeak(fitFunc, hpy, 500., 3., 2., Form(
"TotBins%04d_%04d", startBin, endBin), histo) != 0) {
538 mean[nPoints] = fitFunc->GetParameter(1);
539 meanerr[nPoints] = fitFunc->GetParError(1);
547 if (meanerr[nPoints] < 100.) {
564 TGraphErrors* gSlewing =
new TGraphErrors(nPoints, tot, mean, toterr, meanerr);
577 Double_t fitCent =
h->GetBinCenter(
h->GetMaximumBin());
578 if (fitCent < -12500) {
579 printf(
"fitCent = %f (%s). This is wrong, please check!\n", fitCent,
h->GetName());
582 if (fitCent > 12500) {
583 printf(
"fitCent = %f (%s). This is wrong, please check!\n", fitCent,
h->GetName());
586 Double_t fitMin = fitCent - nSigmaMin * startSigma;
587 Double_t fitMax = fitCent + nSigmaMax * startSigma;
588 if (fitMin < -12500) {
591 if (fitMax > 12500) {
594 fitFunc->SetParLimits(1, fitMin, fitMax);
595 fitFunc->SetParameter(0, 100);
596 fitFunc->SetParameter(1, fitCent);
597 fitFunc->SetParameter(2, startSigma);
598 Int_t fitres =
h->Fit(fitFunc,
"WWq0",
"", fitMin, fitMax);
604 for (Int_t
i = 0;
i < 3;
i++) {
605 fitCent = fitFunc->GetParameter(1);
606 fitMin = fitCent - nSigmaMin * std::abs(fitFunc->GetParameter(2));
607 fitMax = fitCent + nSigmaMax * std::abs(fitFunc->GetParameter(2));
608 if (fitMin < -12500) {
611 if (fitMax > 12500) {
614 if (fitMin >= fitMax) {
615 printf(
"%s) step%i: %f %f\n ",
h->GetName(),
i, fitMin, fitMax);
617 fitFunc->SetParLimits(1, fitMin, fitMax);
618 fitres =
h->Fit(fitFunc,
"q0",
"", fitMin, fitMax);
620 printf(
"%s) step%i: %f in %f - %f\n ",
h->GetName(),
i, fitCent, fitMin, fitMax);
622 if (mDebugMode > 1) {
623 char*
filename = Form(
"TOFDBG_%s.root",
h->GetName());
625 filename = Form(
"TOFDBG_%s_%s.root", hdbg->GetName(), debuginfo);
640 if (mDebugMode > 1 && fitFunc->GetParError(1) > 100) {
641 char*
filename = Form(
"TOFDBG_%s.root",
h->GetName());
643 filename = Form(
"TOFDBG_%s_%s.root", hdbg->GetName(), debuginfo);
660 TFile*
f = TFile::Open(
name);
662 LOG(error) <<
"File " <<
name <<
"not found (merging skept)";
665 TTree* t = (TTree*)
f->Get(mOutputTree->GetName());
667 LOG(error) <<
"Tree " << mOutputTree->GetName() <<
"not found in " <<
name <<
" (merging skept)";
677 t->SetBranchAddress(
"mLHCphaseObj", &LHCphaseObj);
678 t->SetBranchAddress(
"mTimeSlewingObj", &timeSlewingObj);
682 *mTimeSlewingObj += *timeSlewingObj;
683 *mLHCphaseObj += *LHCphaseObj;
693 TH1F* hsigmapeak =
new TH1F(
"hsigmapeak",
";#sigma_{peak} (ps)", 1000, 0, 1000);
694 TH1F* hfractionpeak =
new TH1F(
"hfractionpeak",
";fraction under peak", 1001, 0, 1.01);
697 float sigmaMin, sigmaMax, fractionMin;
699 int nActiveChannels = 0;
700 int nGoodChannels = 0;
702 TF1* fFuncSigma =
new TF1(
"fFuncSigma",
"TMath::Gaus(x,[1],[2])*[0]*(x<[1]) + TMath::Gaus(x,[1],[3])*[0]*(x>[1])");
703 fFuncSigma->SetParameter(0, 1000);
704 fFuncSigma->SetParameter(1, 200);
705 fFuncSigma->SetParameter(2, 200);
706 fFuncSigma->SetParameter(3, 200);
708 TF1* fFuncFraction =
new TF1(
"fFuncFraction",
"TMath::Gaus(x,[1],[2])*[0]*(x<[1]) + TMath::Gaus(x,[1],[3])*[0]*(x>[1])");
709 fFuncFraction->SetParameter(0, 1000);
710 fFuncFraction->SetParameter(1, 0.8);
711 fFuncFraction->SetParameter(2, 0.1);
712 fFuncFraction->SetParameter(3, 0.1);
717 hfractionpeak->Reset();
722 for (
int i = 0;
i < 18;
i++) {
735 hsigmapeak->Fit(fFuncSigma,
"WWq0");
736 hfractionpeak->Fit(fFuncFraction,
"WWq0");
738 sigmaMin = fFuncSigma->GetParameter(1) - mNsigmaSigmaProblematicCut * std::abs(fFuncSigma->GetParameter(2));
739 sigmaMax = fFuncSigma->GetParameter(1) + mNsigmaSigmaProblematicCut * std::abs(fFuncSigma->GetParameter(3));
740 fractionMin = fFuncFraction->GetParameter(1) - mNsigmaFractionProblematicCut * std::abs(fFuncFraction->GetParameter(2));
745 for (
int i = 0;
i < 18;
i++) {
763 Printf(
"Check for TOF problematics: nActiveChannels=%d - nGoodChannels=%d - fractionGood = %f",
int(nActiveChannels),
int(nGoodChannels), nGoodChannels * 1. / nActiveChannels);
Header of the General Run Parameters object.
Header to collect LHC related constants.
Class for time synchronization of RawReader instances.
static constexpr int NPADSPERSTEP
Int_t FitPeak(TF1 *fitFunc, TH1 *h, Float_t startSigma, Float_t nSigmaMin, Float_t nSigmaMax, const char *debuginfo="", TH2 *hdbg=nullptr)
void merge(const char *name)
TGraphErrors * processSlewing(TH2F *histo, Bool_t forceZero, TF1 *fitFunc)
void run(int flag, int sector=-1)
void init()
set tree/chain containing TOF calib info
~CalibTOF()
calibrate using the provided input
void fillOutput(int flag=kLHCphase|kChannelOffset|kChannelTimeSlewing)
perform all initializations
void flagProblematics()
problematics are flagged with negative values for frationUnderPeak: -100 empty channels,...
void writeLHCphase(LhcPhase *phase, std::map< std::string, std::string > metadataLHCphase, uint64_t minTimeSTamp, uint64_t maxTimeStamp)
void writeTimeSlewingParam(SlewParam *param, std::map< std::string, std::string > metadataChannelCalib, uint64_t minTimeSTamp, uint64_t maxTimeStamp=0)
void setURL(const std::string url)
static constexpr Int_t NSTRIPXSECTOR
static constexpr Int_t NPADS
static constexpr Int_t NPADSXSECTOR
static constexpr int NCHANNELS
static constexpr Int_t NPADX
GLuint const GLchar * name
double mean(std::vector< double >::const_iterator first, std::vector< double >::const_iterator last)
constexpr double LHCRFFreq
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"