Heavy ion Analysis Libriares
Loading...
Searching...
No Matches
ChiSqMap2D.cxx
1/*
2 * HalChiSqMap.cxx
3 *
4 * Created on: 23 paź 2019
5 * Author: Daniel Wielanek
6 * E-mail: daniel.wielanek@gmail.com
7 * Warsaw University of Technology, Faculty of Physics
8 */
9
10#include "ChiSqMap2D.h"
11#include "Splines.h"
12
13#include "StdMath.h"
14#include <TAttLine.h>
15#include <TAxis.h>
16#include <TH1.h>
17#include <TH2.h>
18#include <TLine.h>
19#include <TMath.h>
20#include <TMathBase.h>
21#include <TMatrix.h>
22#include <TMatrixDfwd.h>
23
24#include <cfloat>
25
26namespace Hal {
27 ChiSqMap2D::ChiSqMap2D() :
28 fHist(NULL),
29 fLineX(NULL),
30 fLineY(NULL),
31 fLineXlow(NULL),
32 fLineXhigh(NULL),
33 fLineYlow(NULL),
34 fLineYhigh(NULL),
35 fLabel("#chi/NDF") {}
36
37 ChiSqMap2D::ChiSqMap2D(TString name, Int_t xbins, Double_t xlow, Double_t xhigh, Int_t ybins, Double_t ylow, Double_t yhigh) :
38 ChiSqMap2D() {
39 fHist = new TH2D(name, "", xbins, xlow, xhigh, ybins, ylow, yhigh);
40 }
41
42 void ChiSqMap2D::SetXFit(Double_t Value, Double_t errLow, Double_t errHigh) {
43 if (errHigh == -1) errHigh = errLow;
44 if (fLineX) delete fLineX;
45 if (fLineXlow) delete fLineXlow;
46 if (fLineXhigh) delete fLineXhigh;
47
48 fLineX = MakeXLine(Value, 1);
49 fLineXlow = MakeXLine(Value - errLow, 10);
50 fLineXhigh = MakeXLine(Value + errHigh, 10);
51 }
52
53 void ChiSqMap2D::SetYFit(Double_t Value, Double_t errLow, Double_t errHigh) {
54 if (errHigh == -1) errHigh = errLow;
55 if (fLineY) delete fLineY;
56 if (fLineYlow) delete fLineYlow;
57 if (fLineYhigh) delete fLineYhigh;
58
59 fLineY = MakeYLine(Value, 1);
60 fLineYlow = MakeYLine(Value - errLow, 10);
61 fLineYhigh = MakeYLine(Value + errHigh, 10);
62 }
63
64 void ChiSqMap2D::Draw(Option_t* opt) {
65 if (fHist == NULL) return;
66 fHist->SetStats(kFALSE);
67 fHist->Draw("colz");
68 TString option = opt;
69 if (!option.Contains("nolin")) {
70 DrawLineX(fLineX);
71 DrawLineX(fLineXlow);
72 DrawLineX(fLineXhigh);
73 DrawLineY(fLineY);
74 DrawLineY(fLineYlow);
75 DrawLineY(fLineYhigh);
76 }
77 if (option.Contains("min")) {
78 Int_t xb = 1, yb = 1;
79 Double_t min = DBL_MAX;
80 for (int i = 1; i <= fHist->GetNbinsX(); i++) {
81 for (int j = 1; j <= fHist->GetNbinsY(); j++) {
82 if (fHist->GetBinContent(i, j) < min) {
83 min = fHist->GetBinContent(i, j);
84 xb = i;
85 yb = j;
86 }
87 }
88 }
89 Double_t x1 = fHist->GetXaxis()->GetBinLowEdge(xb);
90 Double_t y1 = fHist->GetYaxis()->GetBinLowEdge(yb);
91 Double_t x2 = fHist->GetXaxis()->GetBinUpEdge(xb);
92 Double_t y2 = fHist->GetYaxis()->GetBinUpEdge(yb);
93 TLine** line = new TLine*[6];
94 line[0] = new TLine(x1, y1, x1, y2);
95 line[1] = new TLine(x2, y1, x2, y2);
96 line[2] = new TLine(x1, y1, x2, y1);
97 line[3] = new TLine(x1, y2, x2, y2);
98 line[4] = new TLine(x1, y1, x2, y2);
99 line[5] = new TLine(x2, y1, x1, y2);
100
101 for (int i = 0; i < 6; i++) {
102 line[i]->SetLineColor(kGray);
103 line[i]->Draw("SAME");
104 }
105 }
106 if (option.Contains("fit")) {
107 Double_t x1 = fHist->GetXaxis()->GetBinLowEdge(1);
108 Double_t y1 = fHist->GetYaxis()->GetBinLowEdge(1);
109 Double_t x2 = fHist->GetXaxis()->GetBinUpEdge(fHist->GetNbinsX());
110 Double_t y2 = fHist->GetYaxis()->GetBinUpEdge(fHist->GetNbinsY());
111 Double_t X = GetEstX();
112 Double_t Y = GetEstY();
113 TLine** line = new TLine*[2];
114 line[0] = new TLine(x1, Y, x2, Y);
115 line[1] = new TLine(X, y1, X, y2);
116 for (int i = 0; i < 2; i++) {
117 line[i]->SetLineColor(kGray + 2);
118 line[i]->Draw("SAME");
119 }
120 }
121 }
122
123 void ChiSqMap2D::SetParNames(TString xpar, TString ypar) {
124 if (fHist == NULL) return;
125 fHist->GetXaxis()->SetTitle(xpar);
126 fHist->GetYaxis()->SetTitle(ypar);
127 }
128
129 Bool_t ChiSqMap2D::CheckX(Double_t x) const {
130 Double_t x_low = fHist->GetXaxis()->GetBinLowEdge(1);
131 Double_t x_high = fHist->GetXaxis()->GetBinUpEdge(fHist->GetNbinsX());
132 if (x < x_low) return kFALSE;
133 if (x > x_high) return kFALSE;
134 return kTRUE;
135 }
136
137 Bool_t ChiSqMap2D::CheckY(Double_t y) const {
138 Double_t y_low = fHist->GetYaxis()->GetBinLowEdge(1);
139 Double_t y_high = fHist->GetYaxis()->GetBinUpEdge(fHist->GetNbinsY());
140 if (y < y_low) return kFALSE;
141 if (y > y_high) return kFALSE;
142 return kTRUE;
143 }
144
145 TLine* ChiSqMap2D::MakeXLine(Double_t x, Style_t style) const {
146 Double_t y_low = fHist->GetYaxis()->GetBinLowEdge(1);
147 Double_t y_high = fHist->GetYaxis()->GetBinUpEdge(fHist->GetNbinsY());
148 TLine* l = new TLine(x, y_low, x, y_high);
149 l->SetLineStyle(style);
150 return l;
151 }
152
153 TLine* ChiSqMap2D::MakeYLine(Double_t y, Style_t style) const {
154 Double_t x_low = fHist->GetXaxis()->GetBinLowEdge(1);
155 Double_t x_high = fHist->GetXaxis()->GetBinUpEdge(fHist->GetNbinsX());
156 TLine* l = new TLine(x_low, y, x_high, y);
157 l->SetLineStyle(style);
158 return l;
159 }
160
161 Double_t ChiSqMap2D::GetFitX() const {
162 if (fLineX == NULL) return 0;
163 return fLineX->GetX1();
164 }
165
166 Double_t ChiSqMap2D::GetFitY() const {
167 if (fLineY == NULL) return 0;
168 return fLineY->GetY1();
169 }
170
171 Double_t ChiSqMap2D::GetFitXErrorUp() const {
172 if (fLineYhigh == NULL) return 0;
173 return fLineYhigh->GetX1();
174 }
175
177 if (fLineXlow == NULL) return 0;
178 return fLineXlow->GetX1();
179 }
180
181 Double_t ChiSqMap2D::GetFitYErrorUp() const {
182 if (fLineYhigh == NULL) return 0;
183 return fLineYhigh->GetY1();
184 }
185
187 if (fLineYlow == NULL) return 0;
188 return fLineYlow->GetY1();
189 }
190
191 void ChiSqMap2D::DrawLineX(TLine* l) {
192 if (l == NULL) return;
193 if (CheckX(l->GetX1())) l->Draw("SAME");
194 }
195
196 void ChiSqMap2D::DrawLineY(TLine* l) {
197 if (l == NULL) return;
198 if (CheckY(l->GetY1())) l->Draw("SAME");
199 }
200
201 void ChiSqMap2D::GetMin(Double_t& x, Double_t& y) const {
202 Int_t xb = 0, yb = 0;
203 Double_t min = DBL_MAX;
204 for (int i = 1; i <= fHist->GetNbinsX(); i++) {
205 for (int j = 1; j <= fHist->GetNbinsY(); j++) {
206 if (fHist->GetBinContent(i, j) < min) {
207 min = fHist->GetBinContent(i, j);
208 xb = i;
209 yb = j;
210 }
211 }
212 }
213 x = fHist->GetXaxis()->GetBinCenter(xb);
214 y = fHist->GetYaxis()->GetBinCenter(yb);
215 }
216
217 ChiSqMap2D::~ChiSqMap2D() {
218 if (fHist) delete fHist;
219 if (fLineX) delete fLineX;
220 if (fLineY) delete fLineY;
221 if (fLineXlow) delete fLineXlow;
222 if (fLineXhigh) delete fLineXhigh;
223 if (fLineYlow) delete fLineYlow;
224 if (fLineYhigh) delete fLineYhigh;
225 }
226
227 Double_t ChiSqMap2D::GetEstErrorX(Double_t thres, Bool_t around_fit) const {
228 Int_t binX, binY;
229 if (around_fit) {
230 binX = fHist->GetXaxis()->FindBin(GetFitX());
231 binY = fHist->GetYaxis()->FindBin(GetFitY());
232 } else {
233 Double_t x, y;
234 GetMin(x, y);
235 binX = fHist->GetXaxis()->FindBin(x);
236 binY = fHist->GetYaxis()->FindBin(y);
237 }
238 if (binX <= 1 || binX >= fHist->GetNbinsX()) return 0;
239 Double_t dX = fHist->GetXaxis()->GetBinWidth(binX);
240 Double_t X = fHist->GetXaxis()->GetBinCenter(binX);
241 Double_t y1 = fHist->GetBinContent(binX - 1, binY);
242 Double_t y2 = fHist->GetBinContent(binX, binY);
243 Double_t y3 = fHist->GetBinContent(binX + 1, binY);
244 Double_t x1 = X - dX;
245 Double_t x2 = X;
246 Double_t x3 = X + dX;
247 Double_t a, b, c;
248 Hal::Std::FitParabola(x1, x2, x3, y1, y2, y3, a, b, c);
249 Double_t X1, X2;
250 if (thres <= 0) return 1.0 / TMath::Sqrt(a);
251 Hal::Std::SolveParabola(a, b, c - y2 * (1.0 + thres), X1, X2);
252 return TMath::Max(TMath::Abs(X1 - X), TMath::Abs(X2 - X));
253 }
254
255 Double_t ChiSqMap2D::GetEstErrorY(Double_t thres, Bool_t around_fit) const {
256 Int_t binX, binY;
257 if (around_fit) {
258 binX = fHist->GetXaxis()->FindBin(GetFitX());
259 binY = fHist->GetYaxis()->FindBin(GetFitY());
260 } else {
261 Double_t x, y;
262 GetMin(x, y);
263 binX = fHist->GetXaxis()->FindBin(x);
264 binY = fHist->GetYaxis()->FindBin(y);
265 }
266 if (binY <= 1 || binY >= fHist->GetNbinsY()) return 0;
267 Double_t dX = fHist->GetYaxis()->GetBinWidth(binY);
268 Double_t X = fHist->GetYaxis()->GetBinCenter(binY);
269 Double_t y1 = fHist->GetBinContent(binX, binY - 1);
270 Double_t y2 = fHist->GetBinContent(binX, binY);
271 Double_t y3 = fHist->GetBinContent(binX, binY + 1);
272 Double_t x1 = X - dX;
273 Double_t x2 = X;
274 Double_t x3 = X + dX;
275 Double_t a, b, c;
276 Hal::Std::FitParabola(x1, x2, x3, y1, y2, y3, a, b, c);
277 Double_t X1, X2;
278 if (thres <= 0) return 1.0 / TMath::Sqrt(a);
279 Hal::Std::SolveParabola(a, b, c - y2 * (1.0 + thres), X1, X2);
280 return TMath::Max(TMath::Abs(X1 - X), TMath::Abs(X2 - X));
281 }
282
283 Double_t ChiSqMap2D::GetEstX() const {
284 Int_t binX, binY;
285 Double_t x, y;
286 GetMin(x, y);
287 binX = fHist->GetXaxis()->FindBin(x);
288 binY = fHist->GetYaxis()->FindBin(y);
289 if (binY <= 1 || binY >= fHist->GetNbinsY()) return 0;
290 Double_t dX = fHist->GetXaxis()->GetBinWidth(binX);
291 Double_t X = fHist->GetXaxis()->GetBinCenter(binX);
292 Double_t y1 = fHist->GetBinContent(binX - 1, binY);
293 Double_t y2 = fHist->GetBinContent(binX, binY);
294 Double_t y3 = fHist->GetBinContent(binX + 1, binY);
295 Double_t x1 = X - dX;
296 Double_t x2 = X;
297 Double_t x3 = X + dX;
298 Double_t a, b, c;
299 Hal::Std::FitParabola(x1, x2, x3, y1, y2, y3, a, b, c);
300 return -b / (2.0 * a);
301 }
302
303 Double_t ChiSqMap2D::GetEstY() const {
304 Int_t binX, binY;
305 Double_t x, y;
306 GetMin(x, y);
307 binX = fHist->GetXaxis()->FindBin(x);
308 binY = fHist->GetYaxis()->FindBin(y);
309 if (binY <= 1 || binY >= fHist->GetNbinsY()) return 0;
310 Double_t dX = fHist->GetYaxis()->GetBinWidth(binY);
311 Double_t X = fHist->GetYaxis()->GetBinCenter(binY);
312 Double_t y1 = fHist->GetBinContent(binX, binY - 1);
313 Double_t y2 = fHist->GetBinContent(binX, binY);
314 Double_t y3 = fHist->GetBinContent(binX, binY + 1);
315 Double_t x1 = X - dX;
316 Double_t x2 = X;
317 Double_t x3 = X + dX;
318 Double_t a, b, c;
319 Hal::Std::FitParabola(x1, x2, x3, y1, y2, y3, a, b, c);
320 return -b / (2.0 * a);
321 }
322
323 void ChiSqMap2D::GetXYE(Double_t& x, Double_t& eX, Double_t& y, Double_t& eY) const {
324 GetMin(x, y);
325 Int_t gBinX = fHist->GetXaxis()->FindBin(x);
326 Int_t gBinY = fHist->GetYaxis()->FindBin(y);
327 Double_t xlow = fHist->GetXaxis()->GetBinCenter(gBinX - 1);
328 Double_t xhig = fHist->GetXaxis()->GetBinCenter(gBinX + 1);
329 Double_t ylow = fHist->GetYaxis()->GetBinCenter(gBinY - 1);
330 Double_t yhig = fHist->GetYaxis()->GetBinCenter(gBinY + 1);
331 Double_t chi2ndf = fHist->GetBinContent(gBinX, gBinY);
332 TH2D* h = new TH2D("tempHes", "tempHes", 3, xlow, xhig, 3, ylow, yhig);
333 for (int i = 1; i <= 3; i++) {
334 for (int j = 1; j <= 3; j++) {
335 h->SetBinContent(i, j, fHist->GetBinContent(gBinX + i - 2, gBinY + j - 2));
336 }
337 }
338 Spline2D sp(h);
339 delete h;
340
341 Double_t a3 = sp.GetExtrapolationParam(x, y, 3);
342 Double_t a4 = sp.GetExtrapolationParam(x, y, 4);
343 Double_t a5 = sp.GetExtrapolationParam(x, y, 5);
344 Double_t a6 = sp.GetExtrapolationParam(x, y, 6);
345 Double_t a7 = sp.GetExtrapolationParam(x, y, 7);
346 Double_t a8 = sp.GetExtrapolationParam(x, y, 8);
347
348 x = GetEstX();
349 y = GetEstY();
350
351 Double_t fXY = a3 + 2. * a6 * x + 2.0 * a7 * y + 4.0 * a8 * x * y;
352 Double_t fYX = fXY;
353 Double_t fXX = 2.0 * a4 + 2.0 * a6 * y + 2.0 * a8 * y * y;
354 Double_t fYY = 2.0 * a5 + 2.0 * a7 * x + 2.0 * a8 * x * x;
355
356 TMatrixD m(2, 2);
357 m[0][0] = fXX;
358 m[1][0] = fYX;
359 m[0][1] = fXY;
360 m[1][1] = fYY;
361 TMatrixD inv = m.Invert();
362
363 eX = TMath::Sqrt(inv[0][0]) * chi2ndf;
364 eY = TMath::Sqrt(inv[1][1]) * chi2ndf;
365 }
366} // namespace Hal
void GetMin(Double_t &x, Double_t &y) const
Double_t GetFitY() const
Double_t GetFitX() const
Double_t GetFitYErrorLow() const
void Draw(Option_t *opt="")
void SetParNames(TString xpar, TString ypar)
Double_t GetFitYErrorUp() const
Double_t GetFitXErrorLow() const
void GetXYE(Double_t &x, Double_t &eX, Double_t &y, Double_t &eY) const
Double_t GetEstX() const
void SetXFit(Double_t Value, Double_t errLow=0, Double_t errHigh=-1)
Double_t GetEstY() const
void SetYFit(Double_t Value, Double_t errLow=0, Double_t errHigh=-1)
Double_t GetFitXErrorUp() const
Double_t GetEstErrorY(Double_t thres=0.1, Bool_t around_fit=kTRUE) const
Double_t GetEstErrorX(Double_t thres=0.1, Bool_t around_fit=kTRUE) const
Double_t GetExtrapolationParam(Double_t x, Double_t y, Int_t param) const
Definition Splines.cxx:445