1 #include "AliPoissonCalculator.h"
2 #include "AliForwardCorrectionManager.h"
11 // A class to calculate the multiplicity in @f$(x,y)@f$ bins
12 // using Poisson statistics.
14 // The input is assumed to be binned in @f$(x,y)@f$ as described by
15 // the 2D histogram passwd to the Reset member function.
17 // The data is grouped in to regions as defined by the parameters
18 // fXLumping and fYLumping. The total number of cells and number of
19 // empty cells is then calculate in each region. The mean
20 // multiplicity over the region is then determined as
23 // \lange m\rangle = -\log\left(\frac{e}{t}\right)
25 // where @f$ e@f$ is the number of empty cells and @f$t@f$ is the
26 // total number of cells in the region. A correction for counting
27 // statistics, is then applied
29 // c &=& \frac{1}{1 - \exp{-\lange m\rangle}}
30 // &=& \frac{1}{1 - \frac{e}{t}}
32 // and the final number in each cell is then
34 // h_i c \lange m\rangle
36 // where @f$h_i@f$ is the number of hits in the cell @f$i@f$
40 //____________________________________________________________________
41 AliPoissonCalculator::AliPoissonCalculator()
58 //____________________________________________________________________
59 AliPoissonCalculator::AliPoissonCalculator(const char*/*, UShort_t d, Char_t r*/)
60 : TNamed("poissonCalculator", "Calculate N_ch using Poisson stat"),
75 //____________________________________________________________________
76 AliPoissonCalculator::AliPoissonCalculator(const AliPoissonCalculator& o)
78 fXLumping(o.fXLumping),
79 fYLumping(o.fYLumping),
92 //____________________________________________________________________
93 AliPoissonCalculator::~AliPoissonCalculator()
98 //____________________________________________________________________
100 AliPoissonCalculator::CleanUp()
102 if (fTotal) { delete fTotal; fTotal = 0; }
103 if (fEmpty) { delete fEmpty; fEmpty = 0; }
104 if (fBasic) { delete fBasic; fBasic = 0; }
105 if (fEmptyVsTotal) { delete fEmptyVsTotal; fEmptyVsTotal = 0; }
106 if (fMean) { delete fMean; fMean = 0; }
107 if (fOcc) { delete fOcc; fOcc = 0; }
108 if (fCorr) { delete fCorr; fCorr = 0; }
110 //____________________________________________________________________
111 AliPoissonCalculator&
112 AliPoissonCalculator::operator=(const AliPoissonCalculator& o)
114 if (&o == this) return *this;
115 TNamed::operator=(o);
116 fXLumping = o.fXLumping;
117 fYLumping = o.fYLumping;
124 //____________________________________________________________________
126 AliPoissonCalculator::Init(Int_t xLumping, Int_t yLumping)
131 if (xLumping > 0) fXLumping = xLumping;
132 if (yLumping > 0) fYLumping = yLumping;
134 //Create diagnostics if void
135 if (fEmptyVsTotal) return;
141 //____________________________________________________________________
142 void AliPoissonCalculator::MakeOutput() {
144 Int_t n = fXLumping * fYLumping + 1;
145 fEmptyVsTotal = new TH2D("emptyVsTotal",
146 "# of empty # bins vs total # bins",
147 n, -.5, n-.5, n, -.5, n-.5);
148 fEmptyVsTotal->SetXTitle("Total # bins");
149 fEmptyVsTotal->SetYTitle("# empty bins");
150 fEmptyVsTotal->SetZTitle("Correlation");
151 fEmptyVsTotal->SetOption("colz");
152 fEmptyVsTotal->SetDirectory(0);
154 n = (fXLumping + fYLumping);
155 fMean = new TH1D("poissonMean", "Mean N_{ch} as calculated by Poisson",
157 fMean->SetXTitle("#bar{N_{ch}}=log(empty/total)");
158 fMean->SetYTitle("Events");
159 fMean->SetFillColor(kRed+1);
160 fMean->SetFillStyle(3001);
161 fMean->SetLineColor(kBlack);
162 fMean->SetDirectory(0);
164 fOcc = new TH1D("occupancy", "Occupancy = #int_{1}^{#infty}dN P(N)",
166 fOcc->SetXTitle("#int_{1}^{#infty}dN P(N) [%]");
167 fOcc->SetYTitle("Events");
168 fOcc->SetFillColor(kBlue+1);
169 fOcc->SetFillStyle(3001);
170 fOcc->SetLineColor(kBlack);
171 fOcc->SetDirectory(0);
173 fCorr = new TH2D("correction", "Correction as function of mean N_{ch}",
174 10*n+1, -.1, n+.1, 100, 0, 10);
175 fCorr->SetXTitle("#bar{N_{ch}}");
176 fCorr->SetYTitle("Correction 1/(1-e^{#bar{N_{c}}})");
177 fCorr->SetZTitle("Events");
178 fCorr->SetOption("colz");
179 fCorr->SetDirectory(0);
183 //____________________________________________________________________
185 AliPoissonCalculator::Output(TList* d)
188 if (!fEmptyVsTotal) MakeOutput();
189 d->Add(fEmptyVsTotal);
195 //____________________________________________________________________
197 AliPoissonCalculator::SetLumping(UShort_t nx, UShort_t ny)
199 if (nx == fXLumping && ny == fYLumping &&
200 fEmptyVsTotal && fTotal)
201 // Check if we have something to do.
207 //____________________________________________________________________
209 AliPoissonCalculator::Reset(const TH2D* base)
216 if (fBasic && fTotal && fEmpty) {
222 Int_t nXF = base->GetNbinsX();
223 Int_t nX = nXF / fXLumping;
224 Double_t xMin = base->GetXaxis()->GetXmin();
225 Double_t xMax = base->GetXaxis()->GetXmax();
226 Int_t nYF = base->GetNbinsY();
227 Int_t nY = nYF / fYLumping;
228 Double_t yMin = base->GetYaxis()->GetXmin();
229 Double_t yMax = base->GetYaxis()->GetXmax();
231 fBasic = static_cast<TH2D*>(base->Clone("basic"));
232 fBasic->SetTitle("Basic number of hits");
233 fBasic->SetDirectory(0);
236 fTotal = new TH2D("total", "Total number of bins/region",
237 nX, xMin, xMax, nY, yMin, yMax);
238 fTotal->SetDirectory(0);
239 fTotal->SetXTitle(fBasic->GetXaxis()->GetTitle());
240 fTotal->SetYTitle(fBasic->GetYaxis()->GetTitle());
243 fEmpty = static_cast<TH2D*>(fTotal->Clone("empty"));
244 fEmpty->SetTitle("Empty number of bins/region");
245 fEmpty->SetDirectory(0);
249 //____________________________________________________________________
251 AliPoissonCalculator::Fill(UShort_t x, UShort_t y, Bool_t hit, Double_t weight)
254 // Fill in an observation
260 // weight Weight if this
263 if (hit) fBasic->Fill(x, y, weight);
264 else fEmpty->Fill(x, y);
267 //____________________________________________________________________
269 AliPoissonCalculator::CalculateMean(Double_t empty, Double_t total) const
271 if (total <= 0) return 0;
272 if (empty < .001) empty = .001;
273 return -TMath::Log(empty/total);
275 //____________________________________________________________________
277 AliPoissonCalculator::CalculateCorrection(Double_t empty, Double_t total) const
279 if (total <= 0) return 0;
280 if (TMath::Abs(empty-total) < .001) empty = total - .001;
281 return 1 / (1 - empty / total);
284 //____________________________________________________________________
286 AliPoissonCalculator::GetReducedXBin(Int_t ix) const
288 if (!fBasic) return 0;
289 Double_t mx = fBasic->GetXaxis()->GetBinCenter(ix);
290 return GetReducedXBin(mx);
292 //____________________________________________________________________
294 AliPoissonCalculator::GetReducedXBin(Double_t x) const
296 if (!fEmpty) return 0;
297 return fEmpty->GetXaxis()->FindBin(x);
299 //____________________________________________________________________
301 AliPoissonCalculator::GetReducedYBin(Int_t iy) const
303 if (!fBasic) return 0;
304 Double_t my = fBasic->GetYaxis()->GetBinCenter(iy);
305 return GetReducedYBin(my);
307 //____________________________________________________________________
309 AliPoissonCalculator::GetReducedYBin(Double_t y) const
311 if (!fEmpty) return 0;
312 return fEmpty->GetYaxis()->FindBin(y);
317 //____________________________________________________________________
319 AliPoissonCalculator::Result(Bool_t correct)
322 // Calculate result and store in @a output
325 // The result histogram (fBase overwritten)
328 // Double_t total = fXLumping * fYLumping;
330 for (Int_t ix = 1; ix <= fBasic->GetNbinsX(); ix++) {
331 // Double_t x = fBasic->GetXaxis()->GetBinCenter(ix);
332 Int_t jx = GetReducedXBin(ix); // fEmpty->GetXaxis()->FindBin(x);
333 for (Int_t iy = 1; iy <= fBasic->GetNbinsY(); iy++) {
334 // Double_t y = fBasic->GetYaxis()->GetBinCenter(iy);
335 Int_t jy = GetReducedYBin(iy); // fEmpty->GetYaxis()->FindBin(y);
336 Double_t empty = fEmpty->GetBinContent(jx, jy);
337 Double_t total = fTotal->GetBinContent(jx, jy);
338 Double_t hits = fBasic->GetBinContent(ix,iy);
339 // Mean in region of interest
340 Double_t poissonM = CalculateMean(empty, total);
341 Double_t poissonC = (correct ? CalculateCorrection(empty, total) : 1);
343 Double_t poissonV = hits * poissonM * poissonC;
344 Double_t poissonE = TMath::Sqrt(poissonV);
345 if(poissonV > 0) poissonE = TMath::Sqrt(poissonV);
347 fBasic->SetBinContent(ix,iy,poissonV);
348 fBasic->SetBinError(ix,iy,poissonE);
351 for (Int_t ix = 1; ix <= fEmpty->GetNbinsX(); ix++) {
352 for (Int_t iy = 1; iy <= fEmpty->GetNbinsY(); iy++) {
353 Double_t empty = fEmpty->GetBinContent(ix, iy);
354 Double_t total = fTotal->GetBinContent(ix, iy);
355 Double_t mean = CalculateMean(empty, total);
356 Double_t corr = CalculateCorrection(empty, total);
357 fEmptyVsTotal->Fill(total, empty);
359 fOcc->Fill(100 * (1 - empty/total));
360 //Old fOcc->Fill(100 * (1 - TMath::PoissonI(0,mean)));
361 fCorr->Fill(mean, corr);
367 //____________________________________________________________________
369 AliPoissonCalculator::Print(const Option_t*) const
377 char ind[gROOT->GetDirLevel()+3];
378 for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
379 ind[gROOT->GetDirLevel()] = '\0';
380 std::cout << ind << ClassName() << ": " << GetName() << '\n'
382 << ind << " X lumping: " << fXLumping << '\n'
383 << ind << " Y lumping: " << fYLumping << '\n'
384 << std::noboolalpha << std::endl;
386 //____________________________________________________________________
388 AliPoissonCalculator::Browse(TBrowser* b)
391 // Browse this object
394 // b Object to browse
396 if (fTotal) b->Add(fTotal);
397 if (fEmpty) b->Add(fEmpty);
398 if (fBasic) b->Add(fBasic);
399 if (fEmptyVsTotal) b->Add(fEmptyVsTotal);
400 if (fMean) b->Add(fMean);
401 if (fOcc) b->Add(fOcc);
402 if (fCorr) b->Add(fCorr);