11 #include <TGraphErrors.h>
19 #include <TLegendEntry.h>
86 return TMath::Landau(x, delta - xi *
fgkMPShift, xi);
128 Double_t x1 = xlow + (i - .5) * step;
129 Double_t x2 = xhigh - (i - .5) * step;
132 TMath::Landau(x1, deltap, xi, kTRUE) * TMath::Gaus(x, x1, sigma);
134 TMath::Landau(x2, deltap, xi, kTRUE) * TMath::Gaus(x, x2, sigma);
163 if (i <= 1)
return LandauGaus(x, delta, xi, sigma);
165 Double_t deltai = i * (delta + xi * TMath::Log(di));
169 if (sigmai < 1e-10)
return Landau(x, deltai, xii);
211 if (dPar == 0)
return 0;
214 Double_t deltaI = i * (delta + xi * TMath::Log(i));
248 Double_t g = 1/(2*dp) * (4*d1 - d0) / 3;
281 for (
Int_t i = 2; i <= n; i++)
282 res += a[i-2] *
ILandauGaus(i, x, delta, xi, sigma);
309 for (
Int_t i = 2; i <= n; i++) {
311 num += a[i-2] * f * i;
314 if (den < 1e-4)
return 0;
354 y1 =
NEstimate(x, delta+dp, xi, sigma, n, a);
355 y2 =
NEstimate(x, delta+d2, xi, sigma, n, a);
356 y3 =
NEstimate(x, delta-d2, xi, sigma, n, a);
357 y4 =
NEstimate(x, delta-dp, xi, sigma, n, a);
360 y1 =
NEstimate(x, delta, xi+dp, sigma, n, a);
361 y2 =
NEstimate(x, delta, xi+d2, sigma, n, a);
362 y3 =
NEstimate(x, delta, xi-d2, sigma, n, a);
363 y4 =
NEstimate(x, delta, xi-dp, sigma, n, a);
366 y1 =
NEstimate(x, delta, xi, sigma+dp, n, a);
367 y2 =
NEstimate(x, delta, xi, sigma+d2, n, a);
368 y3 =
NEstimate(x, delta, xi, sigma-d2, n, a);
369 y4 =
NEstimate(x, delta, xi, sigma-dp, n, a);
373 if (j+1 > n)
return 0;
375 a[j] = aa+dp; y1 =
NEstimate(x, delta, xi, sigma, n, a);
376 a[j] = aa+d2; y2 =
NEstimate(x, delta, xi, sigma, n, a);
377 a[j] = aa-d2; y3 =
NEstimate(x, delta, xi, sigma, n, a);
378 a[j] = aa-dp; y4 =
NEstimate(x, delta, xi, sigma, n, a);
386 Double_t g = 1/(2*dp) * (4*d1 - d0) / 3;
408 TF1* f =
new TF1(Form(
"landGaus%d",n), &
landauGausN, xmin, xmax, nPar);
410 f->SetParName(
kC,
"C");
411 f->SetParName(
kDelta,
"#Delta_{p}");
412 f->SetParName(
kXi,
"#xi");
413 f->SetParName(
kSigma,
"#sigma");
414 f->SetParName(
kN,
"N");
415 f->SetParameter(
kC, c);
416 f->SetParameter(
kDelta, delta);
417 f->SetParameter(
kXi, xi);
418 f->SetParameter(
kSigma, sigma);
419 f->FixParameter(
kN, n);
420 f->SetParLimits(
kDelta, xmin, 4);
421 f->SetParLimits(
kXi, 0.00, 4);
422 f->SetParLimits(
kSigma, 0.01, 0.11);
424 for (
Int_t i = 2; i <= n; i++) {
426 f->SetParName(
kA+j, Form(
"a_{%d}", i));
427 f->SetParameter(
kA+j, a[j]);
428 f->SetParLimits(
kA+j, 0, 1);
451 TF1* f =
new TF1(Form(
"landGausI%d",i), &
landauGausI, xmin, xmax, nPar);
453 f->SetParName(
kC,
"C");
454 f->SetParName(
kDelta,
"#Delta_{p}");
455 f->SetParName(
kXi,
"#xi");
456 f->SetParName(
kSigma,
"#sigma");
457 f->SetParName(
kN,
"N");
458 f->SetParameter(
kC, c);
459 f->SetParameter(
kDelta, delta);
460 f->SetParameter(
kXi, xi);
461 f->SetParameter(
kSigma, sigma);
462 f->FixParameter(
kN, i);
483 :
fF(MakeFunc(n, c, delta, xi, sigma, a, xmin, xmax))
491 TF1* GetF1() {
return fF; }
544 dFdDelta2 += dDelta * dDelta;
546 dFdSigma2 += dSigma * dSigma;
547 e += TMath::Power(dFda *
GetEA(i),2);
552 e += (dFdDelta2 * edelta * edelta +
554 dFdSigma2 * esigma * esigma);
629 e = dDelta * dDelta + dXi * dXi + dSigma * dSigma;
630 for (
Int_t i = 2; i <= n; i++) {
665 for (
Int_t i = 1; i <= n; i++) {
674 for (
Int_t i = 1; i <= n; i++) {
675 if (r > l && r <= l + p[i-1]) {
754 Int_t midBin = dist->GetMaximumBin();
755 Double_t midE = dist->GetBinLowEdge(midBin);
759 Double_t minE = dist->GetBinCenter(minBin);
760 Double_t maxE = dist->GetBinCenter(midBin+2*fNMinus);
762 TF1* f = Function::MakeFunc(1, 0.5, midE, 0.07, 0.1, a, minE, maxE);
765 dist->Fit(f,
"RNQS",
"", minE, maxE);
780 TF1* f1 =
static_cast<TF1*
>(
fFunctions.At(0));
784 ::Warning(
"FitN",
"First fit missing");
791 Double_t maxEi = n * (delta1 + xi1 * TMath::Log(n)) + 2 * n * xi1;
795 for (
UShort_t i = 2; i <= n; i++) a.fArray[i-2] = (n==2? 0.05 : 0.000001);
797 TF1* fn = Function::MakeFunc(n, f1->GetParameter(
Function::kC),
800 a.fArray, minE, maxEi);
802 dist->Fit(fn,
"RSNQ",
"", minE, maxEi);
803 dist->Fit(fn,
"RSNQM",
"", minE, maxEi);
913 const Double_t ps[] = { 1, .05, .02, .005, .002 };
916 for (
Int_t i = 0; i < maxN; i++)
fRP[i] = a[i];
921 for (
Int_t i = 0; i <
fP.fN; i++) {
922 fP[i] =
fRP[i] / sum;
923 if (i != 0)
fP[i] +=
fP[i-1];
926 fSingle =
new TH1D(
"single",
"Single signals", 500, 0, 10);
930 fSingle->SetMarkerColor(kRed+1);
938 fSummed->SetTitle(
"Summed signals");
939 fSummed->SetFillColor(kBlue+1);
940 fSummed->SetMarkerColor(kBlue+1);
941 fSummed->SetLineColor(kBlue+1);
945 fSimple->SetTitle(
"Summed signals");
946 fSimple->SetFillColor(kGreen+1);
947 fSimple->SetMarkerColor(kGreen+1);
948 fSimple->SetLineColor(kGreen+1);
951 fNSum =
new TH2D(
"single",
"Observation signals",
952 fMaxN, .5, fMaxN+.5, 100, 0, 10);
953 fNSum->SetMarkerColor(kMagenta+1);
954 fNSum->SetLineColor(kMagenta+1);
955 fNSum->SetFillColor(kMagenta+1);
956 fNSum->SetYTitle(
"Signal");
957 fNSum->SetXTitle(
"N");
958 fNSum->SetZTitle(
"Events");
959 fNSum->SetDirectory(0);
962 fN =
new TH1D(
"n",
"Number of particles", fMaxN, .5, fMaxN+.5);
964 fN->SetYTitle(
"Events");
965 fN->SetMarkerColor(kMagenta+1);
966 fN->SetLineColor(kMagenta+1);
967 fN->SetFillColor(kMagenta+1);
968 fN->SetMarkerStyle(22);
969 fN->SetFillStyle(3001);
972 std::cout <<
"Probabilities:" << std::setprecision(4)
975 std::cout << std::setw(7) <<
fRP[i] <<
" ";
976 std::cout <<
" = " <<
fRP.GetSum() <<
"\n ";
977 for (
Int_t i = 0; i <
fP.fN; i++)
978 std::cout << std::setw(7) <<
fP[i] <<
" ";
979 std::cout << std::endl;
1005 if ( rndm <
fP[0]) ret = 1;
1006 else if (rndm >=
fP[0] && rndm <
fP[1]) ret = 2;
1007 else if (rndm >=
fP[1] && rndm <
fP[2]) ret = 3;
1008 else if (rndm >=
fP[2] && rndm <
fP[3]) ret = 4;
1009 else if (rndm >=
fP[3] && rndm <
fP[4]) ret = 5;
1020 if (
fF) ret =
fF->GetRandom();
1039 fNSum->Fill(n, ret);
1053 for (
Int_t i = 0; i < nObs; i++) {
1066 std::cout <<
"Resulting probabilities:\n ";
1067 for (
Int_t i = 1; i <=
fN->GetNbinsX(); i++)
1068 std::cout << std::setprecision(4) << std::setw(7)
1069 <<
fN->GetBinContent(i) <<
" ";
1070 std::cout << std::endl;
1082 if (i < f->GetNpar()) {
1083 val = f->GetParameter(i);
1084 err = f->GetParError(i);
1086 std::cout <<
" " << std::setw(16) << f->GetParName(i) <<
": "
1088 << std::setprecision(4) << std::setw(6) << input <<
" -> "
1089 << std::setprecision(4) << std::setw(6) << val <<
" +/- "
1090 << std::setprecision(5) << std::setw(7) << err <<
" [delta:"
1091 << std::setw(3) << int(100 * (input-val) / input) <<
"%,err:"
1092 << std::setw(3) << int(100 * err / val) <<
"%]"
1103 Int_t ndf = f->GetNDF();
1104 std::cout <<
"Chi^2/NDF = " << chi2 <<
"/" << ndf <<
"="
1105 << chi2/ndf << std::endl;
1126 if (i < f->GetNpar()) {
1127 val = f->GetParameter(i);
1128 err = f->GetParError(i);
1131 TLatex* ltx =
new TLatex(x, y, f->GetParName(i));
1132 ltx->SetTextSize(.04);
1133 ltx->SetTextFont(132);
1134 ltx->SetTextAlign(11);
1138 ltx->DrawLatex(x+.05, y, Form(
"%5.3f", input));
1139 ltx->DrawLatex(x+.14, y,
"#rightarrow");
1140 ltx->SetTextAlign(21);
1141 ltx->DrawLatex(x+.3, y, Form(
"%5.3f #pm %6.4f", val, err));
1142 ltx->SetTextAlign(11);
1143 ltx->DrawLatex(x+.48, y, Form(
"[#Delta=%3d%%, #delta=%3d%%]",
1144 int(100 * (input-val)/input),
1157 Int_t ndf = f->GetNDF();
1158 TLatex* ltx =
new TLatex(x, y, Form(
"#chi^{2}/NDF=%5.2f/%3d=%6.3f",
1159 chi2, ndf, chi2/ndf));
1160 ltx->SetTextSize(.04);
1162 ltx->SetTextFont(132);
1181 gStyle->SetOptTitle(0);
1182 gStyle->SetOptStat(0);
1183 gStyle->SetPalette(1);
1185 TCanvas* c =
new TCanvas(
"c",
"Generator distributions", 1200, 1000);
1187 c->SetBorderSize(0);
1188 c->SetBorderMode(0);
1189 c->SetTopMargin(0.01);
1190 c->SetRightMargin(0.01);
1195 TVirtualPad* p = c->cd(1);
1197 p->SetBorderSize(0);
1198 p->SetBorderMode(0);
1199 p->SetTopMargin(0.01);
1200 p->SetRightMargin(0.01);
1208 TF1* fcopy = Function::MakeFunc(1,
1214 fcopy->SetLineColor(2);
1215 fcopy->SetLineStyle(2);
1216 fcopy->Draw(
"same");
1221 TF1* f = fit->GetF1();
1223 f->SetLineColor(kBlack);
1224 TF1* fst =
static_cast<TF1*
>(fitter->
fFunctions.At(0));
1225 fst->SetLineWidth(3);
1226 fst->SetLineStyle(2);
1227 fst->SetLineColor(kMagenta);
1232 gr->SetName(
"fitError");
1233 gr->SetTitle(
"Fit w/errors");
1234 gr->SetFillColor(kYellow+1);
1235 gr->SetFillStyle(3001);
1240 gr->SetPoint(j-1, x, y);
1241 gr->SetPointError(j-1, 0, e);
1243 gr->Draw(
"same l e4");
1245 TLegend* l =
new TLegend(.15, .11, .5, .4);
1246 l->SetBorderSize(0);
1249 l->SetTextFont(132);
1250 l->AddEntry(
fSimple,
"L: Single-L",
"lp");
1251 l->AddEntry(
fSingle,
"LG: Single-L#otimesG",
"lp");
1252 l->AddEntry(
fSummed,
"NLG: Multi-L#otimesG",
"lp");
1253 l->AddEntry(gr,
"f_{N}: Fit to NLG");
1259 p->SetBorderSize(0);
1260 p->SetBorderMode(0);
1261 p->SetTopMargin(0.01);
1262 p->SetRightMargin(0.01);
1264 THStack* stack =
new THStack(
fNSum,
"y");
1265 TIter next(stack->GetHists());
1269 TLegend* l2 =
new TLegend(.6, .5, .95, .95);
1270 l2->SetBorderSize(0);
1271 l2->SetFillStyle(0);
1272 l2->SetFillColor(0);
1273 l2->SetTextFont(132);
1274 while ((h = static_cast<TH1*>(next()))) {
1275 if (i == 2) max = h->GetMaximum();
1278 h->SetFillStyle(3001);
1280 l2->AddEntry(h, Form(
"%d particles", i - 1),
"f");
1283 stack->Draw(
"hist nostack");
1284 stack->GetHistogram()->SetXTitle(
"Signal");
1285 stack->GetHistogram()->SetYTitle(
"Events");
1287 for (
Int_t j = 1; j <= 5; j++) {
1289 if (j == 1) max = fi->GetMaximum();
1290 fi->SetParameter(0,
fRP[j-1]/max);
1291 fi->SetLineColor(i);
1292 fi->SetLineWidth(3);
1293 fi->SetLineStyle(2);
1296 TF1* fj = Function::MakeIFunc(j, fit->
GetC() * fit->
GetA(j),
1299 fj->SetLineColor(i);
1300 fj->SetLineWidth(2);
1303 std::cout <<
"Component " << j <<
" scale=" << fi->GetParameter(0)
1304 <<
" (" <<
fRP[j-1] <<
")" <<
" " << fj->GetParameter(0)
1305 <<
" (" << fit->
GetC() <<
"*" << fit->
GetA(j) <<
")"
1309 TLegendEntry* ee = l2->AddEntry(
"",
"Input f_{i}",
"l");
1310 ee->SetLineStyle(2);
1311 ee->SetLineWidth(3);
1312 l2->AddEntry(
"",
"Fit f_{i}",
"l");
1317 TH1* nhist1 =
new TH1F(
"nhist1",
"NHist", 5, 0.5, 5.5);
1318 nhist1->SetFillColor(kCyan+1);
1319 nhist1->SetMarkerColor(kCyan+1);
1320 nhist1->SetLineColor(kCyan+1);
1321 nhist1->SetFillStyle(3002);
1322 TH1* nhist2 =
new TH1F(
"nhist2",
"NHist", 5, 0.5, 5.5);
1323 nhist2->SetFillColor(kYellow+1);
1324 nhist2->SetMarkerColor(kYellow+1);
1325 nhist2->SetLineColor(kYellow+1);
1326 nhist2->SetFillStyle(3002);
1328 TH2* resp =
new TH2F(
"resp",
"Reponse", 100, 0, 10, 6, -.5, 5.5);
1329 resp->SetXTitle(
"Signal");
1330 resp->SetYTitle(
"# particles");
1332 if (((j+1) % (fNObs / 10)) == 0)
1333 std::cout <<
"Event # " << j+1 << std::endl;
1340 graph->SetName(
"evalWeighted");
1341 graph->SetTitle(
"Evaluated function");
1342 graph->SetLineColor(kBlack);
1343 graph->SetFillColor(kYellow+1);
1344 graph->SetFillStyle(3001);
1349 nhist2->Fill(y,
fSummed->GetBinContent(j));
1350 graph->SetPoint(j-1, x, y);
1351 graph->SetPointError(j-1, 0, e);
1353 nhist1->Scale(1. / nhist1->GetMaximum());
1354 nhist2->Scale(1. / nhist2->GetMaximum());
1355 fN->Scale(1. /
fN->GetMaximum());
1359 p->SetBorderSize(0);
1360 p->SetBorderMode(0);
1361 p->SetTopMargin(0.01);
1362 p->SetRightMargin(0.01);
1364 nhist1->Draw(
"same");
1365 nhist2->Draw(
"same");
1367 TLegend* l3 =
new TLegend(.3, .7, .95, .95);
1368 l3->SetBorderSize(0);
1369 l3->SetFillStyle(0);
1370 l3->SetFillColor(0);
1371 l3->SetTextFont(132);
1373 Form(
"Input n distribution: #bar{m}=%5.3f, s_{m}=%5.3f",
1374 fN->GetMean(),
fN->GetRMS()),
"f");
1375 l3->AddEntry(nhist1,
1376 Form(
"Random draw from fit: #bar{m}=%5.3f, s_{m}=%5.3f",
1377 nhist1->GetMean(), nhist1->GetRMS()),
"f");
1378 l3->AddEntry(nhist2,
1379 Form(
"Weighted evaluation of fit: #bar{m}=%5.3f, s_{m}=%5.3f",
1380 nhist2->GetMean(), nhist2->GetRMS()),
"f");
1386 p->SetBorderSize(0);
1387 p->SetBorderMode(0);
1388 p->SetTopMargin(0.01);
1389 p->SetRightMargin(0.01);
1391 TProfile* prof1 =
fNSum->ProfileY();
1392 prof1->SetLineColor(kMagenta+1);
1394 TProfile* prof2 = resp->ProfileX();
1395 prof2->SetLineColor(kCyan+2);
1396 prof2->Draw(
"same");
1397 graph->SetLineWidth(2);
1398 graph->Draw(
"same LP E4");
1400 TLegend* l4 =
new TLegend(.2, .11, .8, .4);
1401 l4->SetBorderSize(0);
1402 l4->SetFillStyle(0);
1403 l4->SetFillColor(0);
1404 l4->SetTextFont(132);
1405 l4->AddEntry(prof1,
"Input distribution of N particles",
"l");
1406 l4->AddEntry(prof2,
"Random estimate of N particles",
"l");
1407 l4->AddEntry(graph,
"E: #sum_{i}^{N}i a_{i}f_{i}/"
1408 "#sum_{i}^{N}a_{i}f_{i} evaluated over NLG",
"lf");
1413 if (type && type[0] !=
'\0')
1414 c->Print(Form(
"TestELossDist.%s", type));
1429 const Double_t a1[] = { 1, .05, .02, .005, .002 };
1430 const Double_t a2[] = { 1, .1, .05, .01, .005 };
1431 const Double_t a3[] = { 1, .2, .10, .05, .01 };
Double_t Evaluate(Double_t x) const
void PrintParameter(Double_t input, TF1 *f, Int_t i)
static Double_t landauGausI(Double_t *xp, Double_t *pp)
static Double_t ILandauGaus(Int_t i, Double_t x, Double_t delta, Double_t xi, Double_t sigma)
static const Double_t fgkConvNSteps
Number of steps in integration.
Double_t Generate1Signal()
static Double_t landauGausN(Double_t *xp, Double_t *pp)
void Draw(const char *type="png")
static const Double_t fgkInvRoot2Pi
1 / sqrt(2 * pi)
static Double_t Landau(Double_t x, Double_t delta, Double_t xi)
Double_t GetESigma() const
TF1 * FitFirst(TH1 *dist)
static Double_t IdLandauGausdPar(Int_t i, Double_t x, UShort_t ipar, Double_t dPar, Double_t delta, Double_t xi, Double_t sigma)
static Double_t NLandauGaus(Double_t x, Double_t delta, Double_t xi, Double_t sigma, Int_t n, Double_t *a)
Double_t EstimateNParticles(Double_t x, Short_t maxN=-1)
Double_t Evaluate(Double_t x, Double_t &e) const
void DrawParameter(Double_t x, Double_t y, Double_t input, TF1 *f, Int_t i)
Double_t GetEDelta() const
Function * FitN(TH1 *dist, Int_t n)
Generator(Double_t delta=.55, Double_t xi=0.06, Double_t sigma=0.02, Int_t maxN=5, const Double_t *a=0)
Double_t RandomEstimateNParticles(Double_t x, Short_t maxN=-1)
Double_t GetDelta() const
Double_t GetSigma() const
Double_t GetA(Int_t i) const
Double_t NEstimate(Double_t x, Double_t delta, Double_t xi, Double_t sigma, Int_t n, Double_t *a)
Double_t EstimateNParticles(Double_t x, Double_t &e, Short_t maxN=-1)
Double_t GetEA(Int_t i) const
static Double_t LandauGaus(Double_t x, Double_t delta, Double_t xi, Double_t sigma)
void Generate(Int_t nObs=1000, Bool_t reset=true)
void DrawResult(Double_t x, Double_t y, TF1 *f)
Double_t GenerateNSignal(Int_t n)
static const Double_t fgkMPShift
MP shift.
Double_t * GetEAs() const
static Double_t landauGaus1(Double_t *xp, Double_t *pp)
static const Double_t fgkConvNSigma
Number of sigmas to integrate over.
void Draw(Option_t *option="")
void TestELossDist(const char *type="png")