CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_10_patch2/src/FWCore/GuiBrowsers/python/ConfigToolBase.py

Go to the documentation of this file.
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 #### patches needed for deepcopy of sorted dicts ####
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 ### Base class for object oriented designed tools
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         #self._path = "".join(self._path)
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     ### __copy__(self) returns a copy of the tool
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     ### use addParameter method in the redefinition of tool constructor in order to add parameters to the tools
00100     ### each tool is defined by its label, default value, description, type and allowedValues (the last two attribute can be ignored
00101     ### if the user gives a valid default values and if there is not a list of allowed values)
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         ### check about input value type 
00124         self.typeError(name)
00125         ### check about input value (it works if allowedValues for the specific parameter is set)
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     #def dumpPython(self):
00130      #   """ Return the python code to perform the action
00131      #   """
00132      #   raise NotImplementedError
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     ### method isAllowed is called by setParameter to check input values for a specific parameter
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     ### check about input value type        
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