]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/FORWARD/analysis2/AliPoissonCalculator.cxx
Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / AliPoissonCalculator.cxx
CommitLineData
71b70904 1#include "AliPoissonCalculator.h"
8449e3e0 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 41namespace {
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//____________________________________________________________________
54AliPoissonCalculator::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 72AliPoissonCalculator::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//____________________________________________________________________
89AliPoissonCalculator::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//____________________________________________________________________
106AliPoissonCalculator::~AliPoissonCalculator()
107{
08683480 108 // CleanUp();
ce63a99e 109}
110
111//____________________________________________________________________
112void
113AliPoissonCalculator::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//____________________________________________________________________
124AliPoissonCalculator&
125AliPoissonCalculator::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//____________________________________________________________________
138void
e18cb8bd 139AliPoissonCalculator::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//____________________________________________________________________
153void
154AliPoissonCalculator::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//____________________________________________________________________
8449e3e0 182void 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");
8449e3e0 219 fCorr->SetDirectory(0);
ce63a99e 220}
ce63a99e 221//____________________________________________________________________
222void
223AliPoissonCalculator::Output(TList* d)
224{
225 if (!d) return;
79909b8b 226 if (!fEmptyVsTotal) MakeOutput();
ce63a99e 227 d->Add(fEmptyVsTotal);
228 d->Add(fMean);
229 d->Add(fOcc);
230 d->Add(fCorr);
231}
71b70904 232
e18cb8bd 233//____________________________________________________________________
234void
235AliPoissonCalculator::SetLumping(UShort_t nx, UShort_t ny)
236{
237 if (nx == fXLumping && ny == fYLumping &&
238 fEmptyVsTotal && fTotal)
239 // Check if we have something to do.
240 return;
241 CleanUp();
242 Init(nx, ny);
243}
244
d23503ee 245//____________________________________________________________________
246Int_t
247AliPoissonCalculator::CheckLumping(char which, Int_t nBins, Int_t lumping) const
248{
249 if ((nBins % lumping) == 0) return lumping;
250 Int_t l = lumping;
251 do {
252 l--;
253 } while (l > 0 && ((nBins % l) != 0));
254 Warning("CheckLumping", "%c lumping %d is not a divisor of %d, set to %d",
255 which, lumping, nBins, l);
256 return l;
257}
258
71b70904 259//____________________________________________________________________
260void
d23503ee 261AliPoissonCalculator::Reset(const TH2D* base)
71b70904 262{
ce63a99e 263 //
264 // Reset histogram
265 //
e18cb8bd 266 if (fBasic && fTotal && fEmpty) {
71b70904 267 fBasic->Reset();
e18cb8bd 268 fTotal->Reset();
269 fEmpty->Reset();
71b70904 270 return;
271 }
d23503ee 272
273 if (!base) return;
274
275 Int_t nXF = base->GetNbinsX();
276 Double_t xMin = base->GetXaxis()->GetXmin();
277 Double_t xMax = base->GetXaxis()->GetXmax();
278 Int_t nYF = base->GetNbinsY();
279 Double_t yMin = base->GetYaxis()->GetXmin();
280 Double_t yMax = base->GetYaxis()->GetXmax();
281
282 fXLumping = CheckLumping('X', nXF, fXLumping);
283 fYLumping = CheckLumping('Y', nYF, fYLumping);
284
e18cb8bd 285 Int_t nY = nYF / fYLumping;
d23503ee 286 Int_t nX = nXF / fXLumping;
63d9ab53 287
d23503ee 288 if (fBasic != base) {
289 fBasic = static_cast<TH2D*>(base->Clone(kBasicN));
290 fBasic->SetTitle(kBasicT);
291 fBasic->SetDirectory(0);
292 fBasic->Sumw2();
293 }
21d778b1 294
d23503ee 295 fTotal = new TH2D(kTotalN, kTotalT, nX, xMin, xMax, nY, yMin, yMax);
e18cb8bd 296 fTotal->SetDirectory(0);
297 fTotal->SetXTitle(fBasic->GetXaxis()->GetTitle());
298 fTotal->SetYTitle(fBasic->GetYaxis()->GetTitle());
299 fTotal->Sumw2();
300
d23503ee 301 fEmpty = static_cast<TH2D*>(fTotal->Clone(kEmptyN));
302 fEmpty->SetTitle(kEmptyT);
e18cb8bd 303 fEmpty->SetDirectory(0);
304 // fEmpty->Sumw2();
71b70904 305}
306
307//____________________________________________________________________
308void
e18cb8bd 309AliPoissonCalculator::Fill(UShort_t x, UShort_t y, Bool_t hit, Double_t weight)
71b70904 310{
ce63a99e 311 //
312 // Fill in an observation
313 //
314 // Parameters:
e18cb8bd 315 // x X value
316 // Y Y value
ce63a99e 317 // hit True if hit
318 // weight Weight if this
319 //
e18cb8bd 320 fTotal->Fill(x, y);
321 if (hit) fBasic->Fill(x, y, weight);
322 else fEmpty->Fill(x, y);
71b70904 323}
324
325//____________________________________________________________________
ce63a99e 326Double_t
327AliPoissonCalculator::CalculateMean(Double_t empty, Double_t total) const
328{
329 if (total <= 0) return 0;
330 if (empty < .001) empty = .001;
331 return -TMath::Log(empty/total);
332}
333//____________________________________________________________________
334Double_t
335AliPoissonCalculator::CalculateCorrection(Double_t empty, Double_t total) const
336{
337 if (total <= 0) return 0;
338 if (TMath::Abs(empty-total) < .001) empty = total - .001;
339 return 1 / (1 - empty / total);
340}
341
e18cb8bd 342//____________________________________________________________________
343Int_t
344AliPoissonCalculator::GetReducedXBin(Int_t ix) const
345{
346 if (!fBasic) return 0;
347 Double_t mx = fBasic->GetXaxis()->GetBinCenter(ix);
348 return GetReducedXBin(mx);
349}
350//____________________________________________________________________
351Int_t
352AliPoissonCalculator::GetReducedXBin(Double_t x) const
353{
354 if (!fEmpty) return 0;
355 return fEmpty->GetXaxis()->FindBin(x);
356}
357//____________________________________________________________________
358Int_t
359AliPoissonCalculator::GetReducedYBin(Int_t iy) const
360{
361 if (!fBasic) return 0;
362 Double_t my = fBasic->GetYaxis()->GetBinCenter(iy);
363 return GetReducedYBin(my);
364}
365//____________________________________________________________________
366Int_t
367AliPoissonCalculator::GetReducedYBin(Double_t y) const
368{
369 if (!fEmpty) return 0;
370 return fEmpty->GetYaxis()->FindBin(y);
371}
372
373
374
ce63a99e 375//____________________________________________________________________
376TH2D*
e18cb8bd 377AliPoissonCalculator::Result(Bool_t correct)
71b70904 378{
ce63a99e 379 //
380 // Calculate result and store in @a output
381 //
382 // Return:
383 // The result histogram (fBase overwritten)
384 //
21d778b1 385
e18cb8bd 386 // Double_t total = fXLumping * fYLumping;
21d778b1 387
e18cb8bd 388 for (Int_t ix = 1; ix <= fBasic->GetNbinsX(); ix++) {
389 // Double_t x = fBasic->GetXaxis()->GetBinCenter(ix);
390 Int_t jx = GetReducedXBin(ix); // fEmpty->GetXaxis()->FindBin(x);
391 for (Int_t iy = 1; iy <= fBasic->GetNbinsY(); iy++) {
392 // Double_t y = fBasic->GetYaxis()->GetBinCenter(iy);
393 Int_t jy = GetReducedYBin(iy); // fEmpty->GetYaxis()->FindBin(y);
394 Double_t empty = fEmpty->GetBinContent(jx, jy);
395 Double_t total = fTotal->GetBinContent(jx, jy);
396 Double_t hits = fBasic->GetBinContent(ix,iy);
71b70904 397 // Mean in region of interest
ce63a99e 398 Double_t poissonM = CalculateMean(empty, total);
e18cb8bd 399 Double_t poissonC = (correct ? CalculateCorrection(empty, total) : 1);
21d778b1 400
ce63a99e 401 Double_t poissonV = hits * poissonM * poissonC;
402 Double_t poissonE = TMath::Sqrt(poissonV);
71b70904 403 if(poissonV > 0) poissonE = TMath::Sqrt(poissonV);
404
e18cb8bd 405 fBasic->SetBinContent(ix,iy,poissonV);
406 fBasic->SetBinError(ix,iy,poissonE);
71b70904 407 }
408 }
77f97e3f
CHC
409 return fBasic;
410}
411
412//____________________________________________________________________
413void
414AliPoissonCalculator::FillDiagnostics()
415{
e18cb8bd 416 for (Int_t ix = 1; ix <= fEmpty->GetNbinsX(); ix++) {
417 for (Int_t iy = 1; iy <= fEmpty->GetNbinsY(); iy++) {
418 Double_t empty = fEmpty->GetBinContent(ix, iy);
419 Double_t total = fTotal->GetBinContent(ix, iy);
ce63a99e 420 Double_t mean = CalculateMean(empty, total);
421 Double_t corr = CalculateCorrection(empty, total);
422 fEmptyVsTotal->Fill(total, empty);
423 fMean->Fill(mean);
9efd555b 424 if (total > 1e-6) fOcc->Fill(100 * (1 - empty/total));
21d778b1 425 //Old fOcc->Fill(100 * (1 - TMath::PoissonI(0,mean)));
ce63a99e 426 fCorr->Fill(mean, corr);
427 }
428 }
71b70904 429}
71b70904 430//____________________________________________________________________
431void
432AliPoissonCalculator::Print(const Option_t*) const
433{
ce63a99e 434 //
435 // Print information
436 //
437 // Parameters:
438 // option Not used
439 //
71b70904 440 char ind[gROOT->GetDirLevel()+3];
441 for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
442 ind[gROOT->GetDirLevel()] = '\0';
443 std::cout << ind << ClassName() << ": " << GetName() << '\n'
444 << std::boolalpha
e18cb8bd 445 << ind << " X lumping: " << fXLumping << '\n'
446 << ind << " Y lumping: " << fYLumping << '\n'
9a621151 447 << std::noboolalpha << std::endl;
71b70904 448}
449//____________________________________________________________________
450void
451AliPoissonCalculator::Browse(TBrowser* b)
452{
ce63a99e 453 //
454 // Browse this object
455 //
456 // Parameters:
457 // b Object to browse
458 //
459 if (fTotal) b->Add(fTotal);
460 if (fEmpty) b->Add(fEmpty);
461 if (fBasic) b->Add(fBasic);
462 if (fEmptyVsTotal) b->Add(fEmptyVsTotal);
463 if (fMean) b->Add(fMean);
464 if (fOcc) b->Add(fOcc);
465 if (fCorr) b->Add(fCorr);
71b70904 466}
467//
468// EOF
469//