]>
Commit | Line | Data |
---|---|---|
71b70904 | 1 | #include "AliPoissonCalculator.h" |
79909b8b | 2 | #include "AliForwardCorrectionManager.h" |
71b70904 | 3 | #include <TH2D.h> |
4 | #include <TBrowser.h> | |
5 | #include <TROOT.h> | |
ce63a99e | 6 | #include <TMath.h> |
7 | #include <TList.h> | |
71b70904 | 8 | #include <iostream> |
d23503ee | 9 | #include <TAxis.h> |
71b70904 | 10 | |
ce63a99e | 11 | // |
e18cb8bd | 12 | // A class to calculate the multiplicity in @f$(x,y)@f$ bins |
ce63a99e | 13 | // using Poisson statistics. |
14 | // | |
d23503ee | 15 | // The input is assumed to be binned in @f$(x,y)@f$ as described by |
16 | // the 2D histogram passwd to the Reset member function. | |
ce63a99e | 17 | // |
18 | // The data is grouped in to regions as defined by the parameters | |
e18cb8bd | 19 | // fXLumping and fYLumping. The total number of cells and number of |
20 | // empty cells is then calculate in each region. The mean | |
21 | // multiplicity over the region is then determined as | |
ce63a99e | 22 | // |
23 | // @f[ | |
24 | // \lange m\rangle = -\log\left(\frac{e}{t}\right) | |
25 | // @f] | |
26 | // where @f$ e@f$ is the number of empty cells and @f$t@f$ is the | |
27 | // total number of cells in the region. A correction for counting | |
28 | // statistics, is then applied | |
29 | // @f{eqnarray*} | |
30 | // c &=& \frac{1}{1 - \exp{-\lange m\rangle}} | |
31 | // &=& \frac{1}{1 - \frac{e}{t}} | |
32 | // @f{eqnarray*} | |
33 | // and the final number in each cell is then | |
34 | // @f[ | |
35 | // h_i c \lange m\rangle | |
36 | // @f] | |
37 | // where @f$h_i@f$ is the number of hits in the cell @f$i@f$ | |
38 | // | |
39 | // | |
40 | ||
d23503ee | 41 | namespace { |
42 | const char* kBasicN = "basic"; | |
43 | const char* kEmptyN = "empty"; | |
44 | const char* kTotalN = "total"; | |
45 | const char* kBasicT = "Basic number of hits"; | |
46 | const char* kEmptyT = "Empty number of bins/region"; | |
47 | const char* kTotalT = "Total number of bins/region"; | |
48 | } | |
49 | ||
50 | ||
51 | ||
52 | ||
71b70904 | 53 | //____________________________________________________________________ |
54 | AliPoissonCalculator::AliPoissonCalculator() | |
55 | : TNamed(), | |
e18cb8bd | 56 | fXLumping(32), |
57 | fYLumping(4), | |
71b70904 | 58 | fTotal(0), |
59 | fEmpty(0), | |
ce63a99e | 60 | fBasic(0), |
61 | fEmptyVsTotal(0), | |
62 | fMean(0), | |
63 | fOcc(0), | |
e18cb8bd | 64 | fCorr(0) |
ce63a99e | 65 | { |
66 | // | |
67 | // CTOR | |
68 | // | |
69 | } | |
71b70904 | 70 | |
71 | //____________________________________________________________________ | |
d23503ee | 72 | AliPoissonCalculator::AliPoissonCalculator(const char*) |
71b70904 | 73 | : TNamed("poissonCalculator", "Calculate N_ch using Poisson stat"), |
e18cb8bd | 74 | fXLumping(32), |
75 | fYLumping(4), | |
71b70904 | 76 | fTotal(0), |
77 | fEmpty(0), | |
ce63a99e | 78 | fBasic(0), |
79 | fEmptyVsTotal(0), | |
80 | fMean(0), | |
81 | fOcc(0), | |
e18cb8bd | 82 | fCorr(0) |
ce63a99e | 83 | { |
84 | // | |
85 | // CTOR | |
21d778b1 | 86 | // |
ce63a99e | 87 | } |
88 | //____________________________________________________________________ | |
89 | AliPoissonCalculator::AliPoissonCalculator(const AliPoissonCalculator& o) | |
90 | : TNamed(o), | |
e18cb8bd | 91 | fXLumping(o.fXLumping), |
92 | fYLumping(o.fYLumping), | |
ce63a99e | 93 | fTotal(0), |
94 | fEmpty(0), | |
95 | fBasic(0), | |
96 | fEmptyVsTotal(0), | |
97 | fMean(0), | |
98 | fOcc(0), | |
e18cb8bd | 99 | fCorr(0) |
ce63a99e | 100 | { |
101 | Init(); | |
d23503ee | 102 | Reset(o.fBasic); |
ce63a99e | 103 | } |
104 | ||
105 | //____________________________________________________________________ | |
106 | AliPoissonCalculator::~AliPoissonCalculator() | |
107 | { | |
08683480 | 108 | // CleanUp(); |
ce63a99e | 109 | } |
110 | ||
111 | //____________________________________________________________________ | |
112 | void | |
113 | AliPoissonCalculator::CleanUp() | |
114 | { | |
e18cb8bd | 115 | if (fTotal) { delete fTotal; fTotal = 0; } |
116 | if (fEmpty) { delete fEmpty; fEmpty = 0; } | |
117 | if (fBasic) { delete fBasic; fBasic = 0; } | |
118 | if (fEmptyVsTotal) { delete fEmptyVsTotal; fEmptyVsTotal = 0; } | |
119 | if (fMean) { delete fMean; fMean = 0; } | |
120 | if (fOcc) { delete fOcc; fOcc = 0; } | |
121 | if (fCorr) { delete fCorr; fCorr = 0; } | |
ce63a99e | 122 | } |
123 | //____________________________________________________________________ | |
124 | AliPoissonCalculator& | |
125 | AliPoissonCalculator::operator=(const AliPoissonCalculator& o) | |
126 | { | |
d015ecfe | 127 | if (&o == this) return *this; |
ce63a99e | 128 | TNamed::operator=(o); |
e18cb8bd | 129 | fXLumping = o.fXLumping; |
130 | fYLumping = o.fYLumping; | |
ce63a99e | 131 | CleanUp(); |
21d778b1 | 132 | Init(); |
d23503ee | 133 | Reset(o.fBasic); |
ce63a99e | 134 | return *this; |
135 | } | |
136 | ||
137 | //____________________________________________________________________ | |
138 | void | |
e18cb8bd | 139 | AliPoissonCalculator::Init(Int_t xLumping, Int_t yLumping) |
ce63a99e | 140 | { |
141 | // | |
142 | // Initialize | |
143 | // | |
e18cb8bd | 144 | if (xLumping > 0) fXLumping = xLumping; |
145 | if (yLumping > 0) fYLumping = yLumping; | |
21d778b1 | 146 | |
21d778b1 | 147 | //Create diagnostics if void |
ce63a99e | 148 | if (fEmptyVsTotal) return; |
149 | ||
d23503ee | 150 | MakeOutput(); |
151 | } | |
152 | //____________________________________________________________________ | |
153 | void | |
154 | AliPoissonCalculator::Define(const TAxis& xaxis, const TAxis& yaxis) | |
155 | { | |
156 | // | |
157 | // Initialize | |
158 | // | |
159 | const Double_t* xBins = xaxis.GetXbins()->GetArray(); | |
160 | const Double_t* yBins = yaxis.GetXbins()->GetArray(); | |
161 | Int_t nX = xaxis.GetNbins(); | |
162 | Int_t nY = yaxis.GetNbins(); | |
163 | Double_t lX = xaxis.GetXmin(); | |
164 | Double_t hX = xaxis.GetXmax(); | |
165 | Double_t lY = yaxis.GetXmin(); | |
166 | Double_t hY = yaxis.GetXmax(); | |
79909b8b | 167 | |
d23503ee | 168 | if (xBins) { |
169 | if (yBins) fBasic = new TH2D(kBasicN, kBasicT, nX, xBins, nY, yBins); | |
170 | else fBasic = new TH2D(kBasicN, kBasicT, nX, xBins, nY, lY, hY); | |
171 | } | |
172 | else { | |
173 | if (yBins) fBasic = new TH2D(kBasicN, kBasicT, nX, lX, hX, nY, yBins); | |
174 | else fBasic = new TH2D(kBasicN, kBasicT, nX, lX, hX, nY, lY, hY); | |
175 | } | |
176 | fBasic->SetXTitle(xaxis.GetTitle()); | |
177 | fBasic->SetYTitle(yaxis.GetTitle()); | |
178 | ||
179 | Reset(fBasic); | |
79909b8b | 180 | } |
d23503ee | 181 | //____________________________________________________________________ |
79909b8b | 182 | void AliPoissonCalculator::MakeOutput() { |
183 | ||
e18cb8bd | 184 | Int_t n = fXLumping * fYLumping + 1; |
ce63a99e | 185 | fEmptyVsTotal = new TH2D("emptyVsTotal", |
186 | "# of empty # bins vs total # bins", | |
187 | n, -.5, n-.5, n, -.5, n-.5); | |
188 | fEmptyVsTotal->SetXTitle("Total # bins"); | |
189 | fEmptyVsTotal->SetYTitle("# empty bins"); | |
190 | fEmptyVsTotal->SetZTitle("Correlation"); | |
191 | fEmptyVsTotal->SetOption("colz"); | |
192 | fEmptyVsTotal->SetDirectory(0); | |
193 | ||
e18cb8bd | 194 | n = (fXLumping + fYLumping); |
ce63a99e | 195 | fMean = new TH1D("poissonMean", "Mean N_{ch} as calculated by Poisson", |
196 | 10*n+1, -.1, n+.1); | |
e18cb8bd | 197 | fMean->SetXTitle("#bar{N_{ch}}=log(empty/total)"); |
ce63a99e | 198 | fMean->SetYTitle("Events"); |
199 | fMean->SetFillColor(kRed+1); | |
200 | fMean->SetFillStyle(3001); | |
e2213ed5 | 201 | fMean->SetLineColor(kBlack); |
ce63a99e | 202 | fMean->SetDirectory(0); |
203 | ||
204 | fOcc = new TH1D("occupancy", "Occupancy = #int_{1}^{#infty}dN P(N)", | |
5ca83fee | 205 | 101, -.5, 100.5); |
ce63a99e | 206 | fOcc->SetXTitle("#int_{1}^{#infty}dN P(N) [%]"); |
207 | fOcc->SetYTitle("Events"); | |
208 | fOcc->SetFillColor(kBlue+1); | |
209 | fOcc->SetFillStyle(3001); | |
e2213ed5 | 210 | fOcc->SetLineColor(kBlack); |
ce63a99e | 211 | fOcc->SetDirectory(0); |
212 | ||
213 | fCorr = new TH2D("correction", "Correction as function of mean N_{ch}", | |
214 | 10*n+1, -.1, n+.1, 100, 0, 10); | |
215 | fCorr->SetXTitle("#bar{N_{ch}}"); | |
216 | fCorr->SetYTitle("Correction 1/(1-e^{#bar{N_{c}}})"); | |
217 | fCorr->SetZTitle("Events"); | |
218 | fCorr->SetOption("colz"); | |
219 | fCorr->SetDirectory(0); | |
21d778b1 | 220 | |
79909b8b | 221 | |
ce63a99e | 222 | } |
ce63a99e | 223 | //____________________________________________________________________ |
224 | void | |
225 | AliPoissonCalculator::Output(TList* d) | |
226 | { | |
227 | if (!d) return; | |
79909b8b | 228 | if (!fEmptyVsTotal) MakeOutput(); |
ce63a99e | 229 | d->Add(fEmptyVsTotal); |
230 | d->Add(fMean); | |
231 | d->Add(fOcc); | |
232 | d->Add(fCorr); | |
233 | } | |
71b70904 | 234 | |
e18cb8bd | 235 | //____________________________________________________________________ |
236 | void | |
237 | AliPoissonCalculator::SetLumping(UShort_t nx, UShort_t ny) | |
238 | { | |
239 | if (nx == fXLumping && ny == fYLumping && | |
240 | fEmptyVsTotal && fTotal) | |
241 | // Check if we have something to do. | |
242 | return; | |
243 | CleanUp(); | |
244 | Init(nx, ny); | |
245 | } | |
246 | ||
d23503ee | 247 | //____________________________________________________________________ |
248 | Int_t | |
249 | AliPoissonCalculator::CheckLumping(char which, Int_t nBins, Int_t lumping) const | |
250 | { | |
251 | if ((nBins % lumping) == 0) return lumping; | |
252 | Int_t l = lumping; | |
253 | do { | |
254 | l--; | |
255 | } while (l > 0 && ((nBins % l) != 0)); | |
256 | Warning("CheckLumping", "%c lumping %d is not a divisor of %d, set to %d", | |
257 | which, lumping, nBins, l); | |
258 | return l; | |
259 | } | |
260 | ||
71b70904 | 261 | //____________________________________________________________________ |
262 | void | |
d23503ee | 263 | AliPoissonCalculator::Reset(const TH2D* base) |
71b70904 | 264 | { |
ce63a99e | 265 | // |
266 | // Reset histogram | |
267 | // | |
e18cb8bd | 268 | if (fBasic && fTotal && fEmpty) { |
71b70904 | 269 | fBasic->Reset(); |
e18cb8bd | 270 | fTotal->Reset(); |
271 | fEmpty->Reset(); | |
71b70904 | 272 | return; |
273 | } | |
d23503ee | 274 | |
275 | if (!base) return; | |
276 | ||
277 | Int_t nXF = base->GetNbinsX(); | |
278 | Double_t xMin = base->GetXaxis()->GetXmin(); | |
279 | Double_t xMax = base->GetXaxis()->GetXmax(); | |
280 | Int_t nYF = base->GetNbinsY(); | |
281 | Double_t yMin = base->GetYaxis()->GetXmin(); | |
282 | Double_t yMax = base->GetYaxis()->GetXmax(); | |
283 | ||
284 | fXLumping = CheckLumping('X', nXF, fXLumping); | |
285 | fYLumping = CheckLumping('Y', nYF, fYLumping); | |
286 | ||
e18cb8bd | 287 | Int_t nY = nYF / fYLumping; |
d23503ee | 288 | Int_t nX = nXF / fXLumping; |
63d9ab53 | 289 | |
d23503ee | 290 | if (fBasic != base) { |
291 | fBasic = static_cast<TH2D*>(base->Clone(kBasicN)); | |
292 | fBasic->SetTitle(kBasicT); | |
293 | fBasic->SetDirectory(0); | |
294 | fBasic->Sumw2(); | |
295 | } | |
21d778b1 | 296 | |
d23503ee | 297 | fTotal = new TH2D(kTotalN, kTotalT, nX, xMin, xMax, nY, yMin, yMax); |
e18cb8bd | 298 | fTotal->SetDirectory(0); |
299 | fTotal->SetXTitle(fBasic->GetXaxis()->GetTitle()); | |
300 | fTotal->SetYTitle(fBasic->GetYaxis()->GetTitle()); | |
301 | fTotal->Sumw2(); | |
302 | ||
d23503ee | 303 | fEmpty = static_cast<TH2D*>(fTotal->Clone(kEmptyN)); |
304 | fEmpty->SetTitle(kEmptyT); | |
e18cb8bd | 305 | fEmpty->SetDirectory(0); |
306 | // fEmpty->Sumw2(); | |
71b70904 | 307 | } |
308 | ||
309 | //____________________________________________________________________ | |
310 | void | |
e18cb8bd | 311 | AliPoissonCalculator::Fill(UShort_t x, UShort_t y, Bool_t hit, Double_t weight) |
71b70904 | 312 | { |
ce63a99e | 313 | // |
314 | // Fill in an observation | |
315 | // | |
316 | // Parameters: | |
e18cb8bd | 317 | // x X value |
318 | // Y Y value | |
ce63a99e | 319 | // hit True if hit |
320 | // weight Weight if this | |
321 | // | |
e18cb8bd | 322 | fTotal->Fill(x, y); |
323 | if (hit) fBasic->Fill(x, y, weight); | |
324 | else fEmpty->Fill(x, y); | |
71b70904 | 325 | } |
326 | ||
327 | //____________________________________________________________________ | |
ce63a99e | 328 | Double_t |
329 | AliPoissonCalculator::CalculateMean(Double_t empty, Double_t total) const | |
330 | { | |
331 | if (total <= 0) return 0; | |
332 | if (empty < .001) empty = .001; | |
333 | return -TMath::Log(empty/total); | |
334 | } | |
335 | //____________________________________________________________________ | |
336 | Double_t | |
337 | AliPoissonCalculator::CalculateCorrection(Double_t empty, Double_t total) const | |
338 | { | |
339 | if (total <= 0) return 0; | |
340 | if (TMath::Abs(empty-total) < .001) empty = total - .001; | |
341 | return 1 / (1 - empty / total); | |
342 | } | |
343 | ||
e18cb8bd | 344 | //____________________________________________________________________ |
345 | Int_t | |
346 | AliPoissonCalculator::GetReducedXBin(Int_t ix) const | |
347 | { | |
348 | if (!fBasic) return 0; | |
349 | Double_t mx = fBasic->GetXaxis()->GetBinCenter(ix); | |
350 | return GetReducedXBin(mx); | |
351 | } | |
352 | //____________________________________________________________________ | |
353 | Int_t | |
354 | AliPoissonCalculator::GetReducedXBin(Double_t x) const | |
355 | { | |
356 | if (!fEmpty) return 0; | |
357 | return fEmpty->GetXaxis()->FindBin(x); | |
358 | } | |
359 | //____________________________________________________________________ | |
360 | Int_t | |
361 | AliPoissonCalculator::GetReducedYBin(Int_t iy) const | |
362 | { | |
363 | if (!fBasic) return 0; | |
364 | Double_t my = fBasic->GetYaxis()->GetBinCenter(iy); | |
365 | return GetReducedYBin(my); | |
366 | } | |
367 | //____________________________________________________________________ | |
368 | Int_t | |
369 | AliPoissonCalculator::GetReducedYBin(Double_t y) const | |
370 | { | |
371 | if (!fEmpty) return 0; | |
372 | return fEmpty->GetYaxis()->FindBin(y); | |
373 | } | |
374 | ||
375 | ||
376 | ||
ce63a99e | 377 | //____________________________________________________________________ |
378 | TH2D* | |
e18cb8bd | 379 | AliPoissonCalculator::Result(Bool_t correct) |
71b70904 | 380 | { |
ce63a99e | 381 | // |
382 | // Calculate result and store in @a output | |
383 | // | |
384 | // Return: | |
385 | // The result histogram (fBase overwritten) | |
386 | // | |
21d778b1 | 387 | |
e18cb8bd | 388 | // Double_t total = fXLumping * fYLumping; |
21d778b1 | 389 | |
e18cb8bd | 390 | for (Int_t ix = 1; ix <= fBasic->GetNbinsX(); ix++) { |
391 | // Double_t x = fBasic->GetXaxis()->GetBinCenter(ix); | |
392 | Int_t jx = GetReducedXBin(ix); // fEmpty->GetXaxis()->FindBin(x); | |
393 | for (Int_t iy = 1; iy <= fBasic->GetNbinsY(); iy++) { | |
394 | // Double_t y = fBasic->GetYaxis()->GetBinCenter(iy); | |
395 | Int_t jy = GetReducedYBin(iy); // fEmpty->GetYaxis()->FindBin(y); | |
396 | Double_t empty = fEmpty->GetBinContent(jx, jy); | |
397 | Double_t total = fTotal->GetBinContent(jx, jy); | |
398 | Double_t hits = fBasic->GetBinContent(ix,iy); | |
71b70904 | 399 | // Mean in region of interest |
ce63a99e | 400 | Double_t poissonM = CalculateMean(empty, total); |
e18cb8bd | 401 | Double_t poissonC = (correct ? CalculateCorrection(empty, total) : 1); |
21d778b1 | 402 | |
ce63a99e | 403 | Double_t poissonV = hits * poissonM * poissonC; |
404 | Double_t poissonE = TMath::Sqrt(poissonV); | |
71b70904 | 405 | if(poissonV > 0) poissonE = TMath::Sqrt(poissonV); |
406 | ||
e18cb8bd | 407 | fBasic->SetBinContent(ix,iy,poissonV); |
408 | fBasic->SetBinError(ix,iy,poissonE); | |
71b70904 | 409 | } |
410 | } | |
e18cb8bd | 411 | for (Int_t ix = 1; ix <= fEmpty->GetNbinsX(); ix++) { |
412 | for (Int_t iy = 1; iy <= fEmpty->GetNbinsY(); iy++) { | |
413 | Double_t empty = fEmpty->GetBinContent(ix, iy); | |
414 | Double_t total = fTotal->GetBinContent(ix, iy); | |
ce63a99e | 415 | Double_t mean = CalculateMean(empty, total); |
416 | Double_t corr = CalculateCorrection(empty, total); | |
417 | fEmptyVsTotal->Fill(total, empty); | |
418 | fMean->Fill(mean); | |
9efd555b | 419 | if (total > 1e-6) fOcc->Fill(100 * (1 - empty/total)); |
21d778b1 | 420 | //Old fOcc->Fill(100 * (1 - TMath::PoissonI(0,mean))); |
ce63a99e | 421 | fCorr->Fill(mean, corr); |
422 | } | |
423 | } | |
424 | return fBasic; | |
71b70904 | 425 | } |
426 | ||
427 | //____________________________________________________________________ | |
428 | void | |
429 | AliPoissonCalculator::Print(const Option_t*) const | |
430 | { | |
ce63a99e | 431 | // |
432 | // Print information | |
433 | // | |
434 | // Parameters: | |
435 | // option Not used | |
436 | // | |
71b70904 | 437 | char ind[gROOT->GetDirLevel()+3]; |
438 | for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' '; | |
439 | ind[gROOT->GetDirLevel()] = '\0'; | |
440 | std::cout << ind << ClassName() << ": " << GetName() << '\n' | |
441 | << std::boolalpha | |
e18cb8bd | 442 | << ind << " X lumping: " << fXLumping << '\n' |
443 | << ind << " Y lumping: " << fYLumping << '\n' | |
9a621151 | 444 | << std::noboolalpha << std::endl; |
71b70904 | 445 | } |
446 | //____________________________________________________________________ | |
447 | void | |
448 | AliPoissonCalculator::Browse(TBrowser* b) | |
449 | { | |
ce63a99e | 450 | // |
451 | // Browse this object | |
452 | // | |
453 | // Parameters: | |
454 | // b Object to browse | |
455 | // | |
456 | if (fTotal) b->Add(fTotal); | |
457 | if (fEmpty) b->Add(fEmpty); | |
458 | if (fBasic) b->Add(fBasic); | |
459 | if (fEmptyVsTotal) b->Add(fEmptyVsTotal); | |
460 | if (fMean) b->Add(fMean); | |
461 | if (fOcc) b->Add(fOcc); | |
462 | if (fCorr) b->Add(fCorr); | |
71b70904 | 463 | } |
464 | // | |
465 | // EOF | |
466 | // |