]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG0/multiplicity/AliMultiplicityCorrection.cxx
Add shared pads also to dictionary and signal array
[u/mrichter/AliRoot.git] / PWG0 / multiplicity / AliMultiplicityCorrection.cxx
CommitLineData
0a173978 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16/* $Id$ */
17
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.
6d81c2de 21// e.g. chi2 minimization and bayesian unfolding
0a173978 22//
23// Author: Jan.Fiete.Grosse-Oetringhaus@cern.ch
24
25#include "AliMultiplicityCorrection.h"
26
27#include <TFile.h>
28#include <TH1F.h>
29#include <TH2F.h>
30#include <TH3F.h>
31#include <TDirectory.h>
0a173978 32#include <TCanvas.h>
33#include <TString.h>
9ca6be09 34#include <TF1.h>
d560b581 35#include <TMath.h>
3602328d 36#include <TCollection.h>
447c325d 37#include <TLegend.h>
38#include <TLine.h>
0b4bfd98 39#include <TRandom.h>
40#include <TProfile.h>
41#include <TProfile2D.h>
0a173978 42
43ClassImp(AliMultiplicityCorrection)
44
0b4bfd98 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!)
48
49// SPD: peak area - flat area - low stat area
69b09e3b 50Int_t AliMultiplicityCorrection::fgQualityRegionsB[kQualityRegions] = {1, 20, 70};
51Int_t AliMultiplicityCorrection::fgQualityRegionsE[kQualityRegions] = {10, 65, 80};
0b4bfd98 52
53//____________________________________________________________________
54void AliMultiplicityCorrection::SetQualityRegions(Bool_t SPDStudy)
55{
56 //
57 // sets the quality region definition to TPC or SPD
58 //
59
60 if (SPDStudy)
61 {
62 // SPD: peak area - flat area - low stat area
69b09e3b 63 fgQualityRegionsB[0] = 1;
64 fgQualityRegionsE[0] = 10;
0b4bfd98 65
69b09e3b 66 fgQualityRegionsB[1] = 20;
67 fgQualityRegionsE[1] = 65;
0b4bfd98 68
69b09e3b 69 fgQualityRegionsB[2] = 70;
70 fgQualityRegionsE[2] = 80;
6d81c2de 71
72 Printf("AliMultiplicityCorrection::SetQualityRegions --> Enabled quality regions for SPD");
0b4bfd98 73 }
74 else
75 {
76 // TPC: peak area - flat area - low stat area
77 fgQualityRegionsB[0] = 4;
78 fgQualityRegionsE[0] = 12;
79
80 fgQualityRegionsB[1] = 25;
81 fgQualityRegionsE[1] = 55;
82
83 fgQualityRegionsB[2] = 88;
84 fgQualityRegionsE[2] = 108;
6d81c2de 85
86 Printf("AliMultiplicityCorrection::SetQualityRegions --> Enabled quality regions for TPC");
0b4bfd98 87 }
88}
89
0a173978 90//____________________________________________________________________
91AliMultiplicityCorrection::AliMultiplicityCorrection() :
0f67a57c 92 TNamed(), fCurrentESD(0), fCurrentCorrelation(0), fCurrentEfficiency(0), fLastBinLimit(0), fLastChi2MC(0), fLastChi2MCLimit(0), fLastChi2Residuals(0), fRatioAverage(0)
0a173978 93{
94 //
95 // default constructor
96 //
97
98 for (Int_t i = 0; i < kESDHists; ++i)
99 fMultiplicityESD[i] = 0;
100
101 for (Int_t i = 0; i < kMCHists; ++i)
cfc19dd5 102 {
103 fMultiplicityVtx[i] = 0;
104 fMultiplicityMB[i] = 0;
105 fMultiplicityINEL[i] = 0;
69b09e3b 106 fMultiplicityNSD[i] = 0;
cfc19dd5 107 }
0a173978 108
109 for (Int_t i = 0; i < kCorrHists; ++i)
110 {
111 fCorrelation[i] = 0;
112 fMultiplicityESDCorrected[i] = 0;
113 }
6d81c2de 114
115 for (Int_t i = 0; i < kQualityRegions; ++i)
116 fQuality[i] = 0;
0a173978 117}
118
69b09e3b 119//____________________________________________________________________
120AliMultiplicityCorrection* AliMultiplicityCorrection::Open(const char* fileName, const char* folderName)
121{
122 // opens the given file, reads the multiplicity from the given folder and returns the object
123
124 TFile* file = TFile::Open(fileName);
125 if (!file)
126 {
127 Printf("ERROR: Could not open %s", fileName);
128 return 0;
129 }
130
131 AliMultiplicityCorrection* mult = new AliMultiplicityCorrection(folderName, folderName);
132 mult->LoadHistograms();
133
134 // TODO closing the file does not work here, because the histograms cannot be read anymore. LoadHistograms need to be adapted
135
136 return mult;
137}
138
0a173978 139//____________________________________________________________________
140AliMultiplicityCorrection::AliMultiplicityCorrection(const Char_t* name, const Char_t* title) :
7307d52c 141 TNamed(name, title),
142 fCurrentESD(0),
143 fCurrentCorrelation(0),
144 fCurrentEfficiency(0),
145 fLastBinLimit(0),
146 fLastChi2MC(0),
147 fLastChi2MCLimit(0),
148 fLastChi2Residuals(0),
149 fRatioAverage(0)
0a173978 150{
151 //
152 // named constructor
153 //
154
155 // do not add this hists to the directory
156 Bool_t oldStatus = TH1::AddDirectoryStatus();
157 TH1::AddDirectory(kFALSE);
158
b477f4f2 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};
0a173978 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,
9ca6be09 169 500.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,
172 //1000.5 };
0a173978 173
b477f4f2 174 #define VTXBINNING 10, binLimitsVtx
6d81c2de 175 #define NBINNING fgkMaxParams, binLimitsN*/
b477f4f2 176
69b09e3b 177 #define NBINNING 201, -0.5, 200.5
b3b260d1 178
179 Double_t vtxRange[] = { 15, 6, 2 };
0a173978 180
181 for (Int_t i = 0; i < kESDHists; ++i)
b3b260d1 182 fMultiplicityESD[i] = new TH2F(Form("fMultiplicityESD%d", i), "fMultiplicityESD;vtx-z;Ntracks;Count", 1, -vtxRange[i], vtxRange[i], NBINNING);
0a173978 183
184 for (Int_t i = 0; i < kMCHists; ++i)
185 {
b3b260d1 186 fMultiplicityVtx[i] = dynamic_cast<TH2F*> (fMultiplicityESD[i%3]->Clone(Form("fMultiplicityVtx%d", i)));
cfc19dd5 187 fMultiplicityVtx[i]->SetTitle("fMultiplicityVtx;vtx-z;Npart");
188
b3b260d1 189 fMultiplicityMB[i] = dynamic_cast<TH2F*> (fMultiplicityVtx[i]->Clone(Form("fMultiplicityMB%d", i)));
cfc19dd5 190 fMultiplicityMB[i]->SetTitle("fMultiplicityMB");
191
b3b260d1 192 fMultiplicityINEL[i] = dynamic_cast<TH2F*> (fMultiplicityVtx[i]->Clone(Form("fMultiplicityINEL%d", i)));
cfc19dd5 193 fMultiplicityINEL[i]->SetTitle("fMultiplicityINEL");
69b09e3b 194
b3b260d1 195 fMultiplicityNSD[i] = dynamic_cast<TH2F*> (fMultiplicityVtx[i]->Clone(Form("fMultiplicityNSD%d", i)));
69b09e3b 196 fMultiplicityNSD[i]->SetTitle("fMultiplicityNSD");
0a173978 197 }
198
199 for (Int_t i = 0; i < kCorrHists; ++i)
200 {
b3b260d1 201 fCorrelation[i] = new TH3F(Form("fCorrelation%d", i), "fCorrelation;vtx-z;Npart;Ntracks", 1, -vtxRange[i%3], vtxRange[i%3], NBINNING, NBINNING);
b477f4f2 202 fMultiplicityESDCorrected[i] = new TH1F(Form("fMultiplicityESDCorrected%d", i), "fMultiplicityESDCorrected;Npart;dN/dN", NBINNING);
0a173978 203 }
204
205 TH1::AddDirectory(oldStatus);
19442b86 206
207 AliUnfolding::SetNbins(120, 120);
208 AliUnfolding::SetSkipBinsBegin(1);
209 AliUnfolding::SetNormalizeInput(kTRUE);
0a173978 210}
211
212//____________________________________________________________________
213AliMultiplicityCorrection::~AliMultiplicityCorrection()
214{
215 //
216 // Destructor
217 //
6d81c2de 218
0f67a57c 219 Printf("AliMultiplicityCorrection::~AliMultiplicityCorrection called");
220
6d81c2de 221 for (Int_t i = 0; i < kESDHists; ++i)
222 {
223 if (fMultiplicityESD[i])
224 delete fMultiplicityESD[i];
225 fMultiplicityESD[i] = 0;
226 }
227
228 for (Int_t i = 0; i < kMCHists; ++i)
229 {
230 if (fMultiplicityVtx[i])
231 delete fMultiplicityVtx[i];
232 fMultiplicityVtx[i] = 0;
233
234 if (fMultiplicityMB[i])
235 delete fMultiplicityMB[i];
236 fMultiplicityMB[i] = 0;
237
238 if (fMultiplicityINEL[i])
239 delete fMultiplicityINEL[i];
240 fMultiplicityINEL[i] = 0;
69b09e3b 241
242 if (fMultiplicityNSD[i])
243 delete fMultiplicityNSD[i];
244 fMultiplicityNSD[i] = 0;
245}
6d81c2de 246
247 for (Int_t i = 0; i < kCorrHists; ++i)
248 {
249 if (fCorrelation[i])
250 delete fCorrelation[i];
251 fCorrelation[i] = 0;
252
253 if (fMultiplicityESDCorrected[i])
254 delete fMultiplicityESDCorrected[i];
255 fMultiplicityESDCorrected[i] = 0;
256 }
0a173978 257}
258
259//____________________________________________________________________
260Long64_t AliMultiplicityCorrection::Merge(TCollection* list)
261{
262 // Merge a list of AliMultiplicityCorrection objects with this (needed for
263 // PROOF).
264 // Returns the number of merged objects (including this).
265
266 if (!list)
267 return 0;
268
269 if (list->IsEmpty())
270 return 1;
271
272 TIterator* iter = list->MakeIterator();
273 TObject* obj;
274
275 // collections of all histograms
69b09e3b 276 TList collections[kESDHists+kMCHists*4+kCorrHists*2];
0a173978 277
278 Int_t count = 0;
279 while ((obj = iter->Next())) {
280
281 AliMultiplicityCorrection* entry = dynamic_cast<AliMultiplicityCorrection*> (obj);
282 if (entry == 0)
283 continue;
284
285 for (Int_t i = 0; i < kESDHists; ++i)
286 collections[i].Add(entry->fMultiplicityESD[i]);
287
288 for (Int_t i = 0; i < kMCHists; ++i)
cfc19dd5 289 {
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]);
69b09e3b 293 collections[kESDHists+kMCHists*3+i].Add(entry->fMultiplicityNSD[i]);
cfc19dd5 294 }
0a173978 295
296 for (Int_t i = 0; i < kCorrHists; ++i)
69b09e3b 297 collections[kESDHists+kMCHists*4+i].Add(entry->fCorrelation[i]);
0a173978 298
299 for (Int_t i = 0; i < kCorrHists; ++i)
69b09e3b 300 collections[kESDHists+kMCHists*4+kCorrHists+i].Add(entry->fMultiplicityESDCorrected[i]);
0a173978 301
302 count++;
303 }
304
305 for (Int_t i = 0; i < kESDHists; ++i)
306 fMultiplicityESD[i]->Merge(&collections[i]);
307
308 for (Int_t i = 0; i < kMCHists; ++i)
cfc19dd5 309 {
310 fMultiplicityVtx[i]->Merge(&collections[kESDHists+i]);
311 fMultiplicityMB[i]->Merge(&collections[kESDHists+kMCHists+i]);
312 fMultiplicityINEL[i]->Merge(&collections[kESDHists+kMCHists*2+i]);
69b09e3b 313 fMultiplicityNSD[i]->Merge(&collections[kESDHists+kMCHists*3+i]);
cfc19dd5 314 }
0a173978 315
316 for (Int_t i = 0; i < kCorrHists; ++i)
69b09e3b 317 fCorrelation[i]->Merge(&collections[kESDHists+kMCHists*4+i]);
0a173978 318
319 for (Int_t i = 0; i < kCorrHists; ++i)
69b09e3b 320 fMultiplicityESDCorrected[i]->Merge(&collections[kESDHists+kMCHists*4+kCorrHists+i]);
0a173978 321
322 delete iter;
323
324 return count+1;
325}
326
327//____________________________________________________________________
328Bool_t AliMultiplicityCorrection::LoadHistograms(const Char_t* dir)
329{
330 //
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)
333 //
334
335 if (!dir)
336 dir = GetName();
337
338 if (!gDirectory->cd(dir))
339 return kFALSE;
340
144ff489 341 // store old hists to delete them later
342 TList oldObjects;
343 oldObjects.SetOwner(1);
344 for (Int_t i = 0; i < kESDHists; ++i)
345 if (fMultiplicityESD[i])
346 oldObjects.Add(fMultiplicityESD[i]);
347
348 for (Int_t i = 0; i < kMCHists; ++i)
349 {
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]);
69b09e3b 356 if (fMultiplicityNSD[i])
357 oldObjects.Add(fMultiplicityNSD[i]);
144ff489 358 }
359
360 for (Int_t i = 0; i < kCorrHists; ++i)
361 if (fCorrelation[i])
362 oldObjects.Add(fCorrelation[i]);
363
364 // load histograms
0a173978 365
366 Bool_t success = kTRUE;
367
368 for (Int_t i = 0; i < kESDHists; ++i)
369 {
370 fMultiplicityESD[i] = dynamic_cast<TH2F*> (gDirectory->Get(fMultiplicityESD[i]->GetName()));
371 if (!fMultiplicityESD[i])
372 success = kFALSE;
373 }
374
375 for (Int_t i = 0; i < kMCHists; ++i)
376 {
cfc19dd5 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()));
69b09e3b 380 fMultiplicityNSD[i] = dynamic_cast<TH2F*> (gDirectory->Get(fMultiplicityNSD[i]->GetName()));
cfc19dd5 381 if (!fMultiplicityVtx[i] || !fMultiplicityMB[i] || !fMultiplicityINEL[i])
0a173978 382 success = kFALSE;
383 }
384
385 for (Int_t i = 0; i < kCorrHists; ++i)
386 {
387 fCorrelation[i] = dynamic_cast<TH3F*> (gDirectory->Get(fCorrelation[i]->GetName()));
388 if (!fCorrelation[i])
389 success = kFALSE;
390 fMultiplicityESDCorrected[i] = dynamic_cast<TH1F*> (gDirectory->Get(fMultiplicityESDCorrected[i]->GetName()));
391 if (!fMultiplicityESDCorrected[i])
392 success = kFALSE;
393 }
394
395 gDirectory->cd("..");
396
144ff489 397 // delete old hists
398 oldObjects.Delete();
399
0a173978 400 return success;
401}
402
403//____________________________________________________________________
144ff489 404void AliMultiplicityCorrection::SaveHistograms(const char* dir)
0a173978 405{
406 //
407 // saves the histograms
408 //
409
144ff489 410 if (!dir)
411 dir = GetName();
412
413 gDirectory->mkdir(dir);
414 gDirectory->cd(dir);
0a173978 415
416 for (Int_t i = 0; i < kESDHists; ++i)
417 if (fMultiplicityESD[i])
69b09e3b 418 {
0a173978 419 fMultiplicityESD[i]->Write();
69b09e3b 420 fMultiplicityESD[i]->ProjectionY(Form("%s_px", fMultiplicityESD[i]->GetName()), 1, fMultiplicityESD[i]->GetNbinsX())->Write();
421 }
0a173978 422
423 for (Int_t i = 0; i < kMCHists; ++i)
cfc19dd5 424 {
425 if (fMultiplicityVtx[i])
69b09e3b 426 {
cfc19dd5 427 fMultiplicityVtx[i]->Write();
69b09e3b 428 fMultiplicityVtx[i]->ProjectionY(Form("%s_px", fMultiplicityVtx[i]->GetName()), 1, fMultiplicityVtx[i]->GetNbinsX())->Write();
429 }
cfc19dd5 430 if (fMultiplicityMB[i])
69b09e3b 431 {
cfc19dd5 432 fMultiplicityMB[i]->Write();
69b09e3b 433 fMultiplicityMB[i]->ProjectionY(Form("%s_px", fMultiplicityMB[i]->GetName()), 1, fMultiplicityMB[i]->GetNbinsX())->Write();
434 }
cfc19dd5 435 if (fMultiplicityINEL[i])
69b09e3b 436 {
cfc19dd5 437 fMultiplicityINEL[i]->Write();
69b09e3b 438 fMultiplicityINEL[i]->ProjectionY(Form("%s_px", fMultiplicityINEL[i]->GetName()), 1, fMultiplicityINEL[i]->GetNbinsX())->Write();
439 }
440 if (fMultiplicityNSD[i])
441 {
442 fMultiplicityNSD[i]->Write();
443 fMultiplicityNSD[i]->ProjectionY(Form("%s_px", fMultiplicityNSD[i]->GetName()), 1, fMultiplicityNSD[i]->GetNbinsX())->Write();
444 }
cfc19dd5 445 }
0a173978 446
447 for (Int_t i = 0; i < kCorrHists; ++i)
448 {
449 if (fCorrelation[i])
450 fCorrelation[i]->Write();
451 if (fMultiplicityESDCorrected[i])
452 fMultiplicityESDCorrected[i]->Write();
453 }
454
455 gDirectory->cd("..");
456}
457
458//____________________________________________________________________
b3b260d1 459void 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)
0a173978 460{
461 //
462 // Fills an event from MC
463 //
464
cfc19dd5 465 if (triggered)
466 {
467 fMultiplicityMB[0]->Fill(vtx, generated05);
468 fMultiplicityMB[1]->Fill(vtx, generated10);
b3b260d1 469 fMultiplicityMB[2]->Fill(vtx, generated14);
470 fMultiplicityMB[3]->Fill(vtx, generatedAll);
cfc19dd5 471
472 if (vertex)
473 {
474 fMultiplicityVtx[0]->Fill(vtx, generated05);
475 fMultiplicityVtx[1]->Fill(vtx, generated10);
b3b260d1 476 fMultiplicityVtx[2]->Fill(vtx, generated14);
477 fMultiplicityVtx[3]->Fill(vtx, generatedAll);
cfc19dd5 478 }
479 }
480
481 fMultiplicityINEL[0]->Fill(vtx, generated05);
482 fMultiplicityINEL[1]->Fill(vtx, generated10);
b3b260d1 483 fMultiplicityINEL[2]->Fill(vtx, generated14);
484 fMultiplicityINEL[3]->Fill(vtx, generatedAll);
69b09e3b 485
486 if (processType != AliPWG0Helper::kSD)
487 {
488 fMultiplicityNSD[0]->Fill(vtx, generated05);
489 fMultiplicityNSD[1]->Fill(vtx, generated10);
b3b260d1 490 fMultiplicityNSD[2]->Fill(vtx, generated14);
491 fMultiplicityNSD[3]->Fill(vtx, generatedAll);
69b09e3b 492 }
0a173978 493}
494
495//____________________________________________________________________
b3b260d1 496void AliMultiplicityCorrection::FillMeasured(Float_t vtx, Int_t measured05, Int_t measured10, Int_t measured14)
0a173978 497{
498 //
499 // Fills an event from ESD
500 //
501
502 fMultiplicityESD[0]->Fill(vtx, measured05);
503 fMultiplicityESD[1]->Fill(vtx, measured10);
b3b260d1 504 fMultiplicityESD[2]->Fill(vtx, measured14);
0a173978 505}
506
507//____________________________________________________________________
b3b260d1 508void 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)
0a173978 509{
510 //
511 // Fills an event into the correlation map with the information from MC and ESD
512 //
513
514 fCorrelation[0]->Fill(vtx, generated05, measured05);
515 fCorrelation[1]->Fill(vtx, generated10, measured10);
b3b260d1 516 fCorrelation[2]->Fill(vtx, generated14, measured14);
0a173978 517
b3b260d1 518 fCorrelation[3]->Fill(vtx, generatedAll, measured05);
519 fCorrelation[4]->Fill(vtx, generatedAll, measured10);
520 fCorrelation[5]->Fill(vtx, generatedAll, measured14);
0a173978 521}
522
523//____________________________________________________________________
19442b86 524void AliMultiplicityCorrection::SetupCurrentHists(Int_t inputRange, Bool_t fullPhaseSpace, EventType eventType)
0a173978 525{
526 //
9ca6be09 527 // fills fCurrentESD, fCurrentCorrelation
528 // resets fMultiplicityESDCorrected
0a173978 529 //
530
531 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
0b4bfd98 532
9ca6be09 533 fMultiplicityESDCorrected[correlationID]->Reset();
0b4bfd98 534 fMultiplicityESDCorrected[correlationID]->Sumw2();
0a173978 535
039e265e 536 // project without under/overflow bins
537 fCurrentESD = fMultiplicityESD[inputRange]->ProjectionY("fCurrentESD", 1, fMultiplicityESD[inputRange]->GetXaxis()->GetNbins());
9ca6be09 538 fCurrentESD->Sumw2();
0a173978 539
540 // empty under/overflow bins in x, otherwise Project3D takes them into account
541 TH3* hist = fCorrelation[correlationID];
039e265e 542 for (Int_t y=0; y<=hist->GetYaxis()->GetNbins()+1; ++y)
0a173978 543 {
039e265e 544 for (Int_t z=0; z<=hist->GetZaxis()->GetNbins()+1; ++z)
0a173978 545 {
546 hist->SetBinContent(0, y, z, 0);
547 hist->SetBinContent(hist->GetXaxis()->GetNbins()+1, y, z, 0);
548 }
549 }
550
19442b86 551 fCurrentCorrelation = (TH2*) hist->Project3D("zy");
9ca6be09 552 fCurrentCorrelation->Sumw2();
69b09e3b 553
44466df2 554 Printf("AliMultiplicityCorrection::SetupCurrentHists: Statistics information: %.f entries in correlation map; %.f entries in measured spectrum", fCurrentCorrelation->Integral(), fCurrentESD->Integral());
555
0b4bfd98 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)
561 {
562 if (fCurrentCorrelation->GetBinContent(x, y) == 1)
563 {
564 fCurrentCorrelation->SetBinContent(x, y, 0);
565 fCurrentCorrelation->SetBinError(x, y, 0);
447c325d 566
0b4bfd98 567 ++nNulledBins;
568 }
569 }
570 Printf("Nulled %d bins", nNulledBins);
571#endif
572
573 fCurrentEfficiency = GetEfficiency(inputRange, eventType);
574 //fCurrentEfficiency->Rebin(2);
575 //fCurrentEfficiency->Scale(0.5);
576}
577
578//____________________________________________________________________
579TH1* AliMultiplicityCorrection::GetEfficiency(Int_t inputRange, EventType eventType)
580{
581 //
582 // calculates efficiency for given event type
583 //
69b09e3b 584
0b4bfd98 585 TH1* divisor = 0;
cfc19dd5 586 switch (eventType)
587 {
69b09e3b 588 case kTrVtx : break;
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;
592 }
593 TH1* eff = fMultiplicityVtx[inputRange]->ProjectionY("CurrentEfficiency", 1, fMultiplicityVtx[inputRange]->GetNbinsX(), "e");
594
595 if (eventType == kTrVtx)
596 {
597 for (Int_t i=0; i<= eff->GetNbinsX()+1; i++)
598 eff->SetBinContent(i, 1);
cfc19dd5 599 }
69b09e3b 600 else
601 eff->Divide(eff, divisor, 1, 1, "B");
602
603 return eff;
604}
605
606//____________________________________________________________________
607TH1* AliMultiplicityCorrection::GetTriggerEfficiency(Int_t inputRange)
608{
609 //
610 // calculates efficiency for given event type
611 //
612
613 TH1* divisor = fMultiplicityINEL[inputRange]->ProjectionY("divisor", 1, fMultiplicityINEL[inputRange]->GetNbinsX(), "e");
614 TH1* eff = fMultiplicityMB[inputRange]->ProjectionY("CurrentEfficiency", 1, fMultiplicityMB[inputRange]->GetNbinsX(), "e");
0b4bfd98 615 eff->Divide(eff, divisor, 1, 1, "B");
616 return eff;
9ca6be09 617}
618
619//____________________________________________________________________
19442b86 620Int_t AliMultiplicityCorrection::ApplyMinuitFit(Int_t inputRange, Bool_t fullPhaseSpace, EventType eventType, Bool_t check, TH1* initialConditions)
6d81c2de 621{
622 //
19442b86 623 // correct spectrum using minuit chi2 method
6d81c2de 624 //
19442b86 625 // for description of parameters, see AliUnfolding::Unfold
6d81c2de 626 //
447c325d 627
19442b86 628 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
629
630 AliUnfolding::SetCreateOverflowBin(5);
631 AliUnfolding::SetUnfoldingMethod(AliUnfolding::kChi2Minimization);
632 SetupCurrentHists(inputRange, fullPhaseSpace, eventType);
633
634 if (!initialConditions)
0a173978 635 {
19442b86 636 initialConditions = (TH1*) fCurrentESD->Clone("initialConditions");
6d81c2de 637 initialConditions->Scale(1.0 / initialConditions->Integral());
44466df2 638 if (!check)
dd701109 639 {
19442b86 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));
dd701109 643 }
644 }
0f67a57c 645
19442b86 646 return AliUnfolding::Unfold(fCurrentCorrelation, fCurrentEfficiency, fCurrentESD, initialConditions, fMultiplicityESDCorrected[correlationID], check);
dd701109 647}
648
6d81c2de 649//____________________________________________________________________
19442b86 650Int_t AliMultiplicityCorrection::ApplyNBDFit(Int_t inputRange, Bool_t fullPhaseSpace, EventType eventType)
6d81c2de 651{
652 //
19442b86 653 // correct spectrum using minuit chi2 method with a NBD function
dd701109 654 //
19442b86 655 // for description of parameters, see AliUnfolding::Unfold
dd701109 656 //
657
658 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
19442b86 659
660 AliUnfolding::SetUnfoldingMethod(AliUnfolding::kFunction);
661 SetupCurrentHists(inputRange, fullPhaseSpace, eventType);
662
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);
670
671 return AliUnfolding::Unfold(fCurrentCorrelation, fCurrentEfficiency, fCurrentESD, 0, fMultiplicityESDCorrected[correlationID]);
0a173978 672}
673
0a173978 674//____________________________________________________________________
675void AliMultiplicityCorrection::DrawHistograms()
676{
6d81c2de 677 //
678 // draws the histograms of this class
679 //
680
0a173978 681 printf("ESD:\n");
682
683 TCanvas* canvas1 = new TCanvas("fMultiplicityESD", "fMultiplicityESD", 900, 600);
684 canvas1->Divide(3, 2);
685 for (Int_t i = 0; i < kESDHists; ++i)
686 {
687 canvas1->cd(i+1);
688 fMultiplicityESD[i]->DrawCopy("COLZ");
689 printf("%d --> %f\n", i, (Float_t) fMultiplicityESD[i]->ProjectionY()->GetMean());
690 }
691
cfc19dd5 692 printf("Vtx:\n");
0a173978 693
694 TCanvas* canvas2 = new TCanvas("fMultiplicityMC", "fMultiplicityMC", 900, 600);
695 canvas2->Divide(3, 2);
696 for (Int_t i = 0; i < kMCHists; ++i)
697 {
698 canvas2->cd(i+1);
cfc19dd5 699 fMultiplicityVtx[i]->DrawCopy("COLZ");
700 printf("%d --> %f\n", i, fMultiplicityVtx[i]->ProjectionY()->GetMean());
0a173978 701 }
702
703 TCanvas* canvas3 = new TCanvas("fCorrelation", "fCorrelation", 900, 900);
704 canvas3->Divide(3, 3);
705 for (Int_t i = 0; i < kCorrHists; ++i)
706 {
707 canvas3->cd(i+1);
b477f4f2 708 TH3* hist = dynamic_cast<TH3*> (fCorrelation[i]->Clone());
709 for (Int_t y=1; y<=hist->GetYaxis()->GetNbins(); ++y)
710 {
711 for (Int_t z=1; z<=hist->GetZaxis()->GetNbins(); ++z)
712 {
713 hist->SetBinContent(0, y, z, 0);
714 hist->SetBinContent(hist->GetXaxis()->GetNbins()+1, y, z, 0);
715 }
716 }
717 TH1* proj = hist->Project3D("zy");
0a173978 718 proj->DrawCopy("COLZ");
719 }
720}
721
722//____________________________________________________________________
1c91c693 723void AliMultiplicityCorrection::DrawComparison(const char* name, Int_t inputRange, Bool_t fullPhaseSpace, Bool_t /*normalizeESD*/, TH1* mcHist, Bool_t simple)
0a173978 724{
039e265e 725 // draw comparison plots
726
727
447c325d 728 //mcHist->Rebin(2);
729
cfc19dd5 730 Int_t esdCorrId = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
731
9ca6be09 732 TString tmpStr;
cfc19dd5 733 tmpStr.Form("%s_DrawComparison_%d", name, esdCorrId);
0a173978 734
447c325d 735 if (fMultiplicityESDCorrected[esdCorrId]->Integral() == 0)
736 {
737 printf("ERROR. Unfolded histogram is empty\n");
738 return;
739 }
740
741 //regain measured distribution used for unfolding, because the bins at high mult. were modified in SetupCurrentHists
039e265e 742 fCurrentESD = fMultiplicityESD[esdCorrId]->ProjectionY("fCurrentESD", 1, fMultiplicityESD[inputRange]->GetXaxis()->GetNbins());
447c325d 743 fCurrentESD->Sumw2();
744 fCurrentESD->Scale(1.0 / fCurrentESD->Integral());
745
746 // normalize unfolded result to 1
747 fMultiplicityESDCorrected[esdCorrId]->Scale(1.0 / fMultiplicityESDCorrected[esdCorrId]->Integral());
748
749 //fCurrentESD->Scale(mcHist->Integral(2, 200));
750
751 //new TCanvas;
752 /*TH1* ratio = (TH1*) fMultiplicityESDCorrected[esdCorrId]->Clone("ratio");
753 ratio->Divide(mcHist);
754 ratio->Draw("HIST");
755 ratio->Fit("pol0", "W0", "", 20, 120);
756 Float_t scalingFactor = ratio->GetFunction("pol0")->GetParameter(0);
757 delete ratio;
758 mcHist->Scale(scalingFactor);*/
759
0f67a57c 760 // find bin with <= 50 entries. this is used as limit for the chi2 calculation
0b4bfd98 761 Int_t mcBinLimit = 0;
762 for (Int_t i=20; i<mcHist->GetNbinsX(); ++i)
763 {
764 if (mcHist->GetBinContent(i) > 50)
765 {
766 mcBinLimit = i;
767 }
768 else
769 break;
770 }
771 Printf("AliMultiplicityCorrection::DrawComparison: MC bin limit is %d", mcBinLimit);
69b09e3b 772
0b4bfd98 773 // scale to 1
774 mcHist->Sumw2();
144ff489 775 if (mcHist->Integral() > 0)
776 mcHist->Scale(1.0 / mcHist->Integral());
447c325d 777
b477f4f2 778 // calculate residual
779
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
dd701109 782 TH1* tmpESDEfficiencyRecorrected = (TH1*) fMultiplicityESDCorrected[esdCorrId]->Clone("tmpESDEfficiencyRecorrected");
783 tmpESDEfficiencyRecorrected->Multiply(fCurrentEfficiency);
447c325d 784 TH2* convoluted = CalculateMultiplicityESD(tmpESDEfficiencyRecorrected, esdCorrId);
785 TH1* convolutedProj = convoluted->ProjectionY("convolutedProj", -1, -1, "e");
786 if (convolutedProj->Integral() > 0)
787 {
788 convolutedProj->Scale(1.0 / convolutedProj->Integral());
789 }
790 else
791 printf("ERROR: convolutedProj is empty. Something went wrong calculating the convoluted histogram.\n");
792
447c325d 793 TH1* residual = (TH1*) convolutedProj->Clone("residual");
794 residual->SetTitle("Residuals;Ntracks;(folded unfolded measured - measured) / e");
b477f4f2 795
796 residual->Add(fCurrentESD, -1);
447c325d 797 //residual->Divide(residual, fCurrentESD, 1, 1, "B");
798
0b4bfd98 799 TH1* residualHist = new TH1F("residualHist", "residualHist", 51, -5, 5);
b477f4f2 800
19442b86 801 // find bin limit
802 Int_t lastBin = 0;
803 for (Int_t i=1; i<=fCurrentESD->GetNbinsX(); ++i)
804 {
805 if (fCurrentESD->GetBinContent(i) <= 5)
806 {
807 lastBin = i;
808 break;
809 }
810 }
811
b477f4f2 812 // TODO fix errors
447c325d 813 Float_t chi2 = 0;
814 for (Int_t i=1; i<=residual->GetNbinsX(); ++i)
b477f4f2 815 {
447c325d 816 if (fCurrentESD->GetBinError(i) > 0)
817 {
818 Float_t value = residual->GetBinContent(i) / fCurrentESD->GetBinError(i);
19442b86 819 if (i > 1 && i <= lastBin)
447c325d 820 chi2 += value * value;
0f67a57c 821 Printf("%d --> %f (%f)", i, value * value, chi2);
447c325d 822 residual->SetBinContent(i, value);
823 residualHist->Fill(value);
824 }
825 else
826 {
827 //printf("Residual bin %d set to 0\n", i);
828 residual->SetBinContent(i, 0);
829 }
830 convolutedProj->SetBinError(i, 0);
b477f4f2 831 residual->SetBinError(i, 0);
447c325d 832 }
0f67a57c 833 fLastChi2Residuals = chi2;
dd701109 834
0b4bfd98 835 new TCanvas; residualHist->DrawCopy();
836
837 //residualHist->Fit("gaus", "N");
838 //delete residualHist;
dd701109 839
19442b86 840 printf("Difference (Residuals) is %f for bin 2-%d\n", fLastChi2Residuals, lastBin);
dd701109 841
447c325d 842 TCanvas* canvas1 = 0;
843 if (simple)
844 {
69b09e3b 845 canvas1 = new TCanvas(tmpStr, tmpStr, 1200, 600);
447c325d 846 canvas1->Divide(2, 1);
847 }
848 else
849 {
850 canvas1 = new TCanvas(tmpStr, tmpStr, 1200, 1200);
851 canvas1->Divide(2, 3);
852 }
0a173978 853
854 canvas1->cd(1);
69b09e3b 855 canvas1->cd(1)->SetGridx();
856 canvas1->cd(1)->SetGridy();
857 canvas1->cd(1)->SetTopMargin(0.05);
858 canvas1->cd(1)->SetRightMargin(0.05);
859 canvas1->cd(1)->SetLeftMargin(0.12);
860 canvas1->cd(1)->SetBottomMargin(0.12);
cfc19dd5 861 TH1* proj = (TH1*) mcHist->Clone("proj");
9ca6be09 862
039e265e 863 // normalize without 0 bin
864 proj->Scale(1.0 / proj->Integral(2, proj->GetNbinsX()));
865 Printf("Normalized without 0 bin!");
dd701109 866 proj->GetXaxis()->SetRangeUser(0, 200);
69b09e3b 867 proj->GetYaxis()->SetTitleOffset(1.4);
868 //proj->SetLabelSize(0.05, "xy");
869 //proj->SetTitleSize(0.05, "xy");
870 proj->SetTitle(Form(";True multiplicity in |#eta| < %.1f;Entries", (inputRange+1)*0.5));
447c325d 871 proj->SetStats(kFALSE);
0a173978 872
cfc19dd5 873 fMultiplicityESDCorrected[esdCorrId]->SetLineColor(2);
69b09e3b 874 fMultiplicityESDCorrected[esdCorrId]->SetMarkerColor(2);
875 //fMultiplicityESDCorrected[esdCorrId]->SetMarkerStyle(5);
039e265e 876 // normalize without 0 bin
877 fMultiplicityESDCorrected[esdCorrId]->Scale(1.0 / fMultiplicityESDCorrected[esdCorrId]->Integral(2, fMultiplicityESDCorrected[esdCorrId]->GetNbinsX()));
878 Printf("Normalized without 0 bin!");
0f67a57c 879
880 if (proj->GetEntries() > 0) {
881 proj->DrawCopy("HIST");
882 fMultiplicityESDCorrected[esdCorrId]->DrawCopy("SAME HIST E");
883 }
884 else
885 fMultiplicityESDCorrected[esdCorrId]->DrawCopy("HIST E");
886
887 gPad->SetLogy();
cfc19dd5 888
447c325d 889 TLegend* legend = new TLegend(0.3, 0.8, 0.93, 0.93);
69b09e3b 890 legend->AddEntry(proj, "True distribution");
891 legend->AddEntry(fMultiplicityESDCorrected[esdCorrId], "Unfolded distribution");
447c325d 892 legend->SetFillColor(0);
69b09e3b 893 legend->SetTextSize(0.04);
447c325d 894 legend->Draw();
895 // unfortunately does not work. maybe a bug? --> legend->SetTextSizePixels(14);
896
897 canvas1->cd(2);
69b09e3b 898 canvas1->cd(2)->SetGridx();
899 canvas1->cd(2)->SetGridy();
900 canvas1->cd(2)->SetTopMargin(0.05);
901 canvas1->cd(2)->SetRightMargin(0.05);
902 canvas1->cd(2)->SetLeftMargin(0.12);
903 canvas1->cd(2)->SetBottomMargin(0.12);
447c325d 904
905 gPad->SetLogy();
906 fCurrentESD->GetXaxis()->SetRangeUser(0, 200);
907 //fCurrentESD->SetLineColor(2);
69b09e3b 908 fCurrentESD->SetTitle(Form(";Measured multiplicity in |#eta| < %.1f;Entries", (inputRange+1)*0.5));
447c325d 909 fCurrentESD->SetStats(kFALSE);
69b09e3b 910 fCurrentESD->GetYaxis()->SetTitleOffset(1.4);
911 //fCurrentESD->SetLabelSize(0.05, "xy");
912 //fCurrentESD->SetTitleSize(0.05, "xy");
447c325d 913 fCurrentESD->DrawCopy("HIST E");
914
915 convolutedProj->SetLineColor(2);
69b09e3b 916 convolutedProj->SetMarkerColor(2);
917 convolutedProj->SetMarkerStyle(5);
447c325d 918 //proj2->SetMarkerColor(2);
919 //proj2->SetMarkerStyle(5);
69b09e3b 920 convolutedProj->DrawCopy("HIST SAME P");
447c325d 921
922 legend = new TLegend(0.3, 0.8, 0.93, 0.93);
69b09e3b 923 legend->AddEntry(fCurrentESD, "Measured distribution");
924 legend->AddEntry(convolutedProj, "R #otimes unfolded distribution", "P");
447c325d 925 legend->SetFillColor(0);
69b09e3b 926 legend->SetTextSize(0.04);
447c325d 927 legend->Draw();
928
0b4bfd98 929 //TH1* diffMCUnfolded = dynamic_cast<TH1*> (proj->Clone("diffMCUnfolded"));
930 //diffMCUnfolded->Add(fMultiplicityESDCorrected[esdCorrId], -1);
447c325d 931
932 /*Float_t chi2 = 0;
933 Float_t chi = 0;
dd701109 934 fLastChi2MCLimit = 0;
447c325d 935 Int_t limit = 0;
dd701109 936 for (Int_t i=2; i<=200; ++i)
cfc19dd5 937 {
dd701109 938 if (proj->GetBinContent(i) != 0)
cfc19dd5 939 {
dd701109 940 Float_t value = (proj->GetBinContent(i) - fMultiplicityESDCorrected[esdCorrId]->GetBinContent(i)) / proj->GetBinContent(i);
cfc19dd5 941 chi2 += value * value;
447c325d 942 chi += TMath::Abs(value);
dd701109 943
447c325d 944 //printf("%d %f\n", i, chi);
cfc19dd5 945
447c325d 946 if (chi2 < 0.2)
947 fLastChi2MCLimit = i;
cfc19dd5 948
447c325d 949 if (chi < 3)
950 limit = i;
cfc19dd5 951
447c325d 952 }
953 }*/
9ca6be09 954
0b4bfd98 955 /*chi2 = 0;
447c325d 956 Float_t chi = 0;
957 Int_t limit = 0;
958 for (Int_t i=1; i<=diffMCUnfolded->GetNbinsX(); ++i)
cfc19dd5 959 {
447c325d 960 if (fMultiplicityESDCorrected[esdCorrId]->GetBinError(i) > 0)
cfc19dd5 961 {
447c325d 962 Double_t value = diffMCUnfolded->GetBinContent(i) / fMultiplicityESDCorrected[esdCorrId]->GetBinError(i);
963 if (value > 1e8)
964 value = 1e8; //prevent arithmetic exception
965 else if (value < -1e8)
966 value = -1e8;
967 if (i > 1)
968 {
969 chi2 += value * value;
970 chi += TMath::Abs(value);
971 }
972 diffMCUnfolded->SetBinContent(i, value);
cfc19dd5 973 }
447c325d 974 else
975 {
976 //printf("diffMCUnfolded bin %d set to 0\n", i);
977 diffMCUnfolded->SetBinContent(i, 0);
978 }
979 if (chi2 < 1000)
980 fLastChi2MCLimit = i;
981 if (chi < 1000)
982 limit = i;
983 if (i == 150)
984 fLastChi2MC = chi2;
cfc19dd5 985 }
0a173978 986
447c325d 987 printf("limits %d %d\n", fLastChi2MCLimit, limit);
988 fLastChi2MCLimit = limit;
989
0b4bfd98 990 printf("Difference (from MC) is %f for bin 2-150. Limit is %d.\n", fLastChi2MC, fLastChi2MCLimit);*/
0a173978 991
447c325d 992 if (!simple)
993 {
0b4bfd98 994 /*canvas1->cd(3);
447c325d 995
0b4bfd98 996 diffMCUnfolded->SetTitle("#chi^{2};Npart;(MC - Unfolded) / e(unfolded)");
447c325d 997 //diffMCUnfolded->GetYaxis()->SetRangeUser(-20, 20);
998 diffMCUnfolded->GetXaxis()->SetRangeUser(0, 200);
999 diffMCUnfolded->DrawCopy("HIST");
0a173978 1000
447c325d 1001 TH1F* fluctuation = new TH1F("fluctuation", "fluctuation", 20, -5, 5);
1002 for (Int_t i=20; i<=diffMCUnfolded->GetNbinsX(); ++i)
1003 fluctuation->Fill(diffMCUnfolded->GetBinContent(i));
3602328d 1004
0b4bfd98 1005 //new TCanvas; fluctuation->DrawCopy();
1006 delete fluctuation;*/
447c325d 1007
1008 /*TLegend* legend = new TLegend(0.6, 0.7, 0.85, 0.85);
1009 legend->AddEntry(fMultiplicityESDCorrected, "ESD corrected");
1010 legend->AddEntry(fMultiplicityMC, "MC");
1011 legend->AddEntry(fMultiplicityESD, "ESD");
1012 legend->Draw();*/
1013
1014 canvas1->cd(4);
039e265e 1015 residual->GetYaxis()->SetRangeUser(-5, 5);
447c325d 1016 residual->GetXaxis()->SetRangeUser(0, 200);
1017 residual->DrawCopy();
1018
1019 canvas1->cd(5);
1020
1021 TH1* ratio = (TH1*) fMultiplicityESDCorrected[esdCorrId]->Clone("ratio");
1022 ratio->Divide(mcHist);
1023 ratio->SetTitle("Ratio;true multiplicity;Unfolded / MC");
1024 ratio->GetYaxis()->SetRangeUser(0.5, 1.5);
1025 ratio->GetXaxis()->SetRangeUser(0, 200);
1026 ratio->SetStats(kFALSE);
1027 ratio->Draw("HIST");
1028
1029 Double_t ratioChi2 = 0;
0b4bfd98 1030 fRatioAverage = 0;
447c325d 1031 fLastChi2MCLimit = 0;
1032 for (Int_t i=2; i<=150; ++i)
1033 {
1034 Float_t value = ratio->GetBinContent(i) - 1;
1035 if (value > 1e8)
1036 value = 1e8; //prevent arithmetic exception
1037 else if (value < -1e8)
1038 value = -1e8;
1039
1040 ratioChi2 += value * value;
0b4bfd98 1041 fRatioAverage += TMath::Abs(value);
447c325d 1042
1043 if (ratioChi2 < 0.1)
1044 fLastChi2MCLimit = i;
1045 }
0b4bfd98 1046 fRatioAverage /= 149;
447c325d 1047
0b4bfd98 1048 printf("Sum over (ratio-1)^2 (2..150) is %f; average of |ratio-1| is %f\n", ratioChi2, fRatioAverage);
447c325d 1049 // TODO FAKE
1050 fLastChi2MC = ratioChi2;
0b4bfd98 1051
1052 // FFT of ratio
1053 canvas1->cd(6);
1054 const Int_t kFFT = 128;
1055 Double_t fftReal[kFFT];
1056 Double_t fftImag[kFFT];
1057
1058 for (Int_t i=0; i<kFFT; ++i)
1059 {
1060 fftReal[i] = ratio->GetBinContent(i+1+10);
1061 // test: ;-)
1062 //fftReal[i] = cos(TMath::Pi() * 5 * 2 * i / 128);
1063 fftImag[i] = 0;
1064 }
1065
04054a84 1066 FFT(-1, TMath::Nint(TMath::Log(kFFT) / TMath::Log(2)), fftReal, fftImag);
0b4bfd98 1067
1068 TH1* fftResult = (TH1*) ratio->Clone("fftResult");
1069 fftResult->SetTitle("FFT;true multiplicity;coeff. (10...137)");
1070 TH1* fftResult2 = (TH1*) ratio->Clone("fftResult2");
1071 TH1* fftResult3 = (TH1*) ratio->Clone("fftResult3");
1072 fftResult->Reset();
1073 fftResult2->Reset();
1074 fftResult3->Reset();
1075 fftResult->GetYaxis()->UnZoom();
1076 fftResult2->GetYaxis()->UnZoom();
1077 fftResult3->GetYaxis()->UnZoom();
1078
0f67a57c 1079 //Printf("AFTER FFT");
0b4bfd98 1080 for (Int_t i=0; i<kFFT; ++i)
1081 {
0f67a57c 1082 //Printf("%d: %f", i, fftReal[i]);
0b4bfd98 1083 fftResult->SetBinContent(i+1, fftReal[i]);
1084 /*if (i != 0 && TMath::Abs(fftReal[i]) > 0.5)
1085 {
1086 Printf("Nulled %d", i);
1087 fftReal[i] = 0;
1088 }*/
1089 }
1090
1091 fftResult->SetLineColor(1);
1092 fftResult->DrawCopy();
1093
1094
0f67a57c 1095 //Printf("IMAG");
0b4bfd98 1096 for (Int_t i=0; i<kFFT; ++i)
1097 {
0f67a57c 1098 //Printf("%d: %f", i, fftImag[i]);
0b4bfd98 1099 fftResult2->SetBinContent(i+1, fftImag[i]);
1100
1101 fftResult3->SetBinContent(i+1, TMath::Sqrt(fftReal[i] * fftReal[i] + fftImag[i] * fftImag[i]));
1102 }
1103
1104 fftResult2->SetLineColor(2);
1105 fftResult2->DrawCopy("SAME");
1106
1107 fftResult3->SetLineColor(4);
1108 fftResult3->DrawCopy("SAME");
1109
1110 for (Int_t i=1; i<kFFT - 1; ++i)
1111 {
1112 if (TMath::Sqrt(fftReal[i] * fftReal[i] + fftImag[i] * fftImag[i]) > 3)
1113 {
1114 fftReal[i-1] = 0;
1115 fftReal[i] = 0;
1116 fftReal[i+1] = 0;
1117 fftImag[i-1] = 0;
1118 fftImag[i] = 0;
1119 fftImag[i+1] = 0;
1120 //fftReal[i] = (fftReal[i-1] + fftReal[i+1]) / 2;
1121 //fftImag[i] = (fftImag[i-1] + fftImag[i+1]) / 2;
0f67a57c 1122 //Printf("Nulled %d to %f %f", i, fftReal[i], fftImag[i]);
0b4bfd98 1123 }
1124 }
1125
04054a84 1126 FFT(1, TMath::Nint(TMath::Log(kFFT) / TMath::Log(2)), fftReal, fftImag);
0b4bfd98 1127
1128 TH1* fftResult4 = (TH1*) fftResult3->Clone("fftResult4");
1129 fftResult4->Reset();
1130
0f67a57c 1131 //Printf("AFTER BACK-TRAFO");
0b4bfd98 1132 for (Int_t i=0; i<kFFT; ++i)
1133 {
0f67a57c 1134 //Printf("%d: %f", i, fftReal[i]);
0b4bfd98 1135 fftResult4->SetBinContent(i+1+10, fftReal[i]);
1136 }
1137
1138 canvas1->cd(5);
1139 fftResult4->SetLineColor(4);
1140 fftResult4->DrawCopy("SAME");
1141
1142 // plot (MC - Unfolded) / error (MC)
1143 canvas1->cd(3);
1144
1145 TH1* diffMCUnfolded2 = dynamic_cast<TH1*> (proj->Clone("diffMCUnfolded2"));
1146 diffMCUnfolded2->Add(fMultiplicityESDCorrected[esdCorrId], -1);
1147
1148 Int_t ndfQual[kQualityRegions];
1149 for (Int_t region=0; region<kQualityRegions; ++region)
1150 {
1151 fQuality[region] = 0;
1152 ndfQual[region] = 0;
1153 }
1154
1155
1156 Double_t newChi2 = 0;
6d81c2de 1157 Double_t newChi2Limit150 = 0;
0b4bfd98 1158 Int_t ndf = 0;
19442b86 1159 for (Int_t i=1; i<=diffMCUnfolded2->GetNbinsX(); ++i)
0b4bfd98 1160 {
1161 Double_t value = 0;
1162 if (proj->GetBinError(i) > 0)
1163 {
1164 value = diffMCUnfolded2->GetBinContent(i) / proj->GetBinError(i);
1165 newChi2 += value * value;
1166 if (i > 1 && i <= mcBinLimit)
6d81c2de 1167 newChi2Limit150 += value * value;
0b4bfd98 1168 ++ndf;
1169
1170 for (Int_t region=0; region<kQualityRegions; ++region)
1171 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
1172 {
1173 fQuality[region] += TMath::Abs(value);
1174 ++ndfQual[region];
1175 }
1176 }
1177
1178 diffMCUnfolded2->SetBinContent(i, value);
1179 }
1180
1181 // normalize region to the number of entries
1182 for (Int_t region=0; region<kQualityRegions; ++region)
1183 {
1184 if (ndfQual[region] > 0)
1185 fQuality[region] /= ndfQual[region];
1186 Printf("Quality parameter %d (%d <= mult <= %d) is %f with %d df", region, fgQualityRegionsB[region], fgQualityRegionsE[region], fQuality[region], ndfQual[region]);
1187 }
1188
1189 if (mcBinLimit > 1)
1190 {
1191 // TODO another FAKE
6d81c2de 1192 fLastChi2MC = newChi2Limit150 / (mcBinLimit - 1);
1193 Printf("Chi2 (2..%d) from (MC - Unfolded) / e(MC) is: %.2f ndf is %d --> chi2 / ndf = %.2f", mcBinLimit, newChi2Limit150, mcBinLimit - 1, fLastChi2MC);
0b4bfd98 1194 }
1195 else
1196 fLastChi2MC = -1;
1197
144ff489 1198 Printf("Chi2 (full range) from (MC - Unfolded) / e(MC) is: %.2f ndf is %d --> chi2 / ndf = %.2f", newChi2, ndf, ((ndf > 0) ? newChi2 / ndf : -1));
0b4bfd98 1199
1200 diffMCUnfolded2->SetTitle("#chi^{2};Npart;(MC - Unfolded) / e(MC)");
039e265e 1201 diffMCUnfolded2->GetYaxis()->SetRangeUser(-5, 5);
0b4bfd98 1202 diffMCUnfolded2->GetXaxis()->SetRangeUser(0, 200);
1203 diffMCUnfolded2->DrawCopy("HIST");
447c325d 1204 }
3602328d 1205
b477f4f2 1206 canvas1->SaveAs(Form("%s.gif", canvas1->GetName()));
0a173978 1207}
1208
1209//____________________________________________________________________
0b4bfd98 1210void AliMultiplicityCorrection::FFT(Int_t dir, Int_t m, Double_t *x, Double_t *y)
1211{
1212/*-------------------------------------------------------------------------
1213 This computes an in-place complex-to-complex FFT
1214 x and y are the real and imaginary arrays of 2^m points.
1215 dir = 1 gives forward transform
1216 dir = -1 gives reverse transform
1217
1218 Formula: forward
1219 N-1
1220 ---
1221 1 \ - j k 2 pi n / N
1222 X(n) = --- > x(k) e = forward transform
1223 N / n=0..N-1
1224 ---
1225 k=0
1226
1227 Formula: reverse
1228 N-1
1229 ---
1230 \ j k 2 pi n / N
1231 X(n) = > x(k) e = forward transform
1232 / n=0..N-1
1233 ---
1234 k=0
1235*/
1236
1237 Long_t nn, i, i1, j, k, i2, l, l1, l2;
1238 Double_t c1, c2, tx, ty, t1, t2, u1, u2, z;
1239
1240 /* Calculate the number of points */
1241 nn = 1;
1242 for (i = 0; i < m; i++)
1243 nn *= 2;
1244
1245 /* Do the bit reversal */
1246 i2 = nn >> 1;
1247 j = 0;
1248 for (i= 0; i < nn - 1; i++) {
1249 if (i < j) {
1250 tx = x[i];
1251 ty = y[i];
1252 x[i] = x[j];
1253 y[i] = y[j];
1254 x[j] = tx;
1255 y[j] = ty;
1256 }
1257 k = i2;
1258 while (k <= j) {
1259 j -= k;
1260 k >>= 1;
1261 }
1262 j += k;
1263 }
1264
1265 /* Compute the FFT */
1266 c1 = -1.0;
1267 c2 = 0.0;
1268 l2 = 1;
1269 for (l = 0; l < m; l++) {
1270 l1 = l2;
1271 l2 <<= 1;
1272 u1 = 1.0;
1273 u2 = 0.0;
1274 for (j = 0;j < l1; j++) {
1275 for (i = j; i < nn; i += l2) {
1276 i1 = i + l1;
1277 t1 = u1 * x[i1] - u2 * y[i1];
1278 t2 = u1 * y[i1] + u2 * x[i1];
1279 x[i1] = x[i] - t1;
1280 y[i1] = y[i] - t2;
1281 x[i] += t1;
1282 y[i] += t2;
1283 }
1284 z = u1 * c1 - u2 * c2;
1285 u2 = u1 * c2 + u2 * c1;
1286 u1 = z;
1287 }
1288 c2 = TMath::Sqrt((1.0 - c1) / 2.0);
1289 if (dir == 1)
1290 c2 = -c2;
1291 c1 = TMath::Sqrt((1.0 + c1) / 2.0);
1292 }
1293
1294 /* Scaling for forward transform */
1295 if (dir == 1) {
1296 for (i=0;i<nn;i++) {
1297 x[i] /= (Double_t)nn;
1298 y[i] /= (Double_t)nn;
1299 }
1300 }
1301}
1302
1303//____________________________________________________________________
6d81c2de 1304void AliMultiplicityCorrection::GetComparisonResults(Float_t* mc, Int_t* mcLimit, Float_t* residuals, Float_t* ratioAverage) const
cfc19dd5 1305{
1306 // Returns the chi2 between the MC and the unfolded ESD as well as between the ESD and the folded unfolded ESD
1307 // These values are computed during DrawComparison, thus this function picks up the
1308 // last calculation
1309
dd701109 1310 if (mc)
1311 *mc = fLastChi2MC;
1312 if (mcLimit)
1313 *mcLimit = fLastChi2MCLimit;
1314 if (residuals)
1315 *residuals = fLastChi2Residuals;
0b4bfd98 1316 if (ratioAverage)
1317 *ratioAverage = fRatioAverage;
cfc19dd5 1318}
1319
cfc19dd5 1320//____________________________________________________________________
1321TH2F* AliMultiplicityCorrection::GetMultiplicityMC(Int_t i, EventType eventType)
1322{
1323 //
1324 // returns the corresponding MC spectrum
1325 //
1326
1327 switch (eventType)
1328 {
1329 case kTrVtx : return fMultiplicityVtx[i]; break;
1330 case kMB : return fMultiplicityMB[i]; break;
1331 case kINEL : return fMultiplicityINEL[i]; break;
69b09e3b 1332 case kNSD : return fMultiplicityNSD[i]; break;
cfc19dd5 1333 }
1334
1335 return 0;
1336}
1337
69b09e3b 1338//____________________________________________________________________
1339void AliMultiplicityCorrection::SetMultiplicityMC(Int_t i, EventType eventType, TH2F* hist)
1340{
1341 //
1342 // returns the corresponding MC spectrum
1343 //
1344
1345 switch (eventType)
1346 {
1347 case kTrVtx : fMultiplicityVtx[i] = hist; break;
1348 case kMB : fMultiplicityMB[i] = hist; break;
1349 case kINEL : fMultiplicityINEL[i] = hist; break;
1350 case kNSD : fMultiplicityNSD[i] = hist; break;
1351 }
1352}
1353
0f67a57c 1354//____________________________________________________________________
1355TH1* AliMultiplicityCorrection::CalculateStdDev(TH1** results, Int_t max)
1356{
1357 // calculate standard deviation of (results[0] - results[k]) k=1...max-1
1358 // per bin one gets: sigma(r[0] - r[n]) / r[0]
1359
1360 TH1* standardDeviation = (TH1*) results[0]->Clone("standardDeviation");
1361 standardDeviation->Reset();
1362
1363 for (Int_t x=1; x<=results[0]->GetNbinsX(); x++)
1364 {
1365 if (results[0]->GetBinContent(x) > 0)
1366 {
1367 Double_t average = 0;
1368 for (Int_t n=1; n<max; ++n)
1369 average += results[n]->GetBinContent(x) - results[0]->GetBinContent(x);
1370 average /= max-1;
1371
1372 Double_t variance = 0;
1373 for (Int_t n=1; n<max; ++n)
1374 {
1375 Double_t value = results[n]->GetBinContent(x) - results[0]->GetBinContent(x) - average;
1376 variance += value * value;
1377 }
1378 variance /= max-1;
1379
1380 Double_t standardDev = TMath::Sqrt(variance);
1381 standardDeviation->SetBinContent(x, standardDev / results[0]->GetBinContent(x));
1382 //Printf("sigma_%d is %f value %f --> error %f", x, standardDev, results[0]->GetBinContent(x), standardDev / results[0]->GetBinContent(x));
1383 }
1384 }
1385
1386 return standardDeviation;
1387}
1388
cfc19dd5 1389//____________________________________________________________________
19442b86 1390TH1* AliMultiplicityCorrection::StatisticalUncertainty(AliUnfolding::MethodType methodType, Int_t inputRange, Bool_t fullPhaseSpace, EventType eventType, Bool_t randomizeMeasured, Bool_t randomizeResponse, TH1* compareTo)
0a173978 1391{
1392 //
0b4bfd98 1393 // evaluates the uncertainty that arises from the non-infinite statistics in the response matrix
1394 // the function unfolds the spectrum using the default response matrix and several modified ones
1395 // the modified ones are created by randomizing each cell using poisson statistics with the mean = bin value
1396 // these unfolded results are compared to the first result gained with the default response OR to the histogram given
1397 // in <compareTo> (optional)
0a173978 1398 //
0b4bfd98 1399 // returns the error assigned to the measurement
1400 //
1401
6d81c2de 1402 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
1403
0b4bfd98 1404 // initialize seed with current time
1405 gRandom->SetSeed(0);
19442b86 1406
1407 if (methodType == AliUnfolding::kChi2Minimization)
1408 AliUnfolding::SetCreateOverflowBin(5);
1409 AliUnfolding::SetUnfoldingMethod(methodType);
0b4bfd98 1410
1411 const Int_t kErrorIterations = 150;
1412
1413 TH1* maxError = 0;
1414 TH1* firstResult = 0;
1415
1416 TH1** results = new TH1*[kErrorIterations];
1417
1418 for (Int_t n=0; n<kErrorIterations; ++n)
1419 {
1420 Printf("Iteration %d of %d...", n, kErrorIterations);
1421
19442b86 1422 SetupCurrentHists(inputRange, fullPhaseSpace, eventType);
0b4bfd98 1423
1424 TH1* measured = (TH1*) fCurrentESD->Clone("measured");
1425
1426 if (n > 0)
1427 {
1428 if (randomizeResponse)
1429 {
1430 // randomize response matrix
1431 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
1432 for (Int_t j=1; j<=fCurrentCorrelation->GetNbinsY(); ++j)
1433 fCurrentCorrelation->SetBinContent(i, j, gRandom->Poisson(fCurrentCorrelation->GetBinContent(i, j)));
1434 }
1435
1436 if (randomizeMeasured)
1437 {
1438 // randomize measured spectrum
1439 for (Int_t x=1; x<=measured->GetNbinsX(); x++) // mult. axis
1440 {
1441 Int_t randomValue = gRandom->Poisson(fCurrentESD->GetBinContent(x));
1442 measured->SetBinContent(x, randomValue);
1443 measured->SetBinError(x, TMath::Sqrt(randomValue));
1444 }
1445 }
1446 }
1447
6d81c2de 1448 // only for bayesian method we have to do it before the call to Unfold...
19442b86 1449 if (methodType == AliUnfolding::kBayesian)
0b4bfd98 1450 {
6d81c2de 1451 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
0b4bfd98 1452 {
6d81c2de 1453 // with this it is normalized to 1
1454 Double_t sum = fCurrentCorrelation->Integral(i, i, 1, fCurrentCorrelation->GetNbinsY());
1455
1456 // with this normalized to the given efficiency
1457 if (fCurrentEfficiency->GetBinContent(i) > 0)
1458 sum /= fCurrentEfficiency->GetBinContent(i);
0b4bfd98 1459 else
6d81c2de 1460 sum = 0;
1461
1462 for (Int_t j=1; j<=fCurrentCorrelation->GetNbinsY(); ++j)
0b4bfd98 1463 {
6d81c2de 1464 if (sum > 0)
1465 {
1466 fCurrentCorrelation->SetBinContent(i, j, fCurrentCorrelation->GetBinContent(i, j) / sum);
1467 fCurrentCorrelation->SetBinError(i, j, fCurrentCorrelation->GetBinError(i, j) / sum);
1468 }
1469 else
1470 {
1471 fCurrentCorrelation->SetBinContent(i, j, 0);
1472 fCurrentCorrelation->SetBinError(i, j, 0);
1473 }
0b4bfd98 1474 }
1475 }
1476 }
1477
1478 TH1* result = 0;
1479 if (n == 0 && compareTo)
1480 {
1481 // in this case we just store the histogram we want to compare to
1482 result = (TH1*) compareTo->Clone("compareTo");
1483 result->Sumw2();
1484 }
1485 else
6d81c2de 1486 {
1487 result = (TH1*) fMultiplicityESDCorrected[correlationID]->Clone(Form("result_%d", n));
0b4bfd98 1488
19442b86 1489 Int_t returnCode = AliUnfolding::Unfold(fCurrentCorrelation, fCurrentEfficiency, measured, 0, result);
6d81c2de 1490
1491 if (returnCode != 0)
1492 return 0;
1493 }
0b4bfd98 1494
1495 // normalize
1496 result->Scale(1.0 / result->Integral());
1497
1498 if (n == 0)
1499 {
1500 firstResult = (TH1*) result->Clone("firstResult");
1501
1502 maxError = (TH1*) result->Clone("maxError");
1503 maxError->Reset();
1504 }
1505 else
1506 {
1507 // calculate ratio
1508 TH1* ratio = (TH1*) firstResult->Clone("ratio");
1509 ratio->Divide(result);
1510
1511 // find max. deviation
1512 for (Int_t x=1; x<=ratio->GetNbinsX(); x++)
1513 maxError->SetBinContent(x, TMath::Max(maxError->GetBinContent(x), TMath::Abs(1 - ratio->GetBinContent(x))));
1514
1515 delete ratio;
1516 }
1517
1518 results[n] = result;
1519 }
1520
1521 // find covariance matrix
1522 // results[n] is X_x
1523 // cov. matrix is M_xy = E ( (X_x - E(X_x)) * (X_y - E(X_y))), with E() = expectation value
1524
1525 Int_t nBins = results[0]->GetNbinsX();
1526 Float_t lowEdge = results[0]->GetXaxis()->GetBinLowEdge(1);
1527 Float_t upEdge = results[0]->GetXaxis()->GetBinUpEdge(nBins);
1528
1529 // find average, E(X)
1530 TProfile* average = new TProfile("average", "average", nBins, lowEdge, upEdge);
1531 for (Int_t n=1; n<kErrorIterations; ++n)
1532 for (Int_t x=1; x<=results[n]->GetNbinsX(); x++)
1533 average->Fill(results[n]->GetXaxis()->GetBinCenter(x), results[n]->GetBinContent(x));
1534 //new TCanvas; average->DrawClone();
69b09e3b 1535
0b4bfd98 1536 // find cov. matrix
1537 TProfile2D* covMatrix = new TProfile2D("covMatrix", "covMatrix", nBins, lowEdge, upEdge, nBins, lowEdge, upEdge);
1538
1539 for (Int_t n=1; n<kErrorIterations; ++n)
1540 for (Int_t x=1; x<=results[n]->GetNbinsX(); x++)
1541 for (Int_t y=1; y<=results[n]->GetNbinsX(); y++)
1542 {
1543 // (X_x - E(X_x)) * (X_y - E(X_y)
1544 Float_t cov = (results[n]->GetBinContent(x) - average->GetBinContent(x)) * (results[n]->GetBinContent(y) - average->GetBinContent(y));
1545 covMatrix->Fill(results[n]->GetXaxis()->GetBinCenter(x), results[n]->GetXaxis()->GetBinCenter(y), cov);
1546 }
69b09e3b 1547 TCanvas* c = new TCanvas; c->cd(); covMatrix->DrawCopy("COLZ");
0b4bfd98 1548
6d81c2de 1549// // fill 2D histogram that contains deviation from first
1550// TH2F* deviations = new TH2F("deviations", "deviations", nBins, lowEdge, upEdge, 1000, -0.01, 0.01);
1551// for (Int_t n=1; n<kErrorIterations; ++n)
1552// for (Int_t x=1; x<=results[n]->GetNbinsX(); x++)
1553// deviations->Fill(results[n]->GetXaxis()->GetBinCenter(x), results[n]->GetBinContent(x) - results[0]->GetBinContent(x));
1554// //new TCanvas; deviations->DrawCopy("COLZ");
1555//
1556// // get standard deviation "by hand"
1557// for (Int_t x=1; x<=nBins; x++)
1558// {
1559// if (results[0]->GetBinContent(x) > 0)
1560// {
1561// TH1* proj = deviations->ProjectionY("projRMS", x, x, "e");
1562// Float_t standardDev = proj->GetRMS(); // this is standard deviation in fact
1563// //standardDeviation->SetBinContent(x, standardDev / results[0]->GetBinContent(x));
1564// Printf("sigma_%d is %f value %f --> error %f", x, standardDev, results[0]->GetBinContent(x), standardDev / results[0]->GetBinContent(x));
1565// }
1566// }
1567
0f67a57c 1568 TH1* standardDeviation = CalculateStdDev(results, kErrorIterations);
0b4bfd98 1569
1570 // compare maxError to RMS of profile (variable name: average)
1571 // first: calculate rms in percent of value
1572 TH1* rmsError = (TH1*) maxError->Clone("rmsError");
1573 rmsError->Reset();
1574
1575 // enable error to be standard deviation (see http://root.cern.ch/root/html/TProfile.html#TProfile:SetErrorOption)
1576 average->SetErrorOption("s");
1577 for (Int_t x=1; x<=rmsError->GetNbinsX(); x++)
1578 if (average->GetBinContent(x) > 0)
1579 rmsError->SetBinContent(x, average->GetBinError(x) / average->GetBinContent(x));
1580
1581 // find maxError deviation from average (not from "first result"/mc as above)
1582 TH1* maxError2 = (TH1*) maxError->Clone("maxError2");
1583 maxError2->Reset();
1584 for (Int_t n=1; n<kErrorIterations; ++n)
1585 for (Int_t x=1; x<=results[n]->GetNbinsX(); x++)
1586 if (average->GetBinContent(x) > 0)
1587 maxError2->SetBinContent(x, TMath::Max(maxError2->GetBinContent(x), TMath::Abs((results[n]->GetBinContent(x) - average->GetBinContent(x)) / average->GetBinContent(x))));
1588
6d81c2de 1589 //new TCanvas; maxError2->DrawCopy(); rmsError->SetLineColor(2); rmsError->DrawCopy("SAME"); standardDeviation->SetLineColor(3); standardDeviation->DrawCopy("SAME");
0b4bfd98 1590
1591 // plot difference between average and MC/first result
1592 TH1* averageFirstRatio = (TH1*) results[0]->Clone("averageFirstRatio");
1593 averageFirstRatio->Reset();
1594 averageFirstRatio->Divide(results[0], average);
1595
6d81c2de 1596 //new TCanvas; results[0]->DrawCopy(); average->SetLineColor(2); average->DrawClone("SAME");
1597 //new TCanvas; averageFirstRatio->DrawCopy();
0b4bfd98 1598
69b09e3b 1599 static TH1* temp = 0;
1600 if (!temp)
1601 {
1602 temp = (TH1*) standardDeviation->Clone("temp");
1603 for (Int_t x=1; x<=results[0]->GetNbinsX(); x++)
1604 temp->SetBinContent(x, temp->GetBinContent(x) * results[0]->GetBinContent(x));
1605 }
1606 else
1607 {
1608 // find difference from result[0] as TH2
1609 TH2F* pulls = new TH2F("pulls", "pulls;multiplicity;difference", nBins, lowEdge, upEdge, 1000, -10, 10);
1610 for (Int_t n=1; n<kErrorIterations; ++n)
1611 for (Int_t x=1; x<=results[n]->GetNbinsX(); x++)
1612 if (temp->GetBinContent(x) > 0)
1613 pulls->Fill(results[n]->GetXaxis()->GetBinCenter(x), (results[0]->GetBinContent(x) - results[n]->GetBinContent(x)) / temp->GetBinContent(x));
1614 new TCanvas("pulls", "pulls", 800, 600); pulls->DrawCopy(); pulls->FitSlicesY();
1615 }
1616
0b4bfd98 1617 // clean up
1618 for (Int_t n=0; n<kErrorIterations; ++n)
1619 delete results[n];
1620 delete[] results;
1621
1622 // fill into result histogram
0b4bfd98 1623 for (Int_t i=1; i<=fMultiplicityESDCorrected[correlationID]->GetNbinsX(); ++i)
1624 fMultiplicityESDCorrected[correlationID]->SetBinContent(i, firstResult->GetBinContent(i));
cfc19dd5 1625
0b4bfd98 1626 for (Int_t i=1; i<=fMultiplicityESDCorrected[correlationID]->GetNbinsX(); ++i)
1627 fMultiplicityESDCorrected[correlationID]->SetBinError(i, maxError->GetBinContent(i) * fMultiplicityESDCorrected[correlationID]->GetBinContent(i));
447c325d 1628
0b4bfd98 1629 return standardDeviation;
1630}
1631
1632//____________________________________________________________________
6d81c2de 1633void AliMultiplicityCorrection::ApplyBayesianMethod(Int_t inputRange, Bool_t fullPhaseSpace, EventType eventType, Float_t regPar, Int_t nIterations, TH1* initialConditions, Bool_t determineError)
0b4bfd98 1634{
1635 //
1636 // correct spectrum using bayesian method
1637 //
1638
1639 // initialize seed with current time
1640 gRandom->SetSeed(0);
1641
19442b86 1642 SetupCurrentHists(inputRange, fullPhaseSpace, eventType);
0a173978 1643
1644 // normalize correction for given nPart
9ca6be09 1645 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
0a173978 1646 {
dd701109 1647 // with this it is normalized to 1
1648 Double_t sum = fCurrentCorrelation->Integral(i, i, 1, fCurrentCorrelation->GetNbinsY());
1649
1650 // with this normalized to the given efficiency
1651 if (fCurrentEfficiency->GetBinContent(i) > 0)
1652 sum /= fCurrentEfficiency->GetBinContent(i);
1653 else
1654 sum = 0;
1655
9ca6be09 1656 for (Int_t j=1; j<=fCurrentCorrelation->GetNbinsY(); ++j)
0a173978 1657 {
dd701109 1658 if (sum > 0)
1659 {
1660 fCurrentCorrelation->SetBinContent(i, j, fCurrentCorrelation->GetBinContent(i, j) / sum);
1661 fCurrentCorrelation->SetBinError(i, j, fCurrentCorrelation->GetBinError(i, j) / sum);
1662 }
1663 else
1664 {
1665 fCurrentCorrelation->SetBinContent(i, j, 0);
1666 fCurrentCorrelation->SetBinError(i, j, 0);
1667 }
0a173978 1668 }
1669 }
1670
0b4bfd98 1671 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
1672
19442b86 1673 AliUnfolding::SetBayesianParameters(regPar, nIterations);
1674 AliUnfolding::SetUnfoldingMethod(AliUnfolding::kBayesian);
1675 if (AliUnfolding::Unfold(fCurrentCorrelation, fCurrentEfficiency, fCurrentESD, initialConditions, fMultiplicityESDCorrected[correlationID]) != 0)
0b4bfd98 1676 return;
1677
0b4bfd98 1678 if (!determineError)
447c325d 1679 {
0b4bfd98 1680 Printf("AliMultiplicityCorrection::ApplyBayesianMethod: WARNING: No errors calculated.");
1681 return;
1682 }
447c325d 1683
0b4bfd98 1684 // evaluate errors, this is done by randomizing the measured spectrum following Poission statistics
1685 // this (new) measured spectrum is then unfolded and the different to the result from the "real" measured
0f67a57c 1686 // spectrum calculated. This is performed N times and the sigma is taken as the statistical
0b4bfd98 1687 // error of the unfolding method itself.
1688
0b4bfd98 1689 const Int_t kErrorIterations = 20;
1690
1691 printf("Spectrum unfolded. Determining error (%d iterations)...\n", kErrorIterations);
1692
1693 TH1* randomized = (TH1*) fCurrentESD->Clone("randomized");
0f67a57c 1694 TH1* resultArray[kErrorIterations+1];
0b4bfd98 1695 for (Int_t n=0; n<kErrorIterations; ++n)
1696 {
1697 // randomize the content of clone following a poisson with the mean = the value of that bin
1698 for (Int_t x=1; x<=randomized->GetNbinsX(); x++) // mult. axis
447c325d 1699 {
0b4bfd98 1700 Int_t randomValue = gRandom->Poisson(fCurrentESD->GetBinContent(x));
1701 //printf("%d --> %d\n", fCurrentESD->GetBinContent(x), randomValue);
1702 randomized->SetBinContent(x, randomValue);
1703 randomized->SetBinError(x, TMath::Sqrt(randomValue));
447c325d 1704 }
447c325d 1705
0f67a57c 1706 TH1* result2 = (TH1*) fMultiplicityESDCorrected[correlationID]->Clone("result2");
6d81c2de 1707 result2->Reset();
19442b86 1708 if (AliUnfolding::Unfold(fCurrentCorrelation, fCurrentEfficiency, randomized, initialConditions, result2) != 0)
0b4bfd98 1709 return;
cfc19dd5 1710
0b4bfd98 1711 result2->Scale(1.0 / result2->Integral());
cfc19dd5 1712
0f67a57c 1713 resultArray[n+1] = result2;
0b4bfd98 1714 }
6d81c2de 1715 delete randomized;
0f67a57c 1716
1717 resultArray[0] = fMultiplicityESDCorrected[correlationID];
1718 TH1* error = CalculateStdDev(resultArray, kErrorIterations+1);
1719
1720 for (Int_t n=0; n<kErrorIterations; ++n)
1721 delete resultArray[n+1];
447c325d 1722
0b4bfd98 1723 for (Int_t i=1; i<=fMultiplicityESDCorrected[correlationID]->GetNbinsX(); ++i)
0f67a57c 1724 fMultiplicityESDCorrected[correlationID]->SetBinError(i, error->GetBinContent(i) * fMultiplicityESDCorrected[correlationID]->GetBinContent(i));
447c325d 1725
0f67a57c 1726 delete error;
0b4bfd98 1727}
447c325d 1728
dd701109 1729//____________________________________________________________________
0b4bfd98 1730Float_t AliMultiplicityCorrection::BayesCovarianceDerivate(Float_t matrixM[251][251], TH2* hResponse, Int_t k, Int_t i, Int_t r, Int_t u)
dd701109 1731{
1732 //
1733 // helper function for the covariance matrix of the bayesian method
1734 //
1735
1736 Float_t result = 0;
1737
1738 if (k == u && r == i)
1739 result += 1.0 / hResponse->GetBinContent(u+1, r+1);
1740
1741 if (k == u)
1742 result -= 1.0 / fCurrentEfficiency->GetBinContent(u+1);
1743
1744 if (r == i)
1745 result -= matrixM[u][i] * fCurrentEfficiency->GetBinContent(u+1) / hResponse->GetBinContent(u+1, i+1);
1746
1747 result *= matrixM[k][i];
1748
1749 return result;
cfc19dd5 1750}
1751
1752//____________________________________________________________________
1753void AliMultiplicityCorrection::ApplyLaszloMethod(Int_t inputRange, Bool_t fullPhaseSpace, EventType eventType)
1754{
1755 //
1756 // correct spectrum using bayesian method
1757 //
1758
dd701109 1759 Float_t regPar = 0;
cfc19dd5 1760
1761 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
1762 Int_t mcTarget = ((fullPhaseSpace == kFALSE) ? inputRange : 4);
1763
19442b86 1764 SetupCurrentHists(inputRange, fullPhaseSpace, eventType);
0b4bfd98 1765 //normalize ESD
1766 fCurrentESD->Scale(1.0 / fCurrentESD->Integral());
cfc19dd5 1767
1768 // TODO should be taken from correlation map
1769 //TH1* sumHist = GetMultiplicityMC(inputRange, eventType)->ProjectionY("sumHist", 1, GetMultiplicityMC(inputRange, eventType)->GetNbinsX());
1770
1771 // normalize correction for given nPart
1772 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
1773 {
1774 Double_t sum = fCurrentCorrelation->Integral(i, i, 1, fCurrentCorrelation->GetNbinsY());
1775 //Double_t sum = sumHist->GetBinContent(i);
1776 if (sum <= 0)
1777 continue;
1778 for (Int_t j=1; j<=fCurrentCorrelation->GetNbinsY(); ++j)
1779 {
1780 // npart sum to 1
1781 fCurrentCorrelation->SetBinContent(i, j, fCurrentCorrelation->GetBinContent(i, j) / sum);
1782 fCurrentCorrelation->SetBinError(i, j, fCurrentCorrelation->GetBinError(i, j) / sum);
1783 }
6127aca6 1784 }
cfc19dd5 1785
1786 new TCanvas;
1787 fCurrentCorrelation->Draw("COLZ");
1788
1789 // FAKE
1790 fCurrentEfficiency = ((TH2*) fCurrentCorrelation)->ProjectionX("eff");
1791
1792 // pick prior distribution
1793 TH1F* hPrior = (TH1F*)fCurrentESD->Clone("prior");
1794 Float_t norm = 1; //hPrior->Integral();
1795 for (Int_t t=1; t<=hPrior->GetNbinsX(); t++)
1796 hPrior->SetBinContent(t, hPrior->GetBinContent(t)/norm);
1797
1798 // zero distribution
1799 TH1F* zero = (TH1F*)hPrior->Clone("zero");
1800
1801 // define temp hist
1802 TH1F* hTemp = (TH1F*)fCurrentESD->Clone("temp");
1803 hTemp->Reset();
1804
1805 // just a shortcut
1806 TH2F* hResponse = (TH2F*) fCurrentCorrelation;
1807
1808 // unfold...
dd701109 1809 Int_t iterations = 25;
cfc19dd5 1810 for (Int_t i=0; i<iterations; i++)
1811 {
1812 //printf(" iteration %i \n", i);
1813
1814 for (Int_t m=1; m<=hResponse->GetNbinsY(); m++)
1815 {
1816 Float_t value = 0;
1817 for (Int_t t = 1; t<=hResponse->GetNbinsX(); t++)
1818 value += hResponse->GetBinContent(t, m) * hPrior->GetBinContent(t);
1819 hTemp->SetBinContent(m, value);
1820 //printf("%d %f %f %f\n", m, zero->GetBinContent(m), hPrior->GetBinContent(m), value);
1821 }
1822
1823 // regularization (simple smoothing)
1824 TH1F* hTrueSmoothed = (TH1F*) hTemp->Clone("truesmoothed");
1825
1826 for (Int_t t=2; t<hTrueSmoothed->GetNbinsX(); t++)
1827 {
1828 Float_t average = (hTemp->GetBinContent(t-1) / hTemp->GetBinWidth(t-1)
1829 + hTemp->GetBinContent(t) / hTemp->GetBinWidth(t)
1830 + hTemp->GetBinContent(t+1) / hTemp->GetBinWidth(t+1)) / 3.;
1831 average *= hTrueSmoothed->GetBinWidth(t);
1832
1833 // weight the average with the regularization parameter
1834 hTrueSmoothed->SetBinContent(t, (1-regPar) * hTemp->GetBinContent(t) + regPar * average);
1835 }
1836
1837 for (Int_t m=1; m<=hResponse->GetNbinsY(); m++)
1838 hTemp->SetBinContent(m, zero->GetBinContent(m) + hPrior->GetBinContent(m) - hTrueSmoothed->GetBinContent(m));
1839
1840 // fill guess
1841 for (Int_t t=1; t<=fMultiplicityESDCorrected[correlationID]->GetNbinsX(); t++)
1842 {
1843 fMultiplicityESDCorrected[correlationID]->SetBinContent(t, hTemp->GetBinContent(t));
1844 fMultiplicityESDCorrected[correlationID]->SetBinError(t, 0.05 * hTemp->GetBinContent(t)); // TODO
1845
1846 //printf(" bin %d content %f \n", t, fMultiplicityESDCorrected[correlationID]->GetBinContent(t));
1847 }
1848
1849
1850 // calculate chi2 (change from last iteration)
1851 Double_t chi2 = 0;
1852
1853 // use smoothed true (normalized) as new prior
745d6088 1854 norm = 1; //hTrueSmoothed->Integral();
cfc19dd5 1855
1856 for (Int_t t=1; t<hTrueSmoothed->GetNbinsX(); t++)
1857 {
dd701109 1858 Float_t newValue = hTemp->GetBinContent(t)/norm;
cfc19dd5 1859 Float_t diff = hPrior->GetBinContent(t) - newValue;
1860 chi2 += (Double_t) diff * diff;
1861
1862 hPrior->SetBinContent(t, newValue);
1863 }
1864
1865 printf("Chi2 of %d iteration = %.10f\n", i, chi2);
1866
dd701109 1867 //if (i % 5 == 0)
cfc19dd5 1868 DrawComparison(Form("Laszlo_%d", i), inputRange, fullPhaseSpace, kTRUE, GetMultiplicityMC(mcTarget, eventType)->ProjectionY());
1869
1870 delete hTrueSmoothed;
1871 } // end of iterations
1872
1873 DrawComparison("Laszlo", inputRange, fullPhaseSpace, kTRUE, GetMultiplicityMC(mcTarget, eventType)->ProjectionY());
1874}
1875
9ca6be09 1876//____________________________________________________________________
1877void AliMultiplicityCorrection::ApplyGaussianMethod(Int_t inputRange, Bool_t fullPhaseSpace)
1878{
1879 //
1880 // correct spectrum using a simple Gaussian approach, that is model-dependent
1881 //
1882
1883 Int_t correlationID = inputRange + ((fullPhaseSpace == kFALSE) ? 0 : 4);
1884 Int_t mcTarget = ((fullPhaseSpace == kFALSE) ? inputRange : 4);
1885
19442b86 1886 SetupCurrentHists(inputRange, fullPhaseSpace, kTrVtx);
0b4bfd98 1887 //normalize ESD
1888 fCurrentESD->Scale(1.0 / fCurrentESD->Integral());
9ca6be09 1889
9ca6be09 1890 TH1D* correction = dynamic_cast<TH1D*> (fCurrentESD->Clone("GaussianMean"));
1891 correction->SetTitle("GaussianMean");
1892
1893 TH1D* correctionWidth = dynamic_cast<TH1D*> (fCurrentESD->Clone("GaussianWidth"));
1894 correction->SetTitle("GaussianWidth");
1895
1896 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
1897 {
1898 TH1D* proj = (dynamic_cast<TH2*> (fCurrentCorrelation))->ProjectionX("_px", i, i+1);
1899 proj->Fit("gaus", "0Q");
1900 correction->SetBinContent(i, proj->GetFunction("gaus")->GetParameter(1));
1901 correctionWidth->SetBinContent(i, proj->GetFunction("gaus")->GetParameter(2));
1902
1903 continue;
1904
1905 // draw for debugging
1906 new TCanvas;
1907 proj->DrawCopy();
1908 proj->GetFunction("gaus")->DrawCopy("SAME");
1909 }
1910
1911 TH1* target = fMultiplicityESDCorrected[correlationID];
1912
1913 Int_t nBins = target->GetNbinsX()*10+1;
1914 Float_t* binning = new Float_t[nBins];
1915 for (Int_t i=1; i<=target->GetNbinsX(); ++i)
1916 for (Int_t j=0; j<10; ++j)
1917 binning[(i-1)*10 + j] = target->GetXaxis()->GetBinLowEdge(i) + target->GetXaxis()->GetBinWidth(i) / 10 * j;
1918
1919 binning[nBins-1] = target->GetXaxis()->GetBinUpEdge(target->GetNbinsX());
1920
1921 TH1F* fineBinned = new TH1F("targetFineBinned", "targetFineBinned", nBins-1, binning);
1922
1923 for (Int_t i=1; i<=fCurrentCorrelation->GetNbinsX(); ++i)
1924 {
1925 Float_t mean = correction->GetBinContent(i);
1926 Float_t width = correctionWidth->GetBinContent(i);
1927
3602328d 1928 Int_t fillBegin = fineBinned->FindBin(mean - width * 5);
1929 Int_t fillEnd = fineBinned->FindBin(mean + width * 5);
1930 //printf("bin %d mean %f width %f, filling from %d to %d\n", i, mean, width, fillBegin, fillEnd);
9ca6be09 1931
1932 for (Int_t j=fillBegin; j <= fillEnd; ++j)
1933 {
1934 fineBinned->AddBinContent(j, TMath::Gaus(fineBinned->GetXaxis()->GetBinCenter(j), mean, width, kTRUE) * fCurrentESD->GetBinContent(i));
1935 }
1936 }
1937
1938 for (Int_t i=1; i<=target->GetNbinsX(); ++i)
1939 {
1940 Float_t sum = 0;
1941 for (Int_t j=1; j<=10; ++j)
1942 sum += fineBinned->GetBinContent((i-1)*10 + j);
1943 target->SetBinContent(i, sum / 10);
1944 }
1945
1946 delete[] binning;
1947
cfc19dd5 1948 DrawComparison("Gaussian", inputRange, fullPhaseSpace, kFALSE, GetMultiplicityMC(mcTarget, kTrVtx)->ProjectionY());
0a173978 1949}
3602328d 1950
1951//____________________________________________________________________
447c325d 1952TH2F* AliMultiplicityCorrection::CalculateMultiplicityESD(TH1* inputMC, Int_t correlationMap)
3602328d 1953{
1954 // runs the distribution given in inputMC through the response matrix identified by
1955 // correlationMap and produces a measured distribution
1956 // although it is a TH2F the vertex axis is not used at the moment and all entries are filled in mid-vertex
b477f4f2 1957 // if normalized is set, inputMC is expected to be normalized to the bin width
3602328d 1958
1959 if (!inputMC)
1960 return 0;
1961
1962 if (correlationMap < 0 || correlationMap >= kCorrHists)
1963 return 0;
1964
1965 // empty under/overflow bins in x, otherwise Project3D takes them into account
1966 TH3* hist = fCorrelation[correlationMap];
039e265e 1967 for (Int_t y=0; y<=hist->GetYaxis()->GetNbins()+1; ++y)
3602328d 1968 {
039e265e 1969 for (Int_t z=0; z<=hist->GetZaxis()->GetNbins()+1; ++z)
3602328d 1970 {
1971 hist->SetBinContent(0, y, z, 0);
1972 hist->SetBinContent(hist->GetXaxis()->GetNbins()+1, y, z, 0);
1973 }
1974 }
1975
447c325d 1976 TH2* corr = (TH2*) hist->Project3D("zy");
1977 //corr->Rebin2D(2, 1);
3602328d 1978 corr->Sumw2();
039e265e 1979 Printf("Correction histogram used for convolution has %f entries", corr->Integral());
3602328d 1980
1981 // normalize correction for given nPart
1982 for (Int_t i=1; i<=corr->GetNbinsX(); ++i)
1983 {
1984 Double_t sum = corr->Integral(i, i, 1, corr->GetNbinsY());
1985 if (sum <= 0)
1986 continue;
1987
1988 for (Int_t j=1; j<=corr->GetNbinsY(); ++j)
1989 {
1990 // npart sum to 1
1991 corr->SetBinContent(i, j, corr->GetBinContent(i, j) / sum);
1992 corr->SetBinError(i, j, corr->GetBinError(i, j) / sum);
1993 }
1994 }
1995
1996 TH2F* target = dynamic_cast<TH2F*> (fMultiplicityESD[0]->Clone(Form("%s_measured", inputMC->GetName())));
1997 target->Reset();
1998
1999 for (Int_t meas=1; meas<=corr->GetNbinsY(); ++meas)
2000 {
2001 Float_t measured = 0;
2002 Float_t error = 0;
2003
447c325d 2004 for (Int_t gen=1; gen<=corr->GetNbinsX(); ++gen)
3602328d 2005 {
447c325d 2006 Int_t mcGenBin = inputMC->GetXaxis()->FindBin(corr->GetXaxis()->GetBinCenter(gen));
b477f4f2 2007
447c325d 2008 measured += inputMC->GetBinContent(mcGenBin) * corr->GetBinContent(gen, meas);
2009 error += inputMC->GetBinError(mcGenBin) * corr->GetBinContent(gen, meas);
3602328d 2010 }
2011
cfc19dd5 2012 //printf("%f +- %f ; %f +- %f \n", inputMC->GetBinContent(meas), inputMC->GetBinError(meas), measured, error);
3602328d 2013
447c325d 2014 target->SetBinContent(1 + target->GetNbinsX() / 2, meas, measured);
2015 target->SetBinError(1 + target->GetNbinsX() / 2, meas, error);
3602328d 2016 }
2017
2018 return target;
2019}
2020
2021//____________________________________________________________________
2022void AliMultiplicityCorrection::SetGenMeasFromFunc(TF1* inputMC, Int_t id)
2023{
2024 // uses the given function to fill the input MC histogram and generates from that
2025 // the measured histogram by applying the response matrix
2026 // this can be used to evaluate if the methods work indepedently of the input
2027 // distribution
2028 // WARNING does not respect the vertex distribution, just fills central vertex bin
2029
2030 if (!inputMC)
2031 return;
2032
2033 if (id < 0 || id >= kESDHists)
2034 return;
2035
69b09e3b 2036 // fill histogram used for random generation
2037 TH1* tmp = fMultiplicityVtx[id]->ProjectionY("tmp");
2038 tmp->Reset();
2039
2040 for (Int_t i=1; i<=tmp->GetNbinsX(); ++i)
2041 tmp->SetBinContent(i, inputMC->Eval(tmp->GetXaxis()->GetBinCenter(i)) * tmp->GetXaxis()->GetBinWidth(i));
2042
2043 TH1* mcRnd = fMultiplicityVtx[id]->ProjectionY("mcRnd");
2044 mcRnd->Reset();
2045 mcRnd->FillRandom(tmp, tmp->Integral());
2046
2047 //new TCanvas; tmp->Draw();
2048 //new TCanvas; mcRnd->Draw();
2049
2050 // and move into 2d histogram
2051 TH1* mc = fMultiplicityVtx[id];
3602328d 2052 mc->Reset();
3602328d 2053 for (Int_t i=1; i<=mc->GetNbinsY(); ++i)
b477f4f2 2054 {
69b09e3b 2055 mc->SetBinContent(mc->GetNbinsX() / 2 + 1, i, mcRnd->GetBinContent(i));
2056 mc->SetBinError(mc->GetNbinsX() / 2 + 1, i, TMath::Sqrt(mcRnd->GetBinContent(i)));
2057 }
2058
2059 //new TCanvas; mc->Draw("COLZ");
2060
2061 // now randomize the measured histogram; funcMeasured is used as pilot function to generated the measured entries
2062 TH1* funcMeasured = CalculateMultiplicityESD(tmp, id)->ProjectionY("funcMeasured");
2063
2064 //new TCanvas; funcMeasured->Draw();
2065
2066 fMultiplicityESD[id]->Reset();
2067
2068 TH1* measRnd = fMultiplicityESD[id]->ProjectionY("measRnd");
2069 measRnd->FillRandom(funcMeasured, tmp->Integral());
2070
2071 //new TCanvas; measRnd->Draw();
2072
2073 fMultiplicityESD[id]->Reset();
2074 for (Int_t i=1; i<=fMultiplicityESD[id]->GetNbinsY(); ++i)
2075 {
2076 fMultiplicityESD[id]->SetBinContent(fMultiplicityESD[id]->GetNbinsX() / 2 + 1, i, measRnd->GetBinContent(i));
2077 fMultiplicityESD[id]->SetBinError(fMultiplicityESD[id]->GetNbinsX() / 2 + 1, i, TMath::Sqrt(measRnd->GetBinContent(i)));
b477f4f2 2078 }
3602328d 2079}