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