5 #include "TGraphAsymmErrors.h"
8 #include "AliCFContainer.h"
9 #include "AliCFEffGrid.h"
10 #include "AliCFDataGrid.h"
15 #include "THnSparseDefinitions.h"
17 enum type { kTrackPt = 0, kZ = 1, kXi = 2, kNtypes = 3 };
20 const Int_t nPtBinsType2 = 44;
21 const 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 };
28 //___________________________________________________________________
29 const Double_t* GetBins(Int_t type, Int_t& nBins)
41 //___________________________________________________________________
42 Double_t trackingPtGeantFlukaCorrectionPrMinus(Double_t pTmc)
44 return (1. - 0.129758 * TMath::Exp(-pTmc * 0.679612));
48 //___________________________________________________________________
49 Double_t trackingPtGeantFlukaCorrectionKaMinus(Double_t pTmc)
51 return TMath::Min((0.972865 + 0.0117093 * pTmc), 1.);
55 //___________________________________________________________________
56 Bool_t geantFlukaCorrection(AliCFContainer* data, Int_t genStepToDownscale)
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.
64 printf("No CFContainer for GEANT/FLUKA correction!\n");
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})");
72 if (iPt < 0 || iMCid < 0 || iCharge < 0) {
73 printf("Data axis for GEANT/FLUKA correction not found!\n");
77 if (!data->GetGrid(genStepToDownscale)) {
78 printf("Step for downscaling (GEANT/FLUKA) not found!\n");
82 const Int_t nDim = data->GetNVar();
84 Double_t binCenterCoord[nDim];
86 Long64_t nBinsGrid = data->GetGrid(genStepToDownscale)->GetGrid()->GetNbins();
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);
92 for (Int_t iDim = 0; iDim < nDim; iDim++)
93 binCenterCoord[iDim] = data->GetBinCenter(iDim, coord[iDim]);
95 if (binCenterCoord[iCharge] < 0) {
96 Double_t corrFactor = 1.;
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]);
105 data->GetGrid(genStepToDownscale)->GetGrid()->SetBinContent(iBin, binContent * corrFactor);
106 data->GetGrid(genStepToDownscale)->GetGrid()->SetBinError(iBin, binError * corrFactor);
115 //___________________________________________________________________
116 void setupHist(TH1* h, TString histName, TString histTitle, TString xAxisTitle, TString yAxisTitle, Int_t color)
119 h->SetName(histName.Data());
120 h->SetTitle(histTitle.Data());
122 if (xAxisTitle != "")
123 h->GetXaxis()->SetTitle(xAxisTitle.Data());
124 if (yAxisTitle != "")
125 h->GetYaxis()->SetTitle(yAxisTitle.Data());
127 h->SetMarkerStyle(24);
128 h->SetLineColor(color);
129 h->SetMarkerColor(color);
135 //____________________________________________________________________________________________________________________
136 void undoJetNormalisationHist2D(TH2* hData, TH2* hNumJets, const Int_t lowerCentralityBinLimit, const Int_t upperCentralityBinLimit)
138 // Undo normalisation to 1/numJets. NOTE: jetPt binning of hData and hNumJets assumed to be the same!
140 if (!hData || !hNumJets)
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;
147 for (Int_t binObs = 0; binObs <= hData->GetNbinsX() + 1; binObs++) {
151 hData->SetBinContent(binObs, binJetPt, hData->GetBinContent(binObs, binJetPt) * numJets);
152 hData->SetBinError(binObs, binJetPt, hData->GetBinError(binObs, binJetPt) * numJets);
158 //___________________________________________________________________
159 void normaliseHist(TH1* h, Double_t scale = 1.0)
161 if (h->GetSumw2N() <= 0)
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);
174 //___________________________________________________________________
175 void multiplyHistsDifferentBinning(TH1* h1, const TH1* h2, Double_t c1, Double_t c2, Bool_t ignoreErrorOfSecondHist = kFALSE)
177 Int_t nbinsx = h1->GetNbinsX();
178 Int_t nbinsy = h1->GetNbinsY();
179 Int_t nbinsz = h1->GetNbinsZ();
181 if (h1->GetDimension() < 2)
183 if (h1->GetDimension() < 3)
186 if (h1->GetSumw2N() == 0)
189 Int_t bin, bin2, binx, biny, binz;
190 Double_t b1,b2,w,d1,d2;
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);
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)));
214 //___________________________________________________________________
215 void divideHistsDifferentBinning(TH1* h1, const TH1* h2, Double_t c1, Double_t c2, Bool_t ignoreErrorOfSecondHist = kFALSE)
217 Int_t nbinsx = h1->GetNbinsX();
218 Int_t nbinsy = h1->GetNbinsY();
219 Int_t nbinsz = h1->GetNbinsZ();
221 if (h1->GetDimension() < 2)
223 if (h1->GetDimension() < 3)
226 if (h1->GetSumw2N() == 0)
229 Int_t bin, bin2, binx, biny, binz;
230 Double_t b1,b2,w,d1,d2;
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);
247 h1->SetBinContent(bin, w);
250 h1->SetBinError(bin, 0);
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)));
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
267 Int_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)
274 TString pathData = pathNameData;
275 pathData.Replace(pathData.Last('/'), pathData.Length(), "");
277 TFile* fileEff = TFile::Open(pathNameEfficiency.Data());
279 printf("Failed to open efficiency file \"%s\"\n", pathNameEfficiency.Data());
283 AliCFContainer* data = (AliCFContainer*)(fileEff->Get("containerEff"));
285 printf("Failed to load efficiency container!\n");
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})");
298 TFile* fileData = TFile::Open(pathNameData.Data());
300 printf("Failed to open data file \"%s\"\n", pathNameData.Data());
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;
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());
321 hYield[species]->SetFillStyle(0);
323 TString graphName = Form("systematicErrorYields_%s", AliPID::ParticleName(species));
324 gYieldSysError[species] = (TGraphAsymmErrors*)fileData->Get(graphName.Data());
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++;
333 if (numMCgenPrimYieldHistsFound > 0 && numMCgenPrimYieldHistsFound != AliPID::kSPECIES) {
334 printf("Error: Unable to retrieve all MC generated prim yield histos! Got %d.\n", numMCgenPrimYieldHistsFound);
338 TCanvas* cFractions = (TCanvas*)fileData->Get("cFractionsWithTotalSystematicError");
340 cFractions = (TCanvas*)fileData->Get("cFractions");
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);
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));
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");
362 if (rebinEfficiency > 1) {
364 const Double_t* newBins = GetBins(rebinEfficiency, nBinsNew);
366 hDummy.SetBins(nBinsNew, newBins);
368 axis = hDummy.GetXaxis();
370 //axis = hDummy.Rebin(rebinEfficiency, "", 0)->GetXaxis();
373 axis = hDummy.GetXaxis();
375 const TArrayD* binsPtCurrent = axis->GetXbins();
376 TArrayD* binsPtNew = new TArrayD(*binsPtCurrent);
378 const Int_t nEffDims = data->GetNVar();
379 Int_t nEffBins[nEffDims];
381 for (Int_t iDim = 0; iDim < nEffDims; iDim++) {
383 nEffBins[iDim] = axis->GetNbins();
385 nEffBins[iDim] = data->GetNBins(iDim);
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
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;
404 binsPtNew->fArray[iBin] = constantCorrectionAbovePtThreshold;
411 AliCFContainer *dataRebinned = new AliCFContainer(Form("%s_rebinned", data->GetName()), Form("%s (rebinned)", data->GetTitle()),
412 data->GetNStep(), nEffDims, nEffBins);
414 for (Int_t iDim = 0; iDim < nEffDims; iDim++) {
415 dataRebinned->SetVarTitle(iDim, data->GetVarTitle(iDim));
418 if (binsPtNew->fN == 0)
419 dataRebinned->SetBinLimits(iDim, axis->GetXmin(), axis->GetXmax());
421 dataRebinned->SetBinLimits(iDim, binsPtNew->fArray);
424 dataRebinned->SetBinLimits(iDim, data->GetBinLimits(iDim));
428 for (Int_t iStep = 0; iStep < data->GetNStep(); iStep++)
429 dataRebinned->SetStepTitle(iStep, data->GetStepTitle(iStep));
431 Int_t coord[nEffDims];
432 Double_t binCenterCoord[nEffDims];
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();
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);
442 for (Int_t iDim = 0; iDim < nEffDims; iDim++) {
443 binCenterCoord[iDim] = data->GetBinCenter(iDim, coord[iDim]);
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);
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.;
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);
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);
471 restrictCentralityAxis = kTRUE;
474 std::cout << std::endl;
475 std::cout << "Requested centrality range out of limits or upper and lower limit are switched!" << std::endl;
480 std::cout << "centrality: ";
481 if (restrictCentralityAxis) {
482 std::cout << actualLowerCentrality << " - " << actualUpperCentrality << std::endl;
483 dataRebinned->SetRangeUser(iMult, lowerCentralityBinLimit, upperCentralityBinLimit, kTRUE);
486 std::cout << "All" << std::endl;
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.;
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);
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);
509 restrictJetPtAxis = kTRUE;
512 std::cout << std::endl;
513 std::cout << "Requested jet pT range out of limits or upper and lower limit are switched!" << std::endl;
518 std::cout << "jet pT: ";
519 if (restrictJetPtAxis) {
520 std::cout << actualLowerJetPt << " - " << actualUpperJetPt << std::endl;
521 dataRebinned->SetRangeUser(iJetPt, lowerJetPtBinLimit, upperJetPtBinLimit, kTRUE);
524 std::cout << "All" << std::endl;
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;
536 std::cout << "Unknown -> ERROR" << std::endl;
540 const Bool_t restrictCharge = (chargeMode != kAllCharged);
542 Int_t lowerChargeBinLimit = -1;
543 Int_t upperChargeBinLimit = -2;
544 Double_t actualLowerCharge = -999;
545 Double_t actualUpperCharge = -999;
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);
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);
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);
564 std::cout << "Charge range (efficiency): " << actualLowerCharge << " - " << actualUpperCharge << std::endl;
567 std::cout << std::endl;
568 std::cout << "Requested charge range (efficiency) out of limits or upper and lower limit are switched!" << std::endl;
572 dataRebinned->SetRangeUser(iCharge, lowerChargeBinLimit, upperChargeBinLimit, kTRUE);
573 data->SetRangeUser(iCharge, lowerChargeBinLimit, upperChargeBinLimit, kTRUE);
576 std::cout << std::endl;
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;
584 if (restrictJetPtAxis) {
585 TString pathNameDataMC = pathNameEfficiency;
586 pathNameDataMC.ReplaceAll("_efficiency", "");
588 TFile* fDataMC = TFile::Open(pathNameDataMC.Data());
590 std::cout << std::endl;
591 std::cout << "Failed to open file \"" << pathNameData.Data() << "\" to obtain num of rec/gen jets!" << std::endl;
596 TString listName = pathNameDataMC;
597 listName.Replace(0, listName.Last('/') + 1, "");
598 listName.ReplaceAll(".root", "");
600 TObjArray* histList = (TObjArray*)(fDataMC->Get(listName.Data()));
602 std::cout << std::endl;
603 std::cout << "Failed to load list \"" << listName.Data() << "\" to obtain num of rec/gen jets!" << std::endl;
607 hNjetsGen = (TH2D*)histList->FindObject("fh2FFJetPtGen");
608 hNjetsRec = (TH2D*)histList->FindObject("fh2FFJetPtRec");
610 if (!hNjetsRec || !hNjetsGen) {
611 std::cout << "Failed to load number of jets histos!" << std::endl;
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());
621 TString dirDataInFile = "";
622 TDirectory* dirData = fBackward ? (TDirectory*)fBackward->Get(fBackward->GetListOfKeys()->At(0)->GetName()) : 0x0;
624 TList* list = dirData ? (TList*)dirData->Get(dirData->GetListOfKeys()->At(0)->GetName()) : 0x0;
626 TH1D* hFFJetPtRec = list ? (TH1D*)list->FindObject("fh1FFJetPtRecCuts") : 0x0;
627 TH1D* hFFJetPtGen = list ? (TH1D*)list->FindObject("fh1FFJetPtGen") : 0x0;
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());
633 hNjetsRec = new TH2D("fh2FFJetPtRec", "", 1, -1, 1, dataRebinned->GetAxis(iJetPt, 0)->GetNbins(),
634 dataRebinned->GetAxis(iJetPt, 0)->GetXbins()->GetArray());
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));
642 hNjetsGen = new TH2D("fh2FFJetPtGen", "", 1, -1, 1, dataRebinned->GetAxis(iJetPt, 0)->GetNbins(),
643 dataRebinned->GetAxis(iJetPt, 0)->GetXbins()->GetArray());
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));
652 if (!hNjetsRec || ! hNjetsGen)
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.;
664 // Secondary correction
665 AliCFEffGrid* sec = new AliCFEffGrid("sec", "Secondary Contamination", *dataRebinned);
666 AliCFEffGrid* secStrangeScale = new AliCFEffGrid("secStrangeScale", "Secondary Contamination with Strangeness Scaling",
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
675 // For testing with data set w/o strangeness secStrangeScale->CalculateEfficiency(kStepRecWithRecCutsMeasuredObsPrimaries, kStepRecWithRecCutsMeasuredObs);
676 secStrangeScale->CalculateEfficiency(kStepRecWithRecCutsMeasuredObsPrimaries, kStepRecWithRecCutsMeasuredObsStrangenessScaled);
677 sec->CalculateEfficiency(kStepRecWithRecCutsMeasuredObsPrimaries, kStepRecWithRecCutsMeasuredObs);
679 // QA plots for secondaries
680 TCanvas* cSec = new TCanvas("cSec", "Secondary Contamination", 100, 10, 1200, 800);
682 cSec->GetPad(1)->SetLogx(kTRUE);
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");
693 TH1* hEtaSec = sec->Project(iEta);
694 hEtaSec->SetName("hEtaSec");
695 hEtaSec->SetStats(kFALSE);
696 hEtaSec->GetYaxis()->SetTitle("Primary Fraction");
698 TH2D* hSecID2Pt = (TH2D*)sec->Project(iPt, iMCid);
699 hSecID2Pt->SetName("hSecID2Pt");
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");
717 TCanvas* cSec2 = new TCanvas("cSec2", "Primary fraction for different species", 100, 10, 1200, 800);
724 for (Int_t i = 1; i < AliPID::kSPECIES; i++) {
725 hSec[i]->Draw("E1 same");
727 cSec2->BuildLegend()->SetFillColor(kWhite);
729 ClearTitleFromHistoInCanvas(cSec2);
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);
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");
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");
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");
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);
774 hSecSS[0]->Draw("E1");
776 for (Int_t i = 1; i < AliPID::kSPECIES; i++) {
777 hSecSS[i]->Draw("E1 same");
779 cSecSS2->BuildLegend()->SetFillColor(kWhite);
781 ClearTitleFromHistoInCanvas(cSecSS2);
784 // Secondary correction for to-pi-ratios
785 TH1D* hSecToPiRatio[AliPID::kSPECIES] = { 0x0, };
786 TH1D* hSecSSToPiRatio[AliPID::kSPECIES] = { 0x0, };
788 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
789 if (species == AliPID::kPion)
790 continue; // Do not consider pion-to-pion ratio
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");
803 hSecSSToPiRatio[species] = new TH1D(*hSecToPiRatio[species]);
804 hSecSSToPiRatio[species]->SetName(Form("hSecSSToPionRatio_%s", AliPID::ParticleShortName(species)));
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);
810 hSecSSToPiRatio[species]->Divide(hSecSS[species], hSecSS[AliPID::kPion], 1., 1., "");
811 hSecSSToPiRatio[species]->GetYaxis()->SetRangeUser(0., 1.1);
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);
819 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
820 if (i == AliPID::kPion)
823 hSecToPiRatio[i]->Draw(Form("E1%s", i == 0 ? "" : " same"));
826 cSecToPiRatio->BuildLegend()->SetFillColor(kWhite);
828 ClearTitleFromHistoInCanvas(cSecToPiRatio);
832 TCanvas* cSecSSToPiRatio = new TCanvas("cSecSSToPiRatio",
833 "Primary fraction of to-#pi-ratio for different species (strangeness scaled)",
835 cSecSSToPiRatio->SetGridx(1);
836 cSecSSToPiRatio->SetGridy(1);
837 cSecSSToPiRatio->SetLogx(1);
839 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
840 if (i == AliPID::kPion)
843 hSecSSToPiRatio[i]->Draw(Form("E1%s", i == 0 ? "" : " same"));
846 cSecSSToPiRatio->BuildLegend()->SetFillColor(kWhite);
848 ClearTitleFromHistoInCanvas(cSecSSToPiRatio);
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");
865 // Construct the efficiency grid from the data container
866 AliCFEffGrid* eff = new AliCFEffGrid("eff", "Efficiency x Acceptance x pT Resolution", *dataRebinned);
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);
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);
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);
886 cEff->GetPad(1)->SetLogx(kTRUE);
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");
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);
901 TH2D* hEffID2Pt = (TH2D*)eff->Project(iPt, iMCid);
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);
920 TCanvas* cEff2 = new TCanvas("cEff2", "Efficiency x Acceptance x pT Resolution for different species", 0, 300, 900, 900);
925 hEfficiency[0]->Draw("E1");
927 for (Int_t i = 1; i < AliPID::kSPECIES; i++) {
928 hEfficiency[i]->Draw("E1 same");
930 cEff2->BuildLegend()->SetFillColor(kWhite);
932 ClearTitleFromHistoInCanvas(cEff2);
937 // Efficiency correction for to-pi-ratios
938 TH1D* hEfficiencyToPiRatio[AliPID::kSPECIES] = { 0x0, };
940 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
941 if (species == AliPID::kPion)
942 continue; // Do not consider pion-to-pion ratio
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)));
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);
954 TCanvas* cEffToPiRatio = new TCanvas("cEffToPiRatio", "Efficiency x Acceptance x pT Resolution of to-#pi-ratio for different species",
956 cEffToPiRatio->SetGridx(1);
957 cEffToPiRatio->SetGridy(1);
958 cEffToPiRatio->SetLogx(1);
960 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
961 if (i == AliPID::kPion)
964 hEfficiencyToPiRatio[i]->Draw(Form("E1%s", i == 0 ? "" : " same"));
967 cEffToPiRatio->BuildLegend()->SetFillColor(kWhite);
969 ClearTitleFromHistoInCanvas(cEffToPiRatio);
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()));
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.);
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()));
992 multiplyHistsDifferentBinning(hYieldCorrectedSysError[species], scaleStrangeness ? hSecSS[species] : hSec[species], 1., 1.,
994 divideHistsDifferentBinning(hYieldCorrectedSysError[species], hEfficiency[species], 1., 1., kTRUE);
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");
1008 for (Int_t i = 1; i < AliPID::kSPECIES; i++)
1009 hYieldCorrectedTotal->Add(hYieldCorrected[i], 1.);
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);
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");
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()));
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);
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;
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)");
1062 for (Int_t i = 1; i < AliPID::kSPECIES; i++)
1063 hMCgenPrimYieldTotal->Add(hMCgenPrimYield[i], 1.);
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)));
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());
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");
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);
1090 cCorrData->GetPad(1)->SetRightMargin(0.001);
1091 cCorrData->GetPad(2)->SetRightMargin(0.001);
1093 cCorrData->GetPad(1)->SetLeftMargin(0.2);
1094 cCorrData->GetPad(2)->SetLeftMargin(0.2);
1096 cCorrData->cd(1); // uncorrected
1097 hYield[AliPID::kPion]->GetYaxis()->SetTitleOffset(1.4);
1098 hYield[AliPID::kPion]->Draw("E1");
1100 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1101 if (hYieldSysError[i])
1102 hYieldSysError[i]->Draw("E2 same");
1104 if (i == AliPID::kPion) continue;
1105 hYield[i]->Draw("E1 same");
1108 ClearTitleFromHistoInCanvas(cCorrData, 1);
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.);
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.);
1126 if (hMCgenPrimYieldTotal) {
1127 hMCgenPrimYieldTotal->Draw("E1");
1128 hYieldCorrectedTotal->Draw("E1 same");
1131 hYieldCorrectedTotal->Draw("E1");
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");
1139 TLegend* legTemp = cCorrData->cd(2)->BuildLegend(0.25, 0.16, 0.65, 0.51);
1140 legTemp->SetNColumns(2);
1141 legTemp->SetFillColor(kWhite);
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");
1149 ClearTitleFromHistoInCanvas(cCorrData, 2);
1151 TCanvas* cCorrYieldsRatio = 0x0;
1153 TH1D* hYieldCorrectedRatioToMC[AliPID::kSPECIES];
1154 for (Int_t i = 0; i < AliPID::kSPECIES; i++)
1155 hYieldCorrectedRatioToMC[i] = 0x0;
1157 TH1D* hYieldCorrectedTotalRatioToMC = 0x0;
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]);
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);
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);
1180 hYieldCorrectedTotalRatioToMC->GetYaxis()->SetRangeUser(0.6, 1.6);
1181 hYieldCorrectedTotalRatioToMC->GetYaxis()->SetTitleOffset(0.85);
1182 hYieldCorrectedTotalRatioToMC->Draw("E1");
1184 for (Int_t species = 0; species < AliPID::kSPECIES; species++)
1185 hYieldCorrectedRatioToMC[species]->Draw("E1 same");
1187 cCorrYieldsRatio->BuildLegend()->SetFillColor(kWhite);
1189 ClearTitleFromHistoInCanvas(cCorrYieldsRatio);
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");
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");
1209 cCorrFractions->BuildLegend()->SetFillColor(kWhite);
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");
1218 ClearTitleFromHistoInCanvas(cCorrFractions);
1220 // Save results to file
1221 TString chargeString = "";
1222 if (chargeMode == kPosCharge)
1223 chargeString = "_posCharge";
1224 else if (chargeMode == kNegCharge)
1225 chargeString = "_negCharge";
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()));
1232 TString saveFilePathName = Form("%s/%s", pathData.Data(), saveFileName.Data());
1233 TFile* saveFile = TFile::Open(saveFilePathName.Data(), "RECREATE");
1249 cSecToPiRatio->Write();
1251 if (cSecSSToPiRatio)
1252 cSecSSToPiRatio->Write();
1261 cEffToPiRatio->Write();
1266 if (cCorrYieldsRatio)
1267 cCorrYieldsRatio->Write();
1270 cFractions->Write();
1273 cCorrFractions->Write();
1275 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1283 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1284 if (hSecToPiRatio[i])
1285 hSecToPiRatio[i]->Write();
1287 if (hSecSSToPiRatio[i])
1288 hSecSSToPiRatio[i]->Write();
1291 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1293 hEfficiency[i]->Write();
1296 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1297 if (hEfficiencyToPiRatio[i])
1298 hEfficiencyToPiRatio[i]->Write();
1301 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1305 if (hYieldSysError[i])
1306 hYieldSysError[i]->Write();
1309 if (hYieldCorrectedTotal)
1310 hYieldCorrectedTotal->Write();
1312 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1313 if (hYieldCorrected[i])
1314 hYieldCorrected[i]->Write();
1316 if (hYieldCorrectedSysError[i])
1317 hYieldCorrectedSysError[i]->Write();
1320 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1321 if (hMCgenPrimYield[i])
1322 hMCgenPrimYield[i]->Write();
1325 if (hMCgenPrimYieldTotal)
1326 hMCgenPrimYieldTotal->Write();
1328 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1329 if (hYieldCorrectedRatioToMC[i])
1330 hYieldCorrectedRatioToMC[i]->Write();
1333 if (hYieldCorrectedTotalRatioToMC)
1334 hYieldCorrectedTotalRatioToMC->Write();
1336 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1337 if (hFractionCorrected[i])
1338 hFractionCorrected[i]->Write();
1340 if (hFractionCorrectedSysError[i])
1341 hFractionCorrectedSysError[i]->Write();
1344 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
1345 if (hMCgenPrimFraction[i])
1346 hMCgenPrimFraction[i]->Write();
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), "");
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
1364 Int_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)
1375 TString titles[kNtypes];
1376 titles[kTrackPt] = "trackPt";
1380 TString pathData = pathNameData;
1381 pathData.Replace(pathData.Last('/'), pathData.Length(), "");
1383 TFile* fileEff = TFile::Open(pathNameEfficiency.Data());
1385 printf("Failed to open efficiency file \"%s\"\n", pathNameEfficiency.Data());
1389 AliCFContainer* data = (AliCFContainer*)(fileEff->Get("containerEff"));
1391 printf("Failed to load efficiency container!\n");
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})");
1404 TH2D* hNjetsGen = 0x0;
1405 TH2D* hNjetsRec = 0x0;
1407 TH2D* hNjetsGenData = 0x0;
1408 TH2D* hNjetsRecData = 0x0;
1410 TH1D* hYieldPt[AliPID::kSPECIES] = {0x0, };
1411 TH1D* hYieldPtSysError[AliPID::kSPECIES] = {0x0, };
1412 TH1D* hMCgenPrimYieldPt[AliPID::kSPECIES] = {0x0, };
1414 TH1D* hYieldZ[AliPID::kSPECIES] = {0x0, };
1415 TH1D* hYieldZSysError[AliPID::kSPECIES] = {0x0, };
1416 TH1D* hMCgenPrimYieldZ[AliPID::kSPECIES] = {0x0, };
1418 TH1D* hYieldXi[AliPID::kSPECIES] = {0x0, };
1419 TH1D* hYieldXiSysError[AliPID::kSPECIES] = {0x0, };
1420 TH1D* hMCgenPrimYieldXi[AliPID::kSPECIES] = {0x0, };
1425 Int_t numMCgenPrimYieldHistsFound = 0;
1427 Int_t lowerJetPtBinYields = -1;
1428 Int_t upperJetPtBinYields = -1;
1430 Double_t actualLowerJetPtYields = -10;
1431 Double_t actualUpperJetPtYields = -10;
1433 TFile* fileData = TFile::Open(pathNameData.Data());
1435 printf("Failed to open data file \"%s\"\n", pathNameData.Data());
1440 hNjetsGenData = (TH2D*)fileData->Get("fh2FFJetPtGen");
1442 hNjetsRecData = (TH2D*)fileData->Get("fh2FFJetPtRec");
1444 if (!hNjetsRecData) {
1445 printf("Failed to load numJet histo for data!\n");
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)
1453 const Int_t upperCentralityBinLimitData = restrictCentralityData ? hNjetsRecData->GetXaxis()->FindBin(upperCentralityData - 0.001)
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;
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());
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);
1472 actualLowerJetPtYields = hTemp->GetYaxis()->GetBinLowEdge(lowerJetPtBinYields);
1473 actualUpperJetPtYields = hTemp->GetYaxis()->GetBinUpEdge(upperJetPtBinYields);
1476 lowerJetPtBinYields = 0;
1477 upperJetPtBinYields = -1;
1481 if ((lowerJetPtBinYields < 0 || upperJetPtBinYields < 0) && (lowerJetPt >= 0 && upperJetPt >= 0)) {
1482 printf("Failed to determine jet pt bin limits!\n");
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).
1491 undoJetNormalisationHist2D(hTemp, hNjetsRecData, lowerCentralityBinLimitData, upperCentralityBinLimitData);
1492 hYieldZ[species] = hTemp->ProjectionX(histName.ReplaceAll("hIDFF", "hYieldIDFF").Data(), lowerJetPtBinYields, upperJetPtBinYields,
1496 if (!hYieldZ[species]) {
1497 printf("Failed to load hist \"%s\"\n", histName.Data());
1503 histName = Form("hIDFFxi_%s", AliPID::ParticleShortName(species));
1505 hTemp = (TH2D*)fileData->Get(histName.Data());
1508 undoJetNormalisationHist2D(hTemp, hNjetsRecData, lowerCentralityBinLimitData, upperCentralityBinLimitData);
1509 hYieldXi[species] = hTemp->ProjectionX(histName.ReplaceAll("hIDFF", "hYieldIDFF").Data(),
1510 lowerJetPtBinYields, upperJetPtBinYields, "e");
1513 if (!hYieldXi[species]) {
1514 printf("Failed to load hist \"%s\"\n", histName.Data());
1518 histName = Form("hIDFFtrackPt_%s", AliPID::ParticleShortName(species));
1520 hTemp = (TH2D*)fileData->Get(histName.Data());
1523 undoJetNormalisationHist2D(hTemp, hNjetsRecData, lowerCentralityBinLimitData, upperCentralityBinLimitData);
1524 hYieldPt[species] = hTemp->ProjectionX(histName.ReplaceAll("hIDFF", "hYieldIDFF").Data(),
1525 lowerJetPtBinYields, upperJetPtBinYields, "e");
1528 if (!hYieldPt[species]) {
1529 printf("Failed to load hist \"%s\"\n", histName.Data());
1535 histName = Form("hIDFFz_%s_sysError", AliPID::ParticleShortName(species));
1537 hTemp = (TH2D*)fileData->Get(histName.Data());
1540 undoJetNormalisationHist2D(hTemp, hNjetsRecData, lowerCentralityBinLimitData, upperCentralityBinLimitData);
1541 hYieldZSysError[species] = hTemp->ProjectionX(histName.ReplaceAll("hIDFF", "hYieldIDFF").Data(), lowerJetPtBinYields,
1542 upperJetPtBinYields, "e");
1545 if (!hYieldZSysError[species]) {
1546 printf("Failed to load hist \"%s\"\n", histName.Data());
1550 histName = Form("hIDFFxi_%s_sysError", AliPID::ParticleShortName(species));
1552 hTemp = (TH2D*)fileData->Get(histName.Data());
1555 undoJetNormalisationHist2D(hTemp, hNjetsRecData, lowerCentralityBinLimitData, upperCentralityBinLimitData);
1556 hYieldXiSysError[species] = hTemp->ProjectionX(histName.ReplaceAll("hIDFF", "hYieldIDFF").Data(), lowerJetPtBinYields,
1557 upperJetPtBinYields, "e");
1560 if (!hYieldXiSysError[species]) {
1561 printf("Failed to load hist \"%s\"\n", histName.Data());
1565 histName = Form("hIDFFtrackPt_%s_sysError", AliPID::ParticleShortName(species));
1567 hTemp = (TH2D*)fileData->Get(histName.Data());
1570 undoJetNormalisationHist2D(hTemp, hNjetsRecData, lowerCentralityBinLimitData, upperCentralityBinLimitData);
1571 hYieldPtSysError[species] = hTemp->ProjectionX(histName.ReplaceAll("hIDFF", "hYieldIDFF").Data(), lowerJetPtBinYields,
1572 upperJetPtBinYields, "e");
1575 if (!hYieldPtSysError[species]) {
1576 printf("Failed to load hist \"%s\"\n", histName.Data());
1580 // In case of MC also retrieve the MC truth generated yields
1581 histName = Form("hMCgenYieldsPrimZ_%s", AliPID::ParticleShortName(species));
1583 hTemp = (TH2D*)fileData->Get(histName.Data());
1586 undoJetNormalisationHist2D(hTemp, hNjetsGenData, lowerCentralityBinLimitData, upperCentralityBinLimitData);
1587 hMCgenPrimYieldZ[species] = hTemp->ProjectionX(histName.ReplaceAll("hMCgen", "hYieldMCgen").Data(), lowerJetPtBinYields,
1588 upperJetPtBinYields, "e");
1592 histName = Form("hMCgenYieldsPrimXi_%s", AliPID::ParticleShortName(species));
1594 hTemp = (TH2D*)fileData->Get(histName.Data());
1597 undoJetNormalisationHist2D(hTemp, hNjetsGenData, lowerCentralityBinLimitData, upperCentralityBinLimitData);
1598 hMCgenPrimYieldXi[species] = hTemp->ProjectionX(histName.ReplaceAll("hMCgen", "hYieldMCgen").Data(), lowerJetPtBinYields,
1599 upperJetPtBinYields, "e");
1603 histName = Form("hMCgenYieldsPrimPt_%s", AliPID::ParticleShortName(species));
1605 hTemp = (TH2D*)fileData->Get(histName.Data());
1608 undoJetNormalisationHist2D(hTemp, hNjetsGenData, lowerCentralityBinLimitData, upperCentralityBinLimitData);
1609 hMCgenPrimYieldPt[species] = hTemp->ProjectionX(histName.ReplaceAll("hMCgen", "hYieldMCgen").Data(), lowerJetPtBinYields,
1610 upperJetPtBinYields, "e");
1613 if (hMCgenPrimYieldPt[species] && hMCgenPrimYieldZ[species] && hMCgenPrimYieldXi[species])
1614 numMCgenPrimYieldHistsFound++;
1617 if (numMCgenPrimYieldHistsFound > 0 && numMCgenPrimYieldHistsFound != AliPID::kSPECIES) {
1618 printf("Error: Unable to retrieve all MC generated prim yield histos! Got %d.\n", numMCgenPrimYieldHistsFound);
1623 /*OLD: Load from AnalysisResults.root
1625 File* fileData = TFile::Open(pathNameData.Data());
1627 printf("Failed to open data file \"%s\"\n", pathNameData.Data());
1631 TString dirDataInFile = "";
1632 TDirectory* dirData = (TDirectory*)fileData->Get(fileData->GetListOfKeys()->At(0)->GetName());
1634 printf("No directory found inside data file \"%s\"\n", pathNameData.Data());
1638 TList* list = (TList*)dirData->Get(dirData->GetListOfKeys()->At(0)->GetName());
1640 printf("No list found in directory \"%s\" inside data file \"%s\"\n",
1641 dirData->GetListOfKeys()->At(0)->GetName(),pathNameData.Data());
1645 hNjetsGen = (TH1D*)list->FindObject("fh1FFJetPtGen");
1646 hNjetsRec = (TH1D*)list->FindObject("fh1FFJetPtRecCuts");
1649 printf("Failed to load number of jets (rec) histo!\n");
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());
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);
1664 actualLowerJetPtYields = hTemp->GetXaxis()->GetBinLowEdge(lowerJetPtBinYields);
1665 actualUpperJetPtYields = hTemp->GetXaxis()->GetBinUpEdge(upperJetPtBinYields);
1668 lowerJetPtBinYields = 0;
1669 upperJetPtBinYields = -1;
1673 if ((lowerJetPtBinYields < 0 || upperJetPtBinYields < 0) && (lowerJetPt >= 0 && upperJetPt >= 0)) {
1674 printf("Failed to determine jet pt bin limits!\n");
1679 hYieldZ[species] = hTemp->ProjectionY(histName.ReplaceAll("fh2", "fh").Data(), lowerJetPtBinYields, upperJetPtBinYields, "e");
1681 if (!hYieldZ[species]) {
1682 printf("Failed to load hist \"%s\"\n", histName.Data());
1688 histName = Form("fh2FFXiRecCuts_%s", AliPID::ParticleName(species));
1690 hTemp = (TH2D*)list->FindObject(histName.Data());
1693 hYieldXi[species] = hTemp->ProjectionY(histName.ReplaceAll("fh2", "fh").Data(), lowerJetPtBinYields, upperJetPtBinYields, "e");
1695 if (!hYieldXi[species]) {
1696 printf("Failed to load hist \"%s\"\n", histName.Data());
1700 histName = Form("fh2FFTrackPtRecCuts_%s", AliPID::ParticleName(species));
1702 hTemp = (TH2D*)list->FindObject(histName.Data());
1705 hYieldPt[species] = hTemp->ProjectionY(histName.ReplaceAll("fh2", "fh").Data(), lowerJetPtBinYields, upperJetPtBinYields, "e");
1707 if (!hYieldPt[species]) {
1708 printf("Failed to load hist \"%s\"\n", histName.Data());
1712 // In case of MC also retrieve the MC truth generated yields
1713 histName = Form("fh2FFZGen_%s", AliPID::ParticleName(species));
1715 hTemp = (TH2D*)list->FindObject(histName.Data());
1717 hMCgenPrimYieldZ[species] = hTemp->ProjectionY(histName.ReplaceAll("fh2", "fh").Data(), lowerJetPtBinYields, upperJetPtBinYields,
1721 histName = Form("fh2FFXiGen_%s", AliPID::ParticleName(species));
1723 hTemp = (TH2D*)list->FindObject(histName.Data());
1725 hMCgenPrimYieldXi[species] = hTemp->ProjectionY(histName.ReplaceAll("fh2", "fh").Data(), lowerJetPtBinYields, upperJetPtBinYields,
1729 histName = Form("fh2FFTrackPtGen_%s", AliPID::ParticleName(species));
1731 hTemp = (TH2D*)list->FindObject(histName.Data());
1733 hMCgenPrimYieldPt[species] = hTemp->ProjectionY(histName.ReplaceAll("fh2", "fh").Data(), lowerJetPtBinYields, upperJetPtBinYields,
1736 if (hMCgenPrimYieldPt[species] && hMCgenPrimYieldZ[species] && hMCgenPrimYieldXi[species])
1737 numMCgenPrimYieldHistsFound++;
1740 if (numMCgenPrimYieldHistsFound > 0 && numMCgenPrimYieldHistsFound != AliPID::kSPECIES) {
1741 printf("Error: Unable to retrieve all MC generated prim yield histos! Got %d.\n", numMCgenPrimYieldHistsFound);
1746 const Double_t nJetsGen = hNjetsGen ? hNjetsGen->Integral(lowerJetPtBinYields, upperJetPtBinYields) : -1;
1747 const Double_t nJetsRec = hNjetsRec->Integral(lowerJetPtBinYields, upperJetPtBinYields);
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;
1755 if (rebinEfficiencyPt > 1) {
1757 const Double_t* newBins = GetBins(rebinEfficiencyPt, nBinsNew);
1759 hDummyPt.SetBins(nBinsNew, newBins);
1761 axisPt = hDummyPt.GetXaxis();
1763 //axisPt = hDummyPt.Rebin(rebinEfficiencyPt, "", 0)->GetXaxis();
1766 axisPt = hDummyPt.GetXaxis();
1768 const TArrayD* binsPtCurrent = axisPt->GetXbins();
1769 TArrayD* binsPtNew = new TArrayD(*binsPtCurrent);
1771 TH1D hDummyZ(*hYieldZ[AliPID::kPion]);
1772 hDummyZ.SetName("hDummyZ");
1775 if (rebinEfficiencyZ > 1)
1776 axisZ = hDummyZ.Rebin(rebinEfficiencyZ, "", 0)->GetXaxis();
1778 axisZ = hDummyZ.GetXaxis();
1780 const TArrayD* binsZCurrent = axisZ->GetXbins();
1781 TArrayD* binsZNew = new TArrayD(*binsZCurrent);
1783 TH1D hDummyXi(*hYieldXi[AliPID::kPion]);
1784 hDummyXi.SetName("hDummyXi");
1785 TAxis* axisXi = 0x0;
1787 if (rebinEfficiencyXi > 1)
1788 axisXi = hDummyXi.Rebin(rebinEfficiencyXi, "", 0)->GetXaxis();
1790 axisXi = hDummyXi.GetXaxis();
1792 const TArrayD* binsXiCurrent = axisXi->GetXbins();
1793 TArrayD* binsXiNew = new TArrayD(*binsXiCurrent);
1796 const Int_t nEffDims = data->GetNVar();
1797 Int_t nEffBins[nEffDims];
1799 for (Int_t iDim = 0; iDim < nEffDims; iDim++) {
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();
1807 nEffBins[iDim] = data->GetNBins(iDim);
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
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;
1826 binsPtNew->fArray[iBin] = constantCorrectionAbovePtThreshold;
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
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;
1847 binsXiNew->fArray[iBin] = constantCorrectionAboveXiThreshold;
1853 AliCFContainer *dataRebinned = new AliCFContainer(Form("%s_rebinned", data->GetName()), Form("%s (rebinned)", data->GetTitle()),
1854 data->GetNStep(), nEffDims, nEffBins);
1856 for (Int_t iDim = 0; iDim < nEffDims; iDim++) {
1857 dataRebinned->SetVarTitle(iDim, data->GetVarTitle(iDim));
1860 if (binsPtNew->fN == 0)
1861 dataRebinned->SetBinLimits(iDim, axisPt->GetXmin(), axisPt->GetXmax());
1863 dataRebinned->SetBinLimits(iDim, binsPtNew->fArray);
1865 else if (iDim == iZ) {
1866 if (binsZNew->fN == 0)
1867 dataRebinned->SetBinLimits(iDim, axisZ->GetXmin(), axisZ->GetXmax());
1869 dataRebinned->SetBinLimits(iDim, binsZNew->fArray);
1871 else if (iDim == iXi) {
1872 if (binsXiNew->fN == 0)
1873 dataRebinned->SetBinLimits(iDim, axisXi->GetXmin(), axisXi->GetXmax());
1875 dataRebinned->SetBinLimits(iDim, binsXiNew->fArray);
1878 dataRebinned->SetBinLimits(iDim, data->GetBinLimits(iDim));
1882 for (Int_t iStep = 0; iStep < data->GetNStep(); iStep++)
1883 dataRebinned->SetStepTitle(iStep, data->GetStepTitle(iStep));
1885 Int_t coord[nEffDims];
1886 Double_t binCenterCoord[nEffDims];
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();
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);
1896 for (Int_t iDim = 0; iDim < nEffDims; iDim++) {
1897 binCenterCoord[iDim] = data->GetBinCenter(iDim, coord[iDim]);
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);
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.;
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);
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);
1925 restrictCentralityAxis = kTRUE;
1928 std::cout << std::endl;
1929 std::cout << "Requested centrality range out of limits or upper and lower limit are switched!" << std::endl;
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);
1941 std::cout << "All" << std::endl;
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.;
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);
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);
1964 restrictJetPtAxis = kTRUE;
1967 std::cout << std::endl;
1968 std::cout << "Requested jet pT range out of limits or upper and lower limit are switched!" << std::endl;
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);
1980 std::cout << "All" << std::endl;
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;
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;
1998 std::cout << "Unknown -> ERROR" << std::endl;
2002 const Bool_t restrictCharge = (chargeMode != kAllCharged);
2004 Int_t lowerChargeBinLimit = -1;
2005 Int_t upperChargeBinLimit = -2;
2006 Double_t actualLowerCharge = -999;
2007 Double_t actualUpperCharge = -999;
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);
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);
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);
2026 std::cout << "Charge range (efficiency): " << actualLowerCharge << " - " << actualUpperCharge << std::endl;
2029 std::cout << std::endl;
2030 std::cout << "Requested charge range (efficiency) out of limits or upper and lower limit are switched!" << std::endl;
2034 dataRebinned->SetRangeUser(iCharge, lowerChargeBinLimit, upperChargeBinLimit, kTRUE);
2035 data->SetRangeUser(iCharge, lowerChargeBinLimit, upperChargeBinLimit, kTRUE);
2038 std::cout << std::endl;
2041 // Load numJet histos from bhess_PID*.root file related to efficiency file.
2042 TString pathNameDataMC = pathNameEfficiency;
2043 pathNameDataMC.ReplaceAll("_efficiency", "");
2045 TFile* fDataMC = TFile::Open(pathNameDataMC.Data());
2047 std::cout << std::endl;
2048 std::cout << "Failed to open file \"" << pathNameData.Data() << "\" to obtain num of rec/gen jets!" << std::endl;
2053 TString listName = pathNameDataMC;
2054 listName.Replace(0, listName.Last('/') + 1, "");
2055 listName.ReplaceAll(".root", "");
2057 TObjArray* histList = (TObjArray*)(fDataMC->Get(listName.Data()));
2059 std::cout << std::endl;
2060 std::cout << "Failed to load list \"" << listName.Data() << "\" to obtain num of rec/gen jets!" << std::endl;
2064 hNjetsGen = (TH2D*)histList->FindObject("fh2FFJetPtGen");
2065 hNjetsRec = (TH2D*)histList->FindObject("fh2FFJetPtRec");
2067 if (!hNjetsRec || !hNjetsGen) {
2068 std::cout << "Failed to load number of jets histos!" << std::endl;
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());
2078 TString dirDataInFile = "";
2079 TDirectory* dirData = fBackward ? (TDirectory*)fBackward->Get(fBackward->GetListOfKeys()->At(0)->GetName()) : 0x0;
2081 TList* list = dirData ? (TList*)dirData->Get(dirData->GetListOfKeys()->At(0)->GetName()) : 0x0;
2083 TH1D* hFFJetPtRec = list ? (TH1D*)list->FindObject("fh1FFJetPtRecCutsInc") : 0x0;
2084 TH1D* hFFJetPtGen = list ? (TH1D*)list->FindObject("fh1FFJetPtGenInc") : 0x0;
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");
2091 hNjetsRec = new TH2D("fh2FFJetPtRec", "", 1, -1, 1, dataRebinned->GetAxis(iJetPt, 0)->GetNbins(),
2092 dataRebinned->GetAxis(iJetPt, 0)->GetXbins()->GetArray());
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));
2100 hNjetsGen = new TH2D("fh2FFJetPtGen", "", 1, -1, 1, dataRebinned->GetAxis(iJetPt, 0)->GetNbins(),
2101 dataRebinned->GetAxis(iJetPt, 0)->GetXbins()->GetArray());
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));
2110 if (!hNjetsRec || ! hNjetsGen)
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.;
2123 // Secondary correction
2124 AliCFEffGrid* sec = new AliCFEffGrid("sec", "Secondary Contamination", *dataRebinned);
2125 sec->CalculateEfficiency(kStepRecWithRecCutsMeasuredObsPrimaries, kStepRecWithRecCutsMeasuredObs);
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;
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;
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;
2145 // Secondary correction with strangeness scaling
2146 AliCFEffGrid* secStrangeScale = new AliCFEffGrid("secStrangeScale", "Secondary Contamination with strangeness scaling",
2148 secStrangeScale->CalculateEfficiency(kStepRecWithRecCutsMeasuredObsPrimaries, kStepRecWithRecCutsMeasuredObsStrangenessScaled);
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;
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;
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;
2169 const Double_t upperTrackPt = restrictJetPtAxis ? actualUpperJetPt : 50.;
2171 TString strangenessString[2] = { "", "SS" };
2173 // Get the secondary contamination vs. pT,z,xi for each species w/ and w/o strangeness scaling
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;
2181 Int_t iDimProj = -1;
2183 AliCFEffGrid* secCurr = strangenessScaling ? secStrangeScale : sec;
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;
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;
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;
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()));
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");
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);
2243 (*cSec)->SetGridx(1);
2244 (*cSec)->SetGridy(1);
2246 if (type == kTrackPt)
2247 (*hSecAll)->GetXaxis()->SetRangeUser(0.15, upperTrackPt);
2249 (*hSecAll)->Draw("E1");
2251 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2252 if (type == kTrackPt)
2253 hSec[i]->GetXaxis()->SetRangeUser(0.15, upperTrackPt);
2255 hSec[i]->Draw("E1 same");
2257 (*cSec)->BuildLegend()->SetFillColor(kWhite);
2259 ClearTitleFromHistoInCanvas(*cSec);
2262 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
2263 if (species == AliPID::kPion)
2264 continue; // Do not consider pion-to-pion ratio
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");
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);
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);
2291 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2292 if (i == AliPID::kPion)
2295 if (type == kTrackPt)
2296 hSecToPiRatio[i]->GetXaxis()->SetRangeUser(0.15, upperTrackPt);
2298 hSecToPiRatio[i]->Draw(Form("E1%s", i == 0 ? "" : " same"));
2300 (*cSecToPiRatio)->BuildLegend()->SetFillColor(kWhite);
2302 ClearTitleFromHistoInCanvas(*cSecToPiRatio);
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)
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");
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;
2333 // The efficiency vs. pT, z, xi
2334 TH1* hSpecPt_RecPrimaries = 0x0;
2335 TH1* hSpecPt_GenPrimaries = 0x0;
2336 TH1D* hEfficiencyAllPt = 0x0;
2338 TH2* hSpecID2Pt_RecPrimaries = 0x0;
2339 TH2* hSpecID2Pt_GenPrimaries = 0x0;
2340 TH2D* hEffID2Pt = 0x0;
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, };
2347 TCanvas *cSpecPt = 0x0, *cEffPt = 0x0, *cEffToPiRatioPt = 0x0;
2350 TH1* hSpecZ_RecPrimaries = 0x0;
2351 TH1* hSpecZ_GenPrimaries = 0x0;
2352 TH1D* hEfficiencyAllZ = 0x0;
2354 TH2* hSpecID2Z_RecPrimaries = 0x0;
2355 TH2* hSpecID2Z_GenPrimaries = 0x0;
2356 TH2D* hEffID2Z = 0x0;
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, };
2363 TCanvas *cSpecZ = 0x0, *cEffZ = 0x0, *cEffToPiRatioZ = 0x0;
2366 TH1* hSpecXi_RecPrimaries = 0x0;
2367 TH1* hSpecXi_GenPrimaries = 0x0;
2368 TH1D* hEfficiencyAllXi = 0x0;
2370 TH2* hSpecID2Xi_RecPrimaries = 0x0;
2371 TH2* hSpecID2Xi_GenPrimaries = 0x0;
2372 TH2D* hEffID2Xi = 0x0;
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, };
2379 TCanvas *cSpecXi = 0x0, *cEffXi = 0x0, *cEffToPiRatioXi = 0x0;
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";
2386 for (Int_t type = 0; type < kNtypes; type++) {
2387 TH1** hSpec_RecPrimaries;
2388 TH1** hSpec_GenPrimaries;
2389 TH1D** hEfficiencyAll;
2391 TH2** hSpecID2_RecPrimaries;
2392 TH2** hSpecID2_GenPrimaries;
2395 TH1D** hSpecID_GenPrimaries;
2396 TH1D** hSpecID_RecPrimaries;
2398 TH1D** hEfficiencyToPiRatio;
2400 TCanvas **cSpec, **cEff, **cEffToPiRatio;
2402 Int_t iDimProj = -1;
2405 if (type == kTrackPt) {
2406 hSpec_RecPrimaries = &hSpecPt_RecPrimaries;
2407 hSpec_GenPrimaries = &hSpecPt_GenPrimaries;
2408 hEfficiencyAll = &hEfficiencyAllPt;
2410 hSpecID2_RecPrimaries = &hSpecID2Pt_RecPrimaries;
2411 hSpecID2_GenPrimaries = &hSpecID2Pt_GenPrimaries;
2412 hEffID2 = &hEffID2Pt;
2414 hSpecID_RecPrimaries = &hSpecIDPt_RecPrimaries[0];
2415 hSpecID_GenPrimaries = &hSpecIDPt_GenPrimaries[0];
2416 hEfficiency = &hEfficiencyPt[0];
2417 hEfficiencyToPiRatio = &hEfficiencyToPiRatioPt[0];
2421 cEffToPiRatio = &cEffToPiRatioPt;
2425 else if (type == kZ) {
2426 hSpec_RecPrimaries = &hSpecZ_RecPrimaries;
2427 hSpec_GenPrimaries = &hSpecZ_GenPrimaries;
2428 hEfficiencyAll = &hEfficiencyAllZ;
2430 hSpecID2_RecPrimaries = &hSpecID2Z_RecPrimaries;
2431 hSpecID2_GenPrimaries = &hSpecID2Z_GenPrimaries;
2432 hEffID2 = &hEffID2Z;
2434 hSpecID_RecPrimaries = &hSpecIDZ_RecPrimaries[0];
2435 hSpecID_GenPrimaries = &hSpecIDZ_GenPrimaries[0];
2436 hEfficiency = &hEfficiencyZ[0];
2437 hEfficiencyToPiRatio = &hEfficiencyToPiRatioZ[0];
2441 cEffToPiRatio = &cEffToPiRatioZ;
2445 else if (type == kXi) {
2446 hSpec_RecPrimaries = &hSpecXi_RecPrimaries;
2447 hSpec_GenPrimaries = &hSpecXi_GenPrimaries;
2448 hEfficiencyAll = &hEfficiencyAllXi;
2450 hSpecID2_RecPrimaries = &hSpecID2Xi_RecPrimaries;
2451 hSpecID2_GenPrimaries = &hSpecID2Xi_GenPrimaries;
2452 hEffID2 = &hEffID2Xi;
2454 hSpecID_RecPrimaries = &hSpecIDXi_RecPrimaries[0];
2455 hSpecID_GenPrimaries = &hSpecIDXi_GenPrimaries[0];
2456 hEfficiency = &hEfficiencyXi[0];
2457 hEfficiencyToPiRatio = &hEfficiencyToPiRatioXi[0];
2461 cEffToPiRatio = &cEffToPiRatioXi;
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);
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);
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);
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.);
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.);
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");
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);
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);
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);
2545 *cSpec = new TCanvas(Form("cSpec_%s", titles[type].Data()), "Spectra for different species", 0, 300, 900, 900);
2547 (*cSpec)->SetGridx(1);
2548 (*cSpec)->SetGridy(1);
2549 (*cSpec)->SetLogy(1);
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);
2559 if (type == kTrackPt)
2560 (*hSpec_GenPrimaries)->GetXaxis()->SetRangeUser(0.15, upperTrackPt);
2561 (*hSpec_GenPrimaries)->Draw("E1");
2563 if (type == kTrackPt)
2564 (*hSpec_RecPrimaries)->GetXaxis()->SetRangeUser(0.15, upperTrackPt);
2565 (*hSpec_RecPrimaries)->Draw("E1 same");
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);
2573 hSpecIDPt_GenPrimaries[i]->Draw("E1 same");
2574 hSpecIDPt_RecPrimaries[i]->Draw("E1 same");
2576 TLegend* leg = (*cSpec)->BuildLegend();
2577 leg->SetFillColor(kWhite);
2578 leg->SetNColumns(2);
2580 ClearTitleFromHistoInCanvas(*cSpec);
2583 *cEff = new TCanvas(Form("cEff_%s", titles[type].Data()), "Efficiency x Acceptance x pT Resolution for different species",
2586 (*cEff)->SetGridx(1);
2587 (*cEff)->SetGridy(1);
2589 if (type == kTrackPt)
2590 (*hEfficiencyAll)->GetXaxis()->SetRangeUser(0.15, upperTrackPt);
2591 (*hEfficiencyAll)->Draw("E1");
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");
2598 (*cEff)->BuildLegend()->SetFillColor(kWhite);
2600 ClearTitleFromHistoInCanvas(*cEff);
2604 for (Int_t species = 0; species < AliPID::kSPECIES; species++) {
2605 if (species == AliPID::kPion)
2606 continue; // Do not consider pion-to-pion ratio
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)));
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);
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);
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);
2632 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2633 if (i == AliPID::kPion)
2636 if (type == kTrackPt)
2637 hEfficiencyToPiRatio[i]->GetXaxis()->SetRangeUser(0.15, upperTrackPt);
2639 hEfficiencyToPiRatio[i]->Draw(Form("E1%s", i == 0 ? "" : " same"));
2641 (*cEffToPiRatio)->BuildLegend()->SetFillColor(kWhite);
2643 ClearTitleFromHistoInCanvas(*cEffToPiRatio);
2646 // Save results to file
2647 TString chargeString = "";
2648 if (chargeMode == kPosCharge)
2649 chargeString = "_posCharge";
2650 else if (chargeMode == kNegCharge)
2651 chargeString = "_negCharge";
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()));
2658 TString saveFilePathName = Form("%s/%s", pathData.Data(), saveFileName.Data());
2659 TFile* saveFile = TFile::Open(saveFilePathName.Data(), "RECREATE");
2662 printf("Could not save results!\n");
2679 hSecSSAllPt->Write();
2681 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2686 hSecSSPt[i]->Write();
2689 if (cSecToPiRatioPt)
2690 cSecToPiRatioPt->Write();
2692 if (cSecSSToPiRatioPt)
2693 cSecSSToPiRatioPt->Write();
2695 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2696 if (hSecToPiRatioPt[i])
2697 hSecToPiRatioPt[i]->Write();
2699 if (hSecSSToPiRatioPt[i])
2700 hSecSSToPiRatioPt[i]->Write();
2715 hSecSSAllZ->Write();
2717 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2722 hSecSSZ[i]->Write();
2726 cSecToPiRatioZ->Write();
2728 if (cSecSSToPiRatioZ)
2729 cSecSSToPiRatioZ->Write();
2731 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2732 if (hSecToPiRatioZ[i])
2733 hSecToPiRatioZ[i]->Write();
2735 if (hSecSSToPiRatioZ[i])
2736 hSecSSToPiRatioZ[i]->Write();
2751 hSecSSAllXi->Write();
2753 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2758 hSecSSXi[i]->Write();
2761 if (cSecToPiRatioXi)
2762 cSecToPiRatioXi->Write();
2764 if (cSecSSToPiRatioXi)
2765 cSecSSToPiRatioXi->Write();
2767 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2768 if (hSecToPiRatioXi[i])
2769 hSecToPiRatioXi[i]->Write();
2771 if (hSecSSToPiRatioXi[i])
2772 hSecSSToPiRatioXi[i]->Write();
2780 if (hSpecPt_RecPrimaries)
2781 hSpecPt_RecPrimaries->Write();
2783 if (hSpecPt_GenPrimaries)
2784 hSpecPt_GenPrimaries->Write();
2786 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2787 if (hSpecIDPt_GenPrimaries[i])
2788 hSpecIDPt_GenPrimaries[i]->Write();
2790 if (hSpecIDPt_RecPrimaries[i])
2791 hSpecIDPt_RecPrimaries[i]->Write();
2798 if (hEfficiencyAllPt)
2799 hEfficiencyAllPt->Write();
2801 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2802 if (hEfficiencyPt[i])
2803 hEfficiencyPt[i]->Write();
2806 if (cEffToPiRatioPt)
2807 cEffToPiRatioPt->Write();
2809 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2810 if (hEfficiencyToPiRatioPt[i])
2811 hEfficiencyToPiRatioPt[i]->Write();
2819 if (hSpecZ_RecPrimaries)
2820 hSpecZ_RecPrimaries->Write();
2822 if (hSpecZ_GenPrimaries)
2823 hSpecZ_GenPrimaries->Write();
2825 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2826 if (hSpecIDZ_GenPrimaries[i])
2827 hSpecIDZ_GenPrimaries[i]->Write();
2829 if (hSpecIDZ_RecPrimaries[i])
2830 hSpecIDZ_RecPrimaries[i]->Write();
2837 if (hEfficiencyAllZ)
2838 hEfficiencyAllZ->Write();
2840 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2841 if (hEfficiencyZ[i])
2842 hEfficiencyZ[i]->Write();
2846 cEffToPiRatioZ->Write();
2848 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2849 if (hEfficiencyToPiRatioZ[i])
2850 hEfficiencyToPiRatioZ[i]->Write();
2858 if (hSpecXi_RecPrimaries)
2859 hSpecXi_RecPrimaries->Write();
2861 if (hSpecXi_GenPrimaries)
2862 hSpecXi_GenPrimaries->Write();
2864 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2865 if (hSpecIDXi_GenPrimaries[i])
2866 hSpecIDXi_GenPrimaries[i]->Write();
2868 if (hSpecIDXi_RecPrimaries[i])
2869 hSpecIDXi_RecPrimaries[i]->Write();
2876 if (hEfficiencyAllXi)
2877 hEfficiencyAllXi->Write();
2879 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2880 if (hEfficiencyXi[i])
2881 hEfficiencyXi[i]->Write();
2884 if (cEffToPiRatioXi)
2885 cEffToPiRatioXi->Write();
2887 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
2888 if (hEfficiencyToPiRatioXi[i])
2889 hEfficiencyToPiRatioXi[i]->Write();
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];
2900 TH1D** hYieldSysError;
2901 TH1D** hMCgenPrimYield;
2906 if (type == kTrackPt) {
2907 hYield = &hYieldPt[0];
2908 hYieldSysError = &hYieldPtSysError[0];
2909 hMCgenPrimYield = &hMCgenPrimYieldPt[0];
2910 hSecSS = &hSecSSPt[0];
2912 hEfficiency = &hEfficiencyPt[0];
2914 else if (type == kZ) {
2915 hYield = &hYieldZ[0];
2916 hYieldSysError = &hYieldZSysError[0];
2917 hMCgenPrimYield = &hMCgenPrimYieldZ[0];
2918 hSecSS = &hSecSSZ[0];
2920 hEfficiency = &hEfficiencyZ[0];
2922 else if (type == kXi) {
2923 hYield = &hYieldXi[0];
2924 hYieldSysError = &hYieldXiSysError[0];
2925 hMCgenPrimYield = &hMCgenPrimYieldXi[0];
2926 hSecSS = &hSecSSXi[0];
2928 hEfficiency = &hEfficiencyXi[0];
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.;
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.);
2947 hYield[species]->SetStats(kFALSE);
2948 hYieldSysError[species]->SetStats(kFALSE);
2950 if (hMCgenPrimYield[species]) {
2951 hMCgenPrimYield[species]->Scale((nJetsGenData > 0) ? 1. / nJetsGenData : 0.);
2952 hMCgenPrimYield[species]->SetStats(kFALSE);
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));
2964 hYield[species]->SetLineColor(getLineColorAliPID(species));
2965 hYield[species]->SetMarkerColor(getLineColorAliPID(species));
2966 hYield[species]->SetMarkerStyle(20);
2968 hYieldSysError[species]->SetLineColor(getLineColorAliPID(species));
2969 hYieldSysError[species]->SetMarkerColor(getLineColorAliPID(species));
2970 hYieldSysError[species]->SetMarkerStyle(20);
2971 hYieldSysError[species]->SetFillStyle(0);
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)));
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)));
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.);
2986 multiplyHistsDifferentBinning(hYieldCorrectedSysError[species], scaleStrangeness ? hSecSS[species] : hSec[species], 1., 1.,
2988 divideHistsDifferentBinning(hYieldCorrectedSysError[species], hEfficiency[species], 1., 1., kTRUE);
2990 //hYieldCorrected[species]->Multiply(hYieldCorrected[species], scaleStrangeness ? hSecSS[species] : hSec[species], 1., 1.,
2992 //hYieldCorrected[species]->Divide(hYieldCorrected[species], hEfficiency[species], 1., 1., "");
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");
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.);
3013 // Calculate the corrected fractions
3014 TH1D* hFractionCorrected[AliPID::kSPECIES];
3015 TH1D* hFractionCorrectedSysError[AliPID::kSPECIES];
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);
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");
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()));
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);
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;
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)");
3066 for (Int_t i = 1; i < AliPID::kSPECIES; i++)
3067 hMCgenPrimYieldTotal->Add(hMCgenPrimYield[i], 1.);
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);
3075 hMCgenPrimYield[species]->SetTitle(Form("%s, MC truth", AliPID::ParticleLatexName(species)));
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());
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");
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);
3095 cCorrData->GetPad(1)->SetRightMargin(0.001);
3096 cCorrData->GetPad(2)->SetRightMargin(0.001);
3098 cCorrData->GetPad(1)->SetLeftMargin(0.2);
3099 cCorrData->GetPad(2)->SetLeftMargin(0.2);
3101 cCorrData->cd(1); // uncorrected
3102 hYield[AliPID::kPion]->GetYaxis()->SetTitleOffset(1.4);
3103 hYield[AliPID::kPion]->Draw("E1");
3105 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
3106 hYieldSysError[i]->Draw("E2 same");
3108 if (i == AliPID::kPion) continue;
3109 hYield[i]->Draw("E1 same");
3113 ClearTitleFromHistoInCanvas(cCorrData, 1);
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;
3124 cCorrData->cd(2); // corrected
3125 hYieldCorrectedTotal->GetXaxis()->SetMoreLogLabels(kTRUE);
3126 hYieldCorrectedTotal->GetXaxis()->SetNoExponent(kTRUE);
3127 hYieldCorrectedTotal->GetYaxis()->SetRangeUser(minimum, maximum);
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);
3137 if (hMCgenPrimYieldTotal) {
3138 hMCgenPrimYieldTotal->Draw("E1");
3139 hYieldCorrectedTotal->Draw("E1 same");
3142 hYieldCorrectedTotal->Draw("E1");
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");
3150 TLegend* legTemp = cCorrData->cd(2)->BuildLegend();//0.25, 0.16, 0.65, 0.51);
3151 legTemp->SetNColumns(2);
3152 legTemp->SetFillColor(kWhite);
3154 // Do not include into legend
3155 for (Int_t i = 0; i < AliPID::kSPECIES; i++)
3156 hYieldCorrectedSysError[i]->Draw("E2 same");
3158 ClearTitleFromHistoInCanvas(cCorrData, 2);
3160 TCanvas* cCorrYieldsRatio = 0x0;
3162 TH1D* hYieldCorrectedRatioToMC[AliPID::kSPECIES];
3163 for (Int_t i = 0; i < AliPID::kSPECIES; i++)
3164 hYieldCorrectedRatioToMC[i] = 0x0;
3166 TH1D* hYieldCorrectedTotalRatioToMC = 0x0;
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]);
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);
3185 cCorrYieldsRatio = new TCanvas(Form("cCorrYieldsRatio_%s", titles[type].Data()), "Corrected Yields Comparison to MC",
3187 cCorrYieldsRatio->SetGridx(1);
3188 cCorrYieldsRatio->SetGridy(1);
3189 cCorrYieldsRatio->SetLogx(1);
3191 hYieldCorrectedTotalRatioToMC->GetYaxis()->SetRangeUser(0.6, 1.6);
3192 hYieldCorrectedTotalRatioToMC->GetYaxis()->SetTitleOffset(0.85);
3193 hYieldCorrectedTotalRatioToMC->Draw("E1");
3195 for (Int_t species = 0; species < AliPID::kSPECIES; species++)
3196 hYieldCorrectedRatioToMC[species]->Draw("E1 same");
3198 cCorrYieldsRatio->BuildLegend()->SetFillColor(kWhite);
3200 ClearTitleFromHistoInCanvas(cCorrYieldsRatio);
3203 TCanvas* cCorrFractions = new TCanvas(Form("cCorrFractions_%s", titles[type].Data()), "Corrected particleFractions",
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");
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");
3217 cCorrFractions->BuildLegend()->SetFillColor(kWhite);
3219 // Do not include into legend
3220 for (Int_t i = 0; i < AliPID::kSPECIES; i++)
3221 hFractionCorrectedSysError[i]->Draw("E2 same");
3223 ClearTitleFromHistoInCanvas(cCorrFractions);
3228 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
3233 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
3234 if (hYieldCorrected[i])
3235 hYieldCorrected[i]->Write();
3237 if (hYieldCorrectedSysError[i])
3238 hYieldCorrectedSysError[i]->Write();
3241 if (hYieldCorrectedTotal)
3242 hYieldCorrectedTotal->Write();
3244 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
3245 if (hMCgenPrimYield[i])
3246 hMCgenPrimYield[i]->Write();
3249 if (hMCgenPrimYieldTotal)
3250 hMCgenPrimYieldTotal->Write();
3252 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
3253 if (hYieldCorrectedRatioToMC[i])
3254 hYieldCorrectedRatioToMC[i]->Write();
3257 if (hYieldCorrectedTotalRatioToMC)
3258 hYieldCorrectedTotalRatioToMC->Write();
3260 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
3261 if (hFractionCorrected[i])
3262 hFractionCorrected[i]->Write();
3264 if (hFractionCorrectedSysError[i])
3265 hFractionCorrectedSysError[i]->Write();
3268 for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
3269 if (hMCgenPrimFraction[i])
3270 hMCgenPrimFraction[i]->Write();
3276 if (cCorrYieldsRatio)
3277 cCorrYieldsRatio->Write();
3280 cCorrFractions->Write();
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), "");