mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
trackster: Add bigWig display to trackster. Automatically converts wig to bigwig if needed (NOTE: datatypes_conf.xml.sample has been edited to add the new converter, you must update datatypes_conf.xml to use it). The converter requires that wigToBigWig be in the PATH, but no other tools are needed to view bigwig files as they are provided by bx_python.
- Fix track preferences not being applied - Fix chroms not being selectable when a new track browser is created - Fix ReferenceTrack not working with filters - Fix visual analytics error when tool configuration has changed
This commit is contained in:
@@ -121,6 +121,7 @@
|
||||
</datatype>
|
||||
<datatype extension="velvet" type="galaxy.datatypes.assembly:Velvet" display_in_upload="false"/>
|
||||
<datatype extension="wig" type="galaxy.datatypes.interval:Wiggle" display_in_upload="true">
|
||||
<converter file="wig_to_bigwig_converter.xml" target_datatype="bigwig"/>
|
||||
<converter file="wiggle_to_array_tree_converter.xml" target_datatype="array_tree"/>
|
||||
<converter file="wiggle_to_simple_converter.xml" target_datatype="interval"/>
|
||||
<!-- <display file="gbrowse/gbrowse_wig.xml" /> -->
|
||||
|
||||
@@ -12,7 +12,7 @@ repository = http://eggs.g2.bx.psu.edu/new
|
||||
no_auto = pbs_python DRMAA_python
|
||||
|
||||
[eggs:platform]
|
||||
bx_python = 0.5.0
|
||||
bx_python = 0.7.0
|
||||
Cheetah = 2.2.2
|
||||
ctypes = 1.0.2
|
||||
DRMAA_python = 0.2
|
||||
@@ -65,7 +65,7 @@ Whoosh = 0.3.18
|
||||
psycopg2 = _8.4.2_static
|
||||
pysqlite = _3.6.17_static
|
||||
MySQL_python = _5.1.41_static
|
||||
bx_python = _dev_f74aec067563
|
||||
bx_python = _14b6a6c95da6
|
||||
GeneTrack = _dev_48da9e998f0caf01c5be731e926f4b0481f658f0
|
||||
SQLAlchemy = _dev_r6498
|
||||
pysam = _kanwei_90e03180969d
|
||||
|
||||
@@ -230,6 +230,8 @@ class BigWig(Binary):
|
||||
return dataset.peek
|
||||
except:
|
||||
return "Binary UCSC %s file (%s)" % ( self._name, data.nice_size( dataset.get_size() ) )
|
||||
def get_track_type( self ):
|
||||
return "LineTrack", {"data_standalone": "bigwig"}
|
||||
|
||||
class BigBed(BigWig):
|
||||
"""BigBed support from UCSC."""
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<tool id="CONVERTER_wig_to_bigwig" name="wig->bigwig for Trackster. Needs 'wigToBigWig' tool in path." hidden="true">
|
||||
<!-- Used internally to generate track indexes -->
|
||||
<command>wigToBigWig $input $chromInfo $output</command>
|
||||
<inputs>
|
||||
<page>
|
||||
<param format="wig" name="input" type="data" label="Choose wiggle"/>
|
||||
</page>
|
||||
</inputs>
|
||||
<outputs>
|
||||
<data format="bigwig" name="output"/>
|
||||
</outputs>
|
||||
<help>
|
||||
</help>
|
||||
</tool>
|
||||
@@ -1169,7 +1169,7 @@ class Wiggle( Tabular, _RemoteCallMixin ):
|
||||
resolution = max( resolution, 1 )
|
||||
return resolution
|
||||
def get_track_type( self ):
|
||||
return "LineTrack", {"data": "array_tree"}
|
||||
return "LineTrack", {"data": "bigwig"}
|
||||
|
||||
class CustomTrack ( Tabular ):
|
||||
"""UCSC CustomTrack"""
|
||||
|
||||
@@ -8,6 +8,7 @@ pkg_resources.require( "bx-python" ); pkg_resources.require( "pysam" ); pkg_reso
|
||||
from galaxy.datatypes.util.gff_util import *
|
||||
from bx.interval_index_file import Indexes
|
||||
from bx.arrays.array_tree import FileArrayTreeDict
|
||||
from bx.bbi.bigwig_file import BigWigFile
|
||||
from galaxy.util.lrucache import LRUCache
|
||||
from galaxy.visualization.tracks.summary import *
|
||||
from galaxy.datatypes.tabular import Vcf
|
||||
@@ -16,6 +17,13 @@ from pysam import csamtools
|
||||
|
||||
MAX_VALS = 5000 # only display first MAX_VALS features
|
||||
|
||||
# Return None instead of NaN to pass jQuery 1.4's strict JSON
|
||||
def float_nan(n):
|
||||
if n != n: # NaN != NaN
|
||||
return None
|
||||
else:
|
||||
return float(n)
|
||||
|
||||
class TracksDataProvider( object ):
|
||||
""" Base class for tracks data providers. """
|
||||
|
||||
@@ -340,6 +348,50 @@ class ArrayTreeDataProvider( TracksDataProvider ):
|
||||
|
||||
f.close()
|
||||
return results
|
||||
|
||||
class BigWigDataProvider( TracksDataProvider ):
|
||||
"""
|
||||
BigWig data provider for the Galaxy track browser.
|
||||
"""
|
||||
|
||||
def get_data( self, chrom, start, end, **kwargs ):
|
||||
# Bigwig has the possibility of it being a standalone bigwig file, in which case we use
|
||||
# original_dataset, or coming from wig->bigwig conversion in which we use converted_dataset
|
||||
if self.converted_dataset is not None:
|
||||
f = open( self.converted_dataset.file_name )
|
||||
else:
|
||||
f = open( self.original_dataset.file_name )
|
||||
bw = BigWigFile(file=f)
|
||||
|
||||
if 'stats' in kwargs:
|
||||
all_dat = bw.query(chrom, 0, 2147483647, 1)
|
||||
f.close()
|
||||
if all_dat is None:
|
||||
return None
|
||||
|
||||
all_dat = all_dat[0] # only 1 summary
|
||||
return { 'max': float( all_dat['max'] ), \
|
||||
'min': float( all_dat['min'] ), \
|
||||
'total_frequency': float( all_dat['coverage'] ) }
|
||||
|
||||
|
||||
start = int(start)
|
||||
end = int(end)
|
||||
num_points = 2000
|
||||
if (end - start) < num_points:
|
||||
num_points = end - start
|
||||
|
||||
data = bw.query(chrom, start, end, num_points)
|
||||
f.close()
|
||||
|
||||
pos = start
|
||||
step_size = (end - start) / num_points
|
||||
result = []
|
||||
for dat_dict in data:
|
||||
result.append( (pos, float_nan(dat_dict['mean']) ) )
|
||||
pos += step_size
|
||||
|
||||
return result
|
||||
|
||||
class IntervalIndexDataProvider( TracksDataProvider ):
|
||||
"""
|
||||
@@ -448,7 +500,8 @@ dataset_type_name_to_data_provider = {
|
||||
"array_tree": ArrayTreeDataProvider,
|
||||
"interval_index": { "vcf": VcfDataProvider, "default" : IntervalIndexDataProvider },
|
||||
"bai": BamDataProvider,
|
||||
"summary_tree": SummaryTreeDataProvider
|
||||
"summary_tree": SummaryTreeDataProvider,
|
||||
"bigwig": BigWigDataProvider
|
||||
}
|
||||
|
||||
dataset_type_to_data_provider = {
|
||||
@@ -477,7 +530,10 @@ def get_data_provider( name=None, original_dataset=None ):
|
||||
# Get data provider mapping and data provider for 'data'. If
|
||||
# provider available, use it; otherwise use generic provider.
|
||||
_ , data_provider_mapping = original_dataset.datatype.get_track_type()
|
||||
data_provider_name = data_provider_mapping[ 'data' ]
|
||||
if 'data_standalone' in data_provider_mapping:
|
||||
data_provider_name = data_provider_mapping[ 'data_standalone' ]
|
||||
else:
|
||||
data_provider_name = data_provider_mapping[ 'data' ]
|
||||
if data_provider_name:
|
||||
data_provider = get_data_provider( name=data_provider_name, original_dataset=original_dataset )
|
||||
else:
|
||||
|
||||
@@ -26,7 +26,7 @@ def get_tool_def( trans, hda ):
|
||||
# Get list of tool parameters that can be interactively modified.
|
||||
tool_params = []
|
||||
tool_param_values = dict( [ ( p.name, p.value ) for p in job.parameters ] )
|
||||
tool_param_values = tool.params_from_strings( tool_param_values, trans.app )
|
||||
tool_param_values = tool.params_from_strings( tool_param_values, trans.app, ignore_errors=True )
|
||||
for name, input in tool.inputs.items():
|
||||
if type( input ) == IntegerToolParameter:
|
||||
tool_params.append( { 'name' : name, 'label': input.label, 'type': 'int', \
|
||||
|
||||
@@ -120,7 +120,6 @@ class TracksController( BaseController, UsesVisualization, UsesHistoryDatasetAss
|
||||
@web.require_login()
|
||||
def index( self, trans, **kwargs ):
|
||||
config = {}
|
||||
|
||||
return trans.fill_template( "tracks/browser.mako", config=config, add_dataset=kwargs.get("dataset_id", None), \
|
||||
default_dbkey=kwargs.get("default_dbkey", None) )
|
||||
|
||||
@@ -267,7 +266,7 @@ class TracksController( BaseController, UsesVisualization, UsesHistoryDatasetAss
|
||||
return msg
|
||||
|
||||
# Get converted datasets.
|
||||
data_sources, message = self._get_converted_datasets( trans, dataset )
|
||||
data_sources, message = self._get_datasource_info( trans, dataset )
|
||||
if not data_sources:
|
||||
return message
|
||||
|
||||
@@ -286,9 +285,14 @@ class TracksController( BaseController, UsesVisualization, UsesHistoryDatasetAss
|
||||
return { 'dataset_type': data_sources['index'], 'data': frequencies, 'max': max_v, 'avg': avg_v, 'delta': delta }
|
||||
|
||||
# Get data provider.
|
||||
tracks_dataset_type = data_sources['data']
|
||||
data_provider_class = get_data_provider( name=tracks_dataset_type, original_dataset=dataset )
|
||||
data_provider = data_provider_class( dataset.get_converted_dataset(trans, tracks_dataset_type), dataset )
|
||||
if "data_standalone" in data_sources:
|
||||
tracks_dataset_type = data_sources['data_standalone']
|
||||
data_provider_class = get_data_provider( name=tracks_dataset_type, original_dataset=dataset )
|
||||
data_provider = data_provider_class( original_dataset=dataset )
|
||||
else:
|
||||
tracks_dataset_type = data_sources['data']
|
||||
data_provider_class = get_data_provider( name=tracks_dataset_type, original_dataset=dataset )
|
||||
data_provider = data_provider_class( dataset.get_converted_dataset(trans, tracks_dataset_type), dataset )
|
||||
|
||||
# Get and return data from data_provider.
|
||||
data = data_provider.get_data( chrom, low, high, **kwargs )
|
||||
@@ -502,13 +506,17 @@ class TracksController( BaseController, UsesVisualization, UsesHistoryDatasetAss
|
||||
return messages.PENDING
|
||||
return None
|
||||
|
||||
def _get_converted_datasets( self, trans, dataset ):
|
||||
def _get_datasource_info( self, trans, dataset ):
|
||||
"""
|
||||
Returns (a) converted datasets for a dataset and (b) dictionary of
|
||||
Returns (a) datasource info for a dataset and (b) dictionary of
|
||||
any messages based on or derived from the conversion.
|
||||
"""
|
||||
track_type, data_sources = dataset.datatype.get_track_type()
|
||||
|
||||
for source_type, data_source in data_sources.iteritems():
|
||||
if source_type == "data_standalone":
|
||||
break
|
||||
|
||||
try:
|
||||
converted_dataset = dataset.get_converted_dataset(trans, data_source)
|
||||
except ValueError:
|
||||
@@ -523,4 +531,4 @@ class TracksController( BaseController, UsesVisualization, UsesHistoryDatasetAss
|
||||
if not converted_dataset or converted_dataset.state != model.Dataset.states.OK:
|
||||
return None, messages.PENDING
|
||||
|
||||
return data_sources, None
|
||||
return data_sources, None
|
||||
|
||||
File diff suppressed because one or more lines are too long
+32
-22
@@ -690,8 +690,8 @@ $.extend( Track.prototype, {
|
||||
track.content_div.text(DATA_ERROR);
|
||||
if (result.message) {
|
||||
var track_id = track.view.tracks.indexOf(track);
|
||||
var error_link = $("<a href='javascript:void(0);'></a>").attr("id", track_id + "_error");
|
||||
error_link.text("Click to view error");
|
||||
var error_link = $(" <a href='javascript:void(0);'></a>").attr("id", track_id + "_error");
|
||||
error_link.text("View error");
|
||||
$("#" + track_id + "_error").live("click", function() {
|
||||
show_modal( "Trackster Error", "<pre>" + result.message + "</pre>", { "Close" : hide_modal } );
|
||||
});
|
||||
@@ -719,16 +719,29 @@ $.extend( Track.prototype, {
|
||||
track.container_div.addClass("nodata");
|
||||
track.content_div.text(DATA_NONE);
|
||||
}
|
||||
},
|
||||
restore_prefs: function(prefs) {
|
||||
var that = this;
|
||||
$.each(prefs, function(pref, val) {
|
||||
if (val !== undefined) {
|
||||
that.prefs[pref] = val;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var TiledTrack = function(filters, tool, parent_track) {
|
||||
var track = this,
|
||||
view = track.view;
|
||||
|
||||
// Attribute init.
|
||||
this.filters = (filters !== undefined ? get_filters_from_dict( filters ) : []);
|
||||
this.tool = (tool !== undefined ? get_tool_from_dict( tool ) : undefined);
|
||||
this.parent_track = parent_track;
|
||||
this.child_tracks = [];
|
||||
|
||||
if (track.hidden) { return; }
|
||||
|
||||
//
|
||||
// Init HTML elements. for tool, filters.
|
||||
//
|
||||
@@ -753,7 +766,6 @@ var TiledTrack = function(filters, tool, parent_track) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
var filters_table = $("<table class='filters'>").appendTo(this.filtering_div);
|
||||
var track = this;
|
||||
$.each(this.filters, function(index, filter) {
|
||||
var table_row = $("<tr>").appendTo(filters_table);
|
||||
var filter_th = $("<th class='filter-info'>").appendTo(table_row);
|
||||
@@ -844,14 +856,6 @@ var TiledTrack = function(filters, tool, parent_track) {
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// Functional init.
|
||||
//
|
||||
var track = this,
|
||||
view = track.view;
|
||||
|
||||
if (track.hidden) { return; }
|
||||
|
||||
if (track.display_modes !== undefined) {
|
||||
if (track.mode_div === undefined) {
|
||||
track.mode_div = $("<div class='right-float menubutton popup' />").appendTo(track.header_div);
|
||||
@@ -882,16 +886,6 @@ var TiledTrack = function(filters, tool, parent_track) {
|
||||
// Track dropdown menu.
|
||||
//
|
||||
var track_dropdown = {};
|
||||
track_dropdown["Set as overview"] = function() {
|
||||
view.overview_viewport.find("canvas").remove();
|
||||
track.is_overview = true;
|
||||
track.set_overview();
|
||||
for (var track_id in view.tracks) {
|
||||
if (view.tracks[track_id] !== track) {
|
||||
view.tracks[track_id].is_overview = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
track_dropdown["Edit configuration"] = function() {
|
||||
var cancel_fn = function() { hide_modal(); $(window).unbind("keypress.check_enter_esc"); },
|
||||
ok_fn = function() { track.update_options(track.track_id); hide_modal(); $(window).unbind("keypress.check_enter_esc"); },
|
||||
@@ -909,6 +903,18 @@ var TiledTrack = function(filters, tool, parent_track) {
|
||||
"OK": ok_fn
|
||||
});
|
||||
};
|
||||
|
||||
track_dropdown["Set as overview"] = function() {
|
||||
view.overview_viewport.find("canvas").remove();
|
||||
track.is_overview = true;
|
||||
track.set_overview();
|
||||
for (var track_id in view.tracks) {
|
||||
if (view.tracks[track_id] !== track) {
|
||||
view.tracks[track_id].is_overview = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (track.filters.length > 0) {
|
||||
// Show/hide filters menu item.
|
||||
track_dropdown["Show filters"] = function() {
|
||||
@@ -1061,7 +1067,9 @@ $.extend( TiledTrack.prototype, Track.prototype, {
|
||||
parent_element.append( tile_element );
|
||||
track.max_height = Math.max( track.max_height, tile_element.height() );
|
||||
track.content_div.css("height", track.max_height + "px");
|
||||
|
||||
|
||||
if (track.hidden) { return; }
|
||||
|
||||
// Show/hide filters based on whether tile is filterable.
|
||||
if ( tile_element.hasClass(FILTERABLE_CLASS) ) {
|
||||
show_hide_popupmenu_options(track.popup_menu, "(Show|Hide) filters");
|
||||
@@ -1234,6 +1242,7 @@ var LineTrack = function ( name, view, dataset_id, prefs ) {
|
||||
this.data_cache = new Cache(CACHED_DATA);
|
||||
this.tile_cache = new Cache(CACHED_TILES_LINE);
|
||||
this.prefs = { 'color': 'black', 'min_value': undefined, 'max_value': undefined, 'mode': this.mode };
|
||||
this.restore_prefs(prefs);
|
||||
};
|
||||
$.extend( LineTrack.prototype, TiledTrack.prototype, {
|
||||
init: function() {
|
||||
@@ -1454,6 +1463,7 @@ var FeatureTrack = function (name, view, dataset_id, prefs, filters, tool, paren
|
||||
this.left_offset = 200;
|
||||
|
||||
this.prefs = { 'block_color': '#444', 'label_color': 'black', 'show_counts': true };
|
||||
this.restore_prefs(prefs);
|
||||
};
|
||||
$.extend( FeatureTrack.prototype, TiledTrack.prototype, {
|
||||
init: function() {
|
||||
|
||||
@@ -15,7 +15,7 @@ ${parent.stylesheets()}
|
||||
${h.css( "history", "autocomplete_tagging", "trackster", "overcast/jquery-ui-1.8.5.custom" )}
|
||||
|
||||
<style type="text/css">
|
||||
#center, #browser-container {
|
||||
#browser-container {
|
||||
overflow: none;
|
||||
}
|
||||
ul#sortable-ul {
|
||||
@@ -120,7 +120,7 @@ ${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jquery.event.drag",
|
||||
init();
|
||||
%else:
|
||||
var continue_fn = function() {
|
||||
view = new View( $("#center"), $("#new-title").val(), undefined, $("#new-dbkey").val() );
|
||||
view = new View( $("#browser-container"), $("#new-title").val(), undefined, $("#new-dbkey").val() );
|
||||
view.editor = true;
|
||||
init();
|
||||
hide_modal();
|
||||
|
||||
Reference in New Issue
Block a user