Belle II Software  release-05-02-19
CreateProdScripts.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 #
5 # CreateProdScripts.py :
6 # Author Phillip Urquijo, December 2014
7 #
8 # create an mc production file from a decay file
9 # warning: this script is under development
10 
11 version = 'v1'
12 
13 bkk_first = True
14 eventid_inbkk = []
15 sql_first = True
16 eventid_insql = []
17 list_of_obsoletes = []
18 exit_status = 0
19 list_of_wg = ['SL', 'EWP', 'TCPV', 'HAD', 'CHARM', 'ONIA', 'TAU']
20 
21 import os
22 import re
23 import string
24 import logging
25 import sys
26 import time
27 import glob
28 import mmap
29 from optparse import OptionParser, OptionValueError
30 
31 
32 class GenericOptionFile(object):
33 
34  """
35  Class to write in an option file
36  """
37 
38  def __init__(self):
39  """
40  Constructor.
41  Parameters:
42  filename name of the file
43  f alternative name of the file
44  """
45 
46  self.filename = None
47 
48  self.f = None
49 
50  def __del__(self):
51  """
52  Destructor.
53  """
54  self.Close()
55 
56  def Close(self):
57  """
58  Close file.
59  """
60  if self.f:
61  self.f.close()
62 
63  def OptionFileName(self):
64  """
65  Set option file name.
66  """
67  return self.filename
68 
69  def SetFileName(self, filename):
70  """
71  Set file name.
72  """
73  self.filename = os.path.normpath(filename + self.suffix)
74 
75  def Open(self):
76  """
77  Open file.
78  """
79  if self.filename:
80  self.f = open(self.filename, 'w')
81 
82  def Write(self, lines):
83  """
84  Write the lines in the file.
85  """
86 
87  self.f.writelines([l + '\n' for l in lines])
88 
89  def WriteHeader(self, eventtype, descriptor):
90  """
91  Write header of .dec file.
92  """
93  lines = [
94  '{0} file {1} generated: {2}'.format(self.comment, self.filename,
95  time.strftime('%a, %d %b %Y %H:%M:%S', time.localtime())),
96  '{0}'.format(self.comment),
97  '{0} Event Type: {1}'.format(self.comment, eventtype),
98  '{0}'.format(self.comment),
99  '{0} ASCII decay Descriptor: {1}'.format(self.comment, descriptor),
100  '{0}'.format(self.comment),
101  ]
102  self.Write(lines)
103 
104  def AddExtraOptions(self, eventtype):
105  """
106  Adds extra options.
107  """
108  self.AddInclude(eventtype.ExtraOptions())
109 
110  def AddEventTypeNumber(self, eventtype):
111  """
112  Adds the Event Type Number.
113  """
114  self.AddOptionValue('GenerationEventType', eventtype.EventTypeNumber())
115 
116  def AddEvtGenUserDecayFile(self, eventtype):
117  """
118  Set the EvtGen .dec file.
119  """
120  self.AddOptionValue('EvtGenUserDecayFile',
121  '"$DECFILESROOT/dec/{0}.dec"'.format(eventtype.DecayName()))
122 
123  def AddDecayOptions(self, eventtype):
124  """
125  Specify options for .dec file.
126  """
127  [self.AddOptionValue('ToolSvc.{0}Decay.{1}'.format(
128  eventtype.DecayEngine(), eventtype.DecayOptions().split()[2 * i]),
129  eventtype.DecayOptions().split()[2 * i + 1])
130  for i in range(len(eventtype.DecayOptions().split()) / 2)]
131 
132 
134 
135  """
136  Class to read generic option file in .txt format.
137 
138  Attributes:
139  comment comment string
140  suffix suffix string
141  true_string true string
142  list_begin open list parenthesis
143  list_end close list parenthesis
144 
145  """
146 
147  comment = '//'
148 
149  suffix = '.opts'
150 
151  true_string = 'true'
152 
153  list_begin = '{'
154 
155  list_end = '}'
156 
157  def AddOptionValue(self, option, value, substitute=False):
158  """
159  Set the value of option.
160  """
161  self.Write(['{0} = {1};'.format(option, value)])
162 
163  def AddInclude(self, filename):
164  """
165  Add include statements.
166  """
167  self.Write(['#include "$DECFILESROOT/prod/{0}.py"'.format(filename)])
168 
169  def IncreaseOptionValue(self, option, value):
170  """
171  Add option string.
172  """
173  self.Write(['{0} += {1};'.format(option, value)])
174 
175 
177 
178  """
179  Class to read generic option file in .py format.
180 
181  Attributes:
182  comment comment string
183  suffix suffix string
184  true_string true string
185  list_begin open list parenthesis
186  list_end close list parenthesis
187 
188  """
189 
190  comment = '#'
191 
192  suffix = '.py'
193 
194  true_string = 'True'
195 
196  list_begin = '['
197 
198  list_end = ']'
199 
200  def __init__(self):
201  """
202  Constructor.
203 
204  Attributes:
205  list_algorithm list of algorithms
206  list_tool list of tools
207  """
208 
209  self.list_algorithm = []
210 
211  self.list_tool = []
212  super(PythonOptionFile, self).__init__()
213 
214  def AddOptionValue(self, option, value, substitute=False):
215  """
216  Add option string.
217  """
218  value = value.replace('{', '[')
219  value = value.replace('}', ']')
220  if substitute:
221  value = value.replace('true', 'True')
222  value = value.replace('false', 'False')
223  self.Write(['{0} = {1}'.format(option, value)])
224 
225  def IncreaseOptionValue(self, option, value):
226  """
227  Add option string.
228  """
229  option = self.ConfigureToolAndAlgo(option)
230  self.Write(['{0} += {1}'.format(option, value)])
231 
232 
233 class EventType:
234 
235  """
236  Class to hold event type information.
237 
238  Attributes:
239  MandatoryKeywords list of mandatory keywords for file description
240  OptionalKeywords list of optional keywords for file description
241  """
242 
243  MandatoryKeywords = [
244  'EventType',
245  'Descriptor',
246  'NickName',
247  'Cuts',
248  'Documentation',
249  'PhysicsWG',
250  'Tested',
251  'Responsible',
252  'Email',
253  'Date',
254  ]
255 
256  OptionalKeywords = [
257  'Sample',
258  'ExtraOptions',
259  'DecayOptions',
260  'DecayEngine',
261  'CutsOptions',
262  'Configuration',
263  'ParticleType',
264  'Momentum',
265  'MomentumRange',
266  'Id',
267  'Production',
268  'FullEventCuts',
269  'ParticleValue',
270  'ParticleTable',
271  'InsertPythonCode',
272  ]
273 
274  def __init__(self, filename, remove, technology):
275  """
276  Constructor.
277 
278  Attributes:
279  DecayFileName name of decay file
280  KeywordDictionary dictionary of keywords
281  remove "remove file" flag - force removing the option file and create a new one
282  OptionFile flag for existence of option file
283  technology specify the langauge of the script
284  """
285 
286 
287  self.DecayFileName = os.path.normpath(filename)
288 
290 
291  self.remove = remove
292 
293  self.OptionFile = None
294 
295  self.technology = technology
296 
297  def DecodeDecayFile(self):
298  """
299  Operates deconding of decay file.
300  """
301  fullstring = ''
302  with open(self.DecayFileName, 'rb') as f:
303  for line in f:
304  # Keep only lines starting with '#'
305  if line.startswith('# '):
306  line = line.replace('# ', '', 1)
307  fullstring += line
308  elif line.startswith('#'):
309  line = line.lstrip('#')
310  fullstring += line
311 
312  pattern1 = r'(?m)(\w+): (.+)'
313  pattern2 = r'(Documentation):((?s).*)EndDocumentation'
314  pattern3 = r'(InsertPythonCode):((?s).*)EndInsertPythonCode'
315  matchObj1 = re.findall(pattern1, fullstring)
316  matchObj2 = re.findall(pattern2, fullstring)
317  matchObj3 = re.findall(pattern3, fullstring)
318  if matchObj1 or matchObj2 or matchObj3:
319  for matchobj in matchObj1 + matchObj2 + matchObj3:
320  self.KeywordDictionary[matchobj[0]] = matchobj[1]
321  keystodelete = []
322  # delete keys found if Python Code
323  if matchObj3:
324  matchObj = re.findall(pattern1,
325  self.KeywordDictionary['InsertPythonCode'])
326  if matchObj:
327  for matchobj in matchObj:
328  keystodelete.append(matchobj[0])
329  # remove leading and ending spaces, except for python code
330  for (k, v) in self.KeywordDictionary.items():
331  if k != 'InsertPythonCode':
332  self.KeywordDictionary[k] = v.rstrip(' \n').lstrip(' \n')
333  if self.KeywordDictionary[k] == '':
334  keystodelete.append(k)
335  for k in keystodelete:
336  del self.KeywordDictionary[k]
337 
338  def Validate(self, obsoletes):
339  """
340  Check for the presence of mandatory keywords.
341  """
342  missing_mandatory = set(self.MandatoryKeywords) \
343  - set(self.KeywordDictionary.keys())
344  if len(missing_mandatory) != 0:
345  logging.error('%s.dec is missing mandatory keywords: %s',
346  self.DecayName(), [key for key in missing_mandatory])
347  raise SyntaxWarning
348  unknown_keywords = set(self.KeywordDictionary.keys()) \
349  - (set(self.MandatoryKeywords) | set(self.OptionalKeywords))
350  if len(unknown_keywords) != 0:
351  logging.error('%s.dec contains unknown keywords: %s',
352  self.DecayName(), [key for key in unknown_keywords])
353  raise SyntaxWarning
354 
355  # check if the nickname is correct
356  if self.NickName() != self.DecayName():
357  logging.error('In %s, the nickname %s is not equal to the name of the file %s.',
358  self.DecayFileName,
359  self.KeywordDictionary['NickName'], self.DecayName())
360  raise UserWarning
361 
362  # check if the date format is correct
363  try:
364  thetime = time.strptime(self.Date(), '%Y%m%d')
365  except ValueError:
366  logging.error('In %s, the date format is not correct, it should be YYYYMMDD instead of %s.',
367  self.DecayFileName, self.Date())
368  raise UserWarning
369 
370  # check physics wg name
371  if self.PhysicsWG() not in list_of_wg:
372  logging.error('In %s, the name of the WG is not correct: %s.',
373  self.DecayFileName, self.PhysicsWG())
374 
375  # check the event type does not start with 0
376  if self.EventTypeNumber()[0] == '0':
377  logging.error('The EventType is not correct in %s.',
378  self.DecayFileName)
379  logging.error('It cannot start with 0.')
380  raise UserWarning
381 
382  # check the event type has at least 8 digits
383  if len(self.EventTypeNumber()) < 8:
384  logging.error('The EventType is not correct in %s.',
385  self.DecayFileName)
386  logging.error('It must have at least 8 digits.')
387  raise UserWarning
388 
389  # check if the event is obsolete
390  if self.EventTypeNumber() in obsoletes:
391  logging.error('The EventType %s is in use in the obsolete list, please change it.', self.EventTypeNumber())
392  raise UserWarning
393 
394  # check Tested is equal to Yes or No
395  self.KeywordDictionary['Tested'] = self.KeywordDictionary['Tested'].lower()
396  if self.KeywordDictionary['Tested'] != 'yes' and self.KeywordDictionary['Tested'] != 'no':
397  logging.error('In %s, Tested should be equal to Yes or No', self.DecayName())
398  raise UserWarning
399 
400  # check that the file has been tested (check can be disabled with --force option)
401  if self.KeywordDictionary['Tested'] == 'no':
402  logging.error('The decay file %s has not been tested',
403  self.DecayName())
404  raise SyntaxWarning
405 
406  def EventTypeNumber(self):
407  """
408  Returns event type number.
409  """
410  return self.KeywordDictionary['EventType'].replace(' ', '')
411 
412  def G(self):
413  """
414  Returns general flag of event type.
415  """
416  return self.EventTypeNumber()[0]
417 
418  def S(self):
419  """
420  Returns selection flag of event type.
421  """
422  return self.EventTypeNumber()[1]
423 
424  def D(self):
425  """
426  Returns the decay flag of even type.
427  """
428  return self.EventTypeNumber()[2]
429 
430  def C(self):
431  """
432  Returns the charm flag of even type.
433  """
434  return self.EventTypeNumber()[3]
435 
436  def L(self):
437  """
438  Returns the lepton flag of even type.
439  """
440  return self.EventTypeNumber()[4]
441 
442  def T(self):
443  """
444  Returns the track flag of even type.
445  """
446  return self.EventTypeNumber()[5]
447 
448  def N(self):
449  """
450  Returns the neutral flag of even type.
451  """
452  return self.EventTypeNumber()[6]
453 
454  def K(self):
455  """
456  Returns the neutral Kaons flag of even type.
457  """
458  return self.EventTypeNumber()[7]
459 
460  def E(self):
461  """
462  Returns the extra flag of even type.
463  """
464  return self.EventTypeNumber()[8]
465 
466  def U(self):
467  """
468  Returns the user flag of even type.
469  """
470  return self.EventTypeNumber()[9]
471 
472  def IsSpecialSource(self):
473  """
474  Check whether it is a special source.
475  """
476  return self.EventTypeNumber()[0] == '6' and self.EventTypeNumber()[3] \
477  == '5' or self.EventTypeNumber()[0] == '6' \
478  and self.EventTypeNumber()[3] == '4'
479 
480  def SetOptionFileName(self, filename=None):
481  """
482  Set name of option file.
483  """
484  if 'Text' in self.technology:
485  self.OptionFile = TextOptionFile()
486  else:
488 
489  if not filename:
490  filename = '{0}/prod/{1}'.format(os.environ['DECFILESROOT'], self.EventTypeNumber())
491 
492  self.OptionFile.SetFileName(filename)
493  if os.path.exists(self.OptionFile.OptionFileName()):
494  if self.remove:
495  os.remove(self.OptionFile.OptionFileName())
496  else:
497  logging.warning('The file %s already exists.',
498  self.OptionFile.OptionFileName())
499  logging.warning('To overwrite it, you should remove it first or run with the --remove option.'
500  )
501  raise UserWarning
502  self.OptionFile.Open()
503 
504  def DecayDescriptor(self):
505  """
506  Returns decay descriptor.
507  """
508  return self.KeywordDictionary['Descriptor']
509 
511  """
512  Check if there is python code to be inserted.
513  """
514  return 'InsertPythonCode' in self.KeywordDictionary
515 
517  """
518  Returns the python code to be inserted.
519  """
520  return self.KeywordDictionary['InsertPythonCode']
521 
522  def HasExtraOptions(self):
523  """
524  Check if it has extra options.
525  """
526  return 'ExtraOptions' in self.KeywordDictionary
527 
528  def ExtraOptions(self):
529  """
530  Returns the extra options.
531  """
532  return self.KeywordDictionary['ExtraOptions']
533 
534  def HasDecayEngine(self):
535  """
536  Check if decay engine has been specified.
537  """
538  return 'DecayEngine' in self.KeywordDictionary
539 
540  def DecayEngine(self):
541  """
542  Returns the decay engine.
543  """
544  return self.KeywordDictionary['DecayEngine']
545 
546  def HasDecayOptions(self):
547  """
548  Check if decay options have been specified.
549  """
550  return 'DecayOptions' in self.KeywordDictionary
551 
552  def DecayOptions(self):
553  """
554  Returns the decay options.
555  """
556  return self.KeywordDictionary['DecayOptions']
557 
558  def HasParticleTable(self):
559  """
560  Check whether particle table already exists.
561  """
562  return 'ParticleTable' in self.KeywordDictionary
563 
564  def ParticleTable(self):
565  """
566  Return particle table.
567  """
568  return self.KeywordDictionary['ParticleTable']
569 
570  def HasParticleValue(self):
571  """
572  Check if particle value parameter has been specified.
573  """
574  return 'ParticleValue' in self.KeywordDictionary
575 
576  def ParticleValue(self):
577  """
578  Returns particle value.
579  """
580  return self.KeywordDictionary['ParticleValue']
581 
582  def HasConfiguration(self):
583  """
584  Check if configuration is present in keyword dictionary.
585  """
586  return 'Configuration' in self.KeywordDictionary
587 
588  def Configuration(self):
589  """
590  Returns configuration.
591  """
592  return self.KeywordDictionary['Configuration'].split()
593 
594  def HasParticleType(self):
595  """
596  Check if Particle Type is present in keyword dictionary.
597  """
598  return 'ParticleType' in self.KeywordDictionary
599 
600  def ParticleType(self):
601  """
602  Returns Particle Type.
603  """
604  return self.KeywordDictionary['ParticleType'].split()
605 
606  def HasMomentum(self):
607  """
608  Check if momentum is present in keyword dictionary.
609  """
610  return 'Momentum' in self.KeywordDictionary
611 
612  def Momentum(self):
613  """
614  Returns momentum.
615  """
616  return self.KeywordDictionary['Momentum'].split()
617 
618  def HasMomentumRange(self):
619  """
620  Check if momentum range is present in keyword dictionary.
621  """
622  return 'MomentumRange' in self.KeywordDictionary
623 
624  def MomentumRange(self):
625  """
626  Returns momentum range.
627  """
628  return self.KeywordDictionary['MomentumRange'].split()
629 
630  def NickName(self):
631  """
632  Return decay NickName.
633  """
634  return self.KeywordDictionary['NickName'].replace(' ', '')
635 
636  def Date(self):
637  """
638  Return date.
639  """
640  return self.KeywordDictionary['Date']
641 
642  def PhysicsWG(self):
643  """
644  Return mode WG.
645  """
646  return self.KeywordDictionary['PhysicsWG']
647 
648  def DecayName(self):
649  """
650  Return decay name string.
651  """
652  return os.path.splitext(os.path.split(self.DecayFileName)[1])[0]
653 
654  def Sample(self):
655  """
656  Check if overriden.
657  """
658  if 'Sample' in self.KeywordDictionary:
659  sample = self.KeywordDictionary['Sample']
660  elif int(self.EventTypeNumber()[0]) in (1, 2, 3, 7):
661  if int(self.EventTypeNumber()[1]) in (0, 9):
662  sample = 'Inclusive'
663  elif int(self.EventTypeNumber()[0]) == 1 and int(self.EventTypeNumber()[1]) in (1, 2, 3, 6, 7):
664  sample = 'Signal'
665  else:
666  sample = 'otherTreatment'
667  return sample
668 
669  def Production(self):
670  """
671  Checks for production algorithm.
672  """
673  production = 'Pythia'
674  if 'Production' in self.KeywordDictionary:
675  production = self.KeywordDictionary['Production']
676  return production
677 
678  def HeaderOptions(self):
679  """
680  Write the header of the options file.
681  """
682 
683  self.OptionFile.WriteHeader(self.EventTypeNumber(),
684  self.DecayDescriptor())
685 
686 
687 def writeBkkTable(evttypeid, descriptor, nickname):
688  """
689  Write the file to create the entry in the ORACLE database.
690  """
691 
692  global bkk_first, eventid_inbkk
693  TableName = '../doc/table_event.txt'.format(os.environ['DECFILESROOT'])
694  logging.warning(TableName)
695  if bkk_first:
696  bkk_first = False
697  if not os.path.exists(TableName):
698  with open(TableName, 'wb') as f:
699  line = 'EventTypeID | NickName | Description\n'
700  f.write(line)
701  else:
702  # read the file
703  with open(TableName, 'rb') as f:
704  for line in f:
705  eventid_inbkk.append(line.split()[0])
706 
707  if evttypeid not in eventid_inbkk:
708  eventid_inbkk.append(evttypeid)
709  nick = nickname[:255]
710  desc = descriptor[:255]
711  with open(TableName, 'a+') as f:
712  line = '{0} | {1} | {2}\n'.format(evttypeid, nick, desc)
713  f.write(line)
714 
715 
716 def writeSQLTable(evttypeid, descriptor, nickname):
717  """
718  Write the file to create the entry in the database.
719  """
720 
721  global sql_first, eventid_insql
722  TableName = '../doc/table_event.sql'.format(os.environ['DECFILESROOT'])
723 
724  if sql_first:
725  sql_first = False
726  if not os.path.exists(TableName):
727  os.system('touch ' + TableName)
728  else:
729  # read the file
730  with open(TableName, 'rb') as f:
731  for line in f:
732  eventid_insql.append(line.split()[2].strip(','))
733 
734  if evttypeid not in eventid_insql:
735  eventid_insql.append(evttypeid)
736  nick = nickname[:255]
737  desc = descriptor[:255]
738  with open(TableName, 'a+') as f:
739  line = 'EVTTYPEID = {0}, DESCRIPTION = "{1}", PRIMARY = "{2}"\n'.format(evttypeid, nick, desc)
740  f.write(line)
741 
742 
743 def readObsoleteTypeTable():
744  """
745  Read the table of obsolete events.
746  """
747 
748  filename = 'doc/table_obsolete.sql'.format(os.environ['DECFILESROOT'])
749  global list_of_obsoletes
750  try:
751  with open(filename, 'rb') as f:
752  for line in f:
753  list_of_obsoletes.append(line.split()[2].strip(','))
754  logging.info(' This will be ignored %s', line)
755  except IOError:
756  logging.warning('No files containing obsolete event types found')
757  except IndexError:
758  pass
759 
760 
761 def run_create(dkfile, remove, python, force):
762  """
763  Create an options file corresponding to a single decay file.
764  """
765 
766  technology = 'Text'
767  if python:
768  technology = 'Python'
769 
770  eventtype = EventType(dkfile, remove, technology)
771  eventtype.DecodeDecayFile()
772 
773  logging.info('Creation of production script file for Decay file %s.dec',
774  eventtype.DecayName())
775  try:
776  eventtype.Validate(list_of_obsoletes)
777  except SyntaxWarning:
778  if force:
779  pass
780  else:
781  raise UserWarning
782 
783  # check if the options file already exist and do not overwrite it
784  eventtype.SetOptionFileName()
785 
786  # get the first digit of the eventtype
787  AB = eventtype.EventTypeNumber()[0:2]
788  ABX = eventtype.EventTypeNumber()[0:2] + eventtype.E()
789  ABU = eventtype.EventTypeNumber()[0:2] + eventtype.U()
790 
791  eventtype.HeaderOptions()
792 
793  # Optional lines for all event types ---------------------------------
794  # Check if exists ExtraOptions keyword
795  if eventtype.HasExtraOptions():
796  eventtype.OptionFile.AddExtraOptions(eventtype)
797 
798  # Mandatory lines to write -------------------------------------------
799  # Event type number
800  eventtype.OptionFile.AddEventTypeNumber(eventtype)
801 
802  # Decay tool
803  if not eventtype.HasDecayEngine():
804  eventtype.OptionFile.AddEvtGenUserDecayFile(eventtype)
805  else:
806  eventtype.OptionFile.AddDecayEngine(eventtype)
807 
808  # Generation.SAMPLE.GENERATOR.InclusivePIDList
809  # if Inclusive
810  if 'Inclusive' in eventtype.Sample():
811  if eventtype.G() == '1':
812  pidlist = '521, -521, 511, -511, 531, -531, 541, -541, 5122, -5122, 5222, -5222, 5212, -5212, 5112, -5112, ' \
813  '5312, -5312, 5322, -5322, 5332, -5332, 5132, -5132, 5232, -5232'
814  elif int(eventtype.G()) in (2, 7):
815  pidlist = '421, -421, 411, -411, 431, -431, 4122, -4122, 443, 4112, -4112, 4212, -4212, 4222, -4222, 4312, ' \
816  '-4312, 4322, -4322, 4332, -4332, 4132, -4132, 4232, -4232, 100443, 441, 10441, 20443, 445, 4214, -4214, ' \
817  '4224, -4224, 4314, -4314, 4324, -4324, 4334, -4334, 4412, -4412, 4414,-4414, 4422, -4422, 4424, -4424, 4432, ' \
818  '-4432, 4434, -4434, 4444, -4444, 14122, -14122, 14124, -14124, 100441'
819  eventtype.OptionFile.AddInclusivePIDList(eventtype, pidlist)
820  else:
821  # if Type Signal
822  listing = { # tau
823  # Sigma
824  # Lambda
825  # Ks
826  # Xi
827  # Omega
828  '10': '521, -521, 511, -511, 531, -531, 541, -541, 5122, -5122, 5222, -5222, 5212, -5212, 5112, -5112, 5312, -5312, '
829  '5322, -5322, 5332, -5332, 5132, -5132, 5232, -5232',
830  '11': '511,-511',
831  '12': '521,-521',
832  '13': '531,-531',
833  '14': '541,-541',
834  '15': '5122,-5122',
835  '19': '521, -521, 511, -511, 531, -531, 541, -541, 5122, -5122, 5332, -5332, 5132, -5132, 5232, -5232',
836  '20': '421, -421, 411, -411, 431, -431, 4122, -4122, 443, 4112, -4112, 4212, -4212, 4222, -4222, 4312, -4312, 4322, '
837  '-4322, 4332, -4332, 4132, -4132, 4232, -4232, 100443, 441, 10441, 20443, 445, 4214, -4214, 4224, -4224, 4314, '
838  '-4314, 4324, -4324, 4334, -4334, 4412, -4412, 4414,-4414, 4422, -4422, 4424, -4424, 4432, -4432, 4434, -4434, '
839  '4444, -4444, 14122, -14122, 14124, -14124, 100441',
840  '21': '411,-411',
841  '22': '421,-421',
842  '23': '431,-431',
843  '24': '443',
844  '25': '4122,-4122',
845  '31': '15,-15',
846  '32': '3222,-3222',
847  '33': '3122,-3122',
848  '34': '310',
849  '35': '3312,-3312',
850  '36': '3334,-3334',
851  '70': '421, -421, 411, -411, 431, -431, 4122, -4122, 443, 4112, -4112, 4212, -4212, 4222, -4222, 4312, -4312, 4322, '
852  '-4322, 4332, -4332, 4132, -4132, 4232, -4232, 100443, 441, 10441, 20443, 445, 4214, -4214, 4224, -4224, 4314, '
853  '-4314, 4324, -4324, 4334, -4334, 4412, -4412, 4414,-4414, 4422, -4422, 4424, -4424, 4432, -4432, 4434, -4434, '
854  '4444, -4444, 14122, -14122, 14124, -14124, 100441',
855  '71': '411,-411',
856  '72': '421,-421',
857  '73': '431,-431',
858  '74': '443',
859  '75': '4122,-4122',
860  }
861  listingExcited = {
862  '270': '413,-413',
863  '271': '423,-423',
864  '272': '433,-433',
865  '273': '435,-435',
866  '274': '425,-425',
867  '275': '415,-415',
868  '276': '10433,-10433',
869  '277': '413,-413',
870  '770': '413,-413',
871  '771': '423,-423',
872  '772': '433,-433',
873  '280': '100443',
874  '281': '9920443',
875  '282': '10443',
876  '283': '10441',
877  '284': '20443',
878  '285': '445',
879  '286': '441',
880  '287': '30443',
881  '180': '553',
882  '181': '100553',
883  '182': '200553',
884  '183': '300553',
885  '184': '9000553',
886  '185': '10551',
887  '186': '20553',
888  '187': '555',
889  '160': '5112,-5112',
890  '161': '5212,-5212',
891  '162': '5222,-5222',
892  '163': '5132,-5132',
893  '164': '5232,-5232',
894  '165': '5332,-5332',
895  '170': '513,-513',
896  '171': '523,-523',
897  '172': '533,-533',
898  '173': '10513,-10513',
899  '174': '10523,-10523',
900  '175': '10533,-10533',
901  '176': '515,-515',
902  '177': '525,-525',
903  '178': '535,-535',
904  }
905 
906  # Check if exists ParticleTable keyword
907  if eventtype.HasParticleTable():
908  eventtype.OptionFile.AddParticleTable(eventtype)
909 
910  # Check if exists ParticleValue keyword
911  if eventtype.HasParticleValue():
912  eventtype.OptionFile.AddParticleValue(eventtype)
913 
914  # insert python lines directly
915  if technology == 'Python':
916  if eventtype.HasPythonCodeToInsert():
917  eventtype.OptionFile.Write([eventtype.PythonCodeToInsert()])
918 
919  writeBkkTable(eventtype.EventTypeNumber(), eventtype.DecayDescriptor(),
920  eventtype.NickName())
921  writeSQLTable(eventtype.EventTypeNumber(), eventtype.DecayDescriptor(),
922  eventtype.NickName())
923 
924 
925 def run_loop(remove, python, force):
926  """
927  Loop in the FILES directory to generate the options file.
928  """
929 
930  files = glob.glob(os.environ['DECFILESROOT'] + '/dec/*.dec')
931  for f in files:
932  try:
933  run_create(f, remove, python, force)
934  except UserWarning:
935  pass
936 
937 
938 def CheckFile(option, opt_str, value, parser):
939  """
940  Check if file exists.
941  """
942 
943  if not os.path.exists('{0}/dec/{1}.dec'.format(os.environ['DECFILESROOT'],
944  value)):
945  raise OptionValueError('Decay file %s.dec ' % value + 'does not ' +
946  'exist in the $DECFILESROOT/dec directory')
947  setattr(parser.values, option.dest, value)
948 
949 
950 # ---------------------------------------------------------------------------
951 # Color formatting
952 # ---------------------------------------------------------------------------
953 
954 (
955  BLACK,
956  RED,
957  GREEN,
958  YELLOW,
959  BLUE,
960  MAGENTA,
961  CYAN,
962  WHITE,
963 ) = list(range(8))
964 
965 # The background is set with 40 plus the number of the color, and the foreground with 30
966 
967 # These are the sequences need to get colored ouput
968 RESET_SEQ = "\033[0m"
969 COLOR_SEQ = "\033[1;%d;40m"
970 BOLD_SEQ = "\033[1m"
971 
972 COLORS = {
973  'WARNING': YELLOW,
974  'INFO': WHITE,
975  'DEBUG': BLUE,
976  'CRITICAL': YELLOW,
977  'ERROR': RED,
978 }
979 
980 
981 class ColoredFormatter(logging.Formatter):
982 
983  """
984  Define color convention for output messages.
985  """
986 
987  def __init__(self, msg, use_color=True):
988  """
989  Constructor.
990 
991  Attributes:
992  use_color use color output flag
993  """
994  logging.Formatter.__init__(self, msg)
995 
996 
997  self.use_color = use_color
998 
999  def format(self, record):
1000  """
1001  Set output format.
1002  """
1003  levelname = record.levelname
1004  color = COLOR_SEQ % (30 + COLORS[levelname])
1005  message = logging.Formatter.format(self, record)
1006  message = message.replace('$RESET', RESET_SEQ).replace('$BOLD', BOLD_SEQ).replace('$COLOR', color)
1007  return message + RESET_SEQ
1008 
1009 
1010 # ---------------------------------------------------------------------------
1011 # Main routine
1012 # ---------------------------------------------------------------------------
1013 
1014 def main():
1015  global exit_status
1016 
1017  mylog = logging.StreamHandler()
1018  logging.getLogger().setLevel(logging.DEBUG)
1019  mylog.setFormatter(ColoredFormatter('$COLOR$BOLD[%(levelname)-10s]$RESET$COLOR %(message)s', True))
1020  logging.getLogger().addHandler(mylog)
1021  usage = 'usage: %prog [options]'
1022  parser = OptionParser(usage=usage, version=version)
1023  parser.add_option(
1024  '-q',
1025  '--quiet',
1026  dest='verbose',
1027  default=False,
1028  action='store_false',
1029  help='switch off info printout',
1030  )
1031  parser.add_option('--remove', dest='remove', default=False,
1032  action='store_true',
1033  help='force the delete of the option file before '
1034  'creating a new one, by default existing option '
1035  'files are not overwritten')
1036  parser.add_option(
1037  '-d',
1038  '--decay',
1039  type='string',
1040  dest='NickName',
1041  help='name of the nick name of the decay to create option '
1042  'for, if not specified, loop over all decay files in the '
1043  'dec directory',
1044  action='callback',
1045  callback=CheckFile,
1046  )
1047  parser.add_option('--text', dest='python', default=True,
1048  action='store_false',
1049  help='create text option files instead of python options'
1050  )
1051  parser.add_option('--force', dest='force', default=False,
1052  action='store_true',
1053  help='force create of option file even when the decay file '
1054  'syntax is not correct')
1055 
1056  # Check that the environment variable DECFILESROOT exist otherwise
1057  # set it to ../dec
1058  if 'DECFILESROOT' not in os.environ:
1059  logging.warning('')
1060  logging.warning('The variable DECFILESROOT is not defined.')
1061  logging.warning('Use ../ instead.')
1062  logging.warning('Run the setup script of the package to set the correct value.'
1063  )
1064  logging.warning('')
1065  os.environ['DECFILESROOT'] = '../'
1066  else:
1067  logging.info('')
1068  logging.info('The DECFILESROOT environment variable is set to: %s',
1069  os.environ['DECFILESROOT'])
1070  logging.info('')
1071 
1072  (options, args) = parser.parse_args()
1073 
1074  if not options.verbose:
1075  logging.getLogger().setLevel(logging.INFO)
1076 
1077  readObsoleteTypeTable()
1078 
1079  if options.NickName:
1080  try:
1081  run_create('{0}/dec/{1}.dec'.format(os.environ['DECFILESROOT'],
1082  options.NickName), options.remove, options.python,
1083  options.force)
1084  except UserWarning:
1085  exit_status = 1
1086  pass
1087  else:
1088  run_loop(options.remove, options.python, options.force)
1089 
1090 
1091 if __name__ == '__main__':
1092  main()
1093  sys.exit(exit_status)
CreateProdScripts.GenericOptionFile.Close
def Close(self)
Definition: CreateProdScripts.py:56
CreateProdScripts.EventType.S
def S(self)
Definition: CreateProdScripts.py:418
CreateProdScripts.PythonOptionFile.IncreaseOptionValue
def IncreaseOptionValue(self, option, value)
Definition: CreateProdScripts.py:225
CreateProdScripts.EventType.HasMomentumRange
def HasMomentumRange(self)
Definition: CreateProdScripts.py:618
CreateProdScripts.GenericOptionFile.filename
filename
name of the file
Definition: CreateProdScripts.py:46
CreateProdScripts.ColoredFormatter.use_color
use_color
use color output flag
Definition: CreateProdScripts.py:997
CreateProdScripts.PythonOptionFile.AddOptionValue
def AddOptionValue(self, option, value, substitute=False)
Definition: CreateProdScripts.py:214
CreateProdScripts.EventType.HasParticleValue
def HasParticleValue(self)
Definition: CreateProdScripts.py:570
CreateProdScripts.PythonOptionFile.list_algorithm
list_algorithm
list of algorithms
Definition: CreateProdScripts.py:209
CreateProdScripts.GenericOptionFile.AddDecayOptions
def AddDecayOptions(self, eventtype)
Definition: CreateProdScripts.py:123
CreateProdScripts.EventType.Production
def Production(self)
Definition: CreateProdScripts.py:669
CreateProdScripts.GenericOptionFile.__init__
def __init__(self)
Definition: CreateProdScripts.py:38
CreateProdScripts.GenericOptionFile.__del__
def __del__(self)
Definition: CreateProdScripts.py:50
CreateProdScripts.EventType.T
def T(self)
Definition: CreateProdScripts.py:442
CreateProdScripts.EventType
Definition: CreateProdScripts.py:233
CreateProdScripts.EventType.OptionalKeywords
list OptionalKeywords
list of optional keywords for file description
Definition: CreateProdScripts.py:256
CreateProdScripts.EventType.HasParticleType
def HasParticleType(self)
Definition: CreateProdScripts.py:594
CreateProdScripts.EventType.Date
def Date(self)
Definition: CreateProdScripts.py:636
CreateProdScripts.GenericOptionFile.AddEvtGenUserDecayFile
def AddEvtGenUserDecayFile(self, eventtype)
Definition: CreateProdScripts.py:116
CreateProdScripts.EventType.NickName
def NickName(self)
Definition: CreateProdScripts.py:630
CreateProdScripts.TextOptionFile
Definition: CreateProdScripts.py:133
CreateProdScripts.TextOptionFile.AddOptionValue
def AddOptionValue(self, option, value, substitute=False)
Definition: CreateProdScripts.py:157
CreateProdScripts.GenericOptionFile.OptionFileName
def OptionFileName(self)
Definition: CreateProdScripts.py:63
CreateProdScripts.EventType.Momentum
def Momentum(self)
Definition: CreateProdScripts.py:612
CreateProdScripts.PythonOptionFile.__init__
def __init__(self)
Definition: CreateProdScripts.py:200
CreateProdScripts.EventType.IsSpecialSource
def IsSpecialSource(self)
Definition: CreateProdScripts.py:472
CreateProdScripts.EventType.E
def E(self)
Definition: CreateProdScripts.py:460
CreateProdScripts.GenericOptionFile.f
f
alternative name of the file
Definition: CreateProdScripts.py:48
CreateProdScripts.EventType.HasParticleTable
def HasParticleTable(self)
Definition: CreateProdScripts.py:558
CreateProdScripts.EventType.SetOptionFileName
def SetOptionFileName(self, filename=None)
Definition: CreateProdScripts.py:480
CreateProdScripts.EventType.N
def N(self)
Definition: CreateProdScripts.py:448
CreateProdScripts.EventType.DecodeDecayFile
def DecodeDecayFile(self)
Definition: CreateProdScripts.py:297
CreateProdScripts.EventType.Configuration
def Configuration(self)
Definition: CreateProdScripts.py:588
CreateProdScripts.EventType.ExtraOptions
def ExtraOptions(self)
Definition: CreateProdScripts.py:528
CreateProdScripts.EventType.MomentumRange
def MomentumRange(self)
Definition: CreateProdScripts.py:624
main
int main(int argc, char **argv)
Run all tests.
Definition: test_main.cc:77
CreateProdScripts.GenericOptionFile.SetFileName
def SetFileName(self, filename)
Definition: CreateProdScripts.py:69
CreateProdScripts.EventType.DecayFileName
DecayFileName
name of decay file
Definition: CreateProdScripts.py:287
CreateProdScripts.GenericOptionFile.WriteHeader
def WriteHeader(self, eventtype, descriptor)
Definition: CreateProdScripts.py:89
CreateProdScripts.EventType.C
def C(self)
Definition: CreateProdScripts.py:430
CreateProdScripts.EventType.L
def L(self)
Definition: CreateProdScripts.py:436
CreateProdScripts.GenericOptionFile.AddExtraOptions
def AddExtraOptions(self, eventtype)
Definition: CreateProdScripts.py:104
CreateProdScripts.EventType.HasPythonCodeToInsert
def HasPythonCodeToInsert(self)
Definition: CreateProdScripts.py:510
CreateProdScripts.EventType.remove
remove
"remove file" flag
Definition: CreateProdScripts.py:291
CreateProdScripts.EventType.DecayOptions
def DecayOptions(self)
Definition: CreateProdScripts.py:552
CreateProdScripts.EventType.HasMomentum
def HasMomentum(self)
Definition: CreateProdScripts.py:606
CreateProdScripts.ColoredFormatter.__init__
def __init__(self, msg, use_color=True)
Definition: CreateProdScripts.py:987
CreateProdScripts.ColoredFormatter.format
def format(self, record)
Definition: CreateProdScripts.py:999
CreateProdScripts.EventType.G
def G(self)
Definition: CreateProdScripts.py:412
CreateProdScripts.TextOptionFile.IncreaseOptionValue
def IncreaseOptionValue(self, option, value)
Definition: CreateProdScripts.py:169
CreateProdScripts.EventType.HasConfiguration
def HasConfiguration(self)
Definition: CreateProdScripts.py:582
CreateProdScripts.EventType.__init__
def __init__(self, filename, remove, technology)
Definition: CreateProdScripts.py:274
CreateProdScripts.EventType.DecayName
def DecayName(self)
Definition: CreateProdScripts.py:648
CreateProdScripts.EventType.technology
technology
specify the langauge of the script
Definition: CreateProdScripts.py:295
CreateProdScripts.EventType.ParticleTable
def ParticleTable(self)
Definition: CreateProdScripts.py:564
CreateProdScripts.EventType.Validate
def Validate(self, obsoletes)
Definition: CreateProdScripts.py:338
CreateProdScripts.EventType.Sample
def Sample(self)
Definition: CreateProdScripts.py:654
CreateProdScripts.EventType.DecayDescriptor
def DecayDescriptor(self)
Definition: CreateProdScripts.py:504
CreateProdScripts.EventType.HasDecayOptions
def HasDecayOptions(self)
Definition: CreateProdScripts.py:546
CreateProdScripts.GenericOptionFile
Definition: CreateProdScripts.py:32
CreateProdScripts.EventType.MandatoryKeywords
list MandatoryKeywords
list of mandatory keywords for file description
Definition: CreateProdScripts.py:243
CreateProdScripts.EventType.HasExtraOptions
def HasExtraOptions(self)
Definition: CreateProdScripts.py:522
CreateProdScripts.GenericOptionFile.AddEventTypeNumber
def AddEventTypeNumber(self, eventtype)
Definition: CreateProdScripts.py:110
CreateProdScripts.EventType.ParticleValue
def ParticleValue(self)
Definition: CreateProdScripts.py:576
CreateProdScripts.EventType.K
def K(self)
Definition: CreateProdScripts.py:454
CreateProdScripts.PythonOptionFile.list_tool
list_tool
list of tools
Definition: CreateProdScripts.py:211
CreateProdScripts.EventType.PhysicsWG
def PhysicsWG(self)
Definition: CreateProdScripts.py:642
CreateProdScripts.EventType.HasDecayEngine
def HasDecayEngine(self)
Definition: CreateProdScripts.py:534
CreateProdScripts.TextOptionFile.AddInclude
def AddInclude(self, filename)
Definition: CreateProdScripts.py:163
CreateProdScripts.EventType.ParticleType
def ParticleType(self)
Definition: CreateProdScripts.py:600
CreateProdScripts.EventType.OptionFile
OptionFile
flag for existence of option file
Definition: CreateProdScripts.py:293
CreateProdScripts.EventType.EventTypeNumber
def EventTypeNumber(self)
Definition: CreateProdScripts.py:406
CreateProdScripts.EventType.PythonCodeToInsert
def PythonCodeToInsert(self)
Definition: CreateProdScripts.py:516
CreateProdScripts.GenericOptionFile.Write
def Write(self, lines)
Definition: CreateProdScripts.py:82
CreateProdScripts.EventType.U
def U(self)
Definition: CreateProdScripts.py:466
CreateProdScripts.EventType.KeywordDictionary
KeywordDictionary
dictionary of keywords
Definition: CreateProdScripts.py:289
CreateProdScripts.GenericOptionFile.Open
def Open(self)
Definition: CreateProdScripts.py:75
CreateProdScripts.EventType.DecayEngine
def DecayEngine(self)
Definition: CreateProdScripts.py:540
CreateProdScripts.EventType.HeaderOptions
def HeaderOptions(self)
Definition: CreateProdScripts.py:678
CreateProdScripts.PythonOptionFile
Definition: CreateProdScripts.py:176
CreateProdScripts.ColoredFormatter
Definition: CreateProdScripts.py:981
CreateProdScripts.EventType.D
def D(self)
Definition: CreateProdScripts.py:424