]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGJE/macros/PID/calcEfficiency.C
Merge branch 'feature-movesplit'
[u/mrichter/AliRoot.git] / PWGJE / macros / PID / calcEfficiency.C
CommitLineData
e131b05f 1#include "TH1D.h"
2#include "TH2D.h"
3#include "TCanvas.h"
4#include "TFile.h"
5#include "TGraphAsymmErrors.h"
6#include "TLegend.h"
7
8#include "AliCFContainer.h"
9#include "AliCFEffGrid.h"
10#include "AliCFDataGrid.h"
11#include "AliPID.h"
12
13#include <iostream>
14
15#include "THnSparseDefinitions.h"
16
17enum type { kTrackPt = 0, kZ = 1, kXi = 2, kNtypes = 3 };
18
19
20const Int_t nPtBinsType2 = 44;
21const Double_t binsPtType2[nPtBinsType2+1] = {0., 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45,
22 0.5, 0.55, 0.6, 0.65, 0.7, 0.8, 0.9, 1.0, 1.2, 1.4,
23 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.4, 3.8,
24 4.5, 5.5, 6.5, 8.0, 10.0, 12.0, 14.0, 16.0, 20.0, 24.0,
25 28.0, 32.0, 36.0, 45.0, 50.0 };
26
27
28//___________________________________________________________________
29const Double_t* GetBins(Int_t type, Int_t& nBins)
30{
31 if (type == 2) {
32 nBins = nPtBinsType2;
33
34 return binsPtType2;
35 }
36
37 return 0x0;
38}
39
40
41//___________________________________________________________________
42Double_t trackingPtGeantFlukaCorrectionPrMinus(Double_t pTmc)
43{
44 return (1. - 0.129758 * TMath::Exp(-pTmc * 0.679612));
45}
46
47
48//___________________________________________________________________
49Double_t trackingPtGeantFlukaCorrectionKaMinus(Double_t pTmc)
50{
51 return TMath::Min((0.972865 + 0.0117093 * pTmc), 1.);
52}
53
54
55//___________________________________________________________________
56Bool_t geantFlukaCorrection(AliCFContainer* data, Int_t genStepToDownscale)
57{
58 // Issue: GEANT/FLUKA correction factor is for MC_pT.
59 // Finally the effeciency should be DIVIDED by this correction factor.
60 // To include resolution effects, it is therefore the best way to just
61 // multiply the generated step with the correction factor.
62
63 if (!data) {
64 printf("No CFContainer for GEANT/FLUKA correction!\n");
65 return kFALSE;
66 }
67
68 const Int_t iPt = data->GetVar("P_{T} (GeV/c)");
69 const Int_t iMCid = data->GetVar("MC ID");
70 const Int_t iCharge = data->GetVar("Charge (e_{0})");
71
72 if (iPt < 0 || iMCid < 0 || iCharge < 0) {
73 printf("Data axis for GEANT/FLUKA correction not found!\n");
74 return kFALSE;
75 }
76
77 if (!data->GetGrid(genStepToDownscale)) {
78 printf("Step for downscaling (GEANT/FLUKA) not found!\n");
79 return kFALSE;
80 }
81
82 const Int_t nDim = data->GetNVar();
83 Int_t coord[nDim];
84 Double_t binCenterCoord[nDim];
85
86 Long64_t nBinsGrid = data->GetGrid(genStepToDownscale)->GetGrid()->GetNbins();
87
88 for (Long64_t iBin = 0; iBin < nBinsGrid; iBin++) {
89 Double_t binContent = data->GetGrid(genStepToDownscale)->GetGrid()->GetBinContent(iBin, coord);
90 Double_t binError = data->GetGrid(genStepToDownscale)->GetGrid()->GetBinError(iBin);
91
92 for (Int_t iDim = 0; iDim < nDim; iDim++)
93 binCenterCoord[iDim] = data->GetBinCenter(iDim, coord[iDim]);
94
95 if (binCenterCoord[iCharge] < 0) {
96 Double_t corrFactor = 1.;
97
98 if (binCenterCoord[iMCid] - 0.5 == AliPID::kProton)
99 corrFactor = trackingPtGeantFlukaCorrectionPrMinus(binCenterCoord[iPt]);
100 else if (binCenterCoord[iMCid] - 0.5 == AliPID::kKaon)
101 corrFactor = trackingPtGeantFlukaCorrectionKaMinus(binCenterCoord[iPt]);
102 else
103 continue;
104
105 data->GetGrid(genStepToDownscale)->GetGrid()->SetBinContent(iBin, binContent * corrFactor);
106 data->GetGrid(genStepToDownscale)->GetGrid()->SetBinError(iBin, binError * corrFactor);
107 }
108 }
109
110 return kTRUE;
111}
112
113
114
115//___________________________________________________________________
116void setupHist(TH1* h, TString histName, TString histTitle, TString xAxisTitle, TString yAxisTitle, Int_t color)
117{
118 if (histName != "")
119 h->SetName(histName.Data());
120 h->SetTitle(histTitle.Data());
121
122 if (xAxisTitle != "")
123 h->GetXaxis()->SetTitle(xAxisTitle.Data());
124 if (yAxisTitle != "")
125 h->GetYaxis()->SetTitle(yAxisTitle.Data());
126
127 h->SetMarkerStyle(24);
128 h->SetLineColor(color);
129 h->SetMarkerColor(color);
130
131 h->SetStats(kFALSE);
132}
133
134
135//____________________________________________________________________________________________________________________
136void undoJetNormalisationHist2D(TH2* hData, TH2* hNumJets, const Int_t lowerCentralityBinLimit, const Int_t upperCentralityBinLimit)
137{
138 // Undo normalisation to 1/numJets. NOTE: jetPt binning of hData and hNumJets assumed to be the same!
139
140 if (!hData || !hNumJets)
141 return;
142
143 for (Int_t binJetPt = 0; binJetPt <= hData->GetNbinsY() + 1; binJetPt++) {
144 const Double_t numJets = hNumJets->Integral(lowerCentralityBinLimit, upperCentralityBinLimit, binJetPt, binJetPt);
145 Bool_t noJets = numJets < 1e-13;
146
147 for (Int_t binObs = 0; binObs <= hData->GetNbinsX() + 1; binObs++) {
148 if (noJets)
149 continue;
150
151 hData->SetBinContent(binObs, binJetPt, hData->GetBinContent(binObs, binJetPt) * numJets);
152 hData->SetBinError(binObs, binJetPt, hData->GetBinError(binObs, binJetPt) * numJets);
153 }
154 }
155}
156
157
158//___________________________________________________________________
159void normaliseHist(TH1* h, Double_t scale = 1.0)
160{
161 if (h->GetSumw2N() <= 0)
162 h->Sumw2();
163
164 h->Scale(scale);
165
166 for (Int_t i = 1; i <= h->GetNbinsX(); i++) {
167 Double_t normFactor = h->GetBinWidth(i);
168 h->SetBinContent(i, h->GetBinContent(i) / normFactor);
169 h->SetBinError(i, h->GetBinError(i) / normFactor);
170 }
171}
172
173
174//___________________________________________________________________
175void multiplyHistsDifferentBinning(TH1* h1, const TH1* h2, Double_t c1, Double_t c2, Bool_t ignoreErrorOfSecondHist = kFALSE)
176{
177 Int_t nbinsx = h1->GetNbinsX();
178 Int_t nbinsy = h1->GetNbinsY();
179 Int_t nbinsz = h1->GetNbinsZ();
180
181 if (h1->GetDimension() < 2)
182 nbinsy -= 1;
183 if (h1->GetDimension() < 3)
184 nbinsz -= 1;
185
186 if (h1->GetSumw2N() == 0)
187 h1->Sumw2();
188
189 Int_t bin, bin2, binx, biny, binz;
190 Double_t b1,b2,w,d1,d2;
191 d1 = c1*c1;
192 d2 = c2*c2;
193
194 // Loop over bins (including underflows/overflows)
195 for (binz = 0; binz <= nbinsz + 1; binz++) {
196 for (biny = 0; biny <= nbinsy + 1; biny++) {
197 for (binx = 0; binx <= nbinsx + 1;binx++) {
198 bin = binx + (nbinsx + 2) * (biny + (nbinsy + 2) * binz);
199 bin2 = h2->FindFixBin(h1->GetXaxis()->GetBinCenter(binx), h1->GetYaxis()->GetBinCenter(biny),
200 h1->GetZaxis()->GetBinCenter(binz));
201 b1 = h1->GetBinContent(bin);
202 b2 = h2->GetBinContent(bin2);
203 w = (c1*b1)*(c2*b2);
204 h1->SetBinContent(bin, w);
205 Double_t e1 = h1->GetBinError(bin);
206 Double_t e2 = ignoreErrorOfSecondHist ? 0. : h2->GetBinError(bin2);
207 h1->SetBinError(bin, TMath::Sqrt(d1*d2*(e1*e1*b2*b2 + e2*e2*b1*b1)));
208 }
209 }
210 }
211}
212
213
214//___________________________________________________________________
215void divideHistsDifferentBinning(TH1* h1, const TH1* h2, Double_t c1, Double_t c2, Bool_t ignoreErrorOfSecondHist = kFALSE)
216{
217 Int_t nbinsx = h1->GetNbinsX();
218 Int_t nbinsy = h1->GetNbinsY();
219 Int_t nbinsz = h1->GetNbinsZ();
220
221 if (h1->GetDimension() < 2)
222 nbinsy -= 1;
223 if (h1->GetDimension() < 3)
224 nbinsz -= 1;
225
226 if (h1->GetSumw2N() == 0)
227 h1->Sumw2();
228
229 Int_t bin, bin2, binx, biny, binz;
230 Double_t b1,b2,w,d1,d2;
231 d1 = c1*c1;
232 d2 = c2*c2;
233
234 // Loop over bins (including underflows/overflows)
235 for (binz = 0; binz <= nbinsz + 1; binz++) {
236 for (biny = 0; biny <= nbinsy + 1; biny++) {
237 for (binx = 0; binx <= nbinsx + 1;binx++) {
238 bin = binx + (nbinsx + 2) * (biny + (nbinsy + 2) * binz);
239 bin2 = h2->FindFixBin(h1->GetXaxis()->GetBinCenter(binx), h1->GetYaxis()->GetBinCenter(biny),
240 h1->GetZaxis()->GetBinCenter(binz));
241 b1 = h1->GetBinContent(bin);
242 b2 = h2->GetBinContent(bin2);
243 if (b2)
244 w = (c1*b1)/(c2*b2);
245 else
246 w = 0;
247 h1->SetBinContent(bin, w);
248
249 if (!b2) {
250 h1->SetBinError(bin, 0);
251 continue;
252 }
253
254 Double_t b22 = b2*b2*d2;
255 Double_t e1 = h1->GetBinError(bin);
256 Double_t e2 = ignoreErrorOfSecondHist ? 0. : h2->GetBinError(bin2);
257 h1->SetBinError(bin, TMath::Sqrt(d1*d2*(e1*e1*b2*b2 + e2*e2*b1*b1)/(b22*b22)));
258 }
259 }
260 }
261}
262
263
264//___________________________________________________________________
265// Efficiency for inclusive spectra vs. pT (or also jets, but without using the generation)
266// E.g. a 'calcEfficiency.C+("finalCuts/MC_pp/7TeV/LHC10f6a/corrected/finalisedSplines/analytical/efficiency_noClCut_preliminary/bhess_PID_Jets_Inclusive_PureGauss_efficiency.root", "finalCuts/pp/7TeV/LHC10e.pass2/corrected/finalisedSplines/finalMapsAndTail/Jets/noCutOn_ncl_or_liav/outputSystematicsTotal_SummedSystematicErrors__2013_10_21.root", kTRUE, kFALSE, 0, -2, -2, -1, -1, 8, 2)' -b -q
267Int_t calcEfficiency(TString pathNameEfficiency, TString pathNameData, Bool_t correctGeantFluka, Bool_t scaleStrangeness,
268 Int_t chargeMode /*kNegCharge = -1, kAllCharged = 0, kPosCharge = 1*/,
269 Double_t lowerCentrality /*= -2*/, Double_t upperCentrality /*= -2*/,
270 Double_t lowerJetPt /*= -1*/ , Double_t upperJetPt/* = -1*/,
271 Double_t constantCorrectionAbovePtThreshold,
272 Int_t rebinEfficiency)
273{
274 TString pathData = pathNameData;
275 pathData.Replace(pathData.Last('/'), pathData.Length(), "");
276
277 TFile* fileEff = TFile::Open(pathNameEfficiency.Data());
278 if (!fileEff) {
279 printf("Failed to open efficiency file \"%s\"\n", pathNameEfficiency.Data());
280 return -1;
281 }
282
283 AliCFContainer* data = (AliCFContainer*)(fileEff->Get("containerEff"));
284 if (!data) {
285 printf("Failed to load efficiency container!\n");
286 return -1;
287 }
288
289 const Int_t iMCid = data->GetVar("MC ID");
290 const Int_t iPt = data->GetVar("P_{T} (GeV/c)");
291 const Int_t iEta = data->GetVar("#eta");
292 const Int_t iCharge = data->GetVar("Charge (e_{0})");
293 const Int_t iMult = data->GetVar("Centrality Percentile");
294 const Int_t iJetPt = data->GetVar("P_{T}^{jet} (GeV/c)");
295 //const Int_t iZ = data->GetVar("z = P_{T}^{track} / P_{T}^{jet}");
296 //const Int_t iXi = data->GetVar("#xi = ln(P_{T}^{jet} / P_{T}^{track})");
297
298 TFile* fileData = TFile::Open(pathNameData.Data());
299 if (!fileData) {
300 printf("Failed to open data file \"%s\"\n", pathNameData.Data());
301 return -1;
302 }
303
304 TH1D* hYield[AliPID::kSPECIES] = { 0x0, };
305 TH1D* hYieldSysError[AliPID::kSPECIES] = { 0x0, };
306 TGraphAsymmErrors* gYieldSysError[AliPID::kSPECIES] = { 0x0, };
307 TH1D* hMCgenPrimYield[AliPID::kSPECIES] = { 0x0, };
308 Int_t numMCgenPrimYieldHistsFound = 0;
309
310 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
311 TString speciesName = AliPID::ParticleName(species);
312 TString firstLetter = speciesName(0);
313 firstLetter.ToUpper();
314 speciesName.Replace(0, 1, firstLetter.Data());
315 TString histName = Form("hYield%ss", speciesName.Data());
316 hYield[species] = (TH1D*)fileData->Get(histName.Data());
317 if (!hYield[species]) {
318 printf("Failed to load hist \"%s\"\n", histName.Data());
319 return -1;
320 }
321 hYield[species]->SetFillStyle(0);
322
323 TString graphName = Form("systematicErrorYields_%s", AliPID::ParticleName(species));
324 gYieldSysError[species] = (TGraphAsymmErrors*)fileData->Get(graphName.Data());
325
326 // In case of MC also retrieve the MC truth generated yields
327 TString histNameMCgenYields = Form("hMCgenYieldsPrimSpecies_%s", AliPID::ParticleShortName(species));
328 hMCgenPrimYield[species] = (TH1D*)fileData->Get(histNameMCgenYields.Data());
329 if (hMCgenPrimYield[species])
330 numMCgenPrimYieldHistsFound++;
331 }
332
333 if (numMCgenPrimYieldHistsFound > 0 && numMCgenPrimYieldHistsFound != AliPID::kSPECIES) {
334 printf("Error: Unable to retrieve all MC generated prim yield histos! Got %d.\n", numMCgenPrimYieldHistsFound);
335 return -1;
336 }
337
338 TCanvas* cFractions = (TCanvas*)fileData->Get("cFractionsWithTotalSystematicError");
339 if (!cFractions)
340 cFractions = (TCanvas*)fileData->Get("cFractions");
341
342
343 // Convert graphs with systematic errors into histograms (assume symmetric error, which is currently true)
344 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
345 if (gYieldSysError[species]) {
346 hYieldSysError[species] = new TH1D(*hYield[species]);
347 hYieldSysError[species]->SetName(Form("%s_sysError", hYieldSysError[species]->GetName()));
348 hYieldSysError[species]->SetFillStyle(0);
349
350 for (Int_t binX = 1; binX <= hYieldSysError[species]->GetNbinsX(); binX++) {
351 hYieldSysError[species]->SetBinContent(binX, gYieldSysError[species]->GetY()[binX - 1]);
352 hYieldSysError[species]->SetBinError(binX, gYieldSysError[species]->GetErrorY(binX - 1));
353 }
354 }
355 }
356
357 // Take pT binning from pion yield (binning for all species the same) and create a new AliCFContainer with this new binning for pT
358 TH1D hDummy(*hYield[AliPID::kPion]);
359 hDummy.SetName("hDummy");
360 TAxis* axis = 0x0;
361
362 if (rebinEfficiency > 1) {
363 Int_t nBinsNew = 0;
364 const Double_t* newBins = GetBins(rebinEfficiency, nBinsNew);
365
366 hDummy.SetBins(nBinsNew, newBins);
367
368 axis = hDummy.GetXaxis();
369
370 //axis = hDummy.Rebin(rebinEfficiency, "", 0)->GetXaxis();
371 }
372 else
373 axis = hDummy.GetXaxis();
374
375 const TArrayD* binsPtCurrent = axis->GetXbins();
376 TArrayD* binsPtNew = new TArrayD(*binsPtCurrent);
377
378 const Int_t nEffDims = data->GetNVar();
379 Int_t nEffBins[nEffDims];
380
381 for (Int_t iDim = 0; iDim < nEffDims; iDim++) {
382 if (iDim == iPt)
383 nEffBins[iDim] = axis->GetNbins();
384 else
385 nEffBins[iDim] = data->GetNBins(iDim);
386 }
387
388
389 // Just make one large pT bin above some threshold, if desired
390 if (binsPtNew->fN != 0 && constantCorrectionAbovePtThreshold > 0) {
391 for (Int_t iBin = 0; iBin < nEffBins[iPt]; iBin++) {
392 // Find the first bin edged really larger than the threshold.
393 // If the bin edge before equals the threshold, just set the
394 // current bin edge to the right end of the spectrum -> Done.
395 // If the bin edge before is different, set the bin edge to the
396 // threshold
397 if (binsPtNew->fArray[iBin] > constantCorrectionAbovePtThreshold) {
398 if (binsPtNew->fArray[iBin - 1] == constantCorrectionAbovePtThreshold) {
399 binsPtNew->fArray[iBin] = binsPtNew->fArray[nEffBins[iPt]];
400 nEffBins[iPt] = iBin;
401 break;
402 }
403 else {
404 binsPtNew->fArray[iBin] = constantCorrectionAbovePtThreshold;
405 }
406 }
407 }
408 }
409
410
411 AliCFContainer *dataRebinned = new AliCFContainer(Form("%s_rebinned", data->GetName()), Form("%s (rebinned)", data->GetTitle()),
412 data->GetNStep(), nEffDims, nEffBins);
413
414 for (Int_t iDim = 0; iDim < nEffDims; iDim++) {
415 dataRebinned->SetVarTitle(iDim, data->GetVarTitle(iDim));
416
417 if (iDim == iPt) {
418 if (binsPtNew->fN == 0)
419 dataRebinned->SetBinLimits(iDim, axis->GetXmin(), axis->GetXmax());
420 else
421 dataRebinned->SetBinLimits(iDim, binsPtNew->fArray);
422 }
423 else {
424 dataRebinned->SetBinLimits(iDim, data->GetBinLimits(iDim));
425 }
426 }
427
428 for (Int_t iStep = 0; iStep < data->GetNStep(); iStep++)
429 dataRebinned->SetStepTitle(iStep, data->GetStepTitle(iStep));
430
431 Int_t coord[nEffDims];
432 Double_t binCenterCoord[nEffDims];
433
434 // Fill content from old grid into the new grid with proper binning
435 for (Int_t iStep = 0; iStep < data->GetNStep(); iStep++) {
436 Long64_t nBinsGrid = data->GetGrid(iStep)->GetGrid()->GetNbins();
437
438 for (Long64_t iBin = 0; iBin < nBinsGrid; iBin++) {
439 Double_t binContent = data->GetGrid(iStep)->GetGrid()->GetBinContent(iBin, coord);
440 Double_t binError2 = data->GetGrid(iStep)->GetGrid()->GetBinError2(iBin);
441
442 for (Int_t iDim = 0; iDim < nEffDims; iDim++) {
443 binCenterCoord[iDim] = data->GetBinCenter(iDim, coord[iDim]);
444 }
445
446 Long64_t iBinRebinned = dataRebinned->GetGrid(iStep)->GetGrid()->GetBin(binCenterCoord);
447 dataRebinned->GetGrid(iStep)->GetGrid()->AddBinContent(iBinRebinned, binContent);
448 dataRebinned->GetGrid(iStep)->GetGrid()->AddBinError2(iBinRebinned, binError2);
449 }
450 }
451
452
453 // If desired, restrict centrality axis
454 Int_t lowerCentralityBinLimit = -1;
455 Int_t upperCentralityBinLimit = -2; // Integral(lowerCentBinLimit, uppCentBinLimit) will not be restricted if these values are kept
456 Bool_t restrictCentralityAxis = kFALSE;
457 Double_t actualLowerCentrality = -1.;
458 Double_t actualUpperCentrality = -1.;
459
460 if (lowerCentrality >= -1 && upperCentrality >= -1) {
461 // Add subtract a very small number to avoid problems with values right on the border between to bins
462 lowerCentralityBinLimit = dataRebinned->GetAxis(iMult, 0)->FindBin(lowerCentrality + 0.001);
463 upperCentralityBinLimit = dataRebinned->GetAxis(iMult, 0)->FindBin(upperCentrality - 0.001);
464
465 // Check if the values look reasonable
466 if (lowerCentralityBinLimit <= upperCentralityBinLimit && lowerCentralityBinLimit >= 1
467 && upperCentralityBinLimit <= dataRebinned->GetAxis(iMult, 0)->GetNbins()) {
468 actualLowerCentrality = dataRebinned->GetAxis(iMult, 0)->GetBinLowEdge(lowerCentralityBinLimit);
469 actualUpperCentrality = dataRebinned->GetAxis(iMult, 0)->GetBinUpEdge(upperCentralityBinLimit);
470
471 restrictCentralityAxis = kTRUE;
472 }
473 else {
474 std::cout << std::endl;
475 std::cout << "Requested centrality range out of limits or upper and lower limit are switched!" << std::endl;
476 return -1;
477 }
478 }
479
480 std::cout << "centrality: ";
481 if (restrictCentralityAxis) {
482 std::cout << actualLowerCentrality << " - " << actualUpperCentrality << std::endl;
483 dataRebinned->SetRangeUser(iMult, lowerCentralityBinLimit, upperCentralityBinLimit, kTRUE);
484 }
485 else {
486 std::cout << "All" << std::endl;
487 }
488
489
490
491 // If desired, restrict jetPt axis
492 Int_t lowerJetPtBinLimit = -1;
493 Int_t upperJetPtBinLimit = -1;
494 Bool_t restrictJetPtAxis = kFALSE;
495 Double_t actualLowerJetPt = -1.;
496 Double_t actualUpperJetPt = -1.;
497
498 if (lowerJetPt >= 0 && upperJetPt >= 0) {
499 // Add subtract a very small number to avoid problems with values right on the border between to bins
500 lowerJetPtBinLimit = dataRebinned->GetAxis(iJetPt, 0)->FindBin(lowerJetPt + 0.001);
501 upperJetPtBinLimit = dataRebinned->GetAxis(iJetPt, 0)->FindBin(upperJetPt - 0.001);
502
503 // Check if the values look reasonable
504 if (lowerJetPtBinLimit <= upperJetPtBinLimit && lowerJetPtBinLimit >= 1 &&
505 upperJetPtBinLimit <= dataRebinned->GetAxis(iJetPt, 0)->GetNbins()) {
506 actualLowerJetPt = dataRebinned->GetAxis(iJetPt, 0)->GetBinLowEdge(lowerJetPtBinLimit);
507 actualUpperJetPt = dataRebinned->GetAxis(iJetPt, 0)->GetBinUpEdge(upperJetPtBinLimit);
508
509 restrictJetPtAxis = kTRUE;
510 }
511 else {
512 std::cout << std::endl;
513 std::cout << "Requested jet pT range out of limits or upper and lower limit are switched!" << std::endl;
514 return -1;
515 }
516 }
517
518 std::cout << "jet pT: ";
519 if (restrictJetPtAxis) {
520 std::cout << actualLowerJetPt << " - " << actualUpperJetPt << std::endl;
521 dataRebinned->SetRangeUser(iJetPt, lowerJetPtBinLimit, upperJetPtBinLimit, kTRUE);
522 }
523 else {
524 std::cout << "All" << std::endl;
525 }
526
527 // If desired, restrict charge axis
528 std::cout << "Charge selection (efficiency): ";
529 if (chargeMode == kAllCharged)
530 std::cout << "All charged particles" << std::endl;
531 else if (chargeMode == kNegCharge)
532 std::cout << "Negative particles only" << std::endl;
533 else if (chargeMode == kPosCharge)
534 std::cout << "Positive particles only" << std::endl;
535 else {
536 std::cout << "Unknown -> ERROR" << std::endl;
537 return -1;
538 }
539
540 const Bool_t restrictCharge = (chargeMode != kAllCharged);
541
542 Int_t lowerChargeBinLimit = -1;
543 Int_t upperChargeBinLimit = -2;
544 Double_t actualLowerCharge = -999;
545 Double_t actualUpperCharge = -999;
546
547 if (restrictCharge) {
548 // Add subtract a very small number to avoid problems with values right on the border between to bins
549 if (chargeMode == kNegCharge) {
550 lowerChargeBinLimit = dataRebinned->GetAxis(iCharge, 0)->FindBin(-1. + 0.001);
551 upperChargeBinLimit = dataRebinned->GetAxis(iCharge, 0)->FindBin(0. - 0.001);
552 }
553 else if (chargeMode == kPosCharge) {
554 lowerChargeBinLimit = dataRebinned->GetAxis(iCharge, 0)->FindBin(0. + 0.001);
555 upperChargeBinLimit = dataRebinned->GetAxis(iCharge, 0)->FindBin(1. - 0.001);
556 }
557
558 // Check if the values look reasonable
559 if (lowerChargeBinLimit <= upperChargeBinLimit && lowerChargeBinLimit >= 1
560 && upperChargeBinLimit <= dataRebinned->GetAxis(iCharge, 0)->GetNbins()) {
561 actualLowerCharge = dataRebinned->GetAxis(iCharge, 0)->GetBinLowEdge(lowerChargeBinLimit);
562 actualUpperCharge = dataRebinned->GetAxis(iCharge, 0)->GetBinUpEdge(upperChargeBinLimit);
563
564 std::cout << "Charge range (efficiency): " << actualLowerCharge << " - " << actualUpperCharge << std::endl;
565 }
566 else {
567 std::cout << std::endl;
568 std::cout << "Requested charge range (efficiency) out of limits or upper and lower limit are switched!" << std::endl;
569 return -1;
570 }
571
572 dataRebinned->SetRangeUser(iCharge, lowerChargeBinLimit, upperChargeBinLimit, kTRUE);
573 data->SetRangeUser(iCharge, lowerChargeBinLimit, upperChargeBinLimit, kTRUE);
574 }
575
576 std::cout << std::endl;
577
578
579 // If jet axis is restricted (i.e. jet input), also need num jet histos for proper normalisation.
580 // Load numJet histos from bhess_PID*.root file related to efficiency file.
581 TH2D* hNjetsGen = 0x0;
582 TH2D* hNjetsRec = 0x0;
583
584 if (restrictJetPtAxis) {
585 TString pathNameDataMC = pathNameEfficiency;
586 pathNameDataMC.ReplaceAll("_efficiency", "");
587
588 TFile* fDataMC = TFile::Open(pathNameDataMC.Data());
589 if (!fDataMC) {
590 std::cout << std::endl;
591 std::cout << "Failed to open file \"" << pathNameData.Data() << "\" to obtain num of rec/gen jets!" << std::endl;
592
593 return -1;
594 }
595
596 TString listName = pathNameDataMC;
597 listName.Replace(0, listName.Last('/') + 1, "");
598 listName.ReplaceAll(".root", "");
599
600 TObjArray* histList = (TObjArray*)(fDataMC->Get(listName.Data()));
601 if (!histList) {
602 std::cout << std::endl;
603 std::cout << "Failed to load list \"" << listName.Data() << "\" to obtain num of rec/gen jets!" << std::endl;
604 return -1;
605 }
606
607 hNjetsGen = (TH2D*)histList->FindObject("fh2FFJetPtGen");
608 hNjetsRec = (TH2D*)histList->FindObject("fh2FFJetPtRec");
609
610 if (!hNjetsRec || !hNjetsGen) {
611 std::cout << "Failed to load number of jets histos!" << std::endl;
612
613
614 // For backward compatibility (TODO REMOVE IN FUTURE): Load info from fixed AnalysisResults file (might be wrong, if other
615 // period is considered; also: No multiplicity information)
616 TString pathEfficiency = pathNameEfficiency;
617 pathEfficiency.Replace(pathEfficiency.Last('/'), pathEfficiency.Length(), "");
618 TString pathBackward = Form("%s/AnalysisResults.root", pathEfficiency.Data());
619 TFile* fBackward = TFile::Open(pathBackward.Data());
620
621 TString dirDataInFile = "";
622 TDirectory* dirData = fBackward ? (TDirectory*)fBackward->Get(fBackward->GetListOfKeys()->At(0)->GetName()) : 0x0;
623
624 TList* list = dirData ? (TList*)dirData->Get(dirData->GetListOfKeys()->At(0)->GetName()) : 0x0;
625
626 TH1D* hFFJetPtRec = list ? (TH1D*)list->FindObject("fh1FFJetPtRecCuts") : 0x0;
627 TH1D* hFFJetPtGen = list ? (TH1D*)list->FindObject("fh1FFJetPtGen") : 0x0;
628
629 if (hFFJetPtRec && hFFJetPtGen) {
630 printf("***WARNING: For backward compatibility, using file \"%s\" to get number of jets. BUT: Might be wrong period and has no mult info!***\n",
631 pathBackward.Data());
632
633 hNjetsRec = new TH2D("fh2FFJetPtRec", "", 1, -1, 1, dataRebinned->GetAxis(iJetPt, 0)->GetNbins(),
634 dataRebinned->GetAxis(iJetPt, 0)->GetXbins()->GetArray());
635
636 for (Int_t iJet = 1; iJet <= hNjetsRec->GetNbinsY(); iJet++) {
637 Int_t lowerBin = hFFJetPtRec->FindBin(hNjetsRec->GetYaxis()->GetBinLowEdge(iJet) + 1e-3);
638 Int_t upperBin = hFFJetPtRec->FindBin(hNjetsRec->GetYaxis()->GetBinUpEdge(iJet) - 1e-3);
639 hNjetsRec->SetBinContent(1, iJet, hFFJetPtRec->Integral(lowerBin, upperBin));
640 }
641
642 hNjetsGen = new TH2D("fh2FFJetPtGen", "", 1, -1, 1, dataRebinned->GetAxis(iJetPt, 0)->GetNbins(),
643 dataRebinned->GetAxis(iJetPt, 0)->GetXbins()->GetArray());
644
645 for (Int_t iJet = 1; iJet <= hNjetsGen->GetNbinsY(); iJet++) {
646 Int_t lowerBin = hFFJetPtGen->FindBin(hNjetsGen->GetYaxis()->GetBinLowEdge(iJet) + 1e-3);
647 Int_t upperBin = hFFJetPtGen->FindBin(hNjetsGen->GetYaxis()->GetBinUpEdge(iJet) - 1e-3);
648 hNjetsGen->SetBinContent(1, iJet, hFFJetPtGen->Integral(lowerBin, upperBin));
649 }
650 }
651
652 if (!hNjetsRec || ! hNjetsGen)
653 return -1;
654 }
655 }
656
657 // For normalisation to number of jets
658 // NOTE: These numbers are for the efficiency only! The data will be normalised to its own number!!!
659 const Double_t nJetsGen = hNjetsGen ? hNjetsGen->Integral(lowerCentralityBinLimit, upperCentralityBinLimit, lowerJetPtBinLimit,
660 upperJetPtBinLimit) : 1.;
661 const Double_t nJetsRec = hNjetsRec ? hNjetsRec->Integral(lowerCentralityBinLimit, upperCentralityBinLimit, lowerJetPtBinLimit,
662 upperJetPtBinLimit) : 1.;
663
664 // Secondary correction
665 AliCFEffGrid* sec = new AliCFEffGrid("sec", "Secondary Contamination", *dataRebinned);
666 AliCFEffGrid* secStrangeScale = new AliCFEffGrid("secStrangeScale", "Secondary Contamination with Strangeness Scaling",
667 *dataRebinned);
668
669 // Either one can take kStepRecWithGenCutsMeasuredObs or, what I prefer, one can take
670 // kStepRecWithRecCutsMeasuredObsPrimaries => The difference is only the eta cut, which is on the rec level
671 // in the latter case, i.e. one corrects for eta resolution (although the effect should be very small)
672 // => TESTED: There is NO difference (only 1 bin vs. pt shows a deviation by one entry), so this cut has,
673 // in principle, more or less no effect
674
675 // For testing with data set w/o strangeness secStrangeScale->CalculateEfficiency(kStepRecWithRecCutsMeasuredObsPrimaries, kStepRecWithRecCutsMeasuredObs);
676 secStrangeScale->CalculateEfficiency(kStepRecWithRecCutsMeasuredObsPrimaries, kStepRecWithRecCutsMeasuredObsStrangenessScaled);
677 sec->CalculateEfficiency(kStepRecWithRecCutsMeasuredObsPrimaries, kStepRecWithRecCutsMeasuredObs);
678
679 // QA plots for secondaries
680 TCanvas* cSec = new TCanvas("cSec", "Secondary Contamination", 100, 10, 1200, 800);
681 cSec->Divide(2, 1);
682 cSec->GetPad(1)->SetLogx(kTRUE);
683 cSec->cd(1);
684 TH1* hSecPt = sec->Project(iPt);
685 hSecPt->SetName("hSecPt");
686 hSecPt->SetStats(kFALSE);
687 hSecPt->GetXaxis()->SetRangeUser(0.15, 50.);
688 hSecPt->GetXaxis()->SetMoreLogLabels(kTRUE);
689 hSecPt->GetXaxis()->SetNoExponent(kTRUE);
690 hSecPt->GetYaxis()->SetTitle("Primary Fraction");
691 hSecPt->Draw("E1");
692 cSec->cd(2);
693 TH1* hEtaSec = sec->Project(iEta);
694 hEtaSec->SetName("hEtaSec");
695 hEtaSec->SetStats(kFALSE);
696 hEtaSec->GetYaxis()->SetTitle("Primary Fraction");
697 hEtaSec->Draw("E1");
698 TH2D* hSecID2Pt = (TH2D*)sec->Project(iPt, iMCid);
699 hSecID2Pt->SetName("hSecID2Pt");
700
701 // Get the secondary contamination vs. pT for each species
702 TH1D* hSec[AliPID::kSPECIES];
703 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
704 hSec[species] = hSecID2Pt->ProjectionX(Form("hSec_%s", AliPID::ParticleShortName(species)), species + 1, species + 1, "e");
705 hSec[species]->SetTitle(Form("%s", AliPID::ParticleLatexName(species)));
706 hSec[species]->SetLineColor(hYield[species]->GetLineColor());
707 hSec[species]->SetMarkerColor(hYield[species]->GetLineColor());
708 hSec[species]->SetLineWidth(2.);
709 hSec[species]->GetXaxis()->SetRangeUser(0.15, 50);
710 hSec[species]->GetYaxis()->SetRangeUser(0., 1.01);
711 hSec[species]->GetXaxis()->SetMoreLogLabels(kTRUE);
712 hSec[species]->GetXaxis()->SetNoExponent(kTRUE);
713 hSec[species]->SetStats(kFALSE);
714 hSec[species]->GetYaxis()->SetTitle("Primary Fraction");
715 }
716
717 TCanvas* cSec2 = new TCanvas("cSec2", "Primary fraction for different species", 100, 10, 1200, 800);
718 cSec2->SetGridx(1);
719 cSec2->SetGridy(1);
720 cSec2->SetLogx(1);
721
722 hSec[0]->Draw("E1");
723
724 for (Int_t i = 1; i < AliPID::kSPECIES; i++) {
725 hSec[i]->Draw("E1 same");
726 }
727 cSec2->BuildLegend()->SetFillColor(kWhite);
728
729 ClearTitleFromHistoInCanvas(cSec2);
730
731 // QA plots for secondaries with strangeness scaling
732 TCanvas* cSecSS = new TCanvas("cSecSS", "Secondary Contamination (strangeness scaled)", 100, 10, 1200, 800);
733 cSecSS->Divide(2, 1);
734 cSecSS->GetPad(1)->SetLogx(kTRUE);
735 cSecSS->cd(1);
736 TH1* hSecSSPt = secStrangeScale->Project(iPt);
737 hSecSSPt->SetName("hSecSSPt");
738 hSecSSPt->SetStats(kFALSE);
739 hSecSSPt->GetXaxis()->SetRangeUser(0.15, 50.);
740 hSecSSPt->GetXaxis()->SetMoreLogLabels(kTRUE);
741 hSecSSPt->GetXaxis()->SetNoExponent(kTRUE);
742 hSecSSPt->GetYaxis()->SetTitle("Primary Fraction");
743 hSecSSPt->Draw("E1");
744 cSecSS->cd(2);
745 TH1* hEtaSecSS = secStrangeScale->Project(iEta);
746 hEtaSecSS->SetName("hEtaSecSS");
747 hEtaSecSS->SetStats(kFALSE);
748 hEtaSecSS->GetYaxis()->SetTitle("Primary Fraction");
749 hEtaSecSS->Draw("E1");
750 TH2D* hSecSSID2Pt = (TH2D*)secStrangeScale->Project(iPt, iMCid);
751 hSecSSID2Pt->SetName("hSecSSID2Pt");
752
753 // Get the secondary contamination vs. pT for each species
754 TH1D* hSecSS[AliPID::kSPECIES];
755 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
756 hSecSS[species] = hSecSSID2Pt->ProjectionX(Form("hSecSS_%s", AliPID::ParticleShortName(species)), species + 1, species + 1, "e");
757 hSecSS[species]->SetTitle(Form("%s", AliPID::ParticleLatexName(species)));
758 hSecSS[species]->SetLineColor(hYield[species]->GetLineColor());
759 hSecSS[species]->SetMarkerColor(hYield[species]->GetLineColor());
760 hSecSS[species]->SetLineWidth(2.);
761 hSecSS[species]->GetXaxis()->SetRangeUser(0.15, 50);
762 hSecSS[species]->GetYaxis()->SetRangeUser(0., 1.01);
763 hSecSS[species]->GetXaxis()->SetMoreLogLabels(kTRUE);
764 hSecSS[species]->GetXaxis()->SetNoExponent(kTRUE);
765 hSecSS[species]->SetStats(kFALSE);
766 hSecSS[species]->GetYaxis()->SetTitle("Primary Fraction");
767 }
768
769 TCanvas* cSecSS2 = new TCanvas("cSecSS2", "Primary fraction for different species (strangeness scaled)", 100, 10, 1200, 800);
770 cSecSS2->SetGridx(1);
771 cSecSS2->SetGridy(1);
772 cSecSS2->SetLogx(1);
773
774 hSecSS[0]->Draw("E1");
775
776 for (Int_t i = 1; i < AliPID::kSPECIES; i++) {
777 hSecSS[i]->Draw("E1 same");
778 }
779 cSecSS2->BuildLegend()->SetFillColor(kWhite);
780
781 ClearTitleFromHistoInCanvas(cSecSS2);
782
783
784 // Secondary correction for to-pi-ratios
785 TH1D* hSecToPiRatio[AliPID::kSPECIES] = { 0x0, };
786 TH1D* hSecSSToPiRatio[AliPID::kSPECIES] = { 0x0, };
787
788 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
789 if (species == AliPID::kPion)
790 continue; // Do not consider pion-to-pion ratio
791
792 hSecToPiRatio[species] = new TH1D(*hSec[species]);
793 hSecToPiRatio[species]->Reset();
794 hSecToPiRatio[species]->SetName(Form("hSecSSToPionRatio_%s", AliPID::ParticleShortName(species)));
795 hSecToPiRatio[species]->SetTitle(Form("%s/#pi", AliPID::ParticleLatexName(species)));
796 hSecToPiRatio[species]->SetLineColor(getLineColorAliPID(species));
797 hSecToPiRatio[species]->SetMarkerColor(getLineColorAliPID(species));
798 hSecToPiRatio[species]->SetMarkerStyle(24);
799 hSecToPiRatio[species]->SetLineWidth(2.);
800 hSecToPiRatio[species]->SetStats(kFALSE);
801 hSecToPiRatio[species]->GetYaxis()->SetTitle("Primary Fraction of Ratio");
802
803 hSecSSToPiRatio[species] = new TH1D(*hSecToPiRatio[species]);
804 hSecSSToPiRatio[species]->SetName(Form("hSecSSToPionRatio_%s", AliPID::ParticleShortName(species)));
805
806 // Samples for different species are independent, so just divide correction factors
807 hSecToPiRatio[species]->Divide(hSec[species], hSec[AliPID::kPion], 1., 1., "");
808 hSecToPiRatio[species]->GetYaxis()->SetRangeUser(0., 1.1);
809
810 hSecSSToPiRatio[species]->Divide(hSecSS[species], hSecSS[AliPID::kPion], 1., 1., "");
811 hSecSSToPiRatio[species]->GetYaxis()->SetRangeUser(0., 1.1);
812 }
813
814 TCanvas* cSecToPiRatio = new TCanvas("cSecToPiRatio", "Primary fraction of to-#pi-ratio for different species", 100, 10, 1200, 800);
815 cSecToPiRatio->SetGridx(1);
816 cSecToPiRatio->SetGridy(1);
817 cSecToPiRatio->SetLogx(1);
818
819 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
820 if (i == AliPID::kPion)
821 continue;
822
823 hSecToPiRatio[i]->Draw(Form("E1%s", i == 0 ? "" : " same"));
824 }
825
826 cSecToPiRatio->BuildLegend()->SetFillColor(kWhite);
827
828 ClearTitleFromHistoInCanvas(cSecToPiRatio);
829
830
831
832 TCanvas* cSecSSToPiRatio = new TCanvas("cSecSSToPiRatio",
833 "Primary fraction of to-#pi-ratio for different species (strangeness scaled)",
834 100, 10, 1200, 800);
835 cSecSSToPiRatio->SetGridx(1);
836 cSecSSToPiRatio->SetGridy(1);
837 cSecSSToPiRatio->SetLogx(1);
838
839 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
840 if (i == AliPID::kPion)
841 continue;
842
843 hSecSSToPiRatio[i]->Draw(Form("E1%s", i == 0 ? "" : " same"));
844 }
845
846 cSecSSToPiRatio->BuildLegend()->SetFillColor(kWhite);
847
848 ClearTitleFromHistoInCanvas(cSecSSToPiRatio);
849
850
851
852
853 // If desired, apply the GEANT/FLUKA correction first
854 // NOTE: This will change dataRebinned! If anything else should also be calculated, it must be done before.
855 // Otherwise, the GEANT/FLUKA correction factor for the efficiency will also affect it!
856 const Int_t genStepEff = kStepGenWithGenCuts;
857 if (correctGeantFluka) {
858 printf("Applying GEANT/FLUKA correction...\n");
859 if (!geantFlukaCorrection(dataRebinned, genStepEff)) {
860 printf("GEANT/FLUKA correction could not be applied!\n");
861 return kFALSE;
862 }
863 }
864
865 // Construct the efficiency grid from the data container
866 AliCFEffGrid* eff = new AliCFEffGrid("eff", "Efficiency x Acceptance x pT Resolution", *dataRebinned);
867
868 // Either one can take kStepRecWithGenCutsMeasuredObs or, what I prefer, one can take
869 // kStepRecWithRecCutsMeasuredObsPrimaries => The difference is only the eta cut, which is on the rec level
870 // in the latter case, i.e. one corrects for eta resolution (although the effect should be very small)
871 eff->CalculateEfficiency(kStepRecWithRecCutsMeasuredObsPrimaries, genStepEff);
872
873 // If the jet axis is restricted (i.e. jet input), scale with the corresponding number of jets.
874 // Note: Since this is supposed to be a real scaling, set the error of the scale factor to zero
875 // (second element of factor array)
876 if (restrictJetPtAxis) {
877 Double_t factor_Numerator[2] = { nJetsRec > 0 ? 1. / nJetsRec : 0., 0. };
878 Double_t factor_Denominator[2] = { nJetsGen > 0 ? 1. / nJetsGen : 0., 0. };
879 eff->GetNum()->Scale(factor_Numerator);
880 eff->GetDen()->Scale(factor_Denominator);
881 }
882
883 //The efficiency along pt and vertex, and 2-D projection
884 TCanvas* cEff = new TCanvas("cEff", "Efficiency x Acceptance x pT Resolution", 100, 10, 1200, 800);
885 cEff->Divide(2, 1);
886 cEff->GetPad(1)->SetLogx(kTRUE);
887 cEff->cd(1);
888 TH1* hEffPt = eff->Project(iPt); //the efficiency vs pt
889 hEffPt->SetStats(kFALSE);
890 hEffPt->GetXaxis()->SetRangeUser(0.15, 50.);
891 hEffPt->GetXaxis()->SetMoreLogLabels(kTRUE);
892 hEffPt->GetXaxis()->SetNoExponent(kTRUE);
893 hEffPt->GetYaxis()->SetTitle("Efficiency x Acceptance x pT Resolution");
894 hEffPt->Draw("E1");
895 cEff->cd(2);
896 TH1* hEffEta = eff->Project(iEta); //the efficiency vs eta
897 hEffEta->SetStats(kFALSE);
898 hEffEta->GetYaxis()->SetTitle("Efficiency x Acceptance x pT Resolution");
899 hEffEta->GetYaxis()->SetTitleSize(0.05);
900 hEffEta->Draw("E1");
901 TH2D* hEffID2Pt = (TH2D*)eff->Project(iPt, iMCid);
902
903 // Get the efficiencies vs. pT for each species
904 TH1D* hEfficiency[AliPID::kSPECIES];
905 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
906 hEfficiency[species] = hEffID2Pt->ProjectionX(Form("hEfficiency_%s", AliPID::ParticleShortName(species)), species + 1, species + 1, "e");
907 hEfficiency[species]->SetTitle(Form("%s", AliPID::ParticleLatexName(species)));
908 hEfficiency[species]->SetLineColor(hYield[species]->GetLineColor());
909 hEfficiency[species]->SetMarkerColor(hYield[species]->GetLineColor());
910 hEfficiency[species]->SetLineWidth(2.);
911 hEfficiency[species]->GetXaxis()->SetRangeUser(0.15, 50);
912 hEfficiency[species]->GetYaxis()->SetRangeUser(0., 1.01);
913 hEfficiency[species]->GetXaxis()->SetMoreLogLabels(kTRUE);
914 hEfficiency[species]->GetXaxis()->SetNoExponent(kTRUE);
915 hEfficiency[species]->SetStats(kFALSE);
916 hEfficiency[species]->GetYaxis()->SetTitle("Efficiency x Acceptance x pT Resolution");
917 hEfficiency[species]->GetYaxis()->SetTitleSize(0.05);
918 }
919
920 TCanvas* cEff2 = new TCanvas("cEff2", "Efficiency x Acceptance x pT Resolution for different species", 0, 300, 900, 900);
921 cEff2->SetGridx(1);
922 cEff2->SetGridy(1);
923 cEff2->SetLogx(1);
924
925 hEfficiency[0]->Draw("E1");
926
927 for (Int_t i = 1; i < AliPID::kSPECIES; i++) {
928 hEfficiency[i]->Draw("E1 same");
929 }
930 cEff2->BuildLegend()->SetFillColor(kWhite);
931
932 ClearTitleFromHistoInCanvas(cEff2);
933
934
935
936
937 // Efficiency correction for to-pi-ratios
938 TH1D* hEfficiencyToPiRatio[AliPID::kSPECIES] = { 0x0, };
939
940 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
941 if (species == AliPID::kPion)
942 continue; // Do not consider pion-to-pion ratio
943
944 hEfficiencyToPiRatio[species] = new TH1D(*hEfficiency[species]);
945 hEfficiencyToPiRatio[species]->Reset();
946 hEfficiencyToPiRatio[species]->SetName(Form("hEfficiencyToPionRatio_%s", AliPID::ParticleShortName(species)));
947 hEfficiencyToPiRatio[species]->SetTitle(Form("%s/#pi", AliPID::ParticleLatexName(species)));
948
949 // Samples for different species are independent, so just divide correction factors
950 hEfficiencyToPiRatio[species]->Divide(hEfficiency[species], hEfficiency[AliPID::kPion], 1., 1., "");
951 hEfficiencyToPiRatio[species]->GetYaxis()->SetRangeUser(0., 2.0);
952 }
953
954 TCanvas* cEffToPiRatio = new TCanvas("cEffToPiRatio", "Efficiency x Acceptance x pT Resolution of to-#pi-ratio for different species",
955 100, 10, 1200, 800);
956 cEffToPiRatio->SetGridx(1);
957 cEffToPiRatio->SetGridy(1);
958 cEffToPiRatio->SetLogx(1);
959
960 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
961 if (i == AliPID::kPion)
962 continue;
963
964 hEfficiencyToPiRatio[i]->Draw(Form("E1%s", i == 0 ? "" : " same"));
965 }
966
967 cEffToPiRatio->BuildLegend()->SetFillColor(kWhite);
968
969 ClearTitleFromHistoInCanvas(cEffToPiRatio);
970
971
972 // Correct the yields with the efficiencies and primary fractions
973 TH1D* hYieldCorrected[AliPID::kSPECIES] = { 0x0, };
974 TH1D* hYieldCorrectedSysError[AliPID::kSPECIES] = { 0x0, };
975 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
976 hYieldCorrected[species] = new TH1D(*hYield[species]);
977 hYieldCorrected[species]->SetName(Form("%s_corrected", hYield[species]->GetName()));
978 hYieldCorrected[species]->SetTitle(Form("%s", hYield[species]->GetTitle()));
979 //hYieldCorrected[species]->SetTitle(Form("%s, secondary and efficiency x acceptance x pT resolution corrected",
980 // hYield[species]->GetTitle()));
981
982 // Correction factor histos can have different binning than data histos (constant factor above some threshold)
983 // -> Need special functions to multiply and divide such histos
984 multiplyHistsDifferentBinning(hYieldCorrected[species], scaleStrangeness ? hSecSS[species] : hSec[species], 1., 1.);
985 divideHistsDifferentBinning(hYieldCorrected[species], hEfficiency[species], 1., 1.);
986
987 if (hYieldSysError[species]) {
988 hYieldCorrectedSysError[species] = new TH1D(*hYieldSysError[species]);
989 hYieldCorrectedSysError[species]->SetName(Form("%s_corrected", hYieldSysError[species]->GetName()));
990 hYieldCorrectedSysError[species]->SetTitle(Form("%s", hYieldSysError[species]->GetTitle()));
991
992 multiplyHistsDifferentBinning(hYieldCorrectedSysError[species], scaleStrangeness ? hSecSS[species] : hSec[species], 1., 1.,
993 kTRUE);
994 divideHistsDifferentBinning(hYieldCorrectedSysError[species], hEfficiency[species], 1., 1., kTRUE);
995 }
996 }
997
998 // Calculate the total corrected yield. The original total yield had no error (just the number of detected tracks in a pT bin),
999 // but due to the correction there is some error for the total yield. Also the error of the fractions introduces uncertainties
1000 // for the yields of individual species
1001 TH1D* hYieldCorrectedTotal = new TH1D(*hYieldCorrected[0]);
1002 hYieldCorrectedTotal->SetLineColor(kBlack);
1003 hYieldCorrectedTotal->SetMarkerColor(kBlack);
1004 hYieldCorrectedTotal->SetName("hYieldCorrectedTotal");
1005 hYieldCorrectedTotal->SetTitle("Total");
1006 //hYieldCorrectedTotal->SetTitle("Total yield, secondary and efficiency x acceptance x pT resolution corrected");
1007
1008 for (Int_t i = 1; i < AliPID::kSPECIES; i++)
1009 hYieldCorrectedTotal->Add(hYieldCorrected[i], 1.);
1010
1011 // Calculate the corrected fractions
1012 TH1D* hFractionCorrected[AliPID::kSPECIES] = { 0x0, };
1013 TH1D* hFractionCorrectedSysError[AliPID::kSPECIES] = { 0x0, };
1014 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
1015 hFractionCorrected[species] = new TH1D(*hYield[species]);
1016 TString oldName = hYield[species]->GetName();
1017 TString newName = oldName.ReplaceAll("Yield", "Fraction");
1018 TString oldTitle = hYield[species]->GetTitle();
1019 TString newTitle = oldTitle.ReplaceAll("Yield", "Fraction");
1020 hFractionCorrected[species]->SetName(Form("%s_corrected", newName.Data()));
1021 hFractionCorrected[species]->SetTitle(Form("%s", AliPID::ParticleLatexName(species)));
1022 hFractionCorrected[species]->GetYaxis()->SetTitle("Corrected Fraction");
1023 hFractionCorrected[species]->GetXaxis()->SetMoreLogLabels(kTRUE);
1024 hFractionCorrected[species]->GetXaxis()->SetNoExponent(kTRUE);
1025
1026 // Binomial error as for efficiencies (numerator and denominator are statistically not independent) for correct error calculation
1027 // (numerator is a "selected" subset of the denominator). It doesn't matter that the error of the histos is not just "sqrt(content)"
1028 // because the error formula also works for weighted histograms (which means that the error can be more or less anything)
1029 hFractionCorrected[species]->Divide(hYieldCorrected[species], hYieldCorrectedTotal, 1., 1., "B");
1030
1031
1032 // The systematic errors just need to be scaled in the same way as the fractions.
1033 // So, just take the ratio to the uncorrected fraction and scale the sys. error accordingly
1034 // or, in this case, just divide by the same total yield as for yield -> fractions
1035 if (hYieldCorrectedSysError[species]) {
1036 hFractionCorrectedSysError[species] = new TH1D(*hFractionCorrected[species]);
1037 hFractionCorrectedSysError[species]->SetName(Form("%s_sysError", hFractionCorrected[species]->GetName()));
1038 hFractionCorrectedSysError[species]->SetTitle(Form("%s (sys. error)", hFractionCorrected[species]->GetTitle()));
1039
1040 for (Int_t binX = 1; binX <= hFractionCorrectedSysError[species]->GetNbinsX(); binX++) {
1041 const Double_t corrTotalYield = hYieldCorrectedTotal->GetBinContent(binX);
1042 const Double_t scaleFactor = corrTotalYield > 0 ? 1.0 / corrTotalYield : 1.;
1043 hFractionCorrectedSysError[species]->SetBinError(binX, hYieldCorrectedSysError[species]->GetBinError(binX) * scaleFactor);
1044 }
1045 }
1046 }
1047
1048 // If MC is available, calculate the generated fractions
1049 TH1D* hMCgenPrimYieldTotal = 0x0;
1050 TH1D* hMCgenPrimFraction[AliPID::kSPECIES];
1051 for (Int_t i = 0; i < AliPID::kSPECIES; i++)
1052 hMCgenPrimFraction[i] = 0x0;
1053
1054 if (numMCgenPrimYieldHistsFound > 0) {
1055 hMCgenPrimYieldTotal = new TH1D(*hMCgenPrimYield[0]);
1056 hMCgenPrimYieldTotal->SetLineColor(kBlack);
1057 hMCgenPrimYieldTotal->SetMarkerColor(kBlack);
1058 hMCgenPrimYieldTotal->SetName("hMCgenPrimYieldTotal");
1059 hMCgenPrimYieldTotal->SetTitle("Total (MC truth)");
1060 //hMCgenPrimYieldTotal->SetTitle("Total generated primary yield (MC truth)");
1061
1062 for (Int_t i = 1; i < AliPID::kSPECIES; i++)
1063 hMCgenPrimYieldTotal->Add(hMCgenPrimYield[i], 1.);
1064
1065 // Calculate the MC fractions
1066 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
1067 hMCgenPrimYield[species]->SetTitle(Form("%s (MC truth)", AliPID::ParticleLatexName(species)));
1068
1069 hMCgenPrimFraction[species] = new TH1D(*hMCgenPrimYield[species]);
1070 TString oldName = hMCgenPrimYield[species]->GetName();
1071 TString newName = oldName.ReplaceAll("Yield", "Fraction");
1072 TString oldTitle = hMCgenPrimYield[species]->GetTitle();
1073 TString newTitle = oldTitle.ReplaceAll("yield", "fraction");
1074 hMCgenPrimFraction[species]->SetName(newName.Data());
1075 hMCgenPrimFraction[species]->SetTitle(newTitle.Data());
1076
1077 // Binomial error as for efficiencies (numerator and denominator are statistically not independent) for correct error calculation
1078 // (numerator is a "selected" subset of the denominator).
1079 hMCgenPrimFraction[species]->Divide(hMCgenPrimFraction[species], hMCgenPrimYieldTotal, 1., 1., "B");
1080 }
1081 }
1082
1083 TCanvas* cCorrData = new TCanvas("cCorrData", "Corrected data", 0, 300, 900, 900);
1084 cCorrData->Divide(2, 1);//, 0., 0.01);
1085 cCorrData->GetPad(1)->SetLogx(1);
1086 cCorrData->GetPad(1)->SetLogy(1);
1087 cCorrData->GetPad(2)->SetLogx(1);
1088 cCorrData->GetPad(2)->SetLogy(1);
1089
1090 cCorrData->GetPad(1)->SetRightMargin(0.001);
1091 cCorrData->GetPad(2)->SetRightMargin(0.001);
1092
1093 cCorrData->GetPad(1)->SetLeftMargin(0.2);
1094 cCorrData->GetPad(2)->SetLeftMargin(0.2);
1095
1096 cCorrData->cd(1); // uncorrected
1097 hYield[AliPID::kPion]->GetYaxis()->SetTitleOffset(1.4);
1098 hYield[AliPID::kPion]->Draw("E1");
1099
1100 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1101 if (hYieldSysError[i])
1102 hYieldSysError[i]->Draw("E2 same");
1103
1104 if (i == AliPID::kPion) continue;
1105 hYield[i]->Draw("E1 same");
1106 }
1107
1108 ClearTitleFromHistoInCanvas(cCorrData, 1);
1109
1110 cCorrData->cd(2); // corrected
1111 hYieldCorrectedTotal->GetYaxis()->SetTitleOffset(1.4);
1112 hYieldCorrectedTotal->GetXaxis()->SetMoreLogLabels(kTRUE);
1113 hYieldCorrectedTotal->GetXaxis()->SetNoExponent(kTRUE);
1114 hYieldCorrectedTotal->GetYaxis()->SetRangeUser(hYieldCorrected[AliPID::kMuon]->GetBinContent(hYieldCorrected[AliPID::kMuon]->FindLastBinAbove(0.)) * 0.1,
1115 hYieldCorrectedTotal->GetBinContent(hYieldCorrectedTotal->GetMaximumBin()) * 10.);
1116
1117 if (hMCgenPrimYieldTotal) {
1118 hMCgenPrimYieldTotal->GetYaxis()->SetTitleOffset(1.4);
1119 hMCgenPrimYieldTotal->GetXaxis()->SetMoreLogLabels(kTRUE);
1120 hMCgenPrimYieldTotal->GetXaxis()->SetNoExponent(kTRUE);
1121 hMCgenPrimYieldTotal->GetXaxis()->SetTitle(hYieldCorrectedTotal->GetXaxis()->GetTitle());
1122 hMCgenPrimYieldTotal->GetYaxis()->SetRangeUser(hYieldCorrected[AliPID::kMuon]->GetBinContent(hYieldCorrected[AliPID::kMuon]->FindLastBinAbove(0.)) * 0.1,
1123 hYieldCorrectedTotal->GetBinContent(hYieldCorrectedTotal->GetMaximumBin()) * 10.);
1124 }
1125
1126 if (hMCgenPrimYieldTotal) {
1127 hMCgenPrimYieldTotal->Draw("E1");
1128 hYieldCorrectedTotal->Draw("E1 same");
1129 }
1130 else
1131 hYieldCorrectedTotal->Draw("E1");
1132
1133 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1134 if (hMCgenPrimYield[i])
1135 hMCgenPrimYield[i]->Draw("E1 same");
1136 hYieldCorrected[i]->Draw("E1 same");
1137 }
1138
1139 TLegend* legTemp = cCorrData->cd(2)->BuildLegend(0.25, 0.16, 0.65, 0.51);
1140 legTemp->SetNColumns(2);
1141 legTemp->SetFillColor(kWhite);
1142
1143 // Do not include in legend
1144 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1145 if (hYieldCorrectedSysError[i])
1146 hYieldCorrectedSysError[i]->Draw("E2 same");
1147 }
1148
1149 ClearTitleFromHistoInCanvas(cCorrData, 2);
1150
1151 TCanvas* cCorrYieldsRatio = 0x0;
1152
1153 TH1D* hYieldCorrectedRatioToMC[AliPID::kSPECIES];
1154 for (Int_t i = 0; i < AliPID::kSPECIES; i++)
1155 hYieldCorrectedRatioToMC[i] = 0x0;
1156
1157 TH1D* hYieldCorrectedTotalRatioToMC = 0x0;
1158
1159 if (numMCgenPrimYieldHistsFound > 0) {
1160 // Compare with MC truth
1161 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
1162 hYieldCorrectedRatioToMC[species] = new TH1D(*hYieldCorrected[species]);
1163 hYieldCorrectedRatioToMC[species]->SetName(Form("hYieldCorrectedRatioToMC_%s", AliPID::ParticleShortName(species)));
1164 hYieldCorrectedRatioToMC[species]->SetTitle(Form("%s", AliPID::ParticleLatexName(species)));
1165 hYieldCorrectedRatioToMC[species]->GetYaxis()->SetTitle("Corrected Yield: Fit / MC Truth");
1166 hYieldCorrectedRatioToMC[species]->Divide(hMCgenPrimYield[species]);
1167 }
1168
1169 hYieldCorrectedTotalRatioToMC = new TH1D(*hYieldCorrectedTotal);
1170 hYieldCorrectedTotalRatioToMC->SetName("hYieldCorrectedTotalRatioToMC");
1171 hYieldCorrectedTotalRatioToMC->SetTitle("Total");
1172 hYieldCorrectedTotalRatioToMC->GetYaxis()->SetTitle("Corrected Yield: Fit / MC Truth");
1173 hYieldCorrectedTotalRatioToMC->Divide(hMCgenPrimYieldTotal);
1174
1175 cCorrYieldsRatio = new TCanvas("cCorrYieldsRatio", "Corrected Yields Comparison to MC", 0, 300, 900, 900);
1176 cCorrYieldsRatio->SetGridx(1);
1177 cCorrYieldsRatio->SetGridy(1);
1178 cCorrYieldsRatio->SetLogx(1);
1179
1180 hYieldCorrectedTotalRatioToMC->GetYaxis()->SetRangeUser(0.6, 1.6);
1181 hYieldCorrectedTotalRatioToMC->GetYaxis()->SetTitleOffset(0.85);
1182 hYieldCorrectedTotalRatioToMC->Draw("E1");
1183
1184 for (Int_t species = 0; species < AliPID::kSPECIES; species++)
1185 hYieldCorrectedRatioToMC[species]->Draw("E1 same");
1186
1187 cCorrYieldsRatio->BuildLegend()->SetFillColor(kWhite);
1188
1189 ClearTitleFromHistoInCanvas(cCorrYieldsRatio);
1190 }
1191
1192
1193 if (cFractions)
1194 cFractions->Draw();
1195
1196 TCanvas* cCorrFractions = new TCanvas("cCorrFractions", "Corrected particleFractions", 0, 300, 900, 900);
1197 cCorrFractions->SetLogx(1);
1198 hFractionCorrected[0]->GetYaxis()->SetRangeUser(0., 1.);
1199 hFractionCorrected[0]->Draw("E1");
1200 if (hMCgenPrimFraction[0])
1201 hMCgenPrimFraction[0]->Draw("E1 same");
1202
1203 for (Int_t i = 1; i < AliPID::kSPECIES; i++) {
1204 hFractionCorrected[i]->Draw("E1 same");
1205 if (hMCgenPrimFraction[i])
1206 hMCgenPrimFraction[i]->Draw("E1 same");
1207 }
1208
1209 cCorrFractions->BuildLegend()->SetFillColor(kWhite);
1210
1211 // Do not include in legend!!
1212 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1213 if (hFractionCorrectedSysError[i])
1214 hFractionCorrectedSysError[i]->Draw("E2 same");
1215 }
1216
1217
1218 ClearTitleFromHistoInCanvas(cCorrFractions);
1219
1220 // Save results to file
1221 TString chargeString = "";
1222 if (chargeMode == kPosCharge)
1223 chargeString = "_posCharge";
1224 else if (chargeMode == kNegCharge)
1225 chargeString = "_negCharge";
1226
1227 TString saveFileName = pathNameData;
1228 saveFileName.ReplaceAll(Form("%s/", pathData.Data()), "");
1229 saveFileName.Prepend("output_EfficiencyCorrection_");
1230 saveFileName.ReplaceAll(".root", Form("%s.root", chargeString.Data()));
1231
1232 TString saveFilePathName = Form("%s/%s", pathData.Data(), saveFileName.Data());
1233 TFile* saveFile = TFile::Open(saveFilePathName.Data(), "RECREATE");
1234 saveFile->cd();
1235
1236 if (cSec)
1237 cSec->Write();
1238
1239 if (cSecSS)
1240 cSecSS->Write();
1241
1242 if (cSec2)
1243 cSec2->Write();
1244
1245 if (cSecSS2)
1246 cSecSS2->Write();
1247
1248 if (cSecToPiRatio)
1249 cSecToPiRatio->Write();
1250
1251 if (cSecSSToPiRatio)
1252 cSecSSToPiRatio->Write();
1253
1254 if (cEff)
1255 cEff->Write();
1256
1257 if (cEff2)
1258 cEff2->Write();
1259
1260 if (cEffToPiRatio)
1261 cEffToPiRatio->Write();
1262
1263 if (cCorrData)
1264 cCorrData->Write();
1265
1266 if (cCorrYieldsRatio)
1267 cCorrYieldsRatio->Write();
1268
1269 if (cFractions)
1270 cFractions->Write();
1271
1272 if (cCorrFractions)
1273 cCorrFractions->Write();
1274
1275 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1276 if (hSec[i])
1277 hSec[i]->Write();
1278
1279 if (hSecSS[i])
1280 hSecSS[i]->Write();
1281 }
1282
1283 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1284 if (hSecToPiRatio[i])
1285 hSecToPiRatio[i]->Write();
1286
1287 if (hSecSSToPiRatio[i])
1288 hSecSSToPiRatio[i]->Write();
1289 }
1290
1291 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1292 if (hEfficiency[i])
1293 hEfficiency[i]->Write();
1294 }
1295
1296 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1297 if (hEfficiencyToPiRatio[i])
1298 hEfficiencyToPiRatio[i]->Write();
1299 }
1300
1301 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1302 if (hYield[i])
1303 hYield[i]->Write();
1304
1305 if (hYieldSysError[i])
1306 hYieldSysError[i]->Write();
1307 }
1308
1309 if (hYieldCorrectedTotal)
1310 hYieldCorrectedTotal->Write();
1311
1312 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1313 if (hYieldCorrected[i])
1314 hYieldCorrected[i]->Write();
1315
1316 if (hYieldCorrectedSysError[i])
1317 hYieldCorrectedSysError[i]->Write();
1318 }
1319
1320 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1321 if (hMCgenPrimYield[i])
1322 hMCgenPrimYield[i]->Write();
1323 }
1324
1325 if (hMCgenPrimYieldTotal)
1326 hMCgenPrimYieldTotal->Write();
1327
1328 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1329 if (hYieldCorrectedRatioToMC[i])
1330 hYieldCorrectedRatioToMC[i]->Write();
1331 }
1332
1333 if (hYieldCorrectedTotalRatioToMC)
1334 hYieldCorrectedTotalRatioToMC->Write();
1335
1336 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1337 if (hFractionCorrected[i])
1338 hFractionCorrected[i]->Write();
1339
1340 if (hFractionCorrectedSysError[i])
1341 hFractionCorrectedSysError[i]->Write();
1342 }
1343
1344 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1345 if (hMCgenPrimFraction[i])
1346 hMCgenPrimFraction[i]->Write();
1347 }
1348
1349 TNamed* settings = new TNamed(
1350 Form("Settings: Efficiency file \"%s\", Data file \"%s\", lowerCentrality %.3f, upperCentrality %.3f, lowerJetPt %.1f, upperJetPt %.1f, constantCorrectionAbovePtThreshold %.3f\n",
1351 pathNameEfficiency.Data(), pathNameData.Data(), lowerCentrality, upperCentrality, lowerJetPt,
1352 upperJetPt, constantCorrectionAbovePtThreshold), "");
1353 settings->Write();
1354
1355 saveFile->Close();
1356
1357 return 0;
1358}
1359
1360
1361//___________________________________________________________________
1362// Efficiency for jet spectra (pT, z and xi)
1363// E.g. a 'calcEfficiency.C+("finalCuts/MC_pp/7TeV/LHC11a1/corrected/allJetPtMergedWeighted/bhess_PID_Jets_PureGauss_efficiency.root", "finalCuts/pp/7TeV/LHC10e.pass2/corrected/finalisedSplines/finalMapsAndTail/Jets/noCutOn_ncl_or_liav/output_extractedFFs_bhess_PID_Jets_centrality_all_highN_rougherXi.root", kTRUE, kFALSE, 0, -2, -2, -2, -2, 40, 80, -100, -100, 2, 1, 2)' -b -q
1364Int_t calcEfficiency(TString pathNameEfficiency, TString pathNameData, Bool_t correctGeantFluka, Bool_t scaleStrangeness,
1365 Int_t chargeMode /*kNegCharge = -1, kAllCharged = 0, kPosCharge = 1*/,
1366 Double_t lowerCentralityData /*= -2*/, Double_t upperCentralityData /*= -2*/,
1367 Double_t lowerCentrality /*= -2*/, Double_t upperCentrality /*= -2*/,
1368 Double_t lowerJetPt /*= -1*/ , Double_t upperJetPt/* = -1*/,
1369 Double_t constantCorrectionAbovePtThreshold,
1370 Double_t constantCorrectionAboveXiThreshold,
1371 Int_t rebinEfficiencyPt,
1372 Int_t rebinEfficiencyZ,
1373 Int_t rebinEfficiencyXi)
1374{
1375 TString titles[kNtypes];
1376 titles[kTrackPt] = "trackPt";
1377 titles[kZ] = "z";
1378 titles[kXi] = "xi";
1379
1380 TString pathData = pathNameData;
1381 pathData.Replace(pathData.Last('/'), pathData.Length(), "");
1382
1383 TFile* fileEff = TFile::Open(pathNameEfficiency.Data());
1384 if (!fileEff) {
1385 printf("Failed to open efficiency file \"%s\"\n", pathNameEfficiency.Data());
1386 return -1;
1387 }
1388
1389 AliCFContainer* data = (AliCFContainer*)(fileEff->Get("containerEff"));
1390 if (!data) {
1391 printf("Failed to load efficiency container!\n");
1392 return -1;
1393 }
1394
1395 const Int_t iMCid = data->GetVar("MC ID");
1396 const Int_t iPt = data->GetVar("P_{T} (GeV/c)");
1397 //const Int_t iEta = data->GetVar("#eta");
1398 const Int_t iCharge = data->GetVar("Charge (e_{0})");
1399 const Int_t iMult = data->GetVar("Centrality Percentile");
1400 const Int_t iJetPt = data->GetVar("P_{T}^{jet} (GeV/c)");
1401 const Int_t iZ = data->GetVar("z = P_{T}^{track} / P_{T}^{jet}");
1402 const Int_t iXi = data->GetVar("#xi = ln(P_{T}^{jet} / P_{T}^{track})");
1403
1404 TH2D* hNjetsGen = 0x0;
1405 TH2D* hNjetsRec = 0x0;
1406
1407 TH2D* hNjetsGenData = 0x0;
1408 TH2D* hNjetsRecData = 0x0;
1409
1410 TH1D* hYieldPt[AliPID::kSPECIES] = {0x0, };
1411 TH1D* hYieldPtSysError[AliPID::kSPECIES] = {0x0, };
1412 TH1D* hMCgenPrimYieldPt[AliPID::kSPECIES] = {0x0, };
1413
1414 TH1D* hYieldZ[AliPID::kSPECIES] = {0x0, };
1415 TH1D* hYieldZSysError[AliPID::kSPECIES] = {0x0, };
1416 TH1D* hMCgenPrimYieldZ[AliPID::kSPECIES] = {0x0, };
1417
1418 TH1D* hYieldXi[AliPID::kSPECIES] = {0x0, };
1419 TH1D* hYieldXiSysError[AliPID::kSPECIES] = {0x0, };
1420 TH1D* hMCgenPrimYieldXi[AliPID::kSPECIES] = {0x0, };
1421
1422
1423 TH2D* hTemp = 0x0;
1424
1425 Int_t numMCgenPrimYieldHistsFound = 0;
1426
1427 Int_t lowerJetPtBinYields = -1;
1428 Int_t upperJetPtBinYields = -1;
1429
1430 Double_t actualLowerJetPtYields = -10;
1431 Double_t actualUpperJetPtYields = -10;
1432
1433 TFile* fileData = TFile::Open(pathNameData.Data());
1434 if (!fileData) {
1435 printf("Failed to open data file \"%s\"\n", pathNameData.Data());
1436 return -1;
1437 }
1438
1439
1440 hNjetsGenData = (TH2D*)fileData->Get("fh2FFJetPtGen");
1441
1442 hNjetsRecData = (TH2D*)fileData->Get("fh2FFJetPtRec");
1443
1444 if (!hNjetsRecData) {
1445 printf("Failed to load numJet histo for data!\n");
1446 return -1;
1447 }
1448
1449 const Bool_t restrictCentralityData = ((lowerCentralityData >= -1) && (upperCentralityData >= -1));
1450 // Integral(lowerCentBinLimitData, uppCentBinLimitData) will not be restricted if these values are kept
1451 const Int_t lowerCentralityBinLimitData = restrictCentralityData ? hNjetsRecData->GetXaxis()->FindBin(lowerCentralityData + 0.001)
1452 : -1;
1453 const Int_t upperCentralityBinLimitData = restrictCentralityData ? hNjetsRecData->GetXaxis()->FindBin(upperCentralityData - 0.001)
1454 : -2;
1455
1456 // Integral(lowerJetBinLimitData, uppJetBinLimitData) will not be restricted if these values are kept
1457 const Int_t lowerJetPtBinLimitData = ((lowerJetPt >= 0) && (upperJetPt >= 0))
1458 ? hNjetsRecData->GetYaxis()->FindBin(lowerJetPt + 0.001) : -1;
1459 const Int_t upperJetPtBinLimitData = ((lowerJetPt >= 0) && (upperJetPt >= 0))
1460 ? hNjetsRecData->GetYaxis()->FindBin(upperJetPt - 0.001) : -2;
1461
1462 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
1463 TString histName = Form("hIDFFz_%s", AliPID::ParticleShortName(species));
1464 hTemp = (TH2D*)fileData->Get(histName.Data());
1465
1466 if (hTemp && (lowerJetPtBinYields < 0 || upperJetPtBinYields < 0)) {
1467 // If the jetPt range is to be restricted
1468 if (lowerJetPt >= 0 && upperJetPt >= 0) {
1469 lowerJetPtBinYields = hTemp->GetYaxis()->FindBin(lowerJetPt + 0.001);
1470 upperJetPtBinYields = hTemp->GetYaxis()->FindBin(upperJetPt - 0.001);
1471
1472 actualLowerJetPtYields = hTemp->GetYaxis()->GetBinLowEdge(lowerJetPtBinYields);
1473 actualUpperJetPtYields = hTemp->GetYaxis()->GetBinUpEdge(upperJetPtBinYields);
1474 }
1475 else {
1476 lowerJetPtBinYields = 0;
1477 upperJetPtBinYields = -1;
1478 }
1479 }
1480
1481 if ((lowerJetPtBinYields < 0 || upperJetPtBinYields < 0) && (lowerJetPt >= 0 && upperJetPt >= 0)) {
1482 printf("Failed to determine jet pt bin limits!\n");
1483 return -1;
1484 }
1485
1486 // NOTE: The yields have already been normalised to nJets in extractFFs. However, the binning in jetPt might be different now.
1487 // Thus, in order to get the correct result, the old normalisation (just the same binnnig as in the nJet histo) has to be
1488 // undone and then it has to be normalised to the number of jets in the new binning again (see below).
1489
1490 if (hTemp) {
1491 undoJetNormalisationHist2D(hTemp, hNjetsRecData, lowerCentralityBinLimitData, upperCentralityBinLimitData);
1492 hYieldZ[species] = hTemp->ProjectionX(histName.ReplaceAll("hIDFF", "hYieldIDFF").Data(), lowerJetPtBinYields, upperJetPtBinYields,
1493 "e");
1494 }
1495
1496 if (!hYieldZ[species]) {
1497 printf("Failed to load hist \"%s\"\n", histName.Data());
1498 return -1;
1499 }
1500
1501
1502
1503 histName = Form("hIDFFxi_%s", AliPID::ParticleShortName(species));
1504
1505 hTemp = (TH2D*)fileData->Get(histName.Data());
1506
1507 if (hTemp) {
1508 undoJetNormalisationHist2D(hTemp, hNjetsRecData, lowerCentralityBinLimitData, upperCentralityBinLimitData);
1509 hYieldXi[species] = hTemp->ProjectionX(histName.ReplaceAll("hIDFF", "hYieldIDFF").Data(),
1510 lowerJetPtBinYields, upperJetPtBinYields, "e");
1511 }
1512
1513 if (!hYieldXi[species]) {
1514 printf("Failed to load hist \"%s\"\n", histName.Data());
1515 return -1;
1516 }
1517
1518 histName = Form("hIDFFtrackPt_%s", AliPID::ParticleShortName(species));
1519
1520 hTemp = (TH2D*)fileData->Get(histName.Data());
1521
1522 if (hTemp) {
1523 undoJetNormalisationHist2D(hTemp, hNjetsRecData, lowerCentralityBinLimitData, upperCentralityBinLimitData);
1524 hYieldPt[species] = hTemp->ProjectionX(histName.ReplaceAll("hIDFF", "hYieldIDFF").Data(),
1525 lowerJetPtBinYields, upperJetPtBinYields, "e");
1526 }
1527
1528 if (!hYieldPt[species]) {
1529 printf("Failed to load hist \"%s\"\n", histName.Data());
1530 return -1;
1531 }
1532
1533
1534
1535 histName = Form("hIDFFz_%s_sysError", AliPID::ParticleShortName(species));
1536
1537 hTemp = (TH2D*)fileData->Get(histName.Data());
1538
1539 if (hTemp) {
1540 undoJetNormalisationHist2D(hTemp, hNjetsRecData, lowerCentralityBinLimitData, upperCentralityBinLimitData);
1541 hYieldZSysError[species] = hTemp->ProjectionX(histName.ReplaceAll("hIDFF", "hYieldIDFF").Data(), lowerJetPtBinYields,
1542 upperJetPtBinYields, "e");
1543 }
1544
1545 if (!hYieldZSysError[species]) {
1546 printf("Failed to load hist \"%s\"\n", histName.Data());
1547 return -1;
1548 }
1549
1550 histName = Form("hIDFFxi_%s_sysError", AliPID::ParticleShortName(species));
1551
1552 hTemp = (TH2D*)fileData->Get(histName.Data());
1553
1554 if (hTemp) {
1555 undoJetNormalisationHist2D(hTemp, hNjetsRecData, lowerCentralityBinLimitData, upperCentralityBinLimitData);
1556 hYieldXiSysError[species] = hTemp->ProjectionX(histName.ReplaceAll("hIDFF", "hYieldIDFF").Data(), lowerJetPtBinYields,
1557 upperJetPtBinYields, "e");
1558 }
1559
1560 if (!hYieldXiSysError[species]) {
1561 printf("Failed to load hist \"%s\"\n", histName.Data());
1562 return -1;
1563 }
1564
1565 histName = Form("hIDFFtrackPt_%s_sysError", AliPID::ParticleShortName(species));
1566
1567 hTemp = (TH2D*)fileData->Get(histName.Data());
1568
1569 if (hTemp) {
1570 undoJetNormalisationHist2D(hTemp, hNjetsRecData, lowerCentralityBinLimitData, upperCentralityBinLimitData);
1571 hYieldPtSysError[species] = hTemp->ProjectionX(histName.ReplaceAll("hIDFF", "hYieldIDFF").Data(), lowerJetPtBinYields,
1572 upperJetPtBinYields, "e");
1573 }
1574
1575 if (!hYieldPtSysError[species]) {
1576 printf("Failed to load hist \"%s\"\n", histName.Data());
1577 return -1;
1578 }
1579
1580 // In case of MC also retrieve the MC truth generated yields
1581 histName = Form("hMCgenYieldsPrimZ_%s", AliPID::ParticleShortName(species));
1582
1583 hTemp = (TH2D*)fileData->Get(histName.Data());
1584
1585 if (hTemp) {
1586 undoJetNormalisationHist2D(hTemp, hNjetsGenData, lowerCentralityBinLimitData, upperCentralityBinLimitData);
1587 hMCgenPrimYieldZ[species] = hTemp->ProjectionX(histName.ReplaceAll("hMCgen", "hYieldMCgen").Data(), lowerJetPtBinYields,
1588 upperJetPtBinYields, "e");
1589 }
1590
1591
1592 histName = Form("hMCgenYieldsPrimXi_%s", AliPID::ParticleShortName(species));
1593
1594 hTemp = (TH2D*)fileData->Get(histName.Data());
1595
1596 if (hTemp) {
1597 undoJetNormalisationHist2D(hTemp, hNjetsGenData, lowerCentralityBinLimitData, upperCentralityBinLimitData);
1598 hMCgenPrimYieldXi[species] = hTemp->ProjectionX(histName.ReplaceAll("hMCgen", "hYieldMCgen").Data(), lowerJetPtBinYields,
1599 upperJetPtBinYields, "e");
1600 }
1601
1602
1603 histName = Form("hMCgenYieldsPrimPt_%s", AliPID::ParticleShortName(species));
1604
1605 hTemp = (TH2D*)fileData->Get(histName.Data());
1606
1607 if (hTemp) {
1608 undoJetNormalisationHist2D(hTemp, hNjetsGenData, lowerCentralityBinLimitData, upperCentralityBinLimitData);
1609 hMCgenPrimYieldPt[species] = hTemp->ProjectionX(histName.ReplaceAll("hMCgen", "hYieldMCgen").Data(), lowerJetPtBinYields,
1610 upperJetPtBinYields, "e");
1611 }
1612
1613 if (hMCgenPrimYieldPt[species] && hMCgenPrimYieldZ[species] && hMCgenPrimYieldXi[species])
1614 numMCgenPrimYieldHistsFound++;
1615 }
1616
1617 if (numMCgenPrimYieldHistsFound > 0 && numMCgenPrimYieldHistsFound != AliPID::kSPECIES) {
1618 printf("Error: Unable to retrieve all MC generated prim yield histos! Got %d.\n", numMCgenPrimYieldHistsFound);
1619 return -1;
1620 }
1621
1622
1623 /*OLD: Load from AnalysisResults.root
1624
1625 File* fileData = TFile::Open(pathNameData.Data());
1626 if (!fileData) {
1627 printf("Failed to open data file \"%s\"\n", pathNameData.Data());
1628 return -1;
1629 }
1630
1631 TString dirDataInFile = "";
1632 TDirectory* dirData = (TDirectory*)fileData->Get(fileData->GetListOfKeys()->At(0)->GetName());
1633 if (!dirData) {
1634 printf("No directory found inside data file \"%s\"\n", pathNameData.Data());
1635 return -1;
1636 }
1637
1638 TList* list = (TList*)dirData->Get(dirData->GetListOfKeys()->At(0)->GetName());
1639 if (!list) {
1640 printf("No list found in directory \"%s\" inside data file \"%s\"\n",
1641 dirData->GetListOfKeys()->At(0)->GetName(),pathNameData.Data());
1642 return -1;
1643 }
1644
1645 hNjetsGen = (TH1D*)list->FindObject("fh1FFJetPtGen");
1646 hNjetsRec = (TH1D*)list->FindObject("fh1FFJetPtRecCuts");
1647
1648 if (!hNjetsRec) {
1649 printf("Failed to load number of jets (rec) histo!\n");
1650 return -1;
1651 }
1652
1653
1654 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
1655 TString histName = Form("fh2FFZRecCuts_%s", AliPID::ParticleName(species));
1656 hTemp = (TH2D*)list->FindObject(histName.Data());
1657
1658 if (hTemp && (lowerJetPtBinYields < 0 || upperJetPtBinYields < 0)) {
1659 // If the jetPt range is to be restricted
1660 if (lowerJetPt >= 0 && upperJetPt >= 0) {
1661 lowerJetPtBinYields = hTemp->GetXaxis()->FindBin(lowerJetPt + 0.001);
1662 upperJetPtBinYields = hTemp->GetXaxis()->FindBin(upperJetPt - 0.001);
1663
1664 actualLowerJetPtYields = hTemp->GetXaxis()->GetBinLowEdge(lowerJetPtBinYields);
1665 actualUpperJetPtYields = hTemp->GetXaxis()->GetBinUpEdge(upperJetPtBinYields);
1666 }
1667 else {
1668 lowerJetPtBinYields = 0;
1669 upperJetPtBinYields = -1;
1670 }
1671 }
1672
1673 if ((lowerJetPtBinYields < 0 || upperJetPtBinYields < 0) && (lowerJetPt >= 0 && upperJetPt >= 0)) {
1674 printf("Failed to determine jet pt bin limits!\n");
1675 return -1;
1676 }
1677
1678 if (hTemp)
1679 hYieldZ[species] = hTemp->ProjectionY(histName.ReplaceAll("fh2", "fh").Data(), lowerJetPtBinYields, upperJetPtBinYields, "e");
1680
1681 if (!hYieldZ[species]) {
1682 printf("Failed to load hist \"%s\"\n", histName.Data());
1683 return -1;
1684 }
1685
1686
1687
1688 histName = Form("fh2FFXiRecCuts_%s", AliPID::ParticleName(species));
1689
1690 hTemp = (TH2D*)list->FindObject(histName.Data());
1691
1692 if (hTemp)
1693 hYieldXi[species] = hTemp->ProjectionY(histName.ReplaceAll("fh2", "fh").Data(), lowerJetPtBinYields, upperJetPtBinYields, "e");
1694
1695 if (!hYieldXi[species]) {
1696 printf("Failed to load hist \"%s\"\n", histName.Data());
1697 return -1;
1698 }
1699
1700 histName = Form("fh2FFTrackPtRecCuts_%s", AliPID::ParticleName(species));
1701
1702 hTemp = (TH2D*)list->FindObject(histName.Data());
1703
1704 if (hTemp)
1705 hYieldPt[species] = hTemp->ProjectionY(histName.ReplaceAll("fh2", "fh").Data(), lowerJetPtBinYields, upperJetPtBinYields, "e");
1706
1707 if (!hYieldPt[species]) {
1708 printf("Failed to load hist \"%s\"\n", histName.Data());
1709 return -1;
1710 }
1711
1712 // In case of MC also retrieve the MC truth generated yields
1713 histName = Form("fh2FFZGen_%s", AliPID::ParticleName(species));
1714
1715 hTemp = (TH2D*)list->FindObject(histName.Data());
1716 if (hTemp)
1717 hMCgenPrimYieldZ[species] = hTemp->ProjectionY(histName.ReplaceAll("fh2", "fh").Data(), lowerJetPtBinYields, upperJetPtBinYields,
1718 "e");
1719
1720
1721 histName = Form("fh2FFXiGen_%s", AliPID::ParticleName(species));
1722
1723 hTemp = (TH2D*)list->FindObject(histName.Data());
1724 if (hTemp)
1725 hMCgenPrimYieldXi[species] = hTemp->ProjectionY(histName.ReplaceAll("fh2", "fh").Data(), lowerJetPtBinYields, upperJetPtBinYields,
1726 "e");
1727
1728
1729 histName = Form("fh2FFTrackPtGen_%s", AliPID::ParticleName(species));
1730
1731 hTemp = (TH2D*)list->FindObject(histName.Data());
1732 if (hTemp)
1733 hMCgenPrimYieldPt[species] = hTemp->ProjectionY(histName.ReplaceAll("fh2", "fh").Data(), lowerJetPtBinYields, upperJetPtBinYields,
1734 "e");
1735
1736 if (hMCgenPrimYieldPt[species] && hMCgenPrimYieldZ[species] && hMCgenPrimYieldXi[species])
1737 numMCgenPrimYieldHistsFound++;
1738 }
1739
1740 if (numMCgenPrimYieldHistsFound > 0 && numMCgenPrimYieldHistsFound != AliPID::kSPECIES) {
1741 printf("Error: Unable to retrieve all MC generated prim yield histos! Got %d.\n", numMCgenPrimYieldHistsFound);
1742 return -1;
1743 }
1744
1745
1746 const Double_t nJetsGen = hNjetsGen ? hNjetsGen->Integral(lowerJetPtBinYields, upperJetPtBinYields) : -1;
1747 const Double_t nJetsRec = hNjetsRec->Integral(lowerJetPtBinYields, upperJetPtBinYields);
1748 */
1749
1750 // Take binning from pion yield (binning for all species the same) and create a new AliCFContainer with this new binning
1751 TH1D hDummyPt(*hYieldPt[AliPID::kPion]);
1752 hDummyPt.SetName("hDummyPt");
1753 TAxis* axisPt = 0x0;
1754
1755 if (rebinEfficiencyPt > 1) {
1756 Int_t nBinsNew = 0;
1757 const Double_t* newBins = GetBins(rebinEfficiencyPt, nBinsNew);
1758
1759 hDummyPt.SetBins(nBinsNew, newBins);
1760
1761 axisPt = hDummyPt.GetXaxis();
1762
1763 //axisPt = hDummyPt.Rebin(rebinEfficiencyPt, "", 0)->GetXaxis();
1764 }
1765 else
1766 axisPt = hDummyPt.GetXaxis();
1767
1768 const TArrayD* binsPtCurrent = axisPt->GetXbins();
1769 TArrayD* binsPtNew = new TArrayD(*binsPtCurrent);
1770
1771 TH1D hDummyZ(*hYieldZ[AliPID::kPion]);
1772 hDummyZ.SetName("hDummyZ");
1773 TAxis* axisZ = 0x0;
1774
1775 if (rebinEfficiencyZ > 1)
1776 axisZ = hDummyZ.Rebin(rebinEfficiencyZ, "", 0)->GetXaxis();
1777 else
1778 axisZ = hDummyZ.GetXaxis();
1779
1780 const TArrayD* binsZCurrent = axisZ->GetXbins();
1781 TArrayD* binsZNew = new TArrayD(*binsZCurrent);
1782
1783 TH1D hDummyXi(*hYieldXi[AliPID::kPion]);
1784 hDummyXi.SetName("hDummyXi");
1785 TAxis* axisXi = 0x0;
1786
1787 if (rebinEfficiencyXi > 1)
1788 axisXi = hDummyXi.Rebin(rebinEfficiencyXi, "", 0)->GetXaxis();
1789 else
1790 axisXi = hDummyXi.GetXaxis();
1791
1792 const TArrayD* binsXiCurrent = axisXi->GetXbins();
1793 TArrayD* binsXiNew = new TArrayD(*binsXiCurrent);
1794
1795
1796 const Int_t nEffDims = data->GetNVar();
1797 Int_t nEffBins[nEffDims];
1798
1799 for (Int_t iDim = 0; iDim < nEffDims; iDim++) {
1800 if (iDim == iPt)
1801 nEffBins[iDim] = axisPt->GetNbins();
1802 else if (iDim == iZ)
1803 nEffBins[iDim] = axisZ->GetNbins();
1804 else if (iDim == iXi)
1805 nEffBins[iDim] = axisXi->GetNbins();
1806 else
1807 nEffBins[iDim] = data->GetNBins(iDim);
1808 }
1809
1810
1811 // Just make one large pT bin above some threshold, if desired
1812 if (binsPtNew->fN != 0 && constantCorrectionAbovePtThreshold > 0) {
1813 for (Int_t iBin = 0; iBin <= nEffBins[iPt] + 1; iBin++) {
1814 // Find the first bin edged really larger than the threshold.
1815 // If the bin edge before equals the threshold, just set the
1816 // current bin edge to the right end of the spectrum -> Done.
1817 // If the bin edge before is different, set the bin edge to the
1818 // threshold
1819 if (binsPtNew->fArray[iBin] > constantCorrectionAbovePtThreshold) {
1820 if (binsPtNew->fArray[iBin - 1] == constantCorrectionAbovePtThreshold) {
1821 binsPtNew->fArray[iBin] = binsPtNew->fArray[nEffBins[iPt]];
1822 nEffBins[iPt] = iBin;
1823 break;
1824 }
1825 else {
1826 binsPtNew->fArray[iBin] = constantCorrectionAbovePtThreshold;
1827 }
1828 }
1829 }
1830 }
1831
1832 // Just make one large Xi bin above some threshold, if desired
1833 if (binsXiNew->fN != 0 && constantCorrectionAboveXiThreshold > 0) {
1834 for (Int_t iBin = 0; iBin <= nEffBins[iXi] + 1; iBin++) {
1835 // Find the first bin edged really larger than the threshold.
1836 // If the bin edge before equals the threshold, just set the
1837 // current bin edge to the right end of the spectrum -> Done.
1838 // If the bin edge before is different, set the bin edge to the
1839 // threshold
1840 if (binsXiNew->fArray[iBin] > constantCorrectionAboveXiThreshold) {
1841 if (binsXiNew->fArray[iBin - 1] == constantCorrectionAboveXiThreshold) {
1842 binsXiNew->fArray[iBin] = binsXiNew->fArray[nEffBins[iXi]];
1843 nEffBins[iXi] = iBin;
1844 break;
1845 }
1846 else {
1847 binsXiNew->fArray[iBin] = constantCorrectionAboveXiThreshold;
1848 }
1849 }
1850 }
1851 }
1852
1853 AliCFContainer *dataRebinned = new AliCFContainer(Form("%s_rebinned", data->GetName()), Form("%s (rebinned)", data->GetTitle()),
1854 data->GetNStep(), nEffDims, nEffBins);
1855
1856 for (Int_t iDim = 0; iDim < nEffDims; iDim++) {
1857 dataRebinned->SetVarTitle(iDim, data->GetVarTitle(iDim));
1858
1859 if (iDim == iPt) {
1860 if (binsPtNew->fN == 0)
1861 dataRebinned->SetBinLimits(iDim, axisPt->GetXmin(), axisPt->GetXmax());
1862 else
1863 dataRebinned->SetBinLimits(iDim, binsPtNew->fArray);
1864 }
1865 else if (iDim == iZ) {
1866 if (binsZNew->fN == 0)
1867 dataRebinned->SetBinLimits(iDim, axisZ->GetXmin(), axisZ->GetXmax());
1868 else
1869 dataRebinned->SetBinLimits(iDim, binsZNew->fArray);
1870 }
1871 else if (iDim == iXi) {
1872 if (binsXiNew->fN == 0)
1873 dataRebinned->SetBinLimits(iDim, axisXi->GetXmin(), axisXi->GetXmax());
1874 else
1875 dataRebinned->SetBinLimits(iDim, binsXiNew->fArray);
1876 }
1877 else {
1878 dataRebinned->SetBinLimits(iDim, data->GetBinLimits(iDim));
1879 }
1880 }
1881
1882 for (Int_t iStep = 0; iStep < data->GetNStep(); iStep++)
1883 dataRebinned->SetStepTitle(iStep, data->GetStepTitle(iStep));
1884
1885 Int_t coord[nEffDims];
1886 Double_t binCenterCoord[nEffDims];
1887
1888 // Fill content from old grid into the new grid with proper binning
1889 for (Int_t iStep = 0; iStep < data->GetNStep(); iStep++) {
1890 Long64_t nBinsGrid = data->GetGrid(iStep)->GetGrid()->GetNbins();
1891
1892 for (Long64_t iBin = 0; iBin <= nBinsGrid + 1; iBin++) {
1893 Double_t binContent = data->GetGrid(iStep)->GetGrid()->GetBinContent(iBin, coord);
1894 Double_t binError2 = data->GetGrid(iStep)->GetGrid()->GetBinError2(iBin);
1895
1896 for (Int_t iDim = 0; iDim < nEffDims; iDim++) {
1897 binCenterCoord[iDim] = data->GetBinCenter(iDim, coord[iDim]);
1898 }
1899
1900 Long64_t iBinRebinned = dataRebinned->GetGrid(iStep)->GetGrid()->GetBin(binCenterCoord);
1901 dataRebinned->GetGrid(iStep)->GetGrid()->AddBinContent(iBinRebinned, binContent);
1902 dataRebinned->GetGrid(iStep)->GetGrid()->AddBinError2(iBinRebinned, binError2);
1903 }
1904 }
1905
1906
1907 // If desired, restrict centrality axis
1908 Int_t lowerCentralityBinLimit = -1;
1909 Int_t upperCentralityBinLimit = -2; // Integral(lowerCentBinLimit, uppCentBinLimit) will not be restricted if these values are kept
1910 Bool_t restrictCentralityAxis = kFALSE;
1911 Double_t actualLowerCentrality = -1.;
1912 Double_t actualUpperCentrality = -1.;
1913
1914 if (lowerCentrality >= -1 && upperCentrality >= -1) {
1915 // Add subtract a very small number to avoid problems with values right on the border between to bins
1916 lowerCentralityBinLimit = dataRebinned->GetAxis(iMult, 0)->FindBin(lowerCentrality + 0.001);
1917 upperCentralityBinLimit = dataRebinned->GetAxis(iMult, 0)->FindBin(upperCentrality - 0.001);
1918
1919 // Check if the values look reasonable
1920 if (lowerCentralityBinLimit <= upperCentralityBinLimit && lowerCentralityBinLimit >= 1
1921 && upperCentralityBinLimit <= dataRebinned->GetAxis(iMult, 0)->GetNbins()) {
1922 actualLowerCentrality = dataRebinned->GetAxis(iMult, 0)->GetBinLowEdge(lowerCentralityBinLimit);
1923 actualUpperCentrality = dataRebinned->GetAxis(iMult, 0)->GetBinUpEdge(upperCentralityBinLimit);
1924
1925 restrictCentralityAxis = kTRUE;
1926 }
1927 else {
1928 std::cout << std::endl;
1929 std::cout << "Requested centrality range out of limits or upper and lower limit are switched!" << std::endl;
1930 return -1;
1931 }
1932 }
1933
1934 std::cout << "centrality: ";
1935 if (restrictCentralityAxis) {
1936 std::cout << actualLowerCentrality << " - " << actualUpperCentrality << std::endl;
1937 dataRebinned->SetRangeUser(iMult, lowerCentralityBinLimit, upperCentralityBinLimit, kTRUE);
1938 data->SetRangeUser(iMult, lowerCentralityBinLimit, upperCentralityBinLimit, kTRUE);
1939 }
1940 else {
1941 std::cout << "All" << std::endl;
1942 }
1943
1944
1945
1946 // If desired, restrict jetPt axis
1947 Int_t lowerJetPtBinLimit = -1;
1948 Int_t upperJetPtBinLimit = -2; // Integral(lowerJetBinLimit, uppJetBinLimit) will not be restricted if these values are kept
1949 Bool_t restrictJetPtAxis = kFALSE;
1950 Double_t actualLowerJetPt = -1.;
1951 Double_t actualUpperJetPt = -1.;
1952
1953 if (lowerJetPt >= 0 && upperJetPt >= 0) {
1954 // Add subtract a very small number to avoid problems with values right on the border between to bins
1955 lowerJetPtBinLimit = dataRebinned->GetAxis(iJetPt, 0)->FindBin(lowerJetPt + 0.001);
1956 upperJetPtBinLimit = dataRebinned->GetAxis(iJetPt, 0)->FindBin(upperJetPt - 0.001);
1957
1958 // Check if the values look reasonable
1959 if (lowerJetPtBinLimit <= upperJetPtBinLimit && lowerJetPtBinLimit >= 1 &&
1960 upperJetPtBinLimit <= dataRebinned->GetAxis(iJetPt, 0)->GetNbins()) {
1961 actualLowerJetPt = dataRebinned->GetAxis(iJetPt, 0)->GetBinLowEdge(lowerJetPtBinLimit);
1962 actualUpperJetPt = dataRebinned->GetAxis(iJetPt, 0)->GetBinUpEdge(upperJetPtBinLimit);
1963
1964 restrictJetPtAxis = kTRUE;
1965 }
1966 else {
1967 std::cout << std::endl;
1968 std::cout << "Requested jet pT range out of limits or upper and lower limit are switched!" << std::endl;
1969 return -1;
1970 }
1971 }
1972
1973 std::cout << "jet pT: ";
1974 if (restrictJetPtAxis) {
1975 std::cout << actualLowerJetPt << " - " << actualUpperJetPt << std::endl;
1976 dataRebinned->SetRangeUser(iJetPt, lowerJetPtBinLimit, upperJetPtBinLimit, kTRUE);
1977 data->SetRangeUser(iJetPt, lowerJetPtBinLimit, upperJetPtBinLimit, kTRUE);
1978 }
1979 else {
1980 std::cout << "All" << std::endl;
1981 }
1982
1983 if (restrictJetPtAxis &&
1984 (TMath::Abs(actualLowerJetPt - actualLowerJetPtYields) > 1e-3 || TMath::Abs(actualUpperJetPt - actualUpperJetPtYields) > 1e-3)) {
1985 std::cout << "ERROR: Disagreement between jetPt bounds of data and efficiency!" << std::endl;
1986 return -1;
1987 }
1988
1989 // If desired, restrict charge axis
1990 std::cout << "Charge selection (efficiency): ";
1991 if (chargeMode == kAllCharged)
1992 std::cout << "All charged particles" << std::endl;
1993 else if (chargeMode == kNegCharge)
1994 std::cout << "Negative particles only" << std::endl;
1995 else if (chargeMode == kPosCharge)
1996 std::cout << "Positive particles only" << std::endl;
1997 else {
1998 std::cout << "Unknown -> ERROR" << std::endl;
1999 return -1;
2000 }
2001
2002 const Bool_t restrictCharge = (chargeMode != kAllCharged);
2003
2004 Int_t lowerChargeBinLimit = -1;
2005 Int_t upperChargeBinLimit = -2;
2006 Double_t actualLowerCharge = -999;
2007 Double_t actualUpperCharge = -999;
2008
2009 if (restrictCharge) {
2010 // Add subtract a very small number to avoid problems with values right on the border between to bins
2011 if (chargeMode == kNegCharge) {
2012 lowerChargeBinLimit = dataRebinned->GetAxis(iCharge, 0)->FindBin(-1. + 0.001);
2013 upperChargeBinLimit = dataRebinned->GetAxis(iCharge, 0)->FindBin(0. - 0.001);
2014 }
2015 else if (chargeMode == kPosCharge) {
2016 lowerChargeBinLimit = dataRebinned->GetAxis(iCharge, 0)->FindBin(0. + 0.001);
2017 upperChargeBinLimit = dataRebinned->GetAxis(iCharge, 0)->FindBin(1. - 0.001);
2018 }
2019
2020 // Check if the values look reasonable
2021 if (lowerChargeBinLimit <= upperChargeBinLimit && lowerChargeBinLimit >= 1
2022 && upperChargeBinLimit <= dataRebinned->GetAxis(iCharge, 0)->GetNbins()) {
2023 actualLowerCharge = dataRebinned->GetAxis(iCharge, 0)->GetBinLowEdge(lowerChargeBinLimit);
2024 actualUpperCharge = dataRebinned->GetAxis(iCharge, 0)->GetBinUpEdge(upperChargeBinLimit);
2025
2026 std::cout << "Charge range (efficiency): " << actualLowerCharge << " - " << actualUpperCharge << std::endl;
2027 }
2028 else {
2029 std::cout << std::endl;
2030 std::cout << "Requested charge range (efficiency) out of limits or upper and lower limit are switched!" << std::endl;
2031 return -1;
2032 }
2033
2034 dataRebinned->SetRangeUser(iCharge, lowerChargeBinLimit, upperChargeBinLimit, kTRUE);
2035 data->SetRangeUser(iCharge, lowerChargeBinLimit, upperChargeBinLimit, kTRUE);
2036 }
2037
2038 std::cout << std::endl;
2039
2040
2041 // Load numJet histos from bhess_PID*.root file related to efficiency file.
2042 TString pathNameDataMC = pathNameEfficiency;
2043 pathNameDataMC.ReplaceAll("_efficiency", "");
2044
2045 TFile* fDataMC = TFile::Open(pathNameDataMC.Data());
2046 if (!fDataMC) {
2047 std::cout << std::endl;
2048 std::cout << "Failed to open file \"" << pathNameData.Data() << "\" to obtain num of rec/gen jets!" << std::endl;
2049
2050 return -1;
2051 }
2052
2053 TString listName = pathNameDataMC;
2054 listName.Replace(0, listName.Last('/') + 1, "");
2055 listName.ReplaceAll(".root", "");
2056
2057 TObjArray* histList = (TObjArray*)(fDataMC->Get(listName.Data()));
2058 if (!histList) {
2059 std::cout << std::endl;
2060 std::cout << "Failed to load list \"" << listName.Data() << "\" to obtain num of rec/gen jets!" << std::endl;
2061 return -1;
2062 }
2063
2064 hNjetsGen = (TH2D*)histList->FindObject("fh2FFJetPtGen");
2065 hNjetsRec = (TH2D*)histList->FindObject("fh2FFJetPtRec");
2066
2067 if (!hNjetsRec || !hNjetsGen) {
2068 std::cout << "Failed to load number of jets histos!" << std::endl;
2069
2070
2071 // For backward compatibility (TODO REMOVE IN FUTURE): Load info from fixed AnalysisResults file (might be wrong, if other
2072 // period is considered; also: No multiplicity information)
2073 TString pathEfficiency = pathNameEfficiency;
2074 pathEfficiency.Replace(pathEfficiency.Last('/'), pathEfficiency.Length(), "");
2075 TString pathBackward = Form("%s/AnalysisResults.root", pathEfficiency.Data());
2076 TFile* fBackward = TFile::Open(pathBackward.Data());
2077
2078 TString dirDataInFile = "";
2079 TDirectory* dirData = fBackward ? (TDirectory*)fBackward->Get(fBackward->GetListOfKeys()->At(0)->GetName()) : 0x0;
2080
2081 TList* list = dirData ? (TList*)dirData->Get(dirData->GetListOfKeys()->At(0)->GetName()) : 0x0;
2082
2083 TH1D* hFFJetPtRec = list ? (TH1D*)list->FindObject("fh1FFJetPtRecCutsInc") : 0x0;
2084 TH1D* hFFJetPtGen = list ? (TH1D*)list->FindObject("fh1FFJetPtGenInc") : 0x0;
2085
2086 if (hFFJetPtRec && hFFJetPtGen) {
2087 printf("***WARNING: For backward compatibility, using file \"%s\" to get number of jets. BUT: Might be wrong period and has no mult info!***\n",
2088 pathBackward.Data());
2089 printf("ALSO: Using Njets for inclusive jets!!!!\n");
2090
2091 hNjetsRec = new TH2D("fh2FFJetPtRec", "", 1, -1, 1, dataRebinned->GetAxis(iJetPt, 0)->GetNbins(),
2092 dataRebinned->GetAxis(iJetPt, 0)->GetXbins()->GetArray());
2093
2094 for (Int_t iJet = 1; iJet <= hNjetsRec->GetNbinsY(); iJet++) {
2095 Int_t lowerBin = hFFJetPtRec->FindBin(hNjetsRec->GetYaxis()->GetBinLowEdge(iJet) + 1e-3);
2096 Int_t upperBin = hFFJetPtRec->FindBin(hNjetsRec->GetYaxis()->GetBinUpEdge(iJet) - 1e-3);
2097 hNjetsRec->SetBinContent(1, iJet, hFFJetPtRec->Integral(lowerBin, upperBin));
2098 }
2099
2100 hNjetsGen = new TH2D("fh2FFJetPtGen", "", 1, -1, 1, dataRebinned->GetAxis(iJetPt, 0)->GetNbins(),
2101 dataRebinned->GetAxis(iJetPt, 0)->GetXbins()->GetArray());
2102
2103 for (Int_t iJet = 1; iJet <= hNjetsGen->GetNbinsY(); iJet++) {
2104 Int_t lowerBin = hFFJetPtGen->FindBin(hNjetsGen->GetYaxis()->GetBinLowEdge(iJet) + 1e-3);
2105 Int_t upperBin = hFFJetPtGen->FindBin(hNjetsGen->GetYaxis()->GetBinUpEdge(iJet) - 1e-3);
2106 hNjetsGen->SetBinContent(1, iJet, hFFJetPtGen->Integral(lowerBin, upperBin));
2107 }
2108 }
2109
2110 if (!hNjetsRec || ! hNjetsGen)
2111 return -1;
2112 }
2113
2114 // For normalisation to number of jets
2115 // NOTE: These numbers are for the efficiency only! The data will be normalised to its own number!!!
2116 const Double_t nJetsGen = hNjetsGen ? hNjetsGen->Integral(lowerCentralityBinLimit, upperCentralityBinLimit, lowerJetPtBinLimit,
2117 upperJetPtBinLimit) : 1.;
2118 const Double_t nJetsRec = hNjetsRec ? hNjetsRec->Integral(lowerCentralityBinLimit, upperCentralityBinLimit, lowerJetPtBinLimit,
2119 upperJetPtBinLimit) : 1.;
2120
2121
2122
2123 // Secondary correction
2124 AliCFEffGrid* sec = new AliCFEffGrid("sec", "Secondary Contamination", *dataRebinned);
2125 sec->CalculateEfficiency(kStepRecWithRecCutsMeasuredObsPrimaries, kStepRecWithRecCutsMeasuredObs);
2126
2127 TH1 *hSecAllPt = 0x0, *hSecID2Pt = 0x0;
2128 TH1D* hSecPt[AliPID::kSPECIES] = { 0x0, };
2129 TH1D* hSecToPiRatioPt[AliPID::kSPECIES] = { 0x0, };
2130 TCanvas *cSecPt = 0x0;
2131 TCanvas *cSecToPiRatioPt = 0x0;
2132
2133 TH1 *hSecAllZ = 0x0, *hSecID2Z = 0x0;
2134 TH1D* hSecZ[AliPID::kSPECIES] = { 0x0, };
2135 TH1D* hSecToPiRatioZ[AliPID::kSPECIES] = { 0x0, };
2136 TCanvas *cSecZ = 0x0;
2137 TCanvas *cSecToPiRatioZ = 0x0;
2138
2139 TH1 *hSecAllXi = 0x0, *hSecID2Xi = 0x0;
2140 TH1D* hSecXi[AliPID::kSPECIES] = { 0x0, };
2141 TH1D* hSecToPiRatioXi[AliPID::kSPECIES] = { 0x0, };
2142 TCanvas *cSecXi = 0x0;
2143 TCanvas *cSecToPiRatioXi = 0x0;
2144
2145 // Secondary correction with strangeness scaling
2146 AliCFEffGrid* secStrangeScale = new AliCFEffGrid("secStrangeScale", "Secondary Contamination with strangeness scaling",
2147 *dataRebinned);
2148 secStrangeScale->CalculateEfficiency(kStepRecWithRecCutsMeasuredObsPrimaries, kStepRecWithRecCutsMeasuredObsStrangenessScaled);
2149
2150 TH1 *hSecSSAllPt = 0x0, *hSecSSID2Pt = 0x0;
2151 TH1D* hSecSSPt[AliPID::kSPECIES] = { 0x0, };
2152 TH1D* hSecSSToPiRatioPt[AliPID::kSPECIES] = { 0x0, };
2153 TCanvas *cSecSSPt = 0x0;
2154 TCanvas *cSecSSToPiRatioPt = 0x0;
2155
2156 TH1 *hSecSSAllZ = 0x0, *hSecSSID2Z = 0x0;
2157 TH1D* hSecSSZ[AliPID::kSPECIES] = { 0x0, };
2158 TH1D* hSecSSToPiRatioZ[AliPID::kSPECIES] = { 0x0, };
2159 TCanvas *cSecSSZ = 0x0;
2160 TCanvas *cSecSSToPiRatioZ = 0x0;
2161
2162 TH1 *hSecSSAllXi = 0x0, *hSecSSID2Xi = 0x0;
2163 TH1D* hSecSSXi[AliPID::kSPECIES] = { 0x0, };
2164 TH1D* hSecSSToPiRatioXi[AliPID::kSPECIES] = { 0x0, };
2165 TCanvas *cSecSSXi = 0x0;
2166 TCanvas *cSecSSToPiRatioXi = 0x0;
2167
2168
2169 const Double_t upperTrackPt = restrictJetPtAxis ? actualUpperJetPt : 50.;
2170
2171 TString strangenessString[2] = { "", "SS" };
2172
2173 // Get the secondary contamination vs. pT,z,xi for each species w/ and w/o strangeness scaling
2174
2175 for (Int_t type = 0; type < kNtypes; type++) {
2176 for (Int_t strangenessScaling = 0; strangenessScaling < 2; strangenessScaling++) {
2177 TH1 **hSecAll, **hSecID2;
2178 TH1D **hSec, **hSecToPiRatio;
2179 TCanvas **cSec, **cSecToPiRatio;
2180
2181 Int_t iDimProj = -1;
2182
2183 AliCFEffGrid* secCurr = strangenessScaling ? secStrangeScale : sec;
2184
2185 if (type == kTrackPt) {
2186 hSecAll = strangenessScaling ? &hSecSSAllPt : &hSecAllPt;
2187 hSecID2 = strangenessScaling ? &hSecSSID2Pt : &hSecID2Pt;
2188 hSec = strangenessScaling ? &hSecSSPt[0] : &hSecPt[0];
2189 hSecToPiRatio = strangenessScaling ? &hSecSSToPiRatioPt[0] : &hSecToPiRatioPt[0];
2190 cSec = strangenessScaling ? &cSecSSPt : &cSecPt;
2191 cSecToPiRatio = strangenessScaling ? &cSecSSToPiRatioPt : &cSecToPiRatioPt;
2192 iDimProj = iPt;
2193 }
2194 else if (type == kZ) {
2195 hSecAll = strangenessScaling ? &hSecSSAllZ : &hSecAllZ;
2196 hSecID2 = strangenessScaling ? &hSecSSID2Z : &hSecID2Z;
2197 hSec = strangenessScaling ? &hSecSSZ[0] : &hSecZ[0];
2198 hSecToPiRatio = strangenessScaling ? &hSecSSToPiRatioZ[0] : &hSecToPiRatioZ[0];
2199 cSec = strangenessScaling ? &cSecSSZ : &cSecZ;
2200 cSecToPiRatio = strangenessScaling ? &cSecSSToPiRatioZ : &cSecToPiRatioZ;
2201 iDimProj = iZ;
2202 }
2203 else if (type == kXi) {
2204 hSecAll = strangenessScaling ? &hSecSSAllXi : &hSecAllXi;
2205 hSecID2 = strangenessScaling ? &hSecSSID2Xi : &hSecID2Xi;
2206 hSec = strangenessScaling ? &hSecSSXi[0] : &hSecXi[0];
2207 hSecToPiRatio = strangenessScaling ? &hSecSSToPiRatioXi[0] : &hSecToPiRatioXi[0];
2208 cSec = strangenessScaling ? &cSecSSXi : &cSecXi;
2209 cSecToPiRatio = strangenessScaling ? &cSecSSToPiRatioXi : &cSecToPiRatioXi;
2210 iDimProj = iXi;
2211 }
2212 else
2213 continue;
2214
2215 *hSecAll = secCurr->Project(iDimProj);
2216 (*hSecAll)->SetName(Form("hSec%s_%s_all", strangenessString[strangenessScaling].Data(), titles[type].Data()));
2217 (*hSecAll)->SetTitle("All");
2218 (*hSecAll)->SetMarkerStyle(24);
2219 (*hSecAll)->SetLineWidth(2.);
2220 (*hSecAll)->SetStats(kFALSE);
2221 (*hSecAll)->GetYaxis()->SetTitle("Primary Fraction");
2222 (*hSecID2) = (TH2D*)secCurr->Project(iDimProj, iMCid);
2223 (*hSecID2)->SetName(Form("hSecID2_%s", titles[type].Data()));
2224
2225 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
2226 hSec[species] = ((TH2D*)*hSecID2)->ProjectionX(Form("hSec%s_%s_%s", strangenessString[strangenessScaling].Data(),
2227 titles[type].Data(), AliPID::ParticleShortName(species)),
2228 species + 1, species + 1, "e");
2229 hSec[species]->SetTitle(Form("%s", AliPID::ParticleLatexName(species)));
2230 hSec[species]->SetLineColor(getLineColorAliPID(species));
2231 hSec[species]->SetMarkerColor(getLineColorAliPID(species));
2232 hSec[species]->SetMarkerStyle(24);
2233 hSec[species]->SetLineWidth(2.);
2234 hSec[species]->GetYaxis()->SetRangeUser(0., 1.01);
2235 hSec[species]->SetStats(kFALSE);
2236 hSec[species]->GetYaxis()->SetTitle("Primary Fraction");
2237 }
2238
2239 *cSec = new TCanvas(Form("cSec%s_%s", strangenessString[strangenessScaling].Data(), titles[type].Data()),
2240 Form("Primary fraction for different species%s", strangenessScaling ? " (strangeness scaled)" : ""),
2241 100, 10, 1200, 800);
2242 (*cSec)->cd();
2243 (*cSec)->SetGridx(1);
2244 (*cSec)->SetGridy(1);
2245
2246 if (type == kTrackPt)
2247 (*hSecAll)->GetXaxis()->SetRangeUser(0.15, upperTrackPt);
2248
2249 (*hSecAll)->Draw("E1");
2250
2251 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2252 if (type == kTrackPt)
2253 hSec[i]->GetXaxis()->SetRangeUser(0.15, upperTrackPt);
2254
2255 hSec[i]->Draw("E1 same");
2256 }
2257 (*cSec)->BuildLegend()->SetFillColor(kWhite);
2258
2259 ClearTitleFromHistoInCanvas(*cSec);
2260
2261 // To-pi ratios
2262 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
2263 if (species == AliPID::kPion)
2264 continue; // Do not consider pion-to-pion ratio
2265
2266 hSecToPiRatio[species] = new TH1D(*hSec[species]);
2267 hSecToPiRatio[species]->Reset();
2268 hSecToPiRatio[species]->SetName(Form("hSec%sToPionRatio_%s_%s", strangenessString[strangenessScaling].Data(),
2269 titles[type].Data(), AliPID::ParticleShortName(species)));
2270 hSecToPiRatio[species]->SetTitle(Form("%s/#pi", AliPID::ParticleLatexName(species)));
2271 hSecToPiRatio[species]->SetLineColor(getLineColorAliPID(species));
2272 hSecToPiRatio[species]->SetMarkerColor(getLineColorAliPID(species));
2273 hSecToPiRatio[species]->SetMarkerStyle(24);
2274 hSecToPiRatio[species]->SetLineWidth(2.);
2275 hSecToPiRatio[species]->SetStats(kFALSE);
2276 hSecToPiRatio[species]->GetYaxis()->SetTitle("Primary Fraction of Ratio");
2277
2278 // Samples for different species are independent, so just divide correction factors
2279 hSecToPiRatio[species]->Divide(hSec[species], hSec[AliPID::kPion], 1., 1., "");
2280 hSecToPiRatio[species]->GetYaxis()->SetRangeUser(0., 1.1);
2281 }
2282
2283 *cSecToPiRatio = new TCanvas(Form("cSec%sToPiRatio_%s", strangenessString[strangenessScaling].Data(), titles[type].Data()),
2284 Form("Primary fraction of to-#pi-ratio for different species%s",
2285 strangenessScaling ? " (strangeness scaled)" : ""),
2286 100, 10, 1200, 800);
2287 (*cSecToPiRatio)->cd();
2288 (*cSecToPiRatio)->SetGridx(1);
2289 (*cSecToPiRatio)->SetGridy(1);
2290
2291 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2292 if (i == AliPID::kPion)
2293 continue;
2294
2295 if (type == kTrackPt)
2296 hSecToPiRatio[i]->GetXaxis()->SetRangeUser(0.15, upperTrackPt);
2297
2298 hSecToPiRatio[i]->Draw(Form("E1%s", i == 0 ? "" : " same"));
2299 }
2300 (*cSecToPiRatio)->BuildLegend()->SetFillColor(kWhite);
2301
2302 ClearTitleFromHistoInCanvas(*cSecToPiRatio);
2303 }
2304 }
2305
2306
2307 // Construct the efficiency grid from the data container
2308 // NOTE: Here, the scale factors 1/nJet are different. This effects the error of the ratio.
2309 // Thus, the histograms must be extracted, scaled and THEN divided to arrive at the correction
2310 // factor and the standard "calculateEfficiency" function CANNOT be used (multiplying the ratio
2311 // of the scale factor afterwards would result in wrong errors)
2312
2313
2314
2315 // If desired, apply the GEANT/FLUKA correction first
2316 // NOTE: This will change dataRebinned! If anything else should also be calculated, it must be done before.
2317 // Otherwise, the GEANT/FLUKA correction factor for the efficiency will also affect it!
2318 const Int_t genStepEff = kStepGenWithGenCuts;
2319 if (correctGeantFluka) {
2320 printf("Applying GEANT/FLUKA correction...\n");
2321 if (!geantFlukaCorrection(dataRebinned, genStepEff)) {
2322 printf("GEANT/FLUKA correction could not be applied!\n");
2323 return kFALSE;
2324 }
2325 }
2326
2327
2328 // Either one can take kStepRecWithGenCutsMeasuredObs or, what I prefer, one can take
2329 // kStepRecWithRecCutsMeasuredObsPrimaries => The difference is only the eta cut, which is on the rec level
2330 // in the latter case, i.e. one corrects for eta resolution (although the effect should be very small)
2331 const Int_t recStepEff = kStepRecWithRecCutsMeasuredObsPrimaries;
2332
2333 // The efficiency vs. pT, z, xi
2334 TH1* hSpecPt_RecPrimaries = 0x0;
2335 TH1* hSpecPt_GenPrimaries = 0x0;
2336 TH1D* hEfficiencyAllPt = 0x0;
2337
2338 TH2* hSpecID2Pt_RecPrimaries = 0x0;
2339 TH2* hSpecID2Pt_GenPrimaries = 0x0;
2340 TH2D* hEffID2Pt = 0x0;
2341
2342 TH1D* hSpecIDPt_GenPrimaries[AliPID::kSPECIES] = { 0x0, };
2343 TH1D* hSpecIDPt_RecPrimaries[AliPID::kSPECIES] = { 0x0, };
2344 TH1D* hEfficiencyPt[AliPID::kSPECIES] = { 0x0, };
2345 TH1D* hEfficiencyToPiRatioPt[AliPID::kSPECIES] = { 0x0, };
2346
2347 TCanvas *cSpecPt = 0x0, *cEffPt = 0x0, *cEffToPiRatioPt = 0x0;
2348
2349
2350 TH1* hSpecZ_RecPrimaries = 0x0;
2351 TH1* hSpecZ_GenPrimaries = 0x0;
2352 TH1D* hEfficiencyAllZ = 0x0;
2353
2354 TH2* hSpecID2Z_RecPrimaries = 0x0;
2355 TH2* hSpecID2Z_GenPrimaries = 0x0;
2356 TH2D* hEffID2Z = 0x0;
2357
2358 TH1D* hSpecIDZ_GenPrimaries[AliPID::kSPECIES] = { 0x0, };
2359 TH1D* hSpecIDZ_RecPrimaries[AliPID::kSPECIES] = { 0x0, };
2360 TH1D* hEfficiencyZ[AliPID::kSPECIES] = { 0x0, };
2361 TH1D* hEfficiencyToPiRatioZ[AliPID::kSPECIES] = { 0x0, };
2362
2363 TCanvas *cSpecZ = 0x0, *cEffZ = 0x0, *cEffToPiRatioZ = 0x0;
2364
2365
2366 TH1* hSpecXi_RecPrimaries = 0x0;
2367 TH1* hSpecXi_GenPrimaries = 0x0;
2368 TH1D* hEfficiencyAllXi = 0x0;
2369
2370 TH2* hSpecID2Xi_RecPrimaries = 0x0;
2371 TH2* hSpecID2Xi_GenPrimaries = 0x0;
2372 TH2D* hEffID2Xi = 0x0;
2373
2374 TH1D* hSpecIDXi_GenPrimaries[AliPID::kSPECIES] = { 0x0, };
2375 TH1D* hSpecIDXi_RecPrimaries[AliPID::kSPECIES] = { 0x0, };
2376 TH1D* hEfficiencyXi[AliPID::kSPECIES] = { 0x0, };
2377 TH1D* hEfficiencyToPiRatioXi[AliPID::kSPECIES] = { 0x0, };
2378
2379 TCanvas *cSpecXi = 0x0, *cEffXi = 0x0, *cEffToPiRatioXi = 0x0;
2380
2381 TString titleYaxis[kNtypes];
2382 titleYaxis[kTrackPt] = "1/N_{Jets} dN/dP_{T} (GeV/c)^{-1}";
2383 titleYaxis[kZ] = "1/N_{Jets} dN/dz";
2384 titleYaxis[kXi] = "1/N_{Jets} dN/d#xi";
2385
2386 for (Int_t type = 0; type < kNtypes; type++) {
2387 TH1** hSpec_RecPrimaries;
2388 TH1** hSpec_GenPrimaries;
2389 TH1D** hEfficiencyAll;
2390
2391 TH2** hSpecID2_RecPrimaries;
2392 TH2** hSpecID2_GenPrimaries;
2393 TH2D** hEffID2;
2394
2395 TH1D** hSpecID_GenPrimaries;
2396 TH1D** hSpecID_RecPrimaries;
2397 TH1D** hEfficiency;
2398 TH1D** hEfficiencyToPiRatio;
2399
2400 TCanvas **cSpec, **cEff, **cEffToPiRatio;
2401
2402 Int_t iDimProj = -1;
2403
2404
2405 if (type == kTrackPt) {
2406 hSpec_RecPrimaries = &hSpecPt_RecPrimaries;
2407 hSpec_GenPrimaries = &hSpecPt_GenPrimaries;
2408 hEfficiencyAll = &hEfficiencyAllPt;
2409
2410 hSpecID2_RecPrimaries = &hSpecID2Pt_RecPrimaries;
2411 hSpecID2_GenPrimaries = &hSpecID2Pt_GenPrimaries;
2412 hEffID2 = &hEffID2Pt;
2413
2414 hSpecID_RecPrimaries = &hSpecIDPt_RecPrimaries[0];
2415 hSpecID_GenPrimaries = &hSpecIDPt_GenPrimaries[0];
2416 hEfficiency = &hEfficiencyPt[0];
2417 hEfficiencyToPiRatio = &hEfficiencyToPiRatioPt[0];
2418
2419 cSpec = &cSpecPt;
2420 cEff = &cEffPt;
2421 cEffToPiRatio = &cEffToPiRatioPt;
2422
2423 iDimProj = iPt;
2424 }
2425 else if (type == kZ) {
2426 hSpec_RecPrimaries = &hSpecZ_RecPrimaries;
2427 hSpec_GenPrimaries = &hSpecZ_GenPrimaries;
2428 hEfficiencyAll = &hEfficiencyAllZ;
2429
2430 hSpecID2_RecPrimaries = &hSpecID2Z_RecPrimaries;
2431 hSpecID2_GenPrimaries = &hSpecID2Z_GenPrimaries;
2432 hEffID2 = &hEffID2Z;
2433
2434 hSpecID_RecPrimaries = &hSpecIDZ_RecPrimaries[0];
2435 hSpecID_GenPrimaries = &hSpecIDZ_GenPrimaries[0];
2436 hEfficiency = &hEfficiencyZ[0];
2437 hEfficiencyToPiRatio = &hEfficiencyToPiRatioZ[0];
2438
2439 cSpec = &cSpecZ;
2440 cEff = &cEffZ;
2441 cEffToPiRatio = &cEffToPiRatioZ;
2442
2443 iDimProj = iZ;
2444 }
2445 else if (type == kXi) {
2446 hSpec_RecPrimaries = &hSpecXi_RecPrimaries;
2447 hSpec_GenPrimaries = &hSpecXi_GenPrimaries;
2448 hEfficiencyAll = &hEfficiencyAllXi;
2449
2450 hSpecID2_RecPrimaries = &hSpecID2Xi_RecPrimaries;
2451 hSpecID2_GenPrimaries = &hSpecID2Xi_GenPrimaries;
2452 hEffID2 = &hEffID2Xi;
2453
2454 hSpecID_RecPrimaries = &hSpecIDXi_RecPrimaries[0];
2455 hSpecID_GenPrimaries = &hSpecIDXi_GenPrimaries[0];
2456 hEfficiency = &hEfficiencyXi[0];
2457 hEfficiencyToPiRatio = &hEfficiencyToPiRatioXi[0];
2458
2459 cSpec = &cSpecXi;
2460 cEff = &cEffXi;
2461 cEffToPiRatio = &cEffToPiRatioXi;
2462
2463 iDimProj = iXi;
2464 }
2465 else
2466 continue;
2467
2468
2469 // Divide steps: recStepEff (=kStepRecWithRecCutsMeasuredObsPrimaries) / genStepEff (=kStepGenWithGenCuts)
2470 *hSpec_RecPrimaries = dataRebinned->GetGrid(recStepEff)->Project(iDimProj);
2471 setupHist(*hSpec_RecPrimaries, Form("hSpec_%s_RecPrimaries", titles[type].Data()), "All, rec", "",
2472 titleYaxis[type].Data(), kBlack);
2473 normaliseHist(*hSpec_RecPrimaries, nJetsRec > 0 ? 1. / nJetsRec : 0.);
2474 (*hSpec_RecPrimaries)->SetLineWidth(2.);
2475 (*hSpec_RecPrimaries)->SetMarkerStyle(20);
2476
2477 *hSpec_GenPrimaries = dataRebinned->GetGrid(genStepEff)->Project(iDimProj);
2478 setupHist(*hSpec_GenPrimaries, Form("hSpec_%s_GenPrimaries", titles[type].Data()), "All, gen", "",
2479 titleYaxis[type].Data(), kBlack);
2480 normaliseHist(*hSpec_GenPrimaries, nJetsGen > 0 ? 1. / nJetsGen : 0.);
2481 (*hSpec_GenPrimaries)->SetLineWidth(2.);
2482 (*hSpec_GenPrimaries)->SetLineStyle(2);
2483
2484 *hEfficiencyAll = new TH1D(*(TH1D*)(*hSpec_RecPrimaries));
2485 (*hEfficiencyAll)->SetName(Form("hEfficiencyAll_%s", titles[type].Data()));
2486 (*hEfficiencyAll)->GetYaxis()->SetTitle("");
2487 (*hEfficiencyAll)->SetTitle("All");
2488 (*hEfficiencyAll)->SetLineWidth(2.0);
2489 (*hEfficiencyAll)->SetStats(kFALSE);
2490 (*hEfficiencyAll)->GetYaxis()->SetTitle("Efficiency x Acceptance x pT Resolution");
2491 (*hEfficiencyAll)->GetYaxis()->SetTitleSize(0.05);
2492 (*hEfficiencyAll)->Divide(*hSpec_RecPrimaries, *hSpec_GenPrimaries, 1., 1., "B");
2493 (*hEfficiencyAll)->GetYaxis()->SetRangeUser(0., 2.0);
2494
2495 *hSpecID2_RecPrimaries = (TH2*)dataRebinned->GetGrid(recStepEff)->Project(iDimProj, iMCid);
2496 (*hSpecID2_RecPrimaries)->SetName(Form("hSpecID2_RecPrimaries_%s", titles[type].Data()));
2497 (*hSpecID2_RecPrimaries)->Scale(nJetsRec > 0 ? 1. / nJetsRec : 0.);
2498
2499 *hSpecID2_GenPrimaries = (TH2*)dataRebinned->GetGrid(genStepEff)->Project(iDimProj, iMCid);
2500 (*hSpecID2_GenPrimaries)->SetName(Form("hSpecID2_GenPrimaries_%s", titles[type].Data()));
2501 (*hSpecID2_GenPrimaries)->Scale(nJetsGen > 0 ? 1. / nJetsGen : 0.);
2502
2503 *hEffID2 = new TH2D(*(TH2D*)(*hSpecID2_RecPrimaries));
2504 (*hEffID2)->SetName(Form("hEff_%s", titles[type].Data()));
2505 (*hEffID2)->SetTitle("All");
2506 (*hEffID2)->Divide(*hSpecID2_RecPrimaries, *hSpecID2_GenPrimaries, 1., 1., "B");
2507
2508 // Get the efficiencies vs. pT,z,xi for each species
2509 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
2510 hEfficiency[species] = ((TH2D*)*hEffID2)->ProjectionX(Form("hEfficiency_%s_%s", titles[type].Data(),
2511 AliPID::ParticleShortName(species)),
2512 species + 1, species + 1, "e");
2513 setupHist(hEfficiency[species], "", Form("%s", AliPID::ParticleLatexName(species)), "", "",
2514 getLineColorAliPID(species));
2515 hEfficiency[species]->SetLineWidth(2.);
2516 hEfficiency[species]->GetYaxis()->SetRangeUser(0., 2.0);
2517 hEfficiency[species]->SetStats(kFALSE);
2518 hEfficiency[species]->GetYaxis()->SetTitle("Efficiency x Acceptance x pT Resolution");
2519 hEfficiency[species]->GetYaxis()->SetTitleSize(0.05);
2520
2521 hSpecID_GenPrimaries[species] = ((TH2D*)*hSpecID2_GenPrimaries)->ProjectionX(Form("hSpecID_%s_gen_%s",
2522 titles[type].Data(),
2523 AliPID::ParticleShortName(species)),
2524 species + 1, species + 1, "e");
2525 setupHist(hSpecID_GenPrimaries[species], "", Form("%s, gen", AliPID::ParticleLatexName(species)), "",
2526 titleYaxis[type].Data(), getLineColorAliPID(species));
2527 normaliseHist(hSpecID_GenPrimaries[species], 1.);
2528 hSpecID_GenPrimaries[species]->SetLineWidth(2.);
2529 hSpecID_GenPrimaries[species]->SetLineStyle(2.);
2530 hSpecID_GenPrimaries[species]->SetStats(kFALSE);
2531
2532
2533 hSpecID_RecPrimaries[species] = ((TH2D*)*hSpecID2_RecPrimaries)->ProjectionX(Form("hSpecID_%s_rec_%s",
2534 titles[type].Data(),
2535 AliPID::ParticleShortName(species)),
2536 species + 1, species + 1, "e");
2537 setupHist(hSpecID_RecPrimaries[species], "", Form("%s, rec", AliPID::ParticleLatexName(species)), "",
2538 titleYaxis[type].Data(), getLineColorAliPID(species));
2539 normaliseHist(hSpecID_RecPrimaries[species], 1.);
2540 hSpecID_RecPrimaries[species]->SetLineWidth(2.);
2541 hSpecID_RecPrimaries[species]->SetMarkerStyle(20);
2542 hSpecID_RecPrimaries[species]->SetStats(kFALSE);
2543 }
2544
2545 *cSpec = new TCanvas(Form("cSpec_%s", titles[type].Data()), "Spectra for different species", 0, 300, 900, 900);
2546 (*cSpec)->cd();
2547 (*cSpec)->SetGridx(1);
2548 (*cSpec)->SetGridy(1);
2549 (*cSpec)->SetLogy(1);
2550
2551 if (type == kTrackPt)
2552 (*hSpec_GenPrimaries)->GetYaxis()->SetRangeUser(1e-8, 1e2);
2553 else if (type == kZ)
2554 (*hSpec_GenPrimaries)->GetYaxis()->SetRangeUser(1e-5, 1e3);
2555 else if (type == kXi)
2556 (*hSpec_GenPrimaries)->GetYaxis()->SetRangeUser(1e-5, 1e3);
2557
2558
2559 if (type == kTrackPt)
2560 (*hSpec_GenPrimaries)->GetXaxis()->SetRangeUser(0.15, upperTrackPt);
2561 (*hSpec_GenPrimaries)->Draw("E1");
2562
2563 if (type == kTrackPt)
2564 (*hSpec_RecPrimaries)->GetXaxis()->SetRangeUser(0.15, upperTrackPt);
2565 (*hSpec_RecPrimaries)->Draw("E1 same");
2566
2567 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2568 if (type == kTrackPt) {
2569 hSpecID_GenPrimaries[i]->GetXaxis()->SetRangeUser(0.15, upperTrackPt);
2570 hSpecID_RecPrimaries[i]->GetXaxis()->SetRangeUser(0.15, upperTrackPt);
2571 }
2572
2573 hSpecIDPt_GenPrimaries[i]->Draw("E1 same");
2574 hSpecIDPt_RecPrimaries[i]->Draw("E1 same");
2575 }
2576 TLegend* leg = (*cSpec)->BuildLegend();
2577 leg->SetFillColor(kWhite);
2578 leg->SetNColumns(2);
2579
2580 ClearTitleFromHistoInCanvas(*cSpec);
2581
2582
2583 *cEff = new TCanvas(Form("cEff_%s", titles[type].Data()), "Efficiency x Acceptance x pT Resolution for different species",
2584 0, 300, 900, 900);
2585 (*cEff)->cd();
2586 (*cEff)->SetGridx(1);
2587 (*cEff)->SetGridy(1);
2588
2589 if (type == kTrackPt)
2590 (*hEfficiencyAll)->GetXaxis()->SetRangeUser(0.15, upperTrackPt);
2591 (*hEfficiencyAll)->Draw("E1");
2592
2593 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2594 if (type == kTrackPt)
2595 hEfficiency[i]->GetXaxis()->SetRangeUser(0.15, upperTrackPt);
2596 hEfficiency[i]->Draw("E1 same");
2597 }
2598 (*cEff)->BuildLegend()->SetFillColor(kWhite);
2599
2600 ClearTitleFromHistoInCanvas(*cEff);
2601
2602
2603 // To-pi ratios
2604 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
2605 if (species == AliPID::kPion)
2606 continue; // Do not consider pion-to-pion ratio
2607
2608 hEfficiencyToPiRatio[species] = new TH1D(*hEfficiency[species]);
2609 hEfficiencyToPiRatio[species]->Reset();
2610 hEfficiencyToPiRatio[species]->SetName(Form("hEfficiency_ToPionRatio_%s_%s", titles[type].Data(),
2611 AliPID::ParticleShortName(species)));
2612
2613 setupHist(hEfficiencyToPiRatio[species], "", Form("%s/#pi", AliPID::ParticleLatexName(species)), "", "",
2614 getLineColorAliPID(species));
2615 hEfficiencyToPiRatio[species]->SetLineWidth(2.);
2616 hEfficiencyToPiRatio[species]->SetStats(kFALSE);
2617 hEfficiencyToPiRatio[species]->GetYaxis()->SetTitle("Efficiency x Acceptance x pT Resolution");
2618 hEfficiencyToPiRatio[species]->GetYaxis()->SetTitleSize(0.05);
2619
2620 // Samples for different species are independent, so just divide correction factors
2621 hEfficiencyToPiRatio[species]->Divide(hEfficiency[species], hEfficiency[AliPID::kPion], 1., 1., "");
2622 hEfficiencyToPiRatio[species]->GetYaxis()->SetRangeUser(0., 2.0);
2623 }
2624
2625 *cEffToPiRatio = new TCanvas(Form("cEffToPiRatio_%s", titles[type].Data()),
2626 "Efficiency x Acceptance x pT Resolution for different to-#pi-ratios",
2627 100, 10, 1200, 800);
2628 (*cEffToPiRatio)->cd();
2629 (*cEffToPiRatio)->SetGridx(1);
2630 (*cEffToPiRatio)->SetGridy(1);
2631
2632 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2633 if (i == AliPID::kPion)
2634 continue;
2635
2636 if (type == kTrackPt)
2637 hEfficiencyToPiRatio[i]->GetXaxis()->SetRangeUser(0.15, upperTrackPt);
2638
2639 hEfficiencyToPiRatio[i]->Draw(Form("E1%s", i == 0 ? "" : " same"));
2640 }
2641 (*cEffToPiRatio)->BuildLegend()->SetFillColor(kWhite);
2642
2643 ClearTitleFromHistoInCanvas(*cEffToPiRatio);
2644 }
2645
2646 // Save results to file
2647 TString chargeString = "";
2648 if (chargeMode == kPosCharge)
2649 chargeString = "_posCharge";
2650 else if (chargeMode == kNegCharge)
2651 chargeString = "_negCharge";
2652
2653 TString saveFileName = pathNameData;
2654 saveFileName.ReplaceAll(Form("%s/", pathData.Data()), "");
2655 saveFileName.Prepend("output_EfficiencyCorrection_");
2656 saveFileName.ReplaceAll(".root", Form("_jetPt%.1f_%.1f%s.root", actualLowerJetPt, actualUpperJetPt, chargeString.Data()));
2657
2658 TString saveFilePathName = Form("%s/%s", pathData.Data(), saveFileName.Data());
2659 TFile* saveFile = TFile::Open(saveFilePathName.Data(), "RECREATE");
2660
2661 if (!saveFile) {
2662 printf("Could not save results!\n");
2663
2664 return -1;
2665 }
2666
2667 saveFile->cd();
2668
2669 if (cSecPt)
2670 cSecPt->Write();
2671
2672 if (cSecSSPt)
2673 cSecSSPt->Write();
2674
2675 if (hSecAllPt)
2676 hSecAllPt->Write();
2677
2678 if (hSecSSAllPt)
2679 hSecSSAllPt->Write();
2680
2681 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2682 if (hSecPt[i])
2683 hSecPt[i]->Write();
2684
2685 if (hSecSSPt[i])
2686 hSecSSPt[i]->Write();
2687 }
2688
2689 if (cSecToPiRatioPt)
2690 cSecToPiRatioPt->Write();
2691
2692 if (cSecSSToPiRatioPt)
2693 cSecSSToPiRatioPt->Write();
2694
2695 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2696 if (hSecToPiRatioPt[i])
2697 hSecToPiRatioPt[i]->Write();
2698
2699 if (hSecSSToPiRatioPt[i])
2700 hSecSSToPiRatioPt[i]->Write();
2701 }
2702
2703
2704
2705 if (cSecZ)
2706 cSecZ->Write();
2707
2708 if (cSecSSZ)
2709 cSecSSZ->Write();
2710
2711 if (hSecAllZ)
2712 hSecAllZ->Write();
2713
2714 if (hSecSSAllZ)
2715 hSecSSAllZ->Write();
2716
2717 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2718 if (hSecZ[i])
2719 hSecZ[i]->Write();
2720
2721 if (hSecSSZ[i])
2722 hSecSSZ[i]->Write();
2723 }
2724
2725 if (cSecToPiRatioZ)
2726 cSecToPiRatioZ->Write();
2727
2728 if (cSecSSToPiRatioZ)
2729 cSecSSToPiRatioZ->Write();
2730
2731 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2732 if (hSecToPiRatioZ[i])
2733 hSecToPiRatioZ[i]->Write();
2734
2735 if (hSecSSToPiRatioZ[i])
2736 hSecSSToPiRatioZ[i]->Write();
2737 }
2738
2739
2740
2741 if (cSecXi)
2742 cSecXi->Write();
2743
2744 if (cSecSSXi)
2745 cSecSSXi->Write();
2746
2747 if (hSecAllXi)
2748 hSecAllXi->Write();
2749
2750 if (hSecSSAllXi)
2751 hSecSSAllXi->Write();
2752
2753 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2754 if (hSecXi[i])
2755 hSecXi[i]->Write();
2756
2757 if (hSecSSXi[i])
2758 hSecSSXi[i]->Write();
2759 }
2760
2761 if (cSecToPiRatioXi)
2762 cSecToPiRatioXi->Write();
2763
2764 if (cSecSSToPiRatioXi)
2765 cSecSSToPiRatioXi->Write();
2766
2767 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2768 if (hSecToPiRatioXi[i])
2769 hSecToPiRatioXi[i]->Write();
2770
2771 if (hSecSSToPiRatioXi[i])
2772 hSecSSToPiRatioXi[i]->Write();
2773 }
2774
2775
2776
2777 if (cSpecPt)
2778 cSpecPt->Write();
2779
2780 if (hSpecPt_RecPrimaries)
2781 hSpecPt_RecPrimaries->Write();
2782
2783 if (hSpecPt_GenPrimaries)
2784 hSpecPt_GenPrimaries->Write();
2785
2786 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2787 if (hSpecIDPt_GenPrimaries[i])
2788 hSpecIDPt_GenPrimaries[i]->Write();
2789
2790 if (hSpecIDPt_RecPrimaries[i])
2791 hSpecIDPt_RecPrimaries[i]->Write();
2792 }
2793
2794
2795 if (cEffPt)
2796 cEffPt->Write();
2797
2798 if (hEfficiencyAllPt)
2799 hEfficiencyAllPt->Write();
2800
2801 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2802 if (hEfficiencyPt[i])
2803 hEfficiencyPt[i]->Write();
2804 }
2805
2806 if (cEffToPiRatioPt)
2807 cEffToPiRatioPt->Write();
2808
2809 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2810 if (hEfficiencyToPiRatioPt[i])
2811 hEfficiencyToPiRatioPt[i]->Write();
2812 }
2813
2814
2815
2816 if (cSpecZ)
2817 cSpecZ->Write();
2818
2819 if (hSpecZ_RecPrimaries)
2820 hSpecZ_RecPrimaries->Write();
2821
2822 if (hSpecZ_GenPrimaries)
2823 hSpecZ_GenPrimaries->Write();
2824
2825 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2826 if (hSpecIDZ_GenPrimaries[i])
2827 hSpecIDZ_GenPrimaries[i]->Write();
2828
2829 if (hSpecIDZ_RecPrimaries[i])
2830 hSpecIDZ_RecPrimaries[i]->Write();
2831 }
2832
2833
2834 if (cEffZ)
2835 cEffZ->Write();
2836
2837 if (hEfficiencyAllZ)
2838 hEfficiencyAllZ->Write();
2839
2840 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2841 if (hEfficiencyZ[i])
2842 hEfficiencyZ[i]->Write();
2843 }
2844
2845 if (cEffToPiRatioZ)
2846 cEffToPiRatioZ->Write();
2847
2848 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2849 if (hEfficiencyToPiRatioZ[i])
2850 hEfficiencyToPiRatioZ[i]->Write();
2851 }
2852
2853
2854
2855 if (cSpecXi)
2856 cSpecXi->Write();
2857
2858 if (hSpecXi_RecPrimaries)
2859 hSpecXi_RecPrimaries->Write();
2860
2861 if (hSpecXi_GenPrimaries)
2862 hSpecXi_GenPrimaries->Write();
2863
2864 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2865 if (hSpecIDXi_GenPrimaries[i])
2866 hSpecIDXi_GenPrimaries[i]->Write();
2867
2868 if (hSpecIDXi_RecPrimaries[i])
2869 hSpecIDXi_RecPrimaries[i]->Write();
2870 }
2871
2872
2873 if (cEffXi)
2874 cEffXi->Write();
2875
2876 if (hEfficiencyAllXi)
2877 hEfficiencyAllXi->Write();
2878
2879 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2880 if (hEfficiencyXi[i])
2881 hEfficiencyXi[i]->Write();
2882 }
2883
2884 if (cEffToPiRatioXi)
2885 cEffToPiRatioXi->Write();
2886
2887 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2888 if (hEfficiencyToPiRatioXi[i])
2889 hEfficiencyToPiRatioXi[i]->Write();
2890 }
2891
2892
2893
2894 // Correct the yields with the efficiencies and primary fractions
2895 for (Int_t type = 0; type < kNtypes; type++) {
2896 TH1D* hYieldCorrected[AliPID::kSPECIES];
2897 TH1D* hYieldCorrectedSysError[AliPID::kSPECIES];
2898
2899 TH1D** hYield;
2900 TH1D** hYieldSysError;
2901 TH1D** hMCgenPrimYield;
2902 TH1D** hSecSS;
2903 TH1D** hSec;
2904 TH1D** hEfficiency;
2905
2906 if (type == kTrackPt) {
2907 hYield = &hYieldPt[0];
2908 hYieldSysError = &hYieldPtSysError[0];
2909 hMCgenPrimYield = &hMCgenPrimYieldPt[0];
2910 hSecSS = &hSecSSPt[0];
2911 hSec = &hSecPt[0];
2912 hEfficiency = &hEfficiencyPt[0];
2913 }
2914 else if (type == kZ) {
2915 hYield = &hYieldZ[0];
2916 hYieldSysError = &hYieldZSysError[0];
2917 hMCgenPrimYield = &hMCgenPrimYieldZ[0];
2918 hSecSS = &hSecSSZ[0];
2919 hSec = &hSecZ[0];
2920 hEfficiency = &hEfficiencyZ[0];
2921 }
2922 else if (type == kXi) {
2923 hYield = &hYieldXi[0];
2924 hYieldSysError = &hYieldXiSysError[0];
2925 hMCgenPrimYield = &hMCgenPrimYieldXi[0];
2926 hSecSS = &hSecSSXi[0];
2927 hSec = &hSecXi[0];
2928 hEfficiency = &hEfficiencyXi[0];
2929 }
2930 else
2931 continue;
2932
2933
2934 // NOTE: The yields have already been normalised to nJets in extractFFs. However, the binning in jetPt might be different now.
2935 // Thus, in order to get the correct result, the old normalisation (just the same binnnig as in the nJet histo) has to be
2936 // undone (was done above) and then it has to be normalised to the number of jets in the new binning again (now).
2937 // Also NOTE: Histos are already normalised to bin width via extractFFs!
2938 const Double_t nJetsGenData = hNjetsGenData ? hNjetsGenData->Integral(lowerCentralityBinLimitData, upperCentralityBinLimitData,
2939 lowerJetPtBinLimitData, upperJetPtBinLimitData) : 1.;
2940 const Double_t nJetsRecData = hNjetsRecData ? hNjetsRecData->Integral(lowerCentralityBinLimitData, upperCentralityBinLimitData,
2941 lowerJetPtBinLimitData, upperJetPtBinLimitData) : 1.;
2942
2943 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
2944 hYield[species]->Scale((nJetsRecData > 0) ? 1. / nJetsRecData : 0.);
2945 hYieldSysError[species]->Scale((nJetsRecData > 0) ? 1. / nJetsRecData : 0.);
2946
2947 hYield[species]->SetStats(kFALSE);
2948 hYieldSysError[species]->SetStats(kFALSE);
2949
2950 if (hMCgenPrimYield[species]) {
2951 hMCgenPrimYield[species]->Scale((nJetsGenData > 0) ? 1. / nJetsGenData : 0.);
2952 hMCgenPrimYield[species]->SetStats(kFALSE);
2953 }
2954
2955 hYield[species]->GetYaxis()->SetTitle(titleYaxis[type].Data());
2956 if (hMCgenPrimYield[species]) {
2957 hMCgenPrimYield[species]->GetYaxis()->SetTitle(titleYaxis[type].Data());
2958 hMCgenPrimYield[species]->SetTitle(Form("%s (MC)", AliPID::ParticleLatexName(species)));
2959 hMCgenPrimYield[species]->SetMarkerStyle(24);
2960 hMCgenPrimYield[species]->SetLineColor(getLineColorAliPID(species));
2961 hMCgenPrimYield[species]->SetMarkerColor(getLineColorAliPID(species));
2962 }
2963
2964 hYield[species]->SetLineColor(getLineColorAliPID(species));
2965 hYield[species]->SetMarkerColor(getLineColorAliPID(species));
2966 hYield[species]->SetMarkerStyle(20);
2967
2968 hYieldSysError[species]->SetLineColor(getLineColorAliPID(species));
2969 hYieldSysError[species]->SetMarkerColor(getLineColorAliPID(species));
2970 hYieldSysError[species]->SetMarkerStyle(20);
2971 hYieldSysError[species]->SetFillStyle(0);
2972
2973 hYieldCorrected[species] = new TH1D(*hYield[species]);
2974 hYieldCorrected[species]->SetName(Form("%s_corrected", hYield[species]->GetName()));
2975 hYieldCorrected[species]->SetTitle(Form("%s", AliPID::ParticleLatexName(species)));
2976
2977 hYieldCorrectedSysError[species] = new TH1D(*hYieldSysError[species]);
2978 hYieldCorrectedSysError[species]->SetName(Form("%s_corrected", hYieldSysError[species]->GetName()));
2979 hYieldCorrectedSysError[species]->SetTitle(Form("%s", AliPID::ParticleLatexName(species)));
2980
2981 // Correction factor histos can have different binning than data histos (constant factor above some threshold)
2982 // -> Need special functions to multiply and divide such histos
2983 multiplyHistsDifferentBinning(hYieldCorrected[species], scaleStrangeness ? hSecSS[species] : hSec[species], 1., 1.);
2984 divideHistsDifferentBinning(hYieldCorrected[species], hEfficiency[species], 1., 1.);
2985
2986 multiplyHistsDifferentBinning(hYieldCorrectedSysError[species], scaleStrangeness ? hSecSS[species] : hSec[species], 1., 1.,
2987 kTRUE);
2988 divideHistsDifferentBinning(hYieldCorrectedSysError[species], hEfficiency[species], 1., 1., kTRUE);
2989
2990 //hYieldCorrected[species]->Multiply(hYieldCorrected[species], scaleStrangeness ? hSecSS[species] : hSec[species], 1., 1.,
2991 //"");
2992 //hYieldCorrected[species]->Divide(hYieldCorrected[species], hEfficiency[species], 1., 1., "");
2993 }
2994
2995 // Calculate the total corrected yield. The original total yield had no error (just the number of detected tracks in a pT bin),
2996 // but due to the correction there is some error for the total yield. Also the error of the fractions introduces uncertainties
2997 // for the yields of individual species
2998 TH1D* hYieldCorrectedTotal = new TH1D(*hYieldCorrected[0]);
2999 hYieldCorrectedTotal->SetLineColor(kBlack);
3000 hYieldCorrectedTotal->SetMarkerColor(kBlack);
3001 hYieldCorrectedTotal->SetMarkerStyle(20);
3002 hYieldCorrectedTotal->SetName(Form("hYieldCorrectedTotal_%s", titles[type].Data()));
3003 hYieldCorrectedTotal->SetTitle("Total");
3004 //hYieldCorrectedTotal->SetTitle("Total, secondary and efficiency x acceptance x pT resolution corrected");
3005
3006 //TODO doesn't it require the covariance matrix here to get the error of the corrected total yield?
3007 // Because before the total count was taken into account just by the fit. Now the fractions and their errors
3008 // influence the MC correction (and its errors), so that there is some error on the corrected total yield.
3009 // However, the errors of the contributing yields are correlated!
3010 for (Int_t i = 1; i < AliPID::kSPECIES; i++)
3011 hYieldCorrectedTotal->Add(hYieldCorrected[i], 1.);
3012
3013 // Calculate the corrected fractions
3014 TH1D* hFractionCorrected[AliPID::kSPECIES];
3015 TH1D* hFractionCorrectedSysError[AliPID::kSPECIES];
3016
3017 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
3018 hFractionCorrected[species] = new TH1D(*hYield[species]);
3019 TString oldName = hYield[species]->GetName();
3020 TString newName = oldName.ReplaceAll("Yield", "Fraction");
3021 hFractionCorrected[species]->SetName(Form("%s_corrected", newName.Data()));
3022 hFractionCorrected[species]->SetTitle(Form("%s", AliPID::ParticleLatexName(species)));
3023 hFractionCorrected[species]->GetYaxis()->SetTitle("Corrected Fraction");
3024 hFractionCorrected[species]->GetXaxis()->SetMoreLogLabels(kTRUE);
3025 hFractionCorrected[species]->GetXaxis()->SetNoExponent(kTRUE);
3026 hFractionCorrected[species]->SetFillStyle(0);
3027
3028
3029 // Binomial error as for efficiencies (numerator and denominator are statistically not independent) for correct error calculation
3030 // (numerator is a "selected" subset of the denominator). It doesn't matter that the error of the histos is not just
3031 // "sqrt(content)" because the error formula also works for weighted histograms (which means that the error can be more
3032 // or less anything)
3033 hFractionCorrected[species]->Divide(hYieldCorrected[species], hYieldCorrectedTotal, 1., 1., "B");
3034
3035
3036
3037 // The systematic errors just need to be scaled in the same way as the fractions.
3038 // So, just take the ratio to the uncorrected fraction and scale the sys. error accordingly
3039 // or, in this case, just divide by the same total yield as for yield -> fractions
3040 hFractionCorrectedSysError[species] = new TH1D(*hFractionCorrected[species]);
3041 hFractionCorrectedSysError[species]->SetName(Form("%s_sysError", hFractionCorrected[species]->GetName()));
3042 hFractionCorrectedSysError[species]->SetTitle(Form("%s (sys. error)", hFractionCorrected[species]->GetTitle()));
3043
3044 for (Int_t binX = 1; binX <= hFractionCorrectedSysError[species]->GetNbinsX(); binX++) {
3045 const Double_t corrTotalYield = hYieldCorrectedTotal->GetBinContent(binX);
3046 const Double_t scaleFactor = corrTotalYield > 0 ? 1.0 / corrTotalYield : 1.;
3047 hFractionCorrectedSysError[species]->SetBinError(binX, hYieldCorrectedSysError[species]->GetBinError(binX) * scaleFactor);
3048 }
3049 }
3050
3051 // If MC is available, calculate the generated fractions
3052 TH1D* hMCgenPrimYieldTotal = 0x0;
3053 TH1D* hMCgenPrimFraction[AliPID::kSPECIES];
3054 for (Int_t i = 0; i < AliPID::kSPECIES; i++)
3055 hMCgenPrimFraction[i] = 0x0;
3056
3057 if (numMCgenPrimYieldHistsFound > 0) {
3058 hMCgenPrimYieldTotal = new TH1D(*hMCgenPrimYield[0]);
3059 hMCgenPrimYieldTotal->SetLineColor(kBlack);
3060 hMCgenPrimYieldTotal->SetMarkerColor(kBlack);
3061 hMCgenPrimYieldTotal->SetMarkerStyle(24);
3062 hMCgenPrimYieldTotal->SetName(Form("hMCgenPrimYieldTotal%s", titles[type].Data()));
3063 hMCgenPrimYieldTotal->SetTitle("Total, MC truth");
3064 //hMCgenPrimYieldTotal->SetTitle("Total generated primary yield (MC truth)");
3065
3066 for (Int_t i = 1; i < AliPID::kSPECIES; i++)
3067 hMCgenPrimYieldTotal->Add(hMCgenPrimYield[i], 1.);
3068
3069 // Calculate the MC fractions
3070 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
3071 hMCgenPrimYield[species]->SetLineColor(getLineColorAliPID(species));
3072 hMCgenPrimYield[species]->SetMarkerColor(getLineColorAliPID(species));
3073 hMCgenPrimYield[species]->SetMarkerStyle(24);
3074
3075 hMCgenPrimYield[species]->SetTitle(Form("%s, MC truth", AliPID::ParticleLatexName(species)));
3076
3077 hMCgenPrimFraction[species] = new TH1D(*hMCgenPrimYield[species]);
3078 TString oldName = hMCgenPrimYield[species]->GetName();
3079 TString newName = oldName.ReplaceAll("Yield", "Fraction");
3080 hMCgenPrimFraction[species]->SetName(newName.Data());
3081
3082 // Binomial error as for efficiencies (numerator and denominator are statistically not independent) for correct error calculation
3083 // (numerator is a "selected" subset of the denominator).
3084 hMCgenPrimFraction[species]->Divide(hMCgenPrimFraction[species], hMCgenPrimYieldTotal, 1., 1., "B");
3085 }
3086 }
3087
3088 TCanvas* cCorrData = new TCanvas(Form("cCorrData_%s", titles[type].Data()), "Corrected data", 0, 300, 900, 900);
3089 cCorrData->Divide(2, 1, 0., 0.01);
3090 cCorrData->GetPad(1)->SetLogx(1);
3091 cCorrData->GetPad(1)->SetLogy(1);
3092 cCorrData->GetPad(2)->SetLogx(1);
3093 cCorrData->GetPad(2)->SetLogy(1);
3094
3095 cCorrData->GetPad(1)->SetRightMargin(0.001);
3096 cCorrData->GetPad(2)->SetRightMargin(0.001);
3097
3098 cCorrData->GetPad(1)->SetLeftMargin(0.2);
3099 cCorrData->GetPad(2)->SetLeftMargin(0.2);
3100
3101 cCorrData->cd(1); // uncorrected
3102 hYield[AliPID::kPion]->GetYaxis()->SetTitleOffset(1.4);
3103 hYield[AliPID::kPion]->Draw("E1");
3104
3105 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
3106 hYieldSysError[i]->Draw("E2 same");
3107
3108 if (i == AliPID::kPion) continue;
3109 hYield[i]->Draw("E1 same");
3110 }
3111
3112
3113 ClearTitleFromHistoInCanvas(cCorrData, 1);
3114
3115 Double_t maximum = hYieldCorrectedTotal->GetBinContent(hYieldCorrectedTotal->GetMaximumBin()) * 10.;
3116 Double_t minimum = maximum;
3117 for (Int_t spec = 0; spec < AliPID::kSPECIES; spec++) {
3118 Double_t temp = hYieldCorrected[spec]->GetBinContent(hYieldCorrected[spec]->FindLastBinAbove(0.)) * 0.1;
3119 if (temp > 0)
3120 minimum = temp;
3121 }
3122
3123
3124 cCorrData->cd(2); // corrected
3125 hYieldCorrectedTotal->GetXaxis()->SetMoreLogLabels(kTRUE);
3126 hYieldCorrectedTotal->GetXaxis()->SetNoExponent(kTRUE);
3127 hYieldCorrectedTotal->GetYaxis()->SetRangeUser(minimum, maximum);
3128
3129 if (hMCgenPrimYieldTotal) {
3130 hMCgenPrimYieldTotal->GetYaxis()->SetTitleOffset(1.4);
3131 hMCgenPrimYieldTotal->GetXaxis()->SetMoreLogLabels(kTRUE);
3132 hMCgenPrimYieldTotal->GetXaxis()->SetNoExponent(kTRUE);
3133 hMCgenPrimYieldTotal->GetXaxis()->SetTitle(hYieldCorrectedTotal->GetXaxis()->GetTitle());
3134 hMCgenPrimYieldTotal->GetYaxis()->SetRangeUser(minimum, maximum);
3135 }
3136
3137 if (hMCgenPrimYieldTotal) {
3138 hMCgenPrimYieldTotal->Draw("E1");
3139 hYieldCorrectedTotal->Draw("E1 same");
3140 }
3141 else
3142 hYieldCorrectedTotal->Draw("E1");
3143
3144 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
3145 if (hMCgenPrimYield[i])
3146 hMCgenPrimYield[i]->Draw("E1 same");
3147 hYieldCorrected[i]->Draw("E1 same");
3148 }
3149
3150 TLegend* legTemp = cCorrData->cd(2)->BuildLegend();//0.25, 0.16, 0.65, 0.51);
3151 legTemp->SetNColumns(2);
3152 legTemp->SetFillColor(kWhite);
3153
3154 // Do not include into legend
3155 for (Int_t i = 0; i < AliPID::kSPECIES; i++)
3156 hYieldCorrectedSysError[i]->Draw("E2 same");
3157
3158 ClearTitleFromHistoInCanvas(cCorrData, 2);
3159
3160 TCanvas* cCorrYieldsRatio = 0x0;
3161
3162 TH1D* hYieldCorrectedRatioToMC[AliPID::kSPECIES];
3163 for (Int_t i = 0; i < AliPID::kSPECIES; i++)
3164 hYieldCorrectedRatioToMC[i] = 0x0;
3165
3166 TH1D* hYieldCorrectedTotalRatioToMC = 0x0;
3167
3168 if (numMCgenPrimYieldHistsFound > 0) {
3169 // Compare with MC truth
3170 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
3171 hYieldCorrectedRatioToMC[species] = new TH1D(*hYieldCorrected[species]);
3172 hYieldCorrectedRatioToMC[species]->SetName(Form("hYieldCorrectedRatioToMC_%s_%s", titles[type].Data(),
3173 AliPID::ParticleShortName(species)));
3174 hYieldCorrectedRatioToMC[species]->SetTitle(Form("%s", AliPID::ParticleLatexName(species)));
3175 hYieldCorrectedRatioToMC[species]->GetYaxis()->SetTitle("Corrected Yield: Fit / MC Truth");
3176 hYieldCorrectedRatioToMC[species]->Divide(hMCgenPrimYield[species]);
3177 }
3178
3179 hYieldCorrectedTotalRatioToMC = new TH1D(*hYieldCorrectedTotal);
3180 hYieldCorrectedTotalRatioToMC->SetName(Form("hYieldCorrectedTotalRatioToMC_%s", titles[type].Data()));
3181 hYieldCorrectedTotalRatioToMC->SetTitle("Total yield");
3182 hYieldCorrectedTotalRatioToMC->GetYaxis()->SetTitle("Corrected Yield: Fit / MC Truth");
3183 hYieldCorrectedTotalRatioToMC->Divide(hMCgenPrimYieldTotal);
3184
3185 cCorrYieldsRatio = new TCanvas(Form("cCorrYieldsRatio_%s", titles[type].Data()), "Corrected Yields Comparison to MC",
3186 0, 300, 900, 900);
3187 cCorrYieldsRatio->SetGridx(1);
3188 cCorrYieldsRatio->SetGridy(1);
3189 cCorrYieldsRatio->SetLogx(1);
3190
3191 hYieldCorrectedTotalRatioToMC->GetYaxis()->SetRangeUser(0.6, 1.6);
3192 hYieldCorrectedTotalRatioToMC->GetYaxis()->SetTitleOffset(0.85);
3193 hYieldCorrectedTotalRatioToMC->Draw("E1");
3194
3195 for (Int_t species = 0; species < AliPID::kSPECIES; species++)
3196 hYieldCorrectedRatioToMC[species]->Draw("E1 same");
3197
3198 cCorrYieldsRatio->BuildLegend()->SetFillColor(kWhite);
3199
3200 ClearTitleFromHistoInCanvas(cCorrYieldsRatio);
3201 }
3202
3203 TCanvas* cCorrFractions = new TCanvas(Form("cCorrFractions_%s", titles[type].Data()), "Corrected particleFractions",
3204 0, 300, 900, 900);
3205 cCorrFractions->SetLogx(1);
3206 hFractionCorrected[0]->GetYaxis()->SetRangeUser(0., 1.);
3207 hFractionCorrected[0]->Draw("E1");
3208 if (hMCgenPrimFraction[0])
3209 hMCgenPrimFraction[0]->Draw("E1 same");
3210
3211 for (Int_t i = 1; i < AliPID::kSPECIES; i++) {
3212 hFractionCorrected[i]->Draw("E1 same");
3213 if (hMCgenPrimFraction[i])
3214 hMCgenPrimFraction[i]->Draw("E1 same");
3215 }
3216
3217 cCorrFractions->BuildLegend()->SetFillColor(kWhite);
3218
3219 // Do not include into legend
3220 for (Int_t i = 0; i < AliPID::kSPECIES; i++)
3221 hFractionCorrectedSysError[i]->Draw("E2 same");
3222
3223 ClearTitleFromHistoInCanvas(cCorrFractions);
3224
3225 // Save results
3226 saveFile->cd();
3227
3228 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
3229 if (hYield[i])
3230 hYield[i]->Write();
3231 }
3232
3233 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
3234 if (hYieldCorrected[i])
3235 hYieldCorrected[i]->Write();
3236
3237 if (hYieldCorrectedSysError[i])
3238 hYieldCorrectedSysError[i]->Write();
3239 }
3240
3241 if (hYieldCorrectedTotal)
3242 hYieldCorrectedTotal->Write();
3243
3244 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
3245 if (hMCgenPrimYield[i])
3246 hMCgenPrimYield[i]->Write();
3247 }
3248
3249 if (hMCgenPrimYieldTotal)
3250 hMCgenPrimYieldTotal->Write();
3251
3252 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
3253 if (hYieldCorrectedRatioToMC[i])
3254 hYieldCorrectedRatioToMC[i]->Write();
3255 }
3256
3257 if (hYieldCorrectedTotalRatioToMC)
3258 hYieldCorrectedTotalRatioToMC->Write();
3259
3260 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
3261 if (hFractionCorrected[i])
3262 hFractionCorrected[i]->Write();
3263
3264 if (hFractionCorrectedSysError[i])
3265 hFractionCorrectedSysError[i]->Write();
3266 }
3267
3268 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
3269 if (hMCgenPrimFraction[i])
3270 hMCgenPrimFraction[i]->Write();
3271 }
3272
3273 if (cCorrData)
3274 cCorrData->Write();
3275
3276 if (cCorrYieldsRatio)
3277 cCorrYieldsRatio->Write();
3278
3279 if (cCorrFractions)
3280 cCorrFractions->Write();
3281 }
3282
3283 saveFile->cd();
3284
3285 TNamed* settings = new TNamed(
3286 Form("Settings: Efficiency file \"%s\", numJetsForEfficiency file \"%s\", Data file \"%s\", lowerCentrality %.3f, upperCentrality %.3f, lowerJetPt %.1f, upperJetPt %.1f, constantCorrectionAbovePtThreshold %.3f\n",
3287 pathNameEfficiency.Data(), pathNameDataMC.Data(), pathNameData.Data(), lowerCentrality, upperCentrality, lowerJetPt,
3288 upperJetPt, constantCorrectionAbovePtThreshold), "");
3289 settings->Write();
3290
3291 saveFile->Close();
3292
3293
3294 return 0;
3295}