4 #include "TFitResult.h"
7 #include "TGraphErrors.h"
18 #include "ProgressBar.h"
19 #include "THnSparseDefinitions.h"
21 //________________________________________________________________________
22 void FitSlicesY(TH2 *hist, Double_t heightFractionForRange, Int_t cutThreshold, TString fitOption, TObjArray *arr)
24 //heightPercentageForRange
31 // If old style is to be used
33 hist->FitSlicesY(0, 0, -1, cutThreshold, fitOption.Data(), arr);
42 TAxis *axis=hist->GetXaxis();
43 const TArrayD *bins = axis->GetXbins();
44 TH1D** hList = new TH1D*[4];
46 for (Int_t i = 0; i < 4; i++) {
47 delete gDirectory->FindObject(Form("%s_%d", hist->GetName(), i));
50 hList[i] = new TH1D(Form("%s_%d", hist->GetName(), i), i < 3 ? Form("Fitted value of par[%d]", i) : "Chi2/NDF",
51 hist->GetNbinsX(), axis->GetXmin(), axis->GetXmax());
53 hList[i] = new TH1D(Form("%s_%d", hist->GetName(), i), i < 3 ? Form("Fitted value of par[%d]", i) : "Chi2/NDF", hist->GetNbinsX(), bins->fArray);
59 for (Int_t ibin=axis->GetFirst(); ibin<=axis->GetLast(); ++ibin){
60 TH1 *h=hist->ProjectionY("_temp",ibin,ibin);
64 if (h->GetEntries() < cutThreshold) {
69 // Average around maximum bin -> Might catch some outliers
70 Int_t maxBin = h->GetMaximumBin();
71 Double_t maxVal = h->GetBinContent(maxBin);
73 if (maxVal < 2) { // It could happen that all entries are in overflow/underflow; don't fit in this case
80 maxVal += h->GetBinContent(maxBin - 1);
83 if (maxBin < h->GetNbinsX()) {
84 maxVal += h->GetBinContent(maxBin + 1);
89 Double_t thresholdFraction = heightFractionForRange * maxVal;
90 Int_t lowThrBin = TMath::Max(1, h->FindFirstBinAbove(thresholdFraction));
91 Int_t highThrBin = TMath::Min(h->GetNbinsX(), h->FindLastBinAbove(thresholdFraction));
93 Double_t lowThreshold = h->GetBinCenter(lowThrBin);
94 Double_t highThreshold = h->GetBinCenter(highThrBin);
96 TFitResultPtr res = h->Fit("gaus", Form("%sS", fitOption.Data()), "", lowThreshold, highThreshold);
98 if ((Int_t)res == 0) {
100 hList[0]->SetBinContent(resBin,res->GetParams()[0]);
101 hList[0]->SetBinError(resBin,res->GetErrors()[0]);
102 hList[1]->SetBinContent(resBin,res->GetParams()[1]);
103 hList[1]->SetBinError(resBin,res->GetErrors()[1]);
104 hList[2]->SetBinContent(resBin,res->GetParams()[2]);
105 hList[2]->SetBinError(resBin,res->GetErrors()[2]);
106 hList[3]->SetBinContent(resBin,res->Ndf()>0?res->Chi2()/res->Ndf():0);
115 //__________________________________________________________________________________________
116 Int_t extractMultiplicityDependence(TString pathTree, Double_t widthFactor /*=1*/, Int_t multStepSize /*= 400*/, Bool_t isMC,
117 Bool_t correct = kFALSE, TString fileNameTree = "bhess_PIDetaTree.root", TString treeName = "fTree",
118 TString pathNameSplines = "splines_10h.pass2.root", TString splineName = "TSPLINE3_DATA_PROTON_LHC10H_PASS2_PBPB_MEAN")
120 const Double_t massProton = AliPID::ParticleMass(AliPID::kProton);
121 const Double_t massPion = AliPID::ParticleMass(AliPID::kPion);
123 Double_t mass = massProton;
126 // Extract the data tree
127 TFile* fTree = TFile::Open(Form("%s/%s", pathTree.Data(), fileNameTree.Data()));
129 std::cout << "Failed to open file \"" << Form("%s/%s", pathTree.Data(), fileNameTree.Data()) << "\"!" << std::endl;
133 TTree* tree = dynamic_cast<TTree*>(fTree->Get(treeName.Data()));
135 std::cout << "Failed to load data tree!" << std::endl;
141 TString savefileName = Form("%s_multiplicityDependence_%04d_%02d_%02d__%02d_%02d.root", fileNameTree.ReplaceAll(".root", "").Data(),
142 daTime.GetYear(), daTime.GetMonth(), daTime.GetDay(), daTime.GetHour(), daTime.GetMinute());
144 TFile* fSave = TFile::Open(Form("%s/%s", pathTree.Data(), savefileName.Data()), "recreate");
146 std::cout << "Failed to open save file \"" << Form("%s/%s", pathTree.Data(), savefileName.Data()) << "\"!" << std::endl;
150 Long64_t nTreeEntries = tree->GetEntriesFast();
154 //Double_t dEdxExpected = 0.;
155 Double_t tanTheta = 0.;
156 UShort_t tpcSignalN = 0.;
157 Int_t fMultiplicity = 0.;
160 tree->SetBranchStatus("*", 0); // Disable all branches
161 tree->SetBranchStatus("pTPC", 1);
162 tree->SetBranchStatus("dEdx", 1);
163 //tree->SetBranchStatus("dEdxExpected", 1);
164 tree->SetBranchStatus("tanTheta", 1);
165 tree->SetBranchStatus("fMultiplicity", 1);
166 tree->SetBranchStatus("tpcSignalN", 1);
167 tree->SetBranchStatus("pidType", 1);
170 tree->SetBranchAddress("pTPC", &pTPC);
171 tree->SetBranchAddress("dEdx", &dEdx);
172 //tree->SetBranchAddress("dEdxExpecttanThetaCentered", &dEdxExpected);
173 tree->SetBranchAddress("tanTheta", &tanTheta);
174 tree->SetBranchAddress("fMultiplicity", &fMultiplicity);
175 tree->SetBranchAddress("tpcSignalN", &tpcSignalN);
176 tree->SetBranchAddress("pidType", &pidType);
178 const Int_t numMultBins = TMath::Ceil((20000. - 0.) / multStepSize);
180 const Int_t numPbins = 24;
181 Double_t pBinEdges[numPbins * 2] = {
182 0.3, 0.3 + 0.005*widthFactor,
183 0.35, 0.35 + 0.005*widthFactor,
184 0.4, 0.4 + 0.005*widthFactor,
185 0.45, 0.45 + 0.005*widthFactor,
186 0.5, 0.5 + 0.005*widthFactor,
187 0.55, 0.55 + 0.005*widthFactor,
188 0.6, 0.6 + 0.005*widthFactor,
189 0.65, 0.65 + 0.005*widthFactor,
190 0.7, 0.7 + 0.005*widthFactor,
191 0.8, 0.8 + 0.01*widthFactor,
192 0.9, 0.9 + 0.01*widthFactor,
193 1.0, 1.0 + 0.01*widthFactor,
194 1.1, 1.1 + 0.01*widthFactor,
195 1.2, 1.2 + 0.01*widthFactor,
196 1.3, 1.3 + 0.01*widthFactor,
197 1.4, 1.4 + 0.01*widthFactor,
198 1.5, 1.5 + 0.01*widthFactor,
199 1.6, 1.6 + 0.02*widthFactor,
200 1.7, 1.7 + 0.02*widthFactor,
201 1.8, 1.8 + 0.02*widthFactor,
202 1.9, 1.9 + 0.02*widthFactor,
203 2.0, 2.0 + 0.1*widthFactor,
204 2.5, 2.5 + 0.1*widthFactor,
205 3.0, 3.0 + 0.15*widthFactor };
207 const Int_t numTanThetaBins = 10;
209 Double_t tanThetaBinEdges[numTanThetaBins * 2] = {
221 Double_t tanThetaBinEdges[numTanThetaBins * 2] = {
233 TH2D* h2[numPbins][numTanThetaBins];
234 TH2D* h2AllEta[numPbins];
236 for (Int_t i = 0; i < numPbins; i++) {
237 h2AllEta[i] = new TH2D(Form("h2AllEta_%d", i), Form("p %.2f - %.2f GeV/c, all #eta; Multiplicity; dEdx", pBinEdges[2*i], pBinEdges[2*i+1]),
238 numMultBins, 0, 20000, 590, 10.0, 600.0);
240 for (Int_t j = 0; j < numTanThetaBins; j++) {
241 h2[i][j] = new TH2D(Form("h2_%d_%d", i, j), Form("p %.2f - %.2f GeV/c & %.2f < tanTheta #leq %.2f; Multiplicity; dEdx",
242 //TODO tanThetaAbs h2[i][j] = new TH2D(Form("h2_%d_%d", i, j), Form("p %.2f - %.2f GeV/c & %.2f < |tanTheta| #leq %.2f; Multiplicity; dEdx",
243 pBinEdges[2*i], pBinEdges[2*i+1], tanThetaBinEdges[2*j], tanThetaBinEdges[2*j+1]),
244 numMultBins, 0, 20000, 590, 10.0, 600.0);
248 TSpline3* splProton = 0x0;
251 printf("CORRECTING data for multiplicity dependence...TODO OBSOLETE - DO NOT USE!!!!\n");
254 f = TFile::Open(pathNameSplines.Data());
256 std::cout << "Failed to open spline file \"" << pathNameSplines.Data() << "\"!" << std::endl;
260 splProton = (TSpline3*)f->Get(splineName.Data());
262 std::cout << "Failed to load splines: " << splineName.Data() << "!" << std::endl;
266 if (splineName.Contains("PION")){
267 printf("Pion mass assumed: %f...\n", massPion);
271 printf("Proton mass assumed: %f...\n", massProton);
276 printf("NOT CORRECTING data for multiplicity dependence...\n");
280 TF1 cutFunc("cutFunc","50./TMath::Power(x,1.3)", 0.05, 6);
282 TF1 corrFunc("corrFunc", "pol2", 0, 0.01);
283 corrFunc.SetParameter(0, 5.5e-6);
284 corrFunc.SetParameter(1, -0.00436);
285 corrFunc.SetParameter(2, 0.103);
287 for (Long64_t i = 0; i < nTreeEntries; i++) {
291 progressbar(100. * (((Double_t)i) / nTreeEntries));
293 // Filter tracks according to shape recognition
294 //if (tpcSignalN < 60 || (!isMC && dEdx < cutFunc.Eval(pTPC))) continue;
295 if (dEdx <= 0 || tpcSignalN < 60) {
300 if ((pTPC < 0.6 && pidType != kTPCid) || // No V0s/TOF below 0.6 due to bad statistics
301 //if ((pTPC < 0.6 && pidType == kTPCandTOFid) || // No TOF below 0.6 GeV/c due to bad statistics
302 //TODO NOW Maybe don't use this line since the tails get fewer V0's than the main peak, so the tails are overall reduced (pTPC >= 0.6 && pTPC < pThreholdV0cut && pidType != kTPCandTOFid) || // Do not mix V0's and TOF in this range
303 (pTPC >= 0.6 && pTPC < 0.9 && pidType != kTPCandTOFid) ||
304 (pTPC >= 0.9 && pidType != kV0idPlusTOFaccepted && pidType != kV0idNoTOF)) // Only V0's WITH TOF above pThreholdV0cut due to contamination
308 // CORRECT multiplicity dependence -> WARNING: Better take into account the eta dependence for dEdxSplines for the determination of corrFactor!!!
310 Double_t dEdxSplines = 50. * splProton->Eval(pTPC / mass);
311 Double_t dEdxSplinesInv = 1. / dEdxSplines;
312 Double_t relSlope = corrFunc.Eval(dEdxSplinesInv);
313 Double_t corrFactor = relSlope * fMultiplicity;
314 dEdx /= 1. + corrFactor;
319 //TODO tanThetaAbs Double_t absTanTheta = TMath::Abs(tanTheta);
321 for (Int_t j = 0; j < numPbins; j++) {
322 if (pTPC >= pBinEdges[2*j] && pTPC < pBinEdges[2*j+1]) {
323 h2AllEta[j]->Fill(fMultiplicity, dEdx);
325 for (Int_t k = 0; k < numTanThetaBins; k++) {
326 if (tanTheta >= tanThetaBinEdges[2*k] && tanTheta < tanThetaBinEdges[2*k+1]) {
327 //TODO tanThetaAbs if (absTanTheta >= tanThetaBinEdges[2*k] && absTanTheta < tanThetaBinEdges[2*k+1]) {
328 h2[j][k]->Fill(fMultiplicity, dEdx);
342 const Double_t MCfitThreshold = 0.006;
343 const Double_t heightFractionForRange = 0.1;
346 { // Fitting for all eta
347 TGraphErrors* gSlvsOffset = new TGraphErrors(numPbins);
348 TGraphErrors* gSlvsInvOffset = new TGraphErrors(numPbins);
350 TGraphErrors* gSigmaSlopevsdEdx = new TGraphErrors(numPbins);
351 TGraphErrors* gSigmaSlopevsInvdEdx = new TGraphErrors(numPbins);
353 fSave->mkdir("allTanTheta");
355 for (Int_t i = 0; i < numPbins; i++) {
356 gSlvsOffset->SetPoint(i, -10, 0);
357 gSlvsOffset->SetPointError(i, 0, 0);
359 gSlvsInvOffset->SetPoint(i, -10, 0);
360 gSlvsInvOffset->SetPointError(i, 0, 0);
362 gSigmaSlopevsdEdx->SetPoint(i, -10, 0);
363 gSigmaSlopevsdEdx->SetPointError(i, 0, 0);
365 gSigmaSlopevsInvdEdx->SetPoint(i, -10, 0);
366 gSigmaSlopevsInvdEdx->SetPointError(i, 0, 0);
368 if (h2AllEta[i]->GetEntries() < 10)
371 printf("Momentum %.2f - %.2f GeV/c, all eta:\n", pBinEdges[2*i], pBinEdges[2*i+1]);
372 TCanvas* c = new TCanvas(Form("canv_pBin%d_allEta", i), Form("canv_pBin%d_allEta", i), 100,10,1380,800);
373 FitSlicesY(h2AllEta[i], heightFractionForRange, 10, "QN", &arr);
374 h2AllEta[i]->GetYaxis()->SetRange(h2AllEta[i]->FindFirstBinAbove(1, 2), h2AllEta[i]->FindLastBinAbove(1,2));
375 h2AllEta[i]->Draw("colz");
377 TH1D* hMean = (TH1D*)arr.At(1);//new TH1D((TH1D&)*arr.At(1));
378 TH1D* hSigma = (TH1D*)arr.At(2);//new TH1D((TH1D&)*arr.At(2));
379 hMean->SetName(Form("hMean_allEta_pBin%d", i));
380 hSigma->SetName(Form("hSigma_allEta_pBin%d", i));
381 hSigma->SetLineColor(kMagenta);
383 TH1D* hSigmaRel = new TH1D(*hSigma);
384 hSigmaRel->SetName(Form("hSigmaRel_allEta_pBin%d", i));
385 hSigmaRel->Divide(hMean);
386 hSigmaRel->SetLineColor(kMagenta + 2);
388 TFitResultPtr fitRes = hMean->Fit("pol1", "s", "same", 0, 12000);
389 TFitResultPtr fitResSigma = hSigmaRel->Fit("pol1", "s", "same", 0, 12000);
391 hMean->DrawClone("same");
393 if (((Int_t)fitRes) != 0) {
394 printf("Fit failed!\n");
397 Double_t p0 = fitRes->GetParams()[0];
398 Double_t p1 = fitRes->GetParams()[1];
399 Double_t err0 = fitRes->GetErrors()[0];
400 Double_t err1 = fitRes->GetErrors()[1];
402 Double_t totError = 99999;
403 if (p0 != 0 && p1 != 0) {
404 totError = TMath::Abs(p1 / p0 * TMath::Sqrt(TMath::Power(err0 / p0, 2) + TMath::Power(err1 / p1, 2)));
406 printf("Result: p1 / p0 = %f / %f = %e\n\n", p1, p0, (p0 != 0 ? p1 / p0 : -99999));
408 gSlvsOffset->SetPoint(i, p0, p1/p0);
409 gSlvsOffset->SetPointError(i, err0, totError);
411 gSlvsInvOffset->SetPoint(i, 1./p0, p1/p0);
412 gSlvsInvOffset->SetPointError(i, TMath::Abs(err0/p0/p0), totError);
414 // Only makes sense, if valid p0 available
415 if (((Int_t)fitResSigma) != 0) {
416 printf("Sigma fit failed!\n");
419 Double_t pSigma0 = fitResSigma->GetParams()[0];
420 Double_t errSigma0 = fitResSigma->GetErrors()[0];
422 Double_t pSigma1 = fitResSigma->GetParams()[1];
423 Double_t errSigma1 = fitResSigma->GetErrors()[1];
425 printf("Result sigma: pSigma1 / pSigma0 = %f / %f = %e\n\n", pSigma1, pSigma0, (pSigma0 != 0 ? pSigma1 / pSigma0 : -99999));
427 Double_t totErrorSigma = 99999;
428 if (pSigma0 != 0 && pSigma1 != 0) {
429 totErrorSigma = TMath::Abs(pSigma1 / pSigma0 * TMath::Sqrt(TMath::Power(errSigma0 / pSigma0, 2) + TMath::Power(errSigma1 / pSigma1, 2)));
433 gSigmaSlopevsdEdx->SetPoint(i, p0, pSigma1/pSigma0);
434 gSigmaSlopevsdEdx->SetPointError(i, err0, totErrorSigma);
436 gSigmaSlopevsInvdEdx->SetPoint(i, 1./p0, pSigma1/pSigma0);
437 gSigmaSlopevsInvdEdx->SetPointError(i, TMath::Abs(err0/p0/p0), totErrorSigma);
439 // Set artificially large errors for points with positive slope vs. multiplicity
440 // (negative slope makes physically no sense and is most likely due to uncertainties)
442 gSigmaSlopevsdEdx->SetPointError(i, err0, 1000);
443 gSigmaSlopevsInvdEdx->SetPointError(i, TMath::Abs(err0/p0/p0), 1000);
450 fSave->cd("allTanTheta");
457 gSlvsOffset->SetName("slopes_AllEta");
458 gSlvsOffset->SetTitle("Rel. slope vs. offset (all #eta)");
459 gSlvsOffset->SetMarkerColor(kBlack);
460 gSlvsOffset->SetLineColor(kBlack);
461 gSlvsOffset->SetMarkerStyle(20);
462 gSlvsOffset->Draw("Ap");
463 gSlvsOffset->GetHistogram()->GetXaxis()->SetTitle("dEdx (offset)");
464 gSlvsOffset->GetHistogram()->GetYaxis()->SetTitle("Multiplicity slope/offset");
465 gSlvsOffset->Fit("pol2", "W EX0", "same", 50, 300);
466 TF1* fitFuncResult = dynamic_cast<TF1*>(gSlvsOffset->GetListOfFunctions()->At(0));
468 fitFuncResult->SetLineColor(kBlack);
470 gSlvsInvOffset->SetName("slopes2_AllEta");
471 gSlvsInvOffset->SetTitle("Rel. slope vs. 1./offset (all #eta)");
472 gSlvsInvOffset->SetMarkerColor(kBlack);
473 gSlvsInvOffset->SetLineColor(kBlack);
474 gSlvsInvOffset->SetMarkerStyle(20);
475 gSlvsInvOffset->Draw("Ap");
476 gSlvsInvOffset->GetHistogram()->GetXaxis()->SetTitle("1./dEdx (1./offset)");
477 gSlvsInvOffset->GetHistogram()->GetYaxis()->SetTitle("Multiplicity slope/offset");
479 TFitResultPtr fitRes = gSlvsInvOffset->Fit("pol2", "S 0 W EX0", "", 0, 0.02);//isMC ? MCfitThreshold : 0., 0.018); // Estimate pol2 params for subsequent fit
480 //TODO NEW Introduced parameter [4]
481 TF1 fitFunc("fitFunc", "[0] + [1]*TMath::Max([4], TMath::Min(x, [3])) + [2] * TMath::Power(TMath::Max([4], TMath::Min(x, [3])), 2)", 0., 0.2);
482 //TF1 fitFunc("fitFunc", "[0] + [1]*TMath::Min(x, [3]) + [2] * TMath::Power(TMath::Min(x, [3]), 2)", 0., 0.1);
485 //TF1* fitFuncResult2 = dynamic_cast<TF1*>(gSlvsInvOffset->GetListOfFunctions()->At(0));
486 if ((Int_t)fitRes == 0)
487 fitFunc.SetParameters(fitRes->GetParams());
488 fitFunc.SetParameter(3, isMC ? 0.1 : 0.018);
489 fitFunc.SetParLimits(3, isMC ? 0.014 : 0.01, 0.2);//TODO NEW
490 // No lower threshold for data
492 fitFunc.SetParameter(4, MCfitThreshold);
493 fitFunc.SetParLimits(4, 0., 0.01);
496 fitFunc.FixParameter(4, 0.);
498 fitFunc.SetLineColor(kBlack);
500 gSlvsInvOffset->Fit(&fitFunc, "EX0", "same", /*TODO NEW isMC ? MCfitThreshold : */0., 0.2);
504 gSigmaSlopevsdEdx->SetName("sigmaSlopes_AllEta");
505 gSigmaSlopevsdEdx->SetTitle("Sigma rel slope vs. dEdx offset (all #eta)");
506 gSigmaSlopevsdEdx->SetMarkerColor(kBlack);
507 gSigmaSlopevsdEdx->SetLineColor(kBlack);
508 gSigmaSlopevsdEdx->SetMarkerStyle(20);
509 gSigmaSlopevsdEdx->Draw("Ap");
510 gSigmaSlopevsdEdx->GetHistogram()->GetXaxis()->SetTitle("dEdx (offset)");
511 gSigmaSlopevsdEdx->GetHistogram()->GetYaxis()->SetTitle("Multiplicity sigma rel. slope");
513 gSigmaSlopevsInvdEdx->SetName("sigmaSlopes2_AllEta");
514 gSigmaSlopevsInvdEdx->SetTitle("Sigma rel slope vs. 1./dEdx offset (all #eta)");
515 gSigmaSlopevsInvdEdx->SetMarkerColor(kBlack);
516 gSigmaSlopevsInvdEdx->SetLineColor(kBlack);
517 gSigmaSlopevsInvdEdx->SetMarkerStyle(20);
518 gSigmaSlopevsInvdEdx->Draw("Ap");
519 gSigmaSlopevsInvdEdx->GetHistogram()->GetXaxis()->SetTitle("1./dEdx (1./offset)");
520 gSigmaSlopevsInvdEdx->GetHistogram()->GetYaxis()->SetTitle("Multiplicity sigma rel. slope");
522 TFitResultPtr fitRes2 = gSigmaSlopevsInvdEdx->Fit("pol2", "S 0 W EX0", "same", 0., 0.012); // Estimate pol2 params for subsequent fit
523 TF1 fitFuncSigma("fitFuncSigma_AllEta", "TMath::Max(0, [0] + [1]*TMath::Min(x, [3]) + [2] * TMath::Power(TMath::Min(x, [3]), 2))", 0., 0.2);
524 if ((Int_t)fitRes2 == 0)
525 fitFuncSigma.SetParameters(fitRes2->GetParams());
526 fitFuncSigma.SetParameter(3, 0.012);
527 fitFuncSigma.SetParLimits(3, 0.01, 0.2);
529 fitFuncSigma.SetLineColor(kBlack);
531 gSigmaSlopevsInvdEdx->Fit(&fitFuncSigma, "EX0", "same", 0., 0.2);
534 fSave->cd("allTanTheta");
535 gSlvsOffset->Write();
536 gSlvsInvOffset->Write();
538 gSigmaSlopevsdEdx->Write();
539 gSigmaSlopevsInvdEdx->Write();
543 TGraphErrors* gSlvsTanTheta[numPbins];
544 for (Int_t j = 0; j < numPbins; j++) {
545 gSlvsTanTheta[j] = new TGraphErrors(numTanThetaBins);
546 gSlvsTanTheta[j]->SetName(Form("tanThetaSlopes_pBin%d", j));
547 gSlvsTanTheta[j]->SetTitle(Form("Rel. slope vs. tanTheta (%.4f #leq pTPC/(GeV/c) < %.4f)", pBinEdges[2*j], pBinEdges[2*j+1]));
548 gSlvsTanTheta[j]->SetMarkerColor((j == 7) ? kBlack : (2 + ((j > 2) ? j + 1 : j)));
549 gSlvsTanTheta[j]->SetLineColor((j == 7) ? kBlack : (2 + ((j > 2) ? j + 1 : j)));
550 gSlvsTanTheta[j]->SetMarkerStyle(20);
553 TGraphErrors* gSigmaSlopevsTanTheta[numPbins];
554 for (Int_t j = 0; j < numPbins; j++) {
555 gSigmaSlopevsTanTheta[j] = new TGraphErrors(numTanThetaBins);
556 gSigmaSlopevsTanTheta[j]->SetName(Form("tanThetaSigmaSlopes_pBin%d", j));
557 gSigmaSlopevsTanTheta[j]->SetTitle(Form("Rel. sigma slope vs. tanTheta (%.4f #leq pTPC/(GeV/c) < %.4f)", pBinEdges[2*j], pBinEdges[2*j+1]));
558 gSigmaSlopevsTanTheta[j]->SetMarkerColor((j == 7) ? kBlack : (2 + ((j > 2) ? j + 1 : j)));
559 gSigmaSlopevsTanTheta[j]->SetLineColor((j == 7) ? kBlack : (2 + ((j > 2) ? j + 1 : j)));
560 gSigmaSlopevsTanTheta[j]->SetMarkerStyle(20);
565 // Fitting for eta bins
566 for (Int_t j = 0; j < numTanThetaBins; j++) {
567 printf("%.2f < tanTheta <= %.2f:\n", tanThetaBinEdges[2*j], tanThetaBinEdges[2*j+1]); //TODO absTanTheta
569 TGraphErrors* gSlvsOffset = new TGraphErrors(numPbins);
570 TGraphErrors* gSlvsInvOffset = new TGraphErrors(numPbins);
572 TGraphErrors* gSigmaSlopevsdEdx = new TGraphErrors(numPbins);
573 TGraphErrors* gSigmaSlopevsInvdEdx = new TGraphErrors(numPbins);
575 fSave->mkdir(Form("tanThetaBin%d", j));
577 for (Int_t i = 0; i < numPbins; i++) {
578 gSlvsOffset->SetPoint(i, -10, 0);
579 gSlvsOffset->SetPointError(i, 0, 0);
581 gSlvsInvOffset->SetPoint(i, -10, 0);
582 gSlvsInvOffset->SetPointError(i, 0, 0);
584 gSlvsTanTheta[i]->SetPoint(j, -10, 0);
585 gSlvsTanTheta[i]->SetPointError(j, 0, 0);
587 gSigmaSlopevsTanTheta[i]->SetPoint(j, -10, 0);
588 gSigmaSlopevsTanTheta[i]->SetPointError(j, 0, 0);
590 gSigmaSlopevsdEdx->SetPoint(i, -10, 0);
591 gSigmaSlopevsdEdx->SetPointError(i, 0, 0);
593 gSigmaSlopevsInvdEdx->SetPoint(i, -10, 0);
594 gSigmaSlopevsInvdEdx->SetPointError(i, 0, 0);
596 if (h2[i][j]->GetEntries() < 10)
599 printf("Momentum %.2f - %.2f GeV/c:\n", pBinEdges[2*i], pBinEdges[2*i+1]);
600 TCanvas* c = new TCanvas(Form("canv_pBin%d_tanThetaBin%d", i, j), Form("canv_pBin%d_tanThetaBin_%d", i, j), 100,10,1380,800);
601 FitSlicesY(h2[i][j], heightFractionForRange, 10, "QN", &arr);
602 h2[i][j]->GetYaxis()->SetRange(h2[i][j]->FindFirstBinAbove(1, 2), h2[i][j]->FindLastBinAbove(1,2));
603 h2[i][j]->Draw("colz");
605 TH1D* hMean = (TH1D*)arr.At(1);//new TH1D((TH1D&)*arr.At(1));
606 TH1D* hSigma = (TH1D*)arr.At(2);//new TH1D((TH1D&)*arr.At(2));
607 hMean->SetName(Form("hMean_pBin%d_tanThetaBin_%d", i, j));
608 hSigma->SetName(Form("hSigma_pBin%d_tanThetaBin_%d", i, j));
609 hSigma->SetLineColor(kMagenta);
611 TH1D* hSigmaRel = new TH1D(*hSigma);
612 hSigmaRel->SetName(Form("hSigmaRel_pBin%d_tanThetaBin_%d", i, j));
613 hSigmaRel->Divide(hMean);
614 hSigmaRel->SetLineColor(kMagenta + 2);
615 TFitResultPtr fitRes = hMean->Fit("pol1", "s", "same", 0, 12000);
616 TFitResultPtr fitResSigma = hSigmaRel->Fit("pol1", "s", "same", 0, 12000);
618 hMean->DrawClone("same");
620 if (((Int_t)fitRes) != 0) {
621 printf("Fit failed!\n");
624 Double_t p0 = fitRes->GetParams()[0];
625 Double_t p1 = fitRes->GetParams()[1];
626 Double_t err0 = fitRes->GetErrors()[0];
627 Double_t err1 = fitRes->GetErrors()[1];
629 Double_t totError = 99999;
630 if (p0 != 0 && p1 != 0) {
631 totError = TMath::Abs(p1 / p0 * TMath::Sqrt(TMath::Power(err0 / p0, 2) + TMath::Power(err1 / p1, 2)));
633 printf("Result: p1 / p0 = %f / %f = %e\n\n", p1, p0, (p0 != 0 ? p1 / p0 : -99999));
635 gSlvsOffset->SetPoint(i, p0, p1/pSigma0);
636 gSlvsOffset->SetPointError(i, err0, totError);
638 gSlvsInvOffset->SetPoint(i, 1./p0, p1/pSigma0);
639 gSlvsInvOffset->SetPointError(i, TMath::Abs(err0/p0/p0), totError);
642 gSlvsTanTheta[i]->SetPoint(j, (tanThetaBinEdges[2*j] + tanThetaBinEdges[2*j+1]) / 2., p1/pSigma0);
643 gSlvsTanTheta[i]->SetPointError(j, (tanThetaBinEdges[2*j+1] - tanThetaBinEdges[2*j]) / 2., totError);
645 // Only makes sense, if valid p0 available
646 if (((Int_t)fitResSigma) != 0) {
647 printf("Sigma fit failed!\n");
650 Double_t pSigma0 = fitResSigma->GetParams()[0];
651 Double_t errSigma0 = fitResSigma->GetErrors()[0];
653 Double_t pSigma1 = fitResSigma->GetParams()[1];
654 Double_t errSigma1 = fitResSigma->GetErrors()[1];
656 printf("Result sigma: pSigma1 / pSigma0 = %f / %f = %e\n\n", pSigma1, pSigma0, (pSigma0 != 0 ? pSigma1 / pSigma0 : -99999));
658 Double_t totErrorSigma = 99999;
659 if (pSigma0 != 0 && pSigma1 != 0) {
660 totErrorSigma = TMath::Abs(pSigma1 / pSigma0 * TMath::Sqrt(TMath::Power(errSigma0 / pSigma0, 2) + TMath::Power(errSigma1 / pSigma1, 2)));
664 gSigmaSlopevsdEdx->SetPoint(i, p0, pSigma1/pSigma0);
665 gSigmaSlopevsdEdx->SetPointError(i, err0, totErrorSigma);
667 gSigmaSlopevsInvdEdx->SetPoint(i, 1./p0, pSigma1/pSigma0);
668 gSigmaSlopevsInvdEdx->SetPointError(i, TMath::Abs(err0/p0/p0), totErrorSigma);
670 gSigmaSlopevsTanTheta[i]->SetPoint(j, (tanThetaBinEdges[2*j] + tanThetaBinEdges[2*j+1]) / 2., pSigma1/pSigma0);
671 gSigmaSlopevsTanTheta[i]->SetPointError(j, (tanThetaBinEdges[2*j+1] - tanThetaBinEdges[2*j]) / 2., totErrorSigma);
673 // Set artificially large errors for points with positive slope vs. multiplicity
674 // (negative slope makes physically no sense and is most likely due to uncertainties)
676 gSigmaSlopevsdEdx->SetPointError(i, err0, 1000);
677 gSigmaSlopevsInvdEdx->SetPointError(i, TMath::Abs(err0/p0/p0), 1000);
678 gSigmaSlopevsTanTheta[i]->SetPointError(j, (tanThetaBinEdges[2*j+1] - tanThetaBinEdges[2*j]) / 2., 1000);
685 fSave->cd(Form("tanThetaBin%d", j));
693 gSlvsOffset->SetName(Form("slopes_tanTheta%d", j));
694 gSlvsOffset->SetTitle(Form("Rel. slope vs. offset (%.2f < tanTheta #leq %.2f)", tanThetaBinEdges[2*j], tanThetaBinEdges[2*j+1]));//TODO tanThetaAbs
695 gSlvsOffset->SetMarkerColor((j == 7) ? kBlack : (2 + ((j > 2) ? j + 1 : j)));// (2 + ((j > 2) ? j + 1 : j));
696 gSlvsOffset->SetLineColor((j == 7) ? kBlack : (2 + ((j > 2) ? j + 1 : j)));//(2 + ((j > 2) ? j + 1 : j));
697 gSlvsOffset->SetMarkerStyle(20);
698 gSlvsOffset->Draw("Ap");
699 gSlvsOffset->GetHistogram()->GetXaxis()->SetTitle("dEdx (offset)");
700 gSlvsOffset->GetHistogram()->GetYaxis()->SetTitle("Multiplicity slope/offset");
701 gSlvsOffset->Fit("pol2", "W Ex0", "same", 10, 2000);
702 TF1* fitFuncResult = dynamic_cast<TF1*>(gSlvsOffset->GetListOfFunctions()->At(0));
704 fitFuncResult->SetLineColor((j == 7) ? kBlack : (2 + ((j > 2) ? j + 1 : j)));//(2 + ((j > 2) ? j + 1 : j));
706 gSlvsInvOffset->SetName(Form("slopes2_tanTheta%d", j));
707 gSlvsInvOffset->SetTitle(Form("Rel. slope vs. 1./offset (%.2f < tanTheta #leq %.2f)", tanThetaBinEdges[2*j], tanThetaBinEdges[2*j+1]));//TODO tanThetaAbs
708 gSlvsInvOffset->SetMarkerColor((j == 7) ? kBlack : (2 + ((j > 2) ? j + 1 : j)));//(2 + ((j > 2) ? j + 1 : j));
709 gSlvsInvOffset->SetLineColor((j == 7) ? kBlack : (2 + ((j > 2) ? j + 1 : j)));//(2 + ((j > 2) ? j + 1 : j));
710 gSlvsInvOffset->SetMarkerStyle(20);
711 gSlvsInvOffset->Draw("Ap");
712 gSlvsInvOffset->GetHistogram()->GetXaxis()->SetTitle("1./dEdx (1./offset)");
713 gSlvsInvOffset->GetHistogram()->GetYaxis()->SetTitle("Multiplicity slope/offset");
715 TFitResultPtr fitRes = gSlvsInvOffset->Fit("pol2", "S 0 W EX0", "same", isMC ? MCfitThreshold : 0., 0.018); // Estimate pol2 params for subsequent fit
716 //TODO NEW Introduced parameter [4]
717 TF1 fitFunc(Form("fitFunc_tanTheta%d", j), "[0] + [1]*TMath::Max([4], TMath::Min(x, [3])) + [2] * TMath::Power(TMath::Max([4], TMath::Min(x, [3])), 2)", 0., 0.2);
718 //TF1 fitFunc(Form("fitFunc_tanTheta%d", j), "[0] + [1]*TMath::Min(x, [3]) + [2] * TMath::Power(TMath::Min(x, [3]), 2)", 0., 0.1);
719 if ((Int_t)fitRes == 0)
720 fitFunc.SetParameters(fitRes->GetParams());
721 fitFunc.SetParameter(3, isMC ? 0.1 : 0.018);
722 fitFunc.SetParLimits(3, isMC ? 0.014 : 0.01, 0.2);//TODO NEW
723 // No lower threshold for data
725 fitFunc.SetParameter(4, MCfitThreshold);
726 fitFunc.SetParLimits(4, 0., 0.01);
729 fitFunc.FixParameter(4, 0.);
731 fitFunc.SetLineColor((j == 7) ? kBlack : (2 + ((j > 2) ? j + 1 : j)));//(2 + ((j > 2) ? j + 1 : j));
733 gSlvsInvOffset->Fit(&fitFunc, "EX0", "same", /*TODO NEW isMC ? MCfitThreshold : */0., 0.2);
737 gSigmaSlopevsdEdx->SetName(Form("sigmaSlopes_tanTheta%d", j));
738 gSigmaSlopevsdEdx->SetTitle(Form("Sigma rel slope vs. dEdx offset (%.2f < tanTheta #leq %.2f)", tanThetaBinEdges[2*j],
739 tanThetaBinEdges[2*j+1]));//TODO tanThetaAbs
740 gSigmaSlopevsdEdx->SetMarkerColor((j == 7) ? kBlack : (2 + ((j > 2) ? j + 1 : j)));
741 gSigmaSlopevsdEdx->SetLineColor((j == 7) ? kBlack : (2 + ((j > 2) ? j + 1 : j)));
742 gSigmaSlopevsdEdx->SetMarkerStyle(20);
743 gSigmaSlopevsdEdx->Draw("Ap");
744 gSigmaSlopevsdEdx->GetHistogram()->GetXaxis()->SetTitle("dEdx (offset)");
745 gSigmaSlopevsdEdx->GetHistogram()->GetYaxis()->SetTitle("Multiplicity sigma rel. slope");
747 gSigmaSlopevsInvdEdx->SetName(Form("sigmaSlopes2_tanTheta%d", j));
748 gSigmaSlopevsInvdEdx->SetTitle(Form("Sigma rel slope vs. 1./dEdx offset (%.2f < tanTheta #leq %.2f)", tanThetaBinEdges[2*j],
749 tanThetaBinEdges[2*j+1]));//TODO tanThetaAbs
750 gSigmaSlopevsInvdEdx->SetMarkerColor((j == 7) ? kBlack : (2 + ((j > 2) ? j + 1 : j)));
751 gSigmaSlopevsInvdEdx->SetLineColor((j == 7) ? kBlack : (2 + ((j > 2) ? j + 1 : j)));
752 gSigmaSlopevsInvdEdx->SetMarkerStyle(20);
753 gSigmaSlopevsInvdEdx->Draw("Ap");
754 gSigmaSlopevsInvdEdx->GetHistogram()->GetXaxis()->SetTitle("1./dEdx (1./offset)");
755 gSigmaSlopevsInvdEdx->GetHistogram()->GetYaxis()->SetTitle("Multiplicity sigma rel. slope");
758 TFitResultPtr fitRes2 = gSigmaSlopevsInvdEdx->Fit("pol2", "S 0 W EX0", "same", 0., 0.012); // Estimate pol2 params for subsequent fit
759 TF1 fitFuncSigma(Form("fitFuncSigma_tanTheta%d", j), "TMath::Max(0, [0] + [1]*TMath::Min(x, [3]) + [2] * TMath::Power(TMath::Min(x, [3]), 2))",
761 if ((Int_t)fitRes2 == 0)
762 fitFuncSigma.SetParameters(fitRes2->GetParams());
763 fitFuncSigma.SetParameter(3, 0.012);
764 fitFuncSigma.SetParLimits(3, 0.006, 0.2); //TODO was 3, 0.01, 0.2
766 fitFuncSigma.SetLineColor((j == 7) ? kBlack : (2 + ((j > 2) ? j + 1 : j)));//(2 + ((j > 2) ? j + 1 : j));
768 gSigmaSlopevsInvdEdx->Fit(&fitFuncSigma, "EX0", "same", 0., 0.2);
771 fSave->cd(Form("tanThetaBin%d", j));
772 gSlvsOffset->Write();
773 gSlvsInvOffset->Write();
775 gSigmaSlopevsdEdx->Write();
776 gSigmaSlopevsInvdEdx->Write();
784 fSave->mkdir("tanThetaFits");
785 fSave->cd("tanThetaFits");
787 for (Int_t j = 0; j < numPbins; j++) {
789 // Scale graphs, just that first bin sits at +-1
790 Double_t scale = 1.0;
791 for (Int_t k = 0; k < gSlvsTanTheta[j]->GetN(); k++) {
793 scale = 1. / TMath::Max(1e-10, TMath::Abs(gSlvsTanTheta[j]->GetY()[k]));
796 gSlvsTanTheta[j]->SetPoint(k, gSlvsTanTheta[j]->GetX()[k], gSlvsTanTheta[j]->GetY()[k] * scale);
797 gSlvsTanTheta[j]->SetPointError(k, gSlvsTanTheta[j]->GetEX()[k], gSlvsTanTheta[j]->GetEY()[k] * scale);
801 // Shift graphs, just that reference bin sits at 0
802 Double_t shift = 0.0;
803 const Int_t refBin = 7;
804 shift = gSlvsTanTheta[j]->GetY()[refBin];
806 for (Int_t k = 0; k < gSlvsTanTheta[j]->GetN(); k++) {
807 gSlvsTanTheta[j]->SetPoint(k, gSlvsTanTheta[j]->GetX()[k], gSlvsTanTheta[j]->GetY()[k] - shift);
810 gSlvsTanTheta[j]->Draw("Ap");
811 gSlvsTanTheta[j]->GetHistogram()->GetXaxis()->SetTitle("tan(#Theta)");//TODO tanThetaAbs
812 gSlvsTanTheta[j]->GetHistogram()->GetYaxis()->SetTitle("Multiplicity slope/offset");
814 gSlvsTanTheta[j]->Fit("pol2", "EX0", "same", tanThetaBinEdges[0], tanThetaBinEdges[numTanThetaBins * 2 - 1]);
816 TF1* fitFuncResult = dynamic_cast<TF1*>(gSlvsTanTheta[j]->GetListOfFunctions()->At(0));
818 fitFuncResult->SetLineColor((j == 7) ? kBlack : (2 + ((j > 2) ? j + 1 : j)));
819 gSlvsTanTheta[j]->Write();
821 gSigmaSlopevsTanTheta[j]->Draw("Ap");
822 gSigmaSlopevsTanTheta[j]->GetHistogram()->GetXaxis()->SetTitle("tanTheta");//TODO tanThetaAbs
823 gSigmaSlopevsTanTheta[j]->GetHistogram()->GetYaxis()->SetTitle("Multiplicity rel. sigma slope");
824 gSigmaSlopevsTanTheta[j]->Write();
832 TNamed* settings = new TNamed(Form("Settings: widthFactor %f, multStepSize %d, isMC %d, correct %d, pathNameSplines %s, splineName %s\n",
833 widthFactor, multStepSize, isMC, correct, pathNameSplines.Data(), splineName.Data()), "");