Belle II Software prerelease-10-00-00a
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
28import b2bii
29from fei import Particle, MVAConfiguration, PreCutConfiguration, PostCutConfiguration
30from basf2 import B2FATAL, B2INFO
31from variables import variables
32
33
34def get_default_channels(
35 B_extra_cut=None,
36 hadronic=True,
37 semileptonic=True,
38 KLong=False,
39 baryonic=True,
40 chargedB=True,
41 neutralB=True,
42 specific=False,
43 removeSLD=False,
44 usePIDNN=False,
45 strangeB=False):
46 """
47 returns list of Particle objects with all default channels for running
48 FEI on Upsilon(4S). For a training with analysis-specific signal selection,
49 adding a cut on nRemainingTracksInRestOfEvent is recommended.
50 @param B_extra_cut Additional user cut on recombination of tag-B-mesons
51 @param hadronic whether to include hadronic B decays (default is True)
52 @param semileptonic whether to include semileptonic B decays (default is True)
53 @param KLong whether to include K_long decays into the training (default is False)
54 @param baryonic whether to include baryons into the training (default is True)
55 @param chargedB whether to recombine charged B mesons (default is True)
56 @param neutralB whether to recombine neutral B mesons (default is True)
57 @param specific if True, this adds isInRestOfEvent cut to all FSP
58 @param removeSLD if True, removes semileptonic D modes from semileptonic B lists (default is False)
59 @param usePIDNN if True, PID probabilities calculated from PID neural network are used (default is False)
60 @param strangeB if True, reconstruct B_s mesons in Upsilon5S decays (default is False)
61 """
62 if strangeB is True:
63 B2INFO('Running 5S FEI')
64 if chargedB is False and neutralB is False and strangeB is False:
65 B2FATAL('No B-Mesons will be recombined, since chargedB==False and neutralB==False and strangeB==False was selected!'
66 ' Please reconfigure the arguments of get_default_channels() accordingly')
67 if hadronic is False and semileptonic is False:
68 if KLong is False:
69 B2FATAL('No B-Mesons will be recombined, since hadronic==False, semileptonic==False, and KLong==False were selected.'
70 ' Please reconfigure the arguments of get_default_channels() accordingly')
71
72 convertedFromBelle = b2bii.isB2BII()
73
74 if convertedFromBelle:
75 if usePIDNN:
76 B2FATAL("The PIDNN variables do not exist for b2bii.")
77 # Using Belle specific Variables for e-ID, mu-ID and K-ID
78 # atcPIDBelle(3,2) is used as K-ID
79 # atcPIDBelle(4,2) and atcPIDBelle(4,3) are used as pr-ID
80
81 chargedVariables = ['eIDBelle',
82 'atcPIDBelle(3,2)',
83 'atcPIDBelle(4,2)', 'atcPIDBelle(4,3)',
84 'muIDBelle'
85 ]
86 else:
87 if usePIDNN:
88 chargedVariables = ['electronIDNN', 'kaonIDNN', 'protonIDNN', 'muonIDNN']
89 else:
90 chargedVariables = ['electronID', 'kaonID', 'protonID', 'muonID']
91
92 chargedVariables += ['p', 'pt', 'pz', 'dr', 'dz', 'chiProb', 'extraInfo(preCut_rank)']
93
94 if specific:
95 charged_user_cut = '[dr < 2] and [abs(dz) < 4] and isInRestOfEvent > 0.5'
96 else:
97 charged_user_cut = '[dr < 2] and [abs(dz) < 4]'
98
99 pion = Particle('pi+',
100 MVAConfiguration(variables=chargedVariables,
101 target='isPrimarySignal'),
102 PreCutConfiguration(userCut=charged_user_cut,
103 bestCandidateMode='highest',
104 bestCandidateVariable="atcPIDBelle(2,3)" if convertedFromBelle
105 else ("pionIDNN" if usePIDNN else "pionID"),
106 bestCandidateCut=20),
107 PostCutConfiguration(bestCandidateCut=10, value=0.01))
108 pion.addChannel(['pi+:FSP'])
109
110 kaon = Particle('K+',
111 MVAConfiguration(variables=chargedVariables,
112 target='isPrimarySignal'),
113 PreCutConfiguration(userCut=charged_user_cut,
114 bestCandidateMode='highest',
115 bestCandidateVariable="atcPIDBelle(3,2)" if convertedFromBelle
116 else ("kaonIDNN" if usePIDNN else "kaonID"),
117 bestCandidateCut=20),
118 PostCutConfiguration(bestCandidateCut=10, value=0.01))
119 kaon.addChannel(['K+:FSP'])
120
121 proton = Particle('p+',
122 MVAConfiguration(variables=chargedVariables,
123 target='isPrimarySignal'),
124 PreCutConfiguration(userCut=charged_user_cut,
125 bestCandidateMode='highest',
126 bestCandidateVariable="atcPIDBelle(4,3)" if convertedFromBelle
127 else ("protonIDNN" if usePIDNN else "protonID"),
128 bestCandidateCut=20),
129 PostCutConfiguration(bestCandidateCut=10, value=0.01))
130 proton.addChannel(['p+:FSP'])
131
132 electron = Particle('e+',
133 MVAConfiguration(variables=chargedVariables,
134 target='isPrimarySignal'),
135 PreCutConfiguration(userCut=charged_user_cut,
136 bestCandidateMode='highest',
137 bestCandidateVariable="eIDBelle" if convertedFromBelle
138 else ("electronIDNN" if usePIDNN else "electronID"),
139 bestCandidateCut=10),
140 PostCutConfiguration(bestCandidateCut=5, value=0.01))
141 electron.addChannel(['e+:FSP'])
142
143 muon = Particle('mu+',
144 MVAConfiguration(variables=chargedVariables,
145 target='isPrimarySignal'),
146 PreCutConfiguration(userCut=charged_user_cut,
147 bestCandidateMode='highest',
148 bestCandidateVariable="muIDBelle" if convertedFromBelle
149 else ("muonIDNN" if usePIDNN else "muonID"),
150 bestCandidateCut=10),
151 PostCutConfiguration(bestCandidateCut=5, value=0.01))
152 muon.addChannel(['mu+:FSP'])
153
154 if convertedFromBelle:
155 gamma_cut = 'goodBelleGamma == 1 and clusterBelleQuality == 0'
156 else:
157 # Same as goodBelleGamma == 1
158 gamma_cut = '[[clusterReg == 1 and E > 0.10] or [clusterReg == 2 and E > 0.05] or [clusterReg == 3 and E > 0.15]]'
159 if specific:
160 gamma_cut += ' and isInRestOfEvent > 0.5'
161
162 gamma = Particle('gamma',
163 MVAConfiguration(variables=['clusterReg', 'clusterNHits', 'clusterTiming', 'extraInfo(preCut_rank)',
164 'clusterE9E25', 'pt', 'E', 'pz'],
165 target='isPrimarySignal'),
166 PreCutConfiguration(userCut=gamma_cut,
167 bestCandidateMode='highest',
168 bestCandidateVariable='E',
169 bestCandidateCut=40),
170 PostCutConfiguration(bestCandidateCut=20, value=0.01))
171 gamma.addChannel(['gamma:FSP'])
172 gamma.addChannel(['gamma:V0'],
173 MVAConfiguration(variables=['pt', 'E', 'pz', 'extraInfo(preCut_rank)'],
174 target='isPrimarySignal'),
175 PreCutConfiguration(userCut='',
176 bestCandidateMode='highest',
177 bestCandidateVariable='E',
178 bestCandidateCut=40))
179
180 if convertedFromBelle:
181
182 pi0_cut = '0.08 < InvM < 0.18'
183 if specific:
184 pi0_cut += ' and isInRestOfEvent > 0.5'
185
186 pi0 = Particle('pi0',
187 MVAConfiguration(variables=['InvM', 'extraInfo(preCut_rank)', 'chiProb', 'abs(BellePi0SigM)',
188 'daughterAngle(0,1)', 'pt', 'pz', 'E'],
189 target='isSignal'),
190 PreCutConfiguration(userCut=pi0_cut,
191 bestCandidateVariable='abs(BellePi0SigM)',
192 bestCandidateCut=20),
193 PostCutConfiguration(bestCandidateCut=10, value=0.01))
194 pi0.addChannel(['pi0:FSP'])
195
196 ks0_cut = '0.4 < M < 0.6'
197 if specific:
198 ks0_cut += ' and isInRestOfEvent > 0.5'
199
200 KS0 = Particle('K_S0',
201 MVAConfiguration(variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M', 'abs(dM)',
202 'useCMSFrame(E)', 'daughterAngle(0,1)',
203 'cosAngleBetweenMomentumAndVertexVector',
204 'extraInfo(preCut_rank)', 'extraInfo(goodKs)', 'extraInfo(ksnbVLike)',
205 'extraInfo(ksnbNoLam)', 'extraInfo(ksnbStandard)'],
206 target='isSignal'),
207 PreCutConfiguration(userCut=ks0_cut,
208 bestCandidateVariable='abs(dM)',
209 bestCandidateCut=20),
210 PostCutConfiguration(bestCandidateCut=10, value=0.01))
211 KS0.addChannel(['K_S0:V0'])
212
213 Lam_cut = '0.9 < M < 1.3'
214 if specific:
215 Lam_cut += ' and isInRestOfEvent > 0.5'
216 L0 = Particle('Lambda0',
217 MVAConfiguration(variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M', 'abs(dM)',
218 'useCMSFrame(E)', 'daughterAngle(0,1)',
219 'cosAngleBetweenMomentumAndVertexVector',
220 'extraInfo(preCut_rank)', 'extraInfo(goodLambda)', 'extraInfo(ksnbVLike)',
221 'extraInfo(ksnbNoLam)'],
222 target='isSignal'),
223 PreCutConfiguration(userCut=Lam_cut,
224 bestCandidateVariable='abs(dM)',
225 bestCandidateCut=20),
226 PostCutConfiguration(bestCandidateCut=10, value=0.01))
227 L0.addChannel(['Lambda0:V0'])
228
229 else:
230
231 pi0 = Particle('pi0',
232 MVAConfiguration(variables=['M', 'daughter({},extraInfo(SignalProbability))', 'extraInfo(preCut_rank)',
233 'daughterAngle(0,1)', 'pt', 'pz', 'E', 'abs(dM)'],
234 target='isSignal'),
235 PreCutConfiguration(userCut='0.08 < M < 0.18',
236 bestCandidateVariable='abs(dM)',
237 bestCandidateCut=20),
238 PostCutConfiguration(bestCandidateCut=10, value=0.01))
239 pi0.addChannel(['gamma', 'gamma'])
240
241 KS0 = Particle('K_S0',
242 MVAConfiguration(variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M', 'abs(dM)',
243 'useCMSFrame(E)', 'daughterAngle(0,1)',
244 'daughter({},extraInfo(SignalProbability))',
245 'useRestFrame(daughter({}, p))', 'cosAngleBetweenMomentumAndVertexVector',
246 'daughter({}, dz)', 'daughter({}, dr)', 'extraInfo(preCut_rank)'],
247 target='isSignal'),
248 PreCutConfiguration(userCut='0.4 < M < 0.6',
249 bestCandidateVariable='abs(dM)',
250 bestCandidateCut=20),
251 PostCutConfiguration(bestCandidateCut=10, value=0.01))
252 KS0.addChannel(['pi+', 'pi-'])
253 KS0.addChannel(['pi0', 'pi0'])
254
255 ks0_cut = '0.4 < M < 0.6'
256 if specific:
257 ks0_cut += ' and isInRestOfEvent > 0.5'
258
259 KS0.addChannel(['K_S0:V0'],
260 MVAConfiguration(variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M',
261 'useCMSFrame(E)', 'daughterAngle(0,1)', 'extraInfo(preCut_rank)', 'abs(dM)',
262 'useRestFrame(daughter({}, p))', 'cosAngleBetweenMomentumAndVertexVector',
263 'daughter({}, dz)', 'daughter({}, dr)'],
264 target='isSignal'),
265 PreCutConfiguration(userCut=ks0_cut,
266 bestCandidateVariable='abs(dM)',
267 bestCandidateCut=20))
268
269 L0 = Particle('Lambda0',
270 MVAConfiguration(variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M', 'abs(dM)',
271 'useCMSFrame(E)', 'daughterAngle(0,1)',
272 'daughter({},extraInfo(SignalProbability))',
273 'useRestFrame(daughter({}, p))', 'cosAngleBetweenMomentumAndVertexVector',
274 'daughter({}, dz)', 'daughter({}, dr)', 'extraInfo(preCut_rank)'],
275 target='isSignal'),
276 PreCutConfiguration(userCut='0.9 < M < 1.3',
277 bestCandidateVariable='abs(dM)',
278 bestCandidateCut=20),
279 PostCutConfiguration(bestCandidateCut=10, value=0.01))
280 L0.addChannel(['p+', 'pi-'])
281
282 Lam_cut = '0.9 < M < 1.3'
283 if specific:
284 Lam_cut += ' and isInRestOfEvent > 0.5'
285
286 L0.addChannel(['Lambda0:V0'],
287 MVAConfiguration(variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M',
288 'useCMSFrame(E)', 'daughterAngle(0,1)', 'extraInfo(preCut_rank)', 'abs(dM)',
289 'useRestFrame(daughter({}, p))', 'cosAngleBetweenMomentumAndVertexVector',
290 'daughter({}, dz)', 'daughter({}, dr)'],
291 target='isSignal'),
292 PreCutConfiguration(userCut=Lam_cut,
293 bestCandidateVariable='abs(dM)',
294 bestCandidateCut=20))
295 kl0_cut = ''
296 if specific:
297 kl0_cut += 'isInRestOfEvent > 0.5'
298
299 KL0 = Particle('K_L0',
300 MVAConfiguration(variables=['E', 'klmClusterTiming'],
301 target='isSignal'),
302 PreCutConfiguration(userCut=kl0_cut,
303 bestCandidateVariable='abs(dM)',
304 bestCandidateCut=20),
305 PostCutConfiguration(bestCandidateCut=10, value=0.01))
306 KL0.addChannel(['K_L0:FSP'])
307
308 SigmaP = Particle('Sigma+',
309 MVAConfiguration(variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M', 'abs(dM)',
310 'useCMSFrame(E)', 'daughterAngle(0,1)',
311 'daughter({},extraInfo(SignalProbability))',
312 'useRestFrame(daughter({}, p))', 'cosAngleBetweenMomentumAndVertexVector',
313 'daughter({}, dz)', 'daughter({}, dr)', 'extraInfo(preCut_rank)'],
314 target='isSignal'),
315 PreCutConfiguration(userCut='1.0 < M < 1.4',
316 bestCandidateVariable='abs(dM)',
317 bestCandidateCut=20),
318 PostCutConfiguration(bestCandidateCut=10, value=0.01))
319 SigmaP.addChannel(['p+', 'pi0'])
320 # variables for D mesons and J/Psi
321 intermediate_vars = ['daughterProductOf(extraInfo(SignalProbability))', 'daughter({},extraInfo(SignalProbability))',
322 'chiProb', 'daughter({}, chiProb)', 'extraInfo(preCut_rank)', 'abs(dM)',
323 'useRestFrame(daughter({}, p))',
324 'useRestFrame(daughter({}, distance))',
325 'decayAngle({})', 'daughterAngle({},{})', 'cosAngleBetweenMomentumAndVertexVector',
326 'daughterInvariantMass({},{})', 'daughterInvariantMass({},{},{})', 'daughterInvariantMass({},{},{},{})',
327 'daughterInvariantMass({},{},{},{},{})', 'dQ', 'Q', 'dM', 'daughter({},extraInfo(decayModeID))']
328
329 # TODO if specific:
330 # We can not do this in the generic case (because this would heavily influence our performance on the unknown signal events
331 # but in the specific case this could work well
332 # intermediate_vars = ['nRemainingTracksInEvent']
333 LC = Particle('Lambda_c+',
334 MVAConfiguration(variables=intermediate_vars,
335 target='isSignal'),
336 PreCutConfiguration(userCut='2.2 < M < 2.4',
337 bestCandidateVariable='abs(dM)',
338 bestCandidateCut=20),
339 PostCutConfiguration(bestCandidateCut=10, value=0.001))
340 LC.addChannel(['p+', 'K-', 'pi+'])
341 LC.addChannel(['p+', 'pi-', 'pi+'])
342 LC.addChannel(['p+', 'K-', 'K+'])
343 LC.addChannel(['p+', 'K-', 'pi+', 'pi0'])
344 LC.addChannel(['p+', 'K-', 'pi+', 'pi0', 'pi0'])
345 LC.addChannel(['p+', 'pi+', 'pi+', 'pi-', 'pi-'])
346 LC.addChannel(['p+', 'K_S0'])
347 LC.addChannel(['p+', 'K_S0', 'pi0'])
348 LC.addChannel(['p+', 'K_S0', 'pi+', 'pi-'])
349 LC.addChannel(['Lambda0', 'pi+'])
350 LC.addChannel(['Lambda0', 'pi+', 'pi0'])
351 LC.addChannel(['Lambda0', 'pi+', 'pi-', 'pi+'])
352 LC.addChannel(['Lambda0', 'pi+', 'gamma'])
353 LC.addChannel(['Lambda0', 'pi+', 'pi0', 'gamma'])
354 LC.addChannel(['Lambda0', 'pi+', 'pi-', 'pi+', 'gamma'])
355 LC.addChannel(['Sigma+', 'pi+', 'pi-'])
356 LC.addChannel(['Sigma+', 'pi+', 'pi-', 'pi0'])
357 LC.addChannel(['Sigma+', 'pi0'])
358
359 D0 = Particle('D0',
360 MVAConfiguration(variables=intermediate_vars,
361 target='isSignal'),
362 PreCutConfiguration(userCut='1.7 < M < 1.95',
363 bestCandidateVariable='abs(dM)',
364 bestCandidateCut=20),
365 PostCutConfiguration(bestCandidateCut=10, value=0.001))
366 D0.addChannel(['K-', 'pi+'])
367 D0.addChannel(['K-', 'pi+', 'pi0'])
368 D0.addChannel(['K-', 'pi+', 'pi0', 'pi0'])
369 D0.addChannel(['K-', 'pi+', 'pi+', 'pi-'])
370 D0.addChannel(['K-', 'pi+', 'pi+', 'pi-', 'pi0'])
371 D0.addChannel(['pi-', 'pi+'])
372 D0.addChannel(['pi-', 'pi+', 'pi+', 'pi-'])
373 D0.addChannel(['pi-', 'pi+', 'pi0'])
374 D0.addChannel(['pi-', 'pi+', 'pi0', 'pi0'])
375 D0.addChannel(['K_S0', 'pi0'])
376 D0.addChannel(['K_S0', 'pi+', 'pi-'])
377 D0.addChannel(['K_S0', 'pi+', 'pi-', 'pi0'])
378 D0.addChannel(['K-', 'K+'])
379 D0.addChannel(['K-', 'K+', 'pi0'])
380 D0.addChannel(['K-', 'K+', 'K_S0'])
381
382 if not removeSLD and semileptonic:
383 D0_SL = Particle('D0:semileptonic',
384 MVAConfiguration(variables=intermediate_vars,
385 target='isSignalAcceptMissingNeutrino'),
386 PreCutConfiguration(userCut='',
387 bestCandidateMode='highest',
388 bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
389 bestCandidateCut=20),
390 PostCutConfiguration(bestCandidateCut=10, value=0.001))
391
392 D0_SL.addChannel(['K-', 'e+'])
393 D0_SL.addChannel(['K-', 'mu+'])
394 D0_SL.addChannel(['K-', 'pi0', 'e+'])
395 D0_SL.addChannel(['K-', 'pi0', 'mu+'])
396 D0_SL.addChannel(['K_S0', 'pi-', 'e+'])
397 D0_SL.addChannel(['K_S0', 'pi-', 'mu+'])
398
399 if KLong:
400 D0_KL = Particle('D0:KL',
401 MVAConfiguration(variables=intermediate_vars,
402 target='isSignal'),
403 PreCutConfiguration(userCut='',
404 bestCandidateMode='highest',
405 bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
406 bestCandidateCut=20),
407 PostCutConfiguration(bestCandidateCut=10, value=0.001))
408
409 D0_KL.addChannel(['K_L0', 'pi0'])
410 D0_KL.addChannel(['K_L0', 'pi+', 'pi-'])
411 D0_KL.addChannel(['K_L0', 'pi+', 'pi-', 'pi0'])
412 D0_KL.addChannel(['K-', 'K+', 'K_L0'])
413
414 DP = Particle('D+',
415 MVAConfiguration(variables=intermediate_vars,
416 target='isSignal'),
417 PreCutConfiguration(userCut='1.7 < M < 1.95',
418 bestCandidateVariable='abs(dM)',
419 bestCandidateCut=20),
420 PostCutConfiguration(bestCandidateCut=10, value=0.001))
421
422 DP.addChannel(['K-', 'pi+', 'pi+'])
423 DP.addChannel(['K-', 'pi+', 'pi+', 'pi0'])
424 DP.addChannel(['K-', 'K+', 'pi+'])
425 DP.addChannel(['K-', 'K+', 'pi+', 'pi0'])
426 DP.addChannel(['pi+', 'pi0'])
427 DP.addChannel(['pi+', 'pi+', 'pi-'])
428 DP.addChannel(['pi+', 'pi+', 'pi-', 'pi0'])
429 DP.addChannel(['K_S0', 'pi+'])
430 DP.addChannel(['K_S0', 'pi+', 'pi0'])
431 DP.addChannel(['K_S0', 'pi+', 'pi+', 'pi-'])
432 DP.addChannel(['K+', 'K_S0', 'K_S0'])
433
434 if not removeSLD and semileptonic:
435 DP_SL = Particle('D+:semileptonic',
436 MVAConfiguration(variables=intermediate_vars,
437 target='isSignalAcceptMissingNeutrino'),
438 PreCutConfiguration(userCut='',
439 bestCandidateMode='highest',
440 bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
441 bestCandidateCut=20),
442 PostCutConfiguration(bestCandidateCut=10, value=0.001))
443
444 DP_SL.addChannel(['K_S0', 'e+'])
445 DP_SL.addChannel(['K_S0', 'mu+'])
446 DP_SL.addChannel(['K-', 'pi+', 'e+'])
447 DP_SL.addChannel(['K-', 'pi+', 'mu+'])
448
449 if KLong:
450 DP_KL = Particle('D+:KL',
451 MVAConfiguration(variables=intermediate_vars,
452 target='isSignal'),
453 PreCutConfiguration(userCut='',
454 bestCandidateMode='highest',
455 bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
456 bestCandidateCut=20),
457 PostCutConfiguration(bestCandidateCut=10, value=0.001))
458
459 DP_KL.addChannel(['K_L0', 'pi+'])
460 DP_KL.addChannel(['K_L0', 'pi+', 'pi0'])
461 DP_KL.addChannel(['K_L0', 'pi+', 'pi+', 'pi-'])
462 DP_KL.addChannel(['K+', 'K_L0', 'K_S0'])
463 DP_KL.addChannel(['K+', 'K_L0', 'K_L0'])
464
465 Jpsi = Particle('J/psi',
466 MVAConfiguration(variables=intermediate_vars,
467 target='isSignal'),
468 PreCutConfiguration(userCut='2.6 < M < 3.7',
469 bestCandidateVariable='abs(dM)',
470 bestCandidateCut=20),
471 PostCutConfiguration(bestCandidateCut=10, value=0.001))
472
473 Jpsi.addChannel(['e+', 'e-'])
474 Jpsi.addChannel(['mu+', 'mu-'])
475
476 DSP = Particle('D*+',
477 MVAConfiguration(variables=intermediate_vars,
478 target='isSignal'),
479 PreCutConfiguration(userCut='0 < Q < 0.3',
480 bestCandidateVariable='abs(dQ)',
481 bestCandidateCut=20),
482 PostCutConfiguration(bestCandidateCut=10, value=0.001))
483
484 DSP.addChannel(['D0', 'pi+'])
485 DSP.addChannel(['D+', 'pi0'])
486 DSP.addChannel(['D+', 'gamma'])
487
488 if not removeSLD and semileptonic:
489 DSP_SL = Particle('D*+:semileptonic',
490 MVAConfiguration(variables=intermediate_vars,
491 target='isSignalAcceptMissingNeutrino'),
492 PreCutConfiguration(userCut='0 < Q < 0.3',
493 bestCandidateVariable='abs(dQ)',
494 bestCandidateCut=20),
495 PostCutConfiguration(bestCandidateCut=10, value=0.001))
496
497 DSP_SL.addChannel(['D0:semileptonic', 'pi+'])
498 DSP_SL.addChannel(['D+:semileptonic', 'pi0'])
499 DSP_SL.addChannel(['D+:semileptonic', 'gamma'])
500
501 if KLong:
502 DSP_KL = Particle('D*+:KL',
503 MVAConfiguration(variables=intermediate_vars,
504 target='isSignal'),
505 PreCutConfiguration(userCut='0 < Q < 0.3',
506 bestCandidateVariable='abs(dQ)',
507 bestCandidateCut=20),
508 PostCutConfiguration(bestCandidateCut=10, value=0.001))
509
510 DSP_KL.addChannel(['D0:KL', 'pi+'])
511 DSP_KL.addChannel(['D+:KL', 'pi0'])
512 DSP_KL.addChannel(['D+:KL', 'gamma'])
513
514 DS0 = Particle('D*0',
515 MVAConfiguration(variables=intermediate_vars,
516 target='isSignal'),
517 PreCutConfiguration(userCut='0 < Q < 0.3',
518 bestCandidateVariable='abs(dQ)',
519 bestCandidateCut=20),
520 PostCutConfiguration(bestCandidateCut=10, value=0.001))
521
522 DS0.addChannel(['D0', 'pi0'])
523 DS0.addChannel(['D0', 'gamma'])
524
525 if not removeSLD and semileptonic:
526 DS0_SL = Particle('D*0:semileptonic',
527 MVAConfiguration(variables=intermediate_vars,
528 target='isSignalAcceptMissingNeutrino'),
529 PreCutConfiguration(userCut='0 < Q < 0.3',
530 bestCandidateVariable='abs(dQ)',
531 bestCandidateCut=20),
532 PostCutConfiguration(bestCandidateCut=10, value=0.001))
533
534 DS0_SL.addChannel(['D0:semileptonic', 'pi0'])
535 DS0_SL.addChannel(['D0:semileptonic', 'gamma'])
536
537 if KLong:
538 DS0_KL = Particle('D*0:KL',
539 MVAConfiguration(variables=intermediate_vars,
540 target='isSignal'),
541 PreCutConfiguration(userCut='0 < Q < 0.3',
542 bestCandidateVariable='abs(dQ)',
543 bestCandidateCut=20),
544 PostCutConfiguration(bestCandidateCut=10, value=0.001))
545
546 DS0_KL.addChannel(['D0:KL', 'pi0'])
547 DS0_KL.addChannel(['D0:KL', 'gamma'])
548
549 DS = Particle('D_s+',
550 MVAConfiguration(variables=intermediate_vars,
551 target='isSignal'),
552 PreCutConfiguration(userCut='1.68 < M < 2.1',
553 bestCandidateVariable='abs(dM)',
554 bestCandidateCut=20),
555 PostCutConfiguration(bestCandidateCut=10, value=0.001))
556
557 DS.addChannel(['K+', 'K_S0'])
558 DS.addChannel(['K+', 'pi+', 'pi-'])
559 DS.addChannel(['K+', 'K-', 'pi+'])
560 DS.addChannel(['K+', 'K-', 'pi+', 'pi0'])
561 DS.addChannel(['K+', 'K_S0', 'pi+', 'pi-'])
562 DS.addChannel(['K-', 'K_S0', 'pi+', 'pi+'])
563 DS.addChannel(['K+', 'K-', 'pi+', 'pi+', 'pi-'])
564 DS.addChannel(['pi+', 'pi+', 'pi-'])
565 DS.addChannel(['K_S0', 'pi+'])
566 DS.addChannel(['K_S0', 'pi+', 'pi0'])
567
568 if KLong:
569 DS_KL = Particle('D_s+:KL',
570 MVAConfiguration(variables=intermediate_vars,
571 target='isSignal'),
572 PreCutConfiguration(userCut='',
573 bestCandidateMode='highest',
574 bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
575 bestCandidateCut=20),
576 PostCutConfiguration(bestCandidateCut=10, value=0.001))
577
578 DS_KL.addChannel(['K+', 'K_L0'])
579 DS_KL.addChannel(['K+', 'K_L0', 'pi+', 'pi-'])
580 DS_KL.addChannel(['K-', 'K_L0', 'pi+', 'pi+'])
581 DS_KL.addChannel(['K_L0', 'pi+'])
582 DS_KL.addChannel(['K_L0', 'pi+', 'pi0'])
583
584 DSS = Particle('D_s*+',
585 MVAConfiguration(variables=intermediate_vars,
586 target='isSignal'),
587 PreCutConfiguration(userCut='0.0 < Q < 0.3',
588 bestCandidateVariable='abs(dQ)',
589 bestCandidateCut=20),
590 PostCutConfiguration(bestCandidateCut=10, value=0.001))
591
592 DSS.addChannel(['D_s+', 'gamma'])
593 DSS.addChannel(['D_s+', 'pi0'])
594
595 if KLong:
596 DSS_KL = Particle('D_s*+:KL',
597 MVAConfiguration(variables=intermediate_vars,
598 target='isSignal'),
599 PreCutConfiguration(userCut='0.0 < Q < 0.3',
600 bestCandidateVariable='abs(dQ)',
601 bestCandidateCut=20),
602 PostCutConfiguration(bestCandidateCut=10, value=0.001))
603
604 DSS_KL.addChannel(['D_s+:KL', 'gamma'])
605 DSS_KL.addChannel(['D_s+:KL', 'pi0'])
606
607 # note: these should not be correlated to Mbc (weak correlation of deltaE is OK)
608 B_vars = ['daughterProductOf(extraInfo(SignalProbability))', 'daughter({},extraInfo(SignalProbability))',
609 'chiProb', 'daughter({}, chiProb)', 'extraInfo(preCut_rank)',
610 'useRestFrame(daughter({}, p))',
611 'useRestFrame(daughter({}, distance))',
612 'decayAngle({})', 'daughterAngle({},{})', 'cosAngleBetweenMomentumAndVertexVector',
613 'dr', 'dz', 'dx', 'dy', 'distance', 'significanceOfDistance', 'deltaE', 'daughter({},extraInfo(decayModeID))']
614
615 hadronic_user_cut = 'Mbc > 5.2 and abs(deltaE) < 0.5'
616 if B_extra_cut is not None:
617 hadronic_user_cut += ' and [' + B_extra_cut + ']'
618
619 BP = Particle('B+',
620 MVAConfiguration(variables=B_vars,
621 spectators={'Mbc': (5.23, None), 'cosThetaBetweenParticleAndNominalB': (-10, 10)},
622 target='isSignal'),
623 PreCutConfiguration(userCut=hadronic_user_cut,
624 bestCandidateMode='highest',
625 bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
626 bestCandidateCut=20),
627 PostCutConfiguration(bestCandidateCut=20))
628
629 BP.addChannel(['anti-D0', 'pi+'])
630 BP.addChannel(['anti-D0', 'pi+', 'pi0'])
631 BP.addChannel(['anti-D0', 'pi+', 'pi0', 'pi0'])
632 BP.addChannel(['anti-D0', 'pi+', 'pi+', 'pi-'])
633 BP.addChannel(['anti-D0', 'pi+', 'pi+', 'pi-', 'pi0'])
634 BP.addChannel(['anti-D0', 'D+'])
635 BP.addChannel(['anti-D0', 'D+', 'K_S0'])
636 BP.addChannel(['anti-D*0', 'D+', 'K_S0'])
637 BP.addChannel(['anti-D0', 'D*+', 'K_S0'])
638 BP.addChannel(['anti-D*0', 'D*+', 'K_S0'])
639 BP.addChannel(['anti-D0', 'D0', 'K+'])
640 BP.addChannel(['anti-D*0', 'D0', 'K+'])
641 BP.addChannel(['anti-D0', 'D*0', 'K+'])
642 BP.addChannel(['anti-D*0', 'D*0', 'K+'])
643 BP.addChannel(['D_s+', 'anti-D0'])
644 BP.addChannel(['anti-D*0', 'pi+'])
645 BP.addChannel(['anti-D*0', 'pi+', 'pi0'])
646 BP.addChannel(['anti-D*0', 'pi+', 'pi0', 'pi0'])
647 BP.addChannel(['anti-D*0', 'pi+', 'pi+', 'pi-'])
648 BP.addChannel(['anti-D*0', 'pi+', 'pi+', 'pi-', 'pi0'])
649 BP.addChannel(['D_s*+', 'anti-D0'])
650 BP.addChannel(['D_s+', 'anti-D*0'])
651 BP.addChannel(['anti-D0', 'K+'])
652 BP.addChannel(['D-', 'pi+', 'pi+'])
653 BP.addChannel(['D-', 'pi+', 'pi+', 'pi0'])
654 BP.addChannel(['J/psi', 'K+'], preCutConfig=BP.preCutConfig._replace(noBackgroundSampling=True))
655 BP.addChannel(['J/psi', 'K+', 'pi+', 'pi-'])
656 BP.addChannel(['J/psi', 'K+', 'pi0'])
657 BP.addChannel(['J/psi', 'K_S0', 'pi+'])
658 if baryonic:
659 BP.addChannel(['anti-Lambda_c-', 'p+', 'pi+', 'pi0'])
660 BP.addChannel(['anti-Lambda_c-', 'p+', 'pi+', 'pi-', 'pi+'])
661 BP.addChannel(['anti-D0', 'p+', 'anti-p-', 'pi+'])
662 BP.addChannel(['anti-D*0', 'p+', 'anti-p-', 'pi+'])
663 BP.addChannel(['D+', 'p+', 'anti-p-', 'pi+', 'pi-'])
664 BP.addChannel(['D*+', 'p+', 'anti-p-', 'pi+', 'pi-'])
665 BP.addChannel(['anti-Lambda_c-', 'p+', 'pi+'])
666
667 B_SL_vars = ['daughterProductOf(extraInfo(SignalProbability))', 'daughter({},extraInfo(SignalProbability))',
668 'chiProb', 'daughter({}, chiProb)', 'extraInfo(preCut_rank)',
669 'useRestFrame(daughter({}, p))',
670 'useRestFrame(daughter({}, distance))',
671 'cosAngleBetweenMomentumAndVertexVector',
672 'dr', 'dz', 'dx', 'dy', 'distance', 'significanceOfDistance', 'daughter({},extraInfo(decayModeID))']
673
674 semileptonic_user_cut = ''
675 if B_extra_cut is not None:
676 semileptonic_user_cut += B_extra_cut
677
678 BP_SL = Particle('B+:semileptonic',
679 MVAConfiguration(variables=B_SL_vars,
680 spectators={'Mbc': (5.23, None), 'cosThetaBetweenParticleAndNominalB': (-10, 10)},
681 target='isSignalAcceptMissingNeutrino'),
682 PreCutConfiguration(userCut=semileptonic_user_cut,
683 bestCandidateMode='highest',
684 bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
685 bestCandidateCut=20),
686 PostCutConfiguration(bestCandidateCut=20))
687 BP_SL.addChannel(['anti-D0', 'e+'])
688 BP_SL.addChannel(['anti-D0', 'mu+'])
689 BP_SL.addChannel(['anti-D*0', 'e+'])
690 BP_SL.addChannel(['anti-D*0', 'mu+'])
691 BP_SL.addChannel(['D-', 'pi+', 'e+'])
692 BP_SL.addChannel(['D-', 'pi+', 'mu+'])
693 BP_SL.addChannel(['D*-', 'pi+', 'e+'])
694 BP_SL.addChannel(['D*-', 'pi+', 'mu+'])
695
696 if not removeSLD and semileptonic:
697 BP_SL.addChannel(['anti-D0:semileptonic', 'pi+'])
698 BP_SL.addChannel(['anti-D0:semileptonic', 'pi+', 'pi0'])
699 BP_SL.addChannel(['anti-D0:semileptonic', 'pi+', 'pi0', 'pi0'])
700 BP_SL.addChannel(['anti-D0:semileptonic', 'pi+', 'pi+', 'pi-'])
701 BP_SL.addChannel(['anti-D0:semileptonic', 'pi+', 'pi+', 'pi-', 'pi0'])
702 BP_SL.addChannel(['anti-D0:semileptonic', 'D+'])
703 BP_SL.addChannel(['anti-D0:semileptonic', 'D+', 'K_S0'])
704 BP_SL.addChannel(['anti-D*0:semileptonic', 'D+', 'K_S0'])
705 BP_SL.addChannel(['anti-D0:semileptonic', 'D*+', 'K_S0'])
706 BP_SL.addChannel(['anti-D*0:semileptonic', 'D*+', 'K_S0'])
707 BP_SL.addChannel(['anti-D0:semileptonic', 'D0', 'K+'])
708 BP_SL.addChannel(['anti-D*0:semileptonic', 'D0', 'K+'])
709 BP_SL.addChannel(['anti-D0:semileptonic', 'D*0', 'K+'])
710 BP_SL.addChannel(['anti-D*0:semileptonic', 'D*0', 'K+'])
711 BP_SL.addChannel(['anti-D0', 'D+:semileptonic'])
712 BP_SL.addChannel(['anti-D0', 'D+:semileptonic', 'K_S0'])
713 BP_SL.addChannel(['anti-D*0', 'D+:semileptonic', 'K_S0'])
714 BP_SL.addChannel(['anti-D0', 'D*+:semileptonic', 'K_S0'])
715 BP_SL.addChannel(['anti-D*0', 'D*+:semileptonic', 'K_S0'])
716 BP_SL.addChannel(['anti-D0', 'D0:semileptonic', 'K+'])
717 BP_SL.addChannel(['anti-D*0', 'D0:semileptonic', 'K+'])
718 BP_SL.addChannel(['anti-D0', 'D*0:semileptonic', 'K+'])
719 BP_SL.addChannel(['anti-D*0', 'D*0:semileptonic', 'K+'])
720 BP_SL.addChannel(['D_s+', 'anti-D0:semileptonic'])
721 BP_SL.addChannel(['anti-D*0:semileptonic', 'pi+'])
722 BP_SL.addChannel(['anti-D*0:semileptonic', 'pi+', 'pi0'])
723 BP_SL.addChannel(['anti-D*0:semileptonic', 'pi+', 'pi0', 'pi0'])
724 BP_SL.addChannel(['anti-D*0:semileptonic', 'pi+', 'pi+', 'pi-'])
725 BP_SL.addChannel(['anti-D*0:semileptonic', 'pi+', 'pi+', 'pi-', 'pi0'])
726 BP_SL.addChannel(['D_s*+', 'anti-D0:semileptonic'])
727 BP_SL.addChannel(['D_s+', 'anti-D*0:semileptonic'])
728 BP_SL.addChannel(['anti-D0:semileptonic', 'K+'])
729 BP_SL.addChannel(['D-:semileptonic', 'pi+', 'pi+'])
730 BP_SL.addChannel(['D-:semileptonic', 'pi+', 'pi+', 'pi0'])
731
732 if KLong:
733 BP_KL = Particle('B+:KL',
734 MVAConfiguration(variables=B_vars,
735 spectators={'Mbc': (5.23, None), 'cosThetaBetweenParticleAndNominalB': (-10, 10)},
736 target='isSignal'),
737 PreCutConfiguration(userCut=semileptonic_user_cut,
738 bestCandidateMode='highest',
739 bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
740 bestCandidateCut=20),
741 PostCutConfiguration(bestCandidateCut=20))
742 BP_KL.addChannel(['anti-D0:KL', 'pi+'])
743 BP_KL.addChannel(['anti-D0:KL', 'pi+', 'pi0'])
744 BP_KL.addChannel(['anti-D0:KL', 'pi+', 'pi0', 'pi0'])
745 BP_KL.addChannel(['anti-D0:KL', 'pi+', 'pi+', 'pi-'])
746 BP_KL.addChannel(['anti-D0:KL', 'pi+', 'pi+', 'pi-', 'pi0'])
747 BP_KL.addChannel(['anti-D0:KL', 'D+'])
748 BP_KL.addChannel(['anti-D0:KL', 'D+', 'K_S0'])
749 BP_KL.addChannel(['anti-D*0:KL', 'D+', 'K_S0'])
750 BP_KL.addChannel(['anti-D0:KL', 'D*+', 'K_S0'])
751 BP_KL.addChannel(['anti-D*0:KL', 'D*+', 'K_S0'])
752 BP_KL.addChannel(['anti-D0:KL', 'D0', 'K+'])
753 BP_KL.addChannel(['anti-D*0:KL', 'D0', 'K+'])
754 BP_KL.addChannel(['anti-D0:KL', 'D*0', 'K+'])
755 BP_KL.addChannel(['anti-D*0:KL', 'D*0', 'K+'])
756 BP_KL.addChannel(['anti-D0', 'D+:KL'])
757 BP_KL.addChannel(['anti-D0', 'D+:KL', 'K_S0'])
758 BP_KL.addChannel(['anti-D*0', 'D+:KL', 'K_S0'])
759 BP_KL.addChannel(['anti-D0', 'D*+:KL', 'K_S0'])
760 BP_KL.addChannel(['anti-D*0', 'D*+:KL', 'K_S0'])
761 BP_KL.addChannel(['anti-D0', 'D0:KL', 'K+'])
762 BP_KL.addChannel(['anti-D*0', 'D0:KL', 'K+'])
763 BP_KL.addChannel(['anti-D0', 'D*0:KL', 'K+'])
764 BP_KL.addChannel(['anti-D*0', 'D*0:KL', 'K+'])
765 BP_KL.addChannel(['D_s+', 'anti-D0:KL'])
766 BP_KL.addChannel(['D_s+:KL', 'anti-D0'])
767 BP_KL.addChannel(['anti-D*0:KL', 'pi+'])
768 BP_KL.addChannel(['anti-D*0:KL', 'pi+', 'pi0'])
769 BP_KL.addChannel(['anti-D*0:KL', 'pi+', 'pi0', 'pi0'])
770 BP_KL.addChannel(['anti-D*0:KL', 'pi+', 'pi+', 'pi-'])
771 BP_KL.addChannel(['anti-D*0:KL', 'pi+', 'pi+', 'pi-', 'pi0'])
772 BP_KL.addChannel(['D_s*+', 'anti-D0:KL'])
773 BP_KL.addChannel(['D_s+', 'anti-D*0:KL'])
774 BP_KL.addChannel(['D_s*+:KL', 'anti-D0'])
775 BP_KL.addChannel(['D_s+:KL', 'anti-D*0'])
776 BP_KL.addChannel(['anti-D0:KL', 'K+'])
777 BP_KL.addChannel(['D-:KL', 'pi+', 'pi+'])
778 BP_KL.addChannel(['D-:KL', 'pi+', 'pi+', 'pi0'])
779 BP_KL.addChannel(['anti-D0', 'D+', 'K_L0'])
780 BP_KL.addChannel(['anti-D*0', 'D+', 'K_L0'])
781 BP_KL.addChannel(['anti-D0', 'D*+', 'K_L0'])
782 BP_KL.addChannel(['anti-D*0', 'D*+', 'K_L0'])
783 BP_KL.addChannel(['J/psi', 'K_L0', 'pi+'])
784
785 B0 = Particle('B0',
786 MVAConfiguration(variables=B_vars,
787 spectators={'Mbc': (5.23, None), 'cosThetaBetweenParticleAndNominalB': (-10, 10)},
788 target='isSignal'),
789 PreCutConfiguration(userCut=hadronic_user_cut,
790 bestCandidateMode='highest',
791 bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
792 bestCandidateCut=20),
793 PostCutConfiguration(bestCandidateCut=20))
794 B0.addChannel(['D-', 'pi+'])
795 B0.addChannel(['D-', 'pi+', 'pi0'])
796 B0.addChannel(['D-', 'pi+', 'pi0', 'pi0'])
797 B0.addChannel(['D-', 'pi+', 'pi+', 'pi-'])
798 B0.addChannel(['D-', 'pi+', 'pi+', 'pi-', 'pi0'])
799 B0.addChannel(['anti-D0', 'pi+', 'pi-'])
800 B0.addChannel(['D-', 'D0', 'K+'])
801 B0.addChannel(['D-', 'D*0', 'K+'])
802 B0.addChannel(['D*-', 'D0', 'K+'])
803 B0.addChannel(['D*-', 'D*0', 'K+'])
804 B0.addChannel(['D-', 'D+', 'K_S0'])
805 B0.addChannel(['D*-', 'D+', 'K_S0'])
806 B0.addChannel(['D-', 'D*+', 'K_S0'])
807 B0.addChannel(['D*-', 'D*+', 'K_S0'])
808 B0.addChannel(['D_s+', 'D-'])
809 B0.addChannel(['D*-', 'pi+'])
810 B0.addChannel(['D*-', 'pi+', 'pi0'])
811 B0.addChannel(['D*-', 'pi+', 'pi0', 'pi0'])
812 B0.addChannel(['D*-', 'pi+', 'pi+', 'pi-'])
813 B0.addChannel(['D*-', 'pi+', 'pi+', 'pi-', 'pi0'])
814 B0.addChannel(['D_s*+', 'D-'])
815 B0.addChannel(['D_s+', 'D*-'])
816 B0.addChannel(['D_s*+', 'D*-'])
817 B0.addChannel(['J/psi', 'K_S0'], preCutConfig=B0.preCutConfig._replace(noBackgroundSampling=True))
818 B0.addChannel(['J/psi', 'K+', 'pi-'])
819 B0.addChannel(['J/psi', 'K_S0', 'pi+', 'pi-'])
820 if baryonic:
821 B0.addChannel(['anti-Lambda_c-', 'p+', 'pi+', 'pi-'])
822 B0.addChannel(['anti-D0', 'p+', 'anti-p-'])
823 B0.addChannel(['D-', 'p+', 'anti-p-', 'pi+'])
824 B0.addChannel(['D*-', 'p+', 'anti-p-', 'pi+'])
825 B0.addChannel(['anti-D0', 'p+', 'anti-p-', 'pi+', 'pi-'])
826 B0.addChannel(['anti-D*0', 'p+', 'anti-p-', 'pi+', 'pi-'])
827
828 B0_SL = Particle('B0:semileptonic',
829 MVAConfiguration(variables=B_SL_vars,
830 spectators={'Mbc': (5.23, None), 'cosThetaBetweenParticleAndNominalB': (-10, 10)},
831 target='isSignalAcceptMissingNeutrino'),
832 PreCutConfiguration(userCut=semileptonic_user_cut,
833 bestCandidateMode='highest',
834 bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
835 bestCandidateCut=20),
836 PostCutConfiguration(bestCandidateCut=20))
837 B0_SL.addChannel(['D-', 'e+'])
838 B0_SL.addChannel(['D-', 'mu+'])
839 B0_SL.addChannel(['D*-', 'e+'])
840 B0_SL.addChannel(['D*-', 'mu+'])
841 B0_SL.addChannel(['anti-D0', 'pi-', 'e+'])
842 B0_SL.addChannel(['anti-D0', 'pi-', 'mu+'])
843 B0_SL.addChannel(['anti-D*0', 'pi-', 'e+'])
844 B0_SL.addChannel(['anti-D*0', 'pi-', 'mu+'])
845
846 if not removeSLD and semileptonic:
847 B0_SL.addChannel(['D-:semileptonic', 'pi+'])
848 B0_SL.addChannel(['D-:semileptonic', 'pi+', 'pi0'])
849 B0_SL.addChannel(['D-:semileptonic', 'pi+', 'pi0', 'pi0'])
850 B0_SL.addChannel(['D-:semileptonic', 'pi+', 'pi+', 'pi-'])
851 B0_SL.addChannel(['D-:semileptonic', 'pi+', 'pi+', 'pi-', 'pi0'])
852 B0_SL.addChannel(['anti-D0:semileptonic', 'pi+', 'pi-'])
853 B0_SL.addChannel(['D-:semileptonic', 'D0', 'K+'])
854 B0_SL.addChannel(['D-:semileptonic', 'D*0', 'K+'])
855 B0_SL.addChannel(['D*-:semileptonic', 'D0', 'K+'])
856 B0_SL.addChannel(['D*-:semileptonic', 'D*0', 'K+'])
857 B0_SL.addChannel(['D-:semileptonic', 'D+', 'K_S0'])
858 B0_SL.addChannel(['D*-:semileptonic', 'D+', 'K_S0'])
859 B0_SL.addChannel(['D-:semileptonic', 'D*+', 'K_S0'])
860 B0_SL.addChannel(['D*-:semileptonic', 'D*+', 'K_S0'])
861 B0_SL.addChannel(['D-', 'D0:semileptonic', 'K+'])
862 B0_SL.addChannel(['D-', 'D*0:semileptonic', 'K+'])
863 B0_SL.addChannel(['D*-', 'D0:semileptonic', 'K+'])
864 B0_SL.addChannel(['D*-', 'D*0:semileptonic', 'K+'])
865 B0_SL.addChannel(['D-', 'D+:semileptonic', 'K_S0'])
866 B0_SL.addChannel(['D*-', 'D+:semileptonic', 'K_S0'])
867 B0_SL.addChannel(['D-', 'D*+:semileptonic', 'K_S0'])
868 B0_SL.addChannel(['D*-', 'D*+:semileptonic', 'K_S0'])
869 B0_SL.addChannel(['D_s+', 'D-:semileptonic'])
870 B0_SL.addChannel(['D*-:semileptonic', 'pi+'])
871 B0_SL.addChannel(['D*-:semileptonic', 'pi+', 'pi0'])
872 B0_SL.addChannel(['D*-:semileptonic', 'pi+', 'pi0', 'pi0'])
873 B0_SL.addChannel(['D*-:semileptonic', 'pi+', 'pi+', 'pi-'])
874 B0_SL.addChannel(['D*-:semileptonic', 'pi+', 'pi+', 'pi-', 'pi0'])
875 B0_SL.addChannel(['D_s*+', 'D-:semileptonic'])
876 B0_SL.addChannel(['D_s+', 'D*-:semileptonic'])
877 B0_SL.addChannel(['D_s*+', 'D*-:semileptonic'])
878
879 if KLong:
880 B0_KL = Particle('B0:KL',
881 MVAConfiguration(variables=B_vars,
882 spectators={'Mbc': (5.23, None), 'cosThetaBetweenParticleAndNominalB': (-10, 10)},
883 target='isSignal'),
884 PreCutConfiguration(userCut=semileptonic_user_cut,
885 bestCandidateMode='highest',
886 bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
887 bestCandidateCut=20),
888 PostCutConfiguration(bestCandidateCut=20))
889 B0_KL.addChannel(['D-:KL', 'pi+'])
890 B0_KL.addChannel(['D-:KL', 'pi+', 'pi0'])
891 B0_KL.addChannel(['D-:KL', 'pi+', 'pi0', 'pi0'])
892 B0_KL.addChannel(['D-:KL', 'pi+', 'pi+', 'pi-'])
893 B0_KL.addChannel(['D-:KL', 'pi+', 'pi+', 'pi-', 'pi0'])
894 B0_KL.addChannel(['anti-D0:KL', 'pi+', 'pi-'])
895 B0_KL.addChannel(['D-:KL', 'D0', 'K+'])
896 B0_KL.addChannel(['D-:KL', 'D*0', 'K+'])
897 B0_KL.addChannel(['D*-:KL', 'D0', 'K+'])
898 B0_KL.addChannel(['D*-:KL', 'D*0', 'K+'])
899 B0_KL.addChannel(['D-:KL', 'D+', 'K_S0'])
900 B0_KL.addChannel(['D*-:KL', 'D+', 'K_S0'])
901 B0_KL.addChannel(['D-:KL', 'D*+', 'K_S0'])
902 B0_KL.addChannel(['D*-:KL', 'D*+', 'K_S0'])
903 B0_KL.addChannel(['D-', 'D0:KL', 'K+'])
904 B0_KL.addChannel(['D-', 'D*0:KL', 'K+'])
905 B0_KL.addChannel(['D*-', 'D0:KL', 'K+'])
906 B0_KL.addChannel(['D*-', 'D*0:KL', 'K+'])
907 B0_KL.addChannel(['D-', 'D+:KL', 'K_S0'])
908 B0_KL.addChannel(['D*-', 'D+:KL', 'K_S0'])
909 B0_KL.addChannel(['D-', 'D*+:KL', 'K_S0'])
910 B0_KL.addChannel(['D*-', 'D*+:KL', 'K_S0'])
911 B0_KL.addChannel(['D_s+', 'D-:KL'])
912 B0_KL.addChannel(['D_s+:KL', 'D-'])
913 B0_KL.addChannel(['D*-:KL', 'pi+'])
914 B0_KL.addChannel(['D*-:KL', 'pi+', 'pi0'])
915 B0_KL.addChannel(['D*-:KL', 'pi+', 'pi0', 'pi0'])
916 B0_KL.addChannel(['D*-:KL', 'pi+', 'pi+', 'pi-'])
917 B0_KL.addChannel(['D*-:KL', 'pi+', 'pi+', 'pi-', 'pi0'])
918 B0_KL.addChannel(['D_s*+', 'D-:KL'])
919 B0_KL.addChannel(['D_s+', 'D*-:KL'])
920 B0_KL.addChannel(['D_s*+', 'D*-:KL'])
921 B0_KL.addChannel(['D_s*+:KL', 'D-'])
922 B0_KL.addChannel(['D_s+:KL', 'D*-'])
923 B0_KL.addChannel(['D_s*+:KL', 'D*-'])
924 B0_KL.addChannel(['D-', 'D+', 'K_L0'])
925 B0_KL.addChannel(['D*-', 'D+', 'K_L0'])
926 B0_KL.addChannel(['D-', 'D*+', 'K_L0'])
927 B0_KL.addChannel(['D*-', 'D*+', 'K_L0'])
928 B0_KL.addChannel(['J/psi', 'K_L0'])
929 B0_KL.addChannel(['J/psi', 'K_L0', 'pi+', 'pi-'])
930
931 # Use deltaE + Mbc - m_(B_s) instead of deltaE since Bs has only one peak here (vs. 3 in deltaE)
932 Bs_vars = ['formula(deltaE+Mbc-5.3669)' if x == 'deltaE' else x for x in B_vars]
933
934 hadronic_bs_user_cut = 'Mbc > 5.3 and abs(formula(deltaE+Mbc-5.3669)) < 0.5'
935 if B_extra_cut is not None:
936 hadronic_bs_user_cut += ' and [' + B_extra_cut + ']'
937
938 BS = Particle('B_s0',
939 MVAConfiguration(variables=Bs_vars,
940 spectators={'Mbc': (5.23, None)},
941 target='isSignal'),
942 PreCutConfiguration(userCut=hadronic_bs_user_cut,
943 bestCandidateMode='highest',
944 bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
945 bestCandidateCut=20),
946 PostCutConfiguration(bestCandidateCut=20))
947
948 # Override precut for some channels as this provides better performance
949 tight_precut = BS.preCutConfig._replace(userCut=hadronic_bs_user_cut + ' and abs(formula(deltaE+Mbc-5.3669)) < 0.1')
950
951 # D_s & D*
952 BS.addChannel(['D_s-', 'D_s+'], preCutConfig=tight_precut)
953 BS.addChannel(['D_s*+', 'D_s-'], preCutConfig=tight_precut)
954 BS.addChannel(['D_s*-', 'D_s+'], preCutConfig=tight_precut)
955 BS.addChannel(['D_s*+', 'D_s*-'], preCutConfig=tight_precut)
956 BS.addChannel(['D_s-', 'D+'], preCutConfig=tight_precut)
957 BS.addChannel(['D_s+', 'D*-'])
958 BS.addChannel(['D_s*+', 'D-'])
959 BS.addChannel(['D_s*+', 'D*-'])
960
961 # D_s
962 BS.addChannel(['D_s-', 'K+'])
963 BS.addChannel(['D_s+', 'K-'])
964 BS.addChannel(['D_s-', 'pi+'])
965 BS.addChannel(['D_s-', 'pi+', 'pi+', 'pi-'], preCutConfig=tight_precut)
966 BS.addChannel(['D_s-', 'D0', 'K+'], preCutConfig=tight_precut)
967 BS.addChannel(['D_s-', 'D+', 'K_S0'])
968 BS.addChannel(['D_s-', 'pi+', 'pi0'], preCutConfig=tight_precut) # rho+
969 BS.addChannel(['D_s-', 'D0', 'K+', 'pi0'], preCutConfig=tight_precut) # K*+
970 BS.addChannel(['D_s-', 'D0', 'K_S0', 'pi+']) # K*+
971 BS.addChannel(['D_s-', 'D+', 'K+', 'pi-']) # K*0
972 BS.addChannel(['D_s-', 'D+', 'K_S0', 'pi0']) # K*0
973 BS.addChannel(['D_s-', 'D*0', 'K+'], preCutConfig=tight_precut)
974 BS.addChannel(['D_s-', 'D*+', 'K_S0'])
975 BS.addChannel(['D_s-', 'D*0', 'K+', 'pi0']) # K*+
976 BS.addChannel(['D_s-', 'D*0', 'K_S0', 'pi+']) # K*+
977 BS.addChannel(['D_s-', 'D*+', 'K+', 'pi-']) # K*0
978 BS.addChannel(['D_s-', 'D*+', 'K_S0', 'pi0']) # K*0
979
980 # D_s*
981 BS.addChannel(['D_s*-', 'K+'])
982 BS.addChannel(['D_s*-', 'pi+'])
983 BS.addChannel(['D_s*-', 'D0', 'K+'], preCutConfig=tight_precut)
984 BS.addChannel(['D_s*-', 'D+', 'K_S0'])
985 BS.addChannel(['D_s*-', 'D*0', 'K+'], preCutConfig=tight_precut)
986 BS.addChannel(['D_s*-', 'D*+', 'K_S0'])
987 BS.addChannel(['D_s*-', 'pi+', 'pi+', 'pi-'], preCutConfig=tight_precut)
988 BS.addChannel(['D_s*-', 'pi+', 'pi0'], preCutConfig=tight_precut) # rho+
989 BS.addChannel(['D_s*-', 'D0', 'K+', 'pi0']) # K*+
990 BS.addChannel(['D_s*-', 'D0', 'K_S0', 'pi+']) # K*+
991 BS.addChannel(['D_s*-', 'D+', 'K+', 'pi-']) # K*0
992 BS.addChannel(['D_s*-', 'D+', 'K_S0', 'pi0']) # K*0
993 BS.addChannel(['D_s*-', 'D*0', 'K+', 'pi0']) # K*+
994 BS.addChannel(['D_s*-', 'D*0', 'K_S0', 'pi+']) # K*+
995 BS.addChannel(['D_s*-', 'D*+', 'K+', 'pi-']) # K*0
996 BS.addChannel(['D_s*-', 'D*+', 'K_S0', 'pi0']) # K*0
997
998 # J/Psi
999 BS.addChannel(['J/psi', 'K_S0'])
1000 BS.addChannel(['J/psi', 'pi+', 'pi-'])
1001 BS.addChannel(['J/psi', 'K+', 'K-'], preCutConfig=BS.preCutConfig._replace(noBackgroundSampling=True)) # Phi
1002 BS.addChannel(['J/psi', 'K_S0', 'K-', 'pi+'])
1003 BS.addChannel(['J/psi', 'K-', 'K+', 'pi0'])
1004 BS.addChannel(['J/psi', 'pi-', 'pi+', 'pi0']) # Eta
1005 BS.addChannel(['J/psi', 'pi+', 'pi-', 'pi-', 'pi+', 'pi0']) # Etaprime
1006
1007 # Other
1008 BS.addChannel(['anti-D*0', 'K_S0'])
1009 BS.addChannel(['anti-D0', 'K_S0'])
1010 BS.addChannel(['anti-D0', 'K-', 'pi+'])
1011
1012 particles = []
1013 particles.append(pion)
1014 particles.append(kaon)
1015 if baryonic:
1016 particles.append(proton)
1017 particles.append(muon)
1018 particles.append(electron)
1019 particles.append(gamma)
1020
1021 particles.append(pi0)
1022 particles.append(KS0)
1023 if baryonic:
1024 particles.append(L0)
1025 particles.append(SigmaP)
1026 particles.append(Jpsi)
1027
1028 particles.append(D0)
1029 particles.append(DP)
1030 particles.append(DS)
1031 if baryonic:
1032 particles.append(LC)
1033
1034 particles.append(DS0)
1035 particles.append(DSP)
1036 particles.append(DSS)
1037
1038 if hadronic:
1039 if neutralB:
1040 particles.append(B0)
1041 if chargedB:
1042 particles.append(BP)
1043
1044 if KLong:
1045 particles.append(KL0)
1046 particles.append(D0_KL)
1047 particles.append(DP_KL)
1048 particles.append(DS_KL)
1049 particles.append(DS0_KL)
1050 particles.append(DSP_KL)
1051 particles.append(DSS_KL)
1052 if neutralB:
1053 particles.append(B0_KL)
1054 if chargedB:
1055 particles.append(BP_KL)
1056
1057 if semileptonic:
1058 if not removeSLD:
1059 particles.append(D0_SL)
1060 particles.append(DP_SL)
1061 particles.append(DS0_SL)
1062 particles.append(DSP_SL)
1063 if neutralB:
1064 particles.append(B0_SL)
1065 if chargedB:
1066 particles.append(BP_SL)
1067
1068 if strangeB:
1069 particles.append(BS)
1070
1071 return particles
1072
1073
1074def get_ccbarLambdaC_channels(
1075 specific=False,
1076 addPi0=False,
1077 addCharged=False,
1078 addStrangness=False,
1079 usePIDNN=False):
1080 """
1081 returns list of Particle objects with all default channels for running
1082 FEI on ccbar to tag Lambda_c+ decays
1083 These channel list has not been optimized yet and currenlty serves
1084 only as an example for FEI application on ccbar events.
1085 @param specific if True, this adds isInRestOfEvent cut to all FSP
1086 @param addPi0 if True, this adds pi0 to all channels
1087 @param addCharged if True, this adds charged pairs to all channels
1088 @param addStrangness if True, this adds strange particles to all channels
1089 @param usePIDNN if True, PID probabilities calculated from PID neural network are used (default is False)
1090 """
1091
1092 convertedFromBelle = b2bii.isB2BII()
1093
1094 if convertedFromBelle:
1095 if usePIDNN:
1096 B2FATAL("The PIDNN variables do not exist for b2bii.")
1097 # Using Belle specific Variables for e-ID, mu-ID and K-ID
1098 # atcPIDBelle(3,2) is used as K-ID
1099 # atcPIDBelle(4,2) and atcPIDBelle(4,3) are used as pr-ID
1100
1101 chargedVariables = ['eIDBelle',
1102 'atcPIDBelle(3,2)',
1103 'atcPIDBelle(4,2)', 'atcPIDBelle(4,3)',
1104 'muIDBelle'
1105 ]
1106 else:
1107 if usePIDNN:
1108 chargedVariables = ['electronIDNN', 'kaonIDNN', 'protonIDNN', 'muonIDNN']
1109 else:
1110 chargedVariables = ['electronID', 'kaonID', 'protonID', 'muonID']
1111
1112 chargedVariables += ['p', 'pt', 'pz', 'dr', 'dz', 'chiProb', 'extraInfo(preCut_rank)']
1113
1114 if specific:
1115 charged_user_cut = '[dr < 2] and [abs(dz) < 4] and isInRestOfEvent > 0.5'
1116 else:
1117 charged_user_cut = '[dr < 2] and [abs(dz) < 4]'
1118
1119 # region 1st stage
1120 pion = Particle('pi+',
1121 MVAConfiguration(variables=chargedVariables,
1122 target='isPrimarySignal'),
1123 PreCutConfiguration(userCut=charged_user_cut,
1124 bestCandidateMode='highest',
1125 bestCandidateVariable="atcPIDBelle(2,3)" if convertedFromBelle
1126 else ("pionIDNN" if usePIDNN else "pionID"),
1127 bestCandidateCut=20),
1128 PostCutConfiguration(bestCandidateCut=10, value=0.01))
1129 pion.addChannel(['pi+:FSP'])
1130
1131 kaon = Particle('K+',
1132 MVAConfiguration(variables=chargedVariables,
1133 target='isPrimarySignal'),
1134 PreCutConfiguration(userCut=charged_user_cut,
1135 bestCandidateMode='highest',
1136 bestCandidateVariable="atcPIDBelle(3,2)" if convertedFromBelle
1137 else ("kaonIDNN" if usePIDNN else "kaonID"),
1138 bestCandidateCut=20),
1139 PostCutConfiguration(bestCandidateCut=10, value=0.01))
1140 kaon.addChannel(['K+:FSP'])
1141
1142 proton = Particle('p+',
1143 MVAConfiguration(variables=chargedVariables,
1144 target='isPrimarySignal'),
1145 PreCutConfiguration(userCut=charged_user_cut,
1146 bestCandidateMode='highest',
1147 bestCandidateVariable="atcPIDBelle(4,3)" if convertedFromBelle
1148 else ("protonIDNN" if usePIDNN else "protonID"),
1149 bestCandidateCut=20),
1150 PostCutConfiguration(bestCandidateCut=10, value=0.01))
1151 proton.addChannel(['p+:FSP'])
1152
1153 electron = Particle('e+',
1154 MVAConfiguration(variables=chargedVariables,
1155 target='isPrimarySignal'),
1156 PreCutConfiguration(userCut=charged_user_cut,
1157 bestCandidateMode='highest',
1158 bestCandidateVariable="eIDBelle" if convertedFromBelle
1159 else ("electronIDNN" if usePIDNN else "electronID"),
1160 bestCandidateCut=10),
1161 PostCutConfiguration(bestCandidateCut=5, value=0.01))
1162 electron.addChannel(['e+:FSP'])
1163
1164 muon = Particle('mu+',
1165 MVAConfiguration(variables=chargedVariables,
1166 target='isPrimarySignal'),
1167 PreCutConfiguration(userCut=charged_user_cut,
1168 bestCandidateMode='highest',
1169 bestCandidateVariable="muIDBelle" if convertedFromBelle
1170 else ("muonIDNN" if usePIDNN else "muonID"),
1171 bestCandidateCut=10),
1172 PostCutConfiguration(bestCandidateCut=5, value=0.01))
1173 muon.addChannel(['mu+:FSP'])
1174
1175 if convertedFromBelle:
1176 gamma_cut = 'goodBelleGamma == 1 and clusterBelleQuality == 0'
1177 else:
1178 # Same as goodBelleGamma == 1
1179 gamma_cut = '[[clusterReg == 1 and E > 0.10] or [clusterReg == 2 and E > 0.05] or [clusterReg == 3 and E > 0.15]]'
1180 if specific:
1181 gamma_cut += ' and isInRestOfEvent > 0.5'
1182
1183 gamma = Particle('gamma',
1184 MVAConfiguration(variables=['clusterReg', 'clusterNHits', 'clusterTiming', 'extraInfo(preCut_rank)',
1185 'clusterE9E25', 'pt', 'E', 'pz'],
1186 target='isPrimarySignal'),
1187 PreCutConfiguration(userCut=gamma_cut,
1188 bestCandidateMode='highest',
1189 bestCandidateVariable='E',
1190 bestCandidateCut=40),
1191 PostCutConfiguration(bestCandidateCut=20, value=0.01))
1192 gamma.addChannel(['gamma:FSP'])
1193 gamma.addChannel(['gamma:V0'],
1194 MVAConfiguration(variables=['pt', 'E', 'pz', 'extraInfo(preCut_rank)'],
1195 target='isPrimarySignal'),
1196 PreCutConfiguration(userCut='',
1197 bestCandidateMode='highest',
1198 bestCandidateVariable='E',
1199 bestCandidateCut=40))
1200
1201 kl0_cut = ''
1202 if specific:
1203 kl0_cut += 'isInRestOfEvent > 0.5'
1204
1205 KL0 = Particle('K_L0',
1206 MVAConfiguration(variables=['E', 'klmClusterTiming'],
1207 target='isSignal'),
1208 PreCutConfiguration(userCut=kl0_cut,
1209 bestCandidateVariable='abs(dM)',
1210 bestCandidateCut=20),
1211 PostCutConfiguration(bestCandidateCut=10, value=0.01))
1212 KL0.addChannel(['K_L0:FSP'])
1213 # endregion 1st stage
1214
1215 # region 2nd stage
1216 variables.addAlias('eneAsy', 'formula((daughter(0,E)-daughter(1,E))/(daughter(0,E)+daughter(1,E)))')
1217 if convertedFromBelle:
1218 pi0_cut = '0.08 < InvM < 0.18'
1219 if specific:
1220 pi0_cut += ' and isInRestOfEvent > 0.5'
1221
1222 pi0 = Particle('pi0',
1223 MVAConfiguration(variables=['InvM', 'extraInfo(preCut_rank)', 'chiProb', 'abs(BellePi0SigM)',
1224 'daughterAngle(0,1)', 'pt', 'pz', 'E',
1225 'daughter({},E)', 'daughter({},clusterReg)'],
1226 target='isSignal'),
1227 PreCutConfiguration(userCut=pi0_cut,
1228 bestCandidateVariable='abs(BellePi0SigM)',
1229 bestCandidateCut=20),
1230 PostCutConfiguration(bestCandidateCut=10, value=0.01))
1231 pi0.addChannel(['pi0:FSP'])
1232
1233 Lam_cut = '0.9 < M < 1.3'
1234 if specific:
1235 Lam_cut += ' and isInRestOfEvent > 0.5'
1236 L0 = Particle(
1237 'Lambda0',
1238 MVAConfiguration(
1239 variables=[
1240 'dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M', 'abs(dM)',
1241 'useCMSFrame(E)', 'daughterAngle(0,1)',
1242 'cosAngleBetweenMomentumAndVertexVector',
1243 'extraInfo(preCut_rank)', 'extraInfo(goodLambda)', 'extraInfo(ksnbVLike)',
1244 'extraInfo(ksnbNoLam)'],
1245 target='isSignal'),
1246 PreCutConfiguration(
1247 userCut=Lam_cut,
1248 bestCandidateVariable='abs(dM)',
1249 bestCandidateCut=20),
1250 PostCutConfiguration(
1251 bestCandidateCut=10,
1252 value=0.01)
1253 )
1254 L0.addChannel(['Lambda0:V0'])
1255 else:
1256 pi0 = Particle('pi0',
1257 MVAConfiguration(variables=['M', 'daughter({},extraInfo(SignalProbability))', 'extraInfo(preCut_rank)',
1258 'daughterAngle(0,1)', 'pt', 'pz', 'E', 'abs(dM)',
1259 'daughter({},E)', 'daughter({},clusterReg)', 'eneAsy'],
1260 target='isSignal'),
1261 PreCutConfiguration(userCut='0.08 < M < 0.18',
1262 bestCandidateVariable='abs(dM)',
1263 bestCandidateCut=20),
1264 PostCutConfiguration(bestCandidateCut=10, value=0.01))
1265 pi0.addChannel(['gamma', 'gamma'])
1266
1267 L0 = Particle(
1268 'Lambda0',
1269 MVAConfiguration(
1270 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(
1277 userCut='0.9 < M < 1.3',
1278 bestCandidateVariable='abs(dM)',
1279 bestCandidateCut=20),
1280 PostCutConfiguration(
1281 bestCandidateCut=10,
1282 value=0.01)
1283 )
1284 L0.addChannel(['p+', 'pi-'])
1285
1286 Lam_cut = '0.9 < M < 1.3'
1287 if specific:
1288 Lam_cut += ' and isInRestOfEvent > 0.5'
1289
1290 L0.addChannel(
1291 ['Lambda0:V0'],
1292 MVAConfiguration(
1293 variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M',
1294 'useCMSFrame(E)', 'daughterAngle(0,1)', 'extraInfo(preCut_rank)', 'abs(dM)',
1295 'useRestFrame(daughter({}, p))', 'cosAngleBetweenMomentumAndVertexVector',
1296 'daughter({}, dz)', 'daughter({}, dr)'],
1297 target='isSignal'),
1298 PreCutConfiguration(
1299 userCut=Lam_cut,
1300 bestCandidateVariable='abs(dM)',
1301 bestCandidateCut=20))
1302 # endregion 2nd stage
1303
1304 # region 3rd stage
1305 if convertedFromBelle:
1306 ks0_cut = '0.4 < M < 0.6'
1307 if specific:
1308 ks0_cut += ' and isInRestOfEvent > 0.5'
1309
1310 KS0 = Particle(
1311 'K_S0',
1312 MVAConfiguration(
1313 variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M', 'abs(dM)',
1314 'useCMSFrame(E)', 'daughterAngle(0,1)',
1315 'cosAngleBetweenMomentumAndVertexVector',
1316 'extraInfo(preCut_rank)', 'extraInfo(goodKs)', 'extraInfo(ksnbVLike)',
1317 'extraInfo(ksnbNoLam)', 'extraInfo(ksnbStandard)'],
1318 target='isSignal'),
1319 PreCutConfiguration(
1320 userCut=ks0_cut,
1321 bestCandidateVariable='abs(dM)',
1322 bestCandidateCut=20),
1323 PostCutConfiguration(
1324 bestCandidateCut=10,
1325 value=0.01)
1326 )
1327 KS0.addChannel(['K_S0:V0'])
1328 else:
1329 KS0 = Particle(
1330 'K_S0',
1331 MVAConfiguration(
1332 variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M', 'abs(dM)',
1333 'useCMSFrame(E)', 'daughterAngle(0,1)',
1334 'useRestFrame(daughterAngle(0,1))',
1335 'daughter({},extraInfo(SignalProbability))',
1336 'useRestFrame(daughter({}, p))', 'cosAngleBetweenMomentumAndVertexVector',
1337 'daughter({}, dz)', 'daughter({}, dr)', 'extraInfo(preCut_rank)', 'eneAsy'],
1338 target='isSignal'),
1339 PreCutConfiguration(
1340 userCut='0.4 < M < 0.6',
1341 bestCandidateVariable='abs(dM)',
1342 bestCandidateCut=20),
1343 PostCutConfiguration(
1344 bestCandidateCut=10,
1345 value=0.01)
1346 )
1347 KS0.addChannel(['pi+', 'pi-'])
1348 KS0.addChannel(['pi0', 'pi0'])
1349
1350 ks0_cut = '0.4 < M < 0.6'
1351 if specific:
1352 ks0_cut += ' and isInRestOfEvent > 0.5'
1353
1354 KS0.addChannel(
1355 ['K_S0:V0'],
1356 MVAConfiguration(
1357 variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M',
1358 'useCMSFrame(E)', 'daughterAngle(0,1)', 'extraInfo(preCut_rank)', 'abs(dM)',
1359 'useRestFrame(daughter({}, p))', 'cosAngleBetweenMomentumAndVertexVector',
1360 'daughter({}, dz)', 'daughter({}, dr)'],
1361 target='isSignal'),
1362 PreCutConfiguration(
1363 userCut=ks0_cut,
1364 bestCandidateVariable='abs(dM)',
1365 bestCandidateCut=20))
1366
1367 SigmaP = Particle(
1368 'Sigma+',
1369 MVAConfiguration(
1370 variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M', 'abs(dM)',
1371 'useCMSFrame(E)', 'daughterAngle(0,1)',
1372 'daughter({},extraInfo(SignalProbability))',
1373 'useRestFrame(daughter({}, p))', 'cosAngleBetweenMomentumAndVertexVector',
1374 'daughter({}, dz)', 'daughter({}, dr)', 'extraInfo(preCut_rank)'],
1375 target='isSignal'),
1376 PreCutConfiguration(
1377 userCut='1.0 < M < 1.4',
1378 bestCandidateVariable='abs(dM)',
1379 bestCandidateCut=20),
1380 PostCutConfiguration(
1381 bestCandidateCut=10,
1382 value=0.01)
1383 )
1384 SigmaP.addChannel(['p+', 'pi0'])
1385 # endregion 3rd stage
1386
1387 # region 4th stage
1388 pi0vetovars = ['extraInfo(pi0vetoMass)', 'extraInfo(pi0vetoEneAsy)']
1389
1390 # variables for D mesons
1391 variables.addAlias('significanceOfFlightDistance', 'formula(flightDistance/flightDistanceErr)')
1392 Dtag_vars = [
1393 'pValueCombinationOfDaughters(extraInfo(SignalProbability))',
1394 'daughter({},extraInfo(SignalProbability))',
1395 'chiProb',
1396 'daughter({}, chiProb)',
1397 'extraInfo(preCut_rank)',
1398 'abs(dM)', 'Q',
1399 'useRestFrame(daughter({}, p))',
1400 'useRestFrame(daughter({}, distance))',
1401 'useCMSFrame(p)',
1402 'decayAngle({1..})',
1403 'daughterAngle({},{})',
1404 'daughterInvM({},{})',
1405 'daughterInvM({},{},{})',
1406 'daughterInvM({},{},{},{})',
1407 'daughterInvM({},{},{},{},{})',
1408 'daughter({},extraInfo(decayModeID))',
1409 'cosAngleBetweenMomentumAndVertexVector',
1410 'cosAngleBetweenMomentumAndVertexVectorInXYPlane',
1411 'vertexDistance',
1412 'vertexDistanceSignificance',
1413 'vertexDistanceOfDaughter({})',
1414 'vertexDistanceOfDaughterSignificance({})',
1415 'significanceOfFlightDistance'
1416 ]
1417
1418 D0 = Particle('D0',
1419 MVAConfiguration(variables=Dtag_vars,
1420 target='isSignal'),
1421 PreCutConfiguration(userCut='1.7 < M < 1.95',
1422 bestCandidateVariable='abs(dM)',
1423 bestCandidateCut=20),
1424 PostCutConfiguration(bestCandidateCut=10, value=0.001))
1425 D0.addChannel(['K-', 'pi+'])
1426 D0.addChannel(['K-', 'pi+', 'pi0'])
1427 D0.addChannel(['K-', 'pi+', 'pi+', 'pi-'])
1428 D0.addChannel(['K-', 'pi+', 'pi+', 'pi-', 'pi0'])
1429 D0.addChannel(['K_S0', 'pi+', 'pi-'])
1430 D0.addChannel(['K_S0', 'pi+', 'pi-', 'pi0'])
1431
1432 D0.addChannel(['K-', 'pi+', 'pi0', 'pi0'])
1433 D0.addChannel(['pi-', 'pi+'])
1434 D0.addChannel(['pi-', 'pi+', 'pi+', 'pi-'])
1435 D0.addChannel(['pi-', 'pi+', 'pi0'])
1436 D0.addChannel(['pi-', 'pi+', 'pi0', 'pi0'])
1437 D0.addChannel(['K-', 'K+'])
1438 D0.addChannel(['K-', 'K+', 'pi0'])
1439 D0.addChannel(['K-', 'K+', 'K_S0'])
1440 D0.addChannel(['K_S0', 'pi0'])
1441
1442 DP = Particle('D+',
1443 MVAConfiguration(variables=Dtag_vars,
1444 target='isSignal'),
1445 PreCutConfiguration(userCut='1.7 < M < 1.95',
1446 bestCandidateVariable='abs(dM)',
1447 bestCandidateCut=20),
1448 PostCutConfiguration(bestCandidateCut=10, value=0.001))
1449 DP.addChannel(['K-', 'pi+', 'pi+'])
1450 DP.addChannel(['K-', 'pi+', 'pi+', 'pi0'])
1451 DP.addChannel(['K_S0', 'pi+'])
1452 DP.addChannel(['K_S0', 'pi+', 'pi0'])
1453 DP.addChannel(['K_S0', 'pi+', 'pi+', 'pi-'])
1454 DP.addChannel(['K-', 'K+', 'pi+'])
1455
1456 DP.addChannel(['K-', 'K+', 'pi+', 'pi0'])
1457 DP.addChannel(['pi+', 'pi0'])
1458 DP.addChannel(['pi+', 'pi+', 'pi-'])
1459 DP.addChannel(['pi+', 'pi+', 'pi-', 'pi0'])
1460 DP.addChannel(['K+', 'K_S0', 'K_S0'])
1461
1462 DS = Particle('D_s+',
1463 MVAConfiguration(variables=Dtag_vars,
1464 target='isSignal'),
1465 PreCutConfiguration(userCut='1.68 < M < 2.1',
1466 bestCandidateVariable='abs(dM)',
1467 bestCandidateCut=20),
1468 PostCutConfiguration(bestCandidateCut=10, value=0.001))
1469 DS.addChannel(['K+', 'pi+', 'pi-'])
1470 DS.addChannel(['K_S0', 'K+'])
1471 DS.addChannel(['K_S0', 'K_S0', 'pi+'])
1472 DS.addChannel(['K+', 'K-', 'pi+', 'pi0'])
1473 DS.addChannel(['K-', 'K_S0', 'pi+', 'pi+'])
1474
1475 DS.addChannel(['K+', 'K-', 'pi+'])
1476 DS.addChannel(['K+', 'K_S0', 'pi+', 'pi-'])
1477 DS.addChannel(['K+', 'K-', 'pi+', 'pi+', 'pi-'])
1478 DS.addChannel(['pi+', 'pi+', 'pi-'])
1479 DS.addChannel(['K_S0', 'pi+'])
1480 DS.addChannel(['K_S0', 'pi+', 'pi0'])
1481
1482 LC = Particle('Lambda_c+',
1483 MVAConfiguration(variables=Dtag_vars,
1484 target='isSignal'),
1485 PreCutConfiguration(userCut='2.2 < M < 2.4',
1486 bestCandidateVariable='abs(dM)',
1487 bestCandidateCut=20),
1488 PostCutConfiguration(bestCandidateCut=10, value=0.001))
1489 LC.addChannel(['p+', 'K-', 'pi+'])
1490 LC.addChannel(['p+', 'K-', 'pi+', 'pi0'])
1491 LC.addChannel(['p+', 'K_S0'])
1492 LC.addChannel(['Lambda0', 'pi+'])
1493 LC.addChannel(['Lambda0', 'pi+', 'pi0'])
1494 LC.addChannel(['Lambda0', 'pi+', 'pi+', 'pi-'])
1495
1496 LC.addChannel(['p+', 'pi-', 'pi+'])
1497 LC.addChannel(['p+', 'K-', 'K+'])
1498 LC.addChannel(['p+', 'K-', 'pi+', 'pi0', 'pi0'])
1499 LC.addChannel(['p+', 'pi+', 'pi+', 'pi-', 'pi-'])
1500 LC.addChannel(['p+', 'K_S0', 'pi0'])
1501 LC.addChannel(['p+', 'K_S0', 'pi+', 'pi-'])
1502 LC.addChannel(['Lambda0', 'pi+', 'gamma'],
1503 MVAConfiguration(variables=Dtag_vars+pi0vetovars, target='isSignal'),
1504 pi0veto=True)
1505 LC.addChannel(['Lambda0', 'pi+', 'pi0', 'gamma'],
1506 MVAConfiguration(variables=Dtag_vars+pi0vetovars, target='isSignal'),
1507 pi0veto=True)
1508 LC.addChannel(['Lambda0', 'pi+', 'pi-', 'pi+', 'gamma'],
1509 MVAConfiguration(variables=Dtag_vars+pi0vetovars, target='isSignal'),
1510 pi0veto=True)
1511 LC.addChannel(['Sigma+', 'pi+', 'pi-'])
1512 LC.addChannel(['Sigma+', 'pi+', 'pi-', 'pi0'])
1513 LC.addChannel(['Sigma+', 'pi0'])
1514 # endregion 4th stage
1515
1516 # region 5th stage
1517 Dstar_vars = Dtag_vars + ['pointingAngle(0)', 'massDifference(0)']
1518 DSP = Particle('D*+',
1519 MVAConfiguration(variables=Dstar_vars,
1520 target='isSignal'),
1521 PreCutConfiguration(userCut='0 < Q < 0.3',
1522 bestCandidateVariable='abs(dQ)',
1523 bestCandidateCut=20),
1524 PostCutConfiguration(bestCandidateCut=10, value=0.001))
1525 DSP.addChannel(['D0', 'pi+'])
1526 DSP.addChannel(['D+', 'pi0'])
1527 DSP.addChannel(['D+', 'gamma'],
1528 MVAConfiguration(variables=Dstar_vars+pi0vetovars, target='isSignal'),
1529 pi0veto=True)
1530
1531 DS0 = Particle('D*0',
1532 MVAConfiguration(variables=Dstar_vars,
1533 target='isSignal'),
1534 PreCutConfiguration(userCut='0 < Q < 0.3',
1535 bestCandidateVariable='abs(dQ)',
1536 bestCandidateCut=20),
1537 PostCutConfiguration(bestCandidateCut=10, value=0.001))
1538 DS0.addChannel(['D0', 'pi0'])
1539 DS0.addChannel(['D0', 'gamma'],
1540 MVAConfiguration(variables=Dstar_vars+pi0vetovars, target='isSignal'),
1541 pi0veto=True)
1542
1543 DSS = Particle('D_s*+',
1544 MVAConfiguration(variables=Dstar_vars,
1545 target='isSignal'),
1546 PreCutConfiguration(userCut='0.0 < Q < 0.3',
1547 bestCandidateVariable='abs(dQ)',
1548 bestCandidateCut=20),
1549 PostCutConfiguration(bestCandidateCut=10, value=0.001))
1550 DSS.addChannel(['D_s+', 'gamma'],
1551 MVAConfiguration(variables=Dstar_vars+pi0vetovars, target='isSignal'),
1552 pi0veto=True)
1553 DSS.addChannel(['D_s+', 'pi0'])
1554 # endregion 5th stage
1555
1556 CharmTag_vars = [
1557 'pValueCombinationOfDaughters(extraInfo(SignalProbability))',
1558 'daughter({},extraInfo(SignalProbability))',
1559 'chiProb',
1560 'daughter({}, chiProb)',
1561 'extraInfo(preCut_rank)',
1562 'useCMSFrame(daughter({1..}, p))',
1563 'useCMSFrame(daughter({}, distance))',
1564 'decayAngle({1..})',
1565 'useCMSFrame(daughterAngle(0,{1..}))',
1566 'cosAngleBetweenMomentumAndVertexVector',
1567 'cosAngleBetweenMomentumAndVertexVectorInXYPlane',
1568 'dr', 'dz', 'dx', 'dy', 'distance', 'significanceOfDistance',
1569 'daughter({},extraInfo(decayModeID))',
1570 'useCMSFrame(p)',
1571 'useCMSFrame(angleBetweenDaughterAndRecoil(0))',
1572 'vertexDistance',
1573 'vertexDistanceSignificance',
1574 'vertexDistanceOfDaughter({})',
1575 'vertexDistanceOfDaughterSignificance({})',
1576 'massDiffRecoil({2..})',
1577 'significanceOfFlightDistance',
1578 ]
1579
1580 ccbarTag_user_cut = '1.8 < mRecoil < 2.6'
1581 variables.addAlias('ccbarTagSignalBinary', 'conditionalVariableSelector(ccbarTagSignal==1,1,0)')
1582
1583 # region 6th stage
1584 LambdaCTag = Particle(
1585 'Lambda_c+:ccbarTag',
1586 MVAConfiguration(
1587 config='--nTrees 400 --nCutLevels 10 --nLevels 3 --shrinkage 0.1 --randRatio 0.5', # --flatnessLoss 1.0',
1588 variables=CharmTag_vars,
1589 spectators={'mRecoil': (1.8, 2.6)},
1590 target='ccbarTagSignalBinary'),
1591 PreCutConfiguration(
1592 userCut=ccbarTag_user_cut,
1593 bestCandidateMode='highest',
1594 bestCandidateVariable='pValueCombinationOfDaughters(extraInfo(SignalProbability))',
1595 noSignalSampling=True,
1596 bkgSamplingFactor=0.01,
1597 bestCandidateCut=20),
1598 PostCutConfiguration(bestCandidateCut=20))
1599 LambdaCTag.addChannel(['D0', 'p+'])
1600 LambdaCTag.addChannel(['D*0', 'p+'])
1601 LambdaCTag.addChannel(['D+', 'p+', 'pi-'])
1602 LambdaCTag.addChannel(['D*+', 'p+', 'pi-'])
1603 LambdaCTag.addChannel(['D_s+', 'p+', 'K-'])
1604 LambdaCTag.addChannel(['D_s*+', 'p+', 'K-'])
1605
1606 if addCharged:
1607 LambdaCTagCharged = Particle(
1608 'Lambda_c+:ccbarTagCharged',
1609 MVAConfiguration(
1610 config='--nTrees 400 --nCutLevels 10 --nLevels 3 --shrinkage 0.1 --randRatio 0.5', # --flatnessLoss 1.0',
1611 variables=CharmTag_vars,
1612 spectators={'mRecoil': (1.8, 2.6)},
1613 target='ccbarTagSignalBinary'),
1614 PreCutConfiguration(
1615 userCut=ccbarTag_user_cut,
1616 bestCandidateMode='highest',
1617 bestCandidateVariable='pValueCombinationOfDaughters(extraInfo(SignalProbability))',
1618 noSignalSampling=True,
1619 bkgSamplingFactor=0.1,
1620 bestCandidateCut=20),
1621 PostCutConfiguration(bestCandidateCut=20))
1622 LambdaCTagCharged.addChannel(['D0', 'p+', 'pi+', 'pi-'])
1623 LambdaCTagCharged.addChannel(['D*0', 'p+', 'pi+', 'pi-'])
1624 LambdaCTagCharged.addChannel(['D+', 'p+', 'pi-', 'pi+', 'pi-'])
1625 LambdaCTagCharged.addChannel(['D*+', 'p+', 'pi-', 'pi+', 'pi-'])
1626 LambdaCTagCharged.addChannel(['D_s+', 'p+', 'K-', 'pi+', 'pi-'])
1627 LambdaCTagCharged.addChannel(['D_s*+', 'p+', 'K-', 'pi+', 'pi-'])
1628 LambdaCTagCharged.addChannel(['D0', 'p+', 'K+', 'K-'])
1629 LambdaCTagCharged.addChannel(['D*0', 'p+', 'K+', 'K-'])
1630 LambdaCTagCharged.addChannel(['D+', 'p+', 'pi-', 'K+', 'K-'])
1631 LambdaCTagCharged.addChannel(['D*+', 'p+', 'pi-', 'K+', 'K-'])
1632
1633 LambdaCTagCharged.addChannel(['D0', 'p+', 'p+', 'anti-p-'])
1634 LambdaCTagCharged.addChannel(['D*0', 'p+', 'p+', 'anti-p-'])
1635
1636 if addPi0:
1637 LambdaCTagPi0 = Particle(
1638 'Lambda_c+:ccbarTagPi0',
1639 MVAConfiguration(
1640 config='--nTrees 400 --nCutLevels 10 --nLevels 3 --shrinkage 0.1 --randRatio 0.5', # --flatnessLoss 1.0',
1641 variables=CharmTag_vars,
1642 spectators={'mRecoil': (1.8, 2.6)},
1643 target='ccbarTagSignalBinary'),
1644 PreCutConfiguration(
1645 userCut=ccbarTag_user_cut,
1646 bestCandidateMode='highest',
1647 bestCandidateVariable='pValueCombinationOfDaughters(extraInfo(SignalProbability))',
1648 noSignalSampling=True,
1649 bkgSamplingFactor=0.05,
1650 bestCandidateCut=20),
1651 PostCutConfiguration(bestCandidateCut=20))
1652 LambdaCTagPi0.addChannel(['D0', 'p+', 'pi0'])
1653 LambdaCTagPi0.addChannel(['D*0', 'p+', 'pi0'])
1654 LambdaCTagPi0.addChannel(['D+', 'p+', 'pi-', 'pi0'])
1655 LambdaCTagPi0.addChannel(['D*+', 'p+', 'pi-', 'pi0'])
1656 LambdaCTagPi0.addChannel(['D_s+', 'p+', 'K-', 'pi0'])
1657 LambdaCTagPi0.addChannel(['D_s*+', 'p+', 'K-', 'pi0'])
1658
1659 if addStrangness:
1660 LambdaCTagStrange = Particle(
1661 'Lambda_c+:ccbarTagStrange',
1662 MVAConfiguration(
1663 config='--nTrees 400 --nCutLevels 10 --nLevels 3 --shrinkage 0.1 --randRatio 0.5', # --flatnessLoss 1.0',
1664 variables=CharmTag_vars,
1665 spectators={'mRecoil': (1.8, 2.6)},
1666 target='ccbarTagSignalBinary'),
1667 PreCutConfiguration(
1668 userCut=ccbarTag_user_cut,
1669 bestCandidateMode='highest',
1670 bestCandidateVariable='pValueCombinationOfDaughters(extraInfo(SignalProbability))',
1671 noSignalSampling=True,
1672 bkgSamplingFactor=0.05,
1673 bestCandidateCut=20),
1674 PostCutConfiguration(bestCandidateCut=20))
1675 LambdaCTagStrange.addChannel(['D0', 'Lambda0', 'K+'])
1676 LambdaCTagStrange.addChannel(['D*0', 'Lambda0', 'K+'])
1677 LambdaCTagStrange.addChannel(['D*+', 'Lambda0', 'K_S0'])
1678 LambdaCTagStrange.addChannel(['D_s+', 'Lambda0'])
1679 LambdaCTagStrange.addChannel(['D_s*+', 'Lambda0'])
1680 LambdaCTagStrange.addChannel(['D*+', 'p+', 'K_S0', 'K-'])
1681 LambdaCTagStrange.addChannel(['D_s+', 'p+', 'K_S0', 'pi-'])
1682 LambdaCTagStrange.addChannel(['D_s*+', 'p+', 'K_S0', 'pi-'])
1683 LambdaCTagStrange.addChannel(['D0', 'Lambda0', 'K_S0', 'pi+'])
1684 LambdaCTagStrange.addChannel(['D+', 'Lambda0', 'K+', 'pi-'])
1685 LambdaCTagStrange.addChannel(['D*+', 'Lambda0', 'K+', 'pi-'])
1686
1687 LambdaCTagStrange.addChannel(['D0', 'Lambda0', 'K+', 'pi0'])
1688
1689 LambdaCTagStrange.addChannel(['D0', 'Lambda0', 'K+', 'pi+', 'pi-'])
1690 LambdaCTagStrange.addChannel(['D*0', 'Lambda0', 'K+', 'pi+', 'pi-'])
1691 LambdaCTagStrange.addChannel(['D_s+', 'Lambda0', 'pi+', 'pi-'])
1692 LambdaCTagStrange.addChannel(['D_s*+', 'Lambda0', 'pi+', 'pi-'])
1693
1694 LambdaCTagStrange.addChannel(['D0', 'Lambda0', 'K+', 'pi+', 'pi-', 'pi0'])
1695 LambdaCTagStrange.addChannel(['D_s+', 'Lambda0', 'pi+', 'pi-', 'pi0'])
1696 LambdaCTagStrange.addChannel(['D_s*+', 'Lambda0', 'pi+', 'pi-', 'pi0'])
1697
1698 # endregion 6th stage
1699
1700 particles = []
1701 particles.append(pion)
1702 particles.append(kaon)
1703 particles.append(proton)
1704 particles.append(muon)
1705 particles.append(electron)
1706 particles.append(gamma)
1707
1708 particles.append(pi0)
1709 particles.append(KS0)
1710 particles.append(SigmaP)
1711 particles.append(L0)
1712
1713 particles.append(D0)
1714 particles.append(DP)
1715 particles.append(DS)
1716 particles.append(LC)
1717
1718 particles.append(DS0)
1719 particles.append(DSP)
1720 particles.append(DSS)
1721
1722 particles.append(LambdaCTag)
1723 if addCharged:
1724 particles.append(LambdaCTagCharged)
1725 if addPi0:
1726 particles.append(LambdaCTagPi0)
1727 if addStrangness:
1728 particles.append(LambdaCTagStrange)
1729
1730 return particles
1731
1732
1733def get_unittest_channels(specific=False):
1734 chargedVariables = ['electronID', 'extraInfo(preCut_rank)',
1735 'kaonID', 'protonID', 'muonID',
1736 'p', 'pt', 'pz', 'dr', 'dz', 'chiProb']
1737
1738 specific_cut = ''
1739 if specific:
1740 specific_cut = ' and isInRestOfEvent > 0.5'
1741
1742 pion = Particle('pi+',
1743 MVAConfiguration(variables=chargedVariables,
1744 target='isPrimarySignal'),
1745 PreCutConfiguration(userCut='[dr < 2] and [abs(dz) < 4]' + specific_cut,
1746 bestCandidateMode='highest',
1747 bestCandidateVariable='pionID',
1748 bestCandidateCut=20),
1749 PostCutConfiguration(bestCandidateCut=10, value=0.01))
1750 pion.addChannel(['pi+:FSP'])
1751
1752 kaon = Particle('K+',
1753 MVAConfiguration(variables=chargedVariables,
1754 target='isPrimarySignal'),
1755 PreCutConfiguration(userCut='[dr < 2] and [abs(dz) < 4]' + specific_cut,
1756 bestCandidateMode='highest',
1757 bestCandidateVariable='kaonID',
1758 bestCandidateCut=20),
1759 PostCutConfiguration(bestCandidateCut=10, value=0.01))
1760 kaon.addChannel(['K+:FSP'])
1761
1762 muon = Particle('mu+',
1763 MVAConfiguration(variables=chargedVariables,
1764 target='isPrimarySignal'),
1765 PreCutConfiguration(userCut='[dr < 2] and [abs(dz) < 4]' + specific_cut,
1766 bestCandidateVariable='muonID',
1767 bestCandidateMode='highest',
1768 bestCandidateCut=10),
1769 PostCutConfiguration(bestCandidateCut=5, value=0.01))
1770 muon.addChannel(['mu+:FSP'])
1771
1772 gamma = Particle('gamma',
1773 MVAConfiguration(variables=['clusterReg', 'clusterNHits', 'clusterTiming', 'clusterE9E25',
1774 'pt', 'E', 'pz', 'extraInfo(preCut_rank)'],
1775 target='isPrimarySignal'),
1776 PreCutConfiguration(userCut='E > 0.05' + specific_cut,
1777 bestCandidateMode='highest',
1778 bestCandidateVariable='E',
1779 bestCandidateCut=40),
1780 PostCutConfiguration(bestCandidateCut=20, value=0.01))
1781 gamma.addChannel(['gamma:FSP'])
1782 gamma.addChannel(['gamma:V0'],
1783 MVAConfiguration(variables=['pt', 'E', 'pz'],
1784 target='isPrimarySignal'))
1785
1786 pi0 = Particle('pi0',
1787 MVAConfiguration(variables=['M', 'daughter({},extraInfo(SignalProbability))', 'extraInfo(preCut_rank)',
1788 'daughterAngle(0,1)', 'pt', 'pz', 'E', 'abs(dM)'],
1789 target='isSignal'),
1790 PreCutConfiguration(userCut='0.08 < M < 0.18',
1791 bestCandidateVariable='abs(dM)',
1792 bestCandidateCut=20),
1793 PostCutConfiguration(bestCandidateCut=10, value=0.01))
1794 pi0.addChannel(['gamma', 'gamma'])
1795
1796 intermediate_vars = ['daughterProductOf(extraInfo(SignalProbability))', 'daughter({},extraInfo(SignalProbability))',
1797 'chiProb', 'daughter({}, chiProb)', 'extraInfo(preCut_rank)', 'abs(dM)',
1798 'useRestFrame(daughter({}, p))',
1799 'useRestFrame(daughter({}, distance))',
1800 'decayAngle({})', 'daughterAngle({},{})', 'cosAngleBetweenMomentumAndVertexVector',
1801 'daughterInvariantMass({},{})', 'daughterInvariantMass({},{},{})', 'daughterInvariantMass({},{},{},{})',
1802 'daughterInvariantMass({},{},{},{},{})', 'dQ', 'Q', 'dM', 'daughter({},extraInfo(decayModeID))']
1803
1804 D0 = Particle('D0',
1805 MVAConfiguration(variables=intermediate_vars,
1806 target='isSignal'),
1807 PreCutConfiguration(userCut='1.7 < M < 1.95',
1808 bestCandidateVariable='abs(dM)',
1809 bestCandidateCut=20),
1810 PostCutConfiguration(bestCandidateCut=10, value=0.001))
1811 D0.addChannel(['K-', 'pi+'])
1812 D0.addChannel(['K-', 'pi+', 'pi0'])
1813 D0.addChannel(['pi-', 'pi+'])
1814
1815 D0_SL = Particle('D0:semileptonic',
1816 MVAConfiguration(variables=intermediate_vars,
1817 target='isSignalAcceptMissingNeutrino'),
1818 PreCutConfiguration(userCut='',
1819 bestCandidateMode='highest',
1820 bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
1821 bestCandidateCut=20),
1822 PostCutConfiguration(bestCandidateCut=10, value=0.001))
1823
1824 D0_SL.addChannel(['K-', 'mu+'])
1825 D0_SL.addChannel(['K-', 'pi0', 'mu+'])
1826
1827 particles = [gamma, muon, pion, kaon, pi0, D0, D0_SL]
1828 return particles
1829
1830
1831def get_fr_channels(convertedFromBelle=False):
1832 """
1833 Get channels of original FR for comparison
1834 @param convertedFromBelle whether to use Belle variables which is necessary for b2bii converted data (default is False)
1835 """
1836
1837 if convertedFromBelle:
1838 # Using Belle specific Variables for e-ID, mu-ID and K-ID
1839 # atcPIDBelle(3,2) is used as K-ID
1840 # atcPIDBelle(4,2) and atcPIDBelle(4,3) are used as pr-ID
1841 chargedVariables = ['eIDBelle',
1842 'atcPIDBelle(3,2)',
1843 'atcPIDBelle(4,2)', 'atcPIDBelle(4,3)',
1844 'muIDBelle',
1845 'p', 'pt', 'pz', 'dr', 'dz', 'chiProb', 'extraInfo(preCut_rank)']
1846 else:
1847 chargedVariables = ['electronID', 'kaonID', 'protonID', 'muonID',
1848 'p', 'pt', 'pz', 'dr', 'dz', 'chiProb', 'extraInfo(preCut_rank)']
1849
1850 charged_user_cut = '[dr < 2] and [abs(dz) < 4]'
1851
1852 pion = Particle('pi+',
1853 MVAConfiguration(variables=chargedVariables,
1854 target='isPrimarySignal'),
1855 PreCutConfiguration(userCut=charged_user_cut,
1856 bestCandidateMode='highest',
1857 bestCandidateVariable='pionID' if not convertedFromBelle else 'atcPIDBelle(2,3)',
1858 bestCandidateCut=20),
1859 PostCutConfiguration(bestCandidateCut=10, value=0.01))
1860 pion.addChannel(['pi+:FSP'])
1861
1862 kaon = Particle('K+',
1863 MVAConfiguration(variables=chargedVariables,
1864 target='isPrimarySignal'),
1865 PreCutConfiguration(userCut=charged_user_cut,
1866 bestCandidateMode='highest',
1867 bestCandidateVariable='kaonID' if not convertedFromBelle else 'atcPIDBelle(3,2)',
1868 bestCandidateCut=20),
1869 PostCutConfiguration(bestCandidateCut=10, value=0.01))
1870 kaon.addChannel(['K+:FSP'])
1871
1872 electron = Particle('e+',
1873 MVAConfiguration(variables=chargedVariables,
1874 target='isPrimarySignal'),
1875 PreCutConfiguration(userCut=charged_user_cut,
1876 bestCandidateMode='highest',
1877 bestCandidateVariable='electronID' if not convertedFromBelle else 'eIDBelle',
1878 bestCandidateCut=10),
1879 PostCutConfiguration(bestCandidateCut=10, value=0.01))
1880 electron.addChannel(['e+:FSP'])
1881
1882 muon = Particle('mu+',
1883 MVAConfiguration(variables=chargedVariables,
1884 target='isPrimarySignal'),
1885 PreCutConfiguration(userCut=charged_user_cut,
1886 bestCandidateMode='highest',
1887 bestCandidateVariable='muonID' if not convertedFromBelle else 'muIDBelle',
1888 bestCandidateCut=10),
1889 PostCutConfiguration(bestCandidateCut=10, value=0.01))
1890 muon.addChannel(['mu+:FSP'])
1891
1892 high_energy_photon = '[[clusterReg == 1 and E > 0.10] or [clusterReg == 2 and E > 0.09] or [clusterReg == 3 and E > 0.16]]'
1893 gamma = Particle('gamma',
1894 MVAConfiguration(variables=['clusterReg', 'clusterNHits', 'clusterTiming', 'extraInfo(preCut_rank)',
1895 'clusterE9E25', 'pt', 'E', 'pz'],
1896 target='isPrimarySignal'),
1897 PreCutConfiguration(userCut=high_energy_photon if not convertedFromBelle else
1898 'goodBelleGamma == 1 and clusterBelleQuality == 0',
1899 bestCandidateMode='highest',
1900 bestCandidateVariable='E',
1901 bestCandidateCut=40),
1902 PostCutConfiguration(bestCandidateCut=20, value=0.01))
1903 gamma.addChannel(['gamma:FSP'])
1904 gamma.addChannel(['gamma:V0'],
1905 MVAConfiguration(variables=['pt', 'E', 'pz', 'extraInfo(preCut_rank)'],
1906 target='isPrimarySignal'),
1907 PreCutConfiguration(userCut='',
1908 bestCandidateMode='highest',
1909 bestCandidateVariable='E',
1910 bestCandidateCut=40))
1911
1912 if convertedFromBelle:
1913
1914 pi0 = Particle('pi0',
1915 MVAConfiguration(variables=['InvM', 'extraInfo(preCut_rank)', 'chiProb', 'abs(BellePi0SigM)',
1916 'daughterAngle(0,1)', 'pt', 'pz', 'E'],
1917 target='isSignal'),
1918 PreCutConfiguration(userCut='0.08 < InvM < 0.18',
1919 bestCandidateVariable='abs(BellePi0SigM)',
1920 bestCandidateCut=20),
1921 PostCutConfiguration(bestCandidateCut=10, value=0.01))
1922 pi0.addChannel(['pi0:FSP'])
1923
1924 KS0 = Particle('K_S0',
1925 MVAConfiguration(variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M', 'abs(dM)',
1926 'useCMSFrame(E)', 'daughterAngle(0,1)',
1927 'cosAngleBetweenMomentumAndVertexVector',
1928 'extraInfo(preCut_rank)', 'extraInfo(goodKs)', 'extraInfo(ksnbVLike)',
1929 'extraInfo(ksnbNoLam)', 'extraInfo(ksnbStandard)'],
1930 target='isSignal'),
1931 PreCutConfiguration(userCut='0.4 < M < 0.6',
1932 bestCandidateVariable='abs(dM)',
1933 bestCandidateCut=20),
1934 PostCutConfiguration(bestCandidateCut=10, value=0.01))
1935 KS0.addChannel(['K_S0:V0'])
1936
1937 else:
1938
1939 pi0 = Particle('pi0',
1940 MVAConfiguration(variables=['M', 'daughter({},extraInfo(SignalProbability))', 'extraInfo(preCut_rank)',
1941 'daughterAngle(0,1)', 'pt', 'pz', 'E', 'abs(dM)'],
1942 target='isSignal'),
1943 PreCutConfiguration(userCut='0.08 < M < 0.18',
1944 bestCandidateVariable='abs(dM)',
1945 bestCandidateCut=20),
1946 PostCutConfiguration(bestCandidateCut=10, value=0.01))
1947 pi0.addChannel(['gamma', 'gamma'])
1948
1949 KS0 = Particle('K_S0',
1950 MVAConfiguration(variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M', 'abs(dM)',
1951 'useCMSFrame(E)', 'daughterAngle(0,1)',
1952 'daughter({},extraInfo(SignalProbability))',
1953 'useRestFrame(daughter({}, p))', 'cosAngleBetweenMomentumAndVertexVector',
1954 'daughter({}, dz)', 'daughter({}, dr)', 'extraInfo(preCut_rank)'],
1955 target='isSignal'),
1956 PreCutConfiguration(userCut='0.4 < M < 0.6',
1957 bestCandidateVariable='abs(dM)',
1958 bestCandidateCut=20),
1959 PostCutConfiguration(bestCandidateCut=10, value=0.01))
1960 KS0.addChannel(['pi+', 'pi-'])
1961 KS0.addChannel(['pi0', 'pi0'])
1962 KS0.addChannel(['K_S0:V0'],
1963 MVAConfiguration(variables=['dr', 'dz', 'distance', 'significanceOfDistance', 'chiProb', 'M',
1964 'useCMSFrame(E)', 'daughterAngle(0,1)', 'extraInfo(preCut_rank)', 'abs(dM)',
1965 'useRestFrame(daughter({}, p))', 'cosAngleBetweenMomentumAndVertexVector',
1966 'daughter({}, dz)', 'daughter({}, dr)'],
1967 target='isSignal'))
1968
1969 # variables for D mesons and J/Psi
1970 intermediate_vars = ['daughterProductOf(extraInfo(SignalProbability))', 'daughter({},extraInfo(SignalProbability))',
1971 'chiProb', 'daughter({}, chiProb)', 'extraInfo(preCut_rank)', 'abs(dM)',
1972 'useRestFrame(daughter({}, p))',
1973 'useRestFrame(daughter({}, distance))',
1974 'decayAngle({})', 'daughterAngle({},{})', 'cosAngleBetweenMomentumAndVertexVector',
1975 'daughterInvariantMass({},{})', 'daughterInvariantMass({},{},{})', 'daughterInvariantMass({},{},{},{})',
1976 'daughterInvariantMass({},{},{},{},{})', 'dQ', 'Q', 'dM', 'daughter({},extraInfo(decayModeID))']
1977
1978 D0 = Particle('D0',
1979 MVAConfiguration(variables=intermediate_vars,
1980 target='isSignal'),
1981 PreCutConfiguration(userCut='1.7 < M < 1.95',
1982 bestCandidateVariable='abs(dM)',
1983 bestCandidateCut=20),
1984 PostCutConfiguration(bestCandidateCut=10, value=0.001))
1985 D0.addChannel(['K-', 'pi+'])
1986 D0.addChannel(['K-', 'pi+', 'pi0'])
1987 D0.addChannel(['K-', 'pi+', 'pi+', 'pi-'])
1988 D0.addChannel(['pi-', 'pi+'])
1989 D0.addChannel(['pi-', 'pi+', 'pi0'])
1990 D0.addChannel(['K_S0', 'pi0'])
1991 D0.addChannel(['K_S0', 'pi+', 'pi-'])
1992 D0.addChannel(['K_S0', 'pi+', 'pi-', 'pi0'])
1993 D0.addChannel(['K-', 'K+'])
1994 D0.addChannel(['K-', 'K+', 'K_S0'])
1995
1996 DP = Particle('D+',
1997 MVAConfiguration(variables=intermediate_vars,
1998 target='isSignal'),
1999 PreCutConfiguration(userCut='1.7 < M < 1.95',
2000 bestCandidateVariable='abs(dM)',
2001 bestCandidateCut=20),
2002 PostCutConfiguration(bestCandidateCut=10, value=0.001))
2003
2004 DP.addChannel(['K-', 'pi+', 'pi+'])
2005 DP.addChannel(['K-', 'pi+', 'pi+', 'pi0'])
2006 DP.addChannel(['K-', 'K+', 'pi+'])
2007 DP.addChannel(['K-', 'K+', 'pi+', 'pi0'])
2008 DP.addChannel(['K_S0', 'pi+'])
2009 DP.addChannel(['K_S0', 'pi+', 'pi0'])
2010 DP.addChannel(['K_S0', 'pi+', 'pi+', 'pi-'])
2011
2012 Jpsi = Particle('J/psi',
2013 MVAConfiguration(variables=intermediate_vars,
2014 target='isSignal'),
2015 PreCutConfiguration(userCut='2.5 < M < 3.7',
2016 bestCandidateVariable='abs(dM)',
2017 bestCandidateCut=20),
2018 PostCutConfiguration(bestCandidateCut=10, value=0.001))
2019
2020 Jpsi.addChannel(['e+', 'e-'])
2021 Jpsi.addChannel(['mu+', 'mu-'])
2022
2023 DSP = Particle('D*+',
2024 MVAConfiguration(variables=intermediate_vars,
2025 target='isSignal'),
2026 PreCutConfiguration(userCut='0 < Q < 0.3',
2027 bestCandidateVariable='abs(dQ)',
2028 bestCandidateCut=20),
2029 PostCutConfiguration(bestCandidateCut=10, value=0.001))
2030
2031 DSP.addChannel(['D0', 'pi+'])
2032 DSP.addChannel(['D+', 'pi0'])
2033
2034 DS0 = Particle('D*0',
2035 MVAConfiguration(variables=intermediate_vars,
2036 target='isSignal'),
2037 PreCutConfiguration(userCut='0 < Q < 0.3',
2038 bestCandidateVariable='abs(dQ)',
2039 bestCandidateCut=20),
2040 PostCutConfiguration(bestCandidateCut=10, value=0.001))
2041
2042 DS0.addChannel(['D0', 'pi0'])
2043 DS0.addChannel(['D0', 'gamma'])
2044
2045 DS = Particle('D_s+',
2046 MVAConfiguration(variables=intermediate_vars,
2047 target='isSignal'),
2048 PreCutConfiguration(userCut='1.68 < M < 2.1',
2049 bestCandidateVariable='abs(dM)',
2050 bestCandidateCut=20),
2051 PostCutConfiguration(bestCandidateCut=10, value=0.001))
2052
2053 DS.addChannel(['K+', 'K_S0'])
2054 DS.addChannel(['K+', 'pi+', 'pi-'])
2055 DS.addChannel(['K+', 'K-', 'pi+'])
2056 DS.addChannel(['K+', 'K-', 'pi+', 'pi0'])
2057 DS.addChannel(['K+', 'K_S0', 'pi+', 'pi-'])
2058 DS.addChannel(['K-', 'K_S0', 'pi+', 'pi+'])
2059 DS.addChannel(['K+', 'K-', 'pi+', 'pi+', 'pi-'])
2060 DS.addChannel(['pi+', 'pi+', 'pi-'])
2061
2062 DSS = Particle('D_s*+',
2063 MVAConfiguration(variables=intermediate_vars,
2064 target='isSignal'),
2065 PreCutConfiguration(userCut='0.0 < Q < 0.3',
2066 bestCandidateVariable='abs(dQ)',
2067 bestCandidateCut=20),
2068 PostCutConfiguration(bestCandidateCut=10, value=0.001))
2069
2070 DSS.addChannel(['D_s+', 'gamma'])
2071
2072 # note: these should not be correlated to Mbc (weak correlation of deltaE is OK)
2073 B_vars = ['daughterProductOf(extraInfo(SignalProbability))', 'daughter({},extraInfo(SignalProbability))',
2074 'chiProb', 'daughter({}, chiProb)', 'extraInfo(preCut_rank)',
2075 'useRestFrame(daughter({}, p))',
2076 'useRestFrame(daughter({}, distance))',
2077 'decayAngle({})', 'daughterAngle({},{})', 'cosAngleBetweenMomentumAndVertexVector',
2078 'dr', 'dz', 'dx', 'dy', 'distance', 'significanceOfDistance', 'deltaE', 'daughter({},extraInfo(decayModeID))']
2079
2080 hadronic_user_cut = 'Mbc > 5.2 and abs(deltaE) < 0.5'
2081
2082 BP = Particle('B+',
2083 MVAConfiguration(variables=B_vars,
2084 spectators={'Mbc': (5.23, None), 'cosThetaBetweenParticleAndNominalB': (-10, 10)},
2085 target='isSignal'),
2086 PreCutConfiguration(userCut=hadronic_user_cut,
2087 bestCandidateMode='highest',
2088 bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
2089 bestCandidateCut=20),
2090 PostCutConfiguration(bestCandidateCut=20))
2091
2092 BP.addChannel(['anti-D0', 'pi+'])
2093 BP.addChannel(['anti-D0', 'pi+', 'pi0'])
2094 BP.addChannel(['anti-D0', 'pi+', 'pi+', 'pi-'])
2095 BP.addChannel(['anti-D0', 'D+'])
2096 BP.addChannel(['D_s+', 'anti-D0'])
2097 BP.addChannel(['anti-D*0', 'pi+'])
2098 BP.addChannel(['anti-D*0', 'pi+', 'pi0'])
2099 BP.addChannel(['anti-D*0', 'pi+', 'pi+', 'pi-'])
2100 BP.addChannel(['anti-D*0', 'pi+', 'pi+', 'pi-', 'pi0'])
2101 BP.addChannel(['D_s*+', 'anti-D0'])
2102 BP.addChannel(['D_s+', 'anti-D*0'])
2103 BP.addChannel(['anti-D0', 'K+'])
2104 BP.addChannel(['D-', 'pi+', 'pi+'])
2105 BP.addChannel(['J/psi', 'K+'])
2106 BP.addChannel(['J/psi', 'K+', 'pi+', 'pi-'])
2107 BP.addChannel(['J/psi', 'K+', 'pi0'])
2108 BP.addChannel(['J/psi', 'K_S0', 'pi+'])
2109
2110 B0 = Particle('B0',
2111 MVAConfiguration(variables=B_vars,
2112 spectators={'Mbc': (5.23, None), 'cosThetaBetweenParticleAndNominalB': (-10, 10)},
2113 target='isSignal'),
2114 PreCutConfiguration(userCut=hadronic_user_cut,
2115 bestCandidateMode='highest',
2116 bestCandidateVariable='daughterProductOf(extraInfo(SignalProbability))',
2117 bestCandidateCut=20),
2118 PostCutConfiguration(bestCandidateCut=20))
2119 B0.addChannel(['D-', 'pi+'])
2120 B0.addChannel(['D-', 'pi+', 'pi0'])
2121 B0.addChannel(['D-', 'pi+', 'pi+', 'pi-'])
2122 B0.addChannel(['anti-D0', 'pi0'])
2123 B0.addChannel(['D_s+', 'D-'])
2124 B0.addChannel(['D*-', 'pi+'])
2125 B0.addChannel(['D*-', 'pi+', 'pi0'])
2126 B0.addChannel(['D*-', 'pi+', 'pi+', 'pi-'])
2127 B0.addChannel(['D*-', 'pi+', 'pi+', 'pi-', 'pi0'])
2128 B0.addChannel(['D_s*+', 'D-'])
2129 B0.addChannel(['D_s+', 'D*-'])
2130 B0.addChannel(['D_s*+', 'D*-'])
2131 B0.addChannel(['J/psi', 'K_S0'])
2132 B0.addChannel(['J/psi', 'K+', 'pi-'])
2133 B0.addChannel(['J/psi', 'K_S0', 'pi+', 'pi-'])
2134
2135 particles = []
2136 particles.append(pion)
2137 particles.append(kaon)
2138 particles.append(muon)
2139 particles.append(electron)
2140 particles.append(gamma)
2141
2142 particles.append(pi0)
2143 particles.append(KS0)
2144 particles.append(Jpsi)
2145
2146 particles.append(D0)
2147 particles.append(DP)
2148 particles.append(DS)
2149
2150 particles.append(DS0)
2151 particles.append(DSP)
2152 particles.append(DSS)
2153
2154 particles.append(B0)
2155 particles.append(BP)
2156
2157 return particles
2158
2159
2160def get_mode_names(particle_name: str,
2161 hadronic=True,
2162 semileptonic=False,
2163 removeSLD=True,
2164 remove_list_labels=True,
2165 **channel_kwargs) -> list:
2166 """
2167 Get the ordered list of mode names for a given FEI particle name
2168
2169 Arguments:
2170 particle_name(str): the name of the particle, e.g. B0 or B+
2171 hadronic(bool): whether to include hadronic modes
2172 semileptonic(bool): whether to include semileptonic modes
2173 removeSLD(bool): whether to remove the semileptonic D and D* modes, should be True for FEI skim
2174 remove_list_labels(bool): whether to remove the generic and semileptonic labels from the mode names
2175 channel_kwargs: keyword arguments for get_default_channels
2176
2177 Returns:
2178 list(str): the list of mode names, or empty list if the particle was not found
2179 """
2180 if hadronic and semileptonic:
2181 B2INFO('Both semileptonic and hadronic arguments are set to True, set one of them to False for a more definite result.')
2182 if not hadronic and not semileptonic:
2183 B2INFO('Both semileptonic and hadronic arguments are set to False, set one of them to True for a more definite result.')
2184 return []
2185 channel_kwargs.update({'hadronic': hadronic,
2186 'semileptonic': semileptonic,
2187 'removeSLD': removeSLD
2188 })
2189 channels = get_default_channels(**channel_kwargs)
2190 modes = []
2191 conjugate_name = particle_name.replace('-', '+')
2192 for channel in channels:
2193 if channel.name == particle_name or channel.name == conjugate_name:
2194 modes += [d_channel.label.split(' ==> ')[1] for d_channel in channel.channels]
2195 if remove_list_labels:
2196 modes = [mode.replace(':generic', '').replace(':semileptonic', '') for mode in modes]
2197 return modes
isB2BII()
Definition b2bii.py:14