ParameterEnumerations
Parameter Enumerations
Currently, parameter values in VisTrails need to be fully specified by a user. This can be cumbersome, especially when these parameters are restricted to specific values. We propose to add a new "values" field to port specifications that allows users to specify a list of specific values. In addition, we add an "entry_type" field so users can specific if and how that list is used. Currently, the entry types are:
- free: any value can be specified
- enum: a value must be selected from the given list (a default is set)
- enumEmpty: a value may be selected from the given list, but may also be left unset
- enumFree: a value may be selected form the given list or any other value may be specified
For constants using the default widgets, these types are translated as follows:
- free: QLineEdit
- enum & enumEmpty: QComboBox
- enumFree: editable QComboBox (combines a QLineEdit and QComboBox)
Note that these entry types can be implemented in different ways by other constant configuration widgets. On the computation side, there is no difference between the different settings. The values are passed in their string representations.
In conjunction with the addition of parameter enumerations, we plan to make other information available to constant widgets, including default value settings. To do, we have converted PortSpec objects to mirror ModuleFunction objects and created a new PortSpecItem object to mirror ModuleParameter. Then, the param object that any constant configuration widget must accept now has a new attribute (port_spec_item) that contains the enumeration values, default value, and related ModuleDescriptor object. This way, developers can access the default value setting and initialize their widgets properly.
Default Values
In addition to displaying default values in widgets, we also propose to use these default values in getInputFromPort calls (with a new "allowDefault" parameter added to this call). Whenever a module requests a port's value, if the user has not set a value, we will look for a default value and return it instead. If there is no default, a ModuleError is raised as before. This unifies the default that is displayed with the one that is used in an implementation, and we suggest this method instead of using forceGetInputFromPort.
Sample Code
IMPORTANT: 'This does not work on current VisTrails distributions. It will probably first be enabled in verison 2.1.
class ModuleE(Module): _input_ports = [('b1', '(edu.utah.sci.vistrails.basic:String)', True), ('b2', '(edu.utah.sci.vistrails.basic:Integer)', {'max_conns': 1, 'shape': 'ellipse', 'entry_types': '["enum"]', 'values': '"123", "456", "789"'}), ('b3', '(edu.utah.sci.vistrails.basic:String)', {'min_conns': 1, 'shape': 'diamond', 'entry_types': '["enumFree"]', 'values': '"abc", "def", "ghi"'}), ('b4', '(edu.utah.sci.vistrails.basic:String)', {'shape': 'triangle0', 'entry_types': '["enum"]', 'values': '"abc", "def", "ghi"', 'defaults': '["def"]'}), ('b5', '(edu.utah.sci.vistrails.basic:String)', {'shape': 'triangle90', 'entry_types': '["enumFree"]', 'values': "123", "456", "789", 'defaults': '["234"]'}), ('b6', '(edu.utah.sci.vistrails.basic:String)', {'shape': 'triangle180', 'entry_types': '["enumFree"]', 'values': "123", "456", "789", 'defaults': ["456"]}), ('b7', '(edu.utah.sci.vistrails.basic:Integer, ' \ 'edu.utah.sci.vistrails.basic:String, ' 'edu.utah.sci.vistrails.basic:Float)', {'shape': 'triangle270', 'entry_types': ["enumEmpty", "enumEmpty", "enumEmpty"], 'values': [["1","2","3"], ["abc", "def", "ghi"], ["4.1", "4.2"]], # 'defaults': ["1", "def", "4.1"], 'labels': ["num", "alpha", "sec"]}), ('b8', '(edu.utah.sci.vistrails.basic:String)', {'shape': [(0,0.2), (0, 0.8), (0.2, None), (0.8, None), (None, 0.8), (None, 0.2), (0.8,0), (0.2, 0)], 'defaults': ["test"]})] _output_ports = [('b1', '(edu.utah.sci.vistrails.basic:String)'), ('b2', '(edu.utah.sci.vistrails.basic:Integer)', True)] def compute(self): for inputPort in ["b%d" % i for i in xrange(1,9)]: val = None try: val = self.getInputFromPort(inputPort) except: pass print inputPort, ":", val
Output:
b1 : None b2 : None b3 : None b4 : def b5 : 234 b6 : 456 b7 : None b8 : test