17 list_of_obsoletes = []
19 list_of_wg = [
'SL',
'EWP',
'TCPV',
'HAD',
'CHARM',
'ONIA',
'TAU']
29 from optparse
import OptionParser, OptionValueError
35 Class to write in an option file
42 filename name of the file
43 f alternative name of the file
73 self.
filename = os.path.normpath(filename + self.suffix)
84 Write the lines in the file.
87 self.
f.writelines([l +
'\n' for l
in lines])
91 Write header of .dec file.
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),
108 self.AddInclude(eventtype.ExtraOptions())
112 Adds the Event Type Number.
114 self.AddOptionValue(
'GenerationEventType', eventtype.EventTypeNumber())
118 Set the EvtGen .dec file.
120 self.AddOptionValue(
'EvtGenUserDecayFile',
121 '"$DECFILESROOT/dec/{0}.dec"'.format(eventtype.DecayName()))
125 Specify options for .dec file.
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)]
136 Class to read generic option file in .txt format.
139 comment comment string
141 true_string true string
142 list_begin open list parenthesis
143 list_end close list parenthesis
159 Set the value of option.
161 self.
Write([
'{0} = {1};'.format(option, value)])
165 Add include statements.
167 self.
Write([
'#include "$DECFILESROOT/prod/{0}.py"'.format(filename)])
173 self.
Write([
'{0} += {1};'.format(option, value)])
179 Class to read generic option file in .py format.
182 comment comment string
184 true_string true string
185 list_begin open list parenthesis
186 list_end close list parenthesis
205 list_algorithm list of algorithms
206 list_tool list of tools
212 super(PythonOptionFile, self).
__init__()
218 value = value.replace(
'{',
'[')
219 value = value.replace(
'}',
']')
221 value = value.replace(
'true',
'True')
222 value = value.replace(
'false',
'False')
223 self.
Write([
'{0} = {1}'.format(option, value)])
229 option = self.ConfigureToolAndAlgo(option)
230 self.
Write([
'{0} += {1}'.format(option, value)])
236 Class to hold event type information.
239 MandatoryKeywords list of mandatory keywords for file description
240 OptionalKeywords list of optional keywords for file description
243 MandatoryKeywords = [
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
299 Operates deconding of decay file.
305 if line.startswith(
'# '):
306 line = line.replace(
'# ',
'', 1)
308 elif line.startswith(
'#'):
309 line = line.lstrip(
'#')
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:
324 matchObj = re.findall(pattern1,
327 for matchobj
in matchObj:
328 keystodelete.append(matchobj[0])
331 if k !=
'InsertPythonCode':
334 keystodelete.append(k)
335 for k
in keystodelete:
340 Check for the presence of mandatory keywords.
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])
350 if len(unknown_keywords) != 0:
351 logging.error(
'%s.dec contains unknown keywords: %s',
352 self.
DecayName(), [key
for key
in unknown_keywords])
357 logging.error(
'In %s, the nickname %s is not equal to the name of the file %s.',
364 thetime = time.strptime(self.
Date(),
'%Y%m%d')
366 logging.error(
'In %s, the date format is not correct, it should be YYYYMMDD instead of %s.',
372 logging.error(
'In %s, the name of the WG is not correct: %s.',
377 logging.error(
'The EventType is not correct in %s.',
379 logging.error(
'It cannot start with 0.')
384 logging.error(
'The EventType is not correct in %s.',
386 logging.error(
'It must have at least 8 digits.')
391 logging.error(
'The EventType %s is in use in the obsolete list, please change it.', self.
EventTypeNumber())
397 logging.error(
'In %s, Tested should be equal to Yes or No', self.
DecayName())
402 logging.error(
'The decay file %s has not been tested',
408 Returns event type number.
414 Returns general flag of event type.
420 Returns selection flag of event type.
426 Returns the decay flag of even type.
432 Returns the charm flag of even type.
438 Returns the lepton flag of even type.
444 Returns the track flag of even type.
450 Returns the neutral flag of even type.
456 Returns the neutral Kaons flag of even type.
462 Returns the extra flag of even type.
468 Returns the user flag of even type.
474 Check whether it is a special source.
482 Set name of option file.
490 filename =
'{0}/prod/{1}'.format(os.environ[
'DECFILESROOT'], self.
EventTypeNumber())
493 if os.path.exists(self.
OptionFile.OptionFileName()):
497 logging.warning(
'The file %s already exists.',
499 logging.warning(
'To overwrite it, you should remove it first or run with the --remove option.'
506 Returns decay descriptor.
512 Check if there is python code to be inserted.
518 Returns the python code to be inserted.
524 Check if it has extra options.
530 Returns the extra options.
536 Check if decay engine has been specified.
542 Returns the decay engine.
548 Check if decay options have been specified.
554 Returns the decay options.
560 Check whether particle table already exists.
566 Return particle table.
572 Check if particle value parameter has been specified.
578 Returns particle value.
584 Check if configuration is present in keyword dictionary.
590 Returns configuration.
596 Check if Particle Type is present in keyword dictionary.
602 Returns Particle Type.
608 Check if momentum is present in keyword dictionary.
620 Check if momentum range is present in keyword dictionary.
626 Returns momentum range.
632 Return decay NickName.
650 Return decay name string.
652 return os.path.splitext(os.path.split(self.
DecayFileName)[1])[0]
666 sample =
'otherTreatment'
671 Checks for production algorithm.
673 production =
'Pythia'
680 Write the header of the options file.
687 def writeBkkTable(evttypeid, descriptor, nickname):
689 Write the file to create the entry in the ORACLE database.
692 global bkk_first, eventid_inbkk
693 TableName =
'../doc/table_event.txt'.format(os.environ[
'DECFILESROOT'])
694 logging.warning(TableName)
697 if not os.path.exists(TableName):
698 with open(TableName,
'wb')
as f:
699 line =
'EventTypeID | NickName | Description\n'
703 with open(TableName,
'rb')
as f:
705 eventid_inbkk.append(line.split()[0])
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)
716 def writeSQLTable(evttypeid, descriptor, nickname):
718 Write the file to create the entry in the database.
721 global sql_first, eventid_insql
722 TableName =
'../doc/table_event.sql'.format(os.environ[
'DECFILESROOT'])
726 if not os.path.exists(TableName):
727 os.system(
'touch ' + TableName)
730 with open(TableName,
'rb')
as f:
732 eventid_insql.append(line.split()[2].strip(
','))
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)
743 def readObsoleteTypeTable():
745 Read the table of obsolete events.
748 filename =
'doc/table_obsolete.sql'.format(os.environ[
'DECFILESROOT'])
749 global list_of_obsoletes
751 with open(filename,
'rb')
as f:
753 list_of_obsoletes.append(line.split()[2].strip(
','))
754 logging.info(
' This will be ignored %s', line)
756 logging.warning(
'No files containing obsolete event types found')
761 def run_create(dkfile, remove, python, force):
763 Create an options file corresponding to a single decay file.
768 technology =
'Python'
770 eventtype =
EventType(dkfile, remove, technology)
771 eventtype.DecodeDecayFile()
773 logging.info(
'Creation of production script file for Decay file %s.dec',
774 eventtype.DecayName())
776 eventtype.Validate(list_of_obsoletes)
777 except SyntaxWarning:
784 eventtype.SetOptionFileName()
787 AB = eventtype.EventTypeNumber()[0:2]
788 ABX = eventtype.EventTypeNumber()[0:2] + eventtype.E()
789 ABU = eventtype.EventTypeNumber()[0:2] + eventtype.U()
791 eventtype.HeaderOptions()
795 if eventtype.HasExtraOptions():
796 eventtype.OptionFile.AddExtraOptions(eventtype)
800 eventtype.OptionFile.AddEventTypeNumber(eventtype)
803 if not eventtype.HasDecayEngine():
804 eventtype.OptionFile.AddEvtGenUserDecayFile(eventtype)
806 eventtype.OptionFile.AddDecayEngine(eventtype)
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)
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',
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',
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',
868 '276':
'10433,-10433',
898 '173':
'10513,-10513',
899 '174':
'10523,-10523',
900 '175':
'10533,-10533',
907 if eventtype.HasParticleTable():
908 eventtype.OptionFile.AddParticleTable(eventtype)
911 if eventtype.HasParticleValue():
912 eventtype.OptionFile.AddParticleValue(eventtype)
915 if technology ==
'Python':
916 if eventtype.HasPythonCodeToInsert():
917 eventtype.OptionFile.Write([eventtype.PythonCodeToInsert()])
919 writeBkkTable(eventtype.EventTypeNumber(), eventtype.DecayDescriptor(),
920 eventtype.NickName())
921 writeSQLTable(eventtype.EventTypeNumber(), eventtype.DecayDescriptor(),
922 eventtype.NickName())
925 def run_loop(remove, python, force):
927 Loop in the FILES directory to generate the options file.
930 files = glob.glob(os.environ[
'DECFILESROOT'] +
'/dec/*.dec')
933 run_create(f, remove, python, force)
938 def CheckFile(option, opt_str, value, parser):
940 Check if file exists.
943 if not os.path.exists(
'{0}/dec/{1}.dec'.format(os.environ[
'DECFILESROOT'],
945 raise OptionValueError(
'Decay file %s.dec ' % value +
'does not ' +
946 'exist in the $DECFILESROOT/dec directory')
947 setattr(parser.values, option.dest, value)
968 RESET_SEQ =
"\033[0m"
969 COLOR_SEQ =
"\033[1;%d;40m"
984 Define color convention for output messages.
992 use_color use color output flag
994 logging.Formatter.__init__(self, msg)
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
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)
1028 action=
'store_false',
1029 help=
'switch off info printout',
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')
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 '
1047 parser.add_option(
'--text', dest=
'python', default=
True,
1048 action=
'store_false',
1049 help=
'create text option files instead of python options'
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')
1058 if 'DECFILESROOT' not in os.environ:
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.'
1065 os.environ[
'DECFILESROOT'] =
'../'
1068 logging.info(
'The DECFILESROOT environment variable is set to: %s',
1069 os.environ[
'DECFILESROOT'])
1072 (options, args) = parser.parse_args()
1074 if not options.verbose:
1075 logging.getLogger().setLevel(logging.INFO)
1077 readObsoleteTypeTable()
1079 if options.NickName:
1081 run_create(
'{0}/dec/{1}.dec'.
format(os.environ[
'DECFILESROOT'],
1082 options.NickName), options.remove, options.python,
1088 run_loop(options.remove, options.python, options.force)
1091 if __name__ ==
'__main__':
1093 sys.exit(exit_status)