16 #include <TDatabasePDG.h>
20 #include <TPaveText.h>
22 #include <TProfile2D.h>
26 #include <TCollection.h>
51 {
"S",
"B",
"S/#sqrt{S+B}",
"S/B",
"Mass",
"MassWidth",
"ChiSqNDFmatch"};
56 "like-sign (arithm.)",
57 "like-sign #times R(#Deltam)",
58 "like-sign (arithm.) #times R(#Deltam)",
84 , fArrHists(c.fArrHists)
85 , fArrCocktail(c.fArrCocktail)
86 , fHistSignal(c.GetSignalHistogram())
87 , fHistSB(c.GetSoverBHistogram())
88 , fHistSgn(c.GetSignificanceHistogram())
89 , fHistBackground(c.GetBackgroundHistogram())
90 , fHistCocktail(c.GetCocktailHistogram())
91 , fHistDataPM(c.GetUnlikeSignHistogram())
92 , fHistRfactor(c.GetRfactorHistogram())
93 , fHistSignalMC(c.GetMCSignalShape())
94 , fValues(c.GetValues())
95 , fErrors(c.GetErrors())
96 , fIntMin(c.GetIntegralMin())
97 , fIntMax(c.GetIntegralMax())
98 , fRebin(c.GetRebin())
102 fMethod(c.GetMethod())
103 , fScaleMin(c.GetScaleMin())
104 , fScaleMax(c.GetScaleMax())
105 , fScaleMin2(c.GetScaleMin2())
106 , fScaleMax2(c.GetScaleMax2())
107 , fScaleFactor(c.GetScaleFactor())
108 , fPeakMethod(c.GetExtractionMethod())
160 if (TMath::Abs(x1) < 1e-20 && TMath::Abs(x2) < 1e-20) {
167 y2 = y1 + 0.025 * opt.Length();
169 y1 = y2 - 0.025 * opt.Length();
174 TPaveText* t =
new TPaveText(x1, y1, x2, y2,
"brNDC");
176 t->SetFillStyle(kFEmpty);
179 if (opt.Contains(
"p"))
181 Form(
"#bf{%s}", (
fPOI ?
fPOI->GetName() :
"particle not found")));
182 if (opt.Contains(
"R"))
183 t->AddText(Form(
"%.2f < %s < %.2f GeV/c^{2}",
fIntMin,
"m_{inv}",
fIntMax));
184 if (opt.Contains(
"n"))
187 if (opt.Contains(
"b"))
190 Int_t smallS2B = (
fValues(3) < 0.1 ? 1 : 100);
191 if (opt.Contains(
"s"))
192 t->AddText(Form(
"%s: %.2f #pm %.2f%s",
196 smallS2B > 1 ?
"" :
"%"));
197 if (opt.Contains(
"S"))
200 if (opt.Contains(
"m") &&
fValues(4) > 0)
201 t->AddText(Form(
"Mass: %.2f #pm %.2f GeV/c^{2}",
fValues(4),
fErrors(4)));
202 if (opt.Contains(
"r") &&
fValues(5) > 0)
203 t->AddText(Form(
"Mass res.: %.1f #pm %.1f MeV/c^{2}",
206 if (opt.Contains(
"c") &&
fValues(6) > 0)
207 t->AddText(Form(
"Match chi2/ndf.: %.1f",
fValues(6)));
218 printf(
"Signal : %.5g #pm %.5g (+-%.3g%%)\n",
222 printf(
"Backgnd: %.5g #pm %.5g (+-%.3g%%)\n",
226 printf(
"Signif : %.5g #pm %.5g (+-%.3g%%)\n",
230 printf(
"SoB : %.5g #pm %.5g (+-%.3g%%)\n",
237 if (
fValues(6) > 0) printf(
"Match chi2/ndf: %.5g \n",
fValues(6));
252 if (intMin < histRaw->GetXaxis()->GetXmin())
253 intMin = histRaw->GetXaxis()->GetXmin();
254 if (intMin < histBackground->GetXaxis()->GetXmin())
255 intMin = histBackground->GetXaxis()->GetXmin();
257 if (intMax > histRaw->GetXaxis()->GetXmax())
258 intMax = histRaw->GetXaxis()->GetXmax()
259 - histRaw->GetBinWidth(histRaw->GetNbinsX()) / 2.;
260 if (intMax > histBackground->GetXaxis()->GetXmax())
261 intMax = histBackground->GetXaxis()->GetXmax()
262 - histBackground->GetBinWidth(histBackground->GetNbinsX()) / 2.;
265 histRaw->Integral(histRaw->FindBin(intMin), histRaw->FindBin(intMax));
266 Double_t intBack = histBackground->Integral(histBackground->FindBin(intMin),
267 histBackground->FindBin(intMax));
270 if (histBackground->GetDefaultSumw2()) histBackground->Sumw2();
287 if (TMath::Abs(intMin2 - intMax2) < 0.00001)
291 if (intMin < histRaw->GetXaxis()->GetXmin())
292 intMin = histRaw->GetXaxis()->GetXmin();
293 if (intMin < histBackground->GetXaxis()->GetXmin())
294 intMin = histBackground->GetXaxis()->GetXmin();
296 if (intMax2 > histRaw->GetXaxis()->GetXmax())
297 intMax2 = histRaw->GetXaxis()->GetXmax()
298 - histRaw->GetBinWidth(histRaw->GetNbinsX()) / 2.;
299 if (intMax2 > histBackground->GetXaxis()->GetXmax())
300 intMax2 = histBackground->GetXaxis()->GetXmax()
301 - histBackground->GetBinWidth(histBackground->GetNbinsX()) / 2.;
304 histRaw->Integral(histRaw->FindBin(intMin), histRaw->FindBin(intMax));
305 Double_t intBack = histBackground->Integral(histBackground->FindBin(intMin),
306 histBackground->FindBin(intMax));
308 histRaw->Integral(histRaw->FindBin(intMin2), histRaw->FindBin(intMax2));
309 intBack += histBackground->Integral(histBackground->FindBin(intMin2),
310 histBackground->FindBin(intMax2));
314 if (histBackground->GetDefaultSumw2()) histBackground->Sumw2();
327 if (!obj1)
return obj2;
328 if (!obj2)
return obj1;
330 TString key = Form(
"%s_%s", obj1->GetName(),
"Signal");
331 if (obj1->IsA() == TProfile2D::Class()
332 && obj2->IsA() == TProfile2D::Class()) {
335 ((TProfile2D*) obj1)->Add(((TProfile2D*) obj2), val);
336 return (TH1*) obj1->Clone(key.Data());
339 }
else if (obj1->IsA() == TProfile::Class()
340 && obj2->IsA() == TProfile::Class()) {
343 ((TProfile*) obj1)->Add(((TProfile*) obj2), val);
344 return (TH1*) obj1->Clone(key.Data());
347 TH1D* histSign =
new TH1D(key.Data(),
349 obj1->GetXaxis()->GetNbins(),
350 obj1->GetXaxis()->GetXmin(),
351 obj1->GetXaxis()->GetXmax());
352 if (histSign->GetDefaultSumw2()) histSign->Sumw2();
353 histSign->SetDirectory(0);
355 for (Int_t
i = 0;
i <= obj1->GetNbinsX();
i++) {
356 histSign->SetBinContent(
357 i, obj1->GetBinContent(
i) - obj2->GetBinContent(
i));
358 histSign->SetBinError(
360 TMath::Sqrt(obj1->GetBinError(
i) * obj1->GetBinError(
i)
361 - obj2->GetBinError(
i) * obj2->GetBinError(
i)));
376 TH1* histSign = (TH1*) obj1->Clone(key.Data());
377 histSign->Add(obj2, val);
380 obj1->Add(obj2, val);
389 Bool_t replaceValErr,
398 Double_t massPOI = TDatabasePDG::Instance()->GetParticle(
fPOIpdg)->Mass();
399 Double_t sigPOI = massPOI * 0.02;
411 "DescribePeakShape",
"Signal extraction method: %d", (Int_t)
fPeakMethod);
419 Error(
"DescribePeakShape",
"No MC histogram passed. Returning.");
423 mc = mcShape->GetBinContent(
fHistSignal->FindBin(massPOI));
424 mcShape->Scale(data / mc);
429 Error(
"DescribePeakShape",
"No MC histogram passed. Returning.");
432 if (mcShape->GetBinWidth(1) !=
fHistSignal->GetBinWidth(1))
434 " WARNING: MC and signal histogram have different bin widths. \n");
438 mcShape->Integral(mcShape->FindBin(
fIntMin), mcShape->FindBin(
fIntMax));
439 mcShape->Scale(data / mc);
444 printf(
" ERROR: No MC histogram passed or set. Returning. \n");
453 fit->SetParNames(
"N");
458 fit =
new TF1(
"Crystal Ball",
464 fit->SetParNames(
"alpha",
"n",
"meanx",
"sigma",
"N");
467 fit->SetParameters(0.4, 4.0, massPOI, sigPOI, 1.3 * nPOI);
468 fit->SetParLimits(0, 0.0, 1.);
469 fit->SetParLimits(1, 0.01, 10.);
470 fit->SetParLimits(2, massPOI - sigPOI, massPOI + sigPOI);
471 fit->SetParLimits(3, sigPOI / 5, 5 * sigPOI);
472 fit->SetParLimits(4, 0.2 * nPOI, 2.0 * nPOI);
479 fit =
new TF1(
"Gaussisan",
486 fit->SetParNames(
"N",
"meanx",
"sigma");
487 fit->SetParameters(1.3 * nPOI, massPOI, sigPOI);
488 fit->SetParLimits(0, 0.2 * nPOI, 2.0 * nPOI);
489 fit->SetParLimits(1, massPOI - sigPOI, massPOI + sigPOI);
490 fit->SetParLimits(2, sigPOI / 5, 5 * sigPOI);
499 Fatal(
"DescribePeakShape",
"Function class not added!");
509 Warning(
"DescripePeakShape",
"fit has error/issue (%d)", fitResult);
513 fValues(6) = (fit->GetNDF() ? fit->GetChisquare() / fit->GetNDF() : -1.);
527 fValues(0) = mcShape->IntegralAndError(
544 fValues(4) = fit->GetParameter(parMass);
545 fErrors(4) = fit->GetParError(parMass);
548 fValues(5) = fit->GetParameter(parSigma);
549 fErrors(5) = fit->GetParError(parSigma);
561 return (TH1F*)
fHistSignal->Clone(
"BinCountReturn");
573 fit->SetName(Form(
"mcShapeFunc-%s",
fgHistSimPM->GetName()));
579 fit->SetName(Form(
"UserFunc"));
789 "Substracted signal",
797 "Background contribution",
803 new TH1D(
"HistRfactor",
804 "Rfactor;;N^{mix}_{+-}/2#sqrt{N^{mix}_{++} N^{mix}_{--}}",
814 "Cocktail contribution",
828 if (htmp->GetDefaultSumw2()) htmp->Sumw2();
829 htmp->SetDirectory(0);
830 htmp->Scale(1.,
"width");
879 "Subtraction method not supported. Please check SetMethod() function.");
899 for (Int_t
i = 1;
i <=
fHistSgn->GetNbinsX();
i++) {
907 if (s + b < 1.e-6)
continue;
908 fHistSgn->SetBinContent(
i, s / TMath::Sqrt(s + b));
910 fHistSgn->SetYTitle(
"S/#sqrt{S+B}");
928 for (Int_t ibin = 1; ibin <=
fHistDataPM->GetXaxis()->GetNbins(); ibin++) {
934 Float_t background = 2 * TMath::Sqrt(pp * mm);
936 Float_t ebackground =
937 TMath::Sqrt(mm / pp * ppe * ppe + pp / mm * mme * mme);
940 background = (pp + mm);
942 ebackground = TMath::Sqrt(ppe * ppe + mme * mme);
943 if (TMath::Abs(ebackground) < 1e-30) ebackground = 1;
958 for (Int_t ibin = 1; ibin <=
fHistMixPM->GetXaxis()->GetNbins(); ibin++) {
966 Float_t background = 2 * TMath::Sqrt(pp * mm);
969 Float_t ebackground =
970 TMath::Sqrt(mm / pp * ppe * ppe + pp / mm * mme * mme);
973 background = (pp + mm);
974 ebackground = TMath::Sqrt(ppe * ppe + mme * mme);
975 if (TMath::Abs(ebackground) < 1e-30) ebackground = 1;
980 if (background > 0.0) {
981 rcon = pm / background;
982 rerr = TMath::Sqrt((1. / background) * (1. / background) * pme * pme
983 + (pm / (background * background))
984 * (pm / (background * background)) * ebackground
1026 Error(
"ProcessEM",
"Mixed event histogram missing");
1032 for (Int_t ibin = 1; ibin <=
fHistDataPM->GetXaxis()->GetNbins(); ibin++) {
1033 Float_t pm =
fHistMixMP->GetBinContent(ibin);
1036 Float_t background = pm;
1037 Float_t ebackground = TMath::Sqrt(pme * pme);
1076 Error(
"ProcessTR",
"Track rotation histogram missing");
1081 for (Int_t ibin = 1; ibin <=
fHistDataPM->GetXaxis()->GetNbins(); ibin++) {
1085 Float_t background = pm;
1086 Float_t ebackground = TMath::Sqrt(pme * pme);
1126 Error(
"ProcessCocktail",
"Cocktail histograms missing");
1179 "Signal extraction results for '%s'",
1181 TString optString(option);
1182 optString.ToLower();
1183 printf(
"Plot extraction: bgrd. estimator: '%s' \t options: '%s' \n",
1186 Bool_t optTask = optString.Contains(
"same");
1187 optString.ReplaceAll(
"same",
"");
1188 Bool_t optLegFull = optString.Contains(
"legf");
1189 optString.ReplaceAll(
"legf",
"");
1190 Bool_t optLeg = optString.Contains(
"leg");
1191 optString.ReplaceAll(
"leg",
"");
1192 Bool_t optCan = optString.Contains(
"can");
1193 optString.ReplaceAll(
"can",
"");
1194 Bool_t optLine = optString.Contains(
"line");
1195 optString.ReplaceAll(
"line",
"");
1196 Bool_t optStat = optString.Contains(
"stat");
1197 optString.ReplaceAll(
"stat",
"");
1198 Bool_t optSSB = optString.Contains(
"ssb");
1199 optString.ReplaceAll(
"ssb",
"");
1200 Bool_t optSB = optString.Contains(
"sb");
1201 optString.ReplaceAll(
"sb",
"");
1202 Bool_t optSgn = optString.Contains(
"sgn");
1203 optString.ReplaceAll(
"sgn",
"");
1204 Bool_t optOnlyRaw = optString.Contains(
"onlyraw");
1205 optString.ReplaceAll(
"onlyraw",
"");
1206 Bool_t optOnlySig = optString.Contains(
"onlysig");
1207 optString.ReplaceAll(
"onlysig",
"");
1208 Bool_t optNoSig = optString.Contains(
"nosig");
1209 optString.ReplaceAll(
"nosig",
"");
1210 Bool_t optNoBgrd = optString.Contains(
"nobgrd");
1211 optString.ReplaceAll(
"nobgrd",
"");
1212 Bool_t optOnlyMC = optString.Contains(
"onlymc");
1213 optString.ReplaceAll(
"onlymc",
"");
1214 Bool_t optNoMC = optString.Contains(
"nomc");
1215 optString.ReplaceAll(
"nomc",
"");
1216 Bool_t optCocktail = optString.Contains(
"cocktail");
1217 optString.ReplaceAll(
"cocktail",
"");
1218 optString.ReplaceAll(
" ",
"");
1224 if (optLegFull) optLeg = kTRUE;
1230 Form(
"cSignalExtraction%s",
1231 (optSB ?
"SB" : (optSgn ?
"SGN" : (optSSB ?
"SSB" :
""))));
1232 c = (TCanvas*) gROOT->FindObject(key.Data());
1233 if (!c) c =
new TCanvas(key.Data(), key.Data());
1241 TList* prim = gPad->GetListOfPrimitives();
1242 for (Int_t io = 0; io < prim->GetSize(); io++) {
1244 if (obj->InheritsFrom(TH1::Class()) && obj != prim->At(io + 1)) nobj++;
1249 if ((optLeg && optTask && !nobj) || (optLeg && !optTask)) {
1250 leg =
new TLegend(.75,
1252 1. - gPad->GetTopMargin() - gStyle->GetTickLength(
"X"),
1253 1. - gPad->GetRightMargin() - gStyle->GetTickLength(
"Y"),
1256 if (optTask) leg->SetHeader(
"");
1257 }
else if (optLeg && nobj) {
1258 leg = (TLegend*) prim->FindObject(
"TPave");
1262 gPad->SetLogx(optString.Contains(
"logx"));
1263 gPad->SetLogy(optString.Contains(
"logy"));
1264 gPad->SetLogz(optString.Contains(
"logz"));
1265 optString.ReplaceAll(
"logx",
"");
1266 optString.ReplaceAll(
"logy",
"");
1267 optString.ReplaceAll(
"logz",
"");
1270 if (optString.Contains(
"e2") || optString.Contains(
"e3")
1271 || optString.Contains(
"e4")) {
1273 gStyle->SetErrorX(0.5);
1278 Info(
"Draw",
"this is object number: %d", nobj);
1281 TString ytitle =
fHistDataPM->GetYaxis()->GetTitle();
1283 if (!(
fHistDataPM->GetXaxis()->IsVariableBinSize())) {
1284 ytitle += Form(
"/%.0f MeV/#it{c}^{2}",
fHistDataPM->GetBinWidth(1) * 1e3);
1290 fHistDataPM->SetNameTitle(Form(
"unlike-sign%s", GetName()),
"unlike-sign");
1300 fHistSignal->SetNameTitle(Form(
"signal%s", GetName()),
"signal");
1306 fHistCocktail->SetNameTitle(Form(
"cocktail%s", GetName()),
"cocktail");
1314 fHistSB->SetNameTitle(Form(
"s2b%s", GetName()),
"signal");
1318 }
else if (optSgn) {
1319 fHistSgn->SetNameTitle(Form(
"sgn%s", GetName()),
"signal");
1335 Info(
"Draw",
"Start plotting stuff with option -%s-", optString.Data());
1336 TString drawOpt = (optString.IsNull() ?
"EP" : optString);
1340 if (optSB && !optOnlyRaw && !optNoSig) {
1341 fHistSB->Draw(
i > 0 ? (drawOpt +
"same").Data() : drawOpt.Data());
1343 }
else if (optSgn && !optOnlyRaw && !optNoSig) {
1344 fHistSgn->Draw(
i > 0 ? (drawOpt +
"same").Data() : drawOpt.Data());
1346 }
else if (optOnlySig) {
1347 drawOpt = (optString.IsNull() ?
"EP0" : optString);
1348 fHistSignal->DrawCopy(
i > 0 ? (drawOpt +
"same").Data() : drawOpt.Data());
1350 drawOpt = (optString.IsNull() ?
"L same" : optString +
"same");
1352 static_cast<TF1*
>(
fgPeakShape)->DrawCopy(drawOpt.Data());
1355 }
else if (!optSB && !optSgn) {
1356 fHistDataPM->DrawCopy(
i > 0 ? (drawOpt +
"same").Data() : drawOpt.Data());
1360 drawOpt = (optString.IsNull() ?
"HIST" : optString);
1366 if (!optOnlyRaw && !optNoSig) {
1367 drawOpt = (optString.IsNull() ?
"EP0" : optString);
1368 fHistSignal->DrawCopy(
i > 0 ? (drawOpt +
"same").Data()
1371 drawOpt = (optString.IsNull() ?
"L same" : optString +
"same");
1373 static_cast<TF1*
>(
fgPeakShape)->DrawCopy(drawOpt.Data());
1380 drawOpt = (optString.IsNull() ?
"HIST" : optString);
1405 while ((hmc =
dynamic_cast<TH1*
>(nextObj()))) {
1406 TString key = hmc->GetTitle();
1407 TString tit = hmc->GetTitle();
1408 if (key.CountChar(
'_') != 1)
continue;
1420 if (1 &&
fHistSignal->GetNbinsX() != hmc->GetNbinsX()) {
1424 hmc->SetTitle(tit.Data());
1425 hmc->Scale(1.,
"width");
1431 hmc->SetYTitle(Form(
"S/(S+B)"));
1438 hmc->Draw(
i > 0 ?
"HISTsame" :
"HIST");
1445 Double_t
max = -1e10;
1446 Double_t
min = +1e10;
1448 TListIter nextObj(gPad->GetListOfPrimitives(), kIterBackward);
1450 while ((obj = nextObj())) {
1451 if (obj->InheritsFrom(TH1::Class())) {
1452 TH1* hobj =
static_cast<TH1*
>(obj);
1456 Double_t tmpmax =
max * (gPad->GetLogy() ? 5. : 1.1);
1457 hobj->SetMaximum(tmpmax);
1460 if (gPad->GetLogy() && objmin < 0.) objmin = 0.5;
1461 min = TMath::Min(
min, objmin);
1462 Double_t tmpmin =
min * (
min < 0. ? 1.1 : 0.9);
1463 hobj->SetMinimum(tmpmin);
1469 && (tmpmax / (tmpmin > 0. ? tmpmin : 1.)
1470 > TMath::Power(10., TGaxis::GetMaxDigits())
1471 || tmpmin < TMath::Power(10., -TGaxis::GetMaxDigits()))) {
1472 hobj->GetYaxis()->SetMoreLogLabels(kFALSE);
1473 hobj->GetYaxis()->SetNoExponent(kFALSE);
1480 TListIter nextObjFwd(gPad->GetListOfPrimitives(), kIterForward);
1481 if (optLeg && leg) {
1484 while ((obj = nextObjFwd())) {
1485 if (obj->InheritsFrom(TH1::Class()) || obj->InheritsFrom(TF1::Class())) {
1487 if (nobj && ileg < nobj) {
1492 TString histClass = obj->GetTitle();
1493 if (histClass.IsNull()) histClass = obj->GetName();
1494 histClass.ReplaceAll(
"Pair.",
"");
1495 histClass.ReplaceAll(
"Pair_",
"");
1502 histClass.Remove(TString::kBoth,
' ');
1507 TString legOpt = obj->GetDrawOption();
1510 legOpt.ReplaceAll(
"hist",
"");
1511 legOpt.ReplaceAll(
"same",
"");
1512 legOpt.ReplaceAll(
"scat",
"");
1513 legOpt.ReplaceAll(
"col",
"");
1514 legOpt.ReplaceAll(
"z",
"");
1515 legOpt.ReplaceAll(
"text",
"");
1516 legOpt.ReplaceAll(
"e",
"");
1518 if (ileg == nobj && optTask)
1519 leg->AddEntry((TObject*) 0x0,
fArrHists->GetName(),
"");
1520 leg->AddEntry(obj, histClass.Data(), legOpt.Data());
1530 if (!nobj) leg->Draw();
1534 TLine* line =
new TLine();
1535 line->SetLineColor(kBlack);
1536 line->SetLineStyle(kDashed);
1542 gPad->GetBottomMargin() + gStyle->GetTickLength(
"Y"),
1543 1. - gPad->GetRightMargin() - gStyle->GetTickLength(
"X"),
1544 gPad->GetBottomMargin() + gStyle->GetTickLength(
"Y") + 5 * 0.025);
1564 default: scalingRef =
nullptr;
break;