Belle II Software release-09-00-00
decfiles_branching_fractions.py
1#!/usr/bin/env python
2
3
10
11# Compare the length of decay description measured in number of lines
12# (excluding comments and empty lines) as well as the sum of the decay
13# mode branching fractions.
14
15import re
16import basf2
17from ROOT.Belle2 import EvtGenDatabasePDG
18from terminal_utils import ANSIColors as ac
19
20database = EvtGenDatabasePDG.Instance()
21
22f = open(basf2.find_file('decfiles/dec/DECAY_BELLE2.DEC'))
23decfile_lines = f.readlines()
24f.close()
25
26re_decay = re.compile('Decay *([^ ]+).*\n')
27re_enddecay = re.compile('Enddecay *')
28
29in_decay = False
30# save the decay mode lines belonging to a certain particle as dictionary
31# to do some checks on these.
32decays = {}
33particle = ''
34for i in range(len(decfile_lines)):
35 if in_decay:
36 match = re_enddecay.match(decfile_lines[i])
37 if match is not None:
38 in_decay = False
39 else:
40 if(decfile_lines[i] != '\n'):
41 if(decfile_lines[i].lstrip()[0] != '#'):
42 decays[particle].append(decfile_lines[i])
43 else:
44 match = re_decay.match(decfile_lines[i])
45 if match is not None:
46 particle = match.group(1)
47 decays[particle] = []
48 in_decay = True
49
50# determine the number of defined decay modes for each defined particle
51# and compare them to the corresponding anti-particle
52
53
54def get_decay_length(particle_name):
55 if particle_name in decays:
56 return len(decays[particle_name])
57 return -1
58
59
60for particle in database.ParticleList():
61 code = particle.PdgCode()
62 name = particle.GetName()
63 if (code > 0):
64 antiparticle = database.GetParticle(-code)
65 if antiparticle:
66 antiname = antiparticle.GetName()
67 length = get_decay_length(name)
68 antilength = get_decay_length(antiname)
69 if (length > 0 and antilength > 0 and length != antilength):
70 print('Inconsistent length of decay description '
71 f'for {name} ({length}) and {antiname} ({antilength}).')
72 exit(1)
73
74
75# Now get the sum of branching fractions for each particle
76def get_branching_fraction(particle_name):
77 if particle_name in decays:
78 bfsum = 0.
79 for decmode in decays[particle_name]:
80 bfsum += float(decmode.split()[0])
81 return bfsum
82 return -1
83
84
85for particle in database.ParticleList():
86 code = particle.PdgCode()
87 name = particle.GetName()
88 if (code > 0):
89 antiparticle = database.GetParticle(-code)
90 if antiparticle:
91 antiname = antiparticle.GetName()
92 bfsum = get_branching_fraction(name)
93 antibfsum = get_branching_fraction(antiname)
94 if (bfsum > 0 and antibfsum > 0 and bfsum != antibfsum):
95 print('Inconsistent sum of decay branching fractions '
96 f'for {name} ({bfsum}) and {antiname} ({antibfsum}).\n'
97 f'Did you remember to modify both {name} and {antiname} branching fractions? '
98 f'Check it also by running "{ac.color("red")}b2dec-compare-BFs{ac.reset()}".')
99 exit(1)
100 # This should be done for each particle, not only B mesons, but the
101 # other particle's decays have not yet been fixed
102 if((abs(code) == 511 or abs(code) == 521) and bfsum > 0 and abs(1.0 - bfsum) > 1e-7):
103 print('Sum of decay mode branching fractions '
104 f'for {name} is not compatible with 1 ({bfsum}).\n'
105 f'Did you remember to run "{ac.color("red")}b2dec-correct-pythiaBFs{ac.reset()}"?')
106 exit(1)
107 # This should be done for each particle, not only B mesons, but the
108 # other particle's decays have not yet been fixed
109 if((abs(code) == 511 or abs(code) == 521) and antibfsum > 0 and abs(1.0 - antibfsum) > 1e-7):
110 print('Sum of decay mode branching fractions '
111 f'for {antiname} is not compatible with 1 ({antibfsum}).\n'
112 f'Did you remember to run "{ac.color("red")}b2dec-correct-pythiaBFs{ac.reset()}"?')
113 exit(1)