galaxy-commits
Threads by month
- ----- 2025 -----
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- 15302 discussions

galaxy-dist commit 7c5d27bf6a41: Make VCF a first-class type in trackster. Added VCF data provider and VCF tracks type to trackster; new functionality is used to show reference base and alternate base for SNPs in VCF tracks. Also refactored data providers so that they inherit from a base provider.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1286501181 14400
# Node ID 7c5d27bf6a41cd215088b8b9081572a30735bd43
# Parent d85159be56e854731822a314a2e982e0c6987389
Make VCF a first-class type in trackster. Added VCF data provider and VCF tracks type to trackster; new functionality is used to show reference base and alternate base for SNPs in VCF tracks. Also refactored data providers so that they inherit from a base provider.
--- a/lib/galaxy/visualization/tracks/data/interval_index.py
+++ b/lib/galaxy/visualization/tracks/data/interval_index.py
@@ -8,15 +8,11 @@ Payload format: [ uid (offset), start, e
import pkg_resources; pkg_resources.require( "bx-python" )
from bx.interval_index_file import Indexes
from galaxy.datatypes.interval import Bed, Gff
-from galaxy.datatypes.tabular import Vcf
+from base import TracksDataProvider
MAX_VALS = 5000 # only display first MAX_VALS features
-class IntervalIndexDataProvider( object ):
- def __init__( self, converted_dataset, original_dataset ):
- self.original_dataset = original_dataset
- self.converted_dataset = converted_dataset
-
+class IntervalIndexDataProvider( TracksDataProvider ):
def get_data( self, chrom, start, end, **kwargs ):
start, end = int(start), int(end)
source = open( self.original_dataset.file_name )
@@ -66,10 +62,7 @@ class IntervalIndexDataProvider( object
block_starts = [ int(n) for n in feature[11].split(',') if n != '' ]
blocks = zip(block_sizes, block_starts)
payload.append( [ (start + block[1], start + block[1] + block[0]) for block in blocks] )
- elif isinstance( self.original_dataset.datatype, Vcf ):
- # VCF dataset.
- payload.append( feature[2] ) # name
-
+
results.append(payload)
return { 'data': results, 'message': message }
--- a/lib/galaxy/visualization/tracks/data/bam.py
+++ b/lib/galaxy/visualization/tracks/data/bam.py
@@ -9,10 +9,11 @@ from pysam import csamtools
from math import floor, ceil, log
import logging
log = logging.getLogger(__name__)
+from base import TracksDataProvider
MAX_VALS = 5000 # only display first MAX_VALS datapoints
-class BamDataProvider( object ):
+class BamDataProvider( TracksDataProvider ):
"""
Provides access to intervals from a sorted indexed BAM file.
"""
--- a/static/scripts/packed/trackster.js
+++ b/static/scripts/packed/trackster.js
@@ -1,1 +1,1 @@
-var DENSITY=200,FEATURE_LEVELS=10,MAX_FEATURE_DEPTH=100,DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),PX_PER_CHAR=CONTEXT.measureText("A").width,RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/strand_right_inv.png";right_img_inv.onload=function()
{RIGHT_STRAND_INV=CONTEXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,c,e,d,b){this.container=a;this.vis_id=d;this.dbkey=b;this.title=e;this.chrom=c;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.
min_separation=30;this.has_changes=false;this.init();this.reset()};$.extend(View.prototype,{init:function(){var c=this.container,a=this;this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(c);this.content_div=$("<div/>").addClass("content").css("position","relative").hide().appendTo(c);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide().appendTo(c);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.nav_container=$("<div/>").addClass("nav-container").appendTo(c);this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.nav);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_box_background=$("<div/>").addClass("overview-boxback").app
endTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){void (0)}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);var b=function(d){if(d.type==="focusout"||(d.keyCode||d.which)===13||(d.keyCode||d.which)===27){if((d.keyCode||d.which)!==27){a.go_to($(this).val())}$(this).hide();a.location_span.show();a.chrom_select.show();return false}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keypress focusout",b).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);this.location_span.bind("click",function(){a.location_span.hi
de();a.chrom_select.hide();a.nav_input.css("display","inline-block");a.nav_input.select();a.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.zo_link=$("<a/>").click(function(){a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);this.zi_link=$("<a/>").click(function(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(d){if(d.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=d.chrom_info;var f='<option value="">Select Chrom/Contig</option>';for(i in a.chrom_data){var e=a.chrom_data[i]["chrom"];f+='<option value="'+e+'">'+e+"</option>"}a.chrom_select.html(f);a.intro_div.show();a.content_div.hide();a.chrom_select.b
ind("change",function(){a.change_chrom(a.chrom_select.val())})},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("dblclick",function(d){a.zoom_in(d.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(d){this.current_x=d.offsetX}).bind("drag",function(d){var g=d.offsetX-this.current_x;this.current_x=d.offsetX;var f=Math.round(g/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-f)});this.viewport_container.bind("dragstart",function(d){this.original_low=a.low;this.current_height=d.clientY;this.current_x=d.offsetX;this.enable_pan=(d.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(g){if(!this.enable_pan||this.in_reordering){return}var d=$(this);var j=g.offsetX-this.current_x;var f=d.scrollTop()-(g.clientY-this.current_height);d.scrollTop(f);this.current_height=g.clientY;this.current_x=g.offsetX;var h=Math.round(j/a.viewport_container.width()*(a.high-a.low));a.move_
delta(h)});this.top_labeltrack.bind("dragstart",function(d){this.drag_origin_x=d.clientX;this.drag_origin_pos=d.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_div=$("<div />").css({height:a.content_div.height()+30,top:"0px",position:"absolute","background-color":"#cfc",border:"1px solid #6a6",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(j){var f=Math.min(j.clientX,this.drag_origin_x)-a.container.offset().left,d=Math.max(j.clientX,this.drag_origin_x)-a.container.offset().left,h=(a.high-a.low),g=a.viewport_container.width();a.update_location(Math.round(f/g*h)+a.low,Math.round(d/g*h)+a.low);this.drag_div.css({left:f+"px",width:(d-f)+"px"})}).bind("dragend",function(k){var f=Math.min(k.clientX,this.drag_origin_x),d=Math.max(k.clientX,this.drag_origin_x),h=(a.high-a.low),g=a.viewport_container.width(),j=a.low;a.low=Math.round(f/g*h)+j;a.high=Math.round(d/g*h)+j;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(th
is,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack))},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(d,a,f){var c=this;var e=$.grep(c.chrom_data,function(h,j){return h.chrom===d})[0];if(e===undefined){return}if(d!==c.chrom){c.chrom=d;if(c.chrom===""){c.intro_div.show();c.content_div.hide()}else{c.intro_div.hide();c.content_div.show()}c.chrom_select.val(c.chrom);c.max_high=e.len;c.reset();c.redraw(true);for(var g in c.tracks){var b=c.tracks[g];if(b.init){b.init()}}}if(a!==undefined&&f!==undefined){c.low=Math.max(a,0);c.high=Math.min(f,c.max_high)}c.overview_viewport.find("canvas").remove();c.redraw()},go_to:function(f){var k=this,b=f.split(":"),h=b[0],j=b[1];if(j!==undefined){try{var g=j.split("-"),a=parseInt(g[0].replace(/,/g,"")),d=parseInt(g[1].replace(/,/g,""))}catch(c){return false}}k.change_chrom(h,a,d)},move_
delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.high-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(h){var d=this.high-this.low,b=this.low,f=this.high;if(b<this.max_low){b=this.max_low}if(f>this.max_high){f=this.max_high}if(this.high!==0&&d<this.min_separation){f=b+this.min_separation}this.low=Math.floor(b);th
is.high=Math.ceil(f);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));var e=(this.low/(this.max_high-this.max_low))*this.overview_viewport.width();var g=(this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width();this.overview_box.css({left:e,width:Math.max(12,g)}).show();if(this.overview_highlight){this.overview_highlight.css({left:e,width:g})}this.update_location(this.low,this.high);if(!h){for(var c=0,a=this.tracks.length;c<a;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,a=this.label_tracks.length;c<a;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.high-this.low)+thi
s.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b=this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()}});var Track=function(b,a,c){this.name=b;this.parent_element=c;this.view=a;this.init_global()};$.extend(Track.prototype,{init_global:function(){this.container_div=$("<div />").addClass("track");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div);this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name)}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.con
tent_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.view.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("he
ight",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){var d=this,c=d.view;if(d.hidden){return}if(d.display_modes!==undefined){if(d.mode_div===undefined){d.mode_div=$("<div class='right-float menubutton popup' />").appendTo(d.header_div);var h=d.display_modes[0];d.mode=h;d.mode_div.text(h);var a=function(j){d.mode_div.text(j);d.mode=j;d.tile_cache.clear();d.draw()};var f={};for(var e in d.display_modes){var g=d.display_modes[e];f[g]=function(j){return function(){a(j)}}(g)}make_popupmenu(d.mode_div,f)}else{d.mode_div.hide()}}var b={};b["Set track as overview"]=function(){c.overview_viewport.find("canvas").remove();d.is_overview=true;d.set_overview();for(var j in c.tracks){if(c.tracks[j]!==d){c.tracks[j].is_overview=false}}};b["Edit configuration"]=function(){var k=function(){hide_modal()};var j=function(){d.update_options(d.track_id);hide_modal()};show_modal("Configure Trac
k",d.gen_options(d.track_id),{Cancel:k,OK:j})};b.Remove=function(){c.remove_track(d);if(c.num_tracks===0){$("#no-tracks").show()}};make_popupmenu(d.name_div,b)};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(){var j=this.view.low,e=this.view.high,f=e-j,d=this.view.resolution;var l=$("<div style='position: relative;'></div>"),m=this.content_div.width()/f,h;this.content_div.children(":first").remove();this.content_div.append(l),this.max_height=0;var a=Math.floor(j/d/DENSITY);while((a*DENSITY*d)<e){var k=this.content_div.width()+"_"+m+"_"+a;var c=this.tile_cache.get(k);if(c){var g=a*DENSITY*d;var b=(g-j)*m;if(this.left_offset){b-=this.left_offset}c.css({left:b});l.append(c);this.max_height=Math.max(this.max_height,c.height());this.content_div.css("height",this.max_height+"px")}else{this.delayed_draw(this,k,j,e,a,d,l,m)}a+=1}},delayed_draw:function(c,e,a,f,b,d,g,h){setTimeout(function(){if(!(a>c.view.high||f<c.view.low)){tile_element=c.draw_tile(d,b,g,h);if(tile_el
ement){if(!c.initial_canvas){c.initial_canvas=$(tile_element).clone();var l=tile_element.get(0).getContext("2d");var j=c.initial_canvas.get(0).getContext("2d");var k=l.getImageData(0,0,l.canvas.width,l.canvas.height);j.putImageData(k,0,0);c.set_overview()}c.tile_cache.set(e,tile_element);c.max_height=Math.max(c.max_height,tile_element.height());c.content_div.css("height",c.max_height+"px")}}},50)},set_overview:function(){var a=this.view;a.overview_viewport.height(a.default_overview_height);a.overview_box.height(a.default_overview_height);if(this.initial_canvas&&this.is_overview){if(!a.overview_highlight){a.overview_highlight=$("<div />").addClass("overview-highlight").appendTo(a.overview_viewport)}a.overview_viewport.append(this.initial_canvas);a.overview_highlight.height(this.initial_canvas.height());a.overview_viewport.height(this.initial_canvas.height()+a.overview_box.height())}$(window).trigger("resize")}});var LabelTrack=function(a,b){this.track_type="LabelTrack";this.h
idden=true;Track.call(this,null,a,b);this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";this.hidden=true;Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.height_px=12;this.container_div.addClass("reference-track");this.dummy_canvas=$("<canvas></canvas>").get(0).getContext("2d");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.proto
type,{get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(f,b,k,o){var g=b*DENSITY*f,d=DENSITY*f,e=$("<canvas class='tile'></canvas>"),n=e.get(0).getContext("2d"),j=f+"_"+b;if(o>PX_PER_CHAR){if(this.data_cache.get(j)===undefined){this.get_data(f,b);return}var m=this.data_cache.get(j);if(m===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*o+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*o-this.left_offset});for(var h=0,l=m.length;h<l;h++){var a=Math.round(h*o);n.fillText(m[h],a+this.left_offset,10)}k.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=function(d,b
,a,c){this.track_type="LineTrack";this.display_modes=["Line","Filled","Intensity"];this.mode="Line";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=80;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={min_value:undefined,max_value:undefined,mode:"Line"};if(c.min_value!==undefined){this.prefs.min_value=c.min_value}if(c.max_value!==undefined){this.prefs.max_value=c.max_value}};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").val(a.prefs.max_value)}a.
vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;$("#linetrack_"+b+"_minval").remove();$("#linetrack_"+b+"_maxval").remove();var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"relative",top:"32px",left:"10px"});d.prependTo(a.container_div);e.css({position:"relative",top:a.height_px+32+"px",left:"10px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(p,r,c,
e){if(this.vertical_range===undefined){return}var s=r*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),v=p+"_"+r;if(this.data_cache.get(v)===undefined){this.get_data(p,r);return}var j=this.data_cache.get(v);if(j===null){return}b.css({position:"absolute",top:0,left:(s-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,t=this.total_frequency,d=this.height_px,m=this.mode;o.beginPath();if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}var u,h;for(var q=0;q<data.length;q++){u=(data[q][0]-s)*e;h=data[q][1];if(m=="Intensity"){if(h===null){continue}if(h<=l){h=l}else{if(h>=g){h=g}}h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")";o.fillRect(u,0,f,this.height_px)}else{if(h===null){if(k&&m==="Filled"){o.lineTo(u,d)}k=false;continue}else{if(h<=l){h=l}else{if(h>=g){h=g}}h=Math.round(d-(h-l)/n*d);if(k)
{o.lineTo(u,h)}else{k=true;if(m==="Filled"){o.moveTo(u,d);o.lineTo(u,h)}else{o.moveTo(u,h)}}}}}if(m==="Filled"){if(k){o.lineTo(u,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(k){var a=$("<div />").addClass("form-row");var e="track_"+k+"_minval",h=$("<label></label>").attr("for",e).text("Min value:"),b=(this.prefs.min_value===undefined?"":this.prefs.min_value),j=$("<input></input>").attr("id",e).val(b),g="track_"+k+"_maxval",d=$("<label></label>").attr("for",g).text("Max value:"),f=(this.prefs.max_value===undefined?"":this.prefs.max_value),c=$("<input></input>").attr("id",g).val(f);return a.append(h).append(j).append(d).append(c)},update_options:function(c){var a=$("#track_"+c+"_minval").val(),b=$("#track_"+c+"_maxval").val();if(a!==this.prefs.min_value||b!==this.prefs.max_value){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(b);this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+c+"_minval").text(this.pre
fs.min_value);$("#linetrack_"+c+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,c){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=2;this.summary_draw_height=20;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.left_offset=200;this.prefs={block_color:"black",label_color:"black",show_counts:true};if(c.block_color!==undefined){this.prefs.block_color=c.block_color}if(c.label_color!==undefined){this.prefs.label_color=c.label_color}if(c.show_counts!==undefined){this.prefs.sh
ow_counts=c.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b="initial";this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution,mode:a.mode},function(c){a.mode_div.show();a.data_cache.set(b,c);a.draw()})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_
e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(this.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.measureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(true){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_tile[a][v].length;u<A;u++){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=[]}this.s_e_by_tile[a][v].push([e,f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(n,o,f,m,b,d,k,e,h){n.textAlign="center";var j=Math.round(o/2);if((this.mode==="Pack"||this.mode==="Auto")&&d!==undefined&&o>PX_PER_CHAR){n.fillStyle=this.prefs.block_color;n.fillRect(k,h+1,e,9);n.fillStyle="#eee";f
or(var g=0,l=d.length;g<l;g++){if(b+g>=f&&b+g<=m){var a=Math.floor(Math.max(0,(b+g-f)*o));n.fillText(d[g],a+this.left_offset+j,h+9)}}}else{n.fillStyle=this.prefs.block_color;n.fillRect(k,h+4,e,3)}},draw_tile:function(aa,l,o,an){var H=l*DENSITY*aa,ag=(l+1)*DENSITY*aa,G=ag-H;var ah=(!this.initial_canvas?"initial":H+"_"+ag);var C=this.data_cache.get(ah);var d;if(C===undefined||(this.mode!=="Auto"&&C.dataset_type==="summary_tree")){this.data_queue[[H,ag]]=true;this.get_data(H,ag);return}var a=Math.ceil(G*an),O=$("<canvas class='tile'></canvas>"),ac=this.prefs.label_color,g=this.prefs.block_color,n=this.mode,r=25,Y=(n==="Squish")||(n==="Dense")&&(n!=="Pack")||(n==="Auto"&&(C.extra_info==="no_detail")),S=this.left_offset,am,v,ao;if(C.dataset_type==="summary_tree"){v=this.summary_draw_height}else{if(n==="Dense"){v=r;ao=10}else{ao=(Y?this.vertical_nodetail_px:this.vertical_detail_px);var s=(an<0.0001?1/view.zoom_res:an);v=this.incremental_slots(s,C.data,Y,n)*ao+r;am=this.inc_slots[s
]}}O.css({position:"absolute",top:0,left:(H-this.view.low)*an-S});O.get(0).width=a+S;O.get(0).height=v;o.parent().css("height",Math.max(this.height_px,v)+"px");var D=O.get(0).getContext("2d");D.fillStyle=g;D.font=this.default_font;D.textAlign="right";if(C.dataset_type=="summary_tree"){var N,K=55,af=255-K,h=af*2/3,U=C.data,F=C.max,m=C.avg,b=Math.ceil(C.delta*an);for(var aj=0,B=U.length;aj<B;aj++){var W=Math.floor((U[aj][0]-H)*an);var V=U[aj][1];if(!V){continue}N=Math.floor(af-(V/F)*af);D.fillStyle="rgb("+N+","+N+","+N+")";D.fillRect(W+S,0,b,this.summary_draw_height);if(this.prefs.show_counts&&D.measureText(V).width<b){if(N>h){D.fillStyle="black"}else{D.fillStyle="#ddd"}D.textAlign="center";D.fillText(V,W+S+(b/2),12)}}d="Summary";o.append(O);return O}if(C.message){O.css({border:"solid red","border-width":"2px 2px 2px 0px"});D.fillStyle="red";D.textAlign="left";D.fillText(C.message,100+S,ao)}var al=C.data;var ai=0;for(var aj=0,B=al.length;aj<B;aj++){var P=al[aj],M=P[0],ak=P[1],
X=P[2],I=P[3];if(ak<=ag&&X>=H){var Z=Math.floor(Math.max(0,(ak-H)*an)),E=Math.ceil(Math.min(a,Math.max(0,(X-H)*an))),T=(n==="Dense"?1:(1+am[M]))*ao;if(C.dataset_type==="bai"){D.fillStyle=g;if(P[4] instanceof Array){var w=Math.floor(Math.max(0,(P[4][0]-H)*an)),L=Math.ceil(Math.min(a,Math.max(0,(P[4][1]-H)*an))),u=Math.floor(Math.max(0,(P[5][0]-H)*an)),q=Math.ceil(Math.min(a,Math.max(0,(P[5][1]-H)*an)));if(P[4][1]>=H&&P[4][0]<=ag){this.rect_or_text(D,an,H,ag,P[4][0],P[4][2],w+S,L-w,T)}if(P[5][1]>=H&&P[5][0]<=ag){this.rect_or_text(D,an,H,ag,P[5][0],P[5][2],u+S,q-u,T)}if(u>L){D.fillStyle="#999";D.fillRect(L+S,T+5,u-L,1)}}else{D.fillStyle=g;this.rect_or_text(D,an,H,ag,ak,I,Z+S,E-Z,T)}if(n!=="Dense"&&!Y&&ak>H){D.fillStyle=this.prefs.label_color;if(l===0&&Z-D.measureText(I).width<0){D.textAlign="left";D.fillText(M,E+2+S,T+8)}else{D.textAlign="right";D.fillText(M,Z-2+S,T+8)}D.fillStyle=g}}else{if(C.dataset_type==="interval_index"){if(Y){D.fillStyle=g;D.fillRect(Z+S,T+5,E-Z,1)}else{v
ar A=P[4],R=P[5],ab=P[6],f=P[7];var z,ad,J=null,ap=null;if(R&&ab){J=Math.floor(Math.max(0,(R-H)*an));ap=Math.ceil(Math.min(a,Math.max(0,(ab-H)*an)))}if(n!=="Dense"&&I!==undefined&&ak>H){D.fillStyle=ac;if(l===0&&Z-D.measureText(I).width<0){D.textAlign="left";D.fillText(I,E+2+S,T+8)}else{D.textAlign="right";D.fillText(I,Z-2+S,T+8)}D.fillStyle=g}if(f){if(A){if(A=="+"){D.fillStyle=RIGHT_STRAND}else{if(A=="-"){D.fillStyle=LEFT_STRAND}}D.fillRect(Z+S,T,E-Z,10);D.fillStyle=g}for(var ah=0,e=f.length;ah<e;ah++){var p=f[ah],c=Math.floor(Math.max(0,(p[0]-H)*an)),Q=Math.ceil(Math.min(a,Math.max((p[1]-H)*an)));if(c>Q){continue}z=5;ad=3;D.fillRect(c+S,T+ad,Q-c,z);if(J!==undefined&&!(c>ap||Q<J)){z=9;ad=1;var ae=Math.max(c,J),t=Math.min(Q,ap);D.fillRect(ae+S,T+ad,t-ae,z)}}}else{z=9;ad=1;D.fillRect(Z+S,T+ad,E-Z,z);if(P.strand){if(P.strand=="+"){D.fillStyle=RIGHT_STRAND_INV}else{if(P.strand=="-"){D.fillStyle=LEFT_STRAND_INV}}D.fillRect(Z+S,T,E-Z,10);D.fillStyle=g}}}}}ai++}}o.append(O);return
O},gen_options:function(j){var a=$("<div />").addClass("form-row");var e="track_"+j+"_block_color",l=$("<label />").attr("for",e).text("Block color:"),m=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),k="track_"+j+"_label_color",g=$("<label />").attr("for",k).text("Text color:"),h=$("<input />").attr("id",k).attr("name",k).val(this.prefs.label_color),f="track_"+j+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(l).append(m).append(g).append(h).append(d)},update_options:function(e){var b=$("#track_"+e+"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_c
olor=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,c){FeatureTrack.call(this,d,b,a,c);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
+var DENSITY=200,FEATURE_LEVELS=10,MAX_FEATURE_DEPTH=100,DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),PX_PER_CHAR=CONTEXT.measureText("A").width,RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/strand_right_inv.png";right_img_inv.onload=function()
{RIGHT_STRAND_INV=CONTEXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,c,e,d,b){this.container=a;this.vis_id=d;this.dbkey=b;this.title=e;this.chrom=c;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.
min_separation=30;this.has_changes=false;this.init();this.reset()};$.extend(View.prototype,{init:function(){var c=this.container,a=this;this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(c);this.content_div=$("<div/>").addClass("content").css("position","relative").hide().appendTo(c);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide().appendTo(c);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.nav_container=$("<div/>").addClass("nav-container").appendTo(c);this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.nav);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_box_background=$("<div/>").addClass("overview-boxback").app
endTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){void (0)}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);var b=function(d){if(d.type==="focusout"||(d.keyCode||d.which)===13||(d.keyCode||d.which)===27){if((d.keyCode||d.which)!==27){a.go_to($(this).val())}$(this).hide();a.location_span.show();a.chrom_select.show();return false}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keypress focusout",b).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);this.location_span.bind("click",function(){a.location_span.hi
de();a.chrom_select.hide();a.nav_input.css("display","inline-block");a.nav_input.select();a.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.zo_link=$("<a/>").click(function(){a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);this.zi_link=$("<a/>").click(function(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(d){if(d.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=d.chrom_info;var f='<option value="">Select Chrom/Contig</option>';for(i in a.chrom_data){var e=a.chrom_data[i]["chrom"];f+='<option value="'+e+'">'+e+"</option>"}a.chrom_select.html(f);a.intro_div.show();a.content_div.hide();a.chrom_select.b
ind("change",function(){a.change_chrom(a.chrom_select.val())})},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("dblclick",function(d){a.zoom_in(d.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(d){this.current_x=d.offsetX}).bind("drag",function(d){var g=d.offsetX-this.current_x;this.current_x=d.offsetX;var f=Math.round(g/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-f)});this.viewport_container.bind("dragstart",function(d){this.original_low=a.low;this.current_height=d.clientY;this.current_x=d.offsetX;this.enable_pan=(d.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(g){if(!this.enable_pan||this.in_reordering){return}var d=$(this);var j=g.offsetX-this.current_x;var f=d.scrollTop()-(g.clientY-this.current_height);d.scrollTop(f);this.current_height=g.clientY;this.current_x=g.offsetX;var h=Math.round(j/a.viewport_container.width()*(a.high-a.low));a.move_
delta(h)});this.top_labeltrack.bind("dragstart",function(d){this.drag_origin_x=d.clientX;this.drag_origin_pos=d.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_div=$("<div />").css({height:a.content_div.height()+30,top:"0px",position:"absolute","background-color":"#cfc",border:"1px solid #6a6",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(j){var f=Math.min(j.clientX,this.drag_origin_x)-a.container.offset().left,d=Math.max(j.clientX,this.drag_origin_x)-a.container.offset().left,h=(a.high-a.low),g=a.viewport_container.width();a.update_location(Math.round(f/g*h)+a.low,Math.round(d/g*h)+a.low);this.drag_div.css({left:f+"px",width:(d-f)+"px"})}).bind("dragend",function(k){var f=Math.min(k.clientX,this.drag_origin_x),d=Math.max(k.clientX,this.drag_origin_x),h=(a.high-a.low),g=a.viewport_container.width(),j=a.low;a.low=Math.round(f/g*h)+j;a.high=Math.round(d/g*h)+j;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(th
is,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack))},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(d,a,f){var c=this;var e=$.grep(c.chrom_data,function(h,j){return h.chrom===d})[0];if(e===undefined){return}if(d!==c.chrom){c.chrom=d;if(c.chrom===""){c.intro_div.show();c.content_div.hide()}else{c.intro_div.hide();c.content_div.show()}c.chrom_select.val(c.chrom);c.max_high=e.len;c.reset();c.redraw(true);for(var g in c.tracks){var b=c.tracks[g];if(b.init){b.init()}}}if(a!==undefined&&f!==undefined){c.low=Math.max(a,0);c.high=Math.min(f,c.max_high)}c.overview_viewport.find("canvas").remove();c.redraw()},go_to:function(f){var k=this,b=f.split(":"),h=b[0],j=b[1];if(j!==undefined){try{var g=j.split("-"),a=parseInt(g[0].replace(/,/g,"")),d=parseInt(g[1].replace(/,/g,""))}catch(c){return false}}k.change_chrom(h,a,d)},move_
delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.high-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(h){var d=this.high-this.low,b=this.low,f=this.high;if(b<this.max_low){b=this.max_low}if(f>this.max_high){f=this.max_high}if(this.high!==0&&d<this.min_separation){f=b+this.min_separation}this.low=Math.floor(b);th
is.high=Math.ceil(f);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));var e=(this.low/(this.max_high-this.max_low))*this.overview_viewport.width();var g=(this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width();this.overview_box.css({left:e,width:Math.max(12,g)}).show();if(this.overview_highlight){this.overview_highlight.css({left:e,width:g})}this.update_location(this.low,this.high);if(!h){for(var c=0,a=this.tracks.length;c<a;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,a=this.label_tracks.length;c<a;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.high-this.low)+thi
s.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b=this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()}});var Track=function(b,a,c){this.name=b;this.parent_element=c;this.view=a;this.init_global()};$.extend(Track.prototype,{init_global:function(){this.container_div=$("<div />").addClass("track");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div);this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name)}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.con
tent_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.view.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("he
ight",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){var d=this,c=d.view;if(d.hidden){return}if(d.display_modes!==undefined){if(d.mode_div===undefined){d.mode_div=$("<div class='right-float menubutton popup' />").appendTo(d.header_div);var h=d.display_modes[0];d.mode=h;d.mode_div.text(h);var a=function(j){d.mode_div.text(j);d.mode=j;d.tile_cache.clear();d.draw()};var f={};for(var e in d.display_modes){var g=d.display_modes[e];f[g]=function(j){return function(){a(j)}}(g)}make_popupmenu(d.mode_div,f)}else{d.mode_div.hide()}}var b={};b["Set track as overview"]=function(){c.overview_viewport.find("canvas").remove();d.is_overview=true;d.set_overview();for(var j in c.tracks){if(c.tracks[j]!==d){c.tracks[j].is_overview=false}}};b["Edit configuration"]=function(){var k=function(){hide_modal()};var j=function(){d.update_options(d.track_id);hide_modal()};show_modal("Configure Trac
k",d.gen_options(d.track_id),{Cancel:k,OK:j})};b.Remove=function(){c.remove_track(d);if(c.num_tracks===0){$("#no-tracks").show()}};make_popupmenu(d.name_div,b)};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(){var j=this.view.low,e=this.view.high,f=e-j,d=this.view.resolution;var l=$("<div style='position: relative;'></div>"),m=this.content_div.width()/f,h;this.content_div.children(":first").remove();this.content_div.append(l),this.max_height=0;var a=Math.floor(j/d/DENSITY);while((a*DENSITY*d)<e){var k=this.content_div.width()+"_"+m+"_"+a;var c=this.tile_cache.get(k);if(c){var g=a*DENSITY*d;var b=(g-j)*m;if(this.left_offset){b-=this.left_offset}c.css({left:b});l.append(c);this.max_height=Math.max(this.max_height,c.height());this.content_div.css("height",this.max_height+"px")}else{this.delayed_draw(this,k,j,e,a,d,l,m)}a+=1}},delayed_draw:function(c,e,a,f,b,d,g,h){setTimeout(function(){if(!(a>c.view.high||f<c.view.low)){tile_element=c.draw_tile(d,b,g,h);if(tile_el
ement){if(!c.initial_canvas){c.initial_canvas=$(tile_element).clone();var l=tile_element.get(0).getContext("2d");var j=c.initial_canvas.get(0).getContext("2d");var k=l.getImageData(0,0,l.canvas.width,l.canvas.height);j.putImageData(k,0,0);c.set_overview()}c.tile_cache.set(e,tile_element);c.max_height=Math.max(c.max_height,tile_element.height());c.content_div.css("height",c.max_height+"px")}}},50)},set_overview:function(){var a=this.view;a.overview_viewport.height(a.default_overview_height);a.overview_box.height(a.default_overview_height);if(this.initial_canvas&&this.is_overview){if(!a.overview_highlight){a.overview_highlight=$("<div />").addClass("overview-highlight").appendTo(a.overview_viewport)}a.overview_viewport.append(this.initial_canvas);a.overview_highlight.height(this.initial_canvas.height());a.overview_viewport.height(this.initial_canvas.height()+a.overview_box.height())}$(window).trigger("resize")}});var LabelTrack=function(a,b){this.track_type="LabelTrack";this.h
idden=true;Track.call(this,null,a,b);this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";this.hidden=true;Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.height_px=12;this.container_div.addClass("reference-track");this.dummy_canvas=$("<canvas></canvas>").get(0).getContext("2d");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.proto
type,{get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(f,b,k,o){var g=b*DENSITY*f,d=DENSITY*f,e=$("<canvas class='tile'></canvas>"),n=e.get(0).getContext("2d"),j=f+"_"+b;if(o>PX_PER_CHAR){if(this.data_cache.get(j)===undefined){this.get_data(f,b);return}var m=this.data_cache.get(j);if(m===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*o+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*o-this.left_offset});for(var h=0,l=m.length;h<l;h++){var a=Math.round(h*o);n.fillText(m[h],a+this.left_offset,10)}k.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=function(d,b
,a,c){this.track_type="LineTrack";this.display_modes=["Line","Filled","Intensity"];this.mode="Line";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=80;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={min_value:undefined,max_value:undefined,mode:"Line"};if(c.min_value!==undefined){this.prefs.min_value=c.min_value}if(c.max_value!==undefined){this.prefs.max_value=c.max_value}};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").val(a.prefs.max_value)}a.
vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;$("#linetrack_"+b+"_minval").remove();$("#linetrack_"+b+"_maxval").remove();var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"relative",top:"32px",left:"10px"});d.prependTo(a.container_div);e.css({position:"relative",top:a.height_px+32+"px",left:"10px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(p,r,c,
e){if(this.vertical_range===undefined){return}var s=r*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),v=p+"_"+r;if(this.data_cache.get(v)===undefined){this.get_data(p,r);return}var j=this.data_cache.get(v);if(j===null){return}b.css({position:"absolute",top:0,left:(s-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,t=this.total_frequency,d=this.height_px,m=this.mode;o.beginPath();if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}var u,h;for(var q=0;q<data.length;q++){u=(data[q][0]-s)*e;h=data[q][1];if(m=="Intensity"){if(h===null){continue}if(h<=l){h=l}else{if(h>=g){h=g}}h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")";o.fillRect(u,0,f,this.height_px)}else{if(h===null){if(k&&m==="Filled"){o.lineTo(u,d)}k=false;continue}else{if(h<=l){h=l}else{if(h>=g){h=g}}h=Math.round(d-(h-l)/n*d);if(k)
{o.lineTo(u,h)}else{k=true;if(m==="Filled"){o.moveTo(u,d);o.lineTo(u,h)}else{o.moveTo(u,h)}}}}}if(m==="Filled"){if(k){o.lineTo(u,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(k){var a=$("<div />").addClass("form-row");var e="track_"+k+"_minval",h=$("<label></label>").attr("for",e).text("Min value:"),b=(this.prefs.min_value===undefined?"":this.prefs.min_value),j=$("<input></input>").attr("id",e).val(b),g="track_"+k+"_maxval",d=$("<label></label>").attr("for",g).text("Max value:"),f=(this.prefs.max_value===undefined?"":this.prefs.max_value),c=$("<input></input>").attr("id",g).val(f);return a.append(h).append(j).append(d).append(c)},update_options:function(c){var a=$("#track_"+c+"_minval").val(),b=$("#track_"+c+"_maxval").val();if(a!==this.prefs.min_value||b!==this.prefs.max_value){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(b);this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+c+"_minval").text(this.pre
fs.min_value);$("#linetrack_"+c+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,c){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=2;this.summary_draw_height=20;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.left_offset=200;this.prefs={block_color:"black",label_color:"black",show_counts:true};if(c.block_color!==undefined){this.prefs.block_color=c.block_color}if(c.label_color!==undefined){this.prefs.label_color=c.label_color}if(c.show_counts!==undefined){this.prefs.sh
ow_counts=c.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b="initial";this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution,mode:a.mode},function(c){a.mode_div.show();a.data_cache.set(b,c);a.draw()})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_
e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(this.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.measureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(true){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_tile[a][v].length;u<A;u++){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=[]}this.s_e_by_tile[a][v].push([e,f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(n,o,f,m,b,d,k,e,h){n.textAlign="center";var j=Math.round(o/2);if((this.mode==="Pack"||this.mode==="Auto")&&d!==undefined&&o>PX_PER_CHAR){n.fillStyle=this.prefs.block_color;n.fillRect(k,h+1,e,9);n.fillStyle="#eee";f
or(var g=0,l=d.length;g<l;g++){if(b+g>=f&&b+g<=m){var a=Math.floor(Math.max(0,(b+g-f)*o));n.fillText(d[g],a+this.left_offset+j,h+9)}}}else{n.fillStyle=this.prefs.block_color;n.fillRect(k,h+4,e,3)}},draw_tile:function(ae,o,r,ar){var L=o*DENSITY*ae,ak=(o+1)*DENSITY*ae,K=ak-L;var al=(!this.initial_canvas?"initial":L+"_"+ak);var G=this.data_cache.get(al);var e;if(G===undefined||(this.mode!=="Auto"&&G.dataset_type==="summary_tree")){this.data_queue[[L,ak]]=true;this.get_data(L,ak);return}var a=Math.ceil(K*ar),S=$("<canvas class='tile'></canvas>"),ag=this.prefs.label_color,h=this.prefs.block_color,q=this.mode,v=25,ac=(q==="Squish")||(q==="Dense")&&(q!=="Pack")||(q==="Auto"&&(G.extra_info==="no_detail")),W=this.left_offset,aq,B,at;if(G.dataset_type==="summary_tree"){B=this.summary_draw_height}else{if(q==="Dense"){B=v;at=10}else{at=(ac?this.vertical_nodetail_px:this.vertical_detail_px);var w=(ar<0.0001?1/view.zoom_res:ar);B=this.incremental_slots(w,G.data,ac,q)*at+v;aq=this.inc_slot
s[w]}}S.css({position:"absolute",top:0,left:(L-this.view.low)*ar-W});S.get(0).width=a+W;S.get(0).height=B;r.parent().css("height",Math.max(this.height_px,B)+"px");var H=S.get(0).getContext("2d");H.fillStyle=h;H.font=this.default_font;H.textAlign="right";if(G.dataset_type=="summary_tree"){var R,O=55,aj=255-O,n=aj*2/3,Y=G.data,J=G.max,p=G.avg,b=Math.ceil(G.delta*ar);for(var an=0,F=Y.length;an<F;an++){var aa=Math.floor((Y[an][0]-L)*ar);var Z=Y[an][1];if(!Z){continue}R=Math.floor(aj-(Z/J)*aj);H.fillStyle="rgb("+R+","+R+","+R+")";H.fillRect(aa+W,0,b,this.summary_draw_height);if(this.prefs.show_counts&&H.measureText(Z).width<b){if(R>n){H.fillStyle="black"}else{H.fillStyle="#ddd"}H.textAlign="center";H.fillText(Z,aa+W+(b/2),12)}}e="Summary";r.append(S);return S}if(G.message){S.css({border:"solid red","border-width":"2px 2px 2px 0px"});H.fillStyle="red";H.textAlign="left";H.fillText(G.message,100+W,at)}var ap=G.data;var am=0;for(var an=0,F=ap.length;an<F;an++){var T=ap[an],Q=T[0],ao
=T[1],ab=T[2],M=T[3];if(ao<=ak&&ab>=L){var ad=Math.floor(Math.max(0,(ao-L)*ar)),I=Math.ceil(Math.min(a,Math.max(0,(ab-L)*ar))),X=(q==="Dense"?1:(1+aq[Q]))*at;if(G.dataset_type==="bai"){H.fillStyle=h;if(T[4] instanceof Array){var C=Math.floor(Math.max(0,(T[4][0]-L)*ar)),P=Math.ceil(Math.min(a,Math.max(0,(T[4][1]-L)*ar))),A=Math.floor(Math.max(0,(T[5][0]-L)*ar)),u=Math.ceil(Math.min(a,Math.max(0,(T[5][1]-L)*ar)));if(T[4][1]>=L&&T[4][0]<=ak){this.rect_or_text(H,ar,L,ak,T[4][0],T[4][2],C+W,P-C,X)}if(T[5][1]>=L&&T[5][0]<=ak){this.rect_or_text(H,ar,L,ak,T[5][0],T[5][2],A+W,u-A,X)}if(A>P){H.fillStyle="#999";H.fillRect(P+W,X+5,A-P,1)}}else{H.fillStyle=h;this.rect_or_text(H,ar,L,ak,ao,M,ad+W,I-ad,X)}if(q!=="Dense"&&!ac&&ao>L){H.fillStyle=this.prefs.label_color;if(o===0&&ad-H.measureText(M).width<0){H.textAlign="left";H.fillText(Q,I+2+W,X+8)}else{H.textAlign="right";H.fillText(Q,ad-2+W,X+8)}H.fillStyle=h}}else{if(G.dataset_type==="interval_index"){if(ac){H.fillStyle=h;H.fillRect(ad+W,
X+5,I-ad,1)}else{var E=T[4],V=T[5],af=T[6],g=T[7];var D,ah,N=null,au=null;if(V&&af){N=Math.floor(Math.max(0,(V-L)*ar));au=Math.ceil(Math.min(a,Math.max(0,(af-L)*ar)))}if(q!=="Dense"&&M!==undefined&&ao>L){H.fillStyle=ag;if(o===0&&ad-H.measureText(M).width<0){H.textAlign="left";H.fillText(M,I+2+W,X+8)}else{H.textAlign="right";H.fillText(M,ad-2+W,X+8)}H.fillStyle=h}if(g){if(E){if(E=="+"){H.fillStyle=RIGHT_STRAND}else{if(E=="-"){H.fillStyle=LEFT_STRAND}}H.fillRect(ad+W,X,I-ad,10);H.fillStyle=h}for(var al=0,f=g.length;al<f;al++){var t=g[al],d=Math.floor(Math.max(0,(t[0]-L)*ar)),U=Math.ceil(Math.min(a,Math.max((t[1]-L)*ar)));if(d>U){continue}D=5;ah=3;H.fillRect(d+W,X+ah,U-d,D);if(N!==undefined&&!(d>au||U<N)){D=9;ah=1;var ai=Math.max(d,N),z=Math.min(U,au);H.fillRect(ai+W,X+ah,z-ai,D)}}}else{D=9;ah=1;H.fillRect(ad+W,X+ah,I-ad,D);if(T.strand){if(T.strand=="+"){H.fillStyle=RIGHT_STRAND_INV}else{if(T.strand=="-"){H.fillStyle=LEFT_STRAND_INV}}H.fillRect(ad+W,X,I-ad,10);H.fillStyle=h}}}}
else{if(G.dataset_type==="vcf"){if(ac){H.fillStyle=h;H.fillRect(ad+W,X+5,I-ad,1)}else{var s=T[4],m=T[5],c=T[6];D=9;ah=1;H.fillRect(ad+W,X,I-ad,D);if(q!=="Dense"&&M!==undefined&&ao>L){H.fillStyle=ag;if(o===0&&ad-H.measureText(M).width<0){H.textAlign="left";H.fillText(M,I+2+W,X+8)}else{H.textAlign="right";H.fillText(M,ad-2+W,X+8)}H.fillStyle=h}var l=s+" / "+m;if(ao>L&&H.measureText(l).width<(I-ad)){H.fillStyle="white";H.textAlign="center";H.fillText(l,W+ad+(I-ad)/2,X+8);H.fillStyle=h}}}}}am++}}r.append(S);return S},gen_options:function(j){var a=$("<div />").addClass("form-row");var e="track_"+j+"_block_color",l=$("<label />").attr("for",e).text("Block color:"),m=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),k="track_"+j+"_label_color",g=$("<label />").attr("for",k).text("Text color:"),h=$("<input />").attr("id",k).attr("name",k).val(this.prefs.label_color),f="track_"+j+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input
type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(l).append(m).append(g).append(h).append(d)},update_options:function(e){var b=$("#track_"+e+"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,c){FeatureTrack.call(this,d,b,a,c);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -1348,8 +1348,45 @@ var FeatureTrack = function ( name, view
}
ctx.fillRect(f_start + left_offset, y_center, f_end - f_start, 10);
ctx.fillStyle = block_color;
+ }
+ }
+ }
+ } else if (result.dataset_type === 'vcf') {
+ if (no_detail) {
+ ctx.fillStyle = block_color;
+ ctx.fillRect(f_start + left_offset, y_center + 5, f_end - f_start, 1);
+ }
+ else { // Show blocks, labels, etc.
+ // Unpack.
+ var ref_base = feature[4], alt_base = feature[5], qual = feature[6];
+
+ // Draw block for entry.
+ thickness = 9;
+ y_start = 1;
+ ctx.fillRect(f_start + left_offset, y_center, f_end - f_start, thickness);
+
+ // Add label for entry.
+ if (mode !== "Dense" && feature_name !== undefined && feature_start > tile_low) {
+ // Draw label
+ ctx.fillStyle = label_color;
+ if (tile_index === 0 && f_start - ctx.measureText(feature_name).width < 0) {
+ ctx.textAlign = "left";
+ ctx.fillText(feature_name, f_end + 2 + left_offset, y_center + 8);
+ } else {
+ ctx.textAlign = "right";
+ ctx.fillText(feature_name, f_start - 2 + left_offset, y_center + 8);
}
+ ctx.fillStyle = block_color;
}
+
+ // Show additional data on block.
+ var vcf_label = ref_base + " / " + alt_base;
+ if (feature_start > tile_low && ctx.measureText(vcf_label).width < (f_end - f_start)) {
+ ctx.fillStyle = "white";
+ ctx.textAlign = "center";
+ ctx.fillText(vcf_label, left_offset + f_start + (f_end-f_start)/2, y_center + 8);
+ ctx.fillStyle = block_color;
+ }
}
}
j++;
--- a/lib/galaxy/web/controllers/tracks.py
+++ b/lib/galaxy/web/controllers/tracks.py
@@ -24,6 +24,7 @@ from galaxy.visualization.tracks.data.ar
from galaxy.visualization.tracks.data.interval_index import IntervalIndexDataProvider
from galaxy.visualization.tracks.data.bam import BamDataProvider
from galaxy.visualization.tracks.data.summary_tree import SummaryTreeDataProvider
+from galaxy.visualization.tracks.data.vcf import VCFDataProvider
# Message strings returned to browser
messages = Bunch(
@@ -36,10 +37,11 @@ messages = Bunch(
)
# Mapping from dataset type to a class that can fetch data from a file of that
-# type. This also needs to be more flexible.
+# type. First key is converted dataset type; if result is another dict, second key
+# is original dataset type. TODO: This needs to be more flexible.
dataset_type_to_data_provider = {
"array_tree": ArrayTreeDataProvider,
- "interval_index": IntervalIndexDataProvider,
+ "interval_index": { "vcf": VCFDataProvider, "default" : IntervalIndexDataProvider },
"bai": BamDataProvider,
"summary_tree": SummaryTreeDataProvider
}
@@ -300,15 +302,28 @@ class TracksController( BaseController,
frequencies, max_v, avg_v, delta = summary
return { 'dataset_type': data_sources['index'], 'data': frequencies, 'max': max_v, 'avg': avg_v, 'delta': delta }
- dataset_type = data_sources['data']
- data_provider = dataset_type_to_data_provider[ dataset_type ]( dataset.get_converted_dataset(trans, dataset_type), dataset )
+ # Get data provider.
+ tracks_dataset_type = data_sources['data']
+ value = dataset_type_to_data_provider[ tracks_dataset_type ]
+ if isinstance( value, dict ):
+ # Get converter by dataset extension; if there is no data provider,
+ # get the default
+ data_provider_class = value.get( dataset.ext, value.get( "default" ) )
+ else:
+ data_provider_class = value
+ 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 )
message = None
if isinstance(data, dict) and 'message' in data:
message = data['message']
- data = data['data']
- return { 'dataset_type': dataset_type, 'extra_info': extra_info, 'data': data, 'message': message }
+ dataset_type = data.get( 'data_type', tracks_dataset_type )
+ track_data = data['data']
+ else:
+ track_data = data
+ return { 'dataset_type': dataset_type, 'extra_info': extra_info, 'data': track_data, 'message': message }
+
@web.json
def save( self, trans, **kwargs ):
--- a/lib/galaxy/visualization/tracks/data/array_tree.py
+++ b/lib/galaxy/visualization/tracks/data/array_tree.py
@@ -7,8 +7,9 @@ pkg_resources.require( "numpy" )
pkg_resources.require( "bx-python" )
from bx.arrays.array_tree import FileArrayTreeDict
from math import floor, ceil, log, pow
+from base import TracksDataProvider
-class ArrayTreeDataProvider( object ):
+class ArrayTreeDataProvider( TracksDataProvider ):
def __init__( self, dataset, original_dataset ):
self.dataset = dataset
--- /dev/null
+++ b/lib/galaxy/visualization/tracks/data/vcf.py
@@ -0,0 +1,53 @@
+"""
+VCF data provider for the Galaxy track browser.
+
+Payload format:
+[ uid (offset), start, end, ID, reference base(s), alternate base(s), quality score]
+"""
+
+import pkg_resources; pkg_resources.require( "bx-python" )
+from bx.interval_index_file import Indexes
+from galaxy.datatypes.tabular import Vcf
+from base import TracksDataProvider
+
+MAX_VALS = 5000 # only display first MAX_VALS features
+
+class VCFDataProvider( TracksDataProvider ):
+ """ Provides data for VCF tracks. """
+
+ def get_data( self, chrom, start, end, **kwargs ):
+ """ Returns data in region defined by chrom, start, and end. """
+ start, end = int(start), int(end)
+ source = open( self.original_dataset.file_name )
+ index = Indexes( self.converted_dataset.file_name )
+ results = []
+ count = 0
+ message = None
+
+ # If chrom is not found in indexes, try removing the first three
+ # characters (e.g. 'chr') and see if that works. This enables the
+ # provider to handle chrome names defined as chrXXX and as XXX.
+ chrom = str(chrom)
+ if chrom not in index.indexes and chrom[3:] in index.indexes:
+ chrom = chrom[3:]
+
+ for start, end, offset in index.find(chrom, start, end):
+ if count >= MAX_VALS:
+ message = "Only the first %s features are being displayed." % MAX_VALS
+ break
+ count += 1
+ source.seek(offset)
+ feature = source.readline().split()
+
+ payload = [ offset, start, end, \
+ # ID:
+ feature[2], \
+ # reference base(s):
+ feature[3], \
+ # alternative base(s)
+ feature[4], \
+ # phred quality score
+ feature[5] ]
+ results.append(payload)
+
+ return { 'data_type' : 'vcf', 'data': results, 'message': message }
--- /dev/null
+++ b/lib/galaxy/visualization/tracks/data/base.py
@@ -0,0 +1,11 @@
+class TracksDataProvider( object ):
+ """ Base class for tracks data providers. """
+
+ def __init__( self, converted_dataset, original_dataset ):
+ self.converted_dataset = converted_dataset
+ self.original_dataset = original_dataset
+
+ def get_data( self, chrom, start, end, **kwargs ):
+ """ Returns data in region defined by chrom, start, and end. """
+ # Override.
+ pass
1
0

galaxy-dist commit 13abfea1b0ef: Removed redundant loading of name as handled by parameter base class
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User peterjc <p.j.a.cock(a)googlemail.com>
# Date 1286451944 -3600
# Node ID 13abfea1b0ef2fa93a6bca55af62c11fd220588d
# Parent 51873f4ee7a6a3535dc028c66259a5381cc46c9c
Removed redundant loading of name as handled by parameter base class
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -161,7 +161,6 @@ class TextToolParameter( ToolParameter )
"""
def __init__( self, tool, elem ):
ToolParameter.__init__( self, tool, elem )
- self.name = elem.get( 'name' )
self.size = elem.get( 'size' )
self.value = elem.get( 'value' )
self.area = string_as_bool( elem.get( 'area', False ) )
@@ -271,7 +270,6 @@ class BooleanToolParameter( ToolParamete
ToolParameter.__init__( self, tool, elem )
self.truevalue = elem.get( 'truevalue', 'true' )
self.falsevalue = elem.get( 'falsevalue', 'false' )
- self.name = elem.get( 'name' )
self.checked = string_as_bool( elem.get( 'checked' ) )
def get_html_field( self, trans=None, value=None, other_values={} ):
checked = self.checked
@@ -308,7 +306,6 @@ class FileToolParameter( ToolParameter )
Example: C{<param name="bins" type="file" />}
"""
ToolParameter.__init__( self, tool, elem )
- self.name = elem.get( 'name' )
self.ajax = string_as_bool( elem.get( 'ajax-upload' ) )
def get_html_field( self, trans=None, value=None, other_values={} ):
return form_builder.FileField( self.name, ajax = self.ajax, value = value )
@@ -371,7 +368,6 @@ class HiddenToolParameter( ToolParameter
"""
def __init__( self, tool, elem ):
ToolParameter.__init__( self, tool, elem )
- self.name = elem.get( 'name' )
self.value = elem.get( 'value' )
def get_html_field( self, trans=None, value=None, other_values={} ):
return form_builder.HiddenField( self.name, self.value )
@@ -391,7 +387,6 @@ class BaseURLToolParameter( ToolParamete
"""
def __init__( self, tool, elem ):
ToolParameter.__init__( self, tool, elem )
- self.name = elem.get( 'name' )
self.value = elem.get( 'value', '' )
def get_value( self, trans ):
# url = trans.request.base + self.value
@@ -1393,7 +1388,6 @@ class DataToolParameter( ToolParameter )
# """
# def __init__( self, tool, elem ):
# ToolParameter.__init__( self, tool, elem )
-# self.name = elem.get('name')
# def get_html( self, trans, value=None, other_values={} ):
# assert trans.history is not None, "HistoryIDParameter requires a history"
# self.html = form_builder.HiddenField( self.name, trans.history.id ).get_html()
1
0

galaxy-dist commit d3fa82adee97: Finish refactoring of tracks data providers so that they all inherit from a single base object, TracksDataProvider.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1286559820 14400
# Node ID d3fa82adee9782d27d4de9a92a3d1be47bd138c8
# Parent 13abfea1b0ef2fa93a6bca55af62c11fd220588d
Finish refactoring of tracks data providers so that they all inherit from a single base object, TracksDataProvider.
--- a/lib/galaxy/visualization/tracks/data/array_tree.py
+++ b/lib/galaxy/visualization/tracks/data/array_tree.py
@@ -10,8 +10,6 @@ from math import floor, ceil, log, pow
from base import TracksDataProvider
class ArrayTreeDataProvider( TracksDataProvider ):
- def __init__( self, dataset, original_dataset ):
- self.dataset = dataset
def get_stats( self, chrom ):
f = open( self.dataset.file_name )
@@ -48,7 +46,7 @@ class ArrayTreeDataProvider( TracksDataP
if 'stats' in kwargs:
return self.get_stats(chrom)
- f = open( self.dataset.file_name )
+ f = open( self.converted_dataset.file_name )
d = FileArrayTreeDict( f )
# Get the right chromosome
--- a/lib/galaxy/visualization/tracks/data/summary_tree.py
+++ b/lib/galaxy/visualization/tracks/data/summary_tree.py
@@ -6,18 +6,16 @@ import pkg_resources; pkg_resources.requ
from galaxy.visualization.tracks.summary import *
from math import ceil, log
from galaxy.util.lrucache import LRUCache
+from base import TracksDataProvider
CACHE = LRUCache(20) # Store 20 recently accessed indices for performance
-class SummaryTreeDataProvider( object ):
- def __init__( self, dataset, original_dataset ):
- self.dataset = dataset
-
+class SummaryTreeDataProvider( TracksDataProvider ):
def get_summary( self, chrom, start, end, **kwargs):
- filename = self.dataset.file_name
+ filename = self.converted_dataset.file_name
st = CACHE[filename]
if st is None:
- st = summary_tree_from_file( self.dataset.file_name )
+ st = summary_tree_from_file( self.converted_dataset.file_name )
CACHE[filename] = st
# If chrom is not found in blocks, try removing the first three
--- a/lib/galaxy/visualization/tracks/data/bam.py
+++ b/lib/galaxy/visualization/tracks/data/bam.py
@@ -16,19 +16,14 @@ MAX_VALS = 5000 # only display first MAX
class BamDataProvider( TracksDataProvider ):
"""
Provides access to intervals from a sorted indexed BAM file.
- """
- def __init__( self, index, original_dataset ):
-
- self.index = index
- self.original_dataset = original_dataset
-
+ """
def get_data( self, chrom, start, end, **kwargs ):
"""
Fetch intervals in the region
"""
start, end = int(start), int(end)
# Attempt to open the BAM file with index
- bamfile = csamtools.Samfile( filename=self.original_dataset.file_name, mode='rb', index_filename=self.index.file_name )
+ bamfile = csamtools.Samfile( filename=self.original_dataset.file_name, mode='rb', index_filename=self.converted_dataset.file_name )
message = None
try:
data = bamfile.fetch(start=start, end=end, reference=chrom)
1
0
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Kanwei Li <kanwei(a)gmail.com>
# Date 1286571405 14400
# Node ID ddcfb334eb3ad53425a62f4b094374b219daa455
# Parent b36700318a817db7d9817213aef9e7d1602b9aec
trackster:
- Fix LineTrack axis labels not aligning consistently
- New image for draggable elements
- New slider that is rounded, easier to see and will go off-screen if smaller than the minimum width
- Added "Close overview" link when overview is showing
- Fix array_tree from recent refactoring
Binary file static/images/draggable_horizontal.png has changed
--- a/static/scripts/packed/trackster.js
+++ b/static/scripts/packed/trackster.js
@@ -1,1 +1,1 @@
-var DENSITY=200,FEATURE_LEVELS=10,MAX_FEATURE_DEPTH=100,DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),PX_PER_CHAR=CONTEXT.measureText("A").width,RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/strand_right_inv.png";right_img_inv.onload=function()
{RIGHT_STRAND_INV=CONTEXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,c,e,d,b){this.container=a;this.vis_id=d;this.dbkey=b;this.title=e;this.chrom=c;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.
min_separation=30;this.has_changes=false;this.init();this.reset()};$.extend(View.prototype,{init:function(){var c=this.container,a=this;this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(c);this.content_div=$("<div/>").addClass("content").css("position","relative").hide().appendTo(c);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide().appendTo(c);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.nav_container=$("<div/>").addClass("nav-container").appendTo(c);this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.nav);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_box_background=$("<div/>").addClass("overview-boxback").app
endTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){void (0)}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);var b=function(d){if(d.type==="focusout"||(d.keyCode||d.which)===13||(d.keyCode||d.which)===27){if((d.keyCode||d.which)!==27){a.go_to($(this).val())}$(this).hide();a.location_span.show();a.chrom_select.show();return false}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keypress focusout",b).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);this.location_span.bind("click",function(){a.location_span.hi
de();a.chrom_select.hide();a.nav_input.css("display","inline-block");a.nav_input.select();a.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.zo_link=$("<a/>").click(function(){a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);this.zi_link=$("<a/>").click(function(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(d){if(d.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=d.chrom_info;var f='<option value="">Select Chrom/Contig</option>';for(i in a.chrom_data){var e=a.chrom_data[i]["chrom"];f+='<option value="'+e+'">'+e+"</option>"}a.chrom_select.html(f);a.intro_div.show();a.content_div.hide();a.chrom_select.b
ind("change",function(){a.change_chrom(a.chrom_select.val())})},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("dblclick",function(d){a.zoom_in(d.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(d){this.current_x=d.offsetX}).bind("drag",function(d){var g=d.offsetX-this.current_x;this.current_x=d.offsetX;var f=Math.round(g/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-f)});this.viewport_container.bind("dragstart",function(d){this.original_low=a.low;this.current_height=d.clientY;this.current_x=d.offsetX;this.enable_pan=(d.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(g){if(!this.enable_pan||this.in_reordering){return}var d=$(this);var j=g.offsetX-this.current_x;var f=d.scrollTop()-(g.clientY-this.current_height);d.scrollTop(f);this.current_height=g.clientY;this.current_x=g.offsetX;var h=Math.round(j/a.viewport_container.width()*(a.high-a.low));a.move_
delta(h)});this.top_labeltrack.bind("dragstart",function(d){this.drag_origin_x=d.clientX;this.drag_origin_pos=d.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_div=$("<div />").css({height:a.content_div.height()+30,top:"0px",position:"absolute","background-color":"#cfc",border:"1px solid #6a6",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(j){var f=Math.min(j.clientX,this.drag_origin_x)-a.container.offset().left,d=Math.max(j.clientX,this.drag_origin_x)-a.container.offset().left,h=(a.high-a.low),g=a.viewport_container.width();a.update_location(Math.round(f/g*h)+a.low,Math.round(d/g*h)+a.low);this.drag_div.css({left:f+"px",width:(d-f)+"px"})}).bind("dragend",function(k){var f=Math.min(k.clientX,this.drag_origin_x),d=Math.max(k.clientX,this.drag_origin_x),h=(a.high-a.low),g=a.viewport_container.width(),j=a.low;a.low=Math.round(f/g*h)+j;a.high=Math.round(d/g*h)+j;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(th
is,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack))},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(d,a,f){var c=this;var e=$.grep(c.chrom_data,function(h,j){return h.chrom===d})[0];if(e===undefined){return}if(d!==c.chrom){c.chrom=d;if(c.chrom===""){c.intro_div.show();c.content_div.hide()}else{c.intro_div.hide();c.content_div.show()}c.chrom_select.val(c.chrom);c.max_high=e.len;c.reset();c.redraw(true);for(var g in c.tracks){var b=c.tracks[g];if(b.init){b.init()}}}if(a!==undefined&&f!==undefined){c.low=Math.max(a,0);c.high=Math.min(f,c.max_high)}c.overview_viewport.find("canvas").remove();c.redraw()},go_to:function(f){var k=this,b=f.split(":"),h=b[0],j=b[1];if(j!==undefined){try{var g=j.split("-"),a=parseInt(g[0].replace(/,/g,"")),d=parseInt(g[1].replace(/,/g,""))}catch(c){return false}}k.change_chrom(h,a,d)},move_
delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.high-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(h){var d=this.high-this.low,b=this.low,f=this.high;if(b<this.max_low){b=this.max_low}if(f>this.max_high){f=this.max_high}if(this.high!==0&&d<this.min_separation){f=b+this.min_separation}this.low=Math.floor(b);th
is.high=Math.ceil(f);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));var e=(this.low/(this.max_high-this.max_low))*this.overview_viewport.width();var g=(this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width();this.overview_box.css({left:e,width:Math.max(12,g)}).show();if(this.overview_highlight){this.overview_highlight.css({left:e,width:g})}this.update_location(this.low,this.high);if(!h){for(var c=0,a=this.tracks.length;c<a;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,a=this.label_tracks.length;c<a;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.high-this.low)+thi
s.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b=this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()}});var Track=function(b,a,c){this.name=b;this.parent_element=c;this.view=a;this.init_global()};$.extend(Track.prototype,{init_global:function(){this.container_div=$("<div />").addClass("track");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div);this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name)}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.con
tent_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.view.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("he
ight",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){var d=this,c=d.view;if(d.hidden){return}if(d.display_modes!==undefined){if(d.mode_div===undefined){d.mode_div=$("<div class='right-float menubutton popup' />").appendTo(d.header_div);var h=d.display_modes[0];d.mode=h;d.mode_div.text(h);var a=function(j){d.mode_div.text(j);d.mode=j;d.tile_cache.clear();d.draw()};var f={};for(var e in d.display_modes){var g=d.display_modes[e];f[g]=function(j){return function(){a(j)}}(g)}make_popupmenu(d.mode_div,f)}else{d.mode_div.hide()}}var b={};b["Set track as overview"]=function(){c.overview_viewport.find("canvas").remove();d.is_overview=true;d.set_overview();for(var j in c.tracks){if(c.tracks[j]!==d){c.tracks[j].is_overview=false}}};b["Edit configuration"]=function(){var k=function(){hide_modal()};var j=function(){d.update_options(d.track_id);hide_modal()};show_modal("Configure Trac
k",d.gen_options(d.track_id),{Cancel:k,OK:j})};b.Remove=function(){c.remove_track(d);if(c.num_tracks===0){$("#no-tracks").show()}};make_popupmenu(d.name_div,b)};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(){var j=this.view.low,e=this.view.high,f=e-j,d=this.view.resolution;var l=$("<div style='position: relative;'></div>"),m=this.content_div.width()/f,h;this.content_div.children(":first").remove();this.content_div.append(l),this.max_height=0;var a=Math.floor(j/d/DENSITY);while((a*DENSITY*d)<e){var k=this.content_div.width()+"_"+m+"_"+a;var c=this.tile_cache.get(k);if(c){var g=a*DENSITY*d;var b=(g-j)*m;if(this.left_offset){b-=this.left_offset}c.css({left:b});l.append(c);this.max_height=Math.max(this.max_height,c.height());this.content_div.css("height",this.max_height+"px")}else{this.delayed_draw(this,k,j,e,a,d,l,m)}a+=1}},delayed_draw:function(c,e,a,f,b,d,g,h){setTimeout(function(){if(!(a>c.view.high||f<c.view.low)){tile_element=c.draw_tile(d,b,g,h);if(tile_el
ement){if(!c.initial_canvas){c.initial_canvas=$(tile_element).clone();var l=tile_element.get(0).getContext("2d");var j=c.initial_canvas.get(0).getContext("2d");var k=l.getImageData(0,0,l.canvas.width,l.canvas.height);j.putImageData(k,0,0);c.set_overview()}c.tile_cache.set(e,tile_element);c.max_height=Math.max(c.max_height,tile_element.height());c.content_div.css("height",c.max_height+"px")}}},50)},set_overview:function(){var a=this.view;a.overview_viewport.height(a.default_overview_height);a.overview_box.height(a.default_overview_height);if(this.initial_canvas&&this.is_overview){if(!a.overview_highlight){a.overview_highlight=$("<div />").addClass("overview-highlight").appendTo(a.overview_viewport)}a.overview_viewport.append(this.initial_canvas);a.overview_highlight.height(this.initial_canvas.height());a.overview_viewport.height(this.initial_canvas.height()+a.overview_box.height())}$(window).trigger("resize")}});var LabelTrack=function(a,b){this.track_type="LabelTrack";this.h
idden=true;Track.call(this,null,a,b);this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";this.hidden=true;Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.height_px=12;this.container_div.addClass("reference-track");this.dummy_canvas=$("<canvas></canvas>").get(0).getContext("2d");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.proto
type,{get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(f,b,k,o){var g=b*DENSITY*f,d=DENSITY*f,e=$("<canvas class='tile'></canvas>"),n=e.get(0).getContext("2d"),j=f+"_"+b;if(o>PX_PER_CHAR){if(this.data_cache.get(j)===undefined){this.get_data(f,b);return}var m=this.data_cache.get(j);if(m===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*o+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*o-this.left_offset});for(var h=0,l=m.length;h<l;h++){var a=Math.round(h*o);n.fillText(m[h],a+this.left_offset,10)}k.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=function(d,b
,a,c){this.track_type="LineTrack";this.display_modes=["Line","Filled","Intensity"];this.mode="Line";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=80;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={min_value:undefined,max_value:undefined,mode:"Line"};if(c.min_value!==undefined){this.prefs.min_value=c.min_value}if(c.max_value!==undefined){this.prefs.max_value=c.max_value}};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").val(a.prefs.max_value)}a.
vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;$("#linetrack_"+b+"_minval").remove();$("#linetrack_"+b+"_maxval").remove();var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"relative",top:"32px",left:"10px"});d.prependTo(a.container_div);e.css({position:"relative",top:a.height_px+32+"px",left:"10px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(p,r,c,
e){if(this.vertical_range===undefined){return}var s=r*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),v=p+"_"+r;if(this.data_cache.get(v)===undefined){this.get_data(p,r);return}var j=this.data_cache.get(v);if(j===null){return}b.css({position:"absolute",top:0,left:(s-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,t=this.total_frequency,d=this.height_px,m=this.mode;o.beginPath();if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}var u,h;for(var q=0;q<data.length;q++){u=(data[q][0]-s)*e;h=data[q][1];if(m=="Intensity"){if(h===null){continue}if(h<=l){h=l}else{if(h>=g){h=g}}h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")";o.fillRect(u,0,f,this.height_px)}else{if(h===null){if(k&&m==="Filled"){o.lineTo(u,d)}k=false;continue}else{if(h<=l){h=l}else{if(h>=g){h=g}}h=Math.round(d-(h-l)/n*d);if(k)
{o.lineTo(u,h)}else{k=true;if(m==="Filled"){o.moveTo(u,d);o.lineTo(u,h)}else{o.moveTo(u,h)}}}}}if(m==="Filled"){if(k){o.lineTo(u,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(k){var a=$("<div />").addClass("form-row");var e="track_"+k+"_minval",h=$("<label></label>").attr("for",e).text("Min value:"),b=(this.prefs.min_value===undefined?"":this.prefs.min_value),j=$("<input></input>").attr("id",e).val(b),g="track_"+k+"_maxval",d=$("<label></label>").attr("for",g).text("Max value:"),f=(this.prefs.max_value===undefined?"":this.prefs.max_value),c=$("<input></input>").attr("id",g).val(f);return a.append(h).append(j).append(d).append(c)},update_options:function(c){var a=$("#track_"+c+"_minval").val(),b=$("#track_"+c+"_maxval").val();if(a!==this.prefs.min_value||b!==this.prefs.max_value){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(b);this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+c+"_minval").text(this.pre
fs.min_value);$("#linetrack_"+c+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,c){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=2;this.summary_draw_height=20;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.left_offset=200;this.prefs={block_color:"black",label_color:"black",show_counts:true};if(c.block_color!==undefined){this.prefs.block_color=c.block_color}if(c.label_color!==undefined){this.prefs.label_color=c.label_color}if(c.show_counts!==undefined){this.prefs.sh
ow_counts=c.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b="initial";this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution,mode:a.mode},function(c){a.mode_div.show();a.data_cache.set(b,c);a.draw()})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_
e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(this.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.measureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(true){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_tile[a][v].length;u<A;u++){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=[]}this.s_e_by_tile[a][v].push([e,f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(n,o,f,m,b,d,k,e,h){n.textAlign="center";var j=Math.round(o/2);if((this.mode==="Pack"||this.mode==="Auto")&&d!==undefined&&o>PX_PER_CHAR){n.fillStyle=this.prefs.block_color;n.fillRect(k,h+1,e,9);n.fillStyle="#eee";f
or(var g=0,l=d.length;g<l;g++){if(b+g>=f&&b+g<=m){var a=Math.floor(Math.max(0,(b+g-f)*o));n.fillText(d[g],a+this.left_offset+j,h+9)}}}else{n.fillStyle=this.prefs.block_color;n.fillRect(k,h+4,e,3)}},draw_tile:function(ae,o,r,ar){var L=o*DENSITY*ae,ak=(o+1)*DENSITY*ae,K=ak-L;var al=(!this.initial_canvas?"initial":L+"_"+ak);var G=this.data_cache.get(al);var e;if(G===undefined||(this.mode!=="Auto"&&G.dataset_type==="summary_tree")){this.data_queue[[L,ak]]=true;this.get_data(L,ak);return}var a=Math.ceil(K*ar),S=$("<canvas class='tile'></canvas>"),ag=this.prefs.label_color,h=this.prefs.block_color,q=this.mode,v=25,ac=(q==="Squish")||(q==="Dense")&&(q!=="Pack")||(q==="Auto"&&(G.extra_info==="no_detail")),W=this.left_offset,aq,B,at;if(G.dataset_type==="summary_tree"){B=this.summary_draw_height}else{if(q==="Dense"){B=v;at=10}else{at=(ac?this.vertical_nodetail_px:this.vertical_detail_px);var w=(ar<0.0001?1/view.zoom_res:ar);B=this.incremental_slots(w,G.data,ac,q)*at+v;aq=this.inc_slot
s[w]}}S.css({position:"absolute",top:0,left:(L-this.view.low)*ar-W});S.get(0).width=a+W;S.get(0).height=B;r.parent().css("height",Math.max(this.height_px,B)+"px");var H=S.get(0).getContext("2d");H.fillStyle=h;H.font=this.default_font;H.textAlign="right";if(G.dataset_type=="summary_tree"){var R,O=55,aj=255-O,n=aj*2/3,Y=G.data,J=G.max,p=G.avg,b=Math.ceil(G.delta*ar);for(var an=0,F=Y.length;an<F;an++){var aa=Math.floor((Y[an][0]-L)*ar);var Z=Y[an][1];if(!Z){continue}R=Math.floor(aj-(Z/J)*aj);H.fillStyle="rgb("+R+","+R+","+R+")";H.fillRect(aa+W,0,b,this.summary_draw_height);if(this.prefs.show_counts&&H.measureText(Z).width<b){if(R>n){H.fillStyle="black"}else{H.fillStyle="#ddd"}H.textAlign="center";H.fillText(Z,aa+W+(b/2),12)}}e="Summary";r.append(S);return S}if(G.message){S.css({border:"solid red","border-width":"2px 2px 2px 0px"});H.fillStyle="red";H.textAlign="left";H.fillText(G.message,100+W,at)}var ap=G.data;var am=0;for(var an=0,F=ap.length;an<F;an++){var T=ap[an],Q=T[0],ao
=T[1],ab=T[2],M=T[3];if(ao<=ak&&ab>=L){var ad=Math.floor(Math.max(0,(ao-L)*ar)),I=Math.ceil(Math.min(a,Math.max(0,(ab-L)*ar))),X=(q==="Dense"?1:(1+aq[Q]))*at;if(G.dataset_type==="bai"){H.fillStyle=h;if(T[4] instanceof Array){var C=Math.floor(Math.max(0,(T[4][0]-L)*ar)),P=Math.ceil(Math.min(a,Math.max(0,(T[4][1]-L)*ar))),A=Math.floor(Math.max(0,(T[5][0]-L)*ar)),u=Math.ceil(Math.min(a,Math.max(0,(T[5][1]-L)*ar)));if(T[4][1]>=L&&T[4][0]<=ak){this.rect_or_text(H,ar,L,ak,T[4][0],T[4][2],C+W,P-C,X)}if(T[5][1]>=L&&T[5][0]<=ak){this.rect_or_text(H,ar,L,ak,T[5][0],T[5][2],A+W,u-A,X)}if(A>P){H.fillStyle="#999";H.fillRect(P+W,X+5,A-P,1)}}else{H.fillStyle=h;this.rect_or_text(H,ar,L,ak,ao,M,ad+W,I-ad,X)}if(q!=="Dense"&&!ac&&ao>L){H.fillStyle=this.prefs.label_color;if(o===0&&ad-H.measureText(M).width<0){H.textAlign="left";H.fillText(Q,I+2+W,X+8)}else{H.textAlign="right";H.fillText(Q,ad-2+W,X+8)}H.fillStyle=h}}else{if(G.dataset_type==="interval_index"){if(ac){H.fillStyle=h;H.fillRect(ad+W,
X+5,I-ad,1)}else{var E=T[4],V=T[5],af=T[6],g=T[7];var D,ah,N=null,au=null;if(V&&af){N=Math.floor(Math.max(0,(V-L)*ar));au=Math.ceil(Math.min(a,Math.max(0,(af-L)*ar)))}if(q!=="Dense"&&M!==undefined&&ao>L){H.fillStyle=ag;if(o===0&&ad-H.measureText(M).width<0){H.textAlign="left";H.fillText(M,I+2+W,X+8)}else{H.textAlign="right";H.fillText(M,ad-2+W,X+8)}H.fillStyle=h}if(g){if(E){if(E=="+"){H.fillStyle=RIGHT_STRAND}else{if(E=="-"){H.fillStyle=LEFT_STRAND}}H.fillRect(ad+W,X,I-ad,10);H.fillStyle=h}for(var al=0,f=g.length;al<f;al++){var t=g[al],d=Math.floor(Math.max(0,(t[0]-L)*ar)),U=Math.ceil(Math.min(a,Math.max((t[1]-L)*ar)));if(d>U){continue}D=5;ah=3;H.fillRect(d+W,X+ah,U-d,D);if(N!==undefined&&!(d>au||U<N)){D=9;ah=1;var ai=Math.max(d,N),z=Math.min(U,au);H.fillRect(ai+W,X+ah,z-ai,D)}}}else{D=9;ah=1;H.fillRect(ad+W,X+ah,I-ad,D);if(T.strand){if(T.strand=="+"){H.fillStyle=RIGHT_STRAND_INV}else{if(T.strand=="-"){H.fillStyle=LEFT_STRAND_INV}}H.fillRect(ad+W,X,I-ad,10);H.fillStyle=h}}}}
else{if(G.dataset_type==="vcf"){if(ac){H.fillStyle=h;H.fillRect(ad+W,X+5,I-ad,1)}else{var s=T[4],m=T[5],c=T[6];D=9;ah=1;H.fillRect(ad+W,X,I-ad,D);if(q!=="Dense"&&M!==undefined&&ao>L){H.fillStyle=ag;if(o===0&&ad-H.measureText(M).width<0){H.textAlign="left";H.fillText(M,I+2+W,X+8)}else{H.textAlign="right";H.fillText(M,ad-2+W,X+8)}H.fillStyle=h}var l=s+" / "+m;if(ao>L&&H.measureText(l).width<(I-ad)){H.fillStyle="white";H.textAlign="center";H.fillText(l,W+ad+(I-ad)/2,X+8);H.fillStyle=h}}}}}am++}}r.append(S);return S},gen_options:function(j){var a=$("<div />").addClass("form-row");var e="track_"+j+"_block_color",l=$("<label />").attr("for",e).text("Block color:"),m=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),k="track_"+j+"_label_color",g=$("<label />").attr("for",k).text("Text color:"),h=$("<input />").attr("id",k).attr("name",k).val(this.prefs.label_color),f="track_"+j+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input
type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(l).append(m).append(g).append(h).append(d)},update_options:function(e){var b=$("#track_"+e+"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,c){FeatureTrack.call(this,d,b,a,c);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
+var DENSITY=200,FEATURE_LEVELS=10,MAX_FEATURE_DEPTH=100,DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),PX_PER_CHAR=CONTEXT.measureText("A").width,RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/strand_right_inv.png";right_img_inv.onload=function()
{RIGHT_STRAND_INV=CONTEXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,c,e,d,b){this.container=a;this.vis_id=d;this.dbkey=b;this.title=e;this.chrom=c;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.
min_separation=30;this.has_changes=false;this.init();this.reset()};$.extend(View.prototype,{init:function(){var c=this.container,a=this;this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(c);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(c);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide();this.nav_container=$("<div/>").addClass("nav-container").appendTo(c);this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.nav);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a href='javascript:void(0);'>Close Overview</a>").addClass("overview
-close").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div />").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){void (0)}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);var b=function(d){if(d.type==="focusout"||(d.keyCode||d.which)===13||(d.keyCode||d.which)===27){if((d.keyCode||d.which)!==27){a.go_to($(this).val())}$(this).hide();a.location_span.show();a.chrom_select.show();return false}};this.nav_input=$("<inp
ut/>").addClass("nav-input").hide().bind("keypress focusout",b).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);this.location_span.bind("click",function(){a.location_span.hide();a.chrom_select.hide();a.nav_input.css("display","inline-block");a.nav_input.select();a.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.zo_link=$("<a/>").click(function(){a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);this.zi_link=$("<a/>").click(function(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(d){if(d.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=d.chrom_info
;var f='<option value="">Select Chrom/Contig</option>';for(i in a.chrom_data){var e=a.chrom_data[i]["chrom"];f+='<option value="'+e+'">'+e+"</option>"}a.chrom_select.html(f);a.intro_div.show();a.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())})},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("dblclick",function(d){a.zoom_in(d.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(d){this.current_x=d.offsetX}).bind("drag",function(d){var g=d.offsetX-this.current_x;this.current_x=d.offsetX;var f=Math.round(g/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-f)});this.overview_close.bind("click",function(){for(var d in a.tracks){a.tracks[d].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",a.overview_box.height());a.overview_highlight.hide();$(this).hide()});this.viewport_container.bind("dragstart",function(d){this.origin
al_low=a.low;this.current_height=d.clientY;this.current_x=d.offsetX;this.enable_pan=(d.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(g){if(!this.enable_pan||this.in_reordering){return}var d=$(this);var j=g.offsetX-this.current_x;var f=d.scrollTop()-(g.clientY-this.current_height);d.scrollTop(f);this.current_height=g.clientY;this.current_x=g.offsetX;var h=Math.round(j/a.viewport_container.width()*(a.high-a.low));a.move_delta(h)});this.top_labeltrack.bind("dragstart",function(d){this.drag_origin_x=d.clientX;this.drag_origin_pos=d.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_div=$("<div />").css({height:a.content_div.height()+30,top:"0px",position:"absolute","background-color":"#cfc",border:"1px solid #6a6",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(j){var f=Math.min(j.clientX,this.drag_origin_x)-a.container.offset().left,d=Math.max(j.clientX,this.drag_origin_x)-a.container.offset().left,h=(a.high-a.
low),g=a.viewport_container.width();a.update_location(Math.round(f/g*h)+a.low,Math.round(d/g*h)+a.low);this.drag_div.css({left:f+"px",width:(d-f)+"px"})}).bind("dragend",function(k){var f=Math.min(k.clientX,this.drag_origin_x),d=Math.max(k.clientX,this.drag_origin_x),h=(a.high-a.low),g=a.viewport_container.width(),j=a.low;a.low=Math.round(f/g*h)+j;a.high=Math.round(d/g*h)+j;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack))},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(d,a,f){var c=this;var e=$.grep(c.chrom_data,function(h,j){return h.chrom===d})[0];if(e===undefined){return}if(d!==c.chrom){c.chrom=d;if(c.chrom===""){c.intro_div.show()}else{c.intro_div.hide()}c.chrom_select.val(c.chrom);c.max_high=e.len;c.reset();c.redraw(true);for(var g i
n c.tracks){var b=c.tracks[g];if(b.init){b.init()}}}if(a!==undefined&&f!==undefined){c.low=Math.max(a,0);c.high=Math.min(f,c.max_high)}c.overview_viewport.find("canvas").remove();c.redraw()},go_to:function(f){var k=this,b=f.split(":"),h=b[0],j=b[1];if(j!==undefined){try{var g=j.split("-"),a=parseInt(g[0].replace(/,/g,"")),d=parseInt(g[1].replace(/,/g,""))}catch(c){return false}}k.change_chrom(h,a,d)},move_delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.high-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()}
);delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(h){var g=this.high-this.low,f=this.low,b=this.high;if(f<this.max_low){f=this.max_low}if(b>this.max_high){b=this.max_high}if(this.high!==0&&g<this.min_separation){b=f+this.min_separation}this.low=Math.floor(f);this.high=Math.ceil(b);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));var a=this.low/(this.max_high-this.max_low)*this.overview_viewport.width();var e=(this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width();var j=13;this.overview_box.css({left:a,width:Math.max(j,e)}).show();if(e<j){this.overview_box.css("left",a-(j-e)/2)}if(this.overview_highlight){this.overview_highlight.css({left:a,widt
h:e})}this.update_location(this.low,this.high);if(!h){for(var c=0,d=this.tracks.length;c<d;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,d=this.label_tracks.length;c<d;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b=this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()}});var Track=function(b,a,c){this.name=b;this.parent_element=c;this.view=a;this.init_global()};$.extend(Track.prototype,{init_global:function(){this.container_div=$("<div />").addClass("track");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.
container_div);this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div);this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name)}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.view.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+
"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){var d=this,c=d.view;if(d.hidden){return}if(d.display_modes!==undefined){if(d.mode_div===undefined){d.mode_div=$("<div class='right-float menubutton popup' />").appendTo(d.header_div);var h=d.display_modes[0];d.mode=h;d.mode_div.text(h);var a=function(j){d.mode_div.text(j);d.mode=j;d.tile_cache.clear();d.draw()};var f={};for(var e in d.display_modes){var g=d.display
_modes[e];f[g]=function(j){return function(){a(j)}}(g)}make_popupmenu(d.mode_div,f)}else{d.mode_div.hide()}}var b={};b["Set as overview"]=function(){c.overview_viewport.find("canvas").remove();d.is_overview=true;d.set_overview();for(var j in c.tracks){if(c.tracks[j]!==d){c.tracks[j].is_overview=false}}};b["Edit configuration"]=function(){var k=function(){hide_modal()};var j=function(){d.update_options(d.track_id);hide_modal()};show_modal("Configure Track",d.gen_options(d.track_id),{Cancel:k,OK:j})};b.Remove=function(){c.remove_track(d);if(c.num_tracks===0){$("#no-tracks").show()}};make_popupmenu(d.name_div,b)};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(){var j=this.view.low,e=this.view.high,f=e-j,d=this.view.resolution;var l=$("<div style='position: relative;'></div>"),m=this.content_div.width()/f,h;this.content_div.children(":first").remove();this.content_div.append(l),this.max_height=0;var a=Math.floor(j/d/DENSITY);while((a*DENSITY*d)<e){var k=this.conten
t_div.width()+"_"+m+"_"+a;var c=this.tile_cache.get(k);if(c){var g=a*DENSITY*d;var b=(g-j)*m;if(this.left_offset){b-=this.left_offset}c.css({left:b});l.append(c);this.max_height=Math.max(this.max_height,c.height());this.content_div.css("height",this.max_height+"px")}else{this.delayed_draw(this,k,j,e,a,d,l,m)}a+=1}},delayed_draw:function(c,e,a,f,b,d,g,h){setTimeout(function(){if(!(a>c.view.high||f<c.view.low)){tile_element=c.draw_tile(d,b,g,h);if(tile_element){if(!c.initial_canvas){c.initial_canvas=$(tile_element).clone();var l=tile_element.get(0).getContext("2d");var j=c.initial_canvas.get(0).getContext("2d");var k=l.getImageData(0,0,l.canvas.width,l.canvas.height);j.putImageData(k,0,0);c.set_overview()}c.tile_cache.set(e,tile_element);c.max_height=Math.max(c.max_height,tile_element.height());c.content_div.css("height",c.max_height+"px")}}},50)},set_overview:function(){var a=this.view;a.overview_viewport.height(a.default_overview_height);a.overview_box.height(a.default_overv
iew_height);if(this.initial_canvas&&this.is_overview){a.overview_close.show();a.overview_viewport.append(this.initial_canvas);a.overview_highlight.show().height(this.initial_canvas.height());a.overview_viewport.height(this.initial_canvas.height()+a.overview_box.height())}$(window).trigger("resize")}});var LabelTrack=function(a,b){this.track_type="LabelTrack";this.hidden=true;Track.call(this,null,a,b);this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrac
k";this.hidden=true;Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.height_px=12;this.container_div.addClass("reference-track");this.dummy_canvas=$("<canvas></canvas>").get(0).getContext("2d");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.prototype,{get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(f,b,k,o){var g=b*DENSITY*f,d=DENSITY*f,e=$("<canvas class='tile'></canvas>"),n=e.get(0).getContext("2d"),j=f+"_"+b;if(o>PX_PER_CHAR){if(this.data_cache.get(j)===undefined){this.get_data(f,b);return}var m=this.data_cache.get(j);if(m===null){this.content
_div.css("height","0px");return}e.get(0).width=Math.ceil(d*o+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*o-this.left_offset});for(var h=0,l=m.length;h<l;h++){var a=Math.round(h*o);n.fillText(m[h],a+this.left_offset,10)}k.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=function(d,b,a,c){this.track_type="LineTrack";this.display_modes=["Line","Filled","Intensity"];this.mode="Line";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=80;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={min_value:undefined,max_value:undefined,mode:"Line"};if(c.min_value!==undefined){this.prefs.min_value=c.min_value}if(c.max_value!==undefined){this.prefs.max_value=c.max_value}};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({s
tats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;$("#linetrack_"+b+"_minval").remove();$("#linetrack_"+b+"_maxval").remove();a.container_div.css("position","relative");var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"absolute",top:"22px",left:"10px"});d.prependTo(a.container_div);e.css({position:"absolute",top:a.height_px+11+"px",left:"10px"});e.prependTo(a.container_div)})},get_dat
a:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(p,r,c,e){if(this.vertical_range===undefined){return}var s=r*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),v=p+"_"+r;if(this.data_cache.get(v)===undefined){this.get_data(p,r);return}var j=this.data_cache.get(v);if(j===null){return}b.css({position:"absolute",top:0,left:(s-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,t=this.total_frequency,d=this.height_px,m=this.mode;o.beginPath();if(data.length>1){var f=Math.ceil((data[1][0]-
data[0][0])*e)}else{var f=10}var u,h;for(var q=0;q<data.length;q++){u=(data[q][0]-s)*e;h=data[q][1];if(m=="Intensity"){if(h===null){continue}if(h<=l){h=l}else{if(h>=g){h=g}}h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")";o.fillRect(u,0,f,this.height_px)}else{if(h===null){if(k&&m==="Filled"){o.lineTo(u,d)}k=false;continue}else{if(h<=l){h=l}else{if(h>=g){h=g}}h=Math.round(d-(h-l)/n*d);if(k){o.lineTo(u,h)}else{k=true;if(m==="Filled"){o.moveTo(u,d);o.lineTo(u,h)}else{o.moveTo(u,h)}}}}}if(m==="Filled"){if(k){o.lineTo(u,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(k){var a=$("<div />").addClass("form-row");var e="track_"+k+"_minval",h=$("<label></label>").attr("for",e).text("Min value:"),b=(this.prefs.min_value===undefined?"":this.prefs.min_value),j=$("<input></input>").attr("id",e).val(b),g="track_"+k+"_maxval",d=$("<label></label>").attr("for",g).text("Max value:"),f=(this.prefs.max_value===undefined?"":this.prefs.max_value),c=$("<inp
ut></input>").attr("id",g).val(f);return a.append(h).append(j).append(d).append(c)},update_options:function(c){var a=$("#track_"+c+"_minval").val(),b=$("#track_"+c+"_maxval").val();if(a!==this.prefs.min_value||b!==this.prefs.max_value){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(b);this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+c+"_minval").text(this.prefs.min_value);$("#linetrack_"+c+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,c){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=2;this.summary_draw_height=20;this.default_font="9px Monaco, Lucida Console, mono
space";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.left_offset=200;this.prefs={block_color:"black",label_color:"black",show_counts:true};if(c.block_color!==undefined){this.prefs.block_color=c.block_color}if(c.label_color!==undefined){this.prefs.label_color=c.label_color}if(c.show_counts!==undefined){this.prefs.show_counts=c.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b="initial";this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution,mode:a.mode},function(c){a.mode_div.show();a.data_cache.set(b,c);a.draw()})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b
.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(this.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.measureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(true){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_tile[a][v].length;u<A;u++){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;
break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=[]}this.s_e_by_tile[a][v].push([e,f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(n,o,f,m,b,d,k,e,h){n.textAlign="center";var j=Math.round(o/2);if((this.mode==="Pack"||this.mode==="Auto")&&d!==undefined&&o>PX_PER_CHAR){n.fillStyle=this.prefs.block_color;n.fillRect(k,h+1,e,9);n.fillStyle="#eee";for(var g=0,l=d.length;g<l;g++){if(b+g>=f&&b+g<=m){var a=Math.floor(Math.max(0,(b+g-f)*o));n.fillText(d[g],a+this.left_offset+j,h+9)}}}else{n.fillStyle=this.prefs.block_color;n.fillRect(k,h+4,e,3)}},draw_tile:function(ae,o,r,ar){var L=o*DENSITY*ae,ak=(o+1)*DENSITY*ae,K=ak-L;var al=(!this.initial_canvas?"initial":L+"_"+ak);var G=this.data_cache.get(al);var e;if(G===undefined||(this.mode!=="Auto"&&G.dataset_type==="summary_tree")){this.data_queue[[L,ak]]=true;this.get_data(L,ak);return}var a=Math.ceil(K*ar),S=$("<canvas class='tile'></canvas>"),ag=this.prefs.label_color,h=thi
s.prefs.block_color,q=this.mode,v=25,ac=(q==="Squish")||(q==="Dense")&&(q!=="Pack")||(q==="Auto"&&(G.extra_info==="no_detail")),W=this.left_offset,aq,B,at;if(G.dataset_type==="summary_tree"){B=this.summary_draw_height}else{if(q==="Dense"){B=v;at=10}else{at=(ac?this.vertical_nodetail_px:this.vertical_detail_px);var w=(ar<0.0001?1/view.zoom_res:ar);B=this.incremental_slots(w,G.data,ac,q)*at+v;aq=this.inc_slots[w]}}S.css({position:"absolute",top:0,left:(L-this.view.low)*ar-W});S.get(0).width=a+W;S.get(0).height=B;r.parent().css("height",Math.max(this.height_px,B)+"px");var H=S.get(0).getContext("2d");H.fillStyle=h;H.font=this.default_font;H.textAlign="right";if(G.dataset_type=="summary_tree"){var R,O=55,aj=255-O,n=aj*2/3,Y=G.data,J=G.max,p=G.avg,b=Math.ceil(G.delta*ar);for(var an=0,F=Y.length;an<F;an++){var aa=Math.floor((Y[an][0]-L)*ar);var Z=Y[an][1];if(!Z){continue}R=Math.floor(aj-(Z/J)*aj);H.fillStyle="rgb("+R+","+R+","+R+")";H.fillRect(aa+W,0,b,this.summary_draw_height);if
(this.prefs.show_counts&&H.measureText(Z).width<b){if(R>n){H.fillStyle="black"}else{H.fillStyle="#ddd"}H.textAlign="center";H.fillText(Z,aa+W+(b/2),12)}}e="Summary";r.append(S);return S}if(G.message){S.css({border:"solid red","border-width":"2px 2px 2px 0px"});H.fillStyle="red";H.textAlign="left";H.fillText(G.message,100+W,at)}var ap=G.data;var am=0;for(var an=0,F=ap.length;an<F;an++){var T=ap[an],Q=T[0],ao=T[1],ab=T[2],M=T[3];if(ao<=ak&&ab>=L){var ad=Math.floor(Math.max(0,(ao-L)*ar)),I=Math.ceil(Math.min(a,Math.max(0,(ab-L)*ar))),X=(q==="Dense"?1:(1+aq[Q]))*at;if(G.dataset_type==="bai"){H.fillStyle=h;if(T[4] instanceof Array){var C=Math.floor(Math.max(0,(T[4][0]-L)*ar)),P=Math.ceil(Math.min(a,Math.max(0,(T[4][1]-L)*ar))),A=Math.floor(Math.max(0,(T[5][0]-L)*ar)),u=Math.ceil(Math.min(a,Math.max(0,(T[5][1]-L)*ar)));if(T[4][1]>=L&&T[4][0]<=ak){this.rect_or_text(H,ar,L,ak,T[4][0],T[4][2],C+W,P-C,X)}if(T[5][1]>=L&&T[5][0]<=ak){this.rect_or_text(H,ar,L,ak,T[5][0],T[5][2],A+W,u-A,X
)}if(A>P){H.fillStyle="#999";H.fillRect(P+W,X+5,A-P,1)}}else{H.fillStyle=h;this.rect_or_text(H,ar,L,ak,ao,M,ad+W,I-ad,X)}if(q!=="Dense"&&!ac&&ao>L){H.fillStyle=this.prefs.label_color;if(o===0&&ad-H.measureText(M).width<0){H.textAlign="left";H.fillText(Q,I+2+W,X+8)}else{H.textAlign="right";H.fillText(Q,ad-2+W,X+8)}H.fillStyle=h}}else{if(G.dataset_type==="interval_index"){if(ac){H.fillStyle=h;H.fillRect(ad+W,X+5,I-ad,1)}else{var E=T[4],V=T[5],af=T[6],g=T[7];var D,ah,N=null,au=null;if(V&&af){N=Math.floor(Math.max(0,(V-L)*ar));au=Math.ceil(Math.min(a,Math.max(0,(af-L)*ar)))}if(q!=="Dense"&&M!==undefined&&ao>L){H.fillStyle=ag;if(o===0&&ad-H.measureText(M).width<0){H.textAlign="left";H.fillText(M,I+2+W,X+8)}else{H.textAlign="right";H.fillText(M,ad-2+W,X+8)}H.fillStyle=h}if(g){if(E){if(E=="+"){H.fillStyle=RIGHT_STRAND}else{if(E=="-"){H.fillStyle=LEFT_STRAND}}H.fillRect(ad+W,X,I-ad,10);H.fillStyle=h}for(var al=0,f=g.length;al<f;al++){var t=g[al],d=Math.floor(Math.max(0,(t[0]-L)*ar))
,U=Math.ceil(Math.min(a,Math.max((t[1]-L)*ar)));if(d>U){continue}D=5;ah=3;H.fillRect(d+W,X+ah,U-d,D);if(N!==undefined&&!(d>au||U<N)){D=9;ah=1;var ai=Math.max(d,N),z=Math.min(U,au);H.fillRect(ai+W,X+ah,z-ai,D)}}}else{D=9;ah=1;H.fillRect(ad+W,X+ah,I-ad,D);if(T.strand){if(T.strand=="+"){H.fillStyle=RIGHT_STRAND_INV}else{if(T.strand=="-"){H.fillStyle=LEFT_STRAND_INV}}H.fillRect(ad+W,X,I-ad,10);H.fillStyle=h}}}}else{if(G.dataset_type==="vcf"){if(ac){H.fillStyle=h;H.fillRect(ad+W,X+5,I-ad,1)}else{var s=T[4],m=T[5],c=T[6];D=9;ah=1;H.fillRect(ad+W,X,I-ad,D);if(q!=="Dense"&&M!==undefined&&ao>L){H.fillStyle=ag;if(o===0&&ad-H.measureText(M).width<0){H.textAlign="left";H.fillText(M,I+2+W,X+8)}else{H.textAlign="right";H.fillText(M,ad-2+W,X+8)}H.fillStyle=h}var l=s+" / "+m;if(ao>L&&H.measureText(l).width<(I-ad)){H.fillStyle="white";H.textAlign="center";H.fillText(l,W+ad+(I-ad)/2,X+8);H.fillStyle=h}}}}}am++}}r.append(S);return S},gen_options:function(j){var a=$("<div />").addClass("form-ro
w");var e="track_"+j+"_block_color",l=$("<label />").attr("for",e).text("Block color:"),m=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),k="track_"+j+"_label_color",g=$("<label />").attr("for",k).text("Text color:"),h=$("<input />").attr("id",k).attr("name",k).val(this.prefs.label_color),f="track_"+j+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(l).append(m).append(g).append(h).append(d)},update_options:function(e){var b=$("#track_"+e+"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.t
ile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,c){FeatureTrack.call(this,d,b,a,c);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -98,15 +98,17 @@ var View = function( container, chrom, t
var parent_element = this.container,
view = this;
this.top_labeltrack = $("<div/>").addClass("top-labeltrack").appendTo(parent_element);
- this.content_div = $("<div/>").addClass("content").css("position", "relative").hide().appendTo(parent_element);
- this.intro_div = $("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide().appendTo(parent_element);
+ this.content_div = $("<div/>").addClass("content").css("position", "relative").appendTo(parent_element);
this.viewport_container = $("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);
+ this.intro_div = $("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide(); // Future overlay
this.nav_container = $("<div/>").addClass("nav-container").appendTo(parent_element);
this.nav_labeltrack = $("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);
this.nav = $("<div/>").addClass("nav").appendTo(this.nav_container);
this.overview = $("<div/>").addClass("overview").appendTo(this.nav);
this.overview_viewport = $("<div/>").addClass("overview-viewport").appendTo(this.overview);
+ this.overview_close = $("<a href='javascript:void(0);'>Close Overview</a>").addClass("overview-close").hide().appendTo(this.overview_viewport);
+ this.overview_highlight = $("<div />").addClass("overview-highlight").hide().appendTo(this.overview_viewport);
this.overview_box_background = $("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);
this.overview_box = $("<div/>").addClass("overview-box").appendTo(this.overview_viewport);
this.default_overview_height = this.overview_box.height();
@@ -156,7 +158,6 @@ var View = function( container, chrom, t
}
view.chrom_select.html(chrom_options);
view.intro_div.show();
- view.content_div.hide();
view.chrom_select.bind("change", function() {
view.change_chrom(view.chrom_select.val());
});
@@ -195,6 +196,16 @@ var View = function( container, chrom, t
view.move_delta(-delta_chrom);
});
+ this.overview_close.bind("click", function() {
+ for (var track_id in view.tracks) {
+ view.tracks[track_id].is_overview = false;
+ }
+ $(this).siblings().filter("canvas").remove();
+ $(this).parent().css("height", view.overview_box.height());
+ view.overview_highlight.hide();
+ $(this).hide();
+ });
+
this.viewport_container.bind( "dragstart", function( e ) {
this.original_low = view.low;
this.current_height = e.clientY;
@@ -262,10 +273,8 @@ var View = function( container, chrom, t
if (view.chrom === "") {
// No chrom selected
view.intro_div.show();
- view.content_div.hide();
} else {
view.intro_div.hide();
- view.content_div.show();
}
view.chrom_select.val(view.chrom);
view.max_high = found.len;
@@ -381,10 +390,14 @@ var View = function( container, chrom, t
this.zoom_res = Math.pow( FEATURE_LEVELS, Math.max(0,Math.ceil( Math.log( this.resolution, FEATURE_LEVELS ) / Math.log(FEATURE_LEVELS) )));
// Overview
- var left_px = ( this.low / (this.max_high - this.max_low) ) * this.overview_viewport.width();
+ var left_px = this.low / (this.max_high - this.max_low) * this.overview_viewport.width();
var width_px = (this.high - this.low)/(this.max_high - this.max_low) * this.overview_viewport.width();
+ var min_width_px = 13;
- this.overview_box.css({ left: left_px, width: Math.max(12, width_px) }).show();
+ this.overview_box.css({ left: left_px, width: Math.max(min_width_px, width_px) }).show();
+ if (width_px < min_width_px) {
+ this.overview_box.css("left", left_px - (min_width_px - width_px)/2);
+ }
if (this.overview_highlight) {
this.overview_highlight.css({ left: left_px, width: width_px });
}
@@ -530,7 +543,7 @@ var TiledTrack = function() {
}
}
var track_dropdown = {};
- track_dropdown["Set track as overview"] = function() {
+ track_dropdown["Set as overview"] = function() {
view.overview_viewport.find("canvas").remove();
track.is_overview = true;
track.set_overview();
@@ -639,11 +652,9 @@ var TiledTrack = function() {
view.overview_box.height(view.default_overview_height);
if (this.initial_canvas && this.is_overview) {
- if (!view.overview_highlight) {
- view.overview_highlight = $("<div />").addClass("overview-highlight").appendTo(view.overview_viewport);
- }
+ view.overview_close.show();
view.overview_viewport.append(this.initial_canvas);
- view.overview_highlight.height(this.initial_canvas.height());
+ view.overview_highlight.show().height(this.initial_canvas.height());
view.overview_viewport.height(this.initial_canvas.height() + view.overview_box.height());
}
$(window).trigger("resize");
@@ -791,13 +802,15 @@ var LineTrack = function ( name, view, d
$('#linetrack_' + track_id + '_minval').remove();
$('#linetrack_' + track_id + '_maxval').remove();
+ track.container_div.css("position", "relative");
+
var min_label = $("<div />").addClass('yaxislabel').attr("id", 'linetrack_' + track_id + '_minval').text(round_1000(track.prefs.min_value));
var max_label = $("<div />").addClass('yaxislabel').attr("id", 'linetrack_' + track_id + '_maxval').text(round_1000(track.prefs.max_value));
- max_label.css({ position: "relative", top: "32px", left: "10px" });
+ max_label.css({ position: "absolute", top: "22px", left: "10px" });
max_label.prependTo(track.container_div);
- min_label.css({ position: "relative", top: track.height_px + 32 + "px", left: "10px" });
+ min_label.css({ position: "absolute", top: track.height_px + 11 + "px", left: "10px" });
min_label.prependTo(track.container_div);
});
},
Binary file static/images/visualization/draggable_horizontal.png has changed
--- a/lib/galaxy/web/controllers/tracks.py
+++ b/lib/galaxy/web/controllers/tracks.py
@@ -318,11 +318,11 @@ class TracksController( BaseController,
message = None
if isinstance(data, dict) and 'message' in data:
message = data['message']
- dataset_type = data.get( 'data_type', tracks_dataset_type )
+ tracks_dataset_type = data.get( 'data_type', tracks_dataset_type )
track_data = data['data']
else:
track_data = data
- return { 'dataset_type': dataset_type, 'extra_info': extra_info, 'data': track_data, 'message': message }
+ return { 'dataset_type': tracks_dataset_type, 'extra_info': extra_info, 'data': track_data, 'message': message }
@web.json
--- a/lib/galaxy/visualization/tracks/data/array_tree.py
+++ b/lib/galaxy/visualization/tracks/data/array_tree.py
@@ -12,7 +12,7 @@ from base import TracksDataProvider
class ArrayTreeDataProvider( TracksDataProvider ):
def get_stats( self, chrom ):
- f = open( self.dataset.file_name )
+ f = open( self.converted_dataset.file_name )
d = FileArrayTreeDict( f )
try:
chrom_array_tree = d[chrom]
--- a/static/june_2007_style/blue/trackster.css
+++ b/static/june_2007_style/blue/trackster.css
@@ -7,12 +7,14 @@
.nav-input{font-size:12px;width:30em;z-index:1000;}
.location{display:inline-block;width:15em;margin:0px 10px;}
.draghandle{float:left;background:transparent url(../images/visualization/draggable_horizontal.png) center center no-repeat;width:10px;height:12px;margin-right:5px;}
-.intro{margin-top:200px;margin-left:auto;margin-right:auto;color:#555;text-align:center;font-size:16px;}
+.intro{z-index:1000;margin-left:auto;margin-right:auto;color:#555;text-align:center;font-size:16px;}
.overview{width:100%;margin:0px;color:white;}
.overview-viewport{position:relative;height:14px;background:white;border-bottom:solid gray 1px;margin:0;}
-.overview-highlight{opacity:0.5;top:0px;position:absolute;z-index:100;border-style:solid;border-color:#6a6;border-width:0px 1px;}
+.overview-close{font:9px verdana;position:absolute;top:0px;right:0px;padding:5px;z-index:500;background-color:white;}
+.overview-highlight{opacity:0.5;top:0px;position:absolute;z-index:100;border-style:solid;border-color:#484848;border-width:0px 1px;}
.overview-boxback{width:100%;bottom:0px;z-index:50;position:absolute;height:14px;background:#eee;}
-.overview-box{opacity:0.5;bottom:0px;z-index:100;position:absolute;margin-top:0px;height:14px;background:#cfc url(../images/visualization/draggable_horizontal.png) center center no-repeat;border-style:solid;border-color:#6a6;border-width:0px 1px;}
+.overview-box{cursor:pointer;opacity:0.5;bottom:0px;z-index:100;position:absolute;margin-top:0px;height:14px;background:#484848 url(../images/visualization/draggable_horizontal.png) center center no-repeat;border-style:solid;border-color:#484848;border-width:0px 1px;-moz-border-radius:3px;border-radius:3px;}
+.overview-box:hover{background-color:#838383;border-color:#838383;}
.viewport-canvas{width:100%;height:100px;}
.yaxislabel{color:#777;}
.line-track .track-content{border-top:1px solid #ddd;border-bottom:1px solid #ddd;}
--- a/static/june_2007_style/trackster.css.tmpl
+++ b/static/june_2007_style/trackster.css.tmpl
@@ -42,7 +42,8 @@
margin-right: 5px;
}
.intro {
- margin-top: 200px;
+ z-index: 1000;
+/* margin-top: 200px;*/
margin-left: auto;
margin-right: auto;
color: #555;
@@ -63,13 +64,22 @@
border-bottom: solid gray 1px;
margin: 0;
}
+.overview-close {
+ font: 9px verdana;
+ position: absolute;
+ top: 0px;
+ right: 0px;
+ padding: 5px;
+ z-index: 500;
+ background-color: white;
+}
.overview-highlight {
opacity: 0.5;
top: 0px;
position: absolute;
z-index: 100;
border-style: solid;
- border-color: #6a6;
+ border-color: #484848;
border-width: 0px 1px;
}
.overview-boxback {
@@ -81,16 +91,23 @@
background: #eee;
}
.overview-box {
+ cursor: pointer;
opacity: 0.5;
bottom: 0px;
z-index: 100;
position: absolute;
margin-top: 0px;
height: 14px;
- background: #cfc url(../images/visualization/draggable_horizontal.png) center center no-repeat;
+ background: #484848 url(../images/visualization/draggable_horizontal.png) center center no-repeat;
border-style: solid;
- border-color: #6a6;
+ border-color: #484848;
border-width: 0px 1px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+}
+.overview-box:hover {
+ background-color: #838383;
+ border-color: #838383;
}
.viewport-canvas {
width: 100%;
1
0

galaxy-dist commit b36700318a81: Making the 'Lab' tab visible to users own at least one sequencing request
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User rc
# Date 1286562829 14400
# Node ID b36700318a817db7d9817213aef9e7d1602b9aec
# Parent d3fa82adee9782d27d4de9a92a3d1be47bd138c8
Making the 'Lab' tab visible to users own at least one sequencing request
--- a/templates/webapps/galaxy/base_panels.mako
+++ b/templates/webapps/galaxy/base_panels.mako
@@ -78,7 +78,7 @@
%>
## Lab menu.
- %if trans.user and trans.user.accessible_request_types(trans):
+ %if trans.user and trans.user.requests:
<%
menu_options = [
[ 'Sequencing Requests', h.url_for( controller='/requests', action='index' ) ],
1
0

galaxy-dist commit e082f7f28e62: Add requirements tag to fasta to bowtie index converters.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Dan Blankenberg <dan(a)bx.psu.edu>
# Date 1286544214 14400
# Node ID e082f7f28e628263faacb652ef9d0ee9b37d8532
# Parent 7c5d27bf6a41cd215088b8b9081572a30735bd43
Add requirements tag to fasta to bowtie index converters.
--- a/lib/galaxy/datatypes/converters/fasta_to_bowtie_color_index_converter.xml
+++ b/lib/galaxy/datatypes/converters/fasta_to_bowtie_color_index_converter.xml
@@ -1,4 +1,5 @@
<tool id="CONVERTER_fasta_to_bowtie_color_index" name="Convert FASTA to Bowtie color space Index" version="1.0.0">
+ <requirements><requirement type='package'>bowtie</requirement></requirements><!-- <description>__NOT_USED_CURRENTLY_FOR_CONVERTERS__</description> --><!-- Used on the metadata edit page. --><command>
--- a/lib/galaxy/datatypes/converters/fasta_to_bowtie_base_index_converter.xml
+++ b/lib/galaxy/datatypes/converters/fasta_to_bowtie_base_index_converter.xml
@@ -1,4 +1,5 @@
<tool id="CONVERTER_fasta_to_bowtie_base_index" name="Convert FASTA to Bowtie base space Index" version="1.0.0">
+ <requirements><requirement type='package'>bowtie</requirement></requirements><!-- <description>__NOT_USED_CURRENTLY_FOR_CONVERTERS__</description> --><!-- Used on the metadata edit page. --><command>
1
0

galaxy-dist commit b67978eeba2c: Add framework for specifying dynamic filters for tracks; framework uses datatype and dataset metadata to specify filters. VCF data provider uses framework to define filter for quality scores. Trackster client does not yet support filters.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1286804627 14400
# Node ID b67978eeba2c67c86453515d90f81a13acb88586
# Parent ddcfb334eb3ad53425a62f4b094374b219daa455
Add framework for specifying dynamic filters for tracks; framework uses datatype and dataset metadata to specify filters. VCF data provider uses framework to define filter for quality scores. Trackster client does not yet support filters.
--- a/lib/galaxy/datatypes/tabular.py
+++ b/lib/galaxy/datatypes/tabular.py
@@ -462,7 +462,14 @@ class ElandMulti( Tabular ):
return False
class Vcf( Tabular ):
+ """ Variant Call Format for describing SNPs and other simple genome variations. """
+
file_ext = 'vcf'
+ column_names = [ 'Chrom', 'Pos', 'ID', 'Ref', 'Alt', 'Qual', 'Filter', 'Info', 'Format', 'data' ]
+
+ MetadataElement( name="columns", default=10, desc="Number of columns", readonly=True, visible=False )
+ MetadataElement( name="column_types", default=['str','int','str','str','str','int','str','list','str','str'], param=metadata.ColumnTypesParameter, desc="Column types", readonly=True, visible=False )
+ MetadataElement( name="viz_filter_columns", default=[5] )
def sniff( self, filename ):
try:
@@ -472,6 +479,21 @@ class Vcf( Tabular ):
return True
except:
return False
+
+ def make_html_table( self, dataset, skipchars=[] ):
+ """Create HTML table, used for displaying peek"""
+ out = ['<table cellspacing="0" cellpadding="3">']
+ try:
+ # Generate column header
+ out.append( '<tr>' )
+ for i, name in enumerate( self.column_names ):
+ out.append( '<th>%s.%s</th>' % ( str( i+1 ), name ) )
+ out.append( self.make_html_peek_rows( dataset, skipchars=skipchars ) )
+ out.append( '</table>' )
+ out = "".join( out )
+ except Exception, exc:
+ out = "Can't create peek %s" % exc
+ return out
def get_track_type( self ):
return "FeatureTrack", {"data": "interval_index", "index": "summary_tree"}
--- a/lib/galaxy/web/controllers/tracks.py
+++ b/lib/galaxy/web/controllers/tracks.py
@@ -24,7 +24,8 @@ from galaxy.visualization.tracks.data.ar
from galaxy.visualization.tracks.data.interval_index import IntervalIndexDataProvider
from galaxy.visualization.tracks.data.bam import BamDataProvider
from galaxy.visualization.tracks.data.summary_tree import SummaryTreeDataProvider
-from galaxy.visualization.tracks.data.vcf import VCFDataProvider
+from galaxy.visualization.tracks.data.vcf import VcfDataProvider
+from galaxy.visualization.tracks.data.base import dataset_to_data_provider
# Message strings returned to browser
messages = Bunch(
@@ -39,9 +40,10 @@ messages = Bunch(
# Mapping from dataset type to a class that can fetch data from a file of that
# type. First key is converted dataset type; if result is another dict, second key
# is original dataset type. TODO: This needs to be more flexible.
+# TODO: move this mapping into TracksDataProvider
dataset_type_to_data_provider = {
"array_tree": ArrayTreeDataProvider,
- "interval_index": { "vcf": VCFDataProvider, "default" : IntervalIndexDataProvider },
+ "interval_index": { "vcf": VcfDataProvider, "default" : IntervalIndexDataProvider },
"bai": BamDataProvider,
"summary_tree": SummaryTreeDataProvider
}
@@ -150,12 +152,15 @@ class TracksController( BaseController,
hda_query = trans.sa_session.query( model.HistoryDatasetAssociation )
dataset = hda_query.get( dataset_id )
track_type, _ = dataset.datatype.get_track_type()
+ track_data_provider_class = dataset_to_data_provider( dataset )
+ track_data_provider = track_data_provider_class( original_dataset=dataset )
track = {
"track_type": track_type,
"name": dataset.name,
"dataset_id": dataset.id,
"prefs": {},
+ "filters": track_data_provider.get_filters()
}
return track
--- a/lib/galaxy/visualization/tracks/data/base.py
+++ b/lib/galaxy/visualization/tracks/data/base.py
@@ -1,7 +1,17 @@
+from galaxy.datatypes.tabular import Vcf
+from galaxy.visualization.tracks import data
+
class TracksDataProvider( object ):
""" Base class for tracks data providers. """
- def __init__( self, converted_dataset, original_dataset ):
+ """
+ Mapping from column name to index in data. This mapping is used to create
+ filters.
+ """
+ col_name_data_index_mapping = {}
+
+ def __init__( self, converted_dataset=None, original_dataset=None ):
+ """ Create basic data provider. """
self.converted_dataset = converted_dataset
self.original_dataset = original_dataset
@@ -9,3 +19,59 @@ class TracksDataProvider( object ):
""" Returns data in region defined by chrom, start, and end. """
# Override.
pass
+
+ def get_filters( self ):
+ """
+ Returns filters for provider's data. Return value is a list of
+ filters; each filter is a dictionary with the keys 'name', 'index', 'value'.
+ NOTE: This method uses the original dataset's datatype and metadata to
+ create the filters.
+ """
+ # Get column names.
+ try:
+ column_names = self.original_dataset.datatype.column_names
+ except AttributeError:
+ column_names = range( self.original_dataset.metadata.columns )
+
+ # Dataset must have column types; if not, cannot create filters.
+ try:
+ column_types = self.original_dataset.metadata.column_types
+ except AttributeError:
+ return []
+
+ # Create and return filters.
+ filters = []
+ if self.original_dataset.metadata.viz_filter_columns:
+ for viz_col_index in self.original_dataset.metadata.viz_filter_columns:
+ col_name = column_names[ viz_col_index ]
+ # Make sure that column has a mapped index. If not, do not add filter.
+ try:
+ index = self.col_name_data_index_mapping[ col_name ]
+ except KeyError:
+ continue
+ filters.append(
+ { 'name' : col_name, 'value' : column_types[viz_col_index], \
+ 'index' : index } )
+ return filters
+
+
+#
+# Helper methods.
+#
+
+def dataset_to_data_provider( dataset=None ):
+ """
+ Returns data provider for a dataset.
+ """
+ # TODO: merge this method with the dict in tracks controller to provide a
+ # unified way to get data providers based on dataset/converted dataset type.
+ if isinstance( dataset.datatype, Vcf ):
+ return data.vcf.VcfDataProvider
+ else:
+ try:
+ # If get_track_type is available, then generic data provider
+ # should work.
+ dataset.datatype.get_track_type()
+ return TracksDataProvider
+ except e:
+ return None
--- a/lib/galaxy/visualization/tracks/data/vcf.py
+++ b/lib/galaxy/visualization/tracks/data/vcf.py
@@ -1,10 +1,3 @@
-"""
-VCF data provider for the Galaxy track browser.
-
-Payload format:
-[ uid (offset), start, end, ID, reference base(s), alternate base(s), quality score]
-"""
-
import pkg_resources; pkg_resources.require( "bx-python" )
from bx.interval_index_file import Indexes
from galaxy.datatypes.tabular import Vcf
@@ -12,8 +5,15 @@ from base import TracksDataProvider
MAX_VALS = 5000 # only display first MAX_VALS features
-class VCFDataProvider( TracksDataProvider ):
- """ Provides data for VCF tracks. """
+class VcfDataProvider( TracksDataProvider ):
+ """
+ VCF data provider for the Galaxy track browser.
+
+ Payload format:
+ [ uid (offset), start, end, ID, reference base(s), alternate base(s), quality score]
+ """
+
+ col_name_data_index_mapping = { 'Qual' : 6 }
def get_data( self, chrom, start, end, **kwargs ):
""" Returns data in region defined by chrom, start, and end. """
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -9,6 +9,7 @@ from galaxy.model.orm import *
from galaxy.workflow.modules import *
from galaxy.web.framework import simplejson
from galaxy.web.form_builder import AddressField, CheckboxField, SelectField, TextArea, TextField, WorkflowField
+from galaxy.visualization.tracks.data.base import dataset_to_data_provider
from Cheetah.Template import Template
@@ -169,11 +170,15 @@ class UsesVisualization( SharableItemSec
prefs = {}
dataset = hda_query.get( dataset_id )
track_type, _ = dataset.datatype.get_track_type()
+ track_data_provider_class = dataset_to_data_provider( dataset )
+ track_data_provider = track_data_provider_class( original_dataset=dataset )
+
tracks.append( {
"track_type": track_type,
"name": dataset.name,
"dataset_id": dataset.id,
"prefs": simplejson.dumps(prefs),
+ "filters": track_data_provider.get_filters()
} )
config = { "title": visualization.title, "vis_id": trans.security.encode_id( visualization.id ),
1
0

galaxy-dist commit 5038f0863ab9: Actually change the invocation of sputnik from bx-sputnik as mentioned in my last commit. Thanks Kanwei.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Nate Coraor <nate(a)bx.psu.edu>
# Date 1286484637 14400
# Node ID 5038f0863ab9a8286fd97c718c63945bfd442dd0
# Parent b9f3c613c0266e9285679b06e39802a452f4b151
Actually change the invocation of sputnik from bx-sputnik as mentioned in my last commit. Thanks Kanwei.
--- a/tools/regVariation/microsats_alignment_level.py
+++ b/tools/regVariation/microsats_alignment_level.py
@@ -34,7 +34,7 @@ def main():
fout = open(outfile, "w")
print >>fout, "#Block\tSeq1_Name\tSeq1_Start\tSeq1_End\tSeq1_Type\tSeq1_Length\tSeq1_RepeatNumber\tSeq1_Unit\tSeq2_Name\tSeq2_Start\tSeq2_End\tSeq2_Type\tSeq2_Length\tSeq2_RepeatNumber\tSeq2_Unit"
#sputnik_cmd = os.path.join(os.path.split(sys.argv[0])[0], "sputnik")
- sputnik_cmd = "bx-sputnik"
+ sputnik_cmd = "sputnik"
input = infile.read()
skipped = 0
block_num = 0
1
0

galaxy-dist commit d85159be56e8: Add basic support for bowtie indexes as a datatype (bowtie_base_index, bowtie_color_index), available via datatype conversion. Currently, the indexes need to be converted manually from the FASTA file before use in bowtie, but they can be reused.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Dan Blankenberg <dan(a)bx.psu.edu>
# Date 1286485181 14400
# Node ID d85159be56e854731822a314a2e982e0c6987389
# Parent 5038f0863ab9a8286fd97c718c63945bfd442dd0
Add basic support for bowtie indexes as a datatype (bowtie_base_index, bowtie_color_index), available via datatype conversion. Currently, the indexes need to be converted manually from the FASTA file before use in bowtie, but they can be reused.
More work is required to allow the one-off indexes built by bowtie to become Galaxy datasets; alternatively, the custom genome selection could be limited to the index datatype for input (and not allow fasta directly), which would allow implicit datatype conversion to occur when a fasta file is selected as input, but this would prevent the index tuning that is currently available when currently selecting a fasta file.
--- a/datatypes_conf.xml.sample
+++ b/datatypes_conf.xml.sample
@@ -45,10 +45,14 @@
<datatype extension="csv" type="galaxy.datatypes.tabular:Tabular"/><!-- End MSI added Datatypes --><datatype extension="customtrack" type="galaxy.datatypes.interval:CustomTrack"/>
+ <datatype extension="bowtie_color_index" type="galaxy.datatypes.ngsindex:BowtieColorIndex" mimetype="text/html" display_in_upload="False"/>
+ <datatype extension="bowtie_base_index" type="galaxy.datatypes.ngsindex:BowtieBaseIndex" mimetype="text/html" display_in_upload="False"/><datatype extension="csfasta" type="galaxy.datatypes.sequence:csFasta" display_in_upload="true"/><datatype extension="data" type="galaxy.datatypes.data:Data" mimetype="application/octet-stream" max_optional_metadata_filesize="1048576" /><datatype extension="fasta" type="galaxy.datatypes.sequence:Fasta" display_in_upload="true"><converter file="fasta_to_tabular_converter.xml" target_datatype="tabular"/>
+ <converter file="fasta_to_bowtie_base_index_converter.xml" target_datatype="bowtie_base_index"/>
+ <converter file="fasta_to_bowtie_color_index_converter.xml" target_datatype="bowtie_color_index"/></datatype><datatype extension="fastq" type="galaxy.datatypes.sequence:Fastq" display_in_upload="true"/><datatype extension="fastqsanger" type="galaxy.datatypes.sequence:FastqSanger" display_in_upload="true"/>
--- a/tools/sr_mapping/bowtie_wrapper.xml
+++ b/tools/sr_mapping/bowtie_wrapper.xml
@@ -12,6 +12,10 @@
--snpfrac="None"
--keepends="None"
#if $refGenomeSource.genomeSource == "history":
+ #if $refGenomeSource.ownFile.extension.startswith( 'bowtie_' ):
+ --ref="${refGenomeSource.ownFile.extra_files_path}/${refGenomeSource.ownFile.metadata.base_name}"
+ --do_not_build_index
+ #else:
--ref=$refGenomeSource.ownFile
--indexSettings=$refGenomeSource.indexParams.indexSettings
#if $refGenomeSource.indexParams.indexSettings == "indexFull":
@@ -50,6 +54,7 @@
--iseed="None"
--icutoff="None"
#end if
+ #end if
#else:
--ref=$refGenomeSource.index
--indexSettings="None"
@@ -203,9 +208,9 @@
</param></when><when value="history">
- <param name="ownFile" type="data" format="fasta" metadata_name="dbkey" label="Select the reference genome" />
+ <param name="ownFile" type="data" format="bowtie_base_index,fasta" metadata_name="dbkey" label="Select the reference genome" /><conditional name="indexParams">
- <param name="indexSettings" type="select" label="Choose whether to use Default options for building indices or to Set your own">
+ <param name="indexSettings" type="select" label="Choose whether to use Default options for building indices or to Set your own" help="These settings are ignored when using a prebuilt index"><option value="indexPreSet">Default</option><option value="indexFull">Set your own</option></param>
--- /dev/null
+++ b/lib/galaxy/datatypes/converters/fasta_to_bowtie_base_index_converter.xml
@@ -0,0 +1,18 @@
+<tool id="CONVERTER_fasta_to_bowtie_base_index" name="Convert FASTA to Bowtie base space Index" version="1.0.0">
+ <!-- <description>__NOT_USED_CURRENTLY_FOR_CONVERTERS__</description> -->
+ <!-- Used on the metadata edit page. -->
+ <command>
+ mkdir ${output.files_path}
+ && bowtie-build --quiet
+ -f
+ $input ${output.files_path}/${output.metadata.base_name}
+ </command>
+ <inputs>
+ <param name="input" type="data" format="fasta" label="Fasta file"/>
+ </inputs>
+ <outputs>
+ <data name="output" format="bowtie_base_index"/>
+ </outputs>
+ <help>
+ </help>
+</tool>
--- a/lib/galaxy/datatypes/registry.py
+++ b/lib/galaxy/datatypes/registry.py
@@ -3,7 +3,7 @@ Provides mapping between extensions and
"""
import os, tempfile
import logging
-import data, tabular, interval, images, sequence, qualityscore, genetics, xml, coverage, tracks, chrominfo, binary, assembly
+import data, tabular, interval, images, sequence, qualityscore, genetics, xml, coverage, tracks, chrominfo, binary, assembly, ngsindex
import galaxy.util
from galaxy.util.odict import odict
from display_applications.application import DisplayApplication
--- a/tools/sr_mapping/bowtie_wrapper.py
+++ b/tools/sr_mapping/bowtie_wrapper.py
@@ -56,6 +56,7 @@ usage: bowtie_wrapper.py [options]
-c, --icutoff=c: Number of first bases of the reference sequence to index
-x, --indexSettings=x: Whether or not indexing options are to be set
-H, --suppressHeader=H: Suppress header
+ --do_not_build_index: Flag to specify that provided file is already indexed and to just use 'as is'
"""
import optparse, os, shutil, subprocess, sys, tempfile
@@ -118,6 +119,7 @@ def __main__():
parser.add_option( '-c', '--icutoff', dest='icutoff', help='Number of first bases of the reference sequence to index' )
parser.add_option( '-x', '--indexSettings', dest='index_settings', help='Whether or not indexing options are to be set' )
parser.add_option( '-H', '--suppressHeader', dest='suppressHeader', help='Suppress header' )
+ parser.add_option( '--do_not_build_index', dest='do_not_build_index', action="store_true", default=False, help='Flag to specify that provided file is already indexed, use as is' )
(options, args) = parser.parse_args()
stdout = ''
@@ -129,7 +131,7 @@ def __main__():
else:
colorspace = ''
# index if necessary
- if options.genomeSource == 'history':
+ if options.genomeSource == 'history' and not options.do_not_build_index:
# set up commands
if options.index_settings =='indexPreSet':
indexing_cmds = '%s' % colorspace
--- a/tools/sr_mapping/bowtie_color_wrapper.xml
+++ b/tools/sr_mapping/bowtie_color_wrapper.xml
@@ -9,6 +9,10 @@
--suppressHeader=$suppressHeader
--genomeSource=$refGenomeSource.genomeSource
#if $refGenomeSource.genomeSource == "history":
+ #if $refGenomeSource.ownFile.extension.startswith( 'bowtie_' ):
+ --ref="${refGenomeSource.ownFile.extra_files_path}/${refGenomeSource.ownFile.metadata.base_name}"
+ --do_not_build_index
+ #else:
--ref=$refGenomeSource.ownFile
--indexSettings=$refGenomeSource.indexParams.indexSettings
#if $refGenomeSource.indexParams.indexSettings == "indexFull":
@@ -47,6 +51,7 @@
--iseed="None"
--icutoff="None"
#end if
+ #end if
#else:
--ref=$refGenomeSource.index
--indexSettings="None"
@@ -206,9 +211,9 @@
</param></when><when value="history">
- <param name="ownFile" type="data" format="fasta" metadata_name="dbkey" label="Select the reference genome" />
+ <param name="ownFile" type="data" format="bowtie_color_index,fasta" metadata_name="dbkey" label="Select the reference genome" /><conditional name="indexParams">
- <param name="indexSettings" type="select" label="Choose whether to use Default options for building indices or to Set your own">
+ <param name="indexSettings" type="select" label="Choose whether to use Default options for building indices or to Set your own" help="These settings are ignored when using a prebuilt index"><option value="indexPreSet">Default</option><option value="indexFull">Set your own</option></param>
--- /dev/null
+++ b/lib/galaxy/datatypes/ngsindex.py
@@ -0,0 +1,75 @@
+"""
+NGS indexes
+"""
+import logging
+from metadata import MetadataElement
+from images import Html
+
+log = logging.getLogger(__name__)
+
+class BowtieIndex( Html ):
+ """
+ base class for BowtieIndex
+ is subclassed by BowtieColorIndex and BowtieBaseIndex
+ """
+ MetadataElement( name="base_name", desc="base name for this index set", default='galaxy_generated_bowtie_index', set_in_upload=True, readonly=True )
+ MetadataElement( name="sequence_space", desc="sequence_space for this index set", default='unknown', set_in_upload=True, readonly=True )
+
+ file_ext = 'bowtie_index'
+ is_binary = True
+ composite_type = 'auto_primary_file'
+ allow_datatype_change = False
+
+ def generate_primary_file( self, dataset = None ):
+ """
+ This is called only at upload to write the html file
+ cannot rename the datasets here - they come with the default unfortunately
+ """
+ return '<html><head></head><body>AutoGenerated Primary File for Composite Dataset</body></html>'
+
+ def regenerate_primary_file(self,dataset):
+ """
+ cannot do this until we are setting metadata
+ """
+ bn = dataset.metadata.base_name
+ flist = os.listdir(dataset.extra_files_path)
+ rval = ['<html><head><title>Files for Composite Dataset %s</title></head><p/>Comprises the following files:<p/><ul>' % (bn)]
+ for i,fname in enumerate(flist):
+ sfname = os.path.split(fname)[-1]
+ rval.append( '<li><a href="%s">%s</a>' % ( sfname, sfname ) )
+ rval.append( '</ul></html>' )
+ f = file(dataset.file_name,'w')
+ f.write("\n".join( rval ))
+ f.write('\n')
+ f.close()
+
+ def set_peek( self, dataset, is_multi_byte=False ):
+ if not dataset.dataset.purged:
+ dataset.peek = "Bowtie index file (%s)" % ( dataset.metadata.sequence_space )
+ dataset.blurb = "%s space" % ( dataset.metadata.sequence_space )
+ else:
+ dataset.peek = 'file does not exist'
+ dataset.blurb = 'file purged from disk'
+ def display_peek( self, dataset ):
+ try:
+ return dataset.peek
+ except:
+ return "Bowtie index file"
+ def sniff( self, filename ):
+ return False
+
+class BowtieColorIndex( BowtieIndex ):
+ """
+ Bowtie color space index
+ """
+ MetadataElement( name="sequence_space", desc="sequence_space for this index set", default='color', set_in_upload=True, readonly=True )
+
+ file_ext = 'bowtie_color_index'
+
+class BowtieBaseIndex( BowtieIndex ):
+ """
+ Bowtie base space index
+ """
+ MetadataElement( name="sequence_space", desc="sequence_space for this index set", default='base', set_in_upload=True, readonly=True )
+
+ file_ext = 'bowtie_base_index'
--- /dev/null
+++ b/lib/galaxy/datatypes/converters/fasta_to_bowtie_color_index_converter.xml
@@ -0,0 +1,19 @@
+<tool id="CONVERTER_fasta_to_bowtie_color_index" name="Convert FASTA to Bowtie color space Index" version="1.0.0">
+ <!-- <description>__NOT_USED_CURRENTLY_FOR_CONVERTERS__</description> -->
+ <!-- Used on the metadata edit page. -->
+ <command>
+ mkdir ${output.files_path}
+ && bowtie-build --quiet
+ --color
+ -f
+ $input ${output.files_path}/${output.metadata.base_name}
+ </command>
+ <inputs>
+ <param name="input" type="data" format="fasta" label="Fasta file"/>
+ </inputs>
+ <outputs>
+ <data name="output" format="bowtie_color_index"/>
+ </outputs>
+ <help>
+ </help>
+</tool>
1
0

galaxy-dist commit 3316517f0980: Enable 'FASTX-Toolkit for FASTQ data' as a subsection under 'NGS: QC and manipulation' in tool_conf.xml.sample/main.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Dan Blankenberg <dan(a)bx.psu.edu>
# Date 1286458054 14400
# Node ID 3316517f0980642b7706f26ab3a5b4ec461acfde
# Parent 9cada14f87657b951ccc9a76af5de03263ba72d9
Enable 'FASTX-Toolkit for FASTQ data' as a subsection under 'NGS: QC and manipulation' in tool_conf.xml.sample/main.
--- a/tool_conf.xml.sample
+++ b/tool_conf.xml.sample
@@ -218,15 +218,6 @@
<tool file="fastq/fastq_paired_end_splitter.xml" /><tool file="fastq/fastq_paired_end_joiner.xml" /><tool file="fastq/fastq_stats.xml" />
- <!--<label text="Deprecated: Generic FASTQ data" id="fastq" />
- <tool file="next_gen_conversion/fastq_gen_conv.xml" />
- <tool file="fastx_toolkit/fastq_quality_converter.xml" />
- <tool file="fastx_toolkit/fastx_quality_statistics.xml" />
- <tool file="fastx_toolkit/fastq_quality_boxplot.xml" />
- <tool file="fastx_toolkit/fastx_nucleotides_distribution.xml" />
- <tool file="metag_tools/split_paired_reads.xml"
- <tool file="fastx_toolkit/fastq_to_fasta.xml" />
- --><label text="Roche-454 data" id="454" /><tool file="metag_tools/short_reads_figure_score.xml" /><tool file="metag_tools/short_reads_trim_seq.xml" />
@@ -244,6 +235,21 @@
<tool file="fastq/fastq_to_fasta.xml" /><tool file="fastq/fastq_to_tabular.xml" /><tool file="fastq/tabular_to_fastq.xml" />
+ <label text="FASTX-Toolkit for FASTQ data" id="fastx_toolkit" />
+ <tool file="fastx_toolkit/fastq_quality_converter.xml" />
+ <tool file="fastx_toolkit/fastx_quality_statistics.xml" />
+ <tool file="fastx_toolkit/fastq_quality_boxplot.xml" />
+ <tool file="fastx_toolkit/fastx_nucleotides_distribution.xml" />
+ <tool file="fastx_toolkit/fastq_to_fasta.xml" />
+ <tool file="fastx_toolkit/fastq_quality_filter.xml" />
+ <tool file="fastx_toolkit/fastq_to_fasta.xml" />
+ <tool file="fastx_toolkit/fastx_artifacts_filter.xml" />
+ <tool file="fastx_toolkit/fastx_barcode_splitter.xml" />
+ <tool file="fastx_toolkit/fastx_clipper.xml" />
+ <tool file="fastx_toolkit/fastx_collapser.xml" />
+ <tool file="fastx_toolkit/fastx_renamer.xml" />
+ <tool file="fastx_toolkit/fastx_reverse_complement.xml" />
+ <tool file="fastx_toolkit/fastx_trimmer.xml" /></section><!--
Keep this section commented until it includes tools that
--- a/tool_conf.xml.main
+++ b/tool_conf.xml.main
@@ -305,15 +305,6 @@
<tool file="fastq/fastq_paired_end_splitter.xml" /><tool file="fastq/fastq_paired_end_joiner.xml" /><tool file="fastq/fastq_stats.xml" />
- <!--<label text="Deprecated: Generic FASTQ data" id="fastq" />
- <tool file="next_gen_conversion/fastq_gen_conv.xml" />
- <tool file="fastx_toolkit/fastq_quality_converter.xml" />
- <tool file="fastx_toolkit/fastx_quality_statistics.xml" />
- <tool file="fastx_toolkit/fastq_quality_boxplot.xml" />
- <tool file="fastx_toolkit/fastx_nucleotides_distribution.xml" />
- <tool file="metag_tools/split_paired_reads.xml" />
- <tool file="fastx_toolkit/fastq_to_fasta.xml" />
- --><label text="Roche-454 data" id="454" /><tool file="metag_tools/short_reads_figure_score.xml" /><tool file="metag_tools/short_reads_trim_seq.xml" />
@@ -331,6 +322,21 @@
<tool file="fastq/fastq_to_fasta.xml" /><tool file="fastq/fastq_to_tabular.xml" /><tool file="fastq/tabular_to_fastq.xml" />
+ <label text="FASTX-Toolkit for FASTQ data" id="fastx_toolkit_fastq" />
+ <tool file="fastx_toolkit/fastq_quality_converter.xml" />
+ <tool file="fastx_toolkit/fastx_quality_statistics.xml" />
+ <tool file="fastx_toolkit/fastq_quality_boxplot.xml" />
+ <tool file="fastx_toolkit/fastx_nucleotides_distribution.xml" />
+ <tool file="fastx_toolkit/fastq_to_fasta.xml" />
+ <tool file="fastx_toolkit/fastq_quality_filter.xml" />
+ <tool file="fastx_toolkit/fastq_to_fasta.xml" />
+ <tool file="fastx_toolkit/fastx_artifacts_filter.xml" />
+ <tool file="fastx_toolkit/fastx_barcode_splitter.xml" />
+ <tool file="fastx_toolkit/fastx_clipper.xml" />
+ <tool file="fastx_toolkit/fastx_collapser.xml" />
+ <tool file="fastx_toolkit/fastx_renamer.xml" />
+ <tool file="fastx_toolkit/fastx_reverse_complement.xml" />
+ <tool file="fastx_toolkit/fastx_trimmer.xml" /></section><section name="NGS: Mapping" id="ngs_mapping"><label text="Illumina" id="illumina"/>
1
0