Belle II Software  release-05-01-25
ewp.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 """
5 
6 Skim list building functions for EWP inclusive skims:
7 B->Xgamma, B->Xll, B->Xll (LFV modes)
8 
9 """
10 
11 __authors__ = [
12  "Trevor Shillington"
13 ]
14 
15 import basf2 as b2
16 import modularAnalysis as ma
17 from skimExpertFunctions import BaseSkim, fancy_skim_header
18 from stdCharged import stdE, stdMu, stdPi
19 from stdPhotons import stdPhotons
20 from variables import variables
21 
22 __liaison__ = "Trevor Shillington <trshillington@hep.physics.mcgill.ca>"
23 
24 
25 @fancy_skim_header
27  """
28  Reconstructed decay modes:
29 
30  * :math:`B^+ \\to X\\gamma` inclusive
31 
32  Event-level cuts:
33 
34  * :math:`\\text{foxWolframR2} < 0.5` constructed using tracks with
35  :math:`p_T>0.1\\,\\text{GeV}` and clusters with :math:`E>0.1\\,\\text{GeV}`.
36  * :math:`n_{\\text{tracks}} \\geq 3`
37 
38  Cuts on photons:
39 
40  * :math:`\\text{clusterE9E21}>0.9`
41  * :math:`1.4\\,\\text{GeV}<\\E_{\\gamma}<3.4\\,\\text{GeV}` in CMS frame
42  """
43 
44  __authors__ = ["Trevor Shillington"]
45  __description__ = ":math:`B\\to X\\gamma` inclusive skim."
46  __contact__ = __liaison__
47  __category__ = "physics, electroweak penguins, radiative decays"
48 
49  def load_standard_lists(self, path):
50  stdPi("all", path=path)
51  stdPhotons("all", path=path)
52  stdPhotons("loose", path=path)
53 
54  def build_lists(self, path):
55  """Build the skim list for :math:`B \\to X\\gamma` decays."""
56  # event level cuts: R2 and require a minimum number of tracks + decent photons
57  ma.fillParticleList(decayString='pi+:BtoXgamma_eventshape', cut='pt > 0.1', path=path)
58  ma.fillParticleList(decayString='gamma:BtoXgamma_eventshape', cut='E > 0.1', path=path)
59 
60  ma.buildEventShape(inputListNames=['pi+:BtoXgamma_eventshape', 'gamma:BtoXgamma_eventshape'],
61  allMoments=False,
62  foxWolfram=True,
63  harmonicMoments=False,
64  cleoCones=False,
65  thrust=False,
66  collisionAxis=False,
67  jets=False,
68  sphericity=False,
69  checkForDuplicates=False,
70  path=path)
71 
72  # Apply event cuts R2 < 0.5 and nTracks >= 3
73  path = self.skim_event_cuts('foxWolframR2 < 0.5 and nTracks >= 3', path=path)
74 
75  # Apply gamma cuts clusterE9E21 > 0.9 and 1.4 < E_gamma < 3.4 GeV (in CMS frame)
76  ma.cutAndCopyList('gamma:ewp', 'gamma:loose', 'clusterE9E21 > 0.9 and 1.4 < useCMSFrame(E) < 3.4', path=path)
77 
78  ma.reconstructDecay('B+:gamma -> gamma:ewp', '', path=path, allowChargeViolation=True)
79 
80  self.SkimLists = ['B+:gamma']
81 
82 
83 @fancy_skim_header
85  """
86  Reconstructed decay modes:
87 
88  * :math:`B^+ \\to X e^+ e^-`
89  * :math:`B^+ \\to X e^+ e^+`
90  * :math:`B^+ \\to X \\mu^+ \\mu^-`
91  * :math:`B^+ \\to X \\mu^+ \\mu^+`
92 
93 
94  Event-level cuts:
95 
96  * :math:`\\text{foxWolframR2} < 0.5` constructed using tracks with
97  :math:`p_T>0.1\\,\\text{GeV}` and clusters with :math:`E>0.1\\,\\text{GeV}`.
98  * :math:`n_{\\text{tracks}} \\geq 3`
99 
100  Cuts on electrons:
101 
102  * :math:`\\text{electronID} > 0.1`
103  * :math:`p > 0.395\\,\\text{GeV}` in lab frame
104  * :math:`dr<0.5 and abs(dz)<2`
105 
106  Cuts on muons:
107 
108  * :math:`\\text{muonID} > 0.5`
109  * :math:`p > 0.395\\,\\text{GeV}` in lab frame
110  * :math:`dr<0.5 and abs(dz)<2`
111 
112 
113  Cut on dilepton energy:
114 
115  * :math:`E_{\\ell\\ell}>1.5\\,\\text{GeV}` in CMS frame.
116  """
117 
118  __authors__ = ["Trevor Shillington"]
119  __description__ = ":math:`B\\to X\\ell\\ell` (no LFV modes) inclusive skim."
120  __contact__ = __liaison__
121  __category__ = "physics, electroweak penguins, radiative decays"
122 
123  def load_standard_lists(self, path):
124  stdE("all", path=path)
125  stdMu("all", path=path)
126  stdPi("all", path=path)
127  stdPhotons("all", path=path)
128 
129  def build_lists(self, path):
130  """Build the skim list for :math:`B \\to X\\ell\\ell` non-LFV decays."""
131 
132  # event level cuts: R2 and require a minimum number of tracks
133  ma.fillParticleList(decayString='pi+:BtoXll_eventshape', cut='pt > 0.1', path=path)
134  ma.fillParticleList(decayString='gamma:BtoXll_eventshape', cut='E > 0.1', path=path)
135 
136  ma.buildEventShape(inputListNames=['pi+:BtoXll_eventshape', 'gamma:BtoXll_eventshape'],
137  allMoments=False,
138  foxWolfram=True,
139  harmonicMoments=False,
140  cleoCones=False,
141  thrust=False,
142  collisionAxis=False,
143  jets=False,
144  sphericity=False,
145  checkForDuplicates=False,
146  path=path)
147 
148  # Apply event cuts R2 < 0.5 and nTracks >= 3
149  path = self.skim_event_cuts('foxWolframR2 < 0.5 and nTracks >= 3', path=path)
150 
151  # Apply electron cut p > 0.395 GeV, electronID > 0.1 + fairTrack
152  # Apply muon cuts p > 0.395 GeV, muonID > 0.5 + fairTrack
153  fairTrack = 'dr < 0.5 and abs(dz) < 2'
154 
155  ma.cutAndCopyList('e+:ewp', 'e+:all', 'p > 0.395 and electronID > 0.1 and ' + fairTrack, path=path)
156  ma.cutAndCopyList('mu+:ewp', 'mu+:all', 'p > 0.395 and muonID > 0.5 and ' + fairTrack, path=path)
157 
158  # Apply dilepton cut E_ll > 1.5 GeV (in CMS frame)
159  E_dilep_cut = 'formula(daughter(0, useCMSFrame(E))+daughter(1, useCMSFrame(E))) > 1.5'
160 
161  # B+ reconstruction:
162  # oppositely charged leptons
163  ma.reconstructDecay('B+:ch1 -> e+:ewp e-:ewp', E_dilep_cut, dmID=1, path=path, allowChargeViolation=True)
164  ma.reconstructDecay('B+:ch2 -> mu+:ewp mu-:ewp', E_dilep_cut, dmID=2, path=path, allowChargeViolation=True)
165  # same charge leptons
166  ma.reconstructDecay('B+:ch3 -> e+:ewp e+:ewp', E_dilep_cut, dmID=3, path=path, allowChargeViolation=True)
167  ma.reconstructDecay('B+:ch4 -> mu+:ewp mu+:ewp', E_dilep_cut, dmID=4, path=path, allowChargeViolation=True)
168 
169  ma.copyLists('B+:xll', ['B+:ch1', 'B+:ch2', 'B+:ch3', 'B+:ch4'], path=path)
170 
171  self.SkimLists = ['B+:xll']
172 
173 
174 @fancy_skim_header
176  """
177  Reconstructed decay modes:
178 
179  * :math:`B^+ \\to X e^+ \\mu^-`
180  * :math:`B^+ \\to X \\mu^+ e^-`
181  * :math:`B^+ \\to X e^+ \\mu^+`
182 
183 
184  Event-level cuts:
185 
186  * :math:`\\text{foxWolframR2} < 0.5` constructed using tracks with
187  :math:`p_T>0.1\\,\\text{GeV}` and clusters with :math:`E>0.1\\,\\text{GeV}`.
188  * :math:`n_{\\text{tracks}} \\geq 3`
189 
190  Cuts on electrons:
191 
192  * :math:`\\text{electronID} > 0.1`
193  * :math:`p > 0.395\\,\\text{GeV}` in lab frame
194  * :math:`dr<0.5 and abs(dz)<2`
195 
196  Cuts on muons:
197 
198  * :math:`\\text{muonID} > 0.5`
199  * :math:`p > 0.395\\,\\text{GeV}` in lab frame
200  * :math:`dr<0.5 and abs(dz)<2`
201 
202 
203  Cut on dilepton energy:
204 
205  * :math:`E_{\\ell\\ell}>1.5\\,\\text{GeV}` in CMS frame.
206  """
207 
208  __authors__ = ["Trevor Shillington"]
209  __description__ = ":math:`B\\to X\\ell\\ell` (LFV modes only) inclusive skim."
210  __contact__ = __liaison__
211  __category__ = "physics, electroweak penguins, radiative decays"
212 
213  def load_standard_lists(self, path):
214  stdE("all", path=path)
215  stdMu("all", path=path)
216  stdPi("all", path=path)
217  stdPhotons("all", path=path)
218 
219  def build_lists(self, path):
220  """Build the skim list for :math:`B \\to X\\ell\\ell` LFV decays."""
221  # Create lists for buildEventShape (basically all tracks and clusters)
222  ma.cutAndCopyList('pi+:BtoXllLFV_eventshape', 'pi+:all', 'pt> 0.1', path=path)
223  ma.cutAndCopyList('gamma:BtoXllLFV_eventshape', 'gamma:all', 'E > 0.1', path=path)
224 
225  # buildEventShape to access R2
226  ma.buildEventShape(inputListNames=['pi+:BtoXllLFV_eventshape', 'gamma:BtoXllLFV_eventshape'],
227  allMoments=False,
228  foxWolfram=True,
229  harmonicMoments=False,
230  cleoCones=False,
231  thrust=False,
232  collisionAxis=False,
233  jets=False,
234  sphericity=False,
235  checkForDuplicates=False,
236  path=path)
237 
238  # Apply event cuts R2 < 0.5 and nTracks >= 3
239  path = self.skim_event_cuts('foxWolframR2 < 0.5 and nTracks >= 3', path=path)
240 
241  # Apply electron cut p > 0.395 GeV, electronID > 0.1 + fairTrack
242  # Apply muon cuts p > 0.395 GeV, muonID > 0.5 + fairTrack
243  fairTrack = 'dr < 0.5 and abs(dz) < 2'
244 
245  ma.cutAndCopyList('e+:ewp', 'e+:all', 'p > 0.395 and electronID > 0.1 and ' + fairTrack, path=path)
246  ma.cutAndCopyList('mu+:ewp', 'mu+:all', 'p > 0.395 and muonID > 0.5 and ' + fairTrack, path=path)
247 
248  # Apply dilepton cut E_ll > 1.5 GeV (in CMS frame)
249  E_dilep_cut = 'formula(daughter(0, useCMSFrame(E))+daughter(1, useCMSFrame(E))) > 1.5'
250 
251  # B+ reconstruction:
252  # oppositely charged leptons
253  ma.reconstructDecay('B+:lfvch1 -> e+:ewp mu-:ewp', E_dilep_cut, dmID=1, path=path, allowChargeViolation=True)
254  ma.reconstructDecay('B+:lfvch2 -> mu+:ewp e-:ewp', E_dilep_cut, dmID=2, path=path, allowChargeViolation=True)
255  # same charge leptons
256  ma.reconstructDecay('B+:lfvch3 -> e+:ewp mu+:ewp', E_dilep_cut, dmID=3, path=path, allowChargeViolation=True)
257 
258  ma.copyLists('B+:lfv', ['B+:lfvch1', 'B+:lfvch2', 'B+:lfvch3'], path=path)
259 
260  self.SkimLists = ['B+:lfv']
261 
262 
264  """
265  Reconstructed decay modes:
266 
267  * :math:`B^+ \\to K\\nu\\nu` inclusive
268 
269  Track cleanup:
270  * :math:`p_t > 0.1`
271  * :math:`thetaInCDCAcceptance`
272  * :math:`dr<0.5 and abs(dz)<3.0`
273 
274  Event cleanup:
275  * :math:`3 < nCleanedTracks < 11`
276 
277  Kaon cuts:
278  * :math:`track cleanup + event cleanup + nPXDHits > 0`
279  * :math:`p_t rank=1`
280  * :math:`kaonID>0.01`
281 
282  MVA info and cuts:
283  * mva_identifier: MVAFastBDT_InclusiveBplusToKplusNuNu_Skim
284  * Global Tag: mva_inclusiveBplusToKplusNuNu
285  * :math:`mva\\_identifier > 0.5`
286  """
287 
288  __authors__ = ["Cyrille Praz"]
289  __description__ = "Inclusive skim for :math:`B\\to K\\nu\\nu` analysis"
290  __contact__ = __liaison__
291  __category__ = "physics, electroweak penguins, radiative decays"
292 
293  NoisyModules = ["ParticleCombiner"]
294 
295  def build_lists(self, path):
296 
297  # Default cleanup also used in and ma.buildEventShape
298  track_cleanup = 'pt > 0.1'
299  track_cleanup += ' and thetaInCDCAcceptance'
300  track_cleanup += ' and abs(dz) < 3.0'
301  track_cleanup += ' and dr < 0.5'
302 
303  # Min 4 tracks and Max 10 tracks per event.
304  event_cleanup = 'nCleanedTracks({}) > 3'.format(track_cleanup)
305  event_cleanup += ' and nCleanedTracks({}) < 11'.format(track_cleanup)
306 
307  # Define the signal
308  total_cleanup = track_cleanup + ' and ' + event_cleanup + ' and ' + 'nPXDHits>0'
309  ma.fillParticleList('K+:inclusiveBplusToKplusNuNu', cut=total_cleanup, path=path)
310  ma.rankByHighest('K+:inclusiveBplusToKplusNuNu', 'pt', path=path)
311  ma.applyCuts('K+:inclusiveBplusToKplusNuNu', 'extraInfo(pt_rank)==1', path=path)
312  ma.applyCuts('K+:inclusiveBplusToKplusNuNu', 'kaonID>1e-2', path=path)
313  ma.reconstructDecay(decayString='B+:inclusiveBplusToKplusNuNu -> K+:inclusiveBplusToKplusNuNu', cut='', path=path)
314 
315  # Build the event-based variables that we need
316  ma.buildEventShape(inputListNames=[],
317  default_cleanup=True,
318  allMoments=False,
319  cleoCones=True,
320  collisionAxis=False,
321  foxWolfram=True,
322  harmonicMoments=True,
323  jets=False,
324  sphericity=True,
325  thrust=True,
326  checkForDuplicates=False,
327  path=path)
328 
329  # Apply a MVA by reading from the DB
330  mva_identifier = 'MVAFastBDT_InclusiveBplusToKplusNuNu_Skim'
331  b2.conditions.append_globaltag('mva_inclusiveBplusToKplusNuNu')
332  path.add_module('MVAExpert', listNames=['B+:inclusiveBplusToKplusNuNu'],
333  extraInfoName=mva_identifier, identifier=mva_identifier)
334  variables.addAlias(mva_identifier, 'extraInfo({})'.format(mva_identifier))
335  ma.applyCuts('B+:inclusiveBplusToKplusNuNu', mva_identifier+'>0.5', path=path)
336 
337  self.SkimLists = ['B+:inclusiveBplusToKplusNuNu']
skimExpertFunctions.BaseSkim.skim_event_cuts
def skim_event_cuts(self, cut, *path)
Definition: skimExpertFunctions.py:716
skim.ewp.BtoXll_LFV.load_standard_lists
def load_standard_lists(self, path)
Definition: ewp.py:213
skim.ewp.BtoXll_LFV.SkimLists
SkimLists
Definition: ewp.py:260
skim.ewp.BtoXgamma.SkimLists
SkimLists
Definition: ewp.py:80
skim.ewp.inclusiveBplusToKplusNuNu.build_lists
def build_lists(self, path)
Definition: ewp.py:295
stdPhotons
Definition: stdPhotons.py:1
skim.ewp.BtoXll.load_standard_lists
def load_standard_lists(self, path)
Definition: ewp.py:123
skim.ewp.BtoXgamma.load_standard_lists
def load_standard_lists(self, path)
Definition: ewp.py:49
skim.ewp.inclusiveBplusToKplusNuNu.SkimLists
SkimLists
Definition: ewp.py:337
skimExpertFunctions.BaseSkim
Definition: skimExpertFunctions.py:504
skim.ewp.inclusiveBplusToKplusNuNu
Definition: ewp.py:263
skim.ewp.BtoXll.SkimLists
SkimLists
Definition: ewp.py:171
skim.ewp.BtoXgamma
Definition: ewp.py:26
skim.ewp.BtoXll_LFV.build_lists
def build_lists(self, path)
Definition: ewp.py:219
skim.ewp.BtoXll_LFV
Definition: ewp.py:175
skim.ewp.BtoXll
Definition: ewp.py:84
skim.ewp.BtoXgamma.build_lists
def build_lists(self, path)
Definition: ewp.py:54
skim.ewp.BtoXll.build_lists
def build_lists(self, path)
Definition: ewp.py:129