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