]>
Commit | Line | Data |
---|---|---|
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 | |
43 | ClassImp(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 | 50 | Int_t AliMultiplicityCorrection::fgQualityRegionsB[kQualityRegions] = {1, 20, 70}; |
51 | Int_t AliMultiplicityCorrection::fgQualityRegionsE[kQualityRegions] = {10, 65, 80}; | |
0b4bfd98 | 52 | |
53 | //____________________________________________________________________ | |
54 | void 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 | //____________________________________________________________________ |
91 | AliMultiplicityCorrection::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 | //____________________________________________________________________ |
120 | AliMultiplicityCorrection* 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 | //____________________________________________________________________ |
140 | AliMultiplicityCorrection::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 | //____________________________________________________________________ | |
213 | AliMultiplicityCorrection::~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 | //____________________________________________________________________ | |
260 | Long64_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 | //____________________________________________________________________ | |
328 | Bool_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 | 404 | void 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 | 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) |
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 | 496 | void 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 | 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) |
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 | 524 | void 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 | //____________________________________________________________________ | |
579 | TH1* 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 | //____________________________________________________________________ | |
607 | TH1* 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 | 620 | Int_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 | 650 | Int_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 | //____________________________________________________________________ |
675 | void 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 | 723 | void 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 | 1210 | void 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 | 1304 | void 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 | //____________________________________________________________________ |
1321 | TH2F* 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 | //____________________________________________________________________ |
1339 | void 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 | //____________________________________________________________________ |
1355 | TH1* 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 | 1390 | TH1* 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 | 1633 | void 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 | 1730 | Float_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 | //____________________________________________________________________ | |
1753 | void 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 | //____________________________________________________________________ |
1877 | void 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 | 1952 | TH2F* 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 | //____________________________________________________________________ | |
2022 | void 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 | } |