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"
41 const Int_t AliUEHist::fgkCFSteps = 10;
43 AliUEHist::AliUEHist(const char* reqHist) :
47 fTrackHistEfficiency(0),
56 fContaminationEnhancement(0),
59 fHistogramType(reqHist)
63 for (UInt_t i=0; i<fkRegions; i++)
66 if (strlen(reqHist) == 0)
69 AliLog::SetClassDebugLevel("AliCFContainer", -1);
70 AliLog::SetClassDebugLevel("AliCFGridSparse", -3);
72 const char* title = "";
75 Int_t nTrackVars = 4; // eta vs pT vs pT,lead (vs delta phi) vs multiplicity
77 Double_t* trackBins[6];
78 const char* trackAxisTitle[6];
82 Double_t etaBins[20+1];
83 for (Int_t i=0; i<=iTrackBin[0]; i++)
84 etaBins[i] = -1.0 + 0.1 * i;
85 trackBins[0] = etaBins;
86 trackAxisTitle[0] = "#eta";
89 const Int_t kNDeltaEtaBins = 40;
90 Double_t deltaEtaBins[kNDeltaEtaBins+1];
91 for (Int_t i=0; i<=kNDeltaEtaBins; i++)
92 deltaEtaBins[i] = -2.0 + 0.1 * i;
96 Double_t pTBins[] = {0.15, 0.2, 0.3, 0.4, 0.5, 0.75, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 12.0, 15.0, 20.0};
97 trackBins[1] = pTBins;
98 trackAxisTitle[1] = "p_{T} (GeV/c)";
101 const Int_t kNLeadingpTBins = 100;
102 Double_t leadingpTBins[kNLeadingpTBins+1];
103 for (Int_t i=0; i<=kNLeadingpTBins; i++)
104 leadingpTBins[i] = 0.5 * i;
107 const Int_t kNLeadingpTBins2 = 9;
108 Double_t leadingpTBins2[] = { 0.5, 1.0, 2.0, 3.0, 4.0, 6.0, 8.0, 10.0, 15.0, 20.0 };
110 // phi,lead; this binning starts at -pi/2 and is modulo 3
111 const Int_t kNLeadingPhiBins = 72;
112 Double_t leadingPhiBins[kNLeadingPhiBins+1];
113 for (Int_t i=0; i<=kNLeadingPhiBins; i++)
114 leadingPhiBins[i] = -TMath::Pi() / 2 + 1.0 / kNLeadingPhiBins * i * TMath::TwoPi();
117 const Int_t kNMultiplicityBins = 15;
118 Double_t multiplicityBins[kNMultiplicityBins+1];
119 for (Int_t i=0; i<=kNMultiplicityBins; i++)
120 multiplicityBins[i] = -0.5 + i;
121 multiplicityBins[kNMultiplicityBins] = 200;
123 trackBins[3] = multiplicityBins;
124 iTrackBin[3] = kNMultiplicityBins;
125 trackAxisTitle[3] = "multiplicity";
128 const Int_t kNCentralityBins = 5 + 1 + 9;
129 Double_t centralityBins[] = { 0, 1, 2, 3, 4, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100.1 };
132 const Int_t kNSpeciesBins = 4; // pi, K, p, rest
133 Double_t speciesBins[] = { -0.5, 0.5, 1.5, 2.5, 3.5 };
136 const Int_t kNVertexBins = 7;
137 Double_t vertexBins[] = { -7, -5, -3, -1, 1, 3, 5, 7 };
139 Bool_t useVtxAxis = kFALSE;
141 // selection depending on requested histogram
142 Int_t axis = -1; // 0 = pT,lead, 1 = phi,lead
143 if (strcmp(reqHist, "NumberDensitypT") == 0)
146 title = "d^{2}N_{ch}/d#varphid#eta";
148 else if (strcmp(reqHist, "NumberDensityPhi") == 0)
151 title = "d^{2}N_{ch}/d#varphid#eta";
153 else if (strcmp(reqHist, "NumberDensityPhiCentrality") == 0 || strcmp(reqHist, "NumberDensityPhiCentralityVtx") == 0)
155 if (strcmp(reqHist, "NumberDensityPhiCentralityVtx") == 0)
157 reqHist = "NumberDensityPhiCentrality";
158 fHistogramType = reqHist;
162 title = "d^{2}N_{ch}/d#varphid#eta";
164 else if (strcmp(reqHist, "SumpT") == 0)
167 title = "d^{2}#Sigma p_{T}/d#varphid#eta";
170 AliFatal(Form("Invalid histogram requested: %s", reqHist));
172 UInt_t initRegions = fkRegions;
176 trackBins[2] = leadingpTBins;
177 iTrackBin[2] = kNLeadingpTBins;
178 trackAxisTitle[2] = "leading p_{T} (GeV/c)";
186 iTrackBin[2] = kNLeadingpTBins2;
187 trackBins[2] = leadingpTBins2;
188 trackAxisTitle[2] = "leading p_{T} (GeV/c)";
190 iTrackBin[4] = kNLeadingPhiBins;
191 trackBins[4] = leadingPhiBins;
192 trackAxisTitle[4] = "#Delta #varphi w.r.t. leading track";
199 iTrackBin[0] = kNDeltaEtaBins;
200 trackBins[0] = deltaEtaBins;
201 trackAxisTitle[0] = "#Delta#eta";
203 iTrackBin[2] = kNLeadingpTBins2;
204 trackBins[2] = leadingpTBins2;
205 trackAxisTitle[2] = "leading p_{T} (GeV/c)";
207 trackBins[3] = centralityBins;
208 iTrackBin[3] = kNCentralityBins;
209 trackAxisTitle[3] = "centrality";
211 iTrackBin[4] = kNLeadingPhiBins;
212 trackBins[4] = leadingPhiBins;
213 trackAxisTitle[4] = "#Delta#varphi (rad.)";
218 iTrackBin[5] = kNVertexBins;
219 trackBins[5] = vertexBins;
220 trackAxisTitle[5] = "z-vtx (cm)";
224 for (UInt_t i=0; i<initRegions; i++)
226 if (strcmp(reqHist, "NumberDensityPhiCentrality") == 0)
227 fTrackHist[i] = new AliTHn(Form("fTrackHist_%d", i), title, fgkCFSteps, nTrackVars, iTrackBin);
229 fTrackHist[i] = new AliCFContainer(Form("fTrackHist_%d", i), title, fgkCFSteps, nTrackVars, iTrackBin);
231 for (Int_t j=0; j<nTrackVars; j++)
233 fTrackHist[i]->SetBinLimits(j, trackBins[j]);
234 fTrackHist[i]->SetVarTitle(j, trackAxisTitle[j]);
237 SetStepNames(fTrackHist[i]);
241 Int_t nEventVars = 2;
244 // track 3rd and 4th axis --> event 1st and 2nd axis
245 iEventBin[0] = iTrackBin[2];
246 iEventBin[1] = iTrackBin[3];
248 // plus track 5th axis (in certain cases)
249 if (axis == 2 && useVtxAxis)
252 iEventBin[2] = iTrackBin[5];
255 fEventHist = new AliCFContainer("fEventHist", title, fgkCFSteps, nEventVars, iEventBin);
257 fEventHist->SetBinLimits(0, trackBins[2]);
258 fEventHist->SetVarTitle(0, trackAxisTitle[2]);
260 fEventHist->SetBinLimits(1, trackBins[3]);
261 fEventHist->SetVarTitle(1, trackAxisTitle[3]);
263 if (axis == 2 && useVtxAxis)
265 fEventHist->SetBinLimits(2, trackBins[5]);
266 fEventHist->SetVarTitle(2, trackAxisTitle[5]);
269 SetStepNames(fEventHist);
271 iTrackBin[2] = kNSpeciesBins;
273 fTrackHistEfficiency = new AliCFContainer("fTrackHistEfficiency", "Tracking efficiency", 3, 4, iTrackBin);
274 fTrackHistEfficiency->SetBinLimits(0, trackBins[0]);
275 fTrackHistEfficiency->SetVarTitle(0, trackAxisTitle[0]);
276 fTrackHistEfficiency->SetBinLimits(1, trackBins[1]);
277 fTrackHistEfficiency->SetVarTitle(1, trackAxisTitle[1]);
278 fTrackHistEfficiency->SetBinLimits(2, speciesBins);
279 fTrackHistEfficiency->SetVarTitle(2, "particle species");
280 fTrackHistEfficiency->SetBinLimits(3, trackBins[3]);
281 fTrackHistEfficiency->SetVarTitle(3, trackAxisTitle[3]);
284 //_____________________________________________________________________________
285 AliUEHist::AliUEHist(const AliUEHist &c) :
289 fTrackHistEfficiency(0),
298 fContaminationEnhancement(0),
304 // AliUEHist copy constructor
307 ((AliUEHist &) c).Copy(*this);
310 //____________________________________________________________________
311 void AliUEHist::SetStepNames(AliCFContainer* container)
313 // sets the names of the correction steps
315 for (Int_t i=0; i<fgkCFSteps; i++)
316 container->SetStepTitle(i, GetStepTitle((CFStep) i));
319 //____________________________________________________________________
320 AliUEHist::~AliUEHist()
324 for (UInt_t i=0; i<fkRegions; i++)
328 delete fTrackHist[i];
339 if (fTrackHistEfficiency)
341 delete fTrackHistEfficiency;
342 fTrackHistEfficiency = 0;
352 //____________________________________________________________________
353 AliUEHist &AliUEHist::operator=(const AliUEHist &c)
355 // assigment operator
358 ((AliUEHist &) c).Copy(*this);
363 //____________________________________________________________________
364 void AliUEHist::Copy(TObject& c) const
368 AliUEHist& target = (AliUEHist &) c;
370 for (UInt_t i=0; i<fkRegions; i++)
372 target.fTrackHist[i] = dynamic_cast<AliCFContainer*> (fTrackHist[i]->Clone());
375 target.fEventHist = dynamic_cast<AliCFContainer*> (fEventHist->Clone());
377 if (fTrackHistEfficiency)
378 target.fTrackHistEfficiency = dynamic_cast<AliCFContainer*> (fTrackHistEfficiency->Clone());
380 target.fEtaMin = fEtaMin;
381 target.fEtaMax = fEtaMax;
382 target.fPtMin = fPtMin;
383 target.fPtMax = fPtMax;
384 target.fCentralityMin = fCentralityMin;
385 target.fCentralityMax = fCentralityMax;
386 target.fZVtxMin = fZVtxMin;
387 target.fZVtxMax = fZVtxMax;
389 if (fContaminationEnhancement)
390 target.fContaminationEnhancement = dynamic_cast<TH1F*> (fContaminationEnhancement->Clone());
392 target.fCombineMinMax = fCombineMinMax;
393 target.fHistogramType = fHistogramType;
396 //____________________________________________________________________
397 Long64_t AliUEHist::Merge(TCollection* list)
399 // Merge a list of AliUEHist objects with this (needed for
401 // Returns the number of merged objects (including this).
409 TIterator* iter = list->MakeIterator();
412 // collections of objects
413 const UInt_t kMaxLists = fkRegions+2;
414 TList** lists = new TList*[kMaxLists];
416 for (UInt_t i=0; i<kMaxLists; i++)
417 lists[i] = new TList;
420 while ((obj = iter->Next())) {
422 AliUEHist* entry = dynamic_cast<AliUEHist*> (obj);
426 for (UInt_t i=0; i<fkRegions; i++)
427 if (entry->fTrackHist[i])
428 lists[i]->Add(entry->fTrackHist[i]);
430 lists[fkRegions]->Add(entry->fEventHist);
431 lists[fkRegions+1]->Add(entry->fTrackHistEfficiency);
435 for (UInt_t i=0; i<fkRegions; i++)
437 fTrackHist[i]->Merge(lists[i]);
439 fEventHist->Merge(lists[fkRegions]);
440 fTrackHistEfficiency->Merge(lists[fkRegions+1]);
442 for (UInt_t i=0; i<kMaxLists; i++)
450 //____________________________________________________________________
451 void AliUEHist::SetBinLimits(AliCFGridSparse* grid)
453 // sets the bin limits in eta and pT defined by fEtaMin/Max, fPtMin/Max
455 if (fEtaMax > fEtaMin)
456 grid->SetRangeUser(0, fEtaMin, fEtaMax);
458 grid->SetRangeUser(1, fPtMin, fPtMax);
461 //____________________________________________________________________
462 void AliUEHist::ResetBinLimits(AliCFGridSparse* grid)
464 // resets all bin limits
466 for (Int_t i=0; i<grid->GetNVar(); i++)
467 if (grid->GetGrid()->GetAxis(i)->TestBit(TAxis::kAxisRange))
468 grid->SetRangeUser(i, 0, -1);
471 //____________________________________________________________________
472 void AliUEHist::CountEmptyBins(AliUEHist::CFStep step, Float_t ptLeadMin, Float_t ptLeadMax)
474 // prints the number of empty bins in the track end event histograms in the given step
479 for (Int_t i=0; i<4; i++)
482 binEnd[i] = fTrackHist[0]->GetNBins(i);
485 if (fEtaMax > fEtaMin)
487 binBegin[0] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(0)->FindBin(fEtaMin);
488 binEnd[0] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(0)->FindBin(fEtaMax);
493 binBegin[1] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(1)->FindBin(fPtMin);
494 binEnd[1] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(1)->FindBin(fPtMax);
497 if (ptLeadMax > ptLeadMin)
499 binBegin[2] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(2)->FindBin(ptLeadMin);
500 binEnd[2] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(2)->FindBin(ptLeadMax);
503 // start from multiplicity 1
504 binBegin[3] = fTrackHist[0]->GetGrid(step)->GetGrid()->GetAxis(3)->FindBin(1);
506 for (UInt_t region=0; region<fkRegions; region++)
512 for (Int_t i=0; i<4; i++)
513 vars[i] = binBegin[i];
515 AliCFGridSparse* grid = fTrackHist[region]->GetGrid(step);
518 if (grid->GetElement(vars) == 0)
520 Printf("Empty bin at eta=%.2f pt=%.2f pt_lead=%.2f mult=%.1f",
521 grid->GetBinCenter(0, vars[0]),
522 grid->GetBinCenter(1, vars[1]),
523 grid->GetBinCenter(2, vars[2]),
524 grid->GetBinCenter(3, vars[3])
530 for (Int_t i=3; i>0; i--)
532 if (vars[i] == binEnd[i]+1)
534 vars[i] = binBegin[i];
539 if (vars[0] == binEnd[0]+1)
544 Printf("Region %s has %d empty bins (out of %d bins)", GetRegionTitle((Region) region), count, total);
548 //____________________________________________________________________
549 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, Int_t* normEvents)
551 // Extracts the UE histogram at the given step and in the given region by projection and dividing tracks by events
553 // ptLeadMin, ptLeadMax: Only meaningful for vs. delta phi plot (third axis is ptLead)
554 // Histogram has to be deleted by the caller of the function
556 // twoD: 0: 1D histogram as function of phi
557 // 1: 2D histogram, deltaphi, deltaeta
558 // 10: 1D histogram, within |deltaeta| < 0.8
559 // 11: 1D histogram, within 0.8 < |deltaeta| < 1.6
561 // etaNorm: if kTRUE (default), the distributions are divided by the area in delta eta
563 // normEvents: if non-0 the number of events/trigger particles for the normalization is filled
566 ResetBinLimits(fTrackHist[region]->GetGrid(step));
567 ResetBinLimits(fEventHist->GetGrid(step));
569 SetBinLimits(fTrackHist[region]->GetGrid(step));
572 if (fZVtxMax > fZVtxMin)
574 Printf("Using z-vtx range %f --> %f", fZVtxMin, fZVtxMax);
575 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(5)->SetRangeUser(fZVtxMin, fZVtxMax);
576 fEventHist->GetGrid(step)->GetGrid()->GetAxis(2)->SetRangeUser(fZVtxMin, fZVtxMax);
583 tracks = fTrackHist[region]->ShowProjection(2, step);
584 tracks->GetYaxis()->SetTitle(fTrackHist[region]->GetTitle());
585 if (fCombineMinMax && region == kMin)
587 ResetBinLimits(fTrackHist[kMax]->GetGrid(step));
588 SetBinLimits(fTrackHist[kMax]->GetGrid(step));
590 TH1D* tracks2 = fTrackHist[kMax]->ShowProjection(2, step);
591 tracks->Add(tracks2);
593 ResetBinLimits(fTrackHist[kMax]->GetGrid(step));
596 // normalize to get a density (deta dphi)
597 TAxis* axis = fTrackHist[region]->GetGrid(step)->GetAxis(0);
598 Float_t phiRegion = TMath::TwoPi() / 3;
599 if (!fCombineMinMax && region == kMin)
601 Float_t normalization = phiRegion;
603 normalization *= (axis->GetBinUpEdge(axis->GetLast()) - axis->GetBinLowEdge(axis->GetFirst()));
604 //Printf("Normalization: %f", normalization);
605 tracks->Scale(1.0 / normalization);
607 TH1D* events = fEventHist->ShowProjection(0, step);
608 tracks->Divide(events);
612 if (multBinEnd >= multBinBegin)
614 Printf("Using multiplicity range %d --> %d", multBinBegin, multBinEnd);
615 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(3)->SetRange(multBinBegin, multBinEnd);
616 fEventHist->GetGrid(step)->GetGrid()->GetAxis(1)->SetRange(multBinBegin, multBinEnd);
619 Int_t firstBin = fTrackHist[region]->GetAxis(2, step)->FindBin(ptLeadMin);
620 Int_t lastBin = fTrackHist[region]->GetAxis(2, step)->FindBin(ptLeadMax);
622 Printf("Using leading pT range %d --> %d", firstBin, lastBin);
624 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(2)->SetRange(firstBin, lastBin);
627 tracks = (TH1D*) fTrackHist[region]->GetGrid(step)->Project(4);
629 tracks = (TH1D*) fTrackHist[region]->GetGrid(step)->Project(4, 0);
631 Printf("Calculated histogram --> %f tracks", tracks->Integral());
632 fTrackHist[region]->GetGrid(step)->SetRangeUser(2, 0, -1);
634 if (twoD == 10 || twoD == 11)
636 Float_t etaLimit = 1.0;
639 tracks = (TH1D*) ((TH2*) tracks)->ProjectionX("proj", tracks->GetYaxis()->FindBin(-etaLimit + 0.01), tracks->GetYaxis()->FindBin(etaLimit - 0.01))->Clone();
641 // TODO calculate acc with 2 * (deta - 0.5 * deta*deta / 1.6)
642 tracks->Scale(1. / 0.75);
646 TH1D* tracksTmp1 = (TH1D*) ((TH2*) tracks)->ProjectionX("proj1", tracks->GetYaxis()->FindBin(-etaLimit * 2 + 0.01), tracks->GetYaxis()->FindBin(-etaLimit - 0.01))->Clone();
647 TH1D* tracksTmp2 = ((TH2*) tracks)->ProjectionX("proj2", tracks->GetYaxis()->FindBin(etaLimit + 0.01), tracks->GetYaxis()->FindBin(2 * etaLimit - 0.01));
649 tracksTmp1->Add(tracksTmp2);
655 tracks->Scale(1. / 0.25);
659 // normalize to get a density (deta dphi)
660 // TODO normalization may be off for 2d histogram
661 Float_t normalization = fTrackHist[region]->GetGrid(step)->GetAxis(4)->GetBinWidth(1);
665 TAxis* axis = fTrackHist[region]->GetGrid(step)->GetAxis(0);
666 if (strcmp(axis->GetTitle(), "#eta") == 0)
668 Printf("Normalizing using eta-axis range");
669 normalization *= axis->GetBinUpEdge(axis->GetLast()) - axis->GetBinLowEdge(axis->GetFirst());
673 Printf("Normalizing assuming accepted range of |eta| < 0.8");
674 normalization *= 0.8 * 2;
678 //Printf("Normalization: %f", normalization);
679 tracks->Scale(1.0 / normalization);
681 // NOTE fEventHist contains the number of events for the underlying event analysis and the number of trigger particles for the azimuthal correlation analysis. In the latter case the naming is therefore somewhat misleading!
682 TH1D* events = fEventHist->ShowProjection(0, step);
683 Int_t nEvents = (Int_t) events->Integral(firstBin, lastBin);
684 Printf("Calculated histogram --> %d events", nEvents);
686 *normEvents = nEvents;
689 tracks->Scale(1.0 / nEvents);
694 ResetBinLimits(fTrackHist[region]->GetGrid(step));
695 ResetBinLimits(fEventHist->GetGrid(step));
700 //____________________________________________________________________
701 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)
703 // Calls GetUEHist(...) for *each* multiplicity bin and performs a sum of ratios:
704 // 1_N [ (same/mixed)_1 + (same/mixed)_2 + (same/mixed)_3 + ... ]
705 // where N is the total number of events/trigger particles and the subscript is the multiplicity bin
707 // Can only be used for the 2D histogram at present
710 // mixed: AliUEHist containing mixed event corresponding to this object
711 // <other parameters> : check documentation of AliUEHist::GetUEHist
713 Int_t multIter = multBinBegin;
715 TH2* totalTracks = 0;
716 Int_t totalEvents = 0;
719 TAxis* vertexAxis = fTrackHist[kToward]->GetGrid(0)->GetGrid()->GetAxis(5);
720 if (useVertexBins && !vertexAxis)
722 Printf("Vertex axis requested but not available");
731 SetZVtxRange(vertexAxis->GetBinLowEdge(vertexBin) + 0.01, vertexAxis->GetBinUpEdge(vertexBin) - 0.01);
732 mixed->SetZVtxRange(vertexAxis->GetBinLowEdge(vertexBin) + 0.01, vertexAxis->GetBinUpEdge(vertexBin) - 0.01);
739 Int_t multBinBeginLocal = multBinBegin;
740 Int_t multBinEndLocal = multBinEnd;
742 if (multBinEnd >= multBinBegin)
744 multBinBeginLocal = multIter;
745 multBinEndLocal = multIter;
750 TH2* tracks = (TH2*) GetUEHist(step, region, ptLeadMin, ptLeadMax, multBinBeginLocal, multBinEndLocal, 1, etaNorm, &nEvents);
751 // undo normalization
752 tracks->Scale(nEvents);
753 totalEvents += nEvents;
755 TH2* mixedTwoD = (TH2*) mixed->GetUEHist(step, region, ptLeadMin, ptLeadMax, multBinBeginLocal, multBinEndLocal, 1, etaNorm);
757 // asssume flat in dphi, gain in statistics
758 // TH1* histMixedproj = mixedTwoD->ProjectionY();
759 // histMixedproj->Scale(1.0 / mixedTwoD->GetNbinsX());
761 // for (Int_t x=1; x<=mixedTwoD->GetNbinsX(); x++)
762 // for (Int_t y=1; y<=mixedTwoD->GetNbinsY(); y++)
763 // mixedTwoD->SetBinContent(x, y, histMixedproj->GetBinContent(y));
765 // delete histMixedproj;
767 // get mixed event normalization by assuming full acceptance at deta of 0 (only works for flat dphi)
768 /* Double_t mixedNorm = mixedTwoD->Integral(1, mixedTwoD->GetNbinsX(), mixedTwoD->GetYaxis()->FindBin(-0.01), mixedTwoD->GetYaxis()->FindBin(0.01));
769 mixedNorm /= mixedTwoD->GetNbinsX() * (mixedTwoD->GetYaxis()->FindBin(0.01) - mixedTwoD->GetYaxis()->FindBin(-0.01) + 1);
770 tracks->Scale(mixedNorm);*/
772 tracks->Scale(mixedTwoD->Integral() / tracks->Integral());
774 tracks->Divide(mixedTwoD);
779 totalTracks = tracks;
782 totalTracks->Add(tracks);
786 if (multIter > multBinEnd)
790 if (!useVertexBins || vertexBin > vertexAxis->GetNbins())
795 totalEvents = vertexAxis->GetNbins();
796 Printf("Dividing %f tracks by %d events", totalTracks->Integral(), totalEvents);
798 totalTracks->Scale(1.0 / totalEvents);
803 //____________________________________________________________________
804 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)
806 // returns a histogram projected to pT,assoc with the provided cuts
809 ResetBinLimits(fTrackHist[region]->GetGrid(step));
810 ResetBinLimits(fEventHist->GetGrid(step));
814 // 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
815 // therefore the number density must be calculated here per leading pT bin and then summed
817 if (multBinEnd > multBinBegin)
818 Printf("Using multiplicity range %d --> %d", multBinBegin, multBinEnd);
819 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(3)->SetRange(multBinBegin, multBinEnd);
820 fEventHist->GetGrid(step)->GetGrid()->GetAxis(1)->SetRange(multBinBegin, multBinEnd);
822 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(0)->SetRangeUser(etaMin, etaMax);
823 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(4)->SetRangeUser(phiMin, phiMax);
825 // get real phi cuts due to binning
826 Float_t phiMinReal = fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(4)->GetBinLowEdge(fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(4)->GetFirst());
827 Float_t phiMaxReal = fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(4)->GetBinUpEdge(fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(4)->GetLast());
828 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);
830 Int_t firstBin = fTrackHist[region]->GetAxis(2, step)->FindBin(ptLeadMin);
831 Int_t lastBin = fTrackHist[region]->GetAxis(2, step)->FindBin(ptLeadMax);
833 TH1D* events = fEventHist->ShowProjection(0, step);
835 for (Int_t bin=firstBin; bin<=lastBin; bin++)
837 fTrackHist[region]->GetGrid(step)->GetGrid()->GetAxis(2)->SetRange(bin, bin);
839 // project to pT,assoc
840 TH1D* tracksTmp = (TH1D*) fTrackHist[region]->GetGrid(step)->Project(1);
842 Printf("Calculated histogram in bin %d --> %f tracks", bin, tracksTmp->Integral());
843 fTrackHist[region]->GetGrid(step)->SetRangeUser(2, 0, -1);
845 // normalize to get a density (deta dphi)
846 Float_t normalization = 1;
847 TAxis* axis = fTrackHist[region]->GetGrid(step)->GetAxis(0);
848 if (strcmp(axis->GetTitle(), "#eta") == 0)
850 Printf("Normalizing using eta-axis range");
851 normalization *= axis->GetBinUpEdge(axis->GetLast()) - axis->GetBinLowEdge(axis->GetFirst());
855 Printf("Normalizating assuming accepted range of |eta| < 0.8");
856 normalization *= 0.8 * 2;
860 if (!skipPhiNormalization)
861 normalization *= phiMaxReal - phiMinReal;
863 //Printf("Normalization: %f", normalization);
864 tracksTmp->Scale(1.0 / normalization);
866 // and now dpT (bins have different width)
867 for (Int_t i=1; i<=tracksTmp->GetNbinsX(); i++)
869 tracksTmp->SetBinContent(i, tracksTmp->GetBinContent(i) / tracksTmp->GetXaxis()->GetBinWidth(i));
870 tracksTmp->SetBinError (i, tracksTmp->GetBinError(i) / tracksTmp->GetXaxis()->GetBinWidth(i));
873 Int_t nEvents = (Int_t) events->GetBinContent(bin);
875 tracksTmp->Scale(1.0 / nEvents);
876 Printf("Calculated histogram in bin %d --> %d events", bin, nEvents);
882 tracks->Add(tracksTmp);
889 ResetBinLimits(fTrackHist[region]->GetGrid(step));
890 ResetBinLimits(fEventHist->GetGrid(step));
895 void AliUEHist::MultiplyHistograms(THnSparse* grid, THnSparse* target, TH1* histogram, Int_t var1, Int_t var2)
897 // multiplies <grid> with <histogram> and put the result in <target>
898 // <grid> has usually more dimensions than histogram. The axis which are used to choose the value
899 // from <histogram> are given in <var1> and <var2>
901 // if <histogram> is 0, just copies content from step1 to step2
903 // clear target histogram
908 if (grid->GetAxis(var1)->GetNbins() != histogram->GetNbinsX())
909 AliFatal(Form("Invalid binning (var1): %d %d", grid->GetAxis(var1)->GetNbins(), histogram->GetNbinsX()));
911 if (var2 >= 0 && grid->GetAxis(var2)->GetNbins() != histogram->GetNbinsY())
912 AliFatal(Form("Invalid binning (var2): %d %d", grid->GetAxis(var2)->GetNbins(), histogram->GetNbinsY()));
915 if (grid->GetNdimensions() > 6)
916 AliFatal("Too many dimensions in THnSparse");
920 // optimized implementation
921 for (Int_t binIdx = 0; binIdx < grid->GetNbins(); binIdx++)
923 Double_t value = grid->GetBinContent(binIdx, bins);
924 Double_t error = grid->GetBinError(binIdx);
930 value *= histogram->GetBinContent(bins[var1]);
931 error *= histogram->GetBinContent(bins[var1]);
935 value *= histogram->GetBinContent(bins[var1], bins[var2]);
936 error *= histogram->GetBinContent(bins[var1], bins[var2]);
940 target->SetBinContent(bins, value);
941 target->SetBinError(bins, error);
945 //____________________________________________________________________
946 void AliUEHist::CorrectTracks(CFStep step1, CFStep step2, TH1* trackCorrection, Int_t var1, Int_t var2)
948 // corrects from step1 to step2 by multiplying the tracks with trackCorrection
949 // trackCorrection can be a function of eta (var1 == 0), pT (var1 == 1), leading pT (var1 == 2), multiplicity (var1 == 3), delta phi (var1 == 4)
950 // if var2 >= 0 a two dimension correction is assumed in trackCorrection
952 // if trackCorrection is 0, just copies content from step1 to step2
954 for (UInt_t region=0; region<fkRegions; region++)
955 CorrectTracks(step1, step2, region, trackCorrection, var1, var2);
958 //____________________________________________________________________
959 void AliUEHist::CorrectTracks(CFStep step1, CFStep step2, Int_t region, TH1* trackCorrection, Int_t var1, Int_t var2)
962 // see documentation of CorrectTracks above
965 if (!fTrackHist[region])
968 THnSparse* grid = fTrackHist[region]->GetGrid(step1)->GetGrid();
969 THnSparse* target = fTrackHist[region]->GetGrid(step2)->GetGrid();
971 MultiplyHistograms(grid, target, trackCorrection, var1, var2);
973 Printf("AliUEHist::CorrectTracks: Corrected from %f to %f entries. Correction histogram: %f entries (integral: %f)", grid->GetEntries(), target->GetEntries(), (trackCorrection) ? trackCorrection->GetEntries() : -1.0, (trackCorrection) ? trackCorrection->Integral() : -1.0);
976 //____________________________________________________________________
977 void AliUEHist::CorrectEvents(CFStep step1, CFStep step2, TH1* eventCorrection, Int_t var1, Int_t var2)
979 // corrects from step1 to step2 by multiplying the events with eventCorrection
980 // eventCorrection is as function of leading pT (var == 0) or multiplicity (var == 1)
982 // if eventCorrection is 0, just copies content from step1 to step2
984 AliCFGridSparse* grid = fEventHist->GetGrid(step1);
985 AliCFGridSparse* target = fEventHist->GetGrid(step2);
987 MultiplyHistograms(grid->GetGrid(), target->GetGrid(), eventCorrection, var1, var2);
989 Printf("AliUEHist::CorrectEvents: Corrected from %f to %f entries. Correction histogram: %f entries (integral: %f)", grid->GetEntries(), target->GetEntries(), (eventCorrection) ? eventCorrection->GetEntries() : -1.0, (eventCorrection) ? eventCorrection->Integral() : -1.0);
992 //____________________________________________________________________
993 void AliUEHist::Correct(AliUEHist* corrections)
995 // applies the given corrections to extract from the step kCFStepReconstructed all previous steps
997 // in this object the data is expected in the step kCFStepReconstructed
999 if (fHistogramType.Length() == 0)
1001 Printf("W-AliUEHist::Correct: fHistogramType not defined. Guessing histogram type...");
1002 if (fTrackHist[kToward]->GetNVar() < 5)
1004 if (strcmp(fTrackHist[kToward]->GetTitle(), "d^{2}N_{ch}/d#varphid#eta") == 0)
1005 fHistogramType = "NumberDensitypT";
1006 else if (strcmp(fTrackHist[kToward]->GetTitle(), "d^{2}#Sigma p_{T}/d#varphid#eta") == 0)
1007 fHistogramType = "SumpT";
1009 else if (fTrackHist[kToward]->GetNVar() == 5)
1011 if (strcmp(fTrackHist[kToward]->GetGrid(0)->GetGrid()->GetAxis(3)->GetTitle(), "multiplicity") == 0)
1012 fHistogramType = "NumberDensityPhi";
1013 else if (strcmp(fTrackHist[kToward]->GetGrid(0)->GetGrid()->GetAxis(3)->GetTitle(), "centrality") == 0)
1014 fHistogramType = "NumberDensityPhiCentrality";
1017 if (fHistogramType.Length() == 0)
1018 AliFatal("Cannot figure out histogram type. Try setting it manually...");
1021 Printf("AliUEHist::Correct: Correcting %s...", fHistogramType.Data());
1023 if (strcmp(fHistogramType, "NumberDensitypT") == 0 || strcmp(fHistogramType, "NumberDensityPhi") == 0 || strcmp(fHistogramType, "SumpT") == 0)
1027 // bias due to migration in leading pT (because the leading particle is not reconstructed, and the subleading is used)
1028 // extracted as function of leading pT
1029 Bool_t biasFromMC = kFALSE;
1030 const char* projAxis = "z";
1031 Int_t secondBin = -1;
1033 if (strcmp(fHistogramType, "NumberDensityPhi") == 0)
1039 for (UInt_t region = 0; region < fkRegions; region++)
1041 if (!fTrackHist[region])
1044 TH1* leadingBiasTracks = 0;
1047 leadingBiasTracks = (TH1*) corrections->GetBias(kCFStepReconstructed, kCFStepTracked, region, projAxis, 0, -1, 1); // from MC
1048 Printf("WARNING: Using MC bias correction");
1051 leadingBiasTracks = (TH1*) GetBias(kCFStepBiasStudy, kCFStepReconstructed, region, projAxis, 0, -1, 1); // from data
1053 CorrectTracks(kCFStepReconstructed, kCFStepTracked, region, leadingBiasTracks, 2, secondBin);
1054 if (region == kMin && fCombineMinMax)
1056 CorrectTracks(kCFStepReconstructed, kCFStepTracked, kMax, leadingBiasTracks, 2, secondBin);
1057 delete leadingBiasTracks;
1060 delete leadingBiasTracks;
1063 TH1* leadingBiasEvents = 0;
1065 leadingBiasEvents = (TH1*) corrections->GetBias(kCFStepReconstructed, kCFStepTracked, kToward, projAxis, 0, -1, 2); // from MC
1067 leadingBiasEvents = (TH1*) GetBias(kCFStepBiasStudy, kCFStepReconstructed, kToward, projAxis, 0, -1, 2); // from data
1069 //new TCanvas; leadingBiasEvents->DrawCopy();
1070 CorrectEvents(kCFStepReconstructed, kCFStepTracked, leadingBiasEvents, 0);
1071 delete leadingBiasEvents;
1073 // --- contamination correction ---
1075 TH2D* contamination = corrections->GetTrackingContamination();
1076 if (corrections->fContaminationEnhancement)
1078 Printf("Applying contamination enhancement");
1080 for (Int_t x=1; x<=contamination->GetNbinsX(); x++)
1081 for (Int_t y=1; y<=contamination->GetNbinsX(); y++)
1082 contamination->SetBinContent(x, y, contamination->GetBinContent(x, y) * corrections->fContaminationEnhancement->GetBinContent(corrections->fContaminationEnhancement->GetXaxis()->FindBin(contamination->GetYaxis()->GetBinCenter(y))));
1084 CorrectTracks(kCFStepTracked, kCFStepTrackedOnlyPrim, contamination, 0, 1);
1085 CorrectEvents(kCFStepTracked, kCFStepTrackedOnlyPrim, 0, 0);
1086 delete contamination;
1088 // --- efficiency correction ---
1089 // correct single-particle efficiency for associated particles
1090 // in addition correct for efficiency on trigger particles (tracks AND events)
1092 TH1* efficiencyCorrection = corrections->GetTrackingEfficiencyCorrection();
1093 // use kCFStepVertex as a temporary step (will be overwritten later anyway)
1094 CorrectTracks(kCFStepTrackedOnlyPrim, kCFStepVertex, efficiencyCorrection, 0, 1);
1095 delete efficiencyCorrection;
1098 efficiencyCorrection = corrections->GetTrackEfficiency(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, 1, -1, 2);
1099 CorrectEvents(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, efficiencyCorrection, 0);
1100 CorrectTracks(kCFStepVertex, kCFStepAnaTopology, efficiencyCorrection, 2);
1101 delete efficiencyCorrection;
1104 CorrectTracks(kCFStepAnaTopology, kCFStepVertex, 0, -1);
1105 CorrectEvents(kCFStepAnaTopology, kCFStepVertex, 0, 0);
1107 // vertex correction on the level of events as function of multiplicity, weighting tracks and events with the same factor
1108 // practically independent of low pT cut
1109 TH1D* vertexCorrection = (TH1D*) corrections->GetEventEfficiency(kCFStepVertex, kCFStepTriggered, 1);
1111 // convert stage from true multiplicity to observed multiplicity by simple conversion factor
1112 TH1D* vertexCorrectionObs = (TH1D*) vertexCorrection->Clone("vertexCorrection2");
1113 vertexCorrectionObs->Reset();
1115 TF1* func = new TF1("func", "[1]+[0]/(x-[2])");
1117 func->SetParameters(0.1, 1, -0.7);
1118 vertexCorrection->Fit(func, "0I", "", 0, 3);
1119 for (Int_t i=1; i<=vertexCorrectionObs->GetNbinsX(); i++)
1121 Float_t xPos = 1.0 / 0.77 * vertexCorrectionObs->GetXaxis()->GetBinCenter(i);
1123 vertexCorrectionObs->SetBinContent(i, func->Eval(xPos));
1125 vertexCorrectionObs->SetBinContent(i, vertexCorrection->Interpolate(xPos));
1130 vertexCorrection->DrawCopy();
1131 vertexCorrectionObs->SetLineColor(2);
1132 vertexCorrectionObs->DrawCopy("same");
1133 func->SetRange(0, 4);
1134 func->DrawClone("same");
1137 CorrectTracks(kCFStepVertex, kCFStepTriggered, vertexCorrectionObs, 3);
1138 CorrectEvents(kCFStepVertex, kCFStepTriggered, vertexCorrectionObs, 1);
1139 delete vertexCorrectionObs;
1140 delete vertexCorrection;
1144 CorrectTracks(kCFStepTriggered, kCFStepAll, 0, -1);
1145 CorrectEvents(kCFStepTriggered, kCFStepAll, 0, 0);
1147 else if (strcmp(fHistogramType, "NumberDensityPhiCentrality") == 0)
1150 CorrectTracks(kCFStepReconstructed, kCFStepTracked, 0, -1);
1151 CorrectEvents(kCFStepReconstructed, kCFStepTracked, 0, -1);
1153 // Dont use eta in the following, because it is a Delta-eta axis
1155 // contamination correction
1156 // correct single-particle contamination for associated particles
1158 TH1* contamination = corrections->GetTrackingContamination(1);
1162 Printf("Applying contamination enhancement");
1164 for (Int_t bin = 1; bin <= contamination->GetNbinsX(); bin++)
1166 printf("%f", contamination->GetBinContent(bin));
1167 if (contamination->GetBinContent(bin) > 0)
1168 contamination->SetBinContent(bin, 1.0 + 1.1 * (contamination->GetBinContent(bin) - 1.0));
1169 printf(" --> %f\n", contamination->GetBinContent(bin));
1173 CorrectTracks(kCFStepTracked, kCFStepTrackedOnlyPrim, contamination, 1);
1174 delete contamination;
1176 // correct for additional contamination due to trigger particle around phi ~ 0
1177 TH2* correlatedContamination = corrections->GetCorrelatedContamination();
1180 Printf("Applying contamination enhancement");
1182 for (Int_t bin = 1; bin <= correlatedContamination->GetNbinsX(); bin++)
1183 for (Int_t bin2 = 1; bin2 <= correlatedContamination->GetNbinsY(); bin2++)
1185 printf("%f", correlatedContamination->GetBinContent(bin, bin2));
1186 if (correlatedContamination->GetBinContent(bin, bin2) > 0)
1187 correlatedContamination->SetBinContent(bin, bin2, 1.0 + 1.1 * (correlatedContamination->GetBinContent(bin, bin2) - 1.0));
1188 printf(" --> %f\n", correlatedContamination->GetBinContent(bin, bin2));
1192 new TCanvas; correlatedContamination->DrawCopy("COLZ");
1193 CorrectCorrelatedContamination(kCFStepTrackedOnlyPrim, 0, correlatedContamination);
1194 // Printf("\n\n\nWARNING ---> SKIPPING CorrectCorrelatedContamination\n\n\n");
1196 delete correlatedContamination;
1198 // TODO correct for contamination of trigger particles (for tracks AND events)
1199 CorrectEvents(kCFStepTracked, kCFStepTrackedOnlyPrim, 0, 0);
1201 // --- efficiency correction ---
1202 // correct single-particle efficiency for associated particles
1203 // in addition correct for efficiency on trigger particles (tracks AND events)
1205 // in bins of pT and centrality
1206 TH1* efficiencyCorrection = corrections->GetTrackingEfficiencyCorrectionCentrality();
1207 // use kCFStepAnaTopology as a temporary step
1208 CorrectTracks(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, efficiencyCorrection, 1, 3);
1209 delete efficiencyCorrection;
1211 // correct pT,T in bins of pT and centrality
1212 efficiencyCorrection = corrections->GetTrackEfficiency(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, 1, 3, 2);
1213 CorrectEvents(kCFStepTrackedOnlyPrim, kCFStepVertex, efficiencyCorrection, 0, 1);
1214 CorrectTracks(kCFStepAnaTopology, kCFStepVertex, efficiencyCorrection, 2, 3);
1215 delete efficiencyCorrection;
1217 // no correction for vertex finding efficiency and trigger efficiency needed in PbPb
1219 CorrectTracks(kCFStepVertex, kCFStepAll, 0, -1);
1220 CorrectEvents(kCFStepVertex, kCFStepAll, 0, -1);
1223 AliFatal(Form("Unknown histogram for correction: %s", GetTitle()));
1226 //____________________________________________________________________
1227 TH1* AliUEHist::GetTrackEfficiency(CFStep step1, CFStep step2, Int_t axis1, Int_t axis2, Int_t source, Int_t axis3)
1229 // creates a track-level efficiency by dividing step2 by step1
1230 // projected to axis1 and axis2 (optional if >= 0)
1232 // source: 0 = fTrackHist; 1 = fTrackHistEfficiency; 2 = fTrackHistEfficiency rebinned for pT,T / pT,lead binning
1234 // integrate over regions
1235 // cache it for efficiency (usually more than one efficiency is requested)
1237 AliCFContainer* sourceContainer = 0;
1243 fCache = (AliCFContainer*) fTrackHist[0]->Clone();
1244 for (UInt_t i = 1; i < fkRegions; i++)
1246 fCache->Add(fTrackHist[i]);
1248 sourceContainer = fCache;
1250 else if (source == 1 || source == 2)
1252 sourceContainer = fTrackHistEfficiency;
1253 // step offset because we start with kCFStepAnaTopology
1254 step1 = (CFStep) ((Int_t) step1 - (Int_t) kCFStepAnaTopology);
1255 step2 = (CFStep) ((Int_t) step2 - (Int_t) kCFStepAnaTopology);
1260 // reset all limits and set the right ones except those in axis1, axis2 and axis3
1261 ResetBinLimits(sourceContainer->GetGrid(step1));
1262 ResetBinLimits(sourceContainer->GetGrid(step2));
1263 if (fEtaMax > fEtaMin && axis1 != 0 && axis2 != 0 && axis3 != 0)
1265 Printf("Restricted eta-range to %f %f", fEtaMin, fEtaMax);
1266 sourceContainer->GetGrid(step1)->SetRangeUser(0, fEtaMin, fEtaMax);
1267 sourceContainer->GetGrid(step2)->SetRangeUser(0, fEtaMin, fEtaMax);
1269 if (fPtMax > fPtMin && axis1 != 1 && axis2 != 1 && axis3 != 1)
1271 sourceContainer->GetGrid(step1)->SetRangeUser(1, fPtMin, fPtMax);
1272 sourceContainer->GetGrid(step2)->SetRangeUser(1, fPtMin, fPtMax);
1274 if (fCentralityMax > fCentralityMin && axis1 != 3 && axis2 != 3 && axis3 != 3)
1276 sourceContainer->GetGrid(step1)->SetRangeUser(3, fCentralityMin, fCentralityMax);
1277 sourceContainer->GetGrid(step2)->SetRangeUser(3, fCentralityMin, fCentralityMax);
1285 generated = sourceContainer->Project(step1, axis1, axis2, axis3);
1286 measured = sourceContainer->Project(step2, axis1, axis2, axis3);
1288 else if (axis2 >= 0)
1290 generated = sourceContainer->Project(step1, axis1, axis2);
1291 measured = sourceContainer->Project(step2, axis1, axis2);
1295 generated = sourceContainer->Project(step1, axis1);
1296 measured = sourceContainer->Project(step2, axis1);
1299 // check for bins with less than 50 entries, print warning
1307 binEnd[0] = generated->GetNbinsX();
1308 binEnd[1] = generated->GetNbinsY();
1309 binEnd[2] = generated->GetNbinsZ();
1311 if (fEtaMax > fEtaMin)
1315 binBegin[0] = generated->GetXaxis()->FindBin(fEtaMin);
1316 binEnd[0] = generated->GetXaxis()->FindBin(fEtaMax);
1320 binBegin[1] = generated->GetYaxis()->FindBin(fEtaMin);
1321 binEnd[1] = generated->GetYaxis()->FindBin(fEtaMax);
1325 binBegin[2] = generated->GetZaxis()->FindBin(fEtaMin);
1326 binEnd[2] = generated->GetZaxis()->FindBin(fEtaMax);
1330 if (fPtMax > fPtMin)
1332 // TODO this is just checking up to 15 for now
1333 Float_t ptMax = TMath::Min((Float_t) 15., fPtMax);
1336 binBegin[0] = generated->GetXaxis()->FindBin(fPtMin);
1337 binEnd[0] = generated->GetXaxis()->FindBin(ptMax);
1341 binBegin[1] = generated->GetYaxis()->FindBin(fPtMin);
1342 binEnd[1] = generated->GetYaxis()->FindBin(ptMax);
1346 binBegin[2] = generated->GetZaxis()->FindBin(fPtMin);
1347 binEnd[2] = generated->GetZaxis()->FindBin(ptMax);
1355 for (Int_t i=0; i<3; i++)
1356 vars[i] = binBegin[i];
1358 const Int_t limit = 50;
1361 if (generated->GetDimension() == 1 && generated->GetBinContent(vars[0]) < limit)
1363 Printf("Empty bin at %s=%.2f (%.2f entries)", generated->GetXaxis()->GetTitle(), generated->GetXaxis()->GetBinCenter(vars[0]), generated->GetBinContent(vars[0]));
1366 else if (generated->GetDimension() == 2 && generated->GetBinContent(vars[0], vars[1]) < limit)
1368 Printf("Empty bin at %s=%.2f %s=%.2f (%.2f entries)",
1369 generated->GetXaxis()->GetTitle(), generated->GetXaxis()->GetBinCenter(vars[0]),
1370 generated->GetYaxis()->GetTitle(), generated->GetYaxis()->GetBinCenter(vars[1]),
1371 generated->GetBinContent(vars[0], vars[1]));
1374 else if (generated->GetDimension() == 3 && generated->GetBinContent(vars[0], vars[1], vars[2]) < limit)
1376 Printf("Empty bin at %s=%.2f %s=%.2f %s=%.2f (%.2f entries)",
1377 generated->GetXaxis()->GetTitle(), generated->GetXaxis()->GetBinCenter(vars[0]),
1378 generated->GetYaxis()->GetTitle(), generated->GetYaxis()->GetBinCenter(vars[1]),
1379 generated->GetZaxis()->GetTitle(), generated->GetZaxis()->GetBinCenter(vars[2]),
1380 generated->GetBinContent(vars[0], vars[1], vars[2]));
1385 if (vars[2] == binEnd[2]+1)
1387 vars[2] = binBegin[2];
1391 if (vars[1] == binEnd[1]+1)
1393 vars[1] = binBegin[1];
1397 if (vars[0] == binEnd[0]+1)
1402 Printf("Correction has %d empty bins (out of %d bins)", count, total);
1404 // rebin if required
1407 TAxis* axis = fEventHist->GetGrid(0)->GetGrid()->GetAxis(0);
1409 if (axis->GetNbins() < measured->GetNbinsX())
1413 // 2d rebin with variable axis does not exist in root
1415 TH1* tmp = measured;
1416 measured = new TH2D(Form("%s_rebinned", tmp->GetName()), tmp->GetTitle(), axis->GetNbins(), axis->GetXbins()->GetArray(), tmp->GetNbinsY(), tmp->GetYaxis()->GetXbins()->GetArray());
1417 for (Int_t x=1; x<=tmp->GetNbinsX(); x++)
1418 for (Int_t y=1; y<=tmp->GetNbinsY(); y++)
1420 ((TH2*) measured)->Fill(tmp->GetXaxis()->GetBinCenter(x), tmp->GetYaxis()->GetBinCenter(y), tmp->GetBinContent(x, y));
1421 measured->SetBinError(x, y, 0); // cannot trust bin error, set to 0
1426 generated = new TH2D(Form("%s_rebinned", tmp->GetName()), tmp->GetTitle(), axis->GetNbins(), axis->GetXbins()->GetArray(), tmp->GetNbinsY(), tmp->GetYaxis()->GetXbins()->GetArray());
1427 for (Int_t x=1; x<=tmp->GetNbinsX(); x++)
1428 for (Int_t y=1; y<=tmp->GetNbinsY(); y++)
1430 ((TH2*) generated)->Fill(tmp->GetXaxis()->GetBinCenter(x), tmp->GetYaxis()->GetBinCenter(y), tmp->GetBinContent(x, y));
1431 generated->SetBinError(x, y, 0); // cannot trust bin error, set to 0
1437 TH1* tmp = measured;
1438 measured = tmp->Rebin(axis->GetNbins(), Form("%s_rebinned", tmp->GetName()), axis->GetXbins()->GetArray());
1442 generated = tmp->Rebin(axis->GetNbins(), Form("%s_rebinned", tmp->GetName()), axis->GetXbins()->GetArray());
1446 else if (axis->GetNbins() > measured->GetNbinsX())
1449 AliFatal("Rebinning only works for 1d at present");
1451 // this is an unfortunate case where the number of bins has to be increased in principle
1452 // there is a region where the binning is finner in one histogram and a region where it is the other way round
1453 // this cannot be resolved in principle, but as we only calculate the ratio the bin in the second region get the same entries
1454 // only a certain binning is supported here
1455 if (axis->GetNbins() != 100 || measured->GetNbinsX() != 39)
1456 AliFatal(Form("Invalid binning --> %d %d", axis->GetNbins(), measured->GetNbinsX()));
1458 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};
1460 // reduce binning below 5 GeV/c
1461 TH1* tmp = measured;
1462 measured = tmp->Rebin(27, Form("%s_rebinned", tmp->GetName()), newBins);
1465 // increase binning above 5 GeV/c
1467 measured = new TH1F(Form("%s_rebinned2", tmp->GetName()), tmp->GetTitle(), axis->GetNbins(), axis->GetBinLowEdge(1), axis->GetBinUpEdge(axis->GetNbins()));
1468 for (Int_t bin=1; bin<=measured->GetNbinsX(); bin++)
1470 measured->SetBinContent(bin, tmp->GetBinContent(tmp->FindBin(measured->GetBinCenter(bin))));
1471 measured->SetBinError(bin, tmp->GetBinError(tmp->FindBin(measured->GetBinCenter(bin))));
1475 // reduce binning below 5 GeV/c
1477 generated = tmp->Rebin(27, Form("%s_rebinned", tmp->GetName()), newBins);
1480 // increase binning above 5 GeV/c
1482 generated = new TH1F(Form("%s_rebinned2", tmp->GetName()), tmp->GetTitle(), axis->GetNbins(), axis->GetBinLowEdge(1), axis->GetBinUpEdge(axis->GetNbins()));
1483 for (Int_t bin=1; bin<=generated->GetNbinsX(); bin++)
1485 generated->SetBinContent(bin, tmp->GetBinContent(tmp->FindBin(generated->GetBinCenter(bin))));
1486 generated->SetBinError(bin, tmp->GetBinError(tmp->FindBin(generated->GetBinCenter(bin))));
1492 measured->Divide(measured, generated, 1, 1, "B");
1496 ResetBinLimits(sourceContainer->GetGrid(step1));
1497 ResetBinLimits(sourceContainer->GetGrid(step2));
1502 //____________________________________________________________________
1503 TH1* AliUEHist::GetEventEfficiency(CFStep step1, CFStep step2, Int_t axis1, Int_t axis2, Float_t ptLeadMin, Float_t ptLeadMax)
1505 // creates a event-level efficiency by dividing step2 by step1
1506 // projected to axis1 and axis2 (optional if >= 0)
1508 if (ptLeadMax > ptLeadMin)
1510 fEventHist->GetGrid(step1)->SetRangeUser(0, ptLeadMin, ptLeadMax);
1511 fEventHist->GetGrid(step2)->SetRangeUser(0, ptLeadMin, ptLeadMax);
1519 generated = fEventHist->Project(step1, axis1, axis2);
1520 measured = fEventHist->Project(step2, axis1, axis2);
1524 generated = fEventHist->Project(step1, axis1);
1525 measured = fEventHist->Project(step2, axis1);
1528 measured->Divide(measured, generated, 1, 1, "B");
1532 if (ptLeadMax > ptLeadMin)
1534 fEventHist->GetGrid(step1)->SetRangeUser(0, 0, -1);
1535 fEventHist->GetGrid(step2)->SetRangeUser(0, 0, -1);
1541 //____________________________________________________________________
1542 void AliUEHist::WeightHistogram(TH3* hist1, TH1* hist2)
1544 // weights each entry of the 3d histogram hist1 with the 1d histogram hist2
1545 // where the matching is done of the z axis of hist1 with the x axis of hist2
1547 if (hist1->GetNbinsZ() != hist2->GetNbinsX())
1548 AliFatal(Form("Inconsistent binning %d %d", hist1->GetNbinsZ(), hist2->GetNbinsX()));
1550 for (Int_t x=1; x<=hist1->GetNbinsX(); x++)
1552 for (Int_t y=1; y<=hist1->GetNbinsY(); y++)
1554 for (Int_t z=1; z<=hist1->GetNbinsZ(); z++)
1556 if (hist2->GetBinContent(z) > 0)
1558 hist1->SetBinContent(x, y, z, hist1->GetBinContent(x, y, z) / hist2->GetBinContent(z));
1559 hist1->SetBinError(x, y, z, hist1->GetBinError(x, y, z) / hist2->GetBinContent(z));
1563 hist1->SetBinContent(x, y, z, 0);
1564 hist1->SetBinError(x, y, z, 0);
1571 //____________________________________________________________________
1572 TH1* AliUEHist::GetBias(CFStep step1, CFStep step2, Int_t region, const char* axis, Float_t leadPtMin, Float_t leadPtMax, Int_t weighting)
1574 // extracts the track-level bias (integrating out the multiplicity) between two steps (dividing step2 by step1)
1575 // in the given region (sum over all regions is calculated if region == -1)
1576 // done by weighting the track-level distribution with the number of events as function of leading pT
1577 // and then calculating the ratio between the distributions
1578 // projected to axis which is a TH3::Project3D string, e.g. "x", or "yx"
1579 // no projection is done if axis == 0
1580 // weighting: 0 = tracks weighted with events (as discussed above)
1581 // 1 = only track bias is returned
1582 // 2 = only event bias is returned
1584 AliCFContainer* tmp = 0;
1588 tmp = (AliCFContainer*) fTrackHist[0]->Clone();
1589 for (UInt_t i = 1; i < fkRegions; i++)
1591 tmp->Add(fTrackHist[i]);
1593 else if (region == kMin && fCombineMinMax)
1595 tmp = (AliCFContainer*) fTrackHist[kMin]->Clone();
1596 tmp->Add(fTrackHist[kMax]);
1599 tmp = fTrackHist[region];
1601 ResetBinLimits(tmp->GetGrid(step1));
1602 ResetBinLimits(fEventHist->GetGrid(step1));
1603 SetBinLimits(tmp->GetGrid(step1));
1605 ResetBinLimits(tmp->GetGrid(step2));
1606 ResetBinLimits(fEventHist->GetGrid(step2));
1607 SetBinLimits(tmp->GetGrid(step2));
1609 TH1D* events1 = (TH1D*)fEventHist->Project(step1, 0);
1610 TH3D* hist1 = (TH3D*)tmp->Project(step1, 0, tmp->GetNVar()-1, 2);
1612 WeightHistogram(hist1, events1);
1614 TH1D* events2 = (TH1D*)fEventHist->Project(step2, 0);
1615 TH3D* hist2 = (TH3D*)tmp->Project(step2, 0, tmp->GetNVar()-1, 2);
1617 WeightHistogram(hist2, events2);
1619 TH1* generated = hist1;
1620 TH1* measured = hist2;
1622 if (weighting == 0 || weighting == 1)
1626 if (leadPtMax > leadPtMin)
1628 hist1->GetZaxis()->SetRangeUser(leadPtMin, leadPtMax);
1629 hist2->GetZaxis()->SetRangeUser(leadPtMin, leadPtMax);
1632 if (fEtaMax > fEtaMin && !TString(axis).Contains("x"))
1634 hist1->GetXaxis()->SetRangeUser(fEtaMin, fEtaMax);
1635 hist2->GetXaxis()->SetRangeUser(fEtaMin, fEtaMax);
1638 generated = hist1->Project3D(axis);
1639 measured = hist2->Project3D(axis);
1641 // delete hists here if projection has been done
1648 else if (weighting == 2)
1652 generated = events1;
1656 measured->Divide(generated);
1660 ResetBinLimits(tmp->GetGrid(step1));
1661 ResetBinLimits(tmp->GetGrid(step2));
1663 if ((region == -1) || (region == kMin && fCombineMinMax))
1669 //____________________________________________________________________
1670 void AliUEHist::CorrectCorrelatedContamination(CFStep step, Int_t region, TH1* trackCorrection)
1672 // corrects for the given factor in a small delta-eta and delta-phi window as function of pT,A and pT,T
1674 if (!fTrackHist[region])
1677 THnSparse* grid = fTrackHist[region]->GetGrid(step)->GetGrid();
1682 if (grid->GetAxis(var1)->GetNbins() != trackCorrection->GetNbinsX())
1683 AliFatal(Form("Invalid binning (var1): %d %d", grid->GetAxis(var1)->GetNbins(), trackCorrection->GetNbinsX()));
1685 if (grid->GetAxis(var2)->GetNbins() != trackCorrection->GetNbinsY())
1686 AliFatal(Form("Invalid binning (var2): %d %d", grid->GetAxis(var2)->GetNbins(), trackCorrection->GetNbinsY()));
1688 // optimized implementation
1689 for (Int_t binIdx = 0; binIdx < grid->GetNbins(); binIdx++)
1693 Double_t value = grid->GetBinContent(binIdx, bins);
1694 Double_t error = grid->GetBinError(binIdx);
1696 // check eta and phi axes
1697 if (TMath::Abs(grid->GetAxis(0)->GetBinCenter(bins[0])) > 0.1)
1699 if (TMath::Abs(grid->GetAxis(4)->GetBinCenter(bins[4])) > 0.1)
1702 value *= trackCorrection->GetBinContent(bins[var1], bins[var2]);
1703 error *= trackCorrection->GetBinContent(bins[var1], bins[var2]);
1705 grid->SetBinContent(bins, value);
1706 grid->SetBinError(bins, error);
1709 Printf("AliUEHist::CorrectCorrelatedContamination: Corrected.");
1712 //____________________________________________________________________
1713 TH2* AliUEHist::GetCorrelatedContamination()
1715 // 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!)
1717 Int_t step1 = kCFStepTrackedOnlyPrim;
1718 Int_t step2 = kCFStepTracked;
1720 fTrackHist[0]->GetGrid(step1)->SetRangeUser(0, -0.01, 0.01); // delta eta
1721 fTrackHist[0]->GetGrid(step1)->SetRangeUser(4, -0.01, 0.01); // delta phi
1722 TH2* tracksStep1 = (TH2*) fTrackHist[0]->Project(step1, 1, 2);
1724 fTrackHist[0]->GetGrid(step2)->SetRangeUser(0, -0.01, 0.01); // delta eta
1725 fTrackHist[0]->GetGrid(step2)->SetRangeUser(4, -0.01, 0.01); // delta phi
1726 TH2* tracksStep2 = (TH2*) fTrackHist[0]->Project(step2, 1, 2);
1728 tracksStep1->Divide(tracksStep2);
1730 TH1* triggersStep1 = fEventHist->Project(step1, 0);
1731 TH1* triggersStep2 = fEventHist->Project(step2, 0);
1733 TH1* singleParticle = GetTrackingContamination(1);
1735 for (Int_t x=1; x<=tracksStep1->GetNbinsX(); x++)
1736 for (Int_t y=1; y<=tracksStep1->GetNbinsY(); y++)
1737 if (singleParticle->GetBinContent(x) > 0 && triggersStep1->GetBinContent(y) > 0)
1738 tracksStep1->SetBinContent(x, y, tracksStep1->GetBinContent(x, y) / triggersStep1->GetBinContent(y) * triggersStep2->GetBinContent(y) / singleParticle->GetBinContent(x));
1740 tracksStep1->SetBinContent(x, y, 0);
1742 delete singleParticle;
1744 delete triggersStep1;
1745 delete triggersStep2;
1750 //____________________________________________________________________
1751 TH2D* AliUEHist::GetTrackingEfficiency()
1753 // extracts the tracking efficiency by calculating the efficiency from step kCFStepAnaTopology to kCFStepTrackedOnlyPrim
1754 // integrates over the regions and all other variables than pT and eta to increase the statistics
1756 // returned histogram has to be deleted by the user
1758 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepAnaTopology, kCFStepTrackedOnlyPrim, 0, 1));
1761 //____________________________________________________________________
1762 TH2D* AliUEHist::GetTrackingEfficiencyCentrality()
1764 // extracts the tracking efficiency by calculating the efficiency from step kCFStepAnaTopology to kCFStepTrackedOnlyPrim
1765 // integrates over the regions and all other variables than pT, centrality to increase the statistics
1767 // returned histogram has to be deleted by the user
1769 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepAnaTopology, kCFStepTrackedOnlyPrim, 1, 3));
1772 //____________________________________________________________________
1773 TH1D* AliUEHist::GetTrackingEfficiency(Int_t axis)
1775 // extracts the tracking efficiency by calculating the efficiency from step kCFStepAnaTopology to kCFStepTrackedOnlyPrim
1776 // integrates over the regions and all other variables than pT (axis == 0) and eta (axis == 1) to increase the statistics
1778 return dynamic_cast<TH1D*> (GetTrackEfficiency(kCFStepAnaTopology, kCFStepTrackedOnlyPrim, axis));
1781 //____________________________________________________________________
1782 TH2D* AliUEHist::GetTrackingCorrection()
1784 // extracts the tracking correction by calculating the efficiency from step kCFStepAnaTopology to kCFStepTracked
1785 // integrates over the regions and all other variables than pT and eta to increase the statistics
1787 // returned histogram has to be deleted by the user
1789 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepTracked, kCFStepAnaTopology, 0, 1));
1792 //____________________________________________________________________
1793 TH1D* AliUEHist::GetTrackingCorrection(Int_t axis)
1795 // extracts the tracking correction by calculating the efficiency from step kCFStepAnaTopology to kCFStepTracked
1796 // integrates over the regions and all other variables than pT (axis == 0) and eta (axis == 1) to increase the statistics
1798 return dynamic_cast<TH1D*> (GetTrackEfficiency(kCFStepTracked, kCFStepAnaTopology, axis));
1801 //____________________________________________________________________
1802 TH2D* AliUEHist::GetTrackingEfficiencyCorrection()
1804 // extracts the tracking correction by calculating the efficiency from step kCFStepAnaTopology to kCFStepTracked
1805 // integrates over the regions and all other variables than pT and eta to increase the statistics
1807 // returned histogram has to be deleted by the user
1809 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, 0, 1));
1812 //____________________________________________________________________
1813 TH2D* AliUEHist::GetTrackingEfficiencyCorrectionCentrality()
1815 // extracts the tracking correction by calculating the efficiency from step kCFStepAnaTopology to kCFStepTracked
1816 // integrates over the regions and all other variables than pT and centrality to increase the statistics
1818 // returned histogram has to be deleted by the user
1820 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, 1, 3));
1823 //____________________________________________________________________
1824 TH1D* AliUEHist::GetTrackingEfficiencyCorrection(Int_t axis)
1826 // extracts the tracking correction by calculating the efficiency from step kCFStepAnaTopology to kCFStepTracked
1827 // integrates over the regions and all other variables than pT (axis == 0) and eta (axis == 1) to increase the statistics
1829 return dynamic_cast<TH1D*> (GetTrackEfficiency(kCFStepTrackedOnlyPrim, kCFStepAnaTopology, axis));
1832 //____________________________________________________________________
1833 TH2D* AliUEHist::GetTrackingContamination()
1835 // extracts the tracking contamination by secondaries by calculating the efficiency from step kCFStepTrackedOnlyPrim to kCFStepTracked
1836 // integrates over the regions and all other variables than pT and eta to increase the statistics
1838 // returned histogram has to be deleted by the user
1840 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepTracked, kCFStepTrackedOnlyPrim, 0, 1));
1843 //____________________________________________________________________
1844 TH2D* AliUEHist::GetTrackingContaminationCentrality()
1846 // extracts the tracking contamination by secondaries by calculating the efficiency from step kCFStepTrackedOnlyPrim to kCFStepTracked
1847 // integrates over the regions and all other variables than pT and centrality to increase the statistics
1849 // returned histogram has to be deleted by the user
1851 return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepTracked, kCFStepTrackedOnlyPrim, 1, 3));
1854 //____________________________________________________________________
1855 TH1D* AliUEHist::GetTrackingContamination(Int_t axis)
1857 // extracts the tracking contamination by secondaries by calculating the efficiency from step kCFStepTrackedOnlyPrim to kCFStepTracked
1858 // integrates over the regions and all other variables than pT (axis == 0) and eta (axis == 1) to increase the statistics
1860 return dynamic_cast<TH1D*> (GetTrackEfficiency(kCFStepTracked, kCFStepTrackedOnlyPrim, axis));
1863 //____________________________________________________________________
1864 const char* AliUEHist::GetRegionTitle(Region region)
1866 // returns the name of the given region
1875 return (fCombineMinMax) ? "Transverse" : "Min";
1883 //____________________________________________________________________
1884 const char* AliUEHist::GetStepTitle(CFStep step)
1886 // returns the name of the given step
1891 return "All events";
1892 case kCFStepTriggered:
1895 return "Primary Vertex";
1896 case kCFStepAnaTopology:
1897 return "Required analysis topology";
1898 case kCFStepTrackedOnlyPrim:
1899 return "Tracked (matched MC, only primaries)";
1900 case kCFStepTracked:
1901 return "Tracked (matched MC, all)";
1902 case kCFStepReconstructed:
1903 return "Reconstructed";
1904 case kCFStepRealLeading:
1905 return "Correct leading particle identified";
1906 case kCFStepBiasStudy:
1907 return "Bias study applying tracking efficiency";
1908 case kCFStepBiasStudy2:
1909 return "Bias study applying tracking efficiency in two steps";
1915 //____________________________________________________________________
1916 void AliUEHist::CopyReconstructedData(AliUEHist* from)
1918 // copies those histograms extracted from ESD to this object
1920 // TODO at present only the pointers are copied
1922 for (Int_t region=0; region<4; region++)
1924 if (!fTrackHist[region])
1927 fTrackHist[region]->SetGrid(AliUEHist::kCFStepReconstructed, from->fTrackHist[region]->GetGrid(AliUEHist::kCFStepReconstructed));
1928 //fTrackHist[region]->SetGrid(AliUEHist::kCFStepTrackedOnlyPrim, from->fTrackHist[region]->GetGrid(AliUEHist::kCFStepTrackedOnlyPrim));
1929 fTrackHist[region]->SetGrid(AliUEHist::kCFStepBiasStudy, from->fTrackHist[region]->GetGrid(AliUEHist::kCFStepBiasStudy));
1932 fEventHist->SetGrid(AliUEHist::kCFStepReconstructed, from->fEventHist->GetGrid(AliUEHist::kCFStepReconstructed));
1933 //fEventHist->SetGrid(AliUEHist::kCFStepTrackedOnlyPrim, from->fEventHist->GetGrid(AliUEHist::kCFStepTrackedOnlyPrim));
1934 fEventHist->SetGrid(AliUEHist::kCFStepBiasStudy, from->fEventHist->GetGrid(AliUEHist::kCFStepBiasStudy));
1937 //____________________________________________________________________
1938 void AliUEHist::ExtendTrackingEfficiency(Bool_t verbose)
1940 // fits the tracking efficiency at high pT with a constant and fills all bins with this tracking efficiency
1942 Float_t fitRangeBegin = 5.01;
1943 Float_t fitRangeEnd = 14.99;
1944 Float_t extendRangeBegin = 10.01;
1946 if (fTrackHistEfficiency->GetNVar() == 3)
1948 TH1* obj = GetTrackingEfficiency(1);
1956 obj->Fit("pol0", (verbose) ? "+" : "0+", "SAME", fitRangeBegin, fitRangeEnd);
1958 Float_t trackingEff = obj->GetFunction("pol0")->GetParameter(0);
1960 obj = GetTrackingContamination(1);
1968 obj->Fit("pol0", (verbose) ? "+" : "0+", "SAME", fitRangeBegin, fitRangeEnd);
1970 Float_t trackingCont = obj->GetFunction("pol0")->GetParameter(0);
1972 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);
1974 // extend for full pT range
1975 for (Int_t x = fTrackHistEfficiency->GetAxis(0, 0)->FindBin(fEtaMin); x <= fTrackHistEfficiency->GetAxis(0, 0)->FindBin(fEtaMax); x++)
1976 for (Int_t y = fTrackHistEfficiency->GetAxis(1, 0)->FindBin(extendRangeBegin); y <= fTrackHistEfficiency->GetNBins(1); y++)
1977 for (Int_t z = 1; z <= fTrackHistEfficiency->GetNBins(2); z++) // particle type axis
1985 fTrackHistEfficiency->GetGrid(0)->SetElement(bins, 100);
1986 fTrackHistEfficiency->GetGrid(1)->SetElement(bins, 100.0 * trackingEff);
1987 fTrackHistEfficiency->GetGrid(2)->SetElement(bins, 100.0 * trackingEff / trackingCont);
1990 else if (fTrackHistEfficiency->GetNVar() == 4)
1992 // fit in centrality intervals of 20% for efficiency, one bin for contamination
1993 Float_t* trackingEff = 0;
1994 Float_t* trackingCont = 0;
1995 Float_t centralityBins[] = { 0, 10, 20, 40, 60, 100 };
1996 Int_t nCentralityBins = 5;
1998 Printf("AliUEHist::ExtendTrackingEfficiency: Fitting efficiencies between %f and %f. Extending from %f onwards (within %f < eta < %f)", fitRangeBegin, fitRangeEnd, extendRangeBegin, fEtaMin, fEtaMax);
2000 // 0 = eff; 1 = cont
2001 for (Int_t caseNo = 0; caseNo < 2; caseNo++)
2003 Float_t* target = 0;
2004 Int_t centralityBinsLocal = nCentralityBins;
2008 trackingEff = new Float_t[centralityBinsLocal];
2009 target = trackingEff;
2013 centralityBinsLocal = 1;
2014 trackingCont = new Float_t[centralityBinsLocal];
2015 target = trackingCont;
2018 for (Int_t i=0; i<centralityBinsLocal; i++)
2020 if (centralityBinsLocal == 1)
2021 SetCentralityRange(centralityBins[0] + 0.1, centralityBins[nCentralityBins] - 0.1);
2023 SetCentralityRange(centralityBins[i] + 0.1, centralityBins[i+1] - 0.1);
2024 TH1* proj = (caseNo == 0) ? GetTrackingEfficiency(1) : GetTrackingContamination(1);
2030 if ((Int_t) proj->Fit("pol0", (verbose) ? "+" : "Q0+", "SAME", fitRangeBegin, fitRangeEnd) == 0)
2031 target[i] = proj->GetFunction("pol0")->GetParameter(0);
2034 Printf("AliUEHist::ExtendTrackingEfficiency: case %d, centrality %d, eff %f", caseNo, i, target[i]);
2038 // extend for full pT range
2039 for (Int_t x = fTrackHistEfficiency->GetAxis(0, 0)->FindBin(fEtaMin); x <= fTrackHistEfficiency->GetAxis(0, 0)->FindBin(fEtaMax); x++)
2040 for (Int_t y = fTrackHistEfficiency->GetAxis(1, 0)->FindBin(extendRangeBegin); y <= fTrackHistEfficiency->GetNBins(1); y++)
2041 for (Int_t z = 1; z <= fTrackHistEfficiency->GetNBins(2); z++) // particle type axis
2043 for (Int_t z2 = 1; z2 <= fTrackHistEfficiency->GetNBins(3); z2++) // centrality axis
2053 while (centralityBins[z2Bin+1] < fTrackHistEfficiency->GetAxis(3, 0)->GetBinCenter(z2))
2056 //Printf("%d %d", z2, z2Bin);
2058 fTrackHistEfficiency->GetGrid(0)->SetElement(bins, 100);
2059 fTrackHistEfficiency->GetGrid(1)->SetElement(bins, 100.0 * trackingEff[z2Bin]);
2060 if (trackingCont[0] > 0)
2061 fTrackHistEfficiency->GetGrid(2)->SetElement(bins, 100.0 * trackingEff[z2Bin] / trackingCont[0]);
2063 fTrackHistEfficiency->GetGrid(2)->SetElement(bins, 0);
2067 delete[] trackingEff;
2068 delete[] trackingCont;
2071 SetCentralityRange(0, 0);
2074 void AliUEHist::AdditionalDPhiCorrection(Int_t step)
2076 // corrects the dphi distribution with an extra factor close to dphi ~ 0
2078 Printf("WARNING: In AliUEHist::AdditionalDPhiCorrection.");
2080 THnSparse* grid = fTrackHist[0]->GetGrid(step)->GetGrid();
2082 // optimized implementation
2083 for (Int_t binIdx = 0; binIdx < grid->GetNbins(); binIdx++)
2086 Double_t value = grid->GetBinContent(binIdx, bins);
2087 Double_t error = grid->GetBinError(binIdx);
2089 Float_t binCenter = grid->GetAxis(4)->GetBinCenter(bins[4]);
2090 if (TMath::Abs(binCenter) < 0.2)
2095 else if (TMath::Abs(binCenter) < 0.3)
2101 grid->SetBinContent(bins, value);
2102 grid->SetBinError(bins, error);
2106 void AliUEHist::Scale(Double_t factor)
2108 // scales all contained histograms by the given factor
2110 for (Int_t i=0; i<4; i++)
2112 fTrackHist[i]->Scale(factor);
2114 fEventHist->Scale(factor);
2115 fTrackHistEfficiency->Scale(factor);
2118 void AliUEHist::Reset()
2120 // resets all contained histograms
2122 for (Int_t i=0; i<4; i++)
2124 for (Int_t step=0; step<fTrackHist[i]->GetNStep(); step++)
2125 fTrackHist[i]->GetGrid(step)->GetGrid()->Reset();
2127 for (Int_t step=0; step<fEventHist->GetNStep(); step++)
2128 fEventHist->GetGrid(step)->GetGrid()->Reset();
2130 for (Int_t step=0; step<fTrackHistEfficiency->GetNStep(); step++)
2131 fTrackHistEfficiency->GetGrid(step)->GetGrid()->Reset();