]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGCF/Correlations/Base/AliUEHist.cxx
bug fixes naming
[u/mrichter/AliRoot.git] / PWGCF / Correlations / Base / AliUEHist.cxx
CommitLineData
a75aacd6 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: AliUEHist.cxx 20164 2007-08-14 15:31:50Z morsch $ */
17
18//
19//
20// encapsulate histogram and corrections for one underlying event histogram
21//
22//
23// Author: Jan Fiete Grosse-Oetringhaus, Sara Vallero
24
25#include "AliUEHist.h"
26#include "AliCFContainer.h"
27#include "THnSparse.h"
28#include "TMath.h"
29#include "TList.h"
30#include "TCollection.h"
31#include "TH1D.h"
32#include "TH2D.h"
33#include "TH3D.h"
34#include "AliLog.h"
35#include "TCanvas.h"
144bd037 36#include "TF1.h"
85bfac17 37#include "AliTHn.h"
a75aacd6 38
39ClassImp(AliUEHist)
40
41const Int_t AliUEHist::fgkCFSteps = 10;
42
43AliUEHist::AliUEHist(const char* reqHist) :
d1c75d06 44 TObject(),
a75aacd6 45 fkRegions(4),
46 fEventHist(0),
b1831bcb 47 fTrackHistEfficiency(0),
a75aacd6 48 fEtaMin(0),
49 fEtaMax(0),
50 fPtMin(0),
51 fPtMax(0),
2a910c25 52 fCentralityMin(0),
53 fCentralityMax(0),
85bfac17 54 fZVtxMin(0),
55 fZVtxMax(0),
144bd037 56 fContaminationEnhancement(0),
a75aacd6 57 fCombineMinMax(0),
c7245604 58 fCache(0),
59 fHistogramType(reqHist)
a75aacd6 60{
61 // Constructor
62
ff458f69 63 for (UInt_t i=0; i<fkRegions; i++)
a75aacd6 64 fTrackHist[i] = 0;
65
66 if (strlen(reqHist) == 0)
67 return;
68
df269636 69 AliLog::SetClassDebugLevel("AliCFContainer", -1);
e741fadd 70 AliLog::SetClassDebugLevel("AliCFGridSparse", -3);
df269636 71
a75aacd6 72 const char* title = "";
73
74 // track level
75 Int_t nTrackVars = 4; // eta vs pT vs pT,lead (vs delta phi) vs multiplicity
85bfac17 76 Int_t iTrackBin[6];
77 Double_t* trackBins[6];
78 const char* trackAxisTitle[6];
a75aacd6 79
80 // eta
81 iTrackBin[0] = 20;
82 Double_t etaBins[20+1];
83 for (Int_t i=0; i<=iTrackBin[0]; i++)
84 etaBins[i] = -1.0 + 0.1 * i;
85 trackBins[0] = etaBins;
86 trackAxisTitle[0] = "#eta";
87
e0331fd9 88 // delta eta
85bfac17 89 const Int_t kNDeltaEtaBins = 40;
e0331fd9 90 Double_t deltaEtaBins[kNDeltaEtaBins+1];
91 for (Int_t i=0; i<=kNDeltaEtaBins; i++)
85bfac17 92 deltaEtaBins[i] = -2.0 + 0.1 * i;
e0331fd9 93
a75aacd6 94 // pT
85bfac17 95 iTrackBin[1] = 22;
96 Double_t pTBins[] = {0.15, 0.2, 0.3, 0.4, 0.5, 0.75, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 12.0, 15.0, 20.0};
a75aacd6 97 trackBins[1] = pTBins;
98 trackAxisTitle[1] = "p_{T} (GeV/c)";
99
100 // pT,lead binning 1
101 const Int_t kNLeadingpTBins = 100;
102 Double_t leadingpTBins[kNLeadingpTBins+1];
103 for (Int_t i=0; i<=kNLeadingpTBins; i++)
104 leadingpTBins[i] = 0.5 * i;
105
106 // pT,lead binning 2
85bfac17 107 const Int_t kNLeadingpTBins2 = 9;
108 Double_t leadingpTBins2[] = { 0.5, 1.0, 2.0, 3.0, 4.0, 6.0, 8.0, 10.0, 15.0, 20.0 };
a75aacd6 109
c7245604 110 // phi,lead; this binning starts at -pi/2 and is modulo 3
85bfac17 111 const Int_t kNLeadingPhiBins = 72;
a75aacd6 112 Double_t leadingPhiBins[kNLeadingPhiBins+1];
113 for (Int_t i=0; i<=kNLeadingPhiBins; i++)
c7245604 114 leadingPhiBins[i] = -TMath::Pi() / 2 + 1.0 / kNLeadingPhiBins * i * TMath::TwoPi();
a75aacd6 115
116 // multiplicity
117 const Int_t kNMultiplicityBins = 15;
118 Double_t multiplicityBins[kNMultiplicityBins+1];
119 for (Int_t i=0; i<=kNMultiplicityBins; i++)
120 multiplicityBins[i] = -0.5 + i;
121 multiplicityBins[kNMultiplicityBins] = 200;
bf58cbde 122
85bfac17 123 trackBins[3] = multiplicityBins;
124 iTrackBin[3] = kNMultiplicityBins;
125 trackAxisTitle[3] = "multiplicity";
126
c7245604 127 // centrality (in %)
85bfac17 128 const Int_t kNCentralityBins = 5 + 1 + 9;
129 Double_t centralityBins[] = { 0, 1, 2, 3, 4, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100.1 };
bf58cbde 130
b1831bcb 131 // particle species
132 const Int_t kNSpeciesBins = 4; // pi, K, p, rest
133 Double_t speciesBins[] = { -0.5, 0.5, 1.5, 2.5, 3.5 };
a75aacd6 134
85bfac17 135 // vtx-z axis
136 const Int_t kNVertexBins = 7;
137 Double_t vertexBins[] = { -7, -5, -3, -1, 1, 3, 5, 7 };
a75aacd6 138
44af28f9 139 Bool_t useVtxAxis = kFALSE;
140
a75aacd6 141 // selection depending on requested histogram
142 Int_t axis = -1; // 0 = pT,lead, 1 = phi,lead
143 if (strcmp(reqHist, "NumberDensitypT") == 0)
144 {
145 axis = 0;
44af28f9 146 title = "d^{2}N_{ch}/d#varphid#eta";
a75aacd6 147 }
148 else if (strcmp(reqHist, "NumberDensityPhi") == 0)
149 {
150 axis = 1;
44af28f9 151 title = "d^{2}N_{ch}/d#varphid#eta";
a75aacd6 152 }
44af28f9 153 else if (strcmp(reqHist, "NumberDensityPhiCentrality") == 0 || strcmp(reqHist, "NumberDensityPhiCentralityVtx") == 0)
bf58cbde 154 {
44af28f9 155 if (strcmp(reqHist, "NumberDensityPhiCentralityVtx") == 0)
156 {
157 reqHist = "NumberDensityPhiCentrality";
158 fHistogramType = reqHist;
159 useVtxAxis = kTRUE;
160 }
bf58cbde 161 axis = 2;
44af28f9 162 title = "d^{2}N_{ch}/d#varphid#eta";
bf58cbde 163 }
a75aacd6 164 else if (strcmp(reqHist, "SumpT") == 0)
165 {
166 axis = 0;
44af28f9 167 title = "d^{2}#Sigma p_{T}/d#varphid#eta";
a75aacd6 168 }
169 else
170 AliFatal(Form("Invalid histogram requested: %s", reqHist));
171
ff458f69 172 UInt_t initRegions = fkRegions;
a75aacd6 173
174 if (axis == 0)
175 {
176 trackBins[2] = leadingpTBins;
177 iTrackBin[2] = kNLeadingpTBins;
178 trackAxisTitle[2] = "leading p_{T} (GeV/c)";
179
180 }
181 else if (axis == 1)
182 {
183 nTrackVars = 5;
184 initRegions = 1;
185
186 iTrackBin[2] = kNLeadingpTBins2;
187 trackBins[2] = leadingpTBins2;
188 trackAxisTitle[2] = "leading p_{T} (GeV/c)";
189
190 iTrackBin[4] = kNLeadingPhiBins;
191 trackBins[4] = leadingPhiBins;
44af28f9 192 trackAxisTitle[4] = "#Delta #varphi w.r.t. leading track";
bf58cbde 193 }
194 else if (axis == 2)
195 {
eb88bdfe 196 nTrackVars = 5;
bf58cbde 197 initRegions = 1;
198
e0331fd9 199 iTrackBin[0] = kNDeltaEtaBins;
200 trackBins[0] = deltaEtaBins;
201 trackAxisTitle[0] = "#Delta#eta";
202
bf58cbde 203 iTrackBin[2] = kNLeadingpTBins2;
204 trackBins[2] = leadingpTBins2;
205 trackAxisTitle[2] = "leading p_{T} (GeV/c)";
206
207 trackBins[3] = centralityBins;
208 iTrackBin[3] = kNCentralityBins;
209 trackAxisTitle[3] = "centrality";
210
211 iTrackBin[4] = kNLeadingPhiBins;
212 trackBins[4] = leadingPhiBins;
44af28f9 213 trackAxisTitle[4] = "#Delta#varphi (rad.)";
85bfac17 214
eb88bdfe 215 if (useVtxAxis)
216 {
217 nTrackVars = 6;
218 iTrackBin[5] = kNVertexBins;
219 trackBins[5] = vertexBins;
220 trackAxisTitle[5] = "z-vtx (cm)";
221 }
a75aacd6 222 }
223
ff458f69 224 for (UInt_t i=0; i<initRegions; i++)
a75aacd6 225 {
85bfac17 226 if (strcmp(reqHist, "NumberDensityPhiCentrality") == 0)
227 fTrackHist[i] = new AliTHn(Form("fTrackHist_%d", i), title, fgkCFSteps, nTrackVars, iTrackBin);
228 else
229 fTrackHist[i] = new AliCFContainer(Form("fTrackHist_%d", i), title, fgkCFSteps, nTrackVars, iTrackBin);
a75aacd6 230
231 for (Int_t j=0; j<nTrackVars; j++)
232 {
233 fTrackHist[i]->SetBinLimits(j, trackBins[j]);
234 fTrackHist[i]->SetVarTitle(j, trackAxisTitle[j]);
235 }
236
237 SetStepNames(fTrackHist[i]);
238 }
239
85bfac17 240 // event level
241 Int_t nEventVars = 2;
242 Int_t iEventBin[3];
243
a75aacd6 244 // track 3rd and 4th axis --> event 1st and 2nd axis
85bfac17 245 iEventBin[0] = iTrackBin[2];
246 iEventBin[1] = iTrackBin[3];
247
248 // plus track 5th axis (in certain cases)
eb88bdfe 249 if (axis == 2 && useVtxAxis)
85bfac17 250 {
251 nEventVars = 3;
252 iEventBin[2] = iTrackBin[5];
253 }
254
255 fEventHist = new AliCFContainer("fEventHist", title, fgkCFSteps, nEventVars, iEventBin);
a75aacd6 256
257 fEventHist->SetBinLimits(0, trackBins[2]);
258 fEventHist->SetVarTitle(0, trackAxisTitle[2]);
259
260 fEventHist->SetBinLimits(1, trackBins[3]);
261 fEventHist->SetVarTitle(1, trackAxisTitle[3]);
262
eb88bdfe 263 if (axis == 2 && useVtxAxis)
85bfac17 264 {
265 fEventHist->SetBinLimits(2, trackBins[5]);
266 fEventHist->SetVarTitle(2, trackAxisTitle[5]);
267 }
268
a75aacd6 269 SetStepNames(fEventHist);
b1831bcb 270
271 iTrackBin[2] = kNSpeciesBins;
272
c7245604 273 fTrackHistEfficiency = new AliCFContainer("fTrackHistEfficiency", "Tracking efficiency", 3, 4, iTrackBin);
b1831bcb 274 fTrackHistEfficiency->SetBinLimits(0, trackBins[0]);
275 fTrackHistEfficiency->SetVarTitle(0, trackAxisTitle[0]);
276 fTrackHistEfficiency->SetBinLimits(1, trackBins[1]);
277 fTrackHistEfficiency->SetVarTitle(1, trackAxisTitle[1]);
278 fTrackHistEfficiency->SetBinLimits(2, speciesBins);
279 fTrackHistEfficiency->SetVarTitle(2, "particle species");
c7245604 280 fTrackHistEfficiency->SetBinLimits(3, trackBins[3]);
281 fTrackHistEfficiency->SetVarTitle(3, trackAxisTitle[3]);
a75aacd6 282}
283
d1c75d06 284//_____________________________________________________________________________
285AliUEHist::AliUEHist(const AliUEHist &c) :
286 TObject(),
287 fkRegions(4),
288 fEventHist(0),
b1831bcb 289 fTrackHistEfficiency(0),
d1c75d06 290 fEtaMin(0),
291 fEtaMax(0),
292 fPtMin(0),
293 fPtMax(0),
2a910c25 294 fCentralityMin(0),
295 fCentralityMax(0),
85bfac17 296 fZVtxMin(0),
297 fZVtxMax(0),
144bd037 298 fContaminationEnhancement(0),
d1c75d06 299 fCombineMinMax(0),
c7245604 300 fCache(0),
301 fHistogramType()
d1c75d06 302{
303 //
304 // AliUEHist copy constructor
305 //
306
307 ((AliUEHist &) c).Copy(*this);
308}
309
a75aacd6 310//____________________________________________________________________
311void AliUEHist::SetStepNames(AliCFContainer* container)
312{
313 // sets the names of the correction steps
314
315 for (Int_t i=0; i<fgkCFSteps; i++)
316 container->SetStepTitle(i, GetStepTitle((CFStep) i));
317}
318
319//____________________________________________________________________
320AliUEHist::~AliUEHist()
321{
322 // Destructor
323
ff458f69 324 for (UInt_t i=0; i<fkRegions; i++)
a75aacd6 325 {
326 if (fTrackHist[i])
327 {
328 delete fTrackHist[i];
329 fTrackHist[i] = 0;
330 }
331 }
332
333 if (fEventHist)
334 {
335 delete fEventHist;
336 fEventHist = 0;
337 }
338
b1831bcb 339 if (fTrackHistEfficiency)
340 {
341 delete fTrackHistEfficiency;
342 fTrackHistEfficiency = 0;
343 }
344
a75aacd6 345 if (fCache)
346 {
347 delete fCache;
348 fCache = 0;
349 }
350}
351
352//____________________________________________________________________
353AliUEHist &AliUEHist::operator=(const AliUEHist &c)
354{
355 // assigment operator
356
357 if (this != &c)
358 ((AliUEHist &) c).Copy(*this);
359
360 return *this;
361}
362
363//____________________________________________________________________
364void AliUEHist::Copy(TObject& c) const
365{
366 // copy function
367
368 AliUEHist& target = (AliUEHist &) c;
369
ff458f69 370 for (UInt_t i=0; i<fkRegions; i++)
a75aacd6 371 if (fTrackHist[i])
372 target.fTrackHist[i] = dynamic_cast<AliCFContainer*> (fTrackHist[i]->Clone());
373
374 if (fEventHist)
375 target.fEventHist = dynamic_cast<AliCFContainer*> (fEventHist->Clone());
b1831bcb 376
377 if (fTrackHistEfficiency)
378 target.fTrackHistEfficiency = dynamic_cast<AliCFContainer*> (fTrackHistEfficiency->Clone());
c7245604 379
380 target.fEtaMin = fEtaMin;
381 target.fEtaMax = fEtaMax;
382 target.fPtMin = fPtMin;
383 target.fPtMax = fPtMax;
2a910c25 384 target.fCentralityMin = fCentralityMin;
385 target.fCentralityMax = fCentralityMax;
85bfac17 386 target.fZVtxMin = fZVtxMin;
387 target.fZVtxMax = fZVtxMax;
c7245604 388
389 if (fContaminationEnhancement)
390 target.fContaminationEnhancement = dynamic_cast<TH1F*> (fContaminationEnhancement->Clone());
391
392 target.fCombineMinMax = fCombineMinMax;
393 target.fHistogramType = fHistogramType;
a75aacd6 394}
395
396//____________________________________________________________________
397Long64_t AliUEHist::Merge(TCollection* list)
398{
399 // Merge a list of AliUEHist objects with this (needed for
400 // PROOF).
401 // Returns the number of merged objects (including this).
402
403 if (!list)
404 return 0;
405
406 if (list->IsEmpty())
407 return 1;
408
409 TIterator* iter = list->MakeIterator();
410 TObject* obj;
411
412 // collections of objects
ff458f69 413 const UInt_t kMaxLists = fkRegions+2;
a75aacd6 414 TList** lists = new TList*[kMaxLists];
415
ff458f69 416 for (UInt_t i=0; i<kMaxLists; i++)
a75aacd6 417 lists[i] = new TList;
418
419 Int_t count = 0;
420 while ((obj = iter->Next())) {
421
422 AliUEHist* entry = dynamic_cast<AliUEHist*> (obj);
423 if (entry == 0)
424 continue;
425
ff458f69 426 for (UInt_t i=0; i<fkRegions; i++)
a75aacd6 427 if (entry->fTrackHist[i])
428 lists[i]->Add(entry->fTrackHist[i]);
429
430 lists[fkRegions]->Add(entry->fEventHist);
b1831bcb 431 lists[fkRegions+1]->Add(entry->fTrackHistEfficiency);
a75aacd6 432
433 count++;
434 }
ff458f69 435 for (UInt_t i=0; i<fkRegions; i++)
a75aacd6 436 if (fTrackHist[i])
437 fTrackHist[i]->Merge(lists[i]);
438
439 fEventHist->Merge(lists[fkRegions]);
b1831bcb 440 fTrackHistEfficiency->Merge(lists[fkRegions+1]);
a75aacd6 441
ff458f69 442 for (UInt_t i=0; i<kMaxLists; i++)
a75aacd6 443 delete lists[i];
444
445 delete[] lists;
446
447 return count+1;
448}
449
450//____________________________________________________________________
451void AliUEHist::SetBinLimits(AliCFGridSparse* grid)
452{
453 // sets the bin limits in eta and pT defined by fEtaMin/Max, fPtMin/Max
454
455 if (fEtaMax > fEtaMin)
456 grid->SetRangeUser(0, fEtaMin, fEtaMax);
457 if (fPtMax > fPtMin)
458 grid->SetRangeUser(1, fPtMin, fPtMax);
459}
460
461//____________________________________________________________________
462void AliUEHist::ResetBinLimits(AliCFGridSparse* grid)
463{
464 // resets all bin limits
465
466 for (Int_t i=0; i<grid->GetNVar(); i++)
144bd037 467 if (grid->GetGrid()->GetAxis(i)->TestBit(TAxis::kAxisRange))
a75aacd6 468 grid->SetRangeUser(i, 0, -1);
469}
470
144bd037 471//____________________________________________________________________
472void AliUEHist::CountEmptyBins(AliUEHist::CFStep step, Float_t ptLeadMin, Float_t ptLeadMax)
473{
474 // prints the number of empty bins in the track end event histograms in the given step
475
476 Int_t binBegin[4];
477 Int_t binEnd[4];
478
479 for (Int_t i=0; i<4; i++)
480 {
481 binBegin[i] = 1;
482 binEnd[i] = fTrackHist[0]->GetNBins(i);
483 }
484
485 if (fEtaMax > fEtaMin)
486 {
487 binBegin[0] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(0)->FindBin(fEtaMin);
488 binEnd[0] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(0)->FindBin(fEtaMax);
489 }
490
491 if (fPtMax > fPtMin)
492 {
493 binBegin[1] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(1)->FindBin(fPtMin);
494 binEnd[1] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(1)->FindBin(fPtMax);
495 }
496
497 if (ptLeadMax > ptLeadMin)
498 {
499 binBegin[2] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(2)->FindBin(ptLeadMin);
500 binEnd[2] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(2)->FindBin(ptLeadMax);
501 }
502
503 // start from multiplicity 1
504 binBegin[3] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(3)->FindBin(1);
505
ff458f69 506 for (UInt_t region=0; region<fkRegions; region++)
144bd037 507 {
508 Int_t total = 0;
509 Int_t count = 0;
510 Int_t vars[4];
511
512 for (Int_t i=0; i<4; i++)
513 vars[i] = binBegin[i];
514
515 AliCFGridSparse* grid = fTrackHist[region]->GetGrid(step);
516 while (1)
517 {
518 if (grid->GetElement(vars) == 0)
519 {
520 Printf("Empty bin at eta=%.2f pt=%.2f pt_lead=%.2f mult=%.1f",
521 grid->GetBinCenter(0, vars[0]),
522 grid->GetBinCenter(1, vars[1]),
523 grid->GetBinCenter(2, vars[2]),
524 grid->GetBinCenter(3, vars[3])
525 );
526 count++;
527 }
528
529 vars[3]++;
530 for (Int_t i=3; i>0; i--)
531 {
532 if (vars[i] == binEnd[i]+1)
533 {
534 vars[i] = binBegin[i];
535 vars[i-1]++;
536 }
537 }
538
539 if (vars[0] == binEnd[0]+1)
540 break;
541 total++;
542 }
543
544 Printf("Region %s has %d empty bins (out of %d bins)", GetRegionTitle((Region) region), count, total);
545 }
546}
547
a75aacd6 548//____________________________________________________________________
44af28f9 549TH1* AliUEHist::GetUEHist(AliUEHist::CFStep step, AliUEHist::Region region, Float_t ptLeadMin, Float_t ptLeadMax, Int_t multBinBegin, Int_t multBinEnd, Int_t twoD, Bool_t etaNorm, Int_t* normEvents)
a75aacd6 550{
551 // Extracts the UE histogram at the given step and in the given region by projection and dividing tracks by events
552 //
553 // ptLeadMin, ptLeadMax: Only meaningful for vs. delta phi plot (third axis is ptLead)
554 // Histogram has to be deleted by the caller of the function
2a910c25 555 //
556 // twoD: 0: 1D histogram as function of phi
557 // 1: 2D histogram, deltaphi, deltaeta
558 // 10: 1D histogram, within |deltaeta| < 0.8
559 // 11: 1D histogram, within 0.8 < |deltaeta| < 1.6
85bfac17 560 //
561 // etaNorm: if kTRUE (default), the distributions are divided by the area in delta eta
44af28f9 562 //
563 // normEvents: if non-0 the number of events/trigger particles for the normalization is filled
a75aacd6 564
565 // unzoom all axes
566 ResetBinLimits(fTrackHist[region]->GetGrid(step));
567 ResetBinLimits(fEventHist->GetGrid(step));
568
569 SetBinLimits(fTrackHist[region]->GetGrid(step));
85bfac17 570
571 // z vtx
572 if (fZVtxMax > fZVtxMin)
573 {
574 Printf("Using z-vtx range %f --> %f", fZVtxMin, fZVtxMax);
575 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(5)->SetRangeUser(fZVtxMin, fZVtxMax);
576 fEventHist->GetGrid(step)->GetGrid()->GetAxis(2)->SetRangeUser(fZVtxMin, fZVtxMax);
577 }
a75aacd6 578
579 TH1D* tracks = 0;
580
581 if (ptLeadMin < 0)
582 {
583 tracks = fTrackHist[region]->ShowProjection(2, step);
584 tracks->GetYaxis()->SetTitle(fTrackHist[region]->GetTitle());
585 if (fCombineMinMax && region == kMin)
586 {
587 ResetBinLimits(fTrackHist[kMax]->GetGrid(step));
588 SetBinLimits(fTrackHist[kMax]->GetGrid(step));
589
590 TH1D* tracks2 = fTrackHist[kMax]->ShowProjection(2, step);
591 tracks->Add(tracks2);
592
593 ResetBinLimits(fTrackHist[kMax]->GetGrid(step));
594 }
595
596 // normalize to get a density (deta dphi)
597 TAxis* axis = fTrackHist[region]->GetGrid(step)->GetAxis(0);
598 Float_t phiRegion = TMath::TwoPi() / 3;
599 if (!fCombineMinMax && region == kMin)
600 phiRegion /= 2;
85bfac17 601 Float_t normalization = phiRegion;
602 if (etaNorm)
603 normalization *= (axis->GetBinUpEdge(axis->GetLast()) - axis->GetBinLowEdge(axis->GetFirst()));
a75aacd6 604 //Printf("Normalization: %f", normalization);
605 tracks->Scale(1.0 / normalization);
606
607 TH1D* events = fEventHist->ShowProjection(0, step);
608 tracks->Divide(events);
609 }
610 else
611 {
2a910c25 612 if (multBinEnd >= multBinBegin)
ff458f69 613 {
e0331fd9 614 Printf("Using multiplicity range %d --> %d", multBinBegin, multBinEnd);
ff458f69 615 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(3)->SetRange(multBinBegin, multBinEnd);
616 fEventHist->GetGrid(step)->GetGrid()->GetAxis(1)->SetRange(multBinBegin, multBinEnd);
617 }
bf58cbde 618
e741fadd 619 Int_t firstBin = fTrackHist[region]->GetAxis(2, step)->FindBin(ptLeadMin);
620 Int_t lastBin = fTrackHist[region]->GetAxis(2, step)->FindBin(ptLeadMax);
a75aacd6 621
c7245604 622 Printf("Using leading pT range %d --> %d", firstBin, lastBin);
bf58cbde 623
c7245604 624 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(2)->SetRange(firstBin, lastBin);
625
626 if (twoD == 0)
627 tracks = (TH1D*) fTrackHist[region]->GetGrid(step)->Project(4);
628 else
2a910c25 629 tracks = (TH1D*) fTrackHist[region]->GetGrid(step)->Project(4, 0);
630
c7245604 631 Printf("Calculated histogram --> %f tracks", tracks->Integral());
632 fTrackHist[region]->GetGrid(step)->SetRangeUser(2, 0, -1);
633
2a910c25 634 if (twoD == 10 || twoD == 11)
635 {
44af28f9 636 Float_t etaLimit = 1.0;
2a910c25 637 if (twoD == 10)
638 {
639 tracks = (TH1D*) ((TH2*) tracks)->ProjectionX("proj", tracks->GetYaxis()->FindBin(-etaLimit + 0.01), tracks->GetYaxis()->FindBin(etaLimit - 0.01))->Clone();
640
641 // TODO calculate acc with 2 * (deta - 0.5 * deta*deta / 1.6)
642 tracks->Scale(1. / 0.75);
643 }
644 else if (twoD == 11)
645 {
646 TH1D* tracksTmp1 = (TH1D*) ((TH2*) tracks)->ProjectionX("proj1", tracks->GetYaxis()->FindBin(-etaLimit * 2 + 0.01), tracks->GetYaxis()->FindBin(-etaLimit - 0.01))->Clone();
647 TH1D* tracksTmp2 = ((TH2*) tracks)->ProjectionX("proj2", tracks->GetYaxis()->FindBin(etaLimit + 0.01), tracks->GetYaxis()->FindBin(2 * etaLimit - 0.01));
648
649 tracksTmp1->Add(tracksTmp2);
650
651 delete tracks;
652 tracks = tracksTmp1;
653 delete tracksTmp2;
654
655 tracks->Scale(1. / 0.25);
656 }
657 }
658
c7245604 659 // normalize to get a density (deta dphi)
2a910c25 660 // TODO normalization may be off for 2d histogram
c7245604 661 Float_t normalization = fTrackHist[region]->GetGrid(step)->GetAxis(4)->GetBinWidth(1);
85bfac17 662
663 if (etaNorm)
c7245604 664 {
85bfac17 665 TAxis* axis = fTrackHist[region]->GetGrid(step)->GetAxis(0);
666 if (strcmp(axis->GetTitle(), "#eta") == 0)
667 {
668 Printf("Normalizing using eta-axis range");
669 normalization *= axis->GetBinUpEdge(axis->GetLast()) - axis->GetBinLowEdge(axis->GetFirst());
670 }
671 else
672 {
673 Printf("Normalizing assuming accepted range of |eta| < 0.8");
674 normalization *= 0.8 * 2;
675 }
e741fadd 676 }
bf58cbde 677
c7245604 678 //Printf("Normalization: %f", normalization);
679 tracks->Scale(1.0 / normalization);
680
2a910c25 681 // NOTE fEventHist contains the number of events for the underlying event analysis and the number of trigger particles for the azimuthal correlation analysis. In the latter case the naming is therefore somewhat misleading!
c7245604 682 TH1D* events = fEventHist->ShowProjection(0, step);
683 Int_t nEvents = (Int_t) events->Integral(firstBin, lastBin);
684 Printf("Calculated histogram --> %d events", nEvents);
44af28f9 685 if (normEvents)
686 *normEvents = nEvents;
2a910c25 687
688 if (nEvents > 0)
689 tracks->Scale(1.0 / nEvents);
c7245604 690
bf58cbde 691 delete events;
a75aacd6 692 }
693
694 ResetBinLimits(fTrackHist[region]->GetGrid(step));
bf58cbde 695 ResetBinLimits(fEventHist->GetGrid(step));
a75aacd6 696
697 return tracks;
698}
699
52c83678 700//____________________________________________________________________
701void AliUEHist::GetHistsZVtx(AliUEHist::CFStep step, AliUEHist::Region region, Float_t ptLeadMin, Float_t ptLeadMax, Int_t multBinBegin, Int_t multBinEnd, TH3** trackHist, TH1** eventHist)
702{
703 // Calculates a 3d histogram with deltaphi, deltaeta, zvtx on track level and a 1d histogram on event level (as fct of zvtx)
704 // Histogram has to be deleted by the caller of the function
705
706 if (!fTrackHist[kToward]->GetGrid(0)->GetGrid()->GetAxis(5))
707 AliFatal("Histogram without vertex axis provided");
708
709 // unzoom all axes
710 ResetBinLimits(fTrackHist[region]->GetGrid(step));
711 ResetBinLimits(fEventHist->GetGrid(step));
712
713 SetBinLimits(fTrackHist[region]->GetGrid(step));
714
715 if (multBinEnd >= multBinBegin)
716 {
717 Printf("Using multiplicity range %d --> %d", multBinBegin, multBinEnd);
718 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(3)->SetRange(multBinBegin, multBinEnd);
719 fEventHist->GetGrid(step)->GetGrid()->GetAxis(1)->SetRange(multBinBegin, multBinEnd);
720 }
721
722 Int_t firstBin = fTrackHist[region]->GetAxis(2, step)->FindBin(ptLeadMin);
723 Int_t lastBin = fTrackHist[region]->GetAxis(2, step)->FindBin(ptLeadMax);
724 Printf("Using leading pT range %d --> %d", firstBin, lastBin);
725 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(2)->SetRange(firstBin, lastBin);
726 fEventHist->GetGrid(step)->GetGrid()->GetAxis(0)->SetRange(firstBin, lastBin);
727
728 *trackHist = (TH3*) fTrackHist[region]->GetGrid(step)->Project(4, 0, 5);
729 *eventHist = (TH1*) fEventHist->GetGrid(step)->Project(2);
730
731 ResetBinLimits(fTrackHist[region]->GetGrid(step));
732 ResetBinLimits(fEventHist->GetGrid(step));
733}
734
735//____________________________________________________________________
736TH2* AliUEHist::GetSumOfRatios2(AliUEHist* mixed, AliUEHist::CFStep step, AliUEHist::Region region, Float_t ptLeadMin, Float_t ptLeadMax, Int_t multBinBegin, Int_t multBinEnd)
737{
738 // Calls GetUEHist(...) for *each* vertex bin and performs a sum of ratios:
739 // 1_N [ (same/mixed)_1 + (same/mixed)_2 + (same/mixed)_3 + ... ]
740 // where N is the total number of events/trigger particles and the subscript is the vertex bin
741 // where mixed is normalized such that the information about the number of pairs in same is kept
742 //
743 // returns a 2D histogram: deltaphi, deltaeta
744 //
745 // Parameters:
746 // mixed: AliUEHist containing mixed event corresponding to this object
747 // <other parameters> : check documentation of AliUEHist::GetUEHist
748
749 TH2* totalTracks = 0;
750
751 TH3* trackSameAll = 0;
752 TH3* trackMixedAll = 0;
753 TH1* eventSameAll = 0;
754 TH1* eventMixedAll = 0;
755
756 GetHistsZVtx(step, region, ptLeadMin, ptLeadMax, multBinBegin, multBinEnd, &trackSameAll, &eventSameAll);
757 mixed->GetHistsZVtx(step, region, ptLeadMin, ptLeadMax, multBinBegin, multBinEnd, &trackMixedAll, &eventMixedAll);
758
759 TAxis* vertexAxis = trackSameAll->GetZaxis();
760 for (Int_t vertexBin = 1; vertexBin <= vertexAxis->GetNbins(); vertexBin++)
761 {
762 trackSameAll->GetZaxis()->SetRange(vertexBin, vertexBin);
763 trackMixedAll->GetZaxis()->SetRange(vertexBin, vertexBin);
764
765 TH2* tracksSame = (TH2*) trackSameAll->Project3D("yx1");
d38fa455 766 TH2* tracksMixed = (TH2*) trackMixedAll->Project3D("yx2");
52c83678 767
768 // asssume flat in dphi, gain in statistics
769// TH1* histMixedproj = mixedTwoD->ProjectionY();
770// histMixedproj->Scale(1.0 / mixedTwoD->GetNbinsX());
771//
772// for (Int_t x=1; x<=mixedTwoD->GetNbinsX(); x++)
773// for (Int_t y=1; y<=mixedTwoD->GetNbinsY(); y++)
774// mixedTwoD->SetBinContent(x, y, histMixedproj->GetBinContent(y));
775
776// delete histMixedproj;
777
778 // get mixed event normalization by assuming full acceptance at deta of 0
52c83678 779 Double_t mixedNorm = tracksMixed->Integral(tracksMixed->GetXaxis()->FindBin(-0.01), tracksMixed->GetXaxis()->FindBin(0.01), tracksMixed->GetYaxis()->FindBin(-0.01), tracksMixed->GetYaxis()->FindBin(0.01));
d38fa455 780 mixedNorm /= (tracksMixed->GetXaxis()->FindBin(0.01) - tracksMixed->GetXaxis()->FindBin(-0.01) + 1) * (tracksMixed->GetYaxis()->FindBin(0.01) - tracksMixed->GetYaxis()->FindBin(-0.01) + 1);
52c83678 781 tracksMixed->Scale(1.0 / mixedNorm);
d38fa455 782
783// tracksSame->Scale(tracksMixed->Integral() / tracksSame->Integral());
52c83678 784
785 tracksSame->Divide(tracksMixed);
786
d38fa455 787 // code to draw contributions
788 /*
789 TH1* proj = tracksSame->ProjectionX("projx", tracksSame->GetYaxis()->FindBin(-1.59), tracksSame->GetYaxis()->FindBin(1.59));
790 proj->SetTitle(Form("Bin %d", vertexBin));
791 proj->SetLineColor(vertexBin);
792 proj->DrawCopy((vertexBin > 1) ? "SAME" : "");
793 */
794
52c83678 795 if (!totalTracks)
796 totalTracks = (TH2*) tracksSame->Clone("totalTracks");
797 else
798 totalTracks->Add(tracksSame);
799
800 delete tracksSame;
801 delete tracksMixed;
802 }
803
804 Int_t totalEvents = eventSameAll->Integral();
f6f8f9af 805 if (totalTracks) {
806 Printf("Dividing %f tracks by %d events", totalTracks->Integral(), totalEvents);
807 if (totalEvents > 0)
808 totalTracks->Scale(1.0 / totalEvents);
809 }
52c83678 810
d38fa455 811 // normalizate to dphi width
812 Float_t normalization = totalTracks->GetXaxis()->GetBinWidth(1);
813 totalTracks->Scale(1.0 / normalization);
814
52c83678 815 delete trackSameAll;
816 delete trackMixedAll;
817 delete eventSameAll;
818 delete eventMixedAll;
819
820 return totalTracks;
821}
822
44af28f9 823//____________________________________________________________________
824TH2* AliUEHist::GetSumOfRatios(AliUEHist* mixed, AliUEHist::CFStep step, AliUEHist::Region region, Float_t ptLeadMin, Float_t ptLeadMax, Int_t multBinBegin, Int_t multBinEnd, Bool_t etaNorm, Bool_t useVertexBins)
825{
826 // Calls GetUEHist(...) for *each* multiplicity bin and performs a sum of ratios:
827 // 1_N [ (same/mixed)_1 + (same/mixed)_2 + (same/mixed)_3 + ... ]
828 // where N is the total number of events/trigger particles and the subscript is the multiplicity bin
829 //
830 // Can only be used for the 2D histogram at present
831 //
832 // Parameters:
833 // mixed: AliUEHist containing mixed event corresponding to this object
834 // <other parameters> : check documentation of AliUEHist::GetUEHist
835
44af28f9 836 TH2* totalTracks = 0;
837 Int_t totalEvents = 0;
838
839 Int_t vertexBin = 1;
840 TAxis* vertexAxis = fTrackHist[kToward]->GetGrid(0)->GetGrid()->GetAxis(5);
93e61a2f 841 if (useVertexBins && !vertexAxis)
842 {
843 Printf("Vertex axis requested but not available");
844 return 0;
845 }
44af28f9 846
847 // vertex bin loop
848 while (1)
849 {
93e61a2f 850 if (useVertexBins)
44af28f9 851 {
852 SetZVtxRange(vertexAxis->GetBinLowEdge(vertexBin) + 0.01, vertexAxis->GetBinUpEdge(vertexBin) - 0.01);
853 mixed->SetZVtxRange(vertexAxis->GetBinLowEdge(vertexBin) + 0.01, vertexAxis->GetBinUpEdge(vertexBin) - 0.01);
854 vertexBin++;
855 }
856
857 // multiplicity loop
d38fa455 858 Int_t multIter = multBinBegin;
44af28f9 859 while (1)
860 {
861 Int_t multBinBeginLocal = multBinBegin;
862 Int_t multBinEndLocal = multBinEnd;
863
864 if (multBinEnd >= multBinBegin)
865 {
866 multBinBeginLocal = multIter;
867 multBinEndLocal = multIter;
868 multIter++;
869 }
870
871 Int_t nEvents = 0;
872 TH2* tracks = (TH2*) GetUEHist(step, region, ptLeadMin, ptLeadMax, multBinBeginLocal, multBinEndLocal, 1, etaNorm, &nEvents);
873 // undo normalization
874 tracks->Scale(nEvents);
875 totalEvents += nEvents;
876
877 TH2* mixedTwoD = (TH2*) mixed->GetUEHist(step, region, ptLeadMin, ptLeadMax, multBinBeginLocal, multBinEndLocal, 1, etaNorm);
878
879 // asssume flat in dphi, gain in statistics
880 // TH1* histMixedproj = mixedTwoD->ProjectionY();
881 // histMixedproj->Scale(1.0 / mixedTwoD->GetNbinsX());
882 //
883 // for (Int_t x=1; x<=mixedTwoD->GetNbinsX(); x++)
884 // for (Int_t y=1; y<=mixedTwoD->GetNbinsY(); y++)
885 // mixedTwoD->SetBinContent(x, y, histMixedproj->GetBinContent(y));
886
887 // delete histMixedproj;
888
889 // get mixed event normalization by assuming full acceptance at deta of 0 (only works for flat dphi)
890/* Double_t mixedNorm = mixedTwoD->Integral(1, mixedTwoD->GetNbinsX(), mixedTwoD->GetYaxis()->FindBin(-0.01), mixedTwoD->GetYaxis()->FindBin(0.01));
891 mixedNorm /= mixedTwoD->GetNbinsX() * (mixedTwoD->GetYaxis()->FindBin(0.01) - mixedTwoD->GetYaxis()->FindBin(-0.01) + 1);
892 tracks->Scale(mixedNorm);*/
893
894 tracks->Scale(mixedTwoD->Integral() / tracks->Integral());
895
896 tracks->Divide(mixedTwoD);
897
898 delete mixedTwoD;
899
900 if (!totalTracks)
901 totalTracks = tracks;
902 else
903 {
904 totalTracks->Add(tracks);
905 delete tracks;
906 }
907
908 if (multIter > multBinEnd)
909 break;
910 }
911
912 if (!useVertexBins || vertexBin > vertexAxis->GetNbins())
913 break;
914 }
915
916 if (useVertexBins)
917 totalEvents = vertexAxis->GetNbins();
f6f8f9af 918 if (totalTracks) {
919 Printf("Dividing %f tracks by %d events", totalTracks->Integral(), totalEvents);
920 if (totalEvents > 0)
921 totalTracks->Scale(1.0 / totalEvents);
922 }
44af28f9 923
924 return totalTracks;
925}
926
c7245604 927//____________________________________________________________________
928TH1* AliUEHist::GetPtHist(CFStep step, Region region, Float_t ptLeadMin, Float_t ptLeadMax, Int_t multBinBegin, Int_t multBinEnd, Float_t phiMin, Float_t phiMax, Float_t etaMin, Float_t etaMax, Bool_t skipPhiNormalization)
929{
930 // returns a histogram projected to pT,assoc with the provided cuts
931
932 // unzoom all axes
933 ResetBinLimits(fTrackHist[region]->GetGrid(step));
934 ResetBinLimits(fEventHist->GetGrid(step));
935
936 TH1D* tracks = 0;
937
938 // the efficiency to have find an event depends on leading pT and this is not corrected for because anyway per bin we calculate tracks over events
939 // therefore the number density must be calculated here per leading pT bin and then summed
940
941 if (multBinEnd > multBinBegin)
942 Printf("Using multiplicity range %d --> %d", multBinBegin, multBinEnd);
943 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(3)->SetRange(multBinBegin, multBinEnd);
944 fEventHist->GetGrid(step)->GetGrid()->GetAxis(1)->SetRange(multBinBegin, multBinEnd);
945
946 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(0)->SetRangeUser(etaMin, etaMax);
947 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(4)->SetRangeUser(phiMin, phiMax);
948
949 // get real phi cuts due to binning
950 Float_t phiMinReal = fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(4)->GetBinLowEdge(fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(4)->GetFirst());
951 Float_t phiMaxReal = fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(4)->GetBinUpEdge(fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(4)->GetLast());
952 Printf("phi min = %.2f and max = %.2f requested; due to binning range will be from %.2f to %.2f, i.e. a %.0f%% larger window", phiMin, phiMax, phiMinReal, phiMaxReal, (phiMaxReal - phiMinReal) / (phiMax - phiMin) * 100 - 100);
953
954 Int_t firstBin = fTrackHist[region]->GetAxis(2, step)->FindBin(ptLeadMin);
955 Int_t lastBin = fTrackHist[region]->GetAxis(2, step)->FindBin(ptLeadMax);
956
957 TH1D* events = fEventHist->ShowProjection(0, step);
958
959 for (Int_t bin=firstBin; bin<=lastBin; bin++)
960 {
961 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(2)->SetRange(bin, bin);
962
963 // project to pT,assoc
964 TH1D* tracksTmp = (TH1D*) fTrackHist[region]->GetGrid(step)->Project(1);
965
966 Printf("Calculated histogram in bin %d --> %f tracks", bin, tracksTmp->Integral());
967 fTrackHist[region]->GetGrid(step)->SetRangeUser(2, 0, -1);
968
969 // normalize to get a density (deta dphi)
970 Float_t normalization = 1;
971 TAxis* axis = fTrackHist[region]->GetGrid(step)->GetAxis(0);
972 if (strcmp(axis->GetTitle(), "#eta") == 0)
973 {
974 Printf("Normalizing using eta-axis range");
975 normalization *= axis->GetBinUpEdge(axis->GetLast()) - axis->GetBinLowEdge(axis->GetFirst());
976 }
977 else
978 {
979 Printf("Normalizating assuming accepted range of |eta| < 0.8");
980 normalization *= 0.8 * 2;
981 }
982
983 // dphi
984 if (!skipPhiNormalization)
985 normalization *= phiMaxReal - phiMinReal;
986
987 //Printf("Normalization: %f", normalization);
988 tracksTmp->Scale(1.0 / normalization);
989
990 // and now dpT (bins have different width)
991 for (Int_t i=1; i<=tracksTmp->GetNbinsX(); i++)
992 {
993 tracksTmp->SetBinContent(i, tracksTmp->GetBinContent(i) / tracksTmp->GetXaxis()->GetBinWidth(i));
994 tracksTmp->SetBinError (i, tracksTmp->GetBinError(i) / tracksTmp->GetXaxis()->GetBinWidth(i));
995 }
996
997 Int_t nEvents = (Int_t) events->GetBinContent(bin);
998 if (nEvents > 0)
999 tracksTmp->Scale(1.0 / nEvents);
1000 Printf("Calculated histogram in bin %d --> %d events", bin, nEvents);
1001
1002 if (!tracks)
1003 tracks = tracksTmp;
1004 else
1005 {
1006 tracks->Add(tracksTmp);
1007 delete tracksTmp;
1008 }
1009 }
1010
1011 delete events;
1012
1013 ResetBinLimits(fTrackHist[region]->GetGrid(step));
1014 ResetBinLimits(fEventHist->GetGrid(step));
1015
1016 return tracks;
1017}
1018
c32a0ca9 1019void AliUEHist::MultiplyHistograms(THnSparse* grid, THnSparse* target, TH1* histogram, Int_t var1, Int_t var2)
a75aacd6 1020{
c32a0ca9 1021 // multiplies <grid> with <histogram> and put the result in <target>
1022 // <grid> has usually more dimensions than histogram. The axis which are used to choose the value
1023 // from <histogram> are given in <var1> and <var2>
a75aacd6 1024 //
c32a0ca9 1025 // if <histogram> is 0, just copies content from step1 to step2
144bd037 1026
1027 // clear target histogram
1028 target->Reset();
1029
c32a0ca9 1030 if (histogram != 0)
a75aacd6 1031 {
c32a0ca9 1032 if (grid->GetAxis(var1)->GetNbins() != histogram->GetNbinsX())
1033 AliFatal(Form("Invalid binning (var1): %d %d", grid->GetAxis(var1)->GetNbins(), histogram->GetNbinsX()));
a75aacd6 1034
c32a0ca9 1035 if (var2 >= 0 && grid->GetAxis(var2)->GetNbins() != histogram->GetNbinsY())
1036 AliFatal(Form("Invalid binning (var2): %d %d", grid->GetAxis(var2)->GetNbins(), histogram->GetNbinsY()));
144bd037 1037 }
c32a0ca9 1038
1039 if (grid->GetNdimensions() > 6)
1040 AliFatal("Too many dimensions in THnSparse");
1041
1042 Int_t bins[6];
144bd037 1043
1044 // optimized implementation
1045 for (Int_t binIdx = 0; binIdx < grid->GetNbins(); binIdx++)
1046 {
144bd037 1047 Double_t value = grid->GetBinContent(binIdx, bins);
1048 Double_t error = grid->GetBinError(binIdx);
a75aacd6 1049
c32a0ca9 1050 if (histogram != 0)
a75aacd6 1051 {
144bd037 1052 if (var2 < 0)
a75aacd6 1053 {
c32a0ca9 1054 value *= histogram->GetBinContent(bins[var1]);
1055 error *= histogram->GetBinContent(bins[var1]);
144bd037 1056 }
1057 else
1058 {
c32a0ca9 1059 value *= histogram->GetBinContent(bins[var1], bins[var2]);
1060 error *= histogram->GetBinContent(bins[var1], bins[var2]);
a75aacd6 1061 }
a75aacd6 1062 }
144bd037 1063
1064 target->SetBinContent(bins, value);
1065 target->SetBinError(bins, error);
a75aacd6 1066 }
c32a0ca9 1067}
1068
1069//____________________________________________________________________
1070void AliUEHist::CorrectTracks(CFStep step1, CFStep step2, TH1* trackCorrection, Int_t var1, Int_t var2)
1071{
1072 // corrects from step1 to step2 by multiplying the tracks with trackCorrection
1073 // trackCorrection can be a function of eta (var1 == 0), pT (var1 == 1), leading pT (var1 == 2), multiplicity (var1 == 3), delta phi (var1 == 4)
1074 // if var2 >= 0 a two dimension correction is assumed in trackCorrection
1075 //
1076 // if trackCorrection is 0, just copies content from step1 to step2
1077
1078 for (UInt_t region=0; region<fkRegions; region++)
1079 CorrectTracks(step1, step2, region, trackCorrection, var1, var2);
1080}
1081
1082//____________________________________________________________________
1083void AliUEHist::CorrectTracks(CFStep step1, CFStep step2, Int_t region, TH1* trackCorrection, Int_t var1, Int_t var2)
1084{
1085 //
1086 // see documentation of CorrectTracks above
1087 //
1088
1089 if (!fTrackHist[region])
1090 return;
1091
1092 THnSparse* grid = fTrackHist[region]->GetGrid(step1)->GetGrid();
1093 THnSparse* target = fTrackHist[region]->GetGrid(step2)->GetGrid();
1094
1095 MultiplyHistograms(grid, target, trackCorrection, var1, var2);
1096
5a53c6f2 1097 Printf("AliUEHist::CorrectTracks: Corrected from %f to %f entries. Correction histogram: %f entries (integral: %f)", grid->GetEntries(), target->GetEntries(), (trackCorrection) ? trackCorrection->GetEntries() : -1.0, (trackCorrection) ? trackCorrection->Integral() : -1.0);
a75aacd6 1098}
1099
1100//____________________________________________________________________
2a910c25 1101void AliUEHist::CorrectEvents(CFStep step1, CFStep step2, TH1* eventCorrection, Int_t var1, Int_t var2)
a75aacd6 1102{
1103 // corrects from step1 to step2 by multiplying the events with eventCorrection
1104 // eventCorrection is as function of leading pT (var == 0) or multiplicity (var == 1)
1105 //
1106 // if eventCorrection is 0, just copies content from step1 to step2
1107
1108 AliCFGridSparse* grid = fEventHist->GetGrid(step1);
1109 AliCFGridSparse* target = fEventHist->GetGrid(step2);
1110
c32a0ca9 1111 MultiplyHistograms(grid->GetGrid(), target->GetGrid(), eventCorrection, var1, var2);
1112
5a53c6f2 1113 Printf("AliUEHist::CorrectEvents: Corrected from %f to %f entries. Correction histogram: %f entries (integral: %f)", grid->GetEntries(), target->GetEntries(), (eventCorrection) ? eventCorrection->GetEntries() : -1.0, (eventCorrection) ? eventCorrection->Integral() : -1.0);
a75aacd6 1114}
1115
1116//____________________________________________________________________
1117void AliUEHist::Correct(AliUEHist* corrections)
1118{
1119 // applies the given corrections to extract from the step kCFStepReconstructed all previous steps
1120 //
1121 // in this object the data is expected in the step kCFStepReconstructed
1122
c7245604 1123 if (fHistogramType.Length() == 0)
1124 {
2a910c25 1125 Printf("W-AliUEHist::Correct: fHistogramType not defined. Guessing histogram type...");
1126 if (fTrackHist[kToward]->GetNVar() < 5)
1127 {
44af28f9 1128 if (strcmp(fTrackHist[kToward]->GetTitle(), "d^{2}N_{ch}/d#varphid#eta") == 0)
2a910c25 1129 fHistogramType = "NumberDensitypT";
44af28f9 1130 else if (strcmp(fTrackHist[kToward]->GetTitle(), "d^{2}#Sigma p_{T}/d#varphid#eta") == 0)
2a910c25 1131 fHistogramType = "SumpT";
1132 }
1133 else if (fTrackHist[kToward]->GetNVar() == 5)
1134 {
1135 if (strcmp(fTrackHist[kToward]->GetGrid(0)->GetGrid()->GetAxis(3)->GetTitle(), "multiplicity") == 0)
1136 fHistogramType = "NumberDensityPhi";
1137 else if (strcmp(fTrackHist[kToward]->GetGrid(0)->GetGrid()->GetAxis(3)->GetTitle(), "centrality") == 0)
1138 fHistogramType = "NumberDensityPhiCentrality";
1139 }
1140
1141 if (fHistogramType.Length() == 0)
1142 AliFatal("Cannot figure out histogram type. Try setting it manually...");
c7245604 1143 }
a75aacd6 1144
c7245604 1145 Printf("AliUEHist::Correct: Correcting %s...", fHistogramType.Data());
1146
44af28f9 1147 if (strcmp(fHistogramType, "NumberDensitypT") == 0 || strcmp(fHistogramType, "NumberDensityPhi") == 0 || strcmp(fHistogramType, "SumpT") == 0)
144bd037 1148 {
c7245604 1149 // ---- track level
1150
1151 // bias due to migration in leading pT (because the leading particle is not reconstructed, and the subleading is used)
1152 // extracted as function of leading pT
1153 Bool_t biasFromMC = kFALSE;
ada1a03f 1154 const char* projAxis = "z";
1155 Int_t secondBin = -1;
1156
2a910c25 1157 if (strcmp(fHistogramType, "NumberDensityPhi") == 0)
ada1a03f 1158 {
1159 projAxis = "yz";
1160 secondBin = 4;
1161 }
1162
ff458f69 1163 for (UInt_t region = 0; region < fkRegions; region++)
144bd037 1164 {
c7245604 1165 if (!fTrackHist[region])
1166 continue;
1167
1168 TH1* leadingBiasTracks = 0;
1169 if (biasFromMC)
1170 {
1171 leadingBiasTracks = (TH1*) corrections->GetBias(kCFStepReconstructed, kCFStepTracked, region, projAxis, 0, -1, 1); // from MC
1172 Printf("WARNING: Using MC bias correction");
1173 }
1174 else
1175 leadingBiasTracks = (TH1*) GetBias(kCFStepBiasStudy, kCFStepReconstructed, region, projAxis, 0, -1, 1); // from data
1176
1177 CorrectTracks(kCFStepReconstructed, kCFStepTracked, region, leadingBiasTracks, 2, secondBin);
1178 if (region == kMin && fCombineMinMax)
1179 {
1180 CorrectTracks(kCFStepReconstructed, kCFStepTracked, kMax, leadingBiasTracks, 2, secondBin);
1181 delete leadingBiasTracks;
1182 break;
1183 }
1184 delete leadingBiasTracks;
1185 }
1186
1187 TH1* leadingBiasEvents = 0;
1188 if (biasFromMC)
1189 leadingBiasEvents = (TH1*) corrections->GetBias(kCFStepReconstructed, kCFStepTracked, kToward, projAxis, 0, -1, 2); // from MC
1190 else
1191 leadingBiasEvents = (TH1*) GetBias(kCFStepBiasStudy, kCFStepReconstructed, kToward, projAxis, 0, -1, 2); // from data
1192
1193 //new TCanvas; leadingBiasEvents->DrawCopy();
1194 CorrectEvents(kCFStepReconstructed, kCFStepTracked, leadingBiasEvents, 0);
1195 delete leadingBiasEvents;
1196
1197 // --- contamination correction ---
1198
1199 TH2D* contamination = corrections->GetTrackingContamination();
1200 if (corrections->fContaminationEnhancement)
1201 {
1202 Printf("Applying contamination enhancement");
1203
1204 for (Int_t x=1; x<=contamination->GetNbinsX(); x++)
1205 for (Int_t y=1; y<=contamination->GetNbinsX(); y++)
1206 contamination->SetBinContent(x, y, contamination->GetBinContent(x, y) * corrections->fContaminationEnhancement->GetBinContent(corrections->fContaminationEnhancement->GetXaxis()->FindBin(contamination->GetYaxis()->GetBinCenter(y))));
1207 }
1208 CorrectTracks(kCFStepTracked, kCFStepTrackedOnlyPrim, contamination, 0, 1);
1209 CorrectEvents(kCFStepTracked, kCFStepTrackedOnlyPrim, 0, 0);
1210 delete contamination;
1211
1212 // --- efficiency correction ---
1213 // correct single-particle efficiency for associated particles
1214 // in addition correct for efficiency on trigger particles (tracks AND events)
1215
1216 TH1* efficiencyCorrection = corrections->GetTrackingEfficiencyCorrection();
1217 // use kCFStepVertex as a temporary step (will be overwritten later anyway)
1218 CorrectTracks(kCFStepTrackedOnlyPrim, kCFStepVertex, efficiencyCorrection, 0, 1);
1219 delete efficiencyCorrection;
1220
1221 // correct pT,T
1222 efficiencyCorrection = corrections->GetTrackEfficiency(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, 1, -1, 2);
1223 CorrectEvents(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, efficiencyCorrection, 0);
1224 CorrectTracks(kCFStepVertex, kCFStepAnaTopology, efficiencyCorrection, 2);
1225 delete efficiencyCorrection;
1226
1227 // copy
1228 CorrectTracks(kCFStepAnaTopology, kCFStepVertex, 0, -1);
1229 CorrectEvents(kCFStepAnaTopology, kCFStepVertex, 0, 0);
1230
1231 // vertex correction on the level of events as function of multiplicity, weighting tracks and events with the same factor
1232 // practically independent of low pT cut
1233 TH1D* vertexCorrection = (TH1D*) corrections->GetEventEfficiency(kCFStepVertex, kCFStepTriggered, 1);
1234
1235 // convert stage from true multiplicity to observed multiplicity by simple conversion factor
1236 TH1D* vertexCorrectionObs = (TH1D*) vertexCorrection->Clone("vertexCorrection2");
1237 vertexCorrectionObs->Reset();
1238
1239 TF1* func = new TF1("func", "[1]+[0]/(x-[2])");
1240 // some defaults
1241 func->SetParameters(0.1, 1, -0.7);
1242 vertexCorrection->Fit(func, "0I", "", 0, 3);
1243 for (Int_t i=1; i<=vertexCorrectionObs->GetNbinsX(); i++)
1244 {
1245 Float_t xPos = 1.0 / 0.77 * vertexCorrectionObs->GetXaxis()->GetBinCenter(i);
1246 if (xPos < 3)
1247 vertexCorrectionObs->SetBinContent(i, func->Eval(xPos));
1248 else
1249 vertexCorrectionObs->SetBinContent(i, vertexCorrection->Interpolate(xPos));
144bd037 1250 }
a75aacd6 1251
c7245604 1252 #if 0
1253 new TCanvas;
1254 vertexCorrection->DrawCopy();
1255 vertexCorrectionObs->SetLineColor(2);
1256 vertexCorrectionObs->DrawCopy("same");
1257 func->SetRange(0, 4);
1258 func->DrawClone("same");
1259 #endif
144bd037 1260
c7245604 1261 CorrectTracks(kCFStepVertex, kCFStepTriggered, vertexCorrectionObs, 3);
1262 CorrectEvents(kCFStepVertex, kCFStepTriggered, vertexCorrectionObs, 1);
1263 delete vertexCorrectionObs;
1264 delete vertexCorrection;
1265 delete func;
1266
1267 // copy
1268 CorrectTracks(kCFStepTriggered, kCFStepAll, 0, -1);
1269 CorrectEvents(kCFStepTriggered, kCFStepAll, 0, 0);
144bd037 1270 }
c7245604 1271 else if (strcmp(fHistogramType, "NumberDensityPhiCentrality") == 0)
144bd037 1272 {
c7245604 1273 // copy
1274 CorrectTracks(kCFStepReconstructed, kCFStepTracked, 0, -1);
1275 CorrectEvents(kCFStepReconstructed, kCFStepTracked, 0, -1);
1276
2a910c25 1277 // Dont use eta in the following, because it is a Delta-eta axis
1278
c7245604 1279 // contamination correction
1280 // correct single-particle contamination for associated particles
2a910c25 1281
1282 TH1* contamination = corrections->GetTrackingContamination(1);
1283
1284 if (1)
1285 {
1286 Printf("Applying contamination enhancement");
1287
1288 for (Int_t bin = 1; bin <= contamination->GetNbinsX(); bin++)
1289 {
1290 printf("%f", contamination->GetBinContent(bin));
1291 if (contamination->GetBinContent(bin) > 0)
1292 contamination->SetBinContent(bin, 1.0 + 1.1 * (contamination->GetBinContent(bin) - 1.0));
1293 printf(" --> %f\n", contamination->GetBinContent(bin));
1294 }
1295 }
1296
1297 CorrectTracks(kCFStepTracked, kCFStepTrackedOnlyPrim, contamination, 1);
c7245604 1298 delete contamination;
1299
2a910c25 1300 // correct for additional contamination due to trigger particle around phi ~ 0
1301 TH2* correlatedContamination = corrections->GetCorrelatedContamination();
1302 if (1)
1303 {
1304 Printf("Applying contamination enhancement");
1305
1306 for (Int_t bin = 1; bin <= correlatedContamination->GetNbinsX(); bin++)
1307 for (Int_t bin2 = 1; bin2 <= correlatedContamination->GetNbinsY(); bin2++)
1308 {
1309 printf("%f", correlatedContamination->GetBinContent(bin, bin2));
1310 if (correlatedContamination->GetBinContent(bin, bin2) > 0)
1311 correlatedContamination->SetBinContent(bin, bin2, 1.0 + 1.1 * (correlatedContamination->GetBinContent(bin, bin2) - 1.0));
1312 printf(" --> %f\n", correlatedContamination->GetBinContent(bin, bin2));
1313 }
1314 }
1315
44af28f9 1316 new TCanvas; correlatedContamination->DrawCopy("COLZ");
2a910c25 1317 CorrectCorrelatedContamination(kCFStepTrackedOnlyPrim, 0, correlatedContamination);
c32a0ca9 1318// Printf("\n\n\nWARNING ---> SKIPPING CorrectCorrelatedContamination\n\n\n");
2a910c25 1319
1320 delete correlatedContamination;
c7245604 1321
1322 // TODO correct for contamination of trigger particles (for tracks AND events)
1323 CorrectEvents(kCFStepTracked, kCFStepTrackedOnlyPrim, 0, 0);
1324
1325 // --- efficiency correction ---
1326 // correct single-particle efficiency for associated particles
1327 // in addition correct for efficiency on trigger particles (tracks AND events)
1328
2a910c25 1329 // in bins of pT and centrality
1330 TH1* efficiencyCorrection = corrections->GetTrackingEfficiencyCorrectionCentrality();
c7245604 1331 // use kCFStepAnaTopology as a temporary step
2a910c25 1332 CorrectTracks(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, efficiencyCorrection, 1, 3);
c7245604 1333 delete efficiencyCorrection;
1334
2a910c25 1335 // correct pT,T in bins of pT and centrality
1336 efficiencyCorrection = corrections->GetTrackEfficiency(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, 1, 3, 2);
1337 CorrectEvents(kCFStepTrackedOnlyPrim, kCFStepVertex, efficiencyCorrection, 0, 1);
1338 CorrectTracks(kCFStepAnaTopology, kCFStepVertex, efficiencyCorrection, 2, 3);
c7245604 1339 delete efficiencyCorrection;
1340
1341 // no correction for vertex finding efficiency and trigger efficiency needed in PbPb
1342 // copy
1343 CorrectTracks(kCFStepVertex, kCFStepAll, 0, -1);
1344 CorrectEvents(kCFStepVertex, kCFStepAll, 0, -1);
144bd037 1345 }
c7245604 1346 else
1347 AliFatal(Form("Unknown histogram for correction: %s", GetTitle()));
a75aacd6 1348}
1349
1350//____________________________________________________________________
2a910c25 1351TH1* AliUEHist::GetTrackEfficiency(CFStep step1, CFStep step2, Int_t axis1, Int_t axis2, Int_t source, Int_t axis3)
a75aacd6 1352{
1353 // creates a track-level efficiency by dividing step2 by step1
1354 // projected to axis1 and axis2 (optional if >= 0)
b1831bcb 1355 //
c7245604 1356 // source: 0 = fTrackHist; 1 = fTrackHistEfficiency; 2 = fTrackHistEfficiency rebinned for pT,T / pT,lead binning
a75aacd6 1357
1358 // integrate over regions
1359 // cache it for efficiency (usually more than one efficiency is requested)
b1831bcb 1360
1361 AliCFContainer* sourceContainer = 0;
1362
1363 if (source == 0)
a75aacd6 1364 {
b1831bcb 1365 if (!fCache)
1366 {
1367 fCache = (AliCFContainer*) fTrackHist[0]->Clone();
ff458f69 1368 for (UInt_t i = 1; i < fkRegions; i++)
b1831bcb 1369 if (fTrackHist[i])
1370 fCache->Add(fTrackHist[i]);
1371 }
1372 sourceContainer = fCache;
a75aacd6 1373 }
c7245604 1374 else if (source == 1 || source == 2)
b1831bcb 1375 {
1376 sourceContainer = fTrackHistEfficiency;
1377 // step offset because we start with kCFStepAnaTopology
1378 step1 = (CFStep) ((Int_t) step1 - (Int_t) kCFStepAnaTopology);
1379 step2 = (CFStep) ((Int_t) step2 - (Int_t) kCFStepAnaTopology);
1380 }
1381 else
1382 return 0;
1383
2a910c25 1384 // reset all limits and set the right ones except those in axis1, axis2 and axis3
b1831bcb 1385 ResetBinLimits(sourceContainer->GetGrid(step1));
1386 ResetBinLimits(sourceContainer->GetGrid(step2));
2a910c25 1387 if (fEtaMax > fEtaMin && axis1 != 0 && axis2 != 0 && axis3 != 0)
a75aacd6 1388 {
44af28f9 1389 Printf("Restricted eta-range to %f %f", fEtaMin, fEtaMax);
b1831bcb 1390 sourceContainer->GetGrid(step1)->SetRangeUser(0, fEtaMin, fEtaMax);
1391 sourceContainer->GetGrid(step2)->SetRangeUser(0, fEtaMin, fEtaMax);
a75aacd6 1392 }
2a910c25 1393 if (fPtMax > fPtMin && axis1 != 1 && axis2 != 1 && axis3 != 1)
a75aacd6 1394 {
b1831bcb 1395 sourceContainer->GetGrid(step1)->SetRangeUser(1, fPtMin, fPtMax);
1396 sourceContainer->GetGrid(step2)->SetRangeUser(1, fPtMin, fPtMax);
a75aacd6 1397 }
2a910c25 1398 if (fCentralityMax > fCentralityMin && axis1 != 3 && axis2 != 3 && axis3 != 3)
1399 {
1400 sourceContainer->GetGrid(step1)->SetRangeUser(3, fCentralityMin, fCentralityMax);
1401 sourceContainer->GetGrid(step2)->SetRangeUser(3, fCentralityMin, fCentralityMax);
1402 }
a75aacd6 1403
1404 TH1* measured = 0;
1405 TH1* generated = 0;
1406
2a910c25 1407 if (axis3 >= 0)
1408 {
1409 generated = sourceContainer->Project(step1, axis1, axis2, axis3);
1410 measured = sourceContainer->Project(step2, axis1, axis2, axis3);
1411 }
1412 else if (axis2 >= 0)
a75aacd6 1413 {
c7245604 1414 generated = sourceContainer->Project(step1, axis1, axis2);
1415 measured = sourceContainer->Project(step2, axis1, axis2);
a75aacd6 1416 }
1417 else
1418 {
c7245604 1419 generated = sourceContainer->Project(step1, axis1);
1420 measured = sourceContainer->Project(step2, axis1);
a75aacd6 1421 }
1422
2a910c25 1423 // check for bins with less than 50 entries, print warning
1424 Int_t binBegin[3];
1425 Int_t binEnd[3];
144bd037 1426
1427 binBegin[0] = 1;
1428 binBegin[1] = 1;
2a910c25 1429 binBegin[2] = 1;
144bd037 1430
1431 binEnd[0] = generated->GetNbinsX();
1432 binEnd[1] = generated->GetNbinsY();
2a910c25 1433 binEnd[2] = generated->GetNbinsZ();
144bd037 1434
1435 if (fEtaMax > fEtaMin)
1436 {
1437 if (axis1 == 0)
1438 {
1439 binBegin[0] = generated->GetXaxis()->FindBin(fEtaMin);
1440 binEnd[0] = generated->GetXaxis()->FindBin(fEtaMax);
1441 }
1442 if (axis2 == 0)
1443 {
1444 binBegin[1] = generated->GetYaxis()->FindBin(fEtaMin);
1445 binEnd[1] = generated->GetYaxis()->FindBin(fEtaMax);
1446 }
2a910c25 1447 if (axis3 == 0)
1448 {
1449 binBegin[2] = generated->GetZaxis()->FindBin(fEtaMin);
1450 binEnd[2] = generated->GetZaxis()->FindBin(fEtaMax);
1451 }
144bd037 1452 }
1453
1454 if (fPtMax > fPtMin)
1455 {
1456 // TODO this is just checking up to 15 for now
1457 Float_t ptMax = TMath::Min((Float_t) 15., fPtMax);
1458 if (axis1 == 1)
1459 {
1460 binBegin[0] = generated->GetXaxis()->FindBin(fPtMin);
1461 binEnd[0] = generated->GetXaxis()->FindBin(ptMax);
1462 }
1463 if (axis2 == 1)
1464 {
1465 binBegin[1] = generated->GetYaxis()->FindBin(fPtMin);
1466 binEnd[1] = generated->GetYaxis()->FindBin(ptMax);
1467 }
2a910c25 1468 if (axis3 == 1)
1469 {
1470 binBegin[2] = generated->GetZaxis()->FindBin(fPtMin);
1471 binEnd[2] = generated->GetZaxis()->FindBin(ptMax);
1472 }
144bd037 1473 }
1474
1475 Int_t total = 0;
1476 Int_t count = 0;
2a910c25 1477 Int_t vars[3];
144bd037 1478
2a910c25 1479 for (Int_t i=0; i<3; i++)
144bd037 1480 vars[i] = binBegin[i];
1481
1482 const Int_t limit = 50;
1483 while (1)
1484 {
1485 if (generated->GetDimension() == 1 && generated->GetBinContent(vars[0]) < limit)
1486 {
1487 Printf("Empty bin at %s=%.2f (%.2f entries)", generated->GetXaxis()->GetTitle(), generated->GetXaxis()->GetBinCenter(vars[0]), generated->GetBinContent(vars[0]));
1488 count++;
1489 }
1490 else if (generated->GetDimension() == 2 && generated->GetBinContent(vars[0], vars[1]) < limit)
1491 {
1492 Printf("Empty bin at %s=%.2f %s=%.2f (%.2f entries)",
1493 generated->GetXaxis()->GetTitle(), generated->GetXaxis()->GetBinCenter(vars[0]),
1494 generated->GetYaxis()->GetTitle(), generated->GetYaxis()->GetBinCenter(vars[1]),
1495 generated->GetBinContent(vars[0], vars[1]));
1496 count++;
1497 }
2a910c25 1498 else if (generated->GetDimension() == 3 && generated->GetBinContent(vars[0], vars[1], vars[2]) < limit)
1499 {
1500 Printf("Empty bin at %s=%.2f %s=%.2f %s=%.2f (%.2f entries)",
1501 generated->GetXaxis()->GetTitle(), generated->GetXaxis()->GetBinCenter(vars[0]),
1502 generated->GetYaxis()->GetTitle(), generated->GetYaxis()->GetBinCenter(vars[1]),
1503 generated->GetZaxis()->GetTitle(), generated->GetZaxis()->GetBinCenter(vars[2]),
1504 generated->GetBinContent(vars[0], vars[1], vars[2]));
1505 count++;
1506 }
1507
1508 vars[2]++;
1509 if (vars[2] == binEnd[2]+1)
1510 {
1511 vars[2] = binBegin[2];
1512 vars[1]++;
1513 }
144bd037 1514
144bd037 1515 if (vars[1] == binEnd[1]+1)
1516 {
1517 vars[1] = binBegin[1];
1518 vars[0]++;
1519 }
1520
1521 if (vars[0] == binEnd[0]+1)
1522 break;
1523 total++;
1524 }
1525
1526 Printf("Correction has %d empty bins (out of %d bins)", count, total);
1527
c7245604 1528 // rebin if required
1529 if (source == 2)
1530 {
c7245604 1531 TAxis* axis = fEventHist->GetGrid(0)->GetGrid()->GetAxis(0);
1532
1533 if (axis->GetNbins() < measured->GetNbinsX())
1534 {
2a910c25 1535 if (axis2 != -1)
1536 {
1537 // 2d rebin with variable axis does not exist in root
1538
1539 TH1* tmp = measured;
1540 measured = new TH2D(Form("%s_rebinned", tmp->GetName()), tmp->GetTitle(), axis->GetNbins(), axis->GetXbins()->GetArray(), tmp->GetNbinsY(), tmp->GetYaxis()->GetXbins()->GetArray());
1541 for (Int_t x=1; x<=tmp->GetNbinsX(); x++)
1542 for (Int_t y=1; y<=tmp->GetNbinsY(); y++)
1543 {
1544 ((TH2*) measured)->Fill(tmp->GetXaxis()->GetBinCenter(x), tmp->GetYaxis()->GetBinCenter(y), tmp->GetBinContent(x, y));
1545 measured->SetBinError(x, y, 0); // cannot trust bin error, set to 0
1546 }
1547 delete tmp;
1548
1549 tmp = generated;
1550 generated = new TH2D(Form("%s_rebinned", tmp->GetName()), tmp->GetTitle(), axis->GetNbins(), axis->GetXbins()->GetArray(), tmp->GetNbinsY(), tmp->GetYaxis()->GetXbins()->GetArray());
1551 for (Int_t x=1; x<=tmp->GetNbinsX(); x++)
1552 for (Int_t y=1; y<=tmp->GetNbinsY(); y++)
1553 {
1554 ((TH2*) generated)->Fill(tmp->GetXaxis()->GetBinCenter(x), tmp->GetYaxis()->GetBinCenter(y), tmp->GetBinContent(x, y));
1555 generated->SetBinError(x, y, 0); // cannot trust bin error, set to 0
1556 }
1557 delete tmp;
1558 }
1559 else
1560 {
1561 TH1* tmp = measured;
1562 measured = tmp->Rebin(axis->GetNbins(), Form("%s_rebinned", tmp->GetName()), axis->GetXbins()->GetArray());
1563 delete tmp;
1564
1565 tmp = generated;
1566 generated = tmp->Rebin(axis->GetNbins(), Form("%s_rebinned", tmp->GetName()), axis->GetXbins()->GetArray());
1567 delete tmp;
1568 }
c7245604 1569 }
1570 else if (axis->GetNbins() > measured->GetNbinsX())
1571 {
2a910c25 1572 if (axis2 != -1)
1573 AliFatal("Rebinning only works for 1d at present");
1574
c7245604 1575 // this is an unfortunate case where the number of bins has to be increased in principle
1576 // there is a region where the binning is finner in one histogram and a region where it is the other way round
1577 // this cannot be resolved in principle, but as we only calculate the ratio the bin in the second region get the same entries
1578 // only a certain binning is supported here
1579 if (axis->GetNbins() != 100 || measured->GetNbinsX() != 39)
1580 AliFatal(Form("Invalid binning --> %d %d", axis->GetNbins(), measured->GetNbinsX()));
1581
1582 Double_t newBins[] = {0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 12.0, 14.0, 16.0, 18.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0, 50.0, 100.0};
1583
1584 // reduce binning below 5 GeV/c
1585 TH1* tmp = measured;
1586 measured = tmp->Rebin(27, Form("%s_rebinned", tmp->GetName()), newBins);
1587 delete tmp;
1588
1589 // increase binning above 5 GeV/c
1590 tmp = measured;
1591 measured = new TH1F(Form("%s_rebinned2", tmp->GetName()), tmp->GetTitle(), axis->GetNbins(), axis->GetBinLowEdge(1), axis->GetBinUpEdge(axis->GetNbins()));
1592 for (Int_t bin=1; bin<=measured->GetNbinsX(); bin++)
1593 {
1594 measured->SetBinContent(bin, tmp->GetBinContent(tmp->FindBin(measured->GetBinCenter(bin))));
1595 measured->SetBinError(bin, tmp->GetBinError(tmp->FindBin(measured->GetBinCenter(bin))));
1596 }
1597 delete tmp;
1598
1599 // reduce binning below 5 GeV/c
1600 tmp = generated;
1601 generated = tmp->Rebin(27, Form("%s_rebinned", tmp->GetName()), newBins);
1602 delete tmp;
1603
1604 // increase binning above 5 GeV/c
1605 tmp = generated;
1606 generated = new TH1F(Form("%s_rebinned2", tmp->GetName()), tmp->GetTitle(), axis->GetNbins(), axis->GetBinLowEdge(1), axis->GetBinUpEdge(axis->GetNbins()));
1607 for (Int_t bin=1; bin<=generated->GetNbinsX(); bin++)
1608 {
1609 generated->SetBinContent(bin, tmp->GetBinContent(tmp->FindBin(generated->GetBinCenter(bin))));
1610 generated->SetBinError(bin, tmp->GetBinError(tmp->FindBin(generated->GetBinCenter(bin))));
1611 }
1612 delete tmp;
1613 }
1614 }
1615
144bd037 1616 measured->Divide(measured, generated, 1, 1, "B");
a75aacd6 1617
1618 delete generated;
1619
b1831bcb 1620 ResetBinLimits(sourceContainer->GetGrid(step1));
1621 ResetBinLimits(sourceContainer->GetGrid(step2));
1622
a75aacd6 1623 return measured;
1624}
1625
1626//____________________________________________________________________
1627TH1* AliUEHist::GetEventEfficiency(CFStep step1, CFStep step2, Int_t axis1, Int_t axis2, Float_t ptLeadMin, Float_t ptLeadMax)
1628{
1629 // creates a event-level efficiency by dividing step2 by step1
1630 // projected to axis1 and axis2 (optional if >= 0)
1631
1632 if (ptLeadMax > ptLeadMin)
1633 {
1634 fEventHist->GetGrid(step1)->SetRangeUser(0, ptLeadMin, ptLeadMax);
1635 fEventHist->GetGrid(step2)->SetRangeUser(0, ptLeadMin, ptLeadMax);
1636 }
1637
1638 TH1* measured = 0;
1639 TH1* generated = 0;
1640
144bd037 1641 if (axis2 >= 0)
a75aacd6 1642 {
c7245604 1643 generated = fEventHist->Project(step1, axis1, axis2);
1644 measured = fEventHist->Project(step2, axis1, axis2);
a75aacd6 1645 }
1646 else
1647 {
c7245604 1648 generated = fEventHist->Project(step1, axis1);
1649 measured = fEventHist->Project(step2, axis1);
a75aacd6 1650 }
1651
144bd037 1652 measured->Divide(measured, generated, 1, 1, "B");
a75aacd6 1653
1654 delete generated;
1655
1656 if (ptLeadMax > ptLeadMin)
1657 {
1658 fEventHist->GetGrid(step1)->SetRangeUser(0, 0, -1);
1659 fEventHist->GetGrid(step2)->SetRangeUser(0, 0, -1);
1660 }
1661
1662 return measured;
1663}
1664
1665//____________________________________________________________________
1666void AliUEHist::WeightHistogram(TH3* hist1, TH1* hist2)
1667{
1668 // weights each entry of the 3d histogram hist1 with the 1d histogram hist2
1669 // where the matching is done of the z axis of hist1 with the x axis of hist2
1670
1671 if (hist1->GetNbinsZ() != hist2->GetNbinsX())
1672 AliFatal(Form("Inconsistent binning %d %d", hist1->GetNbinsZ(), hist2->GetNbinsX()));
1673
1674 for (Int_t x=1; x<=hist1->GetNbinsX(); x++)
1675 {
1676 for (Int_t y=1; y<=hist1->GetNbinsY(); y++)
1677 {
1678 for (Int_t z=1; z<=hist1->GetNbinsZ(); z++)
1679 {
1680 if (hist2->GetBinContent(z) > 0)
1681 {
1682 hist1->SetBinContent(x, y, z, hist1->GetBinContent(x, y, z) / hist2->GetBinContent(z));
1683 hist1->SetBinError(x, y, z, hist1->GetBinError(x, y, z) / hist2->GetBinContent(z));
1684 }
1685 else
1686 {
1687 hist1->SetBinContent(x, y, z, 0);
1688 hist1->SetBinError(x, y, z, 0);
1689 }
1690 }
1691 }
1692 }
1693}
1694
1695//____________________________________________________________________
c7245604 1696TH1* AliUEHist::GetBias(CFStep step1, CFStep step2, Int_t region, const char* axis, Float_t leadPtMin, Float_t leadPtMax, Int_t weighting)
a75aacd6 1697{
1698 // extracts the track-level bias (integrating out the multiplicity) between two steps (dividing step2 by step1)
144bd037 1699 // in the given region (sum over all regions is calculated if region == -1)
a75aacd6 1700 // done by weighting the track-level distribution with the number of events as function of leading pT
1701 // and then calculating the ratio between the distributions
1702 // projected to axis which is a TH3::Project3D string, e.g. "x", or "yx"
1703 // no projection is done if axis == 0
c7245604 1704 // weighting: 0 = tracks weighted with events (as discussed above)
1705 // 1 = only track bias is returned
1706 // 2 = only event bias is returned
a75aacd6 1707
144bd037 1708 AliCFContainer* tmp = 0;
1709
1710 if (region == -1)
1711 {
1712 tmp = (AliCFContainer*) fTrackHist[0]->Clone();
ff458f69 1713 for (UInt_t i = 1; i < fkRegions; i++)
144bd037 1714 if (fTrackHist[i])
1715 tmp->Add(fTrackHist[i]);
1716 }
1717 else if (region == kMin && fCombineMinMax)
1718 {
1719 tmp = (AliCFContainer*) fTrackHist[kMin]->Clone();
1720 tmp->Add(fTrackHist[kMax]);
1721 }
1722 else
1723 tmp = fTrackHist[region];
1724
1725 ResetBinLimits(tmp->GetGrid(step1));
1726 ResetBinLimits(fEventHist->GetGrid(step1));
1727 SetBinLimits(tmp->GetGrid(step1));
1728
1729 ResetBinLimits(tmp->GetGrid(step2));
1730 ResetBinLimits(fEventHist->GetGrid(step2));
1731 SetBinLimits(tmp->GetGrid(step2));
a75aacd6 1732
c7245604 1733 TH1D* events1 = (TH1D*)fEventHist->Project(step1, 0);
1734 TH3D* hist1 = (TH3D*)tmp->Project(step1, 0, tmp->GetNVar()-1, 2);
1735 if (weighting == 0)
1736 WeightHistogram(hist1, events1);
a75aacd6 1737
c7245604 1738 TH1D* events2 = (TH1D*)fEventHist->Project(step2, 0);
1739 TH3D* hist2 = (TH3D*)tmp->Project(step2, 0, tmp->GetNVar()-1, 2);
1740 if (weighting == 0)
1741 WeightHistogram(hist2, events2);
a75aacd6 1742
1743 TH1* generated = hist1;
1744 TH1* measured = hist2;
1745
c7245604 1746 if (weighting == 0 || weighting == 1)
a75aacd6 1747 {
c7245604 1748 if (axis)
a75aacd6 1749 {
c7245604 1750 if (leadPtMax > leadPtMin)
1751 {
1752 hist1->GetZaxis()->SetRangeUser(leadPtMin, leadPtMax);
1753 hist2->GetZaxis()->SetRangeUser(leadPtMin, leadPtMax);
1754 }
1755
1756 if (fEtaMax > fEtaMin && !TString(axis).Contains("x"))
1757 {
1758 hist1->GetXaxis()->SetRangeUser(fEtaMin, fEtaMax);
1759 hist2->GetXaxis()->SetRangeUser(fEtaMin, fEtaMax);
1760 }
a75aacd6 1761
c7245604 1762 generated = hist1->Project3D(axis);
1763 measured = hist2->Project3D(axis);
1764
1765 // delete hists here if projection has been done
1766 delete hist1;
1767 delete hist2;
a75aacd6 1768 }
c7245604 1769 delete events1;
1770 delete events2;
1771 }
1772 else if (weighting == 2)
1773 {
a75aacd6 1774 delete hist1;
1775 delete hist2;
c7245604 1776 generated = events1;
1777 measured = events2;
a75aacd6 1778 }
1779
1780 measured->Divide(generated);
1781
a75aacd6 1782 delete generated;
144bd037 1783
1784 ResetBinLimits(tmp->GetGrid(step1));
1785 ResetBinLimits(tmp->GetGrid(step2));
1786
29e8465c 1787 if ((region == -1) || (region == kMin && fCombineMinMax))
144bd037 1788 delete tmp;
a75aacd6 1789
1790 return measured;
1791}
1792
2a910c25 1793//____________________________________________________________________
1794void AliUEHist::CorrectCorrelatedContamination(CFStep step, Int_t region, TH1* trackCorrection)
1795{
1796 // corrects for the given factor in a small delta-eta and delta-phi window as function of pT,A and pT,T
1797
1798 if (!fTrackHist[region])
1799 return;
1800
1801 THnSparse* grid = fTrackHist[region]->GetGrid(step)->GetGrid();
1802
1803 Int_t var1 = 1;
1804 Int_t var2 = 2;
1805
1806 if (grid->GetAxis(var1)->GetNbins() != trackCorrection->GetNbinsX())
1807 AliFatal(Form("Invalid binning (var1): %d %d", grid->GetAxis(var1)->GetNbins(), trackCorrection->GetNbinsX()));
1808
1809 if (grid->GetAxis(var2)->GetNbins() != trackCorrection->GetNbinsY())
1810 AliFatal(Form("Invalid binning (var2): %d %d", grid->GetAxis(var2)->GetNbins(), trackCorrection->GetNbinsY()));
1811
1812 // optimized implementation
1813 for (Int_t binIdx = 0; binIdx < grid->GetNbins(); binIdx++)
1814 {
c32a0ca9 1815 Int_t bins[6];
2a910c25 1816
1817 Double_t value = grid->GetBinContent(binIdx, bins);
1818 Double_t error = grid->GetBinError(binIdx);
1819
1820 // check eta and phi axes
1821 if (TMath::Abs(grid->GetAxis(0)->GetBinCenter(bins[0])) > 0.1)
1822 continue;
1823 if (TMath::Abs(grid->GetAxis(4)->GetBinCenter(bins[4])) > 0.1)
1824 continue;
1825
1826 value *= trackCorrection->GetBinContent(bins[var1], bins[var2]);
1827 error *= trackCorrection->GetBinContent(bins[var1], bins[var2]);
1828
1829 grid->SetBinContent(bins, value);
1830 grid->SetBinError(bins, error);
1831 }
1832
1833 Printf("AliUEHist::CorrectCorrelatedContamination: Corrected.");
1834}
1835
1836//____________________________________________________________________
1837TH2* AliUEHist::GetCorrelatedContamination()
1838{
1839 // contamination correlated with the trigger particle is evaluated between step kCFStepTracked and kCFStepTrackedOnlyPrim in the region of delta eta and delta phi < 0.1 (smallest bin!)
1840
1841 Int_t step1 = kCFStepTrackedOnlyPrim;
1842 Int_t step2 = kCFStepTracked;
1843
1844 fTrackHist[0]->GetGrid(step1)->SetRangeUser(0, -0.01, 0.01); // delta eta
1845 fTrackHist[0]->GetGrid(step1)->SetRangeUser(4, -0.01, 0.01); // delta phi
1846 TH2* tracksStep1 = (TH2*) fTrackHist[0]->Project(step1, 1, 2);
1847
1848 fTrackHist[0]->GetGrid(step2)->SetRangeUser(0, -0.01, 0.01); // delta eta
1849 fTrackHist[0]->GetGrid(step2)->SetRangeUser(4, -0.01, 0.01); // delta phi
1850 TH2* tracksStep2 = (TH2*) fTrackHist[0]->Project(step2, 1, 2);
1851
1852 tracksStep1->Divide(tracksStep2);
1853
1854 TH1* triggersStep1 = fEventHist->Project(step1, 0);
1855 TH1* triggersStep2 = fEventHist->Project(step2, 0);
1856
1857 TH1* singleParticle = GetTrackingContamination(1);
1858
1859 for (Int_t x=1; x<=tracksStep1->GetNbinsX(); x++)
1860 for (Int_t y=1; y<=tracksStep1->GetNbinsY(); y++)
44af28f9 1861 if (singleParticle->GetBinContent(x) > 0 && triggersStep1->GetBinContent(y) > 0)
2a910c25 1862 tracksStep1->SetBinContent(x, y, tracksStep1->GetBinContent(x, y) / triggersStep1->GetBinContent(y) * triggersStep2->GetBinContent(y) / singleParticle->GetBinContent(x));
1863 else
1864 tracksStep1->SetBinContent(x, y, 0);
1865
1866 delete singleParticle;
1867 delete tracksStep2;
1868 delete triggersStep1;
1869 delete triggersStep2;
1870
1871 return tracksStep1;
1872}
1873
a75aacd6 1874//____________________________________________________________________
1875TH2D* AliUEHist::GetTrackingEfficiency()
1876{
1877 // extracts the tracking efficiency by calculating the efficiency from step kCFStepAnaTopology to kCFStepTrackedOnlyPrim
1878 // integrates over the regions and all other variables than pT and eta to increase the statistics
1879 //
1880 // returned histogram has to be deleted by the user
1881
1882 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepAnaTopology, kCFStepTrackedOnlyPrim, 0, 1));
1883}
1884
2a910c25 1885//____________________________________________________________________
1886TH2D* AliUEHist::GetTrackingEfficiencyCentrality()
1887{
1888 // extracts the tracking efficiency by calculating the efficiency from step kCFStepAnaTopology to kCFStepTrackedOnlyPrim
1889 // integrates over the regions and all other variables than pT, centrality to increase the statistics
1890 //
1891 // returned histogram has to be deleted by the user
1892
1893 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepAnaTopology, kCFStepTrackedOnlyPrim, 1, 3));
1894}
1895
a75aacd6 1896//____________________________________________________________________
1897TH1D* AliUEHist::GetTrackingEfficiency(Int_t axis)
1898{
1899 // extracts the tracking efficiency by calculating the efficiency from step kCFStepAnaTopology to kCFStepTrackedOnlyPrim
1900 // integrates over the regions and all other variables than pT (axis == 0) and eta (axis == 1) to increase the statistics
1901
1902 return dynamic_cast<TH1D*> (GetTrackEfficiency(kCFStepAnaTopology, kCFStepTrackedOnlyPrim, axis));
1903}
1904
1905//____________________________________________________________________
1906TH2D* AliUEHist::GetTrackingCorrection()
1907{
1908 // extracts the tracking correction by calculating the efficiency from step kCFStepAnaTopology to kCFStepTracked
1909 // integrates over the regions and all other variables than pT and eta to increase the statistics
1910 //
1911 // returned histogram has to be deleted by the user
1912
1913 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepTracked, kCFStepAnaTopology, 0, 1));
1914}
1915
1916//____________________________________________________________________
1917TH1D* AliUEHist::GetTrackingCorrection(Int_t axis)
1918{
1919 // extracts the tracking correction by calculating the efficiency from step kCFStepAnaTopology to kCFStepTracked
1920 // integrates over the regions and all other variables than pT (axis == 0) and eta (axis == 1) to increase the statistics
1921
1922 return dynamic_cast<TH1D*> (GetTrackEfficiency(kCFStepTracked, kCFStepAnaTopology, axis));
1923}
1924
144bd037 1925//____________________________________________________________________
1926TH2D* AliUEHist::GetTrackingEfficiencyCorrection()
1927{
1928 // extracts the tracking correction by calculating the efficiency from step kCFStepAnaTopology to kCFStepTracked
1929 // integrates over the regions and all other variables than pT and eta to increase the statistics
1930 //
1931 // returned histogram has to be deleted by the user
1932
1933 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, 0, 1));
1934}
1935
2a910c25 1936//____________________________________________________________________
1937TH2D* AliUEHist::GetTrackingEfficiencyCorrectionCentrality()
1938{
1939 // extracts the tracking correction by calculating the efficiency from step kCFStepAnaTopology to kCFStepTracked
1940 // integrates over the regions and all other variables than pT and centrality to increase the statistics
1941 //
1942 // returned histogram has to be deleted by the user
1943
1944 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, 1, 3));
1945}
1946
144bd037 1947//____________________________________________________________________
1948TH1D* AliUEHist::GetTrackingEfficiencyCorrection(Int_t axis)
1949{
1950 // extracts the tracking correction by calculating the efficiency from step kCFStepAnaTopology to kCFStepTracked
1951 // integrates over the regions and all other variables than pT (axis == 0) and eta (axis == 1) to increase the statistics
1952
1953 return dynamic_cast<TH1D*> (GetTrackEfficiency(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, axis));
1954}
1955
a75aacd6 1956//____________________________________________________________________
1957TH2D* AliUEHist::GetTrackingContamination()
1958{
1959 // extracts the tracking contamination by secondaries by calculating the efficiency from step kCFStepTrackedOnlyPrim to kCFStepTracked
1960 // integrates over the regions and all other variables than pT and eta to increase the statistics
1961 //
1962 // returned histogram has to be deleted by the user
1963
1964 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepTracked, kCFStepTrackedOnlyPrim, 0, 1));
1965}
1966
2a910c25 1967//____________________________________________________________________
1968TH2D* AliUEHist::GetTrackingContaminationCentrality()
1969{
1970 // extracts the tracking contamination by secondaries by calculating the efficiency from step kCFStepTrackedOnlyPrim to kCFStepTracked
1971 // integrates over the regions and all other variables than pT and centrality to increase the statistics
1972 //
1973 // returned histogram has to be deleted by the user
1974
1975 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepTracked, kCFStepTrackedOnlyPrim, 1, 3));
1976}
1977
a75aacd6 1978//____________________________________________________________________
1979TH1D* AliUEHist::GetTrackingContamination(Int_t axis)
1980{
1981 // extracts the tracking contamination by secondaries by calculating the efficiency from step kCFStepTrackedOnlyPrim to kCFStepTracked
1982 // integrates over the regions and all other variables than pT (axis == 0) and eta (axis == 1) to increase the statistics
1983
1984 return dynamic_cast<TH1D*> (GetTrackEfficiency(kCFStepTracked, kCFStepTrackedOnlyPrim, axis));
1985}
1986
1987//____________________________________________________________________
1988const char* AliUEHist::GetRegionTitle(Region region)
1989{
1990 // returns the name of the given region
1991
1992 switch (region)
1993 {
1994 case kToward:
1995 return "Towards";
1996 case kAway:
1997 return "Away";
1998 case kMin:
1999 return (fCombineMinMax) ? "Transverse" : "Min";
2000 case kMax:
2001 return "Max";
2002 }
2003
2004 return 0;
2005}
2006
2007//____________________________________________________________________
2008const char* AliUEHist::GetStepTitle(CFStep step)
2009{
2010 // returns the name of the given step
2011
2012 switch (step)
2013 {
2014 case kCFStepAll:
2015 return "All events";
2016 case kCFStepTriggered:
2017 return "Triggered";
2018 case kCFStepVertex:
2019 return "Primary Vertex";
2020 case kCFStepAnaTopology:
2021 return "Required analysis topology";
2022 case kCFStepTrackedOnlyPrim:
2023 return "Tracked (matched MC, only primaries)";
2024 case kCFStepTracked:
2025 return "Tracked (matched MC, all)";
2026 case kCFStepReconstructed:
2027 return "Reconstructed";
2028 case kCFStepRealLeading:
2029 return "Correct leading particle identified";
2030 case kCFStepBiasStudy:
2031 return "Bias study applying tracking efficiency";
2032 case kCFStepBiasStudy2:
2033 return "Bias study applying tracking efficiency in two steps";
2034 }
2035
2036 return 0;
2037}
b1831bcb 2038
2039//____________________________________________________________________
2040void AliUEHist::CopyReconstructedData(AliUEHist* from)
2041{
2042 // copies those histograms extracted from ESD to this object
2043
2044 // TODO at present only the pointers are copied
2045
2046 for (Int_t region=0; region<4; region++)
2047 {
2048 if (!fTrackHist[region])
2049 continue;
2050
2051 fTrackHist[region]->SetGrid(AliUEHist::kCFStepReconstructed, from->fTrackHist[region]->GetGrid(AliUEHist::kCFStepReconstructed));
df269636 2052 //fTrackHist[region]->SetGrid(AliUEHist::kCFStepTrackedOnlyPrim, from->fTrackHist[region]->GetGrid(AliUEHist::kCFStepTrackedOnlyPrim));
b1831bcb 2053 fTrackHist[region]->SetGrid(AliUEHist::kCFStepBiasStudy, from->fTrackHist[region]->GetGrid(AliUEHist::kCFStepBiasStudy));
2054 }
2055
2056 fEventHist->SetGrid(AliUEHist::kCFStepReconstructed, from->fEventHist->GetGrid(AliUEHist::kCFStepReconstructed));
df269636 2057 //fEventHist->SetGrid(AliUEHist::kCFStepTrackedOnlyPrim, from->fEventHist->GetGrid(AliUEHist::kCFStepTrackedOnlyPrim));
b1831bcb 2058 fEventHist->SetGrid(AliUEHist::kCFStepBiasStudy, from->fEventHist->GetGrid(AliUEHist::kCFStepBiasStudy));
2059}
6f803f6c 2060
2061//____________________________________________________________________
df269636 2062void AliUEHist::ExtendTrackingEfficiency(Bool_t verbose)
6f803f6c 2063{
2064 // fits the tracking efficiency at high pT with a constant and fills all bins with this tracking efficiency
2065
2066 Float_t fitRangeBegin = 5.01;
2067 Float_t fitRangeEnd = 14.99;
2068 Float_t extendRangeBegin = 10.01;
2069
2a910c25 2070 if (fTrackHistEfficiency->GetNVar() == 3)
c7245604 2071 {
2a910c25 2072 TH1* obj = GetTrackingEfficiency(1);
c7245604 2073
2a910c25 2074 if (verbose)
2075 {
2076 new TCanvas;
2077 obj->Draw();
2078 }
2079
2080 obj->Fit("pol0", (verbose) ? "+" : "0+", "SAME", fitRangeBegin, fitRangeEnd);
c7245604 2081
2a910c25 2082 Float_t trackingEff = obj->GetFunction("pol0")->GetParameter(0);
2083
2084 obj = GetTrackingContamination(1);
2085
2086 if (verbose)
2087 {
2088 new TCanvas;
2089 obj->Draw();
2090 }
2091
2092 obj->Fit("pol0", (verbose) ? "+" : "0+", "SAME", fitRangeBegin, fitRangeEnd);
2093
2094 Float_t trackingCont = obj->GetFunction("pol0")->GetParameter(0);
2095
2096 Printf("AliUEHist::ExtendTrackingEfficiency: Fitted efficiency between %f and %f and got %f tracking efficiency and %f tracking contamination correction. Extending from %f onwards (within %f < eta < %f)", fitRangeBegin, fitRangeEnd, trackingEff, trackingCont, extendRangeBegin, fEtaMin, fEtaMax);
2097
2098 // extend for full pT range
2099 for (Int_t x = fTrackHistEfficiency->GetAxis(0, 0)->FindBin(fEtaMin); x <= fTrackHistEfficiency->GetAxis(0, 0)->FindBin(fEtaMax); x++)
2100 for (Int_t y = fTrackHistEfficiency->GetAxis(1, 0)->FindBin(extendRangeBegin); y <= fTrackHistEfficiency->GetNBins(1); y++)
2101 for (Int_t z = 1; z <= fTrackHistEfficiency->GetNBins(2); z++) // particle type axis
2102 {
2103
2104 Int_t bins[3];
2105 bins[0] = x;
2106 bins[1] = y;
2107 bins[2] = z;
2108
2109 fTrackHistEfficiency->GetGrid(0)->SetElement(bins, 100);
2110 fTrackHistEfficiency->GetGrid(1)->SetElement(bins, 100.0 * trackingEff);
2111 fTrackHistEfficiency->GetGrid(2)->SetElement(bins, 100.0 * trackingEff / trackingCont);
2112 }
2113 }
2114 else if (fTrackHistEfficiency->GetNVar() == 4)
2115 {
2116 // fit in centrality intervals of 20% for efficiency, one bin for contamination
2117 Float_t* trackingEff = 0;
2118 Float_t* trackingCont = 0;
44af28f9 2119 Float_t centralityBins[] = { 0, 10, 20, 40, 60, 100 };
2120 Int_t nCentralityBins = 5;
2a910c25 2121
2122 Printf("AliUEHist::ExtendTrackingEfficiency: Fitting efficiencies between %f and %f. Extending from %f onwards (within %f < eta < %f)", fitRangeBegin, fitRangeEnd, extendRangeBegin, fEtaMin, fEtaMax);
2123
2124 // 0 = eff; 1 = cont
2125 for (Int_t caseNo = 0; caseNo < 2; caseNo++)
2126 {
2127 Float_t* target = 0;
44af28f9 2128 Int_t centralityBinsLocal = nCentralityBins;
2a910c25 2129
2130 if (caseNo == 0)
6f803f6c 2131 {
2a910c25 2132 trackingEff = new Float_t[centralityBinsLocal];
2133 target = trackingEff;
2134 }
2135 else
2136 {
2137 centralityBinsLocal = 1;
2138 trackingCont = new Float_t[centralityBinsLocal];
2139 target = trackingCont;
6f803f6c 2140 }
2a910c25 2141
2142 for (Int_t i=0; i<centralityBinsLocal; i++)
2143 {
44af28f9 2144 if (centralityBinsLocal == 1)
2145 SetCentralityRange(centralityBins[0] + 0.1, centralityBins[nCentralityBins] - 0.1);
2146 else
2147 SetCentralityRange(centralityBins[i] + 0.1, centralityBins[i+1] - 0.1);
2a910c25 2148 TH1* proj = (caseNo == 0) ? GetTrackingEfficiency(1) : GetTrackingContamination(1);
2149 if (verbose)
2150 {
2151 new TCanvas;
2152 proj->DrawCopy();
2153 }
2154 if ((Int_t) proj->Fit("pol0", (verbose) ? "+" : "Q0+", "SAME", fitRangeBegin, fitRangeEnd) == 0)
2155 target[i] = proj->GetFunction("pol0")->GetParameter(0);
2156 else
2157 target[i] = 0;
2158 Printf("AliUEHist::ExtendTrackingEfficiency: case %d, centrality %d, eff %f", caseNo, i, target[i]);
2159 }
2160 }
2161
2162 // extend for full pT range
2163 for (Int_t x = fTrackHistEfficiency->GetAxis(0, 0)->FindBin(fEtaMin); x <= fTrackHistEfficiency->GetAxis(0, 0)->FindBin(fEtaMax); x++)
2164 for (Int_t y = fTrackHistEfficiency->GetAxis(1, 0)->FindBin(extendRangeBegin); y <= fTrackHistEfficiency->GetNBins(1); y++)
2165 for (Int_t z = 1; z <= fTrackHistEfficiency->GetNBins(2); z++) // particle type axis
2166 {
2167 for (Int_t z2 = 1; z2 <= fTrackHistEfficiency->GetNBins(3); z2++) // centrality axis
2168 {
2169
2170 Int_t bins[4];
2171 bins[0] = x;
2172 bins[1] = y;
2173 bins[2] = z;
2174 bins[3] = z2;
2175
44af28f9 2176 Int_t z2Bin = 0;
2177 while (centralityBins[z2Bin+1] < fTrackHistEfficiency->GetAxis(3, 0)->GetBinCenter(z2))
2178 z2Bin++;
2179
2a910c25 2180 //Printf("%d %d", z2, z2Bin);
2181
2182 fTrackHistEfficiency->GetGrid(0)->SetElement(bins, 100);
2183 fTrackHistEfficiency->GetGrid(1)->SetElement(bins, 100.0 * trackingEff[z2Bin]);
2184 if (trackingCont[0] > 0)
2185 fTrackHistEfficiency->GetGrid(2)->SetElement(bins, 100.0 * trackingEff[z2Bin] / trackingCont[0]);
2186 else
2187 fTrackHistEfficiency->GetGrid(2)->SetElement(bins, 0);
2188 }
2189 }
59064365 2190
2191 delete[] trackingEff;
2192 delete[] trackingCont;
2a910c25 2193 }
2194
2195 SetCentralityRange(0, 0);
6f803f6c 2196}
e741fadd 2197
2198void AliUEHist::AdditionalDPhiCorrection(Int_t step)
2199{
2200 // corrects the dphi distribution with an extra factor close to dphi ~ 0
2201
2202 Printf("WARNING: In AliUEHist::AdditionalDPhiCorrection.");
2203
2204 THnSparse* grid = fTrackHist[0]->GetGrid(step)->GetGrid();
2205
2206 // optimized implementation
2207 for (Int_t binIdx = 0; binIdx < grid->GetNbins(); binIdx++)
2208 {
c32a0ca9 2209 Int_t bins[6];
e741fadd 2210 Double_t value = grid->GetBinContent(binIdx, bins);
2211 Double_t error = grid->GetBinError(binIdx);
2212
2213 Float_t binCenter = grid->GetAxis(4)->GetBinCenter(bins[4]);
2214 if (TMath::Abs(binCenter) < 0.2)
2215 {
2216 value *= 0.985;
2217 error *= 0.985;
2218 }
2219 else if (TMath::Abs(binCenter) < 0.3)
2220 {
2221 value *= 0.9925;
2222 error *= 0.9925;
2223 }
2224
2225 grid->SetBinContent(bins, value);
2226 grid->SetBinError(bins, error);
2227 }
2228}
c7245604 2229
2230void AliUEHist::Scale(Double_t factor)
2231{
2232 // scales all contained histograms by the given factor
2233
2234 for (Int_t i=0; i<4; i++)
2235 if (fTrackHist[i])
2236 fTrackHist[i]->Scale(factor);
2237
2238 fEventHist->Scale(factor);
2239 fTrackHistEfficiency->Scale(factor);
2240}
2241
2242void AliUEHist::Reset()
2243{
2244 // resets all contained histograms
2245
2246 for (Int_t i=0; i<4; i++)
2247 if (fTrackHist[i])
2248 for (Int_t step=0; step<fTrackHist[i]->GetNStep(); step++)
2249 fTrackHist[i]->GetGrid(step)->GetGrid()->Reset();
2250
2251 for (Int_t step=0; step<fEventHist->GetNStep(); step++)
2252 fEventHist->GetGrid(step)->GetGrid()->Reset();
2253
2254 for (Int_t step=0; step<fTrackHistEfficiency->GetNStep(); step++)
2255 fTrackHistEfficiency->GetGrid(step)->GetGrid()->Reset();
2256}