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