Belle II Software  release-05-01-25
semileptonic.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 """(Semi-)Leptonic Working Group Skim list building functions for semi-leptonic analyses.
5 """
6 
7 __authors__ = [
8  "Racha Cheaib",
9  "Hannah Wakeling",
10  "Phil Grace"
11 ]
12 
13 import modularAnalysis as ma
14 from skim.standardlists.charm import (loadKForBtoHadrons, loadPiForBtoHadrons,
15  loadStdD0, loadStdDplus, loadStdDstar0,
16  loadStdDstarPlus, loadPiSkimHighEff,
17  loadKSkimHighEff, loadSlowPi,
18  loadSkimHighEffD0_Kpi, loadSkimHighEffDstarPlus_D0pi_Kpi,
19  loadSkimHighEffD0_Kpipipi, loadSkimHighEffDstarPlus_D0pi_Kpipipi,
20  loadStdD0_eff20_Kpipi0, loadStdDstarPlus_D0pi_Kpipi0_eff20)
21 from skim.standardlists.lightmesons import loadStdPi0ForBToHadrons
22 from skimExpertFunctions import BaseSkim, fancy_skim_header
23 from stdCharged import stdE, stdK, stdMu, stdPi
24 from stdPhotons import stdPhotons
25 from stdPi0s import stdPi0s
26 from stdV0s import stdKshorts
27 from variables import variables as vm
28 
29 __liaison__ = "Shanette De La Motte <shanette.delamotte@adelaide.edu.au>"
30 
31 
32 @fancy_skim_header
34  """
35  Reconstructed decay modes:
36 
37  * :math:`B^0 \\to \\pi^- e^+`
38  * :math:`B^0 \\to \\pi^- \\mu^+`
39 
40  Event-level cuts:
41 
42  * :math:`\\text{foxWolframR2} > 0.5` constructed using tracks with
43  :math:`p_T>0.1\\,\\text{GeV}` and clusters with :math:`E>0.1\\,\\text{GeV}`.
44  * :math:`n_{\\text{tracks}} > 4`
45 
46  Cuts on electrons:
47 
48  * :math:`\\text{electronID} > 0.5`
49  * :math:`p > 1.5\\,\\text{GeV}` in CMS frame
50 
51  Cuts on muons:
52 
53  * :math:`\\text{muonID} > 0.5`
54  * :math:`p > 1.5\\,\\text{GeV}` in CMS frame
55 
56  Cuts on pions:
57 
58  * :math:`\\text{pionID}>0.5`
59  * :math:`\\text{muonID}<0.2`
60  * :math:`0.060\\,\\text{GeV}<p<0.220\\,\\text{GeV}` in CMS frame
61 
62  Cuts on partially reconstructed :math:`B` mesons:
63 
64  * :math:`\\cos\\theta_{\\ell,\\,\\pi}<0` in CMS frame.
65  """
66 
67  __authors__ = ["Lucien Cremaldi", "Racha Cheaib", "Romulus Godang"]
68  __description__ = "Skim for partial reconstruction analysis in leptonic group."
69  __contact__ = __liaison__
70  __category__ = "physics, semileptonic"
71 
72  def load_standard_lists(self, path):
73  stdE("all", path=path)
74  stdMu("all", path=path)
75  stdPi("all", path=path)
76 
77  def build_lists(self, path):
78  ma.fillParticleList(decayString="pi+:PRSL_eventshape",
79  cut="pt> 0.1", path=path)
80  ma.fillParticleList(decayString="gamma:PRSL_eventshape",
81  cut="E > 0.1", path=path)
82 
83  ma.buildEventShape(inputListNames=["pi+:PRSL_eventshape", "gamma:PRSL_eventshape"],
84  allMoments=False,
85  foxWolfram=True,
86  harmonicMoments=False,
87  cleoCones=False,
88  thrust=False,
89  collisionAxis=False,
90  jets=False,
91  sphericity=False,
92  checkForDuplicates=False,
93  path=path)
94 
95  path = self.skim_event_cuts("foxWolframR2<0.5 and nTracks>4", path=path)
96 
97  ma.cutAndCopyList("e+:PRSemileptonic_1", "e+:all",
98  "useCMSFrame(p) > 1.50 and electronID > 0.5", path=path)
99  ma.cutAndCopyList("mu+:PRSemileptonic_1", "mu+:all",
100  "useCMSFrame(p) > 1.50 and muonID > 0.5", path=path)
101  ma.cutAndCopyList("pi-:PRSemileptonic_1", "pi-:all",
102  "pionID>0.5 and muonID<0.2 and 0.060<useCMSFrame(p)<0.220", path=path)
103 
104  ma.cutAndCopyList("e+:PRSemileptonic_2", "e+:all",
105  "0.600 < useCMSFrame(p) <= 1.50 and electronID > 0.5", path=path)
106  ma.cutAndCopyList("mu+:PRSemileptonic_2", "mu+:all",
107  "0.350 < useCMSFrame(p) <= 1.50 and muonID > 0.5", path=path)
108  ma.cutAndCopyList("pi-:PRSemileptonic_2", "pi-:all",
109  "pionID>0.5 and muonID<0.2 and 0.060<useCMSFrame(p)<0.160", path=path)
110 
111  ma.reconstructDecay("B0:PRSemileptonic_1 -> pi-:PRSemileptonic_1 e+:PRSemileptonic_1",
112  "useCMSFrame(cos(daughterAngle(0,1)))<0.00", 1, path=path)
113  ma.reconstructDecay("B0:PRSemileptonic_2 -> pi-:PRSemileptonic_1 mu+:PRSemileptonic_1",
114  "useCMSFrame(cos(daughterAngle(0,1)))<0.00", 2, path=path)
115  ma.reconstructDecay("B0:PRSemileptonic_3 -> pi-:PRSemileptonic_2 e+:PRSemileptonic_2",
116  "useCMSFrame(cos(daughterAngle(0,1)))<1.00", 3, path=path)
117  ma.reconstructDecay("B0:PRSemileptonic_4 -> pi-:PRSemileptonic_2 mu+:PRSemileptonic_2",
118  "useCMSFrame(cos(daughterAngle(0,1)))<1.00", 4, path=path)
119 
120  self.SkimLists = ["B0:PRSemileptonic_1", "B0:PRSemileptonic_2"]
121 
122  def validation_histograms(self, path):
123  # NOTE: the validation package is not part of the light releases, so this import
124  # must be made here rather than at the top of the file.
125  from validation_tools.metadata import create_validation_histograms
126 
127  ma.cutAndCopyLists("B0:PRSemileptonic_semileptonic",
128  ["B0:PRSemileptonic_1", "B0:PRSemileptonic_2"], "", path=path)
129 
130  ma.buildRestOfEvent("B0:PRSemileptonic_semileptonic", path=path)
131  ma.appendROEMask("B0:PRSemileptonic_semileptonic", "basic",
132  "pt>0.05 and -2<dr<2 and -4.0<dz<4.0",
133  "E>0.05",
134  path=path)
135  ma.buildContinuumSuppression("B0:PRSemileptonic_semileptonic", "basic", path=path)
136 
137  vm.addAlias("d0_p", "daughter(0, p)")
138  vm.addAlias("d1_p", "daughter(1, p)")
139  vm.addAlias("MissM2", "weMissM2(basic,0)")
140 
141  histogramFilename = f"{self}_Validation.root"
142  email = "Phil Grace <philip.grace@adelaide.edu.au>"
143 
144  create_validation_histograms(
145  rootfile=histogramFilename,
146  particlelist="B0:PRSemileptonic",
147  variables_1d=[
148  ("Mbc", 100, 4.0, 5.3, "Mbc", email, "", ""),
149  ("d0_p", 100, 0, 5.2, "Signal-side pion momentum", email, "", ""),
150  ("d1_p", 100, 0, 5.2, "Signal-side lepton momentum", email, "", ""),
151  ("MissM2", 100, -5, 5, "Missing mass squared", email, "", "")
152  ],
153  variables_2d=[("deltaE", 100, -5, 5, "Mbc", 100, 4.0, 5.3, "Mbc vs deltaE", email, "", "")],
154  path=path)
155 
156 
157 @fancy_skim_header
159  """
160  Cuts applied:
161 
162  * :math:`p_{\\ell} > 0.35\\,\\text{GeV}`
163  * :math:`5.24 < M_{\\text{bc}} < 5.29`
164  * :math:`|\\Delta E | < 0.5`
165  * :math:`n_{\\text{tracks}} > 4`
166 
167  Reconstructed decays:
168 
169  * :math:`B^+ \\to \\overline{D}^{0} e^+`
170  * :math:`B^+ \\to \\overline{D}^{0} \\mu^+`
171  * :math:`B^+ \\to \\overline{D}^{*0} e^+`
172  * :math:`B^+ \\to \\overline{D}^{*0} \\mu^+`
173  * :math:`B^0 \\to D^{-} e^+`
174  * :math:`B^0 \\to D^{-} \\mu^+`
175  * :math:`B^0 \\to D^{*-} e^+`
176  * :math:`B^0 \\to D^{*-} \\mu^+`
177  """
178 
179  __authors__ = ["Phillip Urquijo", "Racha Cheaib"]
180  __description__ = (
181  "Skim for semileptonic decays, :math:`B` decays "
182  "(:math:`B \\to D \\ell\\nu`, where :math:`\\ell=e,\\mu`)"
183  )
184  __contact__ = __liaison__
185  __category__ = "physics, semileptonic"
186 
187  def load_standard_lists(self, path):
188  stdE("all", path=path)
189  stdK("all", path=path)
190  stdMu("all", path=path)
191  stdPi("all", path=path)
192  stdPi("loose", path=path)
193  stdPhotons("loose", path=path)
194  stdPi0s("eff40_Jan2020", path=path)
195  stdKshorts(path=path)
196  loadStdPi0ForBToHadrons(path=path)
197  loadPiForBtoHadrons(path=path)
198  loadKForBtoHadrons(path=path)
199  loadStdD0(path=path)
200  loadStdDstar0(path=path)
201  loadStdDplus(path=path)
202  loadStdDstarPlus(path=path)
203 
204  def build_lists(self, path):
205  ma.cutAndCopyList("e+:SLUntagged", "e+:all", "p>0.35", True, path=path)
206  ma.cutAndCopyList("mu+:SLUntagged", "mu+:all", "p>0.35", True, path=path)
207  Bcuts = "5.24 < Mbc < 5.29 and abs(deltaE) < 0.5"
208 
209  BplusChannels = ["anti-D0:all e+:SLUntagged",
210  "anti-D0:all mu+:SLUntagged",
211  "anti-D*0:all e+:SLUntagged",
212  "anti-D*0:all mu+:SLUntagged"
213  ]
214 
215  B0Channels = ["D-:all e+:SLUntagged",
216  "D-:all mu+:SLUntagged",
217  "D*-:all e+:SLUntagged",
218  "D*-:all mu+:SLUntagged"
219  ]
220 
221  bplusList = []
222  for chID, channel in enumerate(BplusChannels):
223  ma.reconstructDecay(f"B+:SLUntagged_{chID} -> {channel}", Bcuts, chID, path=path)
224  ma.applyCuts(f"B+:SLUntagged_{chID}", "nTracks>4", path=path)
225  bplusList.append(f"B+:SLUntagged_{chID}")
226 
227  b0List = []
228  for chID, channel in enumerate(B0Channels):
229  ma.reconstructDecay(f"B0:SLUntagged_{chID} -> {channel}", Bcuts, chID, path=path)
230  ma.applyCuts(f"B0:SLUntagged_{chID}", "nTracks>4", path=path)
231  b0List.append(f"B0:SLUntagged_{chID}")
232 
233  self.SkimLists = b0List + bplusList
234 
235  def validation_histograms(self, path):
236  # NOTE: the validation package is not part of the light releases, so this import
237  # must be made here rather than at the top of the file.
238  from validation_tools.metadata import create_validation_histograms
239 
240  ma.cutAndCopyLists("B+:SLUntagged",
241  ["B+:SLUntagged_0", "B+:SLUntagged_1", "B+:SLUntagged_2", "B+:SLUntagged_3"],
242  "", path=path)
243 
244  ma.buildRestOfEvent("B+:SLUntagged", path=path)
245  ma.appendROEMask("B+:SLUntagged", "basic",
246  "pt>0.05 and -2<dr<2 and -4.0<dz<4.0",
247  "E>0.05",
248  path=path)
249  ma.buildContinuumSuppression("B+:SLUntagged", "basic", path=path)
250 
251  vm.addAlias("d1_p", "daughter(1,p)")
252  vm.addAlias("MissM2", "weMissM2(basic,0)")
253 
254  histogramFilename = f"{self}_Validation.root"
255  myEmail = "Phil Grace <philip.grace@adelaide.edu.au>"
256 
257  create_validation_histograms(
258  rootfile=histogramFilename,
259  particlelist="B+:SLUntagged",
260  variables_1d=[
261  ("cosThetaBetweenParticleAndNominalB", 100, -6.0, 4.0, "cosThetaBY", myEmail, "", ""),
262  ("Mbc", 100, 4.0, 5.3, "Mbc", myEmail, "", ""),
263  ("d1_p", 100, 0, 5.2, "Signal-side lepton momentum", myEmail, "", ""),
264  ("MissM2", 100, -5, 5, "Missing mass squared", myEmail, "", "")
265  ],
266  variables_2d=[("deltaE", 100, -5, 5, "Mbc", 100, 4.0, 5.3, "Mbc vs deltaE", myEmail, "", "")],
267  path=path)
268 
269 
270 @fancy_skim_header
272  """
273  Cuts applied:
274 
275  * ``SkimHighEff tracks thetaInCDCAcceptance AND abs(dr) < 2 AND abs(dz) < 5 AND PID>=0.01``
276  * ``slowPi tracks thetaInCDCAcceptance AND abs(dr) < 2 AND abs(dz) < 5 AND useCMSFrame(p) < 0.4``
277  * :math:`2.5 > p_{\\ell} > 1.1\\,\\text{GeV}`
278  * ``lepton with abs(d0) < 0.5 AND abs(z0) < 2 AND thetaInCDCAcceptance AND ID >= 0.95 AND 1.1 < useCMSFrame(p) < 2.5``
279  * ``1.8 < M_D0 < 2.0``
280  * ``DM_Dstar_D < 0.16``
281 
282  Reconstructed decays:
283 
284  * :math:`B^{0}\\to D^{*-} (D^{0} \\to K^+ \\pi^-) e^+`,
285  * :math:`B^{0}\\to D^{*-} (D^{0} \\to K^+ \\pi^- \\pi^0) e^+`,
286  * :math:`B^{0}\\to D^{*-} (D^{0} \\to K^+ \\pi^- \\pi^- \\pi^+) e^+`,
287  * :math:`B^{0}\\to D^{*-} (D^{0} \\to K^+ \\pi^-) mu^+`,
288  * :math:`B^{0}\\to D^{*-} (D^{0} \\to K^+ \\pi^- \\pi^0) mu^+`,
289  * :math:`B^{0}\\to D^{*-} (D^{0} \\to K^+ \\pi^- \\pi^- \\pi^+) mu^+`,
290 
291  Note:
292 
293  This skim uses `skim.standardlists.charm.loadSkimHighEffD0_Kpi`,
294  `skim.standardlists.charm.loadSkimHighEffD0_Kpipipi` and
295  `skim.standardlists.charm.loadStdD0_eff20_Kpipi0`, where :math:`D^0`
296  channel is defined.
297  `skim.standardlists.charm.loadSkimHighEffDstarPlus_D0pi_Kpi`,
298  `skim.standardlists.charm.loadSkimHighEffDstarPlus_D0pi_Kpipipi`,
299  `skim.standardlists.charm.loadStdDstarPlus_D0pi_Kpipi0_eff20`,where the
300  :math:`D^{*-}` channel is defined.
301 
302  The pion and kaon lists used to define :math:`D^0` and :math:`D^{*-}` are:
303  `skim.standardlists.charm.loadPiSkimHighEff`, `skim.standardlists.charm.loadKSkimHighEff` and
304  `skim.standardlists.charm.loadSlowPi`
305  """
306  __authors__ = ["Bae Hanwook, Chiara La Licata"]
307  __description__ = ""
308  __contact__ = __liaison__
309  __category__ = "physics, semileptonic"
310 
311  ApplyHLTHadronCut = True
312  produce_on_tau_samples = False # retention is very close to zero on taupair
313 
314  def load_standard_lists(self, path):
315  stdE("all", path=path)
316  stdMu("all", path=path)
317  stdPi("all", path=path)
318  stdK("all", path=path)
319  stdPi0s("eff20_Jan2020", path=path)
320  loadPiSkimHighEff(path=path)
321  loadKSkimHighEff(path=path)
322  loadSlowPi(path=path)
323  loadSkimHighEffD0_Kpi(path=path)
324  loadSkimHighEffDstarPlus_D0pi_Kpi(path=path)
325  loadSkimHighEffD0_Kpipipi(path=path)
326  loadSkimHighEffDstarPlus_D0pi_Kpipipi(path=path)
327  loadStdD0_eff20_Kpipi0(path=path)
328  loadStdDstarPlus_D0pi_Kpipi0_eff20(path=path)
329 
330  def build_lists(self, path):
331 
332  ma.cutAndCopyList(
333  'e+:sig',
334  'e+:all',
335  'abs(d0) < 0.5 and abs(z0) < 2 and thetaInCDCAcceptance and electronID >= 0.95 and 1.1 < useCMSFrame(p) < 2.5 ',
336  path=path)
337  ma.cutAndCopyList(
338  'mu+:sig',
339  'mu+:all',
340  'abs(d0) < 0.5 and abs(z0) < 2 and thetaInCDCAcceptance and muonID >= 0.95 and 1.1 < useCMSFrame(p) < 2.5',
341  path=path)
342 
343  B0_channels = ["D*-:D0_Kpi_skimhigheff e+:sig",
344  "D*-:D0_Kpipi0_eff20 e+:sig",
345  "D*-:D0_Kpipipi_skimhigheff e+:sig",
346  "D*-:D0_Kpi_skimhigheff mu+:sig",
347  "D*-:D0_Kpipi0_eff20 mu+:sig",
348  "D*-:D0_Kpipipi_skimhigheff mu+:sig"]
349 
350  B0_list = []
351 
352  for chID, channel in enumerate(B0_channels):
353  ma.reconstructDecay("B0:Dstl_kpi_kpipi0_kpipipi" + str(chID) + " -> " + channel, "", chID, path=path)
354  B0_list.append("B0:Dstl_kpi_kpipi0_kpipipi" + str(chID))
355 
356  self.SkimLists = B0_list
skim.semileptonic.B0toDstarl_Kpi_Kpipi0_Kpipipi.build_lists
def build_lists(self, path)
Definition: semileptonic.py:330
skimExpertFunctions.BaseSkim.skim_event_cuts
def skim_event_cuts(self, cut, *path)
Definition: skimExpertFunctions.py:716
skim.semileptonic.PRsemileptonicUntagged.load_standard_lists
def load_standard_lists(self, path)
Definition: semileptonic.py:72
skim.semileptonic.PRsemileptonicUntagged.build_lists
def build_lists(self, path)
Definition: semileptonic.py:77
stdPhotons
Definition: stdPhotons.py:1
skim.semileptonic.SLUntagged.build_lists
def build_lists(self, path)
Definition: semileptonic.py:204
skim.semileptonic.B0toDstarl_Kpi_Kpipi0_Kpipipi.SkimLists
SkimLists
Definition: semileptonic.py:356
skim.semileptonic.SLUntagged
Definition: semileptonic.py:158
skim.semileptonic.PRsemileptonicUntagged.validation_histograms
def validation_histograms(self, path)
Definition: semileptonic.py:122
stdPi0s
Definition: stdPi0s.py:1
skimExpertFunctions.BaseSkim
Definition: skimExpertFunctions.py:504
skim.semileptonic.PRsemileptonicUntagged
Definition: semileptonic.py:33
skim.semileptonic.B0toDstarl_Kpi_Kpipi0_Kpipipi
Definition: semileptonic.py:271
skim.semileptonic.SLUntagged.SkimLists
SkimLists
Definition: semileptonic.py:233
skim.semileptonic.PRsemileptonicUntagged.SkimLists
SkimLists
Definition: semileptonic.py:120
validation_tools.metadata
Definition: metadata.py:1
skim.semileptonic.B0toDstarl_Kpi_Kpipi0_Kpipipi.load_standard_lists
def load_standard_lists(self, path)
Definition: semileptonic.py:314
skim.semileptonic.SLUntagged.validation_histograms
def validation_histograms(self, path)
Definition: semileptonic.py:235
skim.semileptonic.SLUntagged.load_standard_lists
def load_standard_lists(self, path)
Definition: semileptonic.py:187