commit/galaxy-central: jgoecks: Use Trackster as an entry point for parameter space visualization. Current viewing area, bookmarks, or both can be used as regions in parameter space visualization. Also handle multiple intervals well.
1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/changeset/29abb6c4b296/ changeset: 29abb6c4b296 user: jgoecks date: 2012-06-29 23:57:40 summary: Use Trackster as an entry point for parameter space visualization. Current viewing area, bookmarks, or both can be used as regions in parameter space visualization. Also handle multiple intervals well. affected #: 10 files diff -r cc5fea2e382ed8edadf0d694f559b46e86a66884 -r 29abb6c4b296815594c93cd8d72944628160145c lib/galaxy/web/api/tools.py --- a/lib/galaxy/web/api/tools.py +++ b/lib/galaxy/web/api/tools.py @@ -141,6 +141,39 @@ elif isinstance( regions, list ): # There is a list of regions. regions = [ GenomeRegion.from_dict( r ) for r in regions ] + + # Sort by chrom name, start so that data is not fetched out of order. + regions.sort( key=lambda r: r.chrom ) + regions.sort( key=lambda r: r.start ) + + # Merge overlapping regions so that regions do not overlap + # and hence data is not included multiple times. + print "REGIONS", regions + for region in regions: + print "\t", region.chrom, region.start, region.end + prev = regions[0] + cur = regions[1] + index = 1 + while True: + if cur.start <= prev.end: + # Found overlapping regions, so join them. + prev.end = cur.end + del regions[ index ] + else: + # No overlap, move to next region. + prev = cur + index += 1 + + # Get next region or exit. + if index == len( regions ): + # Done. + break + else: + cur = regions[ index ] + + print "REGIONS", regions + for region in regions: + print "\t", region.chrom, region.start, region.end run_on_regions = True # Dataset check. diff -r cc5fea2e382ed8edadf0d694f559b46e86a66884 -r 29abb6c4b296815594c93cd8d72944628160145c lib/galaxy/web/controllers/tracks.py --- a/lib/galaxy/web/controllers/tracks.py +++ b/lib/galaxy/web/controllers/tracks.py @@ -484,22 +484,8 @@ viz_config = { 'dataset_id': dataset_id, 'tool_id': job.tool_id, - 'regions': regions + 'regions': from_json_string( regions ) } - - viz_config[ 'regions' ] = [ - { - 'chrom': 'chr19', - 'start': '10000', - 'end': '26000' - }, - { - 'chrom': 'chr19', - 'start': '150000', - 'end': '175000' - } - - ] # Add tool, dataset attributes to config based on id. tool = trans.app.toolbox.get_tool( viz_config[ 'tool_id' ] ) diff -r cc5fea2e382ed8edadf0d694f559b46e86a66884 -r 29abb6c4b296815594c93cd8d72944628160145c static/images/fugue/arrow-split-bw.png Binary file static/images/fugue/arrow-split-bw.png has changed diff -r cc5fea2e382ed8edadf0d694f559b46e86a66884 -r 29abb6c4b296815594c93cd8d72944628160145c static/images/fugue/arrow-split.png Binary file static/images/fugue/arrow-split.png has changed diff -r cc5fea2e382ed8edadf0d694f559b46e86a66884 -r 29abb6c4b296815594c93cd8d72944628160145c static/june_2007_style/base_sprites.less.tmpl --- a/static/june_2007_style/base_sprites.less.tmpl +++ b/static/june_2007_style/base_sprites.less.tmpl @@ -122,6 +122,14 @@ -sprite-group: fugue; -sprite-image: fugue/cross-circle.png; } +.icon-button.arrow-split { + -sprite-group: fugue; + -sprite-image: fugue/arrow-split-bw.png; +} +.icon-button.arrow-split:hover { + -sprite-group: fugue; + -sprite-image: fugue/arrow-split.png; +} .text-and-autocomplete-select { -sprite-group: fugue; -sprite-image: fugue/control-270.png; diff -r cc5fea2e382ed8edadf0d694f559b46e86a66884 -r 29abb6c4b296815594c93cd8d72944628160145c static/june_2007_style/blue/base.css --- a/static/june_2007_style/blue/base.css +++ b/static/june_2007_style/blue/base.css @@ -759,7 +759,9 @@ .icon-button.disk--arrow:hover{background:url(fugue.png) no-repeat 0px -494px;} .icon-button.cross-circle{background:url(fugue.png) no-repeat 0px -520px;} .icon-button.cross-circle:hover{background:url(fugue.png) no-repeat 0px -546px;} -.text-and-autocomplete-select{background:url(fugue.png) no-repeat right -572px;} +.icon-button.arrow-split{background:url(fugue.png) no-repeat 0px -572px;} +.icon-button.arrow-split:hover{background:url(fugue.png) no-repeat 0px -598px;} +.text-and-autocomplete-select{background:url(fugue.png) no-repeat right -624px;} div.historyItem-error .state-icon{background:url(history-states.png) no-repeat 0px 0px;} div.historyItem-empty .state-icon{background:url(history-states.png) no-repeat 0px -25px;} div.historyItem-queued .state-icon{background:url(history-states.png) no-repeat 0px -50px;} diff -r cc5fea2e382ed8edadf0d694f559b46e86a66884 -r 29abb6c4b296815594c93cd8d72944628160145c static/june_2007_style/blue/fugue.png Binary file static/june_2007_style/blue/fugue.png has changed diff -r cc5fea2e382ed8edadf0d694f559b46e86a66884 -r 29abb6c4b296815594c93cd8d72944628160145c static/scripts/viz/trackster.js --- a/static/scripts/viz/trackster.js +++ b/static/scripts/viz/trackster.js @@ -838,11 +838,11 @@ // /// All tracks the same? - var drawable, + var i, j, drawable, same_type = true, a_type = this.drawables[0].get_type(), num_feature_tracks = 0; - for (var i = 0; i < num_drawables; i++) { + for (i = 0; i < num_drawables; i++) { drawable = this.drawables[i]; if (drawable.get_type() !== a_type) { can_composite = false; @@ -868,21 +868,20 @@ // // Find shared filters. // - var - shared_filters = {}, + var shared_filters = {}, filter; // Init shared filters with filters from first drawable. drawable = this.drawables[0]; - for (var j = 0; j < drawable.filters_manager.filters.length; j++) { + for (j = 0; j < drawable.filters_manager.filters.length; j++) { filter = drawable.filters_manager.filters[j]; shared_filters[filter.name] = [filter]; } // Create lists of shared filters. - for (var i = 1; i < this.drawables.length; i++) { + for (i = 1; i < this.drawables.length; i++) { drawable = this.drawables[i]; - for (var j = 0; j < drawable.filters_manager.filters.length; j++) { + for (j = 0; j < drawable.filters_manager.filters.length; j++) { filter = drawable.filters_manager.filters[j]; if (filter.name in shared_filters) { shared_filters[filter.name].push(filter); @@ -1278,8 +1277,8 @@ * Load chrom data for the view. Returns a jQuery Deferred. */ load_chroms: function(url_parms) { - url_parms['num'] = MAX_CHROMS_SELECTABLE; - url_parms['dbkey'] = this.dbkey; + url_parms.num = MAX_CHROMS_SELECTABLE; + url_parms.dbkey = this.dbkey; var view = this, @@ -1729,7 +1728,6 @@ var run_tool_row = $("<div>").addClass("param-row").appendTo(this.parent_div); var run_on_dataset_button = $("<input type='submit'>").attr("value", "Run on complete dataset").appendTo(run_tool_row); var run_on_region_button = $("<input type='submit'>").attr("value", "Run on visible region").css("margin-left", "3em").appendTo(run_tool_row); - var tool = this; run_on_region_button.click( function() { // Run tool to create new track. tool.run_on_region(); @@ -2413,14 +2411,14 @@ filter = this.filters[i]; filter_dicts.push(filter.to_dict()); } - obj_dict['filters'] = filter_dicts; + obj_dict.filters = filter_dicts; // Include transparency, height filters. - obj_dict['alpha_filter'] = (this.alpha_filter ? this.alpha_filter.name : null); - obj_dict['height_filter'] = (this.height_filter ? this.height_filter.name : null); + obj_dict.alpha_filter = (this.alpha_filter ? this.alpha_filter.name : null); + obj_dict.height_filter = (this.height_filter ? this.height_filter.name : null); // Include visibility. - obj_dict['visible'] = this.parent_div.is(":visible"); + obj_dict.visible = this.parent_div.is(":visible"); return obj_dict; }, @@ -3028,6 +3026,76 @@ $(".tipsy").remove(); } }, + // Go to parameter exploration visualization. + { + name: "param_space_viz_icon", + title: "Tool parameter space visualization", + css_class: "arrow-split", + on_click_fn: function(track) { + var template = + '<strong>Tool</strong>: <%= track.tool.name %><br/>' + + '<strong>Dataset</strong>: <%= track.name %><br/>' + + '<strong>Region(s)</strong>: <select name="regions">' + + '<option value="cur">current viewing area</option>' + + '<option value="bookmarks">bookmarks</option>' + + '<option value="both">current viewing area and bookmarks</option>' + + '</select>', + html = _.template(template, { track: track }); + var cancel_fn = function() { hide_modal(); $(window).unbind("keypress.check_enter_esc"); }, + ok_fn = function() { + var regions_to_use = $('select[name="regions"] option:selected').val(), + regions, + view_region = new GenomeRegion({ + chrom: view.chrom, + start: view.low, + end: view.high + }), + bookmarked_regions = _.map($(".bookmark"), function(elt) { + return new GenomeRegion({from_str: $(elt).children(".position").text()}); + }); + + console.log(regions_to_use); + + // Get regions for visualization. + if (regions_to_use === 'cur') { + // Use only current region. + regions = [ view_region ]; + } + else if (regions_to_use === 'bookmarks') { + // Use only bookmarks. + regions = new Backbone.Collection(bookmarked_regions); + } + else { + // Use both current region and bookmarks. + regions = new Backbone.Collection([ view_region ].concat(bookmarked_regions)); + } + + hide_modal(); + + // Go to visualization. + window.location.href = + galaxy_paths.get('paramamonster_url') + "?" + + $.param({ + dataset_id: track.dataset_id, + hda_ldda: track.hda_ldda, + regions: JSON.stringify(regions.toJSON()) + }); + }, + check_enter_esc = function(e) { + if ((e.keyCode || e.which) === 27) { // Escape key + cancel_fn(); + } else if ((e.keyCode || e.which) === 13) { // Enter key + ok_fn(); + } + }; + + show_modal("Visualize tool parameter space and output from different parameter settings?", html, { + "No": cancel_fn, + "Yes": ok_fn + }); + + } + }, // Remove track. Drawable.prototype.action_icons_def[2] ], @@ -3379,13 +3447,15 @@ } // - // Show/hide tool icon. + // Show/hide tool icons. // if (track.tool) { track.action_icons.tools_icon.show(); + track.action_icons.param_space_viz_icon.show(); } else { track.action_icons.tools_icon.hide(); + track.action_icons.param_space_viz_icon.hide(); } // @@ -3856,6 +3926,7 @@ // For now, hide filters and tool. this.action_icons.filters_icon.hide(); this.action_icons.tools_icon.hide(); + this.action_icons.param_space_viz_icon.hide(); }, can_draw: Drawable.prototype.can_draw, draw_helper: function(force, width, tile_index, resolution, parent_element, w_scale, kwargs) { @@ -4341,6 +4412,7 @@ } this.tiles_div.css("height", track_height + "px"); }, + /** * Actions to be taken after draw has been completed. Draw is completed when all tiles have been * drawn/fetched and shown. @@ -4353,15 +4425,15 @@ // If mode is Histogram and tiles do not share max, redraw tiles as necessary using new max. if (track.mode === "Histogram") { // Get global max. - var global_max = -1; - for (var i = 0; i < tiles.length; i++) { + var i, global_max = -1; + for (i = 0; i < tiles.length; i++) { var cur_max = tiles[i].max_val; if (cur_max > global_max) { global_max = cur_max; } } - for (var i = 0; i < tiles.length; i++) { + for (i = 0; i < tiles.length; i++) { var tile = tiles[i]; if (tile.max_val !== global_max) { tile.html_elt.remove(); @@ -4477,7 +4549,7 @@ var dummy_context = this.view.canvas_manager.dummy_context, slotter = this.slotters[level]; if (!slotter || (slotter.mode !== mode)) { - slotter = new (slotting.FeatureSlotter)( level, mode, MAX_FEATURE_DEPTH, function ( x ) { return dummy_context.measureText( x ) } ); + slotter = new (slotting.FeatureSlotter)( level, mode, MAX_FEATURE_DEPTH, function ( x ) { return dummy_context.measureText( x ); } ); this.slotters[level] = slotter; } @@ -4726,7 +4798,7 @@ } return true; - }, + } }); var VcfTrack = function(view, container, obj_dict) { @@ -4740,7 +4812,7 @@ { key: 'label_color', label: 'Label color', type: 'color', default_value: 'black' }, { key: 'show_insertions', label: 'Show insertions', type: 'bool', default_value: false }, { key: 'show_counts', label: 'Show summary counts', type: 'bool', default_value: true }, - { key: 'mode', type: 'string', default_value: this.mode, hidden: true }, + { key: 'mode', type: 'string', default_value: this.mode, hidden: true } ], saved_values: obj_dict.prefs, onchange: function() { @@ -4773,7 +4845,7 @@ { key: 'show_differences', label: 'Show differences only', type: 'bool', default_value: true }, { key: 'show_counts', label: 'Show summary counts', type: 'bool', default_value: true }, { key: 'histogram_max', label: 'Histogram maximum', type: 'float', default_value: null, help: 'Clear value to set automatically' }, - { key: 'mode', type: 'string', default_value: this.mode, hidden: true }, + { key: 'mode', type: 'string', default_value: this.mode, hidden: true } ], saved_values: obj_dict.prefs, onchange: function() { diff -r cc5fea2e382ed8edadf0d694f559b46e86a66884 -r 29abb6c4b296815594c93cd8d72944628160145c static/scripts/viz/visualization.js --- a/static/scripts/viz/visualization.js +++ b/static/scripts/viz/visualization.js @@ -269,7 +269,7 @@ obj_cache = this.get('obj_cache'), key, entry_region; for (var i = 0; i < key_ary.length; i++) { - entry_region = new GenomeRegion(key_ary[i]); + entry_region = new GenomeRegion({from_str: key_ary[i]}); if (entry_region.contains(region)) { // This entry has data in the requested range. Return if data @@ -420,20 +420,19 @@ }, /** - * If options is a string, parsing using the format - * chrom:start-end is attempted to set object attributes. + * If from_str specified, use it to initialize attributes. */ initialize: function(options) { - if (typeof(options) === 'string') { - var pieces = options.split(':'), + if (options.from_str) { + var pieces = options.from_str.split(':'), chrom = pieces[0], start_end = pieces[1].split('-'); this.set({ chrom: chrom, - start: parseInt(start_end[0]), - end: parseInt(start_end[1]) + start: parseInt(start_end[0], 10), + end: parseInt(start_end[1], 10) }); - } + } }, copy: function() { @@ -552,7 +551,12 @@ datasets: [] }, - url: galaxy_paths.get("visualization_url"), + // Use function because visualization_url changes depending on viz. + // FIXME: all visualizations should save to the same URL (and hence + // this function won't be needed). + url: function() { + return galaxy_paths.get("visualization_url"); + }, /** * POSTs visualization's JSON to its URL using the parameter 'vis_json' @@ -561,7 +565,7 @@ */ save: function() { return $.ajax({ - url: this.url, + url: this.url(), type: "POST", dataType: "json", data: { diff -r cc5fea2e382ed8edadf0d694f559b46e86a66884 -r 29abb6c4b296815594c93cd8d72944628160145c templates/tracks/browser.mako --- a/templates/tracks/browser.mako +++ b/templates/tracks/browser.mako @@ -49,7 +49,8 @@ // Place URLs here so that url_for can be used to generate them. // galaxy_paths.set({ - visualization_url: "${h.url_for( action='save' )}" + visualization_url: "${h.url_for( action='save' )}", + paramamonster_url: "${h.url_for( action='paramamonster' )}", }); var add_track_async_url = "${h.url_for( action='add_track_async' )}", @@ -141,10 +142,10 @@ // Save bookmarks. var bookmarks = []; $(".bookmark").each(function() { - bookmarks[bookmarks.length] = { + bookmarks.push({ position: $(this).children(".position").text(), annotation: $(this).children(".annotation").text() - }; + }); }); // FIXME: give unique IDs to Drawables and save overview as ID. 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)
-
Bitbucket