Belle II Software  release-06-02-00
decparser.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 
11 
12 """
13 Decay File Parser to check whether a decay file is correctly defined
14 """
15 
16 import sys
17 import settings
18 import os
19 import time
20 from colours import mesg, query, fail, done, warning
21 import descriptcheck
22 
23 mesg('Starting the decfile check')
24 query('Opening decfile')
25 if len(sys.argv) < 2:
26  fail(['Please pass the decfile as the first argument.'])
27  sys.exit()
28 
29 filename = sys.argv[1]
30 dkfilespath = os.path.dirname(os.path.abspath(sys.argv[0])) + '/' \
31  + settings.dkfilespath
32 
33 if not os.path.exists(filename):
34  fail(['The file does not exist'])
35  sys.exit()
36 elif not os.path.isfile(filename):
37 
38  fail(['The path does not point to a regular file.'])
39  sys.exit()
40 
41 file = open(filename)
42 if not file:
43  fail(['Unknown error opening file.'])
44  sys.exit()
45 
46 done()
47 
48 documentation_inprocess = False
49 date = ''
50 responsible = ''
51 eventtype = 0
52 descriptor = ''
53 nickname = ''
54 cuts = ''
55 fulleventcuts = ''
56 documentation = []
57 physicswg = ''
58 tested = ''
59 email = ''
60 extraopts = ''
61 particledefs = []
62 decay = {}
63 current_decay = []
64 order = []
65 
66 decay_started = False
67 decay_inprocess = False
68 
69 alias = {}
70 chargeconj = {}
71 cdecay = []
72 mother = ''
73 
74 Ended = False
75 endcheck = False
76 
77 linecount = 0
78 
79 
80 def getfield(line, string):
81  tmp = ''
82  if string + ':' in line:
83  query('Now parsing: ' + string)
84  tmp = line.partition(string + ':')[2]
85  done()
86  if tmp.startswith(' '):
87  tmp = tmp.strip()
88 # warning("Please leave a single space after the : sign. on line:"+str(linecount))
89  if tmp == '':
90  warning('Field empty on line ' + str(linecount))
91  return tmp
92 
93 
94 for line in file:
95  linecount += 1
96 
97  if line.strip() == '':
98  continue
99 
100  if line.startswith('#') and not decay_started:
101 
102  if documentation_inprocess:
103  if 'EndDocumentation' in line:
104  documentation_inprocess = False
105  documentation = ' '.join(documentation)
106  continue
107  documentation += [line.strip('#')]
108  continue
109 
110  tmp = getfield(line, 'Documentation')
111  if tmp:
112  file2 = open(filename)
113  for line2 in file2:
114  if 'EndDocumentation' in line2:
115  documentation_inprocess = True
116  break
117  file2.close()
118  documentation += [tmp]
119 
120  tmp = getfield(line, 'EventType')
121  if tmp:
122  try:
123  eventtype = int(tmp)
124  except BaseException:
125  fail(['Failed parsing eventtype on line ' + str(linecount),
126  'Not a number.'])
127  order += ['EventType']
128  mesg('Eventtype found: ' + str(eventtype))
129 
130  tmp = getfield(line, 'Descriptor')
131  if tmp:
132  descriptor = tmp
133  order += ['descriptor']
134  if '{,gamma}' in tmp:
135  warning(
136  'Please do not include radiative photons in the descriptor.')
137 
138  tmp = getfield(line, 'NickName')
139  if tmp:
140  if tmp == '':
141  fail(['NickName empty on line ' + str(linecount)])
142  elif not tmp == os.path.basename(filename).partition('.dec')[0]:
143  fail(['NickName not the same as filename!'])
144  else:
145  nickname = tmp
146  order += ['nickname']
147 
148  tmp = getfield(line, 'Cuts')
149  if tmp:
150  cuts = tmp
151  order += ['cuts']
152  test_cuts = ['None', 'DaughtersInBelleII']
153  if cuts not in test_cuts:
154  warning(
155  'Unknown cuts <' +
156  cuts +
157  '> on line ' +
158  str(linecount) +
159  '. Please check.')
160 
161  tmp = getfield(line, 'FullEventCuts')
162  if tmp:
163  fulleventcuts = tmp
164  order += ['fulleventcuts']
165 
166  tmp = getfield(line, 'ExtraOptions')
167  if tmp:
168  extraopts = tmp
169  order += ['extraopts']
170 
171  tmp = getfield(line, 'PhysicsWG')
172  if tmp:
173  physicswg = tmp
174  order += ['physicswg']
175 
176  tmp = getfield(line, 'Tested')
177  if tmp:
178  if tmp == 'No':
179  warning('File not tested! Please test the file!')
180  elif not tmp == 'Yes':
181  warning('Unkown Tested state. Please use Yes or No.')
182  else:
183  tested = tmp
184  order += ['tested']
185 
186  tmp = getfield(line, 'Responsible')
187  if tmp:
188  responsible = tmp
189  order += ['responsible']
190 
191  tmp = getfield(line, 'Email')
192  if tmp:
193  if '@' not in tmp:
194  warning('Please use a correct email format.')
195  else:
196  email = tmp
197  order += ['email']
198 
199  tmp = getfield(line, 'ParticleValue')
200  if tmp:
201  tmp = tmp.split(',')
202  tmp2 = {}
203  for part in tmp:
204  part = part.strip('"')
205  part = part.split()
206  tmp2[part[6]] = part[1]
207  particledefs = tmp2
208 
209  tmp = getfield(line, 'Date')
210  if tmp:
211  try:
212  date = int(tmp)
213  if not date / 10000 == time.gmtime().tm_year:
214  warning('Date is not from this year. Please use YYYYMMDD for date field. YYYY parsed:' +
215  str(date / 10000) + ' vs. current year: ' + str(time.gmtime().tm_year))
216  if date - 10000 * (date / 10000) > 1231:
217  warning('Cannot parse date. Please use YYYYMMDD for date field. MMDD parsed:' +
218  str(date - 10000 * (date / 10000)))
219  if date - 100 * (date / 100) > 31:
220  warning('Cannot parse date. Please use YYYYMMDD for date field. DD parsed:' +
221  str(date - 100 * (date / 100)))
222  except BaseException:
223  warning('Cannot parse date. Please use YYYYMMDD for date field.'
224  )
225  elif not line == '' and not decay_started and not Ended:
226 
227  mesg('End of header.')
228  decay_started = True
229 
230  if Ended:
231  endcheck = True
232 
233  if decay_started:
234  if not line.startswith('#'):
235  if 'Alias' in line:
236  elements = line.partition('Alias')[2].strip().split()
237  alias[elements[0].strip()] = elements[1].strip()
238  if 'ChargeConj' in line:
239  elements = line.partition('ChargeConj')[2].strip().split()
240  chargeconj[elements[0].strip()] = elements[1].strip()
241 
242  if 'CDecay' in line:
243  elements = line.partition('CDecay')[2].strip()
244  cdecay += [elements]
245  elif 'Decay' in line:
246 
247  mother = line.partition('Decay ')[2].strip()
248  mesg('Found decay: ' + mother)
249  decay_inprocess = True
250  continue
251 
252  if 'End' in line and 'Enddecay' not in line:
253  Ended = True
254  decay_started = False
255 
256  if decay_inprocess:
257  if 'Enddecay' in line:
258  decay[mother] = current_decay
259  decay_inprocess = False
260  # mesg("Found decay end of: "+mother)
261  current_decay = []
262  else:
263 
264  line = line.strip().split()
265  bf = line[0]
266  dec = []
267  try:
268  bf = float(bf)
269  except BaseException:
270  warning('Branching fraction not a number on line: ' +
271  str(linecount) + '. Skipping.')
272  continue
273  for daug in line[1:-1]:
274  if daug.strip(';') in settings.terminators:
275  # mesg("Terminator found, ending decay line.")
276  break
277  elif daug.endswith(';'):
278  warning(
279  'A new terminator found: ' +
280  daug.strip(';') +
281  '. Adding to list')
282  settings.terminators += [daug.strip(';')]
283  break
284  if daug in alias:
285  # daug = alias[daug]
286  pass
287  elif daug in chargeconj:
288  # daug = chargeconj[daug]
289  if daug in alias:
290  daug = alias[daug]
291  else:
292  warning(
293  "You defined a charge conjugation without either particle being an alias. "
294  "Are you sure you know what you're doing on line " + str(linecount) + '?')
295  else:
296  for k in alias:
297  if daug == alias[k]:
298  warning(
299  'You defined an alias to particle ' +
300  daug +
301  ' called ' +
302  k +
303  ' but on line ' +
304  str(linecount) +
305  ' you use the original particle. Is this what you want?')
306  dec += [daug]
307  if not line[-1].endswith(';'):
308  warning(
309  'Line ' +
310  str(linecount) +
311  ' does not end with a ;')
312  current_decay += [(bf, dec)]
313 
314 mesg('File parsed successfully.')
315 file.close()
316 
317 if not eventtype:
318  warning("Cannot proceed without eventtype. Please fix the eventtype so it's recognisable."
319  )
320  sys.exit()
321 
322 newevtype = ''
323 parttype = eventtype
324 query('Checking general flag')
325 general = parttype / 10000000
326 flag = 0
327 parttype -= general * 10000000
328 mother = ''
329 for daug in decay:
330  if 'sig' in daug:
331  mother = daug.partition('sig')[0]
332  # mesg("Found mother: "+mother)
333  break
334 else:
335  if nickname.startswith('uubar'):
336  flag = 3
337  elif nickname.startswith('ddbar'):
338  flag = 3
339  elif nickname.startswith('ssbar'):
340  flag = 3
341  elif nickname.startswith('mixed'):
342  flag = 1
343  elif nickname.startswith('charged'):
344  flag = 1
345  elif nickname.startswith('charm'):
346  flag = 2
347  else:
348  fail(['Cannot find the signal particle and cannot determine the inclusive mode.'])
349  sys.exit()
350  done()
351 if mother:
352  if 'B' in mother or 'b0' in mother or 'Upsilon' in mother or 'chi_b' in mother:
353  flag = 1
354  elif 'D' in mother or 'psi' in mother or 'chi_c' in mother or 'c+' in mother:
355  flag = 2
356  elif 'K_S0' in mother or 'Lambda' in mother or 'Sigma' in mother or 'tau' in mother:
357  flag = 3
358  else:
359  warning("Didn't recognise the mother particle. Check general flag manually.")
360  flag = general
361  if not flag == general:
362  fail(['General flag not compliant. Should be ' + str(flag) + '.Please check.'])
363  else:
364  done()
365 newevtype += str(flag)
366 
367 query('Checking selection flag')
368 selection = parttype / 1000000
369 parttype -= selection * 1000000
370 flag = selection
371 if not mother:
372  flag = 0
373 elif mother == 'D-' or mother == 'B0' or mother == 'D+' or mother == 'anti-B0':
374  flag = 1
375 elif mother == 'D0' or mother == 'anti-D0' or mother == 'B+' or mother == 'B-':
376  flag = 2
377 elif mother == 'B_s0' or mother == 'D_s-' or mother == 'D_s+':
378  flag = 3
379 elif mother == 'J/psi':
380  flag = 4
381 elif mother == 'Lambda_b0' or mother == 'Lambda_c+':
382  flag = 5
383 elif ('Sigma_b' in mother or 'chi_b' in mother or 'Omega_b' in mother) and general == 1:
384  flag = 6
385 elif ('Upsilon' in mother or 'chi_b' in mother) and general == 1:
386  flag = 8
387 elif ('D' in mother and '*' in mother or 'D_s1' in mother) and general == 2:
388  flag = 7
389 elif ('psi(2S)' in mother or 'X_1(3872)' in mother or 'h_c' in mother or
390  'chi_c' in mother or mother == 'eta_c') and general == 2:
391 
392  flag = 8
393 elif general == 3:
394 
395  if mother == 'tau+' or mother == 'tau-':
396  flag = 1
397  elif 'Lambda' in mother:
398  flag = 3
399  elif 'Sigma' in mother:
400  flag = 2
401  elif mother == 'K_S0':
402  flag = 4
403  else:
404  warning(
405  'General flag is 3 but mother particle is not recogniced - assuming minbias.')
406  flag = 0
407 else:
408  warning('Cannot determine selection flag. Please check manually.')
409  flag = selection
410 if not flag == selection:
411  warning(
412  'Selection flag is not compliant, should be ' +
413  str(flag) +
414  '. Please check.')
415 else:
416  done()
417 newevtype += str(flag)
418 
419 query('Unfolding decay.')
420 
421 current_decay = []
422 if mother:
423  current_decay = (decay[mother + 'sig'])[:]
424 
425 for (bf2, dec2) in current_decay:
426  for daug in dec2:
427  if daug in decay:
428  newdecay = dec2[:]
429  newdecay.remove(daug)
430  for (bf2, dau2) in decay[daug]:
431  norm = 0.0
432  for (bf3, dau3) in decay[daug]:
433  norm += float(bf3)
434  newbf = bf * bf2 / norm
435  newdecay2 = sorted(newdecay[:] + dau2[:])
436  current_decay += [(newbf, newdecay2)]
437  break
438 
439 
440 def getmax(dec):
441  maximumbf = 0
442  toret = []
443  for (bf, dec2) in dec:
444  if bf > maximumbf:
445  maximumbf = bf
446  toret = dec2[:]
447  return toret
448 
449 
450 main_decay = []
451 if mother:
452  main_decay = [getmax(decay[mother + 'sig'])]
453 
454 clean = False
455 while not clean and mother:
456  clean = True
457  olddec = (main_decay[-1])[:]
458  for daug in main_decay[-1]:
459  if daug in alias:
460  olddec.remove(daug)
461  if daug not in decay:
462  for k in chargeconj:
463  if k == daug:
464  daug = chargeconj[k]
465  elif chargeconj[k] == daug:
466  daug = k
467  if daug not in decay:
468  warning('Aliased particle but cannot find its decay!: ' + daug)
469  newdec = [alias[daug]]
470  else:
471  newdec = getmax(decay[daug])
472  olddec += newdec
473  clean = False
474  if not clean:
475  main_decay += [olddec]
476 done()
477 
478 query('Checking the decay flag')
479 
480 decayflag = parttype / 100000
481 parttype -= decayflag * 100000
482 neutrinos = False
483 nFinal = 0
484 nCommon = 0
485 
486 final = []
487 
488 for (bf, dec) in current_decay:
489  common = 0
490  for (bf2, dec2) in current_decay:
491  test_dec1 = dec
492  test_dec2 = dec2
493  test_dec1.sort()
494  test_dec2.sort()
495  if test_dec2 == test_dec1:
496  common += 1
497  for daug in dec:
498  if 'nu_' in daug:
499  neutrinos = True
500  if common >= 2:
501  nCommon += 1
502  for daug in dec:
503  if daug in alias:
504  break
505  else:
506  if not final:
507  final = sorted(dec)
508  else:
509  dec.sort()
510  if final == dec:
511  continue
512  nFinal += 1
513 
514 flag = 0
515 if mother:
516  flag += 1
517 if nFinal > 1:
518  flag += 2
519 if nCommon > 0:
520  flag += 1
521 if neutrinos:
522  flag += 4
523 
524 if not decayflag == flag:
525  fail(['Decay flag is not compliant. Should be ' + str(flag) + '. Please check'])
526 else:
527  done()
528 newevtype += str(flag)
529 
530 query('Checking charm and lepton flag')
531 electron = False
532 muon = False
533 opencharm = False
534 closedcharm = False
535 doubleopen = False
536 
537 charmflag = parttype / 10000
538 parttype -= charmflag * 10000
539 
540 caughtopen = False
541 if not mother:
542  for field in [extraopts, cuts, fulleventcuts]:
543  if 'Electron' in field or 'electron' in field:
544  electron = True
545  if 'mu' in field or 'Mu' in field:
546  muon = True
547  if 'D0' in field or 'Dmu' in field or 'Ds' in field or 'DS' in field or 'DMass' in field or 'DMu' in field:
548  opencharm = True
549  if 'Jpsi' in field:
550  closedcharm = True
551 
552 for dec in main_decay:
553  caughtopen = False
554  for daug in dec:
555  if daug in alias:
556  daug = alias[daug]
557  # if "D" in mother or "Lambda_c" in mother:
558  # opencharm=True
559  if daug == 'e-' or daug == 'e+':
560  electron = True
561  continue
562  if daug == 'mu-' or daug == 'mu+':
563  muon = True
564  continue
565  if ('D' in daug or '_c' in daug) and 'chi_c' not in daug:
566  if caughtopen:
567  doubleopen = True
568  caughtopen = False
569  continue
570  caughtopen = True
571  opencharm = True
572  continue
573  if 'psi' in daug or 'chi_c' in daug:
574  closedcharm = True
575  continue
576 flag = 0
577 if opencharm:
578  flag += 6
579 elif closedcharm:
580  flag += 3
581 if electron:
582  flag += 2
583 elif muon:
584  flag += 1
585 if doubleopen:
586  flag = 9
587 
588 if not flag == charmflag:
589  fail(['Charm flag is not compliant. Should be :' + str(flag) + '. Please check'])
590 else:
591  done()
592 newevtype += str(flag)
593 
594 query('Checking track flag.')
595 trackflag = parttype / 1000
596 parttype -= trackflag * 1000
597 
598 maxbf = 0
599 maxtracks = 0
600 if not mother:
601  warning('Inclusive decay: Problem with settings the track flag. Check manually.'
602  )
603  if 'DiLepton' in fulleventcuts or 'DiLepton' in cuts or 'DiLepton' in extraopts:
604  maxtracks = 2
605 for dec in main_decay:
606  for daug in dec:
607  if daug in decay:
608  break
609  else:
610  tracks = 0
611  for daug in dec:
612  if daug in settings.longlived:
613  if tracks <= 9:
614  tracks += 1
615  if tracks > maxtracks:
616  maxtracks = tracks
617 
618 if not trackflag == maxtracks:
619  fail(['Track flag not compliant. Should be: ' +
620  str(maxtracks) + '. Please check.'])
621 else:
622  done()
623 newevtype += str(maxtracks)
624 
625 query('Checking neutrals flag.')
626 neutrals = parttype / 100
627 parttype -= neutrals * 100
628 
629 pi0eta = False
630 gamma = False
631 Kslambda = False
632 klong = False
633 
634 for dec in main_decay:
635  for daug in dec:
636  if daug in alias:
637  daug = alias[daug]
638  if daug == 'K_S0' or daug == 'Lambda0' or mother == 'K_S0' or mother == 'Lambda0':
639  Kslambda = True
640  elif daug == 'pi0' or daug == 'eta':
641  pi0eta = True
642  elif daug == 'K_L0':
643  Klong = True
644 
645 previous_pi = False
646 for i in range(len(main_decay)):
647  if 'gamma' in main_decay[i]:
648  toBreak = False
649  if i != 0:
650  for daug in main_decay[i - 1]:
651  daug2 = daug
652  if daug in alias:
653  daug2 = alias[daug]
654  if daug2 == 'pi0' or daug2 == 'eta':
655  if daug not in main_decay[i]:
656  toBreak = True
657  if toBreak:
658  continue
659  gamma = True
660 
661 flag = 0
662 if Kslambda:
663  flag += 1
664 if klong:
665  flag += 8
666 else:
667  if gamma:
668  flag += 2
669  if pi0eta:
670  flag += 4
671 
672 if not flag == neutrals:
673  fail(['Neutrals flag not compliant. Should be ' + str(flag) + '. Please check.'])
674 else:
675  done()
676 newevtype += str(flag)
677 
678 query('Checking the extra and user for duplicity .')
679 
680 if settings.use_url:
681  if not zippednos:
682  warning('Cannot parse decfiles webpage')
683  settings.use_url = False
684  else:
685  for (k, v) in zippednos:
686  if filename.partition('=')[0] == v.partition(
687  '=')[0] and not eventtype / 10 == k / 10:
688  warning(
689  'The decfile: ' +
690  v +
691  ':' +
692  str(k) +
693  ' should contain the same decay, therefore the first 7 '
694  'digits of the eventtype should match. Please check and use the same extra flag.')
695  failed = True
696  if k == eventtype:
697  warning('Error: ' + v + ' has this eventtype already.')
698  failed = True
699  if k / 10 == eventtype / \
700  10 and not os.path.basename(filename).partition('=')[0] == v.partition('=')[0]:
701  warning(
702  'The decfile: ' +
703  v +
704  ':' +
705  str(k) +
706  ' uses this extra flag, but the decay seems different. '
707  'Please check and use a unique extra flag.')
708  failed = True
709 
710  if settings.obs_url:
711 
712  if not obsnos:
713  warning('Cannot parse obsoletes trac file.')
714  settings.use_url = False
715  else:
716  if str(eventtype) in obsnos:
717  warning('The eventtype is obsolete on the line ' +
718  str(obsnos.index(str(eventtype)) + 1) + ' in: ' +
719  settings.obs_url)
720  failed = True
721 
722 if not settings.use_url:
723  filelist = os.listdir(dkfilespath)
724  newtype = 0
725  failed = False
726  for filen in filelist:
727  if filen.endswith('.dec'):
728  file = open(dkfilespath + '/' + filen)
729  for line in file:
730  if 'EventType: ' in line:
731  try:
732  newtype = int(line.partition('EventType: ')[2].strip())
733  break
734  except BaseException:
735  break
736  if filen.partition('=')[0] == filename.partition('='):
737  if not newtype / 10 == eventtype / 10:
738  warning(
739  'The decfile: ' +
740  filen +
741  ':' +
742  str(newtype) +
743  ' should contain the same decay, therefore the first 7 '
744  'digits of the eventtype should match. Please check and use the same extra flag.')
745  failed = True
746 # if newtype == eventtype and not os.path.basename(filename) == v:
747  if newtype == eventtype:
748  warning('Error: ' + filen + ' has this eventtype already.')
749  failed = True
750 
751  if settings.obsoletepath:
752  obsfile = open(settings.obsoletepath + '/table_obsolete.sql')
753  if obsfile:
754  for line in obsfile:
755  if int(line.partition('EVTTYPEID = ')[2].partition(
756  ', DESCRIPTION')[0]) == eventtype:
757  warning(
758  'The eventtype is obsolete on the following line in: ' +
759  settings.obsoletepath +
760  '/table_obsolete.sql')
761  mesg(line)
762  failed = True
763 
764 extraflag = eventtype / 10
765 extraflag = eventtype - extraflag * 10
766 if 'DaughtersInBelleII' not in cuts and extraflag and cuts == 0:
767  warning(
768  'Your cuts are not empty, please set your userflag to greater or equal to 1.')
769  failed = True
770 if cuts == ['None'] and extraflag != 0:
771  warning("Your cuts are empty, your user flag should be 0 unless that's taken. Please check."
772  )
773 
774 if failed:
775  fail([])
776 else:
777  done()
778 mesg('Eventtype constructed: ' + newevtype + 'XX')
779 
780 query('Checking nickname.')
781 faillist = []
782 failed = False
783 if not nickname == os.path.basename(filename).partition('.dec')[0]:
784  faillist += ['Filename not the same as nickname! Fix.']
785  failed = True
786 nick = nickname.partition('=')
787 if not nick[1] == '=' and not cuts == []:
788  faillist += \
789  ['The = sign not found in the nickname while cuts are present. Check nickname conventions and fix.'
790  ]
791  warning('The = sign not found in the nickname while cuts are present. Check nickname conventions and fix.'
792  )
793  # failed = True
794 if 'DaughtersInBelleII' in cuts and 'DecProdCut' not in nick[2].split(','):
795  faillist += \
796  ['You have decay angular acceptance cut in Cuts but not in the nickname.'
797  ]
798  failed = True
799 
800 if failed:
801  fail(faillist)
802 else:
803  done()
804 
805 if not len(nick[0].split(',')) > 1 and mother:
806  warning('Found only one decay level in the nickname - highly unusual, you should probably use at least two.'
807  )
808 
809 if len(nick[2].split(',')) < len(cuts.split(',')):
810  warning('You have more cuts than declared in the nickname. Please check.')
811 
812 query('Checking the Physics WG.')
813 if physicswg not in settings.groups:
814  fail(['The group /' + physicswg +
815  '/ is not known. Please use one of the following:', settings.groups])
816 else:
817  done()
818 
819 if mother:
820  query('Building descriptor.')
821  max_bf = 0
822  curdec = []
823  for (bf, dec) in decay[mother + 'sig']:
824  if bf > max_bf:
825  max_bf = bf
826  for (bf, dec) in decay[mother + 'sig']:
827  if bf == max_bf:
828  curdec = dec[:]
829  descript = [mother] + ['->'] + curdec
830 
831  notclean = True
832  while notclean:
833  for daug in descript:
834  notclean = False
835  if daug in decay:
836  notclean = True
837  max_bf = 0
838  for (bf, dec) in decay[daug]:
839  if bf > max_bf:
840  max_bf = bf
841  for (bf, dec) in decay[daug]:
842  if bf == max_bf:
843  curdec = dec[:]
844  ind = descript.index(daug)
845  descript.remove(daug)
846  if daug not in alias:
847  warning('You decay a particle: [' + daug +
848  '] without aliasing it first. Step aborted.')
849  notclean = False
850  break
851  else:
852  daug = alias[daug]
853  toadd = ['(', daug, '->'] + curdec + [')']
854  toadd.reverse()
855  for el in toadd:
856  descript.insert(ind, el)
857 
858 # Obsolete piece of code
859 # for i in range(len(descript)):
860 # if descript[i] in settings.descripslation:
861 # descript[i] = settings.descripslation[descript[i]]
862 
863  descript = '[' + ' '.join(descript) + ']'
864  descript = descript.replace('( ', '(')
865  descript = descript.replace(' )', ')')
866  for daug in cdecay:
867  if 'sig' in daug:
868  descript += 'cc'
869  break
870 
871  done()
872 
873  query('Checking descriptor.')
874 
875  decr_old = descriptor.partition('[')[2].partition(']')[0].split()
876  decr_new = descript.partition('[')[2].partition(']')[0].split()
877 
878  listA = descriptcheck.convertToList(descript)
879  listB = descriptcheck.convertToList(descriptor)
880 
881  if descriptcheck.compareList(listB, listA):
882  done()
883  else:
884  fail(['Descriptor not matched. Please check the old one:', descriptor,
885  '\nAnd the one built by the parser: ', descript])
886  for mes in descriptcheck.mesgdict:
887  warning(mes)
888 
889  for daug in decay:
890  print(daug, decay[daug])
891 
892  print('Main decay chain:')
893  for dec in main_decay:
894  print(dec)
895 
896 sys.exit('Decfile check complete.')
def convertToList(stringA)
def compareList(listA, listB)