22 : hDebugFile(nullptr), theVerbosityLevel(0), theSigma(10.) {
24 if (debugFileName !=
"")
25 hDebugFile =
new TFile(debugFileName.Data(),
"RECREATE");
37 hTimeBox->Rebin(
rebin);
40 if (hTimeBox->GetEntries() == 0) {
41 cout <<
"[DTTimeBoxFitter]***Error: the time box contains no entry!" << endl;
42 return make_pair(-1, -1);
45 if (hTimeBox->GetEntries() < 50000) {
59 TH1F* hTimeBoxForSeed = (TH1F*)hTimeBox->Clone();
61 getFitSeeds(hTimeBoxForSeed, xValue, xFitSigma, tBoxMax, xFitMin, xFitMax);
67 TF1* fIntGaus =
new TF1(
"IntGauss",
intGauss, xFitMin, xFitMax, 3);
68 fIntGaus->SetParName(0,
"Constant");
69 fIntGaus->SetParameter(0, tBoxMax);
70 fIntGaus->SetParName(1,
"Mean");
71 fIntGaus->SetParameter(1, xValue);
72 fIntGaus->SetParName(2,
"Sigma");
73 fIntGaus->SetParameter(2, xFitSigma);
74 fIntGaus->SetLineColor(kRed);
81 hTimeBox->Fit(fIntGaus,
option.c_str(),
"", xFitMin, xFitMax);
84 double mean = fIntGaus->GetParameter(
"Mean");
85 double sigma = fIntGaus->GetParameter(
"Sigma");
87 double chiSquare = fIntGaus->GetChisquare() / fIntGaus->GetNDF();
90 cout <<
" === Fit Results: " << endl;
91 cout <<
" Fitted mean = " <<
mean << endl;
92 cout <<
" Fitted sigma = " << sigma << endl;
95 return make_pair(
mean, sigma);
100 TH1F* hTBox,
double&
mean,
double& sigma,
double& tBoxMax,
double& xFitMin,
double& xFitMax) {
102 cout <<
" === Insert seeds for the Time Box fit:" << endl;
104 cout <<
"Inser the fit mean:" << endl;
109 tBoxMax = hTBox->GetMaximum();
112 xFitMin =
mean - 5. * sigma;
113 xFitMax =
mean + 5. * sigma;
116 cout <<
" Time Box Rising edge: " <<
mean << endl;
117 cout <<
" = Seeds and range for fit:" << endl;
118 cout <<
" Seed mean = " <<
mean << endl;
119 cout <<
" Seed sigma = " << sigma << endl;
120 cout <<
" Fitting from = " << xFitMin <<
" to " << xFitMax << endl << endl;
126 TH1F* hTBox,
double&
mean,
double& sigma,
double& tBoxMax,
double& xFitMin,
double& xFitMax) {
128 cout <<
" === Looking for fit seeds in Time Box:" << endl;
131 static const int tBoxWidth = 400;
133 int nBins = hTBox->GetNbinsX();
134 const int xMin = (
int)hTBox->GetXaxis()->GetXmin();
135 const int xMax = (
int)hTBox->GetXaxis()->GetXmax();
136 const int nEntries = (
int)hTBox->GetEntries();
141 const double threshold = binValue * nEntries / (double)(tBoxWidth * 3.);
143 cout <<
" Threshold for logic time box is (# entries): " <<
threshold << endl;
146 while (
threshold > hTBox->GetMaximum() / 2. && nRebins < 5) {
147 cout <<
" Rebinning!" << endl;
149 nBins = hTBox->GetNbinsX();
156 TString hLName = TString(hTBox->GetName()) +
"L";
157 TH1F hLTB(hLName.Data(),
"Logic Time Box",
nBins,
xMin,
xMax);
161 hLTB.SetBinContent(
i, 1);
167 vector<pair<int, int> > startAndLenght;
169 cout <<
" Look for rising and folling edges of logic time box: " << endl;
173 int diff = (
int)hLTB.GetBinContent(
j + 1) - (
int)hLTB.GetBinContent(
j);
178 cout <<
" >>>----" << endl;
179 cout <<
" bin: " <<
j <<
" is a rising edge" << endl;
181 }
else if (
diff == -1) {
182 startAndLenght.push_back(make_pair(
start, lenght));
184 cout <<
" bin: " <<
j <<
" is a falling edge, lenght is: " << lenght << endl;
185 cout <<
" <<<----" << endl;
189 }
else if (
diff == 0 && (
int)hLTB.GetBinContent(
j) == 1) {
195 cout <<
" Add macro intervals: " << endl;
197 vector<pair<int, int> > superIntervals;
198 for (
vector<pair<int, int> >::const_iterator
interval = startAndLenght.begin();
interval != startAndLenght.end();
200 pair<int, int> theInterval = (*interval);
201 vector<pair<int, int> >::const_iterator
next =
interval;
202 while (++
next != startAndLenght.end()) {
203 int gap = (*next).first - (theInterval.first + theInterval.second);
204 double gabInNs = binValue *
gap;
206 cout <<
" gap: " << gabInNs <<
"(ns)" << endl;
210 theInterval = make_pair(theInterval.first, theInterval.second +
gap + (*next).second);
211 superIntervals.push_back(theInterval);
213 cout <<
" Add interval, start: " << theInterval.first <<
" width: " << theInterval.second << endl;
219 copy(superIntervals.begin(), superIntervals.end(), back_inserter(startAndLenght));
223 cout <<
" Look for the best interval:" << endl;
227 for (
vector<pair<int, int> >::const_iterator stAndL = startAndLenght.begin(); stAndL != startAndLenght.end();
229 if (
abs((*stAndL).second - tBoxWidth) <
delta) {
230 delta =
abs((*stAndL).second - tBoxWidth);
231 beginning = (*stAndL).first;
232 tbWidth = (*stAndL).second;
234 cout <<
" Candidate: First: " << beginning <<
", width: " << tbWidth <<
", delta: " <<
delta << endl;
241 tBoxMax = hTBox->GetMaximum();
244 xFitMin =
mean - 5. * sigma;
245 xFitMax =
mean + 5. * sigma;
248 cout <<
" Time Box Rising edge: " <<
mean << endl;
249 cout <<
" Time Box Width: " << tbWidth * binValue << endl;
250 cout <<
" = Seeds and range for fit:" << endl;
251 cout <<
" Seed mean = " <<
mean << endl;
252 cout <<
" Seed sigma = " << sigma << endl;
253 cout <<
" Fitting from = " << xFitMin <<
" to " << xFitMax << endl << endl;
258 double media = par[1];
259 double sigma = par[2];
260 double var = (
x[0] - media) / (sigma *
sqrt(2.));
262 return 0.5 * par[0] * (1 + TMath::Erf(
var));
double intGauss(double *x, double *par)
Abs< T >::type abs(const T &t)
void getFitSeeds(TH1F *hTBox, double &mean, double &sigma, double &tBoxMax, double &xFitMin, double &xFitMax)
Automatically compute the seeds the range to be used for time box fit.
virtual ~DTTimeBoxFitter()
Destructor.
void getInteractiveFitSeeds(TH1F *hTBox, double &mean, double &sigma, double &tBoxMax, double &xFitMin, double &xFitMax)
Ask the user to provide the seeds.
DTTimeBoxFitter(const TString &debugFileName=TString(""))
Constructor.
unsigned int theVerbosityLevel
std::pair< double, double > fitTimeBox(TH1F *hTimeBox)
Fit the rising edge of the time box returning mean value and sigma (first and second respectively) ...