3 """ muons_pdf.py : construct the pdf for muon ECL charged PID. """
5 __author__ =
"Marco Milesi"
6 __email__ =
"marco.milesi@unimelb.edu.au"
7 __maintainer__ =
"Marco Milesi"
11 from plotting_utils
import draw_plots, get_ndf
16 def fit_muon_e(**kwargs):
20 def fit_muon_eop(**kwargs):
22 append =
"anti" if kwargs[
"charge"] > 0
else ""
24 idx_p = kwargs[
"idx_p"]
25 idx_th = kwargs[
"idx_theta"]
28 if kwargs[
"pmin"] < 5.5e3:
29 eop_range = (0.0, 0.1)
30 bifurgaus_mu_range = (0.05, 0.0, 0.1)
31 bifurgaus_sigmaL_range = (0.003, 0.001, 0.005)
32 bifurgaus_sigmaR_range = (0.1, 0.005, 0.12)
33 bifurgaus_frac_range = (0.99, 1.0)
34 gaus_mu_range = (0.075, 0.05, 0.1)
35 gaus_sigma_range = (0.0, 0.02)
36 if kwargs[
"pmin"] < 4.5e3:
37 eop_range = (0.0, 0.1)
38 bifurgaus_mu_range = (0.05, 0.035, 0.06)
39 bifurgaus_sigmaL_range = (0.01, 0.005, 0.1)
40 bifurgaus_sigmaR_range = (0.1, 0.005, 0.12)
41 bifurgaus_frac_range = (0.99, 1.0)
42 gaus_mu_range = (0.075, 0.05, 0.1)
43 gaus_sigma_range = (0.0, 0.02)
44 if kwargs[
"pmin"] < 4e3:
45 eop_range = (0.0, 0.2)
46 bifurgaus_mu_range = (0.06, 0.0, 0.15)
47 bifurgaus_sigmaL_range = (0.055, 0.001, 0.01)
48 bifurgaus_sigmaR_range = (0.028, 0.005, 0.05)
49 bifurgaus_frac_range = (0.0, 1.0)
50 gaus_mu_range = (0.1, 0.06, 0.2)
51 gaus_sigma_range = (0.0, 0.04)
52 if kwargs[
"pmin"] < 3e3:
53 eop_range = (0.0, 0.2)
54 bifurgaus_mu_range = (0.085, 0.0, 0.15)
55 bifurgaus_sigmaL_range = (0.0125, 0.005, 0.03)
56 bifurgaus_sigmaR_range = (0.0075, 0.005, 0.02)
57 bifurgaus_frac_range = (0.0, 1.0)
58 gaus_mu_range = (0.1, 0.06, 0.2)
59 gaus_sigma_range = (0.0, 0.04)
60 if kwargs[
"pmin"] < 2e3:
61 eop_range = (0.0, 0.3)
62 bifurgaus_mu_range = (0.16, 0.0, 0.3)
63 bifurgaus_sigmaL_range = (0.019, 0.01, 0.1)
64 bifurgaus_sigmaR_range = (0.033, 0.005, 0.1)
65 bifurgaus_frac_range = (0.0, 1.0)
66 gaus_mu_range = (0.16, 0.0, 0.3)
67 gaus_sigma_range = (0.0, 0.1)
68 if kwargs[
"pmin"] < 1e3:
69 eop_range = (0.0, 0.6)
70 bifurgaus_mu_range = (0.25, 0.0, 0.45)
71 bifurgaus_sigmaL_range = (0.1, 0.01, 0.15)
72 bifurgaus_sigmaR_range = (0.1, 0.005, 0.15)
73 bifurgaus_frac_range = (0.0, 1.0)
74 gaus_mu_range = (0.35, 0.2, 0.6)
75 gaus_sigma_range = (0.0, 0.05)
76 if kwargs[
"pmin"] < 0.5e3:
77 eop_range = (0.0, 1.0)
78 bifurgaus_mu_range = (0.27, 0.0, 0.5)
79 bifurgaus_sigmaL_range = (0.145, 0.01, 0.3)
80 bifurgaus_sigmaR_range = (0.1475, 0.005, 0.3)
81 bifurgaus_frac_range = (0.0, 1.0)
82 gaus_mu_range = (0.43, 0.1, 1.0)
83 gaus_sigma_range = (0.0, 0.2)
86 inpath =
"{0}/pdg{1}13.root".format(kwargs[
"inputpath"], append)
87 infile = ROOT.TFile(inpath)
90 eopvar = ROOT.RooRealVar(
"eop",
"E/p", eop_range[0], eop_range[1])
91 eophist_data = infile.Get(
"h_Eop_{0}_{1}".format(idx_p - 1, idx_th - 1))
92 eopdata = ROOT.RooDataHist(
"eopdata",
"eopdata", ROOT.RooArgList(eopvar), ROOT.RooFit.Import(eophist_data))
95 pm =
"+" if kwargs[
"charge"] > 0
else "-"
96 particle =
"#mu^{{{0}}}".format(pm)
97 p_range =
"{0:.2f} < p_{{lab}} #leq {1:.2f} [GeV/c]".format(kwargs[
"pmin"] / 1e3, kwargs[
"pmax"] / 1e3)
98 theta_range =
"{0:.1f} < #theta_{{lab}} #leq {1:.1f} [deg]".format(kwargs[
"thetamin"], kwargs[
"thetamax"])
99 title =
"{0}, {1}, {2}".format(particle, p_range, theta_range)
100 frame1 = eopvar.frame(ROOT.RooFit.Title(title))
101 eopdata.plotOn(frame1, ROOT.RooFit.DataError(ROOT.RooAbsData.SumW2))
104 bifurgaus_mu = ROOT.RooRealVar(
"#mu_{bg}",
105 "mean of bifurcated gaussian",
106 bifurgaus_mu_range[0],
107 bifurgaus_mu_range[1],
108 bifurgaus_mu_range[2])
109 bifurgaus_sigmal = ROOT.RooRealVar(
"#sigma_{bg}_{L}",
110 "widthL of bifurcated gaussian",
111 bifurgaus_sigmaL_range[0],
112 bifurgaus_sigmaL_range[1],
113 bifurgaus_sigmaL_range[2])
114 bifurgaus_sigmar = ROOT.RooRealVar(
"#sigma_{bg}_{R}",
115 "widthR of bifurcated gaussian",
116 bifurgaus_sigmaR_range[0],
117 bifurgaus_sigmaR_range[1],
118 bifurgaus_sigmaR_range[2])
119 bifurgaus_frac = ROOT.RooRealVar(
"frac_{bg}",
120 "bifurcated gaussian fraction",
121 bifurgaus_frac_range[0],
122 bifurgaus_frac_range[1])
123 bifurgaus = ROOT.RooBifurGauss(
"bifurgaus",
"bifurcated gaussian", eopvar, bifurgaus_mu, bifurgaus_sigmal, bifurgaus_sigmar)
125 gaus_mean = ROOT.RooRealVar(
"#mu_{g}",
130 gaus_sigma = ROOT.RooRealVar(
"#sigma_{g}",
134 gaus = ROOT.RooGaussian(
"gaus",
"gaussian", eopvar, gaus_mean, gaus_sigma)
136 pdf = ROOT.RooAddPdf(
"pdf",
"bifurcated gaussian + gaussian", bifurgaus, gaus, bifurgaus_frac)
139 fitres = pdf.fitTo(eopdata, ROOT.RooFit.Save(), ROOT.RooFit.PrintEvalErrors(-1))
142 ral1 = ROOT.RooArgList(eopvar)
143 ral2 = ROOT.RooArgList(pdf.getParameters(ROOT.RooArgSet(eopvar)))
144 ras = ROOT.RooArgSet(eopvar)
145 pdffunc = pdf.asTF(ral1, ral2, ras)
149 ROOT.RooFit.LineColor(ROOT.kBlack),
150 ROOT.RooFit.LineWidth(2),
151 ROOT.RooFit.MoveToBack())
153 ROOT.RooFit.Components(
"bifurgaus"),
154 ROOT.RooFit.LineStyle(ROOT.kDashed),
155 ROOT.RooFit.LineColor(ROOT.kRed),
156 ROOT.RooFit.LineWidth(2),
157 ROOT.RooFit.MoveToBack())
159 ROOT.RooFit.Components(
"gaus"),
160 ROOT.RooFit.LineStyle(ROOT.kSolid),
161 ROOT.RooFit.LineColor(ROOT.kRed + 2),
162 ROOT.RooFit.LineWidth(2),
163 ROOT.RooFit.MoveToBack())
164 pdf.paramOn(frame1, ROOT.RooFit.Layout(0.55, 0.9, 0.75))
167 frame2 = eopvar.frame(ROOT.RooFit.Title(
"Residuals"))
168 frame2.addPlotable(frame1.residHist(),
"P")
171 ndf = get_ndf(eopdata, fitres)
172 print(
"X^2/ndf = {0:.3f} (ndf = {1})".format(frame1.chiSquare(), ndf))
175 if kwargs[
"outputplots"]:
176 plotargs = dict(kwargs, frame1=frame1.Clone(), frame2=frame2.Clone(), ndf=ndf, ndiv=510, append=append)
177 draw_plots(**plotargs)
179 pdfname =
"pdf_EoP_{0}_{1}".format(idx_p, idx_th)
180 return pdffunc.Clone(pdfname)