15 from optparse
import OptionParser, OptionValueError
28 list_of_obsoletes = []
30 list_of_wg = [
'SL',
'EWP',
'TCPV',
'HAD',
'CHARM',
'ONIA',
'TAU']
36 Class to write in an option file
43 filename name of the file
44 f alternative name of the file
74 self.
filenamefilename = os.path.normpath(filename + self.suffix)
81 self.
ff = open(self.
filenamefilename,
'w')
85 Write the lines in the file.
88 self.
ff.writelines([line +
'\n' for line
in lines])
92 Write header of .dec file.
94 timeString = time.strftime(
"%a, %d %b %Y %H:%M:%S", time.localtime())
96 f
"{self.comment} file {self.filename} generated: {timeString}",
98 f
"{self.comment} Event Type: {eventtype}",
100 f
"{self.comment} ASCII decay Descriptor: {descriptor}",
104 self.
WriteWrite(lines)
110 self.AddInclude(eventtype.ExtraOptions())
114 Adds the Event Type Number.
116 self.AddOptionValue(
'GenerationEventType', eventtype.EventTypeNumber())
120 Set the EvtGen .dec file.
122 self.AddOptionValue(
'EvtGenUserDecayFile',
123 '"$DECFILESROOT/dec/{0}.dec"'.format(eventtype.DecayName()))
127 Specify options for .dec file.
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)]
138 Class to read generic option file in .txt format.
141 comment comment string
143 true_string true string
144 list_begin open list parenthesis
145 list_end close list parenthesis
161 Set the value of option.
163 self.
WriteWrite([
'{0} = {1};'.format(option, value)])
167 Add include statements.
169 self.
WriteWrite([
'#include "$DECFILESROOT/prod/{0}.py"'.format(filename)])
175 self.
WriteWrite([
'{0} += {1};'.format(option, value)])
181 Class to read generic option file in .py format.
184 comment comment string
186 true_string true string
187 list_begin open list parenthesis
188 list_end close list parenthesis
207 list_algorithm list of algorithms
208 list_tool list of tools
214 super(PythonOptionFile, self).
__init__()
220 value = value.replace(
'{',
'[')
221 value = value.replace(
'}',
']')
223 value = value.replace(
'true',
'True')
224 value = value.replace(
'false',
'False')
225 self.
WriteWrite([
'{0} = {1}'.format(option, value)])
231 option = self.ConfigureToolAndAlgo(option)
232 self.
WriteWrite([
'{0} += {1}'.format(option, value)])
238 Class to hold event type information.
241 MandatoryKeywords list of mandatory keywords for file description
242 OptionalKeywords list of optional keywords for file description
245 MandatoryKeywords = [
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
301 Operates deconding of decay file.
307 if line.startswith(
'# '):
308 line = line.replace(
'# ',
'', 1)
310 elif line.startswith(
'#'):
311 line = line.lstrip(
'#')
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:
326 matchObj = re.findall(pattern1,
329 for matchobj
in matchObj:
330 keystodelete.append(matchobj[0])
333 if k !=
'InsertPythonCode':
336 keystodelete.append(k)
337 for k
in keystodelete:
342 Check for the presence of mandatory keywords.
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])
352 if len(unknown_keywords) != 0:
353 logging.error(
'%s.dec contains unknown keywords: %s',
354 self.
DecayNameDecayName(), [key
for key
in unknown_keywords])
360 'In %s, the nickname %s is not equal to the name of the file %s.',
368 time.strptime(self.
DateDate(),
'%Y%m%d')
371 'In %s, the date format is not correct, it should be YYYYMMDD instead of %s.',
377 if self.
PhysicsWGPhysicsWG()
not in list_of_wg:
378 logging.error(
'In %s, the name of the WG is not correct: %s.',
383 logging.error(
'The EventType is not correct in %s.',
385 logging.error(
'It cannot start with 0.')
390 logging.error(
'The EventType is not correct in %s.',
392 logging.error(
'It must have at least 8 digits.')
398 'The EventType %s is in use in the obsolete list, please change it.',
407 'In %s, Tested should be equal to Yes or No',
414 logging.error(
'The decay file %s has not been tested',
420 Returns event type number.
426 Returns general flag of event type.
432 Returns selection flag of event type.
438 Returns the decay flag of even type.
444 Returns the charm flag of even type.
450 Returns the lepton flag of even type.
456 Returns the track flag of even type.
462 Returns the neutral flag of even type.
468 Returns the neutral Kaons flag of even type.
474 Returns the extra flag of even type.
480 Returns the user flag of even type.
486 Check whether it is a special source.
494 Set name of option file.
502 filename =
'{0}/prod/{1}'.format(
505 self.
OptionFileOptionFile.SetFileName(filename)
506 if os.path.exists(self.
OptionFileOptionFile.OptionFileName()):
508 os.remove(self.
OptionFileOptionFile.OptionFileName())
510 logging.warning(
'The file %s already exists.',
513 'To overwrite it, you should remove it first or run with the --remove option.')
519 Returns decay descriptor.
525 Check if there is python code to be inserted.
531 Returns the python code to be inserted.
537 Check if it has extra options.
543 Returns the extra options.
549 Check if decay engine has been specified.
555 Returns the decay engine.
561 Check if decay options have been specified.
567 Returns the decay options.
573 Check whether particle table already exists.
579 Return particle table.
585 Check if particle value parameter has been specified.
591 Returns particle value.
597 Check if configuration is present in keyword dictionary.
603 Returns configuration.
609 Check if Particle Type is present in keyword dictionary.
615 Returns Particle Type.
621 Check if momentum is present in keyword dictionary.
633 Check if momentum range is present in keyword dictionary.
639 Returns momentum range.
645 Return decay NickName.
663 Return decay name string.
665 return os.path.splitext(os.path.split(self.
DecayFileNameDecayFileName)[1])[0]
679 sample =
'otherTreatment'
684 Checks for production algorithm.
686 production =
'Pythia'
693 Write the header of the options file.
700 def writeBkkTable(evttypeid, descriptor, nickname):
702 Write the file to create the entry in the ORACLE database.
705 global bkk_first, eventid_inbkk
706 TableName =
'../doc/table_event.txt'
707 logging.warning(TableName)
710 if not os.path.exists(TableName):
711 with open(TableName,
'wb')
as f:
712 line =
'EventTypeID | NickName | Description\n'
716 with open(TableName,
'rb')
as f:
718 eventid_inbkk.append(line.split()[0])
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)
729 def writeSQLTable(evttypeid, descriptor, nickname):
731 Write the file to create the entry in the database.
734 global sql_first, eventid_insql
735 TableName =
'../doc/table_event.sql'
739 if not os.path.exists(TableName):
740 os.system(
'touch ' + TableName)
743 with open(TableName,
'rb')
as f:
745 eventid_insql.append(line.split()[2].strip(
','))
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)
757 def readObsoleteTypeTable():
759 Read the table of obsolete events.
762 filename =
'../doc/table_obsolete.sql'
763 global list_of_obsoletes
765 with open(filename,
'rb')
as f:
767 list_of_obsoletes.append(line.split()[2].strip(
','))
768 logging.info(
' This will be ignored %s', line)
770 logging.warning(
'No files containing obsolete event types found')
775 def run_create(dkfile, remove, python, force):
777 Create an options file corresponding to a single decay file.
782 technology =
'Python'
784 eventtype =
EventType(dkfile, remove, technology)
785 eventtype.DecodeDecayFile()
787 logging.info(
'Creation of production script file for Decay file %s.dec',
788 eventtype.DecayName())
790 eventtype.Validate(list_of_obsoletes)
791 except SyntaxWarning:
798 eventtype.SetOptionFileName()
801 eventtype.EventTypeNumber()[0:2]
802 eventtype.EventTypeNumber()[0:2] + eventtype.E()
803 eventtype.EventTypeNumber()[0:2] + eventtype.U()
805 eventtype.HeaderOptions()
809 if eventtype.HasExtraOptions():
810 eventtype.OptionFile.AddExtraOptions(eventtype)
814 eventtype.OptionFile.AddEventTypeNumber(eventtype)
817 if not eventtype.HasDecayEngine():
818 eventtype.OptionFile.AddEvtGenUserDecayFile(eventtype)
820 eventtype.OptionFile.AddDecayEngine(eventtype)
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)
836 if eventtype.HasParticleTable():
837 eventtype.OptionFile.AddParticleTable(eventtype)
840 if eventtype.HasParticleValue():
841 eventtype.OptionFile.AddParticleValue(eventtype)
844 if technology ==
'Python':
845 if eventtype.HasPythonCodeToInsert():
846 eventtype.OptionFile.Write([eventtype.PythonCodeToInsert()])
848 writeBkkTable(eventtype.EventTypeNumber(), eventtype.DecayDescriptor(),
849 eventtype.NickName())
850 writeSQLTable(eventtype.EventTypeNumber(), eventtype.DecayDescriptor(),
851 eventtype.NickName())
854 def run_loop(remove, python, force):
856 Loop in the FILES directory to generate the options file.
859 files = glob.glob(os.environ[
'DECFILESROOT'] +
'/dec/*.dec')
862 run_create(f, remove, python, force)
867 def CheckFile(option, opt_str, value, parser):
869 Check if file exists.
872 if not os.path.exists(
'{0}/dec/{1}.dec'.format(os.environ[
'DECFILESROOT'],
874 raise OptionValueError(
'Decay file %s.dec ' % value +
'does not ' +
875 'exist in the $DECFILESROOT/dec directory')
876 setattr(parser.values, option.dest, value)
898 RESET_SEQ =
"\033[0m"
899 COLOR_SEQ =
"\033[1;%d;40m"
914 Define color convention for output messages.
922 use_color use color output flag
924 logging.Formatter.__init__(self, msg)
933 levelname = record.levelname
934 color = COLOR_SEQ % (30 + COLORS[levelname])
935 message = logging.Formatter.format(self, record)
936 message = message.replace(
943 return message + RESET_SEQ
953 mylog = logging.StreamHandler()
954 logging.getLogger().setLevel(logging.DEBUG)
957 '$COLOR$BOLD[%(levelname)-10s]$RESET$COLOR %(message)s',
959 logging.getLogger().addHandler(mylog)
960 usage =
'usage: %prog [options]'
961 parser = OptionParser(usage=usage, version=version)
967 action=
'store_false',
968 help=
'switch off info printout',
970 parser.add_option(
'--remove', dest=
'remove', default=
False,
972 help=
'force the delete of the option file before '
973 'creating a new one, by default existing option '
974 'files are not overwritten')
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 '
986 parser.add_option(
'--text', dest=
'python', default=
True,
987 action=
'store_false',
988 help=
'create text option files instead of python options'
995 help=
'force create of option file even when the decay file '
996 'syntax is not correct')
1000 if 'DECFILESROOT' not in os.environ:
1002 logging.warning(
'The variable DECFILESROOT is not defined.')
1003 logging.warning(
'Use ../ instead.')
1005 'Run the setup script of the package to set the correct value.')
1007 os.environ[
'DECFILESROOT'] =
'../'
1010 logging.info(
'The DECFILESROOT environment variable is set to: %s',
1011 os.environ[
'DECFILESROOT'])
1014 (options, args) = parser.parse_args()
1016 if not options.verbose:
1017 logging.getLogger().setLevel(logging.INFO)
1019 readObsoleteTypeTable()
1021 if options.NickName:
1024 '{0}/dec/{1}.dec'.
format(
1025 os.environ[
'DECFILESROOT'],
1033 run_loop(options.remove, options.python, options.force)
1036 if __name__ ==
'__main__':
1038 sys.exit(exit_status)
def __init__(self, filename, remove, technology)
list MandatoryKeywords
list of mandatory keywords for file description
technology
specify the langauge of the script
def PythonCodeToInsert(self)
def HasParticleType(self)
OptionFile
flag for existence of option file
def HasExtraOptions(self)
def HasDecayOptions(self)
list OptionalKeywords
list of optional keywords for file description
def EventTypeNumber(self)
def HasParticleTable(self)
def DecayDescriptor(self)
def HasConfiguration(self)
def HasParticleValue(self)
def SetOptionFileName(self, filename=None)
def IsSpecialSource(self)
KeywordDictionary
dictionary of keywords
def DecodeDecayFile(self)
def HasMomentumRange(self)
def Validate(self, obsoletes)
DecayFileName
name of decay file
def HasPythonCodeToInsert(self)
def AddExtraOptions(self, eventtype)
def WriteHeader(self, eventtype, descriptor)
def AddEvtGenUserDecayFile(self, eventtype)
def AddEventTypeNumber(self, eventtype)
f
alternative name of the file
def AddDecayOptions(self, eventtype)
def SetFileName(self, filename)
list_algorithm
list of algorithms
def IncreaseOptionValue(self, option, value)
def AddOptionValue(self, option, value, substitute=False)
def AddInclude(self, filename)
def IncreaseOptionValue(self, option, value)
def AddOptionValue(self, option, value, substitute=False)
int main(int argc, char **argv)
Run all tests.