GRSISort "v4.0.0.5"
An extension of the ROOT analysis Framework
Loading...
Searching...
No Matches
GGaus.cxx
Go to the documentation of this file.
1#include "GGaus.h"
2#include "TGraph.h"
3#include "TVirtualFitter.h"
4#include "TFitResult.h"
5#include "TFitResultPtr.h"
6
7#include "Globals.h"
8#include "GRootFunctions.h"
9#include "GCanvas.h"
10
11GGaus::GGaus(Double_t xlow, Double_t xhigh, Option_t*)
12 : TF1("gausbg", "gaus(0)+pol1(3)", xlow, xhigh), fBGFit("background", "pol1", xlow, xhigh)
13{
14 Clear("");
15 if(xlow > xhigh) {
16 std::swap(xlow, xhigh);
17 }
18
19 TF1::SetRange(xlow, xhigh);
20
21 fBGFit.SetNpx(1000);
22 fBGFit.SetLineStyle(2);
23 fBGFit.SetLineColor(kBlack);
24
25 // Changing the name here causes an infinite loop when starting the FitEditor
26 // SetName(Form("gaus_%d_to_%d",(Int_t)(xlow),(Int_t)(xhigh)));
27 InitNames();
28}
29
30GGaus::GGaus(Double_t xlow, Double_t xhigh, TF1* bg, Option_t*) : TF1("gausbg", "gaus(0)+pol1(3)", xlow, xhigh)
31{
32 Clear("");
33 if(xlow > xhigh) {
34 std::swap(xlow, xhigh);
35 }
36 TF1::SetRange(xlow, xhigh);
37 // Changing the name here causes an infinite loop when starting the FitEditor
38 // SetName(Form("gaus_%d_to_%d",(Int_t)(xlow),(Int_t)(xhigh)));
39 InitNames();
40
41 if(bg != nullptr) {
42 fBGFit.Clear();
43 fBGFit.Copy(*bg);
44 } else {
45 fBGFit = TF1("BGFit", "pol1", xlow, xhigh);
46 }
47
48 fBGFit.SetNpx(1000);
49 fBGFit.SetLineStyle(2);
50 fBGFit.SetLineColor(kBlack);
51}
52
53GGaus::GGaus() : TF1("gausbg", "gaus(0)+pol1(3)", 0, 1000), fBGFit("background", "pol1", 0, 1000)
54{
55 Clear();
56 InitNames();
57 fBGFit.SetNpx(1000);
58 fBGFit.SetLineStyle(2);
59 fBGFit.SetLineColor(kBlack);
60}
61
62GGaus::GGaus(const GGaus& peak) : TF1(peak)
63{
64 peak.Copy(*this);
65}
66
68{
69 TF1::SetParName(0, "Height");
70 TF1::SetParName(1, "centroid");
71 TF1::SetParName(2, "sigma");
72 TF1::SetParName(3, "bg_offset");
73 TF1::SetParName(4, "bg_slope");
74}
75
76void GGaus::Copy(TObject& obj) const
77{
78 TF1::Copy(obj);
79 (static_cast<GGaus&>(obj)).fInitFlag = fInitFlag;
80 (static_cast<GGaus&>(obj)).fArea = fArea;
81 (static_cast<GGaus&>(obj)).fDArea = fDArea;
82 (static_cast<GGaus&>(obj)).fSum = fSum;
83 (static_cast<GGaus&>(obj)).fDSum = fDSum;
84 (static_cast<GGaus&>(obj)).fChi2 = fChi2;
85 (static_cast<GGaus&>(obj)).fNdf = fNdf;
86
87 fBGFit.Copy(((static_cast<GGaus&>(obj)).fBGFit));
88}
89
90bool GGaus::InitParams(TH1* fithist)
91{
92 if(fithist == nullptr) {
93 std::cout << "No histogram is associated yet, no initial guesses made" << std::endl;
94 return false;
95 }
96 // Makes initial guesses at parameters for the fit. Uses the histogram to
97 Double_t xlow = 0.;
98 Double_t xhigh = 0.;
99 GetRange(xlow, xhigh);
100
101 Int_t binlow = fithist->GetXaxis()->FindBin(xlow);
102 Int_t binhigh = fithist->GetXaxis()->FindBin(xhigh);
103
104 Double_t highy = fithist->GetBinContent(binlow);
105 Double_t lowy = fithist->GetBinContent(binhigh);
106 for(int x = 1; x < 5; x++) {
107 highy += fithist->GetBinContent(binlow - x);
108 lowy += fithist->GetBinContent(binhigh + x);
109 }
110 highy = highy / 5.0;
111 lowy = lowy / 5.0;
112
113 if(lowy > highy) {
114 std::swap(lowy, highy);
115 }
116
117 double largestx = 0.0;
118 double largesty = 0.0;
119 int i = binlow;
120 for(; i <= binhigh; i++) {
121 if(fithist->GetBinContent(i) > largesty) {
122 largesty = fithist->GetBinContent(i);
123 largestx = fithist->GetXaxis()->GetBinCenter(i);
124 }
125 }
126
127 // - par[0]: height of peak
128 // - par[1]: cent of peak
129 // - par[2]: sigma
130 // - par[3]: bg constent
131 // - par[4]: bg slope
132
133 // limits.
134 TF1::SetParLimits(0, 0, largesty * 2);
135 TF1::SetParLimits(1, xlow, xhigh);
136 TF1::SetParLimits(2, 0, xhigh - xlow);
137
138 // Make initial guesses
139 TF1::SetParameter(0, largesty); // fithist->GetBinContent(bin));
140 TF1::SetParameter(1, largestx); // GetParameter("centroid"));
141 TF1::SetParameter(2, (largestx * .01) / 2.35); // 2,(xhigh-xlow)); //2.0/binWidth); //
142
143 TF1::SetParError(0, 0.10 * largesty);
144 TF1::SetParError(1, 0.25);
145 TF1::SetParError(2, 0.10 * ((largestx * .01) / 2.35));
146
148 return true;
149}
150
151Bool_t GGaus::Fit(TH1* fithist, Option_t* opt)
152{
153 if(fithist == nullptr) {
154 return false;
155 }
156 TString options = opt;
157 if(!IsInitialized()) {
158 InitParams(fithist);
159 }
160 TVirtualFitter::SetMaxIterations(100000);
161
162 bool verbose = !options.Contains("Q");
163 bool noprint = options.Contains("no-print");
164 if(noprint) {
165 options.ReplaceAll("no-print", "");
166 }
167
168 if(fithist->GetSumw2()->fN != fithist->GetNbinsX() + 2) {
169 fithist->Sumw2();
170 }
171
172 TFitResultPtr fitres = fithist->Fit(this, Form("%sRSME", options.Data()));
173
174 if(!fitres.Get()->IsValid()) {
175 if(!verbose) {
176 std::cout << RED << "fit has failed, trying refit... " << RESET_COLOR;
177 }
178 fithist->GetListOfFunctions()->Last()->Delete();
179 fitres = fithist->Fit(this, Form("%sRSME", options.Data())); //,Form("%sRSM",options.Data()))
180 if(fitres.Get()->IsValid()) {
181 if(!verbose && !noprint) {
182 std::cout << DGREEN << " refit passed!" << RESET_COLOR << std::endl;
183 }
184 } else {
185 if(!verbose && !noprint) {
186 std::cout << DRED << " refit also failed :( " << RESET_COLOR << std::endl;
187 }
188 }
189 }
190
191 Double_t xlow = 0.;
192 Double_t xhigh = 0.;
193 TF1::GetRange(xlow, xhigh);
194
195 std::array<double, 2> bgpars = {TF1::GetParameters()[3], TF1::GetParameters()[4]};
196
197 fBGFit.SetParameters(bgpars.data());
198
199 fArea = Integral(xlow, xhigh) / fithist->GetBinWidth(1);
200 double bgArea = fBGFit.Integral(xlow, xhigh) / fithist->GetBinWidth(1);
201
202 fArea -= bgArea;
203
204 if(xlow > xhigh) {
205 std::swap(xlow, xhigh);
206 }
207 fSum = fithist->Integral(fithist->GetXaxis()->FindBin(xlow),
208 fithist->GetXaxis()->FindBin(xhigh)); //* fithist->GetBinWidth(1);
209 std::cout << "sum between markers: " << fSum << std::endl;
210 fDSum = TMath::Sqrt(fSum);
211 fSum -= bgArea;
212 std::cout << "sum after subtraction: " << fSum << std::endl;
213
214 if(!verbose && !noprint) {
215 Print();
216 }
217
218 Copy(*fithist->GetListOfFunctions()->FindObject(GetName()));
219 fithist->GetListOfFunctions()->Add(fBGFit.Clone());
220
221 return true;
222}
223
224void GGaus::Clear(Option_t* opt)
225{
226 TString options = opt;
227 // Clear the GGaus including functions and histogram
228 if(options.Contains("all")) {
229 TF1::Clear();
230 }
231 fInitFlag = false;
232 fArea = 0.0;
233 fDArea = 0.0;
234 fSum = 0.0;
235 fDSum = 0.0;
236 fChi2 = 0.0;
237 fNdf = 0.0;
238}
239
240void GGaus::Print(Option_t* opt) const
241{
242 TString options = opt;
243 std::cout << GREEN;
244 std::cout << "Name: " << GetName() << std::endl;
245 std::cout << "Centroid: " << GetParameter("centroid") << " +- " << GetParError(GetParNumber("centroid")) << std::endl;
246 std::cout << "Area: " << fArea << " +- " << fDArea << std::endl;
247 std::cout << "Sum: " << fSum << " +- " << fDSum << std::endl;
248 std::cout << "FWHM: " << GetFWHM() << " +- " << GetFWHMErr() << std::endl;
249 std::cout << "Reso: " << GetFWHM() / GetParameter("centroid") * 100. << "%%" << std::endl;
250 std::cout << "Chi^2/NDF: " << fChi2 / fNdf << std::endl;
251 if(options.Contains("all")) {
252 TF1::Print(opt);
253 }
254 std::cout << RESET_COLOR;
255}
256
258{
259 if(hist == nullptr) {
260 return;
261 }
262 if(fChi2 < 0.000000001) {
263 std::cout << "No fit performed" << std::endl;
264 return;
265 }
266 Double_t xlow = 0.;
267 Double_t xhigh = 0.;
268 GetRange(xlow, xhigh);
269 Int_t nbins = hist->GetXaxis()->GetNbins();
270 auto* res = new Double_t[nbins];
271 auto* bin = new Double_t[nbins];
272 Int_t points = 0;
273 for(int i = 1; i <= nbins; i++) {
274 if(hist->GetBinCenter(i) <= xlow || hist->GetBinCenter(i) >= xhigh) {
275 continue;
276 }
277 res[points] = (hist->GetBinContent(i) - Eval(hist->GetBinCenter(i))) + GetParameter("Height") / 2;
278 bin[points] = hist->GetBinCenter(i);
279 points++;
280 }
281 new GCanvas();
282 auto* residuals = new TGraph(points, bin, res);
283 residuals->Draw("*AC");
284 delete[] res;
285 delete[] bin;
286}
#define DRED
Definition Globals.h:18
#define DGREEN
Definition Globals.h:17
#define RED
Definition Globals.h:9
#define GREEN
Definition Globals.h:8
#define RESET_COLOR
Definition Globals.h:5
TH1D * hist
Definition UserFillObj.h:3
Definition GGaus.h:9
TF1 fBGFit
Definition GGaus.h:75
double fArea
Definition GGaus.h:63
bool fInitFlag
Definition GGaus.h:73
double fDSum
Definition GGaus.h:69
double fNdf
Definition GGaus.h:66
bool InitParams(TH1 *fithist=nullptr)
Definition GGaus.cxx:90
void DrawResiduals(TH1 *) const
Definition GGaus.cxx:257
Bool_t IsInitialized() const
Definition GGaus.h:71
void Copy(TObject &) const override
Definition GGaus.cxx:76
void SetInitialized(Bool_t flag=true)
Definition GGaus.h:72
double fChi2
Definition GGaus.h:65
GGaus()
Definition GGaus.cxx:53
void Clear(Option_t *opt="") override
Definition GGaus.cxx:224
Double_t GetFWHM() const
Definition GGaus.h:39
Double_t GetFWHMErr() const
Definition GGaus.h:40
double fDArea
Definition GGaus.h:64
bool Fit(TH1 *, Option_t *opt="")
Definition GGaus.cxx:151
void InitNames()
Definition GGaus.cxx:67
double fSum
Definition GGaus.h:68
void Print(Option_t *opt="") const override
Definition GGaus.cxx:240