]>
Commit | Line | Data |
---|---|---|
c683985a | 1 | #include "THnSparse.h" |
2 | #include "TH2D.h" | |
3 | #include "TH1D.h" | |
4 | #include "TProfile.h" | |
5 | #include "TF1.h" | |
6 | #include "TFitResultPtr.h" | |
7 | #include "TFitResult.h" | |
8 | #include "TCanvas.h" | |
9 | #include "TStyle.h" | |
10 | #include "TVirtualFitter.h" | |
11 | #include "TObjArray.h" | |
12 | #include "TString.h" | |
13 | #include "TLegend.h" | |
14 | #include "TFile.h" | |
15 | #include "TGraphErrors.h" | |
16 | #include "TGraph.h" | |
17 | #include "TMath.h" | |
18 | #include "TMatrixDSym.h" | |
19 | #include "TRandom3.h" | |
20 | #include "TROOT.h" | |
21 | ||
22 | #include <iostream> | |
23 | #include <iomanip> | |
24 | ||
25 | #include "AliPID.h" | |
26 | ||
27 | #include "THnSparseDefinitions.h" | |
28 | #include "AliTPCPIDmathFit.h" | |
29 | ||
30 | enum processMode { kPMpT = 0, kPMz = 1, kPMxi = 2 }; | |
31 | enum muonTreatment { kNoMuons = 0, kMuonFracEqualElFrac = 1, kMuonFracOverElFracTunedOnMCStandardTrackCuts = 2, | |
32 | kMuonFracOverElFracTunedOnMCHybridTrackCuts = 3, kMuonFracOverElFracTunedOnMCHybridTrackCutsJets = 4, | |
33 | kMuonFracOverElFracTunedOnMCStandardTrackCutsPPb = 5, | |
34 | kNumHandlings = 6 }; | |
35 | ||
36 | const TString modeShortName[3] = { "Pt", "Z", "Xi" }; | |
37 | const TString modeLatexName[3] = { "P_{T}", "z", "#xi" }; | |
38 | ||
39 | const TString muonFractionHandlingShortName[kNumHandlings] = | |
40 | { "noMuons", "muonsEqualElectrons", "muonToElTunedOnMCStandardTrackCuts", "muonToElTunedOnMCHybridTrackCuts", | |
41 | "muonToElTunedOnMCHybridTrackCutsJets", "muonToElTunedOnMCStandardTrackCutsPPB" }; | |
42 | ||
43 | const Double_t epsilon = 1e-10; | |
44 | const TString identifiedLabels[2] = { "Most Probable PID", "MC" }; | |
45 | Int_t isMC = 0; | |
46 | ||
47 | TString minimisationStrategy = "MIGRAD"; // "MINIMIZE" | |
48 | Bool_t takeIntoAccountMuons = kTRUE; | |
49 | ||
50 | // 0 = no muons, 1 = muonFrac=elFrac, 2(3) = muonFrac/elFrac tuned on MC for DefaultTrackCuts (hybridTrackCuts), | |
51 | // 4 = muonFrac/elFrac tuned on MC for hybridTrackCuts for jet particles, | |
52 | Int_t muonFractionHandling = 3; | |
53 | ||
54 | ||
55 | //TODO getErrorOf.... is COMPLETELY wrong now, since the parameter numbering has changed and the muons had come into play!!!!!! | |
56 | ||
57 | // TODO CAREFUL: fitMethod == 1 adds errors of electrons to pions, but not to muons (should be added to electron error instead!) | |
58 | const Bool_t muonContamination = kFALSE;//TODO CAREFUL: fitMethod == 1 takes into account the muon contamination in the error calculation!!! | |
59 | ||
60 | const Bool_t normaliseResults = kTRUE; // Works only for fitMethod == 2 | |
61 | ||
62 | const Bool_t enableShift = kFALSE; | |
63 | const Int_t dataAxis = kPidDeltaPrime;//kPidDelta; kPidDeltaPrime | |
64 | ||
65 | const Int_t numSimultaneousFits = 4; | |
66 | ||
67 | // Upper and lower axis bounds (y-axis) of (data - fit) / data QA histos | |
68 | const Double_t fitQAaxisLowBound = -0.5; | |
69 | const Double_t fitQAaxisUpBound = 0.5; | |
70 | ||
71 | Bool_t useDeltaPrime = (dataAxis == kPidDeltaPrime); | |
72 | ||
73 | // Will be set later | |
74 | Double_t muonFractionThresholdForFitting = -1.; | |
75 | Double_t muonFractionThresholdBinForFitting = -1; | |
76 | ||
77 | Double_t electronFractionThresholdForFitting = -1.; | |
78 | Double_t electronFractionThresholdBinForFitting = -1; | |
79 | ||
80 | ||
81 | TF1 fMuonOverElFractionMC("fMuonOverElFractionMC", "[0]+[1]/TMath::Min(x, [4])+[2]*TMath::Min(x, [4])+[3]*TMath::Min(x, [4])*TMath::Min(x, [4])+[5]*TMath::Min(x, [4])*TMath::Min(x, [4])*TMath::Min(x, [4])+[6]*(x>[7])*TMath::Min(x-[7], [8]-[7])", | |
82 | 0.01, 50.); | |
83 | ||
84 | TF1* fElectronFraction = 0x0; | |
85 | const Double_t lowFittingBoundElectronFraction = 3.0; | |
86 | ||
87 | TGraphErrors* gFractionElectronsData = 0x0; | |
88 | Double_t lastPtForCallOfGetElectronFraction = -1; | |
89 | ||
90 | ||
91 | //____________________________________________________________________________________________________________________ | |
92 | Double_t GetElectronFraction(const Double_t pT, const Double_t *par) | |
93 | { | |
94 | // During the fit (both, simultaneous and non-simultaneous), the algorithm will always start off from | |
95 | // the low pT and go to higher pT. So, it is only necessary to do the fit once the first fixed bin is reached. | |
96 | // Then the parameters for the electron fraction remain fixed until the next fit iteration. | |
97 | // Since only for the case of regularisation the electron fractions of all x bins are stored in mathFit, | |
98 | // the evaluation of this function is done here only in that case (only then the electron fraction will | |
99 | // be set to "-pT". | |
100 | ||
101 | // NOTE 1: Electrons have index 3 per x bin | |
102 | // NOTE 2: This function is only called for fitting vs. pT. In that case, xValue holds the LOG of pT! | |
103 | ||
104 | AliTPCPIDmathFit* mathFit = AliTPCPIDmathFit::Instance(); | |
105 | ||
106 | // lastPtForCallOfGetElectronFraction will be initialised with a value larger than any pT during the fit. | |
107 | // So, if this function is called and the pT is smaller than lastPtForCallOfGetElectronFraction, the parameters | |
108 | // must have changed and the electron fit needs to be re-done (also see comment above) | |
109 | if (pT < lastPtForCallOfGetElectronFraction) { | |
110 | for (Int_t xBin = 0; xBin < mathFit->GetNumXbinsRegularisation(); xBin++) { | |
111 | ||
112 | const Double_t xCoord = TMath::Exp(mathFit->GetXvaluesForRegularisation()[xBin]); | |
113 | const Int_t parIndexWithFraction = 3 + xBin * mathFit->GetNumParametersPerXbin(); | |
114 | ||
115 | if (xCoord >= lowFittingBoundElectronFraction && xCoord <= electronFractionThresholdForFitting | |
116 | && par[parIndexWithFraction] > epsilon) { // Skip zero values (usually due to failed fits) | |
117 | gFractionElectronsData->SetPoint(xBin, TMath::Exp(mathFit->GetXvaluesForRegularisation()[xBin]), par[parIndexWithFraction]); | |
118 | // Since the errors during the fitting are not reliable, use the following approximation on a statistical basis | |
119 | // (which indeed turns out to be rather good!) | |
120 | ||
121 | // Bin effective weight required for weighted data sets. In case of no weighting, the weight error is sqrt(weight), | |
122 | // i.e. effWeight is 1 | |
123 | const Double_t effWeight = mathFit->GetXstatisticalWeightError()[xBin] * mathFit->GetXstatisticalWeightError()[xBin] | |
124 | / mathFit->GetXstatisticalWeight()[xBin]; | |
125 | gFractionElectronsData->SetPointError(xBin, 0, effWeight * TMath::Sqrt(par[parIndexWithFraction] | |
126 | / mathFit->GetXstatisticalWeight()[xBin])); | |
127 | } | |
128 | else { | |
129 | gFractionElectronsData->SetPoint(xBin, -1, 0); | |
130 | gFractionElectronsData->SetPointError(xBin, 0, 0); | |
131 | } | |
132 | } | |
133 | ||
134 | gFractionElectronsData->Fit(fElectronFraction, "Ex0NQ", "", lowFittingBoundElectronFraction, electronFractionThresholdForFitting); | |
135 | } | |
136 | ||
137 | lastPtForCallOfGetElectronFraction = pT; | |
138 | ||
139 | // Catch cases in which the fit function yields invalid fractions (i.e. < 0 or > 1) | |
140 | return TMath::Max(0.0, TMath::Min(1.0, fElectronFraction->Eval(pT))); | |
141 | } | |
142 | ||
143 | ||
144 | //____________________________________________________________________________________________________________________ | |
145 | Double_t GetElectronFractionError() | |
146 | { | |
147 | // This function estimates the error of the electron fraction for the fixed values via using the parameter errors of | |
148 | // the electron fraction function. Note that the parameters (and errors) must be set before calling this function. | |
149 | ||
150 | // Produce several values via setting the parameters to a random value, which is distributed with a gaussian with mean = parValue | |
151 | // and sigma = parError and then take the 2*RMS as the error | |
152 | const Int_t nGenValues = 1000; | |
153 | Double_t genValues[nGenValues]; | |
154 | ||
155 | const Int_t nPars = fElectronFraction->GetNpar(); | |
156 | Double_t par[nPars]; | |
157 | ||
158 | TRandom3 rnd(0); // 0 means random seed | |
159 | ||
160 | const Double_t x = electronFractionThresholdForFitting + 1.; // Some value above the threshold to obtain a fixed value | |
161 | for (Int_t i = 0 ; i < nGenValues; i++) { | |
162 | for (Int_t iPar = 0; iPar < nPars; iPar++) | |
163 | par[iPar] = rnd.Gaus(fElectronFraction->GetParameter(iPar), fElectronFraction->GetParError(iPar)); | |
164 | ||
165 | genValues[i] = fElectronFraction->EvalPar(&x, &par[0]); | |
166 | } | |
167 | ||
168 | // NOTE: RMS is not really the root mean square, is it rather the sigma deviation, which is what is wanted here | |
169 | return 2. * TMath::RMS(nGenValues, &genValues[0]); | |
170 | } | |
171 | ||
172 | ||
173 | //____________________________________________________________________________________________________________________ | |
174 | Double_t GetMuonFractionFromElectronFractionAndPt(Double_t pT, Double_t elFrac) | |
175 | { | |
176 | if (muonFractionHandling == kMuonFracOverElFracTunedOnMCStandardTrackCuts) { | |
177 | // return elFrac / (1. + 7.06909e+01 * TMath::Exp(-2.95078e+00 * TMath::Power(pT, 5.05016e-01))); | |
178 | return elFrac / (1. + 2.01840e+10 * TMath::Exp(-2.50480e+01 * TMath::Power(pT, 5.89044e-02))); | |
179 | } | |
180 | else if (muonFractionHandling == kMuonFracOverElFracTunedOnMCHybridTrackCuts) { | |
181 | fMuonOverElFractionMC.SetParameters(-6.87241e-01, 4.19528e-02, 4.52095e+00, -6.20026e+00, 5.16629e-01, 2.88604e+00, 3.68058e-02, | |
182 | 2.21086e+00, 5.75003e+00); | |
183 | return elFrac * fMuonOverElFractionMC.Eval(pT); | |
184 | } | |
185 | else if (muonFractionHandling == kMuonFracOverElFracTunedOnMCHybridTrackCutsJets) { | |
186 | fMuonOverElFractionMC.SetParameters(-7.64548e-01, 2.47929e-02, 4.49057e+00, -2.06320e-01, 4.23339e-02, 1.19697e+02, 1.28832e-01, | |
187 | -1.71895e-01, 6.00000e+00); | |
188 | return elFrac * fMuonOverElFractionMC.Eval(pT); | |
189 | } | |
190 | else if (muonFractionHandling == kMuonFracOverElFracTunedOnMCStandardTrackCutsPPb) { | |
191 | // WITH PID cluster cut! | |
192 | fMuonOverElFractionMC.SetParameters(-6.62149e-01, 4.89591e-02, 4.58356e+00, -6.04319e+00, 6.25368e-01, 3.27191e+00, 1.69933e-01, | |
193 | 1.00004e+00, 2.61438e+00); | |
194 | return elFrac * fMuonOverElFractionMC.Eval(pT); | |
195 | } | |
196 | else if (muonFractionHandling == kMuonFracEqualElFrac) { | |
197 | return elFrac; | |
198 | } | |
199 | ||
200 | return 0.; | |
201 | } | |
202 | ||
203 | ||
204 | //____________________________________________________________________________________________________________________ | |
205 | Double_t GetCorrelatedError(const Double_t x, const Double_t y, const Double_t cov00, const Double_t cov11, const Double_t cov01) | |
206 | { | |
207 | // Calculate the correlated error df of f: | |
208 | // (cov00 cov01) (x) | |
209 | //df^2 = (x, y) * (cov01 cov11) (y) = x^2 * cov00 + y^2 * cov11 + 2 * x * y * cov01 | |
210 | // | |
211 | // with f = f(p1, p2) = p1 / p2 | |
212 | // and (x, y) = (\partial f / \partial p1, \partial f / \partial p2) | |
213 | // = (f / p1, -f / p2) | |
214 | ||
215 | const Double_t df2 = x * x * cov00 + y * y * cov11 + 2. * x * y * cov01; | |
216 | ||
217 | if (df2 < epsilon) | |
218 | return 0.; | |
219 | ||
220 | return TMath::Sqrt(df2); | |
221 | } | |
222 | ||
223 | ||
224 | //____________________________________________________________________________________________________________________ | |
225 | void GetRatioWithCorrelatedError(const Double_t fractionA, const Double_t fractionB, | |
226 | const Double_t fractionErrorA, const Double_t fractionErrorB, | |
227 | const Double_t covMatrixElementAB, Double_t& ratio, Double_t& ratioError) | |
228 | { | |
229 | // Given fractions A and B with corresponding errors and the off-diagonal covariance matrix element of | |
230 | // these fractions, calculate the ratio A/B and the error taking into account the correlation. | |
231 | // The results are stored in ratio and ratioError. | |
232 | ||
233 | if (fractionB < epsilon) { | |
234 | ratio = -999.; | |
235 | ratioError = 999.; | |
236 | ||
237 | return; | |
238 | } | |
239 | ||
240 | if (fractionA < epsilon) { | |
241 | ratio = 0.; | |
242 | ratioError = 999.; | |
243 | ||
244 | return; | |
245 | } | |
246 | ||
247 | ratio = fractionA / fractionB; | |
248 | ||
249 | const Double_t x = ratio / fractionA; | |
250 | const Double_t y = -ratio / fractionB; | |
251 | ||
252 | // covMatrixElement(i, i) = error(i)^2 | |
253 | ratioError = GetCorrelatedError(x, y, fractionErrorA * fractionErrorA, fractionErrorB * fractionErrorB, covMatrixElementAB); | |
254 | ||
255 | //printf("frationA %e\nfractionB %e\nfractionErrorA %e\nfractionErrorB %e\ncovMatrixElementAB %e\nratio %e\nx %e\ny %e\nratioError %e\n\n", | |
256 | // fractionA, fractionB, fractionErrorA, fractionErrorB, covMatrixElementAB, ratio, x, y, ratioError); | |
257 | } | |
258 | ||
259 | ||
260 | //____________________________________________________________________________________________________________________ | |
261 | void SetReasonableAxisRange(TAxis* axis, Int_t mode, Double_t pLow = -1, Double_t pHigh = -1) | |
262 | { | |
263 | if (mode == kPMpT) | |
264 | axis->SetRangeUser(TMath::Max(0.15, pLow - 0.1), TMath::Min(50., pHigh + 0.1)); | |
265 | else if (mode == kPMz) | |
266 | axis->SetRange(0, -1); | |
267 | else if (mode == kPMxi) | |
268 | axis->SetRange(0, -1); | |
269 | } | |
270 | ||
271 | //____________________________________________________________________________________________________________________ | |
272 | void SetReasonableXaxisRange(TH1* h, Int_t& binLow, Int_t& binHigh) | |
273 | { | |
274 | binLow = TMath::Max(1, h->FindFirstBinAbove(0)); | |
275 | binHigh = TMath::Min(h->GetNbinsX(), h->FindLastBinAbove(0)); | |
276 | ||
277 | h->GetXaxis()->SetRange(binLow, binHigh); | |
278 | h->GetXaxis()->SetMoreLogLabels(kTRUE); | |
279 | h->GetXaxis()->SetNoExponent(kTRUE); | |
280 | } | |
281 | ||
282 | ||
283 | //____________________________________________________________________________________________________________________ | |
284 | Int_t FindMomentumBin(const Double_t* pTbins, const Double_t value, const Int_t numPtBins = nPtBins) | |
285 | { | |
286 | for (Int_t bin = 0; bin < numPtBins; bin++) { | |
287 | if (value >= pTbins[bin] && value < pTbins[bin + 1]) | |
288 | return bin; | |
289 | } | |
290 | ||
291 | return -1; | |
292 | } | |
293 | ||
294 | ||
295 | //____________________________________________________________________________________________________________________ | |
296 | Double_t normaliseHist(TH1* h, Double_t scaleFactor = -1) | |
297 | { | |
298 | // Scales the histogram with the scale factor. If the scale factor is < 0, | |
299 | // the histogram is normalised to it's integral. | |
300 | // In both cases, the normalisation factor is returned. | |
301 | ||
302 | Double_t normFactor = 1.; | |
303 | ||
304 | if (scaleFactor < 0) { | |
305 | Double_t integralTemp = h->Integral(); | |
306 | if (integralTemp > 0) { | |
307 | normFactor = 1.0 / integralTemp; | |
308 | h->Scale(normFactor); | |
309 | } | |
310 | } | |
311 | else { | |
312 | normFactor = scaleFactor; | |
313 | h->Scale(normFactor); | |
314 | } | |
315 | ||
316 | h->GetXaxis()->SetTitleOffset(1.0); | |
317 | ||
318 | return normFactor; | |
319 | } | |
320 | ||
321 | ||
322 | //____________________________________________________________________________________________________________________ | |
323 | void normaliseYieldHist(TH1* h, Double_t numEvents, Double_t deta) | |
324 | { | |
325 | // Yield histos are already normalised to dpT. Now normalise to 1/NeV 1/(2pi pT) 1/deta in addition | |
326 | ||
327 | if (numEvents <= 0) // Do not normalise | |
328 | numEvents = 1; | |
329 | ||
330 | for (Int_t bin = 1; bin <= h->GetNbinsX(); bin++) { | |
331 | Double_t normFactor = 1. / (numEvents * 2 * TMath::Pi() * h->GetXaxis()->GetBinCenter(bin) * deta); | |
332 | h->SetBinContent(bin, h->GetBinContent(bin) * normFactor); | |
333 | h->SetBinError(bin, h->GetBinError(bin) * normFactor); | |
334 | } | |
335 | } | |
336 | ||
337 | ||
338 | //____________________________________________________________________________________________________________________ | |
339 | void normaliseGenYieldMCtruthHist(TH1* h, Double_t numEvents, Double_t deta) | |
340 | { | |
341 | // Yield histos are NOT normalised to dpT. Now normalise to 1/NeV 1/(2pi pT) 1/deta 1/dpT! | |
342 | ||
343 | if (numEvents <= 0) // Do not normalise | |
344 | numEvents = 1; | |
345 | ||
346 | for (Int_t bin = 1; bin <= h->GetNbinsX(); bin++) { | |
347 | Double_t normFactor = 1. / (numEvents * 2 * TMath::Pi() * h->GetXaxis()->GetBinCenter(bin) * h->GetXaxis()->GetBinWidth(bin) * deta); | |
348 | h->SetBinContent(bin, h->GetBinContent(bin) * normFactor); | |
349 | h->SetBinError(bin, h->GetBinError(bin) * normFactor); | |
350 | } | |
351 | } | |
352 | ||
353 | ||
354 | //____________________________________________________________________________________________________________________ | |
355 | void setUpFitFunction(TF1* fitFunc, Int_t nBins, Bool_t noShift = kFALSE) | |
356 | { | |
357 | fitFunc->SetLineColor(kGray + 1); | |
358 | fitFunc->SetLineWidth(2); | |
359 | fitFunc->SetLineStyle(1); | |
360 | fitFunc->SetNpx(nBins * 100); | |
361 | fitFunc->SetParName(0, "Pion fraction"); | |
362 | fitFunc->SetParName(1, "Kaon fraction"); | |
363 | fitFunc->SetParName(2, "Proton fraction"); | |
364 | fitFunc->SetParName(3, "Electron fraction"); | |
365 | fitFunc->SetParName(4, "Muon fraction"); | |
366 | fitFunc->SetParName(5, "Total yield"); | |
367 | if (noShift == kFALSE) { | |
368 | fitFunc->SetParName(6, "Shift of pion peak"); | |
369 | fitFunc->SetParName(7, "Shift of kaon peak"); | |
370 | fitFunc->SetParName(8, "Shift of proton peak"); | |
371 | fitFunc->SetParName(9, "Shift of electron peak"); | |
372 | fitFunc->SetParName(10, "Shift of muon peak"); | |
373 | } | |
374 | } | |
375 | ||
376 | ||
377 | //____________________________________________________________________________________________________________________ | |
378 | inline Int_t findBinWithinRange(const TAxis* axis, Double_t value) | |
379 | { | |
380 | Int_t bin = axis->FindFixBin(value); | |
381 | if (bin <= 0) | |
382 | bin = 1; | |
383 | if (bin > axis->GetNbins()) | |
384 | bin = axis->GetNbins(); | |
385 | ||
386 | return bin; | |
387 | } | |
388 | ||
389 | ||
390 | //____________________________________________________________________________________________________________________ | |
391 | Double_t linearInterpolation(const TH1* h, Double_t x, Double_t scaleFactor, Double_t shift, Double_t* error) | |
392 | { | |
393 | // Do linear interpolation between 2 bins to handle non-integer values of the shift parameters. | |
394 | // The shift also introduces some uncertainty, which is rather hard to estimate. Therefore, just take the maximum error of the involved bins. | |
395 | const Double_t xShifted = x - shift; | |
396 | ||
397 | // Just take value of bin, if beyond center of first/last bin | |
398 | if (xShifted <= h->GetBinCenter(1)) { | |
399 | if (error) | |
400 | *error = h->GetBinError(1) * scaleFactor; | |
401 | return h->GetBinContent(1) * scaleFactor; | |
402 | } | |
403 | else if(xShifted >= h->GetBinCenter(h->GetNbinsX())) { | |
404 | if (error) | |
405 | *error = h->GetBinError(h->GetNbinsX()) * scaleFactor; | |
406 | return h->GetBinContent(h->GetNbinsX()) * scaleFactor; | |
407 | } | |
408 | else { | |
409 | const Int_t xbin = h->FindFixBin(xShifted); | |
410 | Double_t x0, x1, y0, y1; | |
411 | ||
412 | if(xShifted <= h->GetBinCenter(xbin)) { | |
413 | y0 = h->GetBinContent(xbin - 1); | |
414 | x0 = h->GetBinCenter(xbin - 1); | |
415 | y1 = h->GetBinContent(xbin); | |
416 | x1 = h->GetBinCenter(xbin); | |
417 | ||
418 | if (error) | |
419 | *error = TMath::Max(h->GetBinError(xbin - 1), h->GetBinError(xbin)) * scaleFactor; | |
420 | } | |
421 | else { | |
422 | y0 = h->GetBinContent(xbin); | |
423 | x0 = h->GetBinCenter(xbin); | |
424 | y1 = h->GetBinContent(xbin + 1); | |
425 | x1 = h->GetBinCenter(xbin + 1); | |
426 | ||
427 | if (error) | |
428 | *error = TMath::Max(h->GetBinError(xbin), h->GetBinError(xbin + 1)) * scaleFactor; | |
429 | } | |
430 | ||
431 | return scaleFactor * (y0 + (xShifted - x0) * ((y1 - y0) / (x1 - x0))); | |
432 | } | |
433 | ||
434 | return 0; | |
435 | ||
436 | /*Old version available for code bevor 03.05.2013*/ | |
437 | } | |
438 | ||
439 | ||
440 | //____________________________________________________________________________________________________________________ | |
441 | void shiftHist(TH1D* h, Double_t shift, Bool_t useRegularisation = kFALSE) | |
442 | { | |
443 | // Shift not available for regularisation. Just for convenience (can use the same code and only set one flag) | |
444 | // call this functions and then do nothing. | |
445 | // Actually, the shift is not availabe for simultaneous fitting also, but the parameter is just set to 0 there | |
446 | if (!h || useRegularisation) | |
447 | return; | |
448 | ||
449 | TString name = h->GetName(); | |
450 | TH1D* hTemp = (TH1D*)h->Clone(Form("%s_clone", name.Data())); | |
451 | h->Reset(); | |
452 | ||
453 | Double_t error = 0; | |
454 | for (Int_t i = 1; i <= h->GetNbinsX(); i++) { | |
455 | // linearInterpolation with scaleFactor = 1.0, since histo is assumed to be properly scaled | |
456 | h->SetBinContent(i, linearInterpolation(hTemp, h->GetXaxis()->GetBinCenter(i), 1.0, shift, &error)); | |
457 | h->SetBinError(i, error); | |
458 | } | |
459 | ||
460 | delete hTemp; | |
461 | } | |
462 | ||
463 | ||
464 | //____________________________________________________________________________________________________________________ | |
465 | Double_t multiGaussFitForSimultaneousFitting(const Double_t *xx, const Double_t *par, const Int_t offset) | |
466 | { | |
467 | // Offset for reference histos for delta_Species | |
468 | AliTPCPIDmathFit* mathFit = AliTPCPIDmathFit::Instance(); | |
469 | ||
470 | // parXbinIndex (fixed) will be used my mathfit to hold the pT bin index (needed for regularisation) | |
471 | const Int_t xBinIndex = mathFit->GetXbinIndex(); | |
472 | const Int_t numParsPerXbin = mathFit->GetNumParametersPerXbin(); | |
473 | ||
474 | const Int_t numRefHistosPerFit = numSimultaneousFits + (takeIntoAccountMuons ? 1 : 0); | |
475 | const Int_t numRefHistosPerXbin = numRefHistosPerFit * numSimultaneousFits; | |
476 | ||
477 | const Int_t refHistOffset = offset * numRefHistosPerFit + xBinIndex * numRefHistosPerXbin; | |
478 | ||
479 | const TH1* hRefPi = mathFit->GetRefHisto(0 + refHistOffset); | |
480 | const TH1* hRefKa = mathFit->GetRefHisto(1 + refHistOffset); | |
481 | const TH1* hRefPr = mathFit->GetRefHisto(2 + refHistOffset); | |
482 | const TH1* hRefEl = mathFit->GetRefHisto(3 + refHistOffset); | |
483 | const TH1* hRefMu = takeIntoAccountMuons ? mathFit->GetRefHisto(4 + refHistOffset) : 0x0; | |
484 | ||
485 | if (!hRefEl || !hRefKa || !hRefPi || !hRefPr) | |
486 | return 0; | |
487 | ||
488 | if (takeIntoAccountMuons && !hRefMu) | |
489 | return 0; | |
490 | ||
491 | const Int_t parOffset = xBinIndex * numParsPerXbin; | |
492 | const Int_t parPi = 0 + parOffset; | |
493 | const Int_t parKa = 1 + parOffset; | |
494 | const Int_t parPr = 2 + parOffset; | |
495 | const Int_t parEl = 3 + parOffset; | |
496 | const Int_t parMu = 4 + parOffset; | |
497 | const Int_t parAll = 5 + parOffset; | |
498 | ||
499 | const Double_t scaleFactorPi = par[parAll] * (par[parPi] + (muonContamination ? par[parEl] : 0)); | |
500 | const Double_t scaleFactorKa = par[parAll] * par[parKa]; | |
501 | const Double_t scaleFactorPr = par[parAll] * par[parPr]; | |
502 | const Double_t parElFraction = (par[parEl] < 0) ? GetElectronFraction(-par[parEl], par) : par[parEl]; | |
503 | const Double_t scaleFactorEl = par[parAll] * parElFraction; | |
504 | // Fix muon fraction to electron fraction (or some modified electron fraction) if desired, i.e. corresponding par < 0 | |
505 | const Double_t scaleFactorMu = (par[parMu] < 0) | |
506 | ? (par[parAll] * GetMuonFractionFromElectronFractionAndPt(-par[parMu], parElFraction)) | |
507 | : (par[parAll] * par[parMu]); | |
508 | ||
509 | // Since one is looking at the same deltaSpecies for all considered species, the reference histograms have the same axes | |
510 | // => Only need to search for the bin once | |
511 | const Int_t binWithinRange = findBinWithinRange(hRefPi->GetXaxis(), xx[0]); | |
512 | const Double_t countPi = scaleFactorPi * hRefPi->GetBinContent(binWithinRange); | |
513 | const Double_t countKa = scaleFactorKa * hRefKa->GetBinContent(binWithinRange); | |
514 | const Double_t countPr = scaleFactorPr * hRefPr->GetBinContent(binWithinRange); | |
515 | const Double_t countEl = scaleFactorEl * hRefEl->GetBinContent(binWithinRange); | |
516 | const Double_t countMu = takeIntoAccountMuons ? scaleFactorMu * hRefMu->GetBinContent(binWithinRange) : 0; | |
517 | ||
518 | const Double_t res = countPi + countKa + countPr + countEl + countMu; | |
519 | ||
520 | ||
521 | return res; | |
522 | } | |
523 | ||
524 | ||
525 | //____________________________________________________________________________________________________________________ | |
526 | inline Double_t multiGaussFitDeltaPi(const Double_t *xx, const Double_t *par) | |
527 | { | |
528 | return multiGaussFitForSimultaneousFitting(xx, par, 0); | |
529 | } | |
530 | ||
531 | //____________________________________________________________________________________________________________________ | |
532 | inline Double_t multiGaussFitDeltaKa(const Double_t *xx, const Double_t *par) | |
533 | { | |
534 | return multiGaussFitForSimultaneousFitting(xx, par, 1); | |
535 | } | |
536 | ||
537 | //____________________________________________________________________________________________________________________ | |
538 | inline Double_t multiGaussFitDeltaPr(const Double_t *xx, const Double_t *par) | |
539 | { | |
540 | return multiGaussFitForSimultaneousFitting(xx, par, 2); | |
541 | } | |
542 | ||
543 | //____________________________________________________________________________________________________________________ | |
544 | inline Double_t multiGaussFitDeltaEl(const Double_t *xx, const Double_t *par) | |
545 | { | |
546 | return multiGaussFitForSimultaneousFitting(xx, par, 3); | |
547 | } | |
548 | ||
549 | ||
550 | //____________________________________________________________________________________________________________________ | |
551 | Double_t multiGaussFit(const Double_t *xx, const Double_t *par) | |
552 | { | |
553 | AliTPCPIDmathFit* mathFit = AliTPCPIDmathFit::Instance(); | |
554 | const TH1* hRefPi = mathFit->GetRefHisto(0); | |
555 | const TH1* hRefKa = mathFit->GetRefHisto(1); | |
556 | const TH1* hRefPr = mathFit->GetRefHisto(2); | |
557 | const TH1* hRefEl = mathFit->GetRefHisto(3); | |
558 | const TH1* hRefMu = takeIntoAccountMuons ? mathFit->GetRefHisto(4) : 0x0; | |
559 | ||
560 | if (!hRefEl || !hRefKa || !hRefPi || !hRefPr) | |
561 | return 0; | |
562 | ||
563 | if (takeIntoAccountMuons && !hRefMu) | |
564 | return 0; | |
565 | ||
566 | // Do linear interpolation between 2 bins to handle non-integer values of the shift parameters | |
567 | const Double_t scaleFactorPi = par[5] * (par[0] + (muonContamination ? par[3] : 0)); | |
568 | const Double_t scaleFactorKa = par[5] * par[1]; | |
569 | const Double_t scaleFactorPr = par[5] * par[2]; | |
570 | const Double_t parElFraction = (par[3] < 0) ? GetElectronFraction(-par[3], par) : par[3]; | |
571 | const Double_t scaleFactorEl = par[5] * parElFraction; | |
572 | // Fix muon fraction to electron fraction (or some modified electron fraction) if desired, i.e. corresponding par < 0 | |
573 | const Double_t scaleFactorMu = (par[4] < 0) | |
574 | ? (par[5] * GetMuonFractionFromElectronFractionAndPt(-par[4], parElFraction)) | |
575 | : (par[5] * par[4]); | |
576 | ||
577 | const Double_t countPi = linearInterpolation(hRefPi, xx[0], scaleFactorPi, par[6], 0x0); | |
578 | const Double_t countKa = linearInterpolation(hRefKa, xx[0], scaleFactorKa, par[7], 0x0); | |
579 | const Double_t countPr = linearInterpolation(hRefPr, xx[0], scaleFactorPr, par[8], 0x0); | |
580 | const Double_t countEl = linearInterpolation(hRefEl, xx[0], scaleFactorEl, par[9], 0x0); | |
581 | const Double_t countMu = takeIntoAccountMuons ? linearInterpolation(hRefMu, xx[0], scaleFactorMu, par[10], 0x0) : 0; | |
582 | ||
583 | const Double_t res = countPi + countKa + countPr + countEl + countMu; | |
584 | ||
585 | /* | |
586 | const Double_t countPi = linearInterpolation(hRefPi, xx[0], par[6], 0x0); | |
587 | const Double_t countKa = linearInterpolation(hRefKa, xx[0], par[7], 0x0); | |
588 | const Double_t countPr = linearInterpolation(hRefPr, xx[0], par[8], 0x0); | |
589 | const Double_t countEl = linearInterpolation(hRefEl, xx[0], par[9], 0x0); | |
590 | const Double_t countMu = takeIntoAccountMuons ? linearInterpolation(hRefMu, xx[0], par[10], 0x0) : 0; | |
591 | ||
592 | const Double_t res = par[5] * ((par[0] + (muonContamination ? par[3] : 0)) * countPi + par[1] * countKa | |
593 | + par[2] * countPr + par[3] * countEl + par[4] * countMu); | |
594 | ||
595 | */ | |
596 | ||
597 | return res; | |
598 | } | |
599 | ||
600 | ||
601 | //____________________________________________________________________________________________________________________ | |
602 | Double_t errorOfFitHistosForSimultaneousFitting(const Double_t *xx, const Double_t *par, const Int_t offset) | |
603 | { | |
604 | AliTPCPIDmathFit* mathFit = AliTPCPIDmathFit::Instance(); | |
605 | ||
606 | Double_t summedError = 0; | |
607 | ||
608 | // parXbinIndex (fixed) will be used my mathfit to hold the pT bin index (needed for regularisation) | |
609 | const Int_t xBinIndex = mathFit->GetXbinIndex(); | |
610 | const Int_t numParsPerXbin = mathFit->GetNumParametersPerXbin(); | |
611 | ||
612 | const Int_t numRefHistosPerFit = numSimultaneousFits + (takeIntoAccountMuons ? 1 : 0); | |
613 | const Int_t numRefHistosPerXbin = numRefHistosPerFit * numSimultaneousFits; | |
614 | ||
615 | const Int_t refHistOffset = offset * numRefHistosPerFit + xBinIndex * numRefHistosPerXbin; | |
616 | ||
617 | const TH1* hRefPi = mathFit->GetRefHisto(0 + refHistOffset); | |
618 | const TH1* hRefKa = mathFit->GetRefHisto(1 + refHistOffset); | |
619 | const TH1* hRefPr = mathFit->GetRefHisto(2 + refHistOffset); | |
620 | const TH1* hRefEl = mathFit->GetRefHisto(3 + refHistOffset); | |
621 | const TH1* hRefMu = takeIntoAccountMuons ? | |
622 | mathFit->GetRefHisto(4 + refHistOffset) | |
623 | : 0x0; | |
624 | ||
625 | if (!hRefEl || !hRefKa || !hRefPi || !hRefPr) | |
626 | return 0; | |
627 | ||
628 | if (takeIntoAccountMuons && !hRefMu) | |
629 | return 0; | |
630 | ||
631 | const Int_t parOffset = xBinIndex * numParsPerXbin; | |
632 | const Int_t parPi = 0 + parOffset; | |
633 | const Int_t parKa = 1 + parOffset; | |
634 | const Int_t parPr = 2 + parOffset; | |
635 | const Int_t parEl = 3 + parOffset; | |
636 | const Int_t parMu = 4 + parOffset; | |
637 | const Int_t parAll = 5 + parOffset; | |
638 | ||
639 | const Double_t scaleFactorPi = par[parAll] * (par[parPi] + (muonContamination ? par[parEl] : 0)); | |
640 | const Double_t scaleFactorKa = par[parAll] * par[parKa]; | |
641 | const Double_t scaleFactorPr = par[parAll] * par[parPr]; | |
642 | const Double_t scaleFactorEl = par[parAll] * ((par[parEl] < 0) ? GetElectronFraction(-par[parEl], par) : par[parEl]); | |
643 | // Fix muon fraction to electron fraction (or some modified electron fraction) if desired, i.e. corresponding par < 0 | |
644 | const Double_t scaleFactorMu = (par[parMu] < 0) ? | |
645 | (scaleFactorEl * GetMuonFractionFromElectronFractionAndPt(-par[parMu], par[parEl]) / par[parEl]) | |
646 | : (par[parAll] * par[parMu]); | |
647 | ||
648 | Double_t errorPi = 0, errorKa = 0, errorPr = 0, errorEl = 0, errorMu = 0; | |
649 | ||
650 | // Do linear interpolation between 2 bins to handle non-integer values of the shift parameters | |
651 | // Shift not implemented for simultaneous fit -> Just set all corresponding parameters to zero | |
652 | linearInterpolation(hRefPi, xx[0], scaleFactorPi, 0, &errorPi); | |
653 | linearInterpolation(hRefKa, xx[0], scaleFactorKa, 0, &errorKa); | |
654 | linearInterpolation(hRefPr, xx[0], scaleFactorPr, 0, &errorPr); | |
655 | linearInterpolation(hRefEl, xx[0], scaleFactorEl, 0, &errorEl); | |
656 | if (takeIntoAccountMuons) | |
657 | linearInterpolation(hRefMu, xx[0], scaleFactorMu, 0, &errorMu); | |
658 | ||
659 | summedError += TMath::Power(errorPi, 2); | |
660 | summedError += TMath::Power(errorKa, 2); | |
661 | summedError += TMath::Power(errorPr, 2); | |
662 | summedError += TMath::Power(errorEl, 2); | |
663 | if (takeIntoAccountMuons) | |
664 | summedError += TMath::Power(errorMu, 2); | |
665 | ||
666 | return summedError; | |
667 | } | |
668 | ||
669 | ||
670 | //____________________________________________________________________________________________________________________ | |
671 | inline Double_t errorOfFitHistosDeltaPi(const Double_t *xx, const Double_t *par) | |
672 | { | |
673 | return errorOfFitHistosForSimultaneousFitting(xx, par, 0); | |
674 | } | |
675 | ||
676 | ||
677 | //____________________________________________________________________________________________________________________ | |
678 | inline Double_t errorOfFitHistosDeltaKa(const Double_t *xx, const Double_t *par) | |
679 | { | |
680 | return errorOfFitHistosForSimultaneousFitting(xx, par, 1); | |
681 | } | |
682 | ||
683 | ||
684 | //____________________________________________________________________________________________________________________ | |
685 | inline Double_t errorOfFitHistosDeltaPr(const Double_t *xx, const Double_t *par) | |
686 | { | |
687 | return errorOfFitHistosForSimultaneousFitting(xx, par, 2); | |
688 | } | |
689 | ||
690 | ||
691 | //____________________________________________________________________________________________________________________ | |
692 | inline Double_t errorOfFitHistosDeltaEl(const Double_t *xx, const Double_t *par) | |
693 | { | |
694 | return errorOfFitHistosForSimultaneousFitting(xx, par, 3); | |
695 | } | |
696 | ||
697 | ||
698 | //____________________________________________________________________________________________________________________ | |
699 | Double_t errorOfFitHistos(const Double_t *xx, const Double_t *par) | |
700 | { | |
701 | //TODO Error of shift is still not taken into account | |
702 | AliTPCPIDmathFit* mathFit = AliTPCPIDmathFit::Instance(); | |
703 | ||
704 | Double_t summedError = 0; | |
705 | ||
706 | const TH1* hRefPi = mathFit->GetRefHisto(0); | |
707 | const TH1* hRefKa = mathFit->GetRefHisto(1); | |
708 | const TH1* hRefPr = mathFit->GetRefHisto(2); | |
709 | const TH1* hRefEl = mathFit->GetRefHisto(3); | |
710 | const TH1* hRefMu = takeIntoAccountMuons ? mathFit->GetRefHisto(4) : 0x0; | |
711 | ||
712 | if (!hRefEl || !hRefKa || !hRefPi || !hRefPr) | |
713 | return 0; | |
714 | ||
715 | if (takeIntoAccountMuons && !hRefMu) | |
716 | return 0; | |
717 | ||
718 | // Do linear interpolation between 2 bins to handle non-integer values of the shift parameters | |
719 | const Double_t scaleFactorPi = par[5] * (par[0] + (muonContamination ? par[3] : 0)); | |
720 | const Double_t scaleFactorKa = par[5] * par[1]; | |
721 | const Double_t scaleFactorPr = par[5] * par[2]; | |
722 | const Double_t scaleFactorEl = par[5] * ((par[3] < 0) ? GetElectronFraction(-par[3], par) : par[3]); | |
723 | // Fix muon fraction to electron fraction (or some modified electron fraction) if desired, i.e. corresponding par < 0 | |
724 | const Double_t scaleFactorMu = (par[4] < 0) ? (scaleFactorEl * GetMuonFractionFromElectronFractionAndPt(-par[4], par[3]) / par[3]) | |
725 | : (par[5] * par[4]); | |
726 | ||
727 | Double_t errorPi = 0, errorKa = 0, errorPr = 0, errorEl = 0, errorMu = 0; | |
728 | ||
729 | linearInterpolation(hRefPi, xx[0], scaleFactorPi, par[6], &errorPi); | |
730 | linearInterpolation(hRefKa, xx[0], scaleFactorKa, par[7], &errorKa); | |
731 | linearInterpolation(hRefPr, xx[0], scaleFactorPr, par[8], &errorPr); | |
732 | linearInterpolation(hRefEl, xx[0], scaleFactorEl, par[9], &errorEl); | |
733 | if (takeIntoAccountMuons) | |
734 | linearInterpolation(hRefMu, xx[0], scaleFactorMu, par[10], &errorMu); // Assume same fraction as electron, i.e. same scale factor | |
735 | ||
736 | summedError += TMath::Power(errorPi, 2); | |
737 | summedError += TMath::Power(errorKa, 2); | |
738 | summedError += TMath::Power(errorPr, 2); | |
739 | summedError += TMath::Power(errorEl, 2); | |
740 | if (takeIntoAccountMuons) | |
741 | summedError += TMath::Power(errorMu, 2); | |
742 | ||
743 | ||
744 | /* | |
745 | for (Int_t index = 0; index < mathFit->GetNrefHistos(); index++) { | |
746 | TH1* HREF = mathFit->GetRefHisto(index); | |
747 | Int_t bin = findBinWithinRange(HREF->GetXaxis(), xx[0]); | |
748 | summedError += TMath::Power(HREF->GetBinError(bin) * par[index] * par[mathFit->GetNrefHistos()], 2); | |
749 | } | |
750 | */ | |
751 | return summedError; | |
752 | } | |
753 | ||
754 | ||
755 | //____________________________________________________________________________________________________________________ | |
756 | inline Double_t saveDivide(Double_t numerator, Double_t denominator) | |
757 | { | |
758 | return ((denominator != 0) ? numerator/denominator : 0 ); | |
759 | } | |
760 | ||
761 | ||
762 | //____________________________________________________________________________________________________________________ | |
763 | Double_t getErrorOfPionIntegral(TMatrixDSym covMat) | |
764 | { | |
765 | return TMath::Sqrt(covMat(0, 0) + covMat(12, 12) + 2 * covMat(0, 12)); | |
766 | } | |
767 | ||
768 | ||
769 | //____________________________________________________________________________________________________________________ | |
770 | Double_t getErrorOfElectronFraction(Double_t* par, TMatrixDSym covMat) | |
771 | { | |
772 | Double_t g = saveDivide(par[3], (par[0] + par[1] + par[2] + 2 * par[3])); | |
773 | Double_t s1 = TMath::Power(g, 4) * (covMat(0, 0) + covMat(1, 1) + covMat(2, 2) + 4 * covMat(3, 3)); | |
774 | Double_t s2 = TMath::Power(g, 2) * covMat(3, 3); | |
775 | Double_t s3 = (4 * TMath::Power(g, 4) - 2 * TMath::Power(g, 3)) * (covMat(3, 2) + covMat(3, 1) + covMat(3, 0)); | |
776 | Double_t s4 = TMath::Power(g, 4) * 2 * (covMat(2, 1) + covMat(2, 0) +covMat(1, 0)); | |
777 | ||
778 | return saveDivide(TMath::Sqrt(s1 + s2 + s3 + s4), par[3]); | |
779 | } | |
780 | ||
781 | ||
782 | //____________________________________________________________________________________________________________________ | |
783 | Double_t getErrorOfKaonFraction(Double_t* par, TMatrixDSym covMat) | |
784 | { | |
785 | Double_t g = saveDivide(par[1], (par[0] + par[1] + par[2] + 2 * par[3])); | |
786 | Double_t s1 = TMath::Power(g, 4) * (covMat(0, 0) + covMat(1, 1) + covMat(2, 2) + 4 * covMat(3, 3)); | |
787 | Double_t s2 = TMath::Power(g, 2) * covMat(1, 1); | |
788 | Double_t s3 = TMath::Power(g, 4) * (4 * covMat(3, 0) + 4 * covMat(3, 2) + 4 * covMat(3, 1) + | |
789 | 2 * covMat(2, 1) + 2 * covMat(2, 0) + 2 * covMat(1, 0)); | |
790 | Double_t s4 = TMath::Power(g, 3) * ((-4) * covMat(3, 1) - 2 * covMat(2, 1) - 2 * covMat(1, 0)); | |
791 | ||
792 | return saveDivide(TMath::Sqrt(s1 + s2 + s3 + s4), par[1]); | |
793 | } | |
794 | ||
795 | ||
796 | //____________________________________________________________________________________________________________________ | |
797 | Double_t getErrorOfPionFraction(Double_t* par, TMatrixDSym covMat) | |
798 | { | |
799 | Double_t g = saveDivide(par[0] + par[3], (par[0] + par[1] + par[2] + 2 * par[3])); | |
800 | Double_t s1 = TMath::Power(g, 4) * (covMat(0, 0) + covMat(1, 1) + covMat(2, 2) + 4 * covMat(3, 3)); | |
801 | Double_t s2 = TMath::Power(g, 2) * (covMat(0, 0) + covMat(3, 3)); | |
802 | Double_t s3 = TMath::Power(g, 4) * 2 * covMat(2, 1); | |
803 | Double_t s4 = (4 * TMath::Power(g, 4) - 2 * TMath::Power(g, 3)) * (covMat(3, 2) + covMat(3, 1)); | |
804 | Double_t s5 = 2 * covMat(3, 0) * (2 * TMath::Power(g, 4) - 3 * TMath::Power(g, 3) + TMath::Power(g, 2)); | |
805 | Double_t s6 = 2 * (covMat(2, 0) + covMat(1, 0)) * (TMath::Power(g, 4) - TMath::Power(g, 3)); | |
806 | ||
807 | return saveDivide(TMath::Sqrt(s1 + s2 + s3 + s4 + s5 + s6), par[0] + par[3]); | |
808 | } | |
809 | ||
810 | ||
811 | //____________________________________________________________________________________________________________________ | |
812 | Double_t getErrorOfProtonFraction(Double_t* par, TMatrixDSym covMat) | |
813 | { | |
814 | Double_t g = saveDivide(par[2], (par[0] + par[2] + par[1] + 2 * par[3])); | |
815 | Double_t s1 = TMath::Power(g, 4) * (covMat(0, 0) + covMat(1, 1) + covMat(2, 2) + 4 * covMat(3, 3)); | |
816 | Double_t s2 = TMath::Power(g, 2) * covMat(2, 2); | |
817 | Double_t s3 = TMath::Power(g, 4) * (4 * covMat(3, 0) + 4 * covMat(3, 2) + 4 * covMat(3, 1) + | |
818 | 2 * covMat(2, 1) + 2 * covMat(2, 0) + 2 * covMat(1, 0)); | |
819 | Double_t s4 = TMath::Power(g, 3) * ((-4) * covMat(3, 2) - 2 * covMat(2, 1) - 2 * covMat(2, 0)); | |
820 | ||
821 | return saveDivide(TMath::Sqrt(s1 + s2 + s3 + s4), par[2]); | |
822 | } | |
823 | ||
824 | ||
825 | //____________________________________________________________________________________________________________________ | |
826 | Double_t getErrorOfTotalIntegral(TMatrixDSym covMat) | |
827 | { | |
828 | Double_t s1 = covMat(0, 0) + covMat(1, 1) + covMat(2, 2) + 4 * covMat(3, 3); | |
829 | Double_t s2 = 4 * (covMat(3, 0) + covMat(3, 1) + covMat(3, 2)); | |
830 | Double_t s3 = 2 * (covMat(2, 1) + covMat(2, 0) + covMat(1, 0)); | |
831 | ||
832 | return TMath::Sqrt(s1 + s2 + s3); | |
833 | } | |
834 | ||
835 | ||
836 | //____________________________________________________________________________________________________________________ | |
837 | Double_t getMedianOfNonZeros(Double_t input[4]) | |
838 | { | |
839 | Double_t values[4] = {0,0,0,0}; | |
840 | Int_t numNonZero = 0; | |
841 | if (input[0] > 0) { | |
842 | values[numNonZero] = input[0]; | |
843 | numNonZero++; | |
844 | } | |
845 | if (input[1] > 0) { | |
846 | values[numNonZero] = input[1]; | |
847 | numNonZero++; | |
848 | } | |
849 | if (input[2] > 0) { | |
850 | values[numNonZero] = input[2]; | |
851 | numNonZero++; | |
852 | } | |
853 | if (input[3] > 0) { | |
854 | values[numNonZero] = input[3]; | |
855 | numNonZero++; | |
856 | } | |
857 | ||
858 | return ((numNonZero > 0) ? TMath::Median(numNonZero, values) : 0); | |
859 | } | |
860 | ||
861 | ||
862 | //____________________________________________________________________________________________________________________ | |
863 | TCanvas* drawFractionHistos(TString canvName, TString canvTitle, Int_t mode, Double_t pLow, Double_t pHigh, | |
864 | TH1* histDeltaPion, TH1* histDeltaElectron, TH1* histDeltaKaon, TH1* histDeltaProton, TH1* histMC, | |
865 | Bool_t plotIdentifiedSpectra) | |
866 | { | |
867 | TCanvas* canv = new TCanvas(canvName.Data(), canvTitle.Data(),100,10,1200,800); | |
868 | canv->SetGridx(1); | |
869 | canv->SetGridy(1); | |
870 | canv->SetLogx(mode == kPMpT); | |
871 | histDeltaPion->GetYaxis()->SetRangeUser(0.0, 1.0); | |
872 | histDeltaPion->GetYaxis()->SetTitle(canvTitle.Data()); | |
873 | SetReasonableAxisRange(histDeltaPion->GetXaxis(), mode, pLow, pHigh); | |
874 | histDeltaPion->SetMarkerStyle(20); | |
875 | histDeltaPion->GetXaxis()->SetMoreLogLabels(kTRUE); | |
876 | histDeltaPion->GetXaxis()->SetNoExponent(kTRUE); | |
877 | histDeltaPion->Draw("e p"); | |
878 | histDeltaElectron->GetYaxis()->SetTitle(canvTitle.Data()); | |
879 | SetReasonableAxisRange(histDeltaElectron->GetXaxis(), mode, pLow, pHigh); | |
880 | histDeltaElectron->SetMarkerStyle(21); | |
881 | histDeltaElectron->Draw("e p same"); | |
882 | histDeltaKaon->GetYaxis()->SetTitle(canvTitle.Data()); | |
883 | SetReasonableAxisRange(histDeltaKaon->GetXaxis(), mode, pLow, pHigh); | |
884 | histDeltaKaon->SetMarkerStyle(22); | |
885 | histDeltaKaon->Draw("e p same"); | |
886 | histDeltaProton->GetYaxis()->SetTitle(canvTitle.Data()); | |
887 | SetReasonableAxisRange(histDeltaProton->GetXaxis(), mode, pLow, pHigh); | |
888 | histDeltaProton->SetMarkerStyle(29); | |
889 | histDeltaProton->Draw("e p same"); | |
890 | if (plotIdentifiedSpectra) { | |
891 | histMC->GetYaxis()->SetTitle(canvTitle.Data()); | |
892 | SetReasonableAxisRange(histMC->GetXaxis(), mode, pLow, pHigh); | |
893 | histMC->SetMarkerStyle(24); | |
894 | histMC->Draw("e p same"); | |
895 | } | |
896 | ||
897 | TLegend* legend = new TLegend(0.622126, 0.605932, 0.862069, 0.855932); | |
898 | legend->SetBorderSize(0); | |
899 | legend->SetFillColor(0); | |
900 | legend->AddEntry(histDeltaPion, Form("#Delta%s", useDeltaPrime ? "'_{#lower[-0.5]{#pi}}" : "_{#pi}"), "p"); | |
901 | legend->AddEntry(histDeltaElectron, Form("#Delta%s", useDeltaPrime ? "'_{#lower[-0.5]{e}}" : "_{e}"), "p"); | |
902 | legend->AddEntry(histDeltaKaon, Form("#Delta%s", useDeltaPrime ? "'_{#lower[-0.5]{K}}" : "_{K}"), "p"); | |
903 | legend->AddEntry(histDeltaProton, Form("#Delta%s", useDeltaPrime ? "'_{#lower[-0.5]{p}}" : "_{p}"), "p"); | |
904 | if (plotIdentifiedSpectra) | |
905 | legend->AddEntry(histMC, identifiedLabels[isMC].Data(), "p"); | |
906 | legend->SetEntrySeparation(0.2); | |
907 | legend->Draw(); | |
908 | ||
909 | ClearTitleFromHistoInCanvas(canv); | |
910 | ||
911 | return canv; | |
912 | } | |
913 | ||
914 | ||
915 | //____________________________________________________________________________________________________________________ | |
916 | TCanvas* drawYieldHistos(TString canvName, TString canvTitle, Int_t mode, Double_t pLow, Double_t pHigh, | |
917 | TH1* histDeltaPion, TH1* histDeltaElectron, TH1* histDeltaKaon, TH1* histDeltaProton, TH1* histMC, | |
918 | Bool_t plotIdentifiedSpectra) | |
919 | { | |
920 | TCanvas* canv = new TCanvas(canvName.Data(), canvTitle.Data(),100,10,1200,800); | |
921 | canv->SetGridx(1); | |
922 | canv->SetGridy(1); | |
923 | canv->SetLogx(mode == kPMpT); | |
924 | canv->SetLogy(1); | |
925 | histDeltaPion->GetYaxis()->SetRangeUser(histDeltaPion->GetBinContent(histDeltaPion->FindLastBinAbove(0.)) / 10., | |
926 | histDeltaPion->GetBinContent(histDeltaPion->GetMaximumBin()) * 10.); | |
927 | histDeltaPion->GetYaxis()->SetTitle(canvTitle.Data()); | |
928 | SetReasonableAxisRange(histDeltaPion->GetXaxis(), mode, pLow, pHigh); | |
929 | histDeltaPion->SetMarkerStyle(20); | |
930 | histDeltaPion->GetXaxis()->SetMoreLogLabels(kTRUE); | |
931 | histDeltaPion->GetXaxis()->SetNoExponent(kTRUE); | |
932 | histDeltaPion->Draw("e p"); | |
933 | histDeltaElectron->GetYaxis()->SetTitle(canvTitle.Data()); | |
934 | SetReasonableAxisRange(histDeltaElectron->GetXaxis(), mode, pLow, pHigh); | |
935 | histDeltaElectron->SetMarkerStyle(21); | |
936 | histDeltaElectron->Draw("e p same"); | |
937 | histDeltaKaon->GetYaxis()->SetTitle(canvTitle.Data()); | |
938 | SetReasonableAxisRange(histDeltaKaon->GetXaxis(), mode, pLow, pHigh); | |
939 | histDeltaKaon->SetMarkerStyle(22); | |
940 | histDeltaKaon->Draw("e p same"); | |
941 | histDeltaProton->GetYaxis()->SetTitle(canvTitle.Data()); | |
942 | SetReasonableAxisRange(histDeltaProton->GetXaxis(), mode, pLow, pHigh); | |
943 | histDeltaProton->SetMarkerStyle(29); | |
944 | histDeltaProton->Draw("e p same"); | |
945 | if (plotIdentifiedSpectra) { | |
946 | histMC->GetYaxis()->SetTitle(canvTitle.Data()); | |
947 | SetReasonableAxisRange(histMC->GetXaxis(), mode, pLow, pHigh); | |
948 | histMC->SetMarkerStyle(24); | |
949 | histMC->Draw("e p same"); | |
950 | } | |
951 | ||
952 | TLegend* legend = new TLegend(0.622126, 0.605932, 0.862069, 0.855932); | |
953 | legend->SetBorderSize(0); | |
954 | legend->SetFillColor(0); | |
955 | ||
956 | legend->AddEntry(histDeltaPion, Form("#Delta%s", useDeltaPrime ? "'_{#lower[-0.5]{#pi}}" : "_{#pi}"), "p"); | |
957 | legend->AddEntry(histDeltaElectron, Form("#Delta%s", useDeltaPrime ? "'_{#lower[-0.5]{e}}" : "_{e}"), "p"); | |
958 | legend->AddEntry(histDeltaKaon, Form("#Delta%s", useDeltaPrime ? "'_{#lower[-0.5]{K}}" : "_{K}"), "p"); | |
959 | legend->AddEntry(histDeltaProton, Form("#Delta%s", useDeltaPrime ? "'_{#lower[-0.5]{p}}" : "_{p}"), "p"); | |
960 | if (plotIdentifiedSpectra) | |
961 | legend->AddEntry(histMC, identifiedLabels[isMC].Data(), "p"); | |
962 | legend->SetEntrySeparation(0.2); | |
963 | legend->Draw(); | |
964 | ||
965 | ClearTitleFromHistoInCanvas(canv); | |
966 | ||
967 | return canv; | |
968 | } | |
969 | ||
970 | ||
971 | //____________________________________________________________________________________________________________________ | |
972 | Int_t doSimultaneousFitRegularised(Int_t nPar, Double_t* gausParams, Double_t* parameterErrorsOut, Double_t* covMatrix, | |
973 | Double_t* stepSize, Double_t* lowParLimits, Double_t* upParLimits, Double_t& reducedChiSquare) | |
974 | { | |
975 | AliTPCPIDmathFit* mathFit = AliTPCPIDmathFit::Instance(); | |
976 | ||
977 | Double_t chiSquare = -999; | |
978 | Int_t ndf = -1; | |
979 | ||
980 | AliTPCPIDmathFit::FitFunc_t* multiGaussFitArray = new AliTPCPIDmathFit::FitFunc_t[numSimultaneousFits]; | |
981 | multiGaussFitArray[0] = multiGaussFitDeltaPi; | |
982 | multiGaussFitArray[1] = multiGaussFitDeltaKa; | |
983 | multiGaussFitArray[2] = multiGaussFitDeltaPr; | |
984 | multiGaussFitArray[3] = multiGaussFitDeltaEl; | |
985 | ||
986 | AliTPCPIDmathFit::FitFunc_t* errorOfFitHistosArray = new AliTPCPIDmathFit::FitFunc_t[numSimultaneousFits]; | |
987 | errorOfFitHistosArray[0] = errorOfFitHistosDeltaPi; | |
988 | errorOfFitHistosArray[1] = errorOfFitHistosDeltaKa; | |
989 | errorOfFitHistosArray[2] = errorOfFitHistosDeltaPr; | |
990 | errorOfFitHistosArray[3] = errorOfFitHistosDeltaEl; | |
991 | ||
992 | //TODO errorFunction for bin errors of fit histos? | |
993 | Int_t errFlag = mathFit->MinuitFit(multiGaussFitArray, 0x0, nPar, gausParams, parameterErrorsOut, covMatrix, | |
994 | chiSquare, ndf, stepSize, lowParLimits, upParLimits); | |
995 | //Int_t errFlag = mathFit->MinuitFit(multiGaussFitArray, errorOfFitHistosArray, nPar, gausParams, parameterErrorsOut, covMatrix, | |
996 | // chiSquare, ndf, stepSize, lowParLimits, upParLimits); | |
997 | ||
998 | std::cout << std::endl; | |
999 | ||
1000 | for (Int_t xBin = 0; xBin < mathFit->GetNumXbinsRegularisation(); xBin++) { | |
1001 | std::cout << "x bin " << xBin << ":" << std::endl; | |
1002 | ||
1003 | Double_t sumFractions = 0; | |
1004 | ||
1005 | for (Int_t parIndex = xBin * mathFit->GetNumParametersPerXbin(); parIndex < (xBin + 1) * mathFit->GetNumParametersPerXbin(); | |
1006 | parIndex++) { | |
1007 | Int_t parIndexModulo = parIndex % mathFit->GetNumParametersPerXbin(); | |
1008 | ||
1009 | // NOTE: Covariance matrix is NOT set. But this doesn't matter since the parameter is fixed anyway, so | |
1010 | // the error from the matrix would be zero. | |
1011 | // parIndexModulo = 4 means muons, parIndexModulo = 3 means electrons, i.e. if parIndexModulo corresponds to muons, | |
1012 | // then parIndexModulo - 1 corresponds to electrons. | |
1013 | ||
1014 | // Set electron fraction to value evaluated from a function above some threshold. | |
1015 | // Fixed electron fraction < 0 does this job within the fitting functions | |
1016 | if (parIndexModulo == 3 && gausParams[parIndex] < 0) { | |
1017 | gausParams[parIndex] = GetElectronFraction(-gausParams[parIndex], &gausParams[0]); | |
1018 | parameterErrorsOut[parIndex] = GetElectronFractionError(); | |
1019 | } | |
1020 | // Set muon fraction equal to electron fraction (or some modified electron fraction) above some threshold, | |
1021 | // which should be a reasonable approximation: | |
1022 | // Fixed muon fraction < 0 does this job within the fitting functions | |
1023 | else if (parIndexModulo == 4 && gausParams[parIndex] < 0) { | |
1024 | gausParams[parIndex] = GetMuonFractionFromElectronFractionAndPt(-gausParams[parIndex], gausParams[parIndex - 1]); | |
1025 | parameterErrorsOut[parIndex] = parameterErrorsOut[parIndex - 1]; | |
1026 | } | |
1027 | ||
1028 | ||
1029 | std::cout << "par[" << parIndex << "]: " << gausParams[parIndex] << " +- " << parameterErrorsOut[parIndex] << std::endl; | |
1030 | ||
1031 | if (parIndexModulo <= 3 || ((muonContamination || takeIntoAccountMuons) && parIndexModulo == 4)) | |
1032 | sumFractions += gausParams[parIndex]; | |
1033 | } | |
1034 | ||
1035 | std::cout << "Sum of fractions" << (muonContamination || takeIntoAccountMuons ? "(including muon contamination)" : "") << ": " | |
1036 | << sumFractions; std::cout << std::endl; | |
1037 | std::cout << std::endl << std::endl; | |
1038 | } | |
1039 | ||
1040 | if (errFlag == 0) | |
1041 | std::cout << std::endl << "***Fit operation completed successfully***" << std::endl << std::endl; | |
1042 | else | |
1043 | std::cout << std::endl << "***Fit operation completed, but with errors***" << std::endl << std::endl; | |
1044 | ||
1045 | reducedChiSquare = (ndf > 0) ? chiSquare / ndf : -1; | |
1046 | ||
1047 | return errFlag; | |
1048 | } | |
1049 | ||
1050 | ||
1051 | //____________________________________________________________________________________________________________________ | |
1052 | Int_t doSimultaneousFit(TH1D** hDelta, Double_t xLow, Double_t xUp, Int_t nPar, Double_t* gausParams, Double_t* parameterErrorsOut, | |
1053 | Double_t* covMatrix, Double_t* stepSize, Double_t* lowParLimits, Double_t* upParLimits, Double_t& | |
1054 | reducedChiSquare) | |
1055 | { | |
1056 | AliTPCPIDmathFit* mathFit = AliTPCPIDmathFit::Instance(); | |
1057 | ||
1058 | Double_t chiSquare = -999; | |
1059 | Int_t ndf = -1; | |
1060 | ||
1061 | //TODO: | |
1062 | // Using no error on x (next TODO line) and no errorFunction (next after next TODO line) sometimes gives good results. | |
1063 | // However, it can completely fail for low statistics for the fit histos. | |
1064 | // Using either an error on x or the errorFunction both gives reasonable results, but might be slightly worse results in some cases | |
1065 | // (shifted/distorted data). Maybe: Choose one method - the rest is for systematic errors of this fitting | |
1066 | ||
1067 | //TODO The next TODO marks are only relevant for chiSquare, but not for loglikelihood | |
1068 | //TODO Use error in x also -> If reference histos have low statistics, this will be very important | |
1069 | ||
1070 | for (Int_t i = 0; i < numSimultaneousFits; i++) { | |
1071 | mathFit->InputData(hDelta[i], 0, i, xLow, xUp, -1., kFALSE); | |
1072 | //mathFit->InputData(hDelta[i], 0, i, xLow, xUp, -1., kTRUE); | |
1073 | } | |
1074 | ||
1075 | AliTPCPIDmathFit::FitFunc_t* multiGaussFitArray = new AliTPCPIDmathFit::FitFunc_t[numSimultaneousFits]; | |
1076 | multiGaussFitArray[0] = multiGaussFitDeltaPi; | |
1077 | multiGaussFitArray[1] = multiGaussFitDeltaKa; | |
1078 | multiGaussFitArray[2] = multiGaussFitDeltaPr; | |
1079 | multiGaussFitArray[3] = multiGaussFitDeltaEl; | |
1080 | ||
1081 | AliTPCPIDmathFit::FitFunc_t* errorOfFitHistosArray = new AliTPCPIDmathFit::FitFunc_t[numSimultaneousFits]; | |
1082 | errorOfFitHistosArray[0] = errorOfFitHistosDeltaPi; | |
1083 | errorOfFitHistosArray[1] = errorOfFitHistosDeltaKa; | |
1084 | errorOfFitHistosArray[2] = errorOfFitHistosDeltaPr; | |
1085 | errorOfFitHistosArray[3] = errorOfFitHistosDeltaEl; | |
1086 | ||
1087 | //TODO errorFunction for bin errors of fit histos? | |
1088 | Int_t errFlag = mathFit->MinuitFit(multiGaussFitArray, 0x0, nPar, gausParams, parameterErrorsOut, covMatrix, | |
1089 | chiSquare, ndf, stepSize, lowParLimits, upParLimits); | |
1090 | //Int_t errFlag = mathFit->MinuitFit(multiGaussFitArray, errorOfFitHistosArray, nPar, gausParams, parameterErrorsOut, covMatrix, | |
1091 | // chiSquare, ndf, stepSize, lowParLimits, upParLimits); | |
1092 | ||
1093 | std::cout << std::endl; | |
1094 | ||
1095 | // If the electron fraction is fixed, evaluate the error of the extrapolation of the fixed value | |
1096 | if (TMath::Abs(lowParLimits[3] - upParLimits[3]) < epsilon) { | |
1097 | // NOTE: Covariance matrix is NOT set. But this doesn't matter since the parameter is fixed anyway, so | |
1098 | // the error from the matrix would be zero | |
1099 | parameterErrorsOut[3] = GetElectronFractionError(); | |
1100 | } | |
1101 | ||
1102 | // Set muon fraction equal to electron fraction (or some modified electron fraction) above some threshold, | |
1103 | // which should be a reasonable approximation: | |
1104 | // Fixed muon fraction < 0 does this job within the fitting functions | |
1105 | if (gausParams[4] < 0 ) { | |
1106 | // NOTE: Covariance matrix is NOT set. But this doesn't matter since the parameter is fixed anyway, so | |
1107 | // the error from the matrix would be zero | |
1108 | gausParams[4] = GetMuonFractionFromElectronFractionAndPt(-gausParams[4], gausParams[3]); | |
1109 | parameterErrorsOut[4] = parameterErrorsOut[3]; | |
1110 | } | |
1111 | ||
1112 | Double_t sumFractions = 0; | |
1113 | for (Int_t parIndex = 0; parIndex < nPar; parIndex++) { | |
1114 | std::cout << "par[" << parIndex << "]: " << gausParams[parIndex] << " +- " << parameterErrorsOut[parIndex] << std::endl; | |
1115 | } | |
1116 | sumFractions = gausParams[0] + gausParams[1] + gausParams[2] + gausParams[3]; | |
1117 | // In case of muon contamination add muon fraction also | |
1118 | if (muonContamination || takeIntoAccountMuons) { | |
1119 | sumFractions += gausParams[4]; | |
1120 | } | |
1121 | ||
1122 | std::cout << "Sum of fractions" << (muonContamination || takeIntoAccountMuons ? "(including muon contamination)" : "") << ": " << sumFractions; std::cout << std::endl; | |
1123 | ||
1124 | if (errFlag == 0) | |
1125 | std::cout << std::endl << "***Fit operation completed successfully***" << std::endl << std::endl; | |
1126 | else | |
1127 | std::cout << std::endl << "***Fit operation completed, but with errors***" << std::endl << std::endl; | |
1128 | ||
1129 | reducedChiSquare = (ndf > 0) ? chiSquare / ndf : -1; | |
1130 | ||
1131 | return errFlag; | |
1132 | } | |
1133 | ||
1134 | ||
1135 | //____________________________________________________________________________________________________________________ | |
1136 | Int_t doFit(TH1D* hDelta, Double_t xLow, Double_t xUp, Int_t nPar, Double_t* gausParams, Double_t* parameterErrorsOut, Double_t* covMatrix, | |
1137 | Double_t* stepSize, Double_t* lowParLimits, Double_t* upParLimits, TF1* totalDeltaSpecies, Double_t& reducedChiSquare) | |
1138 | { | |
1139 | AliTPCPIDmathFit* mathFit = AliTPCPIDmathFit::Instance(); | |
1140 | ||
1141 | Double_t chiSquare = -999; | |
1142 | Int_t ndf = -1; | |
1143 | ||
1144 | //TODO: | |
1145 | // Using no error on x (next TODO line) and no errorFunction (next after next TODO line) sometimes gives good results. | |
1146 | // However, it can completely fail for low statistics for the fit histos. | |
1147 | // Using either an error on x or the errorFunction both gives reasonable results, but might be slightly worse results in some cases | |
1148 | // (shifted/distorted data). Maybe: Choose one method - the rest is for systematic errors of this fitting | |
1149 | ||
1150 | //TODO The next TODO marks are only relevant for chiSquare, but not for loglikelihood | |
1151 | //TODO Use error in x also -> If reference histos have low statistics, this will be very important | |
1152 | mathFit->InputData(hDelta, 0, 0, xLow, xUp, -1., kFALSE); | |
1153 | //mathFit->InputData(hDelta, 0, 0, xLow, xUp, -1., kTRUE); | |
1154 | ||
1155 | AliTPCPIDmathFit::FitFunc_t* multiGaussFitArray = new AliTPCPIDmathFit::FitFunc_t[1]; | |
1156 | multiGaussFitArray[0] = multiGaussFit; | |
1157 | ||
1158 | AliTPCPIDmathFit::FitFunc_t* errorOfFitHistosArray = new AliTPCPIDmathFit::FitFunc_t[1]; | |
1159 | errorOfFitHistosArray[0] = errorOfFitHistos; | |
1160 | ||
1161 | //TODO errorFunction for bin errors of fit histos? | |
1162 | Int_t errFlag = mathFit->MinuitFit(multiGaussFitArray, 0x0, nPar, gausParams, parameterErrorsOut, covMatrix, | |
1163 | chiSquare, ndf, stepSize, lowParLimits, upParLimits); | |
1164 | //Int_t errFlag = mathFit->MinuitFit(multiGaussFitArray, errorOfFitHistosArray, nPar, gausParams, parameterErrorsOut, covMatrix, | |
1165 | // chiSquare, ndf, stepSize, lowParLimits, upParLimits); | |
1166 | ||
1167 | // If the electron fraction is fixed, evaluate the error of the extrapolation of the fixed value | |
1168 | if (TMath::Abs(lowParLimits[3] - upParLimits[3]) < epsilon) { | |
1169 | // NOTE: Covariance matrix is NOT set. But this doesn't matter since the parameter is fixed anyway, so | |
1170 | // the error from the matrix would be zero | |
1171 | parameterErrorsOut[3] = GetElectronFractionError(); | |
1172 | } | |
1173 | ||
1174 | // Set muon fraction equal to electron fraction (or some modified electron fraction) above some threshold, which should be a reasonable approximation: | |
1175 | // Fixed muon fraction < 0 does this job within the fitting functions | |
1176 | if (gausParams[4] < 0 ) { | |
1177 | // NOTE: Covariance matrix is NOT set. But this doesn't matter since the parameter is fixed anyway, so | |
1178 | // the error from the matrix would be zero | |
1179 | gausParams[4] = GetMuonFractionFromElectronFractionAndPt(-gausParams[4], gausParams[3]); | |
1180 | parameterErrorsOut[4] = parameterErrorsOut[3]; | |
1181 | } | |
1182 | ||
1183 | Double_t sumFractions = 0; | |
1184 | for (Int_t parIndex = 0; parIndex < nPar; parIndex++) { | |
1185 | std::cout << totalDeltaSpecies->GetParName(parIndex) << ": " << gausParams[parIndex] << " +- " << parameterErrorsOut[parIndex] << std::endl; | |
1186 | } | |
1187 | sumFractions = gausParams[0] + gausParams[1] + gausParams[2] + gausParams[3]; | |
1188 | // In case of muon contamination add muon fraction also | |
1189 | if (muonContamination || takeIntoAccountMuons) { | |
1190 | sumFractions += gausParams[4]; | |
1191 | } | |
1192 | ||
1193 | std::cout << "Sum of fractions" << (muonContamination || takeIntoAccountMuons ? "(including muon contamination)" : "") << ": " << sumFractions; | |
1194 | std::cout << std::endl; | |
1195 | ||
1196 | if (errFlag == 0) | |
1197 | std::cout << std::endl << "***Fit operation completed successfully***" << std::endl << std::endl; | |
1198 | else | |
1199 | std::cout << std::endl << "***Fit operation completed, but with errors***" << std::endl << std::endl; | |
1200 | ||
1201 | for (Int_t parIndex = 0; parIndex < nPar; parIndex++) { | |
1202 | totalDeltaSpecies->SetParameter(parIndex, gausParams[parIndex]); | |
1203 | totalDeltaSpecies->SetParError(parIndex, parameterErrorsOut[parIndex]); | |
1204 | } | |
1205 | ||
1206 | reducedChiSquare = (ndf > 0) ? chiSquare / ndf : -1; | |
1207 | ||
1208 | return errFlag; | |
1209 | } | |
1210 | ||
1211 | ||
1212 | //____________________________________________________________________________________________________________________ | |
1213 | Double_t setFractionsAndYields(Int_t slice, Double_t inverseBinWidth, Double_t binWidthFitHisto, Int_t species, Double_t* parametersOut, | |
1214 | Double_t* parameterErrorsOut, TH1* hFractionSpecies, TH1* hFractionPionsDeltaSpecies, | |
1215 | TH1* hFractionElectronsDeltaSpecies, TH1* hFractionKaonsDeltaSpecies, TH1* hFractionProtonsDeltaSpecies, | |
1216 | TH1* hFractionMuonsDeltaSpecies, TH1* hYieldSpecies, TH1* hYieldPionsDeltaSpecies, | |
1217 | TH1* hYieldElectronsDeltaSpecies, TH1* hYieldKaonsDeltaSpecies, TH1* hYieldProtonsDeltaSpecies, | |
1218 | TH1* hYieldMuonsDeltaSpecies, | |
1219 | Bool_t normaliseFractions = kFALSE) | |
1220 | { | |
1221 | // Set fraction and yields in corresponding histograms. If normaliseFractions is kTRUE, the fractions will be normalised to unity | |
1222 | // and the normalisation factor will be returned (i.e. 1./sumFraction) | |
1223 | ||
1224 | Double_t normalisationFactor = 1.0; | |
1225 | ||
1226 | // Since a log likelihood fit is anyway used, the normalisation should give a factor close to unity | |
1227 | if (normaliseFractions) { | |
1228 | Double_t sumFractions = parametersOut[0] + (muonContamination ? parametersOut[3] : 0) + parametersOut[1] + parametersOut[2] + | |
1229 | parametersOut[3] + (takeIntoAccountMuons ? parametersOut[4] : 0.); | |
1230 | if (sumFractions > 0) { | |
1231 | normalisationFactor = 1./sumFractions; | |
1232 | for (Int_t i = 0; i < 5; i++) { | |
1233 | parametersOut[i] *= normalisationFactor; | |
1234 | ||
1235 | // Do not introduce an error for the normalisation, i.e. just scale parameters and fractions with the same factor which is | |
1236 | // assumed to be exact. | |
1237 | // Note that correlations should already be included in the parameterError | |
1238 | parameterErrorsOut[i] *= normalisationFactor; | |
1239 | } | |
1240 | } | |
1241 | } | |
1242 | ||
1243 | Double_t sumOfParticles = inverseBinWidth * parametersOut[5] / binWidthFitHisto; // Divide by binWidthFitHisto since parametersOut includes this width | |
1244 | ||
1245 | if (species == kPi) { | |
1246 | hFractionSpecies->SetBinContent(slice + 1, (parametersOut[0]+(muonContamination ? parametersOut[3] : 0))); | |
1247 | hFractionSpecies->SetBinError(slice + 1, parameterErrorsOut[0]); | |
1248 | } | |
1249 | else if (species == kEl) { | |
1250 | hFractionSpecies->SetBinContent(slice + 1, parametersOut[3]); | |
1251 | hFractionSpecies->SetBinError(slice + 1, parameterErrorsOut[3]); | |
1252 | } | |
1253 | else if (species == kKa) { | |
1254 | hFractionSpecies->SetBinContent(slice + 1, parametersOut[1]); | |
1255 | hFractionSpecies->SetBinError(slice + 1, parameterErrorsOut[1]); | |
1256 | } | |
1257 | else if (species == kPr) { | |
1258 | hFractionSpecies->SetBinContent(slice + 1, parametersOut[2]); | |
1259 | hFractionSpecies->SetBinError(slice + 1, parameterErrorsOut[2]); | |
1260 | } | |
1261 | else if (species == kMu) { | |
1262 | if (takeIntoAccountMuons) { | |
1263 | hFractionSpecies->SetBinContent(slice + 1, parametersOut[4]); | |
1264 | hFractionSpecies->SetBinError(slice + 1, parameterErrorsOut[4]); | |
1265 | ||
1266 | hYieldSpecies->SetBinContent(slice + 1, sumOfParticles * hFractionSpecies->GetBinContent(slice + 1)); | |
1267 | hYieldSpecies->SetBinError(slice + 1, sumOfParticles * hFractionSpecies->GetBinError(slice + 1)); | |
1268 | } | |
1269 | ||
1270 | // Only set these histos for muons. The DeltaSpecies histos for muons will be set together with all other species | |
1271 | return normalisationFactor; | |
1272 | } | |
1273 | ||
1274 | hFractionPionsDeltaSpecies->SetBinContent(slice + 1, (parametersOut[0]+(muonContamination ? parametersOut[3] : 0))); | |
1275 | hFractionPionsDeltaSpecies->SetBinError(slice + 1, parameterErrorsOut[0]);//TODO What about error of parOut[3]? | |
1276 | hFractionElectronsDeltaSpecies->SetBinContent(slice + 1, parametersOut[3]); | |
1277 | hFractionElectronsDeltaSpecies->SetBinError(slice + 1, parameterErrorsOut[3]); | |
1278 | hFractionKaonsDeltaSpecies->SetBinContent(slice + 1, parametersOut[1]); | |
1279 | hFractionKaonsDeltaSpecies->SetBinError(slice + 1, parameterErrorsOut[1]); | |
1280 | hFractionProtonsDeltaSpecies->SetBinContent(slice + 1, parametersOut[2]); | |
1281 | hFractionProtonsDeltaSpecies->SetBinError(slice + 1, parameterErrorsOut[2]); | |
1282 | if (takeIntoAccountMuons) { | |
1283 | hFractionMuonsDeltaSpecies->SetBinContent(slice + 1, parametersOut[4]); | |
1284 | hFractionMuonsDeltaSpecies->SetBinError(slice + 1, parameterErrorsOut[4]); | |
1285 | } | |
1286 | ||
1287 | hYieldSpecies->SetBinContent(slice + 1, sumOfParticles * hFractionSpecies->GetBinContent(slice + 1)); | |
1288 | hYieldSpecies->SetBinError(slice + 1, sumOfParticles * hFractionSpecies->GetBinError(slice + 1)); | |
1289 | ||
1290 | hYieldPionsDeltaSpecies->SetBinContent(slice + 1, sumOfParticles * hFractionPionsDeltaSpecies->GetBinContent(slice + 1)); | |
1291 | hYieldPionsDeltaSpecies->SetBinError(slice + 1, sumOfParticles * hFractionPionsDeltaSpecies->GetBinError(slice + 1)); | |
1292 | hYieldElectronsDeltaSpecies->SetBinContent(slice + 1, sumOfParticles * hFractionElectronsDeltaSpecies->GetBinContent(slice + 1)); | |
1293 | hYieldElectronsDeltaSpecies->SetBinError(slice + 1, sumOfParticles * hFractionElectronsDeltaSpecies->GetBinError(slice + 1)); | |
1294 | hYieldKaonsDeltaSpecies->SetBinContent(slice + 1, sumOfParticles * hFractionKaonsDeltaSpecies->GetBinContent(slice + 1)); | |
1295 | hYieldKaonsDeltaSpecies->SetBinError(slice + 1, sumOfParticles * hFractionKaonsDeltaSpecies->GetBinError(slice + 1)); | |
1296 | hYieldProtonsDeltaSpecies->SetBinContent(slice + 1, sumOfParticles * hFractionProtonsDeltaSpecies->GetBinContent(slice + 1)); | |
1297 | hYieldProtonsDeltaSpecies->SetBinError(slice + 1, sumOfParticles * hFractionProtonsDeltaSpecies->GetBinError(slice + 1)); | |
1298 | if (takeIntoAccountMuons) { | |
1299 | hYieldMuonsDeltaSpecies->SetBinContent(slice + 1, sumOfParticles * hFractionMuonsDeltaSpecies->GetBinContent(slice + 1)); | |
1300 | hYieldMuonsDeltaSpecies->SetBinError(slice + 1, sumOfParticles * hFractionMuonsDeltaSpecies->GetBinError(slice + 1)); | |
1301 | } | |
1302 | ||
1303 | return normalisationFactor; | |
1304 | } | |
1305 | ||
1306 | //____________________________________________________________________________________________________________________ | |
1307 | Int_t PID(TString fileName, Double_t deta, Double_t pLow, Double_t pHigh, Bool_t isMCdataSet, Int_t fitMethod, | |
1308 | Int_t muonFractionHandlingParameter, //0 = no muons, 1 = muonFrac=elFrac, | |
1309 | //2(3) = muonFrac/elFrac tuned on MC for StandardTrackCuts(HybridTrackCuts) | |
1310 | Bool_t useIdentifiedGeneratedSpectra, Bool_t plotIdentifiedSpectra, Int_t mode/*0=pT,1=z,2=xi*/, | |
1311 | Int_t chargeMode /*kNegCharge = -1, kAllCharged = 0, kPosCharge = 1*/, | |
1312 | Double_t lowerCentrality /*= -2*/, Double_t upperCentrality /*= -2*/, | |
1313 | Double_t lowerJetPt /*= -1*/ , Double_t upperJetPt/* = -1*/, | |
1314 | Int_t rebin/* = 1 -> DON'T USE FOR PT (will not work since binsPt will and should be used!)*/, | |
1315 | Int_t rebinDeltaPrime/* = 1*/, | |
1316 | TString listName /* = "bhess_PID"*/, | |
1317 | Bool_t useLogLikelihood /*= kTRUE*/, Bool_t useWeightsForLogLikelihood /*= kFALSE*/, | |
1318 | Int_t regularisation /*= 0*/, | |
1319 | Double_t regularisationFactor /*= 1*/, | |
1320 | TString filePathNameFileWithInititalFractions /*= ""*/, | |
1321 | TString* filePathNameResults /*= 0x0*/) | |
1322 | { | |
1323 | // Do all the fitting | |
1324 | ||
1325 | isMC = isMCdataSet; | |
1326 | ||
1327 | muonFractionHandling = muonFractionHandlingParameter; | |
1328 | ||
1329 | Int_t genAxis = useDeltaPrime ? kPidGenDeltaPrime : 1000/*kPidGenDelta*/; | |
1330 | if (!useDeltaPrime) { | |
1331 | std::cout << "ERROR: delta plots no longer available!" << std::endl; | |
1332 | return -1; | |
1333 | } | |
1334 | ||
1335 | if (listName == "") { | |
1336 | listName = fileName; | |
1337 | listName.Replace(0, listName.Last('/') + 1, ""); | |
1338 | listName.ReplaceAll(".root", ""); | |
1339 | } | |
1340 | ||
1341 | ||
1342 | if (rebin > 1 && mode == kPMpT) { | |
1343 | std::cout << "ERROR: Requested re-binning of pT-axis! Since binsPt will be used, re-binning the data histo will lead to " | |
1344 | << "unforeseen consequences!" << std::endl; | |
1345 | return -1; | |
1346 | } | |
1347 | ||
1348 | Int_t pSliceLow = -1; | |
1349 | Int_t pSliceHigh = -1; | |
1350 | ||
1351 | Int_t axisForMode = kPidPt; | |
1352 | Int_t axisGenForMode = kPidGenPt; | |
1353 | ||
1354 | std::cout << "Fitting \"" << fileName.Data() << "\" with settings:" << std::endl; | |
1355 | ||
1356 | std::cout << "Minimisation strategy: " << minimisationStrategy.Data() << std::endl; | |
1357 | if (useLogLikelihood) | |
1358 | std::cout << "Binned loglikelihood fit" << (useWeightsForLogLikelihood ? " (weighted)" : "") << std::endl; | |
1359 | else | |
1360 | std::cout << "ChiSquare fit" << std::endl; | |
1361 | std::cout << "Processing mode: "; | |
1362 | if (mode == kPMpT) | |
1363 | std::cout << "pT" << std::endl; | |
1364 | else if (mode == kPMz) { | |
1365 | std::cout << "z" << std::endl; | |
1366 | axisForMode = kPidZ; | |
1367 | axisGenForMode = kPidGenZ; | |
1368 | } | |
1369 | else if (mode == kPMxi) { | |
1370 | std::cout << "xi" << std::endl; | |
1371 | axisForMode = kPidXi; | |
1372 | axisGenForMode = kPidGenXi; | |
1373 | } | |
1374 | else { | |
1375 | std::cout << "Unknown -> ERROR" << std::endl; | |
1376 | return -1; | |
1377 | } | |
1378 | ||
1379 | std::cout << "Charge selection: "; | |
1380 | if (chargeMode == kAllCharged) | |
1381 | std::cout << "All charged particles" << std::endl; | |
1382 | else if (chargeMode == kNegCharge) | |
1383 | std::cout << "Negative particles only" << std::endl; | |
1384 | else if (chargeMode == kPosCharge) | |
1385 | std::cout << "Positive particles only" << std::endl; | |
1386 | else { | |
1387 | std::cout << "Unknown -> ERROR" << std::endl; | |
1388 | return -1; | |
1389 | } | |
1390 | ||
1391 | const Bool_t restrictCharge = (chargeMode != kAllCharged); | |
1392 | ||
1393 | if (regularisation > 0) | |
1394 | std::cout << "Regularisation with +-" << regularisation << " bins and factor " << regularisationFactor << " for penalty term." | |
1395 | << std::endl; | |
1396 | else | |
1397 | std::cout << "No regularisation" << std::endl; | |
1398 | ||
1399 | std::cout << "Assumption on muon fraction: "; | |
1400 | if (muonFractionHandlingParameter >= 0 && muonFractionHandlingParameter < kNumHandlings) | |
1401 | std::cout << muonFractionHandlingShortName[muonFractionHandlingParameter].Data() << std::endl; | |
1402 | /*if (muonFractionHandlingParameter == kNoMuons) | |
1403 | std::cout << "Identical zero" << std::endl; | |
1404 | else if (muonFractionHandlingParameter == kMuonFracEqualElFrac) | |
1405 | std::cout << "Equal electron fraction" << std::endl; | |
1406 | else if (muonFractionHandlingParameter == kMuonFracOverElFracTunedOnMCStandardTrackCuts) | |
1407 | std::cout << "Ratio to electron fraction tuned on MC for standard track cuts" << std::endl; | |
1408 | else if (muonFractionHandlingParameter == kMuonFracOverElFracTunedOnMCHybridTrackCuts) | |
1409 | std::cout << "Ratio to electron fraction tuned on MC for hybrid track cuts" << std::endl; | |
1410 | else if (muonFractionHandlingParameter == kMuonFracOverElFracTunedOnMCHybridTrackCutsJets) | |
1411 | std::cout << "Ratio to electron fraction tuned on MC for hybrid track cuts for jet particles" << std::endl; | |
1412 | else if (muonFractionHandlingParameter == kMuonFracOverElFracTunedOnMCHybridTrackCutsJets) | |
1413 | std::cout << "Ratio to electron fraction tuned on MC for hybrid track cuts for jet particles" << std::endl;*/ | |
1414 | else { | |
1415 | std::cout << "Unknown -> ERROR" << std::endl; | |
1416 | return -1; | |
1417 | } | |
1418 | ||
1419 | if (mode == kPMpT) { | |
1420 | Int_t index = 0; | |
1421 | while (pLow >= binsPt[index] && index < nPtBins) | |
1422 | index++; | |
1423 | pSliceLow = index - 1; | |
1424 | ||
1425 | index = 0; | |
1426 | while (pHigh > binsPt[index] && index < nPtBins) | |
1427 | index++; | |
1428 | pSliceHigh = index - 1; | |
1429 | ||
1430 | Int_t numMomIntervals = pSliceHigh - pSliceLow + 1; | |
1431 | ||
1432 | if (numMomIntervals <= 0 || pSliceLow < 0 || pSliceHigh > nPtBins) { | |
1433 | std::cout << "Wrong choice of limits pLow/pHigh!" << std::endl; | |
1434 | return -1; | |
1435 | } | |
1436 | ||
1437 | pLow = binsPt[pSliceLow]; | |
1438 | pHigh = binsPt[pSliceHigh + 1]; // need upper edge, but binsPt holds lower edge | |
1439 | std::cout << "pLow/pHigh: "; | |
1440 | std::cout << pLow << " / " << pHigh << std::endl; | |
1441 | } | |
1442 | ||
1443 | Bool_t initialiseWithFractionsFromFile = kFALSE; | |
1444 | TFile* fInitialFractions = 0x0; | |
1445 | TH1 *hInitFracEl = 0x0, *hInitFracKa = 0x0, *hInitFracPi = 0x0, *hInitFracMu = 0x0, *hInitFracPr = 0x0; | |
1446 | ||
1447 | if (filePathNameFileWithInititalFractions != "") { | |
1448 | initialiseWithFractionsFromFile = kTRUE; | |
1449 | ||
1450 | std::cout << "Initialising fractions from file: " << filePathNameFileWithInititalFractions.Data() << std::endl; | |
1451 | } | |
1452 | else | |
1453 | std::cout << "Not initialising fractions from file" << std::endl; | |
1454 | ||
1455 | if (initialiseWithFractionsFromFile) { | |
1456 | fInitialFractions = TFile::Open(filePathNameFileWithInititalFractions.Data()); | |
1457 | if (!fInitialFractions) { | |
1458 | std::cout << std::endl; | |
1459 | std::cout << "Failed to open file with initial fractions \"" << filePathNameFileWithInititalFractions.Data() << "\"!" | |
1460 | << std::endl; | |
1461 | return -1; | |
1462 | } | |
1463 | ||
1464 | hInitFracEl = (TH1*)fInitialFractions->Get("hFractionElectrons"); | |
1465 | hInitFracKa = (TH1*)fInitialFractions->Get("hFractionKaons"); | |
1466 | hInitFracPi = (TH1*)fInitialFractions->Get("hFractionPions"); | |
1467 | hInitFracMu = (TH1*)fInitialFractions->Get("hFractionMuons"); | |
1468 | hInitFracPr = (TH1*)fInitialFractions->Get("hFractionProtons"); | |
1469 | ||
1470 | if (!hInitFracEl || ! hInitFracKa || ! hInitFracPi || ! hInitFracMu || ! hInitFracPr) { | |
1471 | std::cout << std::endl; | |
1472 | std::cout << "Failed to load initial fractions from file \"" << filePathNameFileWithInititalFractions.Data() << "\"!" | |
1473 | << std::endl; | |
1474 | ||
1475 | fInitialFractions->Close(); | |
1476 | return -1; | |
1477 | } | |
1478 | } | |
1479 | ||
1480 | ||
1481 | ||
1482 | TObjArray* histList = 0x0; | |
1483 | ||
1484 | TFile* f = TFile::Open(fileName.Data()); | |
1485 | if (!f) { | |
1486 | std::cout << std::endl; | |
1487 | std::cout << "Failed to open file \"" << fileName.Data() << "\"!" << std::endl; | |
1488 | return -1; | |
1489 | } | |
1490 | ||
1491 | //TString listName = fileName; | |
1492 | //listName = listName.ReplaceAll(".root", ""); | |
1493 | //listName = listName.Remove(1, listName.Last('/') + 1); | |
1494 | histList = (TObjArray*)(f->Get(listName.Data())); | |
1495 | if (!histList) { | |
1496 | std::cout << std::endl; | |
1497 | std::cout << "Failed to load list \"" << listName.Data() << "\"!" << std::endl; | |
1498 | return -1; | |
1499 | } | |
1500 | ||
1501 | // Extract the data histogram | |
1502 | THnSparse* hPIDdata = dynamic_cast<THnSparse*>(histList->FindObject("hPIDdataAll")); | |
1503 | if (!hPIDdata) { | |
1504 | std::cout << std::endl; | |
1505 | std::cout << "Failed to load data histo!" << std::endl; | |
1506 | return -1; | |
1507 | } | |
1508 | ||
1509 | // If desired, rebin considered axis | |
1510 | if (rebin > 1 || rebinDeltaPrime > 1) { | |
1511 | const Int_t nDimensions = hPIDdata->GetNdimensions(); | |
1512 | Int_t rebinFactor[nDimensions]; | |
1513 | ||
1514 | for (Int_t dim = 0; dim < nDimensions; dim++) { | |
1515 | if (dim == axisForMode && rebin > 1) | |
1516 | rebinFactor[dim] = rebin; | |
1517 | else if (dim == kPidDeltaPrime && rebinDeltaPrime > 1) | |
1518 | rebinFactor[dim] = rebinDeltaPrime; | |
1519 | else | |
1520 | rebinFactor[dim] = 1; | |
1521 | } | |
1522 | ||
1523 | THnSparse* temp = hPIDdata->Rebin(&rebinFactor[0]); | |
1524 | hPIDdata->Reset(); | |
1525 | hPIDdata = temp; | |
1526 | } | |
1527 | ||
1528 | // Set proper errors, if not yet calculated | |
1529 | if (!hPIDdata->GetCalculateErrors()) { | |
1530 | std::cout << "Re-calculating errors of " << hPIDdata->GetName() << "..." << std::endl; | |
1531 | hPIDdata->Sumw2(); | |
1532 | Long64_t nBinsTHnSparse = hPIDdata->GetNbins(); | |
1533 | Double_t binContent = 0; | |
1534 | ||
1535 | for (Long64_t bin = 0; bin < nBinsTHnSparse; bin++) { | |
1536 | binContent = hPIDdata->GetBinContent(bin); | |
1537 | hPIDdata->SetBinError(bin, TMath::Sqrt(binContent)); | |
1538 | } | |
1539 | } | |
1540 | ||
1541 | ||
1542 | // If desired, restrict centrality axis | |
1543 | Int_t lowerCentralityBinLimit = -1; | |
1544 | Int_t upperCentralityBinLimit = -1; | |
1545 | Bool_t restrictCentralityAxis = kFALSE; | |
1546 | Double_t actualLowerCentrality = -1.; | |
1547 | Double_t actualUpperCentrality = -1.; | |
1548 | ||
1549 | if (lowerCentrality >= -1 && upperCentrality >= -1) { | |
1550 | // Add subtract a very small number to avoid problems with values right on the border between to bins | |
1551 | lowerCentralityBinLimit = hPIDdata->GetAxis(kPidCentrality)->FindBin(lowerCentrality + 0.001); | |
1552 | upperCentralityBinLimit = hPIDdata->GetAxis(kPidCentrality)->FindBin(upperCentrality - 0.001); | |
1553 | ||
1554 | // Check if the values look reasonable | |
1555 | if (lowerCentralityBinLimit <= upperCentralityBinLimit && lowerCentralityBinLimit >= 1 | |
1556 | && upperCentralityBinLimit <= hPIDdata->GetAxis(kPidCentrality)->GetNbins()) { | |
1557 | actualLowerCentrality = hPIDdata->GetAxis(kPidCentrality)->GetBinLowEdge(lowerCentralityBinLimit); | |
1558 | actualUpperCentrality = hPIDdata->GetAxis(kPidCentrality)->GetBinUpEdge(upperCentralityBinLimit); | |
1559 | ||
1560 | restrictCentralityAxis = kTRUE; | |
1561 | } | |
1562 | else { | |
1563 | std::cout << std::endl; | |
1564 | std::cout << "Requested centrality range out of limits or upper and lower limit are switched!" << std::endl; | |
1565 | return -1; | |
1566 | } | |
1567 | } | |
1568 | ||
1569 | std::cout << "centrality: "; | |
1570 | if (restrictCentralityAxis) { | |
1571 | std::cout << actualLowerCentrality << " - " << actualUpperCentrality << std::endl; | |
1572 | } | |
1573 | else { | |
1574 | std::cout << "All" << std::endl; | |
1575 | } | |
1576 | ||
1577 | if (restrictCentralityAxis) { | |
1578 | hPIDdata->GetAxis(kPidCentrality)->SetRange(lowerCentralityBinLimit, upperCentralityBinLimit); | |
1579 | } | |
1580 | ||
1581 | ||
1582 | ||
1583 | // If desired, restrict jetPt axis | |
1584 | Int_t lowerJetPtBinLimit = -1; | |
1585 | Int_t upperJetPtBinLimit = -1; | |
1586 | Bool_t restrictJetPtAxis = kFALSE; | |
1587 | Double_t actualLowerJetPt = -1.; | |
1588 | Double_t actualUpperJetPt = -1.; | |
1589 | ||
1590 | if (lowerJetPt >= 0 && upperJetPt >= 0) { | |
1591 | // Add subtract a very small number to avoid problems with values right on the border between to bins | |
1592 | lowerJetPtBinLimit = hPIDdata->GetAxis(kPidJetPt)->FindBin(lowerJetPt + 0.001); | |
1593 | upperJetPtBinLimit = hPIDdata->GetAxis(kPidJetPt)->FindBin(upperJetPt - 0.001); | |
1594 | ||
1595 | // Check if the values look reasonable | |
1596 | if (lowerJetPtBinLimit <= upperJetPtBinLimit && lowerJetPtBinLimit >= 1 && upperJetPtBinLimit <= hPIDdata->GetAxis(kPidJetPt)->GetNbins()) { | |
1597 | actualLowerJetPt = hPIDdata->GetAxis(kPidJetPt)->GetBinLowEdge(lowerJetPtBinLimit); | |
1598 | actualUpperJetPt = hPIDdata->GetAxis(kPidJetPt)->GetBinUpEdge(upperJetPtBinLimit); | |
1599 | ||
1600 | restrictJetPtAxis = kTRUE; | |
1601 | } | |
1602 | else { | |
1603 | std::cout << std::endl; | |
1604 | std::cout << "Requested jet pT range out of limits or upper and lower limit are switched!" << std::endl; | |
1605 | return -1; | |
1606 | } | |
1607 | } | |
1608 | ||
1609 | std::cout << "jet pT: "; | |
1610 | if (restrictJetPtAxis) { | |
1611 | std::cout << actualLowerJetPt << " - " << actualUpperJetPt << std::endl; | |
1612 | } | |
1613 | else { | |
1614 | std::cout << "All" << std::endl; | |
1615 | } | |
1616 | ||
1617 | if (restrictJetPtAxis) { | |
1618 | hPIDdata->GetAxis(kPidJetPt)->SetRange(lowerJetPtBinLimit, upperJetPtBinLimit); | |
1619 | } | |
1620 | ||
1621 | ||
1622 | // If desired, restrict charge axis | |
1623 | const Int_t indexChargeAxisData = GetAxisByTitle(hPIDdata, "Charge (e_{0})"); | |
1624 | if (indexChargeAxisData < 0 && restrictCharge) { | |
1625 | std::cout << "Error: Charge axis not found for data histogram!" << std::endl; | |
1626 | return -1; | |
1627 | } | |
1628 | Int_t lowerChargeBinLimitData = -1; | |
1629 | Int_t upperChargeBinLimitData = -2; | |
1630 | Double_t actualLowerChargeData = -999; | |
1631 | Double_t actualUpperChargeData = -999; | |
1632 | ||
1633 | if (restrictCharge) { | |
1634 | // Add subtract a very small number to avoid problems with values right on the border between to bins | |
1635 | if (chargeMode == kNegCharge) { | |
1636 | lowerChargeBinLimitData = hPIDdata->GetAxis(indexChargeAxisData)->FindBin(-1. + 0.001); | |
1637 | upperChargeBinLimitData = hPIDdata->GetAxis(indexChargeAxisData)->FindBin(0. - 0.001); | |
1638 | } | |
1639 | else if (chargeMode == kPosCharge) { | |
1640 | lowerChargeBinLimitData = hPIDdata->GetAxis(indexChargeAxisData)->FindBin(0. + 0.001); | |
1641 | upperChargeBinLimitData = hPIDdata->GetAxis(indexChargeAxisData)->FindBin(1. - 0.001); | |
1642 | } | |
1643 | ||
1644 | // Check if the values look reasonable | |
1645 | if (lowerChargeBinLimitData <= upperChargeBinLimitData && lowerChargeBinLimitData >= 1 | |
1646 | && upperChargeBinLimitData <= hPIDdata->GetAxis(indexChargeAxisData)->GetNbins()) { | |
1647 | actualLowerChargeData = hPIDdata->GetAxis(indexChargeAxisData)->GetBinLowEdge(lowerChargeBinLimitData); | |
1648 | actualUpperChargeData = hPIDdata->GetAxis(indexChargeAxisData)->GetBinUpEdge(upperChargeBinLimitData); | |
1649 | ||
1650 | std::cout << "Charge range data: " << actualLowerChargeData << " - " << actualUpperChargeData << std::endl; | |
1651 | } | |
1652 | else { | |
1653 | std::cout << std::endl; | |
1654 | std::cout << "Requested charge range out of limits or upper and lower limit are switched!" << std::endl; | |
1655 | return -1; | |
1656 | } | |
1657 | ||
1658 | hPIDdata->GetAxis(indexChargeAxisData)->SetRange(lowerChargeBinLimitData, upperChargeBinLimitData); | |
1659 | } | |
1660 | ||
1661 | std::cout << std::endl; | |
1662 | ||
1663 | ||
1664 | ||
1665 | // Open file in which all the projections (= intermediate results) will be saved | |
1666 | TString saveInterFName = fileName; | |
1667 | TString chargeString = ""; | |
1668 | if (chargeMode == kPosCharge) | |
1669 | chargeString = "_posCharge"; | |
1670 | else if (chargeMode == kNegCharge) | |
1671 | chargeString = "_negCharge"; | |
1672 | ||
1673 | saveInterFName = Form("%s_Projections_%s_%d_%s%s%s%s%s.root", saveInterFName.ReplaceAll(".root", "").Data(), | |
1674 | modeShortName[mode].Data(), | |
1675 | fitMethod, muonFractionHandlingShortName[muonFractionHandlingParameter].Data(), | |
1676 | useIdentifiedGeneratedSpectra ? "_idSpectra" : "", | |
1677 | restrictCentralityAxis ? Form("_centrality%.0f_%.0f", actualLowerCentrality, actualUpperCentrality) : "", | |
1678 | restrictJetPtAxis ? Form("_jetPt%.1f_%.1f", actualLowerJetPt, actualUpperJetPt) : "", | |
1679 | chargeString.Data()); | |
1680 | TFile *saveInterF = TFile::Open(saveInterFName.Data(), "RECREATE"); | |
1681 | saveInterF->cd(); | |
1682 | ||
1683 | // TH1 hist with number of processed events | |
1684 | Double_t numEvents = -1; | |
1685 | TH1* hNumEvents = dynamic_cast<TH1*>(histList->FindObject("fhEventsProcessed")); | |
1686 | if (!hNumEvents) { | |
1687 | std::cout << std::endl; | |
1688 | std::cout << "Histo with number of processed events not found! Yields will NOT be normalised to this number!" << std::endl | |
1689 | << std::endl; | |
1690 | } | |
1691 | else { | |
1692 | numEvents = restrictCentralityAxis ? hNumEvents->Integral(lowerCentralityBinLimit, upperCentralityBinLimit) : | |
1693 | hNumEvents->Integral(); | |
1694 | ||
1695 | if (numEvents <= 0) { | |
1696 | numEvents = -1; | |
1697 | std::cout << std::endl; | |
1698 | std::cout << "Number of processed events < 1 in selected range! Yields will NOT be normalised to this number!" | |
1699 | << std::endl << std::endl; | |
1700 | } | |
1701 | } | |
1702 | ||
1703 | ||
1704 | // TH1D hist with total yield per pT bin (-> project to arbitrary selectSpecies to avoid multiple counting) | |
1705 | hPIDdata->GetAxis(kPidSelectSpecies)->SetRange(1, 1); | |
1706 | TH1D* hYieldPt = hPIDdata->Projection(axisForMode, "e"); | |
1707 | hYieldPt->SetName(Form("hYield%s", modeShortName[mode].Data())); | |
1708 | hPIDdata->GetAxis(kPidSelectSpecies)->SetRange(0, -1); | |
1709 | ||
1710 | ||
1711 | // Fill \Delta\species histograms for each momentum slice | |
1712 | Int_t nBins = hPIDdata->GetAxis(dataAxis)->GetNbins(); | |
1713 | Double_t xLow = hPIDdata->GetAxis(dataAxis)->GetXmin(); | |
1714 | Double_t xUp = hPIDdata->GetAxis(dataAxis)->GetXmax(); | |
1715 | ||
1716 | const Int_t numSlices = (mode == kPMpT) ? nPtBins : hPIDdata->GetAxis(axisForMode)->GetNbins(); | |
1717 | ||
1718 | TH1D* hDeltaPi[numSlices]; | |
1719 | TH1D* hDeltaEl[numSlices]; | |
1720 | TH1D* hDeltaKa[numSlices]; | |
1721 | TH1D* hDeltaPr[numSlices]; | |
1722 | ||
1723 | TH1D* hDeltaPiFitQA[numSlices]; | |
1724 | TH1D* hDeltaElFitQA[numSlices]; | |
1725 | TH1D* hDeltaKaFitQA[numSlices]; | |
1726 | TH1D* hDeltaPrFitQA[numSlices]; | |
1727 | ||
1728 | const Int_t nMCbins = 5; | |
1729 | TH1D* hDeltaPiMC[numSlices][nMCbins]; | |
1730 | TH1D* hDeltaElMC[numSlices][nMCbins]; | |
1731 | TH1D* hDeltaKaMC[numSlices][nMCbins]; | |
1732 | TH1D* hDeltaPrMC[numSlices][nMCbins]; | |
1733 | ||
1734 | ||
1735 | TH2D* h2Delta[4]; | |
1736 | TH2D* h2DeltaMC[4][nMCbins]; | |
1737 | ||
1738 | for (Int_t i = 0; i < 4; i++) { | |
1739 | TString speciesLabel = hPIDdata->GetAxis(kPidSelectSpecies)->GetBinLabel(i + 1); | |
1740 | ||
1741 | hPIDdata->GetAxis(kPidSelectSpecies)->SetRange(i + 1, i + 1); | |
1742 | h2Delta[i] = hPIDdata->Projection(dataAxis, axisForMode, "e"); | |
1743 | h2Delta[i]->SetName(Form("h2Delta_%s", speciesLabel.Data())); | |
1744 | h2Delta[i]->GetXaxis()->SetTitle(hPIDdata->GetAxis(axisForMode)->GetTitle()); | |
1745 | h2Delta[i]->GetYaxis()->SetTitle(Form("#Delta%s_{%s} = dE/dx %s <dE/dx>_{%s} (arb. units)", useDeltaPrime ? "'" : "", speciesLabel.Data(), | |
1746 | useDeltaPrime ? "/" : "-", speciesLabel.Data())); | |
1747 | ||
1748 | for (Int_t species = 0; species < nMCbins; species++) { | |
1749 | hPIDdata->GetAxis(kPidMCpid)->SetRange(species + 1, species + 1); // Select MC species | |
1750 | h2DeltaMC[i][species] = hPIDdata->Projection(dataAxis, axisGenForMode, "e"); | |
1751 | h2DeltaMC[i][species]->SetName(Form("h2Delta_MC_%s", speciesLabel.Data())); | |
1752 | h2DeltaMC[i][species]->GetXaxis()->SetTitle(hPIDdata->GetAxis(axisGenForMode)->GetTitle()); | |
1753 | h2DeltaMC[i][species]->GetYaxis()->SetTitle(h2Delta[i]->GetYaxis()->GetTitle()); | |
1754 | } | |
1755 | hPIDdata->GetAxis(kPidMCpid)->SetRange(0, -1); | |
1756 | } | |
1757 | ||
1758 | Int_t firstValidSlice = -1; | |
1759 | for (Int_t slice = 0; (mode == kPMpT) ? slice < nPtBins : slice < hPIDdata->GetAxis(axisForMode)->GetNbins(); slice++) { | |
1760 | if (mode == kPMpT && (slice < pSliceLow || slice > pSliceHigh)) | |
1761 | continue; | |
1762 | ||
1763 | if (firstValidSlice < 0) | |
1764 | firstValidSlice = slice; | |
1765 | ||
1766 | // Add/subtract some very small offset to be sure not to sit on the bin boundary, when looking for the integration/projection limits. | |
1767 | // For modes different from pT, just take 1 bin | |
1768 | const Int_t pBinLowProjLimit = (mode == kPMpT) ? h2Delta[0]->GetXaxis()->FindBin(binsPt[slice] + 1e-5) : slice + 1; | |
1769 | const Int_t pBinUpProjLimit = (mode == kPMpT) ? h2Delta[0]->GetXaxis()->FindBin(binsPt[slice + 1]- 1e-5) : slice + 1; | |
1770 | ||
1771 | const TString binInfo = (mode == kPMpT) ? Form("%.2f_Pt_%.2f", binsPt[slice], binsPt[slice + 1]) | |
1772 | : Form("%.2f_%s_%.2f", hPIDdata->GetAxis(axisForMode)->GetBinLowEdge(pBinLowProjLimit), | |
1773 | modeShortName[mode].Data(), | |
1774 | hPIDdata->GetAxis(axisForMode)->GetBinUpEdge(pBinUpProjLimit)); | |
1775 | ||
1776 | hDeltaEl[slice] = h2Delta[0]->ProjectionY(Form("hDeltaEl_%s", binInfo.Data()), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
1777 | hDeltaEl[slice]->GetXaxis()->SetTitle(h2Delta[0]->GetYaxis()->GetTitle()); | |
1778 | hDeltaEl[slice]->GetXaxis()->SetTitleOffset(1.0); | |
1779 | hDeltaEl[slice]->SetStats(kFALSE); | |
1780 | ||
1781 | hDeltaKa[slice] = h2Delta[1]->ProjectionY(Form("hDeltaKa_%s", binInfo.Data()), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
1782 | hDeltaKa[slice]->SetName(Form("hDeltaKa_%s", binInfo.Data())); | |
1783 | hDeltaKa[slice]->GetXaxis()->SetTitle(h2Delta[1]->GetYaxis()->GetTitle()); | |
1784 | hDeltaKa[slice]->GetXaxis()->SetTitleOffset(1.0); | |
1785 | hDeltaKa[slice]->SetStats(kFALSE); | |
1786 | ||
1787 | hDeltaPi[slice] = h2Delta[2]->ProjectionY(Form("hDeltaPi_%s", binInfo.Data()), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
1788 | hDeltaPi[slice]->SetName(Form("hDeltaPi_%s", binInfo.Data())); | |
1789 | hDeltaPi[slice]->GetXaxis()->SetTitle(h2Delta[2]->GetYaxis()->GetTitle()); | |
1790 | hDeltaPi[slice]->GetXaxis()->SetTitleOffset(1.0); | |
1791 | hDeltaPi[slice]->SetStats(kFALSE); | |
1792 | ||
1793 | hDeltaPr[slice] = h2Delta[3]->ProjectionY(Form("hDeltaPr_%s", binInfo.Data()), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
1794 | hDeltaPr[slice]->SetName(Form("hDeltaPr_%s", binInfo.Data())); | |
1795 | hDeltaPr[slice]->GetXaxis()->SetTitle(h2Delta[3]->GetYaxis()->GetTitle()); | |
1796 | hDeltaPr[slice]->GetXaxis()->SetTitleOffset(1.0); | |
1797 | hDeltaPr[slice]->SetStats(kFALSE); | |
1798 | ||
1799 | if (plotIdentifiedSpectra) { | |
1800 | // If identified spectra are available (mainly useful in the MC case) and shall be used, | |
1801 | // create histos with signals from identified particles | |
1802 | ||
1803 | // DeltaEl | |
1804 | for (Int_t species = 0; species < nMCbins; species++) { | |
1805 | hDeltaElMC[slice][species] = h2DeltaMC[0][species]->ProjectionY(Form("hDeltaElMC_%s_species_%d", binInfo.Data(), species), | |
1806 | pBinLowProjLimit, pBinUpProjLimit, "e"); | |
1807 | hDeltaElMC[slice][species]->SetLineColor(getLineColor(species + 1)); | |
1808 | hDeltaElMC[slice][species]->SetMarkerColor(getLineColor(species + 1)); | |
1809 | hDeltaElMC[slice][species]->SetMarkerStyle(24); | |
1810 | hDeltaElMC[slice][species]->SetLineStyle(1); | |
1811 | hDeltaElMC[slice][species]->GetXaxis()->SetTitle(h2DeltaMC[0][species]->GetYaxis()->GetTitle()); | |
1812 | hDeltaElMC[slice][species]->GetXaxis()->SetTitleOffset(1.0); | |
1813 | hDeltaElMC[slice][species]->SetStats(kFALSE); | |
1814 | } | |
1815 | ||
1816 | // DeltaKa | |
1817 | for (Int_t species = 0; species < nMCbins; species++) { | |
1818 | hDeltaKaMC[slice][species] = h2DeltaMC[1][species]->ProjectionY(Form("hDeltaKaMC_%s_species_%d", binInfo.Data(), species), | |
1819 | pBinLowProjLimit, pBinUpProjLimit, "e"); | |
1820 | hDeltaKaMC[slice][species]->SetLineColor(getLineColor(species + 1)); | |
1821 | hDeltaKaMC[slice][species]->SetMarkerColor(getLineColor(species + 1)); | |
1822 | hDeltaKaMC[slice][species]->SetMarkerStyle(24); | |
1823 | hDeltaKaMC[slice][species]->SetLineStyle(1); | |
1824 | hDeltaKaMC[slice][species]->GetXaxis()->SetTitle(h2DeltaMC[1][species]->GetYaxis()->GetTitle()); | |
1825 | hDeltaKaMC[slice][species]->GetXaxis()->SetTitleOffset(1.0); | |
1826 | hDeltaKaMC[slice][species]->SetStats(kFALSE); | |
1827 | } | |
1828 | ||
1829 | // DeltaPi | |
1830 | for (Int_t species = 0; species < nMCbins; species++) { | |
1831 | hDeltaPiMC[slice][species] = h2DeltaMC[2][species]->ProjectionY(Form("hDeltaPiMC_%s_species_%d", binInfo.Data(), species), | |
1832 | pBinLowProjLimit, pBinUpProjLimit, "e"); | |
1833 | hDeltaPiMC[slice][species]->SetLineColor(getLineColor(species + 1)); | |
1834 | hDeltaPiMC[slice][species]->SetMarkerColor(getLineColor(species + 1)); | |
1835 | hDeltaPiMC[slice][species]->SetMarkerStyle(24); | |
1836 | hDeltaPiMC[slice][species]->SetLineStyle(1); | |
1837 | hDeltaPiMC[slice][species]->GetXaxis()->SetTitle(h2DeltaMC[2][species]->GetYaxis()->GetTitle()); | |
1838 | hDeltaPiMC[slice][species]->GetXaxis()->SetTitleOffset(1.0); | |
1839 | hDeltaPiMC[slice][species]->SetStats(kFALSE); | |
1840 | } | |
1841 | ||
1842 | // DeltaPr | |
1843 | for (Int_t species = 0; species < nMCbins; species++) { | |
1844 | hDeltaPrMC[slice][species] = h2DeltaMC[3][species]->ProjectionY(Form("hDeltaPrMC_%s_species_%d", binInfo.Data(), species), | |
1845 | pBinLowProjLimit, pBinUpProjLimit, "e"); | |
1846 | hDeltaPrMC[slice][species]->SetLineColor(getLineColor(species + 1)); | |
1847 | hDeltaPrMC[slice][species]->SetMarkerColor(getLineColor(species + 1)); | |
1848 | hDeltaPrMC[slice][species]->SetMarkerStyle(24); | |
1849 | hDeltaPrMC[slice][species]->SetLineStyle(1); | |
1850 | hDeltaPrMC[slice][species]->GetXaxis()->SetTitle(h2DeltaMC[3][species]->GetYaxis()->GetTitle()); | |
1851 | hDeltaPrMC[slice][species]->GetXaxis()->SetTitleOffset(1.0); | |
1852 | hDeltaPrMC[slice][species]->SetStats(kFALSE); | |
1853 | } | |
1854 | } | |
1855 | } | |
1856 | hPIDdata->GetAxis(kPidMCpid)->SetRange(0, -1); | |
1857 | hPIDdata->GetAxis(kPidSelectSpecies)->SetRange(0, -1); | |
1858 | ||
1859 | hPIDdata->GetAxis(axisForMode)->SetRange(0, -1); | |
1860 | ||
1861 | /* | |
1862 | // TOF TODO | |
1863 | TCanvas* cTOF = new TCanvas("cTOF", "TOF PID",100,10,1200,800); | |
1864 | cTOF->Divide(4,1); | |
1865 | cTOF->cd(1); | |
1866 | hPIDdata->GetAxis(kPidSelectSpecies)->SetRange(1, 1); | |
1867 | TH2D* h2TOFel = hPIDdata->Projection(kPidDeltaTOF, kPidPvertex); | |
1868 | h2TOFel->SetName("h2TOFel"); | |
1869 | h2TOFel->GetYaxis()->SetTitle(Form("#DeltaTOF_{%s} (ps)", hPIDdata->GetAxis(kPidSelectSpecies)->GetBinLabel(1))); | |
1870 | h2TOFel->Draw("colz"); | |
1871 | ||
1872 | cTOF->cd(2); | |
1873 | hPIDdata->GetAxis(kPidSelectSpecies)->SetRange(2, 2); | |
1874 | TH2D* h2TOFka = hPIDdata->Projection(kPidDeltaTOF, kPidPvertex); | |
1875 | h2TOFka->SetName("h2TOFka"); | |
1876 | h2TOFka->GetYaxis()->SetTitle(Form("#DeltaTOF_{%s} (ps)", hPIDdata->GetAxis(kPidSelectSpecies)->GetBinLabel(2))); | |
1877 | h2TOFka->Draw("colz"); | |
1878 | ||
1879 | cTOF->cd(3); | |
1880 | hPIDdata->GetAxis(kPidSelectSpecies)->SetRange(3, 3); | |
1881 | TH2D* h2TOFpi = hPIDdata->Projection(kPidDeltaTOF, kPidPvertex); | |
1882 | h2TOFpi->SetName("h2TOFpi"); | |
1883 | h2TOFpi->GetYaxis()->SetTitle(Form("#DeltaTOF_{%s} (ps)", hPIDdata->GetAxis(kPidSelectSpecies)->GetBinLabel(3))); | |
1884 | h2TOFpi->Draw("colz"); | |
1885 | ||
1886 | cTOF->cd(4); | |
1887 | hPIDdata->GetAxis(kPidSelectSpecies)->SetRange(4, 4); | |
1888 | TH2D* h2TOFpr = hPIDdata->Projection(kPidDeltaTOF, kPidPvertex); | |
1889 | h2TOFpr->SetName("h2TOFpr"); | |
1890 | h2TOFpr->GetYaxis()->SetTitle(Form("#DeltaTOF_{%s} (ps)", hPIDdata->GetAxis(kPidSelectSpecies)->GetBinLabel(4))); | |
1891 | h2TOFpr->Draw("colz"); | |
1892 | ||
1893 | hPIDdata->GetAxis(kPidSelectSpecies)->SetRange(0, -1); | |
1894 | */ | |
1895 | ||
1896 | // Start fitting of slices | |
1897 | TCanvas* cSingleFit[numSlices][4]; | |
1898 | ||
1899 | TF1* fitFuncTotalDeltaPion[numSlices]; | |
1900 | TF1* fitFuncTotalDeltaElectron[numSlices]; | |
1901 | TF1* fitFuncTotalDeltaKaon[numSlices]; | |
1902 | TF1* fitFuncTotalDeltaProton[numSlices]; | |
1903 | ||
1904 | // Histos for particle fractions | |
1905 | TH1F* hFractionElectrons = 0x0; | |
1906 | if (mode == kPMpT) | |
1907 | hFractionElectrons = new TH1F("hFractionElectrons", "e", nPtBins, binsPt); | |
1908 | else { | |
1909 | const TArrayD* histBins = hPIDdata->GetAxis(axisForMode)->GetXbins(); | |
1910 | if (histBins->fN == 0) | |
1911 | hFractionElectrons = new TH1F("hFractionElectrons", "e", hPIDdata->GetAxis(axisForMode)->GetNbins(), hPIDdata->GetAxis(axisForMode)->GetXmin(), | |
1912 | hPIDdata->GetAxis(axisForMode)->GetXmax()); | |
1913 | else | |
1914 | hFractionElectrons = new TH1F("hFractionElectrons", "e", hPIDdata->GetAxis(axisForMode)->GetNbins(), histBins->fArray); | |
1915 | } | |
1916 | ||
1917 | hFractionElectrons->GetXaxis()->SetTitle(hPIDdata->GetAxis(axisForMode)->GetTitle()); | |
1918 | hFractionElectrons->GetYaxis()->SetTitle("Fraction"); | |
1919 | hFractionElectrons->SetLineColor(getLineColor(kEl)); | |
1920 | hFractionElectrons->SetMarkerColor(getLineColor(kEl)); | |
1921 | hFractionElectrons->SetMarkerStyle(20); | |
1922 | hFractionElectrons->Sumw2(); | |
1923 | hFractionElectrons->SetStats(kFALSE); | |
1924 | ||
1925 | TH1F* hFractionElectronsDeltaPion = (TH1F*)hFractionElectrons->Clone("hFractionElectronsDeltaPion"); | |
1926 | TH1F* hFractionElectronsDeltaElectron = (TH1F*)hFractionElectrons->Clone("hFractionElectronsDeltaElectron"); | |
1927 | TH1F* hFractionElectronsDeltaKaon = (TH1F*)hFractionElectrons->Clone("hFractionElectronsDeltaKaon"); | |
1928 | TH1F* hFractionElectronsDeltaProton = (TH1F*)hFractionElectrons->Clone("hFractionElectronsDeltaProton"); | |
1929 | ||
1930 | TH1F* hFractionKaons = (TH1F*)hFractionElectrons->Clone("hFractionKaons"); | |
1931 | hFractionKaons->SetTitle("K"); | |
1932 | hFractionKaons->SetLineColor(getLineColor(kKa)); | |
1933 | hFractionKaons->SetMarkerColor(getLineColor(kKa)); | |
1934 | ||
1935 | TH1F* hFractionKaonsDeltaPion = (TH1F*)hFractionKaons->Clone("hFractionKaonsDeltaPion"); | |
1936 | TH1F* hFractionKaonsDeltaElectron = (TH1F*)hFractionKaons->Clone("hFractionKaonsDeltaElectron"); | |
1937 | TH1F* hFractionKaonsDeltaKaon = (TH1F*)hFractionKaons->Clone("hFractionKaonsDeltaKaon"); | |
1938 | TH1F* hFractionKaonsDeltaProton = (TH1F*)hFractionKaons->Clone("hFractionKaonsDeltaProton"); | |
1939 | ||
1940 | TH1F* hFractionPions = (TH1F*)hFractionElectrons->Clone("hFractionPions"); | |
1941 | hFractionPions->SetTitle("#pi"); | |
1942 | hFractionPions->SetLineColor(getLineColor(kPi)); | |
1943 | hFractionPions->SetMarkerColor(getLineColor(kPi)); | |
1944 | ||
1945 | TH1F* hFractionPionsDeltaPion = (TH1F*)hFractionPions->Clone("hFractionPionsDeltaPion"); | |
1946 | TH1F* hFractionPionsDeltaElectron = (TH1F*)hFractionPions->Clone("hFractionPionsDeltaElectron"); | |
1947 | TH1F* hFractionPionsDeltaKaon = (TH1F*)hFractionPions->Clone("hFractionPionsDeltaKaon"); | |
1948 | TH1F* hFractionPionsDeltaProton = (TH1F*)hFractionPions->Clone("hFractionPionsDeltaProton"); | |
1949 | ||
1950 | TH1F* hFractionProtons = (TH1F*)hFractionElectrons->Clone("hFractionProtons"); | |
1951 | hFractionProtons->SetTitle("p"); | |
1952 | hFractionProtons->SetLineColor(getLineColor(kPr)); | |
1953 | hFractionProtons->SetMarkerColor(getLineColor(kPr)); | |
1954 | ||
1955 | TH1F* hFractionProtonsDeltaPion = (TH1F*)hFractionProtons->Clone("hFractionProtonsDeltaPion"); | |
1956 | TH1F* hFractionProtonsDeltaElectron = (TH1F*)hFractionProtons->Clone("hFractionProtonsDeltaElectron"); | |
1957 | TH1F* hFractionProtonsDeltaKaon = (TH1F*)hFractionProtons->Clone("hFractionProtonsDeltaKaon"); | |
1958 | TH1F* hFractionProtonsDeltaProton = (TH1F*)hFractionProtons->Clone("hFractionProtonsDeltaProton"); | |
1959 | ||
1960 | TH1F* hFractionMuons = (TH1F*)hFractionElectrons->Clone("hFractionMuons"); | |
1961 | hFractionMuons->SetTitle("#mu"); | |
1962 | hFractionMuons->SetLineColor(getLineColor(kMu)); | |
1963 | hFractionMuons->SetMarkerColor(getLineColor(kMu)); | |
1964 | ||
1965 | TH1F* hFractionMuonsDeltaPion = (TH1F*)hFractionMuons->Clone("hFractionMuonsDeltaPion"); | |
1966 | TH1F* hFractionMuonsDeltaElectron = (TH1F*)hFractionMuons->Clone("hFractionMuonsDeltaElectron"); | |
1967 | TH1F* hFractionMuonsDeltaKaon = (TH1F*)hFractionMuons->Clone("hFractionMuonsDeltaKaon"); | |
1968 | TH1F* hFractionMuonsDeltaProton = (TH1F*)hFractionMuons->Clone("hFractionMuonsDeltaProton"); | |
1969 | ||
1970 | TH1F* hFractionSummed = (TH1F*)hFractionProtons->Clone("hFractionSummed"); | |
1971 | hFractionSummed->SetTitle("Sum"); | |
1972 | hFractionSummed->SetLineColor(kBlack); | |
1973 | hFractionSummed->SetMarkerColor(kBlack); | |
1974 | ||
1975 | ||
1976 | // MC fractions | |
1977 | TH1F* hFractionElectronsMC = (TH1F*)hFractionElectrons->Clone("hFractionElectronsMC"); | |
1978 | hFractionElectronsMC->SetMarkerStyle(24); | |
1979 | TH1F* hFractionKaonsMC = (TH1F*)hFractionKaons->Clone("hFractionKaonsMC"); | |
1980 | hFractionKaonsMC->SetMarkerStyle(24); | |
1981 | TH1F* hFractionPionsMC = (TH1F*)hFractionPions->Clone("hFractionPionsMC"); | |
1982 | hFractionPionsMC->SetMarkerStyle(24); | |
1983 | TH1F* hFractionMuonsMC = (TH1F*)hFractionMuons->Clone("hFractionMuonsMC"); | |
1984 | hFractionMuonsMC->SetMarkerStyle(24); | |
1985 | TH1F* hFractionProtonsMC = (TH1F*)hFractionProtons->Clone("hFractionProtonsMC"); | |
1986 | hFractionProtonsMC->SetMarkerStyle(24); | |
1987 | ||
1988 | ||
1989 | // Comparison fit result<->MC | |
1990 | TString fractionComparisonTitle = Form("Fraction fit / fraction %s", identifiedLabels[isMC].Data()); | |
1991 | TH1F* hFractionComparisonElectrons = (TH1F*)hFractionElectrons->Clone("hFractionComparisonElectrons"); | |
1992 | hFractionComparisonElectrons->GetYaxis()->SetTitle(fractionComparisonTitle.Data()); | |
1993 | TH1F* hFractionComparisonMuons = (TH1F*)hFractionMuons->Clone("hFractionComparisonMuons"); | |
1994 | hFractionComparisonMuons->GetYaxis()->SetTitle(fractionComparisonTitle.Data()); | |
1995 | TH1F* hFractionComparisonKaons = (TH1F*)hFractionKaons->Clone("hFractionComparisonKaons"); | |
1996 | hFractionComparisonKaons->GetYaxis()->SetTitle(fractionComparisonTitle.Data()); | |
1997 | TH1F* hFractionComparisonPions = (TH1F*)hFractionPions->Clone("hFractionComparisonPions"); | |
1998 | hFractionComparisonPions->GetYaxis()->SetTitle(fractionComparisonTitle.Data()); | |
1999 | TH1F* hFractionComparisonProtons = (TH1F*)hFractionProtons->Clone("hFractionComparisonProtons"); | |
2000 | hFractionComparisonProtons->GetYaxis()->SetTitle(fractionComparisonTitle.Data()); | |
2001 | TH1F* hFractionComparisonTotal = (TH1F*)hFractionSummed->Clone("hFractionComparisonTotal"); | |
2002 | hFractionComparisonTotal->GetYaxis()->SetTitle(fractionComparisonTitle.Data()); | |
2003 | ||
2004 | ||
2005 | ||
2006 | // Histos for particle yields | |
2007 | TH1F* hYieldElectrons = 0x0; | |
2008 | if (mode == kPMpT) | |
2009 | hYieldElectrons = new TH1F("hYieldElectrons", "e", nPtBins, binsPt); | |
2010 | else { | |
2011 | const TArrayD* histBins = hPIDdata->GetAxis(axisForMode)->GetXbins(); | |
2012 | if (histBins->fN == 0) | |
2013 | hYieldElectrons = new TH1F("hYieldElectrons", "e", hPIDdata->GetAxis(axisForMode)->GetNbins(), hPIDdata->GetAxis(axisForMode)->GetXmin(), | |
2014 | hPIDdata->GetAxis(axisForMode)->GetXmax()); | |
2015 | else | |
2016 | hYieldElectrons = new TH1F("hYieldElectrons", "e", hPIDdata->GetAxis(axisForMode)->GetNbins(), histBins->fArray); | |
2017 | } | |
2018 | ||
2019 | hYieldElectrons->GetXaxis()->SetTitle(hPIDdata->GetAxis(axisForMode)->GetTitle()); | |
2020 | hYieldElectrons->GetYaxis()->SetTitle(Form("%s1/(2#pi%s) d^{2}N/d#etad%s%s", numEvents > 0 ? "1/N_{ev} " : "", | |
2021 | modeLatexName[mode].Data(), modeLatexName[mode].Data(), | |
2022 | mode == kPMpT ? " (GeV/c)^{-2}" : 0)); | |
2023 | hYieldElectrons->SetLineColor(getLineColor(kEl)); | |
2024 | hYieldElectrons->SetMarkerColor(getLineColor(kEl)); | |
2025 | hYieldElectrons->SetMarkerStyle(20); | |
2026 | hYieldElectrons->Sumw2(); | |
2027 | hYieldElectrons->SetStats(kFALSE); | |
2028 | ||
2029 | TH1F* hYieldElectronsDeltaPion = (TH1F*)hYieldElectrons->Clone("hYieldElectronsDeltaPion"); | |
2030 | TH1F* hYieldElectronsDeltaElectron = (TH1F*)hYieldElectrons->Clone("hYieldElectronsDeltaElectron"); | |
2031 | TH1F* hYieldElectronsDeltaKaon = (TH1F*)hYieldElectrons->Clone("hYieldElectronsDeltaKaon"); | |
2032 | TH1F* hYieldElectronsDeltaProton = (TH1F*)hYieldElectrons->Clone("hYieldElectronsDeltaProton"); | |
2033 | ||
2034 | TH1F* hYieldKaons = (TH1F*)hYieldElectrons->Clone("hYieldKaons"); | |
2035 | hYieldKaons->SetTitle("K"); | |
2036 | hYieldKaons->SetLineColor(getLineColor(kKa)); | |
2037 | hYieldKaons->SetMarkerColor(getLineColor(kKa)); | |
2038 | ||
2039 | TH1F* hYieldKaonsDeltaPion = (TH1F*)hYieldKaons->Clone("hYieldKaonsDeltaPion"); | |
2040 | TH1F* hYieldKaonsDeltaElectron = (TH1F*)hYieldKaons->Clone("hYieldKaonsDeltaElectron"); | |
2041 | TH1F* hYieldKaonsDeltaKaon = (TH1F*)hYieldKaons->Clone("hYieldKaonsDeltaKaon"); | |
2042 | TH1F* hYieldKaonsDeltaProton = (TH1F*)hYieldKaons->Clone("hYieldKaonsDeltaProton"); | |
2043 | ||
2044 | TH1F* hYieldPions = (TH1F*)hYieldElectrons->Clone("hYieldPions"); | |
2045 | hYieldPions->SetTitle("#pi"); | |
2046 | hYieldPions->SetLineColor(getLineColor(kPi)); | |
2047 | hYieldPions->SetMarkerColor(getLineColor(kPi)); | |
2048 | ||
2049 | TH1F* hYieldPionsDeltaPion = (TH1F*)hYieldPions->Clone("hYieldPionsDeltaPion"); | |
2050 | TH1F* hYieldPionsDeltaElectron = (TH1F*)hYieldPions->Clone("hYieldPionsDeltaElectron"); | |
2051 | TH1F* hYieldPionsDeltaKaon = (TH1F*)hYieldPions->Clone("hYieldPionsDeltaKaon"); | |
2052 | TH1F* hYieldPionsDeltaProton = (TH1F*)hYieldPions->Clone("hYieldPionsDeltaProton"); | |
2053 | ||
2054 | TH1F* hYieldProtons = (TH1F*)hYieldElectrons->Clone("hYieldProtons"); | |
2055 | hYieldProtons->SetTitle("p"); | |
2056 | hYieldProtons->SetLineColor(getLineColor(kPr)); | |
2057 | hYieldProtons->SetMarkerColor(getLineColor(kPr)); | |
2058 | ||
2059 | TH1F* hYieldProtonsDeltaPion = (TH1F*)hYieldProtons->Clone("hYieldProtonsDeltaPion"); | |
2060 | TH1F* hYieldProtonsDeltaElectron = (TH1F*)hYieldProtons->Clone("hYieldProtonsDeltaElectron"); | |
2061 | TH1F* hYieldProtonsDeltaKaon = (TH1F*)hYieldProtons->Clone("hYieldProtonsDeltaKaon"); | |
2062 | TH1F* hYieldProtonsDeltaProton = (TH1F*)hYieldProtons->Clone("hYieldProtonsDeltaProton"); | |
2063 | ||
2064 | TH1F* hYieldMuons = (TH1F*)hYieldElectrons->Clone("hYieldMuons"); | |
2065 | hYieldMuons->SetTitle("#mu"); | |
2066 | hYieldMuons->SetLineColor(getLineColor(kMu)); | |
2067 | hYieldMuons->SetMarkerColor(getLineColor(kMu)); | |
2068 | ||
2069 | TH1F* hYieldMuonsDeltaPion = (TH1F*)hYieldMuons->Clone("hYieldMuonsDeltaPion"); | |
2070 | TH1F* hYieldMuonsDeltaElectron = (TH1F*)hYieldMuons->Clone("hYieldMuonsDeltaElectron"); | |
2071 | TH1F* hYieldMuonsDeltaKaon = (TH1F*)hYieldMuons->Clone("hYieldMuonsDeltaKaon"); | |
2072 | TH1F* hYieldMuonsDeltaProton = (TH1F*)hYieldMuons->Clone("hYieldMuonsDeltaProton"); | |
2073 | ||
2074 | // MC yields | |
2075 | TH1F* hYieldElectronsMC = (TH1F*)hYieldElectrons->Clone("hYieldElectronsMC"); | |
2076 | hYieldElectronsMC->SetMarkerStyle(24); | |
2077 | TH1F* hYieldMuonsMC = (TH1F*)hYieldElectrons->Clone("hYieldMuonsMC"); | |
2078 | hYieldMuonsMC->SetMarkerStyle(24); | |
2079 | hYieldMuonsMC->SetLineColor(getLineColor(kMu)); | |
2080 | hYieldMuonsMC->SetMarkerColor(getLineColor(kMu)); | |
2081 | TH1F* hYieldKaonsMC = (TH1F*)hYieldKaons->Clone("hYieldKaonsMC"); | |
2082 | hYieldKaonsMC->SetMarkerStyle(24); | |
2083 | TH1F* hYieldPionsMC = (TH1F*)hYieldPions->Clone("hYieldPionsMC"); | |
2084 | hYieldPionsMC->SetMarkerStyle(24); | |
2085 | TH1F* hYieldProtonsMC = (TH1F*)hYieldProtons->Clone("hYieldProtonsMC"); | |
2086 | hYieldProtonsMC->SetMarkerStyle(24); | |
2087 | TH1F* hYieldSummedMC = (TH1F*)hYieldProtonsMC->Clone("hYieldSummedMC"); | |
2088 | hYieldSummedMC->SetTitle("Sum"); | |
2089 | hYieldSummedMC->SetLineColor(kBlack); | |
2090 | hYieldSummedMC->SetMarkerColor(kBlack); | |
2091 | ||
2092 | // Comparison fit result<->MC (yields) | |
2093 | TString yieldComparisonTitle = Form("Yield fit / yield %s", identifiedLabels[isMC].Data()); | |
2094 | TH1F* hYieldComparisonElectrons = (TH1F*)hYieldElectrons->Clone("hYieldComparisonElectrons"); | |
2095 | hYieldComparisonElectrons->GetYaxis()->SetTitle(yieldComparisonTitle.Data()); | |
2096 | TH1F* hYieldComparisonMuons = (TH1F*)hYieldMuons->Clone("hYieldComparisonMuons"); | |
2097 | hYieldComparisonMuons->GetYaxis()->SetTitle(yieldComparisonTitle.Data()); | |
2098 | TH1F* hYieldComparisonKaons = (TH1F*)hYieldKaons->Clone("hYieldComparisonKaons"); | |
2099 | hYieldComparisonKaons->GetYaxis()->SetTitle(yieldComparisonTitle.Data()); | |
2100 | TH1F* hYieldComparisonPions = (TH1F*)hYieldPions->Clone("hYieldComparisonPions"); | |
2101 | hYieldComparisonPions->GetYaxis()->SetTitle(yieldComparisonTitle.Data()); | |
2102 | TH1F* hYieldComparisonProtons = (TH1F*)hYieldProtons->Clone("hYieldComparisonProtons"); | |
2103 | hYieldComparisonProtons->GetYaxis()->SetTitle(yieldComparisonTitle.Data()); | |
2104 | ||
2105 | ||
2106 | // To-pi ratios | |
2107 | TString electronString[3] = { "e^{-}", "e^{+}+e^{-}", "e^{+}" }; | |
2108 | TString muonString[3] = { "#mu^{-}", "#mu^{+}+#mu^{-}", "#mu^{+}" }; | |
2109 | TString kaonString[3] = { "K^{-}", "K^{+}+K^{-}", "K^{+}" }; | |
2110 | TString pionString[3] = { "#pi^{-}", "#pi^{+}+#pi^{-}", "#pi^{+}" }; | |
2111 | TString protonString[3] = { "#bar{p}", "p+#bar{p}", "p" }; | |
2112 | ||
2113 | TH1F* hRatioToPiElectrons = (TH1F*)hYieldElectrons->Clone("hRatioToPiElectrons"); | |
2114 | hRatioToPiElectrons->GetYaxis()->SetTitle(Form("d^{2}N_{%s}/d#etad%s / d^{2}N_{%s}/d#etad%s", | |
2115 | electronString[chargeMode+1].Data(), | |
2116 | modeLatexName[mode].Data(), | |
2117 | pionString[chargeMode+1].Data(), | |
2118 | modeLatexName[mode].Data())); | |
2119 | hRatioToPiElectrons->SetTitle(Form("%s", chargeMode == 0 | |
2120 | ? Form("(%s)/(%s)", electronString[chargeMode+1].Data(), pionString[chargeMode+1].Data()) | |
2121 | : Form("%s/%s", electronString[chargeMode+1].Data(), pionString[chargeMode+1].Data()))); | |
2122 | ||
2123 | ||
2124 | TH1F* hRatioToPiMuons = (TH1F*)hYieldMuons->Clone("hRatioToPiMuons"); | |
2125 | hRatioToPiMuons->GetYaxis()->SetTitle(Form("d^{2}N_{%s}/d#etad%s / d^{2}N_{%s}/d#etad%s", | |
2126 | muonString[chargeMode+1].Data(), | |
2127 | modeLatexName[mode].Data(), | |
2128 | pionString[chargeMode+1].Data(), | |
2129 | modeLatexName[mode].Data())); | |
2130 | hRatioToPiMuons->SetTitle(Form("%s", chargeMode == 0 | |
2131 | ? Form("(%s)/(%s)", muonString[chargeMode+1].Data(), pionString[chargeMode+1].Data()) | |
2132 | : Form("%s/%s", muonString[chargeMode+1].Data(), pionString[chargeMode+1].Data()))); | |
2133 | ||
2134 | TH1F* hRatioToPiKaons = (TH1F*)hYieldKaons->Clone("hRatioToPiKaons"); | |
2135 | hRatioToPiKaons->GetYaxis()->SetTitle(Form("d^{2}N_{%s}/d#etad%s / d^{2}N_{%s}/d#etad%s", | |
2136 | kaonString[chargeMode+1].Data(), | |
2137 | modeLatexName[mode].Data(), | |
2138 | pionString[chargeMode+1].Data(), | |
2139 | modeLatexName[mode].Data())); | |
2140 | hRatioToPiKaons->SetTitle(Form("%s", chargeMode == 0 | |
2141 | ? Form("(%s)/(%s)", kaonString[chargeMode+1].Data(), pionString[chargeMode+1].Data()) | |
2142 | : Form("%s/%s", kaonString[chargeMode+1].Data(), pionString[chargeMode+1].Data()))); | |
2143 | ||
2144 | TH1F* hRatioToPiProtons = (TH1F*)hYieldProtons->Clone("hRatioToPiProtons"); | |
2145 | hRatioToPiProtons->GetYaxis()->SetTitle(Form("d^{2}N_{%s}/d#etad%s / d^{2}N_{%s}/d#etad%s", | |
2146 | protonString[chargeMode+1].Data(), | |
2147 | modeLatexName[mode].Data(), | |
2148 | pionString[chargeMode+1].Data(), | |
2149 | modeLatexName[mode].Data())); | |
2150 | hRatioToPiProtons->SetTitle(Form("%s", chargeMode == 0 | |
2151 | ? Form("(%s)/(%s)", protonString[chargeMode+1].Data(), pionString[chargeMode+1].Data()) | |
2152 | : Form("%s/%s", protonString[chargeMode+1].Data(), pionString[chargeMode+1].Data()))); | |
2153 | ||
2154 | // MC to-pi ratios | |
2155 | TH1F* hRatioToPiElectronsMC = (TH1F*)hRatioToPiElectrons->Clone("hRatioToPiElectronsMC"); | |
2156 | hRatioToPiElectronsMC->SetMarkerStyle(24); | |
2157 | TH1F* hRatioToPiMuonsMC = (TH1F*)hRatioToPiMuons->Clone("hRatioToPiMuonsMC"); | |
2158 | hRatioToPiMuonsMC->SetMarkerStyle(24); | |
2159 | hRatioToPiMuonsMC->SetLineColor(getLineColor(kMu)); | |
2160 | hRatioToPiMuonsMC->SetMarkerColor(getLineColor(kMu)); | |
2161 | TH1F* hRatioToPiKaonsMC = (TH1F*)hRatioToPiKaons->Clone("hRatioToPiKaonsMC"); | |
2162 | hRatioToPiKaonsMC->SetMarkerStyle(24); | |
2163 | TH1F* hRatioToPiProtonsMC = (TH1F*)hRatioToPiProtons->Clone("hRatioToPiProtonsMC"); | |
2164 | hRatioToPiProtonsMC->SetMarkerStyle(24); | |
2165 | ||
2166 | // Reduced Chi^2 of fits vs. pT for all Delta_Species | |
2167 | TH2F* hReducedChiSquarePt = 0x0; | |
2168 | if (mode == kPMpT) | |
2169 | hReducedChiSquarePt = new TH2F("hReducedChiSquarePt", "e", nPtBins, binsPt, 4, 0, 4); | |
2170 | else { | |
2171 | const TArrayD* histBins = hPIDdata->GetAxis(axisForMode)->GetXbins(); | |
2172 | if (histBins->fN == 0) | |
2173 | hReducedChiSquarePt = new TH2F(Form("hReducedChiSquare%s", modeShortName[mode].Data()), "e", | |
2174 | hPIDdata->GetAxis(axisForMode)->GetNbins(), hPIDdata->GetAxis(axisForMode)->GetXmin(), | |
2175 | hPIDdata->GetAxis(axisForMode)->GetXmax(), 4, 0, 4); | |
2176 | else | |
2177 | hReducedChiSquarePt = new TH2F(Form("hReducedChiSquare%s", modeShortName[mode].Data()), "e", | |
2178 | hPIDdata->GetAxis(axisForMode)->GetNbins(), histBins->fArray, 4, 0, 4); | |
2179 | } | |
2180 | ||
2181 | hReducedChiSquarePt->GetXaxis()->SetTitle(hPIDdata->GetAxis(axisForMode)->GetTitle()); | |
2182 | hReducedChiSquarePt->GetYaxis()->SetTitle("Delta_{Species}"); | |
2183 | hReducedChiSquarePt->GetYaxis()->SetBinLabel(1, "e"); | |
2184 | hReducedChiSquarePt->GetYaxis()->SetBinLabel(2, "K"); | |
2185 | hReducedChiSquarePt->GetYaxis()->SetBinLabel(3, "#pi"); | |
2186 | hReducedChiSquarePt->GetYaxis()->SetBinLabel(4, "p"); | |
2187 | hReducedChiSquarePt->SetMarkerColor(kRed); | |
2188 | hReducedChiSquarePt->SetMarkerStyle(20); | |
2189 | hReducedChiSquarePt->SetStats(kFALSE); | |
2190 | ||
2191 | // Obtain MC information about particle yields | |
2192 | hPIDdata->GetAxis(kPidSelectSpecies)->SetRange(1, 1); // Do not count each particle more than once | |
2193 | TH2D* hMCdata = (TH2D*)hPIDdata->Projection(kPidMCpid, axisForMode, "e"); | |
2194 | hMCdata->SetName("hMCdata"); | |
2195 | hPIDdata->GetAxis(kPidSelectSpecies)->SetRange(0, -1); // Reset range | |
2196 | ||
2197 | ||
2198 | ||
2199 | // Extract the MC truth generated primary yields | |
2200 | THnSparse* hMCgeneratedYieldsPrimaries = isMCdataSet ? dynamic_cast<THnSparse*>(histList->FindObject("fhMCgeneratedYieldsPrimaries")) | |
2201 | : 0x0; | |
2202 | ||
2203 | TH1D* hMCgenYieldsPrimSpecies[AliPID::kSPECIES]; | |
2204 | for (Int_t i = 0; i < AliPID::kSPECIES; i++) | |
2205 | hMCgenYieldsPrimSpecies[i] = 0x0; | |
2206 | ||
2207 | if (hMCgeneratedYieldsPrimaries) { | |
2208 | // Set proper errors, if not yet calculated | |
2209 | if (!hMCgeneratedYieldsPrimaries->GetCalculateErrors()) { | |
2210 | std::cout << "Re-calculating errors of " << hMCgeneratedYieldsPrimaries->GetName() << "..." << std::endl; | |
2211 | ||
2212 | hMCgeneratedYieldsPrimaries->Sumw2(); | |
2213 | ||
2214 | Long64_t nBinsTHnSparseGenYield = hMCgeneratedYieldsPrimaries->GetNbins(); | |
2215 | Double_t binContentGenYield = 0; | |
2216 | for (Long64_t bin = 0; bin < nBinsTHnSparseGenYield; bin++) { | |
2217 | binContentGenYield = hMCgeneratedYieldsPrimaries->GetBinContent(bin); | |
2218 | hMCgeneratedYieldsPrimaries->SetBinError(bin, TMath::Sqrt(binContentGenYield)); | |
2219 | } | |
2220 | } | |
2221 | ||
2222 | if (restrictJetPtAxis) | |
2223 | hMCgeneratedYieldsPrimaries->GetAxis(kPidGenYieldJetPt)->SetRange(lowerJetPtBinLimit, upperJetPtBinLimit); | |
2224 | ||
2225 | if (restrictCentralityAxis) | |
2226 | hMCgeneratedYieldsPrimaries->GetAxis(kPidGenYieldCentrality)->SetRange(lowerCentralityBinLimit, upperCentralityBinLimit); | |
2227 | ||
2228 | ||
2229 | if (restrictCharge) { | |
2230 | const Int_t indexChargeAxisGenYield = GetAxisByTitle(hMCgeneratedYieldsPrimaries, "Charge (e_{0})"); | |
2231 | if (indexChargeAxisGenYield < 0) { | |
2232 | std::cout << "Error: Charge axis not found for gen yield histogram!" << std::endl; | |
2233 | return -1; | |
2234 | } | |
2235 | ||
2236 | Int_t lowerChargeBinLimitGenYield = -1; | |
2237 | Int_t upperChargeBinLimitGenYield = -2; | |
2238 | Double_t actualLowerChargeGenYield = -999; | |
2239 | Double_t actualUpperChargeGenYield = -999; | |
2240 | ||
2241 | // Add subtract a very small number to avoid problems with values right on the border between to bins | |
2242 | if (chargeMode == kNegCharge) { | |
2243 | lowerChargeBinLimitGenYield = hMCgeneratedYieldsPrimaries->GetAxis(indexChargeAxisGenYield)->FindBin(-1. + 0.001); | |
2244 | upperChargeBinLimitGenYield = hMCgeneratedYieldsPrimaries->GetAxis(indexChargeAxisGenYield)->FindBin(0. - 0.001); | |
2245 | } | |
2246 | else if (chargeMode == kPosCharge) { | |
2247 | lowerChargeBinLimitGenYield = hMCgeneratedYieldsPrimaries->GetAxis(indexChargeAxisGenYield)->FindBin(0. + 0.001); | |
2248 | upperChargeBinLimitGenYield = hMCgeneratedYieldsPrimaries->GetAxis(indexChargeAxisGenYield)->FindBin(1. - 0.001); | |
2249 | } | |
2250 | ||
2251 | // Check if the values look reasonable | |
2252 | if (lowerChargeBinLimitGenYield <= upperChargeBinLimitGenYield && lowerChargeBinLimitGenYield >= 1 | |
2253 | && upperChargeBinLimitGenYield <= hMCgeneratedYieldsPrimaries->GetAxis(indexChargeAxisGenYield)->GetNbins()) { | |
2254 | actualLowerChargeGenYield = hMCgeneratedYieldsPrimaries->GetAxis(indexChargeAxisGenYield)->GetBinLowEdge(lowerChargeBinLimitGenYield); | |
2255 | actualUpperChargeGenYield = hMCgeneratedYieldsPrimaries->GetAxis(indexChargeAxisGenYield)->GetBinUpEdge(upperChargeBinLimitGenYield); | |
2256 | ||
2257 | if (TMath::Abs(actualLowerChargeGenYield - actualLowerChargeData) > 1e-4 || | |
2258 | TMath::Abs(actualUpperChargeGenYield - actualUpperChargeData) > 1e-4) { | |
2259 | std::cout << std::endl; | |
2260 | std::cout << "Error: Charge range gen yield: " << actualLowerChargeGenYield << " - " << actualUpperChargeGenYield | |
2261 | << std::endl << "differs from that of data: " << actualLowerChargeData << " - " << actualUpperChargeData | |
2262 | << std::endl; | |
2263 | return -1; | |
2264 | } | |
2265 | } | |
2266 | else { | |
2267 | std::cout << std::endl; | |
2268 | std::cout << "Requested charge range (gen yield) out of limits or upper and lower limit are switched!" << std::endl; | |
2269 | return -1; | |
2270 | } | |
2271 | ||
2272 | hMCgeneratedYieldsPrimaries->GetAxis(indexChargeAxisGenYield)->SetRange(lowerChargeBinLimitGenYield, upperChargeBinLimitGenYield); | |
2273 | } | |
2274 | ||
2275 | for (Int_t MCid = 0; MCid < AliPID::kSPECIES; MCid++) { | |
2276 | hMCgeneratedYieldsPrimaries->GetAxis(kPidGenYieldMCpid)->SetRange(MCid + 1, MCid + 1); | |
2277 | ||
2278 | hMCgenYieldsPrimSpecies[MCid] = hMCgeneratedYieldsPrimaries->Projection(kPidGenYieldPt, "e"); | |
2279 | hMCgenYieldsPrimSpecies[MCid]->SetName(Form("hMCgenYieldsPrimSpecies_%s", AliPID::ParticleShortName(MCid))); | |
2280 | hMCgenYieldsPrimSpecies[MCid]->SetTitle(Form("MC truth generated primary yield, %s", AliPID::ParticleName(MCid))); | |
2281 | ||
2282 | // Choose the same binning as for the fitted yields, i.e. rebin the histogram (Rebin will create a clone!) | |
2283 | TH1D* temp = (TH1D*)hMCgenYieldsPrimSpecies[MCid]->Rebin(nPtBins, hMCgenYieldsPrimSpecies[MCid]->GetName(), binsPt); | |
2284 | // Delete the old binned histo and take the new binned one | |
2285 | delete hMCgenYieldsPrimSpecies[MCid]; | |
2286 | hMCgenYieldsPrimSpecies[MCid] = temp; | |
2287 | ||
2288 | hMCgeneratedYieldsPrimaries->GetAxis(kPidGenYieldMCpid)->SetRange(0, -1); | |
2289 | } | |
2290 | } | |
2291 | ||
2292 | ||
2293 | // Get expected shapes for pT bins | |
2294 | TString Ytitle = ""; | |
2295 | ||
2296 | // Array index 0 as unused dummy | |
2297 | TH2D* hGenDelta[6][6]; // DeltaSpecies (first index) for species (second index) | |
2298 | TH2D* hGenDeltaMCid[6][6]; // DeltaSpecies (first index) for species (second index) | |
2299 | ||
2300 | for (Int_t i = 0; i < 6; i++) { | |
2301 | for (Int_t j = 0; j < 6; j++) { | |
2302 | hGenDelta[i][j] = 0x0; | |
2303 | hGenDeltaMCid[i][j] = 0x0; | |
2304 | } | |
2305 | } | |
2306 | ||
2307 | THnSparse* current = 0x0; | |
2308 | ||
2309 | THnSparse* hGenEl = dynamic_cast<THnSparse*>(histList->FindObject("hGenEl")); | |
2310 | if (!hGenEl) { | |
2311 | std::cout << "Failed to load expected dEdx signal shape for: Electrons!" << std::endl; | |
2312 | return -1; | |
2313 | } | |
2314 | ||
2315 | THnSparse* hGenKa = dynamic_cast<THnSparse*>(histList->FindObject("hGenKa")); | |
2316 | if (!hGenKa) { | |
2317 | std::cout << "Failed to load expected dEdx signal shape for: Kaons!" << std::endl; | |
2318 | return -1; | |
2319 | } | |
2320 | ||
2321 | THnSparse* hGenPi = dynamic_cast<THnSparse*>(histList->FindObject("hGenPi")); | |
2322 | if (!hGenPi) { | |
2323 | std::cout << "Failed to load expected dEdx signal shape for: Pions!" << std::endl; | |
2324 | return -1; | |
2325 | } | |
2326 | ||
2327 | THnSparse* hGenMu = dynamic_cast<THnSparse*>(histList->FindObject("hGenMu")); | |
2328 | if (!hGenMu) { | |
2329 | std::cout << "Failed to load expected dEdx signal shape for: Muons! Treated muons as pions in the following." << std::endl; | |
2330 | takeIntoAccountMuons = kFALSE; | |
2331 | } | |
2332 | ||
2333 | THnSparse* hGenPr = dynamic_cast<THnSparse*>(histList->FindObject("hGenPr")); | |
2334 | if (!hGenPr) { | |
2335 | std::cout << "Failed to load expected dEdx signal shape for: Protons!" << std::endl; | |
2336 | return -1; | |
2337 | } | |
2338 | ||
2339 | for (Int_t MCid = kEl; MCid <= kPr; MCid++) { | |
2340 | if (MCid == kEl) | |
2341 | current = hGenEl; | |
2342 | else if (MCid == kKa) | |
2343 | current = hGenKa; | |
2344 | else if (MCid == kMu) { | |
2345 | if (takeIntoAccountMuons) | |
2346 | current = hGenMu; | |
2347 | else | |
2348 | continue; // No histo for muons in this case | |
2349 | } | |
2350 | else if (MCid == kPi) | |
2351 | current = hGenPi; | |
2352 | else if (MCid == kPr) | |
2353 | current = hGenPr; | |
2354 | else | |
2355 | break; | |
2356 | ||
2357 | // If desired, rebin considered axis | |
2358 | if (rebin > 1 || rebinDeltaPrime > 1) { | |
2359 | const Int_t nDimensions = current->GetNdimensions(); | |
2360 | Int_t rebinFactor[nDimensions]; | |
2361 | ||
2362 | for (Int_t dim = 0; dim < nDimensions; dim++) { | |
2363 | if (dim == axisGenForMode) | |
2364 | rebinFactor[dim] = rebin; | |
2365 | else if (dim == kPidGenDeltaPrime && rebinDeltaPrime > 1) | |
2366 | rebinFactor[dim] = rebinDeltaPrime; | |
2367 | else | |
2368 | rebinFactor[dim] = 1; | |
2369 | } | |
2370 | ||
2371 | THnSparse* temp = current->Rebin(&rebinFactor[0]); | |
2372 | current->Reset(); | |
2373 | current = temp; | |
2374 | } | |
2375 | ||
2376 | // Set proper errors, if not yet calculated | |
2377 | if (!current->GetCalculateErrors()) { | |
2378 | std::cout << "Re-calculating errors of " << current->GetName() << "..." << std::endl; | |
2379 | ||
2380 | current->Sumw2(); | |
2381 | ||
2382 | Long64_t nBinsTHnSparseGen = current->GetNbins(); | |
2383 | Double_t binContentGen = 0; | |
2384 | for (Long64_t bin = 0; bin < nBinsTHnSparseGen; bin++) { | |
2385 | binContentGen = current->GetBinContent(bin); | |
2386 | current->SetBinError(bin, TMath::Sqrt(binContentGen)); | |
2387 | } | |
2388 | } | |
2389 | ||
2390 | // If desired, restrict centrality range | |
2391 | if (restrictCentralityAxis) { | |
2392 | current->GetAxis(kPidGenCentrality)->SetRange(lowerCentralityBinLimit, upperCentralityBinLimit); | |
2393 | } | |
2394 | ||
2395 | // If desired, restrict jet pT range | |
2396 | if (restrictJetPtAxis) { | |
2397 | current->GetAxis(kPidGenJetPt)->SetRange(lowerJetPtBinLimit, upperJetPtBinLimit); | |
2398 | } | |
2399 | ||
2400 | // If desired, restrict charge range | |
2401 | if (restrictCharge) { | |
2402 | const Int_t indexChargeAxisGen = GetAxisByTitle(current, "Charge (e_{0})"); | |
2403 | if (indexChargeAxisGen < 0) { | |
2404 | std::cout << "Error: Charge axis not found for gen histogram!" << std::endl; | |
2405 | return -1; | |
2406 | } | |
2407 | ||
2408 | Int_t lowerChargeBinLimitGen = -1; | |
2409 | Int_t upperChargeBinLimitGen = -2; | |
2410 | Double_t actualLowerChargeGen = -999; | |
2411 | Double_t actualUpperChargeGen = -999; | |
2412 | ||
2413 | // Add subtract a very small number to avoid problems with values right on the border between to bins | |
2414 | if (chargeMode == kNegCharge) { | |
2415 | lowerChargeBinLimitGen = current->GetAxis(indexChargeAxisGen)->FindBin(-1. + 0.001); | |
2416 | upperChargeBinLimitGen = current->GetAxis(indexChargeAxisGen)->FindBin(0. - 0.001); | |
2417 | } | |
2418 | else if (chargeMode == kPosCharge) { | |
2419 | lowerChargeBinLimitGen = current->GetAxis(indexChargeAxisGen)->FindBin(0. + 0.001); | |
2420 | upperChargeBinLimitGen = current->GetAxis(indexChargeAxisGen)->FindBin(1. - 0.001); | |
2421 | } | |
2422 | ||
2423 | // Check if the values look reasonable | |
2424 | if (lowerChargeBinLimitGen <= upperChargeBinLimitGen && lowerChargeBinLimitGen >= 1 | |
2425 | && upperChargeBinLimitGen <= current->GetAxis(indexChargeAxisGen)->GetNbins()) { | |
2426 | actualLowerChargeGen = current->GetAxis(indexChargeAxisGen)->GetBinLowEdge(lowerChargeBinLimitGen); | |
2427 | actualUpperChargeGen = current->GetAxis(indexChargeAxisGen)->GetBinUpEdge(upperChargeBinLimitGen); | |
2428 | ||
2429 | if (TMath::Abs(actualLowerChargeGen - actualLowerChargeData) > 1e-4 || | |
2430 | TMath::Abs(actualUpperChargeGen - actualUpperChargeData) > 1e-4) { | |
2431 | std::cout << std::endl; | |
2432 | std::cout << "Error: Charge range gen: " << actualLowerChargeGen << " - " << actualUpperChargeGen | |
2433 | << std::endl << "differs from that of data: " << actualLowerChargeData << " - " << actualUpperChargeData | |
2434 | << std::endl; | |
2435 | return -1; | |
2436 | } | |
2437 | } | |
2438 | else { | |
2439 | std::cout << std::endl; | |
2440 | std::cout << "Requested charge range (gen) out of limits or upper and lower limit are switched!" << std::endl; | |
2441 | return -1; | |
2442 | } | |
2443 | ||
2444 | current->GetAxis(indexChargeAxisGen)->SetRange(lowerChargeBinLimitGen, upperChargeBinLimitGen); | |
2445 | } | |
2446 | ||
2447 | ||
2448 | ||
2449 | for (Int_t selectBin = 1; selectBin <= 4; selectBin++) { | |
2450 | Int_t selectMCid = (selectBin >= 3) ? (selectBin+1) : selectBin; | |
2451 | ||
2452 | current->GetAxis(kPidGenSelectSpecies)->SetRange(selectBin, selectBin); | |
2453 | ||
2454 | Ytitle = Form("#Delta%s_{%s} = dE/dx %s <dE/dx>_{%s} (arb. units)", useDeltaPrime ? "'" : "", | |
2455 | partShortName[selectMCid - 1].Data(), useDeltaPrime ? "/" : "-", | |
2456 | partShortName[selectMCid - 1].Data()); | |
2457 | ||
2458 | TH2* hGenCurrent = 0x0; | |
2459 | if (!useIdentifiedGeneratedSpectra) { | |
2460 | hGenDelta[selectMCid][MCid] = current->Projection(genAxis, axisGenForMode, "e"); | |
2461 | hGenDelta[selectMCid][MCid]->SetName(Form("hGenDelta%sFor%s", partShortName[selectMCid - 1].Data(), | |
2462 | partShortName[MCid - 1].Data())); | |
2463 | hGenCurrent = hGenDelta[selectMCid][MCid]; | |
2464 | } | |
2465 | else { | |
2466 | current->GetAxis(kPidGenMCpid)->SetRange(MCid, MCid); | |
2467 | hGenDeltaMCid[selectMCid][MCid] = current->Projection(genAxis, axisGenForMode, "e"); | |
2468 | hGenDeltaMCid[selectMCid][MCid]->SetName(Form("hGenDelta%sForMCid%s", partShortName[selectMCid - 1].Data(), | |
2469 | partShortName[MCid - 1].Data())); | |
2470 | ||
2471 | hGenCurrent = hGenDeltaMCid[selectMCid][MCid]; | |
2472 | current->GetAxis(kPidGenMCpid)->SetRange(0, -1); | |
2473 | } | |
2474 | ||
2475 | hGenCurrent->GetYaxis()->SetTitle(Ytitle.Data()); | |
2476 | hGenCurrent->SetLineColor(getLineColor(MCid)); | |
2477 | hGenCurrent->SetMarkerColor(getLineColor(MCid)); | |
2478 | hGenCurrent->SetLineWidth(2); | |
2479 | hGenCurrent->SetLineStyle(2); | |
2480 | hGenCurrent->SetMarkerStyle(20); | |
2481 | hGenCurrent->GetXaxis()->SetTitleOffset(1.0); | |
2482 | } | |
2483 | ||
2484 | current->GetAxis(kPidGenSelectSpecies)->SetRange(0, -1); | |
2485 | } | |
2486 | ||
2487 | // Free a lot of memory for the following procedure. Histogram is not needed anymore (only its projections) | |
2488 | delete f; | |
2489 | ||
2490 | // Save intermediate results | |
2491 | //TODO save intermediate TOF results | |
2492 | saveInterF->cd(); | |
2493 | ||
2494 | if (hMCdata) | |
2495 | hMCdata->Write(); | |
2496 | ||
2497 | for (Int_t i = 0; i < 6; i++) { | |
2498 | for (Int_t j = 0; j < 6; j++) { | |
2499 | if (hGenDelta[i][j]) | |
2500 | hGenDelta[i][j]->Write(); | |
2501 | ||
2502 | if (hGenDeltaMCid[i][j]) | |
2503 | hGenDeltaMCid[i][j]->Write(); | |
2504 | } | |
2505 | } | |
2506 | ||
2507 | for (Int_t slice = 0; (mode == kPMpT) ? slice < nPtBins : slice < hFractionPions->GetXaxis()->GetNbins(); slice++) { | |
2508 | if (mode == kPMpT && (slice < pSliceLow || slice > pSliceHigh)) | |
2509 | continue; | |
2510 | ||
2511 | if(hDeltaPi[slice]) | |
2512 | hDeltaPi[slice]->Write(); | |
2513 | if(hDeltaEl[slice]) | |
2514 | hDeltaEl[slice]->Write(); | |
2515 | if(hDeltaKa[slice]) | |
2516 | hDeltaKa[slice]->Write(); | |
2517 | if(hDeltaPr[slice]) | |
2518 | hDeltaPr[slice]->Write(); | |
2519 | ||
2520 | if (plotIdentifiedSpectra) { | |
2521 | for (Int_t species = 0; species < 5; species++) { | |
2522 | hDeltaElMC[slice][species]->Write(); | |
2523 | hDeltaKaMC[slice][species]->Write(); | |
2524 | hDeltaPiMC[slice][species]->Write(); | |
2525 | hDeltaPrMC[slice][species]->Write(); | |
2526 | } | |
2527 | } | |
2528 | } | |
2529 | ||
2530 | // File may not be closed because the projections are needed in the following! | |
2531 | //saveInterF->Close(); | |
2532 | ||
2533 | // Save some first results for the final output | |
2534 | TString saveFName = fileName; | |
2535 | saveFName = Form("%s_results_%s__%s_%d_reg%d_regFac%.2f_%s%s%s%s%s.root", saveFName.ReplaceAll(".root", "").Data(), | |
2536 | useLogLikelihood ? (useWeightsForLogLikelihood ? "weightedLLFit" : "LLFit") : "ChiSquareFit", | |
2537 | modeShortName[mode].Data(), fitMethod, regularisation, regularisationFactor, | |
2538 | muonFractionHandlingShortName[muonFractionHandlingParameter].Data(), | |
2539 | useIdentifiedGeneratedSpectra ? "_idSpectra" : "", | |
2540 | restrictCentralityAxis ? Form("_centrality%.0f_%.0f", actualLowerCentrality, actualUpperCentrality) : "", | |
2541 | restrictJetPtAxis ? Form("_jetPt%.1f_%.1f", actualLowerJetPt, actualUpperJetPt) : "", | |
2542 | chargeString.Data()); | |
2543 | TFile *saveF = TFile::Open(saveFName.Data(), "RECREATE"); | |
2544 | saveF->cd(); | |
2545 | ||
2546 | if (hFractionElectrons) | |
2547 | hFractionElectrons->Write(0, TObject::kWriteDelete); | |
2548 | ||
2549 | if (hFractionKaons) | |
2550 | hFractionKaons->Write(0, TObject::kWriteDelete); | |
2551 | ||
2552 | if (hFractionPions) | |
2553 | hFractionPions->Write(0, TObject::kWriteDelete); | |
2554 | ||
2555 | if (hFractionProtons) | |
2556 | hFractionProtons->Write(0, TObject::kWriteDelete); | |
2557 | ||
2558 | if (hFractionMuons) | |
2559 | hFractionMuons->Write(0, TObject::kWriteDelete); | |
2560 | ||
2561 | if (hFractionSummed) | |
2562 | hFractionSummed->Write(0, TObject::kWriteDelete); | |
2563 | ||
2564 | if (hFractionElectronsMC) | |
2565 | hFractionElectronsMC->Write(0, TObject::kWriteDelete); | |
2566 | ||
2567 | if (hFractionKaonsMC) | |
2568 | hFractionKaonsMC->Write(0, TObject::kWriteDelete); | |
2569 | ||
2570 | if (hFractionPionsMC) | |
2571 | hFractionPionsMC->Write(0, TObject::kWriteDelete); | |
2572 | ||
2573 | if (hFractionMuonsMC) | |
2574 | hFractionMuonsMC->Write(0, TObject::kWriteDelete); | |
2575 | ||
2576 | if (hFractionProtonsMC) | |
2577 | hFractionProtonsMC->Write(0, TObject::kWriteDelete); | |
2578 | ||
2579 | ||
2580 | if (hYieldElectrons) | |
2581 | hYieldElectrons->Write(0, TObject::kWriteDelete); | |
2582 | ||
2583 | if (hYieldKaons) | |
2584 | hYieldKaons->Write(0, TObject::kWriteDelete); | |
2585 | ||
2586 | if (hYieldPions) | |
2587 | hYieldPions->Write(0, TObject::kWriteDelete); | |
2588 | ||
2589 | if (hYieldProtons) | |
2590 | hYieldProtons->Write(0, TObject::kWriteDelete); | |
2591 | ||
2592 | if (hYieldMuons) | |
2593 | hYieldMuons->Write(0, TObject::kWriteDelete); | |
2594 | ||
2595 | if (hYieldElectronsMC) | |
2596 | hYieldElectronsMC->Write(0, TObject::kWriteDelete); | |
2597 | ||
2598 | if (hYieldMuonsMC) | |
2599 | hYieldMuonsMC->Write(0, TObject::kWriteDelete); | |
2600 | ||
2601 | if (hYieldKaonsMC) | |
2602 | hYieldKaonsMC->Write(0, TObject::kWriteDelete); | |
2603 | ||
2604 | if (hYieldPionsMC) | |
2605 | hYieldPionsMC->Write(0, TObject::kWriteDelete); | |
2606 | ||
2607 | if (hYieldProtonsMC) | |
2608 | hYieldProtonsMC->Write(0, TObject::kWriteDelete); | |
2609 | ||
2610 | if (hYieldSummedMC) | |
2611 | hYieldSummedMC->Write(0, TObject::kWriteDelete); | |
2612 | ||
2613 | ||
2614 | if (hRatioToPiElectrons) | |
2615 | hRatioToPiElectrons->Write(0, TObject::kWriteDelete); | |
2616 | ||
2617 | if (hRatioToPiMuons) | |
2618 | hRatioToPiMuons->Write(0, TObject::kWriteDelete); | |
2619 | ||
2620 | if (hRatioToPiKaons) | |
2621 | hRatioToPiKaons->Write(0, TObject::kWriteDelete); | |
2622 | ||
2623 | if (hRatioToPiProtons) | |
2624 | hRatioToPiProtons->Write(0, TObject::kWriteDelete); | |
2625 | ||
2626 | if (hRatioToPiElectronsMC) | |
2627 | hRatioToPiElectronsMC->Write(0, TObject::kWriteDelete); | |
2628 | ||
2629 | if (hRatioToPiMuonsMC) | |
2630 | hRatioToPiMuonsMC->Write(0, TObject::kWriteDelete); | |
2631 | ||
2632 | if (hRatioToPiKaonsMC) | |
2633 | hRatioToPiKaonsMC->Write(0, TObject::kWriteDelete); | |
2634 | ||
2635 | if (hRatioToPiProtonsMC) | |
2636 | hRatioToPiProtonsMC->Write(0, TObject::kWriteDelete); | |
2637 | ||
2638 | ||
2639 | // Dummy histo to create generic legend entries from | |
2640 | TH1D* hMCmuonsAndPionsDummy = 0x0; | |
2641 | if (plotIdentifiedSpectra && firstValidSlice >= 0) { | |
2642 | hMCmuonsAndPionsDummy = new TH1D(*hDeltaPiMC[firstValidSlice][kPi]); | |
2643 | hMCmuonsAndPionsDummy->SetLineColor(getLineColor(kMuPlusPi)); | |
2644 | hMCmuonsAndPionsDummy->SetMarkerColor(getLineColor(kMuPlusPi)); | |
2645 | hMCmuonsAndPionsDummy->SetName("hMCmuonsAndPionsDummy"); | |
2646 | } | |
2647 | ||
2648 | ||
2649 | muonFractionThresholdForFitting = 0.;//OLD 0.295; | |
2650 | muonFractionThresholdBinForFitting = (mode == kPMpT) ? FindMomentumBin(binsPt, muonFractionThresholdForFitting) : -1; | |
2651 | ||
2652 | electronFractionThresholdForFitting = 9.; | |
2653 | electronFractionThresholdBinForFitting = (mode == kPMpT) ? FindMomentumBin(binsPt, electronFractionThresholdForFitting) : -1; | |
2654 | ||
2655 | lastPtForCallOfGetElectronFraction = pHigh + 10.; // Make sure that this value is higher than in any call during the fit | |
2656 | ||
2657 | fElectronFraction = new TF1("fElectronFraction", Form("[0]+(x<%f)*[1]*(x-%f)", electronFractionThresholdForFitting, | |
2658 | electronFractionThresholdForFitting), | |
2659 | pLow, pHigh); | |
2660 | fElectronFraction->SetParameters(0.01, 0.0); | |
2661 | ||
2662 | ||
2663 | ||
2664 | TString speciesLabel[4] = {"El", "Ka", "Pi", "Pr" }; | |
2665 | ||
2666 | const Double_t binWidthFitHisto = 1.0; // Not used any longer | |
2667 | ||
2668 | // In case of regularisation, the actual number of x bins and the (for pT: logs of their) bin centres are required | |
2669 | Int_t numXBins = 0; | |
2670 | Double_t* xBinCentres = 0x0; | |
2671 | Double_t* xBinStatisticalWeight = 0x0; | |
2672 | Double_t* xBinStatisticalWeightError = 0x0; | |
2673 | ||
2674 | // Set the number of parameters per x bin: | |
2675 | // Regularisation only implemented for simultaneous fit. | |
2676 | const Int_t numParamsPerXbin = AliPID::kSPECIES + 1; // Fractions of each species + total yield in x bin | |
2677 | ||
2678 | // Construct the array of all the parameters that are to be regularised, i.e. only the FREE fractions | |
2679 | // and NOT the total yields or the x bin | |
2680 | Int_t nParToRegulariseSimultaneousFit = 0; | |
2681 | Int_t* indexParametersToRegularise = 0x0; | |
2682 | Int_t* lastNotFixedIndexOfParameters = 0x0; | |
2683 | ||
2684 | if (regularisation > 0) { | |
2685 | Int_t xBinIndexTemp = 0; | |
2686 | Int_t internalParIndexTemp = 0; | |
2687 | ||
2688 | // Loop twice over data: Determine the number of bins in the first iteration, allocate the memory and fill in the 2. iteration | |
2689 | for (Int_t i = 0; i < 2; i++) { | |
2690 | if (i == 1) { | |
2691 | if (numXBins == 0) { | |
2692 | printf("No bins for fitting! Exiting...\n"); | |
2693 | ||
2694 | return -1; | |
2695 | } | |
2696 | if (nParToRegulariseSimultaneousFit == 0) { | |
2697 | printf("No parameters to regularise! Exiting...\n"); | |
2698 | ||
2699 | return -1; | |
2700 | } | |
2701 | ||
2702 | xBinCentres = new Double_t[numXBins]; | |
2703 | xBinStatisticalWeight = new Double_t[numXBins]; | |
2704 | xBinStatisticalWeightError = new Double_t[numXBins]; | |
2705 | ||
2706 | indexParametersToRegularise = new Int_t[nParToRegulariseSimultaneousFit]; | |
2707 | ||
2708 | lastNotFixedIndexOfParameters = new Int_t[numParamsPerXbin]; | |
2709 | ||
2710 | // Set last not fixed index of parameter to numXBins, i.e. a index larger than any existing index. | |
2711 | // This will not restrict the parameter regularisation range. In the following, the range for electrons | |
2712 | // and muons will be restricted | |
2713 | for (Int_t iPar = 0; iPar < numParamsPerXbin; iPar++) | |
2714 | lastNotFixedIndexOfParameters[iPar] = numXBins; | |
2715 | } | |
2716 | ||
2717 | ||
2718 | for (Int_t slice = 0; (mode == kPMpT) ? slice < nPtBins : slice < hFractionPions->GetXaxis()->GetNbins(); slice++) { | |
2719 | if (mode == kPMpT && (slice < pSliceLow || slice > pSliceHigh)) | |
2720 | continue; | |
2721 | ||
2722 | // There won't (actually: shouldn't) be tracks with a pT larger than the jet pT | |
2723 | if (mode == kPMpT && restrictJetPtAxis && binsPt[slice] >= actualUpperJetPt) | |
2724 | continue; | |
2725 | ||
2726 | const Int_t pBinLowProjLimit = (mode == kPMpT) ? hYieldPt->GetXaxis()->FindBin(binsPt[slice] + 1e-5) : slice + 1; | |
2727 | const Int_t pBinUpProjLimit = (mode == kPMpT) ? hYieldPt->GetXaxis()->FindBin(binsPt[slice + 1]- 1e-5) : slice + 1; | |
2728 | ||
2729 | // NOTE: In case of regularisation, only the simultaneous fit values will be used, i.e. totalYield and not allDeltaSpecies! | |
2730 | ||
2731 | // Also take into account bin width in delta(Prime) plots -> Multiply by binWidthFitHisto | |
2732 | Double_t totalYieldError = 0; | |
2733 | const Double_t totalYield = binWidthFitHisto * hYieldPt->IntegralAndError(pBinLowProjLimit, pBinUpProjLimit, totalYieldError); | |
2734 | totalYieldError *= binWidthFitHisto; | |
2735 | ||
2736 | if (totalYield <= 0) | |
2737 | continue; | |
2738 | ||
2739 | if (i == 1) { | |
2740 | if (mode == kPMpT) | |
2741 | // Take the logarithm in case of pT | |
2742 | xBinCentres[xBinIndexTemp] = TMath::Log((binsPt[slice + 1] + binsPt[slice]) / 2.); | |
2743 | else | |
2744 | xBinCentres[xBinIndexTemp] = hFractionPions->GetXaxis()->GetBinCenter(slice + 1); | |
2745 | ||
2746 | xBinStatisticalWeight[xBinIndexTemp] = totalYield; | |
2747 | ||
2748 | // NOTE: The total yield is a fact - a number w/o error. However, one assigns this error here to use it | |
2749 | // to calculate the effective weighting for the weighted likelihood fit (and the error is only used for this). | |
2750 | // So, it is more like a weighting than an error... | |
2751 | xBinStatisticalWeightError[xBinIndexTemp] = totalYieldError; | |
2752 | ||
2753 | ||
2754 | // Mark the fractions for all species except for electrons and muons in this bin for regularisation | |
2755 | for (Int_t speciesIndex = 0; speciesIndex < AliPID::kSPECIES - 2; speciesIndex++) | |
2756 | indexParametersToRegularise[internalParIndexTemp++] = numParamsPerXbin * xBinIndexTemp + speciesIndex; | |
2757 | ||
2758 | // Also mark electrons for regularisation in this bin, if not fixed | |
2759 | if( !(mode == kPMpT && slice >= electronFractionThresholdBinForFitting) ) { | |
2760 | indexParametersToRegularise[internalParIndexTemp++] = numParamsPerXbin * xBinIndexTemp + 3; | |
2761 | } | |
2762 | else { | |
2763 | // Set the index of the last x bin in which the parameter is not fixed. | |
2764 | // If the parameter is fixed in all x bins, this index will be -1. | |
2765 | if (xBinIndexTemp - 1 < lastNotFixedIndexOfParameters[3]) | |
2766 | lastNotFixedIndexOfParameters[3] = xBinIndexTemp - 1; | |
2767 | } | |
2768 | ||
2769 | // Also mark muons for regularisation in this bin, if not fixed | |
2770 | if( !(mode != kPMpT || slice >= muonFractionThresholdBinForFitting) ) { | |
2771 | indexParametersToRegularise[internalParIndexTemp++] = numParamsPerXbin * xBinIndexTemp + 4; | |
2772 | } | |
2773 | else { | |
2774 | // Set the index of the last x bin in which the parameter is not fixed. | |
2775 | // If the parameter is fixed in all x bins, this index will be -1. | |
2776 | if (xBinIndexTemp - 1 < lastNotFixedIndexOfParameters[4]) | |
2777 | lastNotFixedIndexOfParameters[4] = xBinIndexTemp - 1; | |
2778 | } | |
2779 | ||
2780 | xBinIndexTemp++; | |
2781 | } | |
2782 | ||
2783 | if (i == 0) { | |
2784 | nParToRegulariseSimultaneousFit += AliPID::kSPECIES - 2; // Fracs for all species in this bin except for electrons and muons | |
2785 | ||
2786 | if( !(mode == kPMpT && slice >= electronFractionThresholdBinForFitting) ) | |
2787 | nParToRegulariseSimultaneousFit++; // Also regularise electrons in this bin (not fixed) | |
2788 | ||
2789 | if( !(mode != kPMpT || slice >= muonFractionThresholdBinForFitting) ) | |
2790 | nParToRegulariseSimultaneousFit++; // Also regularise muons in this bin (not fixed) | |
2791 | ||
2792 | numXBins++; | |
2793 | } | |
2794 | } | |
2795 | } | |
2796 | } | |
2797 | AliTPCPIDmathFit* mathFit = 0x0; | |
2798 | ||
2799 | if (regularisation > 0) { | |
2800 | mathFit = (fitMethod == 2) ? AliTPCPIDmathFit::Instance(numXBins, 4, 1810) | |
2801 | : AliTPCPIDmathFit::Instance(numXBins, 1, 1810); | |
2802 | } | |
2803 | else { | |
2804 | mathFit = (fitMethod == 2) ? AliTPCPIDmathFit::Instance(1, 4, 1810) | |
2805 | : AliTPCPIDmathFit::Instance(1, 1, 1810); | |
2806 | } | |
2807 | ||
2808 | mathFit->SetDebugLevel(0); | |
2809 | mathFit->SetEpsilon(5e-05); | |
2810 | mathFit->SetMaxCalls(1e8); | |
2811 | ||
2812 | mathFit->SetMinimisationStrategy(minimisationStrategy); | |
2813 | ||
2814 | mathFit->SetUseLogLikelihood(useLogLikelihood); | |
2815 | mathFit->SetUseWeightsForLogLikelihood(useWeightsForLogLikelihood); | |
2816 | ||
2817 | if (fitMethod == 2) { | |
2818 | // If the deltaPrime range is large enough, we artificially get a factor 4 in statistics by looking at the four | |
2819 | // different deltaPrimeSpecies, which have (except for binning effects) the same information. | |
2820 | // Therefore, to get the "real" statistical error, we need to multiply the obtained error by sqrt(4) = 2 | |
2821 | mathFit->SetScaleFactorError(2.); | |
2822 | } | |
2823 | ||
2824 | mathFit->SetRegularisation(regularisation, regularisationFactor); | |
2825 | ||
2826 | // Number of parameters for fitting | |
2827 | const Int_t nPar = 11; | |
2828 | ||
2829 | // Fracs of each species + total yield in x bin | |
2830 | const Int_t nParSimultaneousFit = AliPID::kSPECIES + 1; | |
2831 | ||
2832 | // Fracs of each species in x bin + tot yield in x bin | |
2833 | const Int_t nParSimultaneousFitRegularised = numXBins * (AliPID::kSPECIES + 1); | |
2834 | ||
2835 | if (regularisation > 0) { | |
2836 | if (!mathFit->SetParametersToRegularise(nParToRegulariseSimultaneousFit, numParamsPerXbin, indexParametersToRegularise, | |
2837 | lastNotFixedIndexOfParameters, xBinCentres, xBinStatisticalWeight, | |
2838 | xBinStatisticalWeightError)) | |
2839 | return -1; | |
2840 | } | |
2841 | ||
2842 | delete xBinCentres; | |
2843 | xBinCentres = 0x0; | |
2844 | ||
2845 | delete xBinStatisticalWeight; | |
2846 | xBinStatisticalWeight = 0x0; | |
2847 | ||
2848 | delete xBinStatisticalWeightError; | |
2849 | xBinStatisticalWeight = 0x0; | |
2850 | ||
2851 | delete indexParametersToRegularise; | |
2852 | indexParametersToRegularise = 0x0; | |
2853 | ||
2854 | delete lastNotFixedIndexOfParameters; | |
2855 | lastNotFixedIndexOfParameters = 0x0; | |
2856 | ||
2857 | ||
2858 | ||
2859 | gFractionElectronsData = new TGraphErrors(numXBins); | |
2860 | ||
2861 | // Fit each slice with sum of 4/5 shapes with means and sigmas fixed from last fitting step | |
2862 | // For electrons: Fit up to certain pT bin and use constant value for higher momenta | |
2863 | ||
2864 | // Two iterations required for regularisation | |
2865 | Bool_t regularisedFitDone = kFALSE; | |
2866 | Double_t reducedChiSquareRegularisation = -1; | |
2867 | ||
2868 | Double_t gausParamsSimultaneousFitRegularised[nParSimultaneousFitRegularised]; | |
2869 | Double_t parameterErrorsOutRegularised[nParSimultaneousFitRegularised]; | |
2870 | Double_t lowParLimitsSimultaneousFitRegularised[nParSimultaneousFitRegularised]; | |
2871 | Double_t upParLimitsSimultaneousFitRegularised[nParSimultaneousFitRegularised]; | |
2872 | Double_t stepSizeSimultaneousFitRegularised[nParSimultaneousFitRegularised]; | |
2873 | ||
2874 | for (Int_t i = 0; i < nParSimultaneousFitRegularised; i++) { | |
2875 | gausParamsSimultaneousFitRegularised[i] = 0; | |
2876 | parameterErrorsOutRegularised[i] = 0; | |
2877 | lowParLimitsSimultaneousFitRegularised[i] = 0; | |
2878 | upParLimitsSimultaneousFitRegularised[i] = 0; | |
2879 | stepSizeSimultaneousFitRegularised[i] = 0; | |
2880 | } | |
2881 | ||
2882 | mathFit->ClearRefHistos(); | |
2883 | ||
2884 | ||
2885 | const Int_t nParUsed = (fitMethod == 2) ? ((regularisation <= 0) ? nParSimultaneousFit: nParSimultaneousFitRegularised) : nPar; | |
2886 | Double_t parameterErrorsOut[nParUsed]; | |
2887 | Double_t covMatrix[nParUsed][nParUsed]; | |
2888 | ||
2889 | for (Int_t iter = 0; iter < 2; iter++) { | |
2890 | if (regularisation <= 0 && iter == 0) | |
2891 | continue; // Only one iteration w/o regularisation | |
2892 | ||
2893 | Int_t currXbin = 0; | |
2894 | ||
2895 | for (Int_t slice = 0; (mode == kPMpT) ? slice < nPtBins : slice < hFractionPions->GetXaxis()->GetNbins(); slice++) { | |
2896 | if (mode == kPMpT && (slice < pSliceLow || slice > pSliceHigh)) | |
2897 | continue; | |
2898 | ||
2899 | // There won't (actually: shouldn't) be tracks with a pT larger than the jet pT | |
2900 | if (mode == kPMpT && restrictJetPtAxis && binsPt[slice] >= actualUpperJetPt) | |
2901 | continue; | |
2902 | ||
2903 | if (regularisation <= 0) { | |
2904 | if (mode == kPMpT) | |
2905 | std::cout << "Fitting range " << binsPt[slice] << " GeV/c < Pt < " << binsPt[slice + 1] << " GeV/c..." << std::endl; | |
2906 | else { | |
2907 | std::cout << "Fitting range " << hFractionPions->GetXaxis()->GetBinLowEdge(slice + 1) << " < " << modeShortName[mode].Data() << " < "; | |
2908 | std::cout << hFractionPions->GetXaxis()->GetBinUpEdge(slice + 1) << "..." << std::endl; | |
2909 | } | |
2910 | } | |
2911 | ||
2912 | // Add/subtract some very small offset to be sure not to sit on the bin boundary, when looking for the integration/projection limits. | |
2913 | const Int_t pBinLowProjLimit = (mode == kPMpT) ? hYieldPt->GetXaxis()->FindBin(binsPt[slice] + 1e-5) : slice + 1; | |
2914 | const Int_t pBinUpProjLimit = (mode == kPMpT) ? hYieldPt->GetXaxis()->FindBin(binsPt[slice + 1]- 1e-5) : slice + 1; | |
2915 | ||
2916 | // Also take into account bin width in delta(Prime) plots -> Multiply by binWidthFitHisto | |
2917 | const Double_t totalYield = binWidthFitHisto * hYieldPt->Integral(pBinLowProjLimit, pBinUpProjLimit); | |
2918 | ||
2919 | if (totalYield <= 0) { | |
2920 | std::cout << "Skipped bin (yield is zero)!" << std::endl; | |
2921 | continue; | |
2922 | } | |
2923 | ||
2924 | const Double_t allDeltaPion = hDeltaPi[slice]->Integral(); | |
2925 | const Double_t allDeltaElectron = hDeltaEl[slice]->Integral(); | |
2926 | const Double_t allDeltaKaon = hDeltaKa[slice]->Integral(); | |
2927 | const Double_t allDeltaProton = hDeltaPr[slice]->Integral(); | |
2928 | ||
2929 | // inverseBinWidth = 1.0, if the raw yield for each bin is requested. | |
2930 | // If divided by the bin size, the histograms give "yield per unit pT in the corresponding bin" or dN/dpT | |
2931 | Double_t inverseBinWidth = (mode == kPMpT) ? 1.0 / (binsPt[slice + 1] - binsPt[slice]) | |
2932 | : 1.0 / hYieldPt->GetBinWidth(slice + 1); | |
2933 | ||
2934 | TH1D *hGenDeltaElForElProj = 0x0, *hGenDeltaKaForElProj = 0x0, *hGenDeltaPiForElProj = 0x0, *hGenDeltaPrForElProj = 0x0; | |
2935 | TH1D *hGenDeltaElForKaProj = 0x0, *hGenDeltaKaForKaProj = 0x0, *hGenDeltaPiForKaProj = 0x0, *hGenDeltaPrForKaProj = 0x0; | |
2936 | TH1D *hGenDeltaElForPiProj = 0x0, *hGenDeltaKaForPiProj = 0x0, *hGenDeltaPiForPiProj = 0x0, *hGenDeltaPrForPiProj = 0x0; | |
2937 | TH1D *hGenDeltaElForMuProj = 0x0, *hGenDeltaKaForMuProj = 0x0, *hGenDeltaPiForMuProj = 0x0, *hGenDeltaPrForMuProj = 0x0; | |
2938 | TH1D *hGenDeltaElForPrProj = 0x0, *hGenDeltaKaForPrProj = 0x0, *hGenDeltaPiForPrProj = 0x0, *hGenDeltaPrForPrProj = 0x0; | |
2939 | ||
2940 | TH2D* hGenDeltaUsed[6][6]; | |
2941 | if (useIdentifiedGeneratedSpectra) { | |
2942 | for (Int_t i = 0; i < 6; i++) { | |
2943 | for (Int_t j = 0; j < 6; j++) { | |
2944 | hGenDeltaUsed[i][j] = hGenDeltaMCid[i][j]; | |
2945 | } | |
2946 | } | |
2947 | } | |
2948 | else { | |
2949 | for (Int_t i = 0; i < 6; i++) { | |
2950 | for (Int_t j = 0; j < 6; j++) { | |
2951 | hGenDeltaUsed[i][j] = hGenDelta[i][j]; | |
2952 | } | |
2953 | } | |
2954 | } | |
2955 | ||
2956 | hGenDeltaElForElProj =(TH1D*)hGenDeltaUsed[kEl][kEl]->ProjectionY(Form("hGenDeltaElForElProj%d", slice), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
2957 | hGenDeltaKaForElProj =(TH1D*)hGenDeltaUsed[kKa][kEl]->ProjectionY(Form("hGenDeltaKaForElProj%d", slice), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
2958 | hGenDeltaPiForElProj =(TH1D*)hGenDeltaUsed[kPi][kEl]->ProjectionY(Form("hGenDeltaPiForElProj%d", slice), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
2959 | hGenDeltaPrForElProj =(TH1D*)hGenDeltaUsed[kPr][kEl]->ProjectionY(Form("hGenDeltaPrForElProj%d", slice), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
2960 | ||
2961 | hGenDeltaElForKaProj =(TH1D*)hGenDeltaUsed[kEl][kKa]->ProjectionY(Form("hGenDeltaElForKaProj%d", slice), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
2962 | hGenDeltaKaForKaProj =(TH1D*)hGenDeltaUsed[kKa][kKa]->ProjectionY(Form("hGenDeltaKaForKaProj%d", slice), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
2963 | hGenDeltaPiForKaProj =(TH1D*)hGenDeltaUsed[kPi][kKa]->ProjectionY(Form("hGenDeltaPiForKaProj%d", slice), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
2964 | hGenDeltaPrForKaProj =(TH1D*)hGenDeltaUsed[kPr][kKa]->ProjectionY(Form("hGenDeltaPrForKaProj%d", slice), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
2965 | ||
2966 | hGenDeltaElForPiProj =(TH1D*)hGenDeltaUsed[kEl][kPi]->ProjectionY(Form("hGenDeltaElForPiProj%d", slice), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
2967 | hGenDeltaKaForPiProj =(TH1D*)hGenDeltaUsed[kKa][kPi]->ProjectionY(Form("hGenDeltaKaForPiProj%d", slice), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
2968 | hGenDeltaPiForPiProj =(TH1D*)hGenDeltaUsed[kPi][kPi]->ProjectionY(Form("hGenDeltaPiForPiProj%d", slice), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
2969 | hGenDeltaPrForPiProj =(TH1D*)hGenDeltaUsed[kPr][kPi]->ProjectionY(Form("hGenDeltaPrForPiProj%d", slice), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
2970 | ||
2971 | if (takeIntoAccountMuons) { | |
2972 | hGenDeltaElForMuProj =(TH1D*)hGenDeltaUsed[kEl][kMu]->ProjectionY(Form("hGenDeltaElForMuProj%d", slice), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
2973 | hGenDeltaKaForMuProj =(TH1D*)hGenDeltaUsed[kKa][kMu]->ProjectionY(Form("hGenDeltaKaForMuProj%d", slice), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
2974 | hGenDeltaPiForMuProj =(TH1D*)hGenDeltaUsed[kPi][kMu]->ProjectionY(Form("hGenDeltaPiForMuProj%d", slice), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
2975 | hGenDeltaPrForMuProj =(TH1D*)hGenDeltaUsed[kPr][kMu]->ProjectionY(Form("hGenDeltaPrForMuProj%d", slice), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
2976 | } | |
2977 | ||
2978 | hGenDeltaElForPrProj =(TH1D*)hGenDeltaUsed[kEl][kPr]->ProjectionY(Form("hGenDeltaElForPrProj%d", slice), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
2979 | hGenDeltaKaForPrProj =(TH1D*)hGenDeltaUsed[kKa][kPr]->ProjectionY(Form("hGenDeltaKaForPrProj%d", slice), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
2980 | hGenDeltaPiForPrProj =(TH1D*)hGenDeltaUsed[kPi][kPr]->ProjectionY(Form("hGenDeltaPiForPrProj%d", slice), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
2981 | hGenDeltaPrForPrProj =(TH1D*)hGenDeltaUsed[kPr][kPr]->ProjectionY(Form("hGenDeltaPrForPrProj%d", slice), pBinLowProjLimit, pBinUpProjLimit, "e"); | |
2982 | ||
2983 | ||
2984 | ||
2985 | if (fitMethod == 2) { | |
2986 | // Normalise generated histos to TOTAL number of GENERATED particles for this species (i.e. including | |
2987 | // entries that lie in the under or overflow bin), so that situations in which the generated spectra lie | |
2988 | // at least partly outside the histo are treated properly. To find the total number of generated particle | |
2989 | // species X, one can just take the integral of the generated histo for DeltaX (which should include all | |
2990 | // generated entries) and apply the same normalisation factor to all other DeltaSpecies. | |
2991 | // Also set some cosmetics | |
2992 | ||
2993 | // Generated electrons | |
2994 | Double_t normEl = normaliseHist(hGenDeltaElForElProj, -1); | |
2995 | normaliseHist(hGenDeltaKaForElProj, normEl); | |
2996 | normaliseHist(hGenDeltaPiForElProj, normEl); | |
2997 | normaliseHist(hGenDeltaPrForElProj, normEl); | |
2998 | ||
2999 | ||
3000 | // Generated kaons | |
3001 | Double_t normKa = normaliseHist(hGenDeltaKaForKaProj, -1); | |
3002 | normaliseHist(hGenDeltaElForKaProj, normKa); | |
3003 | normaliseHist(hGenDeltaPiForKaProj, normKa); | |
3004 | normaliseHist(hGenDeltaPrForKaProj, normKa); | |
3005 | ||
3006 | ||
3007 | // Generated pions | |
3008 | Double_t normPi = normaliseHist(hGenDeltaPiForPiProj, -1); | |
3009 | normaliseHist(hGenDeltaElForPiProj, normPi); | |
3010 | normaliseHist(hGenDeltaKaForPiProj, normPi); | |
3011 | normaliseHist(hGenDeltaPrForPiProj, normPi); | |
3012 | ||
3013 | ||
3014 | Double_t normMu = 1; | |
3015 | if (takeIntoAccountMuons) { | |
3016 | // Generated pions | |
3017 | // Since masses of muons and pions are so similar, the normalisation scheme should still work when looking at deltaPion instead | |
3018 | normMu = normaliseHist(hGenDeltaPiForMuProj, -1); | |
3019 | normaliseHist(hGenDeltaElForMuProj, normMu); | |
3020 | normaliseHist(hGenDeltaKaForMuProj, normMu); | |
3021 | normaliseHist(hGenDeltaPrForMuProj, normMu); | |
3022 | } | |
3023 | ||
3024 | ||
3025 | // Generated protons | |
3026 | Double_t normPr = normaliseHist(hGenDeltaPrForPrProj, -1); | |
3027 | normaliseHist(hGenDeltaElForPrProj, normPr); | |
3028 | normaliseHist(hGenDeltaKaForPrProj, normPr); | |
3029 | normaliseHist(hGenDeltaPiForPrProj, normPr); | |
3030 | } | |
3031 | else { | |
3032 | // Normalise generated histos to total number of particles for this delta | |
3033 | // and also set some cosmetics | |
3034 | ||
3035 | // DeltaEl | |
3036 | normaliseHist(hGenDeltaElForElProj); | |
3037 | normaliseHist(hGenDeltaElForKaProj); | |
3038 | normaliseHist(hGenDeltaElForPiProj); | |
3039 | if (takeIntoAccountMuons) | |
3040 | normaliseHist(hGenDeltaElForMuProj); | |
3041 | normaliseHist(hGenDeltaElForPrProj); | |
3042 | ||
3043 | // DeltaKa | |
3044 | normaliseHist(hGenDeltaKaForElProj); | |
3045 | normaliseHist(hGenDeltaKaForKaProj); | |
3046 | normaliseHist(hGenDeltaKaForPiProj); | |
3047 | if (takeIntoAccountMuons) | |
3048 | normaliseHist(hGenDeltaKaForMuProj); | |
3049 | normaliseHist(hGenDeltaKaForPrProj); | |
3050 | ||
3051 | // DeltaPi | |
3052 | normaliseHist(hGenDeltaPiForElProj); | |
3053 | normaliseHist(hGenDeltaPiForKaProj); | |
3054 | normaliseHist(hGenDeltaPiForPiProj); | |
3055 | if (takeIntoAccountMuons) | |
3056 | normaliseHist(hGenDeltaPiForMuProj); | |
3057 | normaliseHist(hGenDeltaPiForPrProj); | |
3058 | ||
3059 | // DeltaPr | |
3060 | normaliseHist(hGenDeltaPrForElProj); | |
3061 | normaliseHist(hGenDeltaPrForKaProj); | |
3062 | normaliseHist(hGenDeltaPrForPiProj); | |
3063 | if (takeIntoAccountMuons) | |
3064 | normaliseHist(hGenDeltaPrForMuProj); | |
3065 | normaliseHist(hGenDeltaPrForPrProj); | |
3066 | } | |
3067 | ||
3068 | ||
3069 | TF1* totalDeltaPion = 0x0; | |
3070 | TF1* totalDeltaKaon = 0x0; | |
3071 | TF1* totalDeltaProton = 0x0; | |
3072 | TF1* totalDeltaElectron = 0x0; | |
3073 | ||
3074 | TLegend* legend = 0x0; | |
3075 | ||
3076 | if (iter == 1) { // Only needed for second iteration (= the only iteration w/o regularisation) | |
3077 | // The number of parameters and their values will always be adjusted, such that using nPar parameters is fine | |
3078 | totalDeltaPion = new TF1(Form("totalDeltaPion_slice%d", slice), (fitMethod == 2) ? multiGaussFitDeltaPi : multiGaussFit, | |
3079 | xLow, xUp, nPar); | |
3080 | setUpFitFunction(totalDeltaPion, nBins); | |
3081 | ||
3082 | totalDeltaKaon = new TF1(Form("totalDeltaKaon_slice%d", slice), (fitMethod == 2) ? multiGaussFitDeltaKa : multiGaussFit, | |
3083 | xLow, xUp, nPar); | |
3084 | setUpFitFunction(totalDeltaKaon, nBins); | |
3085 | ||
3086 | totalDeltaProton = new TF1(Form("totalDeltaProton_slice%d", slice), (fitMethod == 2) ? multiGaussFitDeltaPr : multiGaussFit, | |
3087 | xLow, xUp, nPar); | |
3088 | setUpFitFunction(totalDeltaProton, nBins); | |
3089 | ||
3090 | totalDeltaElectron = new TF1(Form("totalDeltaElectron_slice%d", slice), | |
3091 | (fitMethod == 2) ? multiGaussFitDeltaEl : multiGaussFit, | |
3092 | xLow, xUp, nPar); | |
3093 | setUpFitFunction(totalDeltaElectron, nBins); | |
3094 | ||
3095 | // Legend is the same for all \Delta "species" plots | |
3096 | legend = new TLegend(0.722126, 0.605932, 0.962069, 0.925932); | |
3097 | legend->SetBorderSize(0); | |
3098 | legend->SetFillColor(0); | |
3099 | if (plotIdentifiedSpectra) | |
3100 | legend->SetNColumns(2); | |
3101 | legend->AddEntry((TObject*)0x0, "Fit", ""); | |
3102 | if (plotIdentifiedSpectra) | |
3103 | legend->AddEntry((TObject*)0x0, identifiedLabels[isMC].Data(), ""); | |
3104 | ||
3105 | legend->AddEntry(hDeltaPi[slice], "Data", "Lp"); | |
3106 | if (plotIdentifiedSpectra) | |
3107 | legend->AddEntry((TObject*)0x0, "", ""); | |
3108 | ||
3109 | legend->AddEntry(totalDeltaPion, "Multi-template fit", "L"); | |
3110 | if (plotIdentifiedSpectra) | |
3111 | legend->AddEntry(hMCmuonsAndPionsDummy, "#mu + #pi", "Lp"); | |
3112 | ||
3113 | if (takeIntoAccountMuons) | |
3114 | legend->AddEntry(hGenDeltaPiForMuProj, "#mu", "Lp"); | |
3115 | else if (plotIdentifiedSpectra) | |
3116 | legend->AddEntry((TObject*)0x0, "", ""); | |
3117 | if (plotIdentifiedSpectra) | |
3118 | legend->AddEntry(hDeltaPiMC[slice][kMu - 1], "#mu", "Lp"); | |
3119 | ||
3120 | legend->AddEntry(hGenDeltaPiForPiProj, takeIntoAccountMuons ? "#pi" : "#pi + #mu", "Lp"); | |
3121 | if (plotIdentifiedSpectra) | |
3122 | legend->AddEntry(hDeltaPiMC[slice][kPi - 1], "#pi", "Lp"); | |
3123 | ||
3124 | legend->AddEntry(hGenDeltaPiForKaProj, "K", "Lp"); | |
3125 | if (plotIdentifiedSpectra) | |
3126 | legend->AddEntry(hDeltaPiMC[slice][kKa - 1], "K", "Lp"); | |
3127 | ||
3128 | legend->AddEntry(hGenDeltaPiForPrProj, "p", "Lp"); | |
3129 | if (plotIdentifiedSpectra) | |
3130 | legend->AddEntry(hDeltaPiMC[slice][kPr - 1], "p", "Lp"); | |
3131 | ||
3132 | legend->AddEntry(hGenDeltaPiForElProj, "e", "Lp"); | |
3133 | if (plotIdentifiedSpectra) | |
3134 | legend->AddEntry(hDeltaPiMC[slice][kEl -1], "e", "Lp"); | |
3135 | } | |
3136 | ||
3137 | ||
3138 | // Allow tolerance of +-2% (for delta -> assume dEdx = 80 and take +-2%) | |
3139 | //const Double_t peakTolerance = (useDeltaPrime ? 0.8 : 1.0) / hGenDeltaElForElProj->GetXaxis()->GetBinWidth(1); | |
3140 | //const Double_t shiftStepSize = 0.01; | |
3141 | const Double_t peakTolerance = (useDeltaPrime ? 0.02 : 1.6); | |
3142 | const Double_t shiftStepSize = 0.01; | |
3143 | ||
3144 | // Assume fractions vs. pT to be smooth. Allow 1 sigma variations from bin to bin. For small pT, the error will be very small. | |
3145 | // Therefore, allow at least a change of some percent. | |
3146 | const Double_t nSigma = 1.; | |
3147 | const Double_t minChange = 1.0; // This disables the sigma restriction | |
3148 | ||
3149 | Double_t fractionPions = (muonContamination ? 0.87 : 0.88); | |
3150 | ||
3151 | Double_t fractionErrorUpPions = 1.; | |
3152 | Double_t fractionErrorLowPions = 0.; | |
3153 | ||
3154 | Int_t xBinInit = 0; | |
3155 | if (initialiseWithFractionsFromFile) { | |
3156 | Double_t xBinCentre = (mode == kPMpT) ? (binsPt[slice + 1] + binsPt[slice]) / 2. | |
3157 | : hYieldPt->GetXaxis()->GetBinCenter(slice + 1); | |
3158 | xBinInit = hInitFracPi->GetXaxis()->FindBin(xBinCentre); | |
3159 | fractionPions = hInitFracPi->GetBinContent(xBinInit) + (muonContamination ? hInitFracMu->GetBinContent(xBinInit) : 0.); | |
3160 | } | |
3161 | else { | |
3162 | // Set found fraction from last slice, if available. Note: Current bin for slice = slice + 1 | |
3163 | // => Bin for last slice = slice | |
3164 | if (hFractionPions->GetBinContent(slice) > 0 && hFractionPions->GetBinError(slice) > 0) { | |
3165 | fractionPions = hFractionPions->GetBinContent(slice); | |
3166 | fractionErrorUpPions = TMath::Min(1.0, fractionPions + TMath::Max(minChange, nSigma * hFractionPions->GetBinError(slice))); | |
3167 | fractionErrorLowPions = TMath::Max(0.0, fractionPions - TMath::Max(minChange, nSigma * hFractionPions->GetBinError(slice))); | |
3168 | } | |
3169 | } | |
3170 | ||
3171 | Double_t fractionKaons = 0.08; | |
3172 | Double_t fractionErrorUpKaons = 1.; | |
3173 | Double_t fractionErrorLowKaons = 0.; | |
3174 | ||
3175 | if (initialiseWithFractionsFromFile) { | |
3176 | fractionKaons = hInitFracKa->GetBinContent(xBinInit); | |
3177 | } | |
3178 | else { | |
3179 | if (hFractionKaons->GetBinContent(slice) > 0 && hFractionKaons->GetBinError(slice) > 0) { | |
3180 | fractionKaons = hFractionKaons->GetBinContent(slice); | |
3181 | fractionErrorUpKaons = TMath::Min(1.0, fractionKaons + TMath::Max(minChange, nSigma * hFractionKaons->GetBinError(slice))); | |
3182 | fractionErrorLowKaons = TMath::Max(0.0, fractionKaons - TMath::Max(minChange, nSigma * hFractionKaons->GetBinError(slice))); | |
3183 | } | |
3184 | } | |
3185 | ||
3186 | Double_t fractionProtons = 0.02; | |
3187 | Double_t fractionErrorUpProtons = 1.; | |
3188 | Double_t fractionErrorLowProtons = 0.; | |
3189 | ||
3190 | if (initialiseWithFractionsFromFile) { | |
3191 | fractionProtons = hInitFracPr->GetBinContent(xBinInit); | |
3192 | } | |
3193 | else { | |
3194 | if (hFractionProtons->GetBinContent(slice) > 0 && hFractionProtons->GetBinError(slice) > 0) { | |
3195 | fractionProtons = hFractionProtons->GetBinContent(slice); | |
3196 | fractionErrorUpProtons = TMath::Min(1.0, fractionProtons + | |
3197 | TMath::Max(minChange, nSigma * hFractionProtons->GetBinError(slice))); | |
3198 | fractionErrorLowProtons = TMath::Max(0.0, fractionProtons - | |
3199 | TMath::Max(minChange, nSigma * hFractionProtons->GetBinError(slice))); | |
3200 | } | |
3201 | } | |
3202 | ||
3203 | Double_t fractionElectrons = (takeIntoAccountMuons ? 0.01 : 0.02); | |
3204 | Double_t fractionErrorUpElectrons = 1.; | |
3205 | Double_t fractionErrorLowElectrons = 0.; | |
3206 | ||
3207 | if (initialiseWithFractionsFromFile) { | |
3208 | fractionElectrons = hInitFracEl->GetBinContent(xBinInit); | |
3209 | } | |
3210 | else { | |
3211 | if (hFractionElectrons->GetBinContent(slice) > 0 && hFractionElectrons->GetBinError(slice) > 0) { | |
3212 | fractionElectrons = hFractionElectrons->GetBinContent(slice); | |
3213 | fractionErrorUpElectrons = TMath::Min(1.0, fractionElectrons + | |
3214 | TMath::Max(minChange, nSigma * hFractionElectrons->GetBinError(slice))); | |
3215 | fractionErrorLowElectrons = TMath::Max(0.0, fractionElectrons - | |
3216 | TMath::Max(minChange, nSigma * hFractionElectrons->GetBinError(slice))); | |
3217 | } | |
3218 | } | |
3219 | ||
3220 | Double_t fractionMuons = (takeIntoAccountMuons ? 0.01 : 0.); | |
3221 | Double_t fractionErrorUpMuons = 1.; | |
3222 | Double_t fractionErrorLowMuons = 0.; | |
3223 | if (!takeIntoAccountMuons) { | |
3224 | fractionErrorUpMuons = 0.; | |
3225 | fractionErrorLowMuons = 0.; | |
3226 | } | |
3227 | else { | |
3228 | if (initialiseWithFractionsFromFile) { | |
3229 | fractionMuons = hInitFracMu->GetBinContent(xBinInit); | |
3230 | } | |
3231 | else { | |
3232 | if (hFractionMuons->GetBinContent(slice) > 0 && hFractionMuons->GetBinError(slice) > 0) { | |
3233 | fractionMuons = hFractionMuons->GetBinContent(slice); | |
3234 | fractionErrorUpMuons = TMath::Min(1.0, fractionMuons + TMath::Max(minChange, nSigma * hFractionMuons->GetBinError(slice))); | |
3235 | fractionErrorLowMuons = TMath::Max(0.0, fractionMuons - TMath::Max(minChange, nSigma * hFractionMuons->GetBinError(slice))); | |
3236 | } | |
3237 | } | |
3238 | } | |
3239 | ||
3240 | Double_t gausParamsPi[nPar] = { | |
3241 | fractionPions, | |
3242 | fractionKaons, | |
3243 | fractionProtons, | |
3244 | fractionElectrons, | |
3245 | fractionMuons, | |
3246 | allDeltaPion, | |
3247 | 0, | |
3248 | 0, | |
3249 | 0, | |
3250 | 0, | |
3251 | 0 | |
3252 | }; | |
3253 | ||
3254 | Double_t gausParamsEl[nPar] = { | |
3255 | fractionPions, | |
3256 | fractionKaons, | |
3257 | fractionProtons, | |
3258 | fractionElectrons, | |
3259 | fractionMuons, | |
3260 | allDeltaElectron, | |
3261 | 0, | |
3262 | 0, | |
3263 | 0, | |
3264 | 0, | |
3265 | 0 | |
3266 | }; | |
3267 | ||
3268 | Double_t gausParamsKa[nPar] = { | |
3269 | fractionPions, | |
3270 | fractionKaons, | |
3271 | fractionProtons, | |
3272 | fractionElectrons, | |
3273 | fractionMuons, | |
3274 | allDeltaKaon, | |
3275 | 0, | |
3276 | 0, | |
3277 | 0, | |
3278 | 0, | |
3279 | 0 | |
3280 | }; | |
3281 | ||
3282 | Double_t gausParamsPr[nPar] = { | |
3283 | fractionPions, | |
3284 | fractionKaons, | |
3285 | fractionProtons, | |
3286 | fractionElectrons, | |
3287 | fractionMuons, | |
3288 | allDeltaProton, | |
3289 | 0, | |
3290 | 0, | |
3291 | 0, | |
3292 | 0, | |
3293 | 0 | |
3294 | }; | |
3295 | ||
3296 | Double_t lowParLimitsPi[nPar] = { | |
3297 | fractionErrorLowPions, | |
3298 | fractionErrorLowKaons, | |
3299 | fractionErrorLowProtons, | |
3300 | fractionErrorLowElectrons, | |
3301 | fractionErrorLowMuons, | |
3302 | allDeltaPion, | |
3303 | -peakTolerance, | |
3304 | -peakTolerance, | |
3305 | -peakTolerance, | |
3306 | -peakTolerance, | |
3307 | -peakTolerance | |
3308 | }; | |
3309 | ||
3310 | Double_t lowParLimitsEl[nPar] = { | |
3311 | fractionErrorLowPions, | |
3312 | fractionErrorLowKaons, | |
3313 | fractionErrorLowProtons, | |
3314 | fractionErrorLowElectrons, | |
3315 | fractionErrorLowMuons, | |
3316 | allDeltaElectron, | |
3317 | -peakTolerance, | |
3318 | -peakTolerance, | |
3319 | -peakTolerance, | |
3320 | -peakTolerance, | |
3321 | -peakTolerance | |
3322 | }; | |
3323 | ||
3324 | Double_t lowParLimitsKa[nPar] = { | |
3325 | fractionErrorLowPions, | |
3326 | fractionErrorLowKaons, | |
3327 | fractionErrorLowProtons, | |
3328 | fractionErrorLowElectrons, | |
3329 | fractionErrorLowMuons, | |
3330 | allDeltaKaon, | |
3331 | -peakTolerance, | |
3332 | -peakTolerance, | |
3333 | -peakTolerance, | |
3334 | -peakTolerance, | |
3335 | -peakTolerance | |
3336 | }; | |
3337 | ||
3338 | Double_t lowParLimitsPr[nPar] = { | |
3339 | fractionErrorLowPions, | |
3340 | fractionErrorLowKaons, | |
3341 | fractionErrorLowProtons, | |
3342 | fractionErrorLowElectrons, | |
3343 | fractionErrorLowMuons, | |
3344 | allDeltaProton, | |
3345 | -peakTolerance, | |
3346 | -peakTolerance, | |
3347 | -peakTolerance, | |
3348 | -peakTolerance | |
3349 | -peakTolerance | |
3350 | }; | |
3351 | ||
3352 | ||
3353 | Double_t upParLimitsPi[nPar] = { | |
3354 | fractionErrorUpPions, | |
3355 | fractionErrorUpKaons, | |
3356 | fractionErrorUpProtons, | |
3357 | fractionErrorUpElectrons, | |
3358 | fractionErrorUpMuons, | |
3359 | allDeltaPion, | |
3360 | peakTolerance, | |
3361 | peakTolerance, | |
3362 | peakTolerance, | |
3363 | peakTolerance, | |
3364 | peakTolerance | |
3365 | }; | |
3366 | ||
3367 | Double_t upParLimitsEl[nPar] = { | |
3368 | fractionErrorUpPions, | |
3369 | fractionErrorUpKaons, | |
3370 | fractionErrorUpProtons, | |
3371 | fractionErrorUpElectrons, | |
3372 | fractionErrorUpMuons, | |
3373 | allDeltaElectron, | |
3374 | peakTolerance, | |
3375 | peakTolerance, | |
3376 | peakTolerance, | |
3377 | peakTolerance, | |
3378 | peakTolerance | |
3379 | }; | |
3380 | ||
3381 | Double_t upParLimitsKa[nPar] = { | |
3382 | fractionErrorUpPions, | |
3383 | fractionErrorUpKaons, | |
3384 | fractionErrorUpProtons, | |
3385 | fractionErrorUpElectrons, | |
3386 | fractionErrorUpMuons, | |
3387 | allDeltaKaon, | |
3388 | peakTolerance, | |
3389 | peakTolerance, | |
3390 | peakTolerance, | |
3391 | peakTolerance, | |
3392 | peakTolerance | |
3393 | }; | |
3394 | ||
3395 | Double_t upParLimitsPr[nPar] = { | |
3396 | fractionErrorUpPions, | |
3397 | fractionErrorUpKaons, | |
3398 | fractionErrorUpProtons, | |
3399 | fractionErrorUpElectrons, | |
3400 | fractionErrorUpMuons, | |
3401 | allDeltaProton, | |
3402 | peakTolerance, | |
3403 | peakTolerance, | |
3404 | peakTolerance, | |
3405 | peakTolerance, | |
3406 | peakTolerance, | |
3407 | }; | |
3408 | ||
3409 | Double_t stepSize[nPar] = { | |
3410 | 0.1, | |
3411 | 0.1, | |
3412 | 0.1, | |
3413 | 0.1, | |
3414 | (takeIntoAccountMuons ? 0.1 : 0.), | |
3415 | ||
3416 | 0.0, | |
3417 | ||
3418 | enableShift ? shiftStepSize : 0., | |
3419 | enableShift ? shiftStepSize : 0., | |
3420 | enableShift ? shiftStepSize : 0., | |
3421 | enableShift ? shiftStepSize : 0., | |
3422 | (enableShift && takeIntoAccountMuons) ? shiftStepSize : 0. | |
3423 | }; | |
3424 | ||
3425 | ||
3426 | Double_t gausParamsSimultaneousFit[nParSimultaneousFit] = { | |
3427 | fractionPions, | |
3428 | fractionKaons, | |
3429 | fractionProtons, | |
3430 | fractionElectrons, | |
3431 | fractionMuons, | |
3432 | totalYield | |
3433 | // No shifts because they do not make too much sense (different eta + possible deviations from Bethe-Bloch in one x-Bin) | |
3434 | }; | |
3435 | ||
3436 | Double_t lowParLimitsSimultaneousFit[nParSimultaneousFit] = { | |
3437 | fractionErrorLowPions, | |
3438 | fractionErrorLowKaons, | |
3439 | fractionErrorLowProtons, | |
3440 | fractionErrorLowElectrons, | |
3441 | fractionErrorLowMuons, | |
3442 | totalYield | |
3443 | }; | |
3444 | ||
3445 | Double_t upParLimitsSimultaneousFit[nParSimultaneousFit] = { | |
3446 | fractionErrorUpPions, | |
3447 | fractionErrorUpKaons, | |
3448 | fractionErrorUpProtons, | |
3449 | fractionErrorUpElectrons, | |
3450 | fractionErrorUpMuons, | |
3451 | totalYield | |
3452 | }; | |
3453 | ||
3454 | Double_t stepSizeSimultaneousFit[nParSimultaneousFit] = { | |
3455 | 0.1, | |
3456 | 0.1, | |
3457 | 0.1, | |
3458 | 0.1, | |
3459 | (takeIntoAccountMuons ? 0.1 : 0.), | |
3460 | ||
3461 | 0.0 | |
3462 | }; | |
3463 | ||
3464 | if (regularisation <= 0 && iter == 1) { | |
3465 | // In case of no regularisation, do the fit of the electron fraction here (compare comment below) | |
3466 | if (mode == kPMpT && slice == electronFractionThresholdBinForFitting) | |
3467 | hFractionElectrons->Fit(fElectronFraction, "N", "", lowFittingBoundElectronFraction, electronFractionThresholdForFitting); | |
3468 | } | |
3469 | ||
3470 | if ((regularisation > 0 && iter == 0) || (regularisation <= 0 && iter == 1)) { | |
3471 | // Set the electron fraction to the negative pT -> A function will be used | |
3472 | // to evaluate the electron fraction for each bin above the threshold | |
3473 | if(mode == kPMpT && slice >= electronFractionThresholdBinForFitting) { | |
3474 | // In case of no regularisation, mathFit has no information about the fraction of other x bins. | |
3475 | // Thus, the electron fraction is evaluated and set here. For the case w/ regularisation, | |
3476 | // just "-pT" is set and the electron fraction will be evaluated during the fit. | |
3477 | Double_t fixElectronFraction = (regularisation <= 0) ? fElectronFraction->Eval((binsPt[slice + 1] + binsPt[slice]) / 2.) | |
3478 | : -(binsPt[slice + 1] + binsPt[slice]) / 2.; | |
3479 | ||
3480 | if (regularisation <= 0) { | |
3481 | fixElectronFraction = TMath::Min(1.0, fixElectronFraction); | |
3482 | fixElectronFraction = TMath::Max(0.0, fixElectronFraction); | |
3483 | } | |
3484 | ||
3485 | gausParamsPi[3] = fixElectronFraction; | |
3486 | lowParLimitsPi[3] = fixElectronFraction; | |
3487 | upParLimitsPi[3] = fixElectronFraction; | |
3488 | ||
3489 | gausParamsEl[3] = fixElectronFraction; | |
3490 | lowParLimitsEl[3] = fixElectronFraction; | |
3491 | upParLimitsEl[3] = fixElectronFraction; | |
3492 | ||
3493 | gausParamsKa[3] = fixElectronFraction; | |
3494 | lowParLimitsKa[3] = fixElectronFraction; | |
3495 | upParLimitsKa[3] = fixElectronFraction; | |
3496 | ||
3497 | gausParamsPr[3] = fixElectronFraction; | |
3498 | lowParLimitsPr[3] = fixElectronFraction; | |
3499 | upParLimitsPr[3] = fixElectronFraction; | |
3500 | ||
3501 | stepSize[3] = 0.0; | |
3502 | ||
3503 | gausParamsSimultaneousFit[3] = fixElectronFraction; | |
3504 | lowParLimitsSimultaneousFit[3] = fixElectronFraction; | |
3505 | upParLimitsSimultaneousFit[3] = fixElectronFraction; | |
3506 | ||
3507 | stepSizeSimultaneousFit[3] = 0.0; | |
3508 | } | |
3509 | ||
3510 | ||
3511 | // Set muon fraction equal to (some modified) electron fraction above some threshold, which should be a reasonable approximation: | |
3512 | // Fixed muon fraction < 0 does this job within the fitting functions | |
3513 | if(mode != kPMpT || slice >= muonFractionThresholdBinForFitting) { | |
3514 | // "Abuse" the muon fraction to forward the pT, which can then be used to get some modified electron fraction | |
3515 | const Double_t fixedValue = -(binsPt[slice] + binsPt[slice + 1]) / 2.; | |
3516 | gausParamsPi[4] = fixedValue; | |
3517 | lowParLimitsPi[4] = fixedValue; | |
3518 | upParLimitsPi[4] = fixedValue; | |
3519 | ||
3520 | gausParamsEl[4] = fixedValue; | |
3521 | lowParLimitsEl[4] = fixedValue; | |
3522 | upParLimitsEl[4] = fixedValue; | |
3523 | ||
3524 | gausParamsKa[4] = fixedValue; | |
3525 | lowParLimitsKa[4] = fixedValue; | |
3526 | upParLimitsKa[4] = fixedValue; | |
3527 | ||
3528 | gausParamsPr[4] = fixedValue; | |
3529 | lowParLimitsPr[4] = fixedValue; | |
3530 | upParLimitsPr[4] = fixedValue; | |
3531 | ||
3532 | stepSize[4] = 0.; | |
3533 | ||
3534 | gausParamsSimultaneousFit[4] = fixedValue; | |
3535 | lowParLimitsSimultaneousFit[4] = fixedValue; | |
3536 | upParLimitsSimultaneousFit[4] = fixedValue; | |
3537 | ||
3538 | stepSizeSimultaneousFit[4] = 0.0; | |
3539 | } | |
3540 | } | |
3541 | ||
3542 | // iter 0 used for initialisation | |
3543 | if (regularisation > 0 && iter == 0) { | |
3544 | const Int_t offset = currXbin * mathFit->GetNumParametersPerXbin(); | |
3545 | for (Int_t i = 0; i < mathFit->GetNumParametersPerXbin(); i++) { | |
3546 | gausParamsSimultaneousFitRegularised[offset + i] = gausParamsSimultaneousFit[i]; | |
3547 | lowParLimitsSimultaneousFitRegularised[offset + i] = lowParLimitsSimultaneousFit[i]; | |
3548 | upParLimitsSimultaneousFitRegularised[offset + i] = upParLimitsSimultaneousFit[i]; | |
3549 | stepSizeSimultaneousFitRegularised[offset + i] = stepSizeSimultaneousFit[i]; | |
3550 | } | |
3551 | } | |
3552 | ||
3553 | ||
3554 | if (iter == 1) { | |
3555 | // The parameters are only used for fitMethod < 2. Thus, they can be set for these methods, | |
3556 | // although a different method is used | |
3557 | totalDeltaPion->SetParameters(gausParamsPi); | |
3558 | totalDeltaElectron->SetParameters(gausParamsEl); | |
3559 | totalDeltaKaon->SetParameters(gausParamsKa); | |
3560 | totalDeltaProton->SetParameters(gausParamsPr); | |
3561 | } | |
3562 | ||
3563 | const TString binInfo = (mode == kPMpT) ? Form("%.2f_Pt_%.2f", binsPt[slice], binsPt[slice + 1]) | |
3564 | : Form("%.2f_%s_%.2f", hFractionPions->GetXaxis()->GetBinLowEdge(slice + 1), | |
3565 | modeShortName[mode].Data(), hFractionPions->GetXaxis()->GetBinUpEdge(slice + 1)); | |
3566 | ||
3567 | const TString binInfoTitle = (mode == kPMpT) ? Form("%.2f < Pt <%.2f", binsPt[slice], binsPt[slice + 1]) | |
3568 | : Form("%.2f < %s < %.2f", hFractionPions->GetXaxis()->GetBinLowEdge(slice + 1), | |
3569 | modeShortName[mode].Data(), | |
3570 | hFractionPions->GetXaxis()->GetBinUpEdge(slice + 1)); | |
3571 | ||
3572 | const TString fitFuncSuffix = (mode == kPMpT) ? Form("%.3f_Pt_%.3f", binsPt[slice], binsPt[slice + 1]) | |
3573 | : Form("%.3f_%s_%.3f", hFractionPions->GetXaxis()->GetBinLowEdge(slice + 1), | |
3574 | modeShortName[mode].Data(), | |
3575 | hFractionPions->GetXaxis()->GetBinUpEdge(slice + 1)); | |
3576 | ||
3577 | if (iter == 1) { | |
3578 | for (Int_t species = 0; species < 4; species++) { | |
3579 | cSingleFit[slice][species] = new TCanvas(Form("cSingleFit_%s_%s", binInfo.Data(), speciesLabel[species].Data()), | |
3580 | Form("single fit for %s (%s)", binInfoTitle.Data(), speciesLabel[species].Data()), | |
3581 | 1366, 768); | |
3582 | cSingleFit[slice][species]->Divide(1, 2, 0.01, 0.); | |
3583 | cSingleFit[slice][species]->GetPad(1)->SetRightMargin(0.001); | |
3584 | cSingleFit[slice][species]->GetPad(2)->SetRightMargin(0.001); | |
3585 | cSingleFit[slice][species]->GetPad(1)->SetTopMargin(0.001); | |
3586 | cSingleFit[slice][species]->GetPad(2)->SetTopMargin(0.01); | |
3587 | cSingleFit[slice][species]->GetPad(1)->SetBottomMargin(0.01); | |
3588 | ||
3589 | cSingleFit[slice][species]->GetPad(1)->SetGridx(kTRUE); | |
3590 | cSingleFit[slice][species]->GetPad(2)->SetGridx(kTRUE); | |
3591 | cSingleFit[slice][species]->GetPad(1)->SetGridy(kTRUE); | |
3592 | cSingleFit[slice][species]->GetPad(2)->SetGridy(kTRUE); | |
3593 | ||
3594 | cSingleFit[slice][species]->GetPad(1)->SetLogy(kTRUE); | |
3595 | cSingleFit[slice][species]->GetPad(1)->SetLogx(kTRUE); | |
3596 | cSingleFit[slice][species]->GetPad(2)->SetLogx(kTRUE); | |
3597 | } | |
3598 | } | |
3599 | ||
3600 | // Problem: For p < 0.5 GeV/c, the fractions cannot be simply taken from the parameters because | |
3601 | // not all entries of the histogram are inside the considered range. | |
3602 | // Also: Small deviations of summed fractions from one if taking the fractions from different Delta species histos. | |
3603 | // Therefore: Add up the integrals of the individual fits (\Delta species) and take the fraction of the sum | |
3604 | Double_t integralTotal = 0; | |
3605 | Double_t integralPions = 0, integralKaons = 0, integralProtons = 0, integralElectrons = 0, integralMuons = 0; | |
3606 | ||
3607 | Double_t integralPionsDeltaPion = 0, integralPionsDeltaElectron = 0, integralPionsDeltaKaon = 0, integralPionsDeltaProton = 0; | |
3608 | Double_t integralElectronsDeltaPion = 0, integralElectronsDeltaElectron = 0, integralElectronsDeltaKaon = 0, | |
3609 | integralElectronsDeltaProton = 0; | |
3610 | Double_t integralKaonsDeltaPion = 0, integralKaonsDeltaElectron = 0, integralKaonsDeltaKaon = 0, integralKaonsDeltaProton = 0; | |
3611 | Double_t integralProtonsDeltaPion = 0, integralProtonsDeltaElectron = 0, integralProtonsDeltaKaon = 0, | |
3612 | integralProtonsDeltaProton = 0; | |
3613 | Double_t integralMuonsDeltaPion = 0, integralMuonsDeltaElectron = 0, integralMuonsDeltaKaon = 0, integralMuonsDeltaProton = 0; | |
3614 | ||
3615 | /* | |
3616 | Double_t integralErrorPions = 0, integralErrorKaons = 0, integralErrorProtons = 0, integralErrorElectrons = 0; | |
3617 | ||
3618 | Double_t integralErrorPionsDeltaPion = 0, integralErrorPionsDeltaElectron = 0, integralErrorPionsDeltaKaon = 0, | |
3619 | integralErrorPionsDeltaProton = 0; | |
3620 | Double_t integralErrorElectronsDeltaPion = 0, integralErrorElectronsDeltaElectron = 0, integralErrorElectronsDeltaKaon = 0, | |
3621 | integralErrorElectronsDeltaProton = 0; | |
3622 | Double_t integralErrorKaonsDeltaPion = 0, integralErrorKaonsDeltaElectron = 0, integralErrorKaonsDeltaKaon = 0, | |
3623 | integralErrorKaonsDeltaProton = 0; | |
3624 | Double_t integralErrorProtonsDeltaPion = 0, integralErrorProtonsDeltaElectron = 0, integralErrorProtonsDeltaKaon = 0, | |
3625 | integralErrorProtonsDeltaProton = 0; | |
3626 | ||
3627 | Double_t integralErrorTotalDeltaPion = 0, integralErrorTotalDeltaElectron = 0, integralErrorTotalDeltaKaon = 0; | |
3628 | Double_t integralErrorTotalDeltaProton = 0; | |
3629 | */ | |
3630 | ||
3631 | Int_t errFlag = 0; | |
3632 | ||
3633 | // Reset temp arrays for next slice | |
3634 | for (Int_t ind = 0; ind < nParUsed; ind++) | |
3635 | parameterErrorsOut[ind] = 0; | |
3636 | ||
3637 | // Do not reset, if regularisation is on and the fit is done because the covariance matrix | |
3638 | // will not be changed anymore in this case. On the other hand it will only be calculated once, | |
3639 | // so resetting it would mean that is not available anymore. | |
3640 | if (regularisation <= 0 || !regularisedFitDone) { | |
3641 | for (Int_t i = 0; i < nParUsed; i++) { | |
3642 | for (Int_t j = 0; j < nParUsed; j++) { | |
3643 | covMatrix[i][j] = 0; | |
3644 | } | |
3645 | } | |
3646 | } | |
3647 | ||
3648 | Double_t reducedChiSquare = -1; | |
3649 | ||
3650 | if (fitMethod == 2) { | |
3651 | if (regularisation <= 0 && iter == 1) | |
3652 | std::cout << "Fitting data simultaneously...." << std::endl << std::endl; | |
3653 | ||
3654 | // Add ref histos in initialisation step (w/ reg) or in the only loop (w/o reg) | |
3655 | if ((regularisation > 0 && iter == 0) || (regularisation <= 0 && iter == 1)) { | |
3656 | ||
3657 | if (regularisation <= 0) | |
3658 | mathFit->ClearRefHistos(); | |
3659 | ||
3660 | mathFit->AddRefHisto(hGenDeltaPiForPiProj); | |
3661 | mathFit->AddRefHisto(hGenDeltaPiForKaProj); | |
3662 | mathFit->AddRefHisto(hGenDeltaPiForPrProj); | |
3663 | mathFit->AddRefHisto(hGenDeltaPiForElProj); | |
3664 | if (takeIntoAccountMuons) | |
3665 | mathFit->AddRefHisto(hGenDeltaPiForMuProj); | |
3666 | ||
3667 | mathFit->AddRefHisto(hGenDeltaKaForPiProj); | |
3668 | mathFit->AddRefHisto(hGenDeltaKaForKaProj); | |
3669 | mathFit->AddRefHisto(hGenDeltaKaForPrProj); | |
3670 | mathFit->AddRefHisto(hGenDeltaKaForElProj); | |
3671 | if (takeIntoAccountMuons) | |
3672 | mathFit->AddRefHisto(hGenDeltaKaForMuProj); | |
3673 | ||
3674 | mathFit->AddRefHisto(hGenDeltaPrForPiProj); | |
3675 | mathFit->AddRefHisto(hGenDeltaPrForKaProj); | |
3676 | mathFit->AddRefHisto(hGenDeltaPrForPrProj); | |
3677 | mathFit->AddRefHisto(hGenDeltaPrForElProj); | |
3678 | if (takeIntoAccountMuons) | |
3679 | mathFit->AddRefHisto(hGenDeltaPrForMuProj); | |
3680 | ||
3681 | mathFit->AddRefHisto(hGenDeltaElForPiProj); | |
3682 | mathFit->AddRefHisto(hGenDeltaElForKaProj); | |
3683 | mathFit->AddRefHisto(hGenDeltaElForPrProj); | |
3684 | mathFit->AddRefHisto(hGenDeltaElForElProj); | |
3685 | if (takeIntoAccountMuons) | |
3686 | mathFit->AddRefHisto(hGenDeltaElForMuProj); | |
3687 | ||
3688 | // In reg case, fill in the data for this bin and continue with the nex bin | |
3689 | if (regularisation > 0) { | |
3690 | TH1D* hDeltaSpecies[numSimultaneousFits] = { hDeltaPi[slice], hDeltaKa[slice], hDeltaPr[slice], hDeltaEl[slice] }; | |
3691 | ||
3692 | for (Int_t i = 0; i < numSimultaneousFits; i++) { | |
3693 | mathFit->InputData(hDeltaSpecies[i], currXbin, i, xLow, xUp, -1., kFALSE); | |
3694 | } | |
3695 | ||
3696 | currXbin++; | |
3697 | continue; | |
3698 | } | |
3699 | } | |
3700 | ||
3701 | if (regularisation > 0 && iter == 1 && !regularisedFitDone) { | |
3702 | std::cout << "Fitting data simultaneously with regularisation...." << std::endl << std::endl; | |
3703 | ||
3704 | // TODO At the moment, the covariance matrix is NOT forwarded from TMinuit (has completely different dimensions) | |
3705 | // -> Since it is not used at the moment, this is not necessary. If it is to be used in future, | |
3706 | // this has to be implemented! But one has to be careful, since parameters from different bins then | |
3707 | // depend on each other! Furthermore, there will be no errors for fixed parameters like muon fraction or electron fraction | |
3708 | // above the corresponding threshold in the covariance matrix, but an estimated error will be set manually. | |
3709 | errFlag = errFlag | doSimultaneousFitRegularised(nParSimultaneousFitRegularised, gausParamsSimultaneousFitRegularised, | |
3710 | parameterErrorsOutRegularised, &covMatrix[0][0], | |
3711 | stepSizeSimultaneousFitRegularised, | |
3712 | lowParLimitsSimultaneousFitRegularised, | |
3713 | upParLimitsSimultaneousFitRegularised, reducedChiSquare); | |
3714 | if (errFlag != 0) | |
3715 | std::cout << "errFlag " << errFlag << std::endl << std::endl; | |
3716 | ||
3717 | reducedChiSquareRegularisation = reducedChiSquare; | |
3718 | ||
3719 | // Since everything is fitted in one go, only do this for the first x bin | |
3720 | // (more convenient to put the fitting in the x bin loop in order to intialise | |
3721 | // the parameters in the same way they are initialised for the fit w/o regularisation. | |
3722 | regularisedFitDone = kTRUE; | |
3723 | } | |
3724 | ||
3725 | if (regularisation > 0 && iter == 1) { | |
3726 | // To allow for an identical processing, just forward the parameter results for the current xBin to the | |
3727 | // array used by the standard simultaneous fit. The rest of the code is then the same for regularisation on and off | |
3728 | ||
3729 | for (Int_t i = 0; i < mathFit->GetNumParametersPerXbin(); i++) { | |
3730 | const Int_t iRegularised = i + currXbin * mathFit->GetNumParametersPerXbin(); | |
3731 | ||
3732 | gausParamsSimultaneousFit[i] = gausParamsSimultaneousFitRegularised[iRegularised]; | |
3733 | parameterErrorsOut[i] = parameterErrorsOutRegularised[iRegularised]; | |
3734 | } | |
3735 | ||
3736 | // Same reducedChiSquare for all bins, since only one fit | |
3737 | reducedChiSquare = reducedChiSquareRegularisation; | |
3738 | ||
3739 | ||
3740 | // Also clear reference histos and load those for the current bin | |
3741 | mathFit->ClearRefHistos(); | |
3742 | ||
3743 | mathFit->AddRefHisto(hGenDeltaPiForPiProj); | |
3744 | mathFit->AddRefHisto(hGenDeltaPiForKaProj); | |
3745 | mathFit->AddRefHisto(hGenDeltaPiForPrProj); | |
3746 | mathFit->AddRefHisto(hGenDeltaPiForElProj); | |
3747 | if (takeIntoAccountMuons) | |
3748 | mathFit->AddRefHisto(hGenDeltaPiForMuProj); | |
3749 | ||
3750 | mathFit->AddRefHisto(hGenDeltaKaForPiProj); | |
3751 | mathFit->AddRefHisto(hGenDeltaKaForKaProj); | |
3752 | mathFit->AddRefHisto(hGenDeltaKaForPrProj); | |
3753 | mathFit->AddRefHisto(hGenDeltaKaForElProj); | |
3754 | if (takeIntoAccountMuons) | |
3755 | mathFit->AddRefHisto(hGenDeltaKaForMuProj); | |
3756 | ||
3757 | mathFit->AddRefHisto(hGenDeltaPrForPiProj); | |
3758 | mathFit->AddRefHisto(hGenDeltaPrForKaProj); | |
3759 | mathFit->AddRefHisto(hGenDeltaPrForPrProj); | |
3760 | mathFit->AddRefHisto(hGenDeltaPrForElProj); | |
3761 | if (takeIntoAccountMuons) | |
3762 | mathFit->AddRefHisto(hGenDeltaPrForMuProj); | |
3763 | ||
3764 | mathFit->AddRefHisto(hGenDeltaElForPiProj); | |
3765 | mathFit->AddRefHisto(hGenDeltaElForKaProj); | |
3766 | mathFit->AddRefHisto(hGenDeltaElForPrProj); | |
3767 | mathFit->AddRefHisto(hGenDeltaElForElProj); | |
3768 | if (takeIntoAccountMuons) | |
3769 | mathFit->AddRefHisto(hGenDeltaElForMuProj); | |
3770 | } | |
3771 | ||
3772 | ||
3773 | if (regularisation <= 0) { | |
3774 | TH1D* hDeltaSpecies[numSimultaneousFits] = { hDeltaPi[slice], hDeltaKa[slice], hDeltaPr[slice], hDeltaEl[slice] }; | |
3775 | errFlag = errFlag | | |
3776 | doSimultaneousFit(hDeltaSpecies, xLow, xUp, nParSimultaneousFit, gausParamsSimultaneousFit, parameterErrorsOut, | |
3777 | &covMatrix[0][0], stepSizeSimultaneousFit, lowParLimitsSimultaneousFit, | |
3778 | upParLimitsSimultaneousFit, reducedChiSquare); | |
3779 | } | |
3780 | ||
3781 | // Forward parameters to single fits | |
3782 | for (Int_t parIndex = 0; parIndex < nPar; parIndex++) { | |
3783 | // Fractions | |
3784 | if (parIndex <= 4) { | |
3785 | totalDeltaPion->SetParameter(parIndex, gausParamsSimultaneousFit[parIndex]); | |
3786 | totalDeltaPion->SetParError(parIndex, parameterErrorsOut[parIndex]); | |
3787 | ||
3788 | totalDeltaKaon->SetParameter(parIndex, gausParamsSimultaneousFit[parIndex]); | |
3789 | totalDeltaKaon->SetParError(parIndex, parameterErrorsOut[parIndex]); | |
3790 | ||
3791 | totalDeltaProton->SetParameter(parIndex, gausParamsSimultaneousFit[parIndex]); | |
3792 | totalDeltaProton->SetParError(parIndex, parameterErrorsOut[parIndex]); | |
3793 | ||
3794 | totalDeltaElectron->SetParameter(parIndex, gausParamsSimultaneousFit[parIndex]); | |
3795 | totalDeltaElectron->SetParError(parIndex, parameterErrorsOut[parIndex]); | |
3796 | } | |
3797 | // Total yield | |
3798 | else if (parIndex == 5) { | |
3799 | totalDeltaPion->SetParameter(parIndex, totalYield); | |
3800 | totalDeltaPion->SetParError(parIndex, 0); | |
3801 | ||
3802 | totalDeltaKaon->SetParameter(parIndex, totalYield); | |
3803 | totalDeltaKaon->SetParError(parIndex, 0); | |
3804 | ||
3805 | totalDeltaProton->SetParameter(parIndex, totalYield); | |
3806 | totalDeltaProton->SetParError(parIndex, 0); | |
3807 | ||
3808 | totalDeltaElectron->SetParameter(parIndex, totalYield); | |
3809 | totalDeltaElectron->SetParError(parIndex, 0); | |
3810 | } | |
3811 | // Hist shifts | |
3812 | else { | |
3813 | totalDeltaPion->SetParameter(parIndex, 0); | |
3814 | totalDeltaPion->SetParError(parIndex, 0); | |
3815 | ||
3816 | totalDeltaKaon->SetParameter(parIndex, 0); | |
3817 | totalDeltaKaon->SetParError(parIndex, 0); | |
3818 | ||
3819 | totalDeltaProton->SetParameter(parIndex, 0); | |
3820 | totalDeltaProton->SetParError(parIndex, 0); | |
3821 | ||
3822 | totalDeltaElectron->SetParameter(parIndex, 0); | |
3823 | totalDeltaElectron->SetParError(parIndex, 0); | |
3824 | } | |
3825 | } | |
3826 | ||
3827 | const Bool_t useRegularisation = regularisation > 0; | |
3828 | ||
3829 | // Plot single fits | |
3830 | ||
3831 | Int_t binLow = -1; | |
3832 | Int_t binHigh = -1; | |
3833 | ||
3834 | // DeltaPions | |
3835 | cSingleFit[slice][2]->cd(1); | |
3836 | ||
3837 | hDeltaPi[slice]->SetTitle(""); | |
3838 | SetReasonableXaxisRange(hDeltaPi[slice], binLow, binHigh); | |
3839 | hDeltaPi[slice]->Draw("e"); | |
3840 | ||
3841 | fitFuncTotalDeltaPion[slice] = (TF1*)totalDeltaPion->Clone(Form("Fit_Total_DeltaPion_%s", fitFuncSuffix.Data())); | |
3842 | ||
3843 | hDeltaPiFitQA[slice] = (TH1D*)hDeltaPi[slice]->Clone(Form("hDeltaPiFitQA_%d", slice)); | |
3844 | hDeltaPiFitQA[slice]->GetYaxis()->SetTitle("(Data - Fit) / Data"); | |
3845 | hDeltaPiFitQA[slice]->Add(fitFuncTotalDeltaPion[slice], -1); | |
3846 | hDeltaPiFitQA[slice]->Divide(hDeltaPi[slice]); | |
3847 | ||
3848 | hDeltaPi[slice]->GetListOfFunctions()->Add(fitFuncTotalDeltaPion[slice]); | |
3849 | fitFuncTotalDeltaPion[slice]->Draw("same"); | |
3850 | ||
3851 | Double_t* parametersOut = &totalDeltaPion->GetParameters()[0]; | |
3852 | ||
3853 | hGenDeltaPiForPiProj->Scale(parametersOut[5] * (parametersOut[0] + (muonContamination ? parametersOut[3] : 0))); | |
3854 | shiftHist(hGenDeltaPiForPiProj, parametersOut[6], useRegularisation); | |
3855 | hGenDeltaPiForPiProj->Draw("same"); | |
3856 | ||
3857 | hGenDeltaPiForKaProj->Scale(parametersOut[5] * parametersOut[1]); | |
3858 | shiftHist(hGenDeltaPiForKaProj, parametersOut[7], useRegularisation); | |
3859 | hGenDeltaPiForKaProj->Draw("same"); | |
3860 | ||
3861 | hGenDeltaPiForPrProj->Scale(parametersOut[5] * parametersOut[2]); | |
3862 | shiftHist(hGenDeltaPiForPrProj, parametersOut[8], useRegularisation); | |
3863 | hGenDeltaPiForPrProj->Draw("same"); | |
3864 | ||
3865 | hGenDeltaPiForElProj->Scale(parametersOut[5] * parametersOut[3]); | |
3866 | shiftHist(hGenDeltaPiForElProj, parametersOut[9], useRegularisation); | |
3867 | hGenDeltaPiForElProj->Draw("same"); | |
3868 | ||
3869 | if (takeIntoAccountMuons) { | |
3870 | hGenDeltaPiForMuProj->Scale(parametersOut[5] * parametersOut[4]); | |
3871 | shiftHist(hGenDeltaPiForMuProj, parametersOut[10], useRegularisation); | |
3872 | hGenDeltaPiForMuProj->Draw("same"); | |
3873 | } | |
3874 | ||
3875 | if (plotIdentifiedSpectra) { | |
3876 | for (Int_t species = 0; species < 5; species++) | |
3877 | hDeltaPiMC[slice][species]->Draw("same"); | |
3878 | ||
3879 | // Draw histo for sum of MC muons and pions | |
3880 | TH1D* hMCmuonsAndPions = new TH1D(*hDeltaPiMC[slice][kPi - 1]); | |
3881 | hMCmuonsAndPions->Add(hDeltaPiMC[slice][kMu - 1]); | |
3882 | hMCmuonsAndPions->SetLineColor(getLineColor(kMuPlusPi)); | |
3883 | hMCmuonsAndPions->SetMarkerColor(getLineColor(kMuPlusPi)); | |
3884 | hMCmuonsAndPions->SetName(Form("%s_muonsAdded", hDeltaPiMC[slice][kPi - 1]->GetName())); | |
3885 | hMCmuonsAndPions->Draw("same"); | |
3886 | } | |
3887 | ||
3888 | hDeltaPi[slice]->Draw("esame"); | |
3889 | ||
3890 | legend->Draw(); | |
3891 | ||
3892 | cSingleFit[slice][2]->cd(2); | |
3893 | hDeltaPiFitQA[slice]->GetYaxis()->SetRangeUser(fitQAaxisLowBound, fitQAaxisUpBound); | |
3894 | hDeltaPiFitQA[slice]->Draw("e"); | |
3895 | ||
3896 | hReducedChiSquarePt->SetBinContent(slice + 1, 3, reducedChiSquare); | |
3897 | ||
3898 | // TMatrixDSym covMatrixPi(nParUsed, &covMatrix[0][0]); | |
3899 | ||
3900 | setFractionsAndYields(slice, inverseBinWidth, binWidthFitHisto, kPi, parametersOut, parameterErrorsOut, hFractionPions, | |
3901 | hFractionPionsDeltaPion, hFractionElectronsDeltaPion, hFractionKaonsDeltaPion, | |
3902 | hFractionProtonsDeltaPion, hFractionMuonsDeltaPion, hYieldPions, hYieldPionsDeltaPion, hYieldElectronsDeltaPion, | |
3903 | hYieldKaonsDeltaPion, hYieldProtonsDeltaPion, hYieldMuonsDeltaPion, normaliseResults); | |
3904 | ||
3905 | // Also set specific muon fractions and yields -> The deltaSpecies histos are not needed here: They will be set together with | |
3906 | // the fraction and yields for all other species | |
3907 | setFractionsAndYields(slice, inverseBinWidth, binWidthFitHisto, kMu, parametersOut, parameterErrorsOut, hFractionMuons, | |
3908 | 0x0, 0x0, 0x0, 0x0, 0x0, hYieldMuons, 0x0, 0x0, 0x0, 0x0, 0x0, normaliseResults); | |
3909 | ||
3910 | ||
3911 | // DeltaElectrons | |
3912 | cSingleFit[slice][0]->cd(1); | |
3913 | ||
3914 | hDeltaEl[slice]->SetTitle(""); | |
3915 | SetReasonableXaxisRange(hDeltaEl[slice], binLow, binHigh); | |
3916 | hDeltaEl[slice]->Draw("e"); | |
3917 | ||
3918 | fitFuncTotalDeltaElectron[slice] = (TF1*)totalDeltaElectron->Clone(Form("Fit_Total_DeltaElectron_%s", fitFuncSuffix.Data())); | |
3919 | ||
3920 | hDeltaElFitQA[slice] = (TH1D*)hDeltaEl[slice]->Clone(Form("hDeltaElFitQA_%d", slice)); | |
3921 | hDeltaElFitQA[slice]->GetYaxis()->SetTitle("(Data - Fit) / Data"); | |
3922 | hDeltaElFitQA[slice]->Add(fitFuncTotalDeltaElectron[slice], -1); | |
3923 | hDeltaElFitQA[slice]->Divide(hDeltaEl[slice]); | |
3924 | ||
3925 | hDeltaEl[slice]->GetListOfFunctions()->Add(fitFuncTotalDeltaElectron[slice]); | |
3926 | fitFuncTotalDeltaElectron[slice]->Draw("same"); | |
3927 | ||
3928 | parametersOut = &totalDeltaElectron->GetParameters()[0]; | |
3929 | ||
3930 | hGenDeltaElForPiProj->Scale(parametersOut[5] * (parametersOut[0] + (muonContamination ? parametersOut[3] : 0))); | |
3931 | shiftHist(hGenDeltaElForPiProj, parametersOut[6], useRegularisation); | |
3932 | hGenDeltaElForPiProj->Draw("same"); | |
3933 | ||
3934 | hGenDeltaElForKaProj->Scale(parametersOut[5] * parametersOut[1]); | |
3935 | shiftHist(hGenDeltaElForKaProj, parametersOut[7], useRegularisation); | |
3936 | hGenDeltaElForKaProj->Draw("same"); | |
3937 | ||
3938 | hGenDeltaElForPrProj->Scale(parametersOut[5] * parametersOut[2]); | |
3939 | shiftHist(hGenDeltaElForPrProj, parametersOut[8], useRegularisation); | |
3940 | hGenDeltaElForPrProj->Draw("same"); | |
3941 | ||
3942 | hGenDeltaElForElProj->Scale(parametersOut[5] * parametersOut[3]); | |
3943 | shiftHist(hGenDeltaElForElProj, parametersOut[9], useRegularisation); | |
3944 | hGenDeltaElForElProj->Draw("same"); | |
3945 | ||
3946 | if (takeIntoAccountMuons) { | |
3947 | hGenDeltaElForMuProj->Scale(parametersOut[5] * parametersOut[4]); | |
3948 | shiftHist(hGenDeltaElForMuProj, parametersOut[10], useRegularisation); | |
3949 | hGenDeltaElForMuProj->Draw("same"); | |
3950 | } | |
3951 | ||
3952 | if (plotIdentifiedSpectra) { | |
3953 | for (Int_t species = 0; species < 5; species++) | |
3954 | hDeltaElMC[slice][species]->Draw("same"); | |
3955 | ||
3956 | // Draw histo for sum of MC muons and pions | |
3957 | TH1D* hMCmuonsAndPions = new TH1D(*hDeltaElMC[slice][kPi - 1]); | |
3958 | hMCmuonsAndPions->Add(hDeltaElMC[slice][kMu - 1]); | |
3959 | hMCmuonsAndPions->SetLineColor(getLineColor(kMuPlusPi)); | |
3960 | hMCmuonsAndPions->SetMarkerColor(getLineColor(kMuPlusPi)); | |
3961 | hMCmuonsAndPions->SetName(Form("%s_muonsAdded", hDeltaElMC[slice][kPi - 1]->GetName())); | |
3962 | hMCmuonsAndPions->Draw("same"); | |
3963 | } | |
3964 | ||
3965 | hDeltaEl[slice]->Draw("esame"); | |
3966 | ||
3967 | legend->Draw(); | |
3968 | ||
3969 | cSingleFit[slice][0]->cd(2); | |
3970 | hDeltaElFitQA[slice]->GetYaxis()->SetRangeUser(fitQAaxisLowBound, fitQAaxisUpBound); | |
3971 | hDeltaElFitQA[slice]->Draw("e"); | |
3972 | ||
3973 | hReducedChiSquarePt->SetBinContent(slice + 1, 1, reducedChiSquare); | |
3974 | ||
3975 | //TMatrixDSym covMatrixEl(nParUsed, &covMatrix[0][0]); | |
3976 | ||
3977 | setFractionsAndYields(slice, inverseBinWidth, binWidthFitHisto, kEl, parametersOut, parameterErrorsOut, hFractionElectrons, | |
3978 | hFractionPionsDeltaElectron, hFractionElectronsDeltaElectron, hFractionKaonsDeltaElectron, | |
3979 | hFractionProtonsDeltaElectron, hFractionMuonsDeltaElectron, hYieldElectrons, hYieldPionsDeltaElectron, | |
3980 | hYieldElectronsDeltaElectron, hYieldKaonsDeltaElectron, hYieldProtonsDeltaElectron, hYieldMuonsDeltaElectron, | |
3981 | normaliseResults); | |
3982 | ||
3983 | ||
3984 | ||
3985 | // DeltaKaons | |
3986 | cSingleFit[slice][1]->cd(1); | |
3987 | ||
3988 | hDeltaKa[slice]->SetTitle(""); | |
3989 | SetReasonableXaxisRange(hDeltaKa[slice], binLow, binHigh); | |
3990 | hDeltaKa[slice]->Draw("e"); | |
3991 | ||
3992 | fitFuncTotalDeltaKaon[slice] = (TF1*)totalDeltaKaon->Clone(Form("Fit_Total_DeltaKaon_%s", fitFuncSuffix.Data())); | |
3993 | ||
3994 | hDeltaKaFitQA[slice] = (TH1D*)hDeltaKa[slice]->Clone(Form("hDeltaKaFitQA_%d", slice)); | |
3995 | hDeltaKaFitQA[slice]->GetYaxis()->SetTitle("(Data - Fit) / Data"); | |
3996 | hDeltaKaFitQA[slice]->Add(fitFuncTotalDeltaKaon[slice], -1); | |
3997 | hDeltaKaFitQA[slice]->Divide(hDeltaKa[slice]); | |
3998 | ||
3999 | hDeltaKa[slice]->GetListOfFunctions()->Add(fitFuncTotalDeltaKaon[slice]); | |
4000 | fitFuncTotalDeltaKaon[slice]->Draw("same"); | |
4001 | ||
4002 | parametersOut = &totalDeltaKaon->GetParameters()[0]; | |
4003 | ||
4004 | hGenDeltaKaForPiProj->Scale(parametersOut[5] * (parametersOut[0] + (muonContamination ? parametersOut[3] : 0))); | |
4005 | shiftHist(hGenDeltaKaForPiProj, parametersOut[6], useRegularisation); | |
4006 | hGenDeltaKaForPiProj->Draw("same"); | |
4007 | ||
4008 | hGenDeltaKaForKaProj->Scale(parametersOut[5] * parametersOut[1]); | |
4009 | shiftHist(hGenDeltaKaForKaProj, parametersOut[7], useRegularisation); | |
4010 | hGenDeltaKaForKaProj->Draw("same"); | |
4011 | ||
4012 | hGenDeltaKaForPrProj->Scale(parametersOut[5] * parametersOut[2]); | |
4013 | shiftHist(hGenDeltaKaForPrProj, parametersOut[8], useRegularisation); | |
4014 | hGenDeltaKaForPrProj->Draw("same"); | |
4015 | ||
4016 | hGenDeltaKaForElProj->Scale(parametersOut[5] * parametersOut[3]); | |
4017 | shiftHist(hGenDeltaKaForElProj, parametersOut[9], useRegularisation); | |
4018 | hGenDeltaKaForElProj->Draw("same"); | |
4019 | ||
4020 | if (takeIntoAccountMuons) { | |
4021 | hGenDeltaKaForMuProj->Scale(parametersOut[5] * parametersOut[4]); | |
4022 | shiftHist(hGenDeltaKaForMuProj, parametersOut[10], useRegularisation); | |
4023 | hGenDeltaKaForMuProj->Draw("same"); | |
4024 | } | |
4025 | ||
4026 | if (plotIdentifiedSpectra) { | |
4027 | for (Int_t species = 0; species < 5; species++) | |
4028 | hDeltaKaMC[slice][species]->Draw("same"); | |
4029 | ||
4030 | // Draw histo for sum of MC muons and pions | |
4031 | TH1D* hMCmuonsAndPions = new TH1D(*hDeltaKaMC[slice][kPi - 1]); | |
4032 | hMCmuonsAndPions->Add(hDeltaKaMC[slice][kMu - 1]); | |
4033 | hMCmuonsAndPions->SetLineColor(getLineColor(kMuPlusPi)); | |
4034 | hMCmuonsAndPions->SetMarkerColor(getLineColor(kMuPlusPi)); | |
4035 | hMCmuonsAndPions->SetName(Form("%s_muonsAdded", hDeltaKaMC[slice][kPi - 1]->GetName())); | |
4036 | hMCmuonsAndPions->Draw("same"); | |
4037 | } | |
4038 | ||
4039 | hDeltaKa[slice]->Draw("esame"); | |
4040 | ||
4041 | legend->Draw(); | |
4042 | ||
4043 | cSingleFit[slice][1]->cd(2); | |
4044 | hDeltaKaFitQA[slice]->GetYaxis()->SetRangeUser(fitQAaxisLowBound, fitQAaxisUpBound); | |
4045 | hDeltaKaFitQA[slice]->Draw("e"); | |
4046 | ||
4047 | hReducedChiSquarePt->SetBinContent(slice + 1, 2, reducedChiSquare); | |
4048 | ||
4049 | //TMatrixDSym covMatrixKa(nParUsed, &covMatrix[0][0]); | |
4050 | ||
4051 | setFractionsAndYields(slice, inverseBinWidth, binWidthFitHisto, kKa, parametersOut, parameterErrorsOut, hFractionKaons, | |
4052 | hFractionPionsDeltaKaon, hFractionElectronsDeltaKaon, hFractionKaonsDeltaKaon, hFractionProtonsDeltaKaon, | |
4053 | hFractionMuonsDeltaKaon, hYieldKaons, hYieldPionsDeltaKaon, hYieldElectronsDeltaKaon, hYieldKaonsDeltaKaon, | |
4054 | hYieldProtonsDeltaKaon, hYieldMuonsDeltaKaon, normaliseResults); | |
4055 | ||
4056 | ||
4057 | ||
4058 | // DeltaProtons | |
4059 | cSingleFit[slice][3]->cd(1); | |
4060 | ||
4061 | hDeltaPr[slice]->SetTitle(""); | |
4062 | SetReasonableXaxisRange(hDeltaPr[slice], binLow, binHigh); | |
4063 | hDeltaPr[slice]->Draw("e"); | |
4064 | ||
4065 | fitFuncTotalDeltaProton[slice] = (TF1*)totalDeltaProton->Clone(Form("Fit_Total_DeltaProton_%s", fitFuncSuffix.Data())); | |
4066 | ||
4067 | hDeltaPrFitQA[slice] = (TH1D*)hDeltaPr[slice]->Clone(Form("hDeltaPrFitQA_%d", slice)); | |
4068 | hDeltaPrFitQA[slice]->GetYaxis()->SetTitle("(Data - Fit) / Data"); | |
4069 | hDeltaPrFitQA[slice]->Add(fitFuncTotalDeltaProton[slice], -1); | |
4070 | hDeltaPrFitQA[slice]->Divide(hDeltaPr[slice]); | |
4071 | ||
4072 | hDeltaPr[slice]->GetListOfFunctions()->Add(fitFuncTotalDeltaProton[slice]); | |
4073 | ||
4074 | fitFuncTotalDeltaProton[slice]->Draw("same"); | |
4075 | ||
4076 | parametersOut = &totalDeltaProton->GetParameters()[0]; | |
4077 | ||
4078 | hGenDeltaPrForPiProj->Scale(parametersOut[5] * (parametersOut[0] + (muonContamination ? parametersOut[3] : 0))); | |
4079 | shiftHist(hGenDeltaPrForPiProj, parametersOut[6], useRegularisation); | |
4080 | hGenDeltaPrForPiProj->Draw("same"); | |
4081 | ||
4082 | hGenDeltaPrForKaProj->Scale(parametersOut[5] * parametersOut[1]); | |
4083 | shiftHist(hGenDeltaPrForKaProj, parametersOut[7], useRegularisation); | |
4084 | hGenDeltaPrForKaProj->Draw("same"); | |
4085 | ||
4086 | hGenDeltaPrForPrProj->Scale(parametersOut[5] * parametersOut[2]); | |
4087 | shiftHist(hGenDeltaPrForPrProj, parametersOut[8], useRegularisation); | |
4088 | hGenDeltaPrForPrProj->Draw("same"); | |
4089 | ||
4090 | hGenDeltaPrForElProj->Scale(parametersOut[5] * parametersOut[3]); | |
4091 | shiftHist(hGenDeltaPrForElProj, parametersOut[9], useRegularisation); | |
4092 | hGenDeltaPrForElProj->Draw("same"); | |
4093 | ||
4094 | if (takeIntoAccountMuons) { | |
4095 | hGenDeltaPrForMuProj->Scale(parametersOut[5] * parametersOut[4]); | |
4096 | shiftHist(hGenDeltaPrForMuProj, parametersOut[10], useRegularisation); | |
4097 | hGenDeltaPrForMuProj->Draw("same"); | |
4098 | } | |
4099 | ||
4100 | if (plotIdentifiedSpectra) { | |
4101 | for (Int_t species = 0; species < 5; species++) | |
4102 | hDeltaPrMC[slice][species]->Draw("same"); | |
4103 | ||
4104 | // Draw histo for sum of MC muons and pions | |
4105 | TH1D* hMCmuonsAndPions = new TH1D(*hDeltaPrMC[slice][kPi - 1]); | |
4106 | hMCmuonsAndPions->Add(hDeltaPrMC[slice][kMu - 1]); | |
4107 | hMCmuonsAndPions->SetLineColor(getLineColor(kMuPlusPi)); | |
4108 | hMCmuonsAndPions->SetMarkerColor(getLineColor(kMuPlusPi)); | |
4109 | hMCmuonsAndPions->SetName(Form("%s_muonsAdded", hDeltaPrMC[slice][kPi - 1]->GetName())); | |
4110 | hMCmuonsAndPions->Draw("same"); | |
4111 | } | |
4112 | ||
4113 | hDeltaPr[slice]->Draw("esame"); | |
4114 | ||
4115 | legend->Draw(); | |
4116 | ||
4117 | cSingleFit[slice][3]->cd(2); | |
4118 | hDeltaPrFitQA[slice]->GetYaxis()->SetRangeUser(fitQAaxisLowBound, fitQAaxisUpBound); | |
4119 | hDeltaPrFitQA[slice]->Draw("e"); | |
4120 | ||
4121 | hReducedChiSquarePt->SetBinContent(slice + 1, 4, reducedChiSquare); | |
4122 | ||
4123 | //TMatrixDSym covMatrixPr(nParUsed, &covMatrix[0][0]); | |
4124 | ||
4125 | Double_t normalisationFactor = 1.0; | |
4126 | normalisationFactor = setFractionsAndYields(slice, inverseBinWidth, binWidthFitHisto, kPr, parametersOut, parameterErrorsOut, | |
4127 | hFractionProtons, hFractionPionsDeltaProton, hFractionElectronsDeltaProton, | |
4128 | hFractionKaonsDeltaProton, hFractionProtonsDeltaProton, hFractionMuonsDeltaProton, | |
4129 | hYieldProtons, hYieldPionsDeltaProton, hYieldElectronsDeltaProton, | |
4130 | hYieldKaonsDeltaProton, hYieldProtonsDeltaProton, hYieldMuonsDeltaProton, | |
4131 | normaliseResults); | |
4132 | ||
4133 | // Fractions are the same for all plots -> just take deltaPion as default | |
4134 | Double_t sumFractions = hFractionPionsDeltaPion->GetBinContent(slice + 1) + | |
4135 | hFractionElectronsDeltaPion->GetBinContent(slice + 1) + (takeIntoAccountMuons ? hFractionMuonsDeltaPion->GetBinContent(slice + 1) : 0.) + | |
4136 | hFractionKaonsDeltaPion->GetBinContent(slice + 1) + hFractionProtonsDeltaPion->GetBinContent(slice + 1); | |
4137 | ||
4138 | hFractionSummed->SetBinContent(slice + 1, sumFractions); | |
4139 | hFractionSummed->SetBinError(slice + 1, | |
4140 | TMath::Sqrt(TMath::Power(hFractionPionsDeltaPion->GetBinError(slice + 1), 2) + | |
4141 | TMath::Power(hFractionElectronsDeltaPion->GetBinError(slice + 1), 2) + | |
4142 | (takeIntoAccountMuons ? TMath::Power(hFractionMuonsDeltaPion->GetBinError(slice + 1), 2) : 0.) + | |
4143 | TMath::Power(hFractionKaonsDeltaPion->GetBinError(slice + 1), 2) + | |
4144 | TMath::Power(hFractionProtonsDeltaPion->GetBinError(slice + 1), 2))); | |
4145 | ||
4146 | for (Int_t species = 0; species < 4; species++) { | |
4147 | cSingleFit[slice][species]->Modified(); | |
4148 | cSingleFit[slice][species]->Update(); | |
4149 | } | |
4150 | ||
4151 | ||
4152 | // Compute the to-pi ratios with proper error for the current slice | |
4153 | // NOTE: error and covariance matrix are already scaled for the simultaneous fit | |
4154 | // by mathFit (it was checked that all (i.e. also off-diagonal) matrix elements grow by fScaleError^2 | |
4155 | // NOTE 2: take the fractions and error from the histogram (takes correct muon and electrons fractions with errors set manually | |
4156 | // in case of fixed fraction; the parameters are fixed, so the elements of the off-diagonal elements of the covariance matrix | |
4157 | // remain zero!). The fractions are then also scaled to sum up to 1 (but correction factor usually close to unity). | |
4158 | // The covariance matrix is NOT scaled like this. Therefore, scale the matrix elements accordingly. | |
4159 | // If the normalisation is not done for the fractions, then this factor is unity by construction. | |
4160 | ||
4161 | ||
4162 | ||
4163 | Double_t covMatrixElementToPiForEl = 0.; | |
4164 | Double_t covMatrixElementToPiForMu = 0.; | |
4165 | Double_t covMatrixElementToPiForKa = 0.; | |
4166 | Double_t covMatrixElementToPiForPr = 0.; | |
4167 | ||
4168 | // Get the correct covariance matrix elements and apply the normalisation factor | |
4169 | Int_t parOffset = 0; | |
4170 | ||
4171 | // In case of regularisation, there is an offset with respect to the current slice | |
4172 | if (useRegularisation) | |
4173 | parOffset = currXbin * numParamsPerXbin; | |
4174 | ||
4175 | ||
4176 | covMatrixElementToPiForEl = covMatrix[3 + parOffset][0 + parOffset] * normalisationFactor * normalisationFactor; | |
4177 | covMatrixElementToPiForMu = covMatrix[4 + parOffset][0 + parOffset] * normalisationFactor * normalisationFactor; | |
4178 | covMatrixElementToPiForKa = covMatrix[1 + parOffset][0 + parOffset] * normalisationFactor * normalisationFactor; | |
4179 | covMatrixElementToPiForPr = covMatrix[2 + parOffset][0 + parOffset] * normalisationFactor * normalisationFactor; | |
4180 | ||
4181 | Double_t ratio = -999.; | |
4182 | Double_t ratioError = 999.; | |
4183 | Double_t currFractionSpecies = 0.; | |
4184 | Double_t currFractionPions = 0.; | |
4185 | Double_t currFractionErrorSpecies = 0.; | |
4186 | Double_t currFractionErrorPions = 0.; | |
4187 | Double_t covMatrixElementAB = 0.; // NOTE that there is only one covariance matrix (simultaneous fit!) | |
4188 | ||
4189 | currFractionPions = hFractionPions->GetBinContent(slice + 1); | |
4190 | currFractionErrorPions = hFractionPions->GetBinError(slice + 1); | |
4191 | ||
4192 | // NOTE: Even in case of regularisation, when fractions of different bins become correlated, this does NOT change | |
4193 | // the formula. Only the covariance matrix element for the considered fraction in the SAME slice needs to be taken | |
4194 | // into account. Explanation: f = f(fracA_slice, fracB_slice), this means that \dell f / \dell fracA_slice+-1 = 0 (etc.). | |
4195 | // So, the formula is the same, although the correlation between different slices is contained in the covariance matrix. | |
4196 | ||
4197 | // el-to-pi ratio | |
4198 | currFractionSpecies = hFractionElectrons->GetBinContent(slice + 1); | |
4199 | currFractionErrorSpecies = hFractionElectrons->GetBinError(slice + 1); | |
4200 | covMatrixElementAB = covMatrixElementToPiForEl; | |
4201 | ||
4202 | GetRatioWithCorrelatedError(currFractionSpecies, currFractionPions, currFractionErrorSpecies, currFractionErrorPions, | |
4203 | covMatrixElementAB, ratio, ratioError); | |
4204 | ||
4205 | hRatioToPiElectrons->SetBinContent(slice + 1, ratio); | |
4206 | hRatioToPiElectrons->SetBinError(slice + 1, ratioError); | |
4207 | ||
4208 | // mu-to-pi ratio | |
4209 | currFractionSpecies = hFractionMuons->GetBinContent(slice + 1); | |
4210 | currFractionErrorSpecies = hFractionMuons->GetBinError(slice + 1); | |
4211 | covMatrixElementAB = covMatrixElementToPiForMu; | |
4212 | ||
4213 | GetRatioWithCorrelatedError(currFractionSpecies, currFractionPions, currFractionErrorSpecies, currFractionErrorPions, | |
4214 | covMatrixElementAB, ratio, ratioError); | |
4215 | ||
4216 | hRatioToPiMuons->SetBinContent(slice + 1, ratio); | |
4217 | hRatioToPiMuons->SetBinError(slice + 1, ratioError); | |
4218 | ||
4219 | ||
4220 | // K-to-pi ratio | |
4221 | currFractionSpecies = hFractionKaons->GetBinContent(slice + 1); | |
4222 | currFractionErrorSpecies = hFractionKaons->GetBinError(slice + 1); | |
4223 | covMatrixElementAB = covMatrixElementToPiForKa; | |
4224 | ||
4225 | GetRatioWithCorrelatedError(currFractionSpecies, currFractionPions, currFractionErrorSpecies, currFractionErrorPions, | |
4226 | covMatrixElementAB, ratio, ratioError); | |
4227 | ||
4228 | hRatioToPiKaons->SetBinContent(slice + 1, ratio); | |
4229 | hRatioToPiKaons->SetBinError(slice + 1, ratioError); | |
4230 | ||
4231 | ||
4232 | // p-to-pi ratio | |
4233 | currFractionSpecies = hFractionProtons->GetBinContent(slice + 1); | |
4234 | currFractionErrorSpecies = hFractionProtons->GetBinError(slice + 1); | |
4235 | covMatrixElementAB = covMatrixElementToPiForPr; | |
4236 | ||
4237 | GetRatioWithCorrelatedError(currFractionSpecies, currFractionPions, currFractionErrorSpecies, currFractionErrorPions, | |
4238 | covMatrixElementAB, ratio, ratioError); | |
4239 | ||
4240 | hRatioToPiProtons->SetBinContent(slice + 1, ratio); | |
4241 | hRatioToPiProtons->SetBinError(slice + 1, ratioError); | |
4242 | ||
4243 | /* | |
4244 | for (Int_t i = 0; i < nParUsed; i++) { | |
4245 | for (Int_t j = 0; j < nParUsed; j++) { | |
4246 | printf("\t%e", covMatrix[i][j]); | |
4247 | } | |
4248 | printf("\n"); | |
4249 | } | |
4250 | */ | |
4251 | ||
4252 | currXbin++; | |
4253 | } | |
4254 | //_____________________________________________________________________ | |
4255 | // Other methods without simultaneous fitting | |
4256 | else { | |
4257 | Int_t binLow = -1; | |
4258 | Int_t binHigh = -1; | |
4259 | ||
4260 | // DeltaPions | |
4261 | ||
4262 | std::cout << "Fitting deltaPion...." << std::endl << std::endl; | |
4263 | ||
4264 | cSingleFit[slice][2]->cd(1); | |
4265 | ||
4266 | mathFit->ClearRefHistos(); | |
4267 | mathFit->AddRefHisto(hGenDeltaPiForPiProj); | |
4268 | mathFit->AddRefHisto(hGenDeltaPiForKaProj); | |
4269 | mathFit->AddRefHisto(hGenDeltaPiForPrProj); | |
4270 | mathFit->AddRefHisto(hGenDeltaPiForElProj); | |
4271 | if (takeIntoAccountMuons) | |
4272 | mathFit->AddRefHisto(hGenDeltaPiForMuProj); | |
4273 | ||
4274 | errFlag = errFlag | | |
4275 | doFit(hDeltaPi[slice], xLow, xUp, nPar, gausParamsPi, parameterErrorsOut, &covMatrix[0][0], | |
4276 | stepSize, lowParLimitsPi, upParLimitsPi, totalDeltaPion, reducedChiSquare); | |
4277 | ||
4278 | hDeltaPi[slice]->SetTitle(""); | |
4279 | SetReasonableXaxisRange(hDeltaPi[slice], binLow, binHigh); | |
4280 | hDeltaPi[slice]->Draw("e"); | |
4281 | ||
4282 | fitFuncTotalDeltaPion[slice] = (TF1*)totalDeltaPion->Clone(Form("Fit_Total_DeltaPion_%s", fitFuncSuffix.Data())); | |
4283 | ||
4284 | hDeltaPiFitQA[slice] = (TH1D*)hDeltaPi[slice]->Clone(Form("hDeltaPiFitQA_%d", slice)); | |
4285 | hDeltaPiFitQA[slice]->GetYaxis()->SetTitle("(Data - Fit) / Data"); | |
4286 | hDeltaPiFitQA[slice]->Add(fitFuncTotalDeltaPion[slice], -1); | |
4287 | hDeltaPiFitQA[slice]->Divide(hDeltaPi[slice]); | |
4288 | ||
4289 | hDeltaPi[slice]->GetListOfFunctions()->Add(fitFuncTotalDeltaPion[slice]); | |
4290 | fitFuncTotalDeltaPion[slice]->Draw("same"); | |
4291 | ||
4292 | Double_t* parametersOut = &gausParamsPi[0]; | |
4293 | ||
4294 | hGenDeltaPiForPiProj->Scale(gausParamsPi[5] * (gausParamsPi[0] + (muonContamination ? gausParamsPi[3] : 0))); | |
4295 | shiftHist(hGenDeltaPiForPiProj, gausParamsPi[6]); | |
4296 | hGenDeltaPiForPiProj->Draw("same"); | |
4297 | ||
4298 | hGenDeltaPiForKaProj->Scale(gausParamsPi[5] * gausParamsPi[1]); | |
4299 | shiftHist(hGenDeltaPiForKaProj, gausParamsPi[7]); | |
4300 | hGenDeltaPiForKaProj->Draw("same"); | |
4301 | ||
4302 | hGenDeltaPiForPrProj->Scale(gausParamsPi[5] * gausParamsPi[2]); | |
4303 | shiftHist(hGenDeltaPiForPrProj, gausParamsPi[8]); | |
4304 | hGenDeltaPiForPrProj->Draw("same"); | |
4305 | ||
4306 | hGenDeltaPiForElProj->Scale(gausParamsPi[5] * gausParamsPi[3]); | |
4307 | shiftHist(hGenDeltaPiForElProj, gausParamsPi[9]); | |
4308 | hGenDeltaPiForElProj->Draw("same"); | |
4309 | ||
4310 | if (takeIntoAccountMuons) { | |
4311 | hGenDeltaPiForMuProj->Scale(gausParamsPi[5] * gausParamsPi[4]); | |
4312 | shiftHist(hGenDeltaPiForMuProj, gausParamsPi[10]); | |
4313 | hGenDeltaPiForMuProj->Draw("same"); | |
4314 | } | |
4315 | ||
4316 | if (plotIdentifiedSpectra) { | |
4317 | for (Int_t species = 0; species < 5; species++) | |
4318 | hDeltaPiMC[slice][species]->Draw("same"); | |
4319 | ||
4320 | // Draw histo for sum of MC muons and pions | |
4321 | TH1D* hMCmuonsAndPions = new TH1D(*hDeltaPiMC[slice][kPi - 1]); | |
4322 | hMCmuonsAndPions->Add(hDeltaPiMC[slice][kMu - 1]); | |
4323 | hMCmuonsAndPions->SetLineColor(getLineColor(kMuPlusPi)); | |
4324 | hMCmuonsAndPions->SetMarkerColor(getLineColor(kMuPlusPi)); | |
4325 | hMCmuonsAndPions->SetName(Form("%s_muonsAdded", hDeltaPiMC[slice][kPi - 1]->GetName())); | |
4326 | hMCmuonsAndPions->Draw("same"); | |
4327 | } | |
4328 | ||
4329 | hDeltaPi[slice]->Draw("esame"); | |
4330 | ||
4331 | legend->Draw(); | |
4332 | ||
4333 | cSingleFit[slice][2]->cd(2); | |
4334 | hDeltaPiFitQA[slice]->GetYaxis()->SetRangeUser(fitQAaxisLowBound, fitQAaxisUpBound); | |
4335 | hDeltaPiFitQA[slice]->Draw("e"); | |
4336 | ||
4337 | hReducedChiSquarePt->SetBinContent(slice + 1, 3, reducedChiSquare); | |
4338 | ||
4339 | TMatrixDSym covMatrixPi(nParUsed, &covMatrix[0][0]); | |
4340 | ||
4341 | if (fitMethod == 1) { | |
4342 | // Histos are normalised => expression equals integral | |
4343 | integralPions = allDeltaPion * (parametersOut[0] + (muonContamination ? parametersOut[3] : 0)); | |
4344 | integralTotal += integralPions; | |
4345 | if (takeIntoAccountMuons) { | |
4346 | integralMuons = allDeltaPion * parametersOut[4]; | |
4347 | integralTotal += integralMuons; | |
4348 | } | |
4349 | ||
4350 | /* | |
4351 | integralErrorTotalDeltaPion = getErrorOfTotalIntegral(covMatrixPi) * allDeltaPion; | |
4352 | ||
4353 | integralErrorPions = getErrorOfPionIntegral(covMatrixPi) * allDeltaPion; | |
4354 | */ | |
4355 | ||
4356 | integralPionsDeltaPion = integralPions; | |
4357 | ||
4358 | // Compare comment above | |
4359 | integralElectronsDeltaPion = allDeltaPion * parametersOut[3]; | |
4360 | integralKaonsDeltaPion = allDeltaPion * parametersOut[1]; | |
4361 | integralProtonsDeltaPion = allDeltaPion * parametersOut[2]; | |
4362 | integralMuonsDeltaPion = allDeltaPion * parametersOut[4]; | |
4363 | ||
4364 | /* | |
4365 | integralErrorPionsDeltaPion = integralErrorPions; | |
4366 | ||
4367 | integralErrorElectronsDeltaPion = allDeltaPion * parameterErrorsOut[3]; | |
4368 | integralErrorKaonsDeltaPion = allDeltaPion * parameterErrorsOut[1]; | |
4369 | integralErrorProtonsDeltaPion = allDeltaPion * parameterErrorsOut[2]; | |
4370 | */ | |
4371 | } | |
4372 | else { | |
4373 | setFractionsAndYields(slice, inverseBinWidth, binWidthFitHisto, kPi, parametersOut, parameterErrorsOut, hFractionPions, | |
4374 | hFractionPionsDeltaPion, hFractionElectronsDeltaPion, hFractionKaonsDeltaPion, | |
4375 | hFractionProtonsDeltaPion, hFractionMuonsDeltaPion, hYieldPions, hYieldPionsDeltaPion, hYieldElectronsDeltaPion, | |
4376 | hYieldKaonsDeltaPion, hYieldProtonsDeltaPion, hYieldMuonsDeltaPion); | |
4377 | ||
4378 | // Also set specific muon fractions and yields -> The deltaSpecies histos are not needed here: They will be set together with | |
4379 | // the fraction and yields for all other species | |
4380 | setFractionsAndYields(slice, inverseBinWidth, binWidthFitHisto, kMu, parametersOut, parameterErrorsOut, hFractionMuons, | |
4381 | 0x0, 0x0, 0x0, 0x0, 0x0, hYieldMuons, 0x0, 0x0, 0x0, 0x0, 0x0); | |
4382 | } | |
4383 | ||
4384 | ||
4385 | std::cout << std::endl << std::endl; | |
4386 | ||
4387 | ||
4388 | // DeltaElectrons | |
4389 | ||
4390 | std::cout << "Fitting deltaElectron...." << std::endl << std::endl; | |
4391 | ||
4392 | cSingleFit[slice][0]->cd(1); | |
4393 | ||
4394 | mathFit->ClearRefHistos(); | |
4395 | mathFit->AddRefHisto(hGenDeltaElForPiProj); | |
4396 | mathFit->AddRefHisto(hGenDeltaElForKaProj); | |
4397 | mathFit->AddRefHisto(hGenDeltaElForPrProj); | |
4398 | mathFit->AddRefHisto(hGenDeltaElForElProj); | |
4399 | if (takeIntoAccountMuons) | |
4400 | mathFit->AddRefHisto(hGenDeltaElForMuProj); | |
4401 | ||
4402 | errFlag = errFlag | | |
4403 | doFit(hDeltaEl[slice], xLow, xUp, nPar, gausParamsEl, parameterErrorsOut, &covMatrix[0][0], | |
4404 | stepSize, lowParLimitsEl, upParLimitsEl, totalDeltaElectron, reducedChiSquare); | |
4405 | ||
4406 | hDeltaEl[slice]->SetTitle(""); | |
4407 | SetReasonableXaxisRange(hDeltaEl[slice], binLow, binHigh); | |
4408 | hDeltaEl[slice]->Draw("e"); | |
4409 | ||
4410 | fitFuncTotalDeltaElectron[slice] = (TF1*)totalDeltaElectron->Clone(Form("Fit_Total_DeltaElectron_%s", fitFuncSuffix.Data())); | |
4411 | ||
4412 | hDeltaElFitQA[slice] = (TH1D*)hDeltaEl[slice]->Clone(Form("hDeltaElFitQA_%d", slice)); | |
4413 | hDeltaElFitQA[slice]->GetYaxis()->SetTitle("(Data - Fit) / Data"); | |
4414 | hDeltaElFitQA[slice]->Add(fitFuncTotalDeltaElectron[slice], -1); | |
4415 | hDeltaElFitQA[slice]->Divide(hDeltaEl[slice]); | |
4416 | ||
4417 | hDeltaEl[slice]->GetListOfFunctions()->Add(fitFuncTotalDeltaElectron[slice]); | |
4418 | fitFuncTotalDeltaElectron[slice]->Draw("same"); | |
4419 | ||
4420 | parametersOut = &gausParamsEl[0]; | |
4421 | ||
4422 | hGenDeltaElForPiProj->Scale(gausParamsEl[5] * (gausParamsEl[0] + (muonContamination ? gausParamsEl[3] : 0))); | |
4423 | shiftHist(hGenDeltaElForPiProj, gausParamsEl[6]); | |
4424 | hGenDeltaElForPiProj->Draw("same"); | |
4425 | ||
4426 | hGenDeltaElForKaProj->Scale(gausParamsEl[5] * gausParamsEl[1]); | |
4427 | shiftHist(hGenDeltaElForKaProj, gausParamsEl[7]); | |
4428 | hGenDeltaElForKaProj->Draw("same"); | |
4429 | ||
4430 | hGenDeltaElForPrProj->Scale(gausParamsEl[5] * gausParamsEl[2]); | |
4431 | shiftHist(hGenDeltaElForPrProj, gausParamsEl[8]); | |
4432 | hGenDeltaElForPrProj->Draw("same"); | |
4433 | ||
4434 | hGenDeltaElForElProj->Scale(gausParamsEl[5] * gausParamsEl[3]); | |
4435 | shiftHist(hGenDeltaElForElProj, gausParamsEl[9]); | |
4436 | hGenDeltaElForElProj->Draw("same"); | |
4437 | ||
4438 | if (takeIntoAccountMuons) { | |
4439 | hGenDeltaElForMuProj->Scale(gausParamsEl[5] * gausParamsEl[4]); | |
4440 | shiftHist(hGenDeltaElForMuProj, gausParamsEl[10]); | |
4441 | hGenDeltaElForMuProj->Draw("same"); | |
4442 | } | |
4443 | ||
4444 | if (plotIdentifiedSpectra) { | |
4445 | for (Int_t species = 0; species < 5; species++) | |
4446 | hDeltaElMC[slice][species]->Draw("same"); | |
4447 | ||
4448 | // Draw histo for sum of MC muons and pions | |
4449 | TH1D* hMCmuonsAndPions = new TH1D(*hDeltaElMC[slice][kPi - 1]); | |
4450 | hMCmuonsAndPions->Add(hDeltaElMC[slice][kMu - 1]); | |
4451 | hMCmuonsAndPions->SetLineColor(getLineColor(kMuPlusPi)); | |
4452 | hMCmuonsAndPions->SetMarkerColor(getLineColor(kMuPlusPi)); | |
4453 | hMCmuonsAndPions->SetName(Form("%s_muonsAdded", hDeltaElMC[slice][kPi - 1]->GetName())); | |
4454 | hMCmuonsAndPions->Draw("same"); | |
4455 | } | |
4456 | ||
4457 | hDeltaEl[slice]->Draw("esame"); | |
4458 | ||
4459 | legend->Draw(); | |
4460 | ||
4461 | cSingleFit[slice][0]->cd(2); | |
4462 | hDeltaElFitQA[slice]->GetYaxis()->SetRangeUser(fitQAaxisLowBound, fitQAaxisUpBound); | |
4463 | hDeltaElFitQA[slice]->Draw("e"); | |
4464 | ||
4465 | hReducedChiSquarePt->SetBinContent(slice + 1, 1, reducedChiSquare); | |
4466 | ||
4467 | TMatrixDSym covMatrixEl(nParUsed, &covMatrix[0][0]); | |
4468 | ||
4469 | if (fitMethod == 1) { | |
4470 | integralElectrons = allDeltaElectron * parametersOut[3]; // Histos are normalised => expression equals integral | |
4471 | integralTotal += integralElectrons; | |
4472 | ||
4473 | /* | |
4474 | integralErrorTotalDeltaElectron = getErrorOfTotalIntegral(covMatrixEl) * allDeltaElectron; | |
4475 | ||
4476 | integralErrorElectrons = allDeltaElectron * parameterErrorsOut[3]; | |
4477 | */ | |
4478 | ||
4479 | // Factor 2 in case of takeIntoAccountMuons will be applied below | |
4480 | integralElectronsDeltaElectron = integralElectrons; | |
4481 | ||
4482 | // Compare comment above | |
4483 | integralPionsDeltaElectron = allDeltaElectron * (parametersOut[0] + (muonContamination ? parametersOut[3] : 0)); | |
4484 | integralKaonsDeltaElectron = allDeltaElectron * parametersOut[1]; | |
4485 | integralProtonsDeltaElectron = allDeltaElectron * parametersOut[2]; | |
4486 | integralMuonsDeltaElectron = allDeltaElectron * parametersOut[4]; | |
4487 | ||
4488 | ||
4489 | /* | |
4490 | integralErrorElectronsDeltaElectron = integralErrorElectrons; | |
4491 | ||
4492 | integralErrorPionsDeltaElectron = getErrorOfPionIntegral(covMatrixEl) * allDeltaElectron; | |
4493 | integralErrorKaonsDeltaElectron = allDeltaElectron * parameterErrorsOut[1]; | |
4494 | integralErrorProtonsDeltaElectron = allDeltaElectron * parameterErrorsOut[2]; | |
4495 | */ | |
4496 | } | |
4497 | else { | |
4498 | setFractionsAndYields(slice, inverseBinWidth, binWidthFitHisto, kEl, parametersOut, parameterErrorsOut, hFractionElectrons, | |
4499 | hFractionPionsDeltaElectron, hFractionElectronsDeltaElectron, hFractionKaonsDeltaElectron, | |
4500 | hFractionProtonsDeltaElectron, hFractionMuonsDeltaElectron, hYieldElectrons, hYieldPionsDeltaElectron, | |
4501 | hYieldElectronsDeltaElectron, hYieldKaonsDeltaElectron, hYieldProtonsDeltaElectron, hYieldMuonsDeltaElectron); | |
4502 | } | |
4503 | ||
4504 | std::cout << std::endl << std::endl; | |
4505 | ||
4506 | // DeltaKaons | |
4507 | ||
4508 | std::cout << "Fitting deltaKaon...." << std::endl << std::endl; | |
4509 | ||
4510 | cSingleFit[slice][1]->cd(1); | |
4511 | ||
4512 | mathFit->ClearRefHistos(); | |
4513 | mathFit->AddRefHisto(hGenDeltaKaForPiProj); | |
4514 | mathFit->AddRefHisto(hGenDeltaKaForKaProj); | |
4515 | mathFit->AddRefHisto(hGenDeltaKaForPrProj); | |
4516 | mathFit->AddRefHisto(hGenDeltaKaForElProj); | |
4517 | if (takeIntoAccountMuons) | |
4518 | mathFit->AddRefHisto(hGenDeltaKaForMuProj); | |
4519 | ||
4520 | errFlag = errFlag | | |
4521 | doFit(hDeltaKa[slice], xLow, xUp, nPar, gausParamsKa, parameterErrorsOut, &covMatrix[0][0], | |
4522 | stepSize, lowParLimitsKa, upParLimitsKa, totalDeltaKaon, reducedChiSquare); | |
4523 | ||
4524 | hDeltaKa[slice]->SetTitle(""); | |
4525 | SetReasonableXaxisRange(hDeltaKa[slice], binLow, binHigh); | |
4526 | hDeltaKa[slice]->Draw("e"); | |
4527 | ||
4528 | fitFuncTotalDeltaKaon[slice] = (TF1*)totalDeltaKaon->Clone(Form("Fit_Total_DeltaKaon_%s", fitFuncSuffix.Data())); | |
4529 | ||
4530 | hDeltaKaFitQA[slice] = (TH1D*)hDeltaKa[slice]->Clone(Form("hDeltaKaFitQA_%d", slice)); | |
4531 | hDeltaKaFitQA[slice]->GetYaxis()->SetTitle("(Data - Fit) / Data"); | |
4532 | hDeltaKaFitQA[slice]->Add(fitFuncTotalDeltaKaon[slice], -1); | |
4533 | hDeltaKaFitQA[slice]->Divide(hDeltaKa[slice]); | |
4534 | ||
4535 | hDeltaKa[slice]->GetListOfFunctions()->Add(fitFuncTotalDeltaKaon[slice]); | |
4536 | fitFuncTotalDeltaKaon[slice]->Draw("same"); | |
4537 | ||
4538 | parametersOut = &gausParamsKa[0]; | |
4539 | ||
4540 | hGenDeltaKaForPiProj->Scale(gausParamsKa[5] * (gausParamsKa[0] + (muonContamination ? gausParamsKa[3] : 0))); | |
4541 | shiftHist(hGenDeltaKaForPiProj, gausParamsKa[6]); | |
4542 | hGenDeltaKaForPiProj->Draw("same"); | |
4543 | ||
4544 | hGenDeltaKaForKaProj->Scale(gausParamsKa[5] * gausParamsKa[1]); | |
4545 | shiftHist(hGenDeltaKaForKaProj, gausParamsKa[7]); | |
4546 | hGenDeltaKaForKaProj->Draw("same"); | |
4547 | ||
4548 | hGenDeltaKaForPrProj->Scale(gausParamsKa[5] * gausParamsKa[2]); | |
4549 | shiftHist(hGenDeltaKaForPrProj, gausParamsKa[8]); | |
4550 | hGenDeltaKaForPrProj->Draw("same"); | |
4551 | ||
4552 | hGenDeltaKaForElProj->Scale(gausParamsKa[5] * gausParamsKa[3]); | |
4553 | shiftHist(hGenDeltaKaForElProj, gausParamsKa[9]); | |
4554 | hGenDeltaKaForElProj->Draw("same"); | |
4555 | ||
4556 | if (takeIntoAccountMuons) { | |
4557 | hGenDeltaKaForMuProj->Scale(gausParamsKa[5] * gausParamsKa[4]); | |
4558 | shiftHist(hGenDeltaKaForMuProj, gausParamsKa[10]); | |
4559 | hGenDeltaKaForMuProj->Draw("same"); | |
4560 | } | |
4561 | ||
4562 | if (plotIdentifiedSpectra) { | |
4563 | for (Int_t species = 0; species < 5; species++) | |
4564 | hDeltaKaMC[slice][species]->Draw("same"); | |
4565 | ||
4566 | // Draw histo for sum of MC muons and pions | |
4567 | TH1D* hMCmuonsAndPions = new TH1D(*hDeltaKaMC[slice][kPi - 1]); | |
4568 | hMCmuonsAndPions->Add(hDeltaKaMC[slice][kMu - 1]); | |
4569 | hMCmuonsAndPions->SetLineColor(getLineColor(kMuPlusPi)); | |
4570 | hMCmuonsAndPions->SetMarkerColor(getLineColor(kMuPlusPi)); | |
4571 | hMCmuonsAndPions->SetName(Form("%s_muonsAdded", hDeltaKaMC[slice][kPi - 1]->GetName())); | |
4572 | hMCmuonsAndPions->Draw("same"); | |
4573 | } | |
4574 | ||
4575 | hDeltaKa[slice]->Draw("esame"); | |
4576 | ||
4577 | legend->Draw(); | |
4578 | ||
4579 | cSingleFit[slice][1]->cd(2); | |
4580 | hDeltaKaFitQA[slice]->GetYaxis()->SetRangeUser(fitQAaxisLowBound, fitQAaxisUpBound); | |
4581 | hDeltaKaFitQA[slice]->Draw("e"); | |
4582 | ||
4583 | hReducedChiSquarePt->SetBinContent(slice + 1, 2, reducedChiSquare); | |
4584 | ||
4585 | TMatrixDSym covMatrixKa(nParUsed, &covMatrix[0][0]); | |
4586 | ||
4587 | if (fitMethod == 1) { | |
4588 | integralKaons = allDeltaKaon * parametersOut[1]; // Histos are normalised => expression equals integral | |
4589 | integralTotal += integralKaons; | |
4590 | /* | |
4591 | integralErrorTotalDeltaKaon = getErrorOfTotalIntegral(covMatrixKa) * allDeltaKaon; | |
4592 | ||
4593 | integralErrorKaons = allDeltaKaon * parameterErrorsOut[1]; | |
4594 | */ | |
4595 | ||
4596 | ||
4597 | integralKaonsDeltaKaon = integralKaons; | |
4598 | ||
4599 | // Compare comment above | |
4600 | integralPionsDeltaKaon = allDeltaKaon * (parametersOut[0] + (muonContamination ? parametersOut[3] : 0)); | |
4601 | integralElectronsDeltaKaon = allDeltaKaon * parametersOut[3]; | |
4602 | integralProtonsDeltaKaon = allDeltaKaon * parametersOut[2]; | |
4603 | integralMuonsDeltaKaon = allDeltaKaon * parametersOut[4]; | |
4604 | ||
4605 | /* | |
4606 | integralErrorKaonsDeltaKaon = integralErrorKaons; | |
4607 | ||
4608 | integralErrorPionsDeltaKaon = getErrorOfPionIntegral(covMatrixKa) * allDeltaKaon; | |
4609 | integralErrorElectronsDeltaKaon = allDeltaKaon * parameterErrorsOut[3]; | |
4610 | integralErrorProtonsDeltaKaon = allDeltaKaon * parameterErrorsOut[2]; | |
4611 | */ | |
4612 | } | |
4613 | else { | |
4614 | setFractionsAndYields(slice, inverseBinWidth, binWidthFitHisto, kKa, parametersOut, parameterErrorsOut, hFractionKaons, | |
4615 | hFractionPionsDeltaKaon, hFractionElectronsDeltaKaon, hFractionKaonsDeltaKaon, hFractionProtonsDeltaKaon, | |
4616 | hFractionMuonsDeltaKaon, hYieldKaons, hYieldPionsDeltaKaon, hYieldElectronsDeltaKaon, hYieldKaonsDeltaKaon, | |
4617 | hYieldProtonsDeltaKaon, hYieldMuonsDeltaKaon); | |
4618 | } | |
4619 | ||
4620 | std::cout << std::endl << std::endl; | |
4621 | ||
4622 | ||
4623 | // DeltaProtons | |
4624 | ||
4625 | std::cout << "Fitting deltaProton...." << std::endl << std::endl; | |
4626 | ||
4627 | cSingleFit[slice][3]->cd(1); | |
4628 | ||
4629 | mathFit->ClearRefHistos(); | |
4630 | mathFit->AddRefHisto(hGenDeltaPrForPiProj); | |
4631 | mathFit->AddRefHisto(hGenDeltaPrForKaProj); | |
4632 | mathFit->AddRefHisto(hGenDeltaPrForPrProj); | |
4633 | mathFit->AddRefHisto(hGenDeltaPrForElProj); | |
4634 | if (takeIntoAccountMuons) | |
4635 | mathFit->AddRefHisto(hGenDeltaPrForMuProj); | |
4636 | ||
4637 | errFlag = errFlag | | |
4638 | doFit(hDeltaPr[slice], xLow, xUp, nPar, gausParamsPr, parameterErrorsOut, &covMatrix[0][0], | |
4639 | stepSize, lowParLimitsPr, upParLimitsPr, totalDeltaProton, reducedChiSquare); | |
4640 | ||
4641 | hDeltaPr[slice]->SetTitle(""); | |
4642 | SetReasonableXaxisRange(hDeltaPr[slice], binLow, binHigh); | |
4643 | hDeltaPr[slice]->Draw("e"); | |
4644 | ||
4645 | fitFuncTotalDeltaProton[slice] = (TF1*)totalDeltaProton->Clone(Form("Fit_Total_DeltaProton_%s", fitFuncSuffix.Data())); | |
4646 | ||
4647 | hDeltaPrFitQA[slice] = (TH1D*)hDeltaPr[slice]->Clone(Form("hDeltaPrFitQA_%d", slice)); | |
4648 | hDeltaPrFitQA[slice]->GetYaxis()->SetTitle("(Data - Fit) / Data"); | |
4649 | hDeltaPrFitQA[slice]->Add(fitFuncTotalDeltaProton[slice], -1); | |
4650 | hDeltaPrFitQA[slice]->Divide(hDeltaPr[slice]); | |
4651 | ||
4652 | hDeltaPr[slice]->GetListOfFunctions()->Add(fitFuncTotalDeltaProton[slice]); | |
4653 | ||
4654 | fitFuncTotalDeltaProton[slice]->Draw("same"); | |
4655 | ||
4656 | parametersOut = &gausParamsPr[0]; | |
4657 | ||
4658 | hGenDeltaPrForPiProj->Scale(gausParamsPr[5] * (gausParamsPr[0] + (muonContamination ? gausParamsPr[3] : 0))); | |
4659 | shiftHist(hGenDeltaPrForPiProj, gausParamsPr[6]); | |
4660 | hGenDeltaPrForPiProj->Draw("same"); | |
4661 | ||
4662 | hGenDeltaPrForKaProj->Scale(gausParamsPr[5] * gausParamsPr[1]); | |
4663 | shiftHist(hGenDeltaPrForKaProj, gausParamsPr[7]); | |
4664 | hGenDeltaPrForKaProj->Draw("same"); | |
4665 | ||
4666 | hGenDeltaPrForPrProj->Scale(gausParamsPr[5] * gausParamsPr[2]); | |
4667 | shiftHist(hGenDeltaPrForPrProj, gausParamsPr[8]); | |
4668 | hGenDeltaPrForPrProj->Draw("same"); | |
4669 | ||
4670 | hGenDeltaPrForElProj->Scale(gausParamsPr[5] * gausParamsPr[3]); | |
4671 | shiftHist(hGenDeltaPrForElProj, gausParamsPr[9]); | |
4672 | hGenDeltaPrForElProj->Draw("same"); | |
4673 | ||
4674 | if (takeIntoAccountMuons) { | |
4675 | hGenDeltaPrForMuProj->Scale(gausParamsPr[5] * gausParamsPr[4]); | |
4676 | shiftHist(hGenDeltaPrForMuProj, gausParamsPr[10]); | |
4677 | hGenDeltaPrForMuProj->Draw("same"); | |
4678 | } | |
4679 | ||
4680 | if (plotIdentifiedSpectra) { | |
4681 | for (Int_t species = 0; species < 5; species++) | |
4682 | hDeltaPrMC[slice][species]->Draw("same"); | |
4683 | ||
4684 | // Draw histo for sum of MC muons and pions | |
4685 | TH1D* hMCmuonsAndPions = new TH1D(*hDeltaPrMC[slice][kPi - 1]); | |
4686 | hMCmuonsAndPions->Add(hDeltaPrMC[slice][kMu - 1]); | |
4687 | hMCmuonsAndPions->SetLineColor(getLineColor(kMuPlusPi)); | |
4688 | hMCmuonsAndPions->SetMarkerColor(getLineColor(kMuPlusPi)); | |
4689 | hMCmuonsAndPions->SetName(Form("%s_muonsAdded", hDeltaPrMC[slice][kPi - 1]->GetName())); | |
4690 | hMCmuonsAndPions->Draw("same"); | |
4691 | } | |
4692 | ||
4693 | hDeltaPr[slice]->Draw("esame"); | |
4694 | ||
4695 | legend->Draw(); | |
4696 | ||
4697 | cSingleFit[slice][3]->cd(2); | |
4698 | hDeltaPrFitQA[slice]->GetYaxis()->SetRangeUser(fitQAaxisLowBound, fitQAaxisUpBound); | |
4699 | hDeltaPrFitQA[slice]->Draw("e"); | |
4700 | ||
4701 | hReducedChiSquarePt->SetBinContent(slice + 1, 4, reducedChiSquare); | |
4702 | ||
4703 | TMatrixDSym covMatrixPr(nParUsed, &covMatrix[0][0]); | |
4704 | ||
4705 | if (fitMethod == 1) { | |
4706 | integralProtons = allDeltaProton * parametersOut[2]; // Histos are normalised => expression equals integral | |
4707 | integralTotal += integralProtons; | |
4708 | /* | |
4709 | integralErrorTotalDeltaProton = getErrorOfTotalIntegral(covMatrixPr) * allDeltaProton; | |
4710 | ||
4711 | integralErrorProtons = allDeltaProton * parameterErrorsOut[2]; | |
4712 | */ | |
4713 | ||
4714 | integralProtonsDeltaProton = integralProtons; | |
4715 | ||
4716 | // Compare comment above | |
4717 | integralPionsDeltaProton = allDeltaProton * (parametersOut[0] + (muonContamination ? parametersOut[3] : 0)); | |
4718 | integralElectronsDeltaProton = allDeltaProton * parametersOut[3]; | |
4719 | integralKaonsDeltaProton = allDeltaProton * parametersOut[1]; | |
4720 | integralMuonsDeltaProton = allDeltaProton * parametersOut[4]; | |
4721 | ||
4722 | ||
4723 | /* | |
4724 | integralErrorProtonsDeltaProton = integralErrorProtons; | |
4725 | ||
4726 | integralErrorPionsDeltaProton = getErrorOfPionIntegral(covMatrixPr) * allDeltaProton; | |
4727 | integralErrorElectronsDeltaProton = allDeltaProton * parameterErrorsOut[3]; | |
4728 | integralErrorKaonsDeltaProton = allDeltaProton * parameterErrorsOut[1]; | |
4729 | */ | |
4730 | } | |
4731 | else { | |
4732 | setFractionsAndYields(slice, inverseBinWidth, binWidthFitHisto, kPr, parametersOut, parameterErrorsOut, hFractionProtons, | |
4733 | hFractionPionsDeltaProton, hFractionElectronsDeltaProton, hFractionKaonsDeltaProton, | |
4734 | hFractionProtonsDeltaProton, hFractionMuonsDeltaProton, hYieldProtons, hYieldPionsDeltaProton, | |
4735 | hYieldElectronsDeltaProton, hYieldKaonsDeltaProton, hYieldProtonsDeltaProton, hYieldMuonsDeltaProton); | |
4736 | } | |
4737 | ||
4738 | std::cout << std::endl << std::endl; | |
4739 | ||
4740 | ||
4741 | if (fitMethod == 1) { | |
4742 | // Calculate fractions and yields for method 1 | |
4743 | if (integralTotal > 0) { | |
4744 | ||
4745 | Double_t sumOfParticles = 0; | |
4746 | ||
4747 | // Check fraction and yield determination for systematics | |
4748 | // DeltaPion | |
4749 | Double_t integralTotalDeltaPion = integralPionsDeltaPion + integralElectronsDeltaPion + | |
4750 | (takeIntoAccountMuons ? integralMuonsDeltaPion : 0.) + | |
4751 | integralKaonsDeltaPion + integralProtonsDeltaPion; | |
4752 | totalDeltaPion->GetParameters(parametersOut); | |
4753 | ||
4754 | Double_t pionFractionDeltaPion = saveDivide(integralPionsDeltaPion, integralTotalDeltaPion); | |
4755 | Double_t pionFractionErrorDeltaPion = getErrorOfPionFraction(parametersOut, covMatrixPi); | |
4756 | hFractionPionsDeltaPion->SetBinContent(slice + 1, pionFractionDeltaPion); | |
4757 | hFractionPionsDeltaPion->SetBinError(slice + 1, pionFractionErrorDeltaPion); | |
4758 | ||
4759 | Double_t electronFractionDeltaPion = saveDivide(integralElectronsDeltaPion, integralTotalDeltaPion); | |
4760 | Double_t electronFractionErrorDeltaPion = getErrorOfElectronFraction(parametersOut, covMatrixPi); | |
4761 | hFractionElectronsDeltaPion->SetBinContent(slice + 1, electronFractionDeltaPion); | |
4762 | hFractionElectronsDeltaPion->SetBinError(slice + 1, electronFractionErrorDeltaPion); | |
4763 | ||
4764 | Double_t kaonFractionDeltaPion = saveDivide(integralKaonsDeltaPion, integralTotalDeltaPion); | |
4765 | Double_t kaonFractionErrorDeltaPion = getErrorOfKaonFraction(parametersOut, covMatrixPi); | |
4766 | hFractionKaonsDeltaPion->SetBinContent(slice + 1, kaonFractionDeltaPion); | |
4767 | hFractionKaonsDeltaPion->SetBinError(slice + 1, kaonFractionErrorDeltaPion); | |
4768 | ||
4769 | Double_t protonFractionDeltaPion = saveDivide(integralProtonsDeltaPion, integralTotalDeltaPion); | |
4770 | Double_t protonFractionErrorDeltaPion = getErrorOfProtonFraction(parametersOut, covMatrixPi); | |
4771 | hFractionProtonsDeltaPion->SetBinContent(slice + 1, protonFractionDeltaPion); | |
4772 | hFractionProtonsDeltaPion->SetBinError(slice + 1, protonFractionErrorDeltaPion); | |
4773 | ||
4774 | Double_t muonFractionDeltaPion = saveDivide(integralMuonsDeltaPion, integralTotalDeltaPion); | |
4775 | // TODO Error is anyway not implemented correctly. Just take electron error as an approximation | |
4776 | Double_t muonFractionErrorDeltaPion = getErrorOfElectronFraction(parametersOut, covMatrixPi); | |
4777 | hFractionMuonsDeltaPion->SetBinContent(slice + 1, muonFractionDeltaPion); | |
4778 | hFractionMuonsDeltaPion->SetBinError(slice + 1, muonFractionErrorDeltaPion); | |
4779 | ||
4780 | sumOfParticles = inverseBinWidth * gausParamsPi[5] / binWidthFitHisto; // Divide by binWidthFitHisto, since gausParamsXX includes this width | |
4781 | ||
4782 | hYieldPionsDeltaPion->SetBinContent(slice + 1, sumOfParticles * hFractionPionsDeltaPion->GetBinContent(slice + 1)); | |
4783 | hYieldPionsDeltaPion->SetBinError(slice + 1, sumOfParticles * hFractionPionsDeltaPion->GetBinError(slice + 1)); | |
4784 | hYieldElectronsDeltaPion->SetBinContent(slice + 1, sumOfParticles * hFractionElectronsDeltaPion->GetBinContent(slice + 1)); | |
4785 | hYieldElectronsDeltaPion->SetBinError(slice + 1, sumOfParticles * hFractionElectronsDeltaPion->GetBinError(slice + 1)); | |
4786 | hYieldKaonsDeltaPion->SetBinContent(slice + 1, sumOfParticles * hFractionKaonsDeltaPion->GetBinContent(slice + 1)); | |
4787 | hYieldKaonsDeltaPion->SetBinError(slice + 1, sumOfParticles * hFractionKaonsDeltaPion->GetBinError(slice + 1)); | |
4788 | hYieldProtonsDeltaPion->SetBinContent(slice + 1, sumOfParticles * hFractionProtonsDeltaPion->GetBinContent(slice + 1)); | |
4789 | hYieldProtonsDeltaPion->SetBinError(slice + 1, sumOfParticles * hFractionProtonsDeltaPion->GetBinError(slice + 1)); | |
4790 | hYieldMuonsDeltaPion->SetBinContent(slice + 1, sumOfParticles * hFractionMuonsDeltaPion->GetBinContent(slice + 1)); | |
4791 | hYieldMuonsDeltaPion->SetBinError(slice + 1, sumOfParticles * hFractionMuonsDeltaPion->GetBinError(slice + 1)); | |
4792 | ||
4793 | ||
4794 | // DeltaElectron | |
4795 | Double_t integralTotalDeltaElectron = integralPionsDeltaElectron + integralElectronsDeltaElectron + | |
4796 | (takeIntoAccountMuons ? integralMuonsDeltaElectron : 0.) + | |
4797 | integralKaonsDeltaElectron + integralProtonsDeltaElectron; | |
4798 | totalDeltaElectron->GetParameters(parametersOut); | |
4799 | ||
4800 | Double_t pionFractionDeltaElectron = saveDivide(integralPionsDeltaElectron, integralTotalDeltaElectron); | |
4801 | Double_t pionFractionErrorDeltaElectron = getErrorOfPionFraction(parametersOut, covMatrixEl); | |
4802 | hFractionPionsDeltaElectron->SetBinContent(slice + 1, pionFractionDeltaElectron); | |
4803 | hFractionPionsDeltaElectron->SetBinError(slice + 1, pionFractionErrorDeltaElectron); | |
4804 | ||
4805 | Double_t electronFractionDeltaElectron = saveDivide(integralElectronsDeltaElectron, integralTotalDeltaElectron); | |
4806 | Double_t electronFractionErrorDeltaElectron = getErrorOfElectronFraction(parametersOut, covMatrixEl); | |
4807 | hFractionElectronsDeltaElectron->SetBinContent(slice + 1, electronFractionDeltaElectron); | |
4808 | hFractionElectronsDeltaElectron->SetBinError(slice + 1, electronFractionErrorDeltaElectron); | |
4809 | ||
4810 | Double_t kaonFractionDeltaElectron = saveDivide(integralKaonsDeltaElectron, integralTotalDeltaElectron); | |
4811 | Double_t kaonFractionErrorDeltaElectron = getErrorOfKaonFraction(parametersOut, covMatrixEl); | |
4812 | hFractionKaonsDeltaElectron->SetBinContent(slice + 1, kaonFractionDeltaElectron); | |
4813 | hFractionKaonsDeltaElectron->SetBinError(slice + 1, kaonFractionErrorDeltaElectron); | |
4814 | ||
4815 | Double_t protonFractionDeltaElectron = saveDivide(integralProtonsDeltaElectron, integralTotalDeltaElectron); | |
4816 | Double_t protonFractionErrorDeltaElectron = getErrorOfProtonFraction(parametersOut, covMatrixEl); | |
4817 | hFractionProtonsDeltaElectron->SetBinContent(slice + 1, protonFractionDeltaElectron); | |
4818 | hFractionProtonsDeltaElectron->SetBinError(slice + 1, protonFractionErrorDeltaElectron); | |
4819 | ||
4820 | Double_t muonFractionDeltaElectron = saveDivide(integralMuonsDeltaElectron, integralTotalDeltaElectron); | |
4821 | // TODO Error is anyway not implemented correctly. Just take electron error as an approximation | |
4822 | Double_t muonFractionErrorDeltaElectron = getErrorOfElectronFraction(parametersOut, covMatrixEl); | |
4823 | hFractionMuonsDeltaElectron->SetBinContent(slice + 1, muonFractionDeltaElectron); | |
4824 | hFractionMuonsDeltaElectron->SetBinError(slice + 1, muonFractionErrorDeltaElectron); | |
4825 | ||
4826 | sumOfParticles = inverseBinWidth * gausParamsEl[5] / binWidthFitHisto; // Divide by binWidthFitHisto, since gausParamsXX includes this width | |
4827 | ||
4828 | hYieldPionsDeltaElectron->SetBinContent(slice + 1, sumOfParticles * hFractionPionsDeltaElectron->GetBinContent(slice + 1)); | |
4829 | hYieldPionsDeltaElectron->SetBinError(slice + 1, sumOfParticles * hFractionPionsDeltaElectron->GetBinError(slice + 1)); | |
4830 | hYieldElectronsDeltaElectron->SetBinContent(slice + 1, sumOfParticles * hFractionElectronsDeltaElectron->GetBinContent(slice + 1)); | |
4831 | hYieldElectronsDeltaElectron->SetBinError(slice + 1, sumOfParticles * hFractionElectronsDeltaElectron->GetBinError(slice + 1)); | |
4832 | hYieldKaonsDeltaElectron->SetBinContent(slice + 1, sumOfParticles * hFractionKaonsDeltaElectron->GetBinContent(slice + 1)); | |
4833 | hYieldKaonsDeltaElectron->SetBinError(slice + 1, sumOfParticles * hFractionKaonsDeltaElectron->GetBinError(slice + 1)); | |
4834 | hYieldProtonsDeltaElectron->SetBinContent(slice + 1, sumOfParticles * hFractionProtonsDeltaElectron->GetBinContent(slice + 1)); | |
4835 | hYieldProtonsDeltaElectron->SetBinError(slice + 1, sumOfParticles * hFractionProtonsDeltaElectron->GetBinError(slice + 1)); | |
4836 | hYieldMuonsDeltaElectron->SetBinContent(slice + 1, sumOfParticles * hFractionMuonsDeltaElectron->GetBinContent(slice + 1)); | |
4837 | hYieldMuonsDeltaElectron->SetBinError(slice + 1, sumOfParticles * hFractionMuonsDeltaElectron->GetBinError(slice + 1)); | |
4838 | ||
4839 | ||
4840 | // DeltaKaon | |
4841 | Double_t integralTotalDeltaKaon = integralPionsDeltaKaon + integralElectronsDeltaKaon + | |
4842 | (takeIntoAccountMuons ? integralMuonsDeltaKaon : 0.) + | |
4843 | integralKaonsDeltaKaon + integralProtonsDeltaKaon; | |
4844 | totalDeltaKaon->GetParameters(parametersOut); | |
4845 | ||
4846 | Double_t pionFractionDeltaKaon = saveDivide(integralPionsDeltaKaon, integralTotalDeltaKaon); | |
4847 | Double_t pionFractionErrorDeltaKaon = getErrorOfPionFraction(parametersOut, covMatrixKa); | |
4848 | hFractionPionsDeltaKaon->SetBinContent(slice + 1, pionFractionDeltaKaon); | |
4849 | hFractionPionsDeltaKaon->SetBinError(slice + 1, pionFractionErrorDeltaKaon); | |
4850 | ||
4851 | Double_t electronFractionDeltaKaon = saveDivide(integralElectronsDeltaKaon, integralTotalDeltaKaon); | |
4852 | Double_t electronFractionErrorDeltaKaon = getErrorOfElectronFraction(parametersOut, covMatrixKa); | |
4853 | hFractionElectronsDeltaKaon->SetBinContent(slice + 1, electronFractionDeltaKaon); | |
4854 | hFractionElectronsDeltaKaon->SetBinError(slice + 1, electronFractionErrorDeltaKaon); | |
4855 | ||
4856 | Double_t kaonFractionDeltaKaon = saveDivide(integralKaonsDeltaKaon, integralTotalDeltaKaon); | |
4857 | Double_t kaonFractionErrorDeltaKaon = getErrorOfKaonFraction(parametersOut, covMatrixKa); | |
4858 | hFractionKaonsDeltaKaon->SetBinContent(slice + 1, kaonFractionDeltaKaon); | |
4859 | hFractionKaonsDeltaKaon->SetBinError(slice + 1, kaonFractionErrorDeltaKaon); | |
4860 | ||
4861 | Double_t protonFractionDeltaKaon = saveDivide(integralProtonsDeltaKaon, integralTotalDeltaKaon); | |
4862 | Double_t protonFractionErrorDeltaKaon = getErrorOfProtonFraction(parametersOut, covMatrixKa); | |
4863 | hFractionProtonsDeltaKaon->SetBinContent(slice + 1, protonFractionDeltaKaon); | |
4864 | hFractionProtonsDeltaKaon->SetBinError(slice + 1, protonFractionErrorDeltaKaon); | |
4865 | ||
4866 | Double_t muonFractionDeltaKaon = saveDivide(integralMuonsDeltaKaon, integralTotalDeltaKaon); | |
4867 | // TODO Error is anyway not implemented correctly. Just take electron error as an approximation | |
4868 | Double_t muonFractionErrorDeltaKaon = getErrorOfElectronFraction(parametersOut, covMatrixKa); | |
4869 | hFractionMuonsDeltaKaon->SetBinContent(slice + 1, muonFractionDeltaKaon); | |
4870 | hFractionMuonsDeltaKaon->SetBinError(slice + 1, muonFractionErrorDeltaKaon); | |
4871 | ||
4872 | sumOfParticles = inverseBinWidth * gausParamsKa[5] / binWidthFitHisto; // Divide by binWidthFitHisto, since gausParamsXX includes this width | |
4873 | ||
4874 | hYieldPionsDeltaKaon->SetBinContent(slice + 1, sumOfParticles * hFractionPionsDeltaKaon->GetBinContent(slice + 1)); | |
4875 | hYieldPionsDeltaKaon->SetBinError(slice + 1, sumOfParticles * hFractionPionsDeltaKaon->GetBinError(slice + 1)); | |
4876 | hYieldElectronsDeltaKaon->SetBinContent(slice + 1, sumOfParticles * hFractionElectronsDeltaKaon->GetBinContent(slice + 1)); | |
4877 | hYieldElectronsDeltaKaon->SetBinError(slice + 1, sumOfParticles * hFractionElectronsDeltaKaon->GetBinError(slice + 1)); | |
4878 | hYieldKaonsDeltaKaon->SetBinContent(slice + 1, sumOfParticles * hFractionKaonsDeltaKaon->GetBinContent(slice + 1)); | |
4879 | hYieldKaonsDeltaKaon->SetBinError(slice + 1, sumOfParticles * hFractionKaonsDeltaKaon->GetBinError(slice + 1)); | |
4880 | hYieldProtonsDeltaKaon->SetBinContent(slice + 1, sumOfParticles * hFractionProtonsDeltaKaon->GetBinContent(slice + 1)); | |
4881 | hYieldProtonsDeltaKaon->SetBinError(slice + 1, sumOfParticles * hFractionProtonsDeltaKaon->GetBinError(slice + 1)); | |
4882 | hYieldMuonsDeltaKaon->SetBinContent(slice + 1, sumOfParticles * hFractionMuonsDeltaKaon->GetBinContent(slice + 1)); | |
4883 | hYieldMuonsDeltaKaon->SetBinError(slice + 1, sumOfParticles * hFractionMuonsDeltaKaon->GetBinError(slice + 1)); | |
4884 | ||
4885 | ||
4886 | ||
4887 | // DeltaProton | |
4888 | Double_t integralTotalDeltaProton = integralPionsDeltaProton + integralElectronsDeltaProton + | |
4889 | (takeIntoAccountMuons ? integralMuonsDeltaProton : 0.) + | |
4890 | integralKaonsDeltaProton + integralProtonsDeltaProton; | |
4891 | totalDeltaProton->GetParameters(parametersOut); | |
4892 | ||
4893 | Double_t pionFractionDeltaProton = saveDivide(integralPionsDeltaProton, integralTotalDeltaProton); | |
4894 | Double_t pionFractionErrorDeltaProton = getErrorOfPionFraction(parametersOut, covMatrixPr); | |
4895 | hFractionPionsDeltaProton->SetBinContent(slice + 1, pionFractionDeltaProton); | |
4896 | hFractionPionsDeltaProton->SetBinError(slice + 1, pionFractionErrorDeltaProton); | |
4897 | ||
4898 | Double_t electronFractionDeltaProton = saveDivide(integralElectronsDeltaProton, integralTotalDeltaProton); | |
4899 | Double_t electronFractionErrorDeltaProton = getErrorOfElectronFraction(parametersOut, covMatrixPr); | |
4900 | hFractionElectronsDeltaProton->SetBinContent(slice + 1, electronFractionDeltaProton); | |
4901 | hFractionElectronsDeltaProton->SetBinError(slice + 1, electronFractionErrorDeltaProton); | |
4902 | ||
4903 | Double_t kaonFractionDeltaProton = saveDivide(integralKaonsDeltaProton, integralTotalDeltaProton); | |
4904 | Double_t kaonFractionErrorDeltaProton = getErrorOfKaonFraction(parametersOut, covMatrixPr); | |
4905 | hFractionKaonsDeltaProton->SetBinContent(slice + 1, kaonFractionDeltaProton); | |
4906 | hFractionKaonsDeltaProton->SetBinError(slice + 1, kaonFractionErrorDeltaProton); | |
4907 | ||
4908 | Double_t protonFractionDeltaProton = saveDivide(integralProtonsDeltaProton, integralTotalDeltaProton); | |
4909 | Double_t protonFractionErrorDeltaProton = getErrorOfProtonFraction(parametersOut, covMatrixPr); | |
4910 | hFractionProtonsDeltaProton->SetBinContent(slice + 1, protonFractionDeltaProton); | |
4911 | hFractionProtonsDeltaProton->SetBinError(slice + 1, protonFractionErrorDeltaProton); | |
4912 | ||
4913 | Double_t muonFractionDeltaProton = saveDivide(integralMuonsDeltaProton, integralTotalDeltaProton); | |
4914 | // TODO Error is anyway not implemented correctly. Just take electron error as an approximation | |
4915 | Double_t muonFractionErrorDeltaProton = getErrorOfElectronFraction(parametersOut, covMatrixPr); | |
4916 | hFractionMuonsDeltaProton->SetBinContent(slice + 1, muonFractionDeltaProton); | |
4917 | hFractionMuonsDeltaProton->SetBinError(slice + 1, muonFractionErrorDeltaProton); | |
4918 | ||
4919 | sumOfParticles = inverseBinWidth * gausParamsPr[5] / binWidthFitHisto; // Divide by binWidthFitHisto, since gausParamsXX includes this width | |
4920 | ||
4921 | hYieldPionsDeltaProton->SetBinContent(slice + 1, sumOfParticles * hFractionPionsDeltaProton->GetBinContent(slice + 1)); | |
4922 | hYieldPionsDeltaProton->SetBinError(slice + 1, sumOfParticles * hFractionPionsDeltaProton->GetBinError(slice + 1)); | |
4923 | hYieldElectronsDeltaProton->SetBinContent(slice + 1, sumOfParticles * hFractionElectronsDeltaProton->GetBinContent(slice + 1)); | |
4924 | hYieldElectronsDeltaProton->SetBinError(slice + 1, sumOfParticles * hFractionElectronsDeltaProton->GetBinError(slice + 1)); | |
4925 | hYieldKaonsDeltaProton->SetBinContent(slice + 1, sumOfParticles * hFractionKaonsDeltaProton->GetBinContent(slice + 1)); | |
4926 | hYieldKaonsDeltaProton->SetBinError(slice + 1, sumOfParticles * hFractionKaonsDeltaProton->GetBinError(slice + 1)); | |
4927 | hYieldProtonsDeltaProton->SetBinContent(slice + 1, sumOfParticles * hFractionProtonsDeltaProton->GetBinContent(slice + 1)); | |
4928 | hYieldProtonsDeltaProton->SetBinError(slice + 1, sumOfParticles * hFractionProtonsDeltaProton->GetBinError(slice + 1)); | |
4929 | hYieldMuonsDeltaProton->SetBinContent(slice + 1, sumOfParticles * hFractionMuonsDeltaProton->GetBinContent(slice + 1)); | |
4930 | hYieldMuonsDeltaProton->SetBinError(slice + 1, sumOfParticles * hFractionMuonsDeltaProton->GetBinError(slice + 1)); | |
4931 | ||
4932 | ||
4933 | ||
4934 | // Take for XXXXfractionError the median of XXXXfractionErrorYYYY and do not take into account errors | |
4935 | // with value zero, since the should correspond to a failed fit (but the other fits can still converge). | |
4936 | // Same for the yields | |
4937 | Double_t pionFraction = saveDivide(integralPions, integralTotal); | |
4938 | Double_t errorsPions[4] = { pionFractionErrorDeltaPion, pionFractionErrorDeltaElectron, | |
4939 | pionFractionErrorDeltaKaon, pionFractionErrorDeltaProton }; | |
4940 | Double_t pionFractionError = getMedianOfNonZeros(errorsPions); | |
4941 | ||
4942 | Double_t electronFraction = saveDivide(integralElectrons, integralTotal); | |
4943 | Double_t errorsElectrons[4] = { electronFractionErrorDeltaPion, electronFractionErrorDeltaElectron, | |
4944 | electronFractionErrorDeltaKaon, electronFractionErrorDeltaProton }; | |
4945 | Double_t electronFractionError = getMedianOfNonZeros(errorsElectrons); | |
4946 | ||
4947 | Double_t kaonFraction = saveDivide(integralKaons, integralTotal); | |
4948 | Double_t errorsKaons[4] = { kaonFractionErrorDeltaPion, kaonFractionErrorDeltaElectron, | |
4949 | kaonFractionErrorDeltaKaon, kaonFractionErrorDeltaProton }; | |
4950 | Double_t kaonFractionError = getMedianOfNonZeros(errorsKaons); | |
4951 | ||
4952 | Double_t protonFraction = saveDivide(integralProtons, integralTotal); | |
4953 | Double_t errorsProtons[4] = { protonFractionErrorDeltaPion, protonFractionErrorDeltaElectron, | |
4954 | protonFractionErrorDeltaKaon, protonFractionErrorDeltaProton }; | |
4955 | Double_t protonFractionError = getMedianOfNonZeros(errorsProtons); | |
4956 | ||
4957 | Double_t muonFraction = saveDivide(integralMuons, integralTotal); | |
4958 | Double_t errorsMuons[4] = { muonFractionErrorDeltaPion, muonFractionErrorDeltaElectron, | |
4959 | muonFractionErrorDeltaKaon, muonFractionErrorDeltaProton }; | |
4960 | Double_t muonFractionError = getMedianOfNonZeros(errorsMuons); | |
4961 | ||
4962 | hFractionPions->SetBinContent(slice + 1, pionFraction); | |
4963 | hFractionPions->SetBinError(slice + 1, pionFractionError); | |
4964 | hFractionElectrons->SetBinContent(slice + 1, electronFraction); | |
4965 | hFractionElectrons->SetBinError(slice + 1, electronFractionError); | |
4966 | hFractionKaons->SetBinContent(slice + 1, kaonFraction); | |
4967 | hFractionKaons->SetBinError(slice + 1, kaonFractionError); | |
4968 | hFractionProtons->SetBinContent(slice + 1, protonFraction); | |
4969 | hFractionProtons->SetBinError(slice + 1, protonFractionError); | |
4970 | hFractionMuons->SetBinContent(slice + 1, muonFraction); | |
4971 | hFractionMuons->SetBinError(slice + 1, muonFractionError); | |
4972 | ||
4973 | hFractionSummed->SetBinContent(slice + 1, pionFraction + electronFraction + (takeIntoAccountMuons ? muonFraction : 0.) + | |
4974 | kaonFraction + protonFraction); | |
4975 | hFractionSummed->SetBinError(slice + 1, | |
4976 | TMath::Sqrt(TMath::Power(pionFractionError, 2) + | |
4977 | TMath::Power(electronFractionError, 2) + | |
4978 | (takeIntoAccountMuons ? TMath::Power(muonFractionError, 2) : 0.) + | |
4979 | TMath::Power(kaonFractionError, 2) + | |
4980 | TMath::Power(protonFractionError, 2))); | |
4981 | ||
4982 | sumOfParticles = inverseBinWidth * integralTotal / binWidthFitHisto; // Divide by binWidthFitHisto, since integralTotal includes this width | |
4983 | ||
4984 | hYieldPions->SetBinContent(slice + 1, sumOfParticles * hFractionPions->GetBinContent(slice + 1)); | |
4985 | hYieldPions->SetBinError(slice + 1, sumOfParticles * hFractionPions->GetBinError(slice + 1)); | |
4986 | hYieldElectrons->SetBinContent(slice + 1, sumOfParticles * hFractionElectrons->GetBinContent(slice + 1)); | |
4987 | hYieldElectrons->SetBinError(slice + 1, sumOfParticles * hFractionElectrons->GetBinError(slice + 1)); | |
4988 | hYieldKaons->SetBinContent(slice + 1, sumOfParticles * hFractionKaons->GetBinContent(slice + 1)); | |
4989 | hYieldKaons->SetBinError(slice + 1, sumOfParticles * hFractionKaons->GetBinError(slice + 1)); | |
4990 | hYieldProtons->SetBinContent(slice + 1, sumOfParticles * hFractionProtons->GetBinContent(slice + 1)); | |
4991 | hYieldProtons->SetBinError(slice + 1, sumOfParticles * hFractionProtons->GetBinError(slice + 1)); | |
4992 | hYieldMuons->SetBinContent(slice + 1, sumOfParticles * hFractionMuons->GetBinContent(slice + 1)); | |
4993 | hYieldMuons->SetBinError(slice + 1, sumOfParticles * hFractionMuons->GetBinError(slice + 1)); | |
4994 | } | |
4995 | } | |
4996 | else { | |
4997 | Double_t SumFractionsDeltaElectron = hFractionPionsDeltaElectron->GetBinContent(slice + 1) + | |
4998 | hFractionElectronsDeltaElectron->GetBinContent(slice + 1) + | |
4999 | (takeIntoAccountMuons ? hFractionMuonsDeltaElectron->GetBinContent(slice + 1) : 0.) + | |
5000 | hFractionKaonsDeltaElectron->GetBinContent(slice + 1) + hFractionProtonsDeltaElectron->GetBinContent(slice + 1); | |
5001 | ||
5002 | Double_t SumFractionsDeltaKaon = hFractionPionsDeltaKaon->GetBinContent(slice + 1) + | |
5003 | hFractionElectronsDeltaKaon->GetBinContent(slice + 1) + | |
5004 | (takeIntoAccountMuons ? hFractionMuonsDeltaKaon->GetBinContent(slice + 1) : 0.) + | |
5005 | hFractionKaonsDeltaKaon->GetBinContent(slice + 1) + hFractionProtonsDeltaKaon->GetBinContent(slice + 1); | |
5006 | ||
5007 | Double_t SumFractionsDeltaPion = hFractionPionsDeltaPion->GetBinContent(slice + 1) + | |
5008 | hFractionElectronsDeltaPion->GetBinContent(slice + 1) + | |
5009 | (takeIntoAccountMuons ? hFractionMuonsDeltaPion->GetBinContent(slice + 1) : 0.) + | |
5010 | hFractionKaonsDeltaPion->GetBinContent(slice + 1) + hFractionProtonsDeltaPion->GetBinContent(slice + 1); | |
5011 | ||
5012 | Double_t SumFractionsDeltaProton = hFractionPionsDeltaProton->GetBinContent(slice + 1) + | |
5013 | hFractionElectronsDeltaProton->GetBinContent(slice + 1) + | |
5014 | (takeIntoAccountMuons ? hFractionMuonsDeltaProton->GetBinContent(slice + 1) : 0.) + | |
5015 | hFractionKaonsDeltaProton->GetBinContent(slice + 1) + hFractionProtonsDeltaProton->GetBinContent(slice + 1); | |
5016 | ||
5017 | Double_t SumFractionsUsed = hFractionPionsDeltaPion->GetBinContent(slice + 1) + | |
5018 | hFractionElectronsDeltaElectron->GetBinContent(slice + 1) + | |
5019 | (takeIntoAccountMuons ? hFractionMuonsDeltaPion->GetBinContent(slice + 1) : 0.) + | |
5020 | hFractionKaonsDeltaKaon->GetBinContent(slice + 1) + hFractionProtonsDeltaProton->GetBinContent(slice + 1); | |
5021 | ||
5022 | hFractionSummed->SetBinContent(slice + 1, SumFractionsUsed); | |
5023 | hFractionSummed->SetBinError(slice + 1, | |
5024 | TMath::Sqrt(TMath::Power(hFractionPionsDeltaPion->GetBinError(slice + 1), 2) + | |
5025 | TMath::Power(hFractionElectronsDeltaElectron->GetBinError(slice + 1), 2) + | |
5026 | (takeIntoAccountMuons ? TMath::Power(hFractionMuonsDeltaPion->GetBinError(slice + 1), | |
5027 | 2) : 0.) + | |
5028 | TMath::Power(hFractionKaonsDeltaKaon->GetBinError(slice + 1), 2) + | |
5029 | TMath::Power(hFractionProtonsDeltaProton->GetBinError(slice + 1), 2))); | |
5030 | ||
5031 | ||
5032 | std::cout << "Sum Fractions DeltaElectron: " << SumFractionsDeltaElectron; | |
5033 | std::cout << (TMath::Abs(SumFractionsDeltaElectron - 1) >= 0.001 ? " WARNING: Deviation >= 0.001" : "") << std::endl; | |
5034 | ||
5035 | std::cout << "Sum Fractions DeltaKaon: " << SumFractionsDeltaKaon; | |
5036 | std::cout << (TMath::Abs(SumFractionsDeltaKaon - 1) >= 0.001 ? " WARNING: Deviation >= 0.001" : "") << std::endl; | |
5037 | ||
5038 | std::cout << "Sum Fractions DeltaPion: " << SumFractionsDeltaPion; | |
5039 | std::cout << (TMath::Abs(SumFractionsDeltaPion - 1) >= 0.001 ? " WARNING: Deviation >= 0.001" : "") << std::endl; | |
5040 | ||
5041 | std::cout << "Sum fractions DeltaProton: " << SumFractionsDeltaProton; | |
5042 | std::cout << (TMath::Abs(SumFractionsDeltaProton - 1) >= 0.001 ? " WARNING: Deviation >= 0.001" : "") << std::endl; | |
5043 | ||
5044 | std::cout << "Sum fractions used: " << SumFractionsUsed; | |
5045 | std::cout << (TMath::Abs(SumFractionsUsed - 1) >= 0.001 ? " WARNING: Deviation >= 0.001" : "") << std::endl; | |
5046 | } | |
5047 | ||
5048 | for (Int_t species = 0; species < 4; species++) { | |
5049 | cSingleFit[slice][species]->Modified(); | |
5050 | cSingleFit[slice][species]->Update(); | |
5051 | } | |
5052 | ||
5053 | ||
5054 | } | |
5055 | ||
5056 | if (regularisation <= 0) | |
5057 | std::cout << std::endl << std::endl; | |
5058 | ||
5059 | ||
5060 | // MC results | |
5061 | Double_t MCtotal = -1, MCelectrons = -1, MCkaons = -1, MCmuons = -1, MCpions = -1, MCprotons = -1; | |
5062 | Double_t MCelectronsErr = 0, MCkaonsErr = 0, MCmuonsErr = 0, MCpionsErr = 0, MCprotonsErr = 0; | |
5063 | ||
5064 | MCelectrons = hMCdata->IntegralAndError(pBinLowProjLimit, pBinUpProjLimit, 1, 1, MCelectronsErr) * inverseBinWidth; | |
5065 | MCkaons = hMCdata->IntegralAndError(pBinLowProjLimit, pBinUpProjLimit, 2, 2, MCkaonsErr) * inverseBinWidth; | |
5066 | MCmuons = hMCdata->IntegralAndError(pBinLowProjLimit, pBinUpProjLimit, 3, 3, MCmuonsErr) * inverseBinWidth; | |
5067 | MCpions = hMCdata->IntegralAndError(pBinLowProjLimit, pBinUpProjLimit, 4, 4, MCpionsErr) * inverseBinWidth; | |
5068 | MCprotons = hMCdata->IntegralAndError(pBinLowProjLimit, pBinUpProjLimit, 5, 5, MCprotonsErr) * inverseBinWidth; | |
5069 | ||
5070 | MCelectronsErr *= inverseBinWidth; | |
5071 | MCkaonsErr *= inverseBinWidth; | |
5072 | MCmuonsErr *= inverseBinWidth; | |
5073 | MCpionsErr *= inverseBinWidth; | |
5074 | MCprotonsErr *= inverseBinWidth; | |
5075 | ||
5076 | MCtotal = MCelectrons + MCkaons + MCpions + MCprotons + MCmuons; | |
5077 | ||
5078 | if (MCtotal > 0) { | |
5079 | hYieldElectronsMC->SetBinContent(slice + 1, MCelectrons); | |
5080 | hYieldElectronsMC->SetBinError(slice + 1, MCelectronsErr); | |
5081 | ||
5082 | hYieldMuonsMC->SetBinContent(slice + 1, MCmuons); | |
5083 | hYieldMuonsMC->SetBinError(slice + 1, MCmuonsErr); | |
5084 | ||
5085 | hYieldKaonsMC->SetBinContent(slice + 1, MCkaons); | |
5086 | hYieldKaonsMC->SetBinError(slice + 1, MCkaonsErr); | |
5087 | ||
5088 | hYieldPionsMC->SetBinContent(slice + 1, MCpions); | |
5089 | hYieldPionsMC->SetBinError(slice + 1, MCpionsErr); | |
5090 | ||
5091 | hYieldProtonsMC->SetBinContent(slice + 1, MCprotons); | |
5092 | hYieldProtonsMC->SetBinError(slice + 1, MCprotonsErr); | |
5093 | ||
5094 | hYieldSummedMC->SetBinContent(slice + 1, hYieldElectronsMC->GetBinContent(slice + 1) + | |
5095 | hYieldKaonsMC->GetBinContent(slice + 1) + | |
5096 | hYieldPionsMC->GetBinContent(slice + 1) + | |
5097 | hYieldProtonsMC->GetBinContent(slice + 1) + | |
5098 | hYieldMuonsMC->GetBinContent(slice + 1)); | |
5099 | hYieldSummedMC->SetBinError(slice + 1, TMath::Sqrt(TMath::Power(hYieldPionsMC->GetBinError(slice + 1), 2) + | |
5100 | TMath::Power(hYieldElectronsMC->GetBinError(slice + 1), 2) + | |
5101 | TMath::Power(hYieldKaonsMC->GetBinError(slice + 1), 2) + | |
5102 | TMath::Power(hYieldProtonsMC->GetBinError(slice + 1), 2) + | |
5103 | TMath::Power(hYieldMuonsMC->GetBinError(slice + 1), 2))); | |
5104 | ||
5105 | // MCspecies and MCtotal are correlated. This can be taken into account via using the binomial error in the division | |
5106 | hFractionElectronsMC->Divide(hYieldElectronsMC, hYieldSummedMC, 1., 1., "B"); | |
5107 | hFractionMuonsMC->Divide(hYieldMuonsMC, hYieldSummedMC, 1., 1., "B"); | |
5108 | hFractionKaonsMC->Divide(hYieldKaonsMC, hYieldSummedMC, 1., 1., "B"); | |
5109 | hFractionPionsMC->Divide(hYieldPionsMC, hYieldSummedMC, 1., 1., "B"); | |
5110 | hFractionProtonsMC->Divide(hYieldProtonsMC, hYieldSummedMC, 1., 1., "B"); | |
5111 | } | |
5112 | ||
5113 | // Save further results | |
5114 | if (slice % 18 == 0 || slice == pSliceLow) { | |
5115 | saveF->cd(); | |
5116 | ||
5117 | if (hFractionElectrons) | |
5118 | hFractionElectrons->Write(0, TObject::kWriteDelete); | |
5119 | ||
5120 | if (hFractionKaons) | |
5121 | hFractionKaons->Write(0, TObject::kWriteDelete); | |
5122 | ||
5123 | if (hFractionPions) | |
5124 | hFractionPions->Write(0, TObject::kWriteDelete); | |
5125 | ||
5126 | if (hFractionProtons) | |
5127 | hFractionProtons->Write(0, TObject::kWriteDelete); | |
5128 | ||
5129 | if (hFractionMuons) | |
5130 | hFractionMuons->Write(0, TObject::kWriteDelete); | |
5131 | ||
5132 | if (hFractionSummed) | |
5133 | hFractionSummed->Write(0, TObject::kWriteDelete); | |
5134 | ||
5135 | ||
5136 | if (hFractionElectronsDeltaElectron) | |
5137 | hFractionElectronsDeltaElectron->Write(0, TObject::kWriteDelete); | |
5138 | ||
5139 | if (hFractionKaonsDeltaElectron) | |
5140 | hFractionKaonsDeltaElectron->Write(0, TObject::kWriteDelete); | |
5141 | ||
5142 | if (hFractionPionsDeltaElectron) | |
5143 | hFractionPionsDeltaElectron->Write(0, TObject::kWriteDelete); | |
5144 | ||
5145 | if (hFractionProtonsDeltaElectron) | |
5146 | hFractionProtonsDeltaElectron->Write(0, TObject::kWriteDelete); | |
5147 | ||
5148 | if (hFractionMuonsDeltaElectron) | |
5149 | hFractionMuonsDeltaElectron->Write(0, TObject::kWriteDelete); | |
5150 | ||
5151 | ||
5152 | if (hFractionElectronsDeltaPion) | |
5153 | hFractionElectronsDeltaPion->Write(0, TObject::kWriteDelete); | |
5154 | ||
5155 | if (hFractionKaonsDeltaPion) | |
5156 | hFractionKaonsDeltaPion->Write(0, TObject::kWriteDelete); | |
5157 | ||
5158 | if (hFractionPionsDeltaPion) | |
5159 | hFractionPionsDeltaPion->Write(0, TObject::kWriteDelete); | |
5160 | ||
5161 | if (hFractionProtonsDeltaPion) | |
5162 | hFractionProtonsDeltaPion->Write(0, TObject::kWriteDelete); | |
5163 | ||
5164 | if (hFractionMuonsDeltaPion) | |
5165 | hFractionMuonsDeltaPion->Write(0, TObject::kWriteDelete); | |
5166 | ||
5167 | ||
5168 | if (hFractionElectronsDeltaKaon) | |
5169 | hFractionElectronsDeltaKaon->Write(0, TObject::kWriteDelete); | |
5170 | ||
5171 | if (hFractionKaonsDeltaKaon) | |
5172 | hFractionKaonsDeltaKaon->Write(0, TObject::kWriteDelete); | |
5173 | ||
5174 | if (hFractionPionsDeltaKaon) | |
5175 | hFractionPionsDeltaKaon->Write(0, TObject::kWriteDelete); | |
5176 | ||
5177 | if (hFractionProtonsDeltaKaon) | |
5178 | hFractionProtonsDeltaKaon->Write(0, TObject::kWriteDelete); | |
5179 | ||
5180 | if (hFractionMuonsDeltaKaon) | |
5181 | hFractionMuonsDeltaKaon->Write(0, TObject::kWriteDelete); | |
5182 | ||
5183 | ||
5184 | if (hFractionElectronsDeltaProton) | |
5185 | hFractionElectronsDeltaProton->Write(0, TObject::kWriteDelete); | |
5186 | ||
5187 | if (hFractionKaonsDeltaProton) | |
5188 | hFractionKaonsDeltaProton->Write(0, TObject::kWriteDelete); | |
5189 | ||
5190 | if (hFractionPionsDeltaProton) | |
5191 | hFractionPionsDeltaProton->Write(0, TObject::kWriteDelete); | |
5192 | ||
5193 | if (hFractionProtonsDeltaProton) | |
5194 | hFractionProtonsDeltaProton->Write(0, TObject::kWriteDelete); | |
5195 | ||
5196 | if (hFractionMuonsDeltaProton) | |
5197 | hFractionMuonsDeltaProton->Write(0, TObject::kWriteDelete); | |
5198 | ||
5199 | ||
5200 | if (hFractionElectronsMC) | |
5201 | hFractionElectronsMC->Write(0, TObject::kWriteDelete); | |
5202 | ||
5203 | if (hFractionKaonsMC) | |
5204 | hFractionKaonsMC->Write(0, TObject::kWriteDelete); | |
5205 | ||
5206 | if (hFractionPionsMC) | |
5207 | hFractionPionsMC->Write(0, TObject::kWriteDelete); | |
5208 | ||
5209 | if (hFractionMuonsMC) | |
5210 | hFractionMuonsMC->Write(0, TObject::kWriteDelete); | |
5211 | ||
5212 | if (hFractionProtonsMC) | |
5213 | hFractionProtonsMC->Write(0, TObject::kWriteDelete); | |
5214 | ||
5215 | ||
5216 | ||
5217 | ||
5218 | if (hYieldElectrons) | |
5219 | hYieldElectrons->Write(0, TObject::kWriteDelete); | |
5220 | ||
5221 | if (hYieldKaons) | |
5222 | hYieldKaons->Write(0, TObject::kWriteDelete); | |
5223 | ||
5224 | if (hYieldPions) | |
5225 | hYieldPions->Write(0, TObject::kWriteDelete); | |
5226 | ||
5227 | if (hYieldProtons) | |
5228 | hYieldProtons->Write(0, TObject::kWriteDelete); | |
5229 | ||
5230 | if (hYieldMuons) | |
5231 | hYieldMuons->Write(0, TObject::kWriteDelete); | |
5232 | ||
5233 | ||
5234 | if (hYieldElectronsDeltaElectron) | |
5235 | hYieldElectronsDeltaElectron->Write(0, TObject::kWriteDelete); | |
5236 | ||
5237 | if (hYieldKaonsDeltaElectron) | |
5238 | hYieldKaonsDeltaElectron->Write(0, TObject::kWriteDelete); | |
5239 | ||
5240 | if (hYieldPionsDeltaElectron) | |
5241 | hYieldPionsDeltaElectron->Write(0, TObject::kWriteDelete); | |
5242 | ||
5243 | if (hYieldProtonsDeltaElectron) | |
5244 | hYieldProtonsDeltaElectron->Write(0, TObject::kWriteDelete); | |
5245 | ||
5246 | if (hYieldMuonsDeltaElectron) | |
5247 | hYieldMuonsDeltaElectron->Write(0, TObject::kWriteDelete); | |
5248 | ||
5249 | ||
5250 | if (hYieldElectronsDeltaPion) | |
5251 | hYieldElectronsDeltaPion->Write(0, TObject::kWriteDelete); | |
5252 | ||
5253 | if (hYieldKaonsDeltaPion) | |
5254 | hYieldKaonsDeltaPion->Write(0, TObject::kWriteDelete); | |
5255 | ||
5256 | if (hYieldPionsDeltaPion) | |
5257 | hYieldPionsDeltaPion->Write(0, TObject::kWriteDelete); | |
5258 | ||
5259 | if (hYieldProtonsDeltaPion) | |
5260 | hYieldProtonsDeltaPion->Write(0, TObject::kWriteDelete); | |
5261 | ||
5262 | if (hYieldMuonsDeltaPion) | |
5263 | hYieldMuonsDeltaPion->Write(0, TObject::kWriteDelete); | |
5264 | ||
5265 | ||
5266 | if (hYieldElectronsDeltaKaon) | |
5267 | hYieldElectronsDeltaKaon->Write(0, TObject::kWriteDelete); | |
5268 | ||
5269 | if (hYieldKaonsDeltaKaon) | |
5270 | hYieldKaonsDeltaKaon->Write(0, TObject::kWriteDelete); | |
5271 | ||
5272 | if (hYieldPionsDeltaKaon) | |
5273 | hYieldPionsDeltaKaon->Write(0, TObject::kWriteDelete); | |
5274 | ||
5275 | if (hYieldProtonsDeltaKaon) | |
5276 | hYieldProtonsDeltaKaon->Write(0, TObject::kWriteDelete); | |
5277 | ||
5278 | if (hYieldMuonsDeltaKaon) | |
5279 | hYieldMuonsDeltaKaon->Write(0, TObject::kWriteDelete); | |
5280 | ||
5281 | ||
5282 | if (hYieldElectronsDeltaProton) | |
5283 | hYieldElectronsDeltaProton->Write(0, TObject::kWriteDelete); | |
5284 | ||
5285 | if (hYieldKaonsDeltaProton) | |
5286 | hYieldKaonsDeltaProton->Write(0, TObject::kWriteDelete); | |
5287 | ||
5288 | if (hYieldPionsDeltaProton) | |
5289 | hYieldPionsDeltaProton->Write(0, TObject::kWriteDelete); | |
5290 | ||
5291 | if (hYieldProtonsDeltaProton) | |
5292 | hYieldProtonsDeltaProton->Write(0, TObject::kWriteDelete); | |
5293 | ||
5294 | if (hYieldMuonsDeltaProton) | |
5295 | hYieldMuonsDeltaProton->Write(0, TObject::kWriteDelete); | |
5296 | ||
5297 | ||
5298 | if (hYieldElectronsMC) | |
5299 | hYieldElectronsMC->Write(0, TObject::kWriteDelete); | |
5300 | ||
5301 | if (hYieldKaonsMC) | |
5302 | hYieldKaonsMC->Write(0, TObject::kWriteDelete); | |
5303 | ||
5304 | if (hYieldPionsMC) | |
5305 | hYieldPionsMC->Write(0, TObject::kWriteDelete); | |
5306 | ||
5307 | if (hYieldMuonsMC) | |
5308 | hYieldMuonsMC->Write(0, TObject::kWriteDelete); | |
5309 | ||
5310 | if (hYieldProtonsMC) | |
5311 | hYieldProtonsMC->Write(0, TObject::kWriteDelete); | |
5312 | ||
5313 | if (hYieldSummedMC) | |
5314 | hYieldSummedMC->Write(0, TObject::kWriteDelete); | |
5315 | } | |
5316 | ||
5317 | TString saveDir = (mode == kPMpT) ? Form("SingleFit_%.2f_Pt_%.2f", binsPt[slice], binsPt[slice + 1]) | |
5318 | : Form("SingleFit_%.2f_%s_%.2f", hFractionPions->GetXaxis()->GetBinLowEdge(slice + 1), | |
5319 | modeShortName[mode].Data(), hFractionPions->GetXaxis()->GetBinUpEdge(slice + 1)); | |
5320 | saveF->mkdir(saveDir.Data()); | |
5321 | saveF->cd(saveDir.Data()); | |
5322 | ||
5323 | for (Int_t species = 0; species < 4; species++) { | |
5324 | if (cSingleFit[slice][species]) { | |
5325 | cSingleFit[slice][species]->Write(); | |
5326 | delete cSingleFit[slice][species]; | |
5327 | } | |
5328 | } | |
5329 | ||
5330 | if (hDeltaPi[slice]) | |
5331 | hDeltaPi[slice]->Write(); | |
5332 | ||
5333 | if (hDeltaEl[slice]) | |
5334 | hDeltaEl[slice]->Write(); | |
5335 | ||
5336 | if (hDeltaKa[slice]) | |
5337 | hDeltaKa[slice]->Write(); | |
5338 | ||
5339 | if (hDeltaPr[slice]) | |
5340 | hDeltaPr[slice]->Write(); | |
5341 | ||
5342 | ||
5343 | if (hDeltaPiFitQA[slice]) | |
5344 | hDeltaPiFitQA[slice]->Write(); | |
5345 | delete hDeltaPiFitQA[slice]; | |
5346 | ||
5347 | if (hDeltaElFitQA[slice]) | |
5348 | hDeltaElFitQA[slice]->Write(); | |
5349 | delete hDeltaElFitQA[slice]; | |
5350 | ||
5351 | if (hDeltaKaFitQA[slice]) | |
5352 | hDeltaKaFitQA[slice]->Write(); | |
5353 | delete hDeltaKaFitQA[slice]; | |
5354 | ||
5355 | if (hDeltaPrFitQA[slice]) | |
5356 | hDeltaPrFitQA[slice]->Write(); | |
5357 | delete hDeltaPrFitQA[slice]; | |
5358 | ||
5359 | if (hGenDeltaElForElProj) | |
5360 | hGenDeltaElForElProj->Write(); | |
5361 | delete hGenDeltaElForElProj; | |
5362 | ||
5363 | if (hGenDeltaElForKaProj) | |
5364 | hGenDeltaElForKaProj->Write(); | |
5365 | delete hGenDeltaElForKaProj; | |
5366 | ||
5367 | if (hGenDeltaElForPiProj) | |
5368 | hGenDeltaElForPiProj->Write(); | |
5369 | delete hGenDeltaElForPiProj; | |
5370 | ||
5371 | if (hGenDeltaElForPrProj) | |
5372 | hGenDeltaElForPrProj->Write(); | |
5373 | delete hGenDeltaElForPrProj; | |
5374 | ||
5375 | if (hGenDeltaElForMuProj) | |
5376 | hGenDeltaElForMuProj->Write(); | |
5377 | delete hGenDeltaElForMuProj; | |
5378 | ||
5379 | //if (fitFuncTotalDeltaElectron[slice]) | |
5380 | // fitFuncTotalDeltaElectron[slice]->Write(); | |
5381 | delete fitFuncTotalDeltaElectron[slice]; | |
5382 | ||
5383 | if (hGenDeltaKaForElProj) | |
5384 | hGenDeltaKaForElProj->Write(); | |
5385 | delete hGenDeltaKaForElProj; | |
5386 | ||
5387 | if (hGenDeltaKaForKaProj) | |
5388 | hGenDeltaKaForKaProj->Write(); | |
5389 | delete hGenDeltaKaForKaProj; | |
5390 | ||
5391 | if (hGenDeltaKaForPiProj) | |
5392 | hGenDeltaKaForPiProj->Write(); | |
5393 | delete hGenDeltaKaForPiProj; | |
5394 | ||
5395 | if (hGenDeltaKaForPrProj) | |
5396 | hGenDeltaKaForPrProj->Write(); | |
5397 | delete hGenDeltaKaForPrProj; | |
5398 | ||
5399 | if (hGenDeltaKaForMuProj) | |
5400 | hGenDeltaKaForMuProj->Write(); | |
5401 | delete hGenDeltaKaForMuProj; | |
5402 | ||
5403 | //if (fitFuncTotalDeltaKaon[slice]) | |
5404 | // fitFuncTotalDeltaKaon[slice]->Write(); | |
5405 | delete fitFuncTotalDeltaKaon[slice]; | |
5406 | ||
5407 | ||
5408 | if (hGenDeltaPiForElProj) | |
5409 | hGenDeltaPiForElProj->Write(); | |
5410 | delete hGenDeltaPiForElProj; | |
5411 | ||
5412 | if (hGenDeltaPiForKaProj) | |
5413 | hGenDeltaPiForKaProj->Write(); | |
5414 | delete hGenDeltaPiForKaProj; | |
5415 | ||
5416 | if (hGenDeltaPiForPiProj) | |
5417 | hGenDeltaPiForPiProj->Write(); | |
5418 | delete hGenDeltaPiForPiProj; | |
5419 | ||
5420 | if (hGenDeltaPiForPrProj) | |
5421 | hGenDeltaPiForPrProj->Write(); | |
5422 | delete hGenDeltaPiForPrProj; | |
5423 | ||
5424 | if (hGenDeltaPiForMuProj) | |
5425 | hGenDeltaPiForMuProj->Write(); | |
5426 | delete hGenDeltaPiForMuProj; | |
5427 | ||
5428 | //if (fitFuncTotalDeltaPion[slice]) | |
5429 | // fitFuncTotalDeltaPion[slice]->Write(); | |
5430 | delete fitFuncTotalDeltaPion[slice]; | |
5431 | ||
5432 | ||
5433 | if (hGenDeltaPrForElProj) | |
5434 | hGenDeltaPrForElProj->Write(); | |
5435 | delete hGenDeltaPrForElProj; | |
5436 | ||
5437 | if (hGenDeltaPrForKaProj) | |
5438 | hGenDeltaPrForKaProj->Write(); | |
5439 | delete hGenDeltaPrForKaProj; | |
5440 | ||
5441 | if (hGenDeltaPrForPiProj) | |
5442 | hGenDeltaPrForPiProj->Write(); | |
5443 | delete hGenDeltaPrForPiProj; | |
5444 | ||
5445 | if (hGenDeltaPrForPrProj) | |
5446 | hGenDeltaPrForPrProj->Write(); | |
5447 | delete hGenDeltaPrForPrProj; | |
5448 | ||
5449 | if (hGenDeltaPrForMuProj) | |
5450 | hGenDeltaPrForMuProj->Write(); | |
5451 | delete hGenDeltaPrForMuProj; | |
5452 | ||
5453 | //if (fitFuncTotalDeltaProton[slice]) | |
5454 | // fitFuncTotalDeltaProton[slice]->Write(); | |
5455 | delete fitFuncTotalDeltaProton[slice]; | |
5456 | ||
5457 | delete totalDeltaElectron; | |
5458 | delete totalDeltaKaon; | |
5459 | delete totalDeltaPion; | |
5460 | delete totalDeltaProton; | |
5461 | ||
5462 | delete legend; | |
5463 | ||
5464 | if (errFlag != 0) | |
5465 | std::cout << "errFlag " << errFlag << std::endl << std::endl; | |
5466 | } | |
5467 | } | |
5468 | ||
5469 | // Calculate MC to-pi ratios -> In MC the yields are uncorrelated, so just divide the histos to get the correct result | |
5470 | hRatioToPiElectronsMC->Divide(hYieldElectronsMC, hYieldPionsMC); | |
5471 | hRatioToPiMuonsMC->Divide(hYieldMuonsMC, hYieldPionsMC); | |
5472 | hRatioToPiKaonsMC->Divide(hYieldKaonsMC, hYieldPionsMC); | |
5473 | hRatioToPiProtonsMC->Divide(hYieldProtonsMC, hYieldPionsMC); | |
5474 | ||
5475 | ||
5476 | TCanvas* cFractions = new TCanvas("cFractions", "Particle fractions",100,10,1200,800); | |
5477 | cFractions->SetGridx(1); | |
5478 | cFractions->SetGridy(1); | |
5479 | cFractions->SetLogx(mode == kPMpT); | |
5480 | hFractionPions->GetYaxis()->SetRangeUser(0.0, 1.0); | |
5481 | SetReasonableAxisRange(hFractionPions->GetXaxis(), mode, pLow, pHigh); | |
5482 | hFractionPions->GetXaxis()->SetMoreLogLabels(kTRUE); | |
5483 | hFractionPions->GetXaxis()->SetNoExponent(kTRUE); | |
5484 | hFractionPions->Draw("e p"); | |
5485 | if (plotIdentifiedSpectra) { | |
5486 | SetReasonableAxisRange(hFractionPionsMC->GetXaxis(), mode, pLow, pHigh); | |
5487 | hFractionPionsMC->Draw("e p same"); | |
5488 | } | |
5489 | ||
5490 | SetReasonableAxisRange(hFractionKaons->GetXaxis(), mode, pLow, pHigh); | |
5491 | hFractionKaons->Draw("e p same"); | |
5492 | if (plotIdentifiedSpectra) { | |
5493 | SetReasonableAxisRange(hFractionKaonsMC->GetXaxis(), mode, pLow, pHigh); | |
5494 | hFractionKaonsMC->Draw("e p same"); | |
5495 | } | |
5496 | ||
5497 | SetReasonableAxisRange(hFractionProtons->GetXaxis(), mode, pLow, pHigh); | |
5498 | hFractionProtons->Draw("e p same"); | |
5499 | if (plotIdentifiedSpectra) { | |
5500 | SetReasonableAxisRange(hFractionProtonsMC->GetXaxis(), mode, pLow, pHigh); | |
5501 | hFractionProtonsMC->Draw("e p same"); | |
5502 | } | |
5503 | ||
5504 | SetReasonableAxisRange(hFractionElectrons->GetXaxis(), mode, pLow, pHigh); | |
5505 | hFractionElectrons->Draw("e p same"); | |
5506 | if (plotIdentifiedSpectra) { | |
5507 | SetReasonableAxisRange(hFractionElectronsMC->GetXaxis(), mode, pLow, pHigh); | |
5508 | hFractionElectronsMC->Draw("e p same"); | |
5509 | } | |
5510 | ||
5511 | if (takeIntoAccountMuons) { | |
5512 | SetReasonableAxisRange(hFractionMuons->GetXaxis(), mode, pLow, pHigh); | |
5513 | hFractionMuons->Draw("e p same"); | |
5514 | } | |
5515 | if (plotIdentifiedSpectra) { | |
5516 | SetReasonableAxisRange(hFractionMuonsMC->GetXaxis(), mode, pLow, pHigh); | |
5517 | hFractionMuonsMC->Draw("e p same"); | |
5518 | } | |
5519 | ||
5520 | hFractionSummed->Draw("e p same"); | |
5521 | ||
5522 | if (mode == kPMpT) { | |
5523 | fElectronFraction->SetRange(lowFittingBoundElectronFraction, pHigh); | |
5524 | fElectronFraction->Draw("same"); | |
5525 | } | |
5526 | ||
5527 | TLegend* legend = new TLegend(0.622126, 0.605932, 0.862069, 0.855932); | |
5528 | legend->SetBorderSize(0); | |
5529 | legend->SetFillColor(0); | |
5530 | if (plotIdentifiedSpectra) | |
5531 | legend->SetNColumns(2); | |
5532 | if (plotIdentifiedSpectra) | |
5533 | legend->AddEntry((TObject*)0x0, "Fit", ""); | |
5534 | if (plotIdentifiedSpectra) | |
5535 | legend->AddEntry((TObject*)0x0, identifiedLabels[isMC].Data(), ""); | |
5536 | legend->AddEntry(hFractionPions, "#pi", "p"); | |
5537 | if (plotIdentifiedSpectra) | |
5538 | legend->AddEntry(hFractionPionsMC, "#pi", "p"); | |
5539 | legend->AddEntry(hFractionKaons, "K", "p"); | |
5540 | if (plotIdentifiedSpectra) | |
5541 | legend->AddEntry(hFractionKaonsMC, "K", "p"); | |
5542 | legend->AddEntry(hFractionProtons, "p", "p"); | |
5543 | if (plotIdentifiedSpectra) | |
5544 | legend->AddEntry(hFractionProtonsMC, "p", "p"); | |
5545 | legend->AddEntry(hFractionElectrons, "e", "p"); | |
5546 | if (plotIdentifiedSpectra) | |
5547 | legend->AddEntry(hFractionElectronsMC, "e", "p"); | |
5548 | if (takeIntoAccountMuons) | |
5549 | legend->AddEntry(hFractionMuons, "#mu", "p"); | |
5550 | else | |
5551 | legend->AddEntry((TObject*)0x0, "", ""); | |
5552 | if (plotIdentifiedSpectra) | |
5553 | legend->AddEntry(hFractionMuonsMC, "#mu", "p"); | |
5554 | legend->AddEntry(hFractionSummed, "Total", "p"); | |
5555 | legend->Draw(); | |
5556 | ||
5557 | ClearTitleFromHistoInCanvas(cFractions); | |
5558 | ||
5559 | ||
5560 | // Compare data points with MC | |
5561 | for (Int_t i = 1; i <= hFractionComparisonPions->GetNbinsX(); i++) { | |
5562 | hFractionComparisonPions->SetBinContent(i, hFractionPions->GetBinContent(i)); | |
5563 | hFractionComparisonPions->SetBinError(i, hFractionPions->GetBinError(i)); | |
5564 | ||
5565 | hFractionComparisonElectrons->SetBinContent(i, hFractionElectrons->GetBinContent(i)); | |
5566 | hFractionComparisonElectrons->SetBinError(i, hFractionElectrons->GetBinError(i)); | |
5567 | ||
5568 | if (takeIntoAccountMuons) { | |
5569 | hFractionComparisonMuons->SetBinContent(i, hFractionMuons->GetBinContent(i)); | |
5570 | hFractionComparisonMuons->SetBinError(i, hFractionMuons->GetBinError(i)); | |
5571 | } | |
5572 | ||
5573 | hFractionComparisonKaons->SetBinContent(i, hFractionKaons->GetBinContent(i)); | |
5574 | hFractionComparisonKaons->SetBinError(i, hFractionKaons->GetBinError(i)); | |
5575 | ||
5576 | hFractionComparisonProtons->SetBinContent(i, hFractionProtons->GetBinContent(i)); | |
5577 | hFractionComparisonProtons->SetBinError(i, hFractionProtons->GetBinError(i)); | |
5578 | ||
5579 | hFractionComparisonTotal->SetBinContent(i, hFractionSummed->GetBinContent(i)); | |
5580 | hFractionComparisonTotal->SetBinError(i, hFractionSummed->GetBinError(i)); | |
5581 | } | |
5582 | ||
5583 | hFractionComparisonPions->Divide(hFractionPionsMC); | |
5584 | hFractionComparisonElectrons->Divide(hFractionElectronsMC); | |
5585 | if (takeIntoAccountMuons) | |
5586 | hFractionComparisonMuons->Divide(hFractionMuonsMC); | |
5587 | hFractionComparisonKaons->Divide(hFractionKaonsMC); | |
5588 | hFractionComparisonProtons->Divide(hFractionProtonsMC); | |
5589 | ||
5590 | ||
5591 | TCanvas* cFractionComparisons = new TCanvas("cFractionComparisons", "Particle fraction comparisons",100,10,1200,800); | |
5592 | cFractionComparisons->SetGridx(1); | |
5593 | cFractionComparisons->SetGridy(1); | |
5594 | cFractionComparisons->SetLogx(mode == kPMpT); | |
5595 | hFractionComparisonPions->GetYaxis()->SetRangeUser(0.0, 10.0); | |
5596 | SetReasonableAxisRange(hFractionComparisonPions->GetXaxis(), mode, pLow, pHigh); | |
5597 | hFractionComparisonPions->GetXaxis()->SetMoreLogLabels(kTRUE); | |
5598 | hFractionComparisonPions->GetXaxis()->SetNoExponent(kTRUE); | |
5599 | hFractionComparisonPions->Draw("e p"); | |
5600 | ||
5601 | hFractionComparisonElectrons->GetYaxis()->SetRangeUser(0.0, 10.0); | |
5602 | SetReasonableAxisRange(hFractionComparisonElectrons->GetXaxis(), mode, pLow, pHigh); | |
5603 | hFractionComparisonElectrons->Draw("e p same"); | |
5604 | ||
5605 | if (takeIntoAccountMuons) { | |
5606 | hFractionComparisonMuons->GetYaxis()->SetRangeUser(0.0, 10.0); | |
5607 | SetReasonableAxisRange(hFractionComparisonMuons->GetXaxis(), mode, pLow, pHigh); | |
5608 | hFractionComparisonMuons->Draw("e p same"); | |
5609 | } | |
5610 | ||
5611 | hFractionComparisonKaons->GetYaxis()->SetRangeUser(0.0, 10.0); | |
5612 | SetReasonableAxisRange(hFractionComparisonKaons->GetXaxis(), mode, pLow, pHigh); | |
5613 | hFractionComparisonKaons->Draw("e p same"); | |
5614 | ||
5615 | hFractionComparisonProtons->GetYaxis()->SetRangeUser(0.0, 10.0); | |
5616 | SetReasonableAxisRange(hFractionComparisonProtons->GetXaxis(), mode, pLow, pHigh); | |
5617 | hFractionComparisonProtons->Draw("e p same"); | |
5618 | ||
5619 | hFractionComparisonTotal->GetYaxis()->SetRangeUser(0.0, 10.0); | |
5620 | SetReasonableAxisRange(hFractionComparisonTotal->GetXaxis(), mode, pLow, pHigh); | |
5621 | hFractionComparisonTotal->Draw("e p same"); | |
5622 | ||
5623 | TLegend* legend2 = new TLegend(0.622126, 0.605932, 0.862069, 0.855932); | |
5624 | legend2->SetBorderSize(0); | |
5625 | legend2->SetFillColor(0); | |
5626 | legend2->SetNColumns(2); | |
5627 | legend2->AddEntry(hFractionComparisonPions, "#pi", "p"); | |
5628 | legend2->AddEntry(hFractionComparisonKaons, "K", "p"); | |
5629 | legend2->AddEntry(hFractionComparisonProtons, "p", "p"); | |
5630 | legend2->AddEntry(hFractionComparisonElectrons, "e", "p"); | |
5631 | if (takeIntoAccountMuons) | |
5632 | legend2->AddEntry(hFractionComparisonMuons, "#mu", "p"); | |
5633 | legend2->AddEntry(hFractionComparisonTotal, "Total", "p"); | |
5634 | legend2->Draw(); | |
5635 | ||
5636 | ClearTitleFromHistoInCanvas(cFractionComparisons); | |
5637 | ||
5638 | // Normalise the yields | |
5639 | normaliseYieldHist(hYieldPions, numEvents, deta); | |
5640 | normaliseYieldHist(hYieldPionsMC, numEvents, deta); | |
5641 | normaliseYieldHist(hYieldPionsDeltaElectron, numEvents, deta); | |
5642 | normaliseYieldHist(hYieldPionsDeltaPion, numEvents, deta); | |
5643 | normaliseYieldHist(hYieldPionsDeltaKaon, numEvents, deta); | |
5644 | normaliseYieldHist(hYieldPionsDeltaProton, numEvents, deta); | |
5645 | ||
5646 | normaliseYieldHist(hYieldElectrons, numEvents, deta); | |
5647 | normaliseYieldHist(hYieldElectronsMC, numEvents, deta); | |
5648 | normaliseYieldHist(hYieldElectronsDeltaElectron, numEvents, deta); | |
5649 | normaliseYieldHist(hYieldElectronsDeltaPion, numEvents, deta); | |
5650 | normaliseYieldHist(hYieldElectronsDeltaKaon, numEvents, deta); | |
5651 | normaliseYieldHist(hYieldElectronsDeltaProton, numEvents, deta); | |
5652 | ||
5653 | normaliseYieldHist(hYieldMuons, numEvents, deta); | |
5654 | normaliseYieldHist(hYieldMuonsMC, numEvents, deta); | |
5655 | normaliseYieldHist(hYieldMuonsDeltaElectron, numEvents, deta); | |
5656 | normaliseYieldHist(hYieldMuonsDeltaPion, numEvents, deta); | |
5657 | normaliseYieldHist(hYieldMuonsDeltaKaon, numEvents, deta); | |
5658 | normaliseYieldHist(hYieldMuonsDeltaProton, numEvents, deta); | |
5659 | ||
5660 | normaliseYieldHist(hYieldKaons, numEvents, deta); | |
5661 | normaliseYieldHist(hYieldKaonsMC, numEvents, deta); | |
5662 | normaliseYieldHist(hYieldKaonsDeltaElectron, numEvents, deta); | |
5663 | normaliseYieldHist(hYieldKaonsDeltaPion, numEvents, deta); | |
5664 | normaliseYieldHist(hYieldKaonsDeltaKaon, numEvents, deta); | |
5665 | normaliseYieldHist(hYieldKaonsDeltaProton, numEvents, deta); | |
5666 | ||
5667 | normaliseYieldHist(hYieldProtons, numEvents, deta); | |
5668 | normaliseYieldHist(hYieldProtonsMC, numEvents, deta); | |
5669 | normaliseYieldHist(hYieldProtonsDeltaElectron, numEvents, deta); | |
5670 | normaliseYieldHist(hYieldProtonsDeltaPion, numEvents, deta); | |
5671 | normaliseYieldHist(hYieldProtonsDeltaKaon, numEvents, deta); | |
5672 | normaliseYieldHist(hYieldProtonsDeltaProton, numEvents, deta); | |
5673 | ||
5674 | normaliseYieldHist(hYieldSummedMC, numEvents, deta); | |
5675 | ||
5676 | for (Int_t i = 0; i < AliPID::kSPECIES; i++) { | |
5677 | if (hMCgenYieldsPrimSpecies[i]) { | |
5678 | Int_t color = kBlack; | |
5679 | ||
5680 | switch (i) { | |
5681 | case AliPID::kElectron: | |
5682 | color = getLineColor(kEl); | |
5683 | break; | |
5684 | case AliPID::kKaon: | |
5685 | color = getLineColor(kKa); | |
5686 | break; | |
5687 | case AliPID::kMuon: | |
5688 | color = getLineColor(kMu); | |
5689 | break; | |
5690 | case AliPID::kPion: | |
5691 | color = getLineColor(kPi); | |
5692 | break; | |
5693 | case AliPID::kProton: | |
5694 | color = getLineColor(kPr); | |
5695 | break; | |
5696 | } | |
5697 | ||
5698 | hMCgenYieldsPrimSpecies[i]->SetLineColor(color); | |
5699 | hMCgenYieldsPrimSpecies[i]->SetMarkerColor(color); | |
5700 | hMCgenYieldsPrimSpecies[i]->SetMarkerStyle(28); | |
5701 | hMCgenYieldsPrimSpecies[i]->SetLineStyle(1); | |
5702 | hMCgenYieldsPrimSpecies[i]->GetXaxis()->SetTitleOffset(1.0); | |
5703 | hMCgenYieldsPrimSpecies[i]->SetStats(kFALSE); | |
5704 | ||
5705 | SetReasonableAxisRange(hMCgenYieldsPrimSpecies[i]->GetXaxis(), kPMpT, pLow, pHigh); | |
5706 | normaliseGenYieldMCtruthHist(hMCgenYieldsPrimSpecies[i], numEvents, deta); | |
5707 | } | |
5708 | } | |
5709 | ||
5710 | ||
5711 | // Compare data points with MC (yield) | |
5712 | for (Int_t i = 1; i <= hYieldComparisonPions->GetNbinsX(); i++) { | |
5713 | hYieldComparisonPions->SetBinContent(i, hYieldPions->GetBinContent(i)); | |
5714 | hYieldComparisonPions->SetBinError(i, hYieldPions->GetBinError(i)); | |
5715 | ||
5716 | hYieldComparisonElectrons->SetBinContent(i, hYieldElectrons->GetBinContent(i)); | |
5717 | hYieldComparisonElectrons->SetBinError(i, hYieldElectrons->GetBinError(i)); | |
5718 | ||
5719 | if (takeIntoAccountMuons) { | |
5720 | hYieldComparisonMuons->SetBinContent(i, hYieldMuons->GetBinContent(i)); | |
5721 | hYieldComparisonMuons->SetBinError(i, hYieldMuons->GetBinError(i)); | |
5722 | } | |
5723 | ||
5724 | hYieldComparisonKaons->SetBinContent(i, hYieldKaons->GetBinContent(i)); | |
5725 | hYieldComparisonKaons->SetBinError(i, hYieldKaons->GetBinError(i)); | |
5726 | ||
5727 | hYieldComparisonProtons->SetBinContent(i, hYieldProtons->GetBinContent(i)); | |
5728 | hYieldComparisonProtons->SetBinError(i, hYieldProtons->GetBinError(i)); | |
5729 | } | |
5730 | ||
5731 | hYieldComparisonPions->Divide(hYieldPionsMC); | |
5732 | hYieldComparisonElectrons->Divide(hYieldElectronsMC); | |
5733 | if (takeIntoAccountMuons) | |
5734 | hYieldComparisonMuons->Divide(hYieldMuonsMC); | |
5735 | hYieldComparisonKaons->Divide(hYieldKaonsMC); | |
5736 | hYieldComparisonProtons->Divide(hYieldProtonsMC); | |
5737 | ||
5738 | ||
5739 | TCanvas* cYieldComparisons = new TCanvas("cYieldComparisons", "Particle yield comparisons",100,10,1200,800); | |
5740 | cYieldComparisons->SetGridx(1); | |
5741 | cYieldComparisons->SetGridy(1); | |
5742 | cYieldComparisons->SetLogx(mode == kPMpT); | |
5743 | hYieldComparisonPions->GetYaxis()->SetRangeUser(0.0, 10.0); | |
5744 | SetReasonableAxisRange(hYieldComparisonPions->GetXaxis(), mode, pLow, pHigh); | |
5745 | hYieldComparisonPions->GetXaxis()->SetMoreLogLabels(kTRUE); | |
5746 | hYieldComparisonPions->GetXaxis()->SetNoExponent(kTRUE); | |
5747 | hYieldComparisonPions->Draw("e p"); | |
5748 | ||
5749 | hYieldComparisonElectrons->GetYaxis()->SetRangeUser(0.0, 10.0); | |
5750 | SetReasonableAxisRange(hYieldComparisonElectrons->GetXaxis(), mode, pLow, pHigh); | |
5751 | hYieldComparisonElectrons->Draw("e p same"); | |
5752 | ||
5753 | if (takeIntoAccountMuons) { | |
5754 | hYieldComparisonMuons->GetYaxis()->SetRangeUser(0.0, 10.0); | |
5755 | SetReasonableAxisRange(hYieldComparisonMuons->GetXaxis(), mode, pLow, pHigh); | |
5756 | hYieldComparisonMuons->Draw("e p same"); | |
5757 | } | |
5758 | ||
5759 | hYieldComparisonKaons->GetYaxis()->SetRangeUser(0.0, 10.0); | |
5760 | SetReasonableAxisRange(hYieldComparisonKaons->GetXaxis(), mode, pLow, pHigh); | |
5761 | hYieldComparisonKaons->Draw("e p same"); | |
5762 | ||
5763 | hYieldComparisonProtons->GetYaxis()->SetRangeUser(0.0, 10.0); | |
5764 | SetReasonableAxisRange(hYieldComparisonProtons->GetXaxis(), mode, pLow, pHigh); | |
5765 | hYieldComparisonProtons->Draw("e p same"); | |
5766 | ||
5767 | TLegend* legend3 = new TLegend(0.622126, 0.605932, 0.862069, 0.855932); | |
5768 | legend3->SetBorderSize(0); | |
5769 | legend3->SetFillColor(0); | |
5770 | legend3->SetNColumns(2); | |
5771 | legend3->AddEntry(hYieldComparisonPions, "#pi", "p"); | |
5772 | legend3->AddEntry(hYieldComparisonKaons, "K", "p"); | |
5773 | legend3->AddEntry(hYieldComparisonProtons, "p", "p"); | |
5774 | legend3->AddEntry(hYieldComparisonElectrons, "e", "p"); | |
5775 | if (takeIntoAccountMuons) | |
5776 | legend3->AddEntry(hYieldComparisonMuons, "#mu", "p"); | |
5777 | legend3->Draw(); | |
5778 | ||
5779 | ClearTitleFromHistoInCanvas(cYieldComparisons); | |
5780 | ||
5781 | ||
5782 | ||
5783 | ||
5784 | TCanvas* cFractionsPions = drawFractionHistos("cFractionsPions", "Pion fractions", mode, pLow, pHigh, hFractionPionsDeltaPion, | |
5785 | hFractionPionsDeltaElectron, hFractionPionsDeltaKaon, hFractionPionsDeltaProton, | |
5786 | hFractionPionsMC, plotIdentifiedSpectra); | |
5787 | ||
5788 | ||
5789 | TCanvas* cFractionsElectrons = drawFractionHistos("cFractionsElectrons", "Electron fractions", mode, pLow, pHigh, | |
5790 | hFractionElectronsDeltaPion, hFractionElectronsDeltaElectron, | |
5791 | hFractionElectronsDeltaKaon, hFractionElectronsDeltaProton, hFractionElectronsMC, | |
5792 | plotIdentifiedSpectra); | |
5793 | ||
5794 | TCanvas* cFractionsKaons = drawFractionHistos("cFractionsKaons", "Kaon fractions", mode, pLow, pHigh, hFractionKaonsDeltaPion, | |
5795 | hFractionKaonsDeltaElectron, hFractionKaonsDeltaKaon, hFractionKaonsDeltaProton, | |
5796 | hFractionKaonsMC, plotIdentifiedSpectra); | |
5797 | ||
5798 | TCanvas* cFractionsProtons = drawFractionHistos("cFractionsProtons", "Proton fractions", mode, pLow, pHigh, hFractionProtonsDeltaPion, | |
5799 | hFractionProtonsDeltaElectron, hFractionProtonsDeltaKaon, hFractionProtonsDeltaProton, | |
5800 | hFractionProtonsMC, plotIdentifiedSpectra); | |
5801 | ||
5802 | TCanvas* cFractionsMuons = drawFractionHistos("cFractionsMuons", "Muon fractions", mode, pLow, pHigh, hFractionMuonsDeltaPion, | |
5803 | hFractionMuonsDeltaElectron, hFractionMuonsDeltaKaon, hFractionMuonsDeltaProton, | |
5804 | hFractionMuonsMC, plotIdentifiedSpectra); | |
5805 | ||
5806 | ||
5807 | ||
5808 | TCanvas* cYields = new TCanvas("cYields", "Particle yields",100,10,1200,800); | |
5809 | cYields->SetGridx(1); | |
5810 | cYields->SetGridy(1); | |
5811 | cYields->SetLogx(mode == kPMpT); | |
5812 | cYields->SetLogy(1); | |
5813 | hYieldPions->GetYaxis()->SetRangeUser(hYieldElectrons->GetBinContent(hYieldElectrons->FindLastBinAbove(0.)) / 10., | |
5814 | hYieldPions->GetBinContent(hYieldPions->GetMaximumBin()) * 10.); | |
5815 | SetReasonableAxisRange(hYieldPions->GetXaxis(), mode, pLow, pHigh); | |
5816 | hYieldPions->GetXaxis()->SetMoreLogLabels(kTRUE); | |
5817 | hYieldPions->GetXaxis()->SetNoExponent(kTRUE); | |
5818 | hYieldPions->Draw("e p"); | |
5819 | if (plotIdentifiedSpectra) { | |
5820 | SetReasonableAxisRange(hYieldPionsMC->GetXaxis(), mode, pLow, pHigh); | |
5821 | hYieldPionsMC->Draw("e p same"); | |
5822 | } | |
5823 | ||
5824 | SetReasonableAxisRange(hYieldKaons->GetXaxis(), mode, pLow, pHigh); | |
5825 | hYieldKaons->Draw("e p same"); | |
5826 | if (plotIdentifiedSpectra) { | |
5827 | SetReasonableAxisRange(hYieldKaonsMC->GetXaxis(), mode, pLow, pHigh); | |
5828 | hYieldKaonsMC->Draw("e p same"); | |
5829 | } | |
5830 | ||
5831 | SetReasonableAxisRange(hYieldProtons->GetXaxis(), mode, pLow, pHigh); | |
5832 | hYieldProtons->Draw("e p same"); | |
5833 | if (plotIdentifiedSpectra) { | |
5834 | SetReasonableAxisRange(hYieldProtonsMC->GetXaxis(), mode, pLow, pHigh); | |
5835 | hYieldProtonsMC->Draw("e p same"); | |
5836 | } | |
5837 | ||
5838 | if (takeIntoAccountMuons) { | |
5839 | SetReasonableAxisRange(hYieldMuons->GetXaxis(), mode, pLow, pHigh); | |
5840 | hYieldMuons->Draw("e p same"); | |
5841 | if (plotIdentifiedSpectra) { | |
5842 | SetReasonableAxisRange(hYieldMuonsMC->GetXaxis(), mode, pLow, pHigh); | |
5843 | hYieldMuonsMC->Draw("e p same"); | |
5844 | } | |
5845 | } | |
5846 | ||
5847 | SetReasonableAxisRange(hYieldElectrons->GetXaxis(), mode, pLow, pHigh); | |
5848 | hYieldElectrons->Draw("e p same"); | |
5849 | if (plotIdentifiedSpectra) { | |
5850 | SetReasonableAxisRange(hYieldElectronsMC->GetXaxis(), mode, pLow, pHigh); | |
5851 | hYieldElectronsMC->Draw("e p same"); | |
5852 | } | |
5853 | ||
5854 | TLegend* legendYields = new TLegend(0.622126, 0.605932, 0.862069, 0.855932); | |
5855 | legendYields->SetBorderSize(0); | |
5856 | legendYields->SetFillColor(0); | |
5857 | if (plotIdentifiedSpectra) | |
5858 | legendYields->SetNColumns(2); | |
5859 | if (plotIdentifiedSpectra) | |
5860 | legendYields->AddEntry((TObject*)0x0, "Fit", ""); | |
5861 | if (plotIdentifiedSpectra) | |
5862 | legendYields->AddEntry((TObject*)0x0, identifiedLabels[isMC].Data(), ""); | |
5863 | legendYields->AddEntry(hYieldPions, "#pi", "p"); | |
5864 | if (plotIdentifiedSpectra) | |
5865 | legendYields->AddEntry(hYieldPionsMC, "#pi", "p"); | |
5866 | legendYields->AddEntry(hYieldKaons, "K", "p"); | |
5867 | if (plotIdentifiedSpectra) | |
5868 | legendYields->AddEntry(hYieldKaonsMC, "K", "p"); | |
5869 | legendYields->AddEntry(hYieldProtons, "p", "p"); | |
5870 | if (plotIdentifiedSpectra) | |
5871 | legendYields->AddEntry(hYieldProtonsMC, "p", "p"); | |
5872 | legendYields->AddEntry(hYieldElectrons, "e", "p"); | |
5873 | if (plotIdentifiedSpectra) | |
5874 | legendYields->AddEntry(hYieldElectronsMC, "e", "p"); | |
5875 | if (takeIntoAccountMuons) | |
5876 | legendYields->AddEntry(hYieldMuons, "#mu", "p"); | |
5877 | else | |
5878 | legendYields->AddEntry((TObject*)0x0, "", ""); | |
5879 | if (plotIdentifiedSpectra) | |
5880 | legendYields->AddEntry(hYieldMuonsMC, "#mu", "p"); | |
5881 | legendYields->Draw(); | |
5882 | ||
5883 | ClearTitleFromHistoInCanvas(cYields); | |
5884 | ||
5885 | ||
5886 | TCanvas* cYieldsPions = drawYieldHistos("cYieldsPions", "Pion yields", mode, pLow, pHigh, hYieldPionsDeltaPion, hYieldPionsDeltaElectron, | |
5887 | hYieldPionsDeltaKaon, hYieldPionsDeltaProton, hYieldPionsMC, plotIdentifiedSpectra); | |
5888 | ||
5889 | ||
5890 | TCanvas* cYieldsElectrons = drawYieldHistos("cYieldsElectrons", "Electron yields", mode, pLow, pHigh, hYieldElectronsDeltaPion, | |
5891 | hYieldElectronsDeltaElectron, hYieldElectronsDeltaKaon, hYieldElectronsDeltaProton, hYieldElectronsMC, | |
5892 | plotIdentifiedSpectra); | |
5893 | ||
5894 | TCanvas* cYieldsKaons = drawYieldHistos("cYieldsKaons", "Kaon yields", mode, pLow, pHigh, hYieldKaonsDeltaPion, hYieldKaonsDeltaElectron, | |
5895 | hYieldKaonsDeltaKaon, hYieldKaonsDeltaProton, hYieldKaonsMC, plotIdentifiedSpectra); | |
5896 | ||
5897 | TCanvas* cYieldsProtons = drawYieldHistos("cYieldsProtons", "Proton yields", mode, pLow, pHigh, hYieldProtonsDeltaPion, hYieldProtonsDeltaElectron, | |
5898 | hYieldProtonsDeltaKaon, hYieldProtonsDeltaProton, hYieldProtonsMC, plotIdentifiedSpectra); | |
5899 | ||
5900 | TCanvas* cYieldsMuons = drawYieldHistos("cYieldsMuons", "Muon yields", mode, pLow, pHigh, hYieldMuonsDeltaPion, hYieldMuonsDeltaElectron, | |
5901 | hYieldMuonsDeltaKaon, hYieldMuonsDeltaProton, hYieldMuonsMC, plotIdentifiedSpectra); | |
5902 | ||
5903 | ||
5904 | // Save final results | |
5905 | saveF->cd(); | |
5906 | ||
5907 | if (fElectronFraction) | |
5908 | fElectronFraction->Write(); | |
5909 | ||
5910 | if (hFractionElectrons) | |
5911 | hFractionElectrons->Write(0, TObject::kWriteDelete); | |
5912 | ||
5913 | if (hFractionKaons) | |
5914 | hFractionKaons->Write(0, TObject::kWriteDelete); | |
5915 | ||
5916 | if (hFractionPions) | |
5917 | hFractionPions->Write(0, TObject::kWriteDelete); | |
5918 | ||
5919 | if (hFractionProtons) | |
5920 | hFractionProtons->Write(0, TObject::kWriteDelete); | |
5921 | ||
5922 | if (hFractionMuons) | |
5923 | hFractionMuons->Write(0, TObject::kWriteDelete); | |
5924 | ||
5925 | if (hFractionSummed) | |
5926 | hFractionSummed->Write(0, TObject::kWriteDelete); | |
5927 | ||
5928 | ||
5929 | if (hFractionElectronsDeltaElectron) | |
5930 | hFractionElectronsDeltaElectron->Write(0, TObject::kWriteDelete); | |
5931 | ||
5932 | if (hFractionKaonsDeltaElectron) | |
5933 | hFractionKaonsDeltaElectron->Write(0, TObject::kWriteDelete); | |
5934 | ||
5935 | if (hFractionPionsDeltaElectron) | |
5936 | hFractionPionsDeltaElectron->Write(0, TObject::kWriteDelete); | |
5937 | ||
5938 | if (hFractionProtonsDeltaElectron) | |
5939 | hFractionProtonsDeltaElectron->Write(0, TObject::kWriteDelete); | |
5940 | ||
5941 | if (hFractionMuonsDeltaElectron) | |
5942 | hFractionMuonsDeltaElectron->Write(0, TObject::kWriteDelete); | |
5943 | ||
5944 | ||
5945 | if (hFractionElectronsDeltaPion) | |
5946 | hFractionElectronsDeltaPion->Write(0, TObject::kWriteDelete); | |
5947 | ||
5948 | if (hFractionKaonsDeltaPion) | |
5949 | hFractionKaonsDeltaPion->Write(0, TObject::kWriteDelete); | |
5950 | ||
5951 | if (hFractionPionsDeltaPion) | |
5952 | hFractionPionsDeltaPion->Write(0, TObject::kWriteDelete); | |
5953 | ||
5954 | if (hFractionProtonsDeltaPion) | |
5955 | hFractionProtonsDeltaPion->Write(0, TObject::kWriteDelete); | |
5956 | ||
5957 | if (hFractionMuonsDeltaPion) | |
5958 | hFractionMuonsDeltaPion->Write(0, TObject::kWriteDelete); | |
5959 | ||
5960 | ||
5961 | if (hFractionElectronsDeltaKaon) | |
5962 | hFractionElectronsDeltaKaon->Write(0, TObject::kWriteDelete); | |
5963 | ||
5964 | if (hFractionKaonsDeltaKaon) | |
5965 | hFractionKaonsDeltaKaon->Write(0, TObject::kWriteDelete); | |
5966 | ||
5967 | if (hFractionPionsDeltaKaon) | |
5968 | hFractionPionsDeltaKaon->Write(0, TObject::kWriteDelete); | |
5969 | ||
5970 | if (hFractionProtonsDeltaKaon) | |
5971 | hFractionProtonsDeltaKaon->Write(0, TObject::kWriteDelete); | |
5972 | ||
5973 | if (hFractionMuonsDeltaKaon) | |
5974 | hFractionMuonsDeltaKaon->Write(0, TObject::kWriteDelete); | |
5975 | ||
5976 | ||
5977 | if (hFractionElectronsDeltaProton) | |
5978 | hFractionElectronsDeltaProton->Write(0, TObject::kWriteDelete); | |
5979 | ||
5980 | if (hFractionKaonsDeltaProton) | |
5981 | hFractionKaonsDeltaProton->Write(0, TObject::kWriteDelete); | |
5982 | ||
5983 | if (hFractionPionsDeltaProton) | |
5984 | hFractionPionsDeltaProton->Write(0, TObject::kWriteDelete); | |
5985 | ||
5986 | if (hFractionProtonsDeltaProton) | |
5987 | hFractionProtonsDeltaProton->Write(0, TObject::kWriteDelete); | |
5988 | ||
5989 | if (hFractionMuonsDeltaProton) | |
5990 | hFractionMuonsDeltaProton->Write(0, TObject::kWriteDelete); | |
5991 | ||
5992 | if (hNumEvents) | |
5993 | hNumEvents->Write(); | |
5994 | ||
5995 | if (cFractions) | |
5996 | cFractions->Write(); | |
5997 | if (cFractionsPions) | |
5998 | cFractionsPions->Write(); | |
5999 | if (cFractionsElectrons) | |
6000 | cFractionsElectrons->Write(); | |
6001 | if (cFractionsKaons) | |
6002 | cFractionsKaons->Write(); | |
6003 | if (cFractionsProtons) | |
6004 | cFractionsProtons->Write(); | |
6005 | if (cFractionsMuons) | |
6006 | cFractionsMuons->Write(); | |
6007 | ||
6008 | ||
6009 | if (hFractionElectronsMC) | |
6010 | hFractionElectronsMC->Write(0, TObject::kWriteDelete); | |
6011 | ||
6012 | if (hFractionKaonsMC) | |
6013 | hFractionKaonsMC->Write(0, TObject::kWriteDelete); | |
6014 | ||
6015 | if (hFractionPionsMC) | |
6016 | hFractionPionsMC->Write(0, TObject::kWriteDelete); | |
6017 | ||
6018 | if (hFractionMuonsMC) | |
6019 | hFractionMuonsMC->Write(0, TObject::kWriteDelete); | |
6020 | ||
6021 | if (hFractionProtonsMC) | |
6022 | hFractionProtonsMC->Write(0, TObject::kWriteDelete); | |
6023 | ||
6024 | ||
6025 | if (hFractionComparisonElectrons) | |
6026 | hFractionComparisonElectrons->Write(0, TObject::kWriteDelete); | |
6027 | ||
6028 | if (hFractionComparisonMuons) | |
6029 | hFractionComparisonMuons->Write(0, TObject::kWriteDelete); | |
6030 | ||
6031 | if (hFractionComparisonKaons) | |
6032 | hFractionComparisonKaons->Write(0, TObject::kWriteDelete); | |
6033 | ||
6034 | if (hFractionComparisonPions) | |
6035 | hFractionComparisonPions->Write(0, TObject::kWriteDelete); | |
6036 | ||
6037 | if (hFractionComparisonProtons) | |
6038 | hFractionComparisonProtons->Write(0, TObject::kWriteDelete); | |
6039 | ||
6040 | if (hFractionComparisonTotal) | |
6041 | hFractionComparisonTotal->Write(0, TObject::kWriteDelete); | |
6042 | ||
6043 | if (cFractionComparisons) | |
6044 | cFractionComparisons->Write(); | |
6045 | ||
6046 | ||
6047 | if (hYieldComparisonElectrons) | |
6048 | hYieldComparisonElectrons->Write(0, TObject::kWriteDelete); | |
6049 | ||
6050 | if (hYieldComparisonMuons) | |
6051 | hYieldComparisonMuons->Write(0, TObject::kWriteDelete); | |
6052 | ||
6053 | if (hYieldComparisonKaons) | |
6054 | hYieldComparisonKaons->Write(0, TObject::kWriteDelete); | |
6055 | ||
6056 | if (hYieldComparisonPions) | |
6057 | hYieldComparisonPions->Write(0, TObject::kWriteDelete); | |
6058 | ||
6059 | if (hYieldComparisonProtons) | |
6060 | hYieldComparisonProtons->Write(0, TObject::kWriteDelete); | |
6061 | ||
6062 | if (cYieldComparisons) | |
6063 | cYieldComparisons->Write(); | |
6064 | ||
6065 | ||
6066 | if (hYieldElectrons) | |
6067 | hYieldElectrons->Write(0, TObject::kWriteDelete); | |
6068 | ||
6069 | if (hYieldKaons) | |
6070 | hYieldKaons->Write(0, TObject::kWriteDelete); | |
6071 | ||
6072 | if (hYieldPions) | |
6073 | hYieldPions->Write(0, TObject::kWriteDelete); | |
6074 | ||
6075 | if (hYieldProtons) | |
6076 | hYieldProtons->Write(0, TObject::kWriteDelete); | |
6077 | ||
6078 | if (hYieldMuons) | |
6079 | hYieldMuons->Write(0, TObject::kWriteDelete); | |
6080 | ||
6081 | ||
6082 | if (hYieldElectronsDeltaElectron) | |
6083 | hYieldElectronsDeltaElectron->Write(0, TObject::kWriteDelete); | |
6084 | ||
6085 | if (hYieldKaonsDeltaElectron) | |
6086 | hYieldKaonsDeltaElectron->Write(0, TObject::kWriteDelete); | |
6087 | ||
6088 | if (hYieldPionsDeltaElectron) | |
6089 | hYieldPionsDeltaElectron->Write(0, TObject::kWriteDelete); | |
6090 | ||
6091 | if (hYieldProtonsDeltaElectron) | |
6092 | hYieldProtonsDeltaElectron->Write(0, TObject::kWriteDelete); | |
6093 | ||
6094 | if (hYieldMuonsDeltaElectron) | |
6095 | hYieldMuonsDeltaElectron->Write(0, TObject::kWriteDelete); | |
6096 | ||
6097 | ||
6098 | if (hYieldElectronsDeltaPion) | |
6099 | hYieldElectronsDeltaPion->Write(0, TObject::kWriteDelete); | |
6100 | ||
6101 | if (hYieldKaonsDeltaPion) | |
6102 | hYieldKaonsDeltaPion->Write(0, TObject::kWriteDelete); | |
6103 | ||
6104 | if (hYieldPionsDeltaPion) | |
6105 | hYieldPionsDeltaPion->Write(0, TObject::kWriteDelete); | |
6106 | ||
6107 | if (hYieldProtonsDeltaPion) | |
6108 | hYieldProtonsDeltaPion->Write(0, TObject::kWriteDelete); | |
6109 | ||
6110 | if (hYieldMuonsDeltaPion) | |
6111 | hYieldMuonsDeltaPion->Write(0, TObject::kWriteDelete); | |
6112 | ||
6113 | ||
6114 | if (hYieldElectronsDeltaKaon) | |
6115 | hYieldElectronsDeltaKaon->Write(0, TObject::kWriteDelete); | |
6116 | ||
6117 | if (hYieldKaonsDeltaKaon) | |
6118 | hYieldKaonsDeltaKaon->Write(0, TObject::kWriteDelete); | |
6119 | ||
6120 | if (hYieldPionsDeltaKaon) | |
6121 | hYieldPionsDeltaKaon->Write(0, TObject::kWriteDelete); | |
6122 | ||
6123 | if (hYieldProtonsDeltaKaon) | |
6124 | hYieldProtonsDeltaKaon->Write(0, TObject::kWriteDelete); | |
6125 | ||
6126 | if (hYieldMuonsDeltaKaon) | |
6127 | hYieldMuonsDeltaKaon->Write(0, TObject::kWriteDelete); | |
6128 | ||
6129 | ||
6130 | if (hYieldElectronsDeltaProton) | |
6131 | hYieldElectronsDeltaProton->Write(0, TObject::kWriteDelete); | |
6132 | ||
6133 | if (hYieldKaonsDeltaProton) | |
6134 | hYieldKaonsDeltaProton->Write(0, TObject::kWriteDelete); | |
6135 | ||
6136 | if (hYieldPionsDeltaProton) | |
6137 | hYieldPionsDeltaProton->Write(0, TObject::kWriteDelete); | |
6138 | ||
6139 | if (hYieldProtonsDeltaProton) | |
6140 | hYieldProtonsDeltaProton->Write(0, TObject::kWriteDelete); | |
6141 | ||
6142 | if (hYieldMuonsDeltaProton) | |
6143 | hYieldMuonsDeltaProton->Write(0, TObject::kWriteDelete); | |
6144 | ||
6145 | ||
6146 | if (hYieldElectronsMC) | |
6147 | hYieldElectronsMC->Write(0, TObject::kWriteDelete); | |
6148 | ||
6149 | if (hYieldKaonsMC) | |
6150 | hYieldKaonsMC->Write(0, TObject::kWriteDelete); | |
6151 | ||
6152 | if (hYieldPionsMC) | |
6153 | hYieldPionsMC->Write(0, TObject::kWriteDelete); | |
6154 | ||
6155 | if (hYieldMuonsMC) | |
6156 | hYieldMuonsMC->Write(0, TObject::kWriteDelete); | |
6157 | ||
6158 | if (hYieldProtonsMC) | |
6159 | hYieldProtonsMC->Write(0, TObject::kWriteDelete); | |
6160 | ||
6161 | if (hYieldSummedMC) | |
6162 | hYieldSummedMC->Write(0, TObject::kWriteDelete); | |
6163 | ||
6164 | ||
6165 | if (hRatioToPiElectrons) | |
6166 | hRatioToPiElectrons->Write(0, TObject::kWriteDelete); | |
6167 | ||
6168 | if (hRatioToPiMuons) | |
6169 | hRatioToPiMuons->Write(0, TObject::kWriteDelete); | |
6170 | ||
6171 | if (hRatioToPiKaons) | |
6172 | hRatioToPiKaons->Write(0, TObject::kWriteDelete); | |
6173 | ||
6174 | if (hRatioToPiProtons) | |
6175 | hRatioToPiProtons->Write(0, TObject::kWriteDelete); | |
6176 | ||
6177 | if (hRatioToPiElectronsMC) | |
6178 | hRatioToPiElectronsMC->Write(0, TObject::kWriteDelete); | |
6179 | ||
6180 | if (hRatioToPiMuonsMC) | |
6181 | hRatioToPiMuonsMC->Write(0, TObject::kWriteDelete); | |
6182 | ||
6183 | if (hRatioToPiKaonsMC) | |
6184 | hRatioToPiKaonsMC->Write(0, TObject::kWriteDelete); | |
6185 | ||
6186 | if (hRatioToPiProtonsMC) | |
6187 | hRatioToPiProtonsMC->Write(0, TObject::kWriteDelete); | |
6188 | ||
6189 | ||
6190 | ||
6191 | if (hReducedChiSquarePt) | |
6192 | hReducedChiSquarePt->Write(0, TObject::kWriteDelete); | |
6193 | ||
6194 | if (cYields) | |
6195 | cYields->Write(); | |
6196 | if (cYieldsPions) | |
6197 | cYieldsPions->Write(); | |
6198 | if (cYieldsElectrons) | |
6199 | cYieldsElectrons->Write(); | |
6200 | if (cYieldsKaons) | |
6201 | cYieldsKaons->Write(); | |
6202 | if (cYieldsProtons) | |
6203 | cYieldsProtons->Write(); | |
6204 | if (cYieldsMuons) | |
6205 | cYieldsMuons->Write(); | |
6206 | ||
6207 | for (Int_t i = 0; i < AliPID::kSPECIES; i++) { | |
6208 | if (hMCgenYieldsPrimSpecies[i]) | |
6209 | hMCgenYieldsPrimSpecies[i]->Write(); | |
6210 | } | |
6211 | ||
6212 | if (filePathNameResults) | |
6213 | *filePathNameResults = saveFName; | |
6214 | ||
6215 | if (TMath::Abs(mathFit->GetScaleFactorError() - 1.) > 1e-6) { | |
6216 | // If the deltaPrime range is large enough, we artificially get a factor 4 in statistics by looking at the four | |
6217 | // different deltaPrimeSpecies, which have (except for binning effects) the same information. | |
6218 | // Therefore, to get the "real" statistical error, we need to multiply the obtained error by sqrt(4) = 2 | |
6219 | std::cout << "NOTE: Errors multiplied by " << mathFit->GetScaleFactorError() | |
6220 | << " to take into account artificially higher statistics (by factor of 4) due to same information " | |
6221 | << "for all deltaPrimeSpecies (except for binning effects), if deltaPrimeRange sufficiently large!" << std::endl | |
6222 | << std::endl; | |
6223 | } | |
6224 | ||
6225 | if (fitMethod < 2) { | |
6226 | std::cout << "WARNING: Errors might be wrong! Especially, for the to-pi ratios there are no correlations taken into account!" | |
6227 | << std::endl; | |
6228 | } | |
6229 | ||
6230 | delete gFractionElectronsData; | |
6231 | delete fElectronFraction; | |
6232 | ||
6233 | delete mathFit; | |
6234 | ||
6235 | delete cFractions; | |
6236 | delete cFractionComparisons; | |
6237 | delete cYieldComparisons; | |
6238 | delete cFractionsPions; | |
6239 | delete cFractionsElectrons; | |
6240 | delete cFractionsKaons; | |
6241 | delete cFractionsProtons; | |
6242 | delete cFractionsMuons; | |
6243 | delete cYields; | |
6244 | delete cYieldsPions; | |
6245 | delete cYieldsKaons; | |
6246 | delete cYieldsMuons; | |
6247 | delete cYieldsProtons; | |
6248 | delete cYieldsElectrons; | |
6249 | ||
6250 | saveF->Close(); | |
6251 | ||
6252 | return 0; | |
6253 | } |