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>
36 #include <TCollection.h>
41 #include <TProfile2D.h>
43 ClassImp(AliMultiplicityCorrection)
45 // These are the areas where the quality of the unfolding results are evaluated
46 // Default defined here, call SetQualityRegions to change them
47 // unit is in multiplicity (not in bin!)
49 // SPD: peak area - flat area - low stat area
50 Int_t AliMultiplicityCorrection::fgQualityRegionsB[kQualityRegions] = {1, 20, 70};
51 Int_t AliMultiplicityCorrection::fgQualityRegionsE[kQualityRegions] = {10, 65, 80};
53 //____________________________________________________________________
54 void AliMultiplicityCorrection::SetQualityRegions(Bool_t SPDStudy)
57 // sets the quality region definition to TPC or SPD
62 // SPD: peak area - flat area - low stat area
63 fgQualityRegionsB[0] = 1;
64 fgQualityRegionsE[0] = 10;
66 fgQualityRegionsB[1] = 20;
67 fgQualityRegionsE[1] = 65;
69 fgQualityRegionsB[2] = 70;
70 fgQualityRegionsE[2] = 80;
72 Printf("AliMultiplicityCorrection::SetQualityRegions --> Enabled quality regions for SPD");
76 // TPC: peak area - flat area - low stat area
77 fgQualityRegionsB[0] = 4;
78 fgQualityRegionsE[0] = 12;
80 fgQualityRegionsB[1] = 25;
81 fgQualityRegionsE[1] = 55;
83 fgQualityRegionsB[2] = 88;
84 fgQualityRegionsE[2] = 108;
86 Printf("AliMultiplicityCorrection::SetQualityRegions --> Enabled quality regions for TPC");
90 //____________________________________________________________________
91 AliMultiplicityCorrection::AliMultiplicityCorrection() :
92 TNamed(), fCurrentESD(0), fCurrentCorrelation(0), fCurrentEfficiency(0), fLastBinLimit(0), fLastChi2MC(0), fLastChi2MCLimit(0), fLastChi2Residuals(0), fRatioAverage(0)
95 // default constructor
98 for (Int_t i = 0; i < kESDHists; ++i)
99 fMultiplicityESD[i] = 0;
101 for (Int_t i = 0; i < kMCHists; ++i)
103 fMultiplicityVtx[i] = 0;
104 fMultiplicityMB[i] = 0;
105 fMultiplicityINEL[i] = 0;
106 fMultiplicityNSD[i] = 0;
109 for (Int_t i = 0; i < kCorrHists; ++i)
112 fMultiplicityESDCorrected[i] = 0;
115 for (Int_t i = 0; i < kQualityRegions; ++i)
119 //____________________________________________________________________
120 AliMultiplicityCorrection* AliMultiplicityCorrection::Open(const char* fileName, const char* folderName)
122 // opens the given file, reads the multiplicity from the given folder and returns the object
124 TFile* file = TFile::Open(fileName);
127 Printf("ERROR: Could not open %s", fileName);
131 AliMultiplicityCorrection* mult = new AliMultiplicityCorrection(folderName, folderName);
132 mult->LoadHistograms();
134 // TODO closing the file does not work here, because the histograms cannot be read anymore. LoadHistograms need to be adapted
139 //____________________________________________________________________
140 AliMultiplicityCorrection::AliMultiplicityCorrection(const Char_t* name, const Char_t* title) :
143 fCurrentCorrelation(0),
144 fCurrentEfficiency(0),
148 fLastChi2Residuals(0),
155 // do not add this hists to the directory
156 Bool_t oldStatus = TH1::AddDirectoryStatus();
157 TH1::AddDirectory(kFALSE);
159 /*Float_t binLimitsVtx[] = {-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10};
160 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,
161 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5, 18.5, 19.5,
162 20.5, 21.5, 22.5, 23.5, 24.5, 25.5, 26.5, 27.5, 28.5, 29.5,
163 30.5, 31.5, 32.5, 33.5, 34.5, 35.5, 36.5, 37.5, 38.5, 39.5,
164 40.5, 41.5, 42.5, 43.5, 44.5, 45.5, 46.5, 47.5, 48.5, 49.5,
165 50.5, 55.5, 60.5, 65.5, 70.5, 75.5, 80.5, 85.5, 90.5, 95.5,
166 100.5, 105.5, 110.5, 115.5, 120.5, 125.5, 130.5, 135.5, 140.5, 145.5,
167 150.5, 160.5, 170.5, 180.5, 190.5, 200.5, 210.5, 220.5, 230.5, 240.5,
168 250.5, 275.5, 300.5, 325.5, 350.5, 375.5, 400.5, 425.5, 450.5, 475.5,
170 //525.5, 550.5, 575.5, 600.5, 625.5, 650.5, 675.5, 700.5, 725.5,
171 //750.5, 775.5, 800.5, 825.5, 850.5, 875.5, 900.5, 925.5, 950.5, 975.5,
174 #define VTXBINNING 10, binLimitsVtx
175 #define NBINNING fgkMaxParams, binLimitsN*/
177 #define NBINNING 201, -0.5, 200.5
179 Double_t vtxRange[] = { 15, 6, 2 };
181 for (Int_t i = 0; i < kESDHists; ++i)
182 fMultiplicityESD[i] = new TH2F(Form("fMultiplicityESD%d", i), "fMultiplicityESD;vtx-z;Ntracks;Count", 1, -vtxRange[i], vtxRange[i], NBINNING);
184 for (Int_t i = 0; i < kMCHists; ++i)
186 fMultiplicityVtx[i] = dynamic_cast<TH2F*> (fMultiplicityESD[i%3]->Clone(Form("fMultiplicityVtx%d", i)));
187 fMultiplicityVtx[i]->SetTitle("fMultiplicityVtx;vtx-z;Npart");
189 fMultiplicityMB[i] = dynamic_cast<TH2F*> (fMultiplicityVtx[i]->Clone(Form("fMultiplicityMB%d", i)));
190 fMultiplicityMB[i]->SetTitle("fMultiplicityMB");
192 fMultiplicityINEL[i] = dynamic_cast<TH2F*> (fMultiplicityVtx[i]->Clone(Form("fMultiplicityINEL%d", i)));
193 fMultiplicityINEL[i]->SetTitle("fMultiplicityINEL");
195 fMultiplicityNSD[i] = dynamic_cast<TH2F*> (fMultiplicityVtx[i]->Clone(Form("fMultiplicityNSD%d", i)));
196 fMultiplicityNSD[i]->SetTitle("fMultiplicityNSD");
199 for (Int_t i = 0; i < kCorrHists; ++i)
201 fCorrelation[i] = new TH3F(Form("fCorrelation%d", i), "fCorrelation;vtx-z;Npart;Ntracks", 1, -vtxRange[i%3], vtxRange[i%3], NBINNING, NBINNING);
202 fMultiplicityESDCorrected[i] = new TH1F(Form("fMultiplicityESDCorrected%d", i), "fMultiplicityESDCorrected;Npart;dN/dN", NBINNING);
205 TH1::AddDirectory(oldStatus);
207 AliUnfolding::SetNbins(120, 120);
208 AliUnfolding::SetSkipBinsBegin(1);
209 AliUnfolding::SetNormalizeInput(kTRUE);
212 //____________________________________________________________________
213 AliMultiplicityCorrection::~AliMultiplicityCorrection()
219 Printf("AliMultiplicityCorrection::~AliMultiplicityCorrection called");
221 for (Int_t i = 0; i < kESDHists; ++i)
223 if (fMultiplicityESD[i])
224 delete fMultiplicityESD[i];
225 fMultiplicityESD[i] = 0;
228 for (Int_t i = 0; i < kMCHists; ++i)
230 if (fMultiplicityVtx[i])
231 delete fMultiplicityVtx[i];
232 fMultiplicityVtx[i] = 0;
234 if (fMultiplicityMB[i])
235 delete fMultiplicityMB[i];
236 fMultiplicityMB[i] = 0;
238 if (fMultiplicityINEL[i])
239 delete fMultiplicityINEL[i];
240 fMultiplicityINEL[i] = 0;
242 if (fMultiplicityNSD[i])
243 delete fMultiplicityNSD[i];
244 fMultiplicityNSD[i] = 0;
247 for (Int_t i = 0; i < kCorrHists; ++i)
250 delete fCorrelation[i];
253 if (fMultiplicityESDCorrected[i])
254 delete fMultiplicityESDCorrected[i];
255 fMultiplicityESDCorrected[i] = 0;
259 //____________________________________________________________________
260 Long64_t AliMultiplicityCorrection::Merge(TCollection* list)
262 // Merge a list of AliMultiplicityCorrection objects with this (needed for
264 // Returns the number of merged objects (including this).
272 TIterator* iter = list->MakeIterator();
275 // collections of all histograms
276 TList collections[kESDHists+kMCHists*4+kCorrHists*2];
279 while ((obj = iter->Next())) {
281 AliMultiplicityCorrection* entry = dynamic_cast<AliMultiplicityCorrection*> (obj);
285 for (Int_t i = 0; i < kESDHists; ++i)
286 collections[i].Add(entry->fMultiplicityESD[i]);
288 for (Int_t i = 0; i < kMCHists; ++i)
290 collections[kESDHists+i].Add(entry->fMultiplicityVtx[i]);
291 collections[kESDHists+kMCHists+i].Add(entry->fMultiplicityMB[i]);
292 collections[kESDHists+kMCHists*2+i].Add(entry->fMultiplicityINEL[i]);
293 collections[kESDHists+kMCHists*3+i].Add(entry->fMultiplicityNSD[i]);
296 for (Int_t i = 0; i < kCorrHists; ++i)
297 collections[kESDHists+kMCHists*4+i].Add(entry->fCorrelation[i]);
299 for (Int_t i = 0; i < kCorrHists; ++i)
300 collections[kESDHists+kMCHists*4+kCorrHists+i].Add(entry->fMultiplicityESDCorrected[i]);
305 for (Int_t i = 0; i < kESDHists; ++i)
306 fMultiplicityESD[i]->Merge(&collections[i]);
308 for (Int_t i = 0; i < kMCHists; ++i)
310 fMultiplicityVtx[i]->Merge(&collections[kESDHists+i]);
311 fMultiplicityMB[i]->Merge(&collections[kESDHists+kMCHists+i]);
312 fMultiplicityINEL[i]->Merge(&collections[kESDHists+kMCHists*2+i]);
313 fMultiplicityNSD[i]->Merge(&collections[kESDHists+kMCHists*3+i]);
316 for (Int_t i = 0; i < kCorrHists; ++i)
317 fCorrelation[i]->Merge(&collections[kESDHists+kMCHists*4+i]);
319 for (Int_t i = 0; i < kCorrHists; ++i)
320 fMultiplicityESDCorrected[i]->Merge(&collections[kESDHists+kMCHists*4+kCorrHists+i]);
327 //____________________________________________________________________
328 Bool_t AliMultiplicityCorrection::LoadHistograms(const Char_t* dir)
331 // loads the histograms from a file
332 // if dir is empty a directory with the name of this object is taken (like in SaveHistogram)
338 if (!gDirectory->cd(dir))
341 // store old hists to delete them later
343 oldObjects.SetOwner(1);
344 for (Int_t i = 0; i < kESDHists; ++i)
345 if (fMultiplicityESD[i])
346 oldObjects.Add(fMultiplicityESD[i]);
348 for (Int_t i = 0; i < kMCHists; ++i)
350 if (fMultiplicityVtx[i])
351 oldObjects.Add(fMultiplicityVtx[i]);
352 if (fMultiplicityMB[i])
353 oldObjects.Add(fMultiplicityMB[i]);
354 if (fMultiplicityINEL[i])
355 oldObjects.Add(fMultiplicityINEL[i]);
356 if (fMultiplicityNSD[i])
357 oldObjects.Add(fMultiplicityNSD[i]);
360 for (Int_t i = 0; i < kCorrHists; ++i)
362 oldObjects.Add(fCorrelation[i]);
366 Bool_t success = kTRUE;
368 for (Int_t i = 0; i < kESDHists; ++i)
370 fMultiplicityESD[i] = dynamic_cast<TH2F*> (gDirectory->Get(fMultiplicityESD[i]->GetName()));
371 if (!fMultiplicityESD[i])
375 for (Int_t i = 0; i < kMCHists; ++i)
377 fMultiplicityVtx[i] = dynamic_cast<TH2F*> (gDirectory->Get(fMultiplicityVtx[i]->GetName()));
378 fMultiplicityMB[i] = dynamic_cast<TH2F*> (gDirectory->Get(fMultiplicityMB[i]->GetName()));
379 fMultiplicityINEL[i] = dynamic_cast<TH2F*> (gDirectory->Get(fMultiplicityINEL[i]->GetName()));
380 fMultiplicityNSD[i] = dynamic_cast<TH2F*> (gDirectory->Get(fMultiplicityNSD[i]->GetName()));
381 if (!fMultiplicityVtx[i] || !fMultiplicityMB[i] || !fMultiplicityINEL[i])
385 for (Int_t i = 0; i < kCorrHists; ++i)
387 fCorrelation[i] = dynamic_cast<TH3F*> (gDirectory->Get(fCorrelation[i]->GetName()));
388 if (!fCorrelation[i])
390 fMultiplicityESDCorrected[i] = dynamic_cast<TH1F*> (gDirectory->Get(fMultiplicityESDCorrected[i]->GetName()));
391 if (!fMultiplicityESDCorrected[i])
395 gDirectory->cd("..");
403 //____________________________________________________________________
404 void AliMultiplicityCorrection::SaveHistograms(const char* dir)
407 // saves the histograms
413 gDirectory->mkdir(dir);
416 for (Int_t i = 0; i < kESDHists; ++i)
417 if (fMultiplicityESD[i])
419 fMultiplicityESD[i]->Write();
420 fMultiplicityESD[i]->ProjectionY(Form("%s_px", fMultiplicityESD[i]->GetName()), 1, fMultiplicityESD[i]->GetNbinsX())->Write();
423 for (Int_t i = 0; i < kMCHists; ++i)
425 if (fMultiplicityVtx[i])
427 fMultiplicityVtx[i]->Write();
428 fMultiplicityVtx[i]->ProjectionY(Form("%s_px", fMultiplicityVtx[i]->GetName()), 1, fMultiplicityVtx[i]->GetNbinsX())->Write();
430 if (fMultiplicityMB[i])
432 fMultiplicityMB[i]->Write();
433 fMultiplicityMB[i]->ProjectionY(Form("%s_px", fMultiplicityMB[i]->GetName()), 1, fMultiplicityMB[i]->GetNbinsX())->Write();
435 if (fMultiplicityINEL[i])
437 fMultiplicityINEL[i]->Write();
438 fMultiplicityINEL[i]->ProjectionY(Form("%s_px", fMultiplicityINEL[i]->GetName()), 1, fMultiplicityINEL[i]->GetNbinsX())->Write();
440 if (fMultiplicityNSD[i])
442 fMultiplicityNSD[i]->Write();
443 fMultiplicityNSD[i]->ProjectionY(Form("%s_px", fMultiplicityNSD[i]->GetName()), 1, fMultiplicityNSD[i]->GetNbinsX())->Write();
447 for (Int_t i = 0; i < kCorrHists; ++i)
450 fCorrelation[i]->Write();
451 if (fMultiplicityESDCorrected[i])
452 fMultiplicityESDCorrected[i]->Write();
455 gDirectory->cd("..");
458 //____________________________________________________________________
459 void AliMultiplicityCorrection::FillGenerated(Float_t vtx, Bool_t triggered, Bool_t vertex, AliPWG0Helper::MCProcessType processType, Int_t generated05, Int_t generated10, Int_t generated14, Int_t generatedAll)
462 // Fills an event from MC
467 fMultiplicityMB[0]->Fill(vtx, generated05);
468 fMultiplicityMB[1]->Fill(vtx, generated10);
469 fMultiplicityMB[2]->Fill(vtx, generated14);
470 fMultiplicityMB[3]->Fill(vtx, generatedAll);
474 fMultiplicityVtx[0]->Fill(vtx, generated05);
475 fMultiplicityVtx[1]->Fill(vtx, generated10);
476 fMultiplicityVtx[2]->Fill(vtx, generated14);
477 fMultiplicityVtx[3]->Fill(vtx, generatedAll);
481 fMultiplicityINEL[0]->Fill(vtx, generated05);
482 fMultiplicityINEL[1]->Fill(vtx, generated10);
483 fMultiplicityINEL[2]->Fill(vtx, generated14);
484 fMultiplicityINEL[3]->Fill(vtx, generatedAll);
486 if (processType != AliPWG0Helper::kSD)
488 fMultiplicityNSD[0]->Fill(vtx, generated05);
489 fMultiplicityNSD[1]->Fill(vtx, generated10);
490 fMultiplicityNSD[2]->Fill(vtx, generated14);
491 fMultiplicityNSD[3]->Fill(vtx, generatedAll);
495 //____________________________________________________________________
496 void AliMultiplicityCorrection::FillMeasured(Float_t vtx, Int_t measured05, Int_t measured10, Int_t measured14)
499 // Fills an event from ESD
502 fMultiplicityESD[0]->Fill(vtx, measured05);
503 fMultiplicityESD[1]->Fill(vtx, measured10);
504 fMultiplicityESD[2]->Fill(vtx, measured14);
507 //____________________________________________________________________
508 void AliMultiplicityCorrection::FillCorrection(Float_t vtx, Int_t generated05, Int_t generated10, Int_t generated14, Int_t generatedAll, Int_t measured05, Int_t measured10, Int_t measured14)
511 // Fills an event into the correlation map with the information from MC and ESD
514 fCorrelation[0]->Fill(vtx, generated05, measured05);
515 fCorrelation[1]->Fill(vtx, generated10, measured10);
516 fCorrelation[2]->Fill(vtx, generated14, measured14);
518 fCorrelation[3]->Fill(vtx, generatedAll, measured05);
519 fCorrelation[4]->Fill(vtx, generatedAll, measured10);
520 fCorrelation[5]->Fill(vtx, generatedAll, measured14);
523 //____________________________________________________________________
524 void AliMultiplicityCorrection::SetupCurrentHists(Int_t inputRange, Bool_t fullPhaseSpace, EventType eventType)
527 // fills fCurrentESD, fCurrentCorrelation
528 // resets fMultiplicityESDCorrected
531 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
533 fMultiplicityESDCorrected[correlationID]->Reset();
534 fMultiplicityESDCorrected[correlationID]->Sumw2();
536 // project without under/overflow bins
537 fCurrentESD = fMultiplicityESD[inputRange]->ProjectionY("fCurrentESD", 1, fMultiplicityESD[inputRange]->GetXaxis()->GetNbins());
538 fCurrentESD->Sumw2();
540 // empty under/overflow bins in x, otherwise Project3D takes them into account
541 TH3* hist = fCorrelation[correlationID];
542 for (Int_t y=0; y<=hist->GetYaxis()->GetNbins()+1; ++y)
544 for (Int_t z=0; z<=hist->GetZaxis()->GetNbins()+1; ++z)
546 hist->SetBinContent(0, y, z, 0);
547 hist->SetBinContent(hist->GetXaxis()->GetNbins()+1, y, z, 0);
551 fCurrentCorrelation = (TH2*) hist->Project3D("zy");
552 fCurrentCorrelation->Sumw2();
554 Printf("AliMultiplicityCorrection::SetupCurrentHists: Statistics information: %.f entries in correlation map; %.f entries in measured spectrum", fCurrentCorrelation->Integral(), fCurrentESD->Integral());
556 #if 0 // does not help
557 // null bins with one entry
558 Int_t nNulledBins = 0;
559 for (Int_t x=1; x<=fCurrentCorrelation->GetXaxis()->GetNbins(); ++x)
560 for (Int_t y=1; y<=fCurrentCorrelation->GetYaxis()->GetNbins(); ++y)
562 if (fCurrentCorrelation->GetBinContent(x, y) == 1)
564 fCurrentCorrelation->SetBinContent(x, y, 0);
565 fCurrentCorrelation->SetBinError(x, y, 0);
570 Printf("Nulled %d bins", nNulledBins);
573 fCurrentEfficiency = GetEfficiency(inputRange, eventType);
574 //fCurrentEfficiency->Rebin(2);
575 //fCurrentEfficiency->Scale(0.5);
578 //____________________________________________________________________
579 TH1* AliMultiplicityCorrection::GetEfficiency(Int_t inputRange, EventType eventType)
582 // calculates efficiency for given event type
589 case kMB: divisor = fMultiplicityMB[inputRange]->ProjectionY("divisor", 1, fMultiplicityMB[inputRange]->GetNbinsX(), "e"); break;
590 case kINEL: divisor = fMultiplicityINEL[inputRange]->ProjectionY("divisor", 1, fMultiplicityINEL[inputRange]->GetNbinsX(), "e"); break;
591 case kNSD: divisor = fMultiplicityNSD[inputRange]->ProjectionY("divisor", 1, fMultiplicityNSD[inputRange]->GetNbinsX(), "e"); break;
593 TH1* eff = fMultiplicityVtx[inputRange]->ProjectionY("CurrentEfficiency", 1, fMultiplicityVtx[inputRange]->GetNbinsX(), "e");
595 if (eventType == kTrVtx)
597 for (Int_t i=0; i<= eff->GetNbinsX()+1; i++)
598 eff->SetBinContent(i, 1);
601 eff->Divide(eff, divisor, 1, 1, "B");
606 //____________________________________________________________________
607 TH1* AliMultiplicityCorrection::GetTriggerEfficiency(Int_t inputRange)
610 // calculates efficiency for given event type
613 TH1* divisor = fMultiplicityINEL[inputRange]->ProjectionY("divisor", 1, fMultiplicityINEL[inputRange]->GetNbinsX(), "e");
614 TH1* eff = fMultiplicityMB[inputRange]->ProjectionY("CurrentEfficiency", 1, fMultiplicityMB[inputRange]->GetNbinsX(), "e");
615 eff->Divide(eff, divisor, 1, 1, "B");
619 //____________________________________________________________________
620 Int_t AliMultiplicityCorrection::ApplyMinuitFit(Int_t inputRange, Bool_t fullPhaseSpace, EventType eventType, Bool_t check, TH1* initialConditions)
623 // correct spectrum using minuit chi2 method
625 // for description of parameters, see AliUnfolding::Unfold
628 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
630 AliUnfolding::SetCreateOverflowBin(5);
631 AliUnfolding::SetUnfoldingMethod(AliUnfolding::kChi2Minimization);
632 SetupCurrentHists(inputRange, fullPhaseSpace, eventType);
634 if (!initialConditions)
636 initialConditions = (TH1*) fCurrentESD->Clone("initialConditions");
637 initialConditions->Scale(1.0 / initialConditions->Integral());
640 // set minimum value to prevent MINUIT just staying in the small value
641 for (Int_t i=1; i<=initialConditions->GetNbinsX(); i++)
642 initialConditions->SetBinContent(i, TMath::Max(initialConditions->GetBinContent(i), 1e-3));
646 return AliUnfolding::Unfold(fCurrentCorrelation, fCurrentEfficiency, fCurrentESD, initialConditions, fMultiplicityESDCorrected[correlationID], check);
649 //____________________________________________________________________
650 Int_t AliMultiplicityCorrection::ApplyNBDFit(Int_t inputRange, Bool_t fullPhaseSpace, EventType eventType)
653 // correct spectrum using minuit chi2 method with a NBD function
655 // for description of parameters, see AliUnfolding::Unfold
658 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
660 AliUnfolding::SetUnfoldingMethod(AliUnfolding::kFunction);
661 SetupCurrentHists(inputRange, fullPhaseSpace, eventType);
663 TF1* func = new TF1("nbd", "[0] * TMath::Gamma([2]+x) / TMath::Gamma([2]) / TMath::Gamma(x+1) * pow([1] / ([1]+[2]), x) * pow(1.0 + [1]/[2], -[2])");
664 func->SetParNames("scaling", "averagen", "k");
665 func->SetParLimits(0, 0, 1000);
666 func->SetParLimits(1, 1, 50);
667 func->SetParLimits(2, 1, 10);
668 func->SetParameters(1, 10, 2);
669 AliUnfolding::SetFunction(func);
671 return AliUnfolding::Unfold(fCurrentCorrelation, fCurrentEfficiency, fCurrentESD, 0, fMultiplicityESDCorrected[correlationID]);
674 //____________________________________________________________________
675 void AliMultiplicityCorrection::DrawHistograms()
678 // draws the histograms of this class
683 TCanvas* canvas1 = new TCanvas("fMultiplicityESD", "fMultiplicityESD", 900, 600);
684 canvas1->Divide(3, 2);
685 for (Int_t i = 0; i < kESDHists; ++i)
688 fMultiplicityESD[i]->DrawCopy("COLZ");
689 printf("%d --> %f\n", i, (Float_t) fMultiplicityESD[i]->ProjectionY()->GetMean());
694 TCanvas* canvas2 = new TCanvas("fMultiplicityMC", "fMultiplicityMC", 900, 600);
695 canvas2->Divide(3, 2);
696 for (Int_t i = 0; i < kMCHists; ++i)
699 fMultiplicityVtx[i]->DrawCopy("COLZ");
700 printf("%d --> %f\n", i, fMultiplicityVtx[i]->ProjectionY()->GetMean());
703 TCanvas* canvas3 = new TCanvas("fCorrelation", "fCorrelation", 900, 900);
704 canvas3->Divide(3, 3);
705 for (Int_t i = 0; i < kCorrHists; ++i)
708 TH3* hist = dynamic_cast<TH3*> (fCorrelation[i]->Clone());
709 for (Int_t y=1; y<=hist->GetYaxis()->GetNbins(); ++y)
711 for (Int_t z=1; z<=hist->GetZaxis()->GetNbins(); ++z)
713 hist->SetBinContent(0, y, z, 0);
714 hist->SetBinContent(hist->GetXaxis()->GetNbins()+1, y, z, 0);
717 TH1* proj = hist->Project3D("zy");
718 proj->DrawCopy("COLZ");
722 //____________________________________________________________________
723 void AliMultiplicityCorrection::DrawComparison(const char* name, Int_t inputRange, Bool_t fullPhaseSpace, Bool_t /*normalizeESD*/, TH1* mcHist, Bool_t simple, EventType eventType)
725 // draw comparison plots
730 Int_t esdCorrId = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
733 tmpStr.Form("%s_DrawComparison_%d", name, esdCorrId);
735 if (fMultiplicityESDCorrected[esdCorrId]->Integral() == 0)
737 printf("ERROR. Unfolded histogram is empty\n");
741 //regain measured distribution used for unfolding, because the bins at high mult. were modified in SetupCurrentHists
742 fCurrentESD = fMultiplicityESD[esdCorrId]->ProjectionY("fCurrentESD", 1, fMultiplicityESD[inputRange]->GetXaxis()->GetNbins());
743 fCurrentESD->Sumw2();
744 fCurrentESD->Scale(1.0 / fCurrentESD->Integral());
746 // normalize unfolded result to 1
747 fMultiplicityESDCorrected[esdCorrId]->Scale(1.0 / fMultiplicityESDCorrected[esdCorrId]->Integral());
749 //fCurrentESD->Scale(mcHist->Integral(2, 200));
752 /*TH1* ratio = (TH1*) fMultiplicityESDCorrected[esdCorrId]->Clone("ratio");
753 ratio->Divide(mcHist);
755 ratio->Fit("pol0", "W0", "", 20, 120);
756 Float_t scalingFactor = ratio->GetFunction("pol0")->GetParameter(0);
758 mcHist->Scale(scalingFactor);*/
760 // find bin with <= 50 entries. this is used as limit for the chi2 calculation
761 Int_t mcBinLimit = 0;
762 for (Int_t i=20; i<mcHist->GetNbinsX(); ++i)
764 if (mcHist->GetBinContent(i) > 50)
771 Printf("AliMultiplicityCorrection::DrawComparison: MC bin limit is %d", mcBinLimit);
775 if (mcHist->Integral() > 0)
776 mcHist->Scale(1.0 / mcHist->Integral());
778 // calculate residual
780 // for that we convolute the response matrix with the gathered result
781 // if normalizeESD is not set, the histogram is already normalized, this needs to be passed to CalculateMultiplicityESD
782 TH1* tmpESDEfficiencyRecorrected = (TH1*) fMultiplicityESDCorrected[esdCorrId]->Clone("tmpESDEfficiencyRecorrected");
784 // undo trigger, vertex efficiency correction
785 fCurrentEfficiency = GetEfficiency(inputRange, eventType);
786 tmpESDEfficiencyRecorrected->Multiply(fCurrentEfficiency);
788 TH2* convoluted = CalculateMultiplicityESD(tmpESDEfficiencyRecorrected, esdCorrId);
789 TH1* convolutedProj = convoluted->ProjectionY("convolutedProj", -1, -1, "e");
790 if (convolutedProj->Integral() > 0)
792 convolutedProj->Scale(1.0 / convolutedProj->Integral());
795 printf("ERROR: convolutedProj is empty. Something went wrong calculating the convoluted histogram.\n");
797 TH1* residual = (TH1*) convolutedProj->Clone("residual");
798 residual->SetTitle("Residuals;Ntracks;(folded unfolded measured - measured) / e");
800 residual->Add(fCurrentESD, -1);
801 //residual->Divide(residual, fCurrentESD, 1, 1, "B");
803 TH1* residualHist = new TH1F("residualHist", "residualHist", 51, -5, 5);
807 for (Int_t i=1; i<=fCurrentESD->GetNbinsX(); ++i)
809 if (fCurrentESD->GetBinContent(i) <= 5)
818 for (Int_t i=1; i<=residual->GetNbinsX(); ++i)
820 if (fCurrentESD->GetBinError(i) > 0)
822 Float_t value = residual->GetBinContent(i) / fCurrentESD->GetBinError(i);
823 if (i > 1 && i <= lastBin)
824 chi2 += value * value;
825 Printf("%d --> %f (%f)", i, value * value, chi2);
826 residual->SetBinContent(i, value);
827 residualHist->Fill(value);
831 //printf("Residual bin %d set to 0\n", i);
832 residual->SetBinContent(i, 0);
834 convolutedProj->SetBinError(i, 0);
835 residual->SetBinError(i, 0);
837 fLastChi2Residuals = chi2;
839 new TCanvas; residualHist->DrawCopy();
841 //residualHist->Fit("gaus", "N");
842 //delete residualHist;
844 printf("Difference (Residuals) is %f for bin 2-%d\n", fLastChi2Residuals, lastBin);
846 TCanvas* canvas1 = 0;
849 canvas1 = new TCanvas(tmpStr, tmpStr, 1200, 600);
850 canvas1->Divide(2, 1);
854 canvas1 = new TCanvas(tmpStr, tmpStr, 1200, 1200);
855 canvas1->Divide(2, 3);
859 canvas1->cd(1)->SetGridx();
860 canvas1->cd(1)->SetGridy();
861 canvas1->cd(1)->SetTopMargin(0.05);
862 canvas1->cd(1)->SetRightMargin(0.05);
863 canvas1->cd(1)->SetLeftMargin(0.12);
864 canvas1->cd(1)->SetBottomMargin(0.12);
865 TH1* proj = (TH1*) mcHist->Clone("proj");
867 // normalize without 0 bin
868 proj->Scale(1.0 / proj->Integral(2, proj->GetNbinsX()));
869 Printf("Normalized without 0 bin!");
870 proj->GetXaxis()->SetRangeUser(0, 200);
871 proj->GetYaxis()->SetTitleOffset(1.4);
872 //proj->SetLabelSize(0.05, "xy");
873 //proj->SetTitleSize(0.05, "xy");
874 proj->SetTitle(Form(";True multiplicity in |#eta| < %.1f;Entries", (inputRange+1)*0.5));
875 proj->SetStats(kFALSE);
877 fMultiplicityESDCorrected[esdCorrId]->SetLineColor(2);
878 fMultiplicityESDCorrected[esdCorrId]->SetMarkerColor(2);
879 //fMultiplicityESDCorrected[esdCorrId]->SetMarkerStyle(5);
880 // normalize without 0 bin
881 fMultiplicityESDCorrected[esdCorrId]->Scale(1.0 / fMultiplicityESDCorrected[esdCorrId]->Integral(2, fMultiplicityESDCorrected[esdCorrId]->GetNbinsX()));
882 Printf("Normalized without 0 bin!");
884 if (proj->GetEntries() > 0) {
885 proj->DrawCopy("HIST");
886 fMultiplicityESDCorrected[esdCorrId]->DrawCopy("SAME HIST E");
889 fMultiplicityESDCorrected[esdCorrId]->DrawCopy("HIST E");
893 TLegend* legend = new TLegend(0.3, 0.8, 0.93, 0.93);
894 legend->AddEntry(proj, "True distribution");
895 legend->AddEntry(fMultiplicityESDCorrected[esdCorrId], "Unfolded distribution");
896 legend->SetFillColor(0);
897 legend->SetTextSize(0.04);
899 // unfortunately does not work. maybe a bug? --> legend->SetTextSizePixels(14);
902 canvas1->cd(2)->SetGridx();
903 canvas1->cd(2)->SetGridy();
904 canvas1->cd(2)->SetTopMargin(0.05);
905 canvas1->cd(2)->SetRightMargin(0.05);
906 canvas1->cd(2)->SetLeftMargin(0.12);
907 canvas1->cd(2)->SetBottomMargin(0.12);
910 fCurrentESD->GetXaxis()->SetRangeUser(0, 200);
911 //fCurrentESD->SetLineColor(2);
912 fCurrentESD->SetTitle(Form(";Measured multiplicity in |#eta| < %.1f;Entries", (inputRange+1)*0.5));
913 fCurrentESD->SetStats(kFALSE);
914 fCurrentESD->GetYaxis()->SetTitleOffset(1.4);
915 //fCurrentESD->SetLabelSize(0.05, "xy");
916 //fCurrentESD->SetTitleSize(0.05, "xy");
917 fCurrentESD->DrawCopy("HIST E");
919 convolutedProj->SetLineColor(2);
920 convolutedProj->SetMarkerColor(2);
921 convolutedProj->SetMarkerStyle(5);
922 //proj2->SetMarkerColor(2);
923 //proj2->SetMarkerStyle(5);
924 convolutedProj->DrawCopy("HIST SAME P");
926 legend = new TLegend(0.3, 0.8, 0.93, 0.93);
927 legend->AddEntry(fCurrentESD, "Measured distribution");
928 legend->AddEntry(convolutedProj, "R #otimes unfolded distribution", "P");
929 legend->SetFillColor(0);
930 legend->SetTextSize(0.04);
933 //TH1* diffMCUnfolded = dynamic_cast<TH1*> (proj->Clone("diffMCUnfolded"));
934 //diffMCUnfolded->Add(fMultiplicityESDCorrected[esdCorrId], -1);
938 fLastChi2MCLimit = 0;
940 for (Int_t i=2; i<=200; ++i)
942 if (proj->GetBinContent(i) != 0)
944 Float_t value = (proj->GetBinContent(i) - fMultiplicityESDCorrected[esdCorrId]->GetBinContent(i)) / proj->GetBinContent(i);
945 chi2 += value * value;
946 chi += TMath::Abs(value);
948 //printf("%d %f\n", i, chi);
951 fLastChi2MCLimit = i;
962 for (Int_t i=1; i<=diffMCUnfolded->GetNbinsX(); ++i)
964 if (fMultiplicityESDCorrected[esdCorrId]->GetBinError(i) > 0)
966 Double_t value = diffMCUnfolded->GetBinContent(i) / fMultiplicityESDCorrected[esdCorrId]->GetBinError(i);
968 value = 1e8; //prevent arithmetic exception
969 else if (value < -1e8)
973 chi2 += value * value;
974 chi += TMath::Abs(value);
976 diffMCUnfolded->SetBinContent(i, value);
980 //printf("diffMCUnfolded bin %d set to 0\n", i);
981 diffMCUnfolded->SetBinContent(i, 0);
984 fLastChi2MCLimit = i;
991 printf("limits %d %d\n", fLastChi2MCLimit, limit);
992 fLastChi2MCLimit = limit;
994 printf("Difference (from MC) is %f for bin 2-150. Limit is %d.\n", fLastChi2MC, fLastChi2MCLimit);*/
1000 diffMCUnfolded->SetTitle("#chi^{2};Npart;(MC - Unfolded) / e(unfolded)");
1001 //diffMCUnfolded->GetYaxis()->SetRangeUser(-20, 20);
1002 diffMCUnfolded->GetXaxis()->SetRangeUser(0, 200);
1003 diffMCUnfolded->DrawCopy("HIST");
1005 TH1F* fluctuation = new TH1F("fluctuation", "fluctuation", 20, -5, 5);
1006 for (Int_t i=20; i<=diffMCUnfolded->GetNbinsX(); ++i)
1007 fluctuation->Fill(diffMCUnfolded->GetBinContent(i));
1009 //new TCanvas; fluctuation->DrawCopy();
1010 delete fluctuation;*/
1012 /*TLegend* legend = new TLegend(0.6, 0.7, 0.85, 0.85);
1013 legend->AddEntry(fMultiplicityESDCorrected, "ESD corrected");
1014 legend->AddEntry(fMultiplicityMC, "MC");
1015 legend->AddEntry(fMultiplicityESD, "ESD");
1019 residual->GetYaxis()->SetRangeUser(-5, 5);
1020 residual->GetXaxis()->SetRangeUser(0, 200);
1021 residual->DrawCopy();
1025 TH1* ratio = (TH1*) fMultiplicityESDCorrected[esdCorrId]->Clone("ratio");
1026 ratio->Divide(mcHist);
1027 ratio->SetTitle("Ratio;true multiplicity;Unfolded / MC");
1028 ratio->GetYaxis()->SetRangeUser(0.5, 1.5);
1029 ratio->GetXaxis()->SetRangeUser(0, 200);
1030 ratio->SetStats(kFALSE);
1031 ratio->Draw("HIST");
1033 Double_t ratioChi2 = 0;
1035 fLastChi2MCLimit = 0;
1036 for (Int_t i=2; i<=150; ++i)
1038 Float_t value = ratio->GetBinContent(i) - 1;
1040 value = 1e8; //prevent arithmetic exception
1041 else if (value < -1e8)
1044 ratioChi2 += value * value;
1045 fRatioAverage += TMath::Abs(value);
1047 if (ratioChi2 < 0.1)
1048 fLastChi2MCLimit = i;
1050 fRatioAverage /= 149;
1052 printf("Sum over (ratio-1)^2 (2..150) is %f; average of |ratio-1| is %f\n", ratioChi2, fRatioAverage);
1054 fLastChi2MC = ratioChi2;
1058 const Int_t kFFT = 128;
1059 Double_t fftReal[kFFT];
1060 Double_t fftImag[kFFT];
1062 for (Int_t i=0; i<kFFT; ++i)
1064 fftReal[i] = ratio->GetBinContent(i+1+10);
1066 //fftReal[i] = cos(TMath::Pi() * 5 * 2 * i / 128);
1070 FFT(-1, TMath::Nint(TMath::Log(kFFT) / TMath::Log(2)), fftReal, fftImag);
1072 TH1* fftResult = (TH1*) ratio->Clone("fftResult");
1073 fftResult->SetTitle("FFT;true multiplicity;coeff. (10...137)");
1074 TH1* fftResult2 = (TH1*) ratio->Clone("fftResult2");
1075 TH1* fftResult3 = (TH1*) ratio->Clone("fftResult3");
1077 fftResult2->Reset();
1078 fftResult3->Reset();
1079 fftResult->GetYaxis()->UnZoom();
1080 fftResult2->GetYaxis()->UnZoom();
1081 fftResult3->GetYaxis()->UnZoom();
1083 //Printf("AFTER FFT");
1084 for (Int_t i=0; i<kFFT; ++i)
1086 //Printf("%d: %f", i, fftReal[i]);
1087 fftResult->SetBinContent(i+1, fftReal[i]);
1088 /*if (i != 0 && TMath::Abs(fftReal[i]) > 0.5)
1090 Printf("Nulled %d", i);
1095 fftResult->SetLineColor(1);
1096 fftResult->DrawCopy();
1100 for (Int_t i=0; i<kFFT; ++i)
1102 //Printf("%d: %f", i, fftImag[i]);
1103 fftResult2->SetBinContent(i+1, fftImag[i]);
1105 fftResult3->SetBinContent(i+1, TMath::Sqrt(fftReal[i] * fftReal[i] + fftImag[i] * fftImag[i]));
1108 fftResult2->SetLineColor(2);
1109 fftResult2->DrawCopy("SAME");
1111 fftResult3->SetLineColor(4);
1112 fftResult3->DrawCopy("SAME");
1114 for (Int_t i=1; i<kFFT - 1; ++i)
1116 if (TMath::Sqrt(fftReal[i] * fftReal[i] + fftImag[i] * fftImag[i]) > 3)
1124 //fftReal[i] = (fftReal[i-1] + fftReal[i+1]) / 2;
1125 //fftImag[i] = (fftImag[i-1] + fftImag[i+1]) / 2;
1126 //Printf("Nulled %d to %f %f", i, fftReal[i], fftImag[i]);
1130 FFT(1, TMath::Nint(TMath::Log(kFFT) / TMath::Log(2)), fftReal, fftImag);
1132 TH1* fftResult4 = (TH1*) fftResult3->Clone("fftResult4");
1133 fftResult4->Reset();
1135 //Printf("AFTER BACK-TRAFO");
1136 for (Int_t i=0; i<kFFT; ++i)
1138 //Printf("%d: %f", i, fftReal[i]);
1139 fftResult4->SetBinContent(i+1+10, fftReal[i]);
1143 fftResult4->SetLineColor(4);
1144 fftResult4->DrawCopy("SAME");
1146 // plot (MC - Unfolded) / error (MC)
1149 TH1* diffMCUnfolded2 = dynamic_cast<TH1*> (proj->Clone("diffMCUnfolded2"));
1150 diffMCUnfolded2->Add(fMultiplicityESDCorrected[esdCorrId], -1);
1152 Int_t ndfQual[kQualityRegions];
1153 for (Int_t region=0; region<kQualityRegions; ++region)
1155 fQuality[region] = 0;
1156 ndfQual[region] = 0;
1160 Double_t newChi2 = 0;
1161 Double_t newChi2Limit150 = 0;
1163 for (Int_t i=1; i<=diffMCUnfolded2->GetNbinsX(); ++i)
1166 if (proj->GetBinError(i) > 0)
1168 value = diffMCUnfolded2->GetBinContent(i) / proj->GetBinError(i);
1169 newChi2 += value * value;
1170 if (i > 1 && i <= mcBinLimit)
1171 newChi2Limit150 += value * value;
1174 for (Int_t region=0; region<kQualityRegions; ++region)
1175 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
1177 fQuality[region] += TMath::Abs(value);
1182 diffMCUnfolded2->SetBinContent(i, value);
1185 // normalize region to the number of entries
1186 for (Int_t region=0; region<kQualityRegions; ++region)
1188 if (ndfQual[region] > 0)
1189 fQuality[region] /= ndfQual[region];
1190 Printf("Quality parameter %d (%d <= mult <= %d) is %f with %d df", region, fgQualityRegionsB[region], fgQualityRegionsE[region], fQuality[region], ndfQual[region]);
1195 // TODO another FAKE
1196 fLastChi2MC = newChi2Limit150 / (mcBinLimit - 1);
1197 Printf("Chi2 (2..%d) from (MC - Unfolded) / e(MC) is: %.2f ndf is %d --> chi2 / ndf = %.2f", mcBinLimit, newChi2Limit150, mcBinLimit - 1, fLastChi2MC);
1202 Printf("Chi2 (full range) from (MC - Unfolded) / e(MC) is: %.2f ndf is %d --> chi2 / ndf = %.2f", newChi2, ndf, ((ndf > 0) ? newChi2 / ndf : -1));
1204 diffMCUnfolded2->SetTitle("#chi^{2};Npart;(MC - Unfolded) / e(MC)");
1205 diffMCUnfolded2->GetYaxis()->SetRangeUser(-5, 5);
1206 diffMCUnfolded2->GetXaxis()->SetRangeUser(0, 200);
1207 diffMCUnfolded2->DrawCopy("HIST");
1210 canvas1->SaveAs(Form("%s.gif", canvas1->GetName()));
1213 //____________________________________________________________________
1214 void AliMultiplicityCorrection::FFT(Int_t dir, Int_t m, Double_t *x, Double_t *y)
1216 /*-------------------------------------------------------------------------
1217 This computes an in-place complex-to-complex FFT
1218 x and y are the real and imaginary arrays of 2^m points.
1219 dir = 1 gives forward transform
1220 dir = -1 gives reverse transform
1225 1 \ - j k 2 pi n / N
1226 X(n) = --- > x(k) e = forward transform
1235 X(n) = > x(k) e = forward transform
1241 Long_t nn, i, i1, j, k, i2, l, l1, l2;
1242 Double_t c1, c2, tx, ty, t1, t2, u1, u2, z;
1244 /* Calculate the number of points */
1246 for (i = 0; i < m; i++)
1249 /* Do the bit reversal */
1252 for (i= 0; i < nn - 1; i++) {
1269 /* Compute the FFT */
1273 for (l = 0; l < m; l++) {
1278 for (j = 0;j < l1; j++) {
1279 for (i = j; i < nn; i += l2) {
1281 t1 = u1 * x[i1] - u2 * y[i1];
1282 t2 = u1 * y[i1] + u2 * x[i1];
1288 z = u1 * c1 - u2 * c2;
1289 u2 = u1 * c2 + u2 * c1;
1292 c2 = TMath::Sqrt((1.0 - c1) / 2.0);
1295 c1 = TMath::Sqrt((1.0 + c1) / 2.0);
1298 /* Scaling for forward transform */
1300 for (i=0;i<nn;i++) {
1301 x[i] /= (Double_t)nn;
1302 y[i] /= (Double_t)nn;
1307 //____________________________________________________________________
1308 void AliMultiplicityCorrection::GetComparisonResults(Float_t* mc, Int_t* mcLimit, Float_t* residuals, Float_t* ratioAverage) const
1310 // Returns the chi2 between the MC and the unfolded ESD as well as between the ESD and the folded unfolded ESD
1311 // These values are computed during DrawComparison, thus this function picks up the
1317 *mcLimit = fLastChi2MCLimit;
1319 *residuals = fLastChi2Residuals;
1321 *ratioAverage = fRatioAverage;
1324 //____________________________________________________________________
1325 TH2F* AliMultiplicityCorrection::GetMultiplicityMC(Int_t i, EventType eventType)
1328 // returns the corresponding MC spectrum
1333 case kTrVtx : return fMultiplicityVtx[i]; break;
1334 case kMB : return fMultiplicityMB[i]; break;
1335 case kINEL : return fMultiplicityINEL[i]; break;
1336 case kNSD : return fMultiplicityNSD[i]; break;
1342 //____________________________________________________________________
1343 void AliMultiplicityCorrection::SetMultiplicityMC(Int_t i, EventType eventType, TH2F* hist)
1346 // returns the corresponding MC spectrum
1351 case kTrVtx : fMultiplicityVtx[i] = hist; break;
1352 case kMB : fMultiplicityMB[i] = hist; break;
1353 case kINEL : fMultiplicityINEL[i] = hist; break;
1354 case kNSD : fMultiplicityNSD[i] = hist; break;
1358 //____________________________________________________________________
1359 TH1* AliMultiplicityCorrection::CalculateStdDev(TH1** results, Int_t max)
1361 // calculate standard deviation of (results[0] - results[k]) k=1...max-1
1362 // per bin one gets: sigma(r[0] - r[n]) / r[0]
1364 TH1* standardDeviation = (TH1*) results[0]->Clone("standardDeviation");
1365 standardDeviation->Reset();
1367 for (Int_t x=1; x<=results[0]->GetNbinsX(); x++)
1369 if (results[0]->GetBinContent(x) > 0)
1371 Double_t average = 0;
1372 for (Int_t n=1; n<max; ++n)
1373 average += results[n]->GetBinContent(x) - results[0]->GetBinContent(x);
1376 Double_t variance = 0;
1377 for (Int_t n=1; n<max; ++n)
1379 Double_t value = results[n]->GetBinContent(x) - results[0]->GetBinContent(x) - average;
1380 variance += value * value;
1384 Double_t standardDev = TMath::Sqrt(variance);
1385 standardDeviation->SetBinContent(x, standardDev / results[0]->GetBinContent(x));
1386 //Printf("sigma_%d is %f value %f --> error %f", x, standardDev, results[0]->GetBinContent(x), standardDev / results[0]->GetBinContent(x));
1390 return standardDeviation;
1393 //____________________________________________________________________
1394 TH1* AliMultiplicityCorrection::StatisticalUncertainty(AliUnfolding::MethodType methodType, Int_t inputRange, Bool_t fullPhaseSpace, EventType eventType, Bool_t randomizeMeasured, Bool_t randomizeResponse, TH1* compareTo)
1397 // evaluates the uncertainty that arises from the non-infinite statistics in the response matrix
1398 // the function unfolds the spectrum using the default response matrix and several modified ones
1399 // the modified ones are created by randomizing each cell using poisson statistics with the mean = bin value
1400 // these unfolded results are compared to the first result gained with the default response OR to the histogram given
1401 // in <compareTo> (optional)
1403 // returns the error assigned to the measurement
1406 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
1408 // initialize seed with current time
1409 gRandom->SetSeed(0);
1411 if (methodType == AliUnfolding::kChi2Minimization)
1412 AliUnfolding::SetCreateOverflowBin(5);
1413 AliUnfolding::SetUnfoldingMethod(methodType);
1415 const Int_t kErrorIterations = 150;
1418 TH1* firstResult = 0;
1420 TH1** results = new TH1*[kErrorIterations];
1422 for (Int_t n=0; n<kErrorIterations; ++n)
1424 Printf("Iteration %d of %d...", n, kErrorIterations);
1426 SetupCurrentHists(inputRange, fullPhaseSpace, eventType);
1428 TH1* measured = (TH1*) fCurrentESD->Clone("measured");
1432 if (randomizeResponse)
1434 // randomize response matrix
1435 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
1436 for (Int_t j=1; j<=fCurrentCorrelation->GetNbinsY(); ++j)
1437 fCurrentCorrelation->SetBinContent(i, j, gRandom->Poisson(fCurrentCorrelation->GetBinContent(i, j)));
1440 if (randomizeMeasured)
1442 // randomize measured spectrum
1443 for (Int_t x=1; x<=measured->GetNbinsX(); x++) // mult. axis
1445 Int_t randomValue = gRandom->Poisson(fCurrentESD->GetBinContent(x));
1446 measured->SetBinContent(x, randomValue);
1447 measured->SetBinError(x, TMath::Sqrt(randomValue));
1452 // only for bayesian method we have to do it before the call to Unfold...
1453 if (methodType == AliUnfolding::kBayesian)
1455 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
1457 // with this it is normalized to 1
1458 Double_t sum = fCurrentCorrelation->Integral(i, i, 1, fCurrentCorrelation->GetNbinsY());
1460 // with this normalized to the given efficiency
1461 if (fCurrentEfficiency->GetBinContent(i) > 0)
1462 sum /= fCurrentEfficiency->GetBinContent(i);
1466 for (Int_t j=1; j<=fCurrentCorrelation->GetNbinsY(); ++j)
1470 fCurrentCorrelation->SetBinContent(i, j, fCurrentCorrelation->GetBinContent(i, j) / sum);
1471 fCurrentCorrelation->SetBinError(i, j, fCurrentCorrelation->GetBinError(i, j) / sum);
1475 fCurrentCorrelation->SetBinContent(i, j, 0);
1476 fCurrentCorrelation->SetBinError(i, j, 0);
1483 if (n == 0 && compareTo)
1485 // in this case we just store the histogram we want to compare to
1486 result = (TH1*) compareTo->Clone("compareTo");
1491 result = (TH1*) fMultiplicityESDCorrected[correlationID]->Clone(Form("result_%d", n));
1493 Int_t returnCode = AliUnfolding::Unfold(fCurrentCorrelation, fCurrentEfficiency, measured, 0, result);
1495 if (returnCode != 0)
1500 result->Scale(1.0 / result->Integral());
1504 firstResult = (TH1*) result->Clone("firstResult");
1506 maxError = (TH1*) result->Clone("maxError");
1512 TH1* ratio = (TH1*) firstResult->Clone("ratio");
1513 ratio->Divide(result);
1515 // find max. deviation
1516 for (Int_t x=1; x<=ratio->GetNbinsX(); x++)
1517 maxError->SetBinContent(x, TMath::Max(maxError->GetBinContent(x), TMath::Abs(1 - ratio->GetBinContent(x))));
1522 results[n] = result;
1525 // find covariance matrix
1526 // results[n] is X_x
1527 // cov. matrix is M_xy = E ( (X_x - E(X_x)) * (X_y - E(X_y))), with E() = expectation value
1529 Int_t nBins = results[0]->GetNbinsX();
1530 Float_t lowEdge = results[0]->GetXaxis()->GetBinLowEdge(1);
1531 Float_t upEdge = results[0]->GetXaxis()->GetBinUpEdge(nBins);
1533 // find average, E(X)
1534 TProfile* average = new TProfile("average", "average", nBins, lowEdge, upEdge);
1535 for (Int_t n=1; n<kErrorIterations; ++n)
1536 for (Int_t x=1; x<=results[n]->GetNbinsX(); x++)
1537 average->Fill(results[n]->GetXaxis()->GetBinCenter(x), results[n]->GetBinContent(x));
1538 //new TCanvas; average->DrawClone();
1541 TProfile2D* covMatrix = new TProfile2D("covMatrix", "covMatrix", nBins, lowEdge, upEdge, nBins, lowEdge, upEdge);
1543 for (Int_t n=1; n<kErrorIterations; ++n)
1544 for (Int_t x=1; x<=results[n]->GetNbinsX(); x++)
1545 for (Int_t y=1; y<=results[n]->GetNbinsX(); y++)
1547 // (X_x - E(X_x)) * (X_y - E(X_y)
1548 Float_t cov = (results[n]->GetBinContent(x) - average->GetBinContent(x)) * (results[n]->GetBinContent(y) - average->GetBinContent(y));
1549 covMatrix->Fill(results[n]->GetXaxis()->GetBinCenter(x), results[n]->GetXaxis()->GetBinCenter(y), cov);
1551 TCanvas* c = new TCanvas; c->cd(); covMatrix->DrawCopy("COLZ");
1553 // // fill 2D histogram that contains deviation from first
1554 // TH2F* deviations = new TH2F("deviations", "deviations", nBins, lowEdge, upEdge, 1000, -0.01, 0.01);
1555 // for (Int_t n=1; n<kErrorIterations; ++n)
1556 // for (Int_t x=1; x<=results[n]->GetNbinsX(); x++)
1557 // deviations->Fill(results[n]->GetXaxis()->GetBinCenter(x), results[n]->GetBinContent(x) - results[0]->GetBinContent(x));
1558 // //new TCanvas; deviations->DrawCopy("COLZ");
1560 // // get standard deviation "by hand"
1561 // for (Int_t x=1; x<=nBins; x++)
1563 // if (results[0]->GetBinContent(x) > 0)
1565 // TH1* proj = deviations->ProjectionY("projRMS", x, x, "e");
1566 // Float_t standardDev = proj->GetRMS(); // this is standard deviation in fact
1567 // //standardDeviation->SetBinContent(x, standardDev / results[0]->GetBinContent(x));
1568 // Printf("sigma_%d is %f value %f --> error %f", x, standardDev, results[0]->GetBinContent(x), standardDev / results[0]->GetBinContent(x));
1572 TH1* standardDeviation = CalculateStdDev(results, kErrorIterations);
1574 // compare maxError to RMS of profile (variable name: average)
1575 // first: calculate rms in percent of value
1576 TH1* rmsError = (TH1*) maxError->Clone("rmsError");
1579 // enable error to be standard deviation (see http://root.cern.ch/root/html/TProfile.html#TProfile:SetErrorOption)
1580 average->SetErrorOption("s");
1581 for (Int_t x=1; x<=rmsError->GetNbinsX(); x++)
1582 if (average->GetBinContent(x) > 0)
1583 rmsError->SetBinContent(x, average->GetBinError(x) / average->GetBinContent(x));
1585 // find maxError deviation from average (not from "first result"/mc as above)
1586 TH1* maxError2 = (TH1*) maxError->Clone("maxError2");
1588 for (Int_t n=1; n<kErrorIterations; ++n)
1589 for (Int_t x=1; x<=results[n]->GetNbinsX(); x++)
1590 if (average->GetBinContent(x) > 0)
1591 maxError2->SetBinContent(x, TMath::Max(maxError2->GetBinContent(x), TMath::Abs((results[n]->GetBinContent(x) - average->GetBinContent(x)) / average->GetBinContent(x))));
1593 //new TCanvas; maxError2->DrawCopy(); rmsError->SetLineColor(2); rmsError->DrawCopy("SAME"); standardDeviation->SetLineColor(3); standardDeviation->DrawCopy("SAME");
1595 // plot difference between average and MC/first result
1596 TH1* averageFirstRatio = (TH1*) results[0]->Clone("averageFirstRatio");
1597 averageFirstRatio->Reset();
1598 averageFirstRatio->Divide(results[0], average);
1600 //new TCanvas; results[0]->DrawCopy(); average->SetLineColor(2); average->DrawClone("SAME");
1601 //new TCanvas; averageFirstRatio->DrawCopy();
1603 static TH1* temp = 0;
1606 temp = (TH1*) standardDeviation->Clone("temp");
1607 for (Int_t x=1; x<=results[0]->GetNbinsX(); x++)
1608 temp->SetBinContent(x, temp->GetBinContent(x) * results[0]->GetBinContent(x));
1612 // find difference from result[0] as TH2
1613 TH2F* pulls = new TH2F("pulls", "pulls;multiplicity;difference", nBins, lowEdge, upEdge, 1000, -10, 10);
1614 for (Int_t n=1; n<kErrorIterations; ++n)
1615 for (Int_t x=1; x<=results[n]->GetNbinsX(); x++)
1616 if (temp->GetBinContent(x) > 0)
1617 pulls->Fill(results[n]->GetXaxis()->GetBinCenter(x), (results[0]->GetBinContent(x) - results[n]->GetBinContent(x)) / temp->GetBinContent(x));
1618 new TCanvas("pulls", "pulls", 800, 600); pulls->DrawCopy(); pulls->FitSlicesY();
1622 for (Int_t n=0; n<kErrorIterations; ++n)
1626 // fill into result histogram
1627 for (Int_t i=1; i<=fMultiplicityESDCorrected[correlationID]->GetNbinsX(); ++i)
1628 fMultiplicityESDCorrected[correlationID]->SetBinContent(i, firstResult->GetBinContent(i));
1630 for (Int_t i=1; i<=fMultiplicityESDCorrected[correlationID]->GetNbinsX(); ++i)
1631 fMultiplicityESDCorrected[correlationID]->SetBinError(i, maxError->GetBinContent(i) * fMultiplicityESDCorrected[correlationID]->GetBinContent(i));
1633 return standardDeviation;
1636 //____________________________________________________________________
1637 void AliMultiplicityCorrection::ApplyBayesianMethod(Int_t inputRange, Bool_t fullPhaseSpace, EventType eventType, Float_t regPar, Int_t nIterations, TH1* initialConditions, Bool_t determineError)
1640 // correct spectrum using bayesian method
1643 // initialize seed with current time
1644 gRandom->SetSeed(0);
1646 SetupCurrentHists(inputRange, fullPhaseSpace, eventType);
1648 // normalize correction for given nPart
1649 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
1651 // with this it is normalized to 1
1652 Double_t sum = fCurrentCorrelation->Integral(i, i, 1, fCurrentCorrelation->GetNbinsY());
1654 // with this normalized to the given efficiency
1655 if (fCurrentEfficiency->GetBinContent(i) > 0)
1656 sum /= fCurrentEfficiency->GetBinContent(i);
1660 for (Int_t j=1; j<=fCurrentCorrelation->GetNbinsY(); ++j)
1664 fCurrentCorrelation->SetBinContent(i, j, fCurrentCorrelation->GetBinContent(i, j) / sum);
1665 fCurrentCorrelation->SetBinError(i, j, fCurrentCorrelation->GetBinError(i, j) / sum);
1669 fCurrentCorrelation->SetBinContent(i, j, 0);
1670 fCurrentCorrelation->SetBinError(i, j, 0);
1675 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
1677 AliUnfolding::SetBayesianParameters(regPar, nIterations);
1678 AliUnfolding::SetUnfoldingMethod(AliUnfolding::kBayesian);
1679 if (AliUnfolding::Unfold(fCurrentCorrelation, fCurrentEfficiency, fCurrentESD, initialConditions, fMultiplicityESDCorrected[correlationID]) != 0)
1682 if (!determineError)
1684 Printf("AliMultiplicityCorrection::ApplyBayesianMethod: WARNING: No errors calculated.");
1688 // evaluate errors, this is done by randomizing the measured spectrum following Poission statistics
1689 // this (new) measured spectrum is then unfolded and the different to the result from the "real" measured
1690 // spectrum calculated. This is performed N times and the sigma is taken as the statistical
1691 // error of the unfolding method itself.
1693 const Int_t kErrorIterations = 20;
1695 printf("Spectrum unfolded. Determining error (%d iterations)...\n", kErrorIterations);
1697 TH1* randomized = (TH1*) fCurrentESD->Clone("randomized");
1698 TH1* resultArray[kErrorIterations+1];
1699 for (Int_t n=0; n<kErrorIterations; ++n)
1701 // randomize the content of clone following a poisson with the mean = the value of that bin
1702 for (Int_t x=1; x<=randomized->GetNbinsX(); x++) // mult. axis
1704 Int_t randomValue = gRandom->Poisson(fCurrentESD->GetBinContent(x));
1705 //printf("%d --> %d\n", fCurrentESD->GetBinContent(x), randomValue);
1706 randomized->SetBinContent(x, randomValue);
1707 randomized->SetBinError(x, TMath::Sqrt(randomValue));
1710 TH1* result2 = (TH1*) fMultiplicityESDCorrected[correlationID]->Clone("result2");
1712 if (AliUnfolding::Unfold(fCurrentCorrelation, fCurrentEfficiency, randomized, initialConditions, result2) != 0)
1715 result2->Scale(1.0 / result2->Integral());
1717 resultArray[n+1] = result2;
1721 resultArray[0] = fMultiplicityESDCorrected[correlationID];
1722 TH1* error = CalculateStdDev(resultArray, kErrorIterations+1);
1724 for (Int_t n=0; n<kErrorIterations; ++n)
1725 delete resultArray[n+1];
1727 for (Int_t i=1; i<=fMultiplicityESDCorrected[correlationID]->GetNbinsX(); ++i)
1728 fMultiplicityESDCorrected[correlationID]->SetBinError(i, error->GetBinContent(i) * fMultiplicityESDCorrected[correlationID]->GetBinContent(i));
1733 //____________________________________________________________________
1734 Float_t AliMultiplicityCorrection::BayesCovarianceDerivate(Float_t matrixM[251][251], TH2* hResponse, Int_t k, Int_t i, Int_t r, Int_t u)
1737 // helper function for the covariance matrix of the bayesian method
1742 if (k == u && r == i)
1743 result += 1.0 / hResponse->GetBinContent(u+1, r+1);
1746 result -= 1.0 / fCurrentEfficiency->GetBinContent(u+1);
1749 result -= matrixM[u][i] * fCurrentEfficiency->GetBinContent(u+1) / hResponse->GetBinContent(u+1, i+1);
1751 result *= matrixM[k][i];
1756 //____________________________________________________________________
1757 void AliMultiplicityCorrection::ApplyLaszloMethod(Int_t inputRange, Bool_t fullPhaseSpace, EventType eventType)
1760 // correct spectrum using bayesian method
1765 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
1766 Int_t mcTarget = ((fullPhaseSpace == kFALSE) ? inputRange : 4);
1768 SetupCurrentHists(inputRange, fullPhaseSpace, eventType);
1770 fCurrentESD->Scale(1.0 / fCurrentESD->Integral());
1772 // TODO should be taken from correlation map
1773 //TH1* sumHist = GetMultiplicityMC(inputRange, eventType)->ProjectionY("sumHist", 1, GetMultiplicityMC(inputRange, eventType)->GetNbinsX());
1775 // normalize correction for given nPart
1776 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
1778 Double_t sum = fCurrentCorrelation->Integral(i, i, 1, fCurrentCorrelation->GetNbinsY());
1779 //Double_t sum = sumHist->GetBinContent(i);
1782 for (Int_t j=1; j<=fCurrentCorrelation->GetNbinsY(); ++j)
1785 fCurrentCorrelation->SetBinContent(i, j, fCurrentCorrelation->GetBinContent(i, j) / sum);
1786 fCurrentCorrelation->SetBinError(i, j, fCurrentCorrelation->GetBinError(i, j) / sum);
1791 fCurrentCorrelation->Draw("COLZ");
1794 fCurrentEfficiency = ((TH2*) fCurrentCorrelation)->ProjectionX("eff");
1796 // pick prior distribution
1797 TH1F* hPrior = (TH1F*)fCurrentESD->Clone("prior");
1798 Float_t norm = 1; //hPrior->Integral();
1799 for (Int_t t=1; t<=hPrior->GetNbinsX(); t++)
1800 hPrior->SetBinContent(t, hPrior->GetBinContent(t)/norm);
1802 // zero distribution
1803 TH1F* zero = (TH1F*)hPrior->Clone("zero");
1806 TH1F* hTemp = (TH1F*)fCurrentESD->Clone("temp");
1810 TH2F* hResponse = (TH2F*) fCurrentCorrelation;
1813 Int_t iterations = 25;
1814 for (Int_t i=0; i<iterations; i++)
1816 //printf(" iteration %i \n", i);
1818 for (Int_t m=1; m<=hResponse->GetNbinsY(); m++)
1821 for (Int_t t = 1; t<=hResponse->GetNbinsX(); t++)
1822 value += hResponse->GetBinContent(t, m) * hPrior->GetBinContent(t);
1823 hTemp->SetBinContent(m, value);
1824 //printf("%d %f %f %f\n", m, zero->GetBinContent(m), hPrior->GetBinContent(m), value);
1827 // regularization (simple smoothing)
1828 TH1F* hTrueSmoothed = (TH1F*) hTemp->Clone("truesmoothed");
1830 for (Int_t t=2; t<hTrueSmoothed->GetNbinsX(); t++)
1832 Float_t average = (hTemp->GetBinContent(t-1) / hTemp->GetBinWidth(t-1)
1833 + hTemp->GetBinContent(t) / hTemp->GetBinWidth(t)
1834 + hTemp->GetBinContent(t+1) / hTemp->GetBinWidth(t+1)) / 3.;
1835 average *= hTrueSmoothed->GetBinWidth(t);
1837 // weight the average with the regularization parameter
1838 hTrueSmoothed->SetBinContent(t, (1-regPar) * hTemp->GetBinContent(t) + regPar * average);
1841 for (Int_t m=1; m<=hResponse->GetNbinsY(); m++)
1842 hTemp->SetBinContent(m, zero->GetBinContent(m) + hPrior->GetBinContent(m) - hTrueSmoothed->GetBinContent(m));
1845 for (Int_t t=1; t<=fMultiplicityESDCorrected[correlationID]->GetNbinsX(); t++)
1847 fMultiplicityESDCorrected[correlationID]->SetBinContent(t, hTemp->GetBinContent(t));
1848 fMultiplicityESDCorrected[correlationID]->SetBinError(t, 0.05 * hTemp->GetBinContent(t)); // TODO
1850 //printf(" bin %d content %f \n", t, fMultiplicityESDCorrected[correlationID]->GetBinContent(t));
1854 // calculate chi2 (change from last iteration)
1857 // use smoothed true (normalized) as new prior
1858 norm = 1; //hTrueSmoothed->Integral();
1860 for (Int_t t=1; t<hTrueSmoothed->GetNbinsX(); t++)
1862 Float_t newValue = hTemp->GetBinContent(t)/norm;
1863 Float_t diff = hPrior->GetBinContent(t) - newValue;
1864 chi2 += (Double_t) diff * diff;
1866 hPrior->SetBinContent(t, newValue);
1869 printf("Chi2 of %d iteration = %.10f\n", i, chi2);
1872 DrawComparison(Form("Laszlo_%d", i), inputRange, fullPhaseSpace, kTRUE, GetMultiplicityMC(mcTarget, eventType)->ProjectionY());
1874 delete hTrueSmoothed;
1875 } // end of iterations
1877 DrawComparison("Laszlo", inputRange, fullPhaseSpace, kTRUE, GetMultiplicityMC(mcTarget, eventType)->ProjectionY());
1880 //____________________________________________________________________
1881 void AliMultiplicityCorrection::ApplyGaussianMethod(Int_t inputRange, Bool_t fullPhaseSpace)
1884 // correct spectrum using a simple Gaussian approach, that is model-dependent
1887 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
1888 Int_t mcTarget = ((fullPhaseSpace == kFALSE) ? inputRange : 4);
1890 SetupCurrentHists(inputRange, fullPhaseSpace, kTrVtx);
1892 fCurrentESD->Scale(1.0 / fCurrentESD->Integral());
1894 TH1D* correction = dynamic_cast<TH1D*> (fCurrentESD->Clone("GaussianMean"));
1895 correction->SetTitle("GaussianMean");
1897 TH1D* correctionWidth = dynamic_cast<TH1D*> (fCurrentESD->Clone("GaussianWidth"));
1898 correction->SetTitle("GaussianWidth");
1900 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
1902 TH1D* proj = (dynamic_cast<TH2*> (fCurrentCorrelation))->ProjectionX("_px", i, i+1);
1903 proj->Fit("gaus", "0Q");
1904 correction->SetBinContent(i, proj->GetFunction("gaus")->GetParameter(1));
1905 correctionWidth->SetBinContent(i, proj->GetFunction("gaus")->GetParameter(2));
1909 // draw for debugging
1912 proj->GetFunction("gaus")->DrawCopy("SAME");
1915 TH1* target = fMultiplicityESDCorrected[correlationID];
1917 Int_t nBins = target->GetNbinsX()*10+1;
1918 Float_t* binning = new Float_t[nBins];
1919 for (Int_t i=1; i<=target->GetNbinsX(); ++i)
1920 for (Int_t j=0; j<10; ++j)
1921 binning[(i-1)*10 + j] = target->GetXaxis()->GetBinLowEdge(i) + target->GetXaxis()->GetBinWidth(i) / 10 * j;
1923 binning[nBins-1] = target->GetXaxis()->GetBinUpEdge(target->GetNbinsX());
1925 TH1F* fineBinned = new TH1F("targetFineBinned", "targetFineBinned", nBins-1, binning);
1927 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
1929 Float_t mean = correction->GetBinContent(i);
1930 Float_t width = correctionWidth->GetBinContent(i);
1932 Int_t fillBegin = fineBinned->FindBin(mean - width * 5);
1933 Int_t fillEnd = fineBinned->FindBin(mean + width * 5);
1934 //printf("bin %d mean %f width %f, filling from %d to %d\n", i, mean, width, fillBegin, fillEnd);
1936 for (Int_t j=fillBegin; j <= fillEnd; ++j)
1938 fineBinned->AddBinContent(j, TMath::Gaus(fineBinned->GetXaxis()->GetBinCenter(j), mean, width, kTRUE) * fCurrentESD->GetBinContent(i));
1942 for (Int_t i=1; i<=target->GetNbinsX(); ++i)
1945 for (Int_t j=1; j<=10; ++j)
1946 sum += fineBinned->GetBinContent((i-1)*10 + j);
1947 target->SetBinContent(i, sum / 10);
1952 DrawComparison("Gaussian", inputRange, fullPhaseSpace, kFALSE, GetMultiplicityMC(mcTarget, kTrVtx)->ProjectionY());
1955 //____________________________________________________________________
1956 TH2F* AliMultiplicityCorrection::CalculateMultiplicityESD(TH1* inputMC, Int_t correlationMap)
1958 // runs the distribution given in inputMC through the response matrix identified by
1959 // correlationMap and produces a measured distribution
1960 // although it is a TH2F the vertex axis is not used at the moment and all entries are filled in mid-vertex
1961 // if normalized is set, inputMC is expected to be normalized to the bin width
1966 if (correlationMap < 0 || correlationMap >= kCorrHists)
1969 // empty under/overflow bins in x, otherwise Project3D takes them into account
1970 TH3* hist = fCorrelation[correlationMap];
1971 for (Int_t y=0; y<=hist->GetYaxis()->GetNbins()+1; ++y)
1973 for (Int_t z=0; z<=hist->GetZaxis()->GetNbins()+1; ++z)
1975 hist->SetBinContent(0, y, z, 0);
1976 hist->SetBinContent(hist->GetXaxis()->GetNbins()+1, y, z, 0);
1980 TH2* corr = (TH2*) hist->Project3D("zy");
1981 //corr->Rebin2D(2, 1);
1983 Printf("Correction histogram used for convolution has %f entries", corr->Integral());
1985 // normalize correction for given nPart
1986 for (Int_t i=1; i<=corr->GetNbinsX(); ++i)
1988 Double_t sum = corr->Integral(i, i, 1, corr->GetNbinsY());
1992 for (Int_t j=1; j<=corr->GetNbinsY(); ++j)
1995 corr->SetBinContent(i, j, corr->GetBinContent(i, j) / sum);
1996 corr->SetBinError(i, j, corr->GetBinError(i, j) / sum);
2000 TH2F* target = dynamic_cast<TH2F*> (fMultiplicityESD[0]->Clone(Form("%s_measured", inputMC->GetName())));
2003 for (Int_t meas=1; meas<=corr->GetNbinsY(); ++meas)
2005 Float_t measured = 0;
2008 for (Int_t gen=1; gen<=corr->GetNbinsX(); ++gen)
2010 Int_t mcGenBin = inputMC->GetXaxis()->FindBin(corr->GetXaxis()->GetBinCenter(gen));
2012 measured += inputMC->GetBinContent(mcGenBin) * corr->GetBinContent(gen, meas);
2013 error += inputMC->GetBinError(mcGenBin) * corr->GetBinContent(gen, meas);
2016 //printf("%f +- %f ; %f +- %f \n", inputMC->GetBinContent(meas), inputMC->GetBinError(meas), measured, error);
2018 target->SetBinContent(1 + target->GetNbinsX() / 2, meas, measured);
2019 target->SetBinError(1 + target->GetNbinsX() / 2, meas, error);
2025 //____________________________________________________________________
2026 void AliMultiplicityCorrection::SetGenMeasFromFunc(TF1* inputMC, Int_t id)
2028 // uses the given function to fill the input MC histogram and generates from that
2029 // the measured histogram by applying the response matrix
2030 // this can be used to evaluate if the methods work indepedently of the input
2032 // WARNING does not respect the vertex distribution, just fills central vertex bin
2037 if (id < 0 || id >= kESDHists)
2040 // fill histogram used for random generation
2041 TH1* tmp = fMultiplicityVtx[id]->ProjectionY("tmp");
2044 for (Int_t i=1; i<=tmp->GetNbinsX(); ++i)
2045 tmp->SetBinContent(i, inputMC->Eval(tmp->GetXaxis()->GetBinCenter(i)) * tmp->GetXaxis()->GetBinWidth(i));
2047 TH1* mcRnd = fMultiplicityVtx[id]->ProjectionY("mcRnd");
2049 mcRnd->FillRandom(tmp, tmp->Integral());
2051 //new TCanvas; tmp->Draw();
2052 //new TCanvas; mcRnd->Draw();
2054 // and move into 2d histogram
2055 TH1* mc = fMultiplicityVtx[id];
2057 for (Int_t i=1; i<=mc->GetNbinsY(); ++i)
2059 mc->SetBinContent(mc->GetNbinsX() / 2 + 1, i, mcRnd->GetBinContent(i));
2060 mc->SetBinError(mc->GetNbinsX() / 2 + 1, i, TMath::Sqrt(mcRnd->GetBinContent(i)));
2063 //new TCanvas; mc->Draw("COLZ");
2065 // now randomize the measured histogram; funcMeasured is used as pilot function to generated the measured entries
2066 TH1* funcMeasured = CalculateMultiplicityESD(tmp, id)->ProjectionY("funcMeasured");
2068 //new TCanvas; funcMeasured->Draw();
2070 fMultiplicityESD[id]->Reset();
2072 TH1* measRnd = fMultiplicityESD[id]->ProjectionY("measRnd");
2073 measRnd->FillRandom(funcMeasured, tmp->Integral());
2075 //new TCanvas; measRnd->Draw();
2077 fMultiplicityESD[id]->Reset();
2078 for (Int_t i=1; i<=fMultiplicityESD[id]->GetNbinsY(); ++i)
2080 fMultiplicityESD[id]->SetBinContent(fMultiplicityESD[id]->GetNbinsX() / 2 + 1, i, measRnd->GetBinContent(i));
2081 fMultiplicityESD[id]->SetBinError(fMultiplicityESD[id]->GetNbinsX() / 2 + 1, i, TMath::Sqrt(measRnd->GetBinContent(i)));