15GPeak::GPeak(Double_t cent, Double_t xlow, Double_t xhigh, Option_t*)
20 if(cent > xhigh || cent < xlow) {
23 std::swap(xlow, cent);
26 std::swap(xlow, xhigh);
29 std::swap(cent, xhigh);
33 TF1::SetRange(xlow, xhigh);
37 fBGFit.SetLineColor(kBlack);
39 SetName(Form(
"Chan%d_%d_to_%d",
static_cast<Int_t
>(cent),
static_cast<Int_t
>(xlow),
static_cast<Int_t
>(xhigh)));
41 TF1::SetParameter(
"centroid", cent);
46 fBGFit.SetBit(TObject::kCanDelete,
false);
50GPeak::GPeak(Double_t cent, Double_t xlow, Double_t xhigh, TF1* bg, Option_t*)
54 if(cent > xhigh || cent < xlow) {
57 std::swap(xlow, cent);
60 std::swap(xlow, xhigh);
63 std::swap(cent, xhigh);
66 TF1::SetRange(xlow, xhigh);
67 SetName(Form(
"Chan%d_%d_to_%d",
static_cast<Int_t
>(cent),
static_cast<Int_t
>(xlow),
static_cast<Int_t
>(xhigh)));
69 TF1::SetParameter(
"centroid", cent);
80 fBGFit.SetLineColor(kBlack);
141 if(fithist ==
nullptr) {
142 std::cout <<
"No histogram is associated yet, no initial guesses made" << std::endl;
148 GetRange(xlow, xhigh);
151 Int_t binlow = fithist->GetXaxis()->FindBin(xlow);
152 Int_t binhigh = fithist->GetXaxis()->FindBin(xhigh);
154 Double_t highy = fithist->GetBinContent(binlow);
155 Double_t lowy = fithist->GetBinContent(binhigh);
156 for(
int x = 1; x < 5; x++) {
157 highy += fithist->GetBinContent(binlow - x);
158 lowy += fithist->GetBinContent(binhigh + x);
166 std::swap(lowy, highy);
169 double largestx = 0.0;
170 double largesty = 0.0;
172 for(; i <= binhigh; i++) {
173 if(fithist->GetBinContent(i) > largesty) {
174 largesty = fithist->GetBinContent(i);
175 largestx = fithist->GetXaxis()->GetBinCenter(i);
189 TF1::SetParLimits(0, 0, largesty * 2);
190 TF1::SetParLimits(1, xlow, xhigh);
191 TF1::SetParLimits(2, 0.1, xhigh - xlow);
192 TF1::SetParLimits(3, 0.0, 40);
193 TF1::SetParLimits(4, 0.01, 5);
194 double step = ((highy - lowy) / largesty) * 50;
197 TF1::SetParLimits(5, 0.0, step + step);
199 double offset = lowy;
200 TF1::SetParLimits(6, offset - 0.5 * offset, offset + offset);
203 TF1::SetParameter(0, largesty);
204 TF1::SetParameter(1, largestx);
205 TF1::SetParameter(2, (largestx * .01) / 2.35);
206 TF1::SetParameter(3, 5.);
207 TF1::SetParameter(4, 1.);
208 TF1::SetParameter(5, step);
209 TF1::SetParameter(6, offset);
211 TF1::SetParError(0, 0.10 * largesty);
212 TF1::SetParError(1, 0.25);
213 TF1::SetParError(2, 0.10 * ((largestx * .01) / 2.35));
214 TF1::SetParError(3, 5);
215 TF1::SetParError(4, 0.5);
216 TF1::SetParError(5, 0.10 * step);
217 TF1::SetParError(6, 0.10 * offset);
225 if(fithist ==
nullptr) {
228 TString options = opt;
233 TVirtualFitter::SetMaxIterations(100000);
235 bool quiet = options.Contains(
"q");
236 bool verbose = options.Contains(
"v");
237 bool retryFit = options.Contains(
"retryfit");
238 options.ReplaceAll(
"retryfit",
"");
239 if(!verbose && !quiet) { options.Append(
"q"); }
241 if(fithist->GetSumw2()->fN != fithist->GetNbinsX() + 2) {
245 TFitResultPtr fitres = fithist->Fit(
this, Form(
"%sLRS", options.Data()));
247 if(verbose) { std::cout <<
"chi^2/NDF = " << GetChisquare() /
static_cast<double>(GetNDF()) << std::endl; }
249 if(!fitres.Get()->IsValid()) {
250 if(!quiet) { std::cout <<
RED <<
"fit has failed, trying refit... " <<
RESET_COLOR << std::endl; }
251 fithist->GetListOfFunctions()->Last()->Delete();
252 fitres = fithist->Fit(
this, Form(
"%sLRSME", options.Data()));
254 if(fitres.Get()->IsValid()) {
257 std::cout <<
DRED <<
" refit also failed :( " <<
RESET_COLOR << std::endl;
266 if(!quiet) { std::cout <<
GREEN <<
"Re-fitting with released parameters (without any limits):" <<
RESET_COLOR << std::endl; }
267 for(
int i = 0; i < GetNpar(); ++i) {
270 fitres = fithist->Fit(
this, Form(
"%sLRSM", options.Data()));
273 if(!quiet) { std::cout <<
YELLOW <<
"Re-fitting with \"E\" option to get better error estimation using Minos technique." <<
RESET_COLOR << std::endl; }
274 fitres = fithist->Fit(
this, Form(
"%sLRSME", options.Data()));
281 TF1::GetRange(xlow, xhigh);
283 std::array<double, 5> bgpars;
284 bgpars[0] = TF1::GetParameters()[0];
285 bgpars[1] = TF1::GetParameters()[1];
286 bgpars[2] = TF1::GetParameters()[2];
287 bgpars[3] = TF1::GetParameters()[5];
288 bgpars[4] = TF1::GetParameters()[6];
290 fBGFit.SetParameters(bgpars.data());
292 fChi2 = GetChisquare();
295 fArea = Integral(xlow, xhigh) / fithist->GetBinWidth(1);
296 double bgArea =
fBGFit.Integral(xlow, xhigh) / fithist->GetBinWidth(1);
300 std::swap(xlow, xhigh);
302 fSum = fithist->Integral(fithist->GetXaxis()->FindBin(xlow),
303 fithist->GetXaxis()->FindBin(xhigh));
304 if(verbose) { std::cout <<
"sum between markers: " <<
fSum << std::endl; }
307 if(verbose) { std::cout <<
"sum after subtraction: " <<
fSum << std::endl; }
313 Double_t range_low = 0.;
314 Double_t range_high = 0.;
315 GetRange(range_low, range_high);
317 auto* tmppeak =
new GPeak;
319 tmppeak->SetParameter(
"step", 0.0);
320 tmppeak->SetParameter(
"A", 0.0);
321 tmppeak->SetParameter(
"B", 0.0);
322 tmppeak->SetParameter(
"C", 0.0);
323 tmppeak->SetParameter(
"bg_offset", 0.0);
324 tmppeak->SetRange(range_low, range_high);
325 tmppeak->SetName(
"tmppeak");
328 TMatrixDSym CovMat = fitres->GetCovarianceMatrix();
331 fDArea = (tmppeak->IntegralError(xlow, xhigh, tmppeak->GetParameters(), CovMat.GetMatrixArray())) / fithist->GetBinWidth(1);
336 if(!quiet) {
Print(); }
338 Copy(*fithist->GetListOfFunctions()->FindObject(GetName()));
339 fithist->GetListOfFunctions()->Add(
fBGFit.Clone());
382 if(
hist ==
nullptr) {
385 if(
fChi2 < 0.000000001) {
386 std::cout <<
"No fit performed" << std::endl;
391 GetRange(xlow, xhigh);
392 Int_t nbins =
hist->GetXaxis()->GetNbins();
393 auto* res =
new Double_t[nbins];
394 auto* bin =
new Double_t[nbins];
396 for(
int i = 1; i <= nbins; i++) {
397 if(
hist->GetBinCenter(i) <= xlow ||
hist->GetBinCenter(i) >= xhigh) {
400 res[points] = (
hist->GetBinContent(i) - Eval(
hist->GetBinCenter(i))) + GetParameter(
"Height") / 2;
401 bin[points] =
hist->GetBinCenter(i);
405 auto* residuals =
new TGraph(points, bin, res);
406 residuals->Draw(
"*AC");