3 """ protons_pdf.py : construct the pdf for proton 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
14 def fit_proton_eop(**kwargs):
16 append =
"anti" if kwargs[
"charge"] < 0
else ""
18 idx_p = kwargs[
"idx_p"]
19 idx_th = kwargs[
"idx_theta"]
22 if kwargs[
"pmin"] < 5.5e3:
24 eop_range = (0.0, 1.0)
if kwargs[
"charge"] < 0
else (0.0, 0.6)
25 bifurgaus_mu_range = (0.03, 0.01, 0.1)
26 bifurgaus_sigmaL_range = (0.01, 0.001, 0.1)
27 bifurgaus_sigmaR_range = (0.01, 0.001, 0.1)
28 bifurgaus_frac_range = (0.7, 1.0)
29 gaus0_mu_range = (0.07, 0.05, 0.2)
30 gaus0_sigma_range = (0.015, 0.001, 0.05)
31 gaus1_mu_range = (0.4, 0.1, 0.8)
if kwargs[
"charge"] < 0
else (0.275, 0.1, 0.5)
32 gaus1_sigma_range = (0.1, 0.01, 0.7)
33 gaus1_frac_range = (0.0, 1.0)
34 if kwargs[
"pmin"] < 4.5e3:
35 eop_range = (0.0, 1.0)
if kwargs[
"charge"] < 0
else (0.0, 0.6)
36 bifurgaus_mu_range = (0.039, 0.01, 0.05)
37 bifurgaus_sigmaL_range = (0.01, 0.001, 0.05)
38 bifurgaus_sigmaR_range = (0.01, 0.01, 0.1)
39 bifurgaus_frac_range = (0.7, 1.0)
40 gaus0_mu_range = (0.08, 0.065, 0.1)
41 gaus0_sigma_range = (0.015, 0.001, 0.1)
42 gaus1_mu_range = (0.4, 0.1, 0.8)
if kwargs[
"charge"] < 0
else (0.275, 0.1, 0.5)
43 gaus1_sigma_range = (0.1, 0.01, 0.7)
44 gaus1_frac_range = (0.0, 1.0)
45 if kwargs[
"pmin"] < 4e3:
46 eop_range = (0.0, 1.0)
if kwargs[
"charge"] < 0
else (0.0, 0.6)
47 bifurgaus_mu_range = (0.05, 0.01, 0.1)
48 bifurgaus_sigmaL_range = (0.01, 0.001, 0.05)
49 bifurgaus_sigmaR_range = (0.02, 0.001, 0.1)
50 bifurgaus_frac_range = (0.3, 1.0)
51 gaus0_mu_range = (0.075, 0.05, 0.2)
52 gaus0_sigma_range = (0.05, 0.01, 0.1)
53 gaus1_mu_range = (0.4, 0.1, 0.8)
if kwargs[
"charge"] < 0
else (0.275, 0.1, 0.5)
54 gaus1_sigma_range = (0.1, 0.01, 0.7)
55 gaus1_frac_range = (0.0, 1.0)
56 if kwargs[
"pmin"] < 3e3:
57 eop_range = (0.0, 1.4)
if kwargs[
"charge"] < 0
else (0.0, 0.6)
58 bifurgaus_mu_range = (0.075, 0.01, 0.15)
59 bifurgaus_sigmaL_range = (0.01, 0.001, 0.05)
60 bifurgaus_sigmaR_range = (0.02, 0.001, 0.1)
61 bifurgaus_frac_range = (0.3, 1.0)
62 gaus0_mu_range = (0.1, 0.05, 0.2)
63 gaus0_sigma_range = (0.05, 0.01, 0.1)
64 gaus1_mu_range = (0.6, 0.1, 0.8)
if kwargs[
"charge"] < 0
else (0.2, 0.1, 0.5)
65 gaus1_sigma_range = (0.1, 0.01, 0.7)
66 gaus1_frac_range = (0.0, 1.0)
67 if kwargs[
"pmin"] < 2e3:
68 eop_range = (0.0, 1.6)
if kwargs[
"charge"] < 0
else (0.0, 0.6)
69 bifurgaus_mu_range = (0.12, 0.01, 0.2)
70 bifurgaus_sigmaL_range = (0.01, 0.001, 0.05)
71 bifurgaus_sigmaR_range = (0.02, 0.001, 0.1)
72 bifurgaus_frac_range = (0.6, 1.0)
73 gaus0_mu_range = (0.15, 0.05, 0.4)
74 gaus0_sigma_range = (0.1, 0.01, 0.2)
75 gaus1_mu_range = (0.6, 0.1, 1.0)
if kwargs[
"charge"] < 0
else (0.2, 0.1, 0.5)
76 gaus1_sigma_range = (0.3, 0.01, 1.0)
77 gaus1_frac_range = (0.0, 1.0)
78 if kwargs[
"pmin"] < 1.5e3:
79 eop_range = (0.0, 1.6)
if kwargs[
"charge"] < 0
else (0.0, 0.6)
80 bifurgaus_mu_range = (0.13, 0.1, 0.3)
81 bifurgaus_sigmaL_range = (0.01, 0.001, 0.1)
if kwargs[
"charge"] < 0
else (0.03, 0.015, 0.06)
82 bifurgaus_sigmaR_range = (0.05, 0.001, 0.1)
if kwargs[
"charge"] < 0
else (0.03, 0.015, 0.06)
83 bifurgaus_frac_range = (0.5, 1.0)
84 gaus0_mu_range = (0.25, 0.2, 0.5)
85 gaus0_sigma_range = (0.1, 0.01, 0.2)
86 gaus1_mu_range = (0.8, 0.1, 1.0)
if kwargs[
"charge"] < 0
else (0.2, 0.1, 0.4)
87 gaus1_sigma_range = (0.3, 0.01, 1.0)
88 gaus1_frac_range = (0.0, 1.0)
89 if kwargs[
"pmin"] < 1e3:
91 eop_range = (0.0, 2.5)
if kwargs[
"charge"] < 0
else (0.0, 0.6)
92 bifurgaus_mu_range = (0.4, 0.1, 0.6)
if kwargs[
"charge"] < 0
else (0.4, 0.2, 0.6)
93 bifurgaus_sigmaL_range = (0.1, 0.001, 0.2)
94 bifurgaus_sigmaR_range = (0.05, 0.001, 0.1)
95 bifurgaus_frac_range = (0.0, 0.5)
if kwargs[
"charge"] < 0
else (0.5, 1.0)
96 gaus0_mu_range = (0.5, 0.35, 0.65)
if kwargs[
"charge"] < 0
else (0.35, 0.1, 0.4)
97 gaus0_sigma_range = (0.1, 0.01, 0.2)
98 gaus1_mu_range = (1.3, 0.8, 2)
if kwargs[
"charge"] < 0
else (0.25, 0.1, 0.4)
99 gaus1_sigma_range = (0.3, 0.01, 0.7)
if kwargs[
"charge"] < 0
else (0.15, 0.01, 0.3)
100 gaus1_frac_range = (0.0, 1.0)
101 if kwargs[
"pmin"] < 0.75e3:
102 eop_range = (0.0, 2.8)
if kwargs[
"charge"] < 0
else (0.0, 0.5)
103 bifurgaus_mu_range = (0.4, 0.1, 0.6)
if kwargs[
"charge"] < 0
else (0.35, 0.2, 0.6)
104 bifurgaus_sigmaL_range = (0.1, 0.001, 0.2)
105 bifurgaus_sigmaR_range = (0.05, 0.001, 0.1)
if kwargs[
"charge"] < 0
else (0.03, 0.02, 0.06)
106 bifurgaus_frac_range = (0.0, 0.5)
if kwargs[
"charge"] < 0
else (0.5, 1.0)
107 gaus0_mu_range = (0.65, 0.35, 0.85)
if kwargs[
"charge"] < 0
else (0.2, 0.1, 0.3)
108 gaus0_sigma_range = (0.1, 0.01, 0.2)
109 gaus1_mu_range = (1.4, 0.8, 2)
if kwargs[
"charge"] < 0
else (0.2, 0.1, 0.4)
110 gaus1_sigma_range = (0.3, 0.01, 0.8)
if kwargs[
"charge"] < 0
else (0.15, 0.01, 0.3)
111 gaus1_frac_range = (0.0, 1.0)
112 if kwargs[
"pmin"] < 0.5e3:
113 eop_range = (0.0, 2.6)
if kwargs[
"charge"] < 0
else (0.0, 0.4)
114 bifurgaus_mu_range = (0.1, 0.01, 0.2)
if kwargs[
"charge"] < 0
else (0.15, 0.01, 0.3)
115 bifurgaus_sigmaL_range = (0.1, 0.001, 0.2)
116 bifurgaus_sigmaR_range = (0.05, 0.001, 0.1)
117 bifurgaus_frac_range = (0.0, 0.2)
if kwargs[
"charge"] < 0
else (0.5, 1.0)
118 gaus0_mu_range = (0.65, 0.35, 0.85)
if kwargs[
"charge"] < 0
else (0.15, 0.05, 0.2)
119 gaus0_sigma_range = (0.1, 0.01, 0.2)
120 gaus1_mu_range = (1.6, 1, 2.2)
if kwargs[
"charge"] < 0
else (0.25, 0.1, 0.4)
121 gaus1_sigma_range = (0.3, 0.01, 0.7)
if kwargs[
"charge"] < 0
else (0.15, 0.01, 0.3)
122 gaus1_frac_range = (0.0, 1.0)
if kwargs[
"charge"] < 0
else (0.0, 0.0001)
123 if kwargs[
"pmin"] < 0.4e3:
124 eop_range = (0.0, 2.0)
if kwargs[
"charge"] < 0
else (0.0, 0.4)
125 bifurgaus_mu_range = (0.1, 0.01, 0.2)
if kwargs[
"charge"] < 0
else (0.075, 0.07, 0.09)
126 bifurgaus_sigmaL_range = (0.05, 0.001, 0.2)
if kwargs[
"charge"] < 0
else (0.05, 0.01, 0.1)
127 bifurgaus_sigmaR_range = (0.05, 0.001, 0.1)
if kwargs[
"charge"] < 0
else (0.025, 0.02, 0.1)
128 bifurgaus_frac_range = (0.0, 0.5)
if kwargs[
"charge"] < 0
else (0.0, 1.0)
129 gaus0_mu_range = (0.45, 0.35, 0.85)
if kwargs[
"charge"] < 0
else (0.15, 0.12, 0.18)
130 gaus0_sigma_range = (0.1, 0.01, 0.2)
131 gaus1_mu_range = (1.3, 1, 2.2)
if kwargs[
"charge"] < 0
else (0.25, 0.2, 0.4)
132 gaus1_sigma_range = (0.3, 0.01, 0.7)
if kwargs[
"charge"] < 0
else (0.18, 0.1, 0.3)
133 gaus1_frac_range = (0.0, 1.0)
136 inpath =
"{0}/pdg{1}2212.root".format(kwargs[
"inputpath"], append)
137 infile = ROOT.TFile(inpath)
139 eopvar = ROOT.RooRealVar(
"eop",
"E/p", eop_range[0], eop_range[1])
140 eophist_data = infile.Get(
"h_Eop_{0}_{1}".format(idx_p - 1, idx_th - 1))
141 eopdata = ROOT.RooDataHist(
"eopdata",
"eopdata", ROOT.RooArgList(eopvar), ROOT.RooFit.Import(eophist_data))
144 pm =
"+" if kwargs[
"charge"] > 0
else "-"
145 particle =
"p^{{{0}}}".format(pm)
146 p_range =
"{0:.2f} < p_{{lab}} #leq {1:.2f} [GeV/c]".format(kwargs[
"pmin"] / 1e3, kwargs[
"pmax"] / 1e3)
147 theta_range =
"{0:.1f} < #theta_{{lab}} #leq {1:.1f} [deg]".format(kwargs[
"thetamin"], kwargs[
"thetamax"])
148 title =
"{0}, {1}, {2}".format(particle, p_range, theta_range)
149 frame1 = eopvar.frame(ROOT.RooFit.Title(title))
150 eopdata.plotOn(frame1, ROOT.RooFit.DataError(ROOT.RooAbsData.SumW2))
153 bifurgaus_mu = ROOT.RooRealVar(
"#mu_{bg}",
154 "mean of bifurcated gaussian",
155 bifurgaus_mu_range[0],
156 bifurgaus_mu_range[1],
157 bifurgaus_mu_range[2])
158 bifurgaus_sigmal = ROOT.RooRealVar(
"#sigma_{bg}_{L}",
159 "widthL of bifurcated gaussian",
160 bifurgaus_sigmaL_range[0],
161 bifurgaus_sigmaL_range[1],
162 bifurgaus_sigmaL_range[2])
163 bifurgaus_sigmar = ROOT.RooRealVar(
"#sigma_{bg}_{R}",
164 "widthR of bifurcated gaussian",
165 bifurgaus_sigmaR_range[0],
166 bifurgaus_sigmaR_range[1],
167 bifurgaus_sigmaR_range[2])
168 bifurgaus_frac = ROOT.RooRealVar(
"frac_{bg}",
169 "bifurcated gaussian fraction",
170 bifurgaus_frac_range[0],
171 bifurgaus_frac_range[1])
172 bifurgaus = ROOT.RooBifurGauss(
"bifurgaus",
"bifurcated gaussian", eopvar, bifurgaus_mu, bifurgaus_sigmal, bifurgaus_sigmar)
174 gaus0_mean = ROOT.RooRealVar(
"#mu_{g0}",
179 gaus0_sigma = ROOT.RooRealVar(
"#sigma_{g0}",
181 gaus0_sigma_range[0],
182 gaus0_sigma_range[1],
183 gaus0_sigma_range[2])
184 gaus0 = ROOT.RooGaussian(
"gaus0",
"gaussian", eopvar, gaus0_mean, gaus0_sigma)
186 pdf0 = ROOT.RooAddPdf(
"pdf0",
"bifurcated gaussian + gaussian", bifurgaus, gaus0, bifurgaus_frac)
188 gaus1_mean = ROOT.RooRealVar(
"#mu_{g1}",
193 gaus1_sigma = ROOT.RooRealVar(
"#sigma_{g1}",
195 gaus1_sigma_range[0],
196 gaus1_sigma_range[1],
197 gaus1_sigma_range[2])
198 gaus1_frac = ROOT.RooRealVar(
"frac_{g1}",
202 gaus1 = ROOT.RooGaussian(
"gaus1",
"gaussian", eopvar, gaus1_mean, gaus1_sigma)
204 pdf = ROOT.RooAddPdf(
"pdf",
"bifurcated gaussian + gaussian + gaussian", pdf0, gaus1, gaus1_frac)
207 fitres = pdf.fitTo(eopdata, ROOT.RooFit.Save(), ROOT.RooFit.PrintEvalErrors(-1))
210 ral1 = ROOT.RooArgList(eopvar)
211 ral2 = ROOT.RooArgList(pdf.getParameters(ROOT.RooArgSet(eopvar)))
212 ras = ROOT.RooArgSet(eopvar)
213 pdffunc = pdf.asTF(ral1, ral2, ras)
217 ROOT.RooFit.LineColor(ROOT.kBlack),
218 ROOT.RooFit.LineWidth(2),
219 ROOT.RooFit.MoveToBack())
221 ROOT.RooFit.Components(
"bifurgaus"),
222 ROOT.RooFit.LineStyle(ROOT.kDashed),
223 ROOT.RooFit.LineColor(ROOT.kMagenta),
224 ROOT.RooFit.LineWidth(2),
225 ROOT.RooFit.MoveToBack())
227 ROOT.RooFit.Components(
"gaus0"),
228 ROOT.RooFit.LineStyle(ROOT.kSolid),
229 ROOT.RooFit.LineColor(ROOT.kMagenta - 9),
230 ROOT.RooFit.LineWidth(2),
231 ROOT.RooFit.MoveToBack())
233 ROOT.RooFit.Components(
"gaus1"),
234 ROOT.RooFit.LineStyle(ROOT.kDotted),
235 ROOT.RooFit.LineColor(ROOT.kPink - 2),
236 ROOT.RooFit.LineWidth(2),
237 ROOT.RooFit.MoveToBack())
238 pdf.paramOn(frame1, ROOT.RooFit.Layout(0.55, 0.9, 0.75))
241 frame2 = eopvar.frame(ROOT.RooFit.Title(
"Residuals"))
242 frame2.addPlotable(frame1.residHist(),
"P")
245 ndf = get_ndf(eopdata, fitres)
246 print(
"X^2/ndf = {0:.3f} (ndf = {1})".format(frame1.chiSquare(), ndf))
249 if kwargs[
"outputplots"]:
250 plotargs = dict(kwargs, frame1=frame1.Clone(), frame2=frame2.Clone(), ndf=ndf, ndiv=520, append=append)
251 draw_plots(**plotargs)
253 pdfname =
"pdf_EoP_{0}_{1}".format(idx_p, idx_th)
254 return pdffunc.Clone(pdfname)