Belle II Software development
B2A405-Rave-MassVertexFit.py
1#!/usr/bin/env python3
2
3
10
11
31
32import basf2 as b2
33from modularAnalysis import inputMdst
34from modularAnalysis import reconstructDecay
35from modularAnalysis import matchMCTruth
36from vertex import raveFit
37from modularAnalysis import variablesToExtraInfo
38from stdCharged import stdPi, stdK
39from modularAnalysis import variablesToNtuple
40from variables import variables as vm
41import variables.collections as vc
42import variables.utils as vu
43
44
45# create path
46my_path = b2.create_path()
47
48# load input ROOT file
49inputMdst(filename=b2.find_file('B02pi0D0_D2kpi_B2Dstarpi_Dstar2Dpi_D2kpi.root', 'examples', False),
50 path=my_path)
51
52# use standard final state particle lists
53#
54# creates "pi+:all" ParticleList (and c.c.)
55stdPi('all', path=my_path)
56# creates "pi+:loose" ParticleList (and c.c.)
57stdPi('loose', path=my_path)
58# creates "K+:loose" ParticleList (and c.c.)
59stdK('loose', path=my_path)
60
61# reconstruct D0 -> K- pi+ decay
62# keep only candidates with 1.8 < M(Kpi) < 1.9 GeV
63reconstructDecay('D0:kpi -> K-:loose pi+:loose', '1.8 < M < 1.9', path=my_path)
64reconstructDecay('D0:kpi_mass -> K-:loose pi+:loose', '1.8 < M < 1.9', path=my_path)
65
66# perform D0 vertex fit
67# First, saving mass before fit
68variablesToExtraInfo("D0:kpi", variables={'M': 'M_before_vertex_fit'}, path=my_path)
69# Second, creating alias for the extra info variable
70vm.addAlias("M_BeforeFit", "extraInfo(M_before_vertex_fit)")
71# Now, do the fit keeping candidates only passing C.L. value of the fit > 0.0 (no cut)
72raveFit('D0:kpi', 0.0, path=my_path)
73
74# perform mass constrained D0 vertex fit
75# keep candidates only passing C.L. value of the fit > 0.0 (no cut)
76variablesToExtraInfo("D0:kpi_mass", variables={'M': 'M_before_vertex_fit'}, path=my_path)
77# no need to create alias again
78raveFit('D0:kpi_mass', 0.0, fit_type='massvertex', path=my_path)
79
80# reconstruct two D*+ -> D0 pi+ decay
81# keep only candidates with Q = M(D0pi) - M(D0) - M(pi) < 20 MeV
82# and D* CMS momentum > 2.5 GeV
83reconstructDecay('D*+:1 -> D0:kpi pi+:all',
84 '0.0 <= Q < 0.02 and 2.5 < useCMSFrame(p) < 5.5', path=my_path)
85reconstructDecay('D*+:2 -> D0:kpi_mass pi+:all',
86 '0.0 <= Q < 0.02 and 2.5 < useCMSFrame(p) < 5.5', path=my_path)
87
88# perform MC matching (MC truth association)
89matchMCTruth('D*+:1', path=my_path)
90matchMCTruth('D*+:2', path=my_path)
91
92# perform D*+ kinematic vertex fit using the D0 and the pi+
93# keep candidates only passing C.L. value of the fit > 0.0 (no cut)
94raveFit('D*+:1', 0.0, path=my_path)
95
96# perform D*+ kinematic beam spot constrained vertex fit using the D0 and the pi+
97# keep candidates only passing C.L. value of the fit > 0.0 (no cut)
98raveFit('D*+:2', 0.0, constraint='ipprofile', path=my_path)
99
100
101# Select variables that we want to store to ntuple
102dstar_vars = vc.inv_mass + vc.mc_truth + \
103 vc.mc_flight_info + vc.flight_info
104
105fs_hadron_vars = vu.create_aliases_for_selected(
106 vc.pid + vc.track + vc.mc_truth,
107 'D*+ -> [D0 -> ^K- ^pi+] ^pi+')
108
109d0_vars = vu.create_aliases_for_selected(
110 vc.inv_mass + vc.mc_truth + ["M_BeforeFit"],
111 'D*+ -> ^D0 pi+', 'D0')
112
113
114# Saving variables to ntuple
115output_file = 'B2A405-Rave-MassVertexFit.root'
116variablesToNtuple('D*+:1', dstar_vars + d0_vars + fs_hadron_vars,
117 filename=output_file, treename='dsttree1', path=my_path)
118variablesToNtuple('D*+:2', dstar_vars + d0_vars + fs_hadron_vars,
119 filename=output_file, treename='dsttree2', path=my_path)
120
121
122# Process the events
123b2.process(my_path)
124
125# print out the summary
126print(b2.statistics)