Belle II Software development
v0ValidationCreatePlots.py
1#!/usr/bin/env python3
2
3
10
11"""
12<header>
13 <contact>software-tracking@belle2.org</contact>
14 <input>V0ValidationHarvested.root</input>
15 <output>V0Validation.root</output>
16 <description>This module creates efficiency plots for the V0 validation.</description>
17</header>
18"""
19
20
21import numpy
22import ROOT
23
24ACTIVE = True
25
26
27class V0ValidationPlots:
28
29 """Reads the output created by the V0Harvester and creates plots from it."""
30
31 def __init__(self, input_file='../V0ValidationHarvested.root', output_file='V0Validation.root'):
32 """Reads the output created by the V0Harvester defines histograms which will be filled later.
33
34 :param input_file: Output of V0ValidationHarvester.
35 :param output_file: Plots displayed in the V0Validation.
36 """
37
38 self.input_file = input_file
39
40 self.output_file = output_file
41
42
43 self.hist_r = ROOT.TH1F("", "True R", 20, 0, 20)
44
45 self.hist_theta = ROOT.TH1F("", "True Theta", 26, 20, 150)
46
47 self.hist_phi = ROOT.TH1F("", "True Phi", 36, -180, 180)
48
49 self.hist_p = ROOT.TH1F("", "True P", 25, 0.0, 1.0)
50
51
52 self.hist_r_found = ROOT.TH1F("", "Found R", 20, 0, 20)
53
54 self.hist_theta_found = ROOT.TH1F("", "Found Theta", 26, 20, 150)
55
56 self.hist_phi_found = ROOT.TH1F("", "Found Phi", 36, -180, 180)
57
58 self.hist_p_found = ROOT.TH1F("", "Found P", 25, 0.0, 1.0)
59
60
61 self.hist_invariant_mass = ROOT.TH1F("", "", 60, 0.470, 0.530)
62
63 self.hist_invariant_mass_res = ROOT.TH1F("", "", 40, -0.02, 0.02)
64
65
66 self.hist_chi2 = ROOT.TH1F("", "", 50, 0, 50)
67
68 self.hist_chi2_inside = ROOT.TH1F("", "", 50, 0, 50)
69
70 self.hist_chi2_outside = ROOT.TH1F("", "", 50, 0, 50)
71
72
73 self.hist_mass_vs_mc_mass = ROOT.TH2F("", "", 80, 0, 0.8, 80, 0, 0.8)
74
75
76 self.hist_invariant_mass_residuum = ROOT.TH1F("", "", 60, -0.05, 0.05)
77
78 self.hist_r_residuum = ROOT.TH1F("", "", 60, -0.1, 0.1)
79
80 self.hist_theta_residuum = ROOT.TH1F("", "", 60, -0.1, 0.1)
81
82 self.hist_phi_residuum = ROOT.TH1F("", "", 60, -0.1, 0.1)
83
84 self.hist_p_residuum = ROOT.TH1F("", "", 60, -0.05, 0.05)
85
87 """Fills the defined histograms with the V0Harvester data.
88
89 :return: self
90 """
91 input_root_file = ROOT.TFile.Open(self.input_file, "READ")
92
93 for event in input_root_file.V0Harvester_tree:
94 self.hist_r.Fill(event.R_MC)
95 self.hist_theta.Fill(numpy.rad2deg(event.THETA_MC))
96 self.hist_phi.Fill(numpy.rad2deg(event.PHI_MC))
97 self.hist_p.Fill(event.P_MC)
98
99 if event.FOUND:
100 self.hist_r_found.Fill(event.R_MC)
101 self.hist_theta_found.Fill(numpy.rad2deg(event.THETA_MC))
102 self.hist_phi_found.Fill(numpy.rad2deg(event.PHI_MC))
103 self.hist_p_found.Fill(event.P_MC)
104
105 self.hist_invariant_mass.Fill(event.M)
106
107 # Residuum histograms
108 self.hist_invariant_mass_residuum.Fill(event.M - event.M_MC)
109 self.hist_r_residuum.Fill(event.R - event.R_MC)
110 self.hist_theta_residuum.Fill(event.THETA - event.THETA_MC)
111 self.hist_phi_residuum.Fill(event.PHI - event.PHI_MC)
112 self.hist_p_residuum.Fill(event.P - event.P_MC)
113
114 self.hist_chi2.Fill(event.CHI2)
115 if event.R_MC > 1.0:
116 self.hist_chi2_outside.Fill(event.CHI2)
117 else:
118 assert event.R_MC <= 1.0
119 self.hist_chi2_inside.Fill(event.CHI2)
120
121 self.hist_mass_vs_mc_mass.Fill(event.M, event.M_MC)
122
123 input_root_file.Close()
124 return self
125
126 @staticmethod
127 def efficiency_plot(found, all, title, x_variable, x_unit, description='', check='', contact='', meta_options=''):
128 """Create an efficiency plot.
129
130 :param found: Histogram with all found entries (i.e. reconstructed).
131 :param all: Histogram with all entries (i.e. MCTruth).
132 :param title: Title of the histogram.
133 :param x_variable: x variable.
134 :param x_unit: x unit.
135 :param description: Description text shown on the validation page.
136 :param check: Check text shown on the validation page.
137 :param contact: Contact text shown on the validation page.
138 :param meta_options: Meta options for the validation page.
139 :return: ROOT.TEfficiency
140 """
141 efficiency = ROOT.TEfficiency(found, all)
142 efficiency.SetName("".join(title.split()))
143 ylabel = f'Efficiency / ({(found.GetXaxis().GetXmax() - found.GetXaxis().GetXmin()) / found.GetNbinsX()} {x_unit})'
144 efficiency.SetTitle(f"{title};{x_variable} / ({x_unit});{ylabel}")
145 efficiency.GetListOfFunctions().Add(ROOT.TNamed('Description', description))
146 efficiency.GetListOfFunctions().Add(ROOT.TNamed('Check', check))
147 efficiency.GetListOfFunctions().Add(ROOT.TNamed('Contact', contact))
148 efficiency.GetListOfFunctions().Add(ROOT.TNamed('MetaOptions', meta_options))
149 return efficiency
150
151 @staticmethod
152 def histogram_plot(hist, title, x_variable, x_unit=None, description='', check='', contact='', meta_options=''):
153 """Create (annotate) an histogram plot.
154
155 :param hist: TH1F
156 :param title: Title of the histogram.
157 :param x_variable: x variable.
158 :param x_unit: x unit.
159 :param description: Description text shown on the validation page.
160 :param check: Check text shown on the validation page.
161 :param contact: Contact text shown on the validation page.
162 :param meta_options: Meta options for the validation page.
163 :return: modified hist
164 """
165 hist.SetName("".join(title.split()))
166 xlabel = f'{x_variable} / ({x_unit})' if x_unit is not None else f'{x_variable}'
167 ylabel = f'Entries / ({(hist.GetXaxis().GetXmax() - hist.GetXaxis().GetXmin()) / hist.GetNbinsX()} {x_unit})' \
168 if x_unit is not None \
169 else f'Entries / ({(hist.GetXaxis().GetXmax() - hist.GetXaxis().GetXmin()) / hist.GetNbinsX()})'
170 hist.SetTitle(f"{title};{xlabel};{ylabel}")
171 hist.GetListOfFunctions().Add(ROOT.TNamed('Description', description))
172 hist.GetListOfFunctions().Add(ROOT.TNamed('Check', check))
173 hist.GetListOfFunctions().Add(ROOT.TNamed('Contact', contact))
174 hist.GetListOfFunctions().Add(ROOT.TNamed('MetaOptions', meta_options))
175 return hist
176
177 @staticmethod
178 def histogram_2d_plot(hist, title, x_variable, y_variable, x_unit=None, y_unit=None,
179 description='', check='', contact='', meta_options=''):
180 """Create a 2d hisogram plot.
181
182 :param hist: TH2F
183 :param title: Title of the histogram.
184 :param x_variable: x variable
185 :param y_variable: y variable
186 :param x_unit: x unit
187 :param y_unit: y unit
188 :param description: Description text shown on the validation page.
189 :param check: Check text shown on the validation page.
190 :param contact: Contact text shown on the validation page.
191 :param meta_options: Meta options for the validation page.
192 :return: ROOT.TEfficiency
193 :return:
194 """
195 hist.SetName("".join(title.split()))
196 xlabel = f'{x_variable} / ({x_unit})' if x_unit is not None else f'{x_variable}'
197 ylabel = f'{y_variable} / ({y_unit})' if y_unit is not None else f'{y_variable}'
198 hist.SetTitle(f"{title};{xlabel};{ylabel}")
199 hist.GetListOfFunctions().Add(ROOT.TNamed('Description', description))
200 hist.GetListOfFunctions().Add(ROOT.TNamed('Check', check))
201 hist.GetListOfFunctions().Add(ROOT.TNamed('Contact', contact))
202 hist.GetListOfFunctions().Add(ROOT.TNamed('MetaOptions', meta_options))
203 return hist
204
205 def plot(self):
206 """Create plots with the data filled with 'collect_histograms'.
207
208 :return: self
209 """
210 output_root_file = ROOT.TFile.Open(self.output_file, "RECREATE")
211
212 V0ValidationPlots.efficiency_plot(
213 self.hist_r_found,
214 self.hist_r,
215 'Efficiency vs R',
216 'r',
217 'cm',
218 description='Reconstruction Efficiency vs. r (perpendicular)',
219 check='Check that efficiencies are close to the reference. Report significant deviations.',
220 contact='software-tracking@belle2.org',
221 meta_options='shifter').Write()
222
223 V0ValidationPlots.efficiency_plot(self.hist_theta_found, self.hist_theta, 'Efficiency vs Theta', 'Theta', 'deg',
224 description='Reconstruction Efficiency vs. theta',
225 check='',
226 contact='software-tracking@belle2.org',
227 meta_options='').Write()
228
229 V0ValidationPlots.efficiency_plot(self.hist_phi_found, self.hist_phi, 'Efficiency vs Phi', 'Phi', 'deg',
230 description='Reconstruction Efficiency vs phi',
231 check='',
232 contact='software-tracking@belle2.org',
233 meta_options='').Write()
234
235 V0ValidationPlots.efficiency_plot(self.hist_p_found, self.hist_p, 'Efficiency vs P', 'P', 'GeV',
236 description='Reconstruction Efficiency vs momentum',
237 check='',
238 contact='software-tracking@belle2.org',
239 meta_options='').Write()
240
241 V0ValidationPlots.histogram_plot(self.hist_invariant_mass, "KShort Invariant Mass", "m", "GeV",
242 description='Reconstructed invariant mass of KShorts with standard reconstruction',
243 check='Invariant mass peak around KShort nominal mass 497.61 MeV.',
244 contact='software-tracking@belle2.org',
245 meta_options='shifter').Write()
246
247 V0ValidationPlots.histogram_plot(self.hist_invariant_mass_residuum, "KShort Invariant Mass Residuum", "Rec - MC", "GeV",
248 description='Invariant mass residuum of KShorts with standard reconstruction',
249 check='',
250 contact='software-tracking@belle2.org',
251 meta_options='').Write()
252
253 V0ValidationPlots.histogram_plot(self.hist_chi2, "Chi2 of Vertex Fits.", "Chi2", None,
254 description='Chi2 distributions of the vertex fits.',
255 check='Check if distribution looks like a Chi2 distribution with 1 dof',
256 contact='software-tracking@belle2.org',
257 meta_options='').Write()
258
259 V0ValidationPlots.histogram_plot(self.hist_chi2_inside, "Chi2 of Vertex Fits Inside Beampipe.", "Chi2", None,
260 description='Chi2 distributions of the vertex fits inside the beampipe.',
261 check='Check if distribution looks like a Chi2 distribution with 1 dof',
262 contact='software-tracking@belle2.org',
263 meta_options='').Write()
264
265 V0ValidationPlots.histogram_plot(self.hist_chi2_outside, "Chi2 of Vertex Fits Outside Beampipe.", "Chi2", None,
266 description='Chi2 distributions of the vertex fits outside the beampipe.',
267 check='Check if distribution looks like a Chi2 distribution with 1 dof',
268 contact='software-tracking@belle2.org',
269 meta_options='').Write()
270
271 V0ValidationPlots.histogram_2d_plot(self.hist_mass_vs_mc_mass, "Reconstructed vs MC Mass.",
272 "Reconstructed Mass", "GeV", "MC Mass", "GeV",
273 description="Reconstructed mass vs invariant Mass.",
274 check="",
275 contact="software-tracking@belle2.org",
276 meta_options='').Write()
277
278 V0ValidationPlots.histogram_plot(self.hist_r_residuum, "KShort R Residuum", "Rec - MC", "cm",
279 description='R residuum of KShorts with standard reconstruction',
280 check='',
281 contact='software-tracking@belle2.org',
282 meta_options='').Write()
283 V0ValidationPlots.histogram_plot(self.hist_theta_residuum, "KShort Theta Residuum", "Rec - MC", "rad",
284 description='Theta residuum of KShorts with standard reconstruction',
285 check='',
286 contact='software-tracking@belle2.org',
287 meta_options='').Write()
288 V0ValidationPlots.histogram_plot(self.hist_phi_residuum, "KShort Phi Residuum", "Rec - MC", "rad",
289 description='Phi residuum of KShorts with standard reconstruction',
290 check='',
291 contact='software-tracking@belle2.org',
292 meta_options='').Write()
293 V0ValidationPlots.histogram_plot(self.hist_p_residuum, "KShort Momentum Residuum", "Rec - MC", "GeV",
294 description='Momentum residuum of KShorts with standard reconstruction',
295 check='',
296 contact='software-tracking@belle2.org',
297 meta_options='').Write()
298
299 output_root_file.Write()
300 output_root_file.Close()
301 return self
302
303
304if __name__ == '__main__':
305 if ACTIVE:
307 else:
308 print("This validation deactivated and thus basf2 is not executed.\n"
309 "If you want to run this validation, please set the 'ACTIVE' flag above to 'True'.\n"
310 "Exiting.")
hist_chi2_outside
Chi2 of vertex fit outside beampipe.
hist_invariant_mass_res
Invariant mass residual histogram.
def efficiency_plot(found, all, title, x_variable, x_unit, description='', check='', contact='', meta_options='')
hist_mass_vs_mc_mass
2D histogram; invariant mass vs reconstructed mass
def histogram_plot(hist, title, x_variable, x_unit=None, description='', check='', contact='', meta_options='')
hist_chi2_inside
Chi2 of vertex fit inside beampipe.
def histogram_2d_plot(hist, title, x_variable, y_variable, x_unit=None, y_unit=None, description='', check='', contact='', meta_options='')
hist_invariant_mass_residuum
Invariant mass residuum histogram.
def __init__(self, input_file='../V0ValidationHarvested.root', output_file='V0Validation.root')
Definition: plot.py:1