Belle II Software  release-06-01-15
default_channels.py
1 #!/usr/bin/env python3
2 
3 
10 
11 """
12  Contains some example configurations of the FEI
13  Mostly you want to use get_default_channels,
14  which can return the configuration for common use-cases
15  - Hadronic tagging (hadronic = True)
16  - Semileptonic tagging (semileptonic = True)
17  - B+/B- (chargedB = True)
18  - B0/anti-B0 (neutralB = True)
19  - running on Belle 1 MC/data (convertedFromBelle = True)
20  - running a specific FEI which is optimized for a signal selection and uses ROEs (specific = True)
21  - run without semileptonic D channels (removeSLD = True )
22  - B mesons with a strange quark in Y(5S) runs (strangeB = True)
23 
24  Another interesting configuration is given by get_fr_channels,
25  which will return a configuration which is equivalent to the original Full Reconstruction algorithm used by Belle
26 """
27 
28 import b2bii
29 from fei import Particle, MVAConfiguration, PreCutConfiguration, PostCutConfiguration
30 from basf2 import B2FATAL, B2INFO
31 
32 
33 def get_default_channels(
34  B_extra_cut=None,
35  hadronic=True,
36  semileptonic=True,
37  KLong=False,
38  baryonic=True,
39  chargedB=True,
40  neutralB=True,
41  specific=False,
42  removeSLD=False,
43  strangeB=False):
44  """
45  returns list of Particle objects with all default channels for running
46  FEI on Upsilon(4S). For a training with analysis-specific signal selection,
47  adding a cut on nRemainingTracksInRestOfEvent is recommended.
48  @param B_extra_cut Additional user cut on recombination of tag-B-mesons
49  @param hadronic whether to include hadronic B decays (default is True)
50  @param semileptonic whether to include semileptonic B decays (default is True)
51  @param KLong whether to include K_long decays into the training (default is False)
52  @param baryonic whether to include baryons into the training (default is True)
53  @param chargedB whether to recombine charged B mesons (default is True)
54  @param neutralB whether to recombine neutral B mesons (default is True)
55  @param specific if True, this adds isInRestOfEvent cut to all FSP
56  @param removeSLD if True, removes semileptonic D modes from semileptonic B lists (default is False)
57  @param strangeB if True, reconstruct B_s mesons in Upsilon5S decays (default is False)
58  """
59  if strangeB is True:
60  B2INFO('Running 5S FEI')
61  if chargedB is False and neutralB is False and strangeB is False:
62  B2FATAL('No B-Mesons will be recombined, since chargedB==False and neutralB==False and strangeB==False was selected!'
63  ' Please reconfigure the arguments of get_default_channels() accordingly')
64  if hadronic is False and semileptonic is False:
65  if KLong is False:
66  B2FATAL('No B-Mesons will be recombined, since hadronic==False, semileptonic==False, and KLong==False were selected.'
67  ' Please reconfigure the arguments of get_default_channels() accordingly')
68 
69  convertedFromBelle = b2bii.isB2BII()
70 
71  if convertedFromBelle:
72  # Using Belle specific Variables for e-ID, mu-ID and K-ID
73  # atcPIDBelle(3,2) is used as K-ID
74  # atcPIDBelle(4,2) and atcPIDBelle(4,3) are used as pr-ID
75 
76  chargedVariables = ['eIDBelle',
77  'atcPIDBelle(3,2)',
78  'atcPIDBelle(4,2)', 'atcPIDBelle(4,3)',
79  'muIDBelle',
80  'p', 'pt', 'pz', 'dr', 'dz', 'chiProb', 'extraInfo(preCut_rank)']
81  else:
82  chargedVariables = ['electronID', 'kaonID', 'protonID', 'muonID',
83  'p', 'pt', 'pz', 'dr', 'dz', 'chiProb', 'extraInfo(preCut_rank)']
84 
85  if specific:
86  charged_user_cut = '[dr < 2] and [abs(dz) < 4] and isInRestOfEvent > 0.5'
87  else:
88  charged_user_cut = '[dr < 2] and [abs(dz) < 4]'
89 
90  pion = Particle('pi+',
91  MVAConfiguration(variables=chargedVariables,
92  target='isPrimarySignal'),
93  PreCutConfiguration(userCut=charged_user_cut,
94  bestCandidateMode='highest',
95  bestCandidateVariable='pionID' if not convertedFromBelle else 'atcPIDBelle(2,3)',
96  bestCandidateCut=20),
97  PostCutConfiguration(bestCandidateCut=10, value=0.01))
98  pion.addChannel(['pi+:FSP'])
99 
100  kaon = Particle('K+',
101  MVAConfiguration(variables=chargedVariables,
102  target='isPrimarySignal'),
103  PreCutConfiguration(userCut=charged_user_cut,
104  bestCandidateMode='highest',
105  bestCandidateVariable='kaonID' if not convertedFromBelle else 'atcPIDBelle(3,2)',
106  bestCandidateCut=20),
107  PostCutConfiguration(bestCandidateCut=10, value=0.01))
108  kaon.addChannel(['K+:FSP'])
109 
110  proton = Particle('p+',
111  MVAConfiguration(variables=chargedVariables,
112  target='isPrimarySignal'),
113  PreCutConfiguration(userCut=charged_user_cut,
114  bestCandidateMode='highest',
115  bestCandidateVariable='protonID' if not convertedFromBelle else 'atcPIDBelle(4,3)',
116  bestCandidateCut=20),
117  PostCutConfiguration(bestCandidateCut=10, value=0.01))
118  proton.addChannel(['p+:FSP'])
119 
120  electron = Particle('e+',
121  MVAConfiguration(variables=chargedVariables,
122  target='isPrimarySignal'),
123  PreCutConfiguration(userCut=charged_user_cut,
124  bestCandidateMode='highest',
125  bestCandidateVariable='electronID' if not convertedFromBelle else 'eIDBelle',
126  bestCandidateCut=10),
127  PostCutConfiguration(bestCandidateCut=5, value=0.01))
128  electron.addChannel(['e+:FSP'])
129 
130  muon = Particle('mu+',
131  MVAConfiguration(variables=chargedVariables,
132  target='isPrimarySignal'),
133  PreCutConfiguration(userCut=charged_user_cut,
134  bestCandidateMode='highest',
135  bestCandidateVariable='muonID' if not convertedFromBelle else 'muIDBelle',
136  bestCandidateCut=10),
137  PostCutConfiguration(bestCandidateCut=5, value=0.01))
138  muon.addChannel(['mu+:FSP'])
139 
140  if convertedFromBelle:
141  gamma_cut = 'goodBelleGamma == 1 and clusterBelleQuality == 0'
142  else:
143  gamma_cut = '[[clusterReg == 1 and E > 0.10] or [clusterReg == 2 and E > 0.09] or [clusterReg == 3 and E > 0.16]]'
144  if specific:
145  gamma_cut += ' and isInRestOfEvent > 0.5'
146 
147  gamma = Particle('gamma',
148  MVAConfiguration(variables=['clusterReg', 'clusterNHits', 'clusterTiming', 'extraInfo(preCut_rank)',
149  'clusterE9E25', 'pt', 'E', 'pz'],
150  target='isPrimarySignal'),
151  PreCutConfiguration(userCut=gamma_cut,
152  bestCandidateMode='highest',
153  bestCandidateVariable='E',
154  bestCandidateCut=40),
155  PostCutConfiguration(bestCandidateCut=20, value=0.01))
156  gamma.addChannel(['gamma:FSP'])
157  gamma.addChannel(['gamma:V0'],
158  MVAConfiguration(variables=['pt', 'E', 'pz', 'extraInfo(preCut_rank)'],
159  target='isPrimarySignal'),
160  PreCutConfiguration(userCut='',
161  bestCandidateMode='highest',
162  bestCandidateVariable='E',
163  bestCandidateCut=40))
164 
165  if convertedFromBelle:
166 
167  pi0_cut = '0.08 < InvM < 0.18'
168  if specific:
169  pi0_cut += ' and isInRestOfEvent > 0.5'
170 
171  pi0 = Particle('pi0',
172  MVAConfiguration(variables=['InvM', 'extraInfo(preCut_rank)', 'chiProb', 'abs(BellePi0SigM)',
173  'daughterAngle(0,1)', 'pt', 'pz', 'E'],
174  target='isSignal'),
175  PreCutConfiguration(userCut=pi0_cut,
176  bestCandidateVariable='abs(BellePi0SigM)',
177  bestCandidateCut=20),
178  PostCutConfiguration(bestCandidateCut=10, value=0.01))
179  pi0.addChannel(['pi0:FSP'])
180 
181  ks0_cut = '0.4 < M < 0.6'
182  if specific:
183  ks0_cut += ' and isInRestOfEvent > 0.5'
184 
185  KS0 = Particle('K_S0',
186  MVAConfiguration(variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M', 'abs(dM)',
187  'useCMSFrame(E)', 'daughterAngle(0,1)',
188  'cosAngleBetweenMomentumAndVertexVector',
189  'extraInfo(preCut_rank)', 'extraInfo(goodKs)', 'extraInfo(ksnbVLike)',
190  'extraInfo(ksnbNoLam)', 'extraInfo(ksnbStandard)'],
191  target='isSignal'),
192  PreCutConfiguration(userCut=ks0_cut,
193  bestCandidateVariable='abs(dM)',
194  bestCandidateCut=20),
195  PostCutConfiguration(bestCandidateCut=10, value=0.01))
196  KS0.addChannel(['K_S0:V0'])
197 
198  Lam_cut = '0.9 < M < 1.3'
199  if specific:
200  Lam_cut += ' and isInRestOfEvent > 0.5'
201  L0 = Particle('Lambda0',
202  MVAConfiguration(variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M', 'abs(dM)',
203  'useCMSFrame(E)', 'daughterAngle(0,1)',
204  'cosAngleBetweenMomentumAndVertexVector',
205  'extraInfo(preCut_rank)', 'extraInfo(goodLambda)', 'extraInfo(ksnbVLike)',
206  'extraInfo(ksnbNoLam)'],
207  target='isSignal'),
208  PreCutConfiguration(userCut=Lam_cut,
209  bestCandidateVariable='abs(dM)',
210  bestCandidateCut=20),
211  PostCutConfiguration(bestCandidateCut=10, value=0.01))
212  L0.addChannel(['Lambda0:V0'])
213 
214  else:
215 
216  pi0 = Particle('pi0',
217  MVAConfiguration(variables=['M', 'daughter({},extraInfo(SignalProbability))', 'extraInfo(preCut_rank)',
218  'daughterAngle(0,1)', 'pt', 'pz', 'E', 'abs(dM)'],
219  target='isSignal'),
220  PreCutConfiguration(userCut='0.08 < M < 0.18',
221  bestCandidateVariable='abs(dM)',
222  bestCandidateCut=20),
223  PostCutConfiguration(bestCandidateCut=10, value=0.01))
224  pi0.addChannel(['gamma', 'gamma'])
225 
226  KS0 = Particle('K_S0',
227  MVAConfiguration(variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M', 'abs(dM)',
228  'useCMSFrame(E)', 'daughterAngle(0,1)',
229  'daughter({},extraInfo(SignalProbability))',
230  'useRestFrame(daughter({}, p))', 'cosAngleBetweenMomentumAndVertexVector',
231  'daughter({}, dz)', 'daughter({}, dr)', 'extraInfo(preCut_rank)'],
232  target='isSignal'),
233  PreCutConfiguration(userCut='0.4 < M < 0.6',
234  bestCandidateVariable='abs(dM)',
235  bestCandidateCut=20),
236  PostCutConfiguration(bestCandidateCut=10, value=0.01))
237  KS0.addChannel(['pi+', 'pi-'])
238  KS0.addChannel(['pi0', 'pi0'])
239 
240  ks0_cut = '0.4 < M < 0.6'
241  if specific:
242  ks0_cut += ' and isInRestOfEvent > 0.5'
243 
244  KS0.addChannel(['K_S0:V0'],
245  MVAConfiguration(variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M',
246  'useCMSFrame(E)', 'daughterAngle(0,1)', 'extraInfo(preCut_rank)', 'abs(dM)',
247  'useRestFrame(daughter({}, p))', 'cosAngleBetweenMomentumAndVertexVector',
248  'daughter({}, dz)', 'daughter({}, dr)'],
249  target='isSignal'),
250  PreCutConfiguration(userCut=ks0_cut,
251  bestCandidateVariable='abs(dM)',
252  bestCandidateCut=20))
253 
254  L0 = Particle('Lambda0',
255  MVAConfiguration(variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M', 'abs(dM)',
256  'useCMSFrame(E)', 'daughterAngle(0,1)',
257  'daughter({},extraInfo(SignalProbability))',
258  'useRestFrame(daughter({}, p))', 'cosAngleBetweenMomentumAndVertexVector',
259  'daughter({}, dz)', 'daughter({}, dr)', 'extraInfo(preCut_rank)'],
260  target='isSignal'),
261  PreCutConfiguration(userCut='0.9 < M < 1.3',
262  bestCandidateVariable='abs(dM)',
263  bestCandidateCut=20),
264  PostCutConfiguration(bestCandidateCut=10, value=0.01))
265  L0.addChannel(['p+', 'pi-'])
266 
267  Lam_cut = '0.9 < M < 1.3'
268  if specific:
269  Lam_cut += ' and isInRestOfEvent > 0.5'
270 
271  L0.addChannel(['Lambda0:V0'],
272  MVAConfiguration(variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M',
273  'useCMSFrame(E)', 'daughterAngle(0,1)', 'extraInfo(preCut_rank)', 'abs(dM)',
274  'useRestFrame(daughter({}, p))', 'cosAngleBetweenMomentumAndVertexVector',
275  'daughter({}, dz)', 'daughter({}, dr)'],
276  target='isSignal'),
277  PreCutConfiguration(userCut=Lam_cut,
278  bestCandidateVariable='abs(dM)',
279  bestCandidateCut=20))
280  kl0_cut = ''
281  if specific:
282  kl0_cut += 'isInRestOfEvent > 0.5'
283 
284  KL0 = Particle('K_L0',
285  MVAConfiguration(variables=['E', 'klmClusterTiming'],
286  target='isSignal'),
287  PreCutConfiguration(userCut=kl0_cut,
288  bestCandidateVariable='abs(dM)',
289  bestCandidateCut=20),
290  PostCutConfiguration(bestCandidateCut=10, value=0.01))
291  KL0.addChannel(['K_L0:FSP'])
292 
293  SigmaP = Particle('Sigma+',
294  MVAConfiguration(variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M', 'abs(dM)',
295  'useCMSFrame(E)', 'daughterAngle(0,1)',
296  'daughter({},extraInfo(SignalProbability))',
297  'useRestFrame(daughter({}, p))', 'cosAngleBetweenMomentumAndVertexVector',
298  'daughter({}, dz)', 'daughter({}, dr)', 'extraInfo(preCut_rank)'],
299  target='isSignal'),
300  PreCutConfiguration(userCut='1.0 < M < 1.4',
301  bestCandidateVariable='abs(dM)',
302  bestCandidateCut=20),
303  PostCutConfiguration(bestCandidateCut=10, value=0.01))
304  SigmaP.addChannel(['p+', 'pi0'])
305  # variables for D mesons and J/Psi
306  intermediate_vars = ['daughterProductOf(extraInfo(SignalProbability))', 'daughter({},extraInfo(SignalProbability))',
307  'chiProb', 'daughter({}, chiProb)', 'extraInfo(preCut_rank)', 'abs(dM)',
308  'useRestFrame(daughter({}, p))',
309  'useRestFrame(daughter({}, distance))',
310  'decayAngle({})', 'daughterAngle({},{})', 'cosAngleBetweenMomentumAndVertexVector',
311  'daughterInvariantMass({},{})', 'daughterInvariantMass({},{},{})', 'daughterInvariantMass({},{},{},{})',
312  'daughterInvariantMass({},{},{},{},{})', 'dQ', 'Q', 'dM', 'daughter({},extraInfo(decayModeID))']
313 
314  # TODO if specific:
315  # We can not do this in the generic case (because this would heavily influence our performance on the unknown signal events
316  # but in the specific case this could work well
317  # intermediate_vars = ['nRemainingTracksInEvent']
318  LC = Particle('Lambda_c+',
319  MVAConfiguration(variables=intermediate_vars,
320  target='isSignal'),
321  PreCutConfiguration(userCut='2.2 < M < 2.4',
322  bestCandidateVariable='abs(dM)',
323  bestCandidateCut=20),
324  PostCutConfiguration(bestCandidateCut=10, value=0.001))
325  LC.addChannel(['p+', 'K-', 'pi+'])
326  LC.addChannel(['p+', 'pi-', 'pi+'])
327  LC.addChannel(['p+', 'K-', 'K+'])
328  LC.addChannel(['p+', 'K-', 'pi+', 'pi0'])
329  LC.addChannel(['p+', 'K-', 'pi+', 'pi0', 'pi0'])
330  LC.addChannel(['p+', 'pi+', 'pi+', 'pi-', 'pi-'])
331  LC.addChannel(['p+', 'K_S0'])
332  LC.addChannel(['p+', 'K_S0', 'pi0'])
333  LC.addChannel(['p+', 'K_S0', 'pi+', 'pi-'])
334  LC.addChannel(['Lambda0', 'pi+'])
335  LC.addChannel(['Lambda0', 'pi+', 'pi0'])
336  LC.addChannel(['Lambda0', 'pi+', 'pi-', 'pi+'])
337  LC.addChannel(['Lambda0', 'pi+', 'gamma'])
338  LC.addChannel(['Lambda0', 'pi+', 'pi0', 'gamma'])
339  LC.addChannel(['Lambda0', 'pi+', 'pi-', 'pi+', 'gamma'])
340  LC.addChannel(['Sigma+', 'pi+', 'pi-'])
341  LC.addChannel(['Sigma+', 'pi+', 'pi-', 'pi0'])
342  LC.addChannel(['Sigma+', 'pi0'])
343 
344  D0 = Particle('D0',
345  MVAConfiguration(variables=intermediate_vars,
346  target='isSignal'),
347  PreCutConfiguration(userCut='1.7 < M < 1.95',
348  bestCandidateVariable='abs(dM)',
349  bestCandidateCut=20),
350  PostCutConfiguration(bestCandidateCut=10, value=0.001))
351  D0.addChannel(['K-', 'pi+'])
352  D0.addChannel(['K-', 'pi+', 'pi0'])
353  D0.addChannel(['K-', 'pi+', 'pi0', 'pi0'])
354  D0.addChannel(['K-', 'pi+', 'pi+', 'pi-'])
355  D0.addChannel(['K-', 'pi+', 'pi+', 'pi-', 'pi0'])
356  D0.addChannel(['pi-', 'pi+'])
357  D0.addChannel(['pi-', 'pi+', 'pi+', 'pi-'])
358  D0.addChannel(['pi-', 'pi+', 'pi0'])
359  D0.addChannel(['pi-', 'pi+', 'pi0', 'pi0'])
360  D0.addChannel(['K_S0', 'pi0'])
361  D0.addChannel(['K_S0', 'pi+', 'pi-'])
362  D0.addChannel(['K_S0', 'pi+', 'pi-', 'pi0'])
363  D0.addChannel(['K-', 'K+'])
364  D0.addChannel(['K-', 'K+', 'pi0'])
365  D0.addChannel(['K-', 'K+', 'K_S0'])
366 
367  if not removeSLD:
368  D0_SL = Particle('D0:semileptonic',
369  MVAConfiguration(variables=intermediate_vars,
370  target='isSignalAcceptMissingNeutrino'),
371  PreCutConfiguration(userCut='',
372  bestCandidateMode='highest',
373  bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
374  bestCandidateCut=20),
375  PostCutConfiguration(bestCandidateCut=10, value=0.001))
376 
377  D0_SL.addChannel(['K-', 'e+'])
378  D0_SL.addChannel(['K-', 'mu+'])
379  D0_SL.addChannel(['K-', 'pi0', 'e+'])
380  D0_SL.addChannel(['K-', 'pi0', 'mu+'])
381  D0_SL.addChannel(['K_S0', 'pi-', 'e+'])
382  D0_SL.addChannel(['K_S0', 'pi-', 'mu+'])
383 
384  if KLong:
385  D0_KL = Particle('D0:KL',
386  MVAConfiguration(variables=intermediate_vars,
387  target='isSignal'),
388  PreCutConfiguration(userCut='',
389  bestCandidateMode='highest',
390  bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
391  bestCandidateCut=20),
392  PostCutConfiguration(bestCandidateCut=10, value=0.001))
393 
394  D0_KL.addChannel(['K_L0', 'pi0'])
395  D0_KL.addChannel(['K_L0', 'pi+', 'pi-'])
396  D0_KL.addChannel(['K_L0', 'pi+', 'pi-', 'pi0'])
397  D0_KL.addChannel(['K-', 'K+', 'K_L0'])
398 
399  DP = Particle('D+',
400  MVAConfiguration(variables=intermediate_vars,
401  target='isSignal'),
402  PreCutConfiguration(userCut='1.7 < M < 1.95',
403  bestCandidateVariable='abs(dM)',
404  bestCandidateCut=20),
405  PostCutConfiguration(bestCandidateCut=10, value=0.001))
406 
407  DP.addChannel(['K-', 'pi+', 'pi+'])
408  DP.addChannel(['K-', 'pi+', 'pi+', 'pi0'])
409  DP.addChannel(['K-', 'K+', 'pi+'])
410  DP.addChannel(['K-', 'K+', 'pi+', 'pi0'])
411  DP.addChannel(['pi+', 'pi0'])
412  DP.addChannel(['pi+', 'pi+', 'pi-'])
413  DP.addChannel(['pi+', 'pi+', 'pi-', 'pi0'])
414  DP.addChannel(['K_S0', 'pi+'])
415  DP.addChannel(['K_S0', 'pi+', 'pi0'])
416  DP.addChannel(['K_S0', 'pi+', 'pi+', 'pi-'])
417  DP.addChannel(['K+', 'K_S0', 'K_S0'])
418 
419  if not removeSLD:
420  DP_SL = Particle('D+:semileptonic',
421  MVAConfiguration(variables=intermediate_vars,
422  target='isSignalAcceptMissingNeutrino'),
423  PreCutConfiguration(userCut='',
424  bestCandidateMode='highest',
425  bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
426  bestCandidateCut=20),
427  PostCutConfiguration(bestCandidateCut=10, value=0.001))
428 
429  DP_SL.addChannel(['K_S0', 'e+'])
430  DP_SL.addChannel(['K_S0', 'mu+'])
431  DP_SL.addChannel(['K-', 'pi+', 'e+'])
432  DP_SL.addChannel(['K-', 'pi+', 'mu+'])
433 
434  if KLong:
435  DP_KL = Particle('D+:KL',
436  MVAConfiguration(variables=intermediate_vars,
437  target='isSignal'),
438  PreCutConfiguration(userCut='',
439  bestCandidateMode='highest',
440  bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
441  bestCandidateCut=20),
442  PostCutConfiguration(bestCandidateCut=10, value=0.001))
443 
444  DP_KL.addChannel(['K_L0', 'pi+'])
445  DP_KL.addChannel(['K_L0', 'pi+', 'pi0'])
446  DP_KL.addChannel(['K_L0', 'pi+', 'pi+', 'pi-'])
447  DP_KL.addChannel(['K+', 'K_L0', 'K_S0'])
448  DP_KL.addChannel(['K+', 'K_L0', 'K_L0'])
449 
450  Jpsi = Particle('J/psi',
451  MVAConfiguration(variables=intermediate_vars,
452  target='isSignal'),
453  PreCutConfiguration(userCut='2.6 < M < 3.7',
454  bestCandidateVariable='abs(dM)',
455  bestCandidateCut=20),
456  PostCutConfiguration(bestCandidateCut=10, value=0.001))
457 
458  Jpsi.addChannel(['e+', 'e-'])
459  Jpsi.addChannel(['mu+', 'mu-'])
460 
461  DSP = Particle('D*+',
462  MVAConfiguration(variables=intermediate_vars,
463  target='isSignal'),
464  PreCutConfiguration(userCut='0 < Q < 0.3',
465  bestCandidateVariable='abs(dQ)',
466  bestCandidateCut=20),
467  PostCutConfiguration(bestCandidateCut=10, value=0.001))
468 
469  DSP.addChannel(['D0', 'pi+'])
470  DSP.addChannel(['D+', 'pi0'])
471  DSP.addChannel(['D+', 'gamma'])
472 
473  if not removeSLD:
474  DSP_SL = Particle('D*+:semileptonic',
475  MVAConfiguration(variables=intermediate_vars,
476  target='isSignalAcceptMissingNeutrino'),
477  PreCutConfiguration(userCut='0 < Q < 0.3',
478  bestCandidateVariable='abs(dQ)',
479  bestCandidateCut=20),
480  PostCutConfiguration(bestCandidateCut=10, value=0.001))
481 
482  DSP_SL.addChannel(['D0:semileptonic', 'pi+'])
483  DSP_SL.addChannel(['D+:semileptonic', 'pi0'])
484  DSP_SL.addChannel(['D+:semileptonic', 'gamma'])
485 
486  if KLong:
487  DSP_KL = Particle('D*+:KL',
488  MVAConfiguration(variables=intermediate_vars,
489  target='isSignal'),
490  PreCutConfiguration(userCut='0 < Q < 0.3',
491  bestCandidateVariable='abs(dQ)',
492  bestCandidateCut=20),
493  PostCutConfiguration(bestCandidateCut=10, value=0.001))
494 
495  DSP_KL.addChannel(['D0:KL', 'pi+'])
496  DSP_KL.addChannel(['D+:KL', 'pi0'])
497  DSP_KL.addChannel(['D+:KL', 'gamma'])
498 
499  DS0 = Particle('D*0',
500  MVAConfiguration(variables=intermediate_vars,
501  target='isSignal'),
502  PreCutConfiguration(userCut='0 < Q < 0.3',
503  bestCandidateVariable='abs(dQ)',
504  bestCandidateCut=20),
505  PostCutConfiguration(bestCandidateCut=10, value=0.001))
506 
507  DS0.addChannel(['D0', 'pi0'])
508  DS0.addChannel(['D0', 'gamma'])
509 
510  if not removeSLD:
511  DS0_SL = Particle('D*0:semileptonic',
512  MVAConfiguration(variables=intermediate_vars,
513  target='isSignalAcceptMissingNeutrino'),
514  PreCutConfiguration(userCut='0 < Q < 0.3',
515  bestCandidateVariable='abs(dQ)',
516  bestCandidateCut=20),
517  PostCutConfiguration(bestCandidateCut=10, value=0.001))
518 
519  DS0_SL.addChannel(['D0:semileptonic', 'pi0'])
520  DS0_SL.addChannel(['D0:semileptonic', 'gamma'])
521 
522  if KLong:
523  DS0_KL = Particle('D*0:KL',
524  MVAConfiguration(variables=intermediate_vars,
525  target='isSignal'),
526  PreCutConfiguration(userCut='0 < Q < 0.3',
527  bestCandidateVariable='abs(dQ)',
528  bestCandidateCut=20),
529  PostCutConfiguration(bestCandidateCut=10, value=0.001))
530 
531  DS0_KL.addChannel(['D0:KL', 'pi0'])
532  DS0_KL.addChannel(['D0:KL', 'gamma'])
533 
534  DS = Particle('D_s+',
535  MVAConfiguration(variables=intermediate_vars,
536  target='isSignal'),
537  PreCutConfiguration(userCut='1.68 < M < 2.1',
538  bestCandidateVariable='abs(dM)',
539  bestCandidateCut=20),
540  PostCutConfiguration(bestCandidateCut=10, value=0.001))
541 
542  DS.addChannel(['K+', 'K_S0'])
543  DS.addChannel(['K+', 'pi+', 'pi-'])
544  DS.addChannel(['K+', 'K-', 'pi+'])
545  DS.addChannel(['K+', 'K-', 'pi+', 'pi0'])
546  DS.addChannel(['K+', 'K_S0', 'pi+', 'pi-'])
547  DS.addChannel(['K-', 'K_S0', 'pi+', 'pi+'])
548  DS.addChannel(['K+', 'K-', 'pi+', 'pi+', 'pi-'])
549  DS.addChannel(['pi+', 'pi+', 'pi-'])
550  DS.addChannel(['K_S0', 'pi+'])
551  DS.addChannel(['K_S0', 'pi+', 'pi0'])
552 
553  if KLong:
554  DS_KL = Particle('D_s+:KL',
555  MVAConfiguration(variables=intermediate_vars,
556  target='isSignal'),
557  PreCutConfiguration(userCut='',
558  bestCandidateMode='highest',
559  bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
560  bestCandidateCut=20),
561  PostCutConfiguration(bestCandidateCut=10, value=0.001))
562 
563  DS_KL.addChannel(['K+', 'K_L0'])
564  DS_KL.addChannel(['K+', 'K_L0', 'pi+', 'pi-'])
565  DS_KL.addChannel(['K-', 'K_L0', 'pi+', 'pi+'])
566  DS_KL.addChannel(['K_L0', 'pi+'])
567  DS_KL.addChannel(['K_L0', 'pi+', 'pi0'])
568 
569  DSS = Particle('D_s*+',
570  MVAConfiguration(variables=intermediate_vars,
571  target='isSignal'),
572  PreCutConfiguration(userCut='0.0 < Q < 0.3',
573  bestCandidateVariable='abs(dQ)',
574  bestCandidateCut=20),
575  PostCutConfiguration(bestCandidateCut=10, value=0.001))
576 
577  DSS.addChannel(['D_s+', 'gamma'])
578  DSS.addChannel(['D_s+', 'pi0'])
579 
580  if KLong:
581  DSS_KL = Particle('D_s*+:KL',
582  MVAConfiguration(variables=intermediate_vars,
583  target='isSignal'),
584  PreCutConfiguration(userCut='0.0 < Q < 0.3',
585  bestCandidateVariable='abs(dQ)',
586  bestCandidateCut=20),
587  PostCutConfiguration(bestCandidateCut=10, value=0.001))
588 
589  DSS_KL.addChannel(['D_s+:KL', 'gamma'])
590  DSS_KL.addChannel(['D_s+:KL', 'pi0'])
591 
592  # note: these should not be correlated to Mbc (weak correlation of deltaE is OK)
593  B_vars = ['daughterProductOf(extraInfo(SignalProbability))', 'daughter({},extraInfo(SignalProbability))',
594  'chiProb', 'daughter({}, chiProb)', 'extraInfo(preCut_rank)',
595  'useRestFrame(daughter({}, p))',
596  'useRestFrame(daughter({}, distance))',
597  'decayAngle({})', 'daughterAngle({},{})', 'cosAngleBetweenMomentumAndVertexVector',
598  'dr', 'dz', 'dx', 'dy', 'distance', 'significanceOfDistance', 'deltaE', 'daughter({},extraInfo(decayModeID))']
599 
600  hadronic_user_cut = 'Mbc > 5.2 and abs(deltaE) < 0.5'
601  if B_extra_cut is not None:
602  hadronic_user_cut += ' and [' + B_extra_cut + ']'
603 
604  BP = Particle('B+',
605  MVAConfiguration(variables=B_vars,
606  target='isSignal'),
607  PreCutConfiguration(userCut=hadronic_user_cut,
608  bestCandidateMode='highest',
609  bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
610  bestCandidateCut=20),
611  PostCutConfiguration(bestCandidateCut=20))
612 
613  BP.addChannel(['anti-D0', 'pi+'])
614  BP.addChannel(['anti-D0', 'pi+', 'pi0'])
615  BP.addChannel(['anti-D0', 'pi+', 'pi0', 'pi0'])
616  BP.addChannel(['anti-D0', 'pi+', 'pi+', 'pi-'])
617  BP.addChannel(['anti-D0', 'pi+', 'pi+', 'pi-', 'pi0'])
618  BP.addChannel(['anti-D0', 'D+'])
619  BP.addChannel(['anti-D0', 'D+', 'K_S0'])
620  BP.addChannel(['anti-D*0', 'D+', 'K_S0'])
621  BP.addChannel(['anti-D0', 'D*+', 'K_S0'])
622  BP.addChannel(['anti-D*0', 'D*+', 'K_S0'])
623  BP.addChannel(['anti-D0', 'D0', 'K+'])
624  BP.addChannel(['anti-D*0', 'D0', 'K+'])
625  BP.addChannel(['anti-D0', 'D*0', 'K+'])
626  BP.addChannel(['anti-D*0', 'D*0', 'K+'])
627  BP.addChannel(['D_s+', 'anti-D0'])
628  BP.addChannel(['anti-D*0', 'pi+'])
629  BP.addChannel(['anti-D*0', 'pi+', 'pi0'])
630  BP.addChannel(['anti-D*0', 'pi+', 'pi0', 'pi0'])
631  BP.addChannel(['anti-D*0', 'pi+', 'pi+', 'pi-'])
632  BP.addChannel(['anti-D*0', 'pi+', 'pi+', 'pi-', 'pi0'])
633  BP.addChannel(['D_s*+', 'anti-D0'])
634  BP.addChannel(['D_s+', 'anti-D*0'])
635  BP.addChannel(['anti-D0', 'K+'])
636  BP.addChannel(['D-', 'pi+', 'pi+'])
637  BP.addChannel(['D-', 'pi+', 'pi+', 'pi0'])
638  BP.addChannel(['J/psi', 'K+'], preCutConfig=BP.preCutConfig._replace(noBackgroundSampling=True))
639  BP.addChannel(['J/psi', 'K+', 'pi+', 'pi-'])
640  BP.addChannel(['J/psi', 'K+', 'pi0'])
641  BP.addChannel(['J/psi', 'K_S0', 'pi+'])
642  if baryonic:
643  BP.addChannel(['anti-Lambda_c-', 'p+', 'pi+', 'pi0'])
644  BP.addChannel(['anti-Lambda_c-', 'p+', 'pi+', 'pi-', 'pi+'])
645  BP.addChannel(['anti-D0', 'p+', 'anti-p-', 'pi+'])
646  BP.addChannel(['anti-D*0', 'p+', 'anti-p-', 'pi+'])
647  BP.addChannel(['D+', 'p+', 'anti-p-', 'pi+', 'pi-'])
648  BP.addChannel(['D*+', 'p+', 'anti-p-', 'pi+', 'pi-'])
649  BP.addChannel(['anti-Lambda_c-', 'p+', 'pi+'])
650 
651  B_SL_vars = ['daughterProductOf(extraInfo(SignalProbability))', 'daughter({},extraInfo(SignalProbability))',
652  'chiProb', 'daughter({}, chiProb)', 'extraInfo(preCut_rank)',
653  'useRestFrame(daughter({}, p))',
654  'useRestFrame(daughter({}, distance))',
655  'cosAngleBetweenMomentumAndVertexVector',
656  'dr', 'dz', 'dx', 'dy', 'distance', 'significanceOfDistance', 'daughter({},extraInfo(decayModeID))']
657 
658  semileptonic_user_cut = ''
659  if B_extra_cut is not None:
660  semileptonic_user_cut += B_extra_cut
661 
662  BP_SL = Particle('B+:semileptonic',
663  MVAConfiguration(variables=B_SL_vars,
664  target='isSignalAcceptMissingNeutrino'),
665  PreCutConfiguration(userCut=semileptonic_user_cut,
666  bestCandidateMode='highest',
667  bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
668  bestCandidateCut=20),
669  PostCutConfiguration(bestCandidateCut=20))
670  BP_SL.addChannel(['anti-D0', 'e+'])
671  BP_SL.addChannel(['anti-D0', 'mu+'])
672  BP_SL.addChannel(['anti-D*0', 'e+'])
673  BP_SL.addChannel(['anti-D*0', 'mu+'])
674  BP_SL.addChannel(['D-', 'pi+', 'e+'])
675  BP_SL.addChannel(['D-', 'pi+', 'mu+'])
676  BP_SL.addChannel(['D*-', 'pi+', 'e+'])
677  BP_SL.addChannel(['D*-', 'pi+', 'mu+'])
678 
679  if not removeSLD:
680  BP_SL.addChannel(['anti-D0:semileptonic', 'pi+'])
681  BP_SL.addChannel(['anti-D0:semileptonic', 'pi+', 'pi0'])
682  BP_SL.addChannel(['anti-D0:semileptonic', 'pi+', 'pi0', 'pi0'])
683  BP_SL.addChannel(['anti-D0:semileptonic', 'pi+', 'pi+', 'pi-'])
684  BP_SL.addChannel(['anti-D0:semileptonic', 'pi+', 'pi+', 'pi-', 'pi0'])
685  BP_SL.addChannel(['anti-D0:semileptonic', 'D+'])
686  BP_SL.addChannel(['anti-D0:semileptonic', 'D+', 'K_S0'])
687  BP_SL.addChannel(['anti-D*0:semileptonic', 'D+', 'K_S0'])
688  BP_SL.addChannel(['anti-D0:semileptonic', 'D*+', 'K_S0'])
689  BP_SL.addChannel(['anti-D*0:semileptonic', 'D*+', 'K_S0'])
690  BP_SL.addChannel(['anti-D0:semileptonic', 'D0', 'K+'])
691  BP_SL.addChannel(['anti-D*0:semileptonic', 'D0', 'K+'])
692  BP_SL.addChannel(['anti-D0:semileptonic', 'D*0', 'K+'])
693  BP_SL.addChannel(['anti-D*0:semileptonic', 'D*0', 'K+'])
694  BP_SL.addChannel(['anti-D0', 'D+:semileptonic'])
695  BP_SL.addChannel(['anti-D0', 'D+:semileptonic', 'K_S0'])
696  BP_SL.addChannel(['anti-D*0', 'D+:semileptonic', 'K_S0'])
697  BP_SL.addChannel(['anti-D0', 'D*+:semileptonic', 'K_S0'])
698  BP_SL.addChannel(['anti-D*0', 'D*+:semileptonic', 'K_S0'])
699  BP_SL.addChannel(['anti-D0', 'D0:semileptonic', 'K+'])
700  BP_SL.addChannel(['anti-D*0', 'D0:semileptonic', 'K+'])
701  BP_SL.addChannel(['anti-D0', 'D*0:semileptonic', 'K+'])
702  BP_SL.addChannel(['anti-D*0', 'D*0:semileptonic', 'K+'])
703  BP_SL.addChannel(['D_s+', 'anti-D0:semileptonic'])
704  BP_SL.addChannel(['anti-D*0:semileptonic', 'pi+'])
705  BP_SL.addChannel(['anti-D*0:semileptonic', 'pi+', 'pi0'])
706  BP_SL.addChannel(['anti-D*0:semileptonic', 'pi+', 'pi0', 'pi0'])
707  BP_SL.addChannel(['anti-D*0:semileptonic', 'pi+', 'pi+', 'pi-'])
708  BP_SL.addChannel(['anti-D*0:semileptonic', 'pi+', 'pi+', 'pi-', 'pi0'])
709  BP_SL.addChannel(['D_s*+', 'anti-D0:semileptonic'])
710  BP_SL.addChannel(['D_s+', 'anti-D*0:semileptonic'])
711  BP_SL.addChannel(['anti-D0:semileptonic', 'K+'])
712  BP_SL.addChannel(['D-:semileptonic', 'pi+', 'pi+'])
713  BP_SL.addChannel(['D-:semileptonic', 'pi+', 'pi+', 'pi0'])
714 
715  if KLong:
716  BP_KL = Particle('B+:KL',
717  MVAConfiguration(variables=B_vars,
718  target='isSignal'),
719  PreCutConfiguration(userCut=semileptonic_user_cut,
720  bestCandidateMode='highest',
721  bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
722  bestCandidateCut=20),
723  PostCutConfiguration(bestCandidateCut=20))
724  BP_KL.addChannel(['anti-D0:KL', 'pi+'])
725  BP_KL.addChannel(['anti-D0:KL', 'pi+', 'pi0'])
726  BP_KL.addChannel(['anti-D0:KL', 'pi+', 'pi0', 'pi0'])
727  BP_KL.addChannel(['anti-D0:KL', 'pi+', 'pi+', 'pi-'])
728  BP_KL.addChannel(['anti-D0:KL', 'pi+', 'pi+', 'pi-', 'pi0'])
729  BP_KL.addChannel(['anti-D0:KL', 'D+'])
730  BP_KL.addChannel(['anti-D0:KL', 'D+', 'K_S0'])
731  BP_KL.addChannel(['anti-D*0:KL', 'D+', 'K_S0'])
732  BP_KL.addChannel(['anti-D0:KL', 'D*+', 'K_S0'])
733  BP_KL.addChannel(['anti-D*0:KL', 'D*+', 'K_S0'])
734  BP_KL.addChannel(['anti-D0:KL', 'D0', 'K+'])
735  BP_KL.addChannel(['anti-D*0:KL', 'D0', 'K+'])
736  BP_KL.addChannel(['anti-D0:KL', 'D*0', 'K+'])
737  BP_KL.addChannel(['anti-D*0:KL', 'D*0', 'K+'])
738  BP_KL.addChannel(['anti-D0', 'D+:KL'])
739  BP_KL.addChannel(['anti-D0', 'D+:KL', 'K_S0'])
740  BP_KL.addChannel(['anti-D*0', 'D+:KL', 'K_S0'])
741  BP_KL.addChannel(['anti-D0', 'D*+:KL', 'K_S0'])
742  BP_KL.addChannel(['anti-D*0', 'D*+:KL', 'K_S0'])
743  BP_KL.addChannel(['anti-D0', 'D0:KL', 'K+'])
744  BP_KL.addChannel(['anti-D*0', 'D0:KL', 'K+'])
745  BP_KL.addChannel(['anti-D0', 'D*0:KL', 'K+'])
746  BP_KL.addChannel(['anti-D*0', 'D*0:KL', 'K+'])
747  BP_KL.addChannel(['D_s+', 'anti-D0:KL'])
748  BP_KL.addChannel(['D_s+:KL', 'anti-D0'])
749  BP_KL.addChannel(['anti-D*0:KL', 'pi+'])
750  BP_KL.addChannel(['anti-D*0:KL', 'pi+', 'pi0'])
751  BP_KL.addChannel(['anti-D*0:KL', 'pi+', 'pi0', 'pi0'])
752  BP_KL.addChannel(['anti-D*0:KL', 'pi+', 'pi+', 'pi-'])
753  BP_KL.addChannel(['anti-D*0:KL', 'pi+', 'pi+', 'pi-', 'pi0'])
754  BP_KL.addChannel(['D_s*+', 'anti-D0:KL'])
755  BP_KL.addChannel(['D_s+', 'anti-D*0:KL'])
756  BP_KL.addChannel(['D_s*+:KL', 'anti-D0'])
757  BP_KL.addChannel(['D_s+:KL', 'anti-D*0'])
758  BP_KL.addChannel(['anti-D0:KL', 'K+'])
759  BP_KL.addChannel(['D-:KL', 'pi+', 'pi+'])
760  BP_KL.addChannel(['D-:KL', 'pi+', 'pi+', 'pi0'])
761  BP_KL.addChannel(['anti-D0', 'D+', 'K_L0'])
762  BP_KL.addChannel(['anti-D*0', 'D+', 'K_L0'])
763  BP_KL.addChannel(['anti-D0', 'D*+', 'K_L0'])
764  BP_KL.addChannel(['anti-D*0', 'D*+', 'K_L0'])
765  BP_KL.addChannel(['J/psi', 'K_L0', 'pi+'])
766 
767  B0 = Particle('B0',
768  MVAConfiguration(variables=B_vars,
769  target='isSignal'),
770  PreCutConfiguration(userCut=hadronic_user_cut,
771  bestCandidateMode='highest',
772  bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
773  bestCandidateCut=20),
774  PostCutConfiguration(bestCandidateCut=20))
775  B0.addChannel(['D-', 'pi+'])
776  B0.addChannel(['D-', 'pi+', 'pi0'])
777  B0.addChannel(['D-', 'pi+', 'pi0', 'pi0'])
778  B0.addChannel(['D-', 'pi+', 'pi+', 'pi-'])
779  B0.addChannel(['D-', 'pi+', 'pi+', 'pi-', 'pi0'])
780  B0.addChannel(['anti-D0', 'pi+', 'pi-'])
781  B0.addChannel(['D-', 'D0', 'K+'])
782  B0.addChannel(['D-', 'D*0', 'K+'])
783  B0.addChannel(['D*-', 'D0', 'K+'])
784  B0.addChannel(['D*-', 'D*0', 'K+'])
785  B0.addChannel(['D-', 'D+', 'K_S0'])
786  B0.addChannel(['D*-', 'D+', 'K_S0'])
787  B0.addChannel(['D-', 'D*+', 'K_S0'])
788  B0.addChannel(['D*-', 'D*+', 'K_S0'])
789  B0.addChannel(['D_s+', 'D-'])
790  B0.addChannel(['D*-', 'pi+'])
791  B0.addChannel(['D*-', 'pi+', 'pi0'])
792  B0.addChannel(['D*-', 'pi+', 'pi0', 'pi0'])
793  B0.addChannel(['D*-', 'pi+', 'pi+', 'pi-'])
794  B0.addChannel(['D*-', 'pi+', 'pi+', 'pi-', 'pi0'])
795  B0.addChannel(['D_s*+', 'D-'])
796  B0.addChannel(['D_s+', 'D*-'])
797  B0.addChannel(['D_s*+', 'D*-'])
798  B0.addChannel(['J/psi', 'K_S0'], preCutConfig=B0.preCutConfig._replace(noBackgroundSampling=True))
799  B0.addChannel(['J/psi', 'K+', 'pi-'])
800  B0.addChannel(['J/psi', 'K_S0', 'pi+', 'pi-'])
801  if baryonic:
802  B0.addChannel(['anti-Lambda_c-', 'p+', 'pi+', 'pi-'])
803  B0.addChannel(['anti-D0', 'p+', 'anti-p-'])
804  B0.addChannel(['D-', 'p+', 'anti-p-', 'pi+'])
805  B0.addChannel(['D*-', 'p+', 'anti-p-', 'pi+'])
806  B0.addChannel(['anti-D0', 'p+', 'anti-p-', 'pi+', 'pi-'])
807  B0.addChannel(['anti-D*0', 'p+', 'anti-p-', 'pi+', 'pi-'])
808 
809  B0_SL = Particle('B0:semileptonic',
810  MVAConfiguration(variables=B_SL_vars,
811  target='isSignalAcceptMissingNeutrino'),
812  PreCutConfiguration(userCut=semileptonic_user_cut,
813  bestCandidateMode='highest',
814  bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
815  bestCandidateCut=20),
816  PostCutConfiguration(bestCandidateCut=20))
817  B0_SL.addChannel(['D-', 'e+'])
818  B0_SL.addChannel(['D-', 'mu+'])
819  B0_SL.addChannel(['D*-', 'e+'])
820  B0_SL.addChannel(['D*-', 'mu+'])
821  B0_SL.addChannel(['anti-D0', 'pi-', 'e+'])
822  B0_SL.addChannel(['anti-D0', 'pi-', 'mu+'])
823  B0_SL.addChannel(['anti-D*0', 'pi-', 'e+'])
824  B0_SL.addChannel(['anti-D*0', 'pi-', 'mu+'])
825 
826  if not removeSLD:
827  B0_SL.addChannel(['D-:semileptonic', 'pi+'])
828  B0_SL.addChannel(['D-:semileptonic', 'pi+', 'pi0'])
829  B0_SL.addChannel(['D-:semileptonic', 'pi+', 'pi0', 'pi0'])
830  B0_SL.addChannel(['D-:semileptonic', 'pi+', 'pi+', 'pi-'])
831  B0_SL.addChannel(['D-:semileptonic', 'pi+', 'pi+', 'pi-', 'pi0'])
832  B0_SL.addChannel(['anti-D0:semileptonic', 'pi+', 'pi-'])
833  B0_SL.addChannel(['D-:semileptonic', 'D0', 'K+'])
834  B0_SL.addChannel(['D-:semileptonic', 'D*0', 'K+'])
835  B0_SL.addChannel(['D*-:semileptonic', 'D0', 'K+'])
836  B0_SL.addChannel(['D*-:semileptonic', 'D*0', 'K+'])
837  B0_SL.addChannel(['D-:semileptonic', 'D+', 'K_S0'])
838  B0_SL.addChannel(['D*-:semileptonic', 'D+', 'K_S0'])
839  B0_SL.addChannel(['D-:semileptonic', 'D*+', 'K_S0'])
840  B0_SL.addChannel(['D*-:semileptonic', 'D*+', 'K_S0'])
841  B0_SL.addChannel(['D-', 'D0:semileptonic', 'K+'])
842  B0_SL.addChannel(['D-', 'D*0:semileptonic', 'K+'])
843  B0_SL.addChannel(['D*-', 'D0:semileptonic', 'K+'])
844  B0_SL.addChannel(['D*-', 'D*0:semileptonic', 'K+'])
845  B0_SL.addChannel(['D-', 'D+:semileptonic', 'K_S0'])
846  B0_SL.addChannel(['D*-', 'D+:semileptonic', 'K_S0'])
847  B0_SL.addChannel(['D-', 'D*+:semileptonic', 'K_S0'])
848  B0_SL.addChannel(['D*-', 'D*+:semileptonic', 'K_S0'])
849  B0_SL.addChannel(['D_s+', 'D-:semileptonic'])
850  B0_SL.addChannel(['D*-:semileptonic', 'pi+'])
851  B0_SL.addChannel(['D*-:semileptonic', 'pi+', 'pi0'])
852  B0_SL.addChannel(['D*-:semileptonic', 'pi+', 'pi0', 'pi0'])
853  B0_SL.addChannel(['D*-:semileptonic', 'pi+', 'pi+', 'pi-'])
854  B0_SL.addChannel(['D*-:semileptonic', 'pi+', 'pi+', 'pi-', 'pi0'])
855  B0_SL.addChannel(['D_s*+', 'D-:semileptonic'])
856  B0_SL.addChannel(['D_s+', 'D*-:semileptonic'])
857  B0_SL.addChannel(['D_s*+', 'D*-:semileptonic'])
858 
859  if KLong:
860  B0_KL = Particle('B0:KL',
861  MVAConfiguration(variables=B_vars,
862  target='isSignal'),
863  PreCutConfiguration(userCut=semileptonic_user_cut,
864  bestCandidateMode='highest',
865  bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
866  bestCandidateCut=20),
867  PostCutConfiguration(bestCandidateCut=20))
868  B0_KL.addChannel(['D-:KL', 'pi+'])
869  B0_KL.addChannel(['D-:KL', 'pi+', 'pi0'])
870  B0_KL.addChannel(['D-:KL', 'pi+', 'pi0', 'pi0'])
871  B0_KL.addChannel(['D-:KL', 'pi+', 'pi+', 'pi-'])
872  B0_KL.addChannel(['D-:KL', 'pi+', 'pi+', 'pi-', 'pi0'])
873  B0_KL.addChannel(['anti-D0:KL', 'pi+', 'pi-'])
874  B0_KL.addChannel(['D-:KL', 'D0', 'K+'])
875  B0_KL.addChannel(['D-:KL', 'D*0', 'K+'])
876  B0_KL.addChannel(['D*-:KL', 'D0', 'K+'])
877  B0_KL.addChannel(['D*-:KL', 'D*0', 'K+'])
878  B0_KL.addChannel(['D-:KL', 'D+', 'K_S0'])
879  B0_KL.addChannel(['D*-:KL', 'D+', 'K_S0'])
880  B0_KL.addChannel(['D-:KL', 'D*+', 'K_S0'])
881  B0_KL.addChannel(['D*-:KL', 'D*+', 'K_S0'])
882  B0_KL.addChannel(['D-', 'D0:KL', 'K+'])
883  B0_KL.addChannel(['D-', 'D*0:KL', 'K+'])
884  B0_KL.addChannel(['D*-', 'D0:KL', 'K+'])
885  B0_KL.addChannel(['D*-', 'D*0:KL', 'K+'])
886  B0_KL.addChannel(['D-', 'D+:KL', 'K_S0'])
887  B0_KL.addChannel(['D*-', 'D+:KL', 'K_S0'])
888  B0_KL.addChannel(['D-', 'D*+:KL', 'K_S0'])
889  B0_KL.addChannel(['D*-', 'D*+:KL', 'K_S0'])
890  B0_KL.addChannel(['D_s+', 'D-:KL'])
891  B0_KL.addChannel(['D_s+:KL', 'D-'])
892  B0_KL.addChannel(['D*-:KL', 'pi+'])
893  B0_KL.addChannel(['D*-:KL', 'pi+', 'pi0'])
894  B0_KL.addChannel(['D*-:KL', 'pi+', 'pi0', 'pi0'])
895  B0_KL.addChannel(['D*-:KL', 'pi+', 'pi+', 'pi-'])
896  B0_KL.addChannel(['D*-:KL', 'pi+', 'pi+', 'pi-', 'pi0'])
897  B0_KL.addChannel(['D_s*+', 'D-:KL'])
898  B0_KL.addChannel(['D_s+', 'D*-:KL'])
899  B0_KL.addChannel(['D_s*+', 'D*-:KL'])
900  B0_KL.addChannel(['D_s*+:KL', 'D-'])
901  B0_KL.addChannel(['D_s+:KL', 'D*-'])
902  B0_KL.addChannel(['D_s*+:KL', 'D*-'])
903  B0_KL.addChannel(['D-', 'D+', 'K_L0'])
904  B0_KL.addChannel(['D*-', 'D+', 'K_L0'])
905  B0_KL.addChannel(['D-', 'D*+', 'K_L0'])
906  B0_KL.addChannel(['D*-', 'D*+', 'K_L0'])
907  B0_KL.addChannel(['J/psi', 'K_L0'])
908  B0_KL.addChannel(['J/psi', 'K_L0', 'pi+', 'pi-'])
909 
910  # Use deltaE + Mbc - m_(B_s) instead of deltaE since Bs has only one peak here (vs. 3 in deltaE)
911  Bs_vars = ['formula(deltaE+Mbc-5.3669)' if x == 'deltaE' else x for x in B_vars]
912 
913  hadronic_bs_user_cut = 'Mbc > 5.3 and abs(formula(deltaE+Mbc-5.3669)) < 0.5'
914  if B_extra_cut is not None:
915  hadronic_bs_user_cut += ' and [' + B_extra_cut + ']'
916 
917  BS = Particle('B_s0',
918  MVAConfiguration(variables=Bs_vars,
919  target='isSignal'),
920  PreCutConfiguration(userCut=hadronic_bs_user_cut,
921  bestCandidateMode='highest',
922  bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
923  bestCandidateCut=20),
924  PostCutConfiguration(bestCandidateCut=20))
925 
926  # Override precut for some channels as this provides better performance
927  tight_precut = BS.preCutConfig._replace(userCut=hadronic_bs_user_cut + ' and abs(formula(deltaE+Mbc-5.3669)) < 0.1')
928 
929  # D_s & D*
930  BS.addChannel(['D_s-', 'D_s+'], preCutConfig=tight_precut)
931  BS.addChannel(['D_s*+', 'D_s-'], preCutConfig=tight_precut)
932  BS.addChannel(['D_s*-', 'D_s+'], preCutConfig=tight_precut)
933  BS.addChannel(['D_s*+', 'D_s*-'], preCutConfig=tight_precut)
934  BS.addChannel(['D_s-', 'D+'], preCutConfig=tight_precut)
935  BS.addChannel(['D_s+', 'D*-'])
936  BS.addChannel(['D_s*+', 'D-'])
937  BS.addChannel(['D_s*+', 'D*-'])
938 
939  # D_s
940  BS.addChannel(['D_s-', 'K+'])
941  BS.addChannel(['D_s+', 'K-'])
942  BS.addChannel(['D_s-', 'pi+'])
943  BS.addChannel(['D_s-', 'pi+', 'pi+', 'pi-'], preCutConfig=tight_precut)
944  BS.addChannel(['D_s-', 'D0', 'K+'], preCutConfig=tight_precut)
945  BS.addChannel(['D_s-', 'D+', 'K_S0'])
946  BS.addChannel(['D_s-', 'pi+', 'pi0'], preCutConfig=tight_precut) # rho+
947  BS.addChannel(['D_s-', 'D0', 'K+', 'pi0'], preCutConfig=tight_precut) # K*+
948  BS.addChannel(['D_s-', 'D0', 'K_S0', 'pi+']) # K*+
949  BS.addChannel(['D_s-', 'D+', 'K+', 'pi-']) # K*0
950  BS.addChannel(['D_s-', 'D+', 'K_S0', 'pi0']) # K*0
951  BS.addChannel(['D_s-', 'D*0', 'K+'], preCutConfig=tight_precut)
952  BS.addChannel(['D_s-', 'D*+', 'K_S0'])
953  BS.addChannel(['D_s-', 'D*0', 'K+', 'pi0']) # K*+
954  BS.addChannel(['D_s-', 'D*0', 'K_S0', 'pi+']) # K*+
955  BS.addChannel(['D_s-', 'D*+', 'K+', 'pi-']) # K*0
956  BS.addChannel(['D_s-', 'D*+', 'K_S0', 'pi0']) # K*0
957 
958  # D_s*
959  BS.addChannel(['D_s*-', 'K+'])
960  BS.addChannel(['D_s*-', 'pi+'])
961  BS.addChannel(['D_s*-', 'D0', 'K+'], preCutConfig=tight_precut)
962  BS.addChannel(['D_s*-', 'D+', 'K_S0'])
963  BS.addChannel(['D_s*-', 'D*0', 'K+'], preCutConfig=tight_precut)
964  BS.addChannel(['D_s*-', 'D*+', 'K_S0'])
965  BS.addChannel(['D_s*-', 'pi+', 'pi+', 'pi-'], preCutConfig=tight_precut)
966  BS.addChannel(['D_s*-', 'pi+', 'pi0'], preCutConfig=tight_precut) # rho+
967  BS.addChannel(['D_s*-', 'D0', 'K+', 'pi0']) # K*+
968  BS.addChannel(['D_s*-', 'D0', 'K_S0', 'pi+']) # K*+
969  BS.addChannel(['D_s*-', 'D+', 'K+', 'pi-']) # K*0
970  BS.addChannel(['D_s*-', 'D+', 'K_S0', 'pi0']) # K*0
971  BS.addChannel(['D_s*-', 'D*0', 'K+', 'pi0']) # K*+
972  BS.addChannel(['D_s*-', 'D*0', 'K_S0', 'pi+']) # K*+
973  BS.addChannel(['D_s*-', 'D*+', 'K+', 'pi-']) # K*0
974  BS.addChannel(['D_s*-', 'D*+', 'K_S0', 'pi0']) # K*0
975 
976  # J/Psi
977  BS.addChannel(['J/psi', 'K_S0'])
978  BS.addChannel(['J/psi', 'pi+', 'pi-'])
979  BS.addChannel(['J/psi', 'K+', 'K-'], preCutConfig=BS.preCutConfig._replace(noBackgroundSampling=True)) # Phi
980  BS.addChannel(['J/psi', 'K_S0', 'K-', 'pi+'])
981  BS.addChannel(['J/psi', 'K-', 'K+', 'pi0'])
982  BS.addChannel(['J/psi', 'pi-', 'pi+', 'pi0']) # Eta
983  BS.addChannel(['J/psi', 'pi+', 'pi-', 'pi-', 'pi+', 'pi0']) # Etaprime
984 
985  # Other
986  BS.addChannel(['anti-D*0', 'K_S0'])
987  BS.addChannel(['anti-D0', 'K_S0'])
988  BS.addChannel(['anti-D0', 'K-', 'pi+'])
989 
990  particles = []
991  particles.append(pion)
992  particles.append(kaon)
993  if baryonic:
994  particles.append(proton)
995  particles.append(muon)
996  particles.append(electron)
997  particles.append(gamma)
998 
999  particles.append(pi0)
1000  particles.append(KS0)
1001  if baryonic:
1002  particles.append(L0)
1003  particles.append(SigmaP)
1004  particles.append(Jpsi)
1005 
1006  particles.append(D0)
1007  particles.append(DP)
1008  particles.append(DS)
1009  if baryonic:
1010  particles.append(LC)
1011 
1012  particles.append(DS0)
1013  particles.append(DSP)
1014  particles.append(DSS)
1015 
1016  if hadronic:
1017  if neutralB:
1018  particles.append(B0)
1019  if chargedB:
1020  particles.append(BP)
1021 
1022  if KLong:
1023  particles.append(KL0)
1024  particles.append(D0_KL)
1025  particles.append(DP_KL)
1026  particles.append(DS_KL)
1027  particles.append(DS0_KL)
1028  particles.append(DSP_KL)
1029  particles.append(DSS_KL)
1030  if neutralB:
1031  particles.append(B0_KL)
1032  if chargedB:
1033  particles.append(BP_KL)
1034 
1035  if semileptonic:
1036  if not removeSLD:
1037  particles.append(D0_SL)
1038  particles.append(DP_SL)
1039  particles.append(DS0_SL)
1040  particles.append(DSP_SL)
1041  if neutralB:
1042  particles.append(B0_SL)
1043  if chargedB:
1044  particles.append(BP_SL)
1045 
1046  if strangeB:
1047  particles.append(BS)
1048 
1049  return particles
1050 
1051 
1052 def get_unittest_channels(specific=False):
1053  chargedVariables = ['electronID', 'extraInfo(preCut_rank)',
1054  'kaonID', 'protonID', 'muonID',
1055  'p', 'pt', 'pz', 'dr', 'dz', 'chiProb']
1056 
1057  specific_cut = ''
1058  if specific:
1059  specific_cut = ' and isInRestOfEvent > 0.5'
1060 
1061  pion = Particle('pi+',
1062  MVAConfiguration(variables=chargedVariables,
1063  target='isPrimarySignal'),
1064  PreCutConfiguration(userCut='[dr < 2] and [abs(dz) < 4]' + specific_cut,
1065  bestCandidateMode='highest',
1066  bestCandidateVariable='pionID',
1067  bestCandidateCut=20),
1068  PostCutConfiguration(bestCandidateCut=10, value=0.01))
1069  pion.addChannel(['pi+:FSP'])
1070 
1071  kaon = Particle('K+',
1072  MVAConfiguration(variables=chargedVariables,
1073  target='isPrimarySignal'),
1074  PreCutConfiguration(userCut='[dr < 2] and [abs(dz) < 4]' + specific_cut,
1075  bestCandidateMode='highest',
1076  bestCandidateVariable='kaonID',
1077  bestCandidateCut=20),
1078  PostCutConfiguration(bestCandidateCut=10, value=0.01))
1079  kaon.addChannel(['K+:FSP'])
1080 
1081  muon = Particle('mu+',
1082  MVAConfiguration(variables=chargedVariables,
1083  target='isPrimarySignal'),
1084  PreCutConfiguration(userCut='[dr < 2] and [abs(dz) < 4]' + specific_cut,
1085  bestCandidateVariable='muonID',
1086  bestCandidateMode='highest',
1087  bestCandidateCut=10),
1088  PostCutConfiguration(bestCandidateCut=5, value=0.01))
1089  muon.addChannel(['mu+:FSP'])
1090 
1091  gamma = Particle('gamma',
1092  MVAConfiguration(variables=['clusterReg', 'clusterNHits', 'clusterTiming', 'clusterE9E25',
1093  'pt', 'E', 'pz', 'extraInfo(preCut_rank)'],
1094  target='isPrimarySignal'),
1095  PreCutConfiguration(userCut='E > 0.05' + specific_cut,
1096  bestCandidateMode='highest',
1097  bestCandidateVariable='E',
1098  bestCandidateCut=40),
1099  PostCutConfiguration(bestCandidateCut=20, value=0.01))
1100  gamma.addChannel(['gamma:FSP'])
1101  gamma.addChannel(['gamma:V0'],
1102  MVAConfiguration(variables=['pt', 'E', 'pz'],
1103  target='isPrimarySignal'))
1104 
1105  pi0 = Particle('pi0',
1106  MVAConfiguration(variables=['M', 'daughter({},extraInfo(SignalProbability))', 'extraInfo(preCut_rank)',
1107  'daughterAngle(0,1)', 'pt', 'pz', 'E', 'abs(dM)'],
1108  target='isSignal'),
1109  PreCutConfiguration(userCut='0.08 < M < 0.18',
1110  bestCandidateVariable='abs(dM)',
1111  bestCandidateCut=20),
1112  PostCutConfiguration(bestCandidateCut=10, value=0.01))
1113  pi0.addChannel(['gamma', 'gamma'])
1114 
1115  intermediate_vars = ['daughterProductOf(extraInfo(SignalProbability))', 'daughter({},extraInfo(SignalProbability))',
1116  'chiProb', 'daughter({}, chiProb)', 'extraInfo(preCut_rank)', 'abs(dM)',
1117  'useRestFrame(daughter({}, p))',
1118  'useRestFrame(daughter({}, distance))',
1119  'decayAngle({})', 'daughterAngle({},{})', 'cosAngleBetweenMomentumAndVertexVector',
1120  'daughterInvariantMass({},{})', 'daughterInvariantMass({},{},{})', 'daughterInvariantMass({},{},{},{})',
1121  'daughterInvariantMass({},{},{},{},{})', 'dQ', 'Q', 'dM', 'daughter({},extraInfo(decayModeID))']
1122 
1123  D0 = Particle('D0',
1124  MVAConfiguration(variables=intermediate_vars,
1125  target='isSignal'),
1126  PreCutConfiguration(userCut='1.7 < M < 1.95',
1127  bestCandidateVariable='abs(dM)',
1128  bestCandidateCut=20),
1129  PostCutConfiguration(bestCandidateCut=10, value=0.001))
1130  D0.addChannel(['K-', 'pi+'])
1131  D0.addChannel(['K-', 'pi+', 'pi0'])
1132  D0.addChannel(['pi-', 'pi+'])
1133 
1134  D0_SL = Particle('D0:semileptonic',
1135  MVAConfiguration(variables=intermediate_vars,
1136  target='isSignalAcceptMissingNeutrino'),
1137  PreCutConfiguration(userCut='',
1138  bestCandidateMode='highest',
1139  bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
1140  bestCandidateCut=20),
1141  PostCutConfiguration(bestCandidateCut=10, value=0.001))
1142 
1143  D0_SL.addChannel(['K-', 'mu+'])
1144  D0_SL.addChannel(['K-', 'pi0', 'mu+'])
1145 
1146  particles = [gamma, muon, pion, kaon, pi0, D0, D0_SL]
1147  return particles
1148 
1149 
1150 def get_fr_channels(convertedFromBelle=False):
1151  """
1152  Get channels of original FR for comparison
1153  @param convertedFromBelle whether to use Belle variables which is necessary for b2bii converted data (default is False)
1154  """
1155 
1156  if convertedFromBelle:
1157  # Using Belle specific Variables for e-ID, mu-ID and K-ID
1158  # atcPIDBelle(3,2) is used as K-ID
1159  # atcPIDBelle(4,2) and atcPIDBelle(4,3) are used as pr-ID
1160  chargedVariables = ['eIDBelle',
1161  'atcPIDBelle(3,2)',
1162  'atcPIDBelle(4,2)', 'atcPIDBelle(4,3)',
1163  'muIDBelle',
1164  'p', 'pt', 'pz', 'dr', 'dz', 'chiProb', 'extraInfo(preCut_rank)']
1165  else:
1166  chargedVariables = ['electronID', 'kaonID', 'protonID', 'muonID',
1167  'p', 'pt', 'pz', 'dr', 'dz', 'chiProb', 'extraInfo(preCut_rank)']
1168 
1169  charged_user_cut = '[dr < 2] and [abs(dz) < 4]'
1170 
1171  pion = Particle('pi+',
1172  MVAConfiguration(variables=chargedVariables,
1173  target='isPrimarySignal'),
1174  PreCutConfiguration(userCut=charged_user_cut,
1175  bestCandidateMode='highest',
1176  bestCandidateVariable='pionID' if not convertedFromBelle else 'atcPIDBelle(2,3)',
1177  bestCandidateCut=20),
1178  PostCutConfiguration(bestCandidateCut=10, value=0.01))
1179  pion.addChannel(['pi+:FSP'])
1180 
1181  kaon = Particle('K+',
1182  MVAConfiguration(variables=chargedVariables,
1183  target='isPrimarySignal'),
1184  PreCutConfiguration(userCut=charged_user_cut,
1185  bestCandidateMode='highest',
1186  bestCandidateVariable='kaonID' if not convertedFromBelle else 'atcPIDBelle(3,2)',
1187  bestCandidateCut=20),
1188  PostCutConfiguration(bestCandidateCut=10, value=0.01))
1189  kaon.addChannel(['K+:FSP'])
1190 
1191  electron = Particle('e+',
1192  MVAConfiguration(variables=chargedVariables,
1193  target='isPrimarySignal'),
1194  PreCutConfiguration(userCut=charged_user_cut,
1195  bestCandidateMode='highest',
1196  bestCandidateVariable='electronID' if not convertedFromBelle else 'eIDBelle',
1197  bestCandidateCut=10),
1198  PostCutConfiguration(bestCandidateCut=10, value=0.01))
1199  electron.addChannel(['e+:FSP'])
1200 
1201  muon = Particle('mu+',
1202  MVAConfiguration(variables=chargedVariables,
1203  target='isPrimarySignal'),
1204  PreCutConfiguration(userCut=charged_user_cut,
1205  bestCandidateMode='highest',
1206  bestCandidateVariable='muonID' if not convertedFromBelle else 'muIDBelle',
1207  bestCandidateCut=10),
1208  PostCutConfiguration(bestCandidateCut=10, value=0.01))
1209  muon.addChannel(['mu+:FSP'])
1210 
1211  high_energy_photon = '[[clusterReg == 1 and E > 0.10] or [clusterReg == 2 and E > 0.09] or [clusterReg == 3 and E > 0.16]]'
1212  gamma = Particle('gamma',
1213  MVAConfiguration(variables=['clusterReg', 'clusterNHits', 'clusterTiming', 'extraInfo(preCut_rank)',
1214  'clusterE9E25', 'pt', 'E', 'pz'],
1215  target='isPrimarySignal'),
1216  PreCutConfiguration(userCut=high_energy_photon if not convertedFromBelle else
1217  'goodBelleGamma == 1 and clusterBelleQuality == 0',
1218  bestCandidateMode='highest',
1219  bestCandidateVariable='E',
1220  bestCandidateCut=40),
1221  PostCutConfiguration(bestCandidateCut=20, value=0.01))
1222  gamma.addChannel(['gamma:FSP'])
1223  gamma.addChannel(['gamma:V0'],
1224  MVAConfiguration(variables=['pt', 'E', 'pz', 'extraInfo(preCut_rank)'],
1225  target='isPrimarySignal'),
1226  PreCutConfiguration(userCut='',
1227  bestCandidateMode='highest',
1228  bestCandidateVariable='E',
1229  bestCandidateCut=40))
1230 
1231  if convertedFromBelle:
1232 
1233  pi0 = Particle('pi0',
1234  MVAConfiguration(variables=['InvM', 'extraInfo(preCut_rank)', 'chiProb', 'abs(BellePi0SigM)',
1235  'daughterAngle(0,1)', 'pt', 'pz', 'E'],
1236  target='isSignal'),
1237  PreCutConfiguration(userCut='0.08 < InvM < 0.18',
1238  bestCandidateVariable='abs(BellePi0SigM)',
1239  bestCandidateCut=20),
1240  PostCutConfiguration(bestCandidateCut=10, value=0.01))
1241  pi0.addChannel(['pi0:FSP'])
1242 
1243  KS0 = Particle('K_S0',
1244  MVAConfiguration(variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M', 'abs(dM)',
1245  'useCMSFrame(E)', 'daughterAngle(0,1)',
1246  'cosAngleBetweenMomentumAndVertexVector',
1247  'extraInfo(preCut_rank)', 'extraInfo(goodKs)', 'extraInfo(ksnbVLike)',
1248  'extraInfo(ksnbNoLam)', 'extraInfo(ksnbStandard)'],
1249  target='isSignal'),
1250  PreCutConfiguration(userCut='0.4 < M < 0.6',
1251  bestCandidateVariable='abs(dM)',
1252  bestCandidateCut=20),
1253  PostCutConfiguration(bestCandidateCut=10, value=0.01))
1254  KS0.addChannel(['K_S0:V0'])
1255 
1256  else:
1257 
1258  pi0 = Particle('pi0',
1259  MVAConfiguration(variables=['M', 'daughter({},extraInfo(SignalProbability))', 'extraInfo(preCut_rank)',
1260  'daughterAngle(0,1)', 'pt', 'pz', 'E', 'abs(dM)'],
1261  target='isSignal'),
1262  PreCutConfiguration(userCut='0.08 < M < 0.18',
1263  bestCandidateVariable='abs(dM)',
1264  bestCandidateCut=20),
1265  PostCutConfiguration(bestCandidateCut=10, value=0.01))
1266  pi0.addChannel(['gamma', 'gamma'])
1267 
1268  KS0 = Particle('K_S0',
1269  MVAConfiguration(variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M', 'abs(dM)',
1270  'useCMSFrame(E)', 'daughterAngle(0,1)',
1271  'daughter({},extraInfo(SignalProbability))',
1272  'useRestFrame(daughter({}, p))', 'cosAngleBetweenMomentumAndVertexVector',
1273  'daughter({}, dz)', 'daughter({}, dr)', 'extraInfo(preCut_rank)'],
1274  target='isSignal'),
1275  PreCutConfiguration(userCut='0.4 < M < 0.6',
1276  bestCandidateVariable='abs(dM)',
1277  bestCandidateCut=20),
1278  PostCutConfiguration(bestCandidateCut=10, value=0.01))
1279  KS0.addChannel(['pi+', 'pi-'])
1280  KS0.addChannel(['pi0', 'pi0'])
1281  KS0.addChannel(['K_S0:V0'],
1282  MVAConfiguration(variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M',
1283  'useCMSFrame(E)', 'daughterAngle(0,1)', 'extraInfo(preCut_rank)', 'abs(dM)',
1284  'useRestFrame(daughter({}, p))', 'cosAngleBetweenMomentumAndVertexVector',
1285  'daughter({}, dz)', 'daughter({}, dr)'],
1286  target='isSignal'))
1287 
1288  # variables for D mesons and J/Psi
1289  intermediate_vars = ['daughterProductOf(extraInfo(SignalProbability))', 'daughter({},extraInfo(SignalProbability))',
1290  'chiProb', 'daughter({}, chiProb)', 'extraInfo(preCut_rank)', 'abs(dM)',
1291  'useRestFrame(daughter({}, p))',
1292  'useRestFrame(daughter({}, distance))',
1293  'decayAngle({})', 'daughterAngle({},{})', 'cosAngleBetweenMomentumAndVertexVector',
1294  'daughterInvariantMass({},{})', 'daughterInvariantMass({},{},{})', 'daughterInvariantMass({},{},{},{})',
1295  'daughterInvariantMass({},{},{},{},{})', 'dQ', 'Q', 'dM', 'daughter({},extraInfo(decayModeID))']
1296 
1297  D0 = Particle('D0',
1298  MVAConfiguration(variables=intermediate_vars,
1299  target='isSignal'),
1300  PreCutConfiguration(userCut='1.7 < M < 1.95',
1301  bestCandidateVariable='abs(dM)',
1302  bestCandidateCut=20),
1303  PostCutConfiguration(bestCandidateCut=10, value=0.001))
1304  D0.addChannel(['K-', 'pi+'])
1305  D0.addChannel(['K-', 'pi+', 'pi0'])
1306  D0.addChannel(['K-', 'pi+', 'pi+', 'pi-'])
1307  D0.addChannel(['pi-', 'pi+'])
1308  D0.addChannel(['pi-', 'pi+', 'pi0'])
1309  D0.addChannel(['K_S0', 'pi0'])
1310  D0.addChannel(['K_S0', 'pi+', 'pi-'])
1311  D0.addChannel(['K_S0', 'pi+', 'pi-', 'pi0'])
1312  D0.addChannel(['K-', 'K+'])
1313  D0.addChannel(['K-', 'K+', 'K_S0'])
1314 
1315  DP = Particle('D+',
1316  MVAConfiguration(variables=intermediate_vars,
1317  target='isSignal'),
1318  PreCutConfiguration(userCut='1.7 < M < 1.95',
1319  bestCandidateVariable='abs(dM)',
1320  bestCandidateCut=20),
1321  PostCutConfiguration(bestCandidateCut=10, value=0.001))
1322 
1323  DP.addChannel(['K-', 'pi+', 'pi+'])
1324  DP.addChannel(['K-', 'pi+', 'pi+', 'pi0'])
1325  DP.addChannel(['K-', 'K+', 'pi+'])
1326  DP.addChannel(['K-', 'K+', 'pi+', 'pi0'])
1327  DP.addChannel(['K_S0', 'pi+'])
1328  DP.addChannel(['K_S0', 'pi+', 'pi0'])
1329  DP.addChannel(['K_S0', 'pi+', 'pi+', 'pi-'])
1330 
1331  Jpsi = Particle('J/psi',
1332  MVAConfiguration(variables=intermediate_vars,
1333  target='isSignal'),
1334  PreCutConfiguration(userCut='2.5 < M < 3.7',
1335  bestCandidateVariable='abs(dM)',
1336  bestCandidateCut=20),
1337  PostCutConfiguration(bestCandidateCut=10, value=0.001))
1338 
1339  Jpsi.addChannel(['e+', 'e-'])
1340  Jpsi.addChannel(['mu+', 'mu-'])
1341 
1342  DSP = Particle('D*+',
1343  MVAConfiguration(variables=intermediate_vars,
1344  target='isSignal'),
1345  PreCutConfiguration(userCut='0 < Q < 0.3',
1346  bestCandidateVariable='abs(dQ)',
1347  bestCandidateCut=20),
1348  PostCutConfiguration(bestCandidateCut=10, value=0.001))
1349 
1350  DSP.addChannel(['D0', 'pi+'])
1351  DSP.addChannel(['D+', 'pi0'])
1352 
1353  DS0 = Particle('D*0',
1354  MVAConfiguration(variables=intermediate_vars,
1355  target='isSignal'),
1356  PreCutConfiguration(userCut='0 < Q < 0.3',
1357  bestCandidateVariable='abs(dQ)',
1358  bestCandidateCut=20),
1359  PostCutConfiguration(bestCandidateCut=10, value=0.001))
1360 
1361  DS0.addChannel(['D0', 'pi0'])
1362  DS0.addChannel(['D0', 'gamma'])
1363 
1364  DS = Particle('D_s+',
1365  MVAConfiguration(variables=intermediate_vars,
1366  target='isSignal'),
1367  PreCutConfiguration(userCut='1.68 < M < 2.1',
1368  bestCandidateVariable='abs(dM)',
1369  bestCandidateCut=20),
1370  PostCutConfiguration(bestCandidateCut=10, value=0.001))
1371 
1372  DS.addChannel(['K+', 'K_S0'])
1373  DS.addChannel(['K+', 'pi+', 'pi-'])
1374  DS.addChannel(['K+', 'K-', 'pi+'])
1375  DS.addChannel(['K+', 'K-', 'pi+', 'pi0'])
1376  DS.addChannel(['K+', 'K_S0', 'pi+', 'pi-'])
1377  DS.addChannel(['K-', 'K_S0', 'pi+', 'pi+'])
1378  DS.addChannel(['K+', 'K-', 'pi+', 'pi+', 'pi-'])
1379  DS.addChannel(['pi+', 'pi+', 'pi-'])
1380 
1381  DSS = Particle('D_s*+',
1382  MVAConfiguration(variables=intermediate_vars,
1383  target='isSignal'),
1384  PreCutConfiguration(userCut='0.0 < Q < 0.3',
1385  bestCandidateVariable='abs(dQ)',
1386  bestCandidateCut=20),
1387  PostCutConfiguration(bestCandidateCut=10, value=0.001))
1388 
1389  DSS.addChannel(['D_s+', 'gamma'])
1390 
1391  # note: these should not be correlated to Mbc (weak correlation of deltaE is OK)
1392  B_vars = ['daughterProductOf(extraInfo(SignalProbability))', 'daughter({},extraInfo(SignalProbability))',
1393  'chiProb', 'daughter({}, chiProb)', 'extraInfo(preCut_rank)',
1394  'useRestFrame(daughter({}, p))',
1395  'useRestFrame(daughter({}, distance))',
1396  'decayAngle({})', 'daughterAngle({},{})', 'cosAngleBetweenMomentumAndVertexVector',
1397  'dr', 'dz', 'dx', 'dy', 'distance', 'significanceOfDistance', 'deltaE', 'daughter({},extraInfo(decayModeID))']
1398 
1399  hadronic_user_cut = 'Mbc > 5.2 and abs(deltaE) < 0.5'
1400 
1401  BP = Particle('B+',
1402  MVAConfiguration(variables=B_vars,
1403  target='isSignal'),
1404  PreCutConfiguration(userCut=hadronic_user_cut,
1405  bestCandidateMode='highest',
1406  bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
1407  bestCandidateCut=20),
1408  PostCutConfiguration(bestCandidateCut=20))
1409 
1410  BP.addChannel(['anti-D0', 'pi+'])
1411  BP.addChannel(['anti-D0', 'pi+', 'pi0'])
1412  BP.addChannel(['anti-D0', 'pi+', 'pi+', 'pi-'])
1413  BP.addChannel(['anti-D0', 'D+'])
1414  BP.addChannel(['D_s+', 'anti-D0'])
1415  BP.addChannel(['anti-D*0', 'pi+'])
1416  BP.addChannel(['anti-D*0', 'pi+', 'pi0'])
1417  BP.addChannel(['anti-D*0', 'pi+', 'pi+', 'pi-'])
1418  BP.addChannel(['anti-D*0', 'pi+', 'pi+', 'pi-', 'pi0'])
1419  BP.addChannel(['D_s*+', 'anti-D0'])
1420  BP.addChannel(['D_s+', 'anti-D*0'])
1421  BP.addChannel(['anti-D0', 'K+'])
1422  BP.addChannel(['D-', 'pi+', 'pi+'])
1423  BP.addChannel(['J/psi', 'K+'])
1424  BP.addChannel(['J/psi', 'K+', 'pi+', 'pi-'])
1425  BP.addChannel(['J/psi', 'K+', 'pi0'])
1426  BP.addChannel(['J/psi', 'K_S0', 'pi+'])
1427 
1428  B0 = Particle('B0',
1429  MVAConfiguration(variables=B_vars,
1430  target='isSignal'),
1431  PreCutConfiguration(userCut=hadronic_user_cut,
1432  bestCandidateMode='highest',
1433  bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
1434  bestCandidateCut=20),
1435  PostCutConfiguration(bestCandidateCut=20))
1436  B0.addChannel(['D-', 'pi+'])
1437  B0.addChannel(['D-', 'pi+', 'pi0'])
1438  B0.addChannel(['D-', 'pi+', 'pi+', 'pi-'])
1439  B0.addChannel(['anti-D0', 'pi0'])
1440  B0.addChannel(['D_s+', 'D-'])
1441  B0.addChannel(['D*-', 'pi+'])
1442  B0.addChannel(['D*-', 'pi+', 'pi0'])
1443  B0.addChannel(['D*-', 'pi+', 'pi+', 'pi-'])
1444  B0.addChannel(['D*-', 'pi+', 'pi+', 'pi-', 'pi0'])
1445  B0.addChannel(['D_s*+', 'D-'])
1446  B0.addChannel(['D_s+', 'D*-'])
1447  B0.addChannel(['D_s*+', 'D*-'])
1448  B0.addChannel(['J/psi', 'K_S0'])
1449  B0.addChannel(['J/psi', 'K+', 'pi-'])
1450  B0.addChannel(['J/psi', 'K_S0', 'pi+', 'pi-'])
1451 
1452  particles = []
1453  particles.append(pion)
1454  particles.append(kaon)
1455  particles.append(muon)
1456  particles.append(electron)
1457  particles.append(gamma)
1458 
1459  particles.append(pi0)
1460  particles.append(KS0)
1461  particles.append(Jpsi)
1462 
1463  particles.append(D0)
1464  particles.append(DP)
1465  particles.append(DS)
1466 
1467  particles.append(DS0)
1468  particles.append(DSP)
1469  particles.append(DSS)
1470 
1471  particles.append(B0)
1472  particles.append(BP)
1473 
1474  return particles
def isB2BII()
Definition: b2bii.py:14