1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 // This class is used to store correction maps, raw input and results of the multiplicity
19 // measurement with the ITS or TPC
20 // It also contains functions to correct the spectrum using different methods.
22 // Author: Jan.Fiete.Grosse-Oetringhaus@cern.ch
24 #include "AliMultiplicityCorrection.h"
30 #include <TDirectory.h>
31 #include <TVirtualFitter.h>
37 ClassImp(AliMultiplicityCorrection)
39 const Int_t AliMultiplicityCorrection::fgMaxParams = 90;
40 TH1* AliMultiplicityCorrection::fCurrentESD = 0;
41 TH1* AliMultiplicityCorrection::fCurrentCorrelation = 0;
43 //____________________________________________________________________
44 AliMultiplicityCorrection::AliMultiplicityCorrection() :
48 // default constructor
51 for (Int_t i = 0; i < kESDHists; ++i)
52 fMultiplicityESD[i] = 0;
54 for (Int_t i = 0; i < kMCHists; ++i)
55 fMultiplicityMC[i] = 0;
57 for (Int_t i = 0; i < kCorrHists; ++i)
60 fMultiplicityESDCorrected[i] = 0;
64 //____________________________________________________________________
65 AliMultiplicityCorrection::AliMultiplicityCorrection(const Char_t* name, const Char_t* title) :
72 // do not add this hists to the directory
73 Bool_t oldStatus = TH1::AddDirectoryStatus();
74 TH1::AddDirectory(kFALSE);
76 Float_t binLimitsVtx[] = {-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10};
77 Float_t binLimitsN[] = {-0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5,
78 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5, 18.5, 19.5,
79 20.5, 21.5, 22.5, 23.5, 24.5, 25.5, 26.5, 27.5, 28.5, 29.5,
80 30.5, 31.5, 32.5, 33.5, 34.5, 35.5, 36.5, 37.5, 38.5, 39.5,
81 40.5, 41.5, 42.5, 43.5, 44.5, 45.5, 46.5, 47.5, 48.5, 49.5,
82 50.5, 55.5, 60.5, 65.5, 70.5, 75.5, 80.5, 85.5, 90.5, 95.5,
83 100.5, 105.5, 110.5, 115.5, 120.5, 125.5, 130.5, 135.5, 140.5, 145.5,
84 150.5, 160.5, 170.5, 180.5, 190.5, 200.5, 210.5, 220.5, 230.5, 240.5,
85 250.5, 275.5, 300.5, 325.5, 350.5, 375.5, 400.5, 425.5, 450.5, 475.5,
87 //525.5, 550.5, 575.5, 600.5, 625.5, 650.5, 675.5, 700.5, 725.5,
88 //750.5, 775.5, 800.5, 825.5, 850.5, 875.5, 900.5, 925.5, 950.5, 975.5,
91 #define BINNING fgMaxParams, binLimitsN
93 for (Int_t i = 0; i < kESDHists; ++i)
94 fMultiplicityESD[i] = new TH2F(Form("fMultiplicityESD%d", i), "fMultiplicityESD;vtx-z;Ntracks;Count", 10, binLimitsVtx, BINNING);
96 for (Int_t i = 0; i < kMCHists; ++i)
98 fMultiplicityMC[i] = dynamic_cast<TH2F*> (fMultiplicityESD[0]->Clone(Form("fMultiplicityMC%d", i)));
99 fMultiplicityMC[i]->SetTitle("fMultiplicityMC");
102 for (Int_t i = 0; i < kCorrHists; ++i)
104 fCorrelation[i] = new TH3F(Form("fCorrelation%d", i), "fCorrelation;vtx-z;Npart;Ntracks", 10, binLimitsVtx, BINNING, BINNING);
105 fMultiplicityESDCorrected[i] = new TH1F(Form("fMultiplicityESDCorrected%d", i), "fMultiplicityESDCorrected;Npart;dN/dN", BINNING);
108 TH1::AddDirectory(oldStatus);
111 //____________________________________________________________________
112 AliMultiplicityCorrection::~AliMultiplicityCorrection()
119 //____________________________________________________________________
120 Long64_t AliMultiplicityCorrection::Merge(TCollection* list)
122 // Merge a list of AliMultiplicityCorrection objects with this (needed for
124 // Returns the number of merged objects (including this).
132 TIterator* iter = list->MakeIterator();
135 // collections of all histograms
136 TList collections[kESDHists+kMCHists+kCorrHists*2];
139 while ((obj = iter->Next())) {
141 AliMultiplicityCorrection* entry = dynamic_cast<AliMultiplicityCorrection*> (obj);
145 for (Int_t i = 0; i < kESDHists; ++i)
146 collections[i].Add(entry->fMultiplicityESD[i]);
148 for (Int_t i = 0; i < kMCHists; ++i)
149 collections[kESDHists+i].Add(entry->fMultiplicityMC[i]);
151 for (Int_t i = 0; i < kCorrHists; ++i)
152 collections[kESDHists+kMCHists+i].Add(entry->fCorrelation[i]);
154 for (Int_t i = 0; i < kCorrHists; ++i)
155 collections[kESDHists+kMCHists+kCorrHists+i].Add(entry->fMultiplicityESDCorrected[i]);
160 for (Int_t i = 0; i < kESDHists; ++i)
161 fMultiplicityESD[i]->Merge(&collections[i]);
163 for (Int_t i = 0; i < kMCHists; ++i)
164 fMultiplicityMC[i]->Merge(&collections[kESDHists+i]);
166 for (Int_t i = 0; i < kCorrHists; ++i)
167 fCorrelation[i]->Merge(&collections[kESDHists+kMCHists+i]);
169 for (Int_t i = 0; i < kCorrHists; ++i)
170 fMultiplicityESDCorrected[i]->Merge(&collections[kESDHists+kMCHists+kCorrHists+i]);
177 //____________________________________________________________________
178 Bool_t AliMultiplicityCorrection::LoadHistograms(const Char_t* dir)
181 // loads the histograms from a file
182 // if dir is empty a directory with the name of this object is taken (like in SaveHistogram)
188 if (!gDirectory->cd(dir))
191 // TODO memory leak. old histograms needs to be deleted.
193 Bool_t success = kTRUE;
195 for (Int_t i = 0; i < kESDHists; ++i)
197 fMultiplicityESD[i] = dynamic_cast<TH2F*> (gDirectory->Get(fMultiplicityESD[i]->GetName()));
198 if (!fMultiplicityESD[i])
202 for (Int_t i = 0; i < kMCHists; ++i)
204 fMultiplicityMC[i] = dynamic_cast<TH2F*> (gDirectory->Get(fMultiplicityMC[i]->GetName()));
205 if (!fMultiplicityMC[i])
209 for (Int_t i = 0; i < kCorrHists; ++i)
211 fCorrelation[i] = dynamic_cast<TH3F*> (gDirectory->Get(fCorrelation[i]->GetName()));
212 if (!fCorrelation[i])
214 fMultiplicityESDCorrected[i] = dynamic_cast<TH1F*> (gDirectory->Get(fMultiplicityESDCorrected[i]->GetName()));
215 if (!fMultiplicityESDCorrected[i])
219 gDirectory->cd("..");
224 //____________________________________________________________________
225 void AliMultiplicityCorrection::SaveHistograms()
228 // saves the histograms
231 gDirectory->mkdir(GetName());
232 gDirectory->cd(GetName());
234 for (Int_t i = 0; i < kESDHists; ++i)
235 if (fMultiplicityESD[i])
236 fMultiplicityESD[i]->Write();
238 for (Int_t i = 0; i < kMCHists; ++i)
239 if (fMultiplicityMC[i])
240 fMultiplicityMC[i]->Write();
242 for (Int_t i = 0; i < kCorrHists; ++i)
245 fCorrelation[i]->Write();
246 if (fMultiplicityESDCorrected[i])
247 fMultiplicityESDCorrected[i]->Write();
250 gDirectory->cd("..");
253 //____________________________________________________________________
254 void AliMultiplicityCorrection::FillGenerated(Float_t vtx, Int_t generated05, Int_t generated10, Int_t generated15, Int_t generated20, Int_t generatedAll)
257 // Fills an event from MC
260 fMultiplicityMC[0]->Fill(vtx, generated05);
261 fMultiplicityMC[1]->Fill(vtx, generated10);
262 fMultiplicityMC[2]->Fill(vtx, generated15);
263 fMultiplicityMC[3]->Fill(vtx, generated20);
264 fMultiplicityMC[4]->Fill(vtx, generatedAll);
267 //____________________________________________________________________
268 void AliMultiplicityCorrection::FillMeasured(Float_t vtx, Int_t measured05, Int_t measured10, Int_t measured15, Int_t measured20)
271 // Fills an event from ESD
274 fMultiplicityESD[0]->Fill(vtx, measured05);
275 fMultiplicityESD[1]->Fill(vtx, measured10);
276 fMultiplicityESD[2]->Fill(vtx, measured15);
277 fMultiplicityESD[3]->Fill(vtx, measured20);
280 //____________________________________________________________________
281 void AliMultiplicityCorrection::FillCorrection(Float_t vtx, Int_t generated05, Int_t generated10, Int_t generated15, Int_t generated20, Int_t generatedAll, Int_t measured05, Int_t measured10, Int_t measured15, Int_t measured20)
284 // Fills an event into the correlation map with the information from MC and ESD
287 fCorrelation[0]->Fill(vtx, generated05, measured05);
288 fCorrelation[1]->Fill(vtx, generated10, measured10);
289 fCorrelation[2]->Fill(vtx, generated15, measured15);
290 fCorrelation[3]->Fill(vtx, generated20, measured20);
292 fCorrelation[4]->Fill(vtx, generatedAll, measured05);
293 fCorrelation[5]->Fill(vtx, generatedAll, measured10);
294 fCorrelation[6]->Fill(vtx, generatedAll, measured15);
295 fCorrelation[7]->Fill(vtx, generatedAll, measured20);
298 //____________________________________________________________________
299 Double_t AliMultiplicityCorrection::RegularizationPol0(Double_t *params)
301 // homogenity term for minuit fitting
302 // pure function of the parameters
303 // prefers constant function (pol0)
307 for (Int_t i=1; i<fgMaxParams; ++i)
312 Double_t right = params[i] / fCurrentESD->GetBinWidth(i+1);
313 Double_t left = params[i-1] / fCurrentESD->GetBinWidth(i);
315 Double_t diff = (right - left) / right;
322 //____________________________________________________________________
323 Double_t AliMultiplicityCorrection::RegularizationPol1(Double_t *params)
325 // homogenity term for minuit fitting
326 // pure function of the parameters
327 // prefers linear function (pol1)
331 for (Int_t i=2; i<fgMaxParams; ++i)
333 if (params[i] == 0 || params[i-1] == 0)
336 Double_t right = params[i] / fCurrentESD->GetBinWidth(i+1);
337 Double_t middle = params[i-1] / fCurrentESD->GetBinWidth(i);
338 Double_t left = params[i-2] / fCurrentESD->GetBinWidth(i-1);
340 Double_t der1 = (right - middle) / fCurrentESD->GetBinWidth(i);
341 Double_t der2 = (middle - left) / fCurrentESD->GetBinWidth(i-1);
343 Double_t diff = der1 - der2;
345 // TODO give additonal weight to big bins
346 chi2 += diff * diff * fCurrentESD->GetBinWidth(i) * fCurrentESD->GetBinWidth(i-1);
348 //printf("%d --> %f\n", i, diff);
351 return chi2 / 1e5 / 2;
354 //____________________________________________________________________
355 Double_t AliMultiplicityCorrection::RegularizationTotalCurvature(Double_t *params)
357 // homogenity term for minuit fitting
358 // pure function of the parameters
359 // minimizes the total curvature (from Unfolding Methods In High-Energy Physics Experiments,
360 // V. Blobel (Hamburg U.) . DESY 84/118, Dec 1984. 40pp.
364 for (Int_t i=2; i<fgMaxParams; ++i)
366 if (params[i] == 0 || params[i-1] == 0)
369 Double_t right = params[i] / fCurrentESD->GetBinWidth(i+1);
370 Double_t middle = params[i-1] / fCurrentESD->GetBinWidth(i);
371 Double_t left = params[i-2] / fCurrentESD->GetBinWidth(i-1);
373 Double_t der1 = (right - middle) / fCurrentESD->GetBinWidth(i);
374 Double_t der2 = (middle - left) / fCurrentESD->GetBinWidth(i-1);
376 Double_t secDer = (der1 - der2) / fCurrentESD->GetBinWidth(i);
378 // square and weight with the bin width
379 chi2 += secDer * secDer * fCurrentESD->GetBinWidth(i) * fCurrentESD->GetBinWidth(i-1);
381 //printf("%d --> %f\n", i, secDer);
387 //____________________________________________________________________
388 void AliMultiplicityCorrection::MinuitFitFunction(Int_t&, Double_t*, Double_t& chi2, Double_t *params, Int_t)
391 // fit function for minuit
394 // TODO take errors into account
396 static Int_t callCount = 0;
398 Double_t chi2FromFit = 0;
400 // loop over multiplicity (x axis of fMultiplicityESD)
401 for (Int_t i=1; i<=fCurrentESD->GetNbinsX(); ++i)
403 if (i > fCurrentCorrelation->GetNbinsY())
407 //Double_t error = 0;
408 // loop over generated particles (x axis of fCorrelation) that resulted in reconstruction of i tracks
409 for (Int_t j=1; j<=fCurrentCorrelation->GetNbinsX(); ++j)
414 sum += fCurrentCorrelation->GetBinContent(j, i) * params[j-1];
416 //if (params[j-1] > 0)
417 // error += fCurrentCorrelation->GetBinError(j, i) * fCurrentCorrelation->GetBinError(j, i) * params[j-1];
418 //printf("%f ", sum);
421 Double_t diff = fCurrentESD->GetBinContent(i) - sum;
422 if (fCurrentESD->GetBinContent(i) > 0)
423 diff /= fCurrentESD->GetBinContent(i);
425 diff /= fCurrentESD->Integral();
427 // weight with bin width
428 //diff *= fCurrentESD->GetBinWidth(i);
430 //error = TMath::Sqrt(error) + fCurrentESD->GetBinError(i);
434 //Double_t tmp = diff / error;
436 chi2FromFit += diff * diff;
438 //printf("\nExpected sum = %f; Diff for bin %d is %f\n**********************************\n", fCurrentESD->GetBinContent(i), i, diff);
439 //printf("Diff for bin %d is %f\n", i, diff);
442 Double_t penaltyVal = RegularizationTotalCurvature(params);
444 chi2 = chi2FromFit * chi2FromFit + penaltyVal * penaltyVal;
446 if ((callCount++ % 100) == 0)
447 printf("%f %f --> %f\n", chi2FromFit, penaltyVal, chi2);
450 //____________________________________________________________________
451 void AliMultiplicityCorrection::SetupCurrentHists(Int_t inputRange, Bool_t fullPhaseSpace)
454 // fills fCurrentESD, fCurrentCorrelation
455 // resets fMultiplicityESDCorrected
458 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
459 fMultiplicityESDCorrected[correlationID]->Reset();
461 fCurrentESD = fMultiplicityESD[inputRange]->ProjectionY();
462 fCurrentESD->Sumw2();
464 // empty under/overflow bins in x, otherwise Project3D takes them into account
465 TH3* hist = fCorrelation[correlationID];
466 for (Int_t y=1; y<=hist->GetYaxis()->GetNbins(); ++y)
468 for (Int_t z=1; z<=hist->GetZaxis()->GetNbins(); ++z)
470 hist->SetBinContent(0, y, z, 0);
471 hist->SetBinContent(hist->GetXaxis()->GetNbins()+1, y, z, 0);
475 fCurrentCorrelation = hist->Project3D("zy");
476 fCurrentCorrelation->Sumw2();
479 //____________________________________________________________________
480 void AliMultiplicityCorrection::ApplyMinuitFit(Int_t inputRange, Bool_t fullPhaseSpace, Bool_t check)
483 // correct spectrum using minuit chi2 method
485 // if check is kTRUE the input MC solution (by definition the right solution) is used
486 // no fit is made and just the chi2 is calculated
489 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
490 Int_t mcTarget = ((fullPhaseSpace == kFALSE) ? inputRange : 4);
492 SetupCurrentHists(inputRange, fullPhaseSpace);
494 // normalize correction for given nPart
495 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
497 Double_t sum = fCurrentCorrelation->Integral(i, i, 1, fCurrentCorrelation->GetNbinsY());
500 Float_t maxValue = 0;
502 for (Int_t j=1; j<=fCurrentCorrelation->GetNbinsY(); ++j)
504 // find most probably value
505 if (maxValue < fCurrentCorrelation->GetBinContent(i, j))
507 maxValue = fCurrentCorrelation->GetBinContent(i, j);
512 fCurrentCorrelation->SetBinContent(i, j, fCurrentCorrelation->GetBinContent(i, j) / sum);
513 fCurrentCorrelation->SetBinError(i, j, fCurrentCorrelation->GetBinError(i, j) / sum);
516 printf("MPV for Ntrue = %f is %f\n", fCurrentCorrelation->GetXaxis()->GetBinCenter(i), fCurrentCorrelation->GetYaxis()->GetBinCenter(maxBin));
519 // small hack to get around charge conservation for full phase space ;-)
520 /*if (fullPhaseSpace)
522 for (Int_t i=2; i<=50; i+=2)
523 for (Int_t j=1; j<=fCurrentCorrelation->GetNbinsY(); ++j)
524 fCurrentCorrelation->SetBinContent(i, j, fCurrentCorrelation->GetBinContent(i-1, j));
527 TCanvas* canvas1 = new TCanvas("ApplyMinuitFit", "ApplyMinuitFit", 800, 400);
528 canvas1->Divide(2, 1);
530 fCurrentESD->DrawCopy();
532 fCurrentCorrelation->DrawCopy("COLZ");
534 // Initialize TMinuit via generic fitter interface
535 TVirtualFitter *minuit = TVirtualFitter::Fitter(0, fgMaxParams);
537 minuit->SetFCN(MinuitFitFunction);
539 Double_t results[fgMaxParams];
541 TH1* proj = fMultiplicityMC[mcTarget]->ProjectionY();
542 for (Int_t i=0; i<fgMaxParams; ++i)
545 results[i] = fCurrentESD->GetBinContent(i+1);
547 results[i] = proj->GetBinContent(i+1);
548 minuit->SetParameter(i, Form("param%d", i), results[i], ((results[i] > 1) ? (results[i] / 10) : 0), 0, fCurrentESD->GetMaximum() * 100);
553 MinuitFitFunction(dummy, 0, chi2, results, 0);
554 printf("Chi2 of right solution is = %f\n", chi2);
559 Double_t arglist[100];
561 //minuit->ExecuteCommand("SET PRINT", arglist, 1);
562 minuit->ExecuteCommand("MIGRAD", arglist, 1);
563 //minuit->ExecuteCommand("MINOS", arglist, 0);
565 for (Int_t i=0; i<fgMaxParams; ++i)
567 results[i] = minuit->GetParameter(i);
568 fMultiplicityESDCorrected[correlationID]->SetBinContent(i+1, results[i]);
569 fMultiplicityESDCorrected[correlationID]->SetBinError(i+1, 0);
572 printf("Penalty is %f\n", RegularizationTotalCurvature(results));
574 DrawComparison("MinuitChi2", mcTarget, correlationID);
577 //____________________________________________________________________
578 void AliMultiplicityCorrection::NormalizeToBinWidth(TH1* hist)
581 // normalizes a 1-d histogram to its bin width
584 for (Int_t i=1; i<=hist->GetNbinsX(); ++i)
586 hist->SetBinContent(i, hist->GetBinContent(i) / hist->GetBinWidth(i));
587 hist->SetBinError(i, hist->GetBinError(i) / hist->GetBinWidth(i));
591 //____________________________________________________________________
592 void AliMultiplicityCorrection::NormalizeToBinWidth(TH2* hist)
595 // normalizes a 2-d histogram to its bin width (x width * y width)
598 for (Int_t i=1; i<=hist->GetNbinsX(); ++i)
599 for (Int_t j=1; j<=hist->GetNbinsY(); ++j)
601 Double_t factor = hist->GetXaxis()->GetBinWidth(i) * hist->GetYaxis()->GetBinWidth(j);
602 hist->SetBinContent(i, j, hist->GetBinContent(i, j) / factor);
603 hist->SetBinError(i, j, hist->GetBinError(i, j) / factor);
607 //____________________________________________________________________
608 void AliMultiplicityCorrection::ApplyMinuitFitAll()
611 // fit all eta ranges
614 for (Int_t i=0; i<kESDHists; ++i)
616 ApplyMinuitFit(i, kFALSE);
617 ApplyMinuitFit(i, kTRUE);
621 //____________________________________________________________________
622 void AliMultiplicityCorrection::DrawHistograms()
626 TCanvas* canvas1 = new TCanvas("fMultiplicityESD", "fMultiplicityESD", 900, 600);
627 canvas1->Divide(3, 2);
628 for (Int_t i = 0; i < kESDHists; ++i)
631 fMultiplicityESD[i]->DrawCopy("COLZ");
632 printf("%d --> %f\n", i, (Float_t) fMultiplicityESD[i]->ProjectionY()->GetMean());
637 TCanvas* canvas2 = new TCanvas("fMultiplicityMC", "fMultiplicityMC", 900, 600);
638 canvas2->Divide(3, 2);
639 for (Int_t i = 0; i < kMCHists; ++i)
642 fMultiplicityMC[i]->DrawCopy("COLZ");
643 printf("%d --> %f\n", i, fMultiplicityMC[i]->ProjectionY()->GetMean());
646 TCanvas* canvas3 = new TCanvas("fCorrelation", "fCorrelation", 900, 900);
647 canvas3->Divide(3, 3);
648 for (Int_t i = 0; i < kCorrHists; ++i)
651 TH1* proj = fCorrelation[i]->Project3D("zy");
652 proj->DrawCopy("COLZ");
656 //____________________________________________________________________
657 void AliMultiplicityCorrection::DrawComparison(const char* name, Int_t mcID, Int_t esdCorrId, Bool_t normalizeESD)
660 tmpStr.Form("%s_DrawComparison_%d_%d", name, mcID, esdCorrId);
662 TCanvas* canvas1 = new TCanvas(tmpStr, tmpStr, 900, 300);
663 canvas1->Divide(3, 1);
666 TH1* proj = fMultiplicityMC[mcID]->ProjectionY();
667 NormalizeToBinWidth(proj);
670 NormalizeToBinWidth(fMultiplicityESDCorrected[esdCorrId]);
672 proj->GetXaxis()->SetRangeUser(0, 200);
673 proj->DrawCopy("HIST");
676 NormalizeToBinWidth(fCurrentESD);
677 fCurrentESD->SetLineColor(2);
678 fCurrentESD->DrawCopy("HISTSAME");
680 fMultiplicityESDCorrected[esdCorrId]->SetMarkerStyle(3);
681 fMultiplicityESDCorrected[esdCorrId]->DrawCopy("SAMEP");
684 fMultiplicityESDCorrected[esdCorrId]->GetXaxis()->SetRangeUser(0, 200);
685 fMultiplicityESDCorrected[esdCorrId]->DrawCopy("HIST");
688 TH1* clone = dynamic_cast<TH1*> (proj->Clone("clone"));
689 clone->Divide(fMultiplicityESDCorrected[esdCorrId]);
690 clone->SetTitle("Ratio;Npart;MC/ESD");
691 clone->GetYaxis()->SetRangeUser(0.8, 1.2);
692 clone->GetXaxis()->SetRangeUser(0, 200);
693 clone->DrawCopy("HIST");
695 /*TLegend* legend = new TLegend(0.6, 0.7, 0.85, 0.85);
696 legend->AddEntry(fMultiplicityESDCorrected, "ESD corrected");
697 legend->AddEntry(fMultiplicityMC, "MC");
698 legend->AddEntry(fMultiplicityESD, "ESD");
702 //____________________________________________________________________
703 void AliMultiplicityCorrection::ApplyBayesianMethod(Int_t inputRange, Bool_t fullPhaseSpace)
706 // correct spectrum using bayesian method
709 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
710 Int_t mcTarget = ((fullPhaseSpace == kFALSE) ? inputRange : 4);
712 SetupCurrentHists(inputRange, fullPhaseSpace);
714 // normalize correction for given nPart
715 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
717 Double_t sum = fCurrentCorrelation->Integral(i, i, 1, fCurrentCorrelation->GetNbinsY());
720 for (Int_t j=1; j<=fCurrentCorrelation->GetNbinsY(); ++j)
723 fCurrentCorrelation->SetBinContent(i, j, fCurrentCorrelation->GetBinContent(i, j) / sum);
724 fCurrentCorrelation->SetBinError(i, j, fCurrentCorrelation->GetBinError(i, j) / sum);
728 Float_t regPar = 0.01;
731 // pick prior distribution
732 TH1F* hPrior = (TH1F*)fCurrentESD->Clone("prior");
733 for (Int_t t=1; t<=hPrior->GetNbinsX(); t++)
734 norm = norm + hPrior->GetBinContent(t);
735 for (Int_t t=1; t<=hPrior->GetNbinsX(); t++) {
736 hPrior->SetBinContent(t, hPrior->GetBinContent(t)/norm);
738 printf(" bin %d content %f \n", t, hPrior->GetBinContent(t));
742 // define hist to store guess of true
743 TH1F* hTrue = (TH1F*)fCurrentESD->Clone("prior");
747 TH2F* hResponse = (TH2F*)fCurrentCorrelation->Clone("pij");
749 // histogram to store the inverse response calculated from bayes theorem (from prior and response)
751 //TAxis* xAxis = hResponse->GetYaxis();
752 //TAxis* yAxis = hResponse->GetXaxis();
754 TH2F* hInverseResponseBayes = (TH2F*)hResponse->Clone("pji");
755 //new TH2F("pji","pji",
756 // xAxis->GetNbins(),xAxis->GetXbins()->GetArray(),
757 // yAxis->GetNbins(),yAxis->GetXbins()->GetArray());
758 hInverseResponseBayes->Reset();
761 Int_t iterations = 50;
762 for (Int_t i=0; i<iterations; i++) {
763 printf(" iteration %i \n", i);
765 // calculate IR from Beyes theorem
766 // IR_ji = R_ij * prior_i / sum_k(R_kj * prior_k)
767 for (Int_t t = 1; t<=hResponse->GetNbinsX(); t++) {
768 for (Int_t m=1; m<=hResponse->GetNbinsY(); m++) {
771 for(Int_t t2 = 1; t2<=hResponse->GetNbinsX(); t2++)
772 norm += (hResponse->GetBinContent(t2,m) * hPrior->GetBinContent(t2));
775 hInverseResponseBayes->SetBinContent(t,m,0);
777 hInverseResponseBayes->SetBinContent(t,m, hResponse->GetBinContent(t,m) * hPrior->GetBinContent(t)/norm);
780 // calculate true assuming IR is the correct inverse response
781 for (Int_t t = 1; t<=hResponse->GetNbinsX(); t++) {
782 hTrue ->SetBinContent(t, 0);
783 for (Int_t m=1; m<=hResponse->GetNbinsY(); m++)
784 hTrue->SetBinContent(t, hTrue->GetBinContent(t) + fCurrentESD->GetBinContent(m)*hInverseResponseBayes->GetBinContent(t,m));
787 // regularization (simple smoothing) NB : not good bin width!!!
788 TH1F* hTrueSmoothed = (TH1F*)hTrue->Clone("truesmoothed");
790 for (Int_t t=2; t<hTrue->GetNbinsX()-1; t++) {
791 Float_t average = (hTrue->GetBinContent(t-1) / hTrue->GetBinWidth(t-1)
792 + hTrue->GetBinContent(t) / hTrue->GetBinWidth(t)
793 + hTrue->GetBinContent(t+1) / hTrue->GetBinWidth(t+1)) / 3.;
794 average *= hTrueSmoothed->GetBinWidth(t);
796 // weight the average with the regularization parameter
797 hTrueSmoothed->SetBinContent(t, (1-regPar)*hTrue->GetBinContent(t) + (regPar*average));
800 // use smoothed true (normalized) as new prior
802 for (Int_t t=1; t<=hPrior->GetNbinsX(); t++)
803 norm = norm + hTrueSmoothed->GetBinContent(t);
804 for (Int_t t=1; t<=hPrior->GetNbinsX(); t++) {
805 hPrior->SetBinContent(t, hTrueSmoothed->GetBinContent(t)/norm);
806 hTrue->SetBinContent(t, hTrueSmoothed->GetBinContent(t));
809 delete hTrueSmoothed;
810 } // end of iterations
812 for (Int_t t=1; t<=fMultiplicityESDCorrected[correlationID]->GetNbinsX(); t++) {
813 fMultiplicityESDCorrected[correlationID]->SetBinContent(t, hTrue->GetBinContent(t));
814 fMultiplicityESDCorrected[correlationID]->SetBinError(t, 0.05*hTrue->GetBinContent(t));
816 printf(" bin %d content %f \n", t, fMultiplicityESDCorrected[correlationID]->GetBinContent(t));
819 DrawComparison("Bayesian", mcTarget, correlationID);
822 //____________________________________________________________________
823 void AliMultiplicityCorrection::ApplyGaussianMethod(Int_t inputRange, Bool_t fullPhaseSpace)
826 // correct spectrum using a simple Gaussian approach, that is model-dependent
829 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
830 Int_t mcTarget = ((fullPhaseSpace == kFALSE) ? inputRange : 4);
832 SetupCurrentHists(inputRange, fullPhaseSpace);
834 NormalizeToBinWidth((TH2*) fCurrentCorrelation);
836 TH1D* correction = dynamic_cast<TH1D*> (fCurrentESD->Clone("GaussianMean"));
837 correction->SetTitle("GaussianMean");
839 TH1D* correctionWidth = dynamic_cast<TH1D*> (fCurrentESD->Clone("GaussianWidth"));
840 correction->SetTitle("GaussianWidth");
842 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
844 TH1D* proj = (dynamic_cast<TH2*> (fCurrentCorrelation))->ProjectionX("_px", i, i+1);
845 proj->Fit("gaus", "0Q");
846 correction->SetBinContent(i, proj->GetFunction("gaus")->GetParameter(1));
847 correctionWidth->SetBinContent(i, proj->GetFunction("gaus")->GetParameter(2));
851 // draw for debugging
854 proj->GetFunction("gaus")->DrawCopy("SAME");
857 TH1* target = fMultiplicityESDCorrected[correlationID];
859 Int_t nBins = target->GetNbinsX()*10+1;
860 Float_t* binning = new Float_t[nBins];
861 for (Int_t i=1; i<=target->GetNbinsX(); ++i)
862 for (Int_t j=0; j<10; ++j)
863 binning[(i-1)*10 + j] = target->GetXaxis()->GetBinLowEdge(i) + target->GetXaxis()->GetBinWidth(i) / 10 * j;
865 binning[nBins-1] = target->GetXaxis()->GetBinUpEdge(target->GetNbinsX());
867 TH1F* fineBinned = new TH1F("targetFineBinned", "targetFineBinned", nBins-1, binning);
869 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
871 Float_t mean = correction->GetBinContent(i);
872 Float_t width = correctionWidth->GetBinContent(i);
874 Int_t fillBegin = fineBinned->FindBin(mean - width * 3);
875 Int_t fillEnd = fineBinned->FindBin(mean + width * 3);
876 printf("bin %d mean %f width %f, filling from %d to %d\n", i, mean, width, fillBegin, fillEnd);
878 for (Int_t j=fillBegin; j <= fillEnd; ++j)
880 fineBinned->AddBinContent(j, TMath::Gaus(fineBinned->GetXaxis()->GetBinCenter(j), mean, width, kTRUE) * fCurrentESD->GetBinContent(i));
884 for (Int_t i=1; i<=target->GetNbinsX(); ++i)
887 for (Int_t j=1; j<=10; ++j)
888 sum += fineBinned->GetBinContent((i-1)*10 + j);
889 target->SetBinContent(i, sum / 10);
894 DrawComparison("Gaussian", mcTarget, correlationID, kFALSE);