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