Belle II Software  release-06-00-14
quarkonium.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 
11 
12 """ Skim list building functions for quarkonium analyses: bottomonium, charmonium, resonance """
13 
14 import modularAnalysis as ma
15 from skim import BaseSkim, fancy_skim_header
16 from stdCharged import stdE, stdMu
17 from stdPhotons import stdPhotons
18 from stdV0s import stdLambdas
19 from variables import variables as v
20 
21 __liaison__ = "Sen Jia <jiasen@buaa.edu.cn>"
22 _VALIDATION_SAMPLE = "mdst14.root"
23 
24 
25 @fancy_skim_header
27  """
28  Reconstructed decay modes:
29 
30  * ``eta_b -> gamma gamma``
31 
32  Selection criteria:
33 
34  * ``2 std photon with E > 3.5 GeV``
35  * ``7 < M(eta_b) < 10 GeV/c^2``
36  * ``foxWolframR2 < 0.995``
37  """
38 
39  __authors__ = ["Stefano Spataro", "Sen Jia"]
40  __description__ = ""
41  __contact__ = __liaison__
42  __category__ = "physics, quarkonium"
43 
44  def load_standard_lists(self, path):
45  stdPhotons("loose", path=path, loadPhotonBeamBackgroundMVA=False)
46 
47  def build_lists(self, path):
48  # create and fill hard photon
49  ma.fillParticleList(decayString="pi+:BottomoniumEtab_eventshape", cut="pt > 0.1", path=path)
50  ma.fillParticleList(decayString="gamma:BottomoniumEtab_eventshape", cut="E > 0.1", path=path,
51  loadPhotonBeamBackgroundMVA=False)
52 
53  ma.buildEventShape(inputListNames=["pi+:BottomoniumEtab_eventshape", "gamma:BottomoniumEtab_eventshape"],
54  allMoments=False,
55  foxWolfram=True,
56  harmonicMoments=False,
57  cleoCones=False,
58  thrust=False,
59  collisionAxis=False,
60  jets=False,
61  sphericity=False,
62  checkForDuplicates=False,
63  path=path)
64 
65  ma.cutAndCopyList("gamma:hard", "gamma:loose", "E>3.5", path=path)
66  ma.applyCuts("gamma:hard", "foxWolframR2 < 0.995", path=path)
67 
68  # the requirement of 7 < M(eta_b) < 10 GeV/c2
69  Etabcuts = "M > 7 and M < 10"
70 
71  # eta_b candidates are reconstructed
72  Etab_Channels = ["gamma:hard gamma:hard"]
73 
74  # define the eta_b decay list
75  EtabList = []
76 
77  # reconstruct the decay eta_b -> gamma gamma
78  for chID, channel in enumerate(Etab_Channels):
79  ma.reconstructDecay("eta_b:all" + str(chID) + " -> " + channel, Etabcuts, chID, path=path)
80  EtabList.append("eta_b:all" + str(chID))
81 
82  return EtabList
83 
84 
85 @fancy_skim_header
87  """
88  Reconstructed decay modes:
89 
90  * Y(1S,2S) -> l^+ l^{-} (l = e or mu)
91 
92  Selection criteria:
93 
94  * 2 tracks with momentum ranging between ``3.5 < p < 15``
95  * At least 1 track ``p < 1.5`` or 1 std photon with ``E > 150 MeV``
96  * ``M(Y(1S,2S)) > 8 GeV/c^2``
97  * ``foxWolframR2 < 0.995``
98  """
99  __authors__ = ["Stefano Spataro", "Sen Jia"]
100  __description__ = ""
101  __contact__ = __liaison__
102  __category__ = "physics, quarkonium"
103 
104  def load_standard_lists(self, path):
105  stdPhotons("loose", path=path, loadPhotonBeamBackgroundMVA=False)
106 
107  def build_lists(self, path):
108  Ycuts = ""
109  # create and fill e/mu/pi/photon ParticleLists
110  ma.fillParticleList("mu+:BottomoniumUpsilon", "p<15 and p>3.5", path=path)
111  ma.fillParticleList("e+:BottomoniumUpsilon", "p<15 and p>3.5", path=path)
112  ma.fillParticleList("pi+:BottomoniumUpsilon", "p<1.5 and pt>0.05", path=path)
113  ma.cutAndCopyList("gamma:soft", "gamma:loose", "E>0.15", path=path)
114 
115  # Y(1S,2S) are reconstructed with e^+ e^- or mu^+ mu^-
116  ma.reconstructDecay("Upsilon:ee -> e+:BottomoniumUpsilon e-:BottomoniumUpsilon", "M > 8", path=path)
117  ma.reconstructDecay("Upsilon:mumu -> mu+:BottomoniumUpsilon mu-:BottomoniumUpsilon", "M > 8", path=path)
118  ma.copyLists("Upsilon:all", ["Upsilon:ee", "Upsilon:mumu"], path=path)
119 
120  # require foxWolframR2 < 0.995
121  ma.fillParticleList(decayString="pi+:BottomoniumUpsilon_eventshape", cut="pt > 0.1", path=path)
122  ma.fillParticleList(decayString="gamma:BottomoniumUpsilon_eventshape", cut="E > 0.1", path=path,
123  loadPhotonBeamBackgroundMVA=False)
124 
125  ma.buildEventShape(inputListNames=["pi+:BottomoniumUpsilon_eventshape", "gamma:BottomoniumUpsilon_eventshape"],
126  allMoments=False,
127  foxWolfram=True,
128  harmonicMoments=False,
129  cleoCones=False,
130  thrust=False,
131  collisionAxis=False,
132  jets=False,
133  sphericity=False,
134  checkForDuplicates=False,
135  path=path)
136 
137  ma.applyCuts("Upsilon:all", "foxWolframR2 < 0.995", path=path)
138 
139  # Y(1S,2S) with pi+ or photon are reconstructed
140  Upsilon_Channels = ["Upsilon:all pi+:BottomoniumUpsilon",
141  "Upsilon:all gamma:soft"]
142 
143  # define the Y(1S,2S) decay channel list
144  UpsilonList = []
145 
146  # reconstruct the decay channel
147  for chID, channel in enumerate(Upsilon_Channels):
148  ma.reconstructDecay("junction:all" + str(chID) + " -> " + channel, Ycuts, chID, path=path, allowChargeViolation=True)
149  UpsilonList.append("junction:all" + str(chID))
150 
151  # reture the list
152  return UpsilonList
153 
154  # *two* sets of validation scripts defined.
155 
156 
157 @fancy_skim_header
159  """
160  Reconstructed decay modes:
161 
162  * J/psi -> l^+ l^- (l = e or mu)
163  * psi(2S) -> l^+ l^- (l = e or mu)
164 
165  Selection criteria:
166 
167  * 2 tracks with electronID > 0.1 or muonID > 0.1 and 2.7 < M < 4.
168  Track-quality requirements are not applied.
169  """
170  __authors__ = ["Kirill Chilikin"]
171  __description__ = "Selection of J/psi and psi(2S) via leptonic decays."
172  __contact__ = __liaison__
173  __category__ = "physics, quarkonium"
174 
175  validation_sample = _VALIDATION_SAMPLE
176 
177  def load_standard_lists(self, path):
178  stdE('loosepid', path=path)
179  stdMu('loosepid', path=path)
180  stdPhotons("all", path=path, loadPhotonBeamBackgroundMVA=False)
181 
182  def build_lists(self, path):
183 
184  # Mass cuts.
185  jpsi_mass_cut = '2.85 < M < 3.3'
186  psi2s_mass_cut = '3.45 < M < 3.9'
187 
188  # Electrons with bremsstrahlung correction.
189  # Use both correction algorithms as well as uncorrected electrons
190  # to allow for algorithm comparison in analysis.
191  # The recommeneded list for further reconstruction is J/psi:eebrems.
192  # The estimated ratio of efficiencies in B decays in release 5.1.5 is
193  # 1.00 (J/psi:eebrems) : 0.95 (J/psi:eebrems2) : 0.82 (J/psi:ee).
194  ma.correctBremsBelle('e+:brems', 'e+:loosepid', 'gamma:all',
195  angleThreshold=0.05,
196  path=path)
197  ma.correctBrems('e+:brems2', 'e+:loosepid', 'gamma:all', path=path)
198 
199  # Reconstruct J/psi or psi(2S).
200  ma.reconstructDecay('J/psi:ee -> e+:loosepid e-:loosepid',
201  jpsi_mass_cut, path=path)
202  ma.reconstructDecay('psi(2S):ee -> e+:loosepid e-:loosepid',
203  psi2s_mass_cut, path=path)
204 
205  ma.reconstructDecay('J/psi:eebrems -> e+:brems e-:brems',
206  jpsi_mass_cut, path=path)
207  ma.reconstructDecay('psi(2S):eebrems -> e+:brems e-:brems',
208  psi2s_mass_cut, path=path)
209 
210  ma.reconstructDecay('J/psi:eebrems2 -> e+:brems2 e-:brems2',
211  jpsi_mass_cut, path=path)
212  ma.reconstructDecay('psi(2S):eebrems2 -> e+:brems2 e-:brems2',
213  psi2s_mass_cut, path=path)
214 
215  ma.reconstructDecay('J/psi:mumu -> mu+:loosepid mu-:loosepid',
216  jpsi_mass_cut, path=path)
217  ma.reconstructDecay('psi(2S):mumu -> mu+:loosepid mu-:loosepid',
218  psi2s_mass_cut, path=path)
219 
220  # Return the lists.
221  return ['J/psi:ee', 'psi(2S):ee',
222  'J/psi:eebrems', 'psi(2S):eebrems',
223  'J/psi:eebrems2', 'psi(2S):eebrems2',
224  'J/psi:mumu', 'psi(2S):mumu']
225 
226  def validation_histograms(self, path):
227  # NOTE: the validation package is not part of the light releases, so this import
228  # must be made here rather than at the top of the file.
229  from validation_tools.metadata import create_validation_histograms
230 
231  # [Y(3S) -> pi+pi- [Y(1S,2S) -> mu+mu-]] decay
232  ma.reconstructDecay('J/psi:mumu_test -> mu+:loosepid mu-:loosepid', '', path=path)
233  ma.reconstructDecay('J/psi:ee_test -> e+:loosepid e-:loosepid', '', path=path)
234  ma.copyList('J/psi:ll', 'J/psi:mumu_test', path=path)
235  ma.copyList('J/psi:ll', 'J/psi:ee_test', path=path)
236 
237  # Print histograms.
238  create_validation_histograms(
239  rootfile=f'{self}_Validation.root',
240  particlelist='J/psi:ll',
241  variables_1d=[(
242  'InvM', 65, 2.7, 4.0,
243  'J/#psi mass',
244  __liaison__,
245  'J/psi mass',
246  'J/psi peak is seen.',
247  'M [GeV/c^{2}]', 'Events / (20 MeV/c^{2})',
248  'shifter'
249  )],
250  path=path
251  )
252 
253 
254 @fancy_skim_header
256  """
257  Reconstructed decay
258  * :math:`\\Lambda \\to p \\pi^-` (and charge conjugate)
259 
260  Selection criteria:
261  * proton
262  ``protonID > 0.1``
263  * Lambda:
264  ``cosAngleBetweenMomentumAndVertexVector > 0.99``
265  ``flightDistance/flightDistanceErr > 3.``
266  * ``0.6 < p,proton/p,Lambda < 1.0 GeV/c``
267 
268  """
269  __authors__ = ["Bianca Scavino"]
270  __description__ = "Inclusive Lambda skim"
271  __contact__ = __liaison__
272  __category__ = "physics, quarkonium"
273 
274  def load_standard_lists(self, path):
275  stdLambdas(path=path)
276 
277  def build_lists(self, path):
278 
279  # Add useful alias
280  v.addAlias("protonID_proton", "daughter(0, protonID)")
281  v.addAlias("momRatio_protonLambda", "formula(daughter(0, p)/p)")
282  v.addAlias('flightSignificance', 'formula(flightDistance/flightDistanceErr)')
283 
284  # Apply selection to Lambdas
285  ma.applyCuts("Lambda0:merged", "cosAngleBetweenMomentumAndVertexVector > 0.99", path=path)
286  ma.applyCuts("Lambda0:merged", "0.6 < momRatio_protonLambda < 1.", path=path)
287  ma.applyCuts("Lambda0:merged", "flightSignificance > 3.", path=path)
288  ma.applyCuts("Lambda0:merged", "protonID_proton > 0.1", path=path)
289 
290  # Return the lists.
291  return ["Lambda0:merged"]
def build_lists(self, path)
Definition: quarkonium.py:107
def load_standard_lists(self, path)
Definition: quarkonium.py:104
def build_lists(self, path)
Definition: quarkonium.py:182
def validation_histograms(self, path)
Definition: quarkonium.py:226
def load_standard_lists(self, path)
Definition: quarkonium.py:177
def build_lists(self, path)
Definition: quarkonium.py:277
def load_standard_lists(self, path)
Definition: quarkonium.py:274