Belle II Software release-09-00-07
stdV0s.py
1#!/usr/bin/env python3
2
3
10
11from basf2 import B2ERROR
12import modularAnalysis as ma
13from stdCharged import stdPi, stdPr
14import vertex
15
16
17def stdKshorts(
18 prioritiseV0=True,
19 fitter="TreeFit",
20 path=None,
21 updateAllDaughters=False,
22 writeOut=False,
23 addSuffix=False,
24):
25 """
26 Load a combined list of the Kshorts list from V0 objects merged with
27 a list of particles combined using the analysis ParticleCombiner module.
28
29 The ParticleList is named ``K_S0:merged`` by default. If ``addSuffix`` is set to True,
30 then a suffix of form ``_<fitter>`` is added depending on the chosen fitter.
31 A vertex fit is performed and only candidates with an invariant mass in the
32 range :math:`0.450 < M < 0.550~GeV` after the vertex fit,
33 and for which the vertex fit did not fail, are kept.
34
35 The vertex fitter can be selected among ``TreeFit``, ``KFit``, and ``Rave``.
36
37 Parameters:
38 prioritiseV0 (bool): should the V0 mdst objects be prioritised when merging?
39 fitter (str): vertex fitter name, valid options are ``TreeFit``, ``KFit``, and ``Rave``.
40 path (basf2.Path): the path to load the modules
41 updateAllDaughters (bool): see the ``updateAllDaughters`` parameter of `vertex.treeFit`
42 or the ``daughtersUpdate`` parameter of `vertex.kFit` / `vertex.raveFit`.
43
44 .. warning:: The momenta of the daughters are updated only if ``updateAllDaughters`` is set
45 to ``True`` (i.e. **not** by default). Some variables, e.g. `daughterAngle`, will only
46 return meaningful results if the daughters momenta are updated.
47
48 This happens because variables like `daughterAngle` assume the direction of the
49 daughers momenta *at the Ks vertex* to be provided, while non-updated daughters will
50 provide their momenta direction at the point-of-closest-approach (POCA) to the beam axis.
51
52 writeOut (bool): whether RootOutput module should save the created ParticleList
53 addSuffix (bool): whether to add a suffix of form ``_<fitter>`` to the ParticleList name
54 depending on the chosen fitter
55 """
56 suffix = ""
57 if addSuffix:
58 suffix = f"_{fitter}"
59 # Fill one list from V0
60 ma.fillParticleList(
61 f"K_S0:V0_ToFit{suffix} -> pi+ pi-", "", writeOut=writeOut, path=path
62 )
63 # Perform vertex fit and apply tighter mass window
64 if fitter == "TreeFit":
66 f"K_S0:V0_ToFit{suffix}",
67 conf_level=0.0,
68 path=path,
69 updateAllDaughters=updateAllDaughters,
70 )
71 elif fitter == "KFit":
73 f"K_S0:V0_ToFit{suffix}",
74 conf_level=0.0,
75 path=path,
76 daughtersUpdate=updateAllDaughters,
77 )
78 elif fitter == "Rave":
80 f"K_S0:V0_ToFit{suffix}",
81 conf_level=0.0,
82 path=path,
83 silence_warning=True,
84 daughtersUpdate=updateAllDaughters,
85 )
86 else:
87 B2ERROR(
88 "Valid fitter options for Kshorts are 'TreeFit', 'KFit', and 'Rave'. However, the latter is not recommended."
89 )
90 ma.applyCuts(f"K_S0:V0_ToFit{suffix}", "0.450 < M < 0.550", path=path)
91 # Reconstruct a second list
92 stdPi("all", path=path, writeOut=writeOut) # no quality cuts
93 ma.reconstructDecay(
94 f"K_S0:RD{suffix} -> pi+:all pi-:all",
95 "0.3 < M < 0.7",
96 1,
97 writeOut=writeOut,
98 path=path,
99 )
100 # Again perform vertex fit and apply tighter mass window
101 if fitter == "TreeFit":
103 f"K_S0:RD{suffix}",
104 conf_level=0.0,
105 path=path,
106 updateAllDaughters=updateAllDaughters,
107 )
108 elif fitter == "KFit":
110 f"K_S0:RD{suffix}",
111 conf_level=0.0,
112 path=path,
113 daughtersUpdate=updateAllDaughters,
114 )
115 elif fitter == "Rave":
117 f"K_S0:RD{suffix}",
118 conf_level=0.0,
119 path=path,
120 silence_warning=True,
121 daughtersUpdate=updateAllDaughters,
122 )
123 ma.applyCuts(f"K_S0:RD{suffix}", "0.450 < M < 0.550", path=path)
124 # Create merged list based on provided priority
125 ma.mergeListsWithBestDuplicate(
126 f"K_S0:merged{suffix}",
127 [f"K_S0:V0_ToFit{suffix}", f"K_S0:RD{suffix}"],
128 variable="particleSource",
129 preferLowest=prioritiseV0,
130 path=path,
131 )
132
133
134def goodBelleKshort(path):
135 """
136 Load the Belle goodKshort list. Creates a ParticleList named
137 ``K_S0:legacyGoodKS``. A vertex fit is performed and only candidates that
138 satisfy the :b2:var:`goodBelleKshort` criteria, with an invariant mass in the range
139 :math:`0.468 < M < 0.528~GeV`, and for which the vertex fit did not fail, are kept
140
141 Parameters:
142 path (basf2.Path): the path to load the modules
143 """
144 ma.fillParticleList('K_S0:legacyGoodKS -> pi+ pi-', '0.3 < M < 0.7', True, path=path)
145 vertex.kFit('K_S0:legacyGoodKS', conf_level=0.0, path=path)
146 ma.applyCuts('K_S0:legacyGoodKS', '0.468 < M < 0.528 and goodBelleKshort==1', path=path)
147
148
149def scaleErrorKshorts(
150 prioritiseV0=True,
151 fitter="TreeFit",
152 scaleFactors_V0=[1.125927, 1.058803, 1.205928, 1.066734, 1.047513],
153 scaleFactorsNoPXD_V0=[1.125927, 1.058803, 1.205928, 1.066734, 1.047513],
154 d0Resolution_V0=[0.001174, 0.000779],
155 z0Resolution_V0=[0.001350, 0.000583],
156 d0MomThr_V0=0.500000,
157 z0MomThr_V0=0.00000,
158 scaleFactors_RD=[1.149631, 1.085547, 1.151704, 1.096434, 1.086659],
159 scaleFactorsNoPXD_RD=[1.149631, 1.085547, 1.151704, 1.096434, 1.086659],
160 d0Resolution_RD=[0.00115328, 0.00134704],
161 z0Resolution_RD=[0.00124327, 0.0013272],
162 d0MomThr_RD=0.500000,
163 z0MomThr_RD=0.500000,
164 addSuffix=False,
165 path=None,
166):
167 """
168 Reconstruct K_S0 applying helix error correction to K_S0 daughters given by ``modularAnalysis.scaleError``.
169 The ParticleList is named ``K_S0:scaled`` by default. If ``addSuffix`` is set to True,
170 then a suffix of form ``_<fitter>`` is added.
171
172 Considering the difference of multiple scattering through the beam pipe,
173 different parameter sets are used for K_S0 decaying outside/inside the beam pipe (``K_S0:V0/RD``).
174
175 Only for TDCPV analysis.
176
177 @param prioritiseV0 If True K_S0 from V0 object is prioritised over RD when merged.
178 @param fitter Vertex fitter option. Choose from ``TreeFit``, ``KFit`` and ``Rave``.
179 @param scaleFactors_V0 List of five constants to be multiplied to each of helix errors (for tracks with a PXD hit)
180 @param scaleFactorsNoPXD_V0 List of five constants to be multiplied to each of helix errors (for tracks without a PXD hit)
181 @param d0Resolution_V0 List of two parameters, (a [cm], b [cm/(GeV/c)]),
182 defining d0 best resolution as sqrt{ a**2 + (b / (p*beta*sinTheta**1.5))**2 }
183 @param z0Resolution_V0 List of two parameters, (a [cm], b [cm/(GeV/c)]),
184 defining z0 best resolution as sqrt{ a**2 + (b / (p*beta*sinTheta**2.5))**2 }
185 @param d0MomThr_V0 d0 best resolution is kept constant below this momentum
186 @param z0MomThr_V0 z0 best resolution is kept constant below this momentum
187 @param scaleFactors_RD List of five constants to be multiplied to each of helix errors (for tracks with a PXD hit)
188 @param scaleFactorsNoPXD_RD List of five constants to be multiplied to each of helix errors (for tracks without a PXD hit)
189 @param d0Resolution_RD List of two parameters, (a [cm], b [cm/(GeV/c)]),
190 defining d0 best resolution as sqrt{ a**2 + (b / (p*beta*sinTheta**1.5))**2 }
191 @param z0Resolution_RD List of two parameters, (a [cm], b [cm/(GeV/c)]),
192 defining z0 best resolution as sqrt{ a**2 + (b / (p*beta*sinTheta**2.5))**2 }
193 @param d0MomThr_RD d0 best resolution is kept constant below this momentum
194 @param z0MomThr_RD z0 best resolution is kept constant below this momentum
195 @param addSuffix Whether to add a suffix of form ``_<fitter>`` to the ParticleList name
196 depending on the chosen fitter
197
198 """
199 from basf2 import register_module
200
201 suffix = ""
202 if addSuffix:
203 suffix = f"_{fitter}"
204
205 # Load K_S0 from V0 and apply helix error correction to V0 daughters
206 ma.fillParticleList(f"K_S0:V0{suffix} -> pi+ pi-", "", True, path=path)
207 scaler_V0 = register_module("HelixErrorScaler")
208 scaler_V0.set_name("ScaleError_" + f"K_S0:V0{suffix}")
209 scaler_V0.param("inputListName", f"K_S0:V0{suffix}")
210 scaler_V0.param("outputListName", f"K_S0:V0_scaled{suffix}")
211 scaler_V0.param("scaleFactors_PXD", scaleFactors_V0)
212 scaler_V0.param("scaleFactors_noPXD", scaleFactorsNoPXD_V0)
213 scaler_V0.param("d0ResolutionParameters", d0Resolution_V0)
214 scaler_V0.param("z0ResolutionParameters", z0Resolution_V0)
215 scaler_V0.param("d0MomentumThreshold", d0MomThr_V0)
216 scaler_V0.param("z0MomentumThreshold", z0MomThr_V0)
217 path.add_module(scaler_V0)
218
219 # Perform vertex fit and apply tighter mass window
220 if fitter == "TreeFit":
221 vertex.treeFit(f"K_S0:V0_scaled{suffix}", conf_level=0.0, path=path)
222 elif fitter == "KFit":
223 vertex.kFit(f"K_S0:V0_scaled{suffix}", conf_level=0.0, path=path)
224 elif fitter == "Rave":
226 f"K_S0:V0_scaled{suffix}", conf_level=0.0, path=path, silence_warning=True
227 )
228 else:
229 B2ERROR(
230 "Valid fitter options for Kshorts are 'TreeFit', 'KFit', and 'Rave'. However, the latter is not recommended."
231 )
232 ma.applyCuts(f"K_S0:V0_scaled{suffix}", "0.450 < M < 0.550", path=path)
233
234 # Reconstruct a second list
235 stdPi("all", path=path)
236 ma.scaleError(
237 "pi+:scaled",
238 "pi+:all",
239 scaleFactors=scaleFactors_RD,
240 scaleFactorsNoPXD=scaleFactorsNoPXD_RD,
241 d0Resolution=d0Resolution_RD,
242 z0Resolution=z0Resolution_RD,
243 d0MomThr=d0MomThr_RD,
244 z0MomThr=z0MomThr_RD,
245 path=path,
246 )
247
248 ma.reconstructDecay(
249 f"K_S0:RD_scaled{suffix} -> pi+:scaled pi-:scaled", "0.3 < M < 0.7", 1, True, path=path
250 )
251 # Again perform vertex fit and apply tighter mass window
252 if fitter == "TreeFit":
253 vertex.treeFit(f"K_S0:RD_scaled{suffix}", conf_level=0.0, path=path)
254 elif fitter == "KFit":
255 vertex.kFit(f"K_S0:RD_scaled{suffix}", conf_level=0.0, path=path)
256 elif fitter == "Rave":
258 f"K_S0:RD_scaled{suffix}", conf_level=0.0, path=path, silence_warning=True
259 )
260 ma.applyCuts(f"K_S0:RD_scaled{suffix}", "0.450 < M < 0.550", path=path)
261 # Create merged list based on provided priority
262 ma.mergeListsWithBestDuplicate(
263 f"K_S0:scaled{suffix}",
264 [f"K_S0:V0_scaled{suffix}", f"K_S0:RD_scaled{suffix}"],
265 variable="particleSource",
266 preferLowest=prioritiseV0,
267 path=path,
268 )
269
270
271def stdLambdas(
272 prioritiseV0=True,
273 fitter="TreeFit",
274 path=None,
275 updateAllDaughters=False,
276 writeOut=False,
277 addSuffix=False,
278):
279 """
280 Load a combined list of the Lambda list from V0 objects merged with
281 a list of particles combined using the analysis ParticleCombiner module.
282
283 The ParticleList is named ``Lambda0:merged`` by default. If ``addSuffix`` is set to True,
284 then a suffix of form ``_<fitter>`` is added depending on the chosen fitter.
285 A vertex fit is performed and only candidates with an invariant mass in the
286 range :math:`1.10 < M < 1.13~GeV` after the vertex fit,
287 and for which the vertex fit did not fail, are kept.
288
289 The vertex fitter can be selected among ``TreeFit``, ``KFit``, and ``Rave``.
290
291 Parameters:
292 prioritiseV0 (bool): should the V0 mdst objects be prioritised when merging?
293 fitter (str): vertex fitter name, valid options are ``TreeFit``, ``KFit``, and ``Rave``.
294 path (basf2.Path): the path to load the modules
295 updateAllDaughters (bool): see the ``updateAllDaughters`` parameter of `vertex.treeFit`
296 or the ``daughtersUpdate`` parameter of `vertex.kFit` / `vertex.raveFit`.
297
298 .. warning:: The momenta of the daughters are updated only if ``updateAllDaughters`` is set
299 to ``True`` (i.e. **not** by default). Some variables, e.g. `daughterAngle`, will only
300 return meaningful results if the daughters momenta are updated.
301
302 This happens because variables like `daughterAngle` assume the direction of the
303 daughers momenta *at the Lambda vertex* to be provided, while non-updated daughters
304 will provide their momenta direction at the point-of-closest-approach (POCA) to the
305 beam axis.
306
307 writeOut (bool): whether RootOutput module should save the created ParticleList
308 addSuffix (bool): whether to add a suffix of form ``_<fitter>`` to the ParticleList name
309 depending on the chosen fitter
310 """
311 suffix = ""
312 if addSuffix:
313 suffix = f"_{fitter}"
314 # Fill one list from V0
315 ma.fillParticleList(
316 f"Lambda0:V0_ToFit{suffix} -> p+ pi-", "", writeOut=writeOut, path=path
317 )
318 # Perform vertex fit and apply tighter mass window
319 if fitter == "TreeFit":
321 f"Lambda0:V0_ToFit{suffix}",
322 conf_level=0.0,
323 path=path,
324 updateAllDaughters=updateAllDaughters,
325 )
326 elif fitter == "KFit":
328 f"Lambda0:V0_ToFit{suffix}",
329 conf_level=0.0,
330 path=path,
331 daughtersUpdate=updateAllDaughters,
332 )
333 elif fitter == "Rave":
335 f"Lambda0:V0_ToFit{suffix}",
336 conf_level=0.0,
337 path=path,
338 silence_warning=True,
339 daughtersUpdate=updateAllDaughters,
340 )
341 else:
342 B2ERROR(
343 "Valid fitter options for Lambdas are 'TreeFit', 'KFit', and 'Rave'. However, the latter is not recommended."
344 )
345 ma.applyCuts(f"Lambda0:V0_ToFit{suffix}", "1.10 < M < 1.13", path=path)
346 # Find V0 duplicate with better vertex fit quality
347 ma.markDuplicate(f"Lambda0:V0_ToFit{suffix}", False, path=path)
348 ma.applyCuts(f"Lambda0:V0_ToFit{suffix}", "extraInfo(highQualityVertex)", path=path)
349 # Reconstruct a second list
350 stdPi("all", path=path, writeOut=writeOut) # no quality cuts
351 stdPr("all", path=path, writeOut=writeOut) # no quality cuts
352 ma.reconstructDecay(
353 f"Lambda0:RD{suffix} -> p+:all pi-:all",
354 "0.9 < M < 1.3",
355 1,
356 writeOut=writeOut,
357 path=path,
358 )
359 # Again perform vertex fit and apply tighter mass window
360 if fitter == "TreeFit":
362 f"Lambda0:RD{suffix}",
363 conf_level=0.0,
364 path=path,
365 updateAllDaughters=updateAllDaughters,
366 )
367 elif fitter == "KFit":
369 f"Lambda0:RD{suffix}",
370 conf_level=0.0,
371 path=path,
372 daughtersUpdate=updateAllDaughters,
373 )
374 elif fitter == "Rave":
376 f"Lambda0:RD{suffix}",
377 conf_level=0.0,
378 path=path,
379 silence_warning=True,
380 daughtersUpdate=updateAllDaughters,
381 )
382 ma.applyCuts(f"Lambda0:RD{suffix}", "1.10 < M < 1.13", path=path)
383 # Find RD duplicate with better vertex fit quality
384 ma.markDuplicate(f"Lambda0:RD{suffix}", False, path=path)
385 ma.applyCuts(f"Lambda0:RD{suffix}", "extraInfo(highQualityVertex)", path=path)
386 ma.mergeListsWithBestDuplicate(
387 f"Lambda0:merged{suffix}",
388 [f"Lambda0:V0_ToFit{suffix}", f"Lambda0:RD{suffix}"],
389 variable="particleSource",
390 preferLowest=prioritiseV0,
391 path=path,
392 )
def treeFit(list_name, conf_level=0.001, massConstraint=[], ipConstraint=False, updateAllDaughters=False, 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:239
def raveFit(list_name, conf_level, fit_type='vertex', decay_string='', constraint='', daughtersUpdate=False, path=None, silence_warning=False)
Definition: vertex.py:172
def kFit(list_name, conf_level, fit_type='vertex', constraint='', daughtersUpdate=False, decay_string='', massConstraint=[], recoilMass=0, smearing=0, path=None)
Definition: vertex.py:129