/WPol2/scripts/fitting_code/test.py

https://github.com/brynmathias/AnalysisV2 · Python · 352 lines · 287 code · 27 blank · 38 comment · 13 complexity · e431ee02875b0b1410f7578d2bdf6dd0 MD5 · raw file

  1. #!/usr/bin/env python
  2. import unittest
  3. from wpolfitter.fit import *
  4. from wpolfitter.utils import *
  5. class WPolTestCase:
  6. def assertWithinErrors(self, name, a, b, err):
  7. self.assert_(abs(a - b) < err, "Value of %s = %.4f. +- %.4f incompatible with %.4f" %
  8. (name, a, err, b))
  9. class MuonTestCase(unittest.TestCase, WPolTestCase):
  10. def setUp(self):
  11. mu_path = "./ROOTFiles/"
  12. mu_file_names = ["RecoRoutines_W-selection_realdata.root",
  13. "RecoRoutines_W-selection_WJets_madgraph_June2010.root",
  14. "RecoRoutines_W-selection_ZJets_madgraph_June2010.root"]
  15. # Open files
  16. self.mu_files = [r.TFile(mu_path + mu_file_name) for mu_file_name in mu_file_names]
  17. # Read histograms
  18. self.mu_plus_hists = [f.Get("RECO_PolPlots_50toinf").Get("RECO_ICVarPFPlus") for f in self.mu_files]
  19. self.mu_minus_hists = [f.Get("RECO_PolPlots_50toinf").Get("RECO_ICVarPFMinus") for f in self.mu_files]
  20. total_ewk_plus = self.mu_plus_hists[1].Clone()
  21. total_ewk_plus.Add(self.mu_plus_hists[2])
  22. self.wfraction_plus = self.mu_plus_hists[1].Integral()/total_ewk_plus.Integral()
  23. total_ewk_minus = self.mu_minus_hists[1].Clone()
  24. total_ewk_minus.Add(self.mu_minus_hists[2])
  25. self.wfraction_minus = self.mu_minus_hists[1].Integral()/total_ewk_minus.Integral()
  26. self.mu_plus_wtemplates = [self.mu_files[1].Get("RECO_PolPlots_50toinf").Get("RECO_ICVarPFPlus_%s" % s)
  27. for s in ["LH", "RH", "LO"]]
  28. self.mu_minus_wtemplates = [self.mu_files[1].Get("RECO_PolPlots_50toinf").Get("RECO_ICVarPFMinus_%s" % s)
  29. for s in ["LH", "RH", "LO"]]
  30. # MC Data
  31. self.mc_plus_hists = [self.mu_plus_hists[1].Clone(), self.mu_plus_hists[2].Clone()]
  32. self.mc_minus_hists = [self.mu_minus_hists[1].Clone(), self.mu_minus_hists[2].Clone()]
  33. # Scale
  34. scale(100, self.mc_plus_hists, self.mc_minus_hists)
  35. # Rebin
  36. rebin(10, self.mc_plus_hists, self.mc_minus_hists)
  37. # Global parameters in fits
  38. self.fit_globals = {
  39. # Set up fit parameters
  40. "lp" : r.RooRealVar("lp", "LP Variable", *default_cfg["lp_range"]),
  41. # Set up fit variables
  42. "f1" : r.RooRealVar("f1", "f1", 0., 1.),
  43. "f2" : r.RooRealVar("f2", "f2", 0., 1.)
  44. }
  45. def test_plus_closure(self):
  46. """ Perform closure test fit for mu+ and check fL, fR, f0 within fit errors of nominal value"""
  47. plus_templates = {
  48. "w" : self.mu_plus_hists[1],
  49. "lh" : self.mu_plus_wtemplates[0],
  50. "rh" : self.mu_plus_wtemplates[1],
  51. "lo" : self.mu_plus_wtemplates[2]
  52. }
  53. rebin(10, plus_templates)
  54. fit = run("mu_plus_mc",
  55. self.fit_globals,
  56. self.mc_plus_hists[0:1],
  57. plus_templates,
  58. {"w" : 1},
  59. action = "fit_minuit"
  60. )
  61. (fL_fit, fL_err) = fL(fit["result"])
  62. (fR_fit, fR_err) = fR(fit["result"])
  63. (f0_fit, f0_err) = f0(fit["result"])
  64. fL_nom = 0.5543
  65. fR_nom = 0.2270
  66. f0_nom = 0.208
  67. self.assertWithinErrors("fL", fL_fit, fL_nom, fL_err)
  68. self.assertWithinErrors("fR", fR_fit, fR_nom, fR_err)
  69. self.assertWithinErrors("f0", f0_fit, f0_nom, f0_err)
  70. def test_plus_bg(self):
  71. """ Perform closure test fit (incl. bg) for mu+ and check fL, fR, f0
  72. within fit errors of nominal value"""
  73. plus_templates = {
  74. "w" : self.mu_plus_hists[1],
  75. "ewk" : self.mu_plus_hists[2],
  76. "lh" : self.mu_plus_wtemplates[0],
  77. "rh" : self.mu_plus_wtemplates[1],
  78. "lo" : self.mu_plus_wtemplates[2]
  79. }
  80. rebin(10, plus_templates)
  81. fit = run("mu_plus_mc",
  82. self.fit_globals,
  83. self.mc_plus_hists[0:2],
  84. plus_templates,
  85. {"w" : self.wfraction_plus},
  86. action = "fit_minuit"
  87. )
  88. (fL_fit, fL_err) = fL(fit["result"])
  89. (fR_fit, fR_err) = fR(fit["result"])
  90. (f0_fit, f0_err) = f0(fit["result"])
  91. fL_nom = 0.5543
  92. fR_nom = 0.2270
  93. f0_nom = 0.208
  94. self.assertWithinErrors("fL", fL_fit, fL_nom, fL_err)
  95. self.assertWithinErrors("fR", fR_fit, fR_nom, fR_err)
  96. self.assertWithinErrors("f0", f0_fit, f0_nom, f0_err)
  97. def test_minus_closure(self):
  98. """ Perform closure test fit for mu- and check fL, fR, f0 within fit
  99. errors of nominal value"""
  100. minus_templates = {
  101. "w" : self.mu_minus_hists[1],
  102. "lh" : self.mu_minus_wtemplates[0],
  103. "rh" : self.mu_minus_wtemplates[1],
  104. "lo" : self.mu_minus_wtemplates[2]
  105. }
  106. rebin(10, minus_templates)
  107. fit = run("mu_minus_mc",
  108. self.fit_globals,
  109. self.mc_minus_hists[0:1],
  110. minus_templates,
  111. {"w" : 1},
  112. action = "fit_minuit"
  113. )
  114. (fL_fit, fL_err) = fL(fit["result"])
  115. (fR_fit, fR_err) = fR(fit["result"])
  116. (f0_fit, f0_err) = f0(fit["result"])
  117. fL_nom = 0.5214
  118. fR_nom = 0.2707
  119. f0_nom = 0.212
  120. assert(abs(fL_fit-fL_nom) < fL_err)
  121. assert(abs(fR_fit - fR_nom) < fR_err)
  122. assert(abs(f0_fit - f0_nom) < f0_err)
  123. def test_minus_bg(self):
  124. """ Perform closure test fit for mu- (incl. bg) and check fL, fR, f0
  125. within fit errors of nominal value"""
  126. minus_templates = {
  127. "w" : self.mu_minus_hists[1],
  128. "ewk" : self.mu_minus_hists[2],
  129. "lh" : self.mu_minus_wtemplates[0],
  130. "rh" : self.mu_minus_wtemplates[1],
  131. "lo" : self.mu_minus_wtemplates[2]
  132. }
  133. rebin(10, minus_templates)
  134. fit = run("mu_minus_mc",
  135. self.fit_globals,
  136. self.mc_minus_hists[0:2],
  137. minus_templates,
  138. {"w" : self.wfraction_minus},
  139. action = "fit_minuit"
  140. )
  141. (fL_fit, fL_err) = fL(fit["result"])
  142. (fR_fit, fR_err) = fR(fit["result"])
  143. (f0_fit, f0_err) = f0(fit["result"])
  144. fL_nom = 0.5214
  145. fR_nom = 0.2707
  146. f0_nom = 0.212
  147. self.assertWithinErrors("fL", fL_fit, fL_nom, fL_err)
  148. self.assertWithinErrors("fR", fR_fit, fR_nom, fR_err)
  149. self.assertWithinErrors("f0", f0_fit, f0_nom, f0_err)
  150. class EleTestCase(unittest.TestCase, WPolTestCase):
  151. def setUp(self):
  152. el_path = "./ROOTFiles/"
  153. el_file_names = ["eWPol_EG.root",
  154. "eWPol_WJets-madgraph_v1.root",
  155. "eWPol_ZJets-madgraph_v1.root",
  156. "eWPol_QCD_EMEnriched.root",
  157. "eWPol_QCD_BCtoE.root",
  158. "eWPol_PhotonJet.root"
  159. ]
  160. # Open files
  161. self.el_files = [r.TFile(el_path + el_file_name) for el_file_name in el_file_names]
  162. # Read histograms
  163. self.el_plus_hists = [f.Get("lp_postmht_met15_mt50_sig").Get("lp_plus") for f in self.el_files]
  164. self.el_minus_hists = [f.Get("lp_postmht_met15_mt50_sig").Get("lp_minus") for f in self.el_files]
  165. # Merge the QCD/photon+jets templates into one histogram
  166. el_qcd_plus = self.el_plus_hists[3].Clone()
  167. for h in self.el_plus_hists[4:]:
  168. el_qcd_plus.Add(h)
  169. el_qcd_minus = self.el_minus_hists[3].Clone()
  170. for h in self.el_minus_hists[4:]:
  171. el_qcd_minus.Add(h)
  172. del self.el_plus_hists[3:]
  173. del self.el_minus_hists[3:]
  174. self.el_plus_hists.append(el_qcd_plus)
  175. self.el_minus_hists.append(el_qcd_minus)
  176. # Calculate w fraction of ewk contribution
  177. total_ewk_plus = self.el_plus_hists[1].Clone()
  178. total_ewk_plus.Add(self.el_plus_hists[2])
  179. self.wfraction_plus = self.el_plus_hists[1].Integral()/total_ewk_plus.Integral()
  180. # Calculate QCD fraction of total MC
  181. total = total_ewk_plus.Clone()
  182. total.Add(self.el_plus_hists[3])
  183. self.qcdfraction_plus = self.el_plus_hists[3].Integral()/total.Integral()
  184. # Same for minus charge
  185. total_ewk_minus = self.el_minus_hists[1].Clone()
  186. total_ewk_minus.Add(self.el_minus_hists[2])
  187. self.wfraction_minus = self.el_minus_hists[1].Integral()/total_ewk_minus.Integral()
  188. total = total_ewk_minus.Clone()
  189. total.Add(self.el_minus_hists[3])
  190. self.qcdfraction_minus = self.el_minus_hists[3].Integral()/total.Integral()
  191. # Read W templates
  192. self.el_plus_wtemplates = [self.el_files[1].Get("lp_postmht_met15_mt50_sig").Get("lp_plus_%s" % s)
  193. for s in ["lh", "rh", "lo"]]
  194. self.el_minus_wtemplates = [self.el_files[1].Get("lp_postmht_met15_mt50_sig").Get("lp_minus_%s" % s)
  195. for s in ["lh", "rh", "lo"]]
  196. # MC Data
  197. self.mc_plus_hists = [self.el_plus_hists[1].Clone(), self.el_plus_hists[2].Clone()]
  198. self.mc_minus_hists = [self.el_minus_hists[1].Clone(), self.el_minus_hists[2].Clone()]
  199. # Scale
  200. #scale(10, self.mc_plus_hists, self.mc_minus_hists)
  201. # Rebin
  202. rebin(10, self.mc_plus_hists, self.mc_minus_hists)
  203. # Global parameters in fits
  204. self.fit_globals = {
  205. # Set up fit parameters
  206. "lp" : r.RooRealVar("lp", "LP Variable", *default_cfg["lp_range"]),
  207. # Set up fit variables
  208. "f1" : r.RooRealVar("f1", "f1", 0., 1.),
  209. "f2" : r.RooRealVar("f2", "f2", 0., 1.)
  210. }
  211. self.cfg = {
  212. "model_class": RooW_TH1D
  213. }
  214. def test_plus_closure(self):
  215. """ Perform closure test fit for el+ and check fL, fR, f0 within fit
  216. errors of nominal value"""
  217. plus_templates = {
  218. "w" : self.el_plus_hists[1],
  219. "lh" : self.el_plus_wtemplates[0],
  220. "rh" : self.el_plus_wtemplates[1],
  221. "lo" : self.el_plus_wtemplates[2]
  222. }
  223. rebin(10, plus_templates)
  224. fit = run("el_plus_mc",
  225. self.fit_globals,
  226. [self.mc_plus_hists[0]],
  227. plus_templates,
  228. {"w" : 1},
  229. action = "fit_minuit",
  230. **self.cfg
  231. )
  232. (fL_fit, fL_err) = fL(fit["result"])
  233. (fR_fit, fR_err) = fR(fit["result"])
  234. (f0_fit, f0_err) = f0(fit["result"])
  235. fL_nom = 0.5543
  236. fR_nom = 0.2270
  237. f0_nom = 0.208
  238. self.assertWithinErrors("fL", fL_fit, fL_nom, fL_err)
  239. self.assertWithinErrors("fR", fR_fit, fR_nom, 3*fR_err)
  240. self.assertWithinErrors("f0", f0_fit, f0_nom, f0_err)
  241. def test_plus_bg(self):
  242. """ Perform closure test fit for el+ (incl. bg) and check fL, fR, f0
  243. within fit errors of nominal value"""
  244. plus_templates = {
  245. "w" : self.el_plus_hists[1],
  246. "ewk" : self.el_plus_hists[2],
  247. "lh" : self.el_plus_wtemplates[0],
  248. "rh" : self.el_plus_wtemplates[1],
  249. "lo" : self.el_plus_wtemplates[2]
  250. }
  251. rebin(10, plus_templates)
  252. fit = run("el_plus_mc",
  253. self.fit_globals,
  254. self.mc_plus_hists[0:2],
  255. plus_templates,
  256. {"w" : self.wfraction_plus},
  257. action = "fit_minuit",
  258. **self.cfg
  259. )
  260. (fL_fit, fL_err) = fL(fit["result"])
  261. (fR_fit, fR_err) = fR(fit["result"])
  262. (f0_fit, f0_err) = f0(fit["result"])
  263. fL_nom = 0.5543
  264. fR_nom = 0.2270
  265. f0_nom = 0.208
  266. self.assertWithinErrors("fL", fL_fit, fL_nom, fL_err)
  267. self.assertWithinErrors("fR", fR_fit, fR_nom, 3*fR_err)
  268. self.assertWithinErrors("f0", f0_fit, f0_nom, f0_err)
  269. def test_minus_closure(self):
  270. """ Perform closure test fit for el- and check fL, fR, f0 within fit
  271. errors of nominal value"""
  272. minus_templates = {
  273. "w" : self.el_minus_hists[1],
  274. "lh" : self.el_minus_wtemplates[0],
  275. "rh" : self.el_minus_wtemplates[1],
  276. "lo" : self.el_minus_wtemplates[2]
  277. }
  278. rebin(10, minus_templates)
  279. fit = run("el_minus_mc",
  280. self.fit_globals,
  281. [self.mc_minus_hists[0]],
  282. minus_templates,
  283. {"w" : 1},
  284. action = "fit_minuit",
  285. **self.cfg
  286. )
  287. (fL_fit, fL_err) = fL(fit["result"])
  288. (fR_fit, fR_err) = fR(fit["result"])
  289. (f0_fit, f0_err) = f0(fit["result"])
  290. fL_nom = 0.5214
  291. fR_nom = 0.2707
  292. f0_nom = 0.212
  293. self.assertWithinErrors("fL", fL_fit, fL_nom, fL_err)
  294. self.assertWithinErrors("fR", fR_fit, fR_nom, fR_err)
  295. self.assertWithinErrors("f0", f0_fit, f0_nom, f0_err)
  296. def test_minus_bg(self):
  297. """ Perform closure test fit for el- (incl. bg) and check fL, fR, f0
  298. within fit errors of nominal value"""
  299. minus_templates = {
  300. "w" : self.el_minus_hists[1],
  301. "ewk" : self.el_minus_hists[2],
  302. "lh" : self.el_minus_wtemplates[0],
  303. "rh" : self.el_minus_wtemplates[1],
  304. "lo" : self.el_minus_wtemplates[2]
  305. }
  306. rebin(10, minus_templates)
  307. fit = run("el_minus_mc",
  308. self.fit_globals,
  309. self.mc_minus_hists[0:2],
  310. minus_templates,
  311. {"w" : self.wfraction_minus},
  312. action = "fit",
  313. **self.cfg
  314. )
  315. (fL_fit, fL_err) = fL(fit["result"])
  316. (fR_fit, fR_err) = fR(fit["result"])
  317. (f0_fit, f0_err) = f0(fit["result"])
  318. fL_nom = 0.5214
  319. fR_nom = 0.2707
  320. f0_nom = 0.212
  321. self.assertWithinErrors("fL", fL_fit, fL_nom, 5*fL_err)
  322. self.assertWithinErrors("fR", fR_fit, fR_nom, 3*fR_err)
  323. self.assertWithinErrors("f0", f0_fit, f0_nom, 3*f0_err)
  324. if __name__ == "__main__":
  325. unittest.main()