mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
trackster: support BAM visualization with samtools, automatically enable tracks for any datatype with "get_track_type" defined
This commit is contained in:
@@ -3,7 +3,9 @@
|
||||
<registration converters_path="lib/galaxy/datatypes/converters">
|
||||
<datatype extension="ab1" type="galaxy.datatypes.binary:Ab1" mimetype="application/octet-stream" display_in_upload="true"/>
|
||||
<datatype extension="axt" type="galaxy.datatypes.sequence:Axt" display_in_upload="true"/>
|
||||
<datatype extension="bam" type="galaxy.datatypes.binary:Bam" mimetype="application/octet-stream" display_in_upload="true"/>
|
||||
<datatype extension="bam" type="galaxy.datatypes.binary:Bam" mimetype="application/octet-stream" display_in_upload="true">
|
||||
<converter file="bam_to_bai.xml" target_datatype="bai"/>
|
||||
</datatype>
|
||||
<datatype extension="bed" type="galaxy.datatypes.interval:Bed" display_in_upload="true">
|
||||
<converter file="bed_to_gff_converter.xml" target_datatype="gff"/>
|
||||
<converter file="interval_to_coverage.xml" target_datatype="coverage"/>
|
||||
|
||||
@@ -19,6 +19,7 @@ MySQL_python = 1.2.2
|
||||
pbs_python = 2.9.4
|
||||
psycopg2 = 2.0.6
|
||||
pycrypto = 2.0.1
|
||||
pysam = 0.1.1
|
||||
pysqlite = 2.5.6
|
||||
python_lzo = 1.08
|
||||
threadframe = 0.2
|
||||
@@ -74,6 +75,7 @@ MySQL_python = http://superb-west.dl.sourceforge.net/sourceforge/mysql-python/My
|
||||
pbs_python = http://ftp.sara.nl/pub/outgoing/pbs_python-2.9.4.tar.gz
|
||||
psycopg2 = http://initd.org/pub/software/psycopg/PSYCOPG-2-0/psycopg2-2.0.6.tar.gz ftp://ftp-archives.postgresql.org/pub/source/v8.2.6/postgresql-8.2.6.tar.bz2
|
||||
pycrypto = http://www.amk.ca/files/python/crypto/pycrypto-2.0.1.tar.gz
|
||||
pysam = http://bitbucket.org/kanwei/kanwei-pysam/get/e3c601a062fd.gz
|
||||
pysqlite = http://pypi.python.org/packages/source/p/pysqlite/pysqlite-2.5.6.tar.gz
|
||||
python_lzo = http://www.oberhumer.com/opensource/lzo/download/LZO-v1/python-lzo-1.08.tar.gz http://www.oberhumer.com/opensource/lzo/download/LZO-v1/lzo-1.08.tar.gz
|
||||
threadframe = http://www.majid.info/python/threadframe/threadframe-0.2.tar.gz
|
||||
|
||||
@@ -132,7 +132,9 @@ class Bam( Binary ):
|
||||
return dataset.peek
|
||||
except:
|
||||
return "Binary bam alignments file (%s)" % ( data.nice_size( dataset.get_size() ) )
|
||||
|
||||
def get_track_type( self ):
|
||||
return "ReadTrack", "bai"
|
||||
|
||||
class Binseq( Binary ):
|
||||
"""Class describing a zip archive of binary sequence files"""
|
||||
file_ext = "binseq.zip"
|
||||
|
||||
@@ -63,6 +63,4 @@ class LastzCoverage( Tabular ):
|
||||
resolution = max( resolution, 1 )
|
||||
return resolution
|
||||
|
||||
def get_track_type( self ):
|
||||
return "LineTrack"
|
||||
|
||||
|
||||
@@ -325,8 +325,6 @@ class Interval( Tabular ):
|
||||
def get_track_resolution( self, dataset, start, end):
|
||||
return None
|
||||
|
||||
def get_track_type( self ):
|
||||
return "FeatureTrack"
|
||||
|
||||
class Bed( Interval ):
|
||||
"""Tab delimited data in BED format"""
|
||||
@@ -484,6 +482,9 @@ class Bed( Interval ):
|
||||
else: return False
|
||||
return True
|
||||
except: return False
|
||||
|
||||
def get_track_type( self ):
|
||||
return "FeatureTrack", "interval_index"
|
||||
|
||||
class _RemoteCallMixin:
|
||||
def _get_remote_call_url( self, redirect_url, site_name, dataset, type, app, base_url ):
|
||||
@@ -904,7 +905,7 @@ class Wiggle( Tabular, _RemoteCallMixin ):
|
||||
resolution = max( resolution, 1 )
|
||||
return resolution
|
||||
def get_track_type( self ):
|
||||
return "LineTrack"
|
||||
return "LineTrack", "array_tree"
|
||||
|
||||
class CustomTrack ( Tabular ):
|
||||
"""UCSC CustomTrack"""
|
||||
|
||||
@@ -18,6 +18,7 @@ class Registry( object ):
|
||||
self.datatype_converters = odict()
|
||||
self.datatype_indexers = odict()
|
||||
self.converters = []
|
||||
self.available_tracks = []
|
||||
self.set_external_metadata_tool = None
|
||||
self.indexers = []
|
||||
self.sniff_order = []
|
||||
@@ -54,6 +55,8 @@ class Registry( object ):
|
||||
# Use default mime type as per datatype spec
|
||||
mimetype = self.datatypes_by_extension[extension].get_mime()
|
||||
self.mimetypes_by_extension[extension] = mimetype
|
||||
if hasattr( getattr( module, datatype_class ), "get_track_type" ):
|
||||
self.available_tracks.append( extension )
|
||||
if display_in_upload:
|
||||
self.upload_file_formats.append( extension )
|
||||
for converter in elem.findall( 'converter' ):
|
||||
@@ -206,7 +209,10 @@ class Registry( object ):
|
||||
if not included:
|
||||
self.sniff_order.append(datatype)
|
||||
append_to_sniff_order()
|
||||
|
||||
|
||||
def get_available_tracks(self):
|
||||
return self.available_tracks
|
||||
|
||||
def get_mimetype_by_extension(self, ext ):
|
||||
"""Returns a mimetype based on an extension"""
|
||||
try:
|
||||
|
||||
@@ -23,35 +23,26 @@ from galaxy.util.bunch import Bunch
|
||||
|
||||
from galaxy.visualization.tracks.data.array_tree import ArrayTreeDataProvider
|
||||
from galaxy.visualization.tracks.data.interval_index import IntervalIndexDataProvider
|
||||
from galaxy.visualization.tracks.data.bam import BamDataProvider
|
||||
|
||||
# Message strings returned to browser
|
||||
messages = Bunch(
|
||||
PENDING = "pending",
|
||||
NO_DATA = "no data",
|
||||
NO_CHROMOSOME = "no chromosome",
|
||||
NO_CONVERTER = "no converter",
|
||||
DATA = "data",
|
||||
ERROR = "error"
|
||||
)
|
||||
|
||||
# Dataset type required for each track type. This needs to be more flexible,
|
||||
# there might be multiple types of indexes that suffice for a given track type.
|
||||
track_type_to_dataset_type = {
|
||||
"line": "array_tree",
|
||||
"feature": "interval_index"
|
||||
}
|
||||
|
||||
# Mapping from dataset type to a class that can fetch data from a file of that
|
||||
# type. This also needs to be more flexible.
|
||||
dataset_type_to_data_provider = {
|
||||
"array_tree": ArrayTreeDataProvider,
|
||||
"interval_index": IntervalIndexDataProvider
|
||||
"interval_index": IntervalIndexDataProvider,
|
||||
"bai": BamDataProvider
|
||||
}
|
||||
|
||||
# FIXME: hardcoding this for now, but it should be derived from the available
|
||||
# converters
|
||||
browsable_types = ( "wig", "bed" )
|
||||
|
||||
|
||||
class TracksController( BaseController ):
|
||||
"""
|
||||
Controller for track browser interface. Handles building a new browser from
|
||||
@@ -107,11 +98,12 @@ class TracksController( BaseController ):
|
||||
# Find all datasets in the current history that are of that dbkey
|
||||
# and can be displayed
|
||||
datasets = {}
|
||||
available_tracks = trans.app.datatypes_registry.get_available_tracks()
|
||||
for dataset in session.query( model.HistoryDatasetAssociation ).filter_by( deleted=False, history_id=trans.history.id ):
|
||||
if dataset.metadata.dbkey == dbkey and dataset.extension in browsable_types:
|
||||
if dataset.metadata.dbkey == dbkey and dataset.extension in available_tracks:
|
||||
datasets[dataset.id] = (dataset.extension, dataset.name)
|
||||
# Render the template
|
||||
return trans.fill_template( "tracks/new_browser.mako", converters=browsable_types, dbkey=dbkey, dbkey_set=dbkey_set, datasets=datasets )
|
||||
return trans.fill_template( "tracks/new_browser.mako", available_tracks=available_tracks, dbkey=dbkey, dbkey_set=dbkey_set, datasets=datasets )
|
||||
|
||||
@web.expose
|
||||
def browser(self, trans, id, chrom=""):
|
||||
@@ -127,8 +119,10 @@ class TracksController( BaseController ):
|
||||
for t in vis.latest_revision.config['tracks']:
|
||||
dataset_id = t['dataset_id']
|
||||
dataset = hda_query.get( dataset_id )
|
||||
track_type, indexer = dataset.datatype.get_track_type()
|
||||
tracks.append( {
|
||||
"type": dataset.datatype.get_track_type(),
|
||||
"type": track_type,
|
||||
"indexer": indexer,
|
||||
"name": dataset.name,
|
||||
"dataset_id": dataset.id
|
||||
} )
|
||||
@@ -184,14 +178,14 @@ class TracksController( BaseController ):
|
||||
return manifest
|
||||
|
||||
@web.json
|
||||
def data( self, trans, dataset_id, track_type, chrom, low, high, **kwargs ):
|
||||
def data( self, trans, dataset_id, indexer, chrom, low, high, **kwargs ):
|
||||
"""
|
||||
Called by the browser to request a block of data
|
||||
"""
|
||||
# Load the requested dataset
|
||||
dataset = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( dataset_id )
|
||||
# No dataset for that id
|
||||
if not dataset:
|
||||
if not dataset or not chrom:
|
||||
return messages.NO_DATA
|
||||
# Dataset is in error state, can't display
|
||||
if dataset.state == trans.app.model.Job.states.ERROR:
|
||||
@@ -200,12 +194,11 @@ class TracksController( BaseController ):
|
||||
if dataset.state != trans.app.model.Job.states.OK:
|
||||
return messages.PENDING
|
||||
# Determine what to return based on the type of track being drawn.
|
||||
converted_dataset_type = track_type_to_dataset_type[track_type]
|
||||
converted_dataset_type = indexer
|
||||
converted_dataset = self.__dataset_as_type( trans, dataset, converted_dataset_type )
|
||||
# If at this point we still don't have an `array_tree_dataset`, there
|
||||
# is no way we can display this data as an array tree
|
||||
if not converted_dataset:
|
||||
return messages.ERROR
|
||||
# No converter
|
||||
return messages.NO_CONVERTER
|
||||
# Need to check states again for the converted version
|
||||
if converted_dataset.state == model.Dataset.states.ERROR:
|
||||
return messages.ERROR
|
||||
@@ -228,6 +221,7 @@ class TracksController( BaseController ):
|
||||
converted dataset (possibly new) is returned, if it cannot be converted,
|
||||
None is returned.
|
||||
"""
|
||||
log.debug("Inside dataset as type")
|
||||
# Already of correct type
|
||||
if dataset.extension == type:
|
||||
return dataset
|
||||
|
||||
@@ -1 +1 @@
|
||||
function ensure_dd_helper(){if($("#DD-helper").length==0){$("<div id='DD-helper'/>").css({background:"white",opacity:0,zIndex:9000,position:"absolute",top:0,left:0,width:"100%",height:"100%"}).appendTo("body").hide()}}function make_left_panel(h,c,e){var g=false;var f=null;var d=function(i){var j=i;if(i<0){i=0}$(h).css("width",i);$(e).css("left",j);$(c).css("left",i+7);if(document.recalc){document.recalc()}};var a=function(){if(g){$(e).removeClass("hover");$(e).animate({left:f},"fast");$(h).css("left",-f).show().animate({left:0},"fast",function(){d(f);$(e).removeClass("hidden")});g=false}else{f=$(e).position().left;$(c).css("left",$(e).innerWidth());if(document.recalc){document.recalc()}$(e).removeClass("hover");$(h).animate({left:-f},"fast");$(e).animate({left:-1},"fast",function(){$(this).addClass("hidden")});g=true}};$(e).hover(function(){$(this).addClass("hover")},function(){$(this).removeClass("hover")}).bind("dragstart",function(i){$("#DD-helper").show()}).bind("dragend",function(i){$("#DD-helper").hide()}).bind("drag",function(i){x=i.offsetX;x=Math.min(400,Math.max(100,x));if(g){$(h).css("left",0);$(e).removeClass("hidden");g=false}d(x)}).bind("dragclickonly",function(i){a()}).find("div").show();var b=function(i){if((g&&i=="show")||(!g&&i=="hide")){a()}};return{force_panel:b}}function make_right_panel(a,e,h){var j=false;var g=false;var c=null;var d=function(k){$(a).css("width",k);$(e).css("right",k+9);$(h).css("right",k).css("left","");if(document.recalc){document.recalc()}};var i=function(){if(j){$(h).removeClass("hover");$(h).animate({right:c},"fast");$(a).css("right",-c).show().animate({right:0},"fast",function(){d(c);$(h).removeClass("hidden")});j=false}else{c=$(document).width()-$(h).position().left-$(h).outerWidth();$(e).css("right",$(h).innerWidth()+1);if(document.recalc){document.recalc()}$(h).removeClass("hover");$(a).animate({right:-c},"fast");$(h).animate({right:-1},"fast",function(){$(this).addClass("hidden")});j=true}g=false};var b=function(k){var l=$(e).width()-(j?c:0);if(l<k){if(!j){i();g=true}}else{if(g){i();g=false}}};$(h).hover(function(){$(this).addClass("hover")},function(){$(this).removeClass("hover")}).bind("dragstart",function(k){$("#DD-helper").show()}).bind("dragend",function(k){$("#DD-helper").hide()}).bind("drag",function(k){x=k.offsetX;w=$(window).width();x=Math.min(w-100,x);x=Math.max(w-400,x);if(j){$(a).css("right",0);$(h).removeClass("hidden");j=false}d(w-x-$(this).outerWidth())}).bind("dragclickonly",function(k){i()}).find("div").show();var f=function(k){if((j&&k=="show")||(!j&&k=="hide")){i()}};return{handle_minwidth_hint:b,force_panel:f}}function hide_modal(){$(".dialog-box-container").fadeOut(function(){$("#overlay").hide();$(".dialog-box").find(".body").children().remove()})}function show_modal(f,c,e,d){if(f){$(".dialog-box").find(".title").html(f);$(".dialog-box").find(".unified-panel-header").show()}else{$(".dialog-box").find(".unified-panel-header").hide()}var a=$(".dialog-box").find(".buttons").html("");if(e){$.each(e,function(b,g){a.append($("<button/>").text(b).click(g));a.append(" ")});a.show()}else{a.hide()}var a=$(".dialog-box").find(".extra_buttons").html("");if(d){$.each(d,function(b,g){a.append($("<button/>").text(b).click(g));a.append(" ")});a.show()}else{a.hide()}if(c=="progress"){c=$("<img src='../images/yui/rel_interstitial_loading.gif')' />")}$(".dialog-box").find(".body").html(c);if(!$(".dialog-box-container").is(":visible")){$("#overlay").show();$(".dialog-box-container").fadeIn()}}function show_in_overlay(c){var d=c.width||"600";var b=c.height||"400";var a=c.scroll||"auto";$("#overlay-background").bind("click.overlay",function(){hide_modal();$("#overlay-background").unbind("click.overlay")});show_modal(null,$("<div style='margin: -5px;'><iframe style='margin: 0; padding: 0;' src='"+c.url+"' width='"+d+"' height='"+b+"' scrolling='"+a+"' frameborder='0'></iframe></div>"))}$(function(){$(".tab").each(function(){var a=$(this).children(".submenu");if(a.length>0){if($.browser.msie){a.prepend("<iframe style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; filter:Alpha(Opacity='0');\"></iframe>")}$(this).hover(function(){a.show()},function(){a.hide()});a.click(function(){a.hide()})}})});function user_changed(a,b){if(a){$(".loggedin-only").show();$(".loggedout-only").hide();$("#user-email").text(a);if(b){$(".admin-only").show()}}else{$(".loggedin-only").hide();$(".loggedout-only").show();$(".admin-only").hide()}};
|
||||
function ensure_dd_helper(){if($("#DD-helper").length==0){$("<div id='DD-helper'/>").css({background:"white",opacity:0,zIndex:9000,position:"absolute",top:0,left:0,width:"100%",height:"100%"}).appendTo("body").hide()}}function make_left_panel(h,c,e){var g=false;var f=null;var d=function(i){var j=i;if(i<0){i=0}$(h).css("width",i);$(e).css("left",j);$(c).css("left",i+7);if(document.recalc){document.recalc()}};var a=function(){if(g){$(e).removeClass("hover");$(e).animate({left:f},"fast");$(h).css("left",-f).show().animate({left:0},"fast",function(){d(f);$(e).removeClass("hidden")});g=false}else{f=$(e).position().left;$(c).css("left",$(e).innerWidth());if(document.recalc){document.recalc()}$(e).removeClass("hover");$(h).animate({left:-f},"fast");$(e).animate({left:-1},"fast",function(){$(this).addClass("hidden")});g=true}};$(e).hover(function(){$(this).addClass("hover")},function(){$(this).removeClass("hover")}).bind("dragstart",function(i){$("#DD-helper").show()}).bind("dragend",function(i){$("#DD-helper").hide()}).bind("drag",function(i){x=i.offsetX;x=Math.min(400,Math.max(100,x));if(g){$(h).css("left",0);$(e).removeClass("hidden");g=false}d(x)}).bind("dragclickonly",function(i){a()}).find("div").show();var b=function(i){if((g&&i=="show")||(!g&&i=="hide")){a()}};return{force_panel:b}}function make_right_panel(a,e,h){var j=false;var g=false;var c=null;var d=function(k){$(a).css("width",k);$(e).css("right",k+9);$(h).css("right",k).css("left","");if(document.recalc){document.recalc()}};var i=function(){if(j){$(h).removeClass("hover");$(h).animate({right:c},"fast");$(a).css("right",-c).show().animate({right:0},"fast",function(){d(c);$(h).removeClass("hidden")});j=false}else{c=$(document).width()-$(h).position().left-$(h).outerWidth();$(e).css("right",$(h).innerWidth()+1);if(document.recalc){document.recalc()}$(h).removeClass("hover");$(a).animate({right:-c},"fast");$(h).animate({right:-1},"fast",function(){$(this).addClass("hidden")});j=true}g=false};var b=function(k){var l=$(e).width()-(j?c:0);if(l<k){if(!j){i();g=true}}else{if(g){i();g=false}}};$(h).hover(function(){$(this).addClass("hover")},function(){$(this).removeClass("hover")}).bind("dragstart",function(k){$("#DD-helper").show()}).bind("dragend",function(k){$("#DD-helper").hide()}).bind("drag",function(k){x=k.offsetX;w=$(window).width();x=Math.min(w-100,x);x=Math.max(w-400,x);if(j){$(a).css("right",0);$(h).removeClass("hidden");j=false}d(w-x-$(this).outerWidth())}).bind("dragclickonly",function(k){i()}).find("div").show();var f=function(k){if((j&&k=="show")||(!j&&k=="hide")){i()}};return{handle_minwidth_hint:b,force_panel:f}}function hide_modal(){$(".dialog-box-container").fadeOut(function(){$("#overlay").hide();$(".dialog-box").find(".body").children().remove()})}function show_modal(f,c,e,d){if(f){$(".dialog-box").find(".title").html(f);$(".dialog-box").find(".unified-panel-header").show()}else{$(".dialog-box").find(".unified-panel-header").hide()}var a=$(".dialog-box").find(".buttons").html("");if(e){$.each(e,function(b,g){a.append($("<button/>").text(b).click(g));a.append(" ")});a.show()}else{a.hide()}var a=$(".dialog-box").find(".extra_buttons").html("");if(d){$.each(d,function(b,g){a.append($("<button/>").text(b).click(g));a.append(" ")});a.show()}else{a.hide()}if(c=="progress"){c=$("<img src='../images/yui/rel_interstitial_loading.gif')' />")}$(".dialog-box").find(".body").html(c);if(!$(".dialog-box-container").is(":visible")){$("#overlay").show();$(".dialog-box-container").fadeIn()}}function show_in_overlay(c){var d=c.width||"600";var b=c.height||"400";var a=c.scroll||"auto";$("#overlay-background").bind("click.overlay",function(){hide_modal();$("#overlay-background").unbind("click.overlay")});show_modal(null,$("<div style='margin: -5px;'><img id='close_button' style='position:absolute;right:3px;top:3px;' src='../images/icon_error_sml.gif'><iframe style='margin: 0; padding: 0;' src='"+c.url+"' width='"+d+"' height='"+b+"' scrolling='"+a+"' frameborder='0'></iframe></div>"));$("#close_button").bind("click",function(){hide_modal()})}$(function(){$(".tab").each(function(){var a=$(this).children(".submenu");if(a.length>0){if($.browser.msie){a.prepend("<iframe style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; filter:Alpha(Opacity='0');\"></iframe>")}$(this).hover(function(){a.show()},function(){a.hide()});a.click(function(){a.hide()})}})});function user_changed(a,b){if(a){$(".loggedin-only").show();$(".loggedout-only").hide();$("#user-email").text(a);if(b){$(".admin-only").show()}}else{$(".loggedin-only").hide();$(".loggedout-only").show();$(".admin-only").hide()}};
|
||||
File diff suppressed because one or more lines are too long
+77
-11
@@ -81,7 +81,7 @@ var View = function( chrom, max_high ) {
|
||||
this.max_high = max_high;
|
||||
this.center = (this.max_high - this.max_low) / 2;
|
||||
this.span = this.max_high - this.max_low;
|
||||
this.zoom_factor = 2;
|
||||
this.zoom_factor = 3;
|
||||
this.zoom_level = 0;
|
||||
};
|
||||
$.extend( View.prototype, {
|
||||
@@ -241,12 +241,12 @@ $.extend( LabelTrack.prototype, Track.prototype, {
|
||||
}
|
||||
});
|
||||
|
||||
var LineTrack = function ( name, dataset_id, height ) {
|
||||
var LineTrack = function ( name, dataset_id, indexer, height ) {
|
||||
this.tile_cache = new Cache(CACHED_TILES_LINE);
|
||||
Track.call( this, name, $("#viewport") );
|
||||
TiledTrack.call( this );
|
||||
|
||||
this.track_type = "line";
|
||||
this.indexer = indexer;
|
||||
this.height_px = (height ? height : 100);
|
||||
this.container_div.addClass( "line-track" );
|
||||
this.dataset_id = dataset_id;
|
||||
@@ -258,7 +258,7 @@ $.extend( LineTrack.prototype, TiledTrack.prototype, {
|
||||
init: function() {
|
||||
var track = this;
|
||||
track.content_div.text(DATA_LOADING);
|
||||
$.getJSON( data_url, { stats: true, track_type: track.track_type,
|
||||
$.getJSON( data_url, { stats: true, indexer: track.indexer,
|
||||
chrom: track.view.chrom, low: null, high: null,
|
||||
dataset_id: track.dataset_id }, function ( data ) {
|
||||
if (!data || data == "error") {
|
||||
@@ -300,7 +300,7 @@ $.extend( LineTrack.prototype, TiledTrack.prototype, {
|
||||
|
||||
if (!track.data_queue[key]) {
|
||||
track.data_queue[key] = true;
|
||||
$.getJSON( data_url, { track_type: this.track_type, chrom: this.view.chrom,
|
||||
$.getJSON( data_url, { indexer: this.indexer, chrom: this.view.chrom,
|
||||
low: low, high: high, dataset_id: this.dataset_id,
|
||||
resolution: this.view.resolution }, function ( data ) {
|
||||
track.cache.set(key, data);
|
||||
@@ -360,12 +360,12 @@ $.extend( LineTrack.prototype, TiledTrack.prototype, {
|
||||
}
|
||||
});
|
||||
|
||||
var FeatureTrack = function ( name, dataset_id, height ) {
|
||||
var FeatureTrack = function ( name, dataset_id, indexer, height ) {
|
||||
this.tile_cache = new Cache(CACHED_TILES_FEATURE);
|
||||
Track.call( this, name, $("#viewport") );
|
||||
TiledTrack.call( this );
|
||||
|
||||
this.track_type = "feature";
|
||||
this.indexer = indexer;
|
||||
this.height_px = (height ? height : 100);
|
||||
this.container_div.addClass( "feature-track" );
|
||||
this.dataset_id = dataset_id;
|
||||
@@ -384,7 +384,7 @@ $.extend( FeatureTrack.prototype, TiledTrack.prototype, {
|
||||
init: function() {
|
||||
var track = this;
|
||||
track.content_div.text(DATA_LOADING);
|
||||
$.getJSON( data_url, { track_type: track.track_type, low: track.view.max_low,
|
||||
$.getJSON( data_url, { indexer: track.indexer, low: track.view.max_low,
|
||||
high: track.view.max_high, dataset_id: track.dataset_id,
|
||||
chrom: track.view.chrom }, function ( data ) {
|
||||
if (data == "error") {
|
||||
@@ -414,7 +414,7 @@ $.extend( FeatureTrack.prototype, TiledTrack.prototype, {
|
||||
|
||||
if (!track.data_queue[key]) {
|
||||
track.data_queue[key] = true;
|
||||
$.getJSON( data_url, { track_type: track.track_type, chrom: track.view.chrom,
|
||||
$.getJSON( data_url, { indexer: track.indexer, chrom: track.view.chrom,
|
||||
low: low, high: high, dataset_id: track.dataset_id,
|
||||
include_blocks: true }, function ( data ) {
|
||||
track.data_cache.set(key, data);
|
||||
@@ -454,8 +454,6 @@ $.extend( FeatureTrack.prototype, TiledTrack.prototype, {
|
||||
if (!this.inc_slots[level]) {
|
||||
this.inc_slots[level] = {};
|
||||
this.inc_slots[level].w_scale = DENSITY / Math.pow(FEATURE_LEVELS, level+1);
|
||||
// this.inc_slots[level].w_scale = 1000 / (this.view.high - this.view.low);
|
||||
|
||||
}
|
||||
var slots = this.inc_slots[level];
|
||||
// console.log(level, slots.w_scale, slots);
|
||||
@@ -629,3 +627,71 @@ $.extend( FeatureTrack.prototype, TiledTrack.prototype, {
|
||||
return new_canvas;
|
||||
}
|
||||
});
|
||||
|
||||
var ReadTrack = function ( name, dataset_id, indexer, height ) {
|
||||
this.tile_cache = new Cache(CACHED_TILES_FEATURE);
|
||||
Track.call( this, name, $("#viewport") );
|
||||
TiledTrack.call( this );
|
||||
FeatureTrack.call( this, name, dataset_id, indexer, height );
|
||||
this.default_font = "9px Monaco, Lucida Console, monospace";
|
||||
|
||||
};
|
||||
$.extend( ReadTrack.prototype, TiledTrack.prototype, FeatureTrack.prototype, {
|
||||
draw_tile: function( resolution, tile_index, parent_element, w_scale ) {
|
||||
if (!this.values) {
|
||||
return;
|
||||
}
|
||||
var tile_low = tile_index * DENSITY * resolution,
|
||||
tile_high = ( tile_index + 1 ) * DENSITY * resolution,
|
||||
tile_span = DENSITY * resolution;
|
||||
// console.log("drawing " + tile_index);
|
||||
// Once we zoom in enough, show name labels
|
||||
var data, slots, required_height;
|
||||
required_height = this.height_px;
|
||||
slots = this.zo_slots;
|
||||
data = this.values;
|
||||
|
||||
// console.log(tile_low, tile_high, tile_length, w_scale);
|
||||
var width = Math.ceil( tile_span * w_scale ),
|
||||
new_canvas = $("<canvas class='tile'></canvas>");
|
||||
|
||||
var dummy_canvas = $("<canvas></canvas>").get(0).getContext("2d");
|
||||
|
||||
new_canvas.css({
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: ( tile_low - this.view.low ) * w_scale - this.left_offset
|
||||
});
|
||||
new_canvas.get(0).width = width + this.left_offset;
|
||||
new_canvas.get(0).height = required_height;
|
||||
// console.log(( tile_low - this.view.low ) * w_scale, tile_index, w_scale);
|
||||
var ctx = new_canvas.get(0).getContext("2d");
|
||||
ctx.fillStyle = this.base_color;
|
||||
ctx.font = this.default_font;
|
||||
ctx.textAlign = "right";
|
||||
var px_per_char = ctx.measureText("A").width;
|
||||
|
||||
var j = 0;
|
||||
for (var i = 0, len = data.length; i < len; i++) {
|
||||
var feature = data[i];
|
||||
if (feature.start <= tile_high && feature.end >= tile_low) {
|
||||
var f_start = Math.floor( Math.max(0, (feature.start - tile_low) * w_scale) ),
|
||||
f_end = Math.ceil( Math.min(width, (feature.end - tile_low) * w_scale) ),
|
||||
y_center = slots[feature.uid] * this.vertical_gap;
|
||||
|
||||
var thickness, y_start, thick_start = null, thick_end = null;
|
||||
if (w_scale > px_per_char) {
|
||||
for (var c = 0, str_len = feature.name.length; c < str_len; c++) {
|
||||
var c_start = Math.floor( Math.max(0, (feature.start + c - tile_low) * w_scale) );
|
||||
ctx.fillText(feature.name[c], c_start + this.left_offset, y_center + 8);
|
||||
}
|
||||
} else {
|
||||
ctx.fillRect(f_start + this.left_offset, y_center + 4, f_end - f_start, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parent_element.append( new_canvas );
|
||||
return new_canvas;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -20,7 +20,7 @@ ${h.js( "jquery", "jquery.event.drag", "jquery.mousewheel", "trackster" )}
|
||||
view.add_track( new LabelTrack( $("#nav-labeltrack" ) ) );
|
||||
|
||||
%for track in tracks:
|
||||
view.add_track( new ${track["type"]}( "${track['name']}", ${track['dataset_id']} ) );
|
||||
view.add_track( new ${track["type"]}( "${track['name']}", ${track['dataset_id']}, "${track['indexer']}" ) );
|
||||
%endfor
|
||||
|
||||
$(document).bind( "redraw", function( e ) {
|
||||
|
||||
@@ -11,7 +11,7 @@ $( function() {
|
||||
</script>
|
||||
</%def>
|
||||
|
||||
% if not converters:
|
||||
% if not available_tracks:
|
||||
<div class="errormessagelarge">
|
||||
There are no available converters needed for visualization. Please verify that your tool_conf.xml file contains
|
||||
converters for datatypes (see tool_conf.xml.sample) for examples.
|
||||
@@ -46,7 +46,7 @@ $( function() {
|
||||
<div style="clear: both;"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="dataset_ids">Datasets to include: </label>
|
||||
<label for="dataset_ids">Datasets to visualize: (${", ".join(available_tracks)} files are supported)</label>
|
||||
%for dataset_id, (dataset_ext, dataset_name) in datasets.iteritems():
|
||||
<div>
|
||||
<input type="checkbox" id="${dataset_id}" name="dataset_ids" value="${dataset_id}" />
|
||||
|
||||
Reference in New Issue
Block a user