1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 /* $Id: AliUEHist.cxx 20164 2007-08-14 15:31:50Z morsch $ */
20 // encapsulate histogram and corrections for one underlying event histogram
23 // Author: Jan Fiete Grosse-Oetringhaus, Sara Vallero
25 #include "AliUEHist.h"
26 #include "AliCFContainer.h"
27 #include "THnSparse.h"
30 #include "TCollection.h"
42 const Int_t AliUEHist::fgkCFSteps = 11;
44 AliUEHist::AliUEHist(const char* reqHist, const char* binning) :
48 fTrackHistEfficiency(0),
59 fContaminationEnhancement(0),
64 fGetMultCacheOn(kFALSE),
66 fHistogramType(reqHist)
70 for (UInt_t i=0; i<fkRegions; i++)
73 if (strlen(reqHist) == 0)
76 Printf("Creating AliUEHist with %s (binning: %s)", reqHist, binning);
78 AliLog::SetClassDebugLevel("AliCFContainer", -1);
79 AliLog::SetClassDebugLevel("AliCFGridSparse", -3);
81 const char* title = "";
84 Int_t nTrackVars = 4; // eta vs pT vs pT,lead (vs delta phi) vs multiplicity
86 Double_t* trackBins[6];
87 const char* trackAxisTitle[6];
91 Double_t* etaBins = GetBinning(binning, "eta", nEtaBins);
92 const char* etaTitle = "#eta";
94 iTrackBin[0] = nEtaBins;
95 trackBins[0] = etaBins;
96 trackAxisTitle[0] = etaTitle;
99 Int_t nDeltaEtaBins = -1;
100 Double_t* deltaEtaBins = GetBinning(binning, "delta_eta", nDeltaEtaBins);
103 trackBins[1] = GetBinning(binning, "p_t_assoc", iTrackBin[1]);
104 trackAxisTitle[1] = "p_{T} (GeV/c)";
107 Int_t npTBinsFine = -1;
108 Double_t* pTBinsFine = GetBinning(binning, "p_t_eff", npTBinsFine);
111 Int_t nLeadingpTBins = -1;
112 Double_t* leadingpTBins = GetBinning(binning, "p_t_leading", nLeadingpTBins);
115 Int_t nLeadingpTBins2 = -1;
116 Double_t* leadingpTBins2 = GetBinning(binning, "p_t_leading_course", nLeadingpTBins2);
119 Int_t nLeadingPhiBins = -1;
120 Double_t* leadingPhiBins = GetBinning(binning, "delta_phi", nLeadingPhiBins);
122 trackBins[3] = GetBinning(binning, "multiplicity", iTrackBin[3]);
123 trackAxisTitle[3] = "multiplicity";
126 const Int_t kNSpeciesBins = 4; // pi, K, p, rest
127 Double_t speciesBins[] = { -0.5, 0.5, 1.5, 2.5, 3.5 };
130 const char* vertexTitle = "z-vtx (cm)";
131 Int_t nVertexBins = -1;
132 Double_t* vertexBins = GetBinning(binning, "vertex", nVertexBins);
133 Int_t nVertexBinsEff = -1;
134 Double_t* vertexBinsEff = GetBinning(binning, "vertex_eff", nVertexBinsEff);
136 Int_t useVtxAxis = 0;
138 // selection depending on requested histogram
139 Int_t axis = -1; // 0 = pT,lead, 1 = phi,lead
140 if (strcmp(reqHist, "NumberDensitypT") == 0)
143 title = "d^{2}N_{ch}/d#varphid#eta";
145 else if (strcmp(reqHist, "NumberDensityPhi") == 0)
148 title = "d^{2}N_{ch}/d#varphid#eta";
150 else if (TString(reqHist).BeginsWith("NumberDensityPhiCentrality"))
152 if (TString(reqHist).Contains("Vtx"))
155 reqHist = "NumberDensityPhiCentrality";
156 fHistogramType = reqHist;
158 title = "d^{2}N_{ch}/d#varphid#eta";
160 else if (strcmp(reqHist, "SumpT") == 0)
163 title = "d^{2}#Sigma p_{T}/d#varphid#eta";
166 AliFatal(Form("Invalid histogram requested: %s", reqHist));
168 UInt_t initRegions = fkRegions;
172 trackBins[2] = leadingpTBins;
173 iTrackBin[2] = nLeadingpTBins;
174 trackAxisTitle[2] = "leading p_{T} (GeV/c)";
182 iTrackBin[2] = nLeadingpTBins2;
183 trackBins[2] = leadingpTBins2;
184 trackAxisTitle[2] = "leading p_{T} (GeV/c)";
186 iTrackBin[4] = nLeadingPhiBins;
187 trackBins[4] = leadingPhiBins;
188 trackAxisTitle[4] = "#Delta #varphi w.r.t. leading track";
195 iTrackBin[0] = nDeltaEtaBins;
196 trackBins[0] = deltaEtaBins;
197 trackAxisTitle[0] = "#Delta#eta";
199 iTrackBin[2] = nLeadingpTBins2;
200 trackBins[2] = leadingpTBins2;
201 trackAxisTitle[2] = "leading p_{T} (GeV/c)";
203 trackAxisTitle[3] = "centrality";
205 iTrackBin[4] = nLeadingPhiBins;
206 trackBins[4] = leadingPhiBins;
207 trackAxisTitle[4] = "#Delta#varphi (rad)";
212 iTrackBin[5] = nVertexBins;
213 trackBins[5] = vertexBins;
214 trackAxisTitle[5] = vertexTitle;
218 for (UInt_t i=0; i<initRegions; i++)
220 if (strcmp(reqHist, "NumberDensityPhiCentrality") == 0)
221 fTrackHist[i] = new AliTHn(Form("fTrackHist_%d", i), title, fgkCFSteps, nTrackVars, iTrackBin);
223 fTrackHist[i] = new AliCFContainer(Form("fTrackHist_%d", i), title, fgkCFSteps, nTrackVars, iTrackBin);
225 for (Int_t j=0; j<nTrackVars; j++)
227 fTrackHist[i]->SetBinLimits(j, trackBins[j]);
228 fTrackHist[i]->SetVarTitle(j, trackAxisTitle[j]);
231 SetStepNames(fTrackHist[i]);
235 Int_t nEventVars = 2;
238 // track 3rd and 4th axis --> event 1st and 2nd axis
239 iEventBin[0] = iTrackBin[2];
240 iEventBin[1] = iTrackBin[3];
242 // plus track 5th axis (in certain cases)
243 if (axis == 2 && useVtxAxis)
246 iEventBin[2] = iTrackBin[5];
249 fEventHist = new AliCFContainer("fEventHist", title, fgkCFSteps, nEventVars, iEventBin);
251 fEventHist->SetBinLimits(0, trackBins[2]);
252 fEventHist->SetVarTitle(0, trackAxisTitle[2]);
254 fEventHist->SetBinLimits(1, trackBins[3]);
255 fEventHist->SetVarTitle(1, trackAxisTitle[3]);
257 if (axis == 2 && useVtxAxis)
259 fEventHist->SetBinLimits(2, trackBins[5]);
260 fEventHist->SetVarTitle(2, trackAxisTitle[5]);
263 SetStepNames(fEventHist);
265 iTrackBin[0] = nEtaBins;
266 iTrackBin[1] = npTBinsFine;
267 iTrackBin[2] = kNSpeciesBins;
268 iTrackBin[4] = nVertexBinsEff;
270 fTrackHistEfficiency = new AliCFContainer("fTrackHistEfficiency", "Tracking efficiency", 6, 5, iTrackBin);
271 fTrackHistEfficiency->SetBinLimits(0, etaBins);
272 fTrackHistEfficiency->SetVarTitle(0, etaTitle);
273 fTrackHistEfficiency->SetBinLimits(1, pTBinsFine);
274 fTrackHistEfficiency->SetVarTitle(1, trackAxisTitle[1]);
275 fTrackHistEfficiency->SetBinLimits(2, speciesBins);
276 fTrackHistEfficiency->SetVarTitle(2, "particle species");
277 fTrackHistEfficiency->SetBinLimits(3, trackBins[3]);
278 fTrackHistEfficiency->SetVarTitle(3, trackAxisTitle[3]);
279 fTrackHistEfficiency->SetBinLimits(4, vertexBinsEff);
280 fTrackHistEfficiency->SetVarTitle(4, vertexTitle);
282 fFakePt = new TH3F("fFakePt","fFakePt;p_{T,rec};p_{T};centrality", 200, 0, 20, 200, 0, 20, 20, 0, 100);
284 delete[] deltaEtaBins;
286 delete[] leadingpTBins;
287 delete[] leadingpTBins2;
288 delete[] leadingPhiBins;
290 delete[] vertexBinsEff;
293 Double_t* AliUEHist::GetBinning(const char* configuration, const char* tag, Int_t& nBins)
295 // takes the binning from <configuration> identified by <tag>
296 // configuration syntax example:
297 // eta: 2.4, -2.3, -2.2, -2.1, -2.0, -1.9, -1.8, -1.7, -1.6, -1.5, -1.4, -1.3, -1.2, -1.1, -1.0, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4
300 // returns bin edges which have to be deleted by the caller
302 TString config(configuration);
303 TObjArray* lines = config.Tokenize("\n");
304 for (Int_t i=0; i<lines->GetEntriesFast(); i++)
306 TString line(lines->At(i)->GetName());
307 if (line.BeginsWith(TString(tag) + ":"))
309 line.Remove(0, strlen(tag) + 1);
310 line.ReplaceAll(" ", "");
311 TObjArray* binning = line.Tokenize(",");
312 Double_t* bins = new Double_t[binning->GetEntriesFast()];
313 for (Int_t j=0; j<binning->GetEntriesFast(); j++)
314 bins[j] = TString(binning->At(j)->GetName()).Atof();
316 nBins = binning->GetEntriesFast() - 1;
325 AliFatal(Form("Tag %s not found in %s", tag, configuration));
329 //_____________________________________________________________________________
330 AliUEHist::AliUEHist(const AliUEHist &c) :
334 fTrackHistEfficiency(0),
345 fContaminationEnhancement(0),
350 fGetMultCacheOn(kFALSE),
355 // AliUEHist copy constructor
358 ((AliUEHist &) c).Copy(*this);
361 //____________________________________________________________________
362 void AliUEHist::SetStepNames(AliCFContainer* container)
364 // sets the names of the correction steps
366 for (Int_t i=0; i<fgkCFSteps; i++)
367 container->SetStepTitle(i, GetStepTitle((CFStep) i));
370 //____________________________________________________________________
371 AliUEHist::~AliUEHist()
375 for (UInt_t i=0; i<fkRegions; i++)
379 delete fTrackHist[i];
390 if (fTrackHistEfficiency)
392 delete fTrackHistEfficiency;
393 fTrackHistEfficiency = 0;
409 //____________________________________________________________________
410 AliUEHist &AliUEHist::operator=(const AliUEHist &c)
412 // assigment operator
415 ((AliUEHist &) c).Copy(*this);
420 //____________________________________________________________________
421 void AliUEHist::Copy(TObject& c) const
425 AliUEHist& target = (AliUEHist &) c;
427 for (UInt_t i=0; i<fkRegions; i++)
429 target.fTrackHist[i] = dynamic_cast<AliCFContainer*> (fTrackHist[i]->Clone());
432 target.fEventHist = dynamic_cast<AliCFContainer*> (fEventHist->Clone());
434 if (fTrackHistEfficiency)
435 target.fTrackHistEfficiency = dynamic_cast<AliCFContainer*> (fTrackHistEfficiency->Clone());
438 target.fFakePt = dynamic_cast<TH3F*> (fFakePt->Clone());
440 target.fEtaMin = fEtaMin;
441 target.fEtaMax = fEtaMax;
442 target.fPtMin = fPtMin;
443 target.fPtMax = fPtMax;
444 target.fPartSpecies = fPartSpecies;
445 target.fCentralityMin = fCentralityMin;
446 target.fCentralityMax = fCentralityMax;
447 target.fZVtxMin = fZVtxMin;
448 target.fZVtxMax = fZVtxMax;
450 if (fContaminationEnhancement)
451 target.fContaminationEnhancement = dynamic_cast<TH1F*> (fContaminationEnhancement->Clone());
453 target.fCombineMinMax = fCombineMinMax;
454 target.fTrackEtaCut = fTrackEtaCut;
455 target.fWeightPerEvent = fWeightPerEvent;
456 target.fHistogramType = fHistogramType;
459 //____________________________________________________________________
460 Long64_t AliUEHist::Merge(TCollection* list)
462 // Merge a list of AliUEHist objects with this (needed for
464 // Returns the number of merged objects (including this).
472 TIterator* iter = list->MakeIterator();
475 // collections of objects
476 const UInt_t kMaxLists = fkRegions+3;
477 TList** lists = new TList*[kMaxLists];
479 for (UInt_t i=0; i<kMaxLists; i++)
480 lists[i] = new TList;
483 while ((obj = iter->Next())) {
485 AliUEHist* entry = dynamic_cast<AliUEHist*> (obj);
489 for (UInt_t i=0; i<fkRegions; i++)
490 if (entry->fTrackHist[i])
491 lists[i]->Add(entry->fTrackHist[i]);
493 lists[fkRegions]->Add(entry->fEventHist);
494 lists[fkRegions+1]->Add(entry->fTrackHistEfficiency);
496 lists[fkRegions+2]->Add(entry->fFakePt);
500 for (UInt_t i=0; i<fkRegions; i++)
502 fTrackHist[i]->Merge(lists[i]);
504 fEventHist->Merge(lists[fkRegions]);
505 fTrackHistEfficiency->Merge(lists[fkRegions+1]);
507 fFakePt->Merge(lists[fkRegions+2]);
509 for (UInt_t i=0; i<kMaxLists; i++)
517 //____________________________________________________________________
518 void AliUEHist::SetBinLimits(THnBase* grid)
520 // sets the bin limits in eta and pT defined by fEtaMin/Max, fPtMin/Max
522 if (fEtaMax > fEtaMin)
523 grid->GetAxis(0)->SetRangeUser(fEtaMin, fEtaMax);
525 grid->GetAxis(1)->SetRangeUser(fPtMin, fPtMax);
528 //____________________________________________________________________
529 void AliUEHist::SetBinLimits(AliCFGridSparse* grid)
531 // sets the bin limits in eta and pT defined by fEtaMin/Max, fPtMin/Max
533 SetBinLimits(grid->GetGrid());
536 //____________________________________________________________________
537 void AliUEHist::ResetBinLimits(THnBase* grid)
539 // resets all bin limits
541 for (Int_t i=0; i<grid->GetNdimensions(); i++)
542 if (grid->GetAxis(i)->TestBit(TAxis::kAxisRange))
543 grid->GetAxis(i)->SetRangeUser(0, -1);
546 //____________________________________________________________________
547 void AliUEHist::ResetBinLimits(AliCFGridSparse* grid)
549 // resets all bin limits
551 ResetBinLimits(grid->GetGrid());
554 //____________________________________________________________________
555 void AliUEHist::CountEmptyBins(AliUEHist::CFStep step, Float_t ptLeadMin, Float_t ptLeadMax)
557 // prints the number of empty bins in the track end event histograms in the given step
562 for (Int_t i=0; i<4; i++)
565 binEnd[i] = fTrackHist[0]->GetNBins(i);
568 if (fEtaMax > fEtaMin)
570 binBegin[0] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(0)->FindBin(fEtaMin);
571 binEnd[0] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(0)->FindBin(fEtaMax);
576 binBegin[1] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(1)->FindBin(fPtMin);
577 binEnd[1] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(1)->FindBin(fPtMax);
580 if (ptLeadMax > ptLeadMin)
582 binBegin[2] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(2)->FindBin(ptLeadMin);
583 binEnd[2] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(2)->FindBin(ptLeadMax);
586 // start from multiplicity 1
587 binBegin[3] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(3)->FindBin(1);
589 for (UInt_t region=0; region<fkRegions; region++)
595 for (Int_t i=0; i<4; i++)
596 vars[i] = binBegin[i];
598 AliCFGridSparse* grid = fTrackHist[region]->GetGrid(step);
601 if (grid->GetElement(vars) == 0)
603 Printf("Empty bin at eta=%.2f pt=%.2f pt_lead=%.2f mult=%.1f",
604 grid->GetBinCenter(0, vars[0]),
605 grid->GetBinCenter(1, vars[1]),
606 grid->GetBinCenter(2, vars[2]),
607 grid->GetBinCenter(3, vars[3])
613 for (Int_t i=3; i>0; i--)
615 if (vars[i] == binEnd[i]+1)
617 vars[i] = binBegin[i];
622 if (vars[0] == binEnd[0]+1)
627 Printf("Region %s has %d empty bins (out of %d bins)", GetRegionTitle((Region) region), count, total);
631 //____________________________________________________________________
632 TH1* 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, Long64_t* normEvents)
634 // Extracts the UE histogram at the given step and in the given region by projection and dividing tracks by events
636 // ptLeadMin, ptLeadMax: Only meaningful for vs. delta phi plot (third axis is ptLead)
637 // Histogram has to be deleted by the caller of the function
639 // twoD: 0: 1D histogram as function of phi
640 // 1: 2D histogram, deltaphi, deltaeta
641 // 10: 1D histogram, within |deltaeta| < 0.8
642 // 11: 1D histogram, within 0.8 < |deltaeta| < 1.6
644 // etaNorm: if kTRUE (default), the distributions are divided by the area in delta eta
646 // normEvents: if non-0 the number of events/trigger particles for the normalization is filled
649 ResetBinLimits(fTrackHist[region]->GetGrid(step));
650 ResetBinLimits(fEventHist->GetGrid(step));
652 SetBinLimits(fTrackHist[region]->GetGrid(step));
655 if (fZVtxMax > fZVtxMin)
657 Printf("Using z-vtx range %f --> %f", fZVtxMin, fZVtxMax);
658 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(5)->SetRangeUser(fZVtxMin, fZVtxMax);
659 fEventHist->GetGrid(step)->GetGrid()->GetAxis(2)->SetRangeUser(fZVtxMin, fZVtxMax);
666 tracks = fTrackHist[region]->ShowProjection(2, step);
667 tracks->GetYaxis()->SetTitle(fTrackHist[region]->GetTitle());
668 if (fCombineMinMax && region == kMin)
670 ResetBinLimits(fTrackHist[kMax]->GetGrid(step));
671 SetBinLimits(fTrackHist[kMax]->GetGrid(step));
673 TH1D* tracks2 = fTrackHist[kMax]->ShowProjection(2, step);
674 tracks->Add(tracks2);
676 ResetBinLimits(fTrackHist[kMax]->GetGrid(step));
679 // normalize to get a density (deta dphi)
680 TAxis* axis = fTrackHist[region]->GetGrid(step)->GetAxis(0);
681 Float_t phiRegion = TMath::TwoPi() / 3;
682 if (!fCombineMinMax && region == kMin)
684 Float_t normalization = phiRegion;
686 normalization *= (axis->GetBinUpEdge(axis->GetLast()) - axis->GetBinLowEdge(axis->GetFirst()));
687 //Printf("Normalization: %f", normalization);
688 tracks->Scale(1.0 / normalization);
690 TH1D* events = fEventHist->ShowProjection(0, step);
691 tracks->Divide(events);
695 if (multBinEnd >= multBinBegin)
697 Printf("Using multiplicity range %d --> %d", multBinBegin, multBinEnd);
698 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(3)->SetRange(multBinBegin, multBinEnd);
699 fEventHist->GetGrid(step)->GetGrid()->GetAxis(1)->SetRange(multBinBegin, multBinEnd);
702 Int_t firstBin = fTrackHist[region]->GetAxis(2, step)->FindBin(ptLeadMin);
703 Int_t lastBin = fTrackHist[region]->GetAxis(2, step)->FindBin(ptLeadMax);
705 Printf("Using leading pT range %d --> %d", firstBin, lastBin);
707 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(2)->SetRange(firstBin, lastBin);
710 tracks = (TH1D*) fTrackHist[region]->GetGrid(step)->Project(4);
712 tracks = (TH1D*) fTrackHist[region]->GetGrid(step)->Project(4, 0);
714 Printf("Calculated histogram --> %f tracks", tracks->Integral());
715 fTrackHist[region]->GetGrid(step)->SetRangeUser(2, 0, -1);
717 if (twoD == 10 || twoD == 11)
719 Float_t etaLimit = 1.0;
722 tracks = (TH1D*) ((TH2*) tracks)->ProjectionX("proj", tracks->GetYaxis()->FindBin(-etaLimit + 0.01), tracks->GetYaxis()->FindBin(etaLimit - 0.01))->Clone();
724 // TODO calculate acc with 2 * (deta - 0.5 * deta*deta / 1.6)
725 tracks->Scale(1. / 0.75);
729 TH1D* tracksTmp1 = (TH1D*) ((TH2*) tracks)->ProjectionX("proj1", tracks->GetYaxis()->FindBin(-etaLimit * 2 + 0.01), tracks->GetYaxis()->FindBin(-etaLimit - 0.01))->Clone();
730 TH1D* tracksTmp2 = ((TH2*) tracks)->ProjectionX("proj2", tracks->GetYaxis()->FindBin(etaLimit + 0.01), tracks->GetYaxis()->FindBin(2 * etaLimit - 0.01));
732 tracksTmp1->Add(tracksTmp2);
738 tracks->Scale(1. / 0.25);
742 // normalize to get a density (deta dphi)
743 // TODO normalization may be off for 2d histogram
744 Float_t normalization = fTrackHist[region]->GetGrid(step)->GetAxis(4)->GetBinWidth(1);
748 TAxis* axis = fTrackHist[region]->GetGrid(step)->GetAxis(0);
749 if (strcmp(axis->GetTitle(), "#eta") == 0)
751 Printf("Normalizing using eta-axis range");
752 normalization *= axis->GetBinUpEdge(axis->GetLast()) - axis->GetBinLowEdge(axis->GetFirst());
756 Printf("Normalizing assuming accepted range of |eta| < 0.8");
757 normalization *= 0.8 * 2;
761 //Printf("Normalization: %f", normalization);
762 tracks->Scale(1.0 / normalization);
764 // 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!
765 TH1D* events = fEventHist->ShowProjection(0, step);
766 Long64_t nEvents = (Long64_t) events->Integral(firstBin, lastBin);
767 Printf("Calculated histogram --> %lld events", nEvents);
769 *normEvents = nEvents;
772 tracks->Scale(1.0 / nEvents);
777 ResetBinLimits(fTrackHist[region]->GetGrid(step));
778 ResetBinLimits(fEventHist->GetGrid(step));
783 //____________________________________________________________________
784 void AliUEHist::GetHistsZVtx(AliUEHist::CFStep step, AliUEHist::Region region, Float_t ptLeadMin, Float_t ptLeadMax, Int_t multBinBegin, Int_t multBinEnd, TH3** trackHist, TH1** eventHist)
786 // Calculates a 3d histogram with deltaphi, deltaeta, zvtx on track level and a 1d histogram on event level (as fct of zvtx)
787 // Histogram has to be deleted by the caller of the function
789 if (!fTrackHist[kToward]->GetGrid(0)->GetGrid()->GetAxis(5))
790 AliFatal("Histogram without vertex axis provided");
793 ResetBinLimits(fTrackHist[region]->GetGrid(step));
794 ResetBinLimits(fEventHist->GetGrid(step));
796 SetBinLimits(fTrackHist[region]->GetGrid(step));
798 if (multBinEnd >= multBinBegin)
800 Printf("Using multiplicity range %d --> %d", multBinBegin, multBinEnd);
801 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(3)->SetRange(multBinBegin, multBinEnd);
802 fEventHist->GetGrid(step)->GetGrid()->GetAxis(1)->SetRange(multBinBegin, multBinEnd);
805 Int_t firstBin = fTrackHist[region]->GetAxis(2, step)->FindBin(ptLeadMin);
806 Int_t lastBin = fTrackHist[region]->GetAxis(2, step)->FindBin(ptLeadMax);
807 Printf("Using leading pT range %d --> %d", firstBin, lastBin);
808 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(2)->SetRange(firstBin, lastBin);
809 fEventHist->GetGrid(step)->GetGrid()->GetAxis(0)->SetRange(firstBin, lastBin);
811 *trackHist = (TH3*) fTrackHist[region]->GetGrid(step)->Project(4, 0, 5);
812 *eventHist = (TH1*) fEventHist->GetGrid(step)->Project(2);
814 ResetBinLimits(fTrackHist[region]->GetGrid(step));
815 ResetBinLimits(fEventHist->GetGrid(step));
818 //____________________________________________________________________
819 void AliUEHist::GetHistsZVtxMult(AliUEHist::CFStep step, AliUEHist::Region region, Float_t ptLeadMin, Float_t ptLeadMax, THnBase** trackHist, TH2** eventHist)
821 // Calculates a 4d histogram with deltaphi, deltaeta, zvtx, multiplicity on track level and
822 // a 2d histogram on event level (as fct of zvtx, multiplicity)
823 // Histograms has to be deleted by the caller of the function
825 if (!fTrackHist[kToward]->GetGrid(0)->GetGrid()->GetAxis(5))
826 AliFatal("Histogram without vertex axis provided");
828 THnBase* sparse = fTrackHist[region]->GetGrid(step)->GetGrid();
833 fGetMultCache = ChangeToThn(sparse);
834 // should work but causes SEGV in ProjectionND below
836 sparse = fGetMultCache;
840 ResetBinLimits(sparse);
841 ResetBinLimits(fEventHist->GetGrid(step));
843 SetBinLimits(sparse);
845 Int_t firstBin = sparse->GetAxis(2)->FindBin(ptLeadMin);
846 Int_t lastBin = sparse->GetAxis(2)->FindBin(ptLeadMax);
847 Printf("Using leading pT range %d --> %d", firstBin, lastBin);
848 sparse->GetAxis(2)->SetRange(firstBin, lastBin);
849 fEventHist->GetGrid(step)->GetGrid()->GetAxis(0)->SetRange(firstBin, lastBin);
851 Int_t dimensions[] = { 4, 0, 5, 3 };
852 THnBase* tmpTrackHist = sparse->ProjectionND(4, dimensions, "E");
853 *eventHist = (TH2*) fEventHist->GetGrid(step)->Project(2, 1);
855 ResetBinLimits(sparse);
856 ResetBinLimits(fEventHist->GetGrid(step));
859 *trackHist = ChangeToThn(tmpTrackHist);
863 //____________________________________________________________________
864 TH2* AliUEHist::GetSumOfRatios2(AliUEHist* mixed, AliUEHist::CFStep step, AliUEHist::Region region, Float_t ptLeadMin, Float_t ptLeadMax, Int_t multBinBegin, Int_t multBinEnd, Bool_t normalizePerTrigger)
866 // Calls GetUEHist(...) for *each* vertex bin and multiplicity bin and performs a sum of ratios:
867 // 1_N [ (same/mixed)_1 + (same/mixed)_2 + (same/mixed)_3 + ... ]
868 // where N is the total number of events/trigger particles and the subscript is the vertex/multiplicity bin
869 // where mixed is normalized such that the information about the number of pairs in same is kept
871 // returns a 2D histogram: deltaphi, deltaeta
874 // mixed: AliUEHist containing mixed event corresponding to this object
875 // <other parameters> : check documentation of AliUEHist::GetUEHist
876 // normalizePerTrigger: divide through number of triggers
878 // do not add this hists to the directory
879 Bool_t oldStatus = TH1::AddDirectoryStatus();
880 TH1::AddDirectory(kFALSE);
882 TH2* totalTracks = 0;
884 THnBase* trackSameAll = 0;
885 THnBase* trackMixedAll = 0;
886 TH2* eventSameAll = 0;
887 TH2* eventMixedAll = 0;
889 Int_t totalEvents = 0;
890 Int_t nCorrelationFunctions = 0;
892 GetHistsZVtxMult(step, region, ptLeadMin, ptLeadMax, &trackSameAll, &eventSameAll);
893 mixed->GetHistsZVtxMult(step, region, ptLeadMin, ptLeadMax, &trackMixedAll, &eventMixedAll);
895 // Printf("%f %f %f %f", trackSameAll->GetEntries(), eventSameAll->GetEntries(), trackMixedAll->GetEntries(), eventMixedAll->GetEntries());
897 // TH1* normParameters = new TH1F("normParameters", "", 100, 0, 2);
899 // trackSameAll->Dump();
901 TAxis* multAxis = trackSameAll->GetAxis(3);
903 if (multBinEnd < multBinBegin)
906 multBinEnd = multAxis->GetNbins();
909 for (Int_t multBin = TMath::Max(1, multBinBegin); multBin <= TMath::Min(multAxis->GetNbins(), multBinEnd); multBin++)
911 trackSameAll->GetAxis(3)->SetRange(multBin, multBin);
912 trackMixedAll->GetAxis(3)->SetRange(multBin, multBin);
914 // get mixed normalization correction factor: is independent of vertex bin if scaled with number of triggers
915 trackMixedAll->GetAxis(2)->SetRange(0, -1);
916 TH2* tracksMixed = trackMixedAll->Projection(1, 0, "E");
917 // Printf("%f", tracksMixed->Integral());
918 Float_t binWidthEta = tracksMixed->GetYaxis()->GetBinWidth(1);
920 // get mixed event normalization by assuming full acceptance at deta at 0 (integrate over dphi), excluding (0, 0)
921 Double_t mixedNormError = 0;
922 Double_t mixedNorm = tracksMixed->IntegralAndError(1, tracksMixed->GetYaxis()->FindBin(-0.01)-1, tracksMixed->GetYaxis()->FindBin(-0.01), tracksMixed->GetYaxis()->FindBin(0.01), mixedNormError);
923 Double_t mixedNormError2 = 0;
924 Double_t mixedNorm2 = tracksMixed->IntegralAndError(tracksMixed->GetYaxis()->FindBin(0.01)+1, tracksMixed->GetNbinsX(), tracksMixed->GetYaxis()->FindBin(-0.01), tracksMixed->GetYaxis()->FindBin(0.01), mixedNormError2);
926 if (mixedNormError == 0 || mixedNormError2 == 0)
928 Printf("ERROR: Skipping multiplicity %d because mixed event is empty %f %f %f %f", multBin, mixedNorm, mixedNormError, mixedNorm2, mixedNormError2);
932 Int_t nBinsMixedNorm = (tracksMixed->GetYaxis()->FindBin(-0.01) - 1 - 1 + 1) * (tracksMixed->GetYaxis()->FindBin(0.01) - tracksMixed->GetYaxis()->FindBin(-0.01) + 1);
933 mixedNorm /= nBinsMixedNorm;
934 mixedNormError /= nBinsMixedNorm;
936 Int_t nBinsMixedNorm2 = (tracksMixed->GetNbinsX() - tracksMixed->GetYaxis()->FindBin(0.01) - 1 + 1) * (tracksMixed->GetYaxis()->FindBin(0.01) - tracksMixed->GetYaxis()->FindBin(-0.01) + 1);
937 mixedNorm2 /= nBinsMixedNorm2;
938 mixedNormError2 /= nBinsMixedNorm2;
940 mixedNorm = mixedNorm / mixedNormError / mixedNormError + mixedNorm2 / mixedNormError2 / mixedNormError2;
941 mixedNormError = TMath::Sqrt(1.0 / (1.0 / mixedNormError / mixedNormError + 1.0 / mixedNormError2 / mixedNormError2));
942 mixedNorm *= mixedNormError * mixedNormError;
944 /* Double_t mixedNorm = tracksMixed->IntegralAndError(tracksMixed->GetXaxis()->FindBin(-0.01), tracksMixed->GetXaxis()->FindBin(0.01), tracksMixed->GetYaxis()->FindBin(-0.01), tracksMixed->GetYaxis()->FindBin(0.01), mixedNormError);
945 Int_t nBinsMixedNorm = (tracksMixed->GetXaxis()->FindBin(0.01) - tracksMixed->GetXaxis()->FindBin(-0.01) + 1) * (tracksMixed->GetYaxis()->FindBin(0.01) - tracksMixed->GetYaxis()->FindBin(-0.01) + 1);*/
949 Float_t triggers = eventMixedAll->Integral(1, eventMixedAll->GetNbinsX(), multBin, multBin);
950 // Printf("%f +- %f | %f | %f", mixedNorm, mixedNormError, triggers, mixedNorm / triggers);
953 Printf("ERROR: Skipping multiplicity %d because mixed event is empty", multBin);
957 mixedNorm /= triggers;
958 mixedNormError /= triggers;
962 Printf("ERROR: Skipping multiplicity %d because mixed event is empty at (0,0)", multBin);
966 // finite bin correction
967 if (fTrackEtaCut > 0)
969 Double_t finiteBinCorrection = -1.0 / (2*fTrackEtaCut) * binWidthEta / 2 + 1;
970 Printf("Finite bin correction: %f", finiteBinCorrection);
971 mixedNorm *= finiteBinCorrection;
972 mixedNormError *= finiteBinCorrection;
976 Printf("ERROR: fTrackEtaCut not set. Finite bin correction cannot be applied. Continuing anyway...");
979 // Printf("Norm: %f +- %f", mixedNorm, mixedNormError);
981 // normParameters->Fill(mixedNorm);
983 TAxis* vertexAxis = trackSameAll->GetAxis(2);
984 for (Int_t vertexBin = 1; vertexBin <= vertexAxis->GetNbins(); vertexBin++)
985 // for (Int_t vertexBin = 5; vertexBin <= 6; vertexBin++)
987 trackSameAll->GetAxis(2)->SetRange(vertexBin, vertexBin);
988 trackMixedAll->GetAxis(2)->SetRange(vertexBin, vertexBin);
990 TH2* tracksSame = trackSameAll->Projection(1, 0, "E");
991 tracksMixed = trackMixedAll->Projection(1, 0, "E");
993 // asssume flat in dphi, gain in statistics
994 // TH1* histMixedproj = mixedTwoD->ProjectionY();
995 // histMixedproj->Scale(1.0 / mixedTwoD->GetNbinsX());
997 // for (Int_t x=1; x<=mixedTwoD->GetNbinsX(); x++)
998 // for (Int_t y=1; y<=mixedTwoD->GetNbinsY(); y++)
999 // mixedTwoD->SetBinContent(x, y, histMixedproj->GetBinContent(y));
1001 // delete histMixedproj;
1003 Float_t triggers2 = eventMixedAll->Integral(vertexBin, vertexBin, multBin, multBin);
1006 Printf("ERROR: Skipping multiplicity %d vertex bin %d because mixed event is empty", multBin, vertexBin);
1010 tracksMixed->Scale(1.0 / triggers2 / mixedNorm);
1011 // tracksSame->Scale(tracksMixed->Integral() / tracksSame->Integral());
1013 // new TCanvas; tracksSame->DrawClone("SURF1");
1014 // new TCanvas; tracksMixed->DrawClone("SURF1");
1016 // some code to judge the relative contribution of the different correlation functions to the overall uncertainty
1017 Double_t sums[] = { 0, 0, 0 };
1018 Double_t errors[] = { 0, 0, 0 };
1020 for (Int_t x=1; x<=tracksSame->GetNbinsX(); x++)
1021 for (Int_t y=1; y<=tracksSame->GetNbinsY(); y++)
1023 sums[0] += tracksSame->GetBinContent(x, y);
1024 errors[0] += tracksSame->GetBinError(x, y);
1025 sums[1] += tracksMixed->GetBinContent(x, y);
1026 errors[1] += tracksMixed->GetBinError(x, y);
1029 tracksSame->Divide(tracksMixed);
1031 for (Int_t x=1; x<=tracksSame->GetNbinsX(); x++)
1032 for (Int_t y=1; y<=tracksSame->GetNbinsY(); y++)
1034 sums[2] += tracksSame->GetBinContent(x, y);
1035 errors[2] += tracksSame->GetBinError(x, y);
1038 for (Int_t x=0; x<3; x++)
1040 errors[x] /= sums[x];
1042 Printf("The correlation function %d %d has uncertainties %f %f %f (Ratio S/M %f)", multBin, vertexBin, errors[0], errors[1], errors[2], (errors[1] > 0) ? errors[0] / errors[1] : -1);
1043 // code to draw contributions
1045 TH1* proj = tracksSame->ProjectionX("projx", tracksSame->GetYaxis()->FindBin(-1.59), tracksSame->GetYaxis()->FindBin(1.59));
1046 proj->SetTitle(Form("Bin %d", vertexBin));
1047 proj->SetLineColor(vertexBin);
1048 proj->DrawCopy((vertexBin > 1) ? "SAME" : "");
1052 totalTracks = (TH2*) tracksSame->Clone("totalTracks");
1054 totalTracks->Add(tracksSame);
1056 totalEvents += eventSameAll->GetBinContent(vertexBin, multBin);
1058 // new TCanvas; tracksMixed->DrawCopy("SURF1");
1064 nCorrelationFunctions++;
1069 Double_t sums[] = { 0, 0, 0 };
1070 Double_t errors[] = { 0, 0, 0 };
1072 for (Int_t x=1; x<=totalTracks->GetNbinsX(); x++)
1073 for (Int_t y=1; y<=totalTracks->GetNbinsY(); y++)
1075 sums[0] += totalTracks->GetBinContent(x, y);
1076 errors[0] += totalTracks->GetBinError(x, y);
1079 errors[0] /= sums[0];
1081 if (normalizePerTrigger)
1083 Printf("Dividing %f tracks by %d events (%d correlation function(s)) (error %f)", totalTracks->Integral(), totalEvents, nCorrelationFunctions, errors[0]);
1084 if (totalEvents > 0)
1085 totalTracks->Scale(1.0 / totalEvents);
1088 // normalizate to dphi width
1089 Float_t normalization = totalTracks->GetXaxis()->GetBinWidth(1);
1090 totalTracks->Scale(1.0 / normalization);
1093 delete trackSameAll;
1094 delete trackMixedAll;
1095 delete eventSameAll;
1096 delete eventMixedAll;
1098 // new TCanvas; normParameters->Draw();
1100 TH1::AddDirectory(oldStatus);
1105 TH1* AliUEHist::GetTriggersAsFunctionOfMultiplicity(AliUEHist::CFStep step, Float_t ptLeadMin, Float_t ptLeadMax)
1107 // returns the distribution of triggers as function of centrality/multiplicity
1109 ResetBinLimits(fEventHist->GetGrid(step));
1111 Int_t firstBin = fEventHist->GetGrid(step)->GetGrid()->GetAxis(0)->FindBin(ptLeadMin);
1112 Int_t lastBin = fEventHist->GetGrid(step)->GetGrid()->GetAxis(0)->FindBin(ptLeadMax);
1113 Printf("Using pT range %d --> %d", firstBin, lastBin);
1114 fEventHist->GetGrid(step)->GetGrid()->GetAxis(0)->SetRange(firstBin, lastBin);
1116 TH1* eventHist = fEventHist->GetGrid(step)->Project(1);
1118 ResetBinLimits(fEventHist->GetGrid(step));
1124 TH2* AliUEHist::GetPtDistInPhiRegion(AliUEHist* mixed, AliUEHist::CFStep step, AliUEHist::Region region, Float_t ptLeadMin, Float_t ptLeadMax, Int_t multBinBegin, Int_t multBinEnd, Float_t phiBegin, Float_t phiEnd)
1126 // Returns pT,assoc distribution in the given pt,trig, multiplicity, phi region
1127 // Does not use sum of ratios for mixed event correction (TODO to be improved)
1128 // returns a 2D histogram: deltaphi, deltaeta
1131 // mixed: AliUEHist containing mixed event corresponding to this object
1134 //____________________________________________________________________
1135 TH2* 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)
1137 // Calls GetUEHist(...) for *each* multiplicity bin and performs a sum of ratios:
1138 // 1_N [ (same/mixed)_1 + (same/mixed)_2 + (same/mixed)_3 + ... ]
1139 // where N is the total number of events/trigger particles and the subscript is the multiplicity bin
1141 // Can only be used for the 2D histogram at present
1144 // mixed: AliUEHist containing mixed event corresponding to this object
1145 // <other parameters> : check documentation of AliUEHist::GetUEHist
1147 TH2* totalTracks = 0;
1148 Int_t totalEvents = 0;
1150 Int_t vertexBin = 1;
1151 TAxis* vertexAxis = fTrackHist[kToward]->GetGrid(0)->GetGrid()->GetAxis(5);
1152 if (useVertexBins && !vertexAxis)
1154 Printf("Vertex axis requested but not available");
1163 SetZVtxRange(vertexAxis->GetBinLowEdge(vertexBin) + 0.01, vertexAxis->GetBinUpEdge(vertexBin) - 0.01);
1164 mixed->SetZVtxRange(vertexAxis->GetBinLowEdge(vertexBin) + 0.01, vertexAxis->GetBinUpEdge(vertexBin) - 0.01);
1168 // multiplicity loop
1169 Int_t multIter = multBinBegin;
1172 Int_t multBinBeginLocal = multBinBegin;
1173 Int_t multBinEndLocal = multBinEnd;
1175 if (multBinEnd >= multBinBegin)
1177 multBinBeginLocal = multIter;
1178 multBinEndLocal = multIter;
1182 Long64_t nEvents = 0;
1183 TH2* tracks = (TH2*) GetUEHist(step, region, ptLeadMin, ptLeadMax, multBinBeginLocal, multBinEndLocal, 1, etaNorm, &nEvents);
1184 // undo normalization
1185 tracks->Scale(nEvents);
1186 totalEvents += nEvents;
1188 TH2* mixedTwoD = (TH2*) mixed->GetUEHist(step, region, ptLeadMin, ptLeadMax, multBinBeginLocal, multBinEndLocal, 1, etaNorm);
1190 // asssume flat in dphi, gain in statistics
1191 // TH1* histMixedproj = mixedTwoD->ProjectionY();
1192 // histMixedproj->Scale(1.0 / mixedTwoD->GetNbinsX());
1194 // for (Int_t x=1; x<=mixedTwoD->GetNbinsX(); x++)
1195 // for (Int_t y=1; y<=mixedTwoD->GetNbinsY(); y++)
1196 // mixedTwoD->SetBinContent(x, y, histMixedproj->GetBinContent(y));
1198 // delete histMixedproj;
1200 // get mixed event normalization by assuming full acceptance at deta of 0 (only works for flat dphi)
1201 /* Double_t mixedNorm = mixedTwoD->Integral(1, mixedTwoD->GetNbinsX(), mixedTwoD->GetYaxis()->FindBin(-0.01), mixedTwoD->GetYaxis()->FindBin(0.01));
1202 mixedNorm /= mixedTwoD->GetNbinsX() * (mixedTwoD->GetYaxis()->FindBin(0.01) - mixedTwoD->GetYaxis()->FindBin(-0.01) + 1);
1203 tracks->Scale(mixedNorm);*/
1205 tracks->Scale(mixedTwoD->Integral() / tracks->Integral());
1207 tracks->Divide(mixedTwoD);
1212 totalTracks = tracks;
1215 totalTracks->Add(tracks);
1219 if (multIter > multBinEnd)
1223 if (!useVertexBins || vertexBin > vertexAxis->GetNbins())
1228 totalEvents = vertexAxis->GetNbins();
1230 Printf("Dividing %f tracks by %d events", totalTracks->Integral(), totalEvents);
1231 if (totalEvents > 0)
1232 totalTracks->Scale(1.0 / totalEvents);
1237 //____________________________________________________________________
1238 TH1* 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)
1240 // returns a histogram projected to pT,assoc with the provided cuts
1243 ResetBinLimits(fTrackHist[region]->GetGrid(step));
1244 ResetBinLimits(fEventHist->GetGrid(step));
1248 // 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
1249 // therefore the number density must be calculated here per leading pT bin and then summed
1251 if (multBinEnd > multBinBegin)
1252 Printf("Using multiplicity range %d --> %d", multBinBegin, multBinEnd);
1253 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(3)->SetRange(multBinBegin, multBinEnd);
1254 fEventHist->GetGrid(step)->GetGrid()->GetAxis(1)->SetRange(multBinBegin, multBinEnd);
1256 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(0)->SetRangeUser(etaMin, etaMax);
1257 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(4)->SetRangeUser(phiMin, phiMax);
1259 // get real phi cuts due to binning
1260 Float_t phiMinReal = fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(4)->GetBinLowEdge(fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(4)->GetFirst());
1261 Float_t phiMaxReal = fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(4)->GetBinUpEdge(fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(4)->GetLast());
1262 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);
1264 Int_t firstBin = fTrackHist[region]->GetAxis(2, step)->FindBin(ptLeadMin);
1265 Int_t lastBin = fTrackHist[region]->GetAxis(2, step)->FindBin(ptLeadMax);
1267 TH1D* events = fEventHist->ShowProjection(0, step);
1269 for (Int_t bin=firstBin; bin<=lastBin; bin++)
1271 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(2)->SetRange(bin, bin);
1273 // project to pT,assoc
1274 TH1D* tracksTmp = (TH1D*) fTrackHist[region]->GetGrid(step)->Project(1);
1276 Printf("Calculated histogram in bin %d --> %f tracks", bin, tracksTmp->Integral());
1277 fTrackHist[region]->GetGrid(step)->SetRangeUser(2, 0, -1);
1279 // normalize to get a density (deta dphi)
1280 Float_t normalization = 1;
1281 TAxis* axis = fTrackHist[region]->GetGrid(step)->GetAxis(0);
1282 if (strcmp(axis->GetTitle(), "#eta") == 0)
1284 Printf("Normalizing using eta-axis range");
1285 normalization *= axis->GetBinUpEdge(axis->GetLast()) - axis->GetBinLowEdge(axis->GetFirst());
1289 Printf("Normalizating assuming accepted range of |eta| < 0.8");
1290 normalization *= 0.8 * 2;
1294 if (!skipPhiNormalization)
1295 normalization *= phiMaxReal - phiMinReal;
1297 //Printf("Normalization: %f", normalization);
1298 tracksTmp->Scale(1.0 / normalization);
1300 // and now dpT (bins have different width)
1301 for (Int_t i=1; i<=tracksTmp->GetNbinsX(); i++)
1303 tracksTmp->SetBinContent(i, tracksTmp->GetBinContent(i) / tracksTmp->GetXaxis()->GetBinWidth(i));
1304 tracksTmp->SetBinError (i, tracksTmp->GetBinError(i) / tracksTmp->GetXaxis()->GetBinWidth(i));
1307 Int_t nEvents = (Int_t) events->GetBinContent(bin);
1309 tracksTmp->Scale(1.0 / nEvents);
1310 Printf("Calculated histogram in bin %d --> %d events", bin, nEvents);
1316 tracks->Add(tracksTmp);
1323 ResetBinLimits(fTrackHist[region]->GetGrid(step));
1324 ResetBinLimits(fEventHist->GetGrid(step));
1329 void AliUEHist::MultiplyHistograms(THnSparse* grid, THnSparse* target, TH1* histogram, Int_t var1, Int_t var2)
1331 // multiplies <grid> with <histogram> and put the result in <target>
1332 // <grid> has usually more dimensions than histogram. The axis which are used to choose the value
1333 // from <histogram> are given in <var1> and <var2>
1335 // if <histogram> is 0, just copies content from step1 to step2
1337 // clear target histogram
1343 if (grid->GetAxis(var1)->GetNbins() != histogram->GetNbinsX())
1344 AliFatal(Form("Invalid binning (var1): %d %d", grid->GetAxis(var1)->GetNbins(), histogram->GetNbinsX()));
1346 if (var2 >= 0 && grid->GetAxis(var2)->GetNbins() != histogram->GetNbinsY())
1347 AliFatal(Form("Invalid binning (var2): %d %d", grid->GetAxis(var2)->GetNbins(), histogram->GetNbinsY()));
1350 if (grid->GetNdimensions() > 6)
1351 AliFatal("Too many dimensions in THnSparse");
1355 // optimized implementation
1356 for (Int_t binIdx = 0; binIdx < grid->GetNbins(); binIdx++)
1358 Double_t value = grid->GetBinContent(binIdx, bins);
1359 Double_t error = grid->GetBinError(binIdx);
1365 value *= histogram->GetBinContent(bins[var1]);
1366 error *= histogram->GetBinContent(bins[var1]);
1370 value *= histogram->GetBinContent(bins[var1], bins[var2]);
1371 error *= histogram->GetBinContent(bins[var1], bins[var2]);
1375 target->SetBinContent(bins, value);
1376 target->SetBinError(bins, error);
1380 //____________________________________________________________________
1381 void AliUEHist::CorrectTracks(CFStep step1, CFStep step2, TH1* trackCorrection, Int_t var1, Int_t var2)
1383 // corrects from step1 to step2 by multiplying the tracks with trackCorrection
1384 // trackCorrection can be a function of eta (var1 == 0), pT (var1 == 1), leading pT (var1 == 2), multiplicity (var1 == 3), delta phi (var1 == 4)
1385 // if var2 >= 0 a two dimension correction is assumed in trackCorrection
1387 // if trackCorrection is 0, just copies content from step1 to step2
1389 for (UInt_t region=0; region<fkRegions; region++)
1390 CorrectTracks(step1, step2, region, trackCorrection, var1, var2);
1393 //____________________________________________________________________
1394 void AliUEHist::CorrectTracks(CFStep step1, CFStep step2, Int_t region, TH1* trackCorrection, Int_t var1, Int_t var2)
1397 // see documentation of CorrectTracks above
1400 if (!fTrackHist[region])
1403 THnSparse* grid = fTrackHist[region]->GetGrid(step1)->GetGrid();
1404 THnSparse* target = fTrackHist[region]->GetGrid(step2)->GetGrid();
1406 Float_t entriesBefore = grid->GetEntries();
1408 MultiplyHistograms(grid, target, trackCorrection, var1, var2);
1410 Printf("AliUEHist::CorrectTracks: Corrected from %f (step %d) to %f (step %d) entries. Correction histogram: %f entries (integral: %f)", entriesBefore, step1, target->GetEntries(), step2, (trackCorrection) ? trackCorrection->GetEntries() : -1.0, (trackCorrection) ? trackCorrection->Integral() : -1.0);
1413 //____________________________________________________________________
1414 void AliUEHist::CorrectEvents(CFStep step1, CFStep step2, TH1* eventCorrection, Int_t var1, Int_t var2)
1416 // corrects from step1 to step2 by multiplying the events with eventCorrection
1417 // eventCorrection is as function of leading pT (var == 0) or multiplicity (var == 1)
1419 // if eventCorrection is 0, just copies content from step1 to step2
1421 AliCFGridSparse* grid = fEventHist->GetGrid(step1);
1422 AliCFGridSparse* target = fEventHist->GetGrid(step2);
1424 Float_t entriesBefore = grid->GetEntries();
1426 MultiplyHistograms(grid->GetGrid(), target->GetGrid(), eventCorrection, var1, var2);
1428 Printf("AliUEHist::CorrectEvents: Corrected from %f (step %d) to %f (step %d) entries. Correction histogram: %f entries (integral: %f)", entriesBefore, step1, target->GetEntries(), step2, (eventCorrection) ? eventCorrection->GetEntries() : -1.0, (eventCorrection) ? eventCorrection->Integral() : -1.0);
1431 //____________________________________________________________________
1432 void AliUEHist::Correct(AliUEHist* corrections)
1434 // applies the given corrections to extract from the step kCFStepReconstructed all previous steps
1436 // in this object the data is expected in the step kCFStepReconstructed
1438 if (fHistogramType.Length() == 0)
1440 Printf("W-AliUEHist::Correct: fHistogramType not defined. Guessing histogram type...");
1441 if (fTrackHist[kToward]->GetNVar() < 5)
1443 if (strcmp(fTrackHist[kToward]->GetTitle(), "d^{2}N_{ch}/d#varphid#eta") == 0)
1444 fHistogramType = "NumberDensitypT";
1445 else if (strcmp(fTrackHist[kToward]->GetTitle(), "d^{2}#Sigma p_{T}/d#varphid#eta") == 0)
1446 fHistogramType = "SumpT";
1448 else if (fTrackHist[kToward]->GetNVar() == 5)
1450 if (strcmp(fTrackHist[kToward]->GetGrid(0)->GetGrid()->GetAxis(3)->GetTitle(), "multiplicity") == 0)
1451 fHistogramType = "NumberDensityPhi";
1452 else if (strcmp(fTrackHist[kToward]->GetGrid(0)->GetGrid()->GetAxis(3)->GetTitle(), "centrality") == 0)
1453 fHistogramType = "NumberDensityPhiCentrality";
1456 if (fHistogramType.Length() == 0)
1457 AliFatal("Cannot figure out histogram type. Try setting it manually...");
1460 Printf("AliUEHist::Correct: Correcting %s...", fHistogramType.Data());
1462 if (strcmp(fHistogramType, "NumberDensitypT") == 0 || strcmp(fHistogramType, "NumberDensityPhi") == 0 || strcmp(fHistogramType, "SumpT") == 0)
1466 // bias due to migration in leading pT (because the leading particle is not reconstructed, and the subleading is used)
1467 // extracted as function of leading pT
1468 Bool_t biasFromMC = kFALSE;
1469 const char* projAxis = "z";
1470 Int_t secondBin = -1;
1472 if (strcmp(fHistogramType, "NumberDensityPhi") == 0)
1478 for (UInt_t region = 0; region < fkRegions; region++)
1480 if (!fTrackHist[region])
1483 TH1* leadingBiasTracks = 0;
1486 leadingBiasTracks = (TH1*) corrections->GetBias(kCFStepReconstructed, kCFStepTracked, region, projAxis, 0, -1, 1); // from MC
1487 Printf("WARNING: Using MC bias correction");
1490 leadingBiasTracks = (TH1*) GetBias(kCFStepBiasStudy, kCFStepReconstructed, region, projAxis, 0, -1, 1); // from data
1492 CorrectTracks(kCFStepReconstructed, kCFStepTracked, region, leadingBiasTracks, 2, secondBin);
1493 if (region == kMin && fCombineMinMax)
1495 CorrectTracks(kCFStepReconstructed, kCFStepTracked, kMax, leadingBiasTracks, 2, secondBin);
1496 delete leadingBiasTracks;
1499 delete leadingBiasTracks;
1502 TH1* leadingBiasEvents = 0;
1504 leadingBiasEvents = (TH1*) corrections->GetBias(kCFStepReconstructed, kCFStepTracked, kToward, projAxis, 0, -1, 2); // from MC
1506 leadingBiasEvents = (TH1*) GetBias(kCFStepBiasStudy, kCFStepReconstructed, kToward, projAxis, 0, -1, 2); // from data
1508 //new TCanvas; leadingBiasEvents->DrawCopy();
1509 CorrectEvents(kCFStepReconstructed, kCFStepTracked, leadingBiasEvents, 0);
1510 delete leadingBiasEvents;
1512 // --- contamination correction ---
1514 TH2D* contamination = corrections->GetTrackingContamination();
1515 if (corrections->fContaminationEnhancement)
1517 Printf("Applying contamination enhancement");
1519 for (Int_t x=1; x<=contamination->GetNbinsX(); x++)
1520 for (Int_t y=1; y<=contamination->GetNbinsX(); y++)
1521 contamination->SetBinContent(x, y, contamination->GetBinContent(x, y) * corrections->fContaminationEnhancement->GetBinContent(corrections->fContaminationEnhancement->GetXaxis()->FindBin(contamination->GetYaxis()->GetBinCenter(y))));
1523 CorrectTracks(kCFStepTracked, kCFStepTrackedOnlyPrim, contamination, 0, 1);
1524 CorrectEvents(kCFStepTracked, kCFStepTrackedOnlyPrim, 0, 0);
1525 delete contamination;
1527 // --- efficiency correction ---
1528 // correct single-particle efficiency for associated particles
1529 // in addition correct for efficiency on trigger particles (tracks AND events)
1531 TH1* efficiencyCorrection = corrections->GetTrackingEfficiencyCorrection();
1532 // use kCFStepVertex as a temporary step (will be overwritten later anyway)
1533 CorrectTracks(kCFStepTrackedOnlyPrim, kCFStepVertex, efficiencyCorrection, 0, 1);
1534 delete efficiencyCorrection;
1537 efficiencyCorrection = corrections->GetTrackEfficiency(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, 1, -1, 2);
1538 CorrectEvents(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, efficiencyCorrection, 0);
1539 CorrectTracks(kCFStepVertex, kCFStepAnaTopology, efficiencyCorrection, 2);
1540 delete efficiencyCorrection;
1543 CorrectTracks(kCFStepAnaTopology, kCFStepVertex, 0, -1);
1544 CorrectEvents(kCFStepAnaTopology, kCFStepVertex, 0, 0);
1546 // vertex correction on the level of events as function of multiplicity, weighting tracks and events with the same factor
1547 // practically independent of low pT cut
1548 TH1D* vertexCorrection = (TH1D*) corrections->GetEventEfficiency(kCFStepVertex, kCFStepTriggered, 1);
1550 // convert stage from true multiplicity to observed multiplicity by simple conversion factor
1551 TH1D* vertexCorrectionObs = (TH1D*) vertexCorrection->Clone("vertexCorrection2");
1552 vertexCorrectionObs->Reset();
1554 TF1* func = new TF1("func", "[1]+[0]/(x-[2])");
1556 func->SetParameters(0.1, 1, -0.7);
1557 vertexCorrection->Fit(func, "0I", "", 0, 3);
1558 for (Int_t i=1; i<=vertexCorrectionObs->GetNbinsX(); i++)
1560 Float_t xPos = 1.0 / 0.77 * vertexCorrectionObs->GetXaxis()->GetBinCenter(i);
1562 vertexCorrectionObs->SetBinContent(i, func->Eval(xPos));
1564 vertexCorrectionObs->SetBinContent(i, vertexCorrection->Interpolate(xPos));
1569 vertexCorrection->DrawCopy();
1570 vertexCorrectionObs->SetLineColor(2);
1571 vertexCorrectionObs->DrawCopy("same");
1572 func->SetRange(0, 4);
1573 func->DrawClone("same");
1576 CorrectTracks(kCFStepVertex, kCFStepTriggered, vertexCorrectionObs, 3);
1577 CorrectEvents(kCFStepVertex, kCFStepTriggered, vertexCorrectionObs, 1);
1578 delete vertexCorrectionObs;
1579 delete vertexCorrection;
1583 CorrectTracks(kCFStepTriggered, kCFStepAll, 0, -1);
1584 CorrectEvents(kCFStepTriggered, kCFStepAll, 0, 0);
1586 else if (strcmp(fHistogramType, "NumberDensityPhiCentrality") == 0)
1588 if (fTrackHist[0]->GetNVar() <= 5)
1590 // do corrections copying between steps
1591 // CFStep step = kCFStepReconstructed;
1592 CFStep step = kCFStepBiasStudy;
1595 CorrectTracks(step, kCFStepTracked, 0, -1);
1596 CorrectEvents(step, kCFStepTracked, 0, -1);
1598 // Dont use eta in the following, because it is a Delta-eta axis
1600 // contamination correction
1601 // correct single-particle contamination for associated particles
1603 TH1* contamination = corrections->GetTrackingContamination(1);
1607 Printf("Applying contamination enhancement");
1609 for (Int_t bin = 1; bin <= contamination->GetNbinsX(); bin++)
1611 printf("%f", contamination->GetBinContent(bin));
1612 if (contamination->GetBinContent(bin) > 0)
1613 contamination->SetBinContent(bin, 1.0 + 1.1 * (contamination->GetBinContent(bin) - 1.0));
1614 printf(" --> %f\n", contamination->GetBinContent(bin));
1618 CorrectTracks(kCFStepTracked, kCFStepTrackedOnlyPrim, contamination, 1);
1619 delete contamination;
1621 // correct for additional contamination due to trigger particle around phi ~ 0
1622 TH2* correlatedContamination = corrections->GetCorrelatedContamination();
1625 Printf("Applying contamination enhancement");
1627 for (Int_t bin = 1; bin <= correlatedContamination->GetNbinsX(); bin++)
1628 for (Int_t bin2 = 1; bin2 <= correlatedContamination->GetNbinsY(); bin2++)
1630 printf("%f", correlatedContamination->GetBinContent(bin, bin2));
1631 if (correlatedContamination->GetBinContent(bin, bin2) > 0)
1632 correlatedContamination->SetBinContent(bin, bin2, 1.0 + 1.1 * (correlatedContamination->GetBinContent(bin, bin2) - 1.0));
1633 printf(" --> %f\n", correlatedContamination->GetBinContent(bin, bin2));
1637 // new TCanvas; correlatedContamination->DrawCopy("COLZ");
1638 CorrectCorrelatedContamination(kCFStepTrackedOnlyPrim, 0, correlatedContamination);
1639 // Printf("\n\n\nWARNING ---> SKIPPING CorrectCorrelatedContamination\n\n\n");
1641 delete correlatedContamination;
1643 // TODO correct for contamination of trigger particles (for tracks AND events)
1644 CorrectEvents(kCFStepTracked, kCFStepTrackedOnlyPrim, 0, 0);
1646 // --- efficiency correction ---
1647 // correct single-particle efficiency for associated particles
1648 // in addition correct for efficiency on trigger particles (tracks AND events)
1650 // in bins of pT and centrality
1651 TH1* efficiencyCorrection = corrections->GetTrackingEfficiencyCorrectionCentrality();
1652 // new TCanvas; efficiencyCorrection->DrawCopy("COLZ");
1653 // use kCFStepAnaTopology as a temporary step
1654 CorrectTracks(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, efficiencyCorrection, 1, 3);
1655 delete efficiencyCorrection;
1657 // correct pT,T in bins of pT and centrality
1658 efficiencyCorrection = corrections->GetTrackEfficiency(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, 1, 3, 2);
1659 CorrectEvents(kCFStepTrackedOnlyPrim, kCFStepVertex, efficiencyCorrection, 0, 1);
1660 CorrectTracks(kCFStepAnaTopology, kCFStepVertex, efficiencyCorrection, 2, 3);
1661 delete efficiencyCorrection;
1663 // no correction for vertex finding efficiency and trigger efficiency needed in PbPb
1665 CorrectTracks(kCFStepVertex, kCFStepAll, 0, -1);
1666 CorrectEvents(kCFStepVertex, kCFStepAll, 0, -1);
1670 // with 6 axes there is not enough memory, do the corrections in-place
1671 Printf(">>>>>>>> Applying corrections in place to reduce memory consumption");
1672 CFStep step = kCFStepBiasStudy;
1673 // CFStep step = kCFStepReconstructed;
1675 // Dont use eta in the following, because it is a Delta-eta axis
1677 // --- contamination correction ---
1678 // correct single-particle contamination for associated particles
1679 // correct contamination for trigger particles (tracks AND events)
1682 TH1* contamination = corrections->GetTrackingContamination(1);
1686 Printf("Applying contamination enhancement");
1688 for (Int_t bin = 1; bin <= contamination->GetNbinsX(); bin++)
1690 printf("%f", contamination->GetBinContent(bin));
1691 if (contamination->GetBinContent(bin) > 0)
1692 contamination->SetBinContent(bin, 1.0 + 1.1 * (contamination->GetBinContent(bin) - 1.0));
1693 printf(" --> %f\n", contamination->GetBinContent(bin));
1697 // correct pT,A in bins of pT
1698 CorrectTracks(step, step, contamination, 1);
1699 delete contamination;
1701 // correct pT,T in bins of pT (for tracks AND events)
1702 contamination = corrections->GetTrackEfficiency(kCFStepTracked, kCFStepTrackedOnlyPrim, 1, -1, 2);
1703 new TCanvas; contamination->DrawCopy();
1704 CorrectEvents(step, step, contamination, 0);
1705 CorrectTracks(step, step, contamination, 2);
1706 delete contamination;
1708 // correct for additional contamination due to trigger particle around phi ~ 0
1711 TH2* correlatedContamination = corrections->GetCorrelatedContamination();
1714 Printf("Applying contamination enhancement");
1716 for (Int_t bin = 1; bin <= correlatedContamination->GetNbinsX(); bin++)
1717 for (Int_t bin2 = 1; bin2 <= correlatedContamination->GetNbinsY(); bin2++)
1719 printf("%f", correlatedContamination->GetBinContent(bin, bin2));
1720 if (correlatedContamination->GetBinContent(bin, bin2) > 0)
1721 correlatedContamination->SetBinContent(bin, bin2, 1.0 + 1.1 * (correlatedContamination->GetBinContent(bin, bin2) - 1.0));
1722 printf(" --> %f\n", correlatedContamination->GetBinContent(bin, bin2));
1726 // new TCanvas; correlatedContamination->DrawCopy("COLZ");
1727 CorrectCorrelatedContamination(step, 0, correlatedContamination);
1729 delete correlatedContamination;
1732 Printf("\n\n\nWARNING ---> SKIPPING CorrectCorrelatedContamination\n\n\n");
1734 // --- tracking efficiency correction ---
1735 // correct single-particle efficiency for associated particles
1736 // correct for efficiency on trigger particles (tracks AND events)
1738 // in bins of pT and centrality
1739 TH1* efficiencyCorrection = corrections->GetTrackingEfficiencyCorrectionCentrality();
1740 // new TCanvas; efficiencyCorrection->DrawCopy("COLZ");
1742 // correct pT,A in bins of pT and centrality
1743 CorrectTracks(step, step, efficiencyCorrection, 1, 3);
1744 delete efficiencyCorrection;
1746 // correct pT,T in bins of pT and centrality
1747 efficiencyCorrection = corrections->GetTrackEfficiency(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, 1, 3, 2);
1748 CorrectEvents(step, step, efficiencyCorrection, 0, 1);
1749 CorrectTracks(step, step, efficiencyCorrection, 2, 3);
1751 delete efficiencyCorrection;
1755 AliFatal(Form("Unknown histogram for correction: %s", GetTitle()));
1758 //____________________________________________________________________
1759 THnBase* AliUEHist::GetTrackEfficiencyND(CFStep step1, CFStep step2)
1761 // creates a track-level efficiency by dividing step2 by step1
1762 // in all dimensions but the particle species one
1764 AliCFContainer* sourceContainer = fTrackHistEfficiency;
1765 // step offset because we start with kCFStepAnaTopology
1766 step1 = (CFStep) ((Int_t) step1 - (Int_t) kCFStepAnaTopology);
1767 step2 = (CFStep) ((Int_t) step2 - (Int_t) kCFStepAnaTopology);
1769 ResetBinLimits(sourceContainer->GetGrid(step1));
1770 ResetBinLimits(sourceContainer->GetGrid(step2));
1772 if (fEtaMax > fEtaMin)
1774 Printf("Restricted eta-range to %f %f", fEtaMin, fEtaMax);
1775 sourceContainer->GetGrid(step1)->SetRangeUser(0, fEtaMin, fEtaMax);
1776 sourceContainer->GetGrid(step2)->SetRangeUser(0, fEtaMin, fEtaMax);
1779 Int_t dimensions[] = { 0, 1, 3, 4 };
1780 THnBase* generated = sourceContainer->GetGrid(step1)->GetGrid()->ProjectionND(4, dimensions);
1781 THnBase* measured = sourceContainer->GetGrid(step2)->GetGrid()->ProjectionND(4, dimensions);
1783 // Printf("%d %d %f %f", step1, step2, generated->GetEntries(), measured->GetEntries());
1785 ResetBinLimits(sourceContainer->GetGrid(step1));
1786 ResetBinLimits(sourceContainer->GetGrid(step2));
1788 measured->Divide(measured, generated, 1, 1, "B");
1795 //____________________________________________________________________
1796 TH1* AliUEHist::GetTrackEfficiency(CFStep step1, CFStep step2, Int_t axis1, Int_t axis2, Int_t source, Int_t axis3)
1798 // creates a track-level efficiency by dividing step2 by step1
1799 // projected to axis1 and axis2 (optional if >= 0)
1801 // source: 0 = fTrackHist; 1 = fTrackHistEfficiency; 2 = fTrackHistEfficiency rebinned for pT,T / pT,lead binning
1803 // integrate over regions
1804 // cache it for efficiency (usually more than one efficiency is requested)
1806 AliCFContainer* sourceContainer = 0;
1812 fCache = (AliCFContainer*) fTrackHist[0]->Clone();
1813 for (UInt_t i = 1; i < fkRegions; i++)
1815 fCache->Add(fTrackHist[i]);
1817 sourceContainer = fCache;
1819 else if (source == 1 || source == 2)
1821 sourceContainer = fTrackHistEfficiency;
1822 // step offset because we start with kCFStepAnaTopology
1823 step1 = (CFStep) ((Int_t) step1 - (Int_t) kCFStepAnaTopology);
1824 step2 = (CFStep) ((Int_t) step2 - (Int_t) kCFStepAnaTopology);
1829 // reset all limits and set the right ones except those in axis1, axis2 and axis3
1830 ResetBinLimits(sourceContainer->GetGrid(step1));
1831 ResetBinLimits(sourceContainer->GetGrid(step2));
1832 if (fEtaMax > fEtaMin && axis1 != 0 && axis2 != 0 && axis3 != 0)
1834 Printf("Restricted eta-range to %f %f", fEtaMin, fEtaMax);
1835 sourceContainer->GetGrid(step1)->SetRangeUser(0, fEtaMin, fEtaMax);
1836 sourceContainer->GetGrid(step2)->SetRangeUser(0, fEtaMin, fEtaMax);
1838 if (fPtMax > fPtMin && axis1 != 1 && axis2 != 1 && axis3 != 1)
1840 Printf("Restricted pt-range to %f %f", fPtMin, fPtMax);
1841 sourceContainer->GetGrid(step1)->SetRangeUser(1, fPtMin, fPtMax);
1842 sourceContainer->GetGrid(step2)->SetRangeUser(1, fPtMin, fPtMax);
1844 if (fPartSpecies != -1 && axis1 != 2 && axis2 != 2 && axis3 != 2)
1846 Printf("Restricted to particle species %d", fPartSpecies);
1847 sourceContainer->GetGrid(step1)->SetRangeUser(2, fPartSpecies, fPartSpecies);
1848 sourceContainer->GetGrid(step2)->SetRangeUser(2, fPartSpecies, fPartSpecies);
1850 if (fCentralityMax > fCentralityMin && axis1 != 3 && axis2 != 3 && axis3 != 3)
1852 Printf("Restricted centrality range to %f %f", fCentralityMin, fCentralityMax);
1853 sourceContainer->GetGrid(step1)->SetRangeUser(3, fCentralityMin, fCentralityMax);
1854 sourceContainer->GetGrid(step2)->SetRangeUser(3, fCentralityMin, fCentralityMax);
1856 if (fZVtxMax > fZVtxMin && axis1 != 4 && axis2 != 4 && axis3 != 4)
1858 Printf("Restricted z-vtx range to %f %f", fZVtxMin, fZVtxMax);
1859 sourceContainer->GetGrid(step1)->SetRangeUser(4, fZVtxMin, fZVtxMax);
1860 sourceContainer->GetGrid(step2)->SetRangeUser(4, fZVtxMin, fZVtxMax);
1868 generated = sourceContainer->Project(step1, axis1, axis2, axis3);
1869 measured = sourceContainer->Project(step2, axis1, axis2, axis3);
1871 else if (axis2 >= 0)
1873 generated = sourceContainer->Project(step1, axis1, axis2);
1874 measured = sourceContainer->Project(step2, axis1, axis2);
1878 generated = sourceContainer->Project(step1, axis1);
1879 measured = sourceContainer->Project(step2, axis1);
1882 // check for bins with less than 50 entries, print warning
1890 binEnd[0] = generated->GetNbinsX();
1891 binEnd[1] = generated->GetNbinsY();
1892 binEnd[2] = generated->GetNbinsZ();
1894 if (fEtaMax > fEtaMin)
1898 binBegin[0] = generated->GetXaxis()->FindBin(fEtaMin);
1899 binEnd[0] = generated->GetXaxis()->FindBin(fEtaMax);
1903 binBegin[1] = generated->GetYaxis()->FindBin(fEtaMin);
1904 binEnd[1] = generated->GetYaxis()->FindBin(fEtaMax);
1908 binBegin[2] = generated->GetZaxis()->FindBin(fEtaMin);
1909 binEnd[2] = generated->GetZaxis()->FindBin(fEtaMax);
1913 if (fPtMax > fPtMin)
1915 // TODO this is just checking up to 15 for now
1916 Float_t ptMax = TMath::Min((Float_t) 15., fPtMax);
1919 binBegin[0] = generated->GetXaxis()->FindBin(fPtMin);
1920 binEnd[0] = generated->GetXaxis()->FindBin(ptMax);
1924 binBegin[1] = generated->GetYaxis()->FindBin(fPtMin);
1925 binEnd[1] = generated->GetYaxis()->FindBin(ptMax);
1929 binBegin[2] = generated->GetZaxis()->FindBin(fPtMin);
1930 binEnd[2] = generated->GetZaxis()->FindBin(ptMax);
1938 for (Int_t i=0; i<3; i++)
1939 vars[i] = binBegin[i];
1941 const Int_t limit = 50;
1944 if (generated->GetDimension() == 1 && generated->GetBinContent(vars[0]) < limit)
1946 Printf("Empty bin at %s=%.2f (%.2f entries)", generated->GetXaxis()->GetTitle(), generated->GetXaxis()->GetBinCenter(vars[0]), generated->GetBinContent(vars[0]));
1949 else if (generated->GetDimension() == 2 && generated->GetBinContent(vars[0], vars[1]) < limit)
1951 Printf("Empty bin at %s=%.2f %s=%.2f (%.2f entries)",
1952 generated->GetXaxis()->GetTitle(), generated->GetXaxis()->GetBinCenter(vars[0]),
1953 generated->GetYaxis()->GetTitle(), generated->GetYaxis()->GetBinCenter(vars[1]),
1954 generated->GetBinContent(vars[0], vars[1]));
1957 else if (generated->GetDimension() == 3 && generated->GetBinContent(vars[0], vars[1], vars[2]) < limit)
1959 Printf("Empty bin at %s=%.2f %s=%.2f %s=%.2f (%.2f entries)",
1960 generated->GetXaxis()->GetTitle(), generated->GetXaxis()->GetBinCenter(vars[0]),
1961 generated->GetYaxis()->GetTitle(), generated->GetYaxis()->GetBinCenter(vars[1]),
1962 generated->GetZaxis()->GetTitle(), generated->GetZaxis()->GetBinCenter(vars[2]),
1963 generated->GetBinContent(vars[0], vars[1], vars[2]));
1968 if (vars[2] == binEnd[2]+1)
1970 vars[2] = binBegin[2];
1974 if (vars[1] == binEnd[1]+1)
1976 vars[1] = binBegin[1];
1980 if (vars[0] == binEnd[0]+1)
1985 Printf("Correction has %d empty bins (out of %d bins)", count, total);
1987 // rebin if required
1990 TAxis* axis = fEventHist->GetGrid(0)->GetGrid()->GetAxis(0);
1992 if (axis->GetNbins() < measured->GetNbinsX())
1996 // 2d rebin with variable axis does not exist in root
1998 TH1* tmp = measured;
1999 measured = new TH2D(Form("%s_rebinned", tmp->GetName()), tmp->GetTitle(), axis->GetNbins(), axis->GetXbins()->GetArray(), tmp->GetNbinsY(), tmp->GetYaxis()->GetXbins()->GetArray());
2000 for (Int_t x=1; x<=tmp->GetNbinsX(); x++)
2001 for (Int_t y=1; y<=tmp->GetNbinsY(); y++)
2003 ((TH2*) measured)->Fill(tmp->GetXaxis()->GetBinCenter(x), tmp->GetYaxis()->GetBinCenter(y), tmp->GetBinContent(x, y));
2004 measured->SetBinError(x, y, 0); // cannot trust bin error, set to 0
2009 generated = new TH2D(Form("%s_rebinned", tmp->GetName()), tmp->GetTitle(), axis->GetNbins(), axis->GetXbins()->GetArray(), tmp->GetNbinsY(), tmp->GetYaxis()->GetXbins()->GetArray());
2010 for (Int_t x=1; x<=tmp->GetNbinsX(); x++)
2011 for (Int_t y=1; y<=tmp->GetNbinsY(); y++)
2013 ((TH2*) generated)->Fill(tmp->GetXaxis()->GetBinCenter(x), tmp->GetYaxis()->GetBinCenter(y), tmp->GetBinContent(x, y));
2014 generated->SetBinError(x, y, 0); // cannot trust bin error, set to 0
2020 TH1* tmp = measured;
2021 measured = tmp->Rebin(axis->GetNbins(), Form("%s_rebinned", tmp->GetName()), axis->GetXbins()->GetArray());
2025 generated = tmp->Rebin(axis->GetNbins(), Form("%s_rebinned", tmp->GetName()), axis->GetXbins()->GetArray());
2029 else if (axis->GetNbins() > measured->GetNbinsX())
2032 AliFatal("Rebinning only works for 1d at present");
2034 // this is an unfortunate case where the number of bins has to be increased in principle
2035 // there is a region where the binning is finner in one histogram and a region where it is the other way round
2036 // this cannot be resolved in principle, but as we only calculate the ratio the bin in the second region get the same entries
2037 // only a certain binning is supported here
2038 if (axis->GetNbins() != 100 || measured->GetNbinsX() != 39)
2039 AliFatal(Form("Invalid binning --> %d %d", axis->GetNbins(), measured->GetNbinsX()));
2041 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};
2043 // reduce binning below 5 GeV/c
2044 TH1* tmp = measured;
2045 measured = tmp->Rebin(27, Form("%s_rebinned", tmp->GetName()), newBins);
2048 // increase binning above 5 GeV/c
2050 measured = new TH1F(Form("%s_rebinned2", tmp->GetName()), tmp->GetTitle(), axis->GetNbins(), axis->GetBinLowEdge(1), axis->GetBinUpEdge(axis->GetNbins()));
2051 for (Int_t bin=1; bin<=measured->GetNbinsX(); bin++)
2053 measured->SetBinContent(bin, tmp->GetBinContent(tmp->FindBin(measured->GetBinCenter(bin))));
2054 measured->SetBinError(bin, tmp->GetBinError(tmp->FindBin(measured->GetBinCenter(bin))));
2058 // reduce binning below 5 GeV/c
2060 generated = tmp->Rebin(27, Form("%s_rebinned", tmp->GetName()), newBins);
2063 // increase binning above 5 GeV/c
2065 generated = new TH1F(Form("%s_rebinned2", tmp->GetName()), tmp->GetTitle(), axis->GetNbins(), axis->GetBinLowEdge(1), axis->GetBinUpEdge(axis->GetNbins()));
2066 for (Int_t bin=1; bin<=generated->GetNbinsX(); bin++)
2068 generated->SetBinContent(bin, tmp->GetBinContent(tmp->FindBin(generated->GetBinCenter(bin))));
2069 generated->SetBinError(bin, tmp->GetBinError(tmp->FindBin(generated->GetBinCenter(bin))));
2075 measured->Divide(measured, generated, 1, 1, "B");
2079 ResetBinLimits(sourceContainer->GetGrid(step1));
2080 ResetBinLimits(sourceContainer->GetGrid(step2));
2085 //____________________________________________________________________
2086 TH1* AliUEHist::GetEventEfficiency(CFStep step1, CFStep step2, Int_t axis1, Int_t axis2, Float_t ptLeadMin, Float_t ptLeadMax)
2088 // creates a event-level efficiency by dividing step2 by step1
2089 // projected to axis1 and axis2 (optional if >= 0)
2091 if (ptLeadMax > ptLeadMin)
2093 fEventHist->GetGrid(step1)->SetRangeUser(0, ptLeadMin, ptLeadMax);
2094 fEventHist->GetGrid(step2)->SetRangeUser(0, ptLeadMin, ptLeadMax);
2102 generated = fEventHist->Project(step1, axis1, axis2);
2103 measured = fEventHist->Project(step2, axis1, axis2);
2107 generated = fEventHist->Project(step1, axis1);
2108 measured = fEventHist->Project(step2, axis1);
2111 measured->Divide(measured, generated, 1, 1, "B");
2115 if (ptLeadMax > ptLeadMin)
2117 fEventHist->GetGrid(step1)->SetRangeUser(0, 0, -1);
2118 fEventHist->GetGrid(step2)->SetRangeUser(0, 0, -1);
2124 //____________________________________________________________________
2125 void AliUEHist::WeightHistogram(TH3* hist1, TH1* hist2)
2127 // weights each entry of the 3d histogram hist1 with the 1d histogram hist2
2128 // where the matching is done of the z axis of hist1 with the x axis of hist2
2130 if (hist1->GetNbinsZ() != hist2->GetNbinsX())
2131 AliFatal(Form("Inconsistent binning %d %d", hist1->GetNbinsZ(), hist2->GetNbinsX()));
2133 for (Int_t x=1; x<=hist1->GetNbinsX(); x++)
2135 for (Int_t y=1; y<=hist1->GetNbinsY(); y++)
2137 for (Int_t z=1; z<=hist1->GetNbinsZ(); z++)
2139 if (hist2->GetBinContent(z) > 0)
2141 hist1->SetBinContent(x, y, z, hist1->GetBinContent(x, y, z) / hist2->GetBinContent(z));
2142 hist1->SetBinError(x, y, z, hist1->GetBinError(x, y, z) / hist2->GetBinContent(z));
2146 hist1->SetBinContent(x, y, z, 0);
2147 hist1->SetBinError(x, y, z, 0);
2154 //____________________________________________________________________
2155 TH1* AliUEHist::GetBias(CFStep step1, CFStep step2, Int_t region, const char* axis, Float_t leadPtMin, Float_t leadPtMax, Int_t weighting)
2157 // extracts the track-level bias (integrating out the multiplicity) between two steps (dividing step2 by step1)
2158 // in the given region (sum over all regions is calculated if region == -1)
2159 // done by weighting the track-level distribution with the number of events as function of leading pT
2160 // and then calculating the ratio between the distributions
2161 // projected to axis which is a TH3::Project3D string, e.g. "x", or "yx"
2162 // no projection is done if axis == 0
2163 // weighting: 0 = tracks weighted with events (as discussed above)
2164 // 1 = only track bias is returned
2165 // 2 = only event bias is returned
2167 AliCFContainer* tmp = 0;
2171 tmp = (AliCFContainer*) fTrackHist[0]->Clone();
2172 for (UInt_t i = 1; i < fkRegions; i++)
2174 tmp->Add(fTrackHist[i]);
2176 else if (region == kMin && fCombineMinMax)
2178 tmp = (AliCFContainer*) fTrackHist[kMin]->Clone();
2179 tmp->Add(fTrackHist[kMax]);
2182 tmp = fTrackHist[region];
2184 ResetBinLimits(tmp->GetGrid(step1));
2185 ResetBinLimits(fEventHist->GetGrid(step1));
2186 SetBinLimits(tmp->GetGrid(step1));
2188 ResetBinLimits(tmp->GetGrid(step2));
2189 ResetBinLimits(fEventHist->GetGrid(step2));
2190 SetBinLimits(tmp->GetGrid(step2));
2192 TH1D* events1 = (TH1D*)fEventHist->Project(step1, 0);
2193 TH3D* hist1 = (TH3D*)tmp->Project(step1, 0, tmp->GetNVar()-1, 2);
2195 WeightHistogram(hist1, events1);
2197 TH1D* events2 = (TH1D*)fEventHist->Project(step2, 0);
2198 TH3D* hist2 = (TH3D*)tmp->Project(step2, 0, tmp->GetNVar()-1, 2);
2200 WeightHistogram(hist2, events2);
2202 TH1* generated = hist1;
2203 TH1* measured = hist2;
2205 if (weighting == 0 || weighting == 1)
2209 if (leadPtMax > leadPtMin)
2211 hist1->GetZaxis()->SetRangeUser(leadPtMin, leadPtMax);
2212 hist2->GetZaxis()->SetRangeUser(leadPtMin, leadPtMax);
2215 if (fEtaMax > fEtaMin && !TString(axis).Contains("x"))
2217 hist1->GetXaxis()->SetRangeUser(fEtaMin, fEtaMax);
2218 hist2->GetXaxis()->SetRangeUser(fEtaMin, fEtaMax);
2221 generated = hist1->Project3D(axis);
2222 measured = hist2->Project3D(axis);
2224 // delete hists here if projection has been done
2231 else if (weighting == 2)
2235 generated = events1;
2239 measured->Divide(generated);
2243 ResetBinLimits(tmp->GetGrid(step1));
2244 ResetBinLimits(tmp->GetGrid(step2));
2246 if ((region == -1) || (region == kMin && fCombineMinMax))
2252 //____________________________________________________________________
2253 void AliUEHist::CorrectCorrelatedContamination(CFStep step, Int_t region, TH1* trackCorrection)
2255 // corrects for the given factor in a small delta-eta and delta-phi window as function of pT,A and pT,T
2257 if (!fTrackHist[region])
2260 THnSparse* grid = fTrackHist[region]->GetGrid(step)->GetGrid();
2265 if (grid->GetAxis(var1)->GetNbins() != trackCorrection->GetNbinsX())
2266 AliFatal(Form("Invalid binning (var1): %d %d", grid->GetAxis(var1)->GetNbins(), trackCorrection->GetNbinsX()));
2268 if (grid->GetAxis(var2)->GetNbins() != trackCorrection->GetNbinsY())
2269 AliFatal(Form("Invalid binning (var2): %d %d", grid->GetAxis(var2)->GetNbins(), trackCorrection->GetNbinsY()));
2271 // optimized implementation
2272 for (Int_t binIdx = 0; binIdx < grid->GetNbins(); binIdx++)
2276 Double_t value = grid->GetBinContent(binIdx, bins);
2277 Double_t error = grid->GetBinError(binIdx);
2279 // check eta and phi axes
2280 if (TMath::Abs(grid->GetAxis(0)->GetBinCenter(bins[0])) > 0.1)
2282 if (TMath::Abs(grid->GetAxis(4)->GetBinCenter(bins[4])) > 0.1)
2285 value *= trackCorrection->GetBinContent(bins[var1], bins[var2]);
2286 error *= trackCorrection->GetBinContent(bins[var1], bins[var2]);
2288 grid->SetBinContent(bins, value);
2289 grid->SetBinError(bins, error);
2292 Printf("AliUEHist::CorrectCorrelatedContamination: Corrected.");
2295 //____________________________________________________________________
2296 TH2* AliUEHist::GetCorrelatedContamination()
2298 // 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!)
2300 Int_t step1 = kCFStepTrackedOnlyPrim;
2301 Int_t step2 = kCFStepTracked;
2303 fTrackHist[0]->GetGrid(step1)->SetRangeUser(0, -0.01, 0.01); // delta eta
2304 fTrackHist[0]->GetGrid(step1)->SetRangeUser(4, -0.01, 0.01); // delta phi
2305 TH2* tracksStep1 = (TH2*) fTrackHist[0]->Project(step1, 1, 2);
2307 fTrackHist[0]->GetGrid(step2)->SetRangeUser(0, -0.01, 0.01); // delta eta
2308 fTrackHist[0]->GetGrid(step2)->SetRangeUser(4, -0.01, 0.01); // delta phi
2309 TH2* tracksStep2 = (TH2*) fTrackHist[0]->Project(step2, 1, 2);
2311 tracksStep1->Divide(tracksStep2);
2313 TH1* triggersStep1 = fEventHist->Project(step1, 0);
2314 TH1* triggersStep2 = fEventHist->Project(step2, 0);
2316 TH1* singleParticle = GetTrackingContamination(1);
2318 for (Int_t x=1; x<=tracksStep1->GetNbinsX(); x++)
2319 for (Int_t y=1; y<=tracksStep1->GetNbinsY(); y++)
2320 if (singleParticle->GetBinContent(x) > 0 && triggersStep1->GetBinContent(y) > 0)
2321 tracksStep1->SetBinContent(x, y, tracksStep1->GetBinContent(x, y) / triggersStep1->GetBinContent(y) * triggersStep2->GetBinContent(y) / singleParticle->GetBinContent(x));
2323 tracksStep1->SetBinContent(x, y, 0);
2325 delete singleParticle;
2327 delete triggersStep1;
2328 delete triggersStep2;
2333 //____________________________________________________________________
2334 TH2D* AliUEHist::GetTrackingEfficiency()
2336 // extracts the tracking efficiency by calculating the efficiency from step kCFStepAnaTopology to kCFStepTrackedOnlyPrim
2337 // integrates over the regions and all other variables than pT and eta to increase the statistics
2339 // returned histogram has to be deleted by the user
2341 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepAnaTopology, kCFStepTrackedOnlyPrim, 0, 1));
2344 //____________________________________________________________________
2345 TH2D* AliUEHist::GetFakeRate()
2347 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepTracked, (CFStep) (kCFStepTracked+3), 0, 1));
2350 //____________________________________________________________________
2351 TH2D* AliUEHist::GetTrackingEfficiencyCentrality()
2353 // extracts the tracking efficiency by calculating the efficiency from step kCFStepAnaTopology to kCFStepTrackedOnlyPrim
2354 // integrates over the regions and all other variables than pT, centrality to increase the statistics
2356 // returned histogram has to be deleted by the user
2358 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepAnaTopology, kCFStepTrackedOnlyPrim, 1, 3));
2361 //____________________________________________________________________
2362 TH1D* AliUEHist::GetTrackingEfficiency(Int_t axis)
2364 // extracts the tracking efficiency by calculating the efficiency from step kCFStepAnaTopology to kCFStepTrackedOnlyPrim
2365 // integrates over the regions and all other variables than pT (axis == 0) and eta (axis == 1) to increase the statistics
2367 return dynamic_cast<TH1D*> (GetTrackEfficiency(kCFStepAnaTopology, kCFStepTrackedOnlyPrim, axis));
2370 //____________________________________________________________________
2371 TH1D* AliUEHist::GetFakeRate(Int_t axis)
2373 return dynamic_cast<TH1D*> (GetTrackEfficiency(kCFStepTracked, (CFStep) (kCFStepTracked+3), axis));
2375 //____________________________________________________________________
2376 TH2D* AliUEHist::GetTrackingCorrection()
2378 // extracts the tracking correction by calculating the efficiency from step kCFStepAnaTopology to kCFStepTracked
2379 // integrates over the regions and all other variables than pT and eta to increase the statistics
2381 // returned histogram has to be deleted by the user
2383 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepTracked, kCFStepAnaTopology, 0, 1));
2386 //____________________________________________________________________
2387 TH1D* AliUEHist::GetTrackingCorrection(Int_t axis)
2389 // extracts the tracking correction by calculating the efficiency from step kCFStepAnaTopology to kCFStepTracked
2390 // integrates over the regions and all other variables than pT (axis == 0) and eta (axis == 1) to increase the statistics
2392 return dynamic_cast<TH1D*> (GetTrackEfficiency(kCFStepTracked, kCFStepAnaTopology, axis));
2395 //____________________________________________________________________
2396 TH2D* AliUEHist::GetTrackingEfficiencyCorrection()
2398 // extracts the tracking correction by calculating the efficiency from step kCFStepAnaTopology to kCFStepTracked
2399 // integrates over the regions and all other variables than pT and eta to increase the statistics
2401 // returned histogram has to be deleted by the user
2403 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, 0, 1));
2406 //____________________________________________________________________
2407 TH2D* AliUEHist::GetTrackingEfficiencyCorrectionCentrality()
2409 // extracts the tracking correction by calculating the efficiency from step kCFStepAnaTopology to kCFStepTracked
2410 // integrates over the regions and all other variables than pT and centrality to increase the statistics
2412 // returned histogram has to be deleted by the user
2414 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, 1, 3));
2417 //____________________________________________________________________
2418 TH1D* AliUEHist::GetTrackingEfficiencyCorrection(Int_t axis)
2420 // extracts the tracking correction by calculating the efficiency from step kCFStepAnaTopology to kCFStepTracked
2421 // integrates over the regions and all other variables than pT (axis == 0) and eta (axis == 1) to increase the statistics
2423 return dynamic_cast<TH1D*> (GetTrackEfficiency(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, axis));
2426 //____________________________________________________________________
2427 TH2D* AliUEHist::GetTrackingContamination()
2429 // extracts the tracking contamination by secondaries by calculating the efficiency from step kCFStepTrackedOnlyPrim to kCFStepTracked
2430 // integrates over the regions and all other variables than pT and eta to increase the statistics
2432 // returned histogram has to be deleted by the user
2434 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepTracked, kCFStepTrackedOnlyPrim, 0, 1));
2437 //____________________________________________________________________
2438 TH2D* AliUEHist::GetTrackingContaminationCentrality()
2440 // extracts the tracking contamination by secondaries by calculating the efficiency from step kCFStepTrackedOnlyPrim to kCFStepTracked
2441 // integrates over the regions and all other variables than pT and centrality to increase the statistics
2443 // returned histogram has to be deleted by the user
2445 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepTracked, kCFStepTrackedOnlyPrim, 1, 3));
2448 //____________________________________________________________________
2449 TH1D* AliUEHist::GetTrackingContamination(Int_t axis)
2451 // extracts the tracking contamination by secondaries by calculating the efficiency from step kCFStepTrackedOnlyPrim to kCFStepTracked
2452 // integrates over the regions and all other variables than pT (axis == 0) and eta (axis == 1) to increase the statistics
2454 return dynamic_cast<TH1D*> (GetTrackEfficiency(kCFStepTracked, kCFStepTrackedOnlyPrim, axis));
2457 //____________________________________________________________________
2458 const char* AliUEHist::GetRegionTitle(Region region)
2460 // returns the name of the given region
2469 return (fCombineMinMax) ? "Transverse" : "Min";
2477 //____________________________________________________________________
2478 const char* AliUEHist::GetStepTitle(CFStep step)
2480 // returns the name of the given step
2485 return "All events";
2486 case kCFStepTriggered:
2489 return "Primary Vertex";
2490 case kCFStepAnaTopology:
2491 return "Required analysis topology";
2492 case kCFStepTrackedOnlyPrim:
2493 return "Tracked (matched MC, only primaries)";
2494 case kCFStepTracked:
2495 return "Tracked (matched MC, all)";
2496 case kCFStepReconstructed:
2497 return "Reconstructed";
2498 case kCFStepRealLeading:
2499 return "Correct leading particle identified";
2500 case kCFStepBiasStudy:
2501 return "Bias study applying tracking efficiency";
2502 case kCFStepBiasStudy2:
2503 return "Bias study applying tracking efficiency in two steps";
2504 case kCFStepCorrected:
2505 return "Corrected for efficiency on-the-fly";
2511 //____________________________________________________________________
2512 void AliUEHist::CopyReconstructedData(AliUEHist* from)
2514 // copies those histograms extracted from ESD to this object
2516 // TODO at present only the pointers are copied
2518 for (Int_t region=0; region<4; region++)
2520 if (!fTrackHist[region])
2523 fTrackHist[region]->SetGrid(AliUEHist::kCFStepReconstructed, from->fTrackHist[region]->GetGrid(AliUEHist::kCFStepReconstructed));
2524 //fTrackHist[region]->SetGrid(AliUEHist::kCFStepTrackedOnlyPrim, from->fTrackHist[region]->GetGrid(AliUEHist::kCFStepTrackedOnlyPrim));
2525 fTrackHist[region]->SetGrid(AliUEHist::kCFStepBiasStudy, from->fTrackHist[region]->GetGrid(AliUEHist::kCFStepBiasStudy));
2528 fEventHist->SetGrid(AliUEHist::kCFStepReconstructed, from->fEventHist->GetGrid(AliUEHist::kCFStepReconstructed));
2529 //fEventHist->SetGrid(AliUEHist::kCFStepTrackedOnlyPrim, from->fEventHist->GetGrid(AliUEHist::kCFStepTrackedOnlyPrim));
2530 fEventHist->SetGrid(AliUEHist::kCFStepBiasStudy, from->fEventHist->GetGrid(AliUEHist::kCFStepBiasStudy));
2533 void AliUEHist::DeepCopy(AliUEHist* from)
2535 // copies the entries of this object's members from the object <from> to this object
2536 // fills using the fill function and thus allows that the objects have different binning
2538 for (Int_t region=0; region<4; region++)
2540 if (!fTrackHist[region] || !from->fTrackHist[region])
2543 for (Int_t step=0; step<fTrackHist[region]->GetNStep(); step++)
2545 Printf("Copying region %d step %d", region, step);
2546 THnSparse* target = fTrackHist[region]->GetGrid(step)->GetGrid();
2547 THnSparse* source = from->fTrackHist[region]->GetGrid(step)->GetGrid();
2550 target->RebinnedAdd(source);
2554 for (Int_t step=0; step<fEventHist->GetNStep(); step++)
2556 Printf("Ev: Copying step %d", step);
2557 THnSparse* target = fEventHist->GetGrid(step)->GetGrid();
2558 THnSparse* source = from->fEventHist->GetGrid(step)->GetGrid();
2561 target->RebinnedAdd(source);
2564 for (Int_t step=0; step<TMath::Min(fTrackHistEfficiency->GetNStep(), from->fTrackHistEfficiency->GetNStep()); step++)
2566 if (!from->fTrackHistEfficiency->GetGrid(step))
2569 Printf("Eff: Copying step %d", step);
2570 THnSparse* target = fTrackHistEfficiency->GetGrid(step)->GetGrid();
2571 THnSparse* source = from->fTrackHistEfficiency->GetGrid(step)->GetGrid();
2574 target->RebinnedAdd(source);
2578 void AliUEHist::SymmetrizepTBins()
2580 // copy pt,a < pt,t bins to pt,a > pt,t (inverting deltaphi and delta eta as it should be) including symmetric bins
2582 for (Int_t region=0; region<4; region++)
2584 if (!fTrackHist[region])
2587 for (Int_t step=0; step<fTrackHist[region]->GetNStep(); step++)
2589 Printf("Copying region %d step %d", region, step);
2590 THnSparse* target = fTrackHist[region]->GetGrid(step)->GetGrid();
2591 if (target->GetEntries() == 0)
2594 // for symmetric bins
2595 THnSparse* source = (THnSparse*) target->Clone();
2597 // axes: 0 delta eta; 1 pT,a; 2 pT,t; 3 centrality; 4 delta phi; 5 vtx-z
2598 for (Int_t i3 = 1; i3 <= target->GetAxis(3)->GetNbins(); i3++)
2599 for (Int_t i5 = 1; i5 <= target->GetAxis(5)->GetNbins(); i5++)
2601 for (Int_t i1 = 1; i1 <= target->GetAxis(1)->GetNbins(); i1++)
2602 for (Int_t i2 = 1; i2 <= target->GetAxis(2)->GetNbins(); i2++)
2605 Int_t binA = target->GetAxis(1)->FindBin(target->GetAxis(2)->GetBinCenter(i2));
2606 Int_t binT = target->GetAxis(2)->FindBin(target->GetAxis(1)->GetBinCenter(i1));
2608 Printf("(%d %d) Copying from %d %d to %d %d", i3, i5, binA, binT, i1, i2);
2610 for (Int_t i0 = 1; i0 <= target->GetAxis(0)->GetNbins(); i0++)
2611 for (Int_t i4 = 1; i4 <= target->GetAxis(4)->GetNbins(); i4++)
2613 Int_t binEta = target->GetAxis(0)->FindBin(-target->GetAxis(0)->GetBinCenter(i0));
2614 Double_t phi = -target->GetAxis(4)->GetBinCenter(i4);
2615 if (phi < -TMath::Pi()/2)
2616 phi += TMath::TwoPi();
2617 Int_t binPhi = target->GetAxis(4)->FindBin(phi);
2619 Int_t binSource[] = { binEta, binA, binT, i3, binPhi, i5 };
2620 Int_t binTarget[] = { i0, i1, i2, i3, i4, i5 };
2622 Double_t value = source->GetBinContent(binSource);
2623 Double_t error = source->GetBinError(binSource);
2628 Double_t value2 = target->GetBinContent(binTarget);
2629 Double_t error2 = target->GetBinError(binTarget);
2631 Double_t sum = value;
2632 Double_t err = error;
2636 sum = value + value2;
2637 err = TMath::Sqrt(error * error + error2 * error2);
2640 // Printf(" Values: %f +- %f; %f +- %f --> %f +- %f", value, error, value2, error2, sum, err);
2642 target->SetBinContent(binTarget, sum);
2643 target->SetBinError(binTarget, err);
2653 //____________________________________________________________________
2654 void AliUEHist::ExtendTrackingEfficiency(Bool_t verbose)
2656 // fits the tracking efficiency at high pT with a constant and fills all bins with this tracking efficiency
2658 Float_t fitRangeBegin = 5.01;
2659 Float_t fitRangeEnd = 14.99;
2660 Float_t extendRangeBegin = 10.01;
2662 if (fTrackHistEfficiency->GetNVar() == 3)
2664 TH1* obj = GetTrackingEfficiency(1);
2672 obj->Fit("pol0", (verbose) ? "+" : "0+", "SAME", fitRangeBegin, fitRangeEnd);
2674 Float_t trackingEff = obj->GetFunction("pol0")->GetParameter(0);
2676 obj = GetTrackingContamination(1);
2684 obj->Fit("pol0", (verbose) ? "+" : "0+", "SAME", fitRangeBegin, fitRangeEnd);
2686 Float_t trackingCont = obj->GetFunction("pol0")->GetParameter(0);
2688 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);
2690 // extend for full pT range
2691 for (Int_t x = fTrackHistEfficiency->GetAxis(0, 0)->FindBin(fEtaMin); x <= fTrackHistEfficiency->GetAxis(0, 0)->FindBin(fEtaMax); x++)
2692 for (Int_t y = fTrackHistEfficiency->GetAxis(1, 0)->FindBin(extendRangeBegin); y <= fTrackHistEfficiency->GetNBins(1); y++)
2693 for (Int_t z = 1; z <= fTrackHistEfficiency->GetNBins(2); z++) // particle type axis
2701 fTrackHistEfficiency->GetGrid(0)->SetElement(bins, 100);
2702 fTrackHistEfficiency->GetGrid(1)->SetElement(bins, 100.0 * trackingEff);
2703 fTrackHistEfficiency->GetGrid(2)->SetElement(bins, 100.0 * trackingEff / trackingCont);
2706 else if (fTrackHistEfficiency->GetNVar() == 4)
2708 // fit in centrality intervals of 20% for efficiency, one bin for contamination
2709 Float_t* trackingEff = 0;
2710 Float_t* trackingCont = 0;
2711 Float_t centralityBins[] = { 0, 10, 20, 40, 60, 100 };
2712 Int_t nCentralityBins = 5;
2714 Printf("AliUEHist::ExtendTrackingEfficiency: Fitting efficiencies between %f and %f. Extending from %f onwards (within %f < eta < %f)", fitRangeBegin, fitRangeEnd, extendRangeBegin, fEtaMin, fEtaMax);
2716 // 0 = eff; 1 = cont
2717 for (Int_t caseNo = 0; caseNo < 2; caseNo++)
2719 Float_t* target = 0;
2720 Int_t centralityBinsLocal = nCentralityBins;
2724 trackingEff = new Float_t[centralityBinsLocal];
2725 target = trackingEff;
2729 centralityBinsLocal = 1;
2730 trackingCont = new Float_t[centralityBinsLocal];
2731 target = trackingCont;
2734 for (Int_t i=0; i<centralityBinsLocal; i++)
2736 if (centralityBinsLocal == 1)
2737 SetCentralityRange(centralityBins[0] + 0.1, centralityBins[nCentralityBins] - 0.1);
2739 SetCentralityRange(centralityBins[i] + 0.1, centralityBins[i+1] - 0.1);
2740 TH1* proj = (caseNo == 0) ? GetTrackingEfficiency(1) : GetTrackingContamination(1);
2746 if ((Int_t) proj->Fit("pol0", (verbose) ? "+" : "Q0+", "SAME", fitRangeBegin, fitRangeEnd) == 0)
2747 target[i] = proj->GetFunction("pol0")->GetParameter(0);
2750 Printf("AliUEHist::ExtendTrackingEfficiency: case %d, centrality %d, eff %f", caseNo, i, target[i]);
2754 // extend for full pT range
2755 for (Int_t x = fTrackHistEfficiency->GetAxis(0, 0)->FindBin(fEtaMin); x <= fTrackHistEfficiency->GetAxis(0, 0)->FindBin(fEtaMax); x++)
2756 for (Int_t y = fTrackHistEfficiency->GetAxis(1, 0)->FindBin(extendRangeBegin); y <= fTrackHistEfficiency->GetNBins(1); y++)
2757 for (Int_t z = 1; z <= fTrackHistEfficiency->GetNBins(2); z++) // particle type axis
2759 for (Int_t z2 = 1; z2 <= fTrackHistEfficiency->GetNBins(3); z2++) // centrality axis
2769 while (centralityBins[z2Bin+1] < fTrackHistEfficiency->GetAxis(3, 0)->GetBinCenter(z2))
2772 //Printf("%d %d", z2, z2Bin);
2774 fTrackHistEfficiency->GetGrid(0)->SetElement(bins, 100);
2775 fTrackHistEfficiency->GetGrid(1)->SetElement(bins, 100.0 * trackingEff[z2Bin]);
2776 if (trackingCont[0] > 0)
2777 fTrackHistEfficiency->GetGrid(2)->SetElement(bins, 100.0 * trackingEff[z2Bin] / trackingCont[0]);
2779 fTrackHistEfficiency->GetGrid(2)->SetElement(bins, 0);
2783 delete[] trackingEff;
2784 delete[] trackingCont;
2787 SetCentralityRange(0, 0);
2790 void AliUEHist::AdditionalDPhiCorrection(Int_t step)
2792 // corrects the dphi distribution with an extra factor close to dphi ~ 0
2794 Printf("WARNING: In AliUEHist::AdditionalDPhiCorrection.");
2796 THnSparse* grid = fTrackHist[0]->GetGrid(step)->GetGrid();
2798 // optimized implementation
2799 for (Int_t binIdx = 0; binIdx < grid->GetNbins(); binIdx++)
2802 Double_t value = grid->GetBinContent(binIdx, bins);
2803 Double_t error = grid->GetBinError(binIdx);
2805 Float_t binCenter = grid->GetAxis(4)->GetBinCenter(bins[4]);
2806 if (TMath::Abs(binCenter) < 0.2)
2811 else if (TMath::Abs(binCenter) < 0.3)
2817 grid->SetBinContent(bins, value);
2818 grid->SetBinError(bins, error);
2822 void AliUEHist::Scale(Double_t factor)
2824 // scales all contained histograms by the given factor
2826 for (Int_t i=0; i<4; i++)
2828 fTrackHist[i]->Scale(factor);
2830 fEventHist->Scale(factor);
2831 fTrackHistEfficiency->Scale(factor);
2834 void AliUEHist::Reset()
2836 // resets all contained histograms
2838 for (Int_t i=0; i<4; i++)
2840 for (Int_t step=0; step<fTrackHist[i]->GetNStep(); step++)
2841 fTrackHist[i]->GetGrid(step)->GetGrid()->Reset();
2843 for (Int_t step=0; step<fEventHist->GetNStep(); step++)
2844 fEventHist->GetGrid(step)->GetGrid()->Reset();
2846 for (Int_t step=0; step<fTrackHistEfficiency->GetNStep(); step++)
2847 fTrackHistEfficiency->GetGrid(step)->GetGrid()->Reset();
2850 THnBase* AliUEHist::ChangeToThn(THnBase* sparse)
2852 // change the object to THn for faster processing
2854 // convert to THn (SEGV's for some strange reason...)
2855 // x = THn::CreateHn("a", "a", sparse);
2857 // own implementation
2859 for (Int_t i=0; i<sparse->GetNdimensions(); i++)
2860 nBins[i] = sparse->GetAxis(i)->GetNbins();
2861 THn* tmpTHn = new THnF(Form("%s_thn", sparse->GetName()), sparse->GetTitle(), sparse->GetNdimensions(), nBins, 0, 0);
2862 for (Int_t i=0; i<sparse->GetNdimensions(); i++)
2864 tmpTHn->SetBinEdges(i, sparse->GetAxis(i)->GetXbins()->GetArray());
2865 tmpTHn->GetAxis(i)->SetTitle(sparse->GetAxis(i)->GetTitle());
2867 tmpTHn->RebinnedAdd(sparse);
2872 void AliUEHist::CondenseBin(THnSparse* grid, THnSparse* target, Int_t axis, Float_t targetValue, Float_t from, Float_t to)
2875 // loops through the histogram and moves all entries to a single point <targetValue> on the axis <axis>
2876 // if <from> and <to> are set, then moving only occurs if value on <axis> is betweem <from> and <to>
2879 if (grid->GetNdimensions() > 6)
2880 AliFatal("Too many dimensions in THnSparse");
2882 Int_t targetBin = grid->GetAxis(axis)->FindBin(targetValue);
2883 AliInfo(Form("Target bin on axis %d with value %f is %d", axis, targetValue, targetBin));
2886 Int_t toBin = grid->GetAxis(axis)->GetNbins();
2889 fromBin = grid->GetAxis(axis)->FindBin(from);
2890 toBin = grid->GetAxis(axis)->FindBin(to);
2891 AliInfo(Form("Only condensing between bin %d and %d", fromBin, toBin));
2895 for (Int_t binIdx = 0; binIdx < grid->GetNbins(); binIdx++)
2897 Double_t value = grid->GetBinContent(binIdx, bins);
2898 Double_t error = grid->GetBinError(binIdx);
2900 if (bins[axis] >= fromBin && bins[axis] <= toBin)
2901 bins[axis] = targetBin;
2903 value += target->GetBinContent(bins);
2904 error = TMath::Sqrt(error * error + target->GetBinError(bins) * target->GetBinError(bins));
2906 target->SetBinContent(bins, value);
2907 target->SetBinError(bins, error);
2911 void AliUEHist::CondenseBin(CFStep step, Int_t trackAxis, Int_t eventAxis, Float_t targetValue, Float_t from, Float_t to, CFStep tmpStep)
2913 // loops through the histogram at <step> and moves all entries to a single point <targetValue> on the axes
2914 // <trackAxis> and <eventAxis>. <tmpStep> is used to temporary store the data
2915 // This is useful e.g. to move bin content around for MC productions where the centrality selection did
2916 // not yield the desired result
2919 fEventHist->GetGrid(tmpStep)->GetGrid()->Reset();
2920 for (UInt_t i=0; i<fkRegions; i++)
2922 fTrackHist[i]->GetGrid(tmpStep)->GetGrid()->Reset();
2925 CorrectTracks(step, tmpStep, 0, -1);
2926 CorrectEvents(step, tmpStep, 0, -1);
2929 fEventHist->GetGrid(step)->GetGrid()->Reset();
2930 for (UInt_t i=0; i<fkRegions; i++)
2932 fTrackHist[i]->GetGrid(step)->GetGrid()->Reset();
2935 for (UInt_t i=0; i<fkRegions; i++)
2940 THnSparse* grid = fTrackHist[i]->GetGrid(tmpStep)->GetGrid();
2941 THnSparse* target = fTrackHist[i]->GetGrid(step)->GetGrid();
2943 CondenseBin(grid, target, trackAxis, targetValue, from, to);
2945 CondenseBin(fEventHist->GetGrid(tmpStep)->GetGrid(), fEventHist->GetGrid(step)->GetGrid(), eventAxis, targetValue, from, to);
2948 fEventHist->GetGrid(tmpStep)->GetGrid()->Reset();
2949 for (UInt_t i=0; i<fkRegions; i++)
2951 fTrackHist[i]->GetGrid(tmpStep)->GetGrid()->Reset();