CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/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             dumpPython+= ", "
00144             if self._parameters[key].type is str:
00145                 string = "'"+str(self.getvalue(key))+"'"
00146             else:
00147                 string = str(self.getvalue(key))
00148             dumpPython+= string
00149         dumpPython+=")"+'\n'
00150         return (dumpPythonImport,dumpPython)
00151     
00152     def setComment(self, comment):
00153         """ Write a comment in the configuration file
00154         """
00155         self._comment = str(comment)
00156     def comment(self):
00157         """ Return the comment set for this tool
00158         """
00159         return self._comment
00160     def errorMessage(self,value,type):
00161         return "The type for parameter "+'"'+str(value)+'"'+" is not "+'"'+str(type)+'"'
00162     ### method isAllowed is called by setParameter to check input values for a specific parameter
00163     def isAllowed(self,name,value):
00164         self.parAccepted=True
00165         if value==[]:
00166             self.parAccepted=False
00167         elif (isinstance(value,dict)) and (isinstance(self._parameters[name].allowedValues,list)):
00168             for key in value.keys():
00169                 if (key not in self._parameters[name].allowedValues):
00170                     raise ValueError("The input key value "+'"'+str(key)+'"'+" for parameter "+'"'+name+'"'+" is not supported. Supported ones are: "+str(self._parameters[name].allowedValues))
00171         elif (isinstance(value,list)) and (isinstance(self._parameters[name].allowedValues,list )):
00172             for i in value:
00173                 if (i not in self._parameters[name].allowedValues) :
00174                     self.parAccepted=False
00175         elif (not isinstance(value,list))and (isinstance(self._parameters[name].allowedValues,list)) :
00176             if (value not in self._parameters[name].allowedValues and value == None) and (not self._parameters[name].acceptNoneValue) :
00177                 self.parAccepted=False
00178         elif not isinstance(self._parameters[name].allowedValues,list):
00179             if (value!=self._parameters[name].allowedValues and value == None) and (not self._parameters[name].acceptNoneValue) :
00180                 self.parAccepted=False  
00181         if self.parAccepted==False:
00182             raise ValueError("The input value "+'"'+str(value)+'"'+" for parameter "+'"'+name+'"'+" is not supported. Supported ones are: "+str(self._parameters[name].allowedValues)[1:-1])
00183     ### check about input value type        
00184     def typeError(self,name):
00185         if self._parameters[name].acceptNoneValue is False:
00186             if not isinstance(self._parameters[name].value,self._parameters[name].type):
00187                 raise TypeError(self.errorMessage(self._parameters[name].value,self._parameters[name].type))
00188         else:
00189             if not (isinstance(self._parameters[name].value,self._parameters[name].type) or self._parameters[name].value is  None):
00190                 raise TypeError(self.errorMessage(self._parameters[name].value,self._parameters[name].type))
00191     def getAllowedValues(self,name):
00192         return self._defaultParameters[name].allowedValues