25 if(debugFileName !=
"")
hDebugFile =
new TFile(debugFileName.Data(),
"RECREATE");
42 hTimeBox->Rebin(
rebin);
45 if(hTimeBox->GetEntries() == 0) {
46 cout <<
"[DTTimeBoxFitter]***Error: the time box contains no entry!" << endl;
47 return make_pair(-1, -1);
50 if(hTimeBox->GetEntries() < 50000) {
64 TH1F *hTimeBoxForSeed = (TH1F*) hTimeBox->Clone();
66 getFitSeeds(hTimeBoxForSeed, xValue, xFitSigma, tBoxMax, xFitMin, xFitMax);
72 TF1 *fIntGaus =
new TF1(
"IntGauss",
intGauss, xFitMin, xFitMax, 3);
73 fIntGaus->SetParName(0,
"Constant");
74 fIntGaus->SetParameter(0, tBoxMax);
75 fIntGaus->SetParName(1,
"Mean");
76 fIntGaus->SetParameter(1, xValue);
77 fIntGaus->SetParName(2,
"Sigma");
78 fIntGaus->SetParameter(2, xFitSigma);
79 fIntGaus->SetLineColor(kRed);
87 hTimeBox->Fit(fIntGaus, option.c_str(),
"",xFitMin, xFitMax);
90 double mean = fIntGaus->GetParameter(
"Mean");
91 double sigma = fIntGaus->GetParameter(
"Sigma");
93 double chiSquare = fIntGaus->GetChisquare()/fIntGaus->GetNDF();
96 cout <<
" === Fit Results: " << endl;
97 cout <<
" Fitted mean = " << mean << endl;
98 cout <<
" Fitted sigma = " << sigma << endl;
99 cout <<
" Reduced Chi Square = " << chiSquare << endl;
101 return make_pair(mean, sigma);
108 double& xFitMin,
double& xFitMax) {
110 cout <<
" === Insert seeds for the Time Box fit:" << endl;
112 cout <<
"Inser the fit mean:" << endl;
117 tBoxMax = hTBox->GetMaximum();
120 xFitMin = mean-5.*
sigma;
121 xFitMax = mean+5.*
sigma;
124 cout <<
" Time Box Rising edge: " << mean << endl;
125 cout <<
" = Seeds and range for fit:" << endl;
126 cout <<
" Seed mean = " << mean << endl;
127 cout <<
" Seed sigma = " << sigma << endl;
128 cout <<
" Fitting from = " << xFitMin <<
" to " << xFitMax << endl << endl;
135 double& xFitMin,
double& xFitMax) {
137 cout <<
" === Looking for fit seeds in Time Box:" << endl;
141 static const int tBoxWidth = 400;
143 int nBins = hTBox->GetNbinsX();
144 const int xMin = (
int)hTBox->GetXaxis()->GetXmin();
145 const int xMax = (
int)hTBox->GetXaxis()->GetXmax();
146 const int nEntries = (
int)hTBox->GetEntries();
148 double binValue = (double)(xMax-xMin)/(double)nBins;
151 const double threshold = binValue*nEntries/(double)(tBoxWidth*3.);
153 cout <<
" Threshold for logic time box is (# entries): " << threshold << endl;
156 while(threshold > hTBox->GetMaximum()/2. && nRebins < 5) {
157 cout <<
" Rebinning!" << endl;
159 nBins = hTBox->GetNbinsX();
160 binValue = (double)(xMax-xMin)/(double)nBins;
165 TString hLName = TString(hTBox->GetName())+
"L";
166 TH1F hLTB(hLName.Data(),
"Logic Time Box", nBins,
xMin,
xMax);
168 for(
int i = 1;
i <= nBins;
i++) {
170 hLTB.SetBinContent(
i, 1);
175 vector< pair<int, int> > startAndLenght;
177 cout <<
" Look for rising and folling edges of logic time box: " << endl;
180 for(
int j = 1; j < nBins;j++) {
181 int diff = (
int)hLTB.GetBinContent(j+1)-(
int)hLTB.GetBinContent(j);
186 cout <<
" >>>----" << endl;
187 cout <<
" bin: " << j <<
" is a rising edge" << endl;
189 }
else if(diff == -1) {
190 startAndLenght.push_back(make_pair(start, lenght));
192 cout <<
" bin: " << j <<
" is a falling edge, lenght is: " << lenght << endl;
193 cout <<
" <<<----" << endl;
197 }
else if(diff == 0 && (
int)hLTB.GetBinContent(j) == 1) {
203 cout <<
" Add macro intervals: " << endl;
205 vector< pair<int, int> > superIntervals;
206 for(vector< pair<int, int> >::const_iterator interval = startAndLenght.begin();
207 interval != startAndLenght.end();
209 pair<int, int> theInterval = (*interval);
210 vector< pair<int, int> >::const_iterator
next = interval;
211 while(++next != startAndLenght.end()) {
212 int gap = (*next).first - (theInterval.first+theInterval.second);
213 double gabInNs = binValue*gap;
215 cout <<
" gap: " << gabInNs <<
"(ns)" << endl;
219 theInterval = make_pair(theInterval.first, theInterval.second+gap+(*next).second);
220 superIntervals.push_back(theInterval);
222 cout <<
" Add interval, start: " << theInterval.first
223 <<
" width: " << theInterval.second << endl;
229 copy(superIntervals.begin(), superIntervals.end(), back_inserter(startAndLenght));
233 cout <<
" Look for the best interval:" << endl;
237 for(vector< pair<int, int> >::const_iterator stAndL = startAndLenght.begin();
238 stAndL != startAndLenght.end();
240 if(
abs((*stAndL).second - tBoxWidth) <
delta) {
241 delta =
abs((*stAndL).second - tBoxWidth);
242 beginning = (*stAndL).first;
243 tbWidth = (*stAndL).second;
245 cout <<
" Candidate: First: " << beginning
246 <<
", width: " << tbWidth
247 <<
", delta: " << delta << endl;
251 mean = xMin + beginning*binValue;
254 tBoxMax = hTBox->GetMaximum();
257 xFitMin = mean-5.*
sigma;
258 xFitMax = mean+5.*
sigma;
261 cout <<
" Time Box Rising edge: " << mean << endl;
262 cout <<
" Time Box Width: " << tbWidth*binValue << endl;
263 cout <<
" = Seeds and range for fit:" << endl;
264 cout <<
" Seed mean = " << mean << endl;
265 cout <<
" Seed sigma = " << sigma << endl;
266 cout <<
" Fitting from = " << xFitMin <<
" to " << xFitMax << endl << endl;
273 double media = par[1];
274 double sigma = par[2];
275 double var = (x[0]-media)/(sigma*
sqrt(2.));
277 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) ...