commit/galaxy-central: jgoecks: Tools and visual analytics: (a) add tool parameter types to client-side code and automatically unpack tools; (b) update Sweepster to work with recent tool parameter enhancements; and (c) fix additional warts.
1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/5b4c4cf9bc96/ Changeset: 5b4c4cf9bc96 User: jgoecks Date: 2013-08-23 22:09:22 Summary: Tools and visual analytics: (a) add tool parameter types to client-side code and automatically unpack tools; (b) update Sweepster to work with recent tool parameter enhancements; and (c) fix additional warts. Affected #: 6 files diff -r ab74f2d8017306fb909778aafcd51b78b24e3e56 -r 5b4c4cf9bc9619d51d7f2471d64896dcdd93707c lib/galaxy/tools/parameters/basic.py --- a/lib/galaxy/tools/parameters/basic.py +++ b/lib/galaxy/tools/parameters/basic.py @@ -236,7 +236,7 @@ ValueError: An integer is required """ - dict_colletion_visible_keys = ToolParameter.dict_collection_visible_keys + ( 'min', 'max' ) + dict_collection_visible_keys = ToolParameter.dict_collection_visible_keys + ( 'min', 'max' ) def __init__( self, tool, elem ): TextToolParameter.__init__( self, tool, elem ) @@ -251,12 +251,12 @@ self.max = elem.get( 'max' ) if self.min: try: - int( self.min ) + self.min = int( self.min ) except: raise ValueError( "An integer is required" ) if self.max: try: - int( self.max ) + self.max = int( self.max ) except: raise ValueError( "An integer is required" ) if self.min and self.max: diff -r ab74f2d8017306fb909778aafcd51b78b24e3e56 -r 5b4c4cf9bc9619d51d7f2471d64896dcdd93707c lib/galaxy/web/base/controller.py --- a/lib/galaxy/web/base/controller.py +++ b/lib/galaxy/web/base/controller.py @@ -37,7 +37,7 @@ from galaxy.datatypes.interval import ChromatinInteractions from galaxy.datatypes.data import Text -from galaxy.model import ExtendedMetadata, ExtendedMetadataIndex, LibraryDatasetDatasetAssociation,HistoryDatasetAssociation +from galaxy.model import ExtendedMetadata, ExtendedMetadataIndex, LibraryDatasetDatasetAssociation from galaxy.datatypes.display_applications import util as da_util from galaxy.datatypes.metadata import FileParameter diff -r ab74f2d8017306fb909778aafcd51b78b24e3e56 -r 5b4c4cf9bc9619d51d7f2471d64896dcdd93707c lib/galaxy/webapps/galaxy/controllers/visualization.py --- a/lib/galaxy/webapps/galaxy/controllers/visualization.py +++ b/lib/galaxy/webapps/galaxy/controllers/visualization.py @@ -873,8 +873,8 @@ # Add tool, dataset attributes to config based on id. tool = trans.app.toolbox.get_tool( viz_config[ 'tool_id' ] ) - viz_config[ 'tool' ] = tool.dictify( trans, for_display=True ) - viz_config[ 'dataset' ] = dataset.dictify() + viz_config[ 'tool' ] = tool.dictify( trans, io_details=True ) + viz_config[ 'dataset' ] = trans.security.encode_dict_ids( dataset.dictify() ) return trans.fill_template_mako( "visualization/sweepster.mako", config=viz_config ) diff -r ab74f2d8017306fb909778aafcd51b78b24e3e56 -r 5b4c4cf9bc9619d51d7f2471d64896dcdd93707c static/scripts/mvc/tools.js --- a/static/scripts/mvc/tools.js +++ b/static/scripts/mvc/tools.js @@ -1,16 +1,12 @@ /** * Model, view, and controller objects for Galaxy tools and tool panel. - * - * Models have no references to views, instead using events to indicate state - * changes; this is advantageous because multiple views can use the same object - * and models can be used without views. */ define( ["libs/underscore", "viz/trackster/util", "mvc/data", "libs/backbone/backbone-relational" ], function(_, util, data) { /** - * Mixin to enable model to track visibility. + * Mixin for tracking model visibility. */ var VisibilityMixin = { hidden: false, @@ -41,6 +37,13 @@ html: null, num_samples: 5 }, + + subModelTypes: { + 'integer': 'IntegerToolParameter', + 'float': 'FloatToolParameter', + 'data': 'DataToolParameter', + 'select': 'SelectToolParameter' + }, initialize: function() { this.attributes.html = unescape(this.attributes.html); @@ -49,69 +52,57 @@ copy: function() { return new ToolParameter(this.toJSON()); }, - + + set_value: function(value) { + this.set('value', value || ''); + } +}); + +// In order to resolve subModelTypes for tool parameters, use a custom scope here rather +// than polluting the global scope. +var tools_scope = {}; +Backbone.Relational.store.addModelScope(tools_scope); + +/** + * A data tool parameter. + */ +var DataToolParameter = tools_scope.DataToolParameter = ToolParameter.extend({}); + +/** + * An integer tool parameter. + */ +var IntegerToolParameter = tools_scope.IntegerToolParameter = ToolParameter.extend({ + set_value: function(value) { + this.set('value', parseInt(value, 10)); + }, + /** * Returns samples from a tool input. */ get_samples: function() { - var type = this.get('type'), - samples = null; - if (type === 'number') { - samples = d3.scale.linear() + return d3.scale.linear() .domain([this.get('min'), this.get('max')]) .ticks(this.get('num_samples')); - } - else if (type === 'select') { - samples = _.map(this.get('options'), function(option) { - return option[0]; - }); - } - - return samples; - }, - - set_value: function(value) { - this.set('value', value || ''); - } -}, -{ - /** - * Dictionary mapping parameter type strings to parameter classes. - */ - TYPE_DICT: { - 'number': IntegerToolParameter - }, - - /** - * Create new parameter from a dictionary. - */ - create: function(options) { - var param_class = ToolParameter.TYPE_DICT[options.type] || ToolParameter; - return new param_class(options); } }); -/** - * A number tool parameter. +var FloatToolParameter = tools_scope.FloatToolParameter = IntegerToolParameter.extend({ + set_value: function(value) { + this.set('value', parseFloat(value)); + } +}); + +/** + * A select tool parameter. */ -var IntegerToolParameter = ToolParameter.extend({ - defaults: _.extend({}, ToolParameter.prototype.defaults, { - min: null, - max: null - }), - - initialize: function() { - ToolParameter.prototype.initialize.call(this); - if (this.attributes.min) { - this.attributes.min = parseInt(this.attributes.min, 10); - } - if (this.attributes.max) { - this.attributes.max = parseInt(this.attributes.max, 10); - } - }, - - set_value: function(value) { - this.set('value', parseInt(value, 10)) +var SelectToolParameter = tools_scope.SelectToolParameter = ToolParameter.extend({ + /** + * Returns tool options. + */ + get_samples: function() { + return _.map(this.get('options'), function(option) { + return option[0]; + }); } }); @@ -125,21 +116,32 @@ name: null, description: null, target: null, - inputs: [] + inputs: [], + outputs: [] }, - initialize: function(options) { - // Unpack parameters manually so that different parameter types can be created. - this.attributes.inputs = new Backbone.Collection( _.map(options.inputs, function(param_dict) { - // FIXME: it is still useful to be able to save/restore tool state? - // Update parameter value from tool state dict. - //param_dict.value = tool_state_dict[ param_dict[name] ] || param_dict.value; - return ToolParameter.create(param_dict); - })); + relations: [ + { + type: Backbone.HasMany, + key: 'inputs', + relatedModel: ToolParameter + } + ], + + urlRoot: galaxy_config.root + 'api/tools', + + /** + * Removes inputs of a particular type; this is useful because not all inputs can be handled by + * client and server yet. + */ + remove_inputs: function(types) { + var tool = this, + incompatible_inputs = tool.get('inputs').filter( function(input) { + return ( types.indexOf( input.get('type') ) !== -1); + }); + tool.get('inputs').remove(incompatible_inputs); }, - urlRoot: galaxy_config.root + 'api/tools', - /** * Returns object copy, optionally including only inputs that can be sampled. */ @@ -735,6 +737,7 @@ return { ToolParameter: ToolParameter, IntegerToolParameter: IntegerToolParameter, + SelectToolParameter: SelectToolParameter, Tool: Tool, ToolCollection: ToolCollection, ToolSearch: ToolSearch, diff -r ab74f2d8017306fb909778aafcd51b78b24e3e56 -r 5b4c4cf9bc9619d51d7f2471d64896dcdd93707c static/scripts/viz/sweepster.js --- a/static/scripts/viz/sweepster.js +++ b/static/scripts/viz/sweepster.js @@ -30,8 +30,6 @@ // Set up tool parameters to work with tree. var self = this; this.get('tool').get('inputs').each(function(input) { - if (!input.get_samples()) { return; } - // Listen for changes to input's attributes. input.on('change:min change:max change:num_samples', function(input) { if (input.get('in_ptree')) { @@ -270,8 +268,8 @@ if (options.track) { // FIXME: find a better way to deal with needed URLs: var track_config = _.extend({ - data_url: galaxy_paths.get('raw_data_url'), - converted_datasets_state_url: galaxy_paths.get('dataset_state_url') + data_url: galaxy_config.root + 'dummy1', + converted_datasets_state_url: galaxy_config.root + 'dummy2' }, options.track); this.set('track', tracks.object_from_template(track_config, {}, null)); } @@ -340,8 +338,10 @@ ], initialize: function(options) { - var tool_with_samplable_inputs = this.get('tool').copy(true); + var tool_with_samplable_inputs = this.get('tool'); this.set('tool_with_samplable_inputs', tool_with_samplable_inputs); + // Remove complex parameters for now. + tool_with_samplable_inputs.remove_inputs( [ 'data', 'hidden_data', 'conditional' ] ); this.set('parameter_tree', new ToolParameterTree({ tool: tool_with_samplable_inputs, @@ -425,7 +425,7 @@ // Render tile placeholders. this.model.get('regions').each(function() { self.$el.append($('<td/>').addClass('tile').html( - $('<img/>').attr('src', galaxy_paths.get('image_path') + '/loading_large_white_bg.gif') + $('<img/>').attr('src', galaxy_config.root + 'images/loading_large_white_bg.gif') )); }); @@ -497,10 +497,10 @@ }); // Add row for parameter sweep inputs. - if (type === 'number') { + if (input instanceof tools.IntegerToolParameter) { sweep_inputs_row = $(_.template(this.number_input_template, this.model.toJSON())); } - else if (type === 'select') { + else if (input instanceof tools.SelectToolParameter) { var options = _.map(this.$el.find('select option'), function(option) { return $(option).val(); }), @@ -918,19 +918,18 @@ _.each(new_tracks, function(pm_track, index) { setTimeout(function() { // Set inputs and run tool. - // console.log('running with settings', pm_track.get('settings')); tool.set_input_values(pm_track.get('settings').get('values')); $.when(tool.rerun(dataset, regions)).then(function(output) { + // HACK: output is an HDA with track config attribute. To create a track, rearrange + // track config to point to HDA. + var dataset = output.first(), + track_config = dataset.get('track_config'); + track_config.dataset = dataset; + // Create and add track for output dataset. - var track_config = _.extend({ - data_url: galaxy_paths.get('raw_data_url'), - converted_datasets_state_url: galaxy_paths.get('dataset_state_url') - }, output.first().get('track_config')), - track_obj = tracks.object_from_template(track_config, self, null); - - // Track uses raw data. - track_obj.data_manager.set('data_type', 'raw_data'); - + var track_obj = tracks.object_from_template(track_config, self, null); + track_obj.init_for_tool_data(); + // Set track block colors. track_obj.prefs.block_color = self.block_color; track_obj.prefs.reverse_strand_color = self.reverse_strand_color; diff -r ab74f2d8017306fb909778aafcd51b78b24e3e56 -r 5b4c4cf9bc9619d51d7f2471d64896dcdd93707c static/scripts/viz/trackster/tracks.js --- a/static/scripts/viz/trackster/tracks.js +++ b/static/scripts/viz/trackster/tracks.js @@ -919,7 +919,7 @@ { key: 'c_color', label: 'C Color', type: 'color', default_value: "#00FF00" }, { key: 'g_color', label: 'G Color', type: 'color', default_value: "#0000FF" }, { key: 't_color', label: 'T Color', type: 'color', default_value: "#FF00FF" }, - { key: 'n_color', label: 'N Color', type: 'color', default_value: "#AAAAAA" }, + { key: 'n_color', label: 'N Color', type: 'color', default_value: "#AAAAAA" } ], saved_values: obj_dict.prefs, onchange: function() { @@ -1393,7 +1393,7 @@ // // Redraw without requesting more data immediately. - view.request_redraw({ data_fetch: false }) + view.request_redraw({ data_fetch: false }); // Set up timeout to redraw with more data when moving stops. if (this.redraw_on_move_fn) { @@ -1637,15 +1637,11 @@ ], initialize: function(options) { - // HACK: remove data and group tool inputs because Trackster - // does not work with them right now. - var tool = this.get('tool'), - incompatible_inputs = tool.get('inputs').filter( function(input) { - return ( [ 'data', 'hidden_data', 'group'].indexOf( input.get('type') ) !== -1); - }); - tool.get('inputs').remove(incompatible_inputs); + // HACK: remove some inputs because Trackster does yet not work with them. + this.get('tool').remove_inputs( [ 'data', 'hidden_data', 'conditional' ] ); + + // FIXME: need to restore tool values/visibility. } - }); /** @@ -2320,8 +2316,12 @@ // Attribute init. // - // Only create dataset if it is defined. - this.dataset = (obj_dict.dataset ? new data.Dataset(obj_dict.dataset) : null); + // Set or create dataset. + this.dataset = null; + if (obj_dict.dataset) { + // Dataset can be a Backbone model or a dict that can be used to create a model. + this.dataset = (obj_dict.dataset instanceof Backbone.Model ? obj_dict.dataset : new data.Dataset(obj_dict.dataset) ); + } this.dataset_check_type = 'converted_datasets_state'; this.data_url_extra_params = {}; this.data_query_wait = ('data_query_wait' in obj_dict ? obj_dict.data_query_wait : DEFAULT_DATA_QUERY_WAIT); @@ -3452,9 +3452,13 @@ this.data_query_wait = 1000; this.dataset_check_type = 'state'; + // FIXME: this is optional and is disabled for now because it creates + // additional converter jobs without a clear benefit because indexing + // such a small dataset provides little benefit. // // Set up one-time, post-draw to clear tool execution settings. // + /* this.normal_postdraw_actions = this.postdraw_actions; this.postdraw_actions = function(tiles, width, w_scale, clear_after) { var self = this; @@ -3484,6 +3488,7 @@ // Reset post-draw actions function. self.postdraw_actions = self.normal_postdraw_actions; }; + */ } }); Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.
participants (1)
-
commits-noreply@bitbucket.org