From VistrailsWiki
Jump to navigation Jump to search

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 developers to specify a list of values. In addition, we add an "entry_type" field so users can specify 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, ' \
                     {'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
                val = self.getInputFromPort(inputPort)
            print inputPort, ":", val


b1 : None
b2 : None
b3 : None
b4 : def
b5 : 234
b6 : 456
b7 : None
b8 : test