Belle II Software  release-06-02-00
2_analysis_pi0.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 
11 
12 """
13 <header>
14  <input>../GenericB_GENSIMRECtoDST.dst.root</input>
15  <output>Pi0_Validation.root</output>
16  <contact>Mario Merola (mario.merola@na.infn.it), Andrea Selce (selce@infn.it)</contact>
17  <description>
18  Check the calibration of the ECL in the MC by determining the measured pi0 invariant mass.
19  </description>
20 </header>
21 """
22 
23 import basf2
24 import ROOT
25 from modularAnalysis import cutAndCopyList, inputMdst, matchMCTruth
26 from stdPi0s import stdPi0s
27 from validation_tools.metadata import create_validation_histograms
28 from validation_tools.metadata import validation_metadata_update
29 from variables import variables as vm
30 
31 INPUT_FILENAME = "../GenericB_GENSIMRECtoDST.dst.root"
32 OUTPUT_FILENAME = "Pi0_Validation.root"
33 
34 main = basf2.Path()
35 inputMdst('default', INPUT_FILENAME, path=main)
36 
37 stdPi0s('all', path=main)
38 matchMCTruth('pi0:all', path=main)
39 
40 cutAndCopyList('pi0:rec', 'pi0:all', 'daughter(0, E)>0.05 and daughter(1, E)>0.05', path=main)
41 cutAndCopyList('pi0:mc', 'pi0:all', 'mcErrors<1', path=main)
42 
43 vm.addAlias('Mreco', 'M')
44 
45 
46 create_validation_histograms(
47  main, OUTPUT_FILENAME, "pi0:rec",
48  variables_1d=[
49  (
50  "Mreco", 40, 0.08, 0.18,
51  "#pi^{0} reconstructed candidates, invariant mass",
52  "Mario Merola <mario.merola@desy.de>; Andrea Selce <selce@infn.it>",
53  r"The $\pi^{0}$ invariant mass distribution with $E_{\gamma}>0.05\, \text{GeV}$",
54  r"Distribution should be peaking at the nominal $\pi^{0}$ mass.",
55  "M(#pi^{0}) [GeV/c^{2}]", "Candidates", "shifter"
56  ),
57  ],
58  description=r"$\pi^0$ reconstructed mass distribution",
59 )
60 
61 
62 vm.addAlias('Mmc', 'M')
63 
64 create_validation_histograms(
65  main, OUTPUT_FILENAME, "pi0:mc",
66  variables_1d=[
67  (
68  "Mmc", 40, 0.08, 0.18,
69  "#pi^{0} MC candidates, invariant mass",
70  "Mario Merola <mario.merola@desy.de>; Andrea Selce <selce@infn.it>",
71  r"The $\pi^{0}$ invariant mass distribution for truth matched candidates",
72  r"Distribution should be peaking at the nominal $\pi^{0}$ mass.",
73  "M(#pi^{0}) [GeV/c^{2}]", "Candidates", "shifter"
74  ),
75  ],
76  description=r"$\pi^0$ MC mass distribution",
77 )
78 
79 basf2.process(main)
80 print(basf2.statistics)
81 
82 
83 f = ROOT.TFile(OUTPUT_FILENAME)
84 Mrecohist = f.Get('Mreco')
85 Mmchist = f.Get('Mmc')
86 
87 
88 mass = ROOT.RooRealVar("recomass", "m_{#gamma#gamma} [GeV/c^{2}]", 0.11, 0.15)
89 
90 h_pi0_reco = ROOT.RooDataHist("h_pi0_reco", "h_pi0_reco", ROOT.RooArgList(mass), Mrecohist)
91 h_pi0_mc = ROOT.RooDataHist("h_pi0_mc", "h_pi0_mc", ROOT.RooArgList(mass), Mmchist)
92 
93 
94 # pi0 signal PDF is a Crystal Ball (Gaussian also listed in case we want to switch)
95 mean = ROOT.RooRealVar("mean", "mean", 0.14, 0.11, 0.15)
96 sig1 = ROOT.RooRealVar("#sigma", "sig", 0.05, 0.002, 0.1)
97 gau1 = ROOT.RooGaussian("gau1", "gau1", mass, mean, sig1)
98 
99 alphacb = ROOT.RooRealVar("alphacb", "alpha", 1.5, 0.1, 1.9)
100 ncb = ROOT.RooRealVar("ncb", "n", 8) # ,2.,15)
101 sigcb = ROOT.RooCBShape("sigcb", "sigcb", mass, mean, sig1, alphacb, ncb)
102 
103 # pi0 background PDF is a 2nd order Chebyshev
104 b1 = ROOT.RooRealVar("b1", "b1", -3.0021e-01, -0.8, 0.8)
105 a1 = ROOT.RooRealVar("a1", "a1", -3.0021e-01, -0.8, 0.8)
106 bList = ROOT.RooArgList(a1, b1)
107 bkg = ROOT.RooChebychev("bkg", "bkg", mass, bList)
108 
109 
110 nsig = ROOT.RooRealVar("nsig", "nsig", 1000, 0, 1000000)
111 nbkg = ROOT.RooRealVar("nbkg", "nbkg", 1000, 0, 1000000)
112 
113 
114 totalPdf = ROOT.RooAddPdf("totalpdf", "", ROOT.RooArgList(sigcb, bkg), ROOT.RooArgList(nsig, nbkg))
115 
116 
117 output = ROOT.TFile("Pi0_Validation_ntuple.root", "recreate")
118 
119 # Store pi0 mass fit results to a tuple for comparison of mean and width among releases.
120 outputNtuple = ROOT.TNtuple(
121  "pi0_mass",
122  "Pi0 mass fit results",
123  "mean:meanerror:width:widtherror")
124 
125 
126 canvas = ROOT.TCanvas("canvas", "pi0 mass fit", 1000, 600)
127 canvas.Divide(2, 1)
128 canvas.cd(1)
129 
130 # Fit to the reco mass
131 totalPdf.fitTo(h_pi0_reco, ROOT.RooFit.Extended(True), ROOT.RooFit.Minos(1), ROOT.RooFit.Range(0.11, 0.15))
132 frame1 = ROOT.RooPlot
133 frame1 = mass.frame()
134 h_pi0_reco.plotOn(frame1, ROOT.RooFit.Name("Hist"))
135 frame1.SetMaximum(frame1.GetMaximum())
136 totalPdf.plotOn(frame1, ROOT.RooFit.Name("curve"))
137 totalPdf.plotOn(frame1, ROOT.RooFit.Components("sigcb"), ROOT.RooFit.LineStyle(ROOT.kDashed), ROOT.RooFit.LineColor(ROOT.kRed))
138 totalPdf.plotOn(frame1, ROOT.RooFit.Components("bkg"), ROOT.RooFit.LineStyle(3), ROOT.RooFit.LineColor(ROOT.kBlue))
139 # totalPdf.paramOn(frame1,ROOT.RooFit.Parameters(ROOT.RooArgSet(sig1,mean,nsig)),ROOT.RooFit.Format("NELU",ROOT.RooFit.AutoPrecision(2)),ROOT.RooFit.Layout(0.5,0.9,0.9))
140 # frame1.getAttText().SetTextSize(0.5)
141 frame1.SetMaximum(Mrecohist.GetMaximum() * 1.5)
142 frame1.GetXaxis().SetTitleOffset(1.4)
143 frame1.GetYaxis().SetTitleOffset(1.5)
144 meanval = mean.getVal()
145 meanerror = mean.getError()
146 width = sig1.getVal()
147 widtherror = sig1.getError()
148 frame1.Draw("")
149 
150 outputNtuple.Fill(meanval, meanerror, width, widtherror)
151 
152 
153 canvas.cd(2)
154 
155 # ---------------------------
156 # Fit to the truth matched mass using the same pdf of the reco mass.
157 # Re-initialize the fit parameters to the default values.
158 mean.setVal(0.14)
159 sig1.setVal(0.005)
160 nsig.setVal(1000)
161 nbkg.setVal(1000)
162 alphacb.setVal(1.5)
163 ncb.setVal(8.)
164 b1.setRange(-0.5, 0.5)
165 a1.setRange(-0.5, 0.5)
166 b1.setVal(-3.0021e-01)
167 a1.setVal(-3.0021e-01)
168 
169 
170 # Fit to the truth matched mass
171 totalPdf.fitTo(h_pi0_mc, ROOT.RooFit.Extended(True), ROOT.RooFit.Minos(1), ROOT.RooFit.Range(0.11, 0.15))
172 frame2 = ROOT.RooPlot
173 frame2 = mass.frame()
174 h_pi0_mc.plotOn(frame2, ROOT.RooFit.Name("Hist"))
175 frame2.SetMaximum(frame2.GetMaximum())
176 totalPdf.plotOn(frame2, ROOT.RooFit.Name("curve"))
177 totalPdf.plotOn(frame2, ROOT.RooFit.Components("sigcb"), ROOT.RooFit.LineStyle(ROOT.kDashed), ROOT.RooFit.LineColor(ROOT.kRed))
178 totalPdf.plotOn(frame2, ROOT.RooFit.Components("bkg"), ROOT.RooFit.LineStyle(3), ROOT.RooFit.LineColor(ROOT.kBlue))
179 # totalPdf.paramOn(frame2,ROOT.RooFit.Parameters(ROOT.RooArgSet(sig1,mean,nsig)),ROOT.RooFit.Format("NELU",ROOT.RooFit.AutoPrecision(2)),ROOT.RooFit.Layout(0.5,0.9,0.9))
180 # frame2.getAttText().SetTextSize(0.5)
181 frame2.SetMaximum(Mmchist.GetMaximum() * 1.5)
182 frame2.GetXaxis().SetTitleOffset(1.4)
183 frame2.GetYaxis().SetTitleOffset(1.5)
184 meanval_mc = mean.getVal()
185 meanerror_mc = mean.getError()
186 width_mc = sig1.getVal()
187 widtherror_mc = sig1.getError()
188 frame2.Draw("")
189 
190 canvas.Write()
191 
192 outputNtuple.Fill(meanval_mc, meanerror_mc, width_mc, widtherror_mc)
193 
194 outputNtuple.Write()
195 
196 validation_metadata_update(
197  output,
198  "pi0_mass",
199  title="Pi0 mass fit results",
200  contact="mario.merola@na.infn.it, selce@infn.it",
201  description="Fit to the invariant mass of the reconstructed and truth matched pi0s",
202  check="Consistent numerical fit results. Stable mean and width.",
203  metaoptions="shifter")
204 
205 
206 output.Close()