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