00001 import copy
00002 import inspect
00003 import FWCore.ParameterSet.Config as cms
00004 from FWCore.ParameterSet.Mixins import *
00005 from os import path
00006
00007
00008
00009 import FWCore.ParameterSet.DictTypes as dicttypes
00010
00011 def new_SortedKeysDict__copy__(self):
00012 return self.__class__(self)
00013 dicttypes.SortedKeysDict.__copy__ = new_SortedKeysDict__copy__
00014
00015 def new_SortedKeysDict__deepcopy__(self, memo=None):
00016 from copy import deepcopy
00017 if memo is None:
00018 memo = {}
00019 d = memo.get(id(self), None)
00020 if d is not None:
00021 return d
00022 memo[id(self)] = d = self.__class__()
00023 d.__init__(deepcopy(self.items(), memo))
00024 return d
00025 dicttypes.SortedKeysDict.__deepcopy__ = new_SortedKeysDict__deepcopy__
00026
00027
00028 class parameter:
00029 pass
00030
00031
00032
00033 class ConfigToolBase(object) :
00034
00035 """ Base class for PAT tools
00036 """
00037 _label="ConfigToolBase"
00038 _defaultValue="No default value. Set parameter value."
00039 _path = ""
00040 def __init__(self):
00041 self._parameters=dicttypes.SortedKeysDict()
00042 self._description=self.__doc__
00043 self._comment = ''
00044 self.parAccepted=True
00045 saveOrigin(self,1)
00046 self._path = path.realpath(self._filename)
00047 self._path = self._path.split("/src/")
00048 self._path = self._path[1].replace("/python","")
00049
00050 self._path = self._path.replace("/",".")
00051 self._path = self._path.replace(".py","")
00052
00053
00054 def __call__(self,process):
00055 """ Call the instance
00056 """
00057 raise NotImplementedError
00058
00059 def apply(self,process):
00060
00061 if hasattr(process, "addAction"):
00062 process.disableRecording()
00063
00064 try:
00065 comment=inspect.stack(2)[2][4][0].rstrip("\n")
00066 if comment.startswith("#"):
00067 self.setComment(comment.lstrip("#"))
00068 except:
00069 pass
00070
00071 self.toolCode(process)
00072
00073 if hasattr(process, "addAction"):
00074 process.enableRecording()
00075 action=self.__copy__()
00076 process.addAction(action)
00077
00078 def toolCode(self, process):
00079 raise NotImplementedError
00080
00081
00082
00083 def __copy__(self):
00084 c=type(self)()
00085 c.setParameters(copy.deepcopy(self._parameters))
00086 c.setComment(self._comment)
00087 return c
00088 def reset(self):
00089 self._parameters=copy.deepcopy(self._defaultParameters)
00090 def getvalue(self,name):
00091 """ Return the value of parameter 'name'
00092 """
00093 return self._parameters[name].value
00094 def description(self):
00095 """ Return a string with a detailed description of the action.
00096 """
00097 return self._description
00098
00099
00100
00101
00102 def addParameter(self,dict,parname, parvalue, description,Type=None, allowedValues=None, acceptNoneValue=False):
00103 """ Add a parameter with its label, value, description and type to self._parameters
00104 """
00105 par=parameter()
00106 par.name=parname
00107 par.value=parvalue
00108 par.description=description
00109 if Type==None:
00110 par.type=type(parvalue)
00111 else: par.type=Type
00112 par.allowedValues=allowedValues
00113 par.acceptNoneValue=acceptNoneValue
00114 dict[par.name]=par
00115 def getParameters(self):
00116 """ Return a copy of the dict of the parameters.
00117 """
00118 return copy.deepcopy(self._parameters)
00119 def setParameter(self, name, value, typeNone=False):
00120 """ Change parameter 'name' to a new value
00121 """
00122 self._parameters[name].value=value
00123
00124 self.typeError(name)
00125
00126 if self._defaultParameters[name].allowedValues is not None: self.isAllowed(name,value )
00127 def setParameters(self, parameters):
00128 self._parameters=copy.deepcopy(parameters)
00129
00130
00131
00132
00133
00134 def dumpPython(self):
00135 """ Return the python code to perform the action
00136 """
00137 dumpPythonImport = "\nfrom "+self._path+" import *\n"
00138 dumpPython=''
00139 if self._comment!="":
00140 dumpPython = '#'+self._comment
00141 dumpPython += "\n"+self._label+"(process "
00142 for key in self._parameters.keys():
00143 if str(self._parameters[key].value)!=str(self._defaultParameters[key].value):
00144 dumpPython+= ", "+str(key)+" = "
00145 if self._parameters[key].type is str:
00146 string = "'"+str(self.getvalue(key))+"'"
00147 else:
00148 string = str(self.getvalue(key))
00149 dumpPython+= string
00150 dumpPython+=")"+'\n'
00151 return (dumpPythonImport,dumpPython)
00152
00153 def setComment(self, comment):
00154 """ Write a comment in the configuration file
00155 """
00156 self._comment = str(comment)
00157 def comment(self):
00158 """ Return the comment set for this tool
00159 """
00160 return self._comment
00161 def errorMessage(self,value,type):
00162 return "The type for parameter "+'"'+str(value)+'"'+" is not "+'"'+str(type)+'"'
00163
00164 def isAllowed(self,name,value):
00165 self.parAccepted=True
00166 if value==[]:
00167 self.parAccepted=False
00168 elif (isinstance(value,dict)) and (isinstance(self._parameters[name].allowedValues,list)):
00169 for key in value.keys():
00170 if (key not in self._parameters[name].allowedValues):
00171 raise ValueError("The input key value "+'"'+str(key)+'"'+" for parameter "+'"'+name+'"'+" is not supported. Supported ones are: "+str(self._parameters[name].allowedValues))
00172 elif (isinstance(value,list)) and (isinstance(self._parameters[name].allowedValues,list )):
00173 for i in value:
00174 if (i not in self._parameters[name].allowedValues) :
00175 self.parAccepted=False
00176 elif (not isinstance(value,list))and (isinstance(self._parameters[name].allowedValues,list)) :
00177 if (value not in self._parameters[name].allowedValues and value == None) and (not self._parameters[name].acceptNoneValue) :
00178 self.parAccepted=False
00179 elif not isinstance(self._parameters[name].allowedValues,list):
00180 if (value!=self._parameters[name].allowedValues and value == None) and (not self._parameters[name].acceptNoneValue) :
00181 self.parAccepted=False
00182 if self.parAccepted==False:
00183 raise ValueError("The input value "+'"'+str(value)+'"'+" for parameter "+'"'+name+'"'+" is not supported. Supported ones are: "+str(self._parameters[name].allowedValues)[1:-1])
00184
00185 def typeError(self,name):
00186 if self._parameters[name].acceptNoneValue is False:
00187 if not isinstance(self._parameters[name].value,self._parameters[name].type):
00188 raise TypeError(self.errorMessage(self._parameters[name].value,self._parameters[name].type))
00189 else:
00190 if not (isinstance(self._parameters[name].value,self._parameters[name].type) or self._parameters[name].value is None):
00191 raise TypeError(self.errorMessage(self._parameters[name].value,self._parameters[name].type))
00192 def getAllowedValues(self,name):
00193 return self._defaultParameters[name].allowedValues