Belle II Software development
decfiles_chargedrare_mixedrare.py
1#!/usr/bin/env python
2
3
10
11# This test ensures that the files "CHARGEDRARE_BELLE2.DEC" and
12# "MIXEDRARE_BELLE2.DEC" stay in sync with "DECAY_BELLE2.DEC".
13
14import re
15import difflib
16import sys
17import basf2
18from itertools import zip_longest
19
20start = '--> Begin'
21end = '<-- End'
22templatestring = "# Decay {particle}. Copy/paste into {mcsample}RARE_BELLE2.DEC after each update."
23
24particle_mc_match = {'mixed': {'particle': 'B0Rare', 'antiparticle': 'anti-B0Rare'},
25 'charged': {'particle': 'B+Rare', 'antiparticle': 'B-Rare'}}
26
27
28decay_belle2 = {}
29
30with open(basf2.find_file('decfiles/dec/DECAY_BELLE2.DEC')) as decfile:
31 for mcsample in ['mixed', 'charged']:
32 for particle in particle_mc_match[mcsample].values():
33 formatted_string = templatestring.format(particle=particle,
34 mcsample=mcsample.upper())
35 startstring = formatted_string + ' '*(87-len(formatted_string) - len(start)) + start
36 endstring = formatted_string + ' '*(87-len(formatted_string) - len(end)) + end
37
38 read = False
39 for lineno, line in enumerate(decfile):
40 if startstring in line:
41 decay_belle2[particle] = []
42 read = True
43 elif read and endstring in line:
44 break
45 elif read and not (line.startswith('#') or line == '\n'):
46 decay_belle2[particle].append((lineno, line))
47 else:
48 print("Couldn't find end string in DECFILE, something must be wrong")
49
50special_files = {}
51re_decay = re.compile('Decay .*B([^ ]+).*\n')
52re_enddecay = re.compile('Enddecay *')
53
54for mcsample in ['mixed', 'charged']:
55 with open(basf2.find_file('decfiles/dec/' + mcsample.upper() + 'RARE_BELLE2.DEC')) as decfile:
56 for particle in particle_mc_match[mcsample].values():
57 read = False
58 for lineno, line in enumerate(decfile):
59 if re_decay.match(line):
60 special_files[particle] = []
61 read = True
62 elif read and re_enddecay.match(line):
63 break
64 elif read and not (line.startswith('#') or line == '\n'):
65 special_files[particle].append((lineno, line))
66 else:
67 print(f"Couldn't find Enddecay in special file {mcsample.upper()} + 'RARE_BELLE2.DEC for "
68 f"particle {particle}, something must be wrong")
69
70diff_found = False
71differ = difflib.Differ()
72for particle in decay_belle2.keys():
73 for group in (d for d in difflib.SequenceMatcher(None, [line for _, line in decay_belle2[particle]],
74 [line for _, line in special_files[particle]])
75 .get_grouped_opcodes(0)):
76 for change in group:
77 if change[0] == 'equal':
78 continue
79 else:
80 diff_found = True
81 diffs = list(differ.compare([line for _, line in decay_belle2[particle]][change[1]:change[2]],
82 [line for _, line in special_files[particle]][change[3]:change[4]]))
83
84 diffs_formatted = ['\n'.join([d.strip('\n') for d in diffs[n:n+4]]) for n in range(0, len(diffs), 4)]
85 lineno_decfile = [lineno for lineno, _ in decay_belle2[particle]][change[1]:change[2]]
86 lineno_specialdecfile = [lineno for lineno, _ in special_files[particle]][change[3]:change[4]]
87 if '+' in particle or '-' in particle:
88 prefix = 'CHARGEDRARE_BELLE2.DEC'
89 else:
90 prefix = 'MIXEDRARE_BELLE2.DEC'
91
92 sys.stderr.writelines(f'Line in DECAY_BELLE2.DEC: {ld} \nLine in {prefix}: '
93 f'{lspecial} \n{d}\n\n' for ld, lspecial, d in
94 (zip_longest(lineno_decfile, lineno_specialdecfile, diffs_formatted,
95 fillvalue='Not found')))
96
97if diff_found:
98 raise RuntimeError("Files differ, check above which lines don't match.")