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.
21 // e.g. chi2 minimization and bayesian unfolding
23 // Author: Jan.Fiete.Grosse-Oetringhaus@cern.ch
25 #include "AliMultiplicityCorrection.h"
31 #include <TDirectory.h>
32 #include <TVirtualFitter.h>
37 #include <TCollection.h>
42 #include <TProfile2D.h>
44 ClassImp(AliMultiplicityCorrection)
46 const Int_t AliMultiplicityCorrection::fgkMaxInput = 250; // bins in measured histogram
47 const Int_t AliMultiplicityCorrection::fgkMaxParams = 250; // bins in unfolded histogram = number of fit params
49 TMatrixD* AliMultiplicityCorrection::fgCorrelationMatrix = 0;
50 TMatrixD* AliMultiplicityCorrection::fgCorrelationCovarianceMatrix = 0;
51 TVectorD* AliMultiplicityCorrection::fgCurrentESDVector = 0;
52 TVectorD* AliMultiplicityCorrection::fgEntropyAPriori = 0;
54 AliMultiplicityCorrection::RegularizationType AliMultiplicityCorrection::fgRegularizationType = AliMultiplicityCorrection::kPol1;
55 Float_t AliMultiplicityCorrection::fgRegularizationWeight = 10000;
57 TF1* AliMultiplicityCorrection::fgNBD = 0;
59 Float_t AliMultiplicityCorrection::fgBayesianSmoothing = 1; // smoothing parameter (0 = no smoothing)
60 Int_t AliMultiplicityCorrection::fgBayesianIterations = 100; // number of iterations in Bayesian method
62 // These are the areas where the quality of the unfolding results are evaluated
63 // Default defined here, call SetQualityRegions to change them
64 // unit is in multiplicity (not in bin!)
66 // SPD: peak area - flat area - low stat area
67 Int_t AliMultiplicityCorrection::fgQualityRegionsB[kQualityRegions] = {4, 60, 180};
68 Int_t AliMultiplicityCorrection::fgQualityRegionsE[kQualityRegions] = {20, 140, 210};
70 //____________________________________________________________________
71 void AliMultiplicityCorrection::SetQualityRegions(Bool_t SPDStudy)
74 // sets the quality region definition to TPC or SPD
79 // SPD: peak area - flat area - low stat area
80 fgQualityRegionsB[0] = 4;
81 fgQualityRegionsE[0] = 20;
83 fgQualityRegionsB[1] = 60;
84 fgQualityRegionsE[1] = 140;
86 fgQualityRegionsB[2] = 180;
87 fgQualityRegionsE[2] = 210;
89 Printf("AliMultiplicityCorrection::SetQualityRegions --> Enabled quality regions for SPD");
93 // TPC: peak area - flat area - low stat area
94 fgQualityRegionsB[0] = 4;
95 fgQualityRegionsE[0] = 12;
97 fgQualityRegionsB[1] = 25;
98 fgQualityRegionsE[1] = 55;
100 fgQualityRegionsB[2] = 88;
101 fgQualityRegionsE[2] = 108;
103 Printf("AliMultiplicityCorrection::SetQualityRegions --> Enabled quality regions for TPC");
107 //____________________________________________________________________
108 AliMultiplicityCorrection::AliMultiplicityCorrection() :
109 TNamed(), fCurrentESD(0), fCurrentCorrelation(0), fCurrentEfficiency(0), fLastChi2MC(0), fLastChi2MCLimit(0), fLastChi2Residuals(0), fRatioAverage(0)
112 // default constructor
115 for (Int_t i = 0; i < kESDHists; ++i)
116 fMultiplicityESD[i] = 0;
118 for (Int_t i = 0; i < kMCHists; ++i)
120 fMultiplicityVtx[i] = 0;
121 fMultiplicityMB[i] = 0;
122 fMultiplicityINEL[i] = 0;
125 for (Int_t i = 0; i < kCorrHists; ++i)
128 fMultiplicityESDCorrected[i] = 0;
131 for (Int_t i = 0; i < kQualityRegions; ++i)
135 //____________________________________________________________________
136 AliMultiplicityCorrection::AliMultiplicityCorrection(const Char_t* name, const Char_t* title) :
137 TNamed(name, title), fLastChi2MC(0), fLastChi2MCLimit(0), fLastChi2Residuals(0), fRatioAverage(0)
143 // do not add this hists to the directory
144 Bool_t oldStatus = TH1::AddDirectoryStatus();
145 TH1::AddDirectory(kFALSE);
147 /*Float_t binLimitsVtx[] = {-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10};
148 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,
149 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5, 18.5, 19.5,
150 20.5, 21.5, 22.5, 23.5, 24.5, 25.5, 26.5, 27.5, 28.5, 29.5,
151 30.5, 31.5, 32.5, 33.5, 34.5, 35.5, 36.5, 37.5, 38.5, 39.5,
152 40.5, 41.5, 42.5, 43.5, 44.5, 45.5, 46.5, 47.5, 48.5, 49.5,
153 50.5, 55.5, 60.5, 65.5, 70.5, 75.5, 80.5, 85.5, 90.5, 95.5,
154 100.5, 105.5, 110.5, 115.5, 120.5, 125.5, 130.5, 135.5, 140.5, 145.5,
155 150.5, 160.5, 170.5, 180.5, 190.5, 200.5, 210.5, 220.5, 230.5, 240.5,
156 250.5, 275.5, 300.5, 325.5, 350.5, 375.5, 400.5, 425.5, 450.5, 475.5,
158 //525.5, 550.5, 575.5, 600.5, 625.5, 650.5, 675.5, 700.5, 725.5,
159 //750.5, 775.5, 800.5, 825.5, 850.5, 875.5, 900.5, 925.5, 950.5, 975.5,
162 #define VTXBINNING 10, binLimitsVtx
163 #define NBINNING fgkMaxParams, binLimitsN*/
165 #define NBINNING 501, -0.5, 500.5
166 #define VTXBINNING 1, -10, 10
168 for (Int_t i = 0; i < kESDHists; ++i)
169 fMultiplicityESD[i] = new TH2F(Form("fMultiplicityESD%d", i), "fMultiplicityESD;vtx-z;Ntracks;Count", VTXBINNING, NBINNING);
171 for (Int_t i = 0; i < kMCHists; ++i)
173 fMultiplicityVtx[i] = dynamic_cast<TH2F*> (fMultiplicityESD[0]->Clone(Form("fMultiplicityVtx%d", i)));
174 fMultiplicityVtx[i]->SetTitle("fMultiplicityVtx;vtx-z;Npart");
176 fMultiplicityMB[i] = dynamic_cast<TH2F*> (fMultiplicityVtx[0]->Clone(Form("fMultiplicityMB%d", i)));
177 fMultiplicityMB[i]->SetTitle("fMultiplicityMB");
179 fMultiplicityINEL[i] = dynamic_cast<TH2F*> (fMultiplicityVtx[0]->Clone(Form("fMultiplicityINEL%d", i)));
180 fMultiplicityINEL[i]->SetTitle("fMultiplicityINEL");
183 for (Int_t i = 0; i < kCorrHists; ++i)
185 fCorrelation[i] = new TH3F(Form("fCorrelation%d", i), "fCorrelation;vtx-z;Npart;Ntracks", VTXBINNING, NBINNING, NBINNING);
186 fMultiplicityESDCorrected[i] = new TH1F(Form("fMultiplicityESDCorrected%d", i), "fMultiplicityESDCorrected;Npart;dN/dN", NBINNING);
189 TH1::AddDirectory(oldStatus);
192 //____________________________________________________________________
193 AliMultiplicityCorrection::~AliMultiplicityCorrection()
199 for (Int_t i = 0; i < kESDHists; ++i)
201 if (fMultiplicityESD[i])
202 delete fMultiplicityESD[i];
203 fMultiplicityESD[i] = 0;
206 for (Int_t i = 0; i < kMCHists; ++i)
208 if (fMultiplicityVtx[i])
209 delete fMultiplicityVtx[i];
210 fMultiplicityVtx[i] = 0;
212 if (fMultiplicityMB[i])
213 delete fMultiplicityMB[i];
214 fMultiplicityMB[i] = 0;
216 if (fMultiplicityINEL[i])
217 delete fMultiplicityINEL[i];
218 fMultiplicityINEL[i] = 0;
221 for (Int_t i = 0; i < kCorrHists; ++i)
224 delete fCorrelation[i];
227 if (fMultiplicityESDCorrected[i])
228 delete fMultiplicityESDCorrected[i];
229 fMultiplicityESDCorrected[i] = 0;
233 //____________________________________________________________________
234 Long64_t AliMultiplicityCorrection::Merge(TCollection* list)
236 // Merge a list of AliMultiplicityCorrection objects with this (needed for
238 // Returns the number of merged objects (including this).
246 TIterator* iter = list->MakeIterator();
249 // collections of all histograms
250 TList collections[kESDHists+kMCHists*3+kCorrHists*2];
253 while ((obj = iter->Next())) {
255 AliMultiplicityCorrection* entry = dynamic_cast<AliMultiplicityCorrection*> (obj);
259 for (Int_t i = 0; i < kESDHists; ++i)
260 collections[i].Add(entry->fMultiplicityESD[i]);
262 for (Int_t i = 0; i < kMCHists; ++i)
264 collections[kESDHists+i].Add(entry->fMultiplicityVtx[i]);
265 collections[kESDHists+kMCHists+i].Add(entry->fMultiplicityMB[i]);
266 collections[kESDHists+kMCHists*2+i].Add(entry->fMultiplicityINEL[i]);
269 for (Int_t i = 0; i < kCorrHists; ++i)
270 collections[kESDHists+kMCHists*3+i].Add(entry->fCorrelation[i]);
272 for (Int_t i = 0; i < kCorrHists; ++i)
273 collections[kESDHists+kMCHists*3+kCorrHists+i].Add(entry->fMultiplicityESDCorrected[i]);
278 for (Int_t i = 0; i < kESDHists; ++i)
279 fMultiplicityESD[i]->Merge(&collections[i]);
281 for (Int_t i = 0; i < kMCHists; ++i)
283 fMultiplicityVtx[i]->Merge(&collections[kESDHists+i]);
284 fMultiplicityMB[i]->Merge(&collections[kESDHists+kMCHists+i]);
285 fMultiplicityINEL[i]->Merge(&collections[kESDHists+kMCHists*2+i]);
288 for (Int_t i = 0; i < kCorrHists; ++i)
289 fCorrelation[i]->Merge(&collections[kESDHists+kMCHists*3+i]);
291 for (Int_t i = 0; i < kCorrHists; ++i)
292 fMultiplicityESDCorrected[i]->Merge(&collections[kESDHists+kMCHists*3+kCorrHists+i]);
299 //____________________________________________________________________
300 Bool_t AliMultiplicityCorrection::LoadHistograms(const Char_t* dir)
303 // loads the histograms from a file
304 // if dir is empty a directory with the name of this object is taken (like in SaveHistogram)
310 if (!gDirectory->cd(dir))
313 // TODO memory leak. old histograms needs to be deleted.
315 Bool_t success = kTRUE;
317 for (Int_t i = 0; i < kESDHists; ++i)
319 fMultiplicityESD[i] = dynamic_cast<TH2F*> (gDirectory->Get(fMultiplicityESD[i]->GetName()));
320 if (!fMultiplicityESD[i])
324 for (Int_t i = 0; i < kMCHists; ++i)
326 fMultiplicityVtx[i] = dynamic_cast<TH2F*> (gDirectory->Get(fMultiplicityVtx[i]->GetName()));
327 fMultiplicityMB[i] = dynamic_cast<TH2F*> (gDirectory->Get(fMultiplicityMB[i]->GetName()));
328 fMultiplicityINEL[i] = dynamic_cast<TH2F*> (gDirectory->Get(fMultiplicityINEL[i]->GetName()));
329 if (!fMultiplicityVtx[i] || !fMultiplicityMB[i] || !fMultiplicityINEL[i])
333 for (Int_t i = 0; i < kCorrHists; ++i)
335 fCorrelation[i] = dynamic_cast<TH3F*> (gDirectory->Get(fCorrelation[i]->GetName()));
336 if (!fCorrelation[i])
338 fMultiplicityESDCorrected[i] = dynamic_cast<TH1F*> (gDirectory->Get(fMultiplicityESDCorrected[i]->GetName()));
339 if (!fMultiplicityESDCorrected[i])
343 gDirectory->cd("..");
348 //____________________________________________________________________
349 void AliMultiplicityCorrection::SaveHistograms()
352 // saves the histograms
355 gDirectory->mkdir(GetName());
356 gDirectory->cd(GetName());
358 for (Int_t i = 0; i < kESDHists; ++i)
359 if (fMultiplicityESD[i])
360 fMultiplicityESD[i]->Write();
362 for (Int_t i = 0; i < kMCHists; ++i)
364 if (fMultiplicityVtx[i])
365 fMultiplicityVtx[i]->Write();
366 if (fMultiplicityMB[i])
367 fMultiplicityMB[i]->Write();
368 if (fMultiplicityINEL[i])
369 fMultiplicityINEL[i]->Write();
372 for (Int_t i = 0; i < kCorrHists; ++i)
375 fCorrelation[i]->Write();
376 if (fMultiplicityESDCorrected[i])
377 fMultiplicityESDCorrected[i]->Write();
380 gDirectory->cd("..");
383 //____________________________________________________________________
384 void AliMultiplicityCorrection::FillGenerated(Float_t vtx, Bool_t triggered, Bool_t vertex, Int_t generated05, Int_t generated10, Int_t generated15, Int_t generated20, Int_t generatedAll)
387 // Fills an event from MC
392 fMultiplicityMB[0]->Fill(vtx, generated05);
393 fMultiplicityMB[1]->Fill(vtx, generated10);
394 fMultiplicityMB[2]->Fill(vtx, generated15);
395 fMultiplicityMB[3]->Fill(vtx, generated20);
396 fMultiplicityMB[4]->Fill(vtx, generatedAll);
400 fMultiplicityVtx[0]->Fill(vtx, generated05);
401 fMultiplicityVtx[1]->Fill(vtx, generated10);
402 fMultiplicityVtx[2]->Fill(vtx, generated15);
403 fMultiplicityVtx[3]->Fill(vtx, generated20);
404 fMultiplicityVtx[4]->Fill(vtx, generatedAll);
408 fMultiplicityINEL[0]->Fill(vtx, generated05);
409 fMultiplicityINEL[1]->Fill(vtx, generated10);
410 fMultiplicityINEL[2]->Fill(vtx, generated15);
411 fMultiplicityINEL[3]->Fill(vtx, generated20);
412 fMultiplicityINEL[4]->Fill(vtx, generatedAll);
415 //____________________________________________________________________
416 void AliMultiplicityCorrection::FillMeasured(Float_t vtx, Int_t measured05, Int_t measured10, Int_t measured15, Int_t measured20)
419 // Fills an event from ESD
422 fMultiplicityESD[0]->Fill(vtx, measured05);
423 fMultiplicityESD[1]->Fill(vtx, measured10);
424 fMultiplicityESD[2]->Fill(vtx, measured15);
425 fMultiplicityESD[3]->Fill(vtx, measured20);
428 //____________________________________________________________________
429 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)
432 // Fills an event into the correlation map with the information from MC and ESD
435 fCorrelation[0]->Fill(vtx, generated05, measured05);
436 fCorrelation[1]->Fill(vtx, generated10, measured10);
437 fCorrelation[2]->Fill(vtx, generated15, measured15);
438 fCorrelation[3]->Fill(vtx, generated20, measured20);
440 fCorrelation[4]->Fill(vtx, generatedAll, measured05);
441 fCorrelation[5]->Fill(vtx, generatedAll, measured10);
442 fCorrelation[6]->Fill(vtx, generatedAll, measured15);
443 fCorrelation[7]->Fill(vtx, generatedAll, measured20);
446 //____________________________________________________________________
447 Double_t AliMultiplicityCorrection::RegularizationPol0(TVectorD& params)
449 // homogenity term for minuit fitting
450 // pure function of the parameters
451 // prefers constant function (pol0)
455 // ignore the first bin here. on purpose...
456 for (Int_t i=2; i<fgkMaxParams; ++i)
458 Double_t right = params[i];
459 Double_t left = params[i-1];
463 Double_t diff = 1 - left / right;
471 //____________________________________________________________________
472 Double_t AliMultiplicityCorrection::RegularizationPol1(TVectorD& params)
474 // homogenity term for minuit fitting
475 // pure function of the parameters
476 // prefers linear function (pol1)
480 // ignore the first bin here. on purpose...
481 for (Int_t i=2+1; i<fgkMaxParams; ++i)
483 if (params[i-1] == 0)
486 Double_t right = params[i];
487 Double_t middle = params[i-1];
488 Double_t left = params[i-2];
490 Double_t der1 = (right - middle);
491 Double_t der2 = (middle - left);
493 Double_t diff = (der1 - der2) / middle;
501 //____________________________________________________________________
502 Double_t AliMultiplicityCorrection::RegularizationLog(TVectorD& params)
504 // homogenity term for minuit fitting
505 // pure function of the parameters
506 // prefers linear function (pol1)
510 /*Float_t der[fgkMaxParams];
512 for (Int_t i=0; i<fgkMaxParams-1; ++i)
513 der[i] = params[i+1] - params[i];
515 for (Int_t i=0; i<fgkMaxParams-6; ++i)
517 for (Int_t j=1; j<=5; ++j)
519 Double_t diff = der[i+j] - der[i];
524 // ignore the first bin here. on purpose...
525 for (Int_t i=2+1; i<fgkMaxParams; ++i)
527 if (params[i-1] == 0)
530 Double_t right = log(params[i]);
531 Double_t middle = log(params[i-1]);
532 Double_t left = log(params[i-2]);
534 Double_t der1 = (right - middle);
535 Double_t der2 = (middle - left);
537 Double_t diff = (der1 - der2) / middle;
545 //____________________________________________________________________
546 Double_t AliMultiplicityCorrection::RegularizationTotalCurvature(TVectorD& params)
548 // homogenity term for minuit fitting
549 // pure function of the parameters
550 // minimizes the total curvature (from Unfolding Methods In High-Energy Physics Experiments,
551 // V. Blobel (Hamburg U.) . DESY 84/118, Dec 1984. 40pp.
555 // ignore the first bin here. on purpose...
556 for (Int_t i=3; i<fgkMaxParams; ++i)
558 Double_t right = params[i];
559 Double_t middle = params[i-1];
560 Double_t left = params[i-2];
562 Double_t der1 = (right - middle);
563 Double_t der2 = (middle - left);
565 Double_t diff = (der1 - der2);
573 //____________________________________________________________________
574 Double_t AliMultiplicityCorrection::RegularizationEntropy(TVectorD& params)
576 // homogenity term for minuit fitting
577 // pure function of the parameters
578 // calculates entropy, from
579 // The method of reduced cross-entropy (M. Schmelling 1993)
581 Double_t paramSum = 0;
582 // ignore the first bin here. on purpose...
583 for (Int_t i=1; i<fgkMaxParams; ++i)
584 paramSum += params[i];
587 for (Int_t i=1; i<fgkMaxParams; ++i)
589 //Double_t tmp = params[i] / paramSum;
590 Double_t tmp = params[i];
591 if (tmp > 0 && (*fgEntropyAPriori)[i] > 0)
592 chi2 += tmp * TMath::Log(tmp / (*fgEntropyAPriori)[i]);
598 //____________________________________________________________________
599 void AliMultiplicityCorrection::MinuitNBD(Int_t& unused1, Double_t* unused2, Double_t& chi2, Double_t *params, Int_t unused3)
602 // fit function for minuit
604 // func = new TF1("nbd", "[0] * TMath::Binomial([2]+TMath::Nint(x)-1, [2]-1) * pow([1] / ([1]+[2]), TMath::Nint(x)) * pow(1 + [1]/[2], -[2])", 0, 50);
605 // func->SetParNames("scaling", "averagen", "k");
606 // func->SetParLimits(0, 0.001, fCurrentESD->GetMaximum() * 1000);
607 // func->SetParLimits(1, 0.001, 1000);
608 // func->SetParLimits(2, 0.001, 1000);
611 fgNBD->SetParameters(params[0], params[1], params[2]);
613 Double_t params2[fgkMaxParams];
615 for (Int_t i=0; i<fgkMaxParams; ++i)
616 params2[i] = fgNBD->Eval(i);
618 MinuitFitFunction(unused1, unused2, chi2, params2, unused3);
620 printf("%f %f %f --> %f\n", params[0], params[1], params[2], chi2);
623 //____________________________________________________________________
624 void AliMultiplicityCorrection::MinuitFitFunction(Int_t&, Double_t*, Double_t& chi2, Double_t *params, Int_t)
627 // fit function for minuit
628 // does: (m - Ad)W(m - Ad) where m = measured, A correlation matrix, d = guess, W = covariance matrix
632 static TVectorD paramsVector(fgkMaxParams);
633 for (Int_t i=0; i<fgkMaxParams; ++i)
634 paramsVector[i] = params[i] * params[i];
636 // calculate penalty factor
637 Double_t penaltyVal = 0;
638 switch (fgRegularizationType)
641 case kPol0: penaltyVal = RegularizationPol0(paramsVector); break;
642 case kPol1: penaltyVal = RegularizationPol1(paramsVector); break;
643 case kCurvature: penaltyVal = RegularizationTotalCurvature(paramsVector); break;
644 case kEntropy: penaltyVal = RegularizationEntropy(paramsVector); break;
645 case kLog: penaltyVal = RegularizationLog(paramsVector); break;
648 //if (penaltyVal > 1e10)
649 // paramsVector2.Print();
651 penaltyVal *= fgRegularizationWeight;
654 TVectorD measGuessVector(fgkMaxInput);
655 measGuessVector = (*fgCorrelationMatrix) * paramsVector;
658 measGuessVector -= (*fgCurrentESDVector);
660 TVectorD copy(measGuessVector);
663 // this step can be optimized because currently only the diagonal elements of fgCorrelationCovarianceMatrix are used
664 // normal way is like this:
665 // measGuessVector *= (*fgCorrelationCovarianceMatrix);
666 // optimized way like this:
667 for (Int_t i=0; i<fgkMaxParams; ++i)
668 measGuessVector[i] *= (*fgCorrelationCovarianceMatrix)(i, i);
670 //measGuessVector.Print();
672 // (Ad - m) W (Ad - m)
673 // the factor 1e6 prevents that a very small number (measGuessVector[i]) is multiplied with a very
674 // big number ((*fgCorrelationCovarianceMatrix)(i, i)) (see ApplyMinuitFit)
675 Double_t chi2FromFit = measGuessVector * copy * 1e6;
677 chi2 = chi2FromFit + penaltyVal;
679 static Int_t callCount = 0;
680 if ((callCount++ % 10000) == 0)
681 printf("%d) %f %f --> %f\n", callCount, chi2FromFit, penaltyVal, chi2);
684 //____________________________________________________________________
685 void AliMultiplicityCorrection::SetupCurrentHists(Int_t inputRange, Bool_t fullPhaseSpace, EventType eventType, Bool_t createBigBin)
688 // fills fCurrentESD, fCurrentCorrelation
689 // resets fMultiplicityESDCorrected
692 Bool_t display = kFALSE;
694 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
696 fMultiplicityESDCorrected[correlationID]->Reset();
697 fMultiplicityESDCorrected[correlationID]->Sumw2();
699 fCurrentESD = fMultiplicityESD[inputRange]->ProjectionY("fCurrentESD"); //"fCurrentESD", -1, -1, "e");
700 fCurrentESD->Sumw2();
702 // empty under/overflow bins in x, otherwise Project3D takes them into account
703 TH3* hist = fCorrelation[correlationID];
704 for (Int_t y=1; y<=hist->GetYaxis()->GetNbins(); ++y)
706 for (Int_t z=1; z<=hist->GetZaxis()->GetNbins(); ++z)
708 hist->SetBinContent(0, y, z, 0);
709 hist->SetBinContent(hist->GetXaxis()->GetNbins()+1, y, z, 0);
713 fCurrentCorrelation = hist->Project3D("zy");
714 //((TH2*) fCurrentCorrelation)->Rebin2D(2, 1);
715 //fMultiplicityESDCorrected[correlationID]->Rebin(2);
716 fCurrentCorrelation->Sumw2();
721 for (Int_t i=1; i<=fCurrentESD->GetNbinsX(); ++i)
723 if (fCurrentESD->GetBinContent(i) <= 5)
736 canvas = new TCanvas("StatSolution", "StatSolution", 1000, 800);
737 canvas->Divide(2, 2);
740 fCurrentESD->GetXaxis()->SetRangeUser(0, 200);
741 fCurrentESD->SetStats(kFALSE);
742 fCurrentESD->SetTitle(";measured multiplicity");
743 fCurrentESD->DrawCopy();
747 fCurrentCorrelation->GetXaxis()->SetRangeUser(0, 250);
748 fCurrentCorrelation->GetYaxis()->SetRangeUser(0, 250);
749 fCurrentCorrelation->SetTitle(";true multiplicity;measured multiplicity");
750 fCurrentCorrelation->SetStats(kFALSE);
751 fCurrentCorrelation->DrawCopy("COLZ");
754 printf("Bin limit in measured spectrum is %d.\n", maxBin);
755 fCurrentESD->SetBinContent(maxBin, fCurrentESD->Integral(maxBin, fCurrentESD->GetNbinsX()));
756 for (Int_t i=maxBin+1; i<=fCurrentESD->GetNbinsX(); ++i)
758 fCurrentESD->SetBinContent(i, 0);
759 fCurrentESD->SetBinError(i, 0);
761 // the error is set to sqrt(N), better solution possible?, sum of relative errors of all contributions???
762 fCurrentESD->SetBinError(maxBin, TMath::Sqrt(fCurrentESD->GetBinContent(maxBin)));
764 printf("This bin has now %f +- %f entries\n", fCurrentESD->GetBinContent(maxBin), fCurrentESD->GetBinError(maxBin));
766 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
768 fCurrentCorrelation->SetBinContent(i, maxBin, fCurrentCorrelation->Integral(i, i, maxBin, fCurrentCorrelation->GetNbinsY()));
769 // the error is set to sqrt(N), better solution possible?, sum of relative errors of all contributions???
770 fCurrentCorrelation->SetBinError(i, maxBin, TMath::Sqrt(fCurrentCorrelation->GetBinContent(i, maxBin)));
772 for (Int_t j=maxBin+1; j<=fCurrentCorrelation->GetNbinsY(); ++j)
774 fCurrentCorrelation->SetBinContent(i, j, 0);
775 fCurrentCorrelation->SetBinError(i, j, 0);
779 printf("Adjusted correlation matrix!\n");
784 fCurrentESD->DrawCopy();
788 fCurrentCorrelation->DrawCopy("COLZ");
793 #if 0 // does not help
794 // null bins with one entry
795 Int_t nNulledBins = 0;
796 for (Int_t x=1; x<=fCurrentCorrelation->GetXaxis()->GetNbins(); ++x)
797 for (Int_t y=1; y<=fCurrentCorrelation->GetYaxis()->GetNbins(); ++y)
799 if (fCurrentCorrelation->GetBinContent(x, y) == 1)
801 fCurrentCorrelation->SetBinContent(x, y, 0);
802 fCurrentCorrelation->SetBinError(x, y, 0);
807 Printf("Nulled %d bins", nNulledBins);
810 fCurrentEfficiency = GetEfficiency(inputRange, eventType);
811 //fCurrentEfficiency->Rebin(2);
812 //fCurrentEfficiency->Scale(0.5);
815 //____________________________________________________________________
816 TH1* AliMultiplicityCorrection::GetEfficiency(Int_t inputRange, EventType eventType)
819 // calculates efficiency for given event type
825 case kTrVtx : divisor = fMultiplicityVtx[inputRange]->ProjectionY("divisor", -1, -1, "e"); break;
826 case kMB: divisor = fMultiplicityMB[inputRange]->ProjectionY("divisor", -1, -1, "e"); break;
827 case kINEL: divisor = fMultiplicityINEL[inputRange]->ProjectionY("divisor", -1, -1, "e"); break;
829 TH1* eff = fMultiplicityVtx[inputRange]->ProjectionY("CurrentEfficiency", -1, -1, "e");
830 eff->Divide(eff, divisor, 1, 1, "B");
834 //____________________________________________________________________
835 void AliMultiplicityCorrection::SetRegularizationParameters(RegularizationType type, Float_t weight)
838 // sets the parameters for chi2 minimization
841 fgRegularizationType = type;
842 fgRegularizationWeight = weight;
844 printf("AliMultiplicityCorrection::SetRegularizationParameters --> Regularization set to %d with weight %f\n", (Int_t) type, weight);
847 //____________________________________________________________________
848 void AliMultiplicityCorrection::SetBayesianParameters(Float_t smoothing, Int_t nIterations)
851 // sets the parameters for Bayesian unfolding
854 fgBayesianSmoothing = smoothing;
855 fgBayesianIterations = nIterations;
857 printf("AliMultiplicityCorrection::SetBayesianParameters --> Paramaters set to %d iterations with smoothing %f\n", fgBayesianIterations, fgBayesianSmoothing);
860 //____________________________________________________________________
861 Int_t AliMultiplicityCorrection::UnfoldWithMinuit(TH1* correlation, TH1* aEfficiency, TH1* measured, TH1* initialConditions, TH1* result, Bool_t check)
864 // implemenation of unfolding (internal function)
866 // unfolds <measured> using response from <correlation> and effiency <aEfficiency>
867 // output is in <result>
868 // <initialConditions> set the initial values for the minimization, if 0 <measured> is used
869 // if <check> is true no unfolding is made, instead only the chi2 without unfolding is printed
871 // returns minuit status (0 = success), (-1 when check was set)
875 measured->Scale(1.0 / measured->Integral());
877 if (!fgCorrelationMatrix)
878 fgCorrelationMatrix = new TMatrixD(fgkMaxInput, fgkMaxParams);
879 if (!fgCorrelationCovarianceMatrix)
880 fgCorrelationCovarianceMatrix = new TMatrixD(fgkMaxInput, fgkMaxInput);
881 if (!fgCurrentESDVector)
882 fgCurrentESDVector = new TVectorD(fgkMaxInput);
883 if (!fgEntropyAPriori)
884 fgEntropyAPriori = new TVectorD(fgkMaxParams);
886 fgCorrelationMatrix->Zero();
887 fgCorrelationCovarianceMatrix->Zero();
888 fgCurrentESDVector->Zero();
889 fgEntropyAPriori->Zero();
891 // normalize correction for given nPart
892 for (Int_t i=1; i<=correlation->GetNbinsX(); ++i)
894 Double_t sum = correlation->Integral(i, i, 1, correlation->GetNbinsY());
897 Float_t maxValue = 0;
899 for (Int_t j=1; j<=correlation->GetNbinsY(); ++j)
901 // find most probably value
902 if (maxValue < correlation->GetBinContent(i, j))
904 maxValue = correlation->GetBinContent(i, j);
909 correlation->SetBinContent(i, j, correlation->GetBinContent(i, j) / sum);
910 correlation->SetBinError(i, j, correlation->GetBinError(i, j) / sum);
912 if (i <= fgkMaxParams && j <= fgkMaxInput)
913 (*fgCorrelationMatrix)(j-1, i-1) = correlation->GetBinContent(i, j);
916 //printf("MPV for Ntrue = %f is %f\n", fCurrentCorrelation->GetXaxis()->GetBinCenter(i), fCurrentCorrelation->GetYaxis()->GetBinCenter(maxBin));
919 // Initialize TMinuit via generic fitter interface
920 TVirtualFitter *minuit = TVirtualFitter::Fitter(0, fgkMaxParams);
921 Double_t arglist[100];
923 // disable any output (-1), unfortuantly we do not see warnings anymore then. Have to find another way...
925 minuit->ExecuteCommand("SET PRINT", arglist, 1);
927 // however, enable warnings
928 //minuit->ExecuteCommand("SET WAR", arglist, 0);
930 // set minimization function
931 minuit->SetFCN(MinuitFitFunction);
933 for (Int_t i=0; i<fgkMaxParams; i++)
934 (*fgEntropyAPriori)[i] = 1;
936 if (initialConditions)
938 printf("Using different starting conditions...\n");
939 //new TCanvas; initialConditions->DrawCopy();
941 initialConditions->Scale(1.0 / initialConditions->Integral());
942 for (Int_t i=0; i<fgkMaxParams; i++)
943 if (initialConditions->GetBinContent(i+1) > 0)
944 (*fgEntropyAPriori)[i] = initialConditions->GetBinContent(i+1);
947 initialConditions = measured;
949 Double_t results[fgkMaxParams+1];
950 for (Int_t i=0; i<fgkMaxParams; ++i)
952 results[i] = initialConditions->GetBinContent(i+1);
955 results[i] = TMath::Max(results[i], 1e-3);
957 Float_t stepSize = 0.1;
959 // minuit sees squared values to prevent it from going negative...
960 results[i] = TMath::Sqrt(results[i]);
961 //stepSize /= results[i]; // keep relative step size
963 minuit->SetParameter(i, Form("param%d", i), results[i], stepSize, 0, 0);
965 //minuit->SetParameter(fgkMaxParams, "alpha", 1e4, 1, 0, 0);
966 // bin 0 is filled with value from bin 1 (otherwise it's 0)
967 //minuit->SetParameter(0, "param0", (results[1] > minStartValue) ? results[1] : minStartValue, 0.1, 0, 0);
969 //minuit->SetParameter(0, "param0", 0, 0, 0, 0);
971 for (Int_t i=0; i<fgkMaxInput; ++i)
973 (*fgCurrentESDVector)[i] = measured->GetBinContent(i+1);
974 if (measured->GetBinError(i+1) > 0)
975 (*fgCorrelationCovarianceMatrix)(i, i) = (Double_t) 1e-6 / measured->GetBinError(i+1) / measured->GetBinError(i+1);
977 if ((*fgCorrelationCovarianceMatrix)(i, i) > 1e7)
978 (*fgCorrelationCovarianceMatrix)(i, i) = 0;
983 MinuitFitFunction(dummy, 0, chi2, results, 0);
984 printf("Chi2 of initial parameters is = %f\n", chi2);
989 // first param is number of iterations, second is precision....
992 //minuit->ExecuteCommand("SCAN", arglist, 0);
993 Int_t status = minuit->ExecuteCommand("MIGRAD", arglist, 1);
994 printf("MINUIT status is %d\n", status);
995 //minuit->ExecuteCommand("MIGRAD", arglist, 1);
996 //minuit->ExecuteCommand("MIGRAD", arglist, 1);
997 //printf("!!!!!!!!!!!!!! MIGRAD finished: Starting MINOS !!!!!!!!!!!!!!");
998 //minuit->ExecuteCommand("MINOS", arglist, 0);
1000 for (Int_t i=0; i<fgkMaxParams; ++i)
1002 if (aEfficiency->GetBinContent(i+1) > 0)
1004 result->SetBinContent(i+1, minuit->GetParameter(i) * minuit->GetParameter(i) / aEfficiency->GetBinContent(i+1));
1005 // error is : (relError) * (value) = (minuit->GetParError(i) / minuit->GetParameter(i)) * (minuit->GetParameter(i) * minuit->GetParameter(i))
1006 result->SetBinError(i+1, minuit->GetParError(i) * minuit->GetParameter(i) / aEfficiency->GetBinContent(i+1));
1010 result->SetBinContent(i+1, 0);
1011 result->SetBinError(i+1, 0);
1018 //____________________________________________________________________
1019 Int_t AliMultiplicityCorrection::ApplyMinuitFit(Int_t inputRange, Bool_t fullPhaseSpace, EventType eventType, Bool_t check, TH1* initialConditions)
1022 // correct spectrum using minuit chi2 method
1024 // for description of parameters, see UnfoldWithMinuit
1027 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
1028 SetupCurrentHists(inputRange, fullPhaseSpace, eventType, kTRUE);
1030 return UnfoldWithMinuit(fCurrentCorrelation, fCurrentEfficiency, fCurrentESD, initialConditions, fMultiplicityESDCorrected[correlationID], check);
1033 //____________________________________________________________________
1034 void AliMultiplicityCorrection::ApplyNBDFit(Int_t inputRange, Bool_t fullPhaseSpace)
1037 // correct spectrum using minuit chi2 method applying a NBD fit
1040 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
1042 SetupCurrentHists(inputRange, fullPhaseSpace, kTrVtx, kFALSE);
1044 fCurrentESD->Scale(1.0 / fCurrentESD->Integral());
1046 fgCorrelationMatrix = new TMatrixD(fgkMaxParams, fgkMaxParams);
1047 fgCorrelationCovarianceMatrix = new TMatrixD(fgkMaxParams, fgkMaxParams);
1048 fgCurrentESDVector = new TVectorD(fgkMaxParams);
1050 // normalize correction for given nPart
1051 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
1053 Double_t sum = fCurrentCorrelation->Integral(i, i, 1, fCurrentCorrelation->GetNbinsY());
1056 for (Int_t j=1; j<=fCurrentCorrelation->GetNbinsY(); ++j)
1059 fCurrentCorrelation->SetBinContent(i, j, fCurrentCorrelation->GetBinContent(i, j) / sum);
1060 fCurrentCorrelation->SetBinError(i, j, fCurrentCorrelation->GetBinError(i, j) / sum);
1062 if (i <= fgkMaxParams && j <= fgkMaxParams)
1063 (*fgCorrelationMatrix)(j-1, i-1) = fCurrentCorrelation->GetBinContent(i, j);
1067 for (Int_t i=0; i<fgkMaxParams; ++i)
1069 (*fgCurrentESDVector)[i] = fCurrentESD->GetBinContent(i+1);
1070 if (fCurrentESD->GetBinError(i+1) > 0)
1071 (*fgCorrelationCovarianceMatrix)(i, i) = 1.0 / (fCurrentESD->GetBinError(i+1) * fCurrentESD->GetBinError(i+1));
1074 // Create NBD function
1077 fgNBD = new TF1("nbd", "[0] * TMath::Binomial([2]+TMath::Nint(x)-1, [2]-1) * pow([1] / ([1]+[2]), TMath::Nint(x)) * pow(1 + [1]/[2], -[2])", 0, 250);
1078 fgNBD->SetParNames("scaling", "averagen", "k");
1081 // Initialize TMinuit via generic fitter interface
1082 TVirtualFitter *minuit = TVirtualFitter::Fitter(0, 3);
1084 minuit->SetFCN(MinuitNBD);
1085 minuit->SetParameter(0, "param0", 1, 0.1, 0.001, fCurrentESD->GetMaximum() * 1000);
1086 minuit->SetParameter(1, "param1", 10, 1, 0.001, 1000);
1087 minuit->SetParameter(2, "param2", 2, 1, 0.001, 1000);
1089 Double_t arglist[100];
1091 minuit->ExecuteCommand("SET PRINT", arglist, 1);
1092 minuit->ExecuteCommand("MIGRAD", arglist, 0);
1093 //minuit->ExecuteCommand("MINOS", arglist, 0);
1095 fgNBD->SetParameters(minuit->GetParameter(0), minuit->GetParameter(1), minuit->GetParameter(2));
1097 for (Int_t i=0; i<fgkMaxParams; ++i)
1099 printf("%d : %f\n", i, fgNBD->Eval(i));
1100 if (fgNBD->Eval(i) > 0)
1102 fMultiplicityESDCorrected[correlationID]->SetBinContent(i+1, fgNBD->Eval(i));
1103 fMultiplicityESDCorrected[correlationID]->SetBinError(i+1, 0);
1108 //____________________________________________________________________
1109 void AliMultiplicityCorrection::NormalizeToBinWidth(TH1* hist)
1112 // normalizes a 1-d histogram to its bin width
1115 for (Int_t i=1; i<=hist->GetNbinsX(); ++i)
1117 hist->SetBinContent(i, hist->GetBinContent(i) / hist->GetBinWidth(i));
1118 hist->SetBinError(i, hist->GetBinError(i) / hist->GetBinWidth(i));
1122 //____________________________________________________________________
1123 void AliMultiplicityCorrection::NormalizeToBinWidth(TH2* hist)
1126 // normalizes a 2-d histogram to its bin width (x width * y width)
1129 for (Int_t i=1; i<=hist->GetNbinsX(); ++i)
1130 for (Int_t j=1; j<=hist->GetNbinsY(); ++j)
1132 Double_t factor = hist->GetXaxis()->GetBinWidth(i) * hist->GetYaxis()->GetBinWidth(j);
1133 hist->SetBinContent(i, j, hist->GetBinContent(i, j) / factor);
1134 hist->SetBinError(i, j, hist->GetBinError(i, j) / factor);
1138 //____________________________________________________________________
1139 void AliMultiplicityCorrection::DrawHistograms()
1142 // draws the histograms of this class
1147 TCanvas* canvas1 = new TCanvas("fMultiplicityESD", "fMultiplicityESD", 900, 600);
1148 canvas1->Divide(3, 2);
1149 for (Int_t i = 0; i < kESDHists; ++i)
1152 fMultiplicityESD[i]->DrawCopy("COLZ");
1153 printf("%d --> %f\n", i, (Float_t) fMultiplicityESD[i]->ProjectionY()->GetMean());
1158 TCanvas* canvas2 = new TCanvas("fMultiplicityMC", "fMultiplicityMC", 900, 600);
1159 canvas2->Divide(3, 2);
1160 for (Int_t i = 0; i < kMCHists; ++i)
1163 fMultiplicityVtx[i]->DrawCopy("COLZ");
1164 printf("%d --> %f\n", i, fMultiplicityVtx[i]->ProjectionY()->GetMean());
1167 TCanvas* canvas3 = new TCanvas("fCorrelation", "fCorrelation", 900, 900);
1168 canvas3->Divide(3, 3);
1169 for (Int_t i = 0; i < kCorrHists; ++i)
1172 TH3* hist = dynamic_cast<TH3*> (fCorrelation[i]->Clone());
1173 for (Int_t y=1; y<=hist->GetYaxis()->GetNbins(); ++y)
1175 for (Int_t z=1; z<=hist->GetZaxis()->GetNbins(); ++z)
1177 hist->SetBinContent(0, y, z, 0);
1178 hist->SetBinContent(hist->GetXaxis()->GetNbins()+1, y, z, 0);
1181 TH1* proj = hist->Project3D("zy");
1182 proj->DrawCopy("COLZ");
1186 //____________________________________________________________________
1187 void AliMultiplicityCorrection::DrawComparison(const char* name, Int_t inputRange, Bool_t fullPhaseSpace, Bool_t normalizeESD, TH1* mcHist, Bool_t simple)
1191 Int_t esdCorrId = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
1194 tmpStr.Form("%s_DrawComparison_%d", name, esdCorrId);
1196 if (fMultiplicityESDCorrected[esdCorrId]->Integral() == 0)
1198 printf("ERROR. Unfolded histogram is empty\n");
1202 //regain measured distribution used for unfolding, because the bins at high mult. were modified in SetupCurrentHists
1203 fCurrentESD = fMultiplicityESD[esdCorrId]->ProjectionY();
1204 fCurrentESD->Sumw2();
1205 fCurrentESD->Scale(1.0 / fCurrentESD->Integral());
1207 // normalize unfolded result to 1
1208 fMultiplicityESDCorrected[esdCorrId]->Scale(1.0 / fMultiplicityESDCorrected[esdCorrId]->Integral());
1210 //fCurrentESD->Scale(mcHist->Integral(2, 200));
1213 /*TH1* ratio = (TH1*) fMultiplicityESDCorrected[esdCorrId]->Clone("ratio");
1214 ratio->Divide(mcHist);
1215 ratio->Draw("HIST");
1216 ratio->Fit("pol0", "W0", "", 20, 120);
1217 Float_t scalingFactor = ratio->GetFunction("pol0")->GetParameter(0);
1219 mcHist->Scale(scalingFactor);*/
1221 // find bin with <= 100 entries. this is used as limit for the chi2 calculation
1222 Int_t mcBinLimit = 0;
1223 for (Int_t i=20; i<mcHist->GetNbinsX(); ++i)
1225 if (mcHist->GetBinContent(i) > 50)
1232 Printf("AliMultiplicityCorrection::DrawComparison: MC bin limit is %d", mcBinLimit);
1236 mcHist->Scale(1.0 / mcHist->Integral());
1238 // calculate residual
1240 // for that we convolute the response matrix with the gathered result
1241 // if normalizeESD is not set, the histogram is already normalized, this needs to be passed to CalculateMultiplicityESD
1242 TH1* tmpESDEfficiencyRecorrected = (TH1*) fMultiplicityESDCorrected[esdCorrId]->Clone("tmpESDEfficiencyRecorrected");
1243 tmpESDEfficiencyRecorrected->Multiply(fCurrentEfficiency);
1244 TH2* convoluted = CalculateMultiplicityESD(tmpESDEfficiencyRecorrected, esdCorrId);
1245 TH1* convolutedProj = convoluted->ProjectionY("convolutedProj", -1, -1, "e");
1246 if (convolutedProj->Integral() > 0)
1248 convolutedProj->Scale(1.0 / convolutedProj->Integral());
1251 printf("ERROR: convolutedProj is empty. Something went wrong calculating the convoluted histogram.\n");
1253 TH1* residual = (TH1*) convolutedProj->Clone("residual");
1254 residual->SetTitle("Residuals;Ntracks;(folded unfolded measured - measured) / e");
1256 residual->Add(fCurrentESD, -1);
1257 //residual->Divide(residual, fCurrentESD, 1, 1, "B");
1259 TH1* residualHist = new TH1F("residualHist", "residualHist", 51, -5, 5);
1263 for (Int_t i=1; i<=residual->GetNbinsX(); ++i)
1265 if (fCurrentESD->GetBinError(i) > 0)
1267 Float_t value = residual->GetBinContent(i) / fCurrentESD->GetBinError(i);
1269 chi2 += value * value;
1270 residual->SetBinContent(i, value);
1271 residualHist->Fill(value);
1275 //printf("Residual bin %d set to 0\n", i);
1276 residual->SetBinContent(i, 0);
1278 convolutedProj->SetBinError(i, 0);
1279 residual->SetBinError(i, 0);
1282 fLastChi2Residuals = chi2;
1285 new TCanvas; residualHist->DrawCopy();
1287 //residualHist->Fit("gaus", "N");
1288 //delete residualHist;
1290 printf("Difference (Residuals) is %f for bin 2-200\n", chi2);
1292 TCanvas* canvas1 = 0;
1295 canvas1 = new TCanvas(tmpStr, tmpStr, 900, 400);
1296 canvas1->Divide(2, 1);
1300 canvas1 = new TCanvas(tmpStr, tmpStr, 1200, 1200);
1301 canvas1->Divide(2, 3);
1305 TH1* proj = (TH1*) mcHist->Clone("proj");
1307 proj->GetXaxis()->SetRangeUser(0, 200);
1308 proj->SetTitle(";true multiplicity;Entries");
1309 proj->SetStats(kFALSE);
1310 proj->DrawCopy("HIST");
1313 //fMultiplicityESDCorrected[esdCorrId]->SetMarkerStyle(3);
1314 fMultiplicityESDCorrected[esdCorrId]->SetLineColor(2);
1315 fMultiplicityESDCorrected[esdCorrId]->DrawCopy("SAME HIST E");
1317 TLegend* legend = new TLegend(0.3, 0.8, 0.93, 0.93);
1318 legend->AddEntry(proj, "true distribution");
1319 legend->AddEntry(fMultiplicityESDCorrected[esdCorrId], "unfolded distribution");
1320 legend->SetFillColor(0);
1322 // unfortunately does not work. maybe a bug? --> legend->SetTextSizePixels(14);
1327 fCurrentESD->GetXaxis()->SetRangeUser(0, 200);
1328 //fCurrentESD->SetLineColor(2);
1329 fCurrentESD->SetTitle(";measured multiplicity;Entries");
1330 fCurrentESD->SetStats(kFALSE);
1331 fCurrentESD->DrawCopy("HIST E");
1333 convolutedProj->SetLineColor(2);
1334 //proj2->SetMarkerColor(2);
1335 //proj2->SetMarkerStyle(5);
1336 convolutedProj->DrawCopy("HIST SAME");
1338 legend = new TLegend(0.3, 0.8, 0.93, 0.93);
1339 legend->AddEntry(fCurrentESD, "measured distribution");
1340 legend->AddEntry(convolutedProj, "R #otimes unfolded distribution");
1341 legend->SetFillColor(0);
1344 //TH1* diffMCUnfolded = dynamic_cast<TH1*> (proj->Clone("diffMCUnfolded"));
1345 //diffMCUnfolded->Add(fMultiplicityESDCorrected[esdCorrId], -1);
1349 fLastChi2MCLimit = 0;
1351 for (Int_t i=2; i<=200; ++i)
1353 if (proj->GetBinContent(i) != 0)
1355 Float_t value = (proj->GetBinContent(i) - fMultiplicityESDCorrected[esdCorrId]->GetBinContent(i)) / proj->GetBinContent(i);
1356 chi2 += value * value;
1357 chi += TMath::Abs(value);
1359 //printf("%d %f\n", i, chi);
1362 fLastChi2MCLimit = i;
1373 for (Int_t i=1; i<=diffMCUnfolded->GetNbinsX(); ++i)
1375 if (fMultiplicityESDCorrected[esdCorrId]->GetBinError(i) > 0)
1377 Double_t value = diffMCUnfolded->GetBinContent(i) / fMultiplicityESDCorrected[esdCorrId]->GetBinError(i);
1379 value = 1e8; //prevent arithmetic exception
1380 else if (value < -1e8)
1384 chi2 += value * value;
1385 chi += TMath::Abs(value);
1387 diffMCUnfolded->SetBinContent(i, value);
1391 //printf("diffMCUnfolded bin %d set to 0\n", i);
1392 diffMCUnfolded->SetBinContent(i, 0);
1395 fLastChi2MCLimit = i;
1402 printf("limits %d %d\n", fLastChi2MCLimit, limit);
1403 fLastChi2MCLimit = limit;
1405 printf("Difference (from MC) is %f for bin 2-150. Limit is %d.\n", fLastChi2MC, fLastChi2MCLimit);*/
1411 diffMCUnfolded->SetTitle("#chi^{2};Npart;(MC - Unfolded) / e(unfolded)");
1412 //diffMCUnfolded->GetYaxis()->SetRangeUser(-20, 20);
1413 diffMCUnfolded->GetXaxis()->SetRangeUser(0, 200);
1414 diffMCUnfolded->DrawCopy("HIST");
1416 TH1F* fluctuation = new TH1F("fluctuation", "fluctuation", 20, -5, 5);
1417 for (Int_t i=20; i<=diffMCUnfolded->GetNbinsX(); ++i)
1418 fluctuation->Fill(diffMCUnfolded->GetBinContent(i));
1420 //new TCanvas; fluctuation->DrawCopy();
1421 delete fluctuation;*/
1423 /*TLegend* legend = new TLegend(0.6, 0.7, 0.85, 0.85);
1424 legend->AddEntry(fMultiplicityESDCorrected, "ESD corrected");
1425 legend->AddEntry(fMultiplicityMC, "MC");
1426 legend->AddEntry(fMultiplicityESD, "ESD");
1430 //residual->GetYaxis()->SetRangeUser(-0.2, 0.2);
1431 residual->GetXaxis()->SetRangeUser(0, 200);
1432 residual->DrawCopy();
1436 TH1* ratio = (TH1*) fMultiplicityESDCorrected[esdCorrId]->Clone("ratio");
1437 ratio->Divide(mcHist);
1438 ratio->SetTitle("Ratio;true multiplicity;Unfolded / MC");
1439 ratio->GetYaxis()->SetRangeUser(0.5, 1.5);
1440 ratio->GetXaxis()->SetRangeUser(0, 200);
1441 ratio->SetStats(kFALSE);
1442 ratio->Draw("HIST");
1444 Double_t ratioChi2 = 0;
1446 fLastChi2MCLimit = 0;
1447 for (Int_t i=2; i<=150; ++i)
1449 Float_t value = ratio->GetBinContent(i) - 1;
1451 value = 1e8; //prevent arithmetic exception
1452 else if (value < -1e8)
1455 ratioChi2 += value * value;
1456 fRatioAverage += TMath::Abs(value);
1458 if (ratioChi2 < 0.1)
1459 fLastChi2MCLimit = i;
1461 fRatioAverage /= 149;
1463 printf("Sum over (ratio-1)^2 (2..150) is %f; average of |ratio-1| is %f\n", ratioChi2, fRatioAverage);
1465 fLastChi2MC = ratioChi2;
1469 const Int_t kFFT = 128;
1470 Double_t fftReal[kFFT];
1471 Double_t fftImag[kFFT];
1473 for (Int_t i=0; i<kFFT; ++i)
1475 fftReal[i] = ratio->GetBinContent(i+1+10);
1477 //fftReal[i] = cos(TMath::Pi() * 5 * 2 * i / 128);
1481 FFT(-1, TMath::Nint(log(kFFT) / log(2)), fftReal, fftImag);
1483 TH1* fftResult = (TH1*) ratio->Clone("fftResult");
1484 fftResult->SetTitle("FFT;true multiplicity;coeff. (10...137)");
1485 TH1* fftResult2 = (TH1*) ratio->Clone("fftResult2");
1486 TH1* fftResult3 = (TH1*) ratio->Clone("fftResult3");
1488 fftResult2->Reset();
1489 fftResult3->Reset();
1490 fftResult->GetYaxis()->UnZoom();
1491 fftResult2->GetYaxis()->UnZoom();
1492 fftResult3->GetYaxis()->UnZoom();
1494 Printf("AFTER FFT");
1495 for (Int_t i=0; i<kFFT; ++i)
1497 Printf("%d: %f", i, fftReal[i]);
1498 fftResult->SetBinContent(i+1, fftReal[i]);
1499 /*if (i != 0 && TMath::Abs(fftReal[i]) > 0.5)
1501 Printf("Nulled %d", i);
1506 fftResult->SetLineColor(1);
1507 fftResult->DrawCopy();
1511 for (Int_t i=0; i<kFFT; ++i)
1513 Printf("%d: %f", i, fftImag[i]);
1514 fftResult2->SetBinContent(i+1, fftImag[i]);
1516 fftResult3->SetBinContent(i+1, TMath::Sqrt(fftReal[i] * fftReal[i] + fftImag[i] * fftImag[i]));
1519 fftResult2->SetLineColor(2);
1520 fftResult2->DrawCopy("SAME");
1522 fftResult3->SetLineColor(4);
1523 fftResult3->DrawCopy("SAME");
1525 for (Int_t i=1; i<kFFT - 1; ++i)
1527 if (TMath::Sqrt(fftReal[i] * fftReal[i] + fftImag[i] * fftImag[i]) > 3)
1535 //fftReal[i] = (fftReal[i-1] + fftReal[i+1]) / 2;
1536 //fftImag[i] = (fftImag[i-1] + fftImag[i+1]) / 2;
1537 Printf("Nulled %d to %f %f", i, fftReal[i], fftImag[i]);
1541 FFT(1, TMath::Nint(log(kFFT) / log(2)), fftReal, fftImag);
1543 TH1* fftResult4 = (TH1*) fftResult3->Clone("fftResult4");
1544 fftResult4->Reset();
1546 Printf("AFTER BACK-TRAFO");
1547 for (Int_t i=0; i<kFFT; ++i)
1549 Printf("%d: %f", i, fftReal[i]);
1550 fftResult4->SetBinContent(i+1+10, fftReal[i]);
1554 fftResult4->SetLineColor(4);
1555 fftResult4->DrawCopy("SAME");
1557 // plot (MC - Unfolded) / error (MC)
1560 TH1* diffMCUnfolded2 = dynamic_cast<TH1*> (proj->Clone("diffMCUnfolded2"));
1561 diffMCUnfolded2->Add(fMultiplicityESDCorrected[esdCorrId], -1);
1563 Int_t ndfQual[kQualityRegions];
1564 for (Int_t region=0; region<kQualityRegions; ++region)
1566 fQuality[region] = 0;
1567 ndfQual[region] = 0;
1571 Double_t newChi2 = 0;
1572 Double_t newChi2Limit150 = 0;
1574 for (Int_t i=1; i<=TMath::Min(diffMCUnfolded2->GetNbinsX(), fgkMaxParams+1); ++i)
1577 if (proj->GetBinError(i) > 0)
1579 value = diffMCUnfolded2->GetBinContent(i) / proj->GetBinError(i);
1580 newChi2 += value * value;
1581 if (i > 1 && i <= mcBinLimit)
1582 newChi2Limit150 += value * value;
1585 for (Int_t region=0; region<kQualityRegions; ++region)
1586 if (diffMCUnfolded2->GetXaxis()->GetBinCenter(i) >= fgQualityRegionsB[region] - 0.1 && diffMCUnfolded2->GetXaxis()->GetBinCenter(i) <= fgQualityRegionsE[region] + 0.1) // 0.1 to avoid e.g. 3.9999 < 4 problem
1588 fQuality[region] += TMath::Abs(value);
1593 diffMCUnfolded2->SetBinContent(i, value);
1596 // normalize region to the number of entries
1597 for (Int_t region=0; region<kQualityRegions; ++region)
1599 if (ndfQual[region] > 0)
1600 fQuality[region] /= ndfQual[region];
1601 Printf("Quality parameter %d (%d <= mult <= %d) is %f with %d df", region, fgQualityRegionsB[region], fgQualityRegionsE[region], fQuality[region], ndfQual[region]);
1606 // TODO another FAKE
1607 fLastChi2MC = newChi2Limit150 / (mcBinLimit - 1);
1608 Printf("Chi2 (2..%d) from (MC - Unfolded) / e(MC) is: %.2f ndf is %d --> chi2 / ndf = %.2f", mcBinLimit, newChi2Limit150, mcBinLimit - 1, fLastChi2MC);
1613 Printf("Chi2 (full range) from (MC - Unfolded) / e(MC) is: %.2f ndf is %d --> chi2 / ndf = %.2f", newChi2, ndf, newChi2 / ndf);
1615 diffMCUnfolded2->SetTitle("#chi^{2};Npart;(MC - Unfolded) / e(MC)");
1616 //diffMCUnfolded->GetYaxis()->SetRangeUser(-20, 20);
1617 diffMCUnfolded2->GetXaxis()->SetRangeUser(0, 200);
1618 diffMCUnfolded2->DrawCopy("HIST");
1621 canvas1->SaveAs(Form("%s.gif", canvas1->GetName()));
1624 //____________________________________________________________________
1625 void AliMultiplicityCorrection::FFT(Int_t dir, Int_t m, Double_t *x, Double_t *y)
1627 /*-------------------------------------------------------------------------
1628 This computes an in-place complex-to-complex FFT
1629 x and y are the real and imaginary arrays of 2^m points.
1630 dir = 1 gives forward transform
1631 dir = -1 gives reverse transform
1636 1 \ - j k 2 pi n / N
1637 X(n) = --- > x(k) e = forward transform
1646 X(n) = > x(k) e = forward transform
1652 Long_t nn, i, i1, j, k, i2, l, l1, l2;
1653 Double_t c1, c2, tx, ty, t1, t2, u1, u2, z;
1655 /* Calculate the number of points */
1657 for (i = 0; i < m; i++)
1660 /* Do the bit reversal */
1663 for (i= 0; i < nn - 1; i++) {
1680 /* Compute the FFT */
1684 for (l = 0; l < m; l++) {
1689 for (j = 0;j < l1; j++) {
1690 for (i = j; i < nn; i += l2) {
1692 t1 = u1 * x[i1] - u2 * y[i1];
1693 t2 = u1 * y[i1] + u2 * x[i1];
1699 z = u1 * c1 - u2 * c2;
1700 u2 = u1 * c2 + u2 * c1;
1703 c2 = TMath::Sqrt((1.0 - c1) / 2.0);
1706 c1 = TMath::Sqrt((1.0 + c1) / 2.0);
1709 /* Scaling for forward transform */
1711 for (i=0;i<nn;i++) {
1712 x[i] /= (Double_t)nn;
1713 y[i] /= (Double_t)nn;
1718 //____________________________________________________________________
1719 void AliMultiplicityCorrection::GetComparisonResults(Float_t* mc, Int_t* mcLimit, Float_t* residuals, Float_t* ratioAverage) const
1721 // Returns the chi2 between the MC and the unfolded ESD as well as between the ESD and the folded unfolded ESD
1722 // These values are computed during DrawComparison, thus this function picks up the
1728 *mcLimit = fLastChi2MCLimit;
1730 *residuals = fLastChi2Residuals;
1732 *ratioAverage = fRatioAverage;
1735 //____________________________________________________________________
1736 TH2F* AliMultiplicityCorrection::GetMultiplicityMC(Int_t i, EventType eventType)
1739 // returns the corresponding MC spectrum
1744 case kTrVtx : return fMultiplicityVtx[i]; break;
1745 case kMB : return fMultiplicityMB[i]; break;
1746 case kINEL : return fMultiplicityINEL[i]; break;
1752 //____________________________________________________________________
1753 TH1* AliMultiplicityCorrection::StatisticalUncertainty(MethodType methodType, Int_t inputRange, Bool_t fullPhaseSpace, EventType eventType, Bool_t randomizeMeasured, Bool_t randomizeResponse, TH1* compareTo)
1756 // evaluates the uncertainty that arises from the non-infinite statistics in the response matrix
1757 // the function unfolds the spectrum using the default response matrix and several modified ones
1758 // the modified ones are created by randomizing each cell using poisson statistics with the mean = bin value
1759 // these unfolded results are compared to the first result gained with the default response OR to the histogram given
1760 // in <compareTo> (optional)
1762 // returns the error assigned to the measurement
1765 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
1767 // initialize seed with current time
1768 gRandom->SetSeed(0);
1770 const Int_t kErrorIterations = 150;
1773 TH1* firstResult = 0;
1775 TH1** results = new TH1*[kErrorIterations];
1777 for (Int_t n=0; n<kErrorIterations; ++n)
1779 Printf("Iteration %d of %d...", n, kErrorIterations);
1781 // only done for chi2 minimization
1782 Bool_t createBigBin = kFALSE;
1783 if (methodType == kChi2Minimization)
1784 createBigBin = kTRUE;
1786 SetupCurrentHists(inputRange, fullPhaseSpace, eventType, createBigBin);
1788 TH1* measured = (TH1*) fCurrentESD->Clone("measured");
1792 if (randomizeResponse)
1794 // randomize response matrix
1795 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
1796 for (Int_t j=1; j<=fCurrentCorrelation->GetNbinsY(); ++j)
1797 fCurrentCorrelation->SetBinContent(i, j, gRandom->Poisson(fCurrentCorrelation->GetBinContent(i, j)));
1800 if (randomizeMeasured)
1802 // randomize measured spectrum
1803 for (Int_t x=1; x<=measured->GetNbinsX(); x++) // mult. axis
1805 Int_t randomValue = gRandom->Poisson(fCurrentESD->GetBinContent(x));
1806 measured->SetBinContent(x, randomValue);
1807 measured->SetBinError(x, TMath::Sqrt(randomValue));
1812 // only for bayesian method we have to do it before the call to Unfold...
1813 if (methodType == kBayesian)
1815 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
1817 // with this it is normalized to 1
1818 Double_t sum = fCurrentCorrelation->Integral(i, i, 1, fCurrentCorrelation->GetNbinsY());
1820 // with this normalized to the given efficiency
1821 if (fCurrentEfficiency->GetBinContent(i) > 0)
1822 sum /= fCurrentEfficiency->GetBinContent(i);
1826 for (Int_t j=1; j<=fCurrentCorrelation->GetNbinsY(); ++j)
1830 fCurrentCorrelation->SetBinContent(i, j, fCurrentCorrelation->GetBinContent(i, j) / sum);
1831 fCurrentCorrelation->SetBinError(i, j, fCurrentCorrelation->GetBinError(i, j) / sum);
1835 fCurrentCorrelation->SetBinContent(i, j, 0);
1836 fCurrentCorrelation->SetBinError(i, j, 0);
1843 if (n == 0 && compareTo)
1845 // in this case we just store the histogram we want to compare to
1846 result = (TH1*) compareTo->Clone("compareTo");
1851 result = (TH1*) fMultiplicityESDCorrected[correlationID]->Clone(Form("result_%d", n));
1853 Int_t returnCode = -1;
1854 if (methodType == kChi2Minimization)
1856 returnCode = UnfoldWithMinuit(fCurrentCorrelation, fCurrentEfficiency, measured, 0, result, kFALSE);
1858 else if (methodType == kBayesian)
1859 returnCode = UnfoldWithBayesian(fCurrentCorrelation, fCurrentEfficiency, measured, 0, result, fgBayesianSmoothing, fgBayesianIterations);
1861 if (returnCode != 0)
1866 result->Scale(1.0 / result->Integral());
1870 firstResult = (TH1*) result->Clone("firstResult");
1872 maxError = (TH1*) result->Clone("maxError");
1878 TH1* ratio = (TH1*) firstResult->Clone("ratio");
1879 ratio->Divide(result);
1881 // find max. deviation
1882 for (Int_t x=1; x<=ratio->GetNbinsX(); x++)
1883 maxError->SetBinContent(x, TMath::Max(maxError->GetBinContent(x), TMath::Abs(1 - ratio->GetBinContent(x))));
1888 results[n] = result;
1891 // find covariance matrix
1892 // results[n] is X_x
1893 // cov. matrix is M_xy = E ( (X_x - E(X_x)) * (X_y - E(X_y))), with E() = expectation value
1895 Int_t nBins = results[0]->GetNbinsX();
1896 Float_t lowEdge = results[0]->GetXaxis()->GetBinLowEdge(1);
1897 Float_t upEdge = results[0]->GetXaxis()->GetBinUpEdge(nBins);
1899 // find average, E(X)
1900 TProfile* average = new TProfile("average", "average", nBins, lowEdge, upEdge);
1901 for (Int_t n=1; n<kErrorIterations; ++n)
1902 for (Int_t x=1; x<=results[n]->GetNbinsX(); x++)
1903 average->Fill(results[n]->GetXaxis()->GetBinCenter(x), results[n]->GetBinContent(x));
1904 //new TCanvas; average->DrawClone();
1907 TProfile2D* covMatrix = new TProfile2D("covMatrix", "covMatrix", nBins, lowEdge, upEdge, nBins, lowEdge, upEdge);
1909 for (Int_t n=1; n<kErrorIterations; ++n)
1910 for (Int_t x=1; x<=results[n]->GetNbinsX(); x++)
1911 for (Int_t y=1; y<=results[n]->GetNbinsX(); y++)
1913 // (X_x - E(X_x)) * (X_y - E(X_y)
1914 Float_t cov = (results[n]->GetBinContent(x) - average->GetBinContent(x)) * (results[n]->GetBinContent(y) - average->GetBinContent(y));
1915 covMatrix->Fill(results[n]->GetXaxis()->GetBinCenter(x), results[n]->GetXaxis()->GetBinCenter(y), cov);
1917 new TCanvas; covMatrix->DrawClone("COLZ");
1919 // // fill 2D histogram that contains deviation from first
1920 // TH2F* deviations = new TH2F("deviations", "deviations", nBins, lowEdge, upEdge, 1000, -0.01, 0.01);
1921 // for (Int_t n=1; n<kErrorIterations; ++n)
1922 // for (Int_t x=1; x<=results[n]->GetNbinsX(); x++)
1923 // deviations->Fill(results[n]->GetXaxis()->GetBinCenter(x), results[n]->GetBinContent(x) - results[0]->GetBinContent(x));
1924 // //new TCanvas; deviations->DrawCopy("COLZ");
1926 // // get standard deviation "by hand"
1927 // for (Int_t x=1; x<=nBins; x++)
1929 // if (results[0]->GetBinContent(x) > 0)
1931 // TH1* proj = deviations->ProjectionY("projRMS", x, x, "e");
1932 // Float_t standardDev = proj->GetRMS(); // this is standard deviation in fact
1933 // //standardDeviation->SetBinContent(x, standardDev / results[0]->GetBinContent(x));
1934 // Printf("sigma_%d is %f value %f --> error %f", x, standardDev, results[0]->GetBinContent(x), standardDev / results[0]->GetBinContent(x));
1938 // calculate standard deviation of (results[0] - results[n])
1939 TH1* standardDeviation = (TH1*) maxError->Clone("standardDeviation");
1940 standardDeviation->Reset();
1942 for (Int_t x=1; x<=results[0]->GetNbinsX(); x++)
1944 if (results[0]->GetBinContent(x) > 0)
1946 Double_t average = 0;
1947 for (Int_t n=1; n<kErrorIterations; ++n)
1948 average += results[n]->GetBinContent(x) - results[0]->GetBinContent(x);
1949 average /= kErrorIterations-1;
1951 Double_t variance = 0;
1952 for (Int_t n=1; n<kErrorIterations; ++n)
1954 Double_t value = results[n]->GetBinContent(x) - results[0]->GetBinContent(x) - average;
1955 variance += value * value;
1957 variance /= kErrorIterations-1;
1959 Double_t standardDev = TMath::Sqrt(variance);
1960 standardDeviation->SetBinContent(x, standardDev / results[0]->GetBinContent(x));
1961 Printf("sigma_%d is %f value %f --> error %f", x, standardDev, results[0]->GetBinContent(x), standardDev / results[0]->GetBinContent(x));
1965 // compare maxError to RMS of profile (variable name: average)
1966 // first: calculate rms in percent of value
1967 TH1* rmsError = (TH1*) maxError->Clone("rmsError");
1970 // enable error to be standard deviation (see http://root.cern.ch/root/html/TProfile.html#TProfile:SetErrorOption)
1971 average->SetErrorOption("s");
1972 for (Int_t x=1; x<=rmsError->GetNbinsX(); x++)
1973 if (average->GetBinContent(x) > 0)
1974 rmsError->SetBinContent(x, average->GetBinError(x) / average->GetBinContent(x));
1976 // find maxError deviation from average (not from "first result"/mc as above)
1977 TH1* maxError2 = (TH1*) maxError->Clone("maxError2");
1979 for (Int_t n=1; n<kErrorIterations; ++n)
1980 for (Int_t x=1; x<=results[n]->GetNbinsX(); x++)
1981 if (average->GetBinContent(x) > 0)
1982 maxError2->SetBinContent(x, TMath::Max(maxError2->GetBinContent(x), TMath::Abs((results[n]->GetBinContent(x) - average->GetBinContent(x)) / average->GetBinContent(x))));
1984 //new TCanvas; maxError2->DrawCopy(); rmsError->SetLineColor(2); rmsError->DrawCopy("SAME"); standardDeviation->SetLineColor(3); standardDeviation->DrawCopy("SAME");
1986 // plot difference between average and MC/first result
1987 TH1* averageFirstRatio = (TH1*) results[0]->Clone("averageFirstRatio");
1988 averageFirstRatio->Reset();
1989 averageFirstRatio->Divide(results[0], average);
1991 //new TCanvas; results[0]->DrawCopy(); average->SetLineColor(2); average->DrawClone("SAME");
1992 //new TCanvas; averageFirstRatio->DrawCopy();
1995 for (Int_t n=0; n<kErrorIterations; ++n)
1999 // fill into result histogram
2000 for (Int_t i=1; i<=fMultiplicityESDCorrected[correlationID]->GetNbinsX(); ++i)
2001 fMultiplicityESDCorrected[correlationID]->SetBinContent(i, firstResult->GetBinContent(i));
2003 for (Int_t i=1; i<=fMultiplicityESDCorrected[correlationID]->GetNbinsX(); ++i)
2004 fMultiplicityESDCorrected[correlationID]->SetBinError(i, maxError->GetBinContent(i) * fMultiplicityESDCorrected[correlationID]->GetBinContent(i));
2006 return standardDeviation;
2009 //____________________________________________________________________
2010 void AliMultiplicityCorrection::ApplyBayesianMethod(Int_t inputRange, Bool_t fullPhaseSpace, EventType eventType, Float_t regPar, Int_t nIterations, TH1* initialConditions, Bool_t determineError)
2013 // correct spectrum using bayesian method
2016 // initialize seed with current time
2017 gRandom->SetSeed(0);
2019 SetupCurrentHists(inputRange, fullPhaseSpace, eventType, kFALSE);
2021 // normalize correction for given nPart
2022 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
2024 // with this it is normalized to 1
2025 Double_t sum = fCurrentCorrelation->Integral(i, i, 1, fCurrentCorrelation->GetNbinsY());
2027 // with this normalized to the given efficiency
2028 if (fCurrentEfficiency->GetBinContent(i) > 0)
2029 sum /= fCurrentEfficiency->GetBinContent(i);
2033 for (Int_t j=1; j<=fCurrentCorrelation->GetNbinsY(); ++j)
2037 fCurrentCorrelation->SetBinContent(i, j, fCurrentCorrelation->GetBinContent(i, j) / sum);
2038 fCurrentCorrelation->SetBinError(i, j, fCurrentCorrelation->GetBinError(i, j) / sum);
2042 fCurrentCorrelation->SetBinContent(i, j, 0);
2043 fCurrentCorrelation->SetBinError(i, j, 0);
2048 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
2050 if (UnfoldWithBayesian(fCurrentCorrelation, fCurrentEfficiency, fCurrentESD, initialConditions, fMultiplicityESDCorrected[correlationID], regPar, nIterations) != 0)
2053 if (!determineError)
2055 Printf("AliMultiplicityCorrection::ApplyBayesianMethod: WARNING: No errors calculated.");
2059 // evaluate errors, this is done by randomizing the measured spectrum following Poission statistics
2060 // this (new) measured spectrum is then unfolded and the different to the result from the "real" measured
2061 // spectrum calculated. This is performed N times and the maximum difference is taken as the systematic
2062 // error of the unfolding method itself.
2064 TH1* maxError = (TH1*) fMultiplicityESDCorrected[correlationID]->Clone("maxError");
2067 TH1* normalizedResult = (TH1*) fMultiplicityESDCorrected[correlationID]->Clone("normalizedResult");
2068 normalizedResult->Scale(1.0 / normalizedResult->Integral());
2070 const Int_t kErrorIterations = 20;
2072 printf("Spectrum unfolded. Determining error (%d iterations)...\n", kErrorIterations);
2074 TH1* randomized = (TH1*) fCurrentESD->Clone("randomized");
2075 TH1* result2 = (TH1*) fMultiplicityESDCorrected[correlationID]->Clone("result2");
2076 for (Int_t n=0; n<kErrorIterations; ++n)
2078 // randomize the content of clone following a poisson with the mean = the value of that bin
2079 for (Int_t x=1; x<=randomized->GetNbinsX(); x++) // mult. axis
2081 Int_t randomValue = gRandom->Poisson(fCurrentESD->GetBinContent(x));
2082 //printf("%d --> %d\n", fCurrentESD->GetBinContent(x), randomValue);
2083 randomized->SetBinContent(x, randomValue);
2084 randomized->SetBinError(x, TMath::Sqrt(randomValue));
2088 if (UnfoldWithBayesian(fCurrentCorrelation, fCurrentEfficiency, randomized, initialConditions, result2, regPar, nIterations) != 0)
2091 result2->Scale(1.0 / result2->Integral());
2094 result2->Divide(normalizedResult);
2096 //new TCanvas; ratio->DrawCopy("HIST");
2098 // find max. deviation
2099 for (Int_t x=1; x<=result2->GetNbinsX(); x++)
2100 maxError->SetBinContent(x, TMath::Max(maxError->GetBinContent(x), TMath::Abs(1 - result2->GetBinContent(x))));
2105 for (Int_t i=1; i<=fMultiplicityESDCorrected[correlationID]->GetNbinsX(); ++i)
2106 fMultiplicityESDCorrected[correlationID]->SetBinError(i, maxError->GetBinContent(i) * fMultiplicityESDCorrected[correlationID]->GetBinContent(i));
2109 delete normalizedResult;
2112 //____________________________________________________________________
2113 Int_t AliMultiplicityCorrection::UnfoldWithBayesian(TH1* correlation, TH1* aEfficiency, TH1* measured, TH1* initialConditions, TH1* aResult, Float_t regPar, Int_t nIterations)
2116 // unfolds a spectrum
2119 if (measured->Integral() <= 0)
2121 Printf("AliMultiplicityCorrection::UnfoldWithBayesian: ERROR: The measured spectrum is empty");
2125 const Int_t kStartBin = 0;
2127 const Int_t kMaxM = fgkMaxInput; //<= fCurrentCorrelation->GetNbinsY(); // max measured axis
2128 const Int_t kMaxT = fgkMaxParams; //<= fCurrentCorrelation->GetNbinsX(); // max true axis
2130 // store information in arrays, to increase processing speed (~ factor 5)
2131 Double_t measuredCopy[kMaxM];
2132 Double_t prior[kMaxT];
2133 Double_t result[kMaxT];
2134 Double_t efficiency[kMaxT];
2136 Double_t response[kMaxT][kMaxM];
2137 Double_t inverseResponse[kMaxT][kMaxM];
2139 // for normalization
2140 Float_t measuredIntegral = measured->Integral();
2141 for (Int_t m=0; m<kMaxM; m++)
2143 measuredCopy[m] = measured->GetBinContent(m+1) / measuredIntegral;
2145 for (Int_t t=0; t<kMaxT; t++)
2147 response[t][m] = correlation->GetBinContent(t+1, m+1);
2148 inverseResponse[t][m] = 0;
2152 for (Int_t t=0; t<kMaxT; t++)
2154 efficiency[t] = aEfficiency->GetBinContent(t+1);
2155 prior[t] = measuredCopy[t];
2159 // pick prior distribution
2160 if (initialConditions)
2162 printf("Using different starting conditions...\n");
2163 // for normalization
2164 Float_t inputDistIntegral = initialConditions->Integral();
2165 for (Int_t i=0; i<kMaxT; i++)
2166 prior[i] = initialConditions->GetBinContent(i+1) / inputDistIntegral;
2169 //TH1F* convergence = new TH1F("convergence", "convergence", 50, 0.5, 50.5);
2172 for (Int_t i=0; i<nIterations; i++)
2174 //printf(" iteration %i \n", i);
2176 // calculate IR from Beyes theorem
2177 // IR_ji = R_ij * prior_i / sum_k(R_kj * prior_k)
2179 for (Int_t m=0; m<kMaxM; m++)
2182 for (Int_t t = kStartBin; t<kMaxT; t++)
2183 norm += response[t][m] * prior[t];
2187 for (Int_t t = kStartBin; t<kMaxT; t++)
2188 inverseResponse[t][m] = response[t][m] * prior[t] / norm;
2192 for (Int_t t = kStartBin; t<kMaxT; t++)
2193 inverseResponse[t][m] = 0;
2197 for (Int_t t = kStartBin; t<kMaxT; t++)
2200 for (Int_t m=0; m<kMaxM; m++)
2201 value += inverseResponse[t][m] * measuredCopy[m];
2203 if (efficiency[t] > 0)
2204 result[t] = value / efficiency[t];
2209 // regularization (simple smoothing)
2210 for (Int_t t=kStartBin; t<kMaxT; t++)
2212 Float_t newValue = 0;
2213 // 0 bin excluded from smoothing
2214 if (t > kStartBin+1 && t<kMaxT-1)
2216 Float_t average = (result[t-1] + result[t] + result[t+1]) / 3;
2218 // weight the average with the regularization parameter
2219 newValue = (1 - regPar) * result[t] + regPar * average;
2222 newValue = result[t];
2224 prior[t] = newValue;
2227 // calculate chi2 (change from last iteration)
2228 //Double_t chi2 = 0;
2229 /*for (Int_t t=kStartBin; t<=hTrueSmoothed->GetNbinsX(); t++)
2231 Float_t newValue = hTrueSmoothed->GetBinContent(t);
2232 //Float_t diff = hPrior->GetBinContent(t) - newValue;
2233 //chi2 += (Double_t) diff * diff;
2235 hPrior->SetBinContent(t, newValue);
2237 //printf("Chi2 of %d iteration = %.10f\n", i, chi2);
2238 //convergence->Fill(i+1, chi2);
2241 // DrawComparison(Form("Bayesian_%d", i), mcTarget, correlationID, kTRUE, eventType);
2243 delete hTrueSmoothed;*/
2244 } // end of iterations
2247 //convergence->DrawCopy();
2250 //delete convergence;
2252 for (Int_t t=0; t<kMaxT; t++)
2253 aResult->SetBinContent(t+1, result[t]);
2258 // Calculate the covariance matrix, all arguments are taken from NIM,A362,487-498,1995
2260 /*printf("Calculating covariance matrix. This may take some time...\n");
2262 // TODO check if this is the right one...
2263 TH1* sumHist = GetMultiplicityMC(inputRange, eventType)->ProjectionY("sumHist", 1, GetMultiplicityMC(inputRange, eventType)->GetNbinsX());
2265 Int_t xBins = hInverseResponseBayes->GetNbinsX();
2266 Int_t yBins = hInverseResponseBayes->GetNbinsY();
2268 // calculate "unfolding matrix" Mij
2269 Float_t matrixM[251][251];
2270 for (Int_t i=1; i<=xBins; i++)
2272 for (Int_t j=1; j<=yBins; j++)
2274 if (fCurrentEfficiency->GetBinContent(i) > 0)
2275 matrixM[i-1][j-1] = hInverseResponseBayes->GetBinContent(i, j) / fCurrentEfficiency->GetBinContent(i);
2277 matrixM[i-1][j-1] = 0;
2281 Float_t* vectorn = new Float_t[yBins];
2282 for (Int_t j=1; j<=yBins; j++)
2283 vectorn[j-1] = fCurrentESD->GetBinContent(j);
2285 // first part of covariance matrix, depends on input distribution n(E)
2286 Float_t cov1[251][251];
2288 Float_t nEvents = fCurrentESD->Integral(); // N
2293 for (Int_t k=0; k<xBins; k++)
2295 printf("In Cov1: %d\n", k);
2296 for (Int_t l=0; l<yBins; l++)
2300 // sum_j Mkj Mlj n(Ej) * (1 - n(Ej) / N)
2301 for (Int_t j=0; j<yBins; j++)
2302 cov1[k][l] += matrixM[k][j] * matrixM[l][j] * vectorn[j]
2303 * (1.0 - vectorn[j] / nEvents);
2305 // - sum_i,j (i != j) Mki Mlj n(Ei) n(Ej) / N
2306 for (Int_t i=0; i<yBins; i++)
2307 for (Int_t j=0; j<yBins; j++)
2311 cov1[k][l] -= matrixM[k][i] * matrixM[l][j] * vectorn[i]
2312 * vectorn[j] / nEvents;
2317 printf("Cov1 finished\n");
2319 TH2F* cov = (TH2F*) hInverseResponseBayes->Clone("cov");
2322 for (Int_t i=1; i<=xBins; i++)
2323 for (Int_t j=1; j<=yBins; j++)
2324 cov->SetBinContent(i, j, cov1[i-1][j-1]);
2329 // second part of covariance matrix, depends on response matrix
2330 Float_t cov2[251][251];
2332 // Cov[P(Er|Cu), P(Es|Cu)] term
2333 Float_t covTerm[100][100][100];
2334 for (Int_t r=0; r<yBins; r++)
2335 for (Int_t u=0; u<xBins; u++)
2336 for (Int_t s=0; s<yBins; s++)
2339 covTerm[r][u][s] = 1.0 / sumHist->GetBinContent(u+1) * hResponse->GetBinContent(u+1, r+1)
2340 * (1.0 - hResponse->GetBinContent(u+1, r+1));
2342 covTerm[r][u][s] = - 1.0 / sumHist->GetBinContent(u+1) * hResponse->GetBinContent(u+1, r+1)
2343 * hResponse->GetBinContent(u+1, s+1);
2346 for (Int_t k=0; k<xBins; k++)
2347 for (Int_t l=0; l<yBins; l++)
2350 printf("In Cov2: %d %d\n", k, l);
2351 for (Int_t i=0; i<yBins; i++)
2352 for (Int_t j=0; j<yBins; j++)
2354 //printf("In Cov2: %d %d %d %d\n", k, l, i, j);
2355 // calculate Cov(Mki, Mlj) = sum{ru},{su} ...
2357 for (Int_t r=0; r<yBins; r++)
2358 for (Int_t u=0; u<xBins; u++)
2359 for (Int_t s=0; s<yBins; s++)
2361 if (hResponse->GetBinContent(u+1, r+1) == 0 || hResponse->GetBinContent(u+1, s+1) == 0
2362 || hResponse->GetBinContent(u+1, i+1) == 0)
2365 tmpCov += BayesCovarianceDerivate(matrixM, hResponse, fCurrentEfficiency, k, i, r, u)
2366 * BayesCovarianceDerivate(matrixM, hResponse, fCurrentEfficiency, l, j, s, u)
2370 cov2[k][l] += fCurrentESD->GetBinContent(i+1) * fCurrentESD->GetBinContent(j+1) * tmpCov;
2374 printf("Cov2 finished\n");
2376 for (Int_t i=1; i<=xBins; i++)
2377 for (Int_t j=1; j<=yBins; j++)
2378 cov->SetBinContent(i, j, cov1[i-1][j-1] + cov2[i-1][j-1]);
2381 cov->Draw("COLZ");*/
2384 //____________________________________________________________________
2385 Float_t AliMultiplicityCorrection::BayesCovarianceDerivate(Float_t matrixM[251][251], TH2* hResponse, Int_t k, Int_t i, Int_t r, Int_t u)
2388 // helper function for the covariance matrix of the bayesian method
2393 if (k == u && r == i)
2394 result += 1.0 / hResponse->GetBinContent(u+1, r+1);
2397 result -= 1.0 / fCurrentEfficiency->GetBinContent(u+1);
2400 result -= matrixM[u][i] * fCurrentEfficiency->GetBinContent(u+1) / hResponse->GetBinContent(u+1, i+1);
2402 result *= matrixM[k][i];
2407 //____________________________________________________________________
2408 void AliMultiplicityCorrection::ApplyLaszloMethod(Int_t inputRange, Bool_t fullPhaseSpace, EventType eventType)
2411 // correct spectrum using bayesian method
2416 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
2417 Int_t mcTarget = ((fullPhaseSpace == kFALSE) ? inputRange : 4);
2419 SetupCurrentHists(inputRange, fullPhaseSpace, eventType, kFALSE);
2421 fCurrentESD->Scale(1.0 / fCurrentESD->Integral());
2423 // TODO should be taken from correlation map
2424 //TH1* sumHist = GetMultiplicityMC(inputRange, eventType)->ProjectionY("sumHist", 1, GetMultiplicityMC(inputRange, eventType)->GetNbinsX());
2426 // normalize correction for given nPart
2427 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
2429 Double_t sum = fCurrentCorrelation->Integral(i, i, 1, fCurrentCorrelation->GetNbinsY());
2430 //Double_t sum = sumHist->GetBinContent(i);
2433 for (Int_t j=1; j<=fCurrentCorrelation->GetNbinsY(); ++j)
2436 fCurrentCorrelation->SetBinContent(i, j, fCurrentCorrelation->GetBinContent(i, j) / sum);
2437 fCurrentCorrelation->SetBinError(i, j, fCurrentCorrelation->GetBinError(i, j) / sum);
2442 fCurrentCorrelation->Draw("COLZ");
2445 fCurrentEfficiency = ((TH2*) fCurrentCorrelation)->ProjectionX("eff");
2447 // pick prior distribution
2448 TH1F* hPrior = (TH1F*)fCurrentESD->Clone("prior");
2449 Float_t norm = 1; //hPrior->Integral();
2450 for (Int_t t=1; t<=hPrior->GetNbinsX(); t++)
2451 hPrior->SetBinContent(t, hPrior->GetBinContent(t)/norm);
2453 // zero distribution
2454 TH1F* zero = (TH1F*)hPrior->Clone("zero");
2457 TH1F* hTemp = (TH1F*)fCurrentESD->Clone("temp");
2461 TH2F* hResponse = (TH2F*) fCurrentCorrelation;
2464 Int_t iterations = 25;
2465 for (Int_t i=0; i<iterations; i++)
2467 //printf(" iteration %i \n", i);
2469 for (Int_t m=1; m<=hResponse->GetNbinsY(); m++)
2472 for (Int_t t = 1; t<=hResponse->GetNbinsX(); t++)
2473 value += hResponse->GetBinContent(t, m) * hPrior->GetBinContent(t);
2474 hTemp->SetBinContent(m, value);
2475 //printf("%d %f %f %f\n", m, zero->GetBinContent(m), hPrior->GetBinContent(m), value);
2478 // regularization (simple smoothing)
2479 TH1F* hTrueSmoothed = (TH1F*) hTemp->Clone("truesmoothed");
2481 for (Int_t t=2; t<hTrueSmoothed->GetNbinsX(); t++)
2483 Float_t average = (hTemp->GetBinContent(t-1) / hTemp->GetBinWidth(t-1)
2484 + hTemp->GetBinContent(t) / hTemp->GetBinWidth(t)
2485 + hTemp->GetBinContent(t+1) / hTemp->GetBinWidth(t+1)) / 3.;
2486 average *= hTrueSmoothed->GetBinWidth(t);
2488 // weight the average with the regularization parameter
2489 hTrueSmoothed->SetBinContent(t, (1-regPar) * hTemp->GetBinContent(t) + regPar * average);
2492 for (Int_t m=1; m<=hResponse->GetNbinsY(); m++)
2493 hTemp->SetBinContent(m, zero->GetBinContent(m) + hPrior->GetBinContent(m) - hTrueSmoothed->GetBinContent(m));
2496 for (Int_t t=1; t<=fMultiplicityESDCorrected[correlationID]->GetNbinsX(); t++)
2498 fMultiplicityESDCorrected[correlationID]->SetBinContent(t, hTemp->GetBinContent(t));
2499 fMultiplicityESDCorrected[correlationID]->SetBinError(t, 0.05 * hTemp->GetBinContent(t)); // TODO
2501 //printf(" bin %d content %f \n", t, fMultiplicityESDCorrected[correlationID]->GetBinContent(t));
2505 // calculate chi2 (change from last iteration)
2508 // use smoothed true (normalized) as new prior
2509 Float_t norm = 1; //hTrueSmoothed->Integral();
2511 for (Int_t t=1; t<hTrueSmoothed->GetNbinsX(); t++)
2513 Float_t newValue = hTemp->GetBinContent(t)/norm;
2514 Float_t diff = hPrior->GetBinContent(t) - newValue;
2515 chi2 += (Double_t) diff * diff;
2517 hPrior->SetBinContent(t, newValue);
2520 printf("Chi2 of %d iteration = %.10f\n", i, chi2);
2523 DrawComparison(Form("Laszlo_%d", i), inputRange, fullPhaseSpace, kTRUE, GetMultiplicityMC(mcTarget, eventType)->ProjectionY());
2525 delete hTrueSmoothed;
2526 } // end of iterations
2528 DrawComparison("Laszlo", inputRange, fullPhaseSpace, kTRUE, GetMultiplicityMC(mcTarget, eventType)->ProjectionY());
2531 //____________________________________________________________________
2532 void AliMultiplicityCorrection::ApplyGaussianMethod(Int_t inputRange, Bool_t fullPhaseSpace)
2535 // correct spectrum using a simple Gaussian approach, that is model-dependent
2538 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
2539 Int_t mcTarget = ((fullPhaseSpace == kFALSE) ? inputRange : 4);
2541 SetupCurrentHists(inputRange, fullPhaseSpace, kTrVtx, kFALSE);
2543 fCurrentESD->Scale(1.0 / fCurrentESD->Integral());
2545 TH1D* correction = dynamic_cast<TH1D*> (fCurrentESD->Clone("GaussianMean"));
2546 correction->SetTitle("GaussianMean");
2548 TH1D* correctionWidth = dynamic_cast<TH1D*> (fCurrentESD->Clone("GaussianWidth"));
2549 correction->SetTitle("GaussianWidth");
2551 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
2553 TH1D* proj = (dynamic_cast<TH2*> (fCurrentCorrelation))->ProjectionX("_px", i, i+1);
2554 proj->Fit("gaus", "0Q");
2555 correction->SetBinContent(i, proj->GetFunction("gaus")->GetParameter(1));
2556 correctionWidth->SetBinContent(i, proj->GetFunction("gaus")->GetParameter(2));
2560 // draw for debugging
2563 proj->GetFunction("gaus")->DrawCopy("SAME");
2566 TH1* target = fMultiplicityESDCorrected[correlationID];
2568 Int_t nBins = target->GetNbinsX()*10+1;
2569 Float_t* binning = new Float_t[nBins];
2570 for (Int_t i=1; i<=target->GetNbinsX(); ++i)
2571 for (Int_t j=0; j<10; ++j)
2572 binning[(i-1)*10 + j] = target->GetXaxis()->GetBinLowEdge(i) + target->GetXaxis()->GetBinWidth(i) / 10 * j;
2574 binning[nBins-1] = target->GetXaxis()->GetBinUpEdge(target->GetNbinsX());
2576 TH1F* fineBinned = new TH1F("targetFineBinned", "targetFineBinned", nBins-1, binning);
2578 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
2580 Float_t mean = correction->GetBinContent(i);
2581 Float_t width = correctionWidth->GetBinContent(i);
2583 Int_t fillBegin = fineBinned->FindBin(mean - width * 5);
2584 Int_t fillEnd = fineBinned->FindBin(mean + width * 5);
2585 //printf("bin %d mean %f width %f, filling from %d to %d\n", i, mean, width, fillBegin, fillEnd);
2587 for (Int_t j=fillBegin; j <= fillEnd; ++j)
2589 fineBinned->AddBinContent(j, TMath::Gaus(fineBinned->GetXaxis()->GetBinCenter(j), mean, width, kTRUE) * fCurrentESD->GetBinContent(i));
2593 for (Int_t i=1; i<=target->GetNbinsX(); ++i)
2596 for (Int_t j=1; j<=10; ++j)
2597 sum += fineBinned->GetBinContent((i-1)*10 + j);
2598 target->SetBinContent(i, sum / 10);
2603 DrawComparison("Gaussian", inputRange, fullPhaseSpace, kFALSE, GetMultiplicityMC(mcTarget, kTrVtx)->ProjectionY());
2606 //____________________________________________________________________
2607 TH2F* AliMultiplicityCorrection::CalculateMultiplicityESD(TH1* inputMC, Int_t correlationMap)
2609 // runs the distribution given in inputMC through the response matrix identified by
2610 // correlationMap and produces a measured distribution
2611 // although it is a TH2F the vertex axis is not used at the moment and all entries are filled in mid-vertex
2612 // if normalized is set, inputMC is expected to be normalized to the bin width
2617 if (correlationMap < 0 || correlationMap >= kCorrHists)
2620 // empty under/overflow bins in x, otherwise Project3D takes them into account
2621 TH3* hist = fCorrelation[correlationMap];
2622 for (Int_t y=1; y<=hist->GetYaxis()->GetNbins(); ++y)
2624 for (Int_t z=1; z<=hist->GetZaxis()->GetNbins(); ++z)
2626 hist->SetBinContent(0, y, z, 0);
2627 hist->SetBinContent(hist->GetXaxis()->GetNbins()+1, y, z, 0);
2631 TH2* corr = (TH2*) hist->Project3D("zy");
2632 //corr->Rebin2D(2, 1);
2635 // normalize correction for given nPart
2636 for (Int_t i=1; i<=corr->GetNbinsX(); ++i)
2638 Double_t sum = corr->Integral(i, i, 1, corr->GetNbinsY());
2642 for (Int_t j=1; j<=corr->GetNbinsY(); ++j)
2645 corr->SetBinContent(i, j, corr->GetBinContent(i, j) / sum);
2646 corr->SetBinError(i, j, corr->GetBinError(i, j) / sum);
2650 TH2F* target = dynamic_cast<TH2F*> (fMultiplicityESD[0]->Clone(Form("%s_measured", inputMC->GetName())));
2653 for (Int_t meas=1; meas<=corr->GetNbinsY(); ++meas)
2655 Float_t measured = 0;
2658 for (Int_t gen=1; gen<=corr->GetNbinsX(); ++gen)
2660 Int_t mcGenBin = inputMC->GetXaxis()->FindBin(corr->GetXaxis()->GetBinCenter(gen));
2662 measured += inputMC->GetBinContent(mcGenBin) * corr->GetBinContent(gen, meas);
2663 error += inputMC->GetBinError(mcGenBin) * corr->GetBinContent(gen, meas);
2666 //printf("%f +- %f ; %f +- %f \n", inputMC->GetBinContent(meas), inputMC->GetBinError(meas), measured, error);
2668 target->SetBinContent(1 + target->GetNbinsX() / 2, meas, measured);
2669 target->SetBinError(1 + target->GetNbinsX() / 2, meas, error);
2675 //____________________________________________________________________
2676 void AliMultiplicityCorrection::SetGenMeasFromFunc(TF1* inputMC, Int_t id)
2678 // uses the given function to fill the input MC histogram and generates from that
2679 // the measured histogram by applying the response matrix
2680 // this can be used to evaluate if the methods work indepedently of the input
2682 // WARNING does not respect the vertex distribution, just fills central vertex bin
2687 if (id < 0 || id >= kESDHists)
2690 TH2F* mc = fMultiplicityVtx[id];
2694 for (Int_t i=1; i<=mc->GetNbinsY(); ++i)
2696 mc->SetBinContent(mc->GetNbinsX() / 2 + 1, i, inputMC->Eval(mc->GetYaxis()->GetBinCenter(i)) * mc->GetYaxis()->GetBinWidth(i));
2697 mc->SetBinError(mc->GetNbinsX() / 2 + 1, i, 0);
2703 TH1* proj = mc->ProjectionY();
2705 TString tmp(fMultiplicityESD[id]->GetName());
2706 delete fMultiplicityESD[id];
2707 fMultiplicityESD[id] = CalculateMultiplicityESD(proj, id);
2708 fMultiplicityESD[id]->SetName(tmp);