Belle II Software development
stdV0s.py
1#!/usr/bin/env python3
2
3
10
11import b2bii
12from basf2 import B2ERROR
13import modularAnalysis as ma
14from stdCharged import stdPi, stdPr
15import vertex
16
17
18def stdKshorts(prioritiseV0=True, fitter='TreeFit', path=None, updateAllDaughters=False, writeOut=False):
19 """
20 Load a combined list of the Kshorts list from V0 objects merged with
21 a list of particles combined using the analysis ParticleCombiner module.
22
23 The ParticleList is named ``K_S0:merged``. A vertex fit is performed and only
24 candidates with an invariant mass in the range :math:`0.450 < M < 0.550~GeV` after the vertex fit,
25 and for which the vertex fit did not fail, are kept.
26
27 The vertex fitter can be selected among ``TreeFit``, ``KFit``, and ``Rave``.
28
29 Parameters:
30 prioritiseV0 (bool): should the V0 mdst objects be prioritised when merging?
31 fitter (str): vertex fitter name, valid options are ``TreeFit``, ``KFit``, and ``Rave``.
32 path (basf2.Path): the path to load the modules
33 updateAllDaughters (bool): see the ``updateAllDaughters`` parameter of `vertex.treeFit`
34 or the ``daughtersUpdate`` parameter of `vertex.kFit` / `vertex.raveFit`.
35
36 .. warning:: The momenta of the daughters are updated only if ``updateAllDaughters`` is set
37 to ``True`` (i.e. **not** by default). Some variables, e.g. `daughterAngle`, will only
38 return meaningful results if the daughters momenta are updated.
39
40 This happens because variables like `daughterAngle` assume the direction of the
41 daughers momenta *at the Ks vertex* to be provided, while non-updated daughters will
42 provide their momenta direction at the point-of-closest-approach (POCA) to the beam axis.
43
44 writeOut (bool): whether RootOutput module should save the created ParticleList
45 """
46 # Fill one list from V0
47 ma.fillParticleList('K_S0:V0_ToFit -> pi+ pi-', '', writeOut=writeOut, path=path)
48 # Perform vertex fit and apply tighter mass window
49 if fitter == 'TreeFit':
50 vertex.treeFit('K_S0:V0_ToFit', conf_level=0.0, path=path, updateAllDaughters=updateAllDaughters)
51 elif fitter == 'KFit':
52 vertex.kFit('K_S0:V0_ToFit', conf_level=0.0, path=path, daughtersUpdate=updateAllDaughters)
53 elif fitter == 'Rave':
54 vertex.raveFit('K_S0:V0_ToFit', conf_level=0.0, path=path, silence_warning=True, daughtersUpdate=updateAllDaughters)
55 else:
56 B2ERROR("Valid fitter options for Kshorts are 'TreeFit', 'KFit', and 'Rave'. However, the latter is not recommended.")
57 ma.applyCuts('K_S0:V0_ToFit', '0.450 < M < 0.550', path=path)
58 # Reconstruct a second list
59 stdPi('all', path=path, writeOut=writeOut) # no quality cuts
60 ma.reconstructDecay('K_S0:RD -> pi+:all pi-:all', '0.3 < M < 0.7', 1, writeOut=writeOut, path=path)
61 # Again perform vertex fit and apply tighter mass window
62 if fitter == 'TreeFit':
63 vertex.treeFit('K_S0:RD', conf_level=0.0, path=path, updateAllDaughters=updateAllDaughters)
64 elif fitter == 'KFit':
65 vertex.kFit('K_S0:RD', conf_level=0.0, path=path, daughtersUpdate=updateAllDaughters)
66 elif fitter == 'Rave':
67 vertex.raveFit('K_S0:RD', conf_level=0.0, path=path, silence_warning=True, daughtersUpdate=updateAllDaughters)
68 ma.applyCuts('K_S0:RD', '0.450 < M < 0.550', path=path)
69 # Create merged list based on provided priority
70 ma.mergeListsWithBestDuplicate('K_S0:merged', ['K_S0:V0_ToFit', 'K_S0:RD'],
71 variable='particleSource', preferLowest=prioritiseV0, path=path)
72
73
74def goodBelleKshort(path):
75 """
76 Load the Belle goodKshort list. Creates a ParticleList named
77 ``K_S0:legacyGoodKS``. A vertex fit is performed and only candidates that
78 satisfy the :b2:var:`goodBelleKshort` criteria, with an invariant mass in the range
79 :math:`0.468 < M < 0.528~GeV` after the vertex fit, and for which the vertex fit did not fail, are kept.
80
81 Parameters:
82 path (basf2.Path): the path to load the modules
83 """
84 if b2bii.isB2BII():
85 ma.cutAndCopyList('K_S0:legacyGoodKS', 'K_S0:mdst', '0.3 < M < 0.7', writeOut=True, path=path)
86 else:
87 ma.fillParticleList('K_S0:legacyGoodKS -> pi+ pi-', '0.3 < M < 0.7', writeOut=True, path=path)
88 vertex.kFit('K_S0:legacyGoodKS', conf_level=0.0, path=path)
89 ma.applyCuts('K_S0:legacyGoodKS', '0.468 < M < 0.528 and goodBelleKshort==1', path=path)
90
91
92def scaleErrorKshorts(prioritiseV0=True, fitter='TreeFit',
93 scaleFactors_V0=[1.125927, 1.058803, 1.205928, 1.066734, 1.047513],
94 scaleFactorsNoPXD_V0=[1.125927, 1.058803, 1.205928, 1.066734, 1.047513],
95 d0Resolution_V0=[0.001174, 0.000779],
96 z0Resolution_V0=[0.001350, 0.000583],
97 d0MomThr_V0=0.500000,
98 z0MomThr_V0=0.00000,
99 scaleFactors_RD=[1.149631, 1.085547, 1.151704, 1.096434, 1.086659],
100 scaleFactorsNoPXD_RD=[1.149631, 1.085547, 1.151704, 1.096434, 1.086659],
101 d0Resolution_RD=[0.00115328, 0.00134704],
102 z0Resolution_RD=[0.00124327, 0.0013272],
103 d0MomThr_RD=0.500000,
104 z0MomThr_RD=0.500000,
105 path=None):
106 '''
107 Reconstruct K_S0 applying helix error correction to K_S0 daughters given by ``modularAnalysis.scaleError``.
108 The ParticleList is named ``K_S0:scaled``
109
110 Considering the difference of multiple scattering through the beam pipe,
111 different parameter sets are used for K_S0 decaying outside/inside the beam pipe (``K_S0:V0/RD``).
112
113 Only for TDCPV analysis.
114
115 @param prioritiseV0 If True K_S0 from V0 object is prioritised over RD when merged.
116 @param fitter Vertex fitter option. Choose from ``TreeFit``, ``KFit`` and ``Rave``.
117 @param scaleFactors_V0 List of five constants to be multiplied to each of helix errors (for tracks with a PXD hit)
118 @param scaleFactorsNoPXD_V0 List of five constants to be multiplied to each of helix errors (for tracks without a PXD hit)
119 @param d0Resolution_V0 List of two parameters, (a [cm], b [cm/(GeV/c)]),
120 defining d0 best resolution as sqrt{ a**2 + (b / (p*beta*sinTheta**1.5))**2 }
121 @param z0Resolution_V0 List of two parameters, (a [cm], b [cm/(GeV/c)]),
122 defining z0 best resolution as sqrt{ a**2 + (b / (p*beta*sinTheta**2.5))**2 }
123 @param d0MomThr_V0 d0 best resolution is kept constant below this momentum
124 @param z0MomThr_V0 z0 best resolution is kept constant below this momentum
125 @param scaleFactors_RD List of five constants to be multiplied to each of helix errors (for tracks with a PXD hit)
126 @param scaleFactorsNoPXD_RD List of five constants to be multiplied to each of helix errors (for tracks without a PXD hit)
127 @param d0Resolution_RD List of two parameters, (a [cm], b [cm/(GeV/c)]),
128 defining d0 best resolution as sqrt{ a**2 + (b / (p*beta*sinTheta**1.5))**2 }
129 @param z0Resolution_RD List of two parameters, (a [cm], b [cm/(GeV/c)]),
130 defining z0 best resolution as sqrt{ a**2 + (b / (p*beta*sinTheta**2.5))**2 }
131 @param d0MomThr_RD d0 best resolution is kept constant below this momentum
132 @param z0MomThr_RD z0 best resolution is kept constant below this momentum
133
134 '''
135 from basf2 import register_module
136 # Load K_S0 from V0 and apply helix error correction to V0 daughters
137 ma.fillParticleList('K_S0:V0 -> pi+ pi-', '', True, path=path)
138 scaler_V0 = register_module("HelixErrorScaler")
139 scaler_V0.set_name('ScaleError_' + 'K_S0:V0')
140 scaler_V0.param('inputListName', 'K_S0:V0')
141 scaler_V0.param('outputListName', 'K_S0:V0_scaled')
142 scaler_V0.param('scaleFactors_PXD', scaleFactors_V0)
143 scaler_V0.param('scaleFactors_noPXD', scaleFactorsNoPXD_V0)
144 scaler_V0.param('d0ResolutionParameters', d0Resolution_V0)
145 scaler_V0.param('z0ResolutionParameters', z0Resolution_V0)
146 scaler_V0.param('d0MomentumThreshold', d0MomThr_V0)
147 scaler_V0.param('z0MomentumThreshold', z0MomThr_V0)
148 path.add_module(scaler_V0)
149
150 # Perform vertex fit and apply tighter mass window
151 if fitter == 'TreeFit':
152 vertex.treeFit('K_S0:V0_scaled', conf_level=0.0, path=path)
153 elif fitter == 'KFit':
154 vertex.kFit('K_S0:V0_scaled', conf_level=0.0, path=path)
155 elif fitter == 'Rave':
156 vertex.raveFit('K_S0:V0_scaled', conf_level=0.0, path=path, silence_warning=True)
157 else:
158 B2ERROR("Valid fitter options for Kshorts are 'TreeFit', 'KFit', and 'Rave'. However, the latter is not recommended.")
159 ma.applyCuts('K_S0:V0_scaled', '0.450 < M < 0.550', path=path)
160
161 # Reconstruct a second list
162 stdPi('all', path=path)
163 ma.scaleError('pi+:scaled', 'pi+:all',
164 scaleFactors=scaleFactors_RD,
165 scaleFactorsNoPXD=scaleFactorsNoPXD_RD,
166 d0Resolution=d0Resolution_RD,
167 z0Resolution=z0Resolution_RD,
168 d0MomThr=d0MomThr_RD,
169 z0MomThr=z0MomThr_RD,
170 path=path)
171
172 ma.reconstructDecay('K_S0:RD_scaled -> pi+:scaled pi-:scaled', '0.3 < M < 0.7', 1, True, path=path)
173 # Again perform vertex fit and apply tighter mass window
174 if fitter == 'TreeFit':
175 vertex.treeFit('K_S0:RD_scaled', conf_level=0.0, path=path)
176 elif fitter == 'KFit':
177 vertex.kFit('K_S0:RD_scaled', conf_level=0.0, path=path)
178 elif fitter == 'Rave':
179 vertex.raveFit('K_S0:RD_scaled', conf_level=0.0, path=path, silence_warning=True)
180 ma.applyCuts('K_S0:RD_scaled', '0.450 < M < 0.550', path=path)
181 # Create merged list based on provided priority
182 ma.mergeListsWithBestDuplicate('K_S0:scaled', ['K_S0:V0_scaled', 'K_S0:RD_scaled'],
183 variable='particleSource', preferLowest=prioritiseV0, path=path)
184
185
186def stdLambdas(prioritiseV0=True, fitter='TreeFit', path=None, updateAllDaughters=False, writeOut=False):
187 """
188 Load a combined list of the Lambda list from V0 objects merged with
189 a list of particles combined using the analysis ParticleCombiner module.
190
191 The ParticleList is named ``Lambda0:merged``. A vertex fit is performed and only
192 candidates with an invariant mass in the range :math:`1.10 < M < 1.13~GeV` after the vertex fit,
193 and for which the vertex fit did not fail, are kept.
194
195 The vertex fitter can be selected among ``TreeFit``, ``KFit``, and ``Rave``.
196
197 Parameters:
198 prioritiseV0 (bool): should the V0 mdst objects be prioritised when merging?
199 fitter (str): vertex fitter name, valid options are ``TreeFit``, ``KFit``, and ``Rave``.
200 path (basf2.Path): the path to load the modules
201 updateAllDaughters (bool): see the ``updateAllDaughters`` parameter of `vertex.treeFit`
202 or the ``daughtersUpdate`` parameter of `vertex.kFit` / `vertex.raveFit`.
203
204 .. warning:: The momenta of the daughters are updated only if ``updateAllDaughters`` is set
205 to ``True`` (i.e. **not** by default). Some variables, e.g. `daughterAngle`, will only
206 return meaningful results if the daughters momenta are updated.
207
208 This happens because variables like `daughterAngle` assume the direction of the
209 daughers momenta *at the Lambda vertex* to be provided, while non-updated daughters
210 will provide their momenta direction at the point-of-closest-approach (POCA) to the
211 beam axis.
212
213 writeOut (bool): whether RootOutput module should save the created ParticleList
214 """
215 # Fill one list from V0
216 ma.fillParticleList('Lambda0:V0_ToFit -> p+ pi-', '', writeOut=writeOut, path=path)
217 # Perform vertex fit and apply tighter mass window
218 if fitter == 'TreeFit':
219 vertex.treeFit('Lambda0:V0_ToFit', conf_level=0.0, path=path, updateAllDaughters=updateAllDaughters)
220 elif fitter == 'KFit':
221 vertex.kFit('Lambda0:V0_ToFit', conf_level=0.0, path=path, daughtersUpdate=updateAllDaughters)
222 elif fitter == 'Rave':
223 vertex.raveFit('Lambda0:V0_ToFit', conf_level=0.0, path=path, silence_warning=True, daughtersUpdate=updateAllDaughters)
224 else:
225 B2ERROR("Valid fitter options for Lambdas are 'TreeFit', 'KFit', and 'Rave'. However, the latter is not recommended.")
226 ma.applyCuts('Lambda0:V0_ToFit', '1.10 < M < 1.13', path=path)
227 # Find V0 duplicate with better vertex fit quality
228 ma.markDuplicate('Lambda0:V0_ToFit', False, path=path)
229 ma.applyCuts('Lambda0:V0_ToFit', 'extraInfo(highQualityVertex)', path=path)
230 # Reconstruct a second list
231 stdPi('all', path=path, writeOut=writeOut) # no quality cuts
232 stdPr('all', path=path, writeOut=writeOut) # no quality cuts
233 ma.reconstructDecay('Lambda0:RD -> p+:all pi-:all', '0.9 < M < 1.3', 1, writeOut=writeOut, path=path)
234 # Again perform vertex fit and apply tighter mass window
235 if fitter == 'TreeFit':
236 vertex.treeFit('Lambda0:RD', conf_level=0.0, path=path, updateAllDaughters=updateAllDaughters)
237 elif fitter == 'KFit':
238 vertex.kFit('Lambda0:RD', conf_level=0.0, path=path, daughtersUpdate=updateAllDaughters)
239 elif fitter == 'Rave':
240 vertex.raveFit('Lambda0:RD', conf_level=0.0, path=path, silence_warning=True, daughtersUpdate=updateAllDaughters)
241 ma.applyCuts('Lambda0:RD', '1.10 < M < 1.13', path=path)
242 # Find RD duplicate with better vertex fit quality
243 ma.markDuplicate('Lambda0:RD', False, path=path)
244 ma.applyCuts('Lambda0:RD', 'extraInfo(highQualityVertex)', path=path)
245 ma.mergeListsWithBestDuplicate('Lambda0:merged', ['Lambda0:V0_ToFit', 'Lambda0:RD'],
246 variable='particleSource', preferLowest=prioritiseV0, path=path)
def isB2BII()
Definition: b2bii.py:14
def raveFit(list_name, conf_level, fit_type='vertex', decay_string='', constraint='', daughtersUpdate=False, path=None, silence_warning=False)
Definition: vertex.py:168
def kFit(list_name, conf_level, fit_type='vertex', constraint='', daughtersUpdate=False, decay_string='', massConstraint=[], recoilMass=0, smearing=0, path=None)
Definition: vertex.py:126
def treeFit(list_name, conf_level=0.001, massConstraint=[], ipConstraint=False, updateAllDaughters=False, massConstraintDecayString='', massConstraintMassValues=[], customOriginConstraint=False, customOriginVertex=[0.001, 0, 0.0116], customOriginCovariance=[0.0048, 0, 0, 0, 0.003567, 0, 0, 0, 0.0400], originDimension=3, treatAsInvisible='', ignoreFromVertexFit='', path=None)
Definition: vertex.py:237