galaxy-commits
Threads by month
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- 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
08 Apr '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/65d680dc05fb/
changeset: r5362:65d680dc05fb
user: jgoecks
date: 2011-04-08 23:07:08
summary: Trackster: fix (a) bug that was not setting appropriate CSS class for track content divs and (b) padding issues with different track states. Also increase bottom border to better delineate tracks.
affected #: 4 files (397 bytes)
--- a/static/june_2007_style/blue/trackster.css Fri Apr 08 16:43:45 2011 -0400
+++ b/static/june_2007_style/blue/trackster.css Fri Apr 08 17:07:08 2011 -0400
@@ -22,13 +22,13 @@
.track{background:white;}
.track-header{text-align:left;padding:4px 0px;color:#666;}
.track-header .menubutton{margin-left:0px;}
-.track-content{overflow:hidden;text-align:center;border-top:1px solid #eee;border-bottom:1px solid #eee;background:#eee url('/static/images/tracks/diag_bg.gif');min-height:16px;}
+.track-content{overflow:hidden;text-align:center;border-top:1px solid #eee;border-bottom:2px solid #eee;background:#eee url('/static/images/tracks/diag_bg.gif');min-height:16px;}
.label-track .track-content{background:white;}
.track-tile{background:white;}
.track-tile canvas{position:relative;z-index:100;border:solid white;border-width:2px 0px 0px 0px;}
-.track.error .track-content{background-color:#ECB4AF;background-image:none;padding:2px 0;}
-.track.nodata .track-content{background-color:#eee;background-image:none;padding:2px 0;}
-.track.pending .track-content{background-color:white;background-image:none;padding:2px 0;}
+.track.error .track-content{background-color:#ECB4AF;background-image:none;}
+.track.nodata .track-content{background-color:#eee;background-image:none;}
+.track.pending .track-content{background-color:white;background-image:none;}
.loading{min-height:100px;}
.label-track{font-size:10px;border:none;padding:0;margin:0;height:1.5em;overflow:hidden;}
.label-track .label{border-left:solid #999 1px;padding:1px;padding-bottom:2px;display:inline-block;}
--- a/static/june_2007_style/trackster.css.tmpl Fri Apr 08 16:43:45 2011 -0400
+++ b/static/june_2007_style/trackster.css.tmpl Fri Apr 08 17:07:08 2011 -0400
@@ -147,7 +147,7 @@
overflow: hidden;
text-align: center;
border-top: 1px solid #eee;
- border-bottom: 1px solid #eee;
+ border-bottom: 2px solid #eee;
background: #eee url('/static/images/tracks/diag_bg.gif');
min-height: 16px;
}
--- a/static/scripts/packed/trackster.js Fri Apr 08 16:43:45 2011 -0400
+++ b/static/scripts/packed/trackster.js Fri Apr 08 17:07:08 2011 -0400
@@ -1,1 +1,1 @@
-var extend=function(){var c=arguments[0];for(var b=1;b<arguments.length;b++){var a=arguments[b];for(key in a){c[key]=a[key]}}};var trackster_module=function(f,Q){var o=f("slotting"),G=f("painters");var V=function(W,X){this.document=W;this.default_font=X!==undefined?X:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};extend(V.prototype,{load_pattern:function(W,aa){var X=this.patterns,Y=this.dummy_context,Z=new Image();Z.src=image_path+aa;Z.onload=function(){X[W]=Y.createPattern(Z,"repeat")}},get_pattern:function(W){return this.patterns[W]},new_canvas:function(){var W=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(W)}W.manager=this;return W}});var B=function(W,X){W.bind("drag",{handle:X,relative:true},function(ab,ac){var aa=$(this).parent();var Z=aa.children();var Y;for(Y=0;Y<Z.length;Y++){if(ac.offsetY<$(Z.get(Y)).position().top){break}}if(Y===Z.length){if(this!==Z.get(Y-1)){aa.append(this)}}else{if(this!==Z.get(Y)){$(this).insertBefore(Z.get(Y))}}})};var h=function(Y,W){var X=W-Y;return(X<=2?0.01:(X<=100?1:(X<=1000?5:10)))};var C=9,z=10,L=C+2,w=100,D=12000,J=200,r=10,F=5000,s=100,m="There was an error in indexing this dataset. ",E="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",A="No data for this chrom/contig.",p="Currently indexing... please wait",u="Tool cannot be rerun: ",a="Loading data...",R="Ready for display",d=10,q=5,y=5;function t(W){return Math.round(W*1000)/1000}var c=function(W){this.num_elements=W;this.clear()};extend(c.prototype,{get:function(X){var W=this.key_ary.indexOf(X);if(W!==-1){this.move_key_to_end(X,W)}return this.obj_cache[X]},set:function(X,Y){if(!this.obj_cache[X]){if(this.key_ary.length>=this.num_elements){var W=this.key_ary.shift();delete this.obj_cache[W]}this.key_ary.push(X)}this.obj_cache[X]=Y;return Y},move_key_to_end:function(X,W){this.key_ary.splice(W,1);this.key_ary.push(X)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var K=function(X,W,Y){c.call(this,X);this.track=W;this.subset=(Y!==undefined?Y:true)};extend(K.prototype,c.prototype,{load_data:function(ad,ae,Z,ac,W,ab){var Y={chrom:ad,low:ae,high:Z,mode:ac,resolution:W,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(Y,ab);var af=[];for(var aa=0;aa<this.track.filters.length;aa++){af[af.length]=this.track.filters[aa].name}Y.filter_cols=JSON.stringify(af);var X=this;return $.getJSON(this.track.data_url,Y,function(ag){X.set_data(ae,Z,ac,ag)})},get_data:function(Y,W,ab,ac,X,aa){var Z=this.get(this.gen_key(W,ab,ac));if(Z){return Z}Z=this.load_data(Y,W,ab,ac,X,aa);this.set_data(W,ab,ac,Z);return Z},set_data:function(X,Y,Z,W){return this.set(this.gen_key(X,Y,Z),W)},gen_key:function(W,Y,Z){var X=W+"_"+Y+"_"+Z;return X},split_key:function(W){return W.split("_")}});var U=function(W,Z,Y,X,aa){this.container=W;this.chrom=null;this.vis_id=Y;this.dbkey=X;this.title=Z;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(aa);this.canvas_manager=new V(W.get(0).ownerDocument);this.reset()};extend(U.prototype,{init:function(Z){var Y=this.container,W=this;this.top_container=$("<div/>").addClass("top-container").appendTo(Y);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(Y);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(Y);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);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_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);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_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var X=function(aa){if(aa.type==="focusout"||(aa.keyCode||aa.which)===13||(aa.keyCode||aa.which)===27){if((aa.keyCode||aa.which)!==27){W.go_to($(this).val())}$(this).hide();$(this).val("");W.location_span.show();W.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",X).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.bind("click",function(){W.location_span.hide();W.chrom_select.hide();W.nav_input.val(W.chrom+":"+W.low+"-"+W.high);W.nav_input.css("display","inline-block");W.nav_input.select();W.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a id='zoom-out' />").click(function(){W.zoom_out();W.redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){W.zoom_in();W.redraw()}).appendTo(this.nav_controls);this.load_chroms({low:0},Z);this.chrom_select.bind("change",function(){W.change_chrom(W.chrom_select.val())});this.intro_div.show();this.content_div.bind("click",function(aa){$(this).find("input").trigger("blur")});this.content_div.bind("dblclick",function(aa){W.zoom_in(aa.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(aa,ab){this.current_x=ab.offsetX}).bind("drag",function(aa,ac){var ad=ac.offsetX-this.current_x;this.current_x=ac.offsetX;var ab=Math.round(ad/W.viewport_container.width()*(W.max_high-W.max_low));W.move_delta(-ab)});this.overview_close.bind("click",function(){for(var ab=0,aa=W.tracks.length;ab<aa;ab++){W.tracks[ab].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",W.overview_box.height());W.overview_highlight.hide();$(this).hide()});this.viewport_container.bind("draginit",function(aa,ab){if(aa.clientX>W.viewport_container.width()-16){return false}}).bind("dragstart",function(aa,ab){ab.original_low=W.low;ab.current_height=aa.clientY;ab.current_x=ab.offsetX}).bind("drag",function(ac,ae){var aa=$(this);var af=ae.offsetX-ae.current_x;var ab=aa.scrollTop()-(ac.clientY-ae.current_height);aa.scrollTop(ab);ae.current_height=ac.clientY;ae.current_x=ae.offsetX;var ad=Math.round(af/W.viewport_container.width()*(W.high-W.low));W.move_delta(ad)}).bind("mousewheel",function(ac,ae,ab,aa){if(ab){var ad=Math.round(-ab/W.viewport_container.width()*(W.high-W.low));W.move_delta(ad)}});this.top_labeltrack.bind("dragstart",function(aa,ab){return $("<div />").css({height:W.content_div.height()+W.top_labeltrack.height()+W.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ae,af){$(af.proxy).css({left:Math.min(ae.pageX,af.startX),width:Math.abs(ae.pageX-af.startX)});var ab=Math.min(ae.pageX,af.startX)-W.container.offset().left,aa=Math.max(ae.pageX,af.startX)-W.container.offset().left,ad=(W.high-W.low),ac=W.viewport_container.width();W.update_location(Math.round(ab/ac*ad)+W.low,Math.round(aa/ac*ad)+W.low)}).bind("dragend",function(af,ag){var ab=Math.min(af.pageX,ag.startX),aa=Math.max(af.pageX,ag.startX),ad=(W.high-W.low),ac=W.viewport_container.width(),ae=W.low;W.low=Math.round(ab/ac*ad)+ae;W.high=Math.round(aa/ac*ad)+ae;$(ag.proxy).remove();W.redraw()});this.add_label_track(new T(this,this.top_labeltrack));this.add_label_track(new T(this,this.nav_labeltrack));$(window).bind("resize",function(){W.resize_window()});$(document).bind("redraw",function(){W.redraw()});this.reset();$(window).trigger("resize")},update_location:function(W,X){this.location_span.text(commatize(W)+" - "+commatize(X));this.nav_input.val(this.chrom+":"+commatize(W)+"-"+commatize(X))},load_chroms:function(X,Y){X.num=s;$.extend(X,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var W=this;$.ajax({url:chrom_url,data:X,dataType:"json",success:function(aa){if(aa.chrom_info.length===0){alert("Invalid chromosome: "+X.chrom);return}if(aa.reference){W.add_label_track(new x(W))}W.chrom_data=aa.chrom_info;var ad='<option value="">Select Chrom/Contig</option>';for(var ac=0,Z=W.chrom_data.length;ac<Z;ac++){var ab=W.chrom_data[ac].chrom;ad+='<option value="'+ab+'">'+ab+"</option>"}if(aa.prev_chroms){ad+='<option value="previous">Previous '+s+"</option>"}if(aa.next_chroms){ad+='<option value="next">Next '+s+"</option>"}W.chrom_select.html(ad);if(Y){Y()}W.chrom_start_index=aa.start_index},error:function(){alert("Could not load chroms for this dbkey:",W.dbkey)}})},change_chrom:function(aa,X,ac){if(!aa||aa==="None"){return}var Z=this;if(aa==="previous"){Z.load_chroms({low:this.chrom_start_index-s});return}if(aa==="next"){Z.load_chroms({low:this.chrom_start_index+s});return}var ab=$.grep(Z.chrom_data,function(ae,af){return ae.chrom===aa})[0];if(ab===undefined){Z.load_chroms({chrom:aa},function(){Z.change_chrom(aa,X,ac)});return}else{if(aa!==Z.chrom){Z.chrom=aa;if(!Z.chrom){Z.intro_div.show()}else{Z.intro_div.hide()}Z.chrom_select.val(Z.chrom);Z.max_high=ab.len-1;Z.reset();Z.redraw(true);for(var ad=0,W=Z.tracks.length;ad<W;ad++){var Y=Z.tracks[ad];if(Y.init){Y.init()}}}if(X!==undefined&&ac!==undefined){Z.low=Math.max(X,0);Z.high=Math.min(ac,Z.max_high)}Z.reset_overview();Z.redraw()}},go_to:function(aa){var ae=this,W,Z,X=aa.split(":"),ac=X[0],ad=X[1];if(ad!==undefined){try{var ab=ad.split("-");W=parseInt(ab[0].replace(/,/g,""),10);Z=parseInt(ab[1].replace(/,/g,""),10)}catch(Y){return false}}ae.change_chrom(ac,W,Z)},move_fraction:function(Y){var W=this;var X=W.high-W.low;this.move_delta(Y*X)},move_delta:function(Y){var W=this;var X=W.high-W.low;if(W.low-Y<W.max_low){W.low=W.max_low;W.high=W.max_low+X}else{if(W.high-Y>W.max_high){W.high=W.max_high;W.low=W.max_high-X}else{W.high-=Y;W.low-=Y}}W.redraw()},add_track:function(W){W.view=this;W.track_id=this.track_id_counter;this.tracks.push(W);if(W.init){W.init()}W.container_div.attr("id","track_"+W.track_id);B(W.container_div,".draghandle");this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(W){W.view=this;this.label_tracks.push(W)},remove_track:function(W){this.has_changes=true;W.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(W)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(ad){var ac=this.high-this.low,ab=this.low,X=this.high;if(ab<this.max_low){ab=this.max_low}if(X>this.max_high){X=this.max_high}if(this.high!==0&&ac<this.min_separation){X=ab+this.min_separation}this.low=Math.floor(ab);this.high=Math.ceil(X);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(r,Math.max(0,Math.ceil(Math.log(this.resolution,r)/Math.log(r))));var W=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var aa=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ae=13;this.overview_box.css({left:W,width:Math.max(ae,aa)}).show();if(aa<ae){this.overview_box.css("left",W-(ae-aa)/2)}if(this.overview_highlight){this.overview_highlight.css({left:W,width:aa})}this.update_location(this.low,this.high);if(!ad){for(var Y=0,Z=this.tracks.length;Y<Z;Y++){if(this.tracks[Y]&&this.tracks[Y].enabled){this.tracks[Y].draw()}}for(Y=0,Z=this.label_tracks.length;Y<Z;Y++){this.label_tracks[Y].draw()}}},zoom_in:function(X,Y){if(this.max_high===0||this.high-this.low<this.min_separation){return}var Z=this.high-this.low,aa=Z/2+this.low,W=(Z/this.zoom_factor)/2;if(X){aa=X/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(aa-W);this.high=Math.round(aa+W);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var X=this.high-this.low,Y=X/2+this.low,W=(X*this.zoom_factor)/2;this.low=Math.round(Y-W);this.high=Math.round(Y+W);this.redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide()}});var n=function(X,aa){this.track=X;this.name=aa.name;this.params=[];var ai=aa.params;for(var Y=0;Y<ai.length;Y++){var ad=ai[Y],W=ad.name,ah=ad.label,Z=unescape(ad.html),af=ad.type;if(af==="number"){this.params[this.params.length]=new g(W,ah,Z,ad.min,ad.max)}else{if(af=="select"){this.params[this.params.length]=new I(W,ah,Z)}else{console.log("WARNING: unrecognized tool parameter type:",W,af)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(ak){ak.stopPropagation()}).bind("click",function(ak){ak.stopPropagation()}).bind("dblclick",function(ak){ak.stopPropagation()});var ag=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var ae=this.params;var ab=this;$.each(this.params,function(al,ao){var an=$("<div>").addClass("param-row").appendTo(ab.parent_div);var ak=$("<div>").addClass("param-label").text(ao.label).appendTo(an);var am=$("<div/>").addClass("slider").html(ao.html).appendTo(an);$("<div style='clear: both;'/>").appendTo(an)});this.parent_div.find("input").click(function(){$(this).select()});var aj=$("<div>").addClass("slider-row").appendTo(this.parent_div);var ac=$("<input type='submit'>").attr("value","Run").appendTo(aj);var ab=this;ac.click(function(){ab.run()})};extend(n.prototype,{get_param_values_dict:function(){var W={};this.parent_div.find(":input").each(function(){var X=$(this).attr("name"),Y=$(this).val();W[X]=JSON.stringify(Y)});return W},get_param_values:function(){var X=[];var W={};this.parent_div.find(":input").each(function(){var Y=$(this).attr("name"),Z=$(this).val();if(Y){X[X.length]=Z}});return X},run:function(){var X={dataset_id:this.track.original_dataset_id,chrom:this.track.view.chrom,low:this.track.view.low,high:this.track.view.high,tool_id:this.name};$.extend(X,this.get_param_values_dict());var Z=this.track,Y=X.tool_id+Z.tool_region_and_parameters_str(X.chrom,X.low,X.high),aa;if(Z.track_type==="FeatureTrack"){aa=new N(Y,view,Z.hda_ldda,undefined,{},{},Z)}this.track.add_track(aa);aa.content_div.text("Starting job.");var W=function(){$.getJSON(run_tool_url,X,function(ab){if(ab==="no converter"){aa.container_div.addClass("error");aa.content_div.text(E)}else{if(ab.error){aa.container_div.addClass("error");aa.content_div.text(u+ab.message)}else{if(ab==="pending"){aa.container_div.addClass("pending");aa.content_div.text("Converting input data so that it can be easily reused.");setTimeout(W,2000)}else{aa.dataset_id=ab.dataset_id;aa.content_div.text("Running job.");aa.init()}}}})};W()}});var I=function(X,W,Y){this.name=X;this.label=W;this.html=Y};var g=function(Y,X,aa,Z,W){I.call(this,Y,X,aa);this.min=Z;this.max=W};var j=function(X,W,Y){this.name=X;this.index=W;this.value=Y};var O=function(X,W){this.name=X;this.index=W;this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.slider=null;this.slider_label=null};extend(O.prototype,{applies_to:function(W){if(W.length>this.index){return true}return false},keep:function(W){if(!this.applies_to(W)){return true}return(W[this.index]>=this.low&&W[this.index]<=this.high)},update_attrs:function(X){var W=false;if(!this.applies_to(X)){return W}if(X[this.index]<this.min){this.min=Math.floor(X[this.index]);W=true}if(X[this.index]>this.max){this.max=Math.ceil(X[this.index]);W=true}return W},update_ui_elt:function(){var X=this.slider.slider("option","min"),W=this.slider.slider("option","max");if(this.min<X||this.max>W){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",h(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var v=function(W){var ac=[];for(var Z=0;Z<W.length;Z++){var ab=W[Z];var Y=ab.name,aa=ab.type,X=ab.index;if(aa==="int"||aa==="float"){ac[Z]=new O(Y,X)}else{ac[Z]=new j(Y,X,aa)}}return ac};var S=function(W){this.track=W.track;this.params=W.params;this.values={};if(W.saved_values){this.restore_values(W.saved_values)}this.onchange=W.onchange};extend(S.prototype,{restore_values:function(W){var X=this;$.each(this.params,function(Y,Z){if(W[Z.key]!==undefined){X.values[Z.key]=W[Z.key]}else{X.values[Z.key]=Z.default_value}})},build_form:function(){var X=this;var W=$("<div />");$.each(this.params,function(ab,Z){if(!Z.hidden){var Y="param_"+ab;var ag=$("<div class='form-row' />").appendTo(W);ag.append($("<label />").attr("for",Y).text(Z.label+":"));if(Z.type==="bool"){ag.append($('<input type="checkbox" />').attr("id",Y).attr("name",Y).attr("checked",X.values[Z.key]))}else{if(Z.type==="color"){var ad=X.values[Z.key];var ac=$("<input />").attr("id",Y).attr("name",Y).val(ad);var ae=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var aa=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(ae);var af=$("<div/>").appendTo(aa).farbtastic({width:100,height:100,callback:ac,color:ad});$("<div />").append(ac).append(ae).appendTo(ag).bind("click",function(ah){ae.css({left:$(this).position().left+($(ac).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){ae.hide();$(document).unbind("click.color-picker")});ah.stopPropagation()})}else{ag.append($("<input />").attr("id",Y).attr("name",Y).val(X.values[Z.key]))}}}});return W},update_from_form:function(W){var Y=this;var X=false;$.each(this.params,function(Z,ab){if(!ab.hidden){var ac="param_"+Z;var aa=W.find("#"+ac).val();if(ab.type==="float"){aa=parseFloat(aa)}else{if(ab.type==="int"){aa=parseInt(aa)}else{if(ab.type==="bool"){aa=W.find("#"+ac).is(":checked")}}}if(aa!==Y.values[ab.key]){Y.values[ab.key]=aa;X=true}}});if(X){this.onchange()}}});var b=function(W,X,Y){this.track=W;this.canvas=X;this.histo_max=Y};var k=function(X,W,aa,Y,Z){this.name=X;this.view=W;this.parent_element=aa;this.data_url=(Y?Y:default_data_url);this.data_url_extra_params={};this.data_query_wait=(Z?Z:F);this.dataset_check_url=converted_datasets_state_url;this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){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.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)};extend(k.prototype,{init:function(){var W=this;W.enabled=false;W.tile_cache.clear();W.data_cache.clear();W.initial_canvas=undefined;W.content_div.css("height","auto");W.container_div.removeClass("nodata error pending");if(!W.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:W.hda_ldda,dataset_id:W.dataset_id,chrom:W.view.chrom},function(X){if(!X||X==="error"||X.kind==="error"){W.container_div.addClass("error");W.content_div.text(m);if(X.message){var Z=W.view.tracks.indexOf(W);var Y=$(" <a href='javascript:void(0);'></a>").text("View error").bind("click",function(){show_modal("Trackster Error","<pre>"+X.message+"</pre>",{Close:hide_modal})});W.content_div.append(Y)}}else{if(X==="no converter"){W.container_div.addClass("error");W.content_div.text(E)}else{if(X==="no data"||(X.data!==undefined&&(X.data===null||X.data.length===0))){W.container_div.addClass("nodata");W.content_div.text(A)}else{if(X==="pending"){W.container_div.addClass("pending");W.content_div.text(p);setTimeout(function(){W.init()},W.data_query_wait)}else{if(X.status==="data"){if(X.valid_chroms){W.valid_chroms=X.valid_chroms;W.make_name_popup_menu()}W.content_div.text(R);if(W.view.chrom){W.content_div.text("");W.content_div.css("height",W.height_px+"px");W.enabled=true;$.when(W.predraw_init()).done(function(){W.draw()})}}}}}}})},predraw_init:function(){},update_name:function(W){this.old_name=this.name;this.name=W;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)}});var H=function(X,ad,ag){var Y=this,ah=Y.view;this.filters=(X!==undefined?v(X):[]);this.filters_available=false;this.filters_visible=false;this.tool=(ad!==undefined&&obj_length(ad)>0?new n(this,ad):undefined);this.parent_track=ag;this.child_tracks=[];if(Y.hidden){return}var af=function(ai,aj,ak){ai.click(function(){var al=aj.text();max=parseFloat(ak.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(ak.slider("option","values")){input_size=2*input_size+1;multi_value=true}aj.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",al).appendTo(aj).focus().select().click(function(am){am.stopPropagation()}).blur(function(){$(this).remove();aj.text(al)}).keyup(function(aq){if(aq.keyCode===27){$(this).trigger("blur")}else{if(aq.keyCode===13){var ao=ak.slider("option","min"),am=ak.slider("option","max"),ap=function(ar){return(isNaN(ar)||ar>am||ar<ao)},an=$(this).val();if(!multi_value){an=parseFloat(an);if(ap(an)){alert("Parameter value must be in the range ["+ao+"-"+am+"]");return $(this)}}else{an=an.split("-");an=[parseFloat(an[0]),parseFloat(an[1])];if(ap(an[0])||ap(an[1])){alert("Parameter value must be in the range ["+ao+"-"+am+"]");return $(this)}}ak.slider((multi_value?"values":"value"),an)}}})})};if(this.parent_track){this.header_div.find(".draghandle").removeClass("draghandle").addClass("child-track-icon").addClass("icon-button");this.parent_element.addClass("child-track");this.tool=undefined}this.filters_div=$("<div/>").addClass("filters").hide();this.header_div.after(this.filters_div);this.filters_div.bind("drag",function(ai){ai.stopPropagation()}).bind("click",function(ai){ai.stopPropagation()}).bind("dblclick",function(ai){ai.stopPropagation()});$.each(this.filters,function(ao,aj){var al=$("<div/>").addClass("slider-row").appendTo(Y.filters_div);var ai=$("<div/>").addClass("slider-label").appendTo(al);var aq=$("<span/>").addClass("slider-name").text(aj.name+" ").appendTo(ai);var ak=$("<span/>");var am=$("<span/>").addClass("slider-value").appendTo(ai).append("[").append(ak).append("]");var ap=$("<div/>").addClass("slider").appendTo(al);aj.control_element=$("<div/>").attr("id",aj.name+"-filter-control").appendTo(ap);var an=[0,0];aj.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(ar,at){an=at.values;ak.text(at.values[0]+"-"+at.values[1]);setTimeout(function(){if(at.values[0]==an[0]&&at.values[1]==an[1]){var au=at.values;ak.text(au[0]+"-"+au[1]);aj.low=au[0];aj.high=au[1];Y.draw(true,true)}},50)},change:function(ar,at){aj.control_element.slider("option","slide").call(aj.control_element,ar,at)}});aj.slider=aj.control_element;aj.slider_label=ak;af(am,ak,aj.control_element);$("<div style='clear: both;'/>").appendTo(al)});if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}Y.child_tracks_container=$("<div/>").addClass("child-tracks-container").hide();Y.container_div.append(Y.child_tracks_container);if(Y.display_modes!==undefined){if(Y.mode_div===undefined){Y.mode_div=$("<div class='right-float menubutton popup' />").appendTo(Y.header_div);var aa=(Y.track_config&&Y.track_config.values.mode?Y.track_config.values.mode:Y.display_modes[0]);Y.mode=aa;Y.mode_div.text(aa);var Z=function(ai){Y.mode_div.text(ai);Y.mode=ai;Y.track_config.values.mode=ai;Y.tile_cache.clear();Y.draw()};var W={};for(var ab=0,ae=Y.display_modes.length;ab<ae;ab++){var ac=Y.display_modes[ab];W[ac]=function(ai){return function(){Z(ai)}}(ac)}make_popupmenu(Y.mode_div,W)}else{Y.mode_div.hide()}}this.make_name_popup_menu()};extend(H.prototype,k.prototype,{make_name_popup_menu:function(){var X=this;var W={};W["Edit configuration"]=function(){var ad=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},ab=function(){X.track_config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ac=function(ae){if((ae.keyCode||ae.which)===27){ad()}else{if((ae.keyCode||ae.which)===13){ab()}}};$(window).bind("keypress.check_enter_esc",ac);show_modal("Configure Track",X.track_config.build_form(),{Cancel:ad,OK:ab})};if(X.filters_available>0){var aa=(X.filters_div.is(":visible")?"Hide filters":"Show filters");W[aa]=function(){X.filters_visible=(X.filters_div.is(":visible"));X.filters_div.toggle();X.make_name_popup_menu()}}if(X.tool){var aa=(X.dynamic_tool_div.is(":visible")?"Hide tool":"Show tool");W[aa]=function(){if(!X.dynamic_tool_div.is(":visible")){X.update_name(X.name+X.tool_region_and_parameters_str())}else{menu_option_text="Show dynamic tool";X.revert_name()}X.dynamic_tool_div.toggle();X.make_name_popup_menu()}}if(X.valid_chroms){W["List chrom/contigs with data"]=function(){show_modal("Chrom/contigs with data","<p>"+X.valid_chroms.join("<br/>")+"</p>",{Close:function(){hide_modal()}})}}var Y=view;var Z=function(){$("#no-tracks").show()};if(this.parent_track){Y=this.parent_track;Z=function(){}}W.Remove=function(){Y.remove_track(X);if(Y.num_tracks===0){Z()}};make_popupmenu(X.name_div,W)},draw:function(W,Z){var an=this.view.low,ac=this.view.high,ae=ac-an,ag=this.view.container.width(),ab=ag/ae,ah=this.view.resolution,aa=$("<div style='position: relative;'></div>");if(!Z){this.content_div.children().remove()}this.content_div.append(aa);this.max_height=0;var aj=Math.floor(an/ah/J);var Y={};while((aj*J*ah)<ac){var am=ag+"_"+ab+"_"+aj;var ad=this.tile_cache.get(am);var ak=aj*J*this.view.resolution;var X=ak+J*this.view.resolution;if(!W&&ad){this.show_tile(ad,aa,ak,ab)}else{this.delayed_draw(W,am,ak,X,aj,ah,aa,ab,Y)}aj+=1}var af=this;var al=setInterval(function(){if(obj_length(Y)===0){clearInterval(al);if(Z){var aq=af.content_div.children();var ap=false;for(var ar=aq.length-1,ao=0;ar>=ao;ar--){var av=$(aq[ar]);if(ap){av.remove()}else{if(av.children().length!==0){ap=true}}}}for(var au=0;au<af.filters.length;au++){af.filters[au].update_ui_elt()}var at=false;if(af.example_feature){for(var au=0;au<af.filters.length;au++){if(af.filters[au].applies_to(af.example_feature)){at=true;break}}}if(af.filters_available!==at){af.filters_available=at;if(!af.filters_available){af.filters_div.hide()}af.make_name_popup_menu()}}},50);for(var ai=0;ai<this.child_tracks.length;ai++){this.child_tracks[ai].draw(W,Z)}},delayed_draw:function(X,ae,ac,ag,Y,aa,af,ah,ab){var Z=this;var ad=function(ap,ai,ak,aj,an,ao,al){returned_tile=Z.draw_tile(ai,ak,aj,an,ao,al);var am=$("<div class='track-tile'>").prepend(returned_tile);tile_element=am;Z.tile_cache.set(ae,tile_element);Z.show_tile(tile_element,an,ac,ao);delete ab[ap]};var W=setTimeout(function(){if(ac<=Z.view.high&&ag>=Z.view.low){var ai=(X?undefined:Z.tile_cache.get(ae));if(ai){Z.show_tile(ai,af,ac,ah);delete ab[W]}else{$.when(Z.data_cache.get_data(view.chrom,ac,ag,Z.mode,aa,Z.data_url_extra_params)).then(function(aj){if(view.reference_track&&ah>view.canvas_manager.char_width_px){$.when(view.reference_track.data_cache.get_data(view.chrom,ac,ag,Z.mode,aa,view.reference_track.data_url_extra_params)).then(function(ak){ad(W,aj,aa,Y,af,ah,ak)})}else{ad(W,aj,aa,Y,af,ah)}})}}},50);ab[W]=true},show_tile:function(W,ab,Z,ac){var X=this;var Y=this.view.high-this.view.low,aa=(Z-this.view.low)*ac;if(this.left_offset){aa-=this.left_offset}W.css({position:"absolute",top:0,left:aa,height:""});ab.append(W);X.max_height=Math.max(X.max_height,W.height());X.content_div.css("height",X.max_height+"px");ab.children().css("height",X.max_height+"px")},set_overview:function(){var W=this.view;if(this.initial_canvas&&this.is_overview){W.overview_close.show();W.overview_viewport.append(this.initial_canvas);W.overview_highlight.show().height(this.initial_canvas.height());W.overview_viewport.height(this.initial_canvas.height()+W.overview_box.height())}$(window).trigger("resize")},tool_region_and_parameters_str:function(Y,W,Z){var X=this,aa=(Y!==undefined&&W!==undefined&&Z!==undefined?Y+":"+W+"-"+Z:"all");return" - region=["+aa+"], parameters=["+X.tool.get_param_values().join(", ")+"]"},add_track:function(W){W.track_id=this.track_id+"_"+this.child_tracks.length;W.container_div.attr("id","track_"+W.track_id);this.child_tracks_container.append(W.container_div);B(W.container_div,".child-track-icon");if(!$(this.child_tracks_container).is(":visible")){this.child_tracks_container.show()}this.child_tracks.push(W);this.view.has_changes=true},remove_track:function(W){W.container_div.fadeOut("slow",function(){$(this).remove()})}});var T=function(W,X){this.track_type="LabelTrack";this.hidden=true;k.call(this,null,W,X);this.container_div.addClass("label-track")};extend(T.prototype,k.prototype,{draw:function(){var Y=this.view,Z=Y.high-Y.low,ac=Math.floor(Math.pow(10,Math.floor(Math.log(Z)/Math.log(10)))),W=Math.floor(Y.low/ac)*ac,aa=this.view.container.width(),X=$("<div style='position: relative; height: 1.3em;'></div>");while(W<Y.high){var ab=(W-Y.low)/Z*aa;X.append($("<div class='label'>"+commatize(W)+"</div>").css({position:"absolute",left:ab-1}));W+=ac}this.content_div.children(":first").remove();this.content_div.append(X)}});var x=function(W){this.track_type="ReferenceTrack";this.hidden=true;k.call(this,null,W,W.top_labeltrack);H.call(this);W.reference_track=this;this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:W.dbkey};this.data_cache=new K(y,this,false);this.tile_cache=new c(q)};extend(x.prototype,H.prototype,{draw_tile:function(ag,ab,X,ad,ah){var aa=this,Y=J*ab;if(ah>this.view.canvas_manager.char_width_px){if(ag===null){aa.content_div.css("height","0px");return}var Z=this.view.canvas_manager.new_canvas();var af=Z.getContext("2d");Z.width=Math.ceil(Y*ah+aa.left_offset);Z.height=aa.height_px;af.font=af.canvas.manager.default_font;af.textAlign="center";for(var ac=0,ae=ag.length;ac<ae;ac++){var W=Math.round(ac*ah);af.fillText(ag[ac],W+aa.left_offset,10)}return Z}this.content_div.css("height","0px")}});var l=function(aa,Y,ab,W,Z){var X=this;this.track_type="LineTrack";this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";k.call(this,aa,Y,Y.viewport_container);H.call(this);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=ab;this.dataset_id=W;this.original_dataset_id=W;this.data_cache=new K(y,this);this.tile_cache=new c(q);this.track_config=new S({track:this,params:[{key:"color",label:"Color",type:"color",default_value:"black"},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.height_px,hidden:true}],saved_values:Z,onchange:function(){X.vertical_range=X.prefs.max_value-X.prefs.min_value;$("#linetrack_"+X.track_id+"_minval").text(X.prefs.min_value);$("#linetrack_"+X.track_id+"_maxval").text(X.prefs.max_value);X.tile_cache.clear();X.draw()}});this.prefs=this.track_config.values;this.height_px=this.track_config.values.height;this.vertical_range=this.track_config.values.max_value-this.track_config.values.min_value;this.add_resize_handle()};extend(l.prototype,H.prototype,{add_resize_handle:function(){var W=this;var Z=false;var Y=false;var X=$("<div class='track-resize'>");$(W.container_div).hover(function(){Z=true;X.show()},function(){Z=false;if(!Y){X.hide()}});X.hide().bind("dragstart",function(aa,ab){Y=true;ab.original_height=$(W.content_div).height()}).bind("drag",function(ab,ac){var aa=Math.min(Math.max(ac.original_height+ac.deltaY,W.min_height_px),W.max_height_px);$(W.content_div).css("height",aa);W.height_px=aa;W.draw(true)}).bind("dragend",function(aa,ab){W.tile_cache.clear();Y=false;if(!Z){X.hide()}W.track_config.values.height=W.height_px}).appendTo(W.container_div)},predraw_init:function(){var W=this,X=W.view.tracks.indexOf(W);W.vertical_range=undefined;return $.getJSON(W.data_url,{stats:true,chrom:W.view.chrom,low:null,high:null,hda_ldda:W.hda_ldda,dataset_id:W.dataset_id},function(Y){W.container_div.addClass("line-track");var aa=Y.data;if(isNaN(parseFloat(W.prefs.min_value))||isNaN(parseFloat(W.prefs.max_value))){W.prefs.min_value=aa.min;W.prefs.max_value=aa.max;$("#track_"+X+"_minval").val(W.prefs.min_value);$("#track_"+X+"_maxval").val(W.prefs.max_value)}W.vertical_range=W.prefs.max_value-W.prefs.min_value;W.total_frequency=aa.total_frequency;W.container_div.find(".yaxislabel").remove();var ab=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+X+"_minval").text(t(W.prefs.min_value));var Z=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+X+"_maxval").text(t(W.prefs.max_value));Z.css({position:"absolute",top:"24px",left:"10px"});Z.prependTo(W.container_div);ab.css({position:"absolute",bottom:"2px",left:"10px"});ab.prependTo(W.container_div)})},draw_tile:function(ah,aa,X,ae,ag){if(this.vertical_range===undefined){return}var ab=X*J*aa,Z=J*aa,W=Math.ceil(Z*ag),ad=this.height_px;var Y=this.view.canvas_manager.new_canvas();Y.width=W,Y.height=ad;var af=Y.getContext("2d");var ac=new G.LinePainter(ah.data,ab,ab+Z,this.prefs.min_value,this.prefs.max_value,this.prefs.color,this.mode);ac.draw(af,W,ad);return Y}});var e=function(W,ab,aa,ae,ad,Y,Z,ac){var X=this;this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];this.track_config=new S({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ad,onchange:function(){X.tile_cache.clear();X.draw()}});this.prefs=this.track_config.values;k.call(this,W,ab,ab.viewport_container);H.call(this,Y,Z,ac);this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=aa;this.dataset_id=ae;this.original_dataset_id=ae;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.inc_slots={};this.start_end_dct={};this.tile_cache=new c(d);this.data_cache=new K(20,this);this.left_offset=200;this.painter=G.LinkedFeaturePainter};extend(e.prototype,H.prototype,{update_auto_mode:function(W){if(this.mode=="Auto"){if(W=="no_detail"){W="reduced to feature spans"}else{if(W=="summary_tree"){W="reduced to coverage histogram"}}this.mode_div.text("Auto ("+W+")")}},incremental_slots:function(aa,X,Z){var Y=this.view.canvas_manager.dummy_context,W=this.inc_slots[aa];if(!W||(W.mode!==Z)){W=new (o.FeatureSlotter)(aa,Z==="Pack",w,function(ab){return Y.measureText(ab)});W.mode=Z;this.inc_slots[aa]=W}return W.slot_features(X)},draw_tile:function(ai,aq,av,ae,ag,Z){var an=this,ax=av*J*aq,X=(av+1)*J*aq,ak=X-ax,ao=Math.ceil(ak*ag),am=this.mode,aB=25,aa=this.left_offset,aj,ab;if(am==="Auto"){if(ai.dataset_type==="summary_tree"){am=ai.dataset_type}else{if(ai.extra_info==="no_detail"){am="no_detail"}else{var aA=ai.data;if((aA.length&&aA.length<4)||(this.view.high-this.view.low>D)){am="Squish"}else{am="Pack"}}}this.update_auto_mode(am)}if(am==="summary_tree"){ab=this.summary_draw_height;ae.parent().css("height",Math.max(this.height_px,ab)+"px");this.container_div.find(".yaxislabel").remove();var W=$("<div />").addClass("yaxislabel");W.text(ai.max);W.css({position:"absolute",top:"22px",left:"10px"});W.prependTo(this.container_div);var Y=this.view.canvas_manager.new_canvas();Y.width=ao+aa;Y.height=ab+L;var ay=new G.SummaryTreePainter(ai.data,ai.delta,ai.max,ax,X,this.prefs.show_counts);var ap=Y.getContext("2d");ap.translate(aa,L);ay.draw(ap,ao,ab);return Y}var aj,ad=1;if(am==="no_detail"||am==="Squish"||am==="Pack"){ad=this.incremental_slots(ag,ai.data,am);aj=this.inc_slots[ag].slots}var af=[];if(ai.data){for(var ar=0,au=ai.data.length;ar<au;ar++){var ac=ai.data[ar];var at=false;var ah;for(var aw=0,az=this.filters.length;aw<az;aw++){ah=this.filters[aw];ah.update_attrs(ac);if(!ah.keep(ac)){at=true;break}}if(!at){af.push(ac)}}}var ay=new (this.painter)(af,ax,X,this.prefs,am,Z);var ab=ay.get_required_height(ad)+z;var Y=this.view.canvas_manager.new_canvas();Y.width=ao+aa;Y.height=ab;ae.parent().css("height",Math.max(this.height_px,ab)+"px");var ap=Y.getContext("2d");ap.fillStyle=this.prefs.block_color;ap.font=ap.canvas.manager.default_font;ap.textAlign="right";this.container_div.find(".yaxislabel").remove();if(ai.message){$(Y).css({"border-top":"1px solid red"});ap.fillStyle="red";ap.textAlign="left";var al=ap.textBaseline;ap.textBaseline="top";ap.fillText(ai.message,aa,0);ap.textBaseline=al;if(!ai.data){return Y}}this.example_feature=(ai.data.length?ai.data[0]:undefined);ap.translate(aa,z);ay.draw(ap,ao,ab,aj);return Y}});var M=function(Z,X,ab,W,Y,aa){e.call(this,Z,X,ab,W,Y,aa);this.track_type="VcfTrack";this.painter=G.VariantPainter};extend(M.prototype,H.prototype,e.prototype);var P=function(Z,X,ab,W,Y,aa){e.call(this,Z,X,ab,W,Y,aa);this.track_config=new S({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:Y,onchange:function(){this.track.tile_cache.clear();this.track.draw()}});this.prefs=this.track_config.values;this.track_type="ReadTrack";this.painter=G.ReadPainter;this.make_name_popup_menu()};extend(P.prototype,H.prototype,e.prototype);var N=function(aa,Y,ac,W,Z,ab,X){e.call(this,aa,Y,ac,W,Z,ab,{},X);this.track_type="ToolDataFeatureTrack";this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};extend(N.prototype,H.prototype,e.prototype,{predraw_init:function(){var X=this;var W=function(){if(X.data_cache.size()===0){setTimeout(W,300)}else{X.data_url=default_data_url;X.data_query_wait=F;X.dataset_state_url=converted_datasets_state_url;$.getJSON(X.dataset_state_url,{dataset_id:X.dataset_id,hda_ldda:X.hda_ldda},function(Y){})}};W()}});Q.View=U;Q.LineTrack=l;Q.FeatureTrack=e;Q.ReadTrack=P};var slotting_module=function(c,b){var d=2,a=5;b.FeatureSlotter=function(h,g,e,f){this.slots={};this.start_end_dct={};this.w_scale=h;this.include_label=g;this.max_rows=e;this.measureText=f};extend(b.FeatureSlotter.prototype,{slot_features:function(l){var o=this.w_scale,r=this.slots,g=this.start_end_dct,x=[],z=[],m=0,y=this.max_rows;for(var v=0,w=l.length;v<w;v++){var k=l[v],n=k[0];if(r[n]!==undefined){m=Math.max(m,r[n]);z.push(r[n])}else{x.push(v)}}var p=function(F,G){for(var E=0;E<=y;E++){var C=false,H=g[E];if(H!==undefined){for(var B=0,D=H.length;B<D;B++){var A=H[B];if(G>A[0]&&F<A[1]){C=true;break}}}if(!C){return E}}return -1};for(var v=0,w=x.length;v<w;v++){var k=l[x[v]],n=k[0],t=k[1],e=k[2],q=k[3],f=Math.floor(t*o),j=Math.ceil(e*o),u=this.measureText(q).width,h;if(q!==undefined&&this.include_label){u+=(d+a);if(f-u>=0){f-=u;h="left"}else{j+=u;h="right"}}var s=p(f,j);if(s>=0){if(g[s]===undefined){g[s]=[]}g[s].push([f,j]);r[n]=s;m=Math.max(m,s)}else{}}return m+1}})};var painters_module=function(k,A){var q=function(L,D,J,C,I,G){if(G===undefined){G=4}var F=C-D;var E=I-J;var H=Math.floor(Math.sqrt(F*F+E*E)/G);var M=F/H;var K=E/H;var B;for(B=0;B<H;B++,D+=M,J+=K){if(B%2!==0){continue}L.fillRect(D,J,G,1)}};var r=function(D,C,B,G){var F=C-G/2,E=C+G/2,H=B-Math.sqrt(G*3/2);D.beginPath();D.moveTo(F,H);D.lineTo(E,H);D.lineTo(C,B);D.lineTo(F,H);D.strokeStyle=this.fillStyle;D.fill();D.stroke();D.closePath()};var v=function(E,G,C,F,B,D){this.data=E;this.delta=G;this.max=C;this.view_start=F;this.view_end=B;this.show_counts=D};v.prototype.draw=function(O,B,N){var G=this.view_start,Q=this.view_end-this.view_start,P=B/Q;var L=this.data,K=this.delta,I=this.max,D=N;delta_x_px=Math.ceil(K*P);O.save();for(var E=0,F=L.length;E<F;E++){var J=Math.floor((L[E][0]-G)*P);var H=L[E][1];if(!H){continue}var M=H/I*N;O.fillStyle="black";O.fillRect(J,D-M,delta_x_px,M);var C=4;if(this.show_counts&&(O.measureText(H).width+C)<delta_x_px){O.fillStyle="#666";O.textAlign="center";O.fillText(H,J+(delta_x_px/2),10)}}O.restore()};var c=function(E,H,B,C,G,D,F){this.data=E;this.view_start=H;this.view_end=B;this.min_value=C;this.max_value=G;this.color=D;this.mode=F;this.overflow_color="#F66"};c.prototype.draw=function(Q,P,N){var I=false,J=this.min_value,G=this.max_value,M=G-J,C=N,D=this.view_start,O=this.view_end-this.view_start,E=P/O,K=this.mode,U=this.data;Q.save();var V=Math.round(N+J/M*N);if(K!=="Intensity"){Q.fillStyle="#aaa";Q.fillRect(0,V,P,1)}Q.beginPath();Q.fillStyle=this.color;var T,H,F;if(U.length>1){F=Math.ceil((U[1][0]-U[0][0])*E)}else{F=10}for(var R=0,S=U.length;R<S;R++){T=Math.round((U[R][0]-D)*E);H=U[R][1];if(H===null){if(I&&K==="Filled"){Q.lineTo(T,C)}I=false;continue}if(H<J){H=J}else{if(H>G){H=G}}if(K==="Histogram"){H=Math.round(H/M*C);Q.fillRect(T,V,F,-H)}else{if(K==="Intensity"){H=255-Math.floor((H-J)/M*255);Q.fillStyle="rgb("+H+","+H+","+H+")";Q.fillRect(T,0,F,C)}else{H=Math.round(C-(H-J)/M*C);if(I){Q.lineTo(T,H)}else{I=true;if(K==="Filled"){Q.moveTo(T,C);Q.lineTo(T,H)}else{Q.moveTo(T,H)}}}}}if(K==="Filled"){if(I){Q.lineTo(T,V);Q.lineTo(0,V)}Q.fill()}else{Q.stroke()}var B=-1,L=-1;Q.fillStyle=this.overflow_color;for(var R=0,S=U.length;R<S;R++){H=U[R][1];T=Math.round((U[R][0]-D)*E);x_minus_scaled=Math.round((U[R][0]-1-D)*E);if(L>=0&&(H===null||H<G)){Q.fillRect(L,0,x_minus_scaled-L+1,2);L=-1}else{if(B>=0&&(H===null||H>J)){Q.fillRect(B,N-2,x_minus_scaled-B+1,2);B=-1}}if(H!==null&&H>G&&L<0){L=T}else{if(H!==null&&H<J&&B<0){B=T}}}Q.restore()};var p=function(D,F,B,C,E){this.data=D;this.view_start=F;this.view_end=B;this.prefs=C;this.mode=E};extend(p.prototype,{get_required_height:function(C){var B=y_scale=this.get_row_height(),D=this.mode;if(D==="no_detail"||D==="Squish"||D==="Pack"){B=C*y_scale}return B+Math.max(Math.round(y_scale/2),5)},draw:function(N,E,M,J){var H=this.data,K=this.view_start,O=this.view_end;N.save();N.fillStyle=this.prefs.block_color;N.textAlign="right";var R=this.view_end-this.view_start,Q=E/R,D=this.get_row_height();for(var G=0,I=H.length;G<I;G++){var P=H[G],F=P[0],B=P[1],C=P[2],L=(J&&J[F]!==undefined?J[F]:null);if((B<O&&C>K)&&(this.mode=="Dense"||L!==null)){this.draw_element(N,this.mode,P,L,K,O,Q,D,E)}}N.restore()}});var d=10,j=3,n=5,z=10,g=1,t=3,f=3,a=9,o=2,h="#ccc";var s=function(D,F,B,C,E){p.call(this,D,F,B,C,E)};extend(s.prototype,p.prototype,{get_row_height:function(){var C=this.mode,B;if(C==="Dense"){B=d}else{if(C==="no_detail"){B=j}else{if(C==="Squish"){B=n}else{B=z}}}return B},draw_element:function(N,G,V,I,P,af,aj,ak,B){var S=V[0],ah=V[1],Z=V[2]-1,Q=V[3],aa=Math.floor(Math.max(0,(ah-P)*aj)),O=Math.ceil(Math.min(B,Math.max(0,(Z-P)*aj))),Y=(G==="Dense"?0:(0+I))*ak,M,ad,R=null,al=null,E=this.prefs.block_color,ac=this.prefs.label_color;if(G=="Dense"){I=1}if(G==="no_detail"){N.fillStyle=E;N.fillRect(aa,Y+5,O-aa,g)}else{var L=V[4],X=V[5],ab=V[6],F=V[7];if(X&&ab){R=Math.floor(Math.max(0,(X-P)*aj));al=Math.ceil(Math.min(B,Math.max(0,(ab-P)*aj)))}var ai,T;if(G==="Squish"||G==="Dense"){ai=1;T=f}else{ai=5;T=a}if(!F){if(V.strand){if(V.strand==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand_inv")}else{if(V.strand==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand_inv")}}}else{N.fillStyle=E}N.fillRect(aa,Y,O-aa,T)}else{var K,U;if(G==="Squish"||G==="Dense"){N.fillStyle=h;K=Y+Math.floor(f/2)+1;U=1}else{if(L){var K=Y;var U=T;if(L==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand")}else{if(L==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand")}}}else{N.fillStyle=h;K+=(f/2)+1;U=1}}N.fillRect(aa,K,O-aa,U);for(var ag=0,D=F.length;ag<D;ag++){var H=F[ag],C=Math.floor(Math.max(0,(H[0]-P)*aj)),W=Math.ceil(Math.min(B,Math.max((H[1]-1-P)*aj)));if(C>W){continue}N.fillStyle=E;N.fillRect(C,Y+(T-ai)/2+1,W-C,ai);if(R!==undefined&&ab>X&&!(C>al||W<R)){var ae=Math.max(C,R),J=Math.min(W,al);N.fillRect(ae,Y+1,J-ae,T);if(F.length==1&&G=="Pack"){if(L==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand_inv")}else{if(L==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand_inv")}}if(ae+14<J){ae+=2;J-=2}N.fillRect(ae,Y+1,J-ae,T)}}}}if(G==="Pack"&&ah>P){N.fillStyle=ac;if(P===0&&aa-N.measureText(Q).width<0){N.textAlign="left";N.fillText(Q,O+o,Y+8)}else{N.textAlign="right";N.fillText(Q,aa-o,Y+8)}N.fillStyle=E}}}});var b=function(D,F,B,C,E){p.call(this,D,F,B,C,E)};extend(b.prototype,p.prototype,{draw_element:function(U,P,J,F,X,D,M,V,S){var J=data[i],L=J[0],T=J[1],E=J[2]-1,O=J[3],H=Math.floor(Math.max(0,(T-X)*M)),K=Math.ceil(Math.min(S,Math.max(0,(E-X)*M))),G=(P==="Dense"?0:(0+F))*V,B,Y,C=null,N=null;if(no_label){U.fillStyle=block_color;U.fillRect(H+left_offset,G+5,K-H,1)}else{var W=J[4],R=J[5],I=J[6];B=9;Y=1;U.fillRect(H+left_offset,G,K-H,B);if(P!=="Dense"&&O!==undefined&&T>X){U.fillStyle=label_color;if(X===0&&H-U.measureText(O).width<0){U.textAlign="left";U.fillText(O,K+2+left_offset,G+8)}else{U.textAlign="right";U.fillText(O,H-2+left_offset,G+8)}U.fillStyle=block_color}var Q=W+" / "+R;if(T>X&&U.measureText(Q).width<(K-H)){U.fillStyle="white";U.textAlign="center";U.fillText(Q,left_offset+H+(K-H)/2,G+8);U.fillStyle=block_color}}}});var y=1001,m=1002,e=1003,x=1004,l=1005;var w=function(F,C){var H=F[0],G=F[1],E=C[0],D=C[1],B;if(H<E){if(G<E){B=y}else{if(G<=D){B=e}else{B=m}}}else{if(H>D){B=y}else{if(G<=D){B=l}else{B=x}}}return B};var u=function(E,G,B,D,F,C){p.call(this,E,G,B,D,F);this.ref_seq=C};extend(u.prototype,p.prototype,{get_row_height:function(){var B,C=this.mode;if(C==="Dense"){B=d}else{if(C==="Squish"){B=n}else{B=z;if(this.prefs.show_insertions){B*=2}}}return B},draw_read:function(Y,T,O,ad,D,X,L,I,H){Y.textAlign="center";var W=this,C=[ad,D],R=0,Z=0,V=0;ref_seq=this.ref_seq,char_width_px=Y.canvas.manager.char_width_px;var ai=[];if((T==="Pack"||this.mode==="Auto")&&I!==undefined&&O>char_width_px){V=Math.round(O/2)}if(!L){L=[[0,I.length]]}for(var P=0,ab=L.length;P<ab;P++){var M=L[P],E="MIDNSHP=X"[M[0]],Q=M[1];if(E==="H"||E==="S"){R-=Q}var J=X+R,ah=Math.floor(Math.max(0,(J-ad)*O)),K=Math.floor(Math.max(0,(J+Q-ad)*O));switch(E){case"H":break;case"S":case"M":case"=":var S=w([J,J+Q],C);if(S!==y){var U=I.slice(Z,Z+Q);if(V>0){Y.fillStyle=this.prefs.block_color;Y.fillRect(ah-V,H+1,K-ah,9);Y.fillStyle=h;for(var af=0,B=U.length;af<B;af++){if(this.prefs.show_differences&&ref_seq){var N=ref_seq[J-ad+af];if(!N||N.toLowerCase()===U[af].toLowerCase()){continue}}if(J+af>=ad&&J+af<=D){var ag=Math.floor(Math.max(0,(J+af-ad)*O));Y.fillText(U[af],ag,H+9)}}}else{Y.fillStyle=this.prefs.block_color;Y.fillRect(ah,H+4,K-ah,f)}}Z+=Q;R+=Q;break;case"N":Y.fillStyle=h;Y.fillRect(ah-V,H+5,K-ah,1);R+=Q;break;case"D":Y.fillStyle="red";Y.fillRect(ah-V,H+4,K-ah,3);R+=Q;break;case"P":break;case"I":var S=w([J,J+Q],C),ac=ah-V;if(S!==y){var U=I.slice(Z,Z+Q);if(this.prefs.show_insertions){var G=ah-(K-ah)/2;if((T==="Pack"||this.mode==="Auto")&&I!==undefined&&O>char_width_px){Y.fillStyle="yellow";Y.fillRect(G-V,H-9,K-ah,9);ai[ai.length]={type:"triangle",data:[ac,H+4,5]};Y.fillStyle=h;switch(S){case (e):U=U.slice(ad-J);break;case (x):U=U.slice(0,J-D);break;case (l):break;case (m):U=U.slice(ad-J,J-D);break}for(var af=0,B=U.length;af<B;af++){var ag=Math.floor(Math.max(0,(J+af-ad)*O));Y.fillText(U[af],ag-(K-ah)/2,H)}}else{Y.fillStyle="yellow";Y.fillRect(G,H+(this.mode!=="Dense"?2:5),K-ah,(T!=="Dense"?f:t))}}else{if((T==="Pack"||this.mode==="Auto")&&I!==undefined&&O>char_width_px){ai[ai.length]={type:"text",data:[U.length,ac,H+9]}}else{}}}Z+=Q;break;case"X":Z+=Q;break}}Y.fillStyle="yellow";var ae,F,aj;for(var aa=0;aa<ai.length;aa++){ae=ai[aa];F=ae.type;aj=ae.data;if(F==="text"){Y.save();Y.font="bold "+Y.font;Y.fillText(aj[0],aj[1],aj[2]);Y.restore()}else{if(F=="triangle"){r(Y,aj[0],aj[1],aj[2])}}}},draw_element:function(U,P,H,E,X,C,L,V,S){var K=H[0],T=H[1],D=H[2],M=H[3],G=Math.floor(Math.max(0,(T-X)*L)),I=Math.ceil(Math.min(S,Math.max(0,(D-X)*L))),F=(P==="Dense"?0:(0+E))*V,Y=this.prefs.block_color,J=this.prefs.label_color,R=0;if((P==="Pack"||this.mode==="Auto")&&L>U.canvas.manager.char_width_px){var R=Math.round(L/2)}U.fillStyle=Y;if(H[5] instanceof Array){var Q=Math.floor(Math.max(0,(H[4][0]-X)*L)),O=Math.ceil(Math.min(S,Math.max(0,(H[4][1]-X)*L))),N=Math.floor(Math.max(0,(H[5][0]-X)*L)),B=Math.ceil(Math.min(S,Math.max(0,(H[5][1]-X)*L)));if(H[4][1]>=X&&H[4][0]<=C&&H[4][2]){this.draw_read(U,P,L,X,C,H[4][0],H[4][2],H[4][3],F)}if(H[5][1]>=X&&H[5][0]<=C&&H[5][2]){this.draw_read(U,P,L,X,C,H[5][0],H[5][2],H[5][3],F)}if(N>O){U.fillStyle=h;q(U,O-R,F+5,N-R,F+5)}}else{U.fillStyle=Y;this.draw_read(U,P,L,X,C,T,H[4],H[5],F)}if(P==="Pack"&&T>X){U.fillStyle=this.prefs.label_color;var W=1;if(W===0&&G-U.measureText(M).width<0){U.textAlign="left";U.fillText(M,I+o-R,F+8)}else{U.textAlign="right";U.fillText(M,G-o-R,F+8)}U.fillStyle=Y}}});A.SummaryTreePainter=v;A.LinePainter=c;A.LinkedFeaturePainter=s;A.ReadPainter=u;A.VariantPainter=b};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("slotting",slotting_module);a("painters",painters_module);a("trackster",trackster_module);for(key in c.trackster){d[key]=c.trackster[key]}})(window);
\ No newline at end of file
+var extend=function(){var c=arguments[0];for(var b=1;b<arguments.length;b++){var a=arguments[b];for(key in a){c[key]=a[key]}}return c};var trackster_module=function(f,Q){var o=f("slotting"),G=f("painters");var V=function(W,X){this.document=W;this.default_font=X!==undefined?X:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};extend(V.prototype,{load_pattern:function(W,aa){var X=this.patterns,Y=this.dummy_context,Z=new Image();Z.src=image_path+aa;Z.onload=function(){X[W]=Y.createPattern(Z,"repeat")}},get_pattern:function(W){return this.patterns[W]},new_canvas:function(){var W=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(W)}W.manager=this;return W}});var B=function(W,X){W.bind("drag",{handle:X,relative:true},function(ab,ac){var aa=$(this).parent();var Z=aa.children();var Y;for(Y=0;Y<Z.length;Y++){if(ac.offsetY<$(Z.get(Y)).position().top){break}}if(Y===Z.length){if(this!==Z.get(Y-1)){aa.append(this)}}else{if(this!==Z.get(Y)){$(this).insertBefore(Z.get(Y))}}})};var h=function(Y,W){var X=W-Y;return(X<=2?0.01:(X<=100?1:(X<=1000?5:10)))};var C=9,z=10,L=C+2,w=100,D=12000,J=200,r=10,F=5000,s=100,m="There was an error in indexing this dataset. ",E="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",A="No data for this chrom/contig.",p="Currently indexing... please wait",u="Tool cannot be rerun: ",a="Loading data...",R="Ready for display",d=10,q=5,y=5;function t(W){return Math.round(W*1000)/1000}var c=function(W){this.num_elements=W;this.clear()};extend(c.prototype,{get:function(X){var W=this.key_ary.indexOf(X);if(W!==-1){this.move_key_to_end(X,W)}return this.obj_cache[X]},set:function(X,Y){if(!this.obj_cache[X]){if(this.key_ary.length>=this.num_elements){var W=this.key_ary.shift();delete this.obj_cache[W]}this.key_ary.push(X)}this.obj_cache[X]=Y;return Y},move_key_to_end:function(X,W){this.key_ary.splice(W,1);this.key_ary.push(X)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var K=function(X,W,Y){c.call(this,X);this.track=W;this.subset=(Y!==undefined?Y:true)};extend(K.prototype,c.prototype,{load_data:function(ad,ae,Z,ac,W,ab){var Y={chrom:ad,low:ae,high:Z,mode:ac,resolution:W,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(Y,ab);var af=[];for(var aa=0;aa<this.track.filters.length;aa++){af[af.length]=this.track.filters[aa].name}Y.filter_cols=JSON.stringify(af);var X=this;return $.getJSON(this.track.data_url,Y,function(ag){X.set_data(ae,Z,ac,ag)})},get_data:function(Y,W,ab,ac,X,aa){var Z=this.get(this.gen_key(W,ab,ac));if(Z){return Z}Z=this.load_data(Y,W,ab,ac,X,aa);this.set_data(W,ab,ac,Z);return Z},set_data:function(X,Y,Z,W){return this.set(this.gen_key(X,Y,Z),W)},gen_key:function(W,Y,Z){var X=W+"_"+Y+"_"+Z;return X},split_key:function(W){return W.split("_")}});var U=function(W,Z,Y,X,aa){this.container=W;this.chrom=null;this.vis_id=Y;this.dbkey=X;this.title=Z;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(aa);this.canvas_manager=new V(W.get(0).ownerDocument);this.reset()};extend(U.prototype,{init:function(Z){var Y=this.container,W=this;this.top_container=$("<div/>").addClass("top-container").appendTo(Y);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(Y);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(Y);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);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_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);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_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var X=function(aa){if(aa.type==="focusout"||(aa.keyCode||aa.which)===13||(aa.keyCode||aa.which)===27){if((aa.keyCode||aa.which)!==27){W.go_to($(this).val())}$(this).hide();$(this).val("");W.location_span.show();W.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",X).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.bind("click",function(){W.location_span.hide();W.chrom_select.hide();W.nav_input.val(W.chrom+":"+W.low+"-"+W.high);W.nav_input.css("display","inline-block");W.nav_input.select();W.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a id='zoom-out' />").click(function(){W.zoom_out();W.redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){W.zoom_in();W.redraw()}).appendTo(this.nav_controls);this.load_chroms({low:0},Z);this.chrom_select.bind("change",function(){W.change_chrom(W.chrom_select.val())});this.intro_div.show();this.content_div.bind("click",function(aa){$(this).find("input").trigger("blur")});this.content_div.bind("dblclick",function(aa){W.zoom_in(aa.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(aa,ab){this.current_x=ab.offsetX}).bind("drag",function(aa,ac){var ad=ac.offsetX-this.current_x;this.current_x=ac.offsetX;var ab=Math.round(ad/W.viewport_container.width()*(W.max_high-W.max_low));W.move_delta(-ab)});this.overview_close.bind("click",function(){for(var ab=0,aa=W.tracks.length;ab<aa;ab++){W.tracks[ab].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",W.overview_box.height());W.overview_highlight.hide();$(this).hide()});this.viewport_container.bind("draginit",function(aa,ab){if(aa.clientX>W.viewport_container.width()-16){return false}}).bind("dragstart",function(aa,ab){ab.original_low=W.low;ab.current_height=aa.clientY;ab.current_x=ab.offsetX}).bind("drag",function(ac,ae){var aa=$(this);var af=ae.offsetX-ae.current_x;var ab=aa.scrollTop()-(ac.clientY-ae.current_height);aa.scrollTop(ab);ae.current_height=ac.clientY;ae.current_x=ae.offsetX;var ad=Math.round(af/W.viewport_container.width()*(W.high-W.low));W.move_delta(ad)}).bind("mousewheel",function(ac,ae,ab,aa){if(ab){var ad=Math.round(-ab/W.viewport_container.width()*(W.high-W.low));W.move_delta(ad)}});this.top_labeltrack.bind("dragstart",function(aa,ab){return $("<div />").css({height:W.content_div.height()+W.top_labeltrack.height()+W.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ae,af){$(af.proxy).css({left:Math.min(ae.pageX,af.startX),width:Math.abs(ae.pageX-af.startX)});var ab=Math.min(ae.pageX,af.startX)-W.container.offset().left,aa=Math.max(ae.pageX,af.startX)-W.container.offset().left,ad=(W.high-W.low),ac=W.viewport_container.width();W.update_location(Math.round(ab/ac*ad)+W.low,Math.round(aa/ac*ad)+W.low)}).bind("dragend",function(af,ag){var ab=Math.min(af.pageX,ag.startX),aa=Math.max(af.pageX,ag.startX),ad=(W.high-W.low),ac=W.viewport_container.width(),ae=W.low;W.low=Math.round(ab/ac*ad)+ae;W.high=Math.round(aa/ac*ad)+ae;$(ag.proxy).remove();W.redraw()});this.add_label_track(new T(this,this.top_labeltrack));this.add_label_track(new T(this,this.nav_labeltrack));$(window).bind("resize",function(){W.resize_window()});$(document).bind("redraw",function(){W.redraw()});this.reset();$(window).trigger("resize")},update_location:function(W,X){this.location_span.text(commatize(W)+" - "+commatize(X));this.nav_input.val(this.chrom+":"+commatize(W)+"-"+commatize(X))},load_chroms:function(X,Y){X.num=s;$.extend(X,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var W=this;$.ajax({url:chrom_url,data:X,dataType:"json",success:function(aa){if(aa.chrom_info.length===0){alert("Invalid chromosome: "+X.chrom);return}if(aa.reference){W.add_label_track(new x(W))}W.chrom_data=aa.chrom_info;var ad='<option value="">Select Chrom/Contig</option>';for(var ac=0,Z=W.chrom_data.length;ac<Z;ac++){var ab=W.chrom_data[ac].chrom;ad+='<option value="'+ab+'">'+ab+"</option>"}if(aa.prev_chroms){ad+='<option value="previous">Previous '+s+"</option>"}if(aa.next_chroms){ad+='<option value="next">Next '+s+"</option>"}W.chrom_select.html(ad);if(Y){Y()}W.chrom_start_index=aa.start_index},error:function(){alert("Could not load chroms for this dbkey:",W.dbkey)}})},change_chrom:function(aa,X,ac){if(!aa||aa==="None"){return}var Z=this;if(aa==="previous"){Z.load_chroms({low:this.chrom_start_index-s});return}if(aa==="next"){Z.load_chroms({low:this.chrom_start_index+s});return}var ab=$.grep(Z.chrom_data,function(ae,af){return ae.chrom===aa})[0];if(ab===undefined){Z.load_chroms({chrom:aa},function(){Z.change_chrom(aa,X,ac)});return}else{if(aa!==Z.chrom){Z.chrom=aa;if(!Z.chrom){Z.intro_div.show()}else{Z.intro_div.hide()}Z.chrom_select.val(Z.chrom);Z.max_high=ab.len-1;Z.reset();Z.redraw(true);for(var ad=0,W=Z.tracks.length;ad<W;ad++){var Y=Z.tracks[ad];if(Y.init){Y.init()}}}if(X!==undefined&&ac!==undefined){Z.low=Math.max(X,0);Z.high=Math.min(ac,Z.max_high)}Z.reset_overview();Z.redraw()}},go_to:function(aa){var ae=this,W,Z,X=aa.split(":"),ac=X[0],ad=X[1];if(ad!==undefined){try{var ab=ad.split("-");W=parseInt(ab[0].replace(/,/g,""),10);Z=parseInt(ab[1].replace(/,/g,""),10)}catch(Y){return false}}ae.change_chrom(ac,W,Z)},move_fraction:function(Y){var W=this;var X=W.high-W.low;this.move_delta(Y*X)},move_delta:function(Y){var W=this;var X=W.high-W.low;if(W.low-Y<W.max_low){W.low=W.max_low;W.high=W.max_low+X}else{if(W.high-Y>W.max_high){W.high=W.max_high;W.low=W.max_high-X}else{W.high-=Y;W.low-=Y}}W.redraw()},add_track:function(W){W.view=this;W.track_id=this.track_id_counter;this.tracks.push(W);if(W.init){W.init()}W.container_div.attr("id","track_"+W.track_id);B(W.container_div,".draghandle");this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(W){W.view=this;this.label_tracks.push(W)},remove_track:function(W){this.has_changes=true;W.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(W)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(ad){var ac=this.high-this.low,ab=this.low,X=this.high;if(ab<this.max_low){ab=this.max_low}if(X>this.max_high){X=this.max_high}if(this.high!==0&&ac<this.min_separation){X=ab+this.min_separation}this.low=Math.floor(ab);this.high=Math.ceil(X);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(r,Math.max(0,Math.ceil(Math.log(this.resolution,r)/Math.log(r))));var W=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var aa=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ae=13;this.overview_box.css({left:W,width:Math.max(ae,aa)}).show();if(aa<ae){this.overview_box.css("left",W-(ae-aa)/2)}if(this.overview_highlight){this.overview_highlight.css({left:W,width:aa})}this.update_location(this.low,this.high);if(!ad){for(var Y=0,Z=this.tracks.length;Y<Z;Y++){if(this.tracks[Y]&&this.tracks[Y].enabled){this.tracks[Y].draw()}}for(Y=0,Z=this.label_tracks.length;Y<Z;Y++){this.label_tracks[Y].draw()}}},zoom_in:function(X,Y){if(this.max_high===0||this.high-this.low<this.min_separation){return}var Z=this.high-this.low,aa=Z/2+this.low,W=(Z/this.zoom_factor)/2;if(X){aa=X/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(aa-W);this.high=Math.round(aa+W);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var X=this.high-this.low,Y=X/2+this.low,W=(X*this.zoom_factor)/2;this.low=Math.round(Y-W);this.high=Math.round(Y+W);this.redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide()}});var n=function(X,aa){this.track=X;this.name=aa.name;this.params=[];var ai=aa.params;for(var Y=0;Y<ai.length;Y++){var ad=ai[Y],W=ad.name,ah=ad.label,Z=unescape(ad.html),af=ad.type;if(af==="number"){this.params[this.params.length]=new g(W,ah,Z,ad.min,ad.max)}else{if(af=="select"){this.params[this.params.length]=new I(W,ah,Z)}else{console.log("WARNING: unrecognized tool parameter type:",W,af)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(ak){ak.stopPropagation()}).bind("click",function(ak){ak.stopPropagation()}).bind("dblclick",function(ak){ak.stopPropagation()});var ag=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var ae=this.params;var ab=this;$.each(this.params,function(al,ao){var an=$("<div>").addClass("param-row").appendTo(ab.parent_div);var ak=$("<div>").addClass("param-label").text(ao.label).appendTo(an);var am=$("<div/>").addClass("slider").html(ao.html).appendTo(an);$("<div style='clear: both;'/>").appendTo(an)});this.parent_div.find("input").click(function(){$(this).select()});var aj=$("<div>").addClass("slider-row").appendTo(this.parent_div);var ac=$("<input type='submit'>").attr("value","Run").appendTo(aj);var ab=this;ac.click(function(){ab.run()})};extend(n.prototype,{get_param_values_dict:function(){var W={};this.parent_div.find(":input").each(function(){var X=$(this).attr("name"),Y=$(this).val();W[X]=JSON.stringify(Y)});return W},get_param_values:function(){var X=[];var W={};this.parent_div.find(":input").each(function(){var Y=$(this).attr("name"),Z=$(this).val();if(Y){X[X.length]=Z}});return X},run:function(){var X={dataset_id:this.track.original_dataset_id,chrom:this.track.view.chrom,low:this.track.view.low,high:this.track.view.high,tool_id:this.name};$.extend(X,this.get_param_values_dict());var Z=this.track,Y=X.tool_id+Z.tool_region_and_parameters_str(X.chrom,X.low,X.high),aa;if(Z.track_type==="FeatureTrack"){aa=new N(Y,view,Z.hda_ldda,undefined,{},{},Z)}this.track.add_track(aa);aa.content_div.text("Starting job.");var W=function(){$.getJSON(run_tool_url,X,function(ab){if(ab==="no converter"){aa.container_div.addClass("error");aa.content_div.text(E)}else{if(ab.error){aa.container_div.addClass("error");aa.content_div.text(u+ab.message)}else{if(ab==="pending"){aa.container_div.addClass("pending");aa.content_div.text("Converting input data so that it can be easily reused.");setTimeout(W,2000)}else{aa.dataset_id=ab.dataset_id;aa.content_div.text("Running job.");aa.init()}}}})};W()}});var I=function(X,W,Y){this.name=X;this.label=W;this.html=Y};var g=function(Y,X,aa,Z,W){I.call(this,Y,X,aa);this.min=Z;this.max=W};var j=function(X,W,Y){this.name=X;this.index=W;this.value=Y};var O=function(X,W){this.name=X;this.index=W;this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.slider=null;this.slider_label=null};extend(O.prototype,{applies_to:function(W){if(W.length>this.index){return true}return false},keep:function(W){if(!this.applies_to(W)){return true}return(W[this.index]>=this.low&&W[this.index]<=this.high)},update_attrs:function(X){var W=false;if(!this.applies_to(X)){return W}if(X[this.index]<this.min){this.min=Math.floor(X[this.index]);W=true}if(X[this.index]>this.max){this.max=Math.ceil(X[this.index]);W=true}return W},update_ui_elt:function(){var X=this.slider.slider("option","min"),W=this.slider.slider("option","max");if(this.min<X||this.max>W){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",h(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var v=function(W){var ac=[];for(var Z=0;Z<W.length;Z++){var ab=W[Z];var Y=ab.name,aa=ab.type,X=ab.index;if(aa==="int"||aa==="float"){ac[Z]=new O(Y,X)}else{ac[Z]=new j(Y,X,aa)}}return ac};var S=function(W){this.track=W.track;this.params=W.params;this.values={};if(W.saved_values){this.restore_values(W.saved_values)}this.onchange=W.onchange};extend(S.prototype,{restore_values:function(W){var X=this;$.each(this.params,function(Y,Z){if(W[Z.key]!==undefined){X.values[Z.key]=W[Z.key]}else{X.values[Z.key]=Z.default_value}})},build_form:function(){var X=this;var W=$("<div />");$.each(this.params,function(ab,Z){if(!Z.hidden){var Y="param_"+ab;var ag=$("<div class='form-row' />").appendTo(W);ag.append($("<label />").attr("for",Y).text(Z.label+":"));if(Z.type==="bool"){ag.append($('<input type="checkbox" />').attr("id",Y).attr("name",Y).attr("checked",X.values[Z.key]))}else{if(Z.type==="color"){var ad=X.values[Z.key];var ac=$("<input />").attr("id",Y).attr("name",Y).val(ad);var ae=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var aa=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(ae);var af=$("<div/>").appendTo(aa).farbtastic({width:100,height:100,callback:ac,color:ad});$("<div />").append(ac).append(ae).appendTo(ag).bind("click",function(ah){ae.css({left:$(this).position().left+($(ac).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){ae.hide();$(document).unbind("click.color-picker")});ah.stopPropagation()})}else{ag.append($("<input />").attr("id",Y).attr("name",Y).val(X.values[Z.key]))}}}});return W},update_from_form:function(W){var Y=this;var X=false;$.each(this.params,function(Z,ab){if(!ab.hidden){var ac="param_"+Z;var aa=W.find("#"+ac).val();if(ab.type==="float"){aa=parseFloat(aa)}else{if(ab.type==="int"){aa=parseInt(aa)}else{if(ab.type==="bool"){aa=W.find("#"+ac).is(":checked")}}}if(aa!==Y.values[ab.key]){Y.values[ab.key]=aa;X=true}}});if(X){this.onchange()}}});var b=function(W,X){this.track=W;this.canvas=X};var k=function(X,W,aa,Y,Z){this.name=X;this.view=W;this.parent_element=aa;this.data_url=(Y?Y:default_data_url);this.data_url_extra_params={};this.data_query_wait=(Z?Z:F);this.dataset_check_url=converted_datasets_state_url;this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){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.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)};extend(k.prototype,{init:function(){var W=this;W.enabled=false;W.tile_cache.clear();W.data_cache.clear();W.initial_canvas=undefined;W.content_div.css("height","auto");W.container_div.removeClass("nodata error pending");if(!W.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:W.hda_ldda,dataset_id:W.dataset_id,chrom:W.view.chrom},function(X){if(!X||X==="error"||X.kind==="error"){W.container_div.addClass("error");W.content_div.text(m);if(X.message){var Z=W.view.tracks.indexOf(W);var Y=$(" <a href='javascript:void(0);'></a>").text("View error").bind("click",function(){show_modal("Trackster Error","<pre>"+X.message+"</pre>",{Close:hide_modal})});W.content_div.append(Y)}}else{if(X==="no converter"){W.container_div.addClass("error");W.content_div.text(E)}else{if(X==="no data"||(X.data!==undefined&&(X.data===null||X.data.length===0))){W.container_div.addClass("nodata");W.content_div.text(A)}else{if(X==="pending"){W.container_div.addClass("pending");W.content_div.text(p);setTimeout(function(){W.init()},W.data_query_wait)}else{if(X.status==="data"){if(X.valid_chroms){W.valid_chroms=X.valid_chroms;W.make_name_popup_menu()}W.content_div.text(R);if(W.view.chrom){W.content_div.text("");W.content_div.css("height",W.height_px+"px");W.enabled=true;$.when(W.predraw_init()).done(function(){W.container_div.removeClass("nodata error pending");W.draw()})}}}}}}})},predraw_init:function(){},update_name:function(W){this.old_name=this.name;this.name=W;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)}});var H=function(X,ad,ag){var Y=this,ah=Y.view;this.filters=(X!==undefined?v(X):[]);this.filters_available=false;this.filters_visible=false;this.tool=(ad!==undefined&&obj_length(ad)>0?new n(this,ad):undefined);this.parent_track=ag;this.child_tracks=[];if(Y.hidden){return}var af=function(ai,aj,ak){ai.click(function(){var al=aj.text();max=parseFloat(ak.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(ak.slider("option","values")){input_size=2*input_size+1;multi_value=true}aj.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",al).appendTo(aj).focus().select().click(function(am){am.stopPropagation()}).blur(function(){$(this).remove();aj.text(al)}).keyup(function(aq){if(aq.keyCode===27){$(this).trigger("blur")}else{if(aq.keyCode===13){var ao=ak.slider("option","min"),am=ak.slider("option","max"),ap=function(ar){return(isNaN(ar)||ar>am||ar<ao)},an=$(this).val();if(!multi_value){an=parseFloat(an);if(ap(an)){alert("Parameter value must be in the range ["+ao+"-"+am+"]");return $(this)}}else{an=an.split("-");an=[parseFloat(an[0]),parseFloat(an[1])];if(ap(an[0])||ap(an[1])){alert("Parameter value must be in the range ["+ao+"-"+am+"]");return $(this)}}ak.slider((multi_value?"values":"value"),an)}}})})};if(this.parent_track){this.header_div.find(".draghandle").removeClass("draghandle").addClass("child-track-icon").addClass("icon-button");this.parent_element.addClass("child-track");this.tool=undefined}this.filters_div=$("<div/>").addClass("filters").hide();this.header_div.after(this.filters_div);this.filters_div.bind("drag",function(ai){ai.stopPropagation()}).bind("click",function(ai){ai.stopPropagation()}).bind("dblclick",function(ai){ai.stopPropagation()});$.each(this.filters,function(ao,aj){var al=$("<div/>").addClass("slider-row").appendTo(Y.filters_div);var ai=$("<div/>").addClass("slider-label").appendTo(al);var aq=$("<span/>").addClass("slider-name").text(aj.name+" ").appendTo(ai);var ak=$("<span/>");var am=$("<span/>").addClass("slider-value").appendTo(ai).append("[").append(ak).append("]");var ap=$("<div/>").addClass("slider").appendTo(al);aj.control_element=$("<div/>").attr("id",aj.name+"-filter-control").appendTo(ap);var an=[0,0];aj.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(ar,at){an=at.values;ak.text(at.values[0]+"-"+at.values[1]);setTimeout(function(){if(at.values[0]==an[0]&&at.values[1]==an[1]){var au=at.values;ak.text(au[0]+"-"+au[1]);aj.low=au[0];aj.high=au[1];Y.draw(true,true)}},50)},change:function(ar,at){aj.control_element.slider("option","slide").call(aj.control_element,ar,at)}});aj.slider=aj.control_element;aj.slider_label=ak;af(am,ak,aj.control_element);$("<div style='clear: both;'/>").appendTo(al)});if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}Y.child_tracks_container=$("<div/>").addClass("child-tracks-container").hide();Y.container_div.append(Y.child_tracks_container);if(Y.display_modes!==undefined){if(Y.mode_div===undefined){Y.mode_div=$("<div class='right-float menubutton popup' />").appendTo(Y.header_div);var aa=(Y.track_config&&Y.track_config.values.mode?Y.track_config.values.mode:Y.display_modes[0]);Y.mode=aa;Y.mode_div.text(aa);var Z=function(ai){Y.mode_div.text(ai);Y.mode=ai;Y.track_config.values.mode=ai;Y.tile_cache.clear();Y.draw()};var W={};for(var ab=0,ae=Y.display_modes.length;ab<ae;ab++){var ac=Y.display_modes[ab];W[ac]=function(ai){return function(){Z(ai)}}(ac)}make_popupmenu(Y.mode_div,W)}else{Y.mode_div.hide()}}this.make_name_popup_menu()};extend(H.prototype,k.prototype,{make_name_popup_menu:function(){var X=this;var W={};W["Edit configuration"]=function(){var ad=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},ab=function(){X.track_config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ac=function(ae){if((ae.keyCode||ae.which)===27){ad()}else{if((ae.keyCode||ae.which)===13){ab()}}};$(window).bind("keypress.check_enter_esc",ac);show_modal("Configure Track",X.track_config.build_form(),{Cancel:ad,OK:ab})};if(X.filters_available>0){var aa=(X.filters_div.is(":visible")?"Hide filters":"Show filters");W[aa]=function(){X.filters_visible=(X.filters_div.is(":visible"));X.filters_div.toggle();X.make_name_popup_menu()}}if(X.tool){var aa=(X.dynamic_tool_div.is(":visible")?"Hide tool":"Show tool");W[aa]=function(){if(!X.dynamic_tool_div.is(":visible")){X.update_name(X.name+X.tool_region_and_parameters_str())}else{menu_option_text="Show dynamic tool";X.revert_name()}X.dynamic_tool_div.toggle();X.make_name_popup_menu()}}if(X.valid_chroms){W["List chrom/contigs with data"]=function(){show_modal("Chrom/contigs with data","<p>"+X.valid_chroms.join("<br/>")+"</p>",{Close:function(){hide_modal()}})}}var Y=view;var Z=function(){$("#no-tracks").show()};if(this.parent_track){Y=this.parent_track;Z=function(){}}W.Remove=function(){Y.remove_track(X);if(Y.num_tracks===0){Z()}};make_popupmenu(X.name_div,W)},draw:function(W,Z){var an=this.view.low,ac=this.view.high,ae=ac-an,ag=this.view.container.width(),ab=ag/ae,ah=this.view.resolution,aa=$("<div style='position: relative;'></div>");if(!Z){this.content_div.children().remove()}this.content_div.append(aa);this.max_height=0;var aj=Math.floor(an/ah/J);var Y={};while((aj*J*ah)<ac){var am=ag+"_"+ab+"_"+aj;var ad=this.tile_cache.get(am);var ak=aj*J*this.view.resolution;var X=ak+J*this.view.resolution;if(!W&&ad){this.show_tile(ad,aa,ak,ab)}else{this.delayed_draw(W,am,ak,X,aj,ah,aa,ab,Y)}aj+=1}var af=this;var al=setInterval(function(){if(obj_length(Y)===0){clearInterval(al);if(Z){var aq=af.content_div.children();var ap=false;for(var ar=aq.length-1,ao=0;ar>=ao;ar--){var av=$(aq[ar]);if(ap){av.remove()}else{if(av.children().length!==0){ap=true}}}}for(var au=0;au<af.filters.length;au++){af.filters[au].update_ui_elt()}var at=false;if(af.example_feature){for(var au=0;au<af.filters.length;au++){if(af.filters[au].applies_to(af.example_feature)){at=true;break}}}if(af.filters_available!==at){af.filters_available=at;if(!af.filters_available){af.filters_div.hide()}af.make_name_popup_menu()}}},50);for(var ai=0;ai<this.child_tracks.length;ai++){this.child_tracks[ai].draw(W,Z)}},delayed_draw:function(X,ae,ac,ag,Y,aa,af,ah,ab){var Z=this;var ad=function(ap,ai,ak,aj,an,ao,al){returned_tile=Z.draw_tile(ai,ak,aj,an,ao,al);var am=$("<div class='track-tile'>").prepend(returned_tile);tile_element=am;Z.tile_cache.set(ae,tile_element);Z.show_tile(tile_element,an,ac,ao);delete ab[ap]};var W=setTimeout(function(){if(ac<=Z.view.high&&ag>=Z.view.low){var ai=(X?undefined:Z.tile_cache.get(ae));if(ai){Z.show_tile(ai,af,ac,ah);delete ab[W]}else{$.when(Z.data_cache.get_data(view.chrom,ac,ag,Z.mode,aa,Z.data_url_extra_params)).then(function(aj){if(view.reference_track&&ah>view.canvas_manager.char_width_px){$.when(view.reference_track.data_cache.get_data(view.chrom,ac,ag,Z.mode,aa,view.reference_track.data_url_extra_params)).then(function(ak){ad(W,aj,aa,Y,af,ah,ak)})}else{ad(W,aj,aa,Y,af,ah)}})}}},50);ab[W]=true},show_tile:function(W,ab,Z,ac){var X=this;var Y=this.view.high-this.view.low,aa=(Z-this.view.low)*ac;if(this.left_offset){aa-=this.left_offset}W.css({position:"absolute",top:0,left:aa,height:""});ab.append(W);X.max_height=Math.max(X.max_height,W.height());X.content_div.css("height",X.max_height+"px");ab.children().css("height",X.max_height+"px")},set_overview:function(){var W=this.view;if(this.initial_canvas&&this.is_overview){W.overview_close.show();W.overview_viewport.append(this.initial_canvas);W.overview_highlight.show().height(this.initial_canvas.height());W.overview_viewport.height(this.initial_canvas.height()+W.overview_box.height())}$(window).trigger("resize")},tool_region_and_parameters_str:function(Y,W,Z){var X=this,aa=(Y!==undefined&&W!==undefined&&Z!==undefined?Y+":"+W+"-"+Z:"all");return" - region=["+aa+"], parameters=["+X.tool.get_param_values().join(", ")+"]"},add_track:function(W){W.track_id=this.track_id+"_"+this.child_tracks.length;W.container_div.attr("id","track_"+W.track_id);this.child_tracks_container.append(W.container_div);B(W.container_div,".child-track-icon");if(!$(this.child_tracks_container).is(":visible")){this.child_tracks_container.show()}this.child_tracks.push(W);this.view.has_changes=true},remove_track:function(W){W.container_div.fadeOut("slow",function(){$(this).remove()})}});var T=function(W,X){this.track_type="LabelTrack";this.hidden=true;k.call(this,null,W,X);this.container_div.addClass("label-track")};extend(T.prototype,k.prototype,{draw:function(){var Y=this.view,Z=Y.high-Y.low,ac=Math.floor(Math.pow(10,Math.floor(Math.log(Z)/Math.log(10)))),W=Math.floor(Y.low/ac)*ac,aa=this.view.container.width(),X=$("<div style='position: relative; height: 1.3em;'></div>");while(W<Y.high){var ab=(W-Y.low)/Z*aa;X.append($("<div class='label'>"+commatize(W)+"</div>").css({position:"absolute",left:ab-1}));W+=ac}this.content_div.children(":first").remove();this.content_div.append(X)}});var x=function(W){this.track_type="ReferenceTrack";this.hidden=true;k.call(this,null,W,W.top_labeltrack);H.call(this);W.reference_track=this;this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:W.dbkey};this.data_cache=new K(y,this,false);this.tile_cache=new c(q)};extend(x.prototype,H.prototype,{draw_tile:function(ag,ab,X,ad,ah){var aa=this,Y=J*ab;if(ah>this.view.canvas_manager.char_width_px){if(ag===null){aa.content_div.css("height","0px");return}var Z=this.view.canvas_manager.new_canvas();var af=Z.getContext("2d");Z.width=Math.ceil(Y*ah+aa.left_offset);Z.height=aa.height_px;af.font=af.canvas.manager.default_font;af.textAlign="center";for(var ac=0,ae=ag.length;ac<ae;ac++){var W=Math.round(ac*ah);af.fillText(ag[ac],W+aa.left_offset,10)}return Z}this.content_div.css("height","0px")}});var l=function(aa,Y,ab,W,Z){var X=this;this.track_type="LineTrack";this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";k.call(this,aa,Y,Y.viewport_container);H.call(this);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=ab;this.dataset_id=W;this.original_dataset_id=W;this.data_cache=new K(y,this);this.tile_cache=new c(q);this.track_config=new S({track:this,params:[{key:"color",label:"Color",type:"color",default_value:"black"},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.height_px,hidden:true}],saved_values:Z,onchange:function(){X.vertical_range=X.prefs.max_value-X.prefs.min_value;$("#linetrack_"+X.track_id+"_minval").text(X.prefs.min_value);$("#linetrack_"+X.track_id+"_maxval").text(X.prefs.max_value);X.tile_cache.clear();X.draw()}});this.prefs=this.track_config.values;this.height_px=this.track_config.values.height;this.vertical_range=this.track_config.values.max_value-this.track_config.values.min_value;this.add_resize_handle()};extend(l.prototype,H.prototype,{add_resize_handle:function(){var W=this;var Z=false;var Y=false;var X=$("<div class='track-resize'>");$(W.container_div).hover(function(){Z=true;X.show()},function(){Z=false;if(!Y){X.hide()}});X.hide().bind("dragstart",function(aa,ab){Y=true;ab.original_height=$(W.content_div).height()}).bind("drag",function(ab,ac){var aa=Math.min(Math.max(ac.original_height+ac.deltaY,W.min_height_px),W.max_height_px);$(W.content_div).css("height",aa);W.height_px=aa;W.draw(true)}).bind("dragend",function(aa,ab){W.tile_cache.clear();Y=false;if(!Z){X.hide()}W.track_config.values.height=W.height_px}).appendTo(W.container_div)},predraw_init:function(){var W=this,X=W.view.tracks.indexOf(W);W.vertical_range=undefined;return $.getJSON(W.data_url,{stats:true,chrom:W.view.chrom,low:null,high:null,hda_ldda:W.hda_ldda,dataset_id:W.dataset_id},function(Y){W.container_div.addClass("line-track");var aa=Y.data;if(isNaN(parseFloat(W.prefs.min_value))||isNaN(parseFloat(W.prefs.max_value))){W.prefs.min_value=aa.min;W.prefs.max_value=aa.max;$("#track_"+X+"_minval").val(W.prefs.min_value);$("#track_"+X+"_maxval").val(W.prefs.max_value)}W.vertical_range=W.prefs.max_value-W.prefs.min_value;W.total_frequency=aa.total_frequency;W.container_div.find(".yaxislabel").remove();var ab=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+X+"_minval").text(t(W.prefs.min_value));var Z=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+X+"_maxval").text(t(W.prefs.max_value));Z.css({position:"absolute",top:"24px",left:"10px"});Z.prependTo(W.container_div);ab.css({position:"absolute",bottom:"2px",left:"10px"});ab.prependTo(W.container_div)})},draw_tile:function(ah,aa,X,ae,ag){if(this.vertical_range===undefined){return}var ab=X*J*aa,Z=J*aa,W=Math.ceil(Z*ag),ad=this.height_px;var Y=this.view.canvas_manager.new_canvas();Y.width=W,Y.height=ad;var af=Y.getContext("2d");var ac=new G.LinePainter(ah.data,ab,ab+Z,this.prefs,this.mode);ac.draw(af,W,ad);return Y}});var e=function(W,ab,aa,ae,ad,Y,Z,ac){var X=this;this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];this.track_config=new S({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ad,onchange:function(){X.tile_cache.clear();X.draw()}});this.prefs=this.track_config.values;k.call(this,W,ab,ab.viewport_container);H.call(this,Y,Z,ac);this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=aa;this.dataset_id=ae;this.original_dataset_id=ae;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.inc_slots={};this.start_end_dct={};this.tile_cache=new c(d);this.data_cache=new K(20,this);this.left_offset=200;this.painter=G.LinkedFeaturePainter};extend(e.prototype,H.prototype,{update_auto_mode:function(W){if(this.mode=="Auto"){if(W=="no_detail"){W="feature spans"}else{if(W=="summary_tree"){W="coverage histogram"}}this.mode_div.text("Auto ("+W+")")}},incremental_slots:function(aa,X,Z){var Y=this.view.canvas_manager.dummy_context,W=this.inc_slots[aa];if(!W||(W.mode!==Z)){W=new (o.FeatureSlotter)(aa,Z==="Pack",w,function(ab){return Y.measureText(ab)});W.mode=Z;this.inc_slots[aa]=W}return W.slot_features(X)},draw_tile:function(ai,aq,av,ae,ag,Z){var an=this,ax=av*J*aq,X=(av+1)*J*aq,ak=X-ax,ao=Math.ceil(ak*ag),am=this.mode,aB=25,aa=this.left_offset,aj,ab;if(am==="Auto"){if(ai.dataset_type==="summary_tree"){am=ai.dataset_type}else{if(ai.extra_info==="no_detail"){am="no_detail"}else{var aA=ai.data;if(this.view.high-this.view.low>D){am="Squish"}else{am="Pack"}}}this.update_auto_mode(am)}if(am==="summary_tree"){ab=this.summary_draw_height;ae.parent().css("height",Math.max(this.height_px,ab)+"px");this.container_div.find(".yaxislabel").remove();var W=$("<div />").addClass("yaxislabel");W.text(ai.max);W.css({position:"absolute",top:"22px",left:"10px"});W.prependTo(this.container_div);var Y=this.view.canvas_manager.new_canvas();Y.width=ao+aa;Y.height=ab+L;var ay=new G.SummaryTreePainter(ai,ax,X,this.prefs);var ap=Y.getContext("2d");ap.translate(aa,L);ay.draw(ap,ao,ab);return Y}var aj,ad=1;if(am==="no_detail"||am==="Squish"||am==="Pack"){ad=this.incremental_slots(ag,ai.data,am);aj=this.inc_slots[ag].slots}var af=[];if(ai.data){for(var ar=0,au=ai.data.length;ar<au;ar++){var ac=ai.data[ar];var at=false;var ah;for(var aw=0,az=this.filters.length;aw<az;aw++){ah=this.filters[aw];ah.update_attrs(ac);if(!ah.keep(ac)){at=true;break}}if(!at){af.push(ac)}}}var ay=new (this.painter)(af,ax,X,this.prefs,am,Z);var ab=ay.get_required_height(ad)+z;var Y=this.view.canvas_manager.new_canvas();Y.width=ao+aa;Y.height=ab;ae.parent().css("height",Math.max(this.height_px,ab)+"px");var ap=Y.getContext("2d");ap.fillStyle=this.prefs.block_color;ap.font=ap.canvas.manager.default_font;ap.textAlign="right";this.container_div.find(".yaxislabel").remove();if(ai.message){$(Y).css({"border-top":"1px solid red"});ap.fillStyle="red";ap.textAlign="left";var al=ap.textBaseline;ap.textBaseline="top";ap.fillText(ai.message,aa,0);ap.textBaseline=al;if(!ai.data){return Y}}this.example_feature=(ai.data.length?ai.data[0]:undefined);ap.translate(aa,z);ay.draw(ap,ao,ab,aj);return Y}});var M=function(Z,X,ab,W,Y,aa){e.call(this,Z,X,ab,W,Y,aa);this.track_type="VcfTrack";this.painter=G.VariantPainter};extend(M.prototype,H.prototype,e.prototype);var P=function(Z,X,ab,W,Y,aa){e.call(this,Z,X,ab,W,Y,aa);this.track_config=new S({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:Y,onchange:function(){this.track.tile_cache.clear();this.track.draw()}});this.prefs=this.track_config.values;this.track_type="ReadTrack";this.painter=G.ReadPainter;this.make_name_popup_menu()};extend(P.prototype,H.prototype,e.prototype);var N=function(aa,Y,ac,W,Z,ab,X){e.call(this,aa,Y,ac,W,Z,ab,{},X);this.track_type="ToolDataFeatureTrack";this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};extend(N.prototype,H.prototype,e.prototype,{predraw_init:function(){var X=this;var W=function(){if(X.data_cache.size()===0){setTimeout(W,300)}else{X.data_url=default_data_url;X.data_query_wait=F;X.dataset_state_url=converted_datasets_state_url;$.getJSON(X.dataset_state_url,{dataset_id:X.dataset_id,hda_ldda:X.hda_ldda},function(Y){})}};W()}});Q.View=U;Q.LineTrack=l;Q.FeatureTrack=e;Q.ReadTrack=P};var slotting_module=function(c,b){var d=2,a=5;b.FeatureSlotter=function(h,g,e,f){this.slots={};this.start_end_dct={};this.w_scale=h;this.include_label=g;this.max_rows=e;this.measureText=f};extend(b.FeatureSlotter.prototype,{slot_features:function(l){var o=this.w_scale,r=this.slots,g=this.start_end_dct,x=[],z=[],m=0,y=this.max_rows;for(var v=0,w=l.length;v<w;v++){var k=l[v],n=k[0];if(r[n]!==undefined){m=Math.max(m,r[n]);z.push(r[n])}else{x.push(v)}}var p=function(F,G){for(var E=0;E<=y;E++){var C=false,H=g[E];if(H!==undefined){for(var B=0,D=H.length;B<D;B++){var A=H[B];if(G>A[0]&&F<A[1]){C=true;break}}}if(!C){return E}}return -1};for(var v=0,w=x.length;v<w;v++){var k=l[x[v]],n=k[0],t=k[1],e=k[2],q=k[3],f=Math.floor(t*o),j=Math.ceil(e*o),u=this.measureText(q).width,h;if(q!==undefined&&this.include_label){u+=(d+a);if(f-u>=0){f-=u;h="left"}else{j+=u;h="right"}}var s=p(f,j);if(s>=0){if(g[s]===undefined){g[s]=[]}g[s].push([f,j]);r[n]=s;m=Math.max(m,s)}else{}}return m+1}})};var painters_module=function(k,B){var r=function(M,E,K,D,J,H){if(H===undefined){H=4}var G=D-E;var F=J-K;var I=Math.floor(Math.sqrt(G*G+F*F)/H);var N=G/I;var L=F/I;var C;for(C=0;C<I;C++,E+=N,K+=L){if(C%2!==0){continue}M.fillRect(E,K,H,1)}};var s=function(E,D,C,H){var G=D-H/2,F=D+H/2,I=C-Math.sqrt(H*3/2);E.beginPath();E.moveTo(G,I);E.lineTo(F,I);E.lineTo(D,C);E.lineTo(G,I);E.strokeStyle=this.fillStyle;E.fill();E.stroke();E.closePath()};var o=function(E,G,C,D,F){this.data=E;this.view_start=G;this.view_end=C;this.prefs=extend({},this.default_prefs,D);this.mode=F};o.prototype.default_prefs={};var w=function(E,G,C,D,F){o.call(this,E,G,C,D,F)};w.prototype.default_prefis={show_counts:false};w.prototype.draw=function(P,C,O){var H=this.view_start,R=this.view_end-this.view_start,Q=C/R;var M=this.data.data,L=this.data.delta,J=this.data.max,E=O;delta_x_px=Math.ceil(L*Q);P.save();for(var F=0,G=M.length;F<G;F++){var K=Math.floor((M[F][0]-H)*Q);var I=M[F][1];if(!I){continue}var N=I/J*O;P.fillStyle="black";P.fillRect(K,E-N,delta_x_px,N);var D=4;if(this.prefs.show_counts&&(P.measureText(I).width+D)<delta_x_px){P.fillStyle="#666";P.textAlign="center";P.fillText(I,K+(delta_x_px/2),10)}}P.restore()};var c=function(E,G,C,D,F){o.call(this,E,G,C,D,F)};c.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};c.prototype.draw=function(R,Q,O){var J=false,K=this.prefs.min_value,H=this.prefs.max_value,N=H-K,D=O,E=this.view_start,P=this.view_end-this.view_start,F=Q/P,L=this.mode,V=this.data;R.save();var W=Math.round(O+K/N*O);if(L!=="Intensity"){R.fillStyle="#aaa";R.fillRect(0,W,Q,1)}R.beginPath();R.fillStyle=this.prefs.color;var U,I,G;if(V.length>1){G=Math.ceil((V[1][0]-V[0][0])*F)}else{G=10}for(var S=0,T=V.length;S<T;S++){U=Math.round((V[S][0]-E)*F);I=V[S][1];if(I===null){if(J&&L==="Filled"){R.lineTo(U,D)}J=false;continue}if(I<K){I=K}else{if(I>H){I=H}}if(L==="Histogram"){I=Math.round(I/N*D);R.fillRect(U,W,G,-I)}else{if(L==="Intensity"){I=255-Math.floor((I-K)/N*255);R.fillStyle="rgb("+I+","+I+","+I+")";R.fillRect(U,0,G,D)}else{I=Math.round(D-(I-K)/N*D);if(J){R.lineTo(U,I)}else{J=true;if(L==="Filled"){R.moveTo(U,D);R.lineTo(U,I)}else{R.moveTo(U,I)}}}}}if(L==="Filled"){if(J){R.lineTo(U,W);R.lineTo(0,W)}R.fill()}else{R.stroke()}var C=-1,M=-1;R.fillStyle=this.prefs.overflow_color;for(var S=0,T=V.length;S<T;S++){I=V[S][1];U=Math.round((V[S][0]-E)*F);x_minus_scaled=Math.round((V[S][0]-1-E)*F);if(M>=0&&(I===null||I<H)){R.fillRect(M,0,x_minus_scaled-M+1,2);M=-1}else{if(C>=0&&(I===null||I>K)){R.fillRect(C,O-2,x_minus_scaled-C+1,2);C=-1}}if(I!==null&&I>H&&M<0){M=U}else{if(I!==null&&I<K&&C<0){C=U}}}R.restore()};var q=function(E,G,C,D,F){o.call(this,E,G,C,D,F)};q.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};extend(q.prototype,{get_required_height:function(D){var C=y_scale=this.get_row_height(),E=this.mode;if(E==="no_detail"||E==="Squish"||E==="Pack"){C=D*y_scale}return C+Math.max(Math.round(y_scale/2),5)},draw:function(O,F,N,K){var I=this.data,L=this.view_start,P=this.view_end;O.save();O.fillStyle=this.prefs.block_color;O.textAlign="right";var S=this.view_end-this.view_start,R=F/S,E=this.get_row_height();for(var H=0,J=I.length;H<J;H++){var Q=I[H],G=Q[0],C=Q[1],D=Q[2],M=(K&&K[G]!==undefined?K[G]:null);if((C<P&&D>L)&&(this.mode=="Dense"||M!==null)){this.draw_element(O,this.mode,Q,M,L,P,R,E,F)}}O.restore()}});var d=10,j=3,n=5,A=10,g=1,u=3,f=3,a=9,p=2,h="#ccc";var t=function(E,G,C,D,F){q.call(this,E,G,C,D,F)};extend(t.prototype,q.prototype,{get_row_height:function(){var D=this.mode,C;if(D==="Dense"){C=d}else{if(D==="no_detail"){C=j}else{if(D==="Squish"){C=n}else{C=A}}}return C},draw_element:function(O,H,W,J,Q,ag,ak,al,C){var T=W[0],ai=W[1],aa=W[2]-1,R=W[3],ab=Math.floor(Math.max(0,(ai-Q)*ak)),P=Math.ceil(Math.min(C,Math.max(0,(aa-Q)*ak))),Z=(H==="Dense"?0:(0+J))*al,N,ae,S=null,am=null,F=this.prefs.block_color,ad=this.prefs.label_color;if(H=="Dense"){J=1}if(H==="no_detail"){O.fillStyle=F;O.fillRect(ab,Z+5,P-ab,g)}else{var M=W[4],Y=W[5],ac=W[6],G=W[7];if(Y&&ac){S=Math.floor(Math.max(0,(Y-Q)*ak));am=Math.ceil(Math.min(C,Math.max(0,(ac-Q)*ak)))}var aj,U;if(H==="Squish"||H==="Dense"){aj=1;U=f}else{aj=5;U=a}if(!G){if(W.strand){if(W.strand==="+"){O.fillStyle=O.canvas.manager.get_pattern("right_strand_inv")}else{if(W.strand==="-"){O.fillStyle=O.canvas.manager.get_pattern("left_strand_inv")}}}else{O.fillStyle=F}O.fillRect(ab,Z,P-ab,U)}else{var L,V;if(H==="Squish"||H==="Dense"){O.fillStyle=h;L=Z+Math.floor(f/2)+1;V=1}else{if(M){var L=Z;var V=U;if(M==="+"){O.fillStyle=O.canvas.manager.get_pattern("right_strand")}else{if(M==="-"){O.fillStyle=O.canvas.manager.get_pattern("left_strand")}}}else{O.fillStyle=h;L+=(f/2)+1;V=1}}O.fillRect(ab,L,P-ab,V);for(var ah=0,E=G.length;ah<E;ah++){var I=G[ah],D=Math.floor(Math.max(0,(I[0]-Q)*ak)),X=Math.ceil(Math.min(C,Math.max((I[1]-1-Q)*ak)));if(D>X){continue}O.fillStyle=F;O.fillRect(D,Z+(U-aj)/2+1,X-D,aj);if(S!==undefined&&ac>Y&&!(D>am||X<S)){var af=Math.max(D,S),K=Math.min(X,am);O.fillRect(af,Z+1,K-af,U);if(G.length==1&&H=="Pack"){if(M==="+"){O.fillStyle=O.canvas.manager.get_pattern("right_strand_inv")}else{if(M==="-"){O.fillStyle=O.canvas.manager.get_pattern("left_strand_inv")}}if(af+14<K){af+=2;K-=2}O.fillRect(af,Z+1,K-af,U)}}}}if(H==="Pack"&&ai>Q){O.fillStyle=ad;if(Q===0&&ab-O.measureText(R).width<0){O.textAlign="left";O.fillText(R,P+p,Z+8)}else{O.textAlign="right";O.fillText(R,ab-p,Z+8)}O.fillStyle=F}}}});var b=function(E,G,C,D,F){q.call(this,E,G,C,D,F)};extend(b.prototype,q.prototype,{draw_element:function(V,Q,K,G,Y,E,N,W,T){var K=data[i],M=K[0],U=K[1],F=K[2]-1,P=K[3],I=Math.floor(Math.max(0,(U-Y)*N)),L=Math.ceil(Math.min(T,Math.max(0,(F-Y)*N))),H=(Q==="Dense"?0:(0+G))*W,C,Z,D=null,O=null;if(no_label){V.fillStyle=block_color;V.fillRect(I+left_offset,H+5,L-I,1)}else{var X=K[4],S=K[5],J=K[6];C=9;Z=1;V.fillRect(I+left_offset,H,L-I,C);if(Q!=="Dense"&&P!==undefined&&U>Y){V.fillStyle=label_color;if(Y===0&&I-V.measureText(P).width<0){V.textAlign="left";V.fillText(P,L+2+left_offset,H+8)}else{V.textAlign="right";V.fillText(P,I-2+left_offset,H+8)}V.fillStyle=block_color}var R=X+" / "+S;if(U>Y&&V.measureText(R).width<(L-I)){V.fillStyle="white";V.textAlign="center";V.fillText(R,left_offset+I+(L-I)/2,H+8);V.fillStyle=block_color}}}});var z=1001,m=1002,e=1003,y=1004,l=1005;var x=function(G,D){var I=G[0],H=G[1],F=D[0],E=D[1],C;if(I<F){if(H<F){C=z}else{if(H<=E){C=e}else{C=m}}}else{if(I>E){C=z}else{if(H<=E){C=l}else{C=y}}}return C};var v=function(F,H,C,E,G,D){q.call(this,F,H,C,E,G);this.ref_seq=D};v.prototype.default_prefs=extend({},q.prototype.default_prefs,{show_insertions:false});extend(v.prototype,q.prototype,{get_row_height:function(){var C,D=this.mode;if(D==="Dense"){C=d}else{if(D==="Squish"){C=n}else{C=A;if(this.prefs.show_insertions){C*=2}}}return C},draw_read:function(Z,U,P,ae,E,Y,M,J,I){Z.textAlign="center";var X=this,D=[ae,E],S=0,aa=0,W=0;ref_seq=this.ref_seq,char_width_px=Z.canvas.manager.char_width_px;var aj=[];if((U==="Pack"||this.mode==="Auto")&&J!==undefined&&P>char_width_px){W=Math.round(P/2)}if(!M){M=[[0,J.length]]}for(var Q=0,ac=M.length;Q<ac;Q++){var N=M[Q],F="MIDNSHP=X"[N[0]],R=N[1];if(F==="H"||F==="S"){S-=R}var K=Y+S,ai=Math.floor(Math.max(0,(K-ae)*P)),L=Math.floor(Math.max(0,(K+R-ae)*P));if(ai===L){L+=1}switch(F){case"H":break;case"S":case"M":case"=":var T=x([K,K+R],D);if(T!==z){var V=J.slice(aa,aa+R);if(W>0){Z.fillStyle=this.prefs.block_color;Z.fillRect(ai-W,I+1,L-ai,9);Z.fillStyle=h;for(var ag=0,C=V.length;ag<C;ag++){if(this.prefs.show_differences&&ref_seq){var O=ref_seq[K-ae+ag];if(!O||O.toLowerCase()===V[ag].toLowerCase()){continue}}if(K+ag>=ae&&K+ag<=E){var ah=Math.floor(Math.max(0,(K+ag-ae)*P));Z.fillText(V[ag],ah,I+9)}}}else{Z.fillStyle=this.prefs.block_color;Z.fillRect(ai,I+4,L-ai,f)}}aa+=R;S+=R;break;case"N":Z.fillStyle=h;Z.fillRect(ai-W,I+5,L-ai,1);S+=R;break;case"D":Z.fillStyle="red";Z.fillRect(ai-W,I+4,L-ai,3);S+=R;break;case"P":break;case"I":var T=x([K,K+R],D),ad=ai-W;if(T!==z){var V=J.slice(aa,aa+R);if(this.prefs.show_insertions){var H=ai-(L-ai)/2;if((U==="Pack"||this.mode==="Auto")&&J!==undefined&&P>char_width_px){Z.fillStyle="yellow";Z.fillRect(H-W,I-9,L-ai,9);aj[aj.length]={type:"triangle",data:[ad,I+4,5]};Z.fillStyle=h;switch(T){case (e):V=V.slice(ae-K);break;case (y):V=V.slice(0,K-E);break;case (l):break;case (m):V=V.slice(ae-K,K-E);break}for(var ag=0,C=V.length;ag<C;ag++){var ah=Math.floor(Math.max(0,(K+ag-ae)*P));Z.fillText(V[ag],ah-(L-ai)/2,I)}}else{Z.fillStyle="yellow";Z.fillRect(H,I+(this.mode!=="Dense"?2:5),L-ai,(U!=="Dense"?f:u))}}else{if((U==="Pack"||this.mode==="Auto")&&J!==undefined&&P>char_width_px){aj[aj.length]={type:"text",data:[V.length,ad,I+9]}}else{}}}aa+=R;break;case"X":aa+=R;break}}Z.fillStyle="yellow";var af,G,ak;for(var ab=0;ab<aj.length;ab++){af=aj[ab];G=af.type;ak=af.data;if(G==="text"){Z.save();Z.font="bold "+Z.font;Z.fillText(ak[0],ak[1],ak[2]);Z.restore()}else{if(G=="triangle"){s(Z,ak[0],ak[1],ak[2])}}}},draw_element:function(V,Q,I,F,Y,D,M,W,T){var L=I[0],U=I[1],E=I[2],N=I[3],H=Math.floor(Math.max(0,(U-Y)*M)),J=Math.ceil(Math.min(T,Math.max(0,(E-Y)*M))),G=(Q==="Dense"?0:(0+F))*W,Z=this.prefs.block_color,K=this.prefs.label_color,S=0;if((Q==="Pack"||this.mode==="Auto")&&M>V.canvas.manager.char_width_px){var S=Math.round(M/2)}V.fillStyle=Z;if(I[5] instanceof Array){var R=Math.floor(Math.max(0,(I[4][0]-Y)*M)),P=Math.ceil(Math.min(T,Math.max(0,(I[4][1]-Y)*M))),O=Math.floor(Math.max(0,(I[5][0]-Y)*M)),C=Math.ceil(Math.min(T,Math.max(0,(I[5][1]-Y)*M)));if(I[4][1]>=Y&&I[4][0]<=D&&I[4][2]){this.draw_read(V,Q,M,Y,D,I[4][0],I[4][2],I[4][3],G)}if(I[5][1]>=Y&&I[5][0]<=D&&I[5][2]){this.draw_read(V,Q,M,Y,D,I[5][0],I[5][2],I[5][3],G)}if(O>P){V.fillStyle=h;r(V,P-S,G+5,O-S,G+5)}}else{V.fillStyle=Z;this.draw_read(V,Q,M,Y,D,U,I[4],I[5],G)}if(Q==="Pack"&&U>Y){V.fillStyle=this.prefs.label_color;var X=1;if(X===0&&H-V.measureText(N).width<0){V.textAlign="left";V.fillText(N,J+p-S,G+8)}else{V.textAlign="right";V.fillText(N,H-p-S,G+8)}V.fillStyle=Z}}});B.SummaryTreePainter=w;B.LinePainter=c;B.LinkedFeaturePainter=t;B.ReadPainter=v;B.VariantPainter=b};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("slotting",slotting_module);a("painters",painters_module);a("trackster",trackster_module);for(key in c.trackster){d[key]=c.trackster[key]}})(window);
\ No newline at end of file
--- a/static/scripts/trackster.js Fri Apr 08 16:43:45 2011 -0400
+++ b/static/scripts/trackster.js Fri Apr 08 17:07:08 2011 -0400
@@ -1235,7 +1235,10 @@
track.content_div.css( "height", track.height_px + "px" );
track.enabled = true;
// predraw_init may be asynchronous, wait for it and then draw
- $.when( track.predraw_init() ).done( function() { track.draw() } );
+ $.when(track.predraw_init()).done(function() {
+ track.container_div.removeClass("nodata error pending");
+ track.draw()
+ });
}
}
});
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: james_taylor: trackster: remove condition that sets mode to squish when less than four features in tile. mode selection must not change across tiles at the same level.
by Bitbucket 08 Apr '11
by Bitbucket 08 Apr '11
08 Apr '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/a77c1ea48451/
changeset: r5361:a77c1ea48451
user: james_taylor
date: 2011-04-08 22:43:45
summary: trackster: remove condition that sets mode to squish when less than four features in tile. mode selection must not change across tiles at the same level.
affected #: 1 file (72 bytes)
--- a/static/scripts/trackster.js Fri Apr 08 14:14:58 2011 -0400
+++ b/static/scripts/trackster.js Fri Apr 08 16:43:45 2011 -0400
@@ -2153,8 +2153,9 @@
//if ( (result.message && result.message.match(/^Only the first [\d]+/)) ||
// (result.data && result.data.length > 2000) ||
var data = result.data;
- if ( (data.length && data.length < 4) ||
- (this.view.high - this.view.low > MIN_SQUISH_VIEW_WIDTH) ) {
+ // if ( (data.length && data.length < 4) ||
+ // (this.view.high - this.view.low > MIN_SQUISH_VIEW_WIDTH) ) {
+ if ( this.view.high - this.view.low > MIN_SQUISH_VIEW_WIDTH ) {
mode = "Squish";
} else {
mode = "Pack";
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: james_taylor: trackster: Painter class defining common interface for all painters
by Bitbucket 08 Apr '11
by Bitbucket 08 Apr '11
08 Apr '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/6389fb7faf5b/
changeset: r5360:6389fb7faf5b
user: james_taylor
date: 2011-04-08 20:14:58
summary: trackster: Painter class defining common interface for all painters
affected #: 1 file (329 bytes)
--- a/static/scripts/trackster.js Fri Apr 08 12:06:28 2011 -0400
+++ b/static/scripts/trackster.js Fri Apr 08 14:14:58 2011 -0400
@@ -11,6 +11,7 @@
target[key] = other[key];
}
}
+ return target;
};
// Encapsulate -- anything to be availabe outside this block is added to exports
@@ -2032,7 +2033,7 @@
// Paint line onto full canvas
var ctx = canvas.getContext("2d");
var painter = new painters.LinePainter( result.data, tile_low, tile_low + tile_length,
- this.prefs.min_value, this.prefs.max_value, this.prefs.color, this.mode );
+ this.prefs, this.mode );
painter.draw( ctx, width, height );
return canvas;
@@ -2180,7 +2181,7 @@
// Extra padding at top of summary tree
canvas.height = required_height + SUMMARY_TREE_TOP_PADDING;
// Paint summary tree into canvas
- var painter = new painters.SummaryTreePainter( result.data, result.delta, result.max, tile_low, tile_high, this.prefs.show_counts );
+ var painter = new painters.SummaryTreePainter( result, tile_low, tile_high, this.prefs );
var ctx = canvas.getContext("2d");
// Deal with left_offset by translating
ctx.translate( left_offset, SUMMARY_TREE_TOP_PADDING );
@@ -2572,27 +2573,39 @@
};
/**
- * SummaryTreePainter, a histogram showing number of intervals in a region
+ * Base class for painters
+ *
+ * -- Mode and prefs are both optional
*/
-var SummaryTreePainter = function( data, delta, max, view_start, view_end, show_counts ) {
+var Painter = function( data, view_start, view_end, prefs, mode ) {
// Data and data properties
this.data = data;
- this.delta = delta;
- this.max = max;
// View
this.view_start = view_start;
this.view_end = view_end;
// Drawing prefs
- this.show_counts = show_counts;
+ this.prefs = extend( {}, this.default_prefs, prefs );
+ this.mode = mode;
}
+Painter.prototype.default_prefs = {};
+
+/**
+ * SummaryTreePainter, a histogram showing number of intervals in a region
+ */
+var SummaryTreePainter = function( data, view_start, view_end, prefs, mode ) {
+ Painter.call( this, data, view_start, view_end, prefs, mode );
+}
+
+SummaryTreePainter.prototype.default_prefis = { show_counts: false };
+
SummaryTreePainter.prototype.draw = function( ctx, width, height ) {
var view_start = this.view_start,
view_range = this.view_end - this.view_start,
w_scale = width / view_range;
- var points = this.data, delta = this.delta, max = this.max,
+ var points = this.data.data, delta = this.data.delta, max = this.data.max,
// Set base Y so that max label and data do not overlap. Base Y is where rectangle bases
// start. However, height of each rectangle is relative to required_height; hence, the
// max rectangle is required_height.
@@ -2614,7 +2627,7 @@
// Draw number count if it can fit the number with some padding, otherwise things clump up
var text_padding_req_x = 4;
- if (this.show_counts && (ctx.measureText(y).width + text_padding_req_x) < delta_x_px) {
+ if (this.prefs.show_counts && (ctx.measureText(y).width + text_padding_req_x) < delta_x_px) {
ctx.fillStyle = "#666";
ctx.textAlign = "center";
ctx.fillText(y, x + (delta_x_px/2), 10);
@@ -2624,25 +2637,17 @@
ctx.restore();
}
-var LinePainter = function( data, view_start, view_end, min_value, max_value, color, mode ) {
- // Data and data properties
- this.data = data;
- // View
- this.view_start = view_start;
- this.view_end = view_end;
- // Drawing prefs
- this.min_value = min_value;
- this.max_value = max_value;
- this.color = color;
- this.mode = mode;
- this.overflow_color = "#F66";
-}
+var LinePainter = function( data, view_start, view_end, prefs, mode ) {
+ Painter.call( this, data, view_start, view_end, prefs, mode );
+};
+
+LinePainter.prototype.default_prefs = { min_value: undefined, max_value: undefined, mode: "Histogram", color: "#000", overflow_color: "#F66" };
LinePainter.prototype.draw = function( ctx, width, height ) {
var
in_path = false,
- min_value = this.min_value,
- max_value = this.max_value,
+ min_value = this.prefs.min_value,
+ max_value = this.prefs.max_value,
vertical_range = max_value - min_value,
height_px = height,
view_start = this.view_start,
@@ -2663,7 +2668,7 @@
}
ctx.beginPath();
- ctx.fillStyle = this.color;
+ ctx.fillStyle = this.prefs.color;
var x_scaled, y, delta_x_px;
if (data.length > 1) {
delta_x_px = Math.ceil((data[1][0] - data[0][0]) * w_scale);
@@ -2724,7 +2729,7 @@
// Draw lines at bounderies if overflowing min or max
var overflow_min_start = -1,
overflow_max_start = -1;
- ctx.fillStyle = this.overflow_color;
+ ctx.fillStyle = this.prefs.overflow_color;
for (var i = 0, len = data.length; i < len; i++) {
y = data[i][1];
x_scaled = Math.round((data[i][0] - view_start) * w_scale);
@@ -2756,13 +2761,11 @@
}
var FeaturePainter = function( data, view_start, view_end, prefs, mode ) {
- this.data = data;
- this.view_start = view_start;
- this.view_end = view_end;
- this.prefs = prefs;
- this.mode = mode;
+ Painter.call( this, data, view_start, view_end, prefs, mode );
}
+FeaturePainter.prototype.default_prefs = { block_color: "#FFF", connector_color: "#FFF" };
+
extend( FeaturePainter.prototype, {
get_required_height: function( rows_required ) {
@@ -3104,7 +3107,9 @@
var ReadPainter = function( data, view_start, view_end, prefs, mode, ref_seq ) {
FeaturePainter.call( this, data, view_start, view_end, prefs, mode );
this.ref_seq = ref_seq;
-}
+};
+
+ReadPainter.prototype.default_prefs = extend( {}, FeaturePainter.prototype.default_prefs, { show_insertions: false } );
extend( ReadPainter.prototype, FeaturePainter.prototype, {
/**
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: kellyv: Removed unnecessary size check on BAM file produce in view step of sam-to-bam
by Bitbucket 08 Apr '11
by Bitbucket 08 Apr '11
08 Apr '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/61b493011087/
changeset: r5359:61b493011087
user: kellyv
date: 2011-04-08 18:06:28
summary: Removed unnecessary size check on BAM file produce in view step of sam-to-bam
affected #: 1 file (560 bytes)
--- a/tools/samtools/sam_to_bam.py Fri Apr 08 09:45:38 2011 -0400
+++ b/tools/samtools/sam_to_bam.py Fri Apr 08 12:06:28 2011 -0400
@@ -125,8 +125,6 @@
tmp_aligns_file = tempfile.NamedTemporaryFile( dir=tmp_dir )
tmp_aligns_file_name = tmp_aligns_file.name
tmp_aligns_file.close()
- # IMPORTANT NOTE: for some reason the samtools view command gzips the resulting bam file without warning,
- # and the docs do not currently state that this occurs ( very bad ).
command = 'samtools view -bt %s -o %s %s' % ( fai_index_file_path, tmp_aligns_file_name, options.input1 )
tmp = tempfile.NamedTemporaryFile( dir=tmp_dir ).name
tmp_stderr = open( tmp, 'wb' )
@@ -147,8 +145,6 @@
tmp_stderr.close()
if returncode != 0:
raise Exception, stderr
- if len( open( tmp_aligns_file_name ).read() ) == 0:
- raise Exception, 'Initial BAM file empty'
except Exception, e:
#clean up temp files
if os.path.exists( tmp_dir ):
@@ -188,11 +184,6 @@
stop_err( 'Error sorting alignments from (%s), %s' % ( tmp_aligns_file_name, str( e ) ) )
# Move tmp_aligns_file_name to our output dataset location
sorted_bam_file = '%s.bam' % tmp_sorted_aligns_file_name
- if os.path.getsize( sorted_bam_file ) == 0:
- #clean up temp files
- if os.path.exists( tmp_dir ):
- shutil.rmtree( tmp_dir )
- stop_err( 'Error creating sorted version of BAM file' )
shutil.move( sorted_bam_file, options.output1 )
#clean up temp files
if os.path.exists( tmp_dir ):
@@ -201,6 +192,6 @@
if os.path.getsize( options.output1 ) > 0:
sys.stdout.write( 'SAM file converted to BAM' )
else:
- stop_err( 'The output file is empty, there may be an error with your input file or settings.' )
+ stop_err( 'Error creating sorted version of BAM file.' )
if __name__=="__main__": __main__()
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new changesets in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/db23b5ef6969/
changeset: r5357:db23b5ef6969
user: natefoo
date: 2011-04-08 15:37:33
summary: Use JobWrapper.get_job() since it's there.
affected #: 1 file (429 bytes)
--- a/lib/galaxy/jobs/__init__.py Thu Apr 07 16:28:56 2011 -0400
+++ b/lib/galaxy/jobs/__init__.py Fri Apr 08 09:37:33 2011 -0400
@@ -306,7 +306,7 @@
"""
Restore the dictionary of parameters from the database.
"""
- job = self.sa_session.query( model.Job ).get( self.job_id )
+ job = self.get_job()
param_dict = dict( [ ( p.name, p.value ) for p in job.parameters ] )
param_dict = self.tool.params_from_strings( param_dict, self.app )
return param_dict
@@ -320,7 +320,7 @@
if not os.path.exists( self.working_directory ):
os.mkdir( self.working_directory )
# Restore parameters from the database
- job = self.sa_session.query( model.Job ).get( self.job_id )
+ job = self.get_job()
if job.user is None and job.galaxy_session is None:
raise Exception( 'Job %s has no user and no session.' % job.id )
incoming = dict( [ ( p.name, p.value ) for p in job.parameters ] )
@@ -395,7 +395,7 @@
Indicate job failure by setting state and message on all output
datasets.
"""
- job = self.sa_session.query( model.Job ).get( self.job_id )
+ job = self.get_job()
self.sa_session.refresh( job )
# if the job was deleted, don't fail it
if not job.state == model.Job.states.DELETED:
@@ -439,7 +439,7 @@
self.cleanup()
def change_state( self, state, info = False ):
- job = self.sa_session.query( model.Job ).get( self.job_id )
+ job = self.get_job()
self.sa_session.refresh( job )
for dataset_assoc in job.output_datasets + job.output_library_datasets:
dataset = dataset_assoc.dataset
@@ -456,12 +456,12 @@
self.sa_session.flush()
def get_state( self ):
- job = self.sa_session.query( model.Job ).get( self.job_id )
+ job = self.get_job()
self.sa_session.refresh( job )
return job.state
def set_runner( self, runner_url, external_id ):
- job = self.sa_session.query( model.Job ).get( self.job_id )
+ job = self.get_job()
self.sa_session.refresh( job )
job.job_runner_name = runner_url
job.job_runner_external_id = external_id
@@ -476,7 +476,7 @@
"""
# default post job setup
self.sa_session.expunge_all()
- job = self.sa_session.query( model.Job ).get( self.job_id )
+ job = self.get_job()
# if the job was deleted, don't finish it
if job.state == job.states.DELETED:
self.cleanup()
@@ -658,7 +658,7 @@
return self.session_id
def get_input_fnames( self ):
- job = self.sa_session.query( model.Job ).get( self.job_id )
+ job = self.get_job()
filenames = []
for da in job.input_datasets: #da is JobToInputDatasetAssociation object
if da.dataset:
@@ -685,7 +685,7 @@
else:
return self.false_path
- job = self.sa_session.query( model.Job ).get( self.job_id )
+ job = self.get_job()
# Job output datasets are combination of output datasets, library datasets, and jeha datasets.
jeha = self.sa_session.query( model.JobExportHistoryArchive ).filter_by( job=job ).first()
if self.app.config.outputs_to_working_directory:
@@ -757,7 +757,7 @@
def setup_external_metadata( self, exec_dir = None, tmp_dir = None, dataset_files_path = None, config_root = None, datatypes_config = None, set_extension = True, **kwds ):
# extension could still be 'auto' if this is the upload tool.
- job = self.sa_session.query( model.Job ).get( self.job_id )
+ job = self.get_job()
if set_extension:
for output_dataset_assoc in job.output_datasets:
if output_dataset_assoc.dataset.ext == 'auto':
@@ -785,7 +785,7 @@
@property
def user( self ):
- job = self.sa_session.query( model.Job ).get( self.job_id )
+ job = self.get_job()
if job.user is not None:
return job.user.email
elif job.galaxy_session is not None and job.galaxy_session.user is not None:
http://bitbucket.org/galaxy/galaxy-central/changeset/defd1d9ab96b/
changeset: r5358:defd1d9ab96b
user: natefoo
date: 2011-04-08 15:45:38
summary: Use cluster_files_directory for SGE/DRMAA instead of the hardcoded database/pbs/. Fixes issue #512 (thanks, Anonymous).
affected #: 2 files (48 bytes)
--- a/lib/galaxy/jobs/runners/drmaa.py Fri Apr 08 09:37:33 2011 -0400
+++ b/lib/galaxy/jobs/runners/drmaa.py Fri Apr 08 09:45:38 2011 -0400
@@ -145,8 +145,8 @@
job_wrapper.change_state( model.Job.states.QUEUED )
# define job attributes
- ofile = "%s/database/pbs/%s.o" % (os.getcwd(), job_wrapper.get_id_tag())
- efile = "%s/database/pbs/%s.e" % (os.getcwd(), job_wrapper.get_id_tag())
+ ofile = "%s/%s.o" % (self.app.config.cluster_files_directory, job_wrapper.job_id)
+ efile = "%s/%s.e" % (self.app.config.cluster_files_directory, job_wrapper.job_id)
jt = self.ds.createJobTemplate()
jt.remoteCommand = "%s/database/pbs/galaxy_%s.sh" % (os.getcwd(), job_wrapper.get_id_tag())
jt.outputPath = ":%s" % ofile
--- a/lib/galaxy/jobs/runners/sge.py Fri Apr 08 09:37:33 2011 -0400
+++ b/lib/galaxy/jobs/runners/sge.py Fri Apr 08 09:45:38 2011 -0400
@@ -188,8 +188,8 @@
sge_extra_params = self.determine_sge_tool_parameters ( runner_url )
# define job attributes
- ofile = "%s/database/pbs/%s.o" % (os.getcwd(), job_wrapper.job_id)
- efile = "%s/database/pbs/%s.e" % (os.getcwd(), job_wrapper.job_id)
+ ofile = "%s/%s.o" % (self.app.config.cluster_files_directory, job_wrapper.job_id)
+ efile = "%s/%s.e" % (self.app.config.cluster_files_directory, job_wrapper.job_id)
jt = self.ds.createJobTemplate()
jt.remoteCommand = "%s/database/pbs/galaxy_%s.sh" % (os.getcwd(), job_wrapper.job_id)
jt.outputPath = ":%s" % ofile
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: jgoecks: Fix hyperlinks in Cuffcompare and Cuffdiff documentation.
by Bitbucket 07 Apr '11
by Bitbucket 07 Apr '11
07 Apr '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/8a43c7a39dd1/
changeset: r5356:8a43c7a39dd1
user: jgoecks
date: 2011-04-07 22:28:56
summary: Fix hyperlinks in Cuffcompare and Cuffdiff documentation.
affected #: 2 files (36 bytes)
--- a/tools/ngs_rna/cuffcompare_wrapper.xml Thu Apr 07 08:39:07 2011 -0400
+++ b/tools/ngs_rna/cuffcompare_wrapper.xml Thu Apr 07 16:28:56 2011 -0400
@@ -130,9 +130,9 @@
**Input format**
-Cuffcompare takes Cufflinks' GTF output as input, and optionally can take a "reference" annotation (such as from Ensembl___)
+Cuffcompare takes Cufflinks' GTF output as input, and optionally can take a "reference" annotation (such as from Ensembl_)
-.. ___: http://www.todo.org
+.. _Ensembl: http://www.ensembl.org
------
--- a/tools/ngs_rna/cuffdiff_wrapper.xml Thu Apr 07 08:39:07 2011 -0400
+++ b/tools/ngs_rna/cuffdiff_wrapper.xml Thu Apr 07 16:28:56 2011 -0400
@@ -198,8 +198,6 @@
Cuffdiff takes Cufflinks or Cuffcompare GTF files as input along with two SAM files containing the fragment alignments for two or more samples.
-.. ___: http://www.todo.org
-
------
**Outputs**
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dan: Additional fix for typo propagated from manual_builds, which was updated in 5350:cd2aff5b117c.
by Bitbucket 07 Apr '11
by Bitbucket 07 Apr '11
07 Apr '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/50e249442c5a/
changeset: r5355:50e249442c5a
user: dan
date: 2011-04-07 14:39:07
summary: Additional fix for typo propagated from manual_builds, which was updated in 5350:cd2aff5b117c.
affected #: 1 file (0 bytes)
--- a/tool-data/shared/gbrowse/gbrowse_build_sites.txt Wed Apr 06 16:28:33 2011 -0400
+++ b/tool-data/shared/gbrowse/gbrowse_build_sites.txt Thu Apr 07 08:39:07 2011 -0400
@@ -10,5 +10,5 @@
modencode_fly http://modencode.oicr.on.ca/fgb2/gbrowse/fly dm2
#SGD
-sgd_yeast http://browse.yeastgenome.org/fgb2/gbrowse/scgenome Saccharomcyes_cerevisiae_S288C_SGD2010
+sgd_yeast http://browse.yeastgenome.org/fgb2/gbrowse/scgenome Saccharomyces_cerevisiae_S288C_SGD2010
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
06 Apr '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/b1657489f16c/
changeset: r5354:b1657489f16c
user: kellyv
date: 2011-04-06 22:28:33
summary: Added BWA for SOLiD to tool_conf.xml.main
affected #: 1 file (53 bytes)
--- a/tool_conf.xml.main Wed Apr 06 12:44:58 2011 -0400
+++ b/tool_conf.xml.main Wed Apr 06 16:28:33 2011 -0400
@@ -358,6 +358,7 @@
<tool file="metag_tools/megablast_xml_parser.xml" /><label text="AB-SOLiD" id="ab_solid"/><tool file="sr_mapping/bowtie_color_wrapper.xml" />
+ <tool file="sr_mapping/bwa_color_wrapper.xml" /></section><section name="NGS: SAM Tools" id="samtools"><tool file="samtools/sam_bitwise_flag_filter.xml" />
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: natefoo: Disable eagerloading of a job's datasets. This results in more queries but does away with a join that was returning a far bigger result than it should've.
by Bitbucket 06 Apr '11
by Bitbucket 06 Apr '11
06 Apr '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/d44244ed570a/
changeset: r5353:d44244ed570a
user: natefoo
date: 2011-04-06 18:44:58
summary: Disable eagerloading of a job's datasets. This results in more queries but does away with a join that was returning a far bigger result than it should've.
affected #: 1 file (36 bytes)
--- a/lib/galaxy/model/mapping.py Wed Apr 06 12:40:20 2011 -0400
+++ b/lib/galaxy/model/mapping.py Wed Apr 06 12:44:58 2011 -0400
@@ -1392,10 +1392,10 @@
history=relation( History ),
library_folder=relation( LibraryFolder ),
parameters=relation( JobParameter, lazy=False ),
- input_datasets=relation( JobToInputDatasetAssociation, lazy=False ),
- output_datasets=relation( JobToOutputDatasetAssociation, lazy=False ),
+ input_datasets=relation( JobToInputDatasetAssociation ),
+ output_datasets=relation( JobToOutputDatasetAssociation ),
post_job_actions=relation( PostJobActionAssociation, lazy=False ),
- output_library_datasets=relation( JobToOutputLibraryDatasetAssociation, lazy=False ),
+ output_library_datasets=relation( JobToOutputLibraryDatasetAssociation ),
external_output_metadata = relation( JobExternalOutputMetadata, lazy = False ) ) )
assign_mapper( context, Task, Task.table,
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new changesets in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/73d12ac49c2a/
changeset: r5351:73d12ac49c2a
user: kanwei
date: 2011-04-06 18:38:00
summary: More BLAST tests
affected #: 20 files (155.6 KB)
Diff too large to display.
http://bitbucket.org/galaxy/galaxy-central/changeset/420ddcb0be8c/
changeset: r5352:420ddcb0be8c
user: kanwei
date: 2011-04-06 18:40:20
summary: Delete unused BLAST tests
affected #: 2 files (0 bytes)
--- a/test-data/blastp_four_human_vs_rhodopsin_22c.tabular Wed Apr 06 12:38:00 2011 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-sp|P08100|OPSD_HUMAN gi|57163783|ref|NP_001009242.1| 96.55 348 12 0 1 348 1 348 0.0 660 gi|57163783|ref|NP_001009242.1| 1704 336 343 0 98.56 1 1 MNGTEGPNFYVPFSNATGVVRSPFEYPQYYLAEPWQFSMLAAYMFLLIVLGFPINFLTLYVTVQHKKLRTPLNYILLNLAVADLFMVLGGFTSTLYTSLHGYFVFGPTGCNLEGFFATLGGEIALWSLVVLAIERYVVVCKPMSNFRFGENHAIMGVAFTWVMALACAAPPLAGWSRYIPEGLQCSCGIDYYTLKPEVNNESFVIYMFVVHFTIPMIIIFFCYGQLVFTVKEAAAQQQESATTQKAEKEVTRMVIIMVIAFLICWVPYASVAFYIFTHQGSNFGPIFMTIPAFFAKSAAIYNPVIYIMMNKQFRNCMLTTICCGKNPLGDDEASATVSKTETSQVAPA MNGTEGPNFYVPFSNKTGVVRSPFEYPQYYLAEPWQFSMLAAYMFLLIVLGFPINFLTLYVTVQHKKLRTPLNYILLNLAVADLFMVFGGFTTTLYTSLHGYFVFGPTGCNLEGFFATLGGEIALWSLVVLAIERYVVVCKPMSNFRFGENHAIMGVAFTWVMALACAAPPLVGWSRYIPEGMQCSCGIDYYTLKPEVNNESFVIYMFVVHFTIPMIVIFFCYGQLVFTVKEAAAQQQESATTQKAEKEVTRMVIIMVIAFLICWVPYASVAFYIFTHQGSNFGPIFMTLPAFFAKSSSIYNPVIYIMMNKQFRNCMLTTLCCGKNPLGDDEASTTGSKTETSQVAPA
-sp|P08100|OPSD_HUMAN gi|3024260|sp|P56514.1|OPSD_BUFBU 84.80 342 51 1 1 341 1 342 8e-170 578 gi|3024260|sp|P56514.1|OPSD_BUFBU 1489 290 322 1 94.15 1 1 MNGTEGPNFYVPFSNATGVVRSPFEYPQYYLAEPWQFSMLAAYMFLLIVLGFPINFLTLYVTVQHKKLRTPLNYILLNLAVADLFMVLGGFTSTLYTSLHGYFVFGPTGCNLEGFFATLGGEIALWSLVVLAIERYVVVCKPMSNFRFGENHAIMGVAFTWVMALACAAPPLAGWSRYIPEGLQCSCGIDYYTLKPEVNNESFVIYMFVVHFTIPMIIIFFCYGQLVFTVKEAAAQQQESATTQKAEKEVTRMVIIMVIAFLICWVPYASVAFYIFTHQGSNFGPIFMTIPAFFAKSAAIYNPVIYIMMNKQFRNCMLTTICCGKNPLGDDEA-SATVSKTE MNGTEGPNFYIPMSNKTGVVRSPFEYPQYYLAEPWQYSILCAYMFLLILLGFPINFMTLYVTIQHKKLRTPLNYILLNLAFANHFMVLCGFTVTMYSSMNGYFILGATGCYVEGFFATLGGEIALWSLVVLAIERYVVVCKPMSNFRFSENHAVMGVAFTWIMALSCAVPPLLGWSRYIPEGMQCSCGVDYYTLKPEVNNESFVIYMFVVHFTIPLIIIFFCYGRLVCTVKEAAAQQQESATTQKAEKEVTRMVIIMVVFFLICWVPYASVAFFIFSNQGSEFGPIFMTVPAFFAKSSSIYNPVIYIMLNKQFRNCMITTLCCGKNPFGEDDASSAATSKTE
-sp|P08100|OPSD_HUMAN gi|283855846|gb|ADB45242.1| 94.82 328 17 0 11 338 1 328 4e-180 612 gi|283855846|gb|ADB45242.1| 1578 311 321 0 97.87 1 1 VPFSNATGVVRSPFEYPQYYLAEPWQFSMLAAYMFLLIVLGFPINFLTLYVTVQHKKLRTPLNYILLNLAVADLFMVLGGFTSTLYTSLHGYFVFGPTGCNLEGFFATLGGEIALWSLVVLAIERYVVVCKPMSNFRFGENHAIMGVAFTWVMALACAAPPLAGWSRYIPEGLQCSCGIDYYTLKPEVNNESFVIYMFVVHFTIPMIIIFFCYGQLVFTVKEAAAQQQESATTQKAEKEVTRMVIIMVIAFLICWVPYASVAFYIFTHQGSNFGPIFMTIPAFFAKSAAIYNPVIYIMMNKQFRNCMLTTICCGKNPLGDDEASATVS VPFSNKTGVVRSPFEHPQYYLAEPWQFSMLAAYMFLLIVLGFPINFLTLYVTVQHKKLRTPLNYILLNLAVADLFMVFGGFTTTLYTSLHGYFVFGPTGCNLEGFFATLGGEIALWSLVVLAIERYVVVCKPMSNFRFGENHAIMGLALTWVMALACAAPPLVGWSRYIPEGMQCSCGIDYYTLKPEVNNESFVIYMFVVHFTIPMIVIFFCYGQLVFTVKEAAAQQQESATTQKAEKEVTRMVIIMVIAFLICWLPYAGVAFYIFTHQGSNFGPIFMTLPAFFAKSSSIYNPVIYIMMNKQFRNCMLTTLCCGKNPLGDDEASTTAS
-sp|P08100|OPSD_HUMAN gi|283855823|gb|ADB45229.1| 94.82 328 17 0 11 338 1 328 1e-173 591 gi|283855823|gb|ADB45229.1| 1523 311 323 0 98.48 1 1 VPFSNATGVVRSPFEYPQYYLAEPWQFSMLAAYMFLLIVLGFPINFLTLYVTVQHKKLRTPLNYILLNLAVADLFMVLGGFTSTLYTSLHGYFVFGPTGCNLEGFFATLGGEIALWSLVVLAIERYVVVCKPMSNFRFGENHAIMGVAFTWVMALACAAPPLAGWSRYIPEGLQCSCGIDYYTLKPEVNNESFVIYMFVVHFTIPMIIIFFCYGQLVFTVKEAAAQQQESATTQKAEKEVTRMVIIMVIAFLICWVPYASVAFYIFTHQGSNFGPIFMTIPAFFAKSAAIYNPVIYIMMNKQFRNCMLTTICCGKNPLGDDEASATVS VPFSNKTGVVRSPFEYPQYYLAEPWQFSMLAAYMFLLIVLGFPINFLTLYVTVQHKKLRTPLNYILLNLAVANLFMVFGGFTTTLYTSMHGYFVFGATGCNLEGFFATLGGEIALWSLVVLAIERYVVVCKPMSNFRFGENHAIMGLAFTWVMALACAAPPLAGWSRYIPEGMQCSCGIDYYTLKPEVNNESFVIYMFVVHFTIPMIVIFFCYGQLVFTVKEAAAQQQESATTQKAEKEVTRMVIIMVVAFLICWLPYASVAFYIFTHQGSNFGPVFMTIPAFFAKSSSIYNPVIYIMMNKQFRNCMLTTLCCGKNPLGDDEASTTAS
-sp|P08100|OPSD_HUMAN gi|223523|prf||0811197A 93.10 348 23 1 1 348 1 347 0.0 634 gi|223523|prf||0811197A 1634 324 336 1 96.55 1 1 MNGTEGPNFYVPFSNATGVVRSPFEYPQYYLAEPWQFSMLAAYMFLLIVLGFPINFLTLYVTVQHKKLRTPLNYILLNLAVADLFMVLGGFTSTLYTSLHGYFVFGPTGCNLEGFFATLGGEIALWSLVVLAIERYVVVCKPMSNFRFGENHAIMGVAFTWVMALACAAPPLAGWSRYIPEGLQCSCGIDYYTLKPEVNNESFVIYMFVVHFTIPMIIIFFCYGQLVFTVKEAAAQQQESATTQKAEKEVTRMVIIMVIAFLICWVPYASVAFYIFTHQGSNFGPIFMTIPAFFAKSAAIYNPVIYIMMNKQFRNCMLTTICCGKNPLGDDEASATVSKTETSQVAPA MNGTEGPNFYVPFSNKTGVVRSPFEAPQYYLAEPWQFSMLAAYMFLLIMLGFPINFLTLYVTVQHKKLRTPLNYILLNLAVADLFMVFGGFTTTLYTSLHGYFVFGPTGCNLEGFFATLGGEIALWSLVVLAIERYVVVCKPMSNFRFGENHAIMGVAFTWVMALACAAPPLVGWSRYIPEGMQCSCGID-YTPHEETNNESFVIYMFVVHFIIPLIVIFFCYGQLVFTVKEAAAQQQESATTQKAEKEVTRMVIIMVIAFLICWLPYAGVAFYIFTHQGSDFGPIFMTIPAFFAKTSAVYNPVIYIMMNKQFRNCMVTTLCCGKNPLGDDEASTTVSKTETSQVAPA
-sp|P08100|OPSD_HUMAN gi|12583665|dbj|BAB21486.1| 82.16 342 60 1 1 341 1 342 2e-165 563 gi|12583665|dbj|BAB21486.1| 1451 281 314 1 91.81 1 1 MNGTEGPNFYVPFSNATGVVRSPFEYPQYYLAEPWQFSMLAAYMFLLIVLGFPINFLTLYVTVQHKKLRTPLNYILLNLAVADLFMVLGGFTSTLYTSLHGYFVFGPTGCNLEGFFATLGGEIALWSLVVLAIERYVVVCKPMSNFRFGENHAIMGVAFTWVMALACAAPPLAGWSRYIPEGLQCSCGIDYYTLKPEVNNESFVIYMFVVHFTIPMIIIFFCYGQLVFTVKEAAAQQQESATTQKAEKEVTRMVIIMVIAFLICWVPYASVAFYIFTHQGSNFGPIFMTIPAFFAKSAAIYNPVIYIMMNKQFRNCMLTTICCGKNPL-GDDEASATVSKTE MNGTEGPNFYIPMSNATGVVRSPFEYPQYYLAEPWAFSALSAYMFFLIIAGFPINFLTLYVTIEHKKLRTPLNYILLNLAVADLFMVFGGFTTTMYTSMHGYFVFGPTGCNIEGFFATLGGEIALWCLVVLAIERWMVVCKPVTNFRFGESHAIMGVMVTWTMALACALPPLFGWSRYIPEGLQCSCGIDYYTRAPGINNESFVIYMFTCHFSIPLAVISFCYGRLVCTVKEAAAQQQESETTQRAEREVTRMVVIMVISFLVCWVPYASVAWYIFTHQGSTFGPIFMTIPSFFAKSSALYNPMIYICMNKQFRHCMITTLCCGKNPFEEEDGASATSSKTE
--- a/test-data/blastp_human_vs_pdb_seg_no_converted_x22.tabular Wed Apr 06 12:38:00 2011 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-sp|Q9BS26|ERP44_HUMAN gi|193885198|pdb|2R2J|A 97.11 381 11 0 26 406 2 382 0.0 768 gi|193885198|pdb|2R2J|A 1982 370 372 0 97.64 1 1 PVTTEITSLDTENIDEILNNADVALVNFYADWCRFSQMLHPIFEEASDVIKEEFPNENQVVFARVDCDQHSDIAQRYRISKYPTLKLFRNGMMMKREYRGQRSVKALADYIRQQKSDPIQEIRDLAEITTLDRSKRNIIGYFEQKDSDNYRVFERVANILHDDCAFLSAFGDVSKPERYSGDNIIYKPPGHSAPDMVYLGAMTNFDVTYNWIQDKCVPLVREITFENGEELTEEGLPFLILFHMKEDTESLEIFQNEVARQLISEKGTINFLHADCDKFRHPLLHIQKTPADCPVIAIDSFRHMYVFGDFKDVLIPGKLKQFVFDLHSGKLHREFHHGPDPTDTAPGEQAQDVASSPPESSFQKLAPSEYRYTLLRDRDEL PLGSEITSLDTENIDEILNNADVALVNFYADWCRFSQXLHPIFEEASDVIKEEFPNENQVVFARVDCDQHSDIAQRYRISKYPTLKLFRNGXXXKREYRGQRSVKALADYIRQQKSDPIQEIRDLAEITTLDRSKRNIIGYFEQKDSDNYRVFERVANILHDDCAFLSAFGDVSKPERYSGDNIIYKPPGHSAPDXVYLGAXTNFDVTYNWIQDKCVPLVREITFENGEELTEEGLPFLILFHXKEDTESLEIFQNEVARQLISEKGTINFLHADCDKFRHPLLHIQKTPADCPVIAIDSFRHXYVFGDFKDVLIPGKLKQFVFDLHSGKLHREFHHGPDPTDTAPGEQAQDVASSPPESSFQKLAPSEYRYTLLRDRDEL
-sp|Q9BS26|ERP44_HUMAN gi|88192228|pdb|2B5E|A 25.17 290 193 8 25 306 10 283 4e-20 95.1 gi|88192228|pdb|2B5E|A;gi|206581884|pdb|3BOA|A 235 73 133 24 45.86 1 1 TPVTTEITSLDTENIDEILNNADVALVNFYADWCRFSQMLHPIFEEASDVIKEEFPNENQVVFARVDCDQHSDIAQRYRISKYPTLKLFRNGMMMKR-EYRGQRSVKALADYIRQQKSDPIQEIRDLAEITTLDRSKRNIIGYFEQKDSDNYRVFERVANILHDDCAFLSAFGDVSKPERYSGDNI---IYKPPGHSAPDMVYLGA---MTNFDVTYNWIQDKCVPLVREITFENGEELTEEGLPFLILFHMKEDTESLEIFQNEVARQLISEKGTINFLHADCDKF-RH APEDSAVVKLATDSFNEYIQSHDLVLAEFFAPWCGHCKNMAPEYVKAAETLVEK-----NITLAQIDCTENQDLCMEHNIPGFPSLKIFKNSDVNNSIDYEGPRTAEAIVQFMIKQSQPAVAVVADLPAYLANETFVTPVIVQSGKIDADFNATFYSMANKHFNDYDFVSA--------ENADDDFKLSIYLPSAMDEP-VVYNGKKADIADADVFEKWLQVEALPYFGEIDGSVFAQYVESGLPLGYLFY--NDEEELEEYKPLFTELAKKNRGLMNFVSIDARKFGRH
-sp|Q9NSY1|BMP2K_HUMAN gi|73536291|pdb|2BUJ|A 29.39 279 182 8 40 308 21 294 1e-22 105 gi|73536291|pdb|2BUJ|A;gi|73536292|pdb|2BUJ|B 262 82 130 15 46.59 1 1 GVRVFAVGRHQVTLEESLAEGGFSTVFLVR-THGGIRCALKRMYVNNMPDLNVCKREITIMKELSGHKNIVGYLDCAVNSISDNVWEVLILMEYCRAGQVVNQMNKKLQTG--FTEPEVLQIFCDTCEAVARLHQCKTPIIHRDLKVENILLNDGGNYVLCDFGSATNKFLNPQKDG-VNVVEEEIKKYTTLSYRAPEMINLYGGKPITTKADIWALGCLLYKLCFFTLPF------GESQVAICDGNFTIPDNSRYSRNIHCLIRFMLEPDPEHRPDI GHMVIIDNKHYLFIQK-LGEGGFSYVDLVEGLHDGHFYALKRILCHEQQDREEAQREAD-MHRLFNHPNILRLVAYCLRERGAKH-EAWLLLPFFKRGTLWNEIERLKDKGNFLTEDQILWLLLGICRGLEAIH--AKGYAHRDLKPTNILLGDEGQPVLMDLGSMNQACIHVEGSRQALTLQDWAAQRCTISYRAPELFSVQSHCVIDERTDVWSLGCVLYAMMFGEGPYDMVFQKGDSVALAVQNQLSIPQSPRHSSALWQLLNSMMTVDPHQRPHI
-sp|Q9NSY1|BMP2K_HUMAN gi|270346335|pdb|2WQM|A 27.21 272 166 12 53 311 36 288 6e-17 86.3 gi|270346335|pdb|2WQM|A;gi|270346336|pdb|2WQN|A 212 74 129 32 47.43 1 1 LEESLAEGGFSTVFLVRTH-GGIRCALKRMYVNNMPDLNV---CKREITIMKELSGHKNIVGYLDCAVNSISDNVWEVLILMEYCRAGQVVNQMN--KKLQTGFTEPEVLQIFCDTCEAVARLHQCKTPIIHRDLKVENILLNDGGNYVLCDFGSATNKFLNPQKDGVNVVEEEIKKYTTLSYRAPEMINLYGGKPITTKADIWALGCLLYKLCFFTLPFGESQV---AICD----GNFTIPDNSRYSRNIHCLIRFMLEPDPEHRPDIFQV IEKKIGRGQFSEVYRAACLLDGVPVALKKVQIFDLMDAKARADCIKEIDLLKQLN-HPNVIKYY---ASFIEDN--ELNIVLELADAGDLSRMIKHFKKQKRLIPERTVWKYFVQLCSALEHMHSRR--VMHRDIKPANVFITATGVVKLGDLG--LGRFFSSKTTAAHSL------VGTPYYMSPERIHENG---YNFKSDIWSLGCLLYEMAALQSPFYGDKMNLYSLCKKIEQCDYPPLPSDHYSEELRQLVNMCINPDPEKRPDVTYV
-sp|P06213|INSR_HUMAN gi|116667097|pdb|2DTG|E 95.91 928 7 2 28 955 1 897 0.0 1846 gi|116667097|pdb|2DTG|E 4781 890 893 31 96.23 1 1 HLYPGEVCPGMDIRNNLTRLHELENCSVIEGHLQILLMFKTRPEDFRDLSFPKLIMITDYLLLFRVYGLESLKDLFPNLTVIRGSRLFFNYALVIFEMVHLKELGLYNLMNITRGSVRIEKNNELCYLATIDWSRILDSVEDNYIVLNKDDNEECGDICPGTAKGKTNCPATVINGQFVERCWTHSHCQKVCPTICKSHGCTAEGLCCHSECLGNCSQPDDPTKCVACRNFYLDGRCVETCPPPYYHFQDWRCVNFSFCQDLHHKCKNSRRQGCHQYVIHNNKCIPECPSGYTMNSSNLLCTPCLGPCPKVCHLLEGEKTIDSVTSAQELRGCTVINGSLIINIRGGNNLAAELEANLGLIEEISGYLKIRRSYALVSLSFFRKLRLIRGETLEIGNYSFYALDNQNLRQLWDWSKHNLTITQGKLFFHYNPKLCLSEIHKMEEVSGTKGRQERNDIALKTNGDQASCENELLKFSYIRTSFDKILLRWEPYWPPDFRDLLGFMLFYKEAPYQNVTEFDGQDACGSNSWTVVDIDPPLRSNDPKSQNHPGWLMRGLKPWTQYAIFVKTLVTFSDERRTYGAKSDIIYVQTDATNPSVPLDPISVSNSSSQIILKWKPPSDPNGNITHYLVFWERQAEDSELFELDYCLKGLKLPSRTWSPPFESEDSQKHNQSEYEDSAGECCSCPKTDSQILKELEESSFRKTFEDYLHNVVFVPRKTSSGTGAEDPRPSRKRRSLGDVGNVTVAVPTVAAFPNTSSTSVPTSPEEHRPFEKVVNKESLVISGLRHFTGYRIELQACNQDTPEERCSVAAYVSARTMPEAKADDIVGPVTHEIFENNVVHLMWQEPKEPNGLIVLYEVSYRRYGDEELHLCVSRKHFALERGCRLRGLSPGNYSVRIRATSLAGNGSWTEPTYFYVTDYLDVPSNIA HLYPGEVCPGMDIRNNLTRLHELENCSVIEGHLQILLMFKTRPEDFRDLSFPKLIMITDYLLLFRVYGLESLKDLFPNLTVIRGSRLFFNYALVIFEMVHLKELGLYNLMNITRGSVRIEKNNELCYLATIDWSRILDSVEDNHIVLNKDDNEECGDICPGTAKGKTNCPATVINGQFVERCWTHSHCQKVCPTICKSHGCTAEGLCCHSECLGNCSQPDDPTKCVACRNFYLDGRCVETCPPPYYHFQDWRCVNFSFCQDLHHKCKNSRRQGCHQYVIHNNKCIPECPSGYTMNSSNLLCTPCLGPCPKVCHLLEGEKTIDSVTSAQELRGCTVINGSLIINIRGGNNLAAELEANLGLIEEISGYLKIRRSYALVSLSFFRKLRLIRGETLEIGNYSFYALDNQNLRQLWDWSKHNLTITQGKLFFHYNPKLCLSEIHKMEEVSGTKGRQERNDIALKTNGDQASCENELLKFSYIRTSFDKILLRWEPYWPPDFRDLLGFMLFYKEAPYQNVTEFDGQDACGSNSWTVVDIDPPLRSNDPKSQNHPGWLMRGLKPWTQYAIFVKTLVTFSDERRTYGAKSDIIYVQTDATNPSVPLDPISVSNSSSQIILKWKPPSDPNGNITHYLVFWERQAEDSELFELDYCLKGLKLPSRTWSPPFESEDSQKHNQSEYEDSAGECCSCPKTDSQILKELEESSFRKTFEDYLHNVVFV------------PRPSRKRRSLGDVGNA-------------------GNNEEHRPFEKVVNKESLVISGLRHFTGYRIELQACNQDTPEERCSVAAYVSARTMPEAKADDIVGPVTHEIFENNVVHLMWQEPKEPNGLIVLYEVSYRRYGDEELHLCDTRKHFALERGCRLRGLSPGNYSVRIRATSLAGNGSWTEPTYFYVTDYLDVPSNIA
-sp|P06213|INSR_HUMAN gi|114794482|pdb|2HR7|A 99.59 485 2 0 28 512 1 485 0.0 1016 gi|114794482|pdb|2HR7|A;gi|114794483|pdb|2HR7|B 2628 483 485 0 100.00 1 1 HLYPGEVCPGMDIRNNLTRLHELENCSVIEGHLQILLMFKTRPEDFRDLSFPKLIMITDYLLLFRVYGLESLKDLFPNLTVIRGSRLFFNYALVIFEMVHLKELGLYNLMNITRGSVRIEKNNELCYLATIDWSRILDSVEDNYIVLNKDDNEECGDICPGTAKGKTNCPATVINGQFVERCWTHSHCQKVCPTICKSHGCTAEGLCCHSECLGNCSQPDDPTKCVACRNFYLDGRCVETCPPPYYHFQDWRCVNFSFCQDLHHKCKNSRRQGCHQYVIHNNKCIPECPSGYTMNSSNLLCTPCLGPCPKVCHLLEGEKTIDSVTSAQELRGCTVINGSLIINIRGGNNLAAELEANLGLIEEISGYLKIRRSYALVSLSFFRKLRLIRGETLEIGNYSFYALDNQNLRQLWDWSKHNLTITQGKLFFHYNPKLCLSEIHKMEEVSGTKGRQERNDIALKTNGDQASCENELLKFSYIRTSFDKI HLYPGEVCPGMDIRNNLTRLHELENCSVIEGHLQILLMFKTRPEDFRDLSFPKLIMITDYLLLFRVYGLESLKDLFPNLTVIRGSRLFFNYALVIFEMVHLKELGLYNLMNITRGSVRIEKNNELCYLATIDWSRILDSVEDNHIVLNKDDNEECGDICPGTAKGKTNCPATVINGQFVERCWTHSHCQKVCPTICKSHGCTAEGLCCHSECLGNCSQPDDPTKCVACRNFYLDGRCVETCPPPYYHFQDWRCVNFSFCQDLHHKCKNSRRQGCHQYVIHNNKCIPECPSGYTMNSSNLLCTPCLGPCPKVCHLLEGEKTIDSVTSAQELRGCTVINGSLIINIRGGNNLAAELEANLGLIEEISGYLKIRRSYALVSLSFFRKLRLIRGETLEIGNYSFYALDNQNLRQLWDWSKHNLTITQGKLFFHYNPKLCLSEIHKMEEVSGTKGRQERNDIALKTNGDKASCENELLKFSYIRTSFDKI
-sp|P08100|OPSD_HUMAN gi|16975387|pdb|1JFP|A 93.39 348 23 0 1 348 1 348 0.0 681 gi|16975387|pdb|1JFP|A;gi|22219255|pdb|1LN6|A;gi|157878065|pdb|1GZM|A;gi|157878066|pdb|1GZM|B;gi|157878298|pdb|1HZX|A;gi|157878299|pdb|1HZX|B;gi|157878979|pdb|1L9H|A;gi|157878980|pdb|1L9H|B;gi|157880263|pdb|1U19|A;gi|157880264|pdb|1U19|B;gi|157883606|pdb|2G87|A;gi|157883607|pdb|2G87|B;gi|157883830|pdb|2HPY|A;gi|157883831|pdb|2HPY|B;gi|157883860|pdb|2I35|A;gi|157883861|pdb|2I36|A;gi|157883862|pdb|2I36|B;gi|157883863|pdb|2I36|C;gi|157883864|pdb|2I37|A;gi|157883865|pdb|2I37|B;gi|157883866|pdb|2I37|C;gi|159795066|pdb|2PED|A;gi|159795067|pdb|2PED|B;gi|192988480|pdb|3CAP|A;gi|192988481|pdb|3CAP|B;gi|195927457|pdb|3C9L|A;gi|197107530|pdb|1F88|A;gi|197107531|pdb|1F88|B;gi|206582030|pdb|3DQB|A 1756 325 337 0 96.84 1 1 MNGTEGPNFYVPFSNATGVVRSPFEYPQYYLAEPWQFSMLAAYMFLLIVLGFPINFLTLYVTVQHKKLRTPLNYILLNLAVADLFMVLGGFTSTLYTSLHGYFVFGPTGCNLEGFFATLGGEIALWSLVVLAIERYVVVCKPMSNFRFGENHAIMGVAFTWVMALACAAPPLAGWSRYIPEGLQCSCGIDYYTLKPEVNNESFVIYMFVVHFTIPMIIIFFCYGQLVFTVKEAAAQQQESATTQKAEKEVTRMVIIMVIAFLICWVPYASVAFYIFTHQGSNFGPIFMTIPAFFAKSAAIYNPVIYIMMNKQFRNCMLTTICCGKNPLGDDEASATVSKTETSQVAPA MNGTEGPNFYVPFSNKTGVVRSPFEAPQYYLAEPWQFSMLAAYMFLLIMLGFPINFLTLYVTVQHKKLRTPLNYILLNLAVADLFMVFGGFTTTLYTSLHGYFVFGPTGCNLEGFFATLGGEIALWSLVVLAIERYVVVCKPMSNFRFGENHAIMGVAFTWVMALACAAPPLVGWSRYIPEGMQCSCGIDYYTPHEETNNESFVIYMFVVHFIIPLIVIFFCYGQLVFTVKEAAAQQQESATTQKAEKEVTRMVIIMVIAFLICWLPYAGVAFYIFTHQGSDFGPIFMTIPAFFAKTSAVYNPVIYIMMNKQFRNCMVTTLCCGKNPLGDDEASTTVSKTETSQVAPA
-sp|P08100|OPSD_HUMAN gi|195927458|pdb|3C9M|A 93.10 348 24 0 1 348 1 348 0.0 674 gi|195927458|pdb|3C9M|A 1738 324 335 0 96.26 1 1 MNGTEGPNFYVPFSNATGVVRSPFEYPQYYLAEPWQFSMLAAYMFLLIVLGFPINFLTLYVTVQHKKLRTPLNYILLNLAVADLFMVLGGFTSTLYTSLHGYFVFGPTGCNLEGFFATLGGEIALWSLVVLAIERYVVVCKPMSNFRFGENHAIMGVAFTWVMALACAAPPLAGWSRYIPEGLQCSCGIDYYTLKPEVNNESFVIYMFVVHFTIPMIIIFFCYGQLVFTVKEAAAQQQESATTQKAEKEVTRMVIIMVIAFLICWVPYASVAFYIFTHQGSNFGPIFMTIPAFFAKSAAIYNPVIYIMMNKQFRNCMLTTICCGKNPLGDDEASATVSKTETSQVAPA MCGTEGPNFYVPFSNKTGVVRSPFEAPQYYLAEPWQFSMLAAYMFLLIMLGFPINFLTLYVTVQHKKLRTPLNYILLNLAVADLFMVFGGFTTTLYTSLHGYFVFGPTGCNLEGFFATLGGEIALWSLVVLAIERYVVVCKPMSNFRFGENHAIMGVAFTWVMALACAAPPLVGWSRYIPEGMQCSCGIDYYTPHEETNNESFVIYMFVVHFIIPLIVIFFCYGQLVFTVKEAAAQQQESATTQKAEKEVTRMVIIMVIAFLICWLPYAGVAFYIFTHQGSCFGPIFMTIPAFFAKTSAVYNPVIYIMMNKQFRNCMVTTLCCGKNPLGDDEASTTVSKTETSQVAPA
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
06 Apr '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/cd2aff5b117c/
changeset: r5350:cd2aff5b117c
user: kellyv
date: 2011-04-06 16:16:30
summary: Corrected typo in manual build name
affected #: 1 file (0 bytes)
--- a/tool-data/shared/ucsc/manual_builds.txt Tue Apr 05 17:59:43 2011 -0400
+++ b/tool-data/shared/ucsc/manual_builds.txt Wed Apr 06 10:16:30 2011 -0400
@@ -692,7 +692,7 @@
eschColi_TW14359 Escherichia coli TW14359 chr=5528136,plasmid_pO157=94601
pUC18 pUC18 Plasmid plasmid=2686
nomLeu1 Gibbon chr1=245538060,chr10=135320619,chr10_random=51011,chr11=134551115,chr12=132397767,chr12_random=336702,chr13=114140689,chr14=106383727,chr15=100373758,chr15_random=814500,chr16=88836341,chr16_random=121782,chr17=78641643,chr17_random=2617017,chr18=76124575,chr19=63791437,chr19_random=297341,chr1_random=3502083,chr2=242756806,chr20=62432189,chr21=47019833,chr22=49520868,chr22_random=31530,chr2_random=335351,chr3=199337376,chr3_random=950829,chr4=191633586,chr4_random=923474,chr5=180612635,chr5_random=150620,chr6=170839170,chr6_random=1837487,chr7=158619002,chr7_random=805938,chr8=146283503,chr8_random=649034,chr9=138402467,chr9_random=1315712,chrUn=217400297,chrX=154793867,chrX_random=1690203,chrY=57470892
-Saccharomcyes_cerevisiae_S288C_SGD2010 S. cerevisae str. S288C chr1=230218,chr2=813184,chr3=316620,chr4=1531933,chr5=576874,chr6=270161,chr7=1090940,chr8=562643,chr9=439888,chr10=745751,chr11=666816,chr12=1078177,chr13=924431,chr14=784333,chr15=1091291,chr16=948066,chrM=85779
+Saccharomyces_cerevisiae_S288C_SGD2010 S. cerevisae str. S288C chr1=230218,chr2=813184,chr3=316620,chr4=1531933,chr5=576874,chr6=270161,chr7=1090940,chr8=562643,chr9=439888,chr10=745751,chr11=666816,chr12=1078177,chr13=924431,chr14=784333,chr15=1091291,chr16=948066,chrM=85779
Spur_v2.6 Purple Sea Urchin (Strongylocentrotus purpuratus) v2.6
Ptrichocarpa_156 Poplar (Populus trichocarpa)
Hydra_JCVI Hydra magnipapillata str. 105
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: jgoecks: Trackster: ensure that reads are drawn in squish and pack modes even when view area is large by setting a minimum width of 1px.
by Bitbucket 05 Apr '11
by Bitbucket 05 Apr '11
05 Apr '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/dd604de40ac4/
changeset: r5349:dd604de40ac4
user: jgoecks
date: 2011-04-05 23:59:43
summary: Trackster: ensure that reads are drawn in squish and pack modes even when view area is large by setting a minimum width of 1px.
affected #: 1 file (317 bytes)
--- a/static/scripts/trackster.js Tue Apr 05 14:16:26 2011 -0400
+++ b/static/scripts/trackster.js Tue Apr 05 17:59:43 2011 -0400
@@ -1126,10 +1126,9 @@
/**
* Tiles for TiledTracks.
*/
-var Tile = function(track, canvas, histo_max) {
+var Tile = function(track, canvas) {
this.track = track;
this.canvas = canvas;
- this.histo_max = histo_max;
};
/**
@@ -2192,7 +2191,7 @@
// Start dealing with row-by-row tracks
- // If working with a mode where slotting is neccesary, update the incremental slotting
+ // If working with a mode where slotting is necessary, update the incremental slotting
var slots, slots_required = 1;
if ( mode === "no_detail" || mode === "Squish" || mode === "Pack" ) {
slots_required = this.incremental_slots(w_scale, result.data, mode);
@@ -3164,6 +3163,14 @@
var seq_start = feature_start + base_offset,
s_start = Math.floor( Math.max(0, (seq_start - tile_low) * w_scale) ),
s_end = Math.floor( Math.max(0, (seq_start + cig_len - tile_low) * w_scale) );
+
+ // Make sure that read is drawn even if it too small to be rendered officially; in this case,
+ // read is drawn at 1px.
+ // TODO: need to ensure that s_start, s_end are calcuated the same for both slotting
+ // and drawing.
+ if (s_start === s_end) {
+ s_end += 1;
+ }
switch (cig_op) {
case "H": // Hard clipping.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
3 new changesets in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/63e0cc9ca457/
changeset: r5346:63e0cc9ca457
user: jgoecks
date: 2011-04-05 20:12:39
summary: Trackster: mode is not reduced if in auto mode.
affected #: 1 file (22 bytes)
--- a/static/scripts/trackster.js Tue Apr 05 12:08:42 2011 -0400
+++ b/static/scripts/trackster.js Tue Apr 05 14:12:39 2011 -0400
@@ -2092,9 +2092,9 @@
update_auto_mode: function( mode ) {
if ( this.mode == "Auto" ) {
if ( mode == "no_detail" ) {
- mode = "reduced to feature spans";
+ mode = "feature spans";
} else if ( mode == "summary_tree" ) {
- mode = "reduced to coverage histogram";
+ mode = "coverage histogram";
}
this.mode_div.text( "Auto (" + mode + ")" );
}
http://bitbucket.org/galaxy/galaxy-central/changeset/6131f91bad52/
changeset: r5347:6131f91bad52
user: jgoecks
date: 2011-04-05 20:14:32
summary: Merge.
affected #: 3 files (740 bytes)
--- a/tool_conf.xml.main Tue Apr 05 14:12:39 2011 -0400
+++ b/tool_conf.xml.main Tue Apr 05 14:14:32 2011 -0400
@@ -169,12 +169,6 @@
<!-- <tool file="hyphy/hyphy_dnds_wrapper.xml" /> --><tool file="evolution/mutate_snp_codon.xml" /></section>
- <section name="Motif Tools" id="motifs">
- <tool file="rgenetics/rgWebLogo3.xml" />
- </section>
- <section name="Multiple Alignments" id="clustal">
- <tool file="rgenetics/rgClustalw.xml" />
- </section><section name="Metagenomic analyses" id="tax_manipulation"><tool file="taxonomy/gi2taxonomy.xml" /><tool file="taxonomy/t2t_report.xml" />
--- a/tools/rgenetics/rgCaCo.py Tue Apr 05 14:12:39 2011 -0400
+++ b/tools/rgenetics/rgCaCo.py Tue Apr 05 14:14:32 2011 -0400
@@ -53,28 +53,26 @@
resfl = resfl[1:]
headl = [x.strip().upper() for x in headl]
headIndex = dict(zip(headl,range(0,len(headl))))
- chrpos = headIndex.get('CHR',None)
- rspos = headIndex.get('RS',None)
- offspos = headIndex.get('OFFSET',None)
- ppos = headIndex.get('LOG10ARMITAGEP',None)
- wewant = [chrpos,rspos,offspos,ppos]
+ whatwewant = ['CHR','RS','OFFSET','LOG10ARMITAGEP']
+ wewant = [headIndex.get(x,None) for x in whatwewant]
if None in wewant: # missing something
- logf.write('### Error missing a required header in makeGFF - headIndex=%s\n' % headIndex)
+ logf.write('### Error missing a required header from %s in makeGFF - headIndex=%s\n' % (whatwewant,headIndex))
return
- resfl = [x for x in resfl if x[ppos] > '']
+ ppos = wewant[3] # last in list
+ resfl = [x for x in resfl if x[ppos] > '' and x[ppos] <> 'NA']
resfl = [(float(x[ppos]),x) for x in resfl] # decorate
resfl.sort()
resfl.reverse() # using -log10 so larger is better
- resfl = resfl[:topn] # truncate
pvals = [x[0] for x in resfl] # need to scale
resfl = [x[1] for x in resfl] # drop decoration
+ resfl = resfl[:topn] # truncate
maxp = max(pvals) # need to scale
minp = min(pvals)
prange = abs(maxp-minp) + 0.5 # fudge
scalefact = 1000.0/prange
logf.write('###maxp=%f,minp=%f,prange=%f,scalefact=%f\n' % (maxp,minp,prange,scalefact))
for i,row in enumerate(resfl):
- row[ppos] = '%d' % (int(scalefact*pvals[i]))
+ row[ppos] = '%d' % (int(scalefact*pvals[i]))
resfl[i] = row # replace
outf = file(outfname,'w')
outf.write(header)
--- a/tools/rgenetics/rgWebLogo3.xml Tue Apr 05 14:12:39 2011 -0400
+++ b/tools/rgenetics/rgWebLogo3.xml Tue Apr 05 14:14:32 2011 -0400
@@ -5,7 +5,7 @@
#if $range.mode == 'part'
-l "$range.seqstart" -u "$range.seqend"
#end if
- </command>
+ </command><inputs><page><param format="fasta" name="input" type="data" label="Fasta File" />
@@ -71,7 +71,7 @@
<param name = "mode" value="complete" /><param name = "size" value="medium" /><param name = "colours" value="auto" />
- <output name="output" file="rgWebLogo3_test.jpg" ftype="jpg" />
+ <output name="output" file="rgWebLogo3_test.jpg" ftype="jpg" compare="sim_size" delta="10000" /></test></tests>
@@ -90,6 +90,15 @@
----
+**Warning about input Fasta format files**
+
+The Weblogo3 program used by this tool will fail if your fasta sequences are not all EXACTLY the same length.
+
+Fasta alignments from the companion ClustalW Galaxy tool will work but many other fasta files may cause this tool to fail - please do not file
+a Galaxy bug report - this is a feature of the tool and a problem with your source data - not a tool error - please make certain all your fasta
+sequences are the same length!
+
+----
**Attribution**
http://bitbucket.org/galaxy/galaxy-central/changeset/79021bb57c1f/
changeset: r5348:79021bb57c1f
user: jgoecks
date: 2011-04-05 20:16:26
summary: Merge.
affected #: 1 file (207 bytes)
--- a/tool_conf.xml.main Tue Apr 05 14:14:32 2011 -0400
+++ b/tool_conf.xml.main Tue Apr 05 14:16:26 2011 -0400
@@ -169,6 +169,12 @@
<!-- <tool file="hyphy/hyphy_dnds_wrapper.xml" /> --><tool file="evolution/mutate_snp_codon.xml" /></section>
+ <section name="Motif Tools" id="motifs">
+ <tool file="rgenetics/rgWebLogo3.xml" />
+ </section>
+ <section name="Multiple Alignments" id="clustal">
+ <tool file="rgenetics/rgClustalw.xml" />
+ </section><section name="Metagenomic analyses" id="tax_manipulation"><tool file="taxonomy/gi2taxonomy.xml" /><tool file="taxonomy/t2t_report.xml" />
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: fubar: reverted unintended changes to tool_conf.xml.main
by Bitbucket 05 Apr '11
by Bitbucket 05 Apr '11
05 Apr '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/4257de2ebdd0/
changeset: r5345:4257de2ebdd0
user: fubar
date: 2011-04-05 20:14:08
summary: reverted unintended changes to tool_conf.xml.main
affected #: 1 file (207 bytes)
--- a/tool_conf.xml.main Tue Apr 05 14:07:10 2011 -0400
+++ b/tool_conf.xml.main Tue Apr 05 14:14:08 2011 -0400
@@ -169,6 +169,12 @@
<!-- <tool file="hyphy/hyphy_dnds_wrapper.xml" /> --><tool file="evolution/mutate_snp_codon.xml" /></section>
+ <section name="Motif Tools" id="motifs">
+ <tool file="rgenetics/rgWebLogo3.xml" />
+ </section>
+ <section name="Multiple Alignments" id="clustal">
+ <tool file="rgenetics/rgClustalw.xml" />
+ </section><section name="Metagenomic analyses" id="tax_manipulation"><tool file="taxonomy/gi2taxonomy.xml" /><tool file="taxonomy/t2t_report.xml" />
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
3 new changesets in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/232df3fff6b3/
changeset: r5342:232df3fff6b3
user: fubar
date: 2011-03-28 01:50:50
summary: minor tweaks to rgCaCo.py
affected #: 1 file (17 bytes)
--- a/tools/rgenetics/rgCaCo.py Fri Mar 25 13:26:40 2011 -0400
+++ b/tools/rgenetics/rgCaCo.py Sun Mar 27 19:50:50 2011 -0400
@@ -53,28 +53,26 @@
resfl = resfl[1:]
headl = [x.strip().upper() for x in headl]
headIndex = dict(zip(headl,range(0,len(headl))))
- chrpos = headIndex.get('CHR',None)
- rspos = headIndex.get('RS',None)
- offspos = headIndex.get('OFFSET',None)
- ppos = headIndex.get('LOG10ARMITAGEP',None)
- wewant = [chrpos,rspos,offspos,ppos]
+ whatwewant = ['CHR','RS','OFFSET','LOG10ARMITAGEP']
+ wewant = [headIndex.get(x,None) for x in whatwewant]
if None in wewant: # missing something
- logf.write('### Error missing a required header in makeGFF - headIndex=%s\n' % headIndex)
+ logf.write('### Error missing a required header from %s in makeGFF - headIndex=%s\n' % (whatwewant,headIndex))
return
- resfl = [x for x in resfl if x[ppos] > '']
+ ppos = wewant[3] # last in list
+ resfl = [x for x in resfl if x[ppos] > '' and x[ppos] <> 'NA']
resfl = [(float(x[ppos]),x) for x in resfl] # decorate
resfl.sort()
resfl.reverse() # using -log10 so larger is better
- resfl = resfl[:topn] # truncate
pvals = [x[0] for x in resfl] # need to scale
resfl = [x[1] for x in resfl] # drop decoration
+ resfl = resfl[:topn] # truncate
maxp = max(pvals) # need to scale
minp = min(pvals)
prange = abs(maxp-minp) + 0.5 # fudge
scalefact = 1000.0/prange
logf.write('###maxp=%f,minp=%f,prange=%f,scalefact=%f\n' % (maxp,minp,prange,scalefact))
for i,row in enumerate(resfl):
- row[ppos] = '%d' % (int(scalefact*pvals[i]))
+ row[ppos] = '%d' % (int(scalefact*pvals[i]))
resfl[i] = row # replace
outf = file(outfname,'w')
outf.write(header)
http://bitbucket.org/galaxy/galaxy-central/changeset/be1accb7a6d0/
changeset: r5343:be1accb7a6d0
user: fubar
date: 2011-04-05 19:57:14
summary: merge
affected #: 33 files (24.1 KB)
--- a/cron/add_manual_builds.py Sun Mar 27 19:50:50 2011 -0400
+++ b/cron/add_manual_builds.py Tue Apr 05 13:57:14 2011 -0400
@@ -21,12 +21,12 @@
build_file_out = open(build_file,'a')
for line in open(input_file):
try:
- fields = line.split("\t")
+ fields = line.replace("\n","").replace("\r","").split("\t")
build = fields.pop(0)
if build in existing_builds: continue # if build exists, leave alone
name = fields.pop(0)
try: # get chrom lens if included in file, otherwise still add build
- chrs = fields.pop(0).replace("\n","").replace("\r","").split(",")
+ chrs = fields.pop(0).split(",")
except:
chrs = []
print>>build_file_out, build+"\t"+name+" ("+build+")"
--- a/datatypes_conf.xml.sample Sun Mar 27 19:50:50 2011 -0400
+++ b/datatypes_conf.xml.sample Tue Apr 05 13:57:14 2011 -0400
@@ -128,9 +128,9 @@
<converter file="wiggle_to_simple_converter.xml" target_datatype="interval"/><!-- <display file="gbrowse/gbrowse_wig.xml" /> --></datatype>
- <datatype extension="array_tree" type="galaxy.datatypes.data:Data" /><datatype extension="summary_tree" type="galaxy.datatypes.data:Data" /><datatype extension="interval_index" type="galaxy.datatypes.data:Data" />
+ <datatype extension="tabix" type="galaxy.datatypes.data:Data" /><!-- Start EMBOSS tools --><datatype extension="acedb" type="galaxy.datatypes.data:Text"/><datatype extension="asn1" type="galaxy.datatypes.data:Text"/>
--- a/lib/galaxy/config.py Sun Mar 27 19:50:50 2011 -0400
+++ b/lib/galaxy/config.py Tue Apr 05 13:57:14 2011 -0400
@@ -2,7 +2,7 @@
Universe configuration builder.
"""
-import sys, os
+import sys, os, tempfile
import logging, logging.config
import ConfigParser
from galaxy.util import string_as_bool
@@ -39,6 +39,7 @@
# Where dataset files are stored
self.file_path = resolve_path( kwargs.get( "file_path", "database/files" ), self.root )
self.new_file_path = resolve_path( kwargs.get( "new_file_path", "database/tmp" ), self.root )
+ tempfile.tempdir = self.new_file_path
self.openid_consumer_cache_path = resolve_path( kwargs.get( "openid_consumer_cache_path", "database/openid_consumer_cache" ), self.root )
self.cookie_path = kwargs.get( "cookie_path", "/" )
# web API
--- a/lib/galaxy/datatypes/converters/gff_to_interval_index_converter.py Sun Mar 27 19:50:50 2011 -0400
+++ b/lib/galaxy/datatypes/converters/gff_to_interval_index_converter.py Tue Apr 05 13:57:14 2011 -0400
@@ -32,7 +32,7 @@
convert_gff_coords_to_bed( feature )
index.add( feature.chrom, feature.start, feature.end, offset )
- offset += feature.raw_size()
+ offset += feature.raw_size
index.write( open(out_fname, "w") )
--- a/lib/galaxy/datatypes/data.py Sun Mar 27 19:50:50 2011 -0400
+++ b/lib/galaxy/datatypes/data.py Tue Apr 05 13:57:14 2011 -0400
@@ -354,6 +354,7 @@
class Text( Data ):
file_ext = 'txt'
+ line_class = 'line'
"""Add metadata elements"""
MetadataElement( name="data_lines", default=0, desc="Number of data lines", readonly=True, optional=True, visible=False, no_value=0 )
@@ -417,26 +418,30 @@
data_lines += 1
return data_lines
def set_peek( self, dataset, line_count=None, is_multi_byte=False ):
+ """
+ Set the peek. This method is used by various subclasses of Text.
+ """
if not dataset.dataset.purged:
# The file must exist on disk for the get_file_peek() method
dataset.peek = get_file_peek( dataset.file_name, is_multi_byte=is_multi_byte )
if line_count is None:
# See if line_count is stored in the metadata
- if dataset.metadata.data_lines is not None:
- dataset.blurb = "%s %s" % ( util.commaify( str(dataset.metadata.data_lines) ), inflector.cond_plural(dataset.metadata.data_lines, "line") )
+ if dataset.metadata.data_lines:
+ dataset.blurb = "%s %s" % ( util.commaify( str(dataset.metadata.data_lines) ), inflector.cond_plural(dataset.metadata.data_lines, self.line_class) )
else:
# Number of lines is not known ( this should not happen ), and auto-detect is
# needed to set metadata
# This can happen when the file is larger than max_optional_metadata_filesize.
if int(dataset.get_size()) <= 1048576:
#Small dataset, recount all lines and reset peek afterward.
- dataset.metadata.data_lines = self.count_data_lines(dataset)
- self.set_peek(dataset)
+ lc = self.count_data_lines(dataset)
+ dataset.metadata.data_lines = lc
+ dataset.blurb = "%s %s" % ( util.commaify( str(lc) ), inflector.cond_plural(lc, self.line_class) )
else:
est_lines = self.estimate_file_lines(dataset)
- dataset.blurb = "~%s %s" % ( util.commaify(util.roundify(str(est_lines))), inflector.cond_plural(est_lines, "line") )
+ dataset.blurb = "~%s %s" % ( util.commaify(util.roundify(str(est_lines))), inflector.cond_plural(est_lines, self.line_class) )
else:
- dataset.blurb = "%s %s" % util.commaify( str(line_count) ), inflector.cond_plural(line_count, "line")
+ dataset.blurb = "%s %s" % ( util.commaify( str(line_count) ), inflector.cond_plural(line_count, self.line_class) )
else:
dataset.peek = 'file does not exist'
dataset.blurb = 'file purged from disk'
--- a/lib/galaxy/datatypes/interval.py Sun Mar 27 19:50:50 2011 -0400
+++ b/lib/galaxy/datatypes/interval.py Tue Apr 05 13:57:14 2011 -0400
@@ -45,6 +45,7 @@
class Interval( Tabular ):
"""Tab delimited data containing interval information"""
file_ext = "interval"
+ line_class = "region"
"""Add metadata elements"""
MetadataElement( name="chromCol", default=1, desc="Chrom column", param=metadata.ColumnParameter )
@@ -60,23 +61,6 @@
self.add_display_app ( 'ucsc', 'display at UCSC', 'as_ucsc_display_file', 'ucsc_links' )
def init_meta( self, dataset, copy_from=None ):
Tabular.init_meta( self, dataset, copy_from=copy_from )
- def set_peek( self, dataset, line_count=None, is_multi_byte=False ):
- """Set the peek and blurb text"""
- if not dataset.dataset.purged:
- dataset.peek = data.get_file_peek( dataset.file_name, is_multi_byte=is_multi_byte )
- if line_count is None:
- # See if line_count is stored in the metadata
- if dataset.metadata.data_lines is not None:
- dataset.blurb = "%s regions" % util.commaify( str( dataset.metadata.data_lines ) )
- else:
- # Number of lines is not known ( this should not happen ), and auto-detect is
- # needed to set metadata
- dataset.blurb = "~%s regions" % util.commaify(util.roundify(str(self.estimate_file_lines(dataset))))
- else:
- dataset.blurb = "%s regions" % util.commaify( str( line_count ) )
- else:
- dataset.peek = 'file does not exist'
- dataset.blurb = 'file purged from disk'
def set_meta( self, dataset, overwrite = True, first_line_is_header = False, **kwd ):
"""Tries to guess from the line the location number of the column for the chromosome, region start-end and strand"""
Tabular.set_meta( self, dataset, overwrite = overwrite, skip = 0 )
--- a/lib/galaxy/datatypes/tabular.py Sun Mar 27 19:50:50 2011 -0400
+++ b/lib/galaxy/datatypes/tabular.py Tue Apr 05 13:57:14 2011 -0400
@@ -223,8 +223,8 @@
out.append( '<tr><td>' )
out.append( '%s</td></tr>' % escape( comments.pop(0) ) )
return "".join( out )
- def set_peek( self, dataset, line_count=None, is_multi_byte=False ):
- data.Text.set_peek( self, dataset, line_count=line_count, is_multi_byte=is_multi_byte )
+ def set_peek( self, dataset, line_count=None, is_multi_byte=False):
+ super(Tabular, self).set_peek( dataset, line_count=line_count, is_multi_byte=is_multi_byte)
if dataset.metadata.comment_lines:
dataset.blurb = "%s, %s comments" % ( dataset.blurb, util.commaify( str( dataset.metadata.comment_lines ) ) )
def display_peek( self, dataset ):
@@ -383,6 +383,7 @@
class Pileup( Tabular ):
"""Tab delimited data in pileup (6- or 10-column) format"""
file_ext = "pileup"
+ line_class = "genomic coordinate"
"""Add metadata elements"""
MetadataElement( name="chromCol", default=1, desc="Chrom column", param=metadata.ColumnParameter )
@@ -392,24 +393,6 @@
def init_meta( self, dataset, copy_from=None ):
Tabular.init_meta( self, dataset, copy_from=copy_from )
- def set_peek( self, dataset, line_count=None, is_multi_byte=False ):
- """Set the peek and blurb text"""
- if not dataset.dataset.purged:
- dataset.peek = data.get_file_peek( dataset.file_name, is_multi_byte=is_multi_byte )
- if line_count is None:
- # See if line_count is stored in the metadata
- if dataset.metadata.data_lines is not None:
- dataset.blurb = "%s genomic coordinates" % util.commaify( str( dataset.metadata.data_lines ) )
- else:
- # Number of lines is not known ( this should not happen ), and auto-detect is
- # needed to set metadata
- dataset.blurb = "? genomic coordinates"
- else:
- dataset.blurb = "%s genomic coordinates" % util.commaify( str( line_count ) )
- else:
- dataset.peek = 'file does not exist'
- dataset.blurb = 'file purged from disk'
-
def make_html_table( self, dataset, skipchars=[] ):
"""Create HTML table, used for displaying peek"""
out = ['<table cellspacing="0" cellpadding="3">']
--- a/lib/galaxy/datatypes/util/gff_util.py Sun Mar 27 19:50:50 2011 -0400
+++ b/lib/galaxy/datatypes/util/gff_util.py Tue Apr 05 13:57:14 2011 -0400
@@ -11,7 +11,7 @@
only attribute is 'group.'
"""
def __init__( self, reader, fields, chrom_col, feature_col, start_col, end_col, \
- strand_col, score_col, default_strand, fix_strand=False, raw_line='' ):
+ strand_col, score_col, default_strand, fix_strand=False ):
# HACK: GFF format allows '.' for strand but GenomicInterval does not. To get around this,
# temporarily set strand and then unset after initing GenomicInterval.
unknown_strand = False
@@ -34,8 +34,7 @@
raise MissingFieldError( "No field for score_col (%d)" % score_col )
self.score = self.fields[ self.score_col ]
- # Attributes specific to GFF.
- self.raw_line = raw_line
+ # GFF attributes.
self.attributes = parse_gff_attributes( fields[8] )
class GFFFeature( GFFInterval ):
@@ -43,11 +42,13 @@
A GFF feature, which can include multiple intervals.
"""
def __init__( self, reader, chrom_col, feature_col, start_col, end_col, \
- strand_col, score_col, default_strand, fix_strand=False, intervals=[] ):
+ strand_col, score_col, default_strand, fix_strand=False, intervals=[], \
+ raw_size=0 ):
GFFInterval.__init__( self, reader, intervals[0].fields, chrom_col, feature_col, \
start_col, end_col, strand_col, score_col, default_strand, \
fix_strand=fix_strand )
self.intervals = intervals
+ self.raw_size = raw_size
# Use intervals to set feature attributes.
for interval in self.intervals:
# Error checking. NOTE: intervals need not share the same strand.
@@ -68,20 +69,6 @@
if not name:
name = self.attributes.get( 'group', None )
return name
-
- def raw_size( self ):
- """
- Returns raw size of feature; raw size is the number of bytes that
- comprise feature.
- """
- # Feature length is all intervals/lines that comprise feature.
- feature_len = 0
- for interval in self.intervals:
- # HACK: +1 for EOL char. Need bx-python to provide raw_line itself
- # b/c TableReader strips EOL characters, thus changing the line
- # length.
- feature_len += len( interval.raw_line ) + 1
- return feature_len
class GFFIntervalToBEDReaderWrapper( NiceReaderWrapper ):
"""
@@ -124,7 +111,7 @@
def parse_row( self, line ):
interval = GFFInterval( self, line.split( "\t" ), self.chrom_col, self.feature_col, \
self.start_col, self.end_col, self.strand_col, self.score_col, \
- self.default_strand, fix_strand=self.fix_strand, raw_line=line )
+ self.default_strand, fix_strand=self.fix_strand )
return interval
def next( self ):
@@ -151,7 +138,8 @@
#
# Get next GFFFeature
- #
+ #
+ raw_size = 0
# If there is no seed interval, set one. Also, if there are no more
# intervals to read, this is where iterator dies.
@@ -161,6 +149,8 @@
self.seed_interval = GenomicIntervalReader.next( self )
except ParseError, e:
handle_parse_error( e )
+ finally:
+ raw_size += len( self.current_line )
# If header or comment, clear seed interval and return it.
if isinstance( self.seed_interval, ( Header, Comment ) ):
@@ -187,6 +177,9 @@
break
except ParseError, e:
handle_parse_error( e )
+ continue
+ finally:
+ raw_size += len( self.current_line )
# If interval not associated with feature, break.
group = interval.attributes.get( 'group', None )
@@ -214,7 +207,7 @@
return GFFFeature( self, self.chrom_col, self.feature_col, self.start_col, \
self.end_col, self.strand_col, self.score_col, \
self.default_strand, fix_strand=self.fix_strand, \
- intervals=feature_intervals )
+ intervals=feature_intervals, raw_size=raw_size )
def convert_bed_coords_to_gff( interval ):
--- a/lib/galaxy/model/__init__.py Sun Mar 27 19:50:50 2011 -0400
+++ b/lib/galaxy/model/__init__.py Tue Apr 05 13:57:14 2011 -0400
@@ -103,14 +103,14 @@
# For historical reasons state propogates down to datasets
for da in self.output_datasets:
da.dataset.state = state
- def get_param_values( self, app ):
+ def get_param_values( self, app, ignore_errors=False ):
"""
Read encoded parameter values from the database and turn back into a
dict of tool parameter values.
"""
param_dict = dict( [ ( p.name, p.value ) for p in self.parameters ] )
tool = app.toolbox.tools_by_id[self.tool_id]
- param_dict = tool.params_from_strings( param_dict, app )
+ param_dict = tool.params_from_strings( param_dict, app, ignore_errors=ignore_errors )
return param_dict
def check_if_output_datasets_deleted( self ):
"""
--- a/lib/galaxy/model/mapping.py Sun Mar 27 19:50:50 2011 -0400
+++ b/lib/galaxy/model/mapping.py Tue Apr 05 13:57:14 2011 -0400
@@ -1268,7 +1268,7 @@
assign_mapper( context, Library, Library.table,
properties=dict(
root_folder=relation( LibraryFolder, backref=backref( "library_root" ) )
- )
+ )
)
assign_mapper( context, LibraryInfoAssociation, LibraryInfoAssociation.table,
@@ -1281,26 +1281,26 @@
) )
assign_mapper( context, LibraryFolder, LibraryFolder.table,
- properties=dict(
- folders=relation(
- LibraryFolder,
+ properties=dict(
+ folders=relation(
+ LibraryFolder,
primaryjoin=( LibraryFolder.table.c.parent_id == LibraryFolder.table.c.id ),
order_by=asc( LibraryFolder.table.c.name ),
backref=backref( "parent", primaryjoin=( LibraryFolder.table.c.parent_id == LibraryFolder.table.c.id ), remote_side=[LibraryFolder.table.c.id] ) ),
- active_folders=relation( LibraryFolder,
- primaryjoin=( ( LibraryFolder.table.c.parent_id == LibraryFolder.table.c.id ) & ( not_( LibraryFolder.table.c.deleted ) ) ),
- order_by=asc( LibraryFolder.table.c.name ),
+ active_folders=relation( LibraryFolder,
+ primaryjoin=( ( LibraryFolder.table.c.parent_id == LibraryFolder.table.c.id ) & ( not_( LibraryFolder.table.c.deleted ) ) ),
+ order_by=asc( LibraryFolder.table.c.name ),
lazy=True, #"""sqlalchemy.exceptions.ArgumentError: Error creating eager relationship 'active_folders' on parent class '<class 'galaxy.model.LibraryFolder'>' to child class '<class 'galaxy.model.LibraryFolder'>': Cant use eager loading on a self referential relationship."""
viewonly=True ),
datasets=relation( LibraryDataset,
- primaryjoin=( ( LibraryDataset.table.c.folder_id == LibraryFolder.table.c.id ) ),
- order_by=asc( LibraryDataset.table.c._name ),
- lazy=False,
+ primaryjoin=( ( LibraryDataset.table.c.folder_id == LibraryFolder.table.c.id ) ),
+ order_by=asc( LibraryDataset.table.c._name ),
+ lazy=True,
viewonly=True ),
active_datasets=relation( LibraryDataset,
primaryjoin=( ( LibraryDataset.table.c.folder_id == LibraryFolder.table.c.id ) & ( not_( LibraryDataset.table.c.deleted ) ) ),
- order_by=asc( LibraryDataset.table.c._name ),
- lazy=False,
+ order_by=asc( LibraryDataset.table.c._name ),
+ lazy=True,
viewonly=True )
) )
--- a/lib/galaxy/tools/__init__.py Sun Mar 27 19:50:50 2011 -0400
+++ b/lib/galaxy/tools/__init__.py Tue Apr 05 13:57:14 2011 -0400
@@ -1252,7 +1252,21 @@
for input in inputs.itervalues():
# No value, insert the default
if input.name not in values:
- messages[ input.name ] = "No value found for '%s%s', used default" % ( prefix, input.label )
+ if isinstance( input, Conditional ):
+ messages[ input.name ] = { input.test_param.name: "No value found for '%s%s', used default" % ( prefix, input.label ) }
+ test_value = input.test_param.get_initial_value( trans, context )
+ current_case = input.get_current_case( test_value, trans )
+ self.check_and_update_param_values_helper( input.cases[ current_case ].inputs, {}, trans, messages[ input.name ], context, prefix )
+ elif isinstance( input, Repeat ):
+ if input.min:
+ messages[ input.name ] = []
+ for i in range( input.min ):
+ rep_prefix = prefix + "%s %d > " % ( input.title, i + 1 )
+ rep_dict = dict()
+ messages[ input.name ].append( rep_dict )
+ self.check_and_update_param_values_helper( input.inputs, {}, trans, rep_dict, context, rep_prefix )
+ else:
+ messages[ input.name ] = "No value found for '%s%s', used default" % ( prefix, input.label )
values[ input.name ] = input.get_initial_value( trans, context )
# Value, visit recursively as usual
else:
--- a/lib/galaxy/tools/actions/__init__.py Sun Mar 27 19:50:50 2011 -0400
+++ b/lib/galaxy/tools/actions/__init__.py Tue Apr 05 13:57:14 2011 -0400
@@ -133,16 +133,18 @@
else:
new_list.append( value )
return new_list
- def wrap_values( inputs, input_values ):
+ def wrap_values( inputs, input_values, skip_missing_values = False ):
# Wrap tool inputs as necessary
for input in inputs.itervalues():
+ if input.name not in input_values and skip_missing_values:
+ continue
if isinstance( input, Repeat ):
for d in input_values[ input.name ]:
- wrap_values( input.inputs, d )
+ wrap_values( input.inputs, d, skip_missing_values = skip_missing_values )
elif isinstance( input, Conditional ):
values = input_values[ input.name ]
current = values[ "__current_case__" ]
- wrap_values( input.cases[current].inputs, values )
+ wrap_values( input.cases[current].inputs, values, skip_missing_values = skip_missing_values )
elif isinstance( input, DataToolParameter ):
input_values[ input.name ] = \
galaxy.tools.DatasetFilenameWrapper( input_values[ input.name ],
@@ -254,7 +256,7 @@
if output.change_format:
if params is None:
params = make_dict_copy( incoming )
- wrap_values( tool.inputs, params )
+ wrap_values( tool.inputs, params, skip_missing_values = not tool.check_values )
for change_elem in output.change_format:
for when_elem in change_elem.findall( 'when' ):
check = when_elem.get( 'input', None )
@@ -304,7 +306,7 @@
# <outputs>
# <data format="input" name="output" label="Blat on ${<input_param>.name}" />
# </outputs>
- wrap_values( tool.inputs, params )
+ wrap_values( tool.inputs, params, skip_missing_values = not tool.check_values )
#tool (only needing to be set once) and on_string (set differently for each label) are overwritten for each output dataset label being determined
params['tool'] = tool
params['on_string'] = on_text
--- a/lib/galaxy/visualization/tracks/data_providers.py Sun Mar 27 19:50:50 2011 -0400
+++ b/lib/galaxy/visualization/tracks/data_providers.py Tue Apr 05 13:57:14 2011 -0400
@@ -11,13 +11,16 @@
pkg_resources.require( "pysam" )
pkg_resources.require( "numpy" )
from galaxy.datatypes.util.gff_util import *
+from galaxy.util.json import from_json_string
from bx.interval_index_file import Indexes
from bx.arrays.array_tree import FileArrayTreeDict
from bx.bbi.bigwig_file import BigWigFile
from galaxy.util.lrucache import LRUCache
from galaxy.visualization.tracks.summary import *
from galaxy.datatypes.tabular import Vcf
-from galaxy.datatypes.interval import Bed, Gff
+from galaxy.datatypes.interval import Bed, Gff, Gtf
+from galaxy.datatypes.util.gff_util import parse_gff_attributes
+
from pysam import csamtools
MAX_VALS = 5000 # only display first MAX_VALS features
@@ -126,7 +129,7 @@
return st.chrom_blocks.keys()
- def get_summary( self, chrom, start, end, **kwargs):
+ def get_summary( self, chrom, start, end, **kwargs ):
filename = self.converted_dataset.file_name
st = self.CACHE[filename]
if st is None:
@@ -170,7 +173,7 @@
self.CACHE[filename] = st
# Check for data.
- return st.chrom_blocks.get(chrom, None) is not None or st.chrom_blocks.get(chrom[3:], None) is not None
+ return st.chrom_blocks.get(chrom, None) is not None or (chrom and st.chrom_blocks.get(chrom[3:], None) is not None)
class VcfDataProvider( TracksDataProvider ):
"""
@@ -303,12 +306,12 @@
if read.is_proper_pair:
if qname in paired_pending: # one in dict is always first
pair = paired_pending[qname]
- results.append( [ "%i_%s" % ( read.pos, qname ),
+ results.append( [ "%i_%s" % ( pair['start'], qname ),
pair['start'],
read.pos + read_len,
qname,
[ pair['start'], pair['end'], pair['cigar'], pair['seq'] ],
- [ read.pos, read.pos + read_len, read.cigar, seq]
+ [ read.pos, read.pos + read_len, read.cigar, seq ]
] )
del paired_pending[qname]
else:
@@ -484,9 +487,76 @@
col_name_data_attr_mapping = { 4 : { 'index': 4 , 'name' : 'Score' } }
def write_data_to_file( self, chrom, start, end, filename ):
- # TODO: write function.
- pass
-
+ source = open( self.original_dataset.file_name )
+ index = Indexes( self.converted_dataset.file_name )
+ out = open( filename, 'w' )
+ for start, end, offset in index.find(chrom, start, end):
+ source.seek( offset )
+ if isinstance( self.original_dataset.datatype, Gff ):
+ reader = GFFReaderWrapper( source, fix_strand=True )
+ feature = reader.next()
+ for interval in feature.intervals:
+ out.write(interval.raw_line + '\n')
+ elif isinstance( self.original_dataset.datatype, Bed ):
+ out.write( source.readline() )
+ out.close()
+
+ def get_filters( self ):
+ """ Returns a dataset's filters. """
+
+ # is_ functions taken from Tabular.set_meta
+ def is_int( column_text ):
+ try:
+ int( column_text )
+ return True
+ except:
+ return False
+ def is_float( column_text ):
+ try:
+ float( column_text )
+ return True
+ except:
+ if column_text.strip().lower() == 'na':
+ return True #na is special cased to be a float
+ return False
+
+ #
+ # Get filters.
+ # TODOs:
+ # (a) might be useful to move this into each datatype's set_meta method;
+ # (b) could look at first N lines to ensure GTF attribute types are consistent.
+ #
+ filters = []
+ # HACK: first 8 fields are for drawing, so start filter column index at 9.
+ filter_col = 8
+ if isinstance( self.original_dataset.datatype, Gff ):
+ # Can filter by score and GTF attributes.
+ filters = [ { 'name': 'Score', 'type': 'int', 'index': filter_col } ]
+ filter_col += 1
+ if isinstance( self.original_dataset.datatype, Gtf ):
+ for i, line in enumerate( open(self.original_dataset.file_name) ):
+ if not line.startswith('#'):
+ # Look at first line for attributes and types.
+ attributes = parse_gff_attributes( line.split('\t')[8] )
+ for attr, value in attributes.items():
+ # Get attribute type.
+ if is_int( value ):
+ attr_type = 'int'
+ elif is_float( value ):
+ attr_type = 'float'
+ else:
+ attr_type = 'str'
+ # Add to filters.
+ if attr_type is not 'str':
+ filters.append( { 'name': attr, 'type': attr_type, 'index': filter_col } )
+ filter_col += 1
+ break
+ elif isinstance( self.original_dataset.datatype, Bed ):
+ # Can filter by score column only.
+ filters = [ { 'name': 'Score', 'type': 'int', 'index': filter_col } ]
+
+ return filters
+
def get_data( self, chrom, start, end, **kwargs ):
start, end = int(start), int(end)
source = open( self.original_dataset.file_name )
@@ -509,6 +579,7 @@
#
# First three entries are mandatory, others are optional.
#
+ filter_cols = from_json_string( kwargs.get( "filter_cols", "[]" ) )
no_detail = ( "no_detail" in kwargs )
for start, end, offset in index.find(chrom, start, end):
if count >= MAX_VALS:
@@ -522,7 +593,7 @@
# GFF dataset.
reader = GFFReaderWrapper( source, fix_strand=True )
feature = reader.next()
- payload = package_gff_feature( feature, no_detail )
+ payload = package_gff_feature( feature, no_detail, filter_cols )
payload.insert( 0, offset )
elif isinstance( self.original_dataset.datatype, Bed ):
# BED dataset.
@@ -536,15 +607,11 @@
#end = min( len( feature ), 8 )
#payload.extend( feature[ 3:end ] )
- # Name, score, strand, thick start, thick end.
+ # Name, strand, thick start, thick end.
if length >= 4:
payload.append(feature[3])
- if length >= 5:
- payload.append( float(feature[4]) )
if length >= 6:
payload.append(feature[5])
-
- # Thick start, end.
if length >= 8:
payload.append(int(feature[6]))
payload.append(int(feature[7]))
@@ -555,7 +622,11 @@
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 ] )
-
+
+ # Score (filter data)
+ if length >= 5 and filter_cols and filter_cols[0] == "Score":
+ payload.append( float(feature[4]) )
+
results.append( payload )
return { 'data': results, 'message': message }
@@ -587,7 +658,7 @@
payload = package_gff_feature( feature )
payload.insert( 0, offset )
results.append( payload )
- offset += feature.raw_size()
+ offset += feature.raw_size
return { 'data': results, 'message': message }
@@ -644,7 +715,7 @@
pass
return data_provider
-def package_gff_feature( feature, no_detail=False ):
+def package_gff_feature( feature, no_detail=False, filter_cols=[] ):
""" Package a GFF feature in an array for data providers. """
feature = convert_gff_coords_to_bed( feature )
@@ -656,7 +727,6 @@
payload = [ feature.start,
feature.end,
feature.name(),
- feature.score,
feature.strand,
# No notion of thick start, end in GFF, so make everything
# thick.
@@ -677,4 +747,13 @@
blocks = zip( block_sizes, block_starts )
payload.append( [ ( feature.start + block[1], feature.start + block[1] + block[0] ) for block in blocks ] )
+ # Add filter data to payload.
+ for col in filter_cols:
+ if col == "Score":
+ payload.append( feature.score )
+ elif col in feature.attributes:
+ payload.append( feature.attributes[col] )
+ else:
+ # Dummy value.
+ payload.append( "na" )
return payload
--- a/lib/galaxy/visualization/tracks/visual_analytics.py Sun Mar 27 19:50:50 2011 -0400
+++ b/lib/galaxy/visualization/tracks/visual_analytics.py Tue Apr 05 13:57:14 2011 -0400
@@ -1,5 +1,7 @@
-from galaxy.tools.parameters.basic import IntegerToolParameter, FloatToolParameter
+import urllib
+from galaxy.tools.parameters.basic import IntegerToolParameter, FloatToolParameter, SelectToolParameter
+from galaxy.tools.parameters.dynamic_options import DynamicOptions
def get_dataset_job( hda ):
# Get dataset's job.
@@ -28,14 +30,19 @@
tool_param_values = dict( [ ( p.name, p.value ) for p in job.parameters ] )
tool_param_values = tool.params_from_strings( tool_param_values, trans.app, ignore_errors=True )
for name, input in tool.inputs.items():
- if type( input ) == IntegerToolParameter:
- tool_params.append( { 'name' : name, 'label': input.label, 'type': 'int', \
- 'value': tool_param_values.get( name, input.value ), \
- 'min' : input.min, 'max' : input.max } )
- elif type( input ) == FloatToolParameter:
- tool_params.append( { 'name' : name, 'label': input.label, 'type': 'float', \
- 'value': tool_param_values.get( name, input.value ), \
- 'min' : input.min, 'max' : input.max } )
+ if type( input ) == IntegerToolParameter or type( input ) == FloatToolParameter:
+ param_dict = { 'name' : name, 'label' : input.label, \
+ 'value' : tool_param_values.get( name, input.value ), \
+ 'type' : 'number', 'init_value' : input.value,
+ 'html' : urllib.quote( input.get_html() ) }
+ if input.min:
+ param_dict['min'] = input.min
+ if input.max:
+ param_dict['max'] = input.max
+ tool_params.append( param_dict )
+ elif type( input ) == SelectToolParameter and type( input.options ) != DynamicOptions:
+ tool_params.append( { 'name' : name, 'label' : input.label, 'type' : 'select', \
+ 'html' : urllib.quote( input.get_html() ) } )
# If tool has parameters that can be interactively modified, return tool.
# Return empty set otherwise.
--- a/lib/galaxy/web/api/workflows.py Sun Mar 27 19:50:50 2011 -0400
+++ b/lib/galaxy/web/api/workflows.py Tue Apr 05 13:57:14 2011 -0400
@@ -57,7 +57,7 @@
inputs = {}
for step in latest_workflow.steps:
if step.type == 'data_input':
- inputs[step.id] = {'label':"Input Dataset", 'value':""}
+ inputs[step.id] = {'label':step.tool_inputs['name'], 'value':""}
else:
pass
# Eventually, allow regular tool parameters to be inserted and modified at runtime.
--- a/lib/galaxy/web/controllers/tool_runner.py Sun Mar 27 19:50:50 2011 -0400
+++ b/lib/galaxy/web/controllers/tool_runner.py Tue Apr 05 13:57:14 2011 -0400
@@ -120,7 +120,7 @@
error( "The '%s' tool does not currently support rerunning." % tool.name )
# Get the job's parameters
try:
- params_objects = job.get_param_values( trans.app )
+ params_objects = job.get_param_values( trans.app, ignore_errors = True )
except:
raise Exception( "Failed to get parameters for dataset id %d " % data.id )
upgrade_messages = tool.check_and_update_param_values( params_objects, trans )
--- a/lib/galaxy/web/controllers/tracks.py Sun Mar 27 19:50:50 2011 -0400
+++ b/lib/galaxy/web/controllers/tracks.py Tue Apr 05 13:57:14 2011 -0400
@@ -2,7 +2,7 @@
Support for constructing and viewing custom "track" browsers within Galaxy.
"""
-import re, time, pkg_resources
+import re, pkg_resources
pkg_resources.require( "bx-python" )
from bx.seq.twobit import TwoBitFile
@@ -13,7 +13,6 @@
from galaxy.web.framework import simplejson
from galaxy.web.framework.helpers import time_ago, grids
from galaxy.util.bunch import Bunch
-from galaxy import util
from galaxy.datatypes.interval import Gff
from galaxy.visualization.tracks.data_providers import *
@@ -202,7 +201,6 @@
return trans.fill_template( "tracks/new_browser.mako", dbkeys=self._get_dbkeys( trans ), default_dbkey=kwargs.get("default_dbkey", None) )
@web.json
- @web.require_login()
def add_track_async(self, trans, hda_id=None, ldda_id=None):
if hda_id:
hda_ldda = "hda"
@@ -671,6 +669,8 @@
if not tool:
return messages.NO_TOOL
tool_params = dict( [ ( p.name, p.value ) for p in original_job.parameters ] )
+ # TODO: need to handle updates to conditional parameters; conditional
+ # params are stored in dicts (and dicts within dicts).
tool_params.update( dict( [ ( key, value ) for key, value in kwargs.items() if key in tool.inputs ] ) )
tool_params = tool.params_from_strings( tool_params, self.app )
@@ -686,13 +686,16 @@
messages_list = []
for jida in original_job.input_datasets:
input_dataset = jida.dataset
- track_type, data_sources = input_dataset.datatype.get_track_type()
- # Convert to datasource that provides 'data' because we need to
- # extract the original data.
- data_source = data_sources[ 'data' ]
- msg = self._convert_dataset( trans, input_dataset, data_source )
- if msg is not None:
- messages_list.append( msg )
+ # TODO: put together more robust way to determine if a dataset can be indexed.
+ if hasattr( input_dataset, 'get_track_type' ):
+ # Can index dataset.
+ track_type, data_sources = input_dataset.datatype.get_track_type()
+ # Convert to datasource that provides 'data' because we need to
+ # extract the original data.
+ data_source = data_sources[ 'data' ]
+ msg = self._convert_dataset( trans, input_dataset, data_source )
+ if msg is not None:
+ messages_list.append( msg )
# Return any messages generated during conversions.
return_message = _get_highest_priority_msg( messages_list )
@@ -703,51 +706,67 @@
# Set input datasets for tool. Input datasets are subsets of full
# datasets and are based on chrom, low, high.
#
- hda_permissions = trans.app.security_agent.history_get_default_permissions( original_dataset.history )
+
+ # If user is rerunning own tool, put new data in original dataset's
+ # history. If another user is running tool, put new data in current
+ # history.
+ if original_dataset.history.user == trans.user:
+ working_history = original_dataset.history
+ else:
+ working_history = trans.get_history( create=True )
+ hda_permissions = trans.app.security_agent.history_get_default_permissions( working_history )
messages_list = []
for jida in original_job.input_datasets:
input_dataset = jida.dataset
- track_type, data_sources = input_dataset.datatype.get_track_type()
- data_source = data_sources[ 'data' ]
- converted_dataset = input_dataset.get_converted_dataset( trans, data_source )
+ if hasattr( input_dataset, 'get_track_type' ):
+ #
+ # Dataset can be indexed and hence a subset can be extracted.
+ #
+ track_type, data_sources = input_dataset.datatype.get_track_type()
+ data_source = data_sources[ 'data' ]
+ converted_dataset = input_dataset.get_converted_dataset( trans, data_source )
- #
- # Create new HDA for input dataset's subset.
- #
- subset_dataset = trans.app.model.HistoryDatasetAssociation( extension=input_dataset.ext, \
- dbkey=input_dataset.dbkey, \
- create_dataset=True, \
- sa_session=trans.sa_session,
- name="Subset [%s:%i-%i] of data %i" % \
- ( chrom, low, high, input_dataset.hid ),
- visible=False )
- input_dataset.history.add_dataset( subset_dataset )
- trans.sa_session.add( subset_dataset )
- trans.app.security_agent.set_all_dataset_permissions( subset_dataset.dataset, hda_permissions )
- if input_dataset.extension == 'bam':
- data_provider = BamDataProvider( original_dataset=input_dataset, converted_dataset=converted_dataset )
- data_provider.write_data_to_file( chrom, low, high, subset_dataset.file_name )
- # TODO: size not working.
- subset_dataset.set_size()
- subset_dataset.info = "Data subset for trackster"
- subset_dataset.set_dataset_state( trans.app.model.Dataset.states.OK )
- trans.sa_session.flush()
+ #
+ # Create new HDA for input dataset's subset.
+ #
+ new_dataset = trans.app.model.HistoryDatasetAssociation( extension=input_dataset.ext, \
+ dbkey=input_dataset.dbkey, \
+ create_dataset=True, \
+ sa_session=trans.sa_session,
+ name="Subset [%s:%i-%i] of data %i" % \
+ ( chrom, low, high, input_dataset.hid ),
+ visible=False )
+ working_history.add_dataset( new_dataset )
+ trans.sa_session.add( new_dataset )
+ trans.app.security_agent.set_all_dataset_permissions( new_dataset.dataset, hda_permissions )
- # Add dataset to tool's parameters.
- tool_params[ jida.name ] = subset_dataset
+ # Write subset of data to new dataset
+ data_provider_class = get_data_provider( original_dataset=input_dataset )
+ data_provider = data_provider_class( original_dataset=input_dataset,
+ converted_dataset=converted_dataset )
+ data_provider.write_data_to_file( chrom, low, high, new_dataset.file_name )
+
+ # TODO: size not working.
+ new_dataset.set_size()
+ new_dataset.info = "Data subset for trackster"
+ new_dataset.set_dataset_state( trans.app.model.Dataset.states.OK )
+ trans.sa_session.flush()
+
+ # Add dataset to tool's parameters.
+ tool_params[ jida.name ] = new_dataset
#
# Start tool and handle outputs.
#
try:
- subset_job, subset_job_outputs = tool.execute( trans, incoming=tool_params, history=original_dataset.history )
+ subset_job, subset_job_outputs = tool.execute( trans, incoming=tool_params, history=working_history )
except Exception, e:
# Lots of things can go wrong when trying to execute tool.
return to_json_string( { "error" : True, "message" : e.__class__.__name__ + ": " + str(e) } )
for output in subset_job_outputs.values():
output.visible = False
trans.sa_session.flush()
-
+
# Return new track that corresponds to the original dataset.
output_name = None
for joda in original_job.output_datasets:
--- a/static/june_2007_style/blue/trackster.css Sun Mar 27 19:50:50 2011 -0400
+++ b/static/june_2007_style/blue/trackster.css Tue Apr 05 13:57:14 2011 -0400
@@ -22,7 +22,7 @@
.track{background:white;}
.track-header{text-align:left;padding:4px 0px;color:#666;}
.track-header .menubutton{margin-left:0px;}
-.track-content{overflow:hidden;text-align:center;border-bottom:1px solid #bbb;background:#eee url('/static/images/tracks/diag_bg.gif');min-height:16px;}
+.track-content{overflow:hidden;text-align:center;border-top:1px solid #eee;border-bottom:1px solid #eee;background:#eee url('/static/images/tracks/diag_bg.gif');min-height:16px;}
.label-track .track-content{background:white;}
.track-tile{background:white;}
.track-tile canvas{position:relative;z-index:100;border:solid white;border-width:2px 0px 0px 0px;}
@@ -38,11 +38,12 @@
.top-labeltrack{position:relative;border-bottom:solid #999 1px;}
.nav-labeltrack{border-top:solid #999 1px;border-bottom:solid #333 1px;}
input{font:10px verdana;}
-.values{padding-left:0.25em;}
-.dynamic-tool,.filters{width:400px;margin-left:0.25em;padding-bottom:0.5em;}
+.dynamic-tool,.filters{width:410px;margin-left:0.25em;padding-bottom:0.5em;}
.slider-row{margin-top:0.4em;margin-left:1em;}
.slider-label{float:left;font-weight:bold;}
.slider{float:right;width:200px;position:relative;}
.tool-name{font-size:110%;font-weight:bold;}
+.param-row{margin-top:0.2em;margin-left:1em;}
+.param-label{float:left;font-weight:bold;padding-top:0.2em;}
.child-track-icon{background:url('../images/fugue/arrow-000-small-bw.png') no-repeat;width:30px;cursor:move;}
.track-resize{background:white url('../images/visualization/draggable_vertical.png') no-repeat top center;position:absolute;right:3px;bottom:-4px;width:14px;height:7px;border:solid #999 1px;z-index:100;}
--- a/static/june_2007_style/trackster.css.tmpl Sun Mar 27 19:50:50 2011 -0400
+++ b/static/june_2007_style/trackster.css.tmpl Tue Apr 05 13:57:14 2011 -0400
@@ -146,8 +146,8 @@
.track-content {
overflow: hidden;
text-align: center;
-/* border-top: 1px solid #eee; */
- border-bottom: 1px solid #bbb;
+ border-top: 1px solid #eee;
+ border-bottom: 1px solid #eee;
background: #eee url('/static/images/tracks/diag_bg.gif');
min-height: 16px;
}
@@ -228,11 +228,8 @@
input {
font: 10px verdana;
}
-.values {
- padding-left: 0.25em;
-}
.dynamic-tool, .filters {
- width: 400px;
+ width: 410px;
margin-left: 0.25em;
padding-bottom:0.5em;
}
@@ -240,7 +237,7 @@
margin-top: 0.4em;
margin-left: 1em;
}
-.slider-label {
+.param-label, .slider-label {
float: left;
font-weight: bold;
}
@@ -253,6 +250,15 @@
font-size: 110%;
font-weight: bold;
}
+.param-row {
+ margin-top: 0.2em;
+ margin-left: 1em;
+}
+.param-label{
+ float: left;
+ font-weight: bold;
+ padding-top: 0.2em;
+}
.child-track-icon {
background:url('../images/fugue/arrow-000-small-bw.png') no-repeat;
width: 30px;
--- a/static/scripts/packed/trackster.js Sun Mar 27 19:50:50 2011 -0400
+++ b/static/scripts/packed/trackster.js Tue Apr 05 13:57:14 2011 -0400
@@ -1,1 +1,1 @@
-CanvasRenderingContext2D.prototype.dashedLine=function(c,j,b,h,f){if(f===undefined){f=4}var e=b-c;var d=h-j;var g=Math.floor(Math.sqrt(e*e+d*d)/f);var l=e/g;var k=d/g;var a;for(a=0;a<g;a++,c+=l,j+=k){if(a%2!==0){continue}this.fillRect(c,j,f,1)}};CanvasRenderingContext2D.prototype.drawDownwardEquilateralTriangle=function(b,a,e){var d=b-e/2,c=b+e/2,f=a-Math.sqrt(e*3/2);this.beginPath();this.moveTo(d,f);this.lineTo(c,f);this.lineTo(b,a);this.lineTo(d,f);this.strokeStyle=this.fillStyle;this.fill();this.stroke();this.closePath()};function sortable(a,b){a.bind("drag",{handle:b,relative:true},function(h,j){var g=$(this).parent();var f=g.children();var c;for(c=0;c<f.length;c++){if(j.offsetY<$(f.get(c)).position().top){break}}if(c===f.length){if(this!==f.get(c-1)){g.append(this)}}else{if(this!==f.get(c)){$(this).insertBefore(f.get(c))}}})}var NO_OVERLAP=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005;function compute_overlap(e,b){var g=e[0],f=e[1],d=b[0],c=b[1],a;if(g<d){if(f<d){a=NO_OVERLAP}else{if(f<=c){a=OVERLAP_START}else{a=CONTAINS}}}else{if(g>c){a=NO_OVERLAP}else{if(f<=c){a=CONTAINED_BY}else{a=OVERLAP_END}}}return a}function is_overlap(b,a){return(compute_overlap(b,a)!==NO_OVERLAP)}var DENSE_TRACK_HEIGHT=10,NO_DETAIL_TRACK_HEIGHT=3,SQUISH_TRACK_HEIGHT=5,PACK_TRACK_HEIGHT=10,NO_DETAIL_FEATURE_HEIGHT=1,DENSE_FEATURE_HEIGHT=1,SQUISH_FEATURE_HEIGHT=3,PACK_FEATURE_HEIGHT=9,ERROR_PADDING=10,LABEL_SPACING=2,PACK_SPACING=5,MIN_SQUISH_VIEW_WIDTH=12000,DEFAULT_FONT="9px Monaco, Lucida Console, monospace",DENSITY=200,FEATURE_LEVELS=10,MAX_FEATURE_DEPTH=100,DEFAULT_DATA_QUERY_WAIT=5000,MAX_CHROMS_SELECTABLE=100,CONNECTOR_COLOR="#ccc",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_CANNOT_RUN_TOOL="Tool cannot be rerun: ",DATA_LOADING="Loading data...",DATA_OK="Ready for display",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=5,CACHED_DATA=5,DUMMY_CANVAS=document.createElement("canvas"),RIGHT_STRAND,LEFT_STRAND;if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(DUMMY_CANVAS)}var CONTEXT=DUMMY_CANVAS.getContext("2d");CONTEXT.font=DEFAULT_FONT;var CHAR_WIDTH_PX=CONTEXT.measureText("A").width,CHAR_HEIGHT_PX=9;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.move_key_to_end(b,a)}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},move_key_to_end:function(b,a){this.key_ary.splice(a,1);this.key_ary.push(b)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var DataManager=function(b,a,c){Cache.call(this,b);this.track=a;this.subset=(c!==undefined?c:true)};$.extend(DataManager.prototype,Cache.prototype,{load_data:function(d,a,f,h,b,e){var g={chrom:d,low:a,high:f,mode:h,resolution:b,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(g,e);var c=this;return $.getJSON(this.track.data_url,g,function(j){c.set_data(a,f,h,j)})},get_data:function(j,k,c,h,b,f){var l=this.get(this.gen_key(k,c,h));if(l){return l}if(this.subset){var m,g,a,e,h,l;for(var d=0;d<this.key_ary.length;d++){m=this.key_ary[d];g=this.split_key(m);a=g[0];e=g[1];if(k>=a&&c<=e){l=this.obj_cache[m];if(l.dataset_type!=="summary_tree"&&l.extra_info!=="no_detail"){this.move_key_to_end(m,d);return l}}}}return this.load_data(j,k,c,h,b,f)},set_data:function(b,c,d,a){return this.set(this.gen_key(b,c,d),a)},gen_key:function(a,c,d){var b=a+"_"+c+"_"+d;return b},split_key:function(a){return a.split("_")}});var View=function(a,d,c,b,e){this.container=a;this.chrom=null;this.vis_id=c;this.dbkey=b;this.title=d;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(e);this.reset()};$.extend(View.prototype,{init:function(d){var c=this.container,a=this;this.top_container=$("<div/>").addClass("top-container").appendTo(c);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(c);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(c);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);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_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);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_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var b=function(f){if(f.type==="focusout"||(f.keyCode||f.which)===13||(f.keyCode||f.which)===27){if((f.keyCode||f.which)!==27){a.go_to($(this).val())}$(this).hide();$(this).val("");a.location_span.show();a.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",b).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.bind("click",function(){a.location_span.hide();a.chrom_select.hide();a.nav_input.val(a.chrom+":"+a.low+"-"+a.high);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.nav_controls)}this.zo_link=$("<a id='zoom-out' />").click(function(){a.zoom_out();a.redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){a.zoom_in();a.redraw()}).appendTo(this.nav_controls);this.load_chroms({low:0},d);this.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())});this.intro_div.show();this.content_div.bind("click",function(f){$(this).find("input").trigger("blur")});this.content_div.bind("dblclick",function(f){a.zoom_in(f.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(f,g){this.current_x=g.offsetX}).bind("drag",function(f,h){var j=h.offsetX-this.current_x;this.current_x=h.offsetX;var g=Math.round(j/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-g)});this.overview_close.bind("click",function(){for(var f=0,e=a.tracks.length;f<e;f++){a.tracks[f].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("draginit",function(f,g){if(f.clientX>a.viewport_container.width()-16){return false}}).bind("dragstart",function(f,g){g.original_low=a.low;g.current_height=f.clientY;g.current_x=g.offsetX}).bind("drag",function(h,k){var f=$(this);var l=k.offsetX-k.current_x;var g=f.scrollTop()-(h.clientY-k.current_height);f.scrollTop(g);k.current_height=h.clientY;k.current_x=k.offsetX;var j=Math.round(l/a.viewport_container.width()*(a.high-a.low));a.move_delta(j)}).bind("mousewheel",function(h,k,g,f){if(g){var j=Math.round(-g/a.viewport_container.width()*(a.high-a.low));a.move_delta(j)}});this.top_labeltrack.bind("dragstart",function(f,g){return $("<div />").css({height:a.content_div.height()+a.top_labeltrack.height()+a.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(k,l){$(l.proxy).css({left:Math.min(k.pageX,l.startX),width:Math.abs(k.pageX-l.startX)});var g=Math.min(k.pageX,l.startX)-a.container.offset().left,f=Math.max(k.pageX,l.startX)-a.container.offset().left,j=(a.high-a.low),h=a.viewport_container.width();a.update_location(Math.round(g/h*j)+a.low,Math.round(f/h*j)+a.low)}).bind("dragend",function(l,m){var g=Math.min(l.pageX,m.startX),f=Math.max(l.pageX,m.startX),j=(a.high-a.low),h=a.viewport_container.width(),k=a.low;a.low=Math.round(g/h*j)+k;a.high=Math.round(f/h*j)+k;$(m.proxy).remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack));$(window).bind("resize",function(){a.resize_window()});$(document).bind("redraw",function(){a.redraw()});this.reset();$(window).trigger("resize")},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},load_chroms:function(b,c){b.num=MAX_CHROMS_SELECTABLE;$.extend(b,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var a=this;$.ajax({url:chrom_url,data:b,dataType:"json",success:function(e){if(e.chrom_info.length===0){alert("Invalid chromosome: "+b.chrom);return}if(e.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=e.chrom_info;var h='<option value="">Select Chrom/Contig</option>';for(var g=0,d=a.chrom_data.length;g<d;g++){var f=a.chrom_data[g].chrom;h+='<option value="'+f+'">'+f+"</option>"}if(e.prev_chroms){h+='<option value="previous">Previous '+MAX_CHROMS_SELECTABLE+"</option>"}if(e.next_chroms){h+='<option value="next">Next '+MAX_CHROMS_SELECTABLE+"</option>"}a.chrom_select.html(h);if(c){c()}a.chrom_start_index=e.start_index},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}})},change_chrom:function(e,b,g){if(!e||e==="None"){return}var d=this;if(e==="previous"){d.load_chroms({low:this.chrom_start_index-MAX_CHROMS_SELECTABLE});return}if(e==="next"){d.load_chroms({low:this.chrom_start_index+MAX_CHROMS_SELECTABLE});return}var f=$.grep(d.chrom_data,function(j,k){return j.chrom===e})[0];if(f===undefined){d.load_chroms({chrom:e},function(){d.change_chrom(e,b,g)});return}else{if(e!==d.chrom){d.chrom=e;if(!d.chrom){d.intro_div.show()}else{d.intro_div.hide()}d.chrom_select.val(d.chrom);d.max_high=f.len-1;d.reset();d.redraw(true);for(var h=0,a=d.tracks.length;h<a;h++){var c=d.tracks[h];if(c.init){c.init()}}}if(b!==undefined&&g!==undefined){d.low=Math.max(b,0);d.high=Math.min(g,d.max_high)}d.reset_overview();d.redraw()}},go_to:function(f){var k=this,a,d,b=f.split(":"),h=b[0],j=b[1];if(j!==undefined){try{var g=j.split("-");a=parseInt(g[0].replace(/,/g,""),10);d=parseInt(g[1].replace(/,/g,""),10)}catch(c){return false}}k.change_chrom(h,a,d)},move_fraction:function(c){var a=this;var b=a.high-a.low;this.move_delta(c*b)},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);sortable(a.container_div,".draghandle");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())||0;var e=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;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,width: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(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()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide()}});var Tool=function(a,b){this.name=a;this.params=b};$.extend(Tool.prototype,{get_param_values_dict:function(){var b={};for(var a=0;a<this.params.length;a++){var c=this.params[a];b[c.name]=c.value}return b},get_param_values:function(){var b=[];for(var a=0;a<this.params.length;a++){b[a]=this.params[a].value}return b}});var NumberToolParameter=function(c,b,e,a,d){this.name=c;this.label=b;this.min=e;this.max=a;this.value=d};var get_tool_from_dict=function(f){if(obj_length(f)===0){return undefined}var b=f.name;var l=f.params;var c=Array();for(var e=0;e<l.length;e++){var g=l[e];var a=g.name,k=g.label,h=g.type,d=g.min,j=g.max,m=g.value;c[c.length]=new NumberToolParameter(a,k,d,j,m)}return new Tool(b,c)};var Filter=function(b,a,c){this.name=b;this.index=a;this.value=c};var NumberFilter=function(b,a){this.name=b;this.index=a;this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.slider_min=Number.MAX_VALUE;this.slider_max=-Number.MAX_VALUE;this.slider=null;this.slider_label=null};$.extend(NumberFilter.prototype,{applies_to:function(a){if(a.length>this.index){return true}return false},keep:function(a){if(!this.applies_to(a)){return true}return(a[this.index]>=this.low&&a[this.index]<=this.high)},update_attrs:function(b){var a=false;if(!this.applies_to(b)){return a}if(b[this.index]<this.slider_min){this.slider_min=b[this.index];a=true}if(b[this.index]>this.slider_max){this.slider_max=b[this.index];a=false}return a},update_ui_elt:function(){var b=this.slider.slider("option","min"),a=this.slider.slider("option","max");if(this.slider_min<b||this.slider_max>a){this.slider.slider("option","min",this.slider_min);this.slider.slider("option","max",this.slider_max);this.slider.slider("option","values",[this.slider_min,this.slider_max])}}});var get_filters_from_dict=function(a){var g=[];for(var d=0;d<a.length;d++){var f=a[d];var c=f.name,e=f.type,b=f.index;if(e==="int"||e==="float"){g[d]=new NumberFilter(c,b)}else{g[d]=new Filter(c,b,e)}}return g};var TrackConfig=function(a){this.track=a.track;this.params=a.params;this.values={};if(a.saved_values){this.restore_values(a.saved_values)}this.onchange=a.onchange};$.extend(TrackConfig.prototype,{restore_values:function(a){var b=this;$.each(this.params,function(c,d){if(a[d.key]!==undefined){b.values[d.key]=a[d.key]}else{b.values[d.key]=d.default_value}})},build_form:function(){var b=this;var a=$("<div />");$.each(this.params,function(f,d){if(!d.hidden){var c="param_"+f;var l=$("<div class='form-row' />").appendTo(a);l.append($("<label />").attr("for",c).text(d.label+":"));if(d.type==="bool"){l.append($('<input type="checkbox" />').attr("id",c).attr("name",c).attr("checked",b.values[d.key]))}else{if(d.type==="color"){var h=b.values[d.key];var g=$("<input />").attr("id",c).attr("name",c).val(h);var j=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var e=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(j);var k=$("<div/>").appendTo(e).farbtastic({width:100,height:100,callback:g,color:h});$("<div />").append(g).append(j).appendTo(l).bind("click",function(m){j.css({left:$(this).position().left+($(g).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){j.hide();$(document).unbind("click.color-picker")});m.stopPropagation()})}else{l.append($("<input />").attr("id",c).attr("name",c).val(b.values[d.key]))}}}});return a},update_from_form:function(a){var c=this;var b=false;$.each(this.params,function(d,f){if(!f.hidden){var g="param_"+d;var e=a.find("#"+g).val();if(f.type==="float"){e=parseFloat(e)}else{if(f.type==="int"){e=parseInt(e)}else{if(f.type==="bool"){e=a.find("#"+g).is(":checked")}}}if(e!==c.values[f.key]){c.values[f.key]=e;b=true}}});if(b){this.onchange()}}});var Track=function(b,a,e,c,d){this.name=b;this.view=a;this.parent_element=e;this.data_url=(c?c:default_data_url);this.data_url_extra_params={};this.data_query_wait=(d?d:DEFAULT_DATA_QUERY_WAIT);this.dataset_check_url=converted_datasets_state_url;this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){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.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)};$.extend(Track.prototype,{init:function(){var a=this;a.enabled=false;a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_div.css("height","auto");a.container_div.removeClass("nodata error pending");if(!a.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:a.hda_ldda,dataset_id:a.dataset_id,chrom:a.view.chrom},function(b){if(!b||b==="error"||b.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(b.message){var d=a.view.tracks.indexOf(a);var c=$(" <a href='javascript:void(0);'></a>").text("View error").bind("click",function(){show_modal("Trackster Error","<pre>"+b.message+"</pre>",{Close:hide_modal})});a.content_div.append(c)}}else{if(b==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(b==="no data"||(b.data!==undefined&&(b.data===null||b.data.length===0))){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(b==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},a.data_query_wait)}else{if(b.status==="data"){if(b.valid_chroms){a.valid_chroms=b.valid_chroms;a.make_name_popup_menu()}a.content_div.text(DATA_OK);if(a.view.chrom){a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;$.when(a.predraw_init()).done(function(){a.draw()})}}}}}}})},predraw_init:function(){},update_name:function(a){this.old_name=this.name;this.name=a;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)}});var TiledTrack=function(b,j,n){var c=this,o=c.view;this.filters=(b!==undefined?get_filters_from_dict(b):[]);this.filters_available=false;this.filters_visible=false;this.tool=(j!==undefined?get_tool_from_dict(j):undefined);this.parent_track=n;this.child_tracks=[];if(c.hidden){return}if(this.parent_track){this.header_div.find(".draghandle").removeClass("draghandle").addClass("child-track-icon").addClass("icon-button");this.parent_element.addClass("child-track");this.tool=undefined}this.filters_div=$("<div/>").addClass("filters").hide();this.header_div.after(this.filters_div);this.filters_div.bind("drag",function(q){q.stopPropagation()}).bind("dblclick",function(q){q.stopPropagation()});$.each(this.filters,function(t,w){var u=$("<div/>").addClass("slider-row").appendTo(c.filters_div);var v=$("<div/>").addClass("slider-label").appendTo(u);var s=$("<span/>").addClass("name").appendTo(v);s.text(w.name+" ");var r=$("<span/>").addClass("values").appendTo(v);var q=$("<div/>").addClass("slider").appendTo(u);w.control_element=$("<div/>").attr("id",w.name+"-filter-control").appendTo(q);w.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(y,z){var x=z.values;r.text("["+x[0]+"-"+x[1]+"]");w.low=x[0];w.high=x[1];c.draw(true,true)},change:function(x,y){w.control_element.slider("option","slide").call(w.control_element,x,y)}});w.slider=w.control_element;w.slider_label=r;$("<div style='clear: both;'/>").appendTo(u)});if(this.tool){this.dynamic_tool_div=$("<div/>").addClass("dynamic-tool").hide();this.header_div.after(this.dynamic_tool_div);this.dynamic_tool_div.bind("drag",function(q){q.stopPropagation()}).bind("click",function(q){q.stopPropagation()}).bind("dblclick",function(q){q.stopPropagation()});var m=$("<div class='tool-name'>").appendTo(this.dynamic_tool_div).text(this.tool.name);var l=this.tool.params;var c=this;$.each(this.tool.params,function(x,s){var v=$("<div>").addClass("slider-row").appendTo(c.dynamic_tool_div);var u=$("<div>").addClass("slider-label").appendTo(v);var z=$("<span class='param-name'>").text(s.label+" ").appendTo(u);var t=$("<span/>").text(s.value);var w=$("<span class='param-value'>").appendTo(u).append("[").append(t).append("]");var y=$("<div/>").addClass("slider").appendTo(v);var q=$("<div id='"+s.name+"-param-control'>").appendTo(y);var r=(s.max<=1?0.01:(s.max<=1000?1:5));q.slider({min:s.min,max:s.max,step:r,value:s.value,slide:function(A,C){var B=C.value;s.value=B;if(0<B&&B<1){B=parseFloat(B).toFixed(2)}t.text(B)},change:function(A,B){s.value=B.value}});w.click(function(){var C=t,B=C.text(),A=(s.max<=1?4:s.max.length);C.text("");$("<input type='text'/>").attr("size",A).attr("maxlength",A).attr("value",B).appendTo(C).focus().select().click(function(D){D.stopPropagation()}).blur(function(){$(this).remove();C.text(B)}).keyup(function(F){if(F.keyCode===27){$(this).trigger("blur")}else{if(F.keyCode===13){var D=$(this),E=parseFloat(D.val());if(isNaN(E)||E>s.max||E<s.min){alert("Parameter value must be in the range ["+s.min+"-"+s.max+"]");return $(this)}C.text(E);q.slider("value",E);s.value=E}}})});$("<div style='clear: both;'/>").appendTo(v)});var p=$("<div>").addClass("slider-row").appendTo(this.dynamic_tool_div);var k=$("<input type='submit'>").attr("value","Run").appendTo(p);var c=this;k.click(function(){c.run_tool()})}c.child_tracks_container=$("<div/>").addClass("child-tracks-container").hide();c.container_div.append(c.child_tracks_container);if(c.display_modes!==undefined){if(c.mode_div===undefined){c.mode_div=$("<div class='right-float menubutton popup' />").appendTo(c.header_div);var e=(c.track_config&&c.track_config.values.mode?c.track_config.values.mode:c.display_modes[0]);c.mode=e;c.mode_div.text(e);var d=function(q){c.mode_div.text(q);c.mode=q;c.track_config.values.mode=q;c.tile_cache.clear();c.draw()};var a={};for(var f=0,h=c.display_modes.length;f<h;f++){var g=c.display_modes[f];a[g]=function(q){return function(){d(q)}}(g)}make_popupmenu(c.mode_div,a)}else{c.mode_div.hide()}}this.make_name_popup_menu()};$.extend(TiledTrack.prototype,Track.prototype,{make_name_popup_menu:function(){var b=this;var a={};a["Edit configuration"]=function(){var h=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},f=function(){b.track_config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},g=function(j){if((j.keyCode||j.which)===27){h()}else{if((j.keyCode||j.which)===13){f()}}};$(window).bind("keypress.check_enter_esc",g);show_modal("Configure Track",b.track_config.build_form(),{Cancel:h,OK:f})};if(b.filters_available>0){var e=(b.filters_div.is(":visible")?"Hide filters":"Show filters");a[e]=function(){b.filters_visible=(b.filters_div.is(":visible"));b.filters_div.toggle();b.make_name_popup_menu()}}if(b.tool){var e=(b.dynamic_tool_div.is(":visible")?"Hide Tool":"Show Tool");a[e]=function(){if(!b.dynamic_tool_div.is(":visible")){b.update_name(b.name+b.tool_region_and_parameters_str())}else{menu_option_text="Show dynamic tool";b.revert_name()}b.dynamic_tool_div.toggle();b.make_name_popup_menu()}}if(b.valid_chroms){a["List chrom/contigs with data"]=function(){show_modal("Chrom/contigs with data","<p>"+b.valid_chroms.join("<br/>")+"</p>",{Close:function(){hide_modal()}})}}var c=view;var d=function(){$("#no-tracks").show()};if(this.parent_track){c=this.parent_track;d=function(){}}a.Remove=function(){c.remove_track(b);if(c.num_tracks===0){d()}};make_popupmenu(b.name_div,a)},draw:function(a,d){var s=this.view.low,g=this.view.high,j=g-s,l=this.view.container.width(),m=this.view.resolution;var e=$("<div style='position: relative;'></div>"),f=l/j;if(!d){this.content_div.children().remove()}this.content_div.append(e);this.max_height=0;var o=Math.floor(s/m/DENSITY);var c={};while((o*DENSITY*m)<g){var r=l+"_"+f+"_"+o;var h=this.tile_cache.get(r);var p=o*DENSITY*this.view.resolution;var b=p+DENSITY*this.view.resolution;if(!a&&h){this.show_tile(h,e,p,f)}else{this.delayed_draw(a,r,p,b,o,m,e,f,c)}o+=1}if(d){var k=this;var q=setInterval(function(){if(obj_length(c)===0){var v=k.content_div.children();var u=false;for(var w=v.length-1,t=0;w>=t;w--){var x=$(v[w]);if(u){x.remove()}else{if(x.children().length!==0){u=true}}}clearInterval(q)}},50)}for(var n=0;n<this.child_tracks.length;n++){this.child_tracks[n].draw(a,d)}},delayed_draw:function(b,j,g,l,c,e,k,m,f){var d=this;var h=function(u,n,p,o,s,t,q){returned_tile=d.draw_tile(n,p,o,s,t,q);var r=$("<div class='track-tile'>").prepend(returned_tile);tile_element=r;d.tile_cache.set(j,tile_element);d.show_tile(tile_element,s,g,t);delete f[u]};var a=setTimeout(function(){if(g<=d.view.high&&l>=d.view.low){var n=(b?undefined:d.tile_cache.get(j));if(n){d.show_tile(n,k,g,m);delete f[a]}else{$.when(d.data_cache.get_data(view.chrom,g,l,d.mode,e,d.data_url_extra_params)).then(function(){var o=d.data_cache.get_data(view.chrom,g,l,d.mode,e,d.data_url_extra_params);if(view.reference_track&&m>CHAR_WIDTH_PX){$.when(view.reference_track.data_cache.get_data(view.chrom,g,l,d.mode,e,view.reference_track.data_url_extra_params)).then(function(){var p=view.reference_track.data_cache.get_data(view.chrom,g,l,d.mode,e,view.reference_track.data_url_extra_params);h(a,o,e,c,k,m,p)})}else{h(a,o,e,c,k,m)}})}}},50);f[a]=true},show_tile:function(h,j,e,k){var a=this;var c=this.view.high-this.view.low,b=(e-this.view.low)*k;if(this.left_offset){b-=this.left_offset}h.css({position:"absolute",top:0,left:b,height:""});j.append(h);a.max_height=Math.max(a.max_height,h.height());a.content_div.css("height",a.max_height+"px");j.children().css("height",a.max_height+"px");if(a.hidden){return}for(var g=0;g<a.filters.length;g++){a.filters[g].update_ui_elt()}var d=false;if(a.example_feature){for(var g=0;g<a.filters.length;g++){if(a.filters[g].applies_to(a.example_feature)){d=true;break}}}if(a.filters_available!==d){a.filters_available=d;if(!a.filters_available){a.filters_div.hide()}a.make_name_popup_menu()}},set_overview:function(){var a=this.view;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")},run_tool:function(){var b={dataset_id:this.original_dataset_id,chrom:this.view.chrom,low:this.view.low,high:this.view.high,tool_id:this.tool.name};$.extend(b,this.tool.get_param_values_dict());var d=this,c=b.tool_id+d.tool_region_and_parameters_str(b.chrom,b.low,b.high),e;if(d.track_type==="FeatureTrack"){e=new ToolDataFeatureTrack(c,view,d.hda_ldda,undefined,{},{},d)}this.add_track(e);e.content_div.text("Starting job.");view.has_changes=true;var a=function(){$.getJSON(run_tool_url,b,function(f){if(f==="no converter"){e.container_div.addClass("error");e.content_div.text(DATA_NOCONVERTER)}else{if(f.error){e.container_div.addClass("error");e.content_div.text(DATA_CANNOT_RUN_TOOL+f.message)}else{if(f==="pending"){e.container_div.addClass("pending");e.content_div.text("Converting input data so that it can be easily reused.");setTimeout(a,2000)}else{e.dataset_id=f.dataset_id;e.content_div.text("Running job.");e.init()}}}})};a()},tool_region_and_parameters_str:function(c,a,d){var b=this,e=(c!==undefined&&a!==undefined&&d!==undefined?c+":"+a+"-"+d:"all");return" - region=["+e+"], parameters=["+b.tool.get_param_values().join(", ")+"]"},add_track:function(a){a.track_id=this.track_id+"_"+this.child_tracks.length;a.container_div.attr("id","track_"+a.track_id);this.child_tracks_container.append(a.container_div);sortable(a.container_div,".child-track-icon");if(!$(this.child_tracks_container).is(":visible")){this.child_tracks_container.show()}this.child_tracks.push(a)},remove_track:function(a){a.container_div.fadeOut("slow",function(){$(this).remove()})}});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.view.container.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);a.reference_track=this;this.left_offset=200;this.height_px=12;this.font=DEFAULT_FONT;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:a.dbkey};this.data_cache=new DataManager(CACHED_DATA,this,false);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.prototype,{draw_tile:function(m,g,b,j,n){var f=this,d=DENSITY*g;if(n>CHAR_WIDTH_PX){if(m===null){f.content_div.css("height","0px");return}var e=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(e)}e=$(e);var l=e.get(0).getContext("2d");e.get(0).width=Math.ceil(d*n+f.left_offset);e.get(0).height=f.height_px;l.font=DEFAULT_FONT;l.textAlign="center";for(var h=0,k=m.length;h<k;h++){var a=Math.round(h*n);l.fillText(m[h],a+f.left_offset,10)}return e}this.content_div.css("height","0px")}});var LineTrack=function(e,c,f,a,d){var b=this;this.track_type="LineTrack";this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";Track.call(this,e,c,c.viewport_container);TiledTrack.call(this);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=f;this.dataset_id=a;this.original_dataset_id=a;this.data_cache=new DataManager(CACHED_DATA,this);this.tile_cache=new Cache(CACHED_TILES_LINE);this.track_config=new TrackConfig({track:this,params:[{key:"color",label:"Color",type:"color",default_value:"black"},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.height_px,hidden:true}],saved_values:d,onchange:function(){b.vertical_range=b.prefs.max_value-b.prefs.min_value;$("#linetrack_"+b.track_id+"_minval").text(b.prefs.min_value);$("#linetrack_"+b.track_id+"_maxval").text(b.prefs.max_value);b.tile_cache.clear();b.draw()}});this.prefs=this.track_config.values;this.height_px=this.track_config.values.height;this.vertical_range=this.track_config.values.max_value-this.track_config.values.min_value;(function(g){var k=false;var j=false;var h=$("<div class='track-resize'>");$(g.container_div).hover(function(){k=true;h.show()},function(){k=false;if(!j){h.hide()}});h.hide().bind("dragstart",function(l,m){j=true;m.original_height=$(g.content_div).height()}).bind("drag",function(m,n){var l=Math.min(Math.max(n.original_height+n.deltaY,g.min_height_px),g.max_height_px);$(g.content_div).css("height",l);g.height_px=l;g.draw(true)}).bind("dragend",function(l,m){g.tile_cache.clear();j=false;if(!k){h.hide()}g.track_config.values.height=g.height_px}).appendTo(g.container_div)})(this)};$.extend(LineTrack.prototype,TiledTrack.prototype,{predraw_init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;return $.getJSON(a.data_url,{stats:true,chrom:a.view.chrom,low:null,high:null,hda_ldda:a.hda_ldda,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");var e=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=e.min;a.prefs.max_value=e.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=e.total_frequency;a.container_div.find(".yaxislabel").remove();var f=$("<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:"24px",left:"10px"});d.prependTo(a.container_div);f.css({position:"absolute",bottom:"2px",left:"10px"});f.prependTo(a.container_div)})},draw_tile:function(j,q,t,c,e){if(this.vertical_range===undefined){return}var o=this,u=t*DENSITY*q,a=DENSITY*q,B=q+"_"+t,v={hda_ldda:this.hda_ldda,dataset_id:this.dataset_id,resolution:this.view.resolution};var b=document.createElement("canvas"),z=j.data;if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(b)}b=$(b);b.get(0).width=Math.ceil(a*e);b.get(0).height=o.height_px;var p=b.get(0).getContext("2d"),k=false,l=o.prefs.min_value,g=o.prefs.max_value,n=o.vertical_range,w=o.total_frequency,d=o.height_px,m=o.mode;var A=Math.round(d+l/n*d);p.beginPath();p.moveTo(0,A);p.lineTo(a*e,A);p.fillStyle="#aaa";p.stroke();p.beginPath();p.fillStyle=o.prefs.color;var x,h,f;if(z.length>1){f=Math.ceil((z[1][0]-z[0][0])*e)}else{f=10}for(var r=0,s=z.length;r<s;r++){x=Math.round((z[r][0]-u)*e);h=z[r][1];if(h===null){if(k&&m==="Filled"){p.lineTo(x,d)}k=false;continue}if(h<l){h=l}else{if(h>g){h=g}}if(m==="Histogram"){h=Math.round(h/n*d);p.fillRect(x,A,f,-h)}else{if(m==="Intensity"){h=255-Math.floor((h-l)/n*255);p.fillStyle="rgb("+h+","+h+","+h+")";p.fillRect(x,0,f,d)}else{h=Math.round(d-(h-l)/n*d);if(k){p.lineTo(x,h)}else{k=true;if(m==="Filled"){p.moveTo(x,d);p.lineTo(x,h)}else{p.moveTo(x,h)}}}}}if(m==="Filled"){if(k){p.lineTo(x,A);p.lineTo(0,A)}p.fill()}else{p.stroke()}return b}});var FeatureTrack=function(a,f,e,j,h,c,d,g){var b=this;this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];this.track_config=new TrackConfig({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:h,onchange:function(){b.tile_cache.clear();b.draw()}});this.prefs=this.track_config.values;Track.call(this,a,f,f.viewport_container);TiledTrack.call(this,c,d,g);this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=e;this.dataset_id=j;this.original_dataset_id=j;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.default_font=DEFAULT_FONT;this.inc_slots={};this.start_end_dct={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new DataManager(20,this);this.left_offset=200};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{incremental_slots:function(a,h,p){var q=this.inc_slots[a];if(!q||(q.mode!==p)){q={};q.w_scale=a;q.mode=p;this.inc_slots[a]=q;this.start_end_dct[a]={}}var l=q.w_scale,w=[],x=[],j=0,n=this.view.max_low;for(var u=0,v=h.length;u<v;u++){var g=h[u],k=g[0];if(q[k]!==undefined){j=Math.max(j,q[k]);x.push(q[k])}else{w.push(u)}}var d=this.start_end_dct[a];var m=function(D,E){for(var C=0;C<=MAX_FEATURE_DEPTH;C++){var A=false,F=d[C];if(F!==undefined){for(var z=0,B=F.length;z<B;z++){var y=F[z];if(E>y[0]&&D<y[1]){A=true;break}}}if(!A){return C}}return -1};for(var u=0,v=w.length;u<v;u++){var g=h[w[u]],k=g[0],s=g[1],b=g[2],o=g[3],c=Math.floor((s-n)*l),f=Math.ceil((b-n)*l),t=CONTEXT.measureText(o).width,e;if(o!==undefined&&p==="Pack"){t+=(LABEL_SPACING+PACK_SPACING);if(c-t>=0){c-=t;e="left"}else{f+=t;e="right"}}var r=m(c,f);if(r>=0){if(d[r]===undefined){d[r]=[]}d[r].push([c,f]);q[k]=r;j=Math.max(j,r)}else{}}return j+1},draw_summary_tree:function(b,o,n,l,r,j,f,e){var c=j+LABEL_SPACING+CHAR_HEIGHT_PX;delta_x_px=Math.ceil(n*r);var h=$("<div />").addClass("yaxislabel");h.text(l);h.css({position:"absolute",top:"22px",left:"10px"});h.prependTo(this.container_div);var q=b.get(0).getContext("2d");for(var d=0,g=o.length;d<g;d++){var m=Math.floor((o[d][0]-f)*r);var k=o[d][1];if(!k){continue}var p=k/l*j;q.fillStyle="black";q.fillRect(m+e,c-p,delta_x_px,p);var a=4;if(this.prefs.show_counts&&(q.measureText(k).width+a)<delta_x_px){q.fillStyle="#666";q.textAlign="center";q.fillText(k,m+e+(delta_x_px/2),10)}}},draw_element:function(p,f,g,x,j,r,I,M,N,a,A){var u=x[0],K=x[1],C=x[2]-1,s=x[3],D=Math.floor(Math.max(0,(K-r)*M)),q=Math.ceil(Math.min(a,Math.max(0,(C-r)*M))),B=ERROR_PADDING+(g==="Dense"?0:(0+j))*N,o,G,t=null,O=null,d=this.prefs.block_color,F=this.prefs.label_color;if(g==="Dense"){p.fillStyle=d;p.fillRect(D+A,B,q-D,DENSE_FEATURE_HEIGHT)}else{if(g==="no_detail"){p.fillStyle=d;p.fillRect(D+A,B+5,q-D,DENSE_FEATURE_HEIGHT)}else{var n=x[5],z=x[6],E=x[7],e=x[8];if(z&&E){t=Math.floor(Math.max(0,(z-r)*M));O=Math.ceil(Math.min(a,Math.max(0,(E-r)*M)))}var L,v;if(g==="Squish"){L=1;v=SQUISH_FEATURE_HEIGHT}else{L=5;v=PACK_FEATURE_HEIGHT}if(!e){if(x.strand){if(x.strand==="+"){p.fillStyle=RIGHT_STRAND_INV}else{if(x.strand==="-"){p.fillStyle=LEFT_STRAND_INV}}}else{p.fillStyle=d}p.fillRect(D+A,B,q-D,v)}else{var m,w;if(g==="Squish"){p.fillStyle=CONNECTOR_COLOR;m=B+Math.floor(SQUISH_FEATURE_HEIGHT/2)+1;w=1}else{if(n){var m=B;var w=v;if(n==="+"){p.fillStyle=RIGHT_STRAND}else{if(n==="-"){p.fillStyle=LEFT_STRAND}}}else{p.fillStyle=CONNECTOR_COLOR;m+=(SQUISH_FEATURE_HEIGHT/2)+1;w=1}}p.fillRect(D+A,m,q-D,w);for(var J=0,c=e.length;J<c;J++){var h=e[J],b=Math.floor(Math.max(0,(h[0]-r)*M)),y=Math.ceil(Math.min(a,Math.max((h[1]-1-r)*M)));if(b>y){continue}p.fillStyle=d;p.fillRect(b+A,B+(v-L)/2+1,y-b,L);if(t!==undefined&&!(b>O||y<t)){var H=Math.max(b,t),l=Math.min(y,O);p.fillRect(H+A,B+1,l-H,v)}}}if(g==="Pack"&&K>r){p.fillStyle=F;if(f===0&&D-p.measureText(s).width<0){p.textAlign="left";p.fillText(s,q+A+LABEL_SPACING,B+8)}else{p.textAlign="right";p.fillText(s,D+A-LABEL_SPACING,B+8)}p.fillStyle=d}}}},get_y_scale:function(b){var a;if(b==="summary_tree"){}if(b==="Dense"){a=DENSE_TRACK_HEIGHT}else{if(b==="no_detail"){a=NO_DETAIL_TRACK_HEIGHT}else{if(b==="Squish"){a=SQUISH_TRACK_HEIGHT}else{a=PACK_TRACK_HEIGHT}}}return a},draw_tile:function(o,x,C,k,m,d){var t=this;var E=C*DENSITY*x,a=(C+1)*DENSITY*x,q=a-E,F={hda_ldda:t.hda_ldda,dataset_id:t.dataset_id,resolution:this.view.resolution,mode:this.mode};var v=Math.ceil(q*m),s=this.mode,H=25,g=this.left_offset,p,h;var c=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(c)}c=$(c);if(s==="Auto"){if(o.dataset_type==="summary_tree"){s=o.dataset_type}else{if(o.extra_info==="no_detail"){s="no_detail"}else{var G=o.data;if((G.length&&G.length<4)||(this.view.high-this.view.low>MIN_SQUISH_VIEW_WIDTH)){s="Squish"}else{s="Pack"}}}}var y=this.get_y_scale(s);if(s==="summary_tree"){h=this.summary_draw_height}if(s==="Dense"){h=H}else{if(s==="no_detail"||s==="Squish"||s==="Pack"){h=this.incremental_slots(m,o.data,s)*y+H;p=this.inc_slots[m]}}c.get(0).width=v+g;c.get(0).height=h;if(o.dataset_type==="summary_tree"){c.get(0).height+=LABEL_SPACING+CHAR_HEIGHT_PX}k.parent().css("height",Math.max(this.height_px,h)+"px");var w=c.get(0).getContext("2d");w.fillStyle=this.prefs.block_color;w.font=this.default_font;w.textAlign="right";this.container_div.find(".yaxislabel").remove();if(s==="summary_tree"){this.draw_summary_tree(c,o.data,o.delta,o.max,m,h,E,g);return c}if(o.message){c.css({"border-top":"1px solid red"});w.fillStyle="red";w.textAlign="left";var r=w.textBaseline;w.textBaseline="top";w.fillText(o.message,g,0);w.textBaseline=r;if(!o.data){return c}}this.example_feature=(o.data.length?o.data[0]:undefined);var G=o.data;for(var z=0,B=G.length;z<B;z++){var j=G[z],l=j[0],u=j[1],b=j[2],e=(p&&p[l]!==undefined?p[l]:null);var A=false;var n;for(var D=0;D<this.filters.length;D++){n=this.filters[D];n.update_attrs(j);if(!n.keep(j)){A=true;break}}if(A){continue}if(is_overlap([u,b],[E,a])&&(s=="Dense"||e!==null)){this.draw_element(w,C,s,j,e,E,a,m,y,v,g,d)}}return c}});var VcfTrack=function(d,b,f,a,c,e){FeatureTrack.call(this,d,b,f,a,c,e);this.track_type="VcfTrack"};$.extend(VcfTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{draw_element:function(u,p,j,e,x,c,m,v,s){var j=data[i],l=j[0],t=j[1],d=j[2]-1,o=j[3],g=Math.floor(Math.max(0,(t-x)*m)),k=Math.ceil(Math.min(s,Math.max(0,(d-x)*m))),f=ERROR_PADDING+(p==="Dense"?0:(0+e))*v,a,y,b=null,n=null;if(no_label){u.fillStyle=block_color;u.fillRect(g+left_offset,f+5,k-g,1)}else{var w=j[4],r=j[5],h=j[6];a=9;y=1;u.fillRect(g+left_offset,f,k-g,a);if(p!=="Dense"&&o!==undefined&&t>x){u.fillStyle=label_color;if(tile_index===0&&g-u.measureText(o).width<0){u.textAlign="left";u.fillText(o,k+2+left_offset,f+8)}else{u.textAlign="right";u.fillText(o,g-2+left_offset,f+8)}u.fillStyle=block_color}var q=w+" / "+r;if(t>x&&u.measureText(q).width<(k-g)){u.fillStyle="white";u.textAlign="center";u.fillText(q,left_offset+g+(k-g)/2,f+8);u.fillStyle=block_color}}}});var ReadTrack=function(d,b,f,a,c,e){FeatureTrack.call(this,d,b,f,a,c,e);this.track_config=new TrackConfig({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:c,onchange:function(){this.track.tile_cache.clear();this.track.draw()}});this.prefs=this.track_config.values;this.track_type="ReadTrack";this.make_name_popup_menu()};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{get_y_scale:function(b){var a;if(b==="summary_tree"){}if(b==="Dense"){a=DENSE_TRACK_HEIGHT}else{if(b==="Squish"){a=SQUISH_TRACK_HEIGHT}else{a=PACK_TRACK_HEIGHT;if(this.track_config.values.show_insertions){a*=2}}}return a},draw_read:function(m,d,J,n,D,G,e,o,y,a){m.textAlign="center";var l=this,u=[n,D],C=0,z=0,f=0;var r=[];if((d==="Pack"||this.mode==="Auto")&&o!==undefined&&J>CHAR_WIDTH_PX){f=Math.round(J/2)}if(!e){e=[[0,o.length]]}for(var h=0,k=e.length;h<k;h++){var b=e[h],g="MIDNSHP=X"[b[0]],v=b[1];if(g==="H"||g==="S"){C-=v}var x=G+C,B=Math.floor(Math.max(0,(x-n)*J)),E=Math.floor(Math.max(0,(x+v-n)*J));switch(g){case"H":break;case"S":case"M":case"=":var p=compute_overlap([x,x+v],u);if(p!==NO_OVERLAP){var q=o.slice(z,z+v);if(f>0){m.fillStyle=this.prefs.block_color;m.fillRect(B+this.left_offset-f,y+1,E-B,9);m.fillStyle=CONNECTOR_COLOR;for(var I=0,j=q.length;I<j;I++){if(this.track_config.values.show_differences&&a){var s=a[x-n+I];if(!s||s.toLowerCase()===q[I].toLowerCase()){continue}}if(x+I>=n&&x+I<=D){var A=Math.floor(Math.max(0,(x+I-n)*J));m.fillText(q[I],A+this.left_offset,y+9)}}}else{m.fillStyle=this.prefs.block_color;m.fillRect(B+this.left_offset,y+(this.mode!=="Dense"?4:5),E-B,(d!=="Dense"?SQUISH_FEATURE_HEIGHT:DENSE_FEATURE_HEIGHT))}}z+=v;C+=v;break;case"N":m.fillStyle=CONNECTOR_COLOR;m.fillRect(B+this.left_offset-f,y+5,E-B,1);C+=v;break;case"D":m.fillStyle="red";m.fillRect(B+this.left_offset-f,y+4,E-B,3);C+=v;break;case"P":break;case"I":var p=compute_overlap([x,x+v],u),K=this.left_offset+B-f;if(p!==NO_OVERLAP){var q=o.slice(z,z+v);if(this.track_config.values.show_insertions){var w=this.left_offset+B-(E-B)/2;if((d==="Pack"||this.mode==="Auto")&&o!==undefined&&J>CHAR_WIDTH_PX){m.fillStyle="yellow";m.fillRect(w-f,y-9,E-B,9);r[r.length]={type:"triangle",data:[K,y+4,5]};m.fillStyle=CONNECTOR_COLOR;switch(p){case (OVERLAP_START):q=q.slice(n-x);break;case (OVERLAP_END):q=q.slice(0,x-D);break;case (CONTAINED_BY):break;case (CONTAINS):q=q.slice(n-x,x-D);break}for(var I=0,j=q.length;I<j;I++){var A=Math.floor(Math.max(0,(x+I-n)*J));m.fillText(q[I],A+this.left_offset-(E-B)/2,y)}}else{m.fillStyle="yellow";m.fillRect(w,y+(this.mode!=="Dense"?2:5),E-B,(d!=="Dense"?SQUISH_FEATURE_HEIGHT:DENSE_FEATURE_HEIGHT))}}else{if((d==="Pack"||this.mode==="Auto")&&o!==undefined&&J>CHAR_WIDTH_PX){r[r.length]={type:"text",data:[q.length,K,y+9]}}else{}}}z+=v;break;case"X":z+=v;break}}m.fillStyle="yellow";var t,L,H;for(var F=0;F<r.length;F++){t=r[F];L=t.type;H=t.data;if(L==="text"){m.font="bold "+DEFAULT_FONT;m.fillText(H[0],H[1],H[2]);m.font=DEFAULT_FONT}else{if(L=="triangle"){m.drawDownwardEquilateralTriangle(H[0],H[1],H[2])}}}},draw_element:function(w,y,r,k,e,A,b,n,x,u,f,c){var m=k[0],v=k[1],d=k[2],o=k[3],h=Math.floor(Math.max(0,(v-A)*n)),j=Math.ceil(Math.min(u,Math.max(0,(d-A)*n))),g=(r==="Dense"?1:(1+e))*x,z=this.prefs.block_color,l=this.prefs.label_color;t=0;w.fillStyle=z;if(k[5] instanceof Array){var s=Math.floor(Math.max(0,(k[4][0]-A)*n)),q=Math.ceil(Math.min(u,Math.max(0,(k[4][1]-A)*n))),p=Math.floor(Math.max(0,(k[5][0]-A)*n)),a=Math.ceil(Math.min(u,Math.max(0,(k[5][1]-A)*n)));if(k[4][1]>=A&&k[4][0]<=b&&k[4][2]){this.draw_read(w,r,n,A,b,k[4][0],k[4][2],k[4][3],g,c)}if(k[5][1]>=A&&k[5][0]<=b&&k[5][2]){this.draw_read(w,r,n,A,b,k[5][0],k[5][2],k[5][3],g,c)}if(p>q){w.fillStyle=CONNECTOR_COLOR;w.dashedLine(q+f,g+5,f+p,g+5)}}else{w.fillStyle=z;this.draw_read(w,r,n,A,b,v,k[4],k[5],g,c)}if(r==="Pack"&&v>A){w.fillStyle=this.prefs.label_color;if((r==="Pack"||this.mode==="Auto")&&n>CHAR_WIDTH_PX){var t=Math.round(n/2)}if(y===0&&h-w.measureText(o).width<0){w.textAlign="left";w.fillText(o,j+f+LABEL_SPACING-t,g+8)}else{w.textAlign="right";w.fillText(o,h+f-LABEL_SPACING-t,g+8)}w.fillStyle=z}}});var ToolDataFeatureTrack=function(e,c,g,a,d,f,b){FeatureTrack.call(this,e,c,g,a,d,f,{},b);this.track_type="ToolDataFeatureTrack";this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};$.extend(ToolDataFeatureTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{predraw_init:function(){var b=this;var a=function(){if(b.data_cache.size()===0){setTimeout(a,300)}else{b.data_url=default_data_url;b.data_query_wait=DEFAULT_DATA_QUERY_WAIT;b.dataset_state_url=converted_datasets_state_url;$.getJSON(b.dataset_state_url,{dataset_id:b.dataset_id,hda_ldda:b.hda_ldda},function(c){})}};a()}});
\ No newline at end of file
+var extend=function(){var c=arguments[0];for(var b=1;b<arguments.length;b++){var a=arguments[b];for(key in a){c[key]=a[key]}}};var trackster_module=function(f,Q){var o=f("slotting"),G=f("painters");var V=function(W,X){this.document=W;this.default_font=X!==undefined?X:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};extend(V.prototype,{load_pattern:function(W,aa){var X=this.patterns,Y=this.dummy_context,Z=new Image();Z.src=image_path+aa;Z.onload=function(){X[W]=Y.createPattern(Z,"repeat")}},get_pattern:function(W){return this.patterns[W]},new_canvas:function(){var W=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(W)}W.manager=this;return W}});var B=function(W,X){W.bind("drag",{handle:X,relative:true},function(ab,ac){var aa=$(this).parent();var Z=aa.children();var Y;for(Y=0;Y<Z.length;Y++){if(ac.offsetY<$(Z.get(Y)).position().top){break}}if(Y===Z.length){if(this!==Z.get(Y-1)){aa.append(this)}}else{if(this!==Z.get(Y)){$(this).insertBefore(Z.get(Y))}}})};var h=function(Y,W){var X=W-Y;return(X<=2?0.01:(X<=100?1:(X<=1000?5:10)))};var C=9,z=10,L=C+2,w=100,D=12000,J=200,r=10,F=5000,s=100,m="There was an error in indexing this dataset. ",E="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",A="No data for this chrom/contig.",p="Currently indexing... please wait",u="Tool cannot be rerun: ",a="Loading data...",R="Ready for display",d=10,q=5,y=5;function t(W){return Math.round(W*1000)/1000}var c=function(W){this.num_elements=W;this.clear()};extend(c.prototype,{get:function(X){var W=this.key_ary.indexOf(X);if(W!==-1){this.move_key_to_end(X,W)}return this.obj_cache[X]},set:function(X,Y){if(!this.obj_cache[X]){if(this.key_ary.length>=this.num_elements){var W=this.key_ary.shift();delete this.obj_cache[W]}this.key_ary.push(X)}this.obj_cache[X]=Y;return Y},move_key_to_end:function(X,W){this.key_ary.splice(W,1);this.key_ary.push(X)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var K=function(X,W,Y){c.call(this,X);this.track=W;this.subset=(Y!==undefined?Y:true)};extend(K.prototype,c.prototype,{load_data:function(ad,ae,Z,ac,W,ab){var Y={chrom:ad,low:ae,high:Z,mode:ac,resolution:W,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(Y,ab);var af=[];for(var aa=0;aa<this.track.filters.length;aa++){af[af.length]=this.track.filters[aa].name}Y.filter_cols=JSON.stringify(af);var X=this;return $.getJSON(this.track.data_url,Y,function(ag){X.set_data(ae,Z,ac,ag)})},get_data:function(Y,W,ab,ac,X,aa){var Z=this.get(this.gen_key(W,ab,ac));if(Z){return Z}Z=this.load_data(Y,W,ab,ac,X,aa);this.set_data(W,ab,ac,Z);return Z},set_data:function(X,Y,Z,W){return this.set(this.gen_key(X,Y,Z),W)},gen_key:function(W,Y,Z){var X=W+"_"+Y+"_"+Z;return X},split_key:function(W){return W.split("_")}});var U=function(W,Z,Y,X,aa){this.container=W;this.chrom=null;this.vis_id=Y;this.dbkey=X;this.title=Z;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(aa);this.canvas_manager=new V(W.get(0).ownerDocument);this.reset()};extend(U.prototype,{init:function(Z){var Y=this.container,W=this;this.top_container=$("<div/>").addClass("top-container").appendTo(Y);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(Y);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(Y);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);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_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);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_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var X=function(aa){if(aa.type==="focusout"||(aa.keyCode||aa.which)===13||(aa.keyCode||aa.which)===27){if((aa.keyCode||aa.which)!==27){W.go_to($(this).val())}$(this).hide();$(this).val("");W.location_span.show();W.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",X).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.bind("click",function(){W.location_span.hide();W.chrom_select.hide();W.nav_input.val(W.chrom+":"+W.low+"-"+W.high);W.nav_input.css("display","inline-block");W.nav_input.select();W.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a id='zoom-out' />").click(function(){W.zoom_out();W.redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){W.zoom_in();W.redraw()}).appendTo(this.nav_controls);this.load_chroms({low:0},Z);this.chrom_select.bind("change",function(){W.change_chrom(W.chrom_select.val())});this.intro_div.show();this.content_div.bind("click",function(aa){$(this).find("input").trigger("blur")});this.content_div.bind("dblclick",function(aa){W.zoom_in(aa.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(aa,ab){this.current_x=ab.offsetX}).bind("drag",function(aa,ac){var ad=ac.offsetX-this.current_x;this.current_x=ac.offsetX;var ab=Math.round(ad/W.viewport_container.width()*(W.max_high-W.max_low));W.move_delta(-ab)});this.overview_close.bind("click",function(){for(var ab=0,aa=W.tracks.length;ab<aa;ab++){W.tracks[ab].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",W.overview_box.height());W.overview_highlight.hide();$(this).hide()});this.viewport_container.bind("draginit",function(aa,ab){if(aa.clientX>W.viewport_container.width()-16){return false}}).bind("dragstart",function(aa,ab){ab.original_low=W.low;ab.current_height=aa.clientY;ab.current_x=ab.offsetX}).bind("drag",function(ac,ae){var aa=$(this);var af=ae.offsetX-ae.current_x;var ab=aa.scrollTop()-(ac.clientY-ae.current_height);aa.scrollTop(ab);ae.current_height=ac.clientY;ae.current_x=ae.offsetX;var ad=Math.round(af/W.viewport_container.width()*(W.high-W.low));W.move_delta(ad)}).bind("mousewheel",function(ac,ae,ab,aa){if(ab){var ad=Math.round(-ab/W.viewport_container.width()*(W.high-W.low));W.move_delta(ad)}});this.top_labeltrack.bind("dragstart",function(aa,ab){return $("<div />").css({height:W.content_div.height()+W.top_labeltrack.height()+W.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ae,af){$(af.proxy).css({left:Math.min(ae.pageX,af.startX),width:Math.abs(ae.pageX-af.startX)});var ab=Math.min(ae.pageX,af.startX)-W.container.offset().left,aa=Math.max(ae.pageX,af.startX)-W.container.offset().left,ad=(W.high-W.low),ac=W.viewport_container.width();W.update_location(Math.round(ab/ac*ad)+W.low,Math.round(aa/ac*ad)+W.low)}).bind("dragend",function(af,ag){var ab=Math.min(af.pageX,ag.startX),aa=Math.max(af.pageX,ag.startX),ad=(W.high-W.low),ac=W.viewport_container.width(),ae=W.low;W.low=Math.round(ab/ac*ad)+ae;W.high=Math.round(aa/ac*ad)+ae;$(ag.proxy).remove();W.redraw()});this.add_label_track(new T(this,this.top_labeltrack));this.add_label_track(new T(this,this.nav_labeltrack));$(window).bind("resize",function(){W.resize_window()});$(document).bind("redraw",function(){W.redraw()});this.reset();$(window).trigger("resize")},update_location:function(W,X){this.location_span.text(commatize(W)+" - "+commatize(X));this.nav_input.val(this.chrom+":"+commatize(W)+"-"+commatize(X))},load_chroms:function(X,Y){X.num=s;$.extend(X,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var W=this;$.ajax({url:chrom_url,data:X,dataType:"json",success:function(aa){if(aa.chrom_info.length===0){alert("Invalid chromosome: "+X.chrom);return}if(aa.reference){W.add_label_track(new x(W))}W.chrom_data=aa.chrom_info;var ad='<option value="">Select Chrom/Contig</option>';for(var ac=0,Z=W.chrom_data.length;ac<Z;ac++){var ab=W.chrom_data[ac].chrom;ad+='<option value="'+ab+'">'+ab+"</option>"}if(aa.prev_chroms){ad+='<option value="previous">Previous '+s+"</option>"}if(aa.next_chroms){ad+='<option value="next">Next '+s+"</option>"}W.chrom_select.html(ad);if(Y){Y()}W.chrom_start_index=aa.start_index},error:function(){alert("Could not load chroms for this dbkey:",W.dbkey)}})},change_chrom:function(aa,X,ac){if(!aa||aa==="None"){return}var Z=this;if(aa==="previous"){Z.load_chroms({low:this.chrom_start_index-s});return}if(aa==="next"){Z.load_chroms({low:this.chrom_start_index+s});return}var ab=$.grep(Z.chrom_data,function(ae,af){return ae.chrom===aa})[0];if(ab===undefined){Z.load_chroms({chrom:aa},function(){Z.change_chrom(aa,X,ac)});return}else{if(aa!==Z.chrom){Z.chrom=aa;if(!Z.chrom){Z.intro_div.show()}else{Z.intro_div.hide()}Z.chrom_select.val(Z.chrom);Z.max_high=ab.len-1;Z.reset();Z.redraw(true);for(var ad=0,W=Z.tracks.length;ad<W;ad++){var Y=Z.tracks[ad];if(Y.init){Y.init()}}}if(X!==undefined&&ac!==undefined){Z.low=Math.max(X,0);Z.high=Math.min(ac,Z.max_high)}Z.reset_overview();Z.redraw()}},go_to:function(aa){var ae=this,W,Z,X=aa.split(":"),ac=X[0],ad=X[1];if(ad!==undefined){try{var ab=ad.split("-");W=parseInt(ab[0].replace(/,/g,""),10);Z=parseInt(ab[1].replace(/,/g,""),10)}catch(Y){return false}}ae.change_chrom(ac,W,Z)},move_fraction:function(Y){var W=this;var X=W.high-W.low;this.move_delta(Y*X)},move_delta:function(Y){var W=this;var X=W.high-W.low;if(W.low-Y<W.max_low){W.low=W.max_low;W.high=W.max_low+X}else{if(W.high-Y>W.max_high){W.high=W.max_high;W.low=W.max_high-X}else{W.high-=Y;W.low-=Y}}W.redraw()},add_track:function(W){W.view=this;W.track_id=this.track_id_counter;this.tracks.push(W);if(W.init){W.init()}W.container_div.attr("id","track_"+W.track_id);B(W.container_div,".draghandle");this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(W){W.view=this;this.label_tracks.push(W)},remove_track:function(W){this.has_changes=true;W.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(W)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(ad){var ac=this.high-this.low,ab=this.low,X=this.high;if(ab<this.max_low){ab=this.max_low}if(X>this.max_high){X=this.max_high}if(this.high!==0&&ac<this.min_separation){X=ab+this.min_separation}this.low=Math.floor(ab);this.high=Math.ceil(X);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(r,Math.max(0,Math.ceil(Math.log(this.resolution,r)/Math.log(r))));var W=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var aa=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ae=13;this.overview_box.css({left:W,width:Math.max(ae,aa)}).show();if(aa<ae){this.overview_box.css("left",W-(ae-aa)/2)}if(this.overview_highlight){this.overview_highlight.css({left:W,width:aa})}this.update_location(this.low,this.high);if(!ad){for(var Y=0,Z=this.tracks.length;Y<Z;Y++){if(this.tracks[Y]&&this.tracks[Y].enabled){this.tracks[Y].draw()}}for(Y=0,Z=this.label_tracks.length;Y<Z;Y++){this.label_tracks[Y].draw()}}},zoom_in:function(X,Y){if(this.max_high===0||this.high-this.low<this.min_separation){return}var Z=this.high-this.low,aa=Z/2+this.low,W=(Z/this.zoom_factor)/2;if(X){aa=X/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(aa-W);this.high=Math.round(aa+W);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var X=this.high-this.low,Y=X/2+this.low,W=(X*this.zoom_factor)/2;this.low=Math.round(Y-W);this.high=Math.round(Y+W);this.redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide()}});var n=function(X,aa){this.track=X;this.name=aa.name;this.params=[];var ai=aa.params;for(var Y=0;Y<ai.length;Y++){var ad=ai[Y],W=ad.name,ah=ad.label,Z=unescape(ad.html),af=ad.type;if(af==="number"){this.params[this.params.length]=new g(W,ah,Z,ad.min,ad.max)}else{if(af=="select"){this.params[this.params.length]=new I(W,ah,Z)}else{console.log("WARNING: unrecognized tool parameter type:",W,af)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(ak){ak.stopPropagation()}).bind("click",function(ak){ak.stopPropagation()}).bind("dblclick",function(ak){ak.stopPropagation()});var ag=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var ae=this.params;var ab=this;$.each(this.params,function(al,ao){var an=$("<div>").addClass("param-row").appendTo(ab.parent_div);var ak=$("<div>").addClass("param-label").text(ao.label).appendTo(an);var am=$("<div/>").addClass("slider").html(ao.html).appendTo(an);$("<div style='clear: both;'/>").appendTo(an)});this.parent_div.find("input").click(function(){$(this).select()});var aj=$("<div>").addClass("slider-row").appendTo(this.parent_div);var ac=$("<input type='submit'>").attr("value","Run").appendTo(aj);var ab=this;ac.click(function(){ab.run()})};extend(n.prototype,{get_param_values_dict:function(){var W={};this.parent_div.find(":input").each(function(){var X=$(this).attr("name"),Y=$(this).val();W[X]=JSON.stringify(Y)});return W},get_param_values:function(){var X=[];var W={};this.parent_div.find(":input").each(function(){var Y=$(this).attr("name"),Z=$(this).val();if(Y){X[X.length]=Z}});return X},run:function(){var X={dataset_id:this.track.original_dataset_id,chrom:this.track.view.chrom,low:this.track.view.low,high:this.track.view.high,tool_id:this.name};$.extend(X,this.get_param_values_dict());var Z=this.track,Y=X.tool_id+Z.tool_region_and_parameters_str(X.chrom,X.low,X.high),aa;if(Z.track_type==="FeatureTrack"){aa=new N(Y,view,Z.hda_ldda,undefined,{},{},Z)}this.track.add_track(aa);aa.content_div.text("Starting job.");var W=function(){$.getJSON(run_tool_url,X,function(ab){if(ab==="no converter"){aa.container_div.addClass("error");aa.content_div.text(E)}else{if(ab.error){aa.container_div.addClass("error");aa.content_div.text(u+ab.message)}else{if(ab==="pending"){aa.container_div.addClass("pending");aa.content_div.text("Converting input data so that it can be easily reused.");setTimeout(W,2000)}else{aa.dataset_id=ab.dataset_id;aa.content_div.text("Running job.");aa.init()}}}})};W()}});var I=function(X,W,Y){this.name=X;this.label=W;this.html=Y};var g=function(Y,X,aa,Z,W){I.call(this,Y,X,aa);this.min=Z;this.max=W};var j=function(X,W,Y){this.name=X;this.index=W;this.value=Y};var O=function(X,W){this.name=X;this.index=W;this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.slider=null;this.slider_label=null};extend(O.prototype,{applies_to:function(W){if(W.length>this.index){return true}return false},keep:function(W){if(!this.applies_to(W)){return true}return(W[this.index]>=this.low&&W[this.index]<=this.high)},update_attrs:function(X){var W=false;if(!this.applies_to(X)){return W}if(X[this.index]<this.min){this.min=Math.floor(X[this.index]);W=true}if(X[this.index]>this.max){this.max=Math.ceil(X[this.index]);W=true}return W},update_ui_elt:function(){var X=this.slider.slider("option","min"),W=this.slider.slider("option","max");if(this.min<X||this.max>W){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",h(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var v=function(W){var ac=[];for(var Z=0;Z<W.length;Z++){var ab=W[Z];var Y=ab.name,aa=ab.type,X=ab.index;if(aa==="int"||aa==="float"){ac[Z]=new O(Y,X)}else{ac[Z]=new j(Y,X,aa)}}return ac};var S=function(W){this.track=W.track;this.params=W.params;this.values={};if(W.saved_values){this.restore_values(W.saved_values)}this.onchange=W.onchange};extend(S.prototype,{restore_values:function(W){var X=this;$.each(this.params,function(Y,Z){if(W[Z.key]!==undefined){X.values[Z.key]=W[Z.key]}else{X.values[Z.key]=Z.default_value}})},build_form:function(){var X=this;var W=$("<div />");$.each(this.params,function(ab,Z){if(!Z.hidden){var Y="param_"+ab;var ag=$("<div class='form-row' />").appendTo(W);ag.append($("<label />").attr("for",Y).text(Z.label+":"));if(Z.type==="bool"){ag.append($('<input type="checkbox" />').attr("id",Y).attr("name",Y).attr("checked",X.values[Z.key]))}else{if(Z.type==="color"){var ad=X.values[Z.key];var ac=$("<input />").attr("id",Y).attr("name",Y).val(ad);var ae=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var aa=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(ae);var af=$("<div/>").appendTo(aa).farbtastic({width:100,height:100,callback:ac,color:ad});$("<div />").append(ac).append(ae).appendTo(ag).bind("click",function(ah){ae.css({left:$(this).position().left+($(ac).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){ae.hide();$(document).unbind("click.color-picker")});ah.stopPropagation()})}else{ag.append($("<input />").attr("id",Y).attr("name",Y).val(X.values[Z.key]))}}}});return W},update_from_form:function(W){var Y=this;var X=false;$.each(this.params,function(Z,ab){if(!ab.hidden){var ac="param_"+Z;var aa=W.find("#"+ac).val();if(ab.type==="float"){aa=parseFloat(aa)}else{if(ab.type==="int"){aa=parseInt(aa)}else{if(ab.type==="bool"){aa=W.find("#"+ac).is(":checked")}}}if(aa!==Y.values[ab.key]){Y.values[ab.key]=aa;X=true}}});if(X){this.onchange()}}});var b=function(W,X,Y){this.track=W;this.canvas=X;this.histo_max=Y};var k=function(X,W,aa,Y,Z){this.name=X;this.view=W;this.parent_element=aa;this.data_url=(Y?Y:default_data_url);this.data_url_extra_params={};this.data_query_wait=(Z?Z:F);this.dataset_check_url=converted_datasets_state_url;this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){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.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)};extend(k.prototype,{init:function(){var W=this;W.enabled=false;W.tile_cache.clear();W.data_cache.clear();W.initial_canvas=undefined;W.content_div.css("height","auto");W.container_div.removeClass("nodata error pending");if(!W.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:W.hda_ldda,dataset_id:W.dataset_id,chrom:W.view.chrom},function(X){if(!X||X==="error"||X.kind==="error"){W.container_div.addClass("error");W.content_div.text(m);if(X.message){var Z=W.view.tracks.indexOf(W);var Y=$(" <a href='javascript:void(0);'></a>").text("View error").bind("click",function(){show_modal("Trackster Error","<pre>"+X.message+"</pre>",{Close:hide_modal})});W.content_div.append(Y)}}else{if(X==="no converter"){W.container_div.addClass("error");W.content_div.text(E)}else{if(X==="no data"||(X.data!==undefined&&(X.data===null||X.data.length===0))){W.container_div.addClass("nodata");W.content_div.text(A)}else{if(X==="pending"){W.container_div.addClass("pending");W.content_div.text(p);setTimeout(function(){W.init()},W.data_query_wait)}else{if(X.status==="data"){if(X.valid_chroms){W.valid_chroms=X.valid_chroms;W.make_name_popup_menu()}W.content_div.text(R);if(W.view.chrom){W.content_div.text("");W.content_div.css("height",W.height_px+"px");W.enabled=true;$.when(W.predraw_init()).done(function(){W.draw()})}}}}}}})},predraw_init:function(){},update_name:function(W){this.old_name=this.name;this.name=W;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)}});var H=function(X,ad,ag){var Y=this,ah=Y.view;this.filters=(X!==undefined?v(X):[]);this.filters_available=false;this.filters_visible=false;this.tool=(ad!==undefined&&obj_length(ad)>0?new n(this,ad):undefined);this.parent_track=ag;this.child_tracks=[];if(Y.hidden){return}var af=function(ai,aj,ak){ai.click(function(){var al=aj.text();max=parseFloat(ak.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(ak.slider("option","values")){input_size=2*input_size+1;multi_value=true}aj.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",al).appendTo(aj).focus().select().click(function(am){am.stopPropagation()}).blur(function(){$(this).remove();aj.text(al)}).keyup(function(aq){if(aq.keyCode===27){$(this).trigger("blur")}else{if(aq.keyCode===13){var ao=ak.slider("option","min"),am=ak.slider("option","max"),ap=function(ar){return(isNaN(ar)||ar>am||ar<ao)},an=$(this).val();if(!multi_value){an=parseFloat(an);if(ap(an)){alert("Parameter value must be in the range ["+ao+"-"+am+"]");return $(this)}}else{an=an.split("-");an=[parseFloat(an[0]),parseFloat(an[1])];if(ap(an[0])||ap(an[1])){alert("Parameter value must be in the range ["+ao+"-"+am+"]");return $(this)}}ak.slider((multi_value?"values":"value"),an)}}})})};if(this.parent_track){this.header_div.find(".draghandle").removeClass("draghandle").addClass("child-track-icon").addClass("icon-button");this.parent_element.addClass("child-track");this.tool=undefined}this.filters_div=$("<div/>").addClass("filters").hide();this.header_div.after(this.filters_div);this.filters_div.bind("drag",function(ai){ai.stopPropagation()}).bind("click",function(ai){ai.stopPropagation()}).bind("dblclick",function(ai){ai.stopPropagation()});$.each(this.filters,function(ao,aj){var al=$("<div/>").addClass("slider-row").appendTo(Y.filters_div);var ai=$("<div/>").addClass("slider-label").appendTo(al);var aq=$("<span/>").addClass("slider-name").text(aj.name+" ").appendTo(ai);var ak=$("<span/>");var am=$("<span/>").addClass("slider-value").appendTo(ai).append("[").append(ak).append("]");var ap=$("<div/>").addClass("slider").appendTo(al);aj.control_element=$("<div/>").attr("id",aj.name+"-filter-control").appendTo(ap);var an=[0,0];aj.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(ar,at){an=at.values;ak.text(at.values[0]+"-"+at.values[1]);setTimeout(function(){if(at.values[0]==an[0]&&at.values[1]==an[1]){var au=at.values;ak.text(au[0]+"-"+au[1]);aj.low=au[0];aj.high=au[1];Y.draw(true,true)}},50)},change:function(ar,at){aj.control_element.slider("option","slide").call(aj.control_element,ar,at)}});aj.slider=aj.control_element;aj.slider_label=ak;af(am,ak,aj.control_element);$("<div style='clear: both;'/>").appendTo(al)});if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}Y.child_tracks_container=$("<div/>").addClass("child-tracks-container").hide();Y.container_div.append(Y.child_tracks_container);if(Y.display_modes!==undefined){if(Y.mode_div===undefined){Y.mode_div=$("<div class='right-float menubutton popup' />").appendTo(Y.header_div);var aa=(Y.track_config&&Y.track_config.values.mode?Y.track_config.values.mode:Y.display_modes[0]);Y.mode=aa;Y.mode_div.text(aa);var Z=function(ai){Y.mode_div.text(ai);Y.mode=ai;Y.track_config.values.mode=ai;Y.tile_cache.clear();Y.draw()};var W={};for(var ab=0,ae=Y.display_modes.length;ab<ae;ab++){var ac=Y.display_modes[ab];W[ac]=function(ai){return function(){Z(ai)}}(ac)}make_popupmenu(Y.mode_div,W)}else{Y.mode_div.hide()}}this.make_name_popup_menu()};extend(H.prototype,k.prototype,{make_name_popup_menu:function(){var X=this;var W={};W["Edit configuration"]=function(){var ad=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},ab=function(){X.track_config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ac=function(ae){if((ae.keyCode||ae.which)===27){ad()}else{if((ae.keyCode||ae.which)===13){ab()}}};$(window).bind("keypress.check_enter_esc",ac);show_modal("Configure Track",X.track_config.build_form(),{Cancel:ad,OK:ab})};if(X.filters_available>0){var aa=(X.filters_div.is(":visible")?"Hide filters":"Show filters");W[aa]=function(){X.filters_visible=(X.filters_div.is(":visible"));X.filters_div.toggle();X.make_name_popup_menu()}}if(X.tool){var aa=(X.dynamic_tool_div.is(":visible")?"Hide tool":"Show tool");W[aa]=function(){if(!X.dynamic_tool_div.is(":visible")){X.update_name(X.name+X.tool_region_and_parameters_str())}else{menu_option_text="Show dynamic tool";X.revert_name()}X.dynamic_tool_div.toggle();X.make_name_popup_menu()}}if(X.valid_chroms){W["List chrom/contigs with data"]=function(){show_modal("Chrom/contigs with data","<p>"+X.valid_chroms.join("<br/>")+"</p>",{Close:function(){hide_modal()}})}}var Y=view;var Z=function(){$("#no-tracks").show()};if(this.parent_track){Y=this.parent_track;Z=function(){}}W.Remove=function(){Y.remove_track(X);if(Y.num_tracks===0){Z()}};make_popupmenu(X.name_div,W)},draw:function(W,Z){var an=this.view.low,ac=this.view.high,ae=ac-an,ag=this.view.container.width(),ab=ag/ae,ah=this.view.resolution,aa=$("<div style='position: relative;'></div>");if(!Z){this.content_div.children().remove()}this.content_div.append(aa);this.max_height=0;var aj=Math.floor(an/ah/J);var Y={};while((aj*J*ah)<ac){var am=ag+"_"+ab+"_"+aj;var ad=this.tile_cache.get(am);var ak=aj*J*this.view.resolution;var X=ak+J*this.view.resolution;if(!W&&ad){this.show_tile(ad,aa,ak,ab)}else{this.delayed_draw(W,am,ak,X,aj,ah,aa,ab,Y)}aj+=1}var af=this;var al=setInterval(function(){if(obj_length(Y)===0){clearInterval(al);if(Z){var aq=af.content_div.children();var ap=false;for(var ar=aq.length-1,ao=0;ar>=ao;ar--){var av=$(aq[ar]);if(ap){av.remove()}else{if(av.children().length!==0){ap=true}}}}for(var au=0;au<af.filters.length;au++){af.filters[au].update_ui_elt()}var at=false;if(af.example_feature){for(var au=0;au<af.filters.length;au++){if(af.filters[au].applies_to(af.example_feature)){at=true;break}}}if(af.filters_available!==at){af.filters_available=at;if(!af.filters_available){af.filters_div.hide()}af.make_name_popup_menu()}}},50);for(var ai=0;ai<this.child_tracks.length;ai++){this.child_tracks[ai].draw(W,Z)}},delayed_draw:function(X,ae,ac,ag,Y,aa,af,ah,ab){var Z=this;var ad=function(ap,ai,ak,aj,an,ao,al){returned_tile=Z.draw_tile(ai,ak,aj,an,ao,al);var am=$("<div class='track-tile'>").prepend(returned_tile);tile_element=am;Z.tile_cache.set(ae,tile_element);Z.show_tile(tile_element,an,ac,ao);delete ab[ap]};var W=setTimeout(function(){if(ac<=Z.view.high&&ag>=Z.view.low){var ai=(X?undefined:Z.tile_cache.get(ae));if(ai){Z.show_tile(ai,af,ac,ah);delete ab[W]}else{$.when(Z.data_cache.get_data(view.chrom,ac,ag,Z.mode,aa,Z.data_url_extra_params)).then(function(aj){if(view.reference_track&&ah>view.canvas_manager.char_width_px){$.when(view.reference_track.data_cache.get_data(view.chrom,ac,ag,Z.mode,aa,view.reference_track.data_url_extra_params)).then(function(ak){ad(W,aj,aa,Y,af,ah,ak)})}else{ad(W,aj,aa,Y,af,ah)}})}}},50);ab[W]=true},show_tile:function(W,ab,Z,ac){var X=this;var Y=this.view.high-this.view.low,aa=(Z-this.view.low)*ac;if(this.left_offset){aa-=this.left_offset}W.css({position:"absolute",top:0,left:aa,height:""});ab.append(W);X.max_height=Math.max(X.max_height,W.height());X.content_div.css("height",X.max_height+"px");ab.children().css("height",X.max_height+"px")},set_overview:function(){var W=this.view;if(this.initial_canvas&&this.is_overview){W.overview_close.show();W.overview_viewport.append(this.initial_canvas);W.overview_highlight.show().height(this.initial_canvas.height());W.overview_viewport.height(this.initial_canvas.height()+W.overview_box.height())}$(window).trigger("resize")},tool_region_and_parameters_str:function(Y,W,Z){var X=this,aa=(Y!==undefined&&W!==undefined&&Z!==undefined?Y+":"+W+"-"+Z:"all");return" - region=["+aa+"], parameters=["+X.tool.get_param_values().join(", ")+"]"},add_track:function(W){W.track_id=this.track_id+"_"+this.child_tracks.length;W.container_div.attr("id","track_"+W.track_id);this.child_tracks_container.append(W.container_div);B(W.container_div,".child-track-icon");if(!$(this.child_tracks_container).is(":visible")){this.child_tracks_container.show()}this.child_tracks.push(W);this.view.has_changes=true},remove_track:function(W){W.container_div.fadeOut("slow",function(){$(this).remove()})}});var T=function(W,X){this.track_type="LabelTrack";this.hidden=true;k.call(this,null,W,X);this.container_div.addClass("label-track")};extend(T.prototype,k.prototype,{draw:function(){var Y=this.view,Z=Y.high-Y.low,ac=Math.floor(Math.pow(10,Math.floor(Math.log(Z)/Math.log(10)))),W=Math.floor(Y.low/ac)*ac,aa=this.view.container.width(),X=$("<div style='position: relative; height: 1.3em;'></div>");while(W<Y.high){var ab=(W-Y.low)/Z*aa;X.append($("<div class='label'>"+commatize(W)+"</div>").css({position:"absolute",left:ab-1}));W+=ac}this.content_div.children(":first").remove();this.content_div.append(X)}});var x=function(W){this.track_type="ReferenceTrack";this.hidden=true;k.call(this,null,W,W.top_labeltrack);H.call(this);W.reference_track=this;this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:W.dbkey};this.data_cache=new K(y,this,false);this.tile_cache=new c(q)};extend(x.prototype,H.prototype,{draw_tile:function(ag,ab,X,ad,ah){var aa=this,Y=J*ab;if(ah>this.view.canvas_manager.char_width_px){if(ag===null){aa.content_div.css("height","0px");return}var Z=this.view.canvas_manager.new_canvas();var af=Z.getContext("2d");Z.width=Math.ceil(Y*ah+aa.left_offset);Z.height=aa.height_px;af.font=af.canvas.manager.default_font;af.textAlign="center";for(var ac=0,ae=ag.length;ac<ae;ac++){var W=Math.round(ac*ah);af.fillText(ag[ac],W+aa.left_offset,10)}return Z}this.content_div.css("height","0px")}});var l=function(aa,Y,ab,W,Z){var X=this;this.track_type="LineTrack";this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";k.call(this,aa,Y,Y.viewport_container);H.call(this);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=ab;this.dataset_id=W;this.original_dataset_id=W;this.data_cache=new K(y,this);this.tile_cache=new c(q);this.track_config=new S({track:this,params:[{key:"color",label:"Color",type:"color",default_value:"black"},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.height_px,hidden:true}],saved_values:Z,onchange:function(){X.vertical_range=X.prefs.max_value-X.prefs.min_value;$("#linetrack_"+X.track_id+"_minval").text(X.prefs.min_value);$("#linetrack_"+X.track_id+"_maxval").text(X.prefs.max_value);X.tile_cache.clear();X.draw()}});this.prefs=this.track_config.values;this.height_px=this.track_config.values.height;this.vertical_range=this.track_config.values.max_value-this.track_config.values.min_value;this.add_resize_handle()};extend(l.prototype,H.prototype,{add_resize_handle:function(){var W=this;var Z=false;var Y=false;var X=$("<div class='track-resize'>");$(W.container_div).hover(function(){Z=true;X.show()},function(){Z=false;if(!Y){X.hide()}});X.hide().bind("dragstart",function(aa,ab){Y=true;ab.original_height=$(W.content_div).height()}).bind("drag",function(ab,ac){var aa=Math.min(Math.max(ac.original_height+ac.deltaY,W.min_height_px),W.max_height_px);$(W.content_div).css("height",aa);W.height_px=aa;W.draw(true)}).bind("dragend",function(aa,ab){W.tile_cache.clear();Y=false;if(!Z){X.hide()}W.track_config.values.height=W.height_px}).appendTo(W.container_div)},predraw_init:function(){var W=this,X=W.view.tracks.indexOf(W);W.vertical_range=undefined;return $.getJSON(W.data_url,{stats:true,chrom:W.view.chrom,low:null,high:null,hda_ldda:W.hda_ldda,dataset_id:W.dataset_id},function(Y){W.container_div.addClass("line-track");var aa=Y.data;if(isNaN(parseFloat(W.prefs.min_value))||isNaN(parseFloat(W.prefs.max_value))){W.prefs.min_value=aa.min;W.prefs.max_value=aa.max;$("#track_"+X+"_minval").val(W.prefs.min_value);$("#track_"+X+"_maxval").val(W.prefs.max_value)}W.vertical_range=W.prefs.max_value-W.prefs.min_value;W.total_frequency=aa.total_frequency;W.container_div.find(".yaxislabel").remove();var ab=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+X+"_minval").text(t(W.prefs.min_value));var Z=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+X+"_maxval").text(t(W.prefs.max_value));Z.css({position:"absolute",top:"24px",left:"10px"});Z.prependTo(W.container_div);ab.css({position:"absolute",bottom:"2px",left:"10px"});ab.prependTo(W.container_div)})},draw_tile:function(ah,aa,X,ae,ag){if(this.vertical_range===undefined){return}var ab=X*J*aa,Z=J*aa,W=Math.ceil(Z*ag),ad=this.height_px;var Y=this.view.canvas_manager.new_canvas();Y.width=W,Y.height=ad;var af=Y.getContext("2d");var ac=new G.LinePainter(ah.data,ab,ab+Z,this.prefs.min_value,this.prefs.max_value,this.prefs.color,this.mode);ac.draw(af,W,ad);return Y}});var e=function(W,ab,aa,ae,ad,Y,Z,ac){var X=this;this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];this.track_config=new S({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ad,onchange:function(){X.tile_cache.clear();X.draw()}});this.prefs=this.track_config.values;k.call(this,W,ab,ab.viewport_container);H.call(this,Y,Z,ac);this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=aa;this.dataset_id=ae;this.original_dataset_id=ae;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.inc_slots={};this.start_end_dct={};this.tile_cache=new c(d);this.data_cache=new K(20,this);this.left_offset=200;this.painter=G.LinkedFeaturePainter};extend(e.prototype,H.prototype,{update_auto_mode:function(W){if(this.mode=="Auto"){if(W=="no_detail"){W="reduced to feature spans"}else{if(W=="summary_tree"){W="reduced to coverage histogram"}}this.mode_div.text("Auto ("+W+")")}},incremental_slots:function(aa,X,Z){var Y=this.view.canvas_manager.dummy_context,W=this.inc_slots[aa];if(!W||(W.mode!==Z)){W=new (o.FeatureSlotter)(aa,Z==="Pack",w,function(ab){return Y.measureText(ab)});W.mode=Z;this.inc_slots[aa]=W}return W.slot_features(X)},draw_tile:function(ai,aq,av,ae,ag,Z){var an=this,ax=av*J*aq,X=(av+1)*J*aq,ak=X-ax,ao=Math.ceil(ak*ag),am=this.mode,aB=25,aa=this.left_offset,aj,ab;if(am==="Auto"){if(ai.dataset_type==="summary_tree"){am=ai.dataset_type}else{if(ai.extra_info==="no_detail"){am="no_detail"}else{var aA=ai.data;if((aA.length&&aA.length<4)||(this.view.high-this.view.low>D)){am="Squish"}else{am="Pack"}}}this.update_auto_mode(am)}if(am==="summary_tree"){ab=this.summary_draw_height;ae.parent().css("height",Math.max(this.height_px,ab)+"px");this.container_div.find(".yaxislabel").remove();var W=$("<div />").addClass("yaxislabel");W.text(ai.max);W.css({position:"absolute",top:"22px",left:"10px"});W.prependTo(this.container_div);var Y=this.view.canvas_manager.new_canvas();Y.width=ao+aa;Y.height=ab+L;var ay=new G.SummaryTreePainter(ai.data,ai.delta,ai.max,ax,X,this.prefs.show_counts);var ap=Y.getContext("2d");ap.translate(aa,L);ay.draw(ap,ao,ab);return Y}var aj,ad=1;if(am==="no_detail"||am==="Squish"||am==="Pack"){ad=this.incremental_slots(ag,ai.data,am);aj=this.inc_slots[ag].slots}var af=[];if(ai.data){for(var ar=0,au=ai.data.length;ar<au;ar++){var ac=ai.data[ar];var at=false;var ah;for(var aw=0,az=this.filters.length;aw<az;aw++){ah=this.filters[aw];ah.update_attrs(ac);if(!ah.keep(ac)){at=true;break}}if(!at){af.push(ac)}}}var ay=new (this.painter)(af,ax,X,this.prefs,am,Z);var ab=ay.get_required_height(ad)+z;var Y=this.view.canvas_manager.new_canvas();Y.width=ao+aa;Y.height=ab;ae.parent().css("height",Math.max(this.height_px,ab)+"px");var ap=Y.getContext("2d");ap.fillStyle=this.prefs.block_color;ap.font=ap.canvas.manager.default_font;ap.textAlign="right";this.container_div.find(".yaxislabel").remove();if(ai.message){$(Y).css({"border-top":"1px solid red"});ap.fillStyle="red";ap.textAlign="left";var al=ap.textBaseline;ap.textBaseline="top";ap.fillText(ai.message,aa,0);ap.textBaseline=al;if(!ai.data){return Y}}this.example_feature=(ai.data.length?ai.data[0]:undefined);ap.translate(aa,z);ay.draw(ap,ao,ab,aj);return Y}});var M=function(Z,X,ab,W,Y,aa){e.call(this,Z,X,ab,W,Y,aa);this.track_type="VcfTrack";this.painter=G.VariantPainter};extend(M.prototype,H.prototype,e.prototype);var P=function(Z,X,ab,W,Y,aa){e.call(this,Z,X,ab,W,Y,aa);this.track_config=new S({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:Y,onchange:function(){this.track.tile_cache.clear();this.track.draw()}});this.prefs=this.track_config.values;this.track_type="ReadTrack";this.painter=G.ReadPainter;this.make_name_popup_menu()};extend(P.prototype,H.prototype,e.prototype);var N=function(aa,Y,ac,W,Z,ab,X){e.call(this,aa,Y,ac,W,Z,ab,{},X);this.track_type="ToolDataFeatureTrack";this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};extend(N.prototype,H.prototype,e.prototype,{predraw_init:function(){var X=this;var W=function(){if(X.data_cache.size()===0){setTimeout(W,300)}else{X.data_url=default_data_url;X.data_query_wait=F;X.dataset_state_url=converted_datasets_state_url;$.getJSON(X.dataset_state_url,{dataset_id:X.dataset_id,hda_ldda:X.hda_ldda},function(Y){})}};W()}});Q.View=U;Q.LineTrack=l;Q.FeatureTrack=e;Q.ReadTrack=P};var slotting_module=function(c,b){var d=2,a=5;b.FeatureSlotter=function(h,g,e,f){this.slots={};this.start_end_dct={};this.w_scale=h;this.include_label=g;this.max_rows=e;this.measureText=f};extend(b.FeatureSlotter.prototype,{slot_features:function(l){var o=this.w_scale,r=this.slots,g=this.start_end_dct,x=[],z=[],m=0,y=this.max_rows;for(var v=0,w=l.length;v<w;v++){var k=l[v],n=k[0];if(r[n]!==undefined){m=Math.max(m,r[n]);z.push(r[n])}else{x.push(v)}}var p=function(F,G){for(var E=0;E<=y;E++){var C=false,H=g[E];if(H!==undefined){for(var B=0,D=H.length;B<D;B++){var A=H[B];if(G>A[0]&&F<A[1]){C=true;break}}}if(!C){return E}}return -1};for(var v=0,w=x.length;v<w;v++){var k=l[x[v]],n=k[0],t=k[1],e=k[2],q=k[3],f=Math.floor(t*o),j=Math.ceil(e*o),u=this.measureText(q).width,h;if(q!==undefined&&this.include_label){u+=(d+a);if(f-u>=0){f-=u;h="left"}else{j+=u;h="right"}}var s=p(f,j);if(s>=0){if(g[s]===undefined){g[s]=[]}g[s].push([f,j]);r[n]=s;m=Math.max(m,s)}else{}}return m+1}})};var painters_module=function(k,A){var q=function(L,D,J,C,I,G){if(G===undefined){G=4}var F=C-D;var E=I-J;var H=Math.floor(Math.sqrt(F*F+E*E)/G);var M=F/H;var K=E/H;var B;for(B=0;B<H;B++,D+=M,J+=K){if(B%2!==0){continue}L.fillRect(D,J,G,1)}};var r=function(D,C,B,G){var F=C-G/2,E=C+G/2,H=B-Math.sqrt(G*3/2);D.beginPath();D.moveTo(F,H);D.lineTo(E,H);D.lineTo(C,B);D.lineTo(F,H);D.strokeStyle=this.fillStyle;D.fill();D.stroke();D.closePath()};var v=function(E,G,C,F,B,D){this.data=E;this.delta=G;this.max=C;this.view_start=F;this.view_end=B;this.show_counts=D};v.prototype.draw=function(O,B,N){var G=this.view_start,Q=this.view_end-this.view_start,P=B/Q;var L=this.data,K=this.delta,I=this.max,D=N;delta_x_px=Math.ceil(K*P);O.save();for(var E=0,F=L.length;E<F;E++){var J=Math.floor((L[E][0]-G)*P);var H=L[E][1];if(!H){continue}var M=H/I*N;O.fillStyle="black";O.fillRect(J,D-M,delta_x_px,M);var C=4;if(this.show_counts&&(O.measureText(H).width+C)<delta_x_px){O.fillStyle="#666";O.textAlign="center";O.fillText(H,J+(delta_x_px/2),10)}}O.restore()};var c=function(E,H,B,C,G,D,F){this.data=E;this.view_start=H;this.view_end=B;this.min_value=C;this.max_value=G;this.color=D;this.mode=F;this.overflow_color="#F66"};c.prototype.draw=function(Q,P,N){var I=false,J=this.min_value,G=this.max_value,M=G-J,C=N,D=this.view_start,O=this.view_end-this.view_start,E=P/O,K=this.mode,U=this.data;Q.save();var V=Math.round(N+J/M*N);if(K!=="Intensity"){Q.fillStyle="#aaa";Q.fillRect(0,V,P,1)}Q.beginPath();Q.fillStyle=this.color;var T,H,F;if(U.length>1){F=Math.ceil((U[1][0]-U[0][0])*E)}else{F=10}for(var R=0,S=U.length;R<S;R++){T=Math.round((U[R][0]-D)*E);H=U[R][1];if(H===null){if(I&&K==="Filled"){Q.lineTo(T,C)}I=false;continue}if(H<J){H=J}else{if(H>G){H=G}}if(K==="Histogram"){H=Math.round(H/M*C);Q.fillRect(T,V,F,-H)}else{if(K==="Intensity"){H=255-Math.floor((H-J)/M*255);Q.fillStyle="rgb("+H+","+H+","+H+")";Q.fillRect(T,0,F,C)}else{H=Math.round(C-(H-J)/M*C);if(I){Q.lineTo(T,H)}else{I=true;if(K==="Filled"){Q.moveTo(T,C);Q.lineTo(T,H)}else{Q.moveTo(T,H)}}}}}if(K==="Filled"){if(I){Q.lineTo(T,V);Q.lineTo(0,V)}Q.fill()}else{Q.stroke()}var B=-1,L=-1;Q.fillStyle=this.overflow_color;for(var R=0,S=U.length;R<S;R++){H=U[R][1];T=Math.round((U[R][0]-D)*E);x_minus_scaled=Math.round((U[R][0]-1-D)*E);if(L>=0&&(H===null||H<G)){Q.fillRect(L,0,x_minus_scaled-L+1,2);L=-1}else{if(B>=0&&(H===null||H>J)){Q.fillRect(B,N-2,x_minus_scaled-B+1,2);B=-1}}if(H!==null&&H>G&&L<0){L=T}else{if(H!==null&&H<J&&B<0){B=T}}}Q.restore()};var p=function(D,F,B,C,E){this.data=D;this.view_start=F;this.view_end=B;this.prefs=C;this.mode=E};extend(p.prototype,{get_required_height:function(C){var B=y_scale=this.get_row_height(),D=this.mode;if(D==="no_detail"||D==="Squish"||D==="Pack"){B=C*y_scale}return B+Math.max(Math.round(y_scale/2),5)},draw:function(N,E,M,J){var H=this.data,K=this.view_start,O=this.view_end;N.save();N.fillStyle=this.prefs.block_color;N.textAlign="right";var R=this.view_end-this.view_start,Q=E/R,D=this.get_row_height();for(var G=0,I=H.length;G<I;G++){var P=H[G],F=P[0],B=P[1],C=P[2],L=(J&&J[F]!==undefined?J[F]:null);if((B<O&&C>K)&&(this.mode=="Dense"||L!==null)){this.draw_element(N,this.mode,P,L,K,O,Q,D,E)}}N.restore()}});var d=10,j=3,n=5,z=10,g=1,t=3,f=3,a=9,o=2,h="#ccc";var s=function(D,F,B,C,E){p.call(this,D,F,B,C,E)};extend(s.prototype,p.prototype,{get_row_height:function(){var C=this.mode,B;if(C==="Dense"){B=d}else{if(C==="no_detail"){B=j}else{if(C==="Squish"){B=n}else{B=z}}}return B},draw_element:function(N,G,V,I,P,af,aj,ak,B){var S=V[0],ah=V[1],Z=V[2]-1,Q=V[3],aa=Math.floor(Math.max(0,(ah-P)*aj)),O=Math.ceil(Math.min(B,Math.max(0,(Z-P)*aj))),Y=(G==="Dense"?0:(0+I))*ak,M,ad,R=null,al=null,E=this.prefs.block_color,ac=this.prefs.label_color;if(G=="Dense"){I=1}if(G==="no_detail"){N.fillStyle=E;N.fillRect(aa,Y+5,O-aa,g)}else{var L=V[4],X=V[5],ab=V[6],F=V[7];if(X&&ab){R=Math.floor(Math.max(0,(X-P)*aj));al=Math.ceil(Math.min(B,Math.max(0,(ab-P)*aj)))}var ai,T;if(G==="Squish"||G==="Dense"){ai=1;T=f}else{ai=5;T=a}if(!F){if(V.strand){if(V.strand==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand_inv")}else{if(V.strand==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand_inv")}}}else{N.fillStyle=E}N.fillRect(aa,Y,O-aa,T)}else{var K,U;if(G==="Squish"||G==="Dense"){N.fillStyle=h;K=Y+Math.floor(f/2)+1;U=1}else{if(L){var K=Y;var U=T;if(L==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand")}else{if(L==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand")}}}else{N.fillStyle=h;K+=(f/2)+1;U=1}}N.fillRect(aa,K,O-aa,U);for(var ag=0,D=F.length;ag<D;ag++){var H=F[ag],C=Math.floor(Math.max(0,(H[0]-P)*aj)),W=Math.ceil(Math.min(B,Math.max((H[1]-1-P)*aj)));if(C>W){continue}N.fillStyle=E;N.fillRect(C,Y+(T-ai)/2+1,W-C,ai);if(R!==undefined&&ab>X&&!(C>al||W<R)){var ae=Math.max(C,R),J=Math.min(W,al);N.fillRect(ae,Y+1,J-ae,T);if(F.length==1&&G=="Pack"){if(L==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand_inv")}else{if(L==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand_inv")}}if(ae+14<J){ae+=2;J-=2}N.fillRect(ae,Y+1,J-ae,T)}}}}if(G==="Pack"&&ah>P){N.fillStyle=ac;if(P===0&&aa-N.measureText(Q).width<0){N.textAlign="left";N.fillText(Q,O+o,Y+8)}else{N.textAlign="right";N.fillText(Q,aa-o,Y+8)}N.fillStyle=E}}}});var b=function(D,F,B,C,E){p.call(this,D,F,B,C,E)};extend(b.prototype,p.prototype,{draw_element:function(U,P,J,F,X,D,M,V,S){var J=data[i],L=J[0],T=J[1],E=J[2]-1,O=J[3],H=Math.floor(Math.max(0,(T-X)*M)),K=Math.ceil(Math.min(S,Math.max(0,(E-X)*M))),G=(P==="Dense"?0:(0+F))*V,B,Y,C=null,N=null;if(no_label){U.fillStyle=block_color;U.fillRect(H+left_offset,G+5,K-H,1)}else{var W=J[4],R=J[5],I=J[6];B=9;Y=1;U.fillRect(H+left_offset,G,K-H,B);if(P!=="Dense"&&O!==undefined&&T>X){U.fillStyle=label_color;if(X===0&&H-U.measureText(O).width<0){U.textAlign="left";U.fillText(O,K+2+left_offset,G+8)}else{U.textAlign="right";U.fillText(O,H-2+left_offset,G+8)}U.fillStyle=block_color}var Q=W+" / "+R;if(T>X&&U.measureText(Q).width<(K-H)){U.fillStyle="white";U.textAlign="center";U.fillText(Q,left_offset+H+(K-H)/2,G+8);U.fillStyle=block_color}}}});var y=1001,m=1002,e=1003,x=1004,l=1005;var w=function(F,C){var H=F[0],G=F[1],E=C[0],D=C[1],B;if(H<E){if(G<E){B=y}else{if(G<=D){B=e}else{B=m}}}else{if(H>D){B=y}else{if(G<=D){B=l}else{B=x}}}return B};var u=function(E,G,B,D,F,C){p.call(this,E,G,B,D,F);this.ref_seq=C};extend(u.prototype,p.prototype,{get_row_height:function(){var B,C=this.mode;if(C==="Dense"){B=d}else{if(C==="Squish"){B=n}else{B=z;if(this.prefs.show_insertions){B*=2}}}return B},draw_read:function(Y,T,O,ad,D,X,L,I,H){Y.textAlign="center";var W=this,C=[ad,D],R=0,Z=0,V=0;ref_seq=this.ref_seq,char_width_px=Y.canvas.manager.char_width_px;var ai=[];if((T==="Pack"||this.mode==="Auto")&&I!==undefined&&O>char_width_px){V=Math.round(O/2)}if(!L){L=[[0,I.length]]}for(var P=0,ab=L.length;P<ab;P++){var M=L[P],E="MIDNSHP=X"[M[0]],Q=M[1];if(E==="H"||E==="S"){R-=Q}var J=X+R,ah=Math.floor(Math.max(0,(J-ad)*O)),K=Math.floor(Math.max(0,(J+Q-ad)*O));switch(E){case"H":break;case"S":case"M":case"=":var S=w([J,J+Q],C);if(S!==y){var U=I.slice(Z,Z+Q);if(V>0){Y.fillStyle=this.prefs.block_color;Y.fillRect(ah-V,H+1,K-ah,9);Y.fillStyle=h;for(var af=0,B=U.length;af<B;af++){if(this.prefs.show_differences&&ref_seq){var N=ref_seq[J-ad+af];if(!N||N.toLowerCase()===U[af].toLowerCase()){continue}}if(J+af>=ad&&J+af<=D){var ag=Math.floor(Math.max(0,(J+af-ad)*O));Y.fillText(U[af],ag,H+9)}}}else{Y.fillStyle=this.prefs.block_color;Y.fillRect(ah,H+4,K-ah,f)}}Z+=Q;R+=Q;break;case"N":Y.fillStyle=h;Y.fillRect(ah-V,H+5,K-ah,1);R+=Q;break;case"D":Y.fillStyle="red";Y.fillRect(ah-V,H+4,K-ah,3);R+=Q;break;case"P":break;case"I":var S=w([J,J+Q],C),ac=ah-V;if(S!==y){var U=I.slice(Z,Z+Q);if(this.prefs.show_insertions){var G=ah-(K-ah)/2;if((T==="Pack"||this.mode==="Auto")&&I!==undefined&&O>char_width_px){Y.fillStyle="yellow";Y.fillRect(G-V,H-9,K-ah,9);ai[ai.length]={type:"triangle",data:[ac,H+4,5]};Y.fillStyle=h;switch(S){case (e):U=U.slice(ad-J);break;case (x):U=U.slice(0,J-D);break;case (l):break;case (m):U=U.slice(ad-J,J-D);break}for(var af=0,B=U.length;af<B;af++){var ag=Math.floor(Math.max(0,(J+af-ad)*O));Y.fillText(U[af],ag-(K-ah)/2,H)}}else{Y.fillStyle="yellow";Y.fillRect(G,H+(this.mode!=="Dense"?2:5),K-ah,(T!=="Dense"?f:t))}}else{if((T==="Pack"||this.mode==="Auto")&&I!==undefined&&O>char_width_px){ai[ai.length]={type:"text",data:[U.length,ac,H+9]}}else{}}}Z+=Q;break;case"X":Z+=Q;break}}Y.fillStyle="yellow";var ae,F,aj;for(var aa=0;aa<ai.length;aa++){ae=ai[aa];F=ae.type;aj=ae.data;if(F==="text"){Y.save();Y.font="bold "+Y.font;Y.fillText(aj[0],aj[1],aj[2]);Y.restore()}else{if(F=="triangle"){r(Y,aj[0],aj[1],aj[2])}}}},draw_element:function(U,P,H,E,X,C,L,V,S){var K=H[0],T=H[1],D=H[2],M=H[3],G=Math.floor(Math.max(0,(T-X)*L)),I=Math.ceil(Math.min(S,Math.max(0,(D-X)*L))),F=(P==="Dense"?0:(0+E))*V,Y=this.prefs.block_color,J=this.prefs.label_color,R=0;if((P==="Pack"||this.mode==="Auto")&&L>U.canvas.manager.char_width_px){var R=Math.round(L/2)}U.fillStyle=Y;if(H[5] instanceof Array){var Q=Math.floor(Math.max(0,(H[4][0]-X)*L)),O=Math.ceil(Math.min(S,Math.max(0,(H[4][1]-X)*L))),N=Math.floor(Math.max(0,(H[5][0]-X)*L)),B=Math.ceil(Math.min(S,Math.max(0,(H[5][1]-X)*L)));if(H[4][1]>=X&&H[4][0]<=C&&H[4][2]){this.draw_read(U,P,L,X,C,H[4][0],H[4][2],H[4][3],F)}if(H[5][1]>=X&&H[5][0]<=C&&H[5][2]){this.draw_read(U,P,L,X,C,H[5][0],H[5][2],H[5][3],F)}if(N>O){U.fillStyle=h;q(U,O-R,F+5,N-R,F+5)}}else{U.fillStyle=Y;this.draw_read(U,P,L,X,C,T,H[4],H[5],F)}if(P==="Pack"&&T>X){U.fillStyle=this.prefs.label_color;var W=1;if(W===0&&G-U.measureText(M).width<0){U.textAlign="left";U.fillText(M,I+o-R,F+8)}else{U.textAlign="right";U.fillText(M,G-o-R,F+8)}U.fillStyle=Y}}});A.SummaryTreePainter=v;A.LinePainter=c;A.LinkedFeaturePainter=s;A.ReadPainter=u;A.VariantPainter=b};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("slotting",slotting_module);a("painters",painters_module);a("trackster",trackster_module);for(key in c.trackster){d[key]=c.trackster[key]}})(window);
\ No newline at end of file
--- a/static/scripts/trackster.js Sun Mar 27 19:50:50 2011 -0400
+++ b/static/scripts/trackster.js Tue Apr 05 13:57:14 2011 -0400
@@ -2,56 +2,79 @@
2010-2011: James Taylor, Kanwei Li, Jeremy Goecks
*/
-/**
- * Draw a dashed line on a canvas using filled rectangles. This function is based on:
- * http://vetruvet.blogspot.com/2010/10/drawing-dashed-lines-on-html5-canvas.h…
- * However, that approach uses lines, which don't seem to render as well, so use
- * rectangles instead.
- */
-CanvasRenderingContext2D.prototype.dashedLine = function(x1, y1, x2, y2, dashLen) {
- if (dashLen === undefined) { dashLen = 4; }
- var dX = x2 - x1;
- var dY = y2 - y1;
- var dashes = Math.floor(Math.sqrt(dX * dX + dY * dY) / dashLen);
- var dashX = dX / dashes;
- var dashY = dY / dashes;
- var q;
-
- for (q = 0; q < dashes; q++, x1 += dashX, y1 += dashY) {
- if (q % 2 !== 0) {
- continue;
+/** Simple extend function for inheritence */
+var extend = function() {
+ var target = arguments[0];
+ for ( var i = 1; i < arguments.length; i++ ) {
+ var other = arguments[i];
+ for ( key in other ) {
+ target[key] = other[key];
}
- this.fillRect(x1, y1, dashLen, 1);
}
};
+// Encapsulate -- anything to be availabe outside this block is added to exports
+var trackster_module = function(require, exports){
+
+var slotting = require('slotting'),
+ painters = require('painters');
+
+// ---- Canvas management and extensions ----
+
/**
- * Draw an isosceles triangle that points down.
+ * Canvas manager is used to create canvases, for browsers, this deals with
+ * backward comparibility using excanvas, as well as providing a pattern cache
*/
-CanvasRenderingContext2D.prototype.drawDownwardEquilateralTriangle = function(down_vertex_x, down_vertex_y, side_len) {
- // Compute other two points of triangle.
- var
- x1 = down_vertex_x - side_len/2,
- x2 = down_vertex_x + side_len/2,
- y = down_vertex_y - Math.sqrt( side_len*3/2 );
-
- // Draw and fill.
- this.beginPath();
- this.moveTo(x1, y);
- this.lineTo(x2, y);
- this.lineTo(down_vertex_x, down_vertex_y);
- this.lineTo(x1, y);
+var CanvasManager = function( document, default_font ) {
+ this.document = document;
+ this.default_font = default_font !== undefined ? default_font : "9px Monaco, Lucida Console, monospace";
+
+ this.dummy_canvas = this.new_canvas();
+ this.dummy_context = this.dummy_canvas.getContext('2d');
+ this.dummy_context.font = this.default_font;
+
+ this.char_width_px = this.dummy_context.measureText("A").width;
+
+ this.patterns = {};
- this.strokeStyle = this.fillStyle;
- this.fill();
- this.stroke();
- this.closePath();
-};
+ // FIXME: move somewhere to make this more general
+ this.load_pattern( 'right_strand', "/visualization/strand_right.png" );
+ this.load_pattern( 'left_strand', "/visualization/strand_left.png" );
+ this.load_pattern( 'right_strand_inv', "/visualization/strand_right_inv.png" );
+ this.load_pattern( 'left_strand_inv', "/visualization/strand_left_inv.png" );
+}
+
+extend( CanvasManager.prototype, {
+ load_pattern: function( key, path ) {
+ var patterns = this.patterns,
+ dummy_context = this.dummy_context,
+ image = new Image();
+ // FIXME: where does image_path come from? not in browser.mako...
+ image.src = image_path + path;
+ image.onload = function() {
+ patterns[key] = dummy_context.createPattern( image, "repeat" );
+ }
+ },
+ get_pattern: function( key ) {
+ return this.patterns[key];
+ },
+ new_canvas: function() {
+ var canvas = this.document.createElement("canvas");
+ // If using excanvas in IE, we need to explicately attach the canvas
+ // methods to the DOM element
+ if (window.G_vmlCanvasManager) { G_vmlCanvasManager.initElement(canvas); }
+ // Keep a reference back to the manager
+ canvas.manager = this;
+ return canvas;
+ }
+});
+
+// ---- Web UI specific utilities ----
/**
* Make `element` sortable in parent by dragging `handle` (a selector)
*/
-function sortable( element, handle ) {
+var sortable = function( element, handle ) {
element.bind( "drag", { handle: handle, relative: true }, function ( e, d ) {
var parent = $(this).parent();
var children = parent.children();
@@ -77,47 +100,11 @@
}
/**
- * Compute the type of overlap between two regions. They are assumed to be on the same chrom/contig.
- * The overlap is computed relative to the second region; hence, OVERLAP_START indicates that the first
- * region overlaps the start (but not the end) of the second region.
+ * Calculates step for slider with a given min, max.
*/
-var NO_OVERLAP = 1001, CONTAINS = 1002, OVERLAP_START = 1003, OVERLAP_END = 1004, CONTAINED_BY = 1005;
-function compute_overlap(first_region, second_region) {
- var
- first_start = first_region[0], first_end = first_region[1],
- second_start = second_region[0], second_end = second_region[1],
- overlap;
- if (first_start < second_start) {
- if (first_end < second_start) {
- overlap = NO_OVERLAP;
- }
- else if (first_end <= second_end) {
- overlap = OVERLAP_START;
- }
- else { // first_end > second_end
- overlap = CONTAINS;
- }
- }
- else { // first_start >= second_start
- if (first_start > second_end) {
- overlap = NO_OVERLAP;
- }
- else if (first_end <= second_end) {
- overlap = CONTAINED_BY;
- }
- else {
- overlap = OVERLAP_END;
- }
- }
-
- return overlap;
-}
-
-/**
- * Returns true if there is any overlap between regions.
- */
-function is_overlap(first_region, second_region) {
- return (compute_overlap(first_region, second_region) !== NO_OVERLAP);
+var get_slider_step = function(min, max) {
+ var range = max - min;
+ return (range <= 2 ? 0.01 : (range <= 100 ? 1 : (range <= 1000 ? 5 : 10)));
}
/**
@@ -126,30 +113,21 @@
var
// Drawing constants; track height is (constant) height of track, and feature height is the
// height of individual features within tracks. Feature height, then, should always be less
- // than track height.
- DENSE_TRACK_HEIGHT = 10,
- NO_DETAIL_TRACK_HEIGHT = 3,
- SQUISH_TRACK_HEIGHT = 5,
- PACK_TRACK_HEIGHT = 10,
- NO_DETAIL_FEATURE_HEIGHT = 1,
- DENSE_FEATURE_HEIGHT = 1,
- SQUISH_FEATURE_HEIGHT = 3,
- PACK_FEATURE_HEIGHT = 9,
+ // than track height.
+ CHAR_HEIGHT_PX = 9, // FIXME: font size may not be static
ERROR_PADDING = 10, // Padding at the top of tracks for error messages
- LABEL_SPACING = 2,
- PACK_SPACING = 5,
+ SUMMARY_TREE_TOP_PADDING = CHAR_HEIGHT_PX + 2,
+ // Maximum number of rows un a slotted track
+ MAX_FEATURE_DEPTH = 100,
// Minimum width for window for squish to be used.
MIN_SQUISH_VIEW_WIDTH = 12000,
// Other constants.
- DEFAULT_FONT = "9px Monaco, Lucida Console, monospace",
DENSITY = 200,
FEATURE_LEVELS = 10,
- MAX_FEATURE_DEPTH = 100,
DEFAULT_DATA_QUERY_WAIT = 5000,
// Maximum number of chromosomes that are selectable at any one time.
MAX_CHROMS_SELECTABLE = 100,
- CONNECTOR_COLOR = "#ccc",
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.",
@@ -159,41 +137,7 @@
DATA_OK = "Ready for display",
CACHED_TILES_FEATURE = 10,
CACHED_TILES_LINE = 5,
- CACHED_DATA = 5,
- DUMMY_CANVAS = document.createElement("canvas"),
- RIGHT_STRAND, LEFT_STRAND;
-
-// Get information for rendering canvas elements.
-if (window.G_vmlCanvasManager) {
- G_vmlCanvasManager.initElement(DUMMY_CANVAS);
-}
-var
- CONTEXT = DUMMY_CANVAS.getContext("2d");
-CONTEXT.font = DEFAULT_FONT; // To ensure consistent measureText width
-var
- CHAR_WIDTH_PX = CONTEXT.measureText("A").width,
- CHAR_HEIGHT_PX = 9; // Taken from DEFAULT_FONT.
-
-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");
-};
+ CACHED_DATA = 5;
function round_1000(num) {
return Math.round(num * 1000) / 1000;
@@ -206,7 +150,7 @@
this.num_elements = num_elements;
this.clear();
};
-$.extend(Cache.prototype, {
+extend(Cache.prototype, {
get: function(key) {
var index = this.key_ary.indexOf(key);
if (index !== -1) {
@@ -250,15 +194,25 @@
this.track = track;
this.subset = (subset !== undefined ? subset : true);
};
-$.extend(DataManager.prototype, Cache.prototype, {
+extend(DataManager.prototype, Cache.prototype, {
/**
* Load data from server; returns AJAX object so that use of Deferred is possible.
*/
load_data: function(chrom, low, high, mode, resolution, extra_params) {
+ // Setup data request params.
var params = {"chrom": chrom, "low": low, "high": high, "mode": mode,
"resolution": resolution, "dataset_id" : this.track.dataset_id,
"hda_ldda": this.track.hda_ldda};
$.extend(params, extra_params);
+
+ // Add track filters to params.
+ var filter_names = [];
+ for (var i = 0; i < this.track.filters.length; i++) {
+ filter_names[filter_names.length] = this.track.filters[i].name;
+ }
+ params.filter_cols = JSON.stringify(filter_names);
+
+ // Do request.
var manager = this;
return $.getJSON(this.track.data_url, params, function (result) {
manager.set_data(low, high, mode, result);
@@ -291,6 +245,8 @@
// the data was "index" or "data." Also could slice the data so that
// only data points in request are returned.
//
+
+ /* Disabling for now, more detailed data is never loaded for line tracks
if (this.subset) {
var key, split_key, entry_low, entry_high, mode, entry;
for (var i = 0; i < this.key_ary.length; i++) {
@@ -310,11 +266,13 @@
}
}
}
+ */
- //
- // Load data from server.
- //
- return this.load_data(chrom, low, high, mode, resolution, extra_params);
+ // Load data from server. The deferred is immediately saved until the
+ // data is ready, it then replaces itself with the actual data
+ entry = this.load_data(chrom, low, high, mode, resolution, extra_params);
+ this.set_data( low, high, mode, entry );
+ return entry
},
set_data: function(low, high, mode, result) {
//console.log("set_data", low, high, mode, result);
@@ -354,9 +312,10 @@
this.min_separation = 30;
this.has_changes = false;
this.init( callback );
+ this.canvas_manager = new CanvasManager( container.get(0).ownerDocument );
this.reset();
};
-$.extend( View.prototype, {
+extend( View.prototype, {
init: function( callback ) {
// Create DOM elements
var parent_element = this.container,
@@ -797,63 +756,175 @@
});
/**
- * Encapsulation of tools that users can apply to tracks/datasets.
+ * Encapsulation of a tool that users can apply to tracks/datasets.
*/
-var Tool = function(name, params) {
- this.name = name;
- this.params = params;
+var Tool = function(track, tool_dict) {
+ //
+ // Unpack tool information from dictionary.
+ //
+ this.track = track;
+ this.name = tool_dict.name;
+ this.params = [];
+ var params_dict = tool_dict.params;
+ for (var i = 0; i < params_dict.length; i++) {
+ var param_dict = params_dict[i],
+ name = param_dict.name,
+ label = param_dict.label,
+ html = unescape(param_dict.html),
+ type = param_dict.type;
+ if (type === "number") {
+ this.params[this.params.length] =
+ new NumberParameter(name, label, html, param_dict.min, param_dict.max);
+ }
+ else if (type == "select") {
+ this.params[this.params.length] = new ToolParameter(name, label, html);
+ }
+ else {
+ console.log("WARNING: unrecognized tool parameter type:", name, type);
+ }
+ }
+
+ //
+ // Create div elt for tool UI.
+ //
+ this.parent_div = $("<div/>").addClass("dynamic-tool").hide();
+ // Disable dragging, clicking, double clicking on div so that actions on slider do not impact viz.
+ this.parent_div.bind("drag", function(e) {
+ e.stopPropagation();
+ }).bind("click", function(e) {
+ e.stopPropagation();
+ }).bind("dblclick", function(e) {
+ e.stopPropagation();
+ });
+ var name_div = $("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);
+ var tool_params = this.params;
+ var tool = this;
+ $.each(this.params, function(index, param) {
+ var param_div = $("<div>").addClass("param-row").appendTo(tool.parent_div);
+ // Param label.
+ var label_div = $("<div>").addClass("param-label").text(param.label).appendTo(param_div);
+ // Param HTML.
+ // TODO: either generalize .slider CSS attributes or create new rule for tool input div.
+ var html_div = $("<div/>").addClass("slider").html(param.html).appendTo(param_div);
+
+ // Add to clear floating layout.
+ $("<div style='clear: both;'/>").appendTo(param_div);
+ });
+
+ // Highlight value for inputs for easy replacement.
+ this.parent_div.find("input").click(function() { $(this).select() });
+
+ // Add 'Go' button.
+ var run_tool_row = $("<div>").addClass("slider-row").appendTo(this.parent_div);
+ var run_tool_button = $("<input type='submit'>").attr("value", "Run").appendTo(run_tool_row);
+ var tool = this;
+ run_tool_button.click( function() {
+ tool.run();
+ });
};
-$.extend(Tool.prototype, {
- // Returns a dictionary of parameter values; key is parameter name, value
- // is parameter value.
+extend(Tool.prototype, {
+ /**
+ * Returns dictionary of parameter name-values.
+ */
get_param_values_dict: function() {
var param_dict = {};
- for (var i = 0; i < this.params.length; i++) {
- var param = this.params[i];
- param_dict[param.name] = param.value;
- }
+ this.parent_div.find(":input").each(function() {
+ var name = $(this).attr("name"), value = $(this).val();
+ param_dict[name] = JSON.stringify(value);
+ });
return param_dict;
},
- // Returns an array of parameter values.
+ /**
+ * Returns array of parameter values.
+ */
get_param_values: function() {
var param_values = [];
- for (var i = 0; i < this.params.length; i++) {
- param_values[i] = this.params[i].value;
+ var param_dict = {};
+ this.parent_div.find(":input").each(function() {
+ // Only include inputs with names; this excludes Run button.
+ var name = $(this).attr("name"), value = $(this).val();
+ if (name) {
+ param_values[param_values.length] = value;
+ }
+ });
+ return param_values;
+ },
+ /**
+ * Run tool. This creates a new child track, runs tool, and places tool's output in the new track.
+ */
+ run: function() {
+ // Put together params for running tool.
+ var url_params = {
+ dataset_id: this.track.original_dataset_id,
+ chrom: this.track.view.chrom,
+ low: this.track.view.low,
+ high: this.track.view.high,
+ tool_id: this.name
+ };
+ $.extend(url_params, this.get_param_values_dict());
+
+ //
+ // Create track for tool's output immediately to provide user feedback.
+ //
+ var
+ current_track = this.track,
+ // Set name of track to include tool name, parameters, and region used.
+ track_name = url_params.tool_id +
+ current_track.tool_region_and_parameters_str(url_params.chrom, url_params.low, url_params.high),
+ new_track;
+
+ // TODO: add support for other kinds of tool data tracks.
+ if (current_track.track_type === 'FeatureTrack') {
+ new_track = new ToolDataFeatureTrack(track_name, view, current_track.hda_ldda, undefined, {}, {}, current_track);
}
- return param_values;
+
+ this.track.add_track(new_track);
+ new_track.content_div.text("Starting job.");
+
+ // Run tool.
+ var json_run_tool = function() {
+ $.getJSON(run_tool_url, url_params, function(track_data) {
+ if (track_data === "no converter") {
+ // No converter available for input datasets, so cannot run tool.
+ new_track.container_div.addClass("error");
+ new_track.content_div.text(DATA_NOCONVERTER);
+ }
+ else if (track_data.error) {
+ // General error.
+ new_track.container_div.addClass("error");
+ new_track.content_div.text(DATA_CANNOT_RUN_TOOL + track_data.message);
+ }
+ else if (track_data === "pending") {
+ // Converting/indexing input datasets; show message and try again.
+ new_track.container_div.addClass("pending");
+ new_track.content_div.text("Converting input data so that it can be easily reused.");
+ setTimeout(json_run_tool, 2000);
+ }
+ else {
+ // Job submitted and running.
+ new_track.dataset_id = track_data.dataset_id;
+ new_track.content_div.text("Running job.");
+ new_track.init();
+ }
+ });
+ };
+ json_run_tool();
}
});
-var NumberToolParameter = function(name, label, min, max, init_value) {
+/**
+ * Tool parameters.
+ */
+var ToolParameter = function(name, label, html) {
this.name = name;
this.label = label;
+ this.html = html;
+};
+
+var NumberParameter = function(name, label, html, min, max) {
+ ToolParameter.call(this, name, label, html)
this.min = min;
this.max = max;
- this.value = init_value;
-}
-
-// Uses a dictionary to construct a tool object.
-var get_tool_from_dict = function(tool_dict) {
- if (obj_length(tool_dict) === 0) {
- return undefined;
- }
-
- // Get tool.
- var tool_name = tool_dict.name;
- var params_dict = tool_dict.params;
- var params = Array();
- for (var i = 0; i < params_dict.length; i++) {
- var param_dict = params_dict[i];
- var
- name = param_dict.name,
- label = param_dict.label,
- type = param_dict.type,
- min = param_dict.min,
- max = param_dict.max,
- value = param_dict.value;
- params[params.length] = new NumberToolParameter(name, label, min, max, value);
- }
- return new Tool(tool_name, params);
};
/**
@@ -864,6 +935,9 @@
this.index = index;
this.value = value;
};
+/**
+ * Number filters have a min, max as well as a low, high; low and high are used
+ */
var NumberFilter = function(name, index) {
this.name = name;
// Index into payload to filter.
@@ -872,21 +946,25 @@
this.low = -Number.MAX_VALUE;
this.high = Number.MAX_VALUE;
// Slide min/max. These values are used to set/update slider.
- this.slider_min = Number.MAX_VALUE;
- this.slider_max = -Number.MAX_VALUE;
+ this.min = Number.MAX_VALUE;
+ this.max = -Number.MAX_VALUE;
// UI Slider element and label that is associated with filter.
this.slider = null;
this.slider_label = null;
};
-$.extend(NumberFilter.prototype, {
- // Returns true if filter can be applied to element.
+extend(NumberFilter.prototype, {
+ /**
+ * Returns true if filter can be applied to element.
+ */
applies_to: function(element) {
if (element.length > this.index) {
return true;
}
return false;
},
- // Returns true iff element is in [low, high]; range is inclusive.
+ /**
+ * Returns true iff element is in [low, high]; range is inclusive.
+ */
keep: function(element) {
if ( !this.applies_to( element ) ) {
// No element to filter on.
@@ -894,7 +972,9 @@
}
return (element[this.index] >= this.low && element[this.index] <= this.high);
},
- // Update filter's min and max values based on element's values.
+ /**
+ * Update filter's min and max values based on element's values.
+ */
update_attrs: function(element) {
var updated = false;
if (!this.applies_to(element) ) {
@@ -902,29 +982,32 @@
}
// Update filter's min, max based on element values.
- if (element[this.index] < this.slider_min) {
- this.slider_min = element[this.index];
+ if (element[this.index] < this.min) {
+ this.min = Math.floor(element[this.index]);
updated = true;
}
- if (element[this.index] > this.slider_max) {
- this.slider_max = element[this.index];
- updated = false;
+ if (element[this.index] > this.max) {
+ this.max = Math.ceil(element[this.index]);
+ updated = true;
}
return updated;
},
- // Update filter's slider.
+ /**
+ * Update filter's slider.
+ */
update_ui_elt: function () {
var
slider_min = this.slider.slider("option", "min"),
slider_max = this.slider.slider("option", "max");
- if (this.slider_min < slider_min || this.slider_max > slider_max) {
- // Need to update slider.
- this.slider.slider("option", "min", this.slider_min);
- this.slider.slider("option", "max", this.slider_max);
+ if (this.min < slider_min || this.max > slider_max) {
+ // Update slider min, max, step.
+ this.slider.slider("option", "min", this.min);
+ this.slider.slider("option", "max", this.max);
+ this.slider.slider("option", "step", get_slider_step(this.min, this.max));
// Refresh slider:
// TODO: do we want to keep current values or reset to min/max?
// Currently we reset values:
- this.slider.slider("option", "values", [this.slider_min, this.slider_max]);
+ this.slider.slider("option", "values", [this.min, this.max]);
// To use the current values.
//var values = this.slider.slider( "option", "values" );
//this.slider.slider( "option", "values", values );
@@ -932,7 +1015,9 @@
}
});
-// Parse filters dict and return filters.
+/**
+ * Parse filters dict and return filters.
+ */
var get_filters_from_dict = function(filters_dict) {
var filters = [];
for (var i = 0; i < filters_dict.length; i++) {
@@ -947,6 +1032,9 @@
return filters;
};
+/**
+ * Container for track configuration data.
+ */
var TrackConfig = function( options ) {
this.track = options.track;
this.params = options.params;
@@ -956,7 +1044,7 @@
}
this.onchange = options.onchange
}
-$.extend( TrackConfig.prototype, {
+extend( TrackConfig.prototype, {
restore_values: function( values ) {
var track_config = this;
$.each( this.params, function( index, param ) {
@@ -1036,6 +1124,15 @@
});
/**
+ * Tiles for TiledTracks.
+ */
+var Tile = function(track, canvas, histo_max) {
+ this.track = track;
+ this.canvas = canvas;
+ this.histo_max = histo_max;
+};
+
+/**
* Tracks are objects can be added to the View.
*
* Track object hierarchy:
@@ -1078,7 +1175,7 @@
this.content_div = $("<div class='track-content'>").appendTo(this.container_div);
this.parent_element.append(this.container_div);
};
-$.extend( Track.prototype, {
+extend(Track.prototype, {
/**
* Initialize and draw the track.
*/
@@ -1159,7 +1256,7 @@
}
});
-var TiledTrack = function(filters, tool, parent_track) {
+var TiledTrack = function(filters, tool_dict, parent_track) {
var track = this,
view = track.view;
@@ -1168,7 +1265,7 @@
// filters_available is determined by data, filters_visible is set by user.
this.filters_available = false;
this.filters_visible = false;
- this.tool = (tool !== undefined ? get_tool_from_dict( tool ) : undefined);
+ this.tool = (tool_dict !== undefined && obj_length(tool_dict) > 0 ? new Tool(this, tool_dict) : undefined);
//
// TODO: Right now there is only the notion of a parent track and multiple child tracks. However,
@@ -1185,6 +1282,66 @@
// Init HTML elements for tool, filters.
//
+ // Function that supports inline text editing of slider values for tools, filters.
+ // Enable users to edit parameter's value via a text box.
+ var edit_slider_values = function(container, span, slider) {
+ container.click(function() {
+ var cur_value = span.text();
+ max = parseFloat(slider.slider("option", "max")),
+ input_size = (max <= 1 ? 4 : max <= 1000000 ? max.toString().length : 6),
+ multi_value = false;
+ // Increase input size if there are two values.
+ if (slider.slider("option", "values")) {
+ input_size = 2*input_size + 1;
+ multi_value = true;
+ }
+ span.text("");
+ // Temporary input for changing value.
+ $("<input type='text'/>").attr("size", input_size).attr("maxlength", input_size)
+ .attr("value", cur_value).appendTo(span).focus().select()
+ .click(function(e) {
+ // Don't want click to propogate up to values_span and restart everything.
+ e.stopPropagation();
+ }).blur(function() {
+ $(this).remove();
+ span.text(cur_value);
+ }).keyup(function(e) {
+ if (e.keyCode === 27) {
+ // Escape key.
+ $(this).trigger("blur");
+ } else if (e.keyCode === 13) {
+ //
+ // Enter/return key initiates callback. If new value(s) are in slider range,
+ // change value (which calls slider's change() function).
+ //
+ var slider_min = slider.slider("option", "min"),
+ slider_max = slider.slider("option", "max"),
+ invalid = function(a_val) {
+ return (isNaN(a_val) || a_val > slider_max || a_val < slider_min);
+ },
+ new_value = $(this).val();
+ if (!multi_value) {
+ new_value = parseFloat(new_value);
+ if (invalid(new_value)) {
+ alert("Parameter value must be in the range [" + slider_min + "-" + slider_max + "]");
+ return $(this);
+ }
+ }
+ else { // Multi value.
+ new_value = new_value.split("-");
+ new_value = [parseFloat(new_value[0]), parseFloat(new_value[1])];
+ if (invalid(new_value[0]) || invalid(new_value[1])) {
+ alert("Parameter value must be in the range [" + slider_min + "-" + slider_max + "]");
+ return $(this);
+ }
+ }
+ slider.slider((multi_value ? "values" : "value"), new_value);
+ }
+ });
+ });
+ };
+
+
// If track has parent:
// -replace drag handle with child-track icon button; (TODO: eventually, we'll want to be able
// to make a set of child tracks dragable.)
@@ -1201,6 +1358,8 @@
// Disable dragging, double clicking on div so that actions on slider do not impact viz.
this.filters_div.bind("drag", function(e) {
e.stopPropagation();
+ }).bind("click", function(e) {
+ e.stopPropagation();
}).bind("dblclick", function(e) {
e.stopPropagation();
});
@@ -1209,36 +1368,49 @@
// Set up filter label (name, values).
var filter_label = $("<div/>").addClass("slider-label").appendTo(filter_div)
- var name_span = $("<span/>").addClass("name").appendTo(filter_label);
- name_span.text(filter.name + " "); // Extra spacing to separate name and values
- var values_span = $("<span/>").addClass("values").appendTo(filter_label);
+ var name_span = $("<span/>").addClass("slider-name").text(filter.name + " ").appendTo(filter_label);
+ var values_span = $("<span/>");
+ var values_span_container = $("<span/>").addClass("slider-value").appendTo(filter_label).append("[").append(values_span).append("]");
// Set up slider for filter.
- // TODO: generate custom interaction elements based on filter type.
var slider_div = $("<div/>").addClass("slider").appendTo(filter_div);
filter.control_element = $("<div/>").attr("id", filter.name + "-filter-control").appendTo(slider_div);
+ var prev_values = [0,0];
filter.control_element.slider({
range: true,
min: Number.MAX_VALUE,
max: -Number.MIN_VALUE,
values: [0, 0],
slide: function(event, ui) {
- var values = ui.values;
- // Set new values in UI.
- values_span.text("[" + values[0] + "-" + values[1] + "]");
- // Set new values in filter.
- filter.low = values[0];
- filter.high = values[1];
- // Redraw track.
- track.draw(true, true);
+ //
+ // Always update UI values, but set timeout for doing more--especially drawing--
+ // so that viz is more responsive.
+ //
+ prev_values = ui.values;
+ values_span.text(ui.values[0] + "-" + ui.values[1]);
+ setTimeout(function() {
+ if (ui.values[0] == prev_values[0] && ui.values[1] == prev_values[1]) {
+ var values = ui.values;
+ // Set new values in UI.
+ values_span.text(values[0] + "-" + values[1]);
+ // Set new values in filter.
+ filter.low = values[0];
+ filter.high = values[1];
+ // Redraw track.
+ track.draw(true, true);
+ }
+ }, 50);
},
- change: function( event, ui ) {
- filter.control_element.slider("option", "slide").call( filter.control_element, event, ui );
+ change: function(event, ui) {
+ filter.control_element.slider("option", "slide").call(filter.control_element, event, ui);
}
});
filter.slider = filter.control_element;
filter.slider_label = values_span;
+ // Enable users to edit slider values via text box.
+ edit_slider_values(values_span_container, values_span, filter.control_element);
+
// Add to clear floating layout.
$("<div style='clear: both;'/>").appendTo(filter_div);
});
@@ -1247,102 +1419,8 @@
// Create dynamic tool div.
//
if (this.tool) {
- // Create div elt for tool UI.
- this.dynamic_tool_div = $("<div/>").addClass("dynamic-tool").hide();
+ this.dynamic_tool_div = this.tool.parent_div;
this.header_div.after(this.dynamic_tool_div);
- // Disable dragging, clicking, double clicking on div so that actions on slider do not impact viz.
- this.dynamic_tool_div.bind( "drag", function(e) {
- e.stopPropagation();
- }).bind("click", function( e ) {
- e.stopPropagation();
- }).bind("dblclick", function( e ) {
- e.stopPropagation();
- });
- var name_div = $("<div class='tool-name'>").appendTo(this.dynamic_tool_div).text(this.tool.name);
- var tool_params = this.tool.params;
- var track = this;
- $.each(this.tool.params, function(index, param) {
- var param_div = $("<div>").addClass("slider-row").appendTo(track.dynamic_tool_div);
-
- // Slider label.
- var label_div = $("<div>").addClass("slider-label").appendTo(param_div);
- var name_span = $("<span class='param-name'>").text(param.label + " ").appendTo(label_div);
- var values_span = $("<span/>").text(param.value);
- var values_span_container = $("<span class='param-value'>").appendTo(label_div).append("[").append(values_span).append("]");
-
- // Slider.
- var slider_div = $("<div/>").addClass("slider").appendTo(param_div);
- var slider = $("<div id='" + param.name + "-param-control'>").appendTo(slider_div);
- // Make step reasonable.
- var step = (param.max <= 1 ? 0.01 : (param.max <= 1000 ? 1 : 5));
- slider.slider({
- min: param.min,
- max: param.max,
- step: step,
- value: param.value,
- slide: function(event, ui) {
- var value = ui.value;
- param.value = value;
- // Set new value in UI.
- if (0 < value && value < 1) {
- value = parseFloat(value).toFixed(2);
- }
- values_span.text(value);
- },
- change: function(event, ui) {
- param.value = ui.value;
- }
- });
-
- // Enable users to edit parameter's value via a text box.
- values_span_container.click(function() {
- var span = values_span,
- cur_value = span.text(),
- // TODO: is there a better way to handle input size when param max is <= 1?
- input_size = (param.max <= 1 ? 4 : param.max.length);
- span.text("");
- // Temporary input for changing value.
- $("<input type='text'/>").attr("size", input_size).attr("maxlength", input_size)
- .attr("value", cur_value).appendTo(span).focus().select()
- .click(function(e) {
- // Don't want click to propogate up to values_span and restart everything.
- e.stopPropagation();
- }).blur(function() {
- $(this).remove();
- span.text(cur_value);
- }).keyup(function(e) {
- if ( e.keyCode === 27 ) {
- // Escape key.
- $(this).trigger("blur");
- } else if ( e.keyCode === 13 ) {
- // Enter/return key sets new value.
- var input = $(this),
- new_value = parseFloat(input.val());
- if (isNaN(new_value) || new_value > param.max || new_value < param.min) {
- // TODO: display popup menu instead of alert?
- alert("Parameter value must be in the range [" + param.min + "-" + param.max + "]");
- return $(this);
- }
- // Update value in three places; update param value last b/c slider updates param value
- // as well and slider may round values depending on its settings.
- span.text(new_value);
- slider.slider('value', new_value);
- param.value = new_value;
- }
- });
- });
-
- // Add to clear floating layout.
- $("<div style='clear: both;'/>").appendTo(param_div);
- });
-
- // Add 'Go' button.
- var run_tool_row = $("<div>").addClass("slider-row").appendTo(this.dynamic_tool_div);
- var run_tool_button = $("<input type='submit'>").attr("value", "Run").appendTo(run_tool_row);
- var track = this;
- run_tool_button.click( function() {
- track.run_tool();
- });
}
//
@@ -1403,7 +1481,7 @@
}
*/
};
-$.extend( TiledTrack.prototype, Track.prototype, {
+extend(TiledTrack.prototype, Track.prototype, {
/**
* Make popup menu for track name.
*/
@@ -1467,7 +1545,7 @@
//
if (track.tool) {
// Show/hide dynamic tool menu item.
- var text = (track.dynamic_tool_div.is(":visible") ? "Hide Tool" : "Show Tool");
+ var text = (track.dynamic_tool_div.is(":visible") ? "Hide tool" : "Show tool");
track_dropdown[text] = function() {
// Set track name, toggle tool div, and remake menu.
if (!track.dynamic_tool_div.is(":visible")) {
@@ -1521,10 +1599,10 @@
high = this.view.high,
range = high - low,
width = this.view.container.width(),
- resolution = this.view.resolution;
-
- var parent_element = $("<div style='position: relative;'></div>"),
- w_scale = width / range;
+ // w_scale units are pixels per base.
+ w_scale = width / range,
+ resolution = this.view.resolution,
+ parent_element = $("<div style='position: relative;'></div>");
if (!clear_after) { this.content_div.children().remove(); }
this.content_div.append( parent_element );
@@ -1551,15 +1629,17 @@
}
//
- // Actions to take after tiles have been drawn:
- // (1) remove old tile(s);
- // (2) update filtering UI elements.
+ // Post-draw actions:
//
- if (clear_after) {
- var track = this;
- var intervalId = setInterval(function() {
- if (obj_length(draw_tile_dict) === 0) {
- // All tiles have been drawn; clear out track content in order to show the most recent content.
+ var track = this;
+ var intervalId = setInterval(function() {
+ if (obj_length(draw_tile_dict) === 0) {
+ // All tiles have been drawn.
+ clearInterval(intervalId);
+
+ // Clear tiles?
+ if (clear_after) {
+ // Clear out track content in order to show the most recent content.
// Most recent content is the div with children (tiles) most recently appended to track.
// However, do not delete recently-appended empty content as calls to draw() may still be active
// and using these divs.
@@ -1575,12 +1655,38 @@
remove = true;
}
}
+ }
+
+ //
+ // Update filter attributes, UI.
+ //
- // Method complete; do not call it again.
- clearInterval(intervalId);
+ // Update filtering UI.
+ for (var f = 0; f < track.filters.length; f++) {
+ track.filters[f].update_ui_elt();
}
- }, 50);
- }
+
+ // Determine if filters are available; this is based on the example feature.
+ var filters_available = false;
+ if (track.example_feature) {
+ for (var f = 0; f < track.filters.length; f++) {
+ if (track.filters[f].applies_to(track.example_feature)) {
+ filters_available = true;
+ break;
+ }
+ }
+ }
+
+ // If filter availability changed, hide filter div if necessary and update menu.
+ if (track.filters_available !== filters_available) {
+ track.filters_available = filters_available;
+ if (!track.filters_available) {
+ track.filters_div.hide();
+ }
+ track.make_name_popup_menu();
+ }
+ }
+ }, 50);
//
// Draw child tracks.
@@ -1593,6 +1699,8 @@
var track = this;
// Put a 50ms delay on drawing so that if the user scrolls fast, we don't load extra data
var draw_and_show_tile = function(id, result, resolution, tile_index, parent_element, w_scale, seq_data) {
+ // DEBUG: this is still called too many times when moving slowly,
+ // console.log( "draw_and_show_tile", resolution, tile_index, w_scale );
returned_tile = track.draw_tile(result, resolution, tile_index, parent_element, w_scale, seq_data)
// Wrap element in div for background
@@ -1631,23 +1739,17 @@
// Really draw tile: get data, seq data if available, and draw tile.
//
$.when(track.data_cache.get_data(view.chrom, tile_low, tile_high, track.mode,
- resolution, track.data_url_extra_params)).then(function() {
- // Data available for track.
- var result = track.data_cache.get_data(view.chrom, tile_low, tile_high, track.mode,
- resolution, track.data_url_extra_params);
+ resolution, track.data_url_extra_params)).then(function(tile_data) {
// If sequence data needed, get that and draw. Otherwise draw.
- if (view.reference_track && w_scale > CHAR_WIDTH_PX) {
+ if (view.reference_track && w_scale > view.canvas_manager.char_width_px) {
$.when(view.reference_track.data_cache.get_data(view.chrom, tile_low, tile_high,
track.mode, resolution,
- view.reference_track.data_url_extra_params)).then(function() {
- var seq_data = view.reference_track.data_cache.get_data(view.chrom, tile_low, tile_high,
- track.mode, resolution,
- view.reference_track.data_url_extra_params);
- draw_and_show_tile(id, result, resolution, tile_index, parent_element, w_scale, seq_data);
+ view.reference_track.data_url_extra_params)).then(function(seq_data) {
+ draw_and_show_tile(id, tile_data, resolution, tile_index, parent_element, w_scale, seq_data);
});
}
else {
- draw_and_show_tile(id, result, resolution, tile_index, parent_element, w_scale);
+ draw_and_show_tile(id, tile_data, resolution, tile_index, parent_element, w_scale);
}
});
}
@@ -1678,40 +1780,7 @@
parent_element.append(tile_element);
track.max_height = Math.max(track.max_height, tile_element.height());
track.content_div.css("height", track.max_height + "px");
- parent_element.children().css("height", track.max_height + "px");
-
- if (track.hidden) { return; }
-
- //
- // Update filter attributes, UI.
- // TODO: this could be done after all tiles are drawn, but there's no reliable way to detect
- // that right now.
- //
-
- // Update filtering UI.
- for (var f = 0; f < track.filters.length; f++) {
- track.filters[f].update_ui_elt();
- }
-
- // Determine if filters are available; this is based on the example feature.
- var filters_available = false;
- if (track.example_feature) {
- for (var f = 0; f < track.filters.length; f++) {
- if (track.filters[f].applies_to(track.example_feature)) {
- filters_available = true;
- break;
- }
- }
- }
-
- // If filter availability changed, hide filter div if necessary and update menu.
- if (track.filters_available !== filters_available) {
- track.filters_available = filters_available;
- if (!track.filters_available) {
- track.filters_div.hide();
- }
- track.make_name_popup_menu();
- }
+ parent_element.children().css("height", track.max_height + "px");
},
// Set track as the overview track in the visualization.
set_overview: function() {
@@ -1725,66 +1794,6 @@
}
$(window).trigger("resize");
},
- // Run track's tool.
- run_tool: function() {
- // Put together params for running tool.
- var url_params = {
- dataset_id: this.original_dataset_id,
- chrom: this.view.chrom,
- low: this.view.low,
- high: this.view.high,
- tool_id: this.tool.name
- };
- $.extend(url_params, this.tool.get_param_values_dict());
-
- //
- // Create track for tool's output immediately to provide user feedback.
- //
- var
- current_track = this,
- // Set name of track to include tool name, parameters, and region used.
- track_name = url_params.tool_id +
- current_track.tool_region_and_parameters_str(url_params.chrom, url_params.low, url_params.high),
- new_track;
-
- // TODO: add support for other kinds of tool data tracks.
- if (current_track.track_type === 'FeatureTrack') {
- new_track = new ToolDataFeatureTrack(track_name, view, current_track.hda_ldda, undefined, {}, {}, current_track);
- }
-
- this.add_track(new_track);
- new_track.content_div.text("Starting job.");
- view.has_changes = true;
-
- // Run tool.
- var json_run_tool = function() {
- $.getJSON(run_tool_url, url_params, function(track_data) {
- if (track_data === "no converter") {
- // No converter available for input datasets, so cannot run tool.
- new_track.container_div.addClass("error");
- new_track.content_div.text(DATA_NOCONVERTER);
- }
- else if (track_data.error) {
- // General error.
- new_track.container_div.addClass("error");
- new_track.content_div.text(DATA_CANNOT_RUN_TOOL + track_data.message);
- }
- else if (track_data === "pending") {
- // Converting/indexing input datasets; show message and try again.
- new_track.container_div.addClass("pending");
- new_track.content_div.text("Converting input data so that it can be easily reused.");
- setTimeout(json_run_tool, 2000);
- }
- else {
- // Job submitted and running.
- new_track.dataset_id = track_data.dataset_id;
- new_track.content_div.text("Running job.");
- new_track.init();
- }
- });
- };
- json_run_tool();
- },
/**
* Utility function that creates a label string describing the region and parameters of a track's tool.
*/
@@ -1808,6 +1817,7 @@
this.child_tracks_container.show();
}
this.child_tracks.push(child_track);
+ this.view.has_changes = true;
},
/**
* Remove a child track from this track.
@@ -1823,7 +1833,7 @@
Track.call( this, null, view, parent_element );
this.container_div.addClass( "label-track" );
};
-$.extend( LabelTrack.prototype, Track.prototype, {
+extend( LabelTrack.prototype, Track.prototype, {
draw: function() {
var view = this.view,
range = view.high - view.low,
@@ -1854,7 +1864,6 @@
view.reference_track = this;
this.left_offset = 200;
this.height_px = 12;
- this.font = DEFAULT_FONT;
this.container_div.addClass( "reference-track" );
this.content_div.css("background", "none");
this.content_div.css("min-height", "0px");
@@ -1864,7 +1873,7 @@
this.data_cache = new DataManager(CACHED_DATA, this, false);
this.tile_cache = new Cache(CACHED_TILES_LINE);
};
-$.extend(ReferenceTrack.prototype, TiledTrack.prototype, {
+extend(ReferenceTrack.prototype, TiledTrack.prototype, {
/**
* Draw ReferenceTrack tile.
*/
@@ -1872,19 +1881,16 @@
var track = this,
tile_length = DENSITY * resolution;
- if (w_scale > CHAR_WIDTH_PX) {
+ if (w_scale > this.view.canvas_manager.char_width_px) {
if (seq === null) {
track.content_div.css("height", "0px");
return;
}
- var canvas = document.createElement("canvas");
- if (window.G_vmlCanvasManager) { G_vmlCanvasManager.initElement(canvas); } // EXCANVAS HACK
- canvas = $(canvas);
-
- var ctx = canvas.get(0).getContext("2d");
- canvas.get(0).width = Math.ceil( tile_length * w_scale + track.left_offset);
- canvas.get(0).height = track.height_px;
- ctx.font = DEFAULT_FONT;
+ var canvas = this.view.canvas_manager.new_canvas();
+ var ctx = canvas.getContext("2d");
+ canvas.width = Math.ceil( tile_length * w_scale + track.left_offset);
+ canvas.height = track.height_px;
+ ctx.font = ctx.canvas.manager.default_font;
ctx.textAlign = "center";
for (var c = 0, str_len = seq.length; c < str_len; c++) {
var c_start = Math.round(c * w_scale);
@@ -1938,10 +1944,14 @@
this.height_px = this.track_config.values.height;
this.vertical_range = this.track_config.values.max_value - this.track_config.values.min_value;
- // Add control for resizing
- // Trickery here to deal with the hovering drag handle, can probably be
- // pulled out and reused.
- (function( track ){
+ this.add_resize_handle();
+};
+extend(LineTrack.prototype, TiledTrack.prototype, {
+ add_resize_handle: function () {
+ // Add control for resizing
+ // Trickery here to deal with the hovering drag handle, can probably be
+ // pulled out and reused.
+ var track = this;
var in_handle = false;
var in_drag = false;
var drag_control = $( "<div class='track-resize'>" )
@@ -1969,9 +1979,7 @@
if ( ! in_handle ) { drag_control.hide(); }
track.track_config.values.height = track.height_px;
}).appendTo( track.container_div );
- })(this);
-};
-$.extend(LineTrack.prototype, TiledTrack.prototype, {
+ },
predraw_init: function() {
var track = this,
track_id = track.view.tracks.indexOf(track);
@@ -2012,98 +2020,22 @@
return;
}
- var track = this,
- tile_low = tile_index * DENSITY * resolution,
+ var tile_low = tile_index * DENSITY * resolution,
tile_length = DENSITY * resolution,
- key = resolution + "_" + tile_index,
- params = { hda_ldda: this.hda_ldda, dataset_id: this.dataset_id, resolution: this.view.resolution };
+ width = Math.ceil( tile_length * w_scale ),
+ height = this.height_px;
+ // Create canvas
+ var canvas = this.view.canvas_manager.new_canvas();
+ canvas.width = width,
+ canvas.height = height;
- var canvas = document.createElement("canvas"),
- data = result.data;
- if (window.G_vmlCanvasManager) { G_vmlCanvasManager.initElement(canvas); } // EXCANVAS HACK
- canvas = $(canvas);
-
- canvas.get(0).width = Math.ceil( tile_length * w_scale );
- canvas.get(0).height = track.height_px;
- var ctx = canvas.get(0).getContext("2d"),
- in_path = false,
- min_value = track.prefs.min_value,
- max_value = track.prefs.max_value,
- vertical_range = track.vertical_range,
- total_frequency = track.total_frequency,
- height_px = track.height_px,
- mode = track.mode;
-
- // Pixel position of 0 on the y axis
- var y_zero = Math.round( height_px + min_value / vertical_range * height_px );
-
- // Line at 0.0
- ctx.beginPath();
- ctx.moveTo( 0, y_zero );
- ctx.lineTo( tile_length * w_scale, y_zero );
- // ctx.lineWidth = 0.5;
- ctx.fillStyle = "#aaa";
- ctx.stroke();
+ // Paint line onto full canvas
+ var ctx = canvas.getContext("2d");
+ var painter = new painters.LinePainter( result.data, tile_low, tile_low + tile_length,
+ this.prefs.min_value, this.prefs.max_value, this.prefs.color, this.mode );
+ painter.draw( ctx, width, height );
- ctx.beginPath();
- ctx.fillStyle = track.prefs.color;
- var x_scaled, y, delta_x_px;
- if (data.length > 1) {
- delta_x_px = Math.ceil((data[1][0] - data[0][0]) * w_scale);
- } else {
- delta_x_px = 10;
- }
- for (var i = 0, len = data.length; i < len; i++) {
- x_scaled = Math.round((data[i][0] - tile_low) * w_scale);
- y = data[i][1];
- if (y === null) {
- if (in_path && mode === "Filled") {
- ctx.lineTo(x_scaled, height_px);
- }
- in_path = false;
- continue;
- }
- if (y < min_value) {
- y = min_value;
- } else if (y > max_value) {
- y = max_value;
- }
-
- if (mode === "Histogram") {
- // y becomes the bar height in pixels, which is the negated for canvas coords
- y = Math.round( y / vertical_range * height_px );
- ctx.fillRect(x_scaled, y_zero, delta_x_px, - y );
- } else if (mode === "Intensity" ) {
- y = 255 - Math.floor( (y - min_value) / vertical_range * 255 );
- ctx.fillStyle = "rgb(" +y+ "," +y+ "," +y+ ")";
- ctx.fillRect(x_scaled, 0, delta_x_px, height_px);
- } else {
- // console.log(y, track.min_value, track.vertical_range, (y - track.min_value) / track.vertical_range * track.height_px);
- y = Math.round( height_px - (y - min_value) / vertical_range * height_px );
- // console.log(canvas.get(0).height, canvas.get(0).width);
- if (in_path) {
- ctx.lineTo(x_scaled, y);
- } else {
- in_path = true;
- if (mode === "Filled") {
- ctx.moveTo(x_scaled, height_px);
- ctx.lineTo(x_scaled, y);
- } else {
- ctx.moveTo(x_scaled, y);
- }
- }
- }
- }
- if (mode === "Filled") {
- if (in_path) {
- ctx.lineTo( x_scaled, y_zero );
- ctx.lineTo( 0, y_zero );
- }
- ctx.fill();
- } else {
- ctx.stroke();
- }
return canvas;
}
});
@@ -2148,14 +2080,25 @@
this.show_labels_scale = 0.001;
this.showing_details = false;
this.summary_draw_height = 30;
- this.default_font = DEFAULT_FONT;
this.inc_slots = {};
this.start_end_dct = {};
this.tile_cache = new Cache(CACHED_TILES_FEATURE);
this.data_cache = new DataManager(20, this);
this.left_offset = 200;
+
+ this.painter = painters.LinkedFeaturePainter;
};
-$.extend(FeatureTrack.prototype, TiledTrack.prototype, {
+extend(FeatureTrack.prototype, TiledTrack.prototype, {
+ update_auto_mode: function( mode ) {
+ if ( this.mode == "Auto" ) {
+ if ( mode == "no_detail" ) {
+ mode = "reduced to feature spans";
+ } else if ( mode == "summary_tree" ) {
+ mode = "reduced to coverage histogram";
+ }
+ this.mode_div.text( "Auto (" + mode + ")" );
+ }
+ },
/**
* Place features in slots for drawing (i.e. pack features).
* this.inc_slots[level] is created in this method. this.inc_slots[level]
@@ -2164,27 +2107,292 @@
* Returns the number of slots used to pack features.
*/
incremental_slots: function(level, features, mode) {
- //
+
// Get/create incremental slots for level. If display mode changed,
// need to create new slots.
- //
- var inc_slots = this.inc_slots[level];
+
+ var dummy_context = this.view.canvas_manager.dummy_context,
+ inc_slots = this.inc_slots[level];
if (!inc_slots || (inc_slots.mode !== mode)) {
- inc_slots = {};
- inc_slots.w_scale = level;
+ inc_slots = new (slotting.FeatureSlotter)( level, mode === "Pack", MAX_FEATURE_DEPTH, function ( x ) { return dummy_context.measureText( x ) } );
inc_slots.mode = mode;
this.inc_slots[level] = inc_slots;
- this.start_end_dct[level] = {};
+ }
+
+ return inc_slots.slot_features( features );
+ },
+ /**
+ * Draw FeatureTrack tile.
+ */
+ draw_tile: function(result, resolution, tile_index, parent_element, w_scale, ref_seq) {
+ var track = this,
+ tile_low = tile_index * DENSITY * resolution,
+ tile_high = ( tile_index + 1 ) * DENSITY * resolution,
+ tile_span = tile_high - tile_low,
+ width = Math.ceil( tile_span * w_scale ),
+ mode = this.mode,
+ min_height = 25,
+ left_offset = this.left_offset,
+ slots,
+ required_height;
+
+ // Set display mode if Auto.
+ if (mode === "Auto") {
+ if (result.dataset_type === "summary_tree") {
+ mode = result.dataset_type;
+ } else if (result.extra_info === "no_detail") {
+ mode = "no_detail";
+ } else {
+ // Choose b/t Squish and Pack.
+ // Proxy measures for using Squish:
+ // (a) error message re: limiting number of features shown;
+ // (b) X number of features shown;
+ // (c) size of view shown.
+ // TODO: cannot use (a) and (b) because it requires coordinating mode across tiles;
+ // fix this so that tiles are redrawn as necessary to use the same mode.
+ //if ( (result.message && result.message.match(/^Only the first [\d]+/)) ||
+ // (result.data && result.data.length > 2000) ||
+ var data = result.data;
+ if ( (data.length && data.length < 4) ||
+ (this.view.high - this.view.low > MIN_SQUISH_VIEW_WIDTH) ) {
+ mode = "Squish";
+ } else {
+ mode = "Pack";
+ }
+ }
+ this.update_auto_mode( mode );
}
- //
+ // Drawing the summary tree (feature coverage histogram)
+ if ( mode === "summary_tree" ) {
+ // Set height of parent_element
+ required_height = this.summary_draw_height;
+ parent_element.parent().css("height", Math.max(this.height_px, required_height) + "px");
+ // Add label to container div showing maximum count
+ // TODO: this shouldn't be done at the tile level
+ this.container_div.find(".yaxislabel").remove();
+ var max_label = $("<div />").addClass('yaxislabel');
+ max_label.text( result.max );
+ max_label.css({ position: "absolute", top: "22px", left: "10px" });
+ max_label.prependTo(this.container_div);
+ // Create canvas
+ var canvas = this.view.canvas_manager.new_canvas();
+ canvas.width = width + left_offset;
+ // Extra padding at top of summary tree
+ canvas.height = required_height + SUMMARY_TREE_TOP_PADDING;
+ // Paint summary tree into canvas
+ var painter = new painters.SummaryTreePainter( result.data, result.delta, result.max, tile_low, tile_high, this.prefs.show_counts );
+ var ctx = canvas.getContext("2d");
+ // Deal with left_offset by translating
+ ctx.translate( left_offset, SUMMARY_TREE_TOP_PADDING );
+ painter.draw( ctx, width, required_height );
+ // Canvas element is returned
+ return canvas;
+ }
+
+ // Start dealing with row-by-row tracks
+
+ // If working with a mode where slotting is neccesary, update the incremental slotting
+ var slots, slots_required = 1;
+ if ( mode === "no_detail" || mode === "Squish" || mode === "Pack" ) {
+ slots_required = this.incremental_slots(w_scale, result.data, mode);
+ slots = this.inc_slots[w_scale].slots;
+ }
+
+ // Filter features
+ var filtered = [];
+ if ( result.data ) {
+ for (var i = 0, len = result.data.length; i < len; i++) {
+ var feature = result.data[i];
+ var hide_feature = false;
+ var filter;
+ for (var f = 0, flen = this.filters.length; f < flen; f++) {
+ filter = this.filters[f];
+ filter.update_attrs(feature);
+ if (!filter.keep(feature)) {
+ hide_feature = true;
+ break;
+ }
+ }
+ if (!hide_feature) {
+ filtered.push( feature );
+ }
+ }
+ }
+
+ // Create painter, and canvas of sufficient size to contain all features
+ // HACK: ref_seq will only be defined for ReadTracks, and only the ReadPainter accepts that argument
+ var painter = new (this.painter)( filtered, tile_low, tile_high, this.prefs, mode, ref_seq );
+ // FIXME: ERROR_PADDING is an ugly gap most of the time
+ var required_height = painter.get_required_height( slots_required ) + ERROR_PADDING;
+ var canvas = this.view.canvas_manager.new_canvas();
+
+ canvas.width = width + left_offset;
+ canvas.height = required_height;
+
+ parent_element.parent().css("height", Math.max(this.height_px, required_height) + "px");
+ // console.log(( tile_low - this.view.low ) * w_scale, tile_index, w_scale);
+ var ctx = canvas.getContext("2d");
+ ctx.fillStyle = this.prefs.block_color;
+ ctx.font = ctx.canvas.manager.default_font;
+ ctx.textAlign = "right";
+ this.container_div.find(".yaxislabel").remove();
+
+ // If there is a message, draw it on canvas so that it moves around with canvas, and make the border red
+ // to indicate region where message is applicable
+ if (result.message) {
+ $(canvas).css({
+ "border-top": "1px solid red"
+ });
+
+ ctx.fillStyle = "red";
+ ctx.textAlign = "left";
+ var old_base = ctx.textBaseline;
+ ctx.textBaseline = "top";
+ ctx.fillText(result.message, left_offset, 0);
+ ctx.textBaseline = old_base;
+
+ // If there's no data, return.
+ if (!result.data) {
+ return canvas;
+ }
+ }
+
+ // Set example feature. This is needed so that track can update its UI based on feature attributes.
+ this.example_feature = (result.data.length ? result.data[0] : undefined);
+
+ // Draw features
+ ctx.translate( left_offset, ERROR_PADDING );
+ painter.draw( ctx, width, required_height, slots );
+
+ return canvas;
+ }
+});
+
+var VcfTrack = function(name, view, hda_ldda, dataset_id, prefs, filters) {
+ FeatureTrack.call(this, name, view, hda_ldda, dataset_id, prefs, filters);
+ this.track_type = "VcfTrack";
+ this.painter = painters.VariantPainter;
+};
+
+extend(VcfTrack.prototype, TiledTrack.prototype, FeatureTrack.prototype);
+
+
+var ReadTrack = function (name, view, hda_ldda, dataset_id, prefs, filters) {
+ FeatureTrack.call(this, name, view, hda_ldda, dataset_id, prefs, filters);
+
+ this.track_config = new TrackConfig( {
+ track: this,
+ params: [
+ { key: 'block_color', label: 'Block color', type: 'color', default_value: '#444' },
+ { key: 'label_color', label: 'Label color', type: 'color', default_value: 'black' },
+ { key: 'show_insertions', label: 'Show insertions', type: 'bool', default_value: false },
+ { key: 'show_differences', label: 'Show differences only', type: 'bool', default_value: true },
+ { key: 'show_counts', label: 'Show summary counts', type: 'bool', default_value: true },
+ { key: 'mode', type: 'string', default_value: this.mode, hidden: true },
+ ],
+ saved_values: prefs,
+ onchange: function() {
+ this.track.tile_cache.clear();
+ this.track.draw();
+ }
+ });
+ this.prefs = this.track_config.values;
+
+ this.track_type = "ReadTrack";
+ this.painter = painters.ReadPainter;
+ this.make_name_popup_menu();
+};
+extend(ReadTrack.prototype, TiledTrack.prototype, FeatureTrack.prototype);
+
+/**
+ * Feature track that displays data generated from tool.
+ */
+var ToolDataFeatureTrack = function(name, view, hda_ldda, dataset_id, prefs, filters, parent_track) {
+ FeatureTrack.call(this, name, view, hda_ldda, dataset_id, prefs, filters, {}, parent_track);
+ this.track_type = "ToolDataFeatureTrack";
+
+ // Set up track to fetch initial data from raw data URL when the dataset--not the converted datasets--
+ // is ready.
+ this.data_url = raw_data_url;
+ this.data_query_wait = 1000;
+ this.dataset_check_url = dataset_state_url;
+};
+
+extend(ToolDataFeatureTrack.prototype, TiledTrack.prototype, FeatureTrack.prototype, {
+ /**
+ * For this track type, the predraw init sets up postdraw init.
+ */
+ predraw_init: function() {
+ // Postdraw init: once data has been fetched, reset data url, wait time and start indexing.
+ var track = this;
+ var post_init = function() {
+ if (track.data_cache.size() === 0) {
+ // Track still drawing initial data, so do nothing.
+ setTimeout(post_init, 300);
+ }
+ else {
+ // Track drawing done: reset dataset check, data URL, wait time and get dataset state to start
+ // indexing.
+ track.data_url = default_data_url;
+ track.data_query_wait = DEFAULT_DATA_QUERY_WAIT;
+ track.dataset_state_url = converted_datasets_state_url;
+ $.getJSON(track.dataset_state_url, {dataset_id : track.dataset_id, hda_ldda: track.hda_ldda}, function(track_data) {});
+ }
+ };
+ post_init();
+ }
+});
+
+// Exports
+
+exports.View = View;
+exports.LineTrack = LineTrack;
+exports.FeatureTrack = FeatureTrack;
+exports.ReadTrack = ReadTrack;
+
+// End trackster_module encapsulation
+};
+
+// ---- To be extracted ------------------------------------------------------
+
+// ---- Feature Packing ----
+
+// Encapsulation
+var slotting_module = function(require, exports) {
+
+// HACK: LABEL_SPACING is currently duplicated between here and painters
+var LABEL_SPACING = 2,
+ PACK_SPACING = 5;
+
+/**
+ * FeatureSlotter determines slots in which to draw features for vertical
+ * packing.
+ *
+ * This implementation is incremental, any feature assigned a slot will be
+ * retained for slotting future features.
+ */
+exports.FeatureSlotter = function ( w_scale, include_label, max_rows, measureText ) {
+ this.slots = {};
+ this.start_end_dct = {};
+ this.w_scale = w_scale;
+ this.include_label = include_label;
+ this.max_rows = max_rows;
+ this.measureText = measureText;
+}
+
+/**
+ * Slot a set of features, `this.slots` will be updated with slots by id, and
+ * the largest slot required for the passed set of features is returned
+ */
+extend( exports.FeatureSlotter.prototype, {
+ slot_features: function( features ) {
+ var w_scale = this.w_scale, inc_slots = this.slots, start_end_dct = this.start_end_dct,
+ undone = [], slotted = [], highest_slot = 0, max_rows = this.max_rows;
+
// If feature already exists in slots (from previously seen tiles), use the same slot,
// otherwise if not seen, add to "undone" list for slot calculation.
- //
- var w_scale = inc_slots.w_scale,
- undone = [], slotted = [],
- highest_slot = 0, // To measure how big to draw canvas
- max_low = this.view.max_low;
+
// TODO: Should calculate zoom tile index, which will improve performance
// by only having to look at a smaller subset
// if (this.start_end_dct[0] === undefined) { this.start_end_dct[0] = []; }
@@ -2198,16 +2406,14 @@
undone.push(i);
}
}
-
- //
+
// Slot unslotted features.
- //
- var start_end_dct = this.start_end_dct[level];
// Find the first slot such that current feature doesn't overlap any other features in that slot.
// Returns -1 if no slot was found.
var find_slot = function(f_start, f_end) {
- for (var slot_num = 0; slot_num <= MAX_FEATURE_DEPTH; slot_num++) {
+ // TODO: Fix constants
+ for (var slot_num = 0; slot_num <= max_rows; slot_num++) {
var has_overlap = false,
slot = start_end_dct[slot_num];
if (slot !== undefined) {
@@ -2236,15 +2442,16 @@
feature_end = feature[2],
feature_name = feature[3],
// Where to start, end drawing on screen.
- f_start = Math.floor( (feature_start - max_low) * w_scale ),
- f_end = Math.ceil( (feature_end - max_low) * w_scale ),
- text_len = CONTEXT.measureText(feature_name).width,
+ f_start = Math.floor( feature_start * w_scale ),
+ f_end = Math.ceil( feature_end * w_scale ),
+ text_len = this.measureText(feature_name).width,
text_align;
// Update start, end drawing locations to include feature name.
// Try to put the name on the left, if not, put on right.
- if (feature_name !== undefined && mode === "Pack") {
+ if (feature_name !== undefined && this.include_label ) {
// Add gap for label spacing and extra pack space padding
+ // TODO: Fix constants
text_len += (LABEL_SPACING + PACK_SPACING);
if (f_start - text_len >= 0) {
f_start -= text_len;
@@ -2257,6 +2464,7 @@
// Find slot.
var slot_num = find_slot(f_start, f_end);
+
/*
if (slot_num < 0) {
@@ -2275,7 +2483,7 @@
if (slot_num >= 0) {
console.log(feature_uid, "found slot with text on the right");
}
-
+
}
*/
// Do slotting.
@@ -2308,188 +2516,325 @@
}
*/
return highest_slot + 1;
- },
- /**
- * Draw summary tree on canvas.
- */
- draw_summary_tree: function(canvas, points, delta, max, w_scale, required_height, tile_low, left_offset) {
- var
- // Set base Y so that max label and data do not overlap. Base Y is where rectangle bases
- // start. However, height of each rectangle is relative to required_height; hence, the
- // max rectangle is required_height.
- base_y = required_height + LABEL_SPACING + CHAR_HEIGHT_PX;
- delta_x_px = Math.ceil(delta * w_scale);
+ }
+});
+
+// End slotting_module encapsulation
+};
+
+// ---- Painters ----
+
+var painters_module = function(require, exports){
+
+/**
+ * Draw a dashed line on a canvas using filled rectangles. This function is based on:
+ * http://vetruvet.blogspot.com/2010/10/drawing-dashed-lines-on-html5-canvas.h…
+ * However, that approach uses lines, which don't seem to render as well, so use
+ * rectangles instead.
+ */
+var dashedLine = function(ctx, x1, y1, x2, y2, dashLen) {
+ if (dashLen === undefined) { dashLen = 4; }
+ var dX = x2 - x1;
+ var dY = y2 - y1;
+ var dashes = Math.floor(Math.sqrt(dX * dX + dY * dY) / dashLen);
+ var dashX = dX / dashes;
+ var dashY = dY / dashes;
+ var q;
+
+ for (q = 0; q < dashes; q++, x1 += dashX, y1 += dashY) {
+ if (q % 2 !== 0) {
+ continue;
+ }
+ ctx.fillRect(x1, y1, dashLen, 1);
+ }
+};
+
+/**
+ * Draw an isosceles triangle that points down.
+ */
+var drawDownwardEquilateralTriangle = function(ctx, down_vertex_x, down_vertex_y, side_len) {
+ // Compute other two points of triangle.
+ var
+ x1 = down_vertex_x - side_len/2,
+ x2 = down_vertex_x + side_len/2,
+ y = down_vertex_y - Math.sqrt( side_len*3/2 );
- var max_label = $("<div />").addClass('yaxislabel');
- max_label.text(max);
+ // Draw and fill.
+ ctx.beginPath();
+ ctx.moveTo(x1, y);
+ ctx.lineTo(x2, y);
+ ctx.lineTo(down_vertex_x, down_vertex_y);
+ ctx.lineTo(x1, y);
+
+ ctx.strokeStyle = this.fillStyle;
+ ctx.fill();
+ ctx.stroke();
+ ctx.closePath();
+};
+
+/**
+ * SummaryTreePainter, a histogram showing number of intervals in a region
+ */
+var SummaryTreePainter = function( data, delta, max, view_start, view_end, show_counts ) {
+ // Data and data properties
+ this.data = data;
+ this.delta = delta;
+ this.max = max;
+ // View
+ this.view_start = view_start;
+ this.view_end = view_end;
+ // Drawing prefs
+ this.show_counts = show_counts;
+}
+
+SummaryTreePainter.prototype.draw = function( ctx, width, height ) {
+
+ var view_start = this.view_start,
+ view_range = this.view_end - this.view_start,
+ w_scale = width / view_range;
+
+ var points = this.data, delta = this.delta, max = this.max,
+ // Set base Y so that max label and data do not overlap. Base Y is where rectangle bases
+ // start. However, height of each rectangle is relative to required_height; hence, the
+ // max rectangle is required_height.
+ base_y = height;
+ delta_x_px = Math.ceil(delta * w_scale);
+
+ ctx.save();
+
+ for (var i = 0, len = points.length; i < len; i++) {
- max_label.css({ position: "absolute", top: "22px", left: "10px" });
- max_label.prependTo(this.container_div);
-
- var ctx = canvas.get(0).getContext("2d");
- for (var i = 0, len = points.length; i < len; i++) {
- var x = Math.floor( (points[i][0] - tile_low) * w_scale );
- var y = points[i][1];
-
- if (!y) { continue; }
- var y_px = y / max * required_height;
-
- ctx.fillStyle = "black";
- ctx.fillRect(x + left_offset, base_y - y_px, delta_x_px, y_px);
-
- // Draw number count if it can fit the number with some padding, otherwise things clump up
- var text_padding_req_x = 4;
- if (this.prefs.show_counts && (ctx.measureText(y).width + text_padding_req_x) < delta_x_px) {
- ctx.fillStyle = "#666";
- ctx.textAlign = "center";
- ctx.fillText(y, x + left_offset + (delta_x_px/2), 10);
+ var x = Math.floor( (points[i][0] - view_start) * w_scale );
+ var y = points[i][1];
+
+ if (!y) { continue; }
+ var y_px = y / max * height;
+
+ ctx.fillStyle = "black";
+ ctx.fillRect( x, base_y - y_px, delta_x_px, y_px );
+
+ // Draw number count if it can fit the number with some padding, otherwise things clump up
+ var text_padding_req_x = 4;
+ if (this.show_counts && (ctx.measureText(y).width + text_padding_req_x) < delta_x_px) {
+ ctx.fillStyle = "#666";
+ ctx.textAlign = "center";
+ ctx.fillText(y, x + (delta_x_px/2), 10);
+ }
+ }
+
+ ctx.restore();
+}
+
+var LinePainter = function( data, view_start, view_end, min_value, max_value, color, mode ) {
+ // Data and data properties
+ this.data = data;
+ // View
+ this.view_start = view_start;
+ this.view_end = view_end;
+ // Drawing prefs
+ this.min_value = min_value;
+ this.max_value = max_value;
+ this.color = color;
+ this.mode = mode;
+ this.overflow_color = "#F66";
+}
+
+LinePainter.prototype.draw = function( ctx, width, height ) {
+ var
+ in_path = false,
+ min_value = this.min_value,
+ max_value = this.max_value,
+ vertical_range = max_value - min_value,
+ height_px = height,
+ view_start = this.view_start,
+ view_range = this.view_end - this.view_start,
+ w_scale = width / view_range,
+ mode = this.mode,
+ data = this.data;
+
+ ctx.save();
+
+ // Pixel position of 0 on the y axis
+ var y_zero = Math.round( height + min_value / vertical_range * height );
+
+ // Line at 0.0
+ if ( mode !== "Intensity" ) {
+ ctx.fillStyle = "#aaa";
+ ctx.fillRect( 0, y_zero, width, 1 );
+ }
+
+ ctx.beginPath();
+ ctx.fillStyle = this.color;
+ var x_scaled, y, delta_x_px;
+ if (data.length > 1) {
+ delta_x_px = Math.ceil((data[1][0] - data[0][0]) * w_scale);
+ } else {
+ delta_x_px = 10;
+ }
+ for (var i = 0, len = data.length; i < len; i++) {
+ x_scaled = Math.round((data[i][0] - view_start) * w_scale);
+ y = data[i][1];
+ if (y === null) {
+ if (in_path && mode === "Filled") {
+ ctx.lineTo(x_scaled, height_px);
+ }
+ in_path = false;
+ continue;
+ }
+ if (y < min_value) {
+ y = min_value;
+ } else if (y > max_value) {
+ y = max_value;
+ }
+
+ if (mode === "Histogram") {
+ // y becomes the bar height in pixels, which is the negated for canvas coords
+ y = Math.round( y / vertical_range * height_px );
+ ctx.fillRect(x_scaled, y_zero, delta_x_px, - y );
+ } else if (mode === "Intensity" ) {
+ y = 255 - Math.floor( (y - min_value) / vertical_range * 255 );
+ ctx.fillStyle = "rgb(" +y+ "," +y+ "," +y+ ")";
+ ctx.fillRect(x_scaled, 0, delta_x_px, height_px);
+ } else {
+ // console.log(y, track.min_value, track.vertical_range, (y - track.min_value) / track.vertical_range * track.height_px);
+ y = Math.round( height_px - (y - min_value) / vertical_range * height_px );
+ // console.log(canvas.get(0).height, canvas.get(0).width);
+ if (in_path) {
+ ctx.lineTo(x_scaled, y);
+ } else {
+ in_path = true;
+ if (mode === "Filled") {
+ ctx.moveTo(x_scaled, height_px);
+ ctx.lineTo(x_scaled, y);
+ } else {
+ ctx.moveTo(x_scaled, y);
+ }
}
}
+ }
+ if (mode === "Filled") {
+ if (in_path) {
+ ctx.lineTo( x_scaled, y_zero );
+ ctx.lineTo( 0, y_zero );
+ }
+ ctx.fill();
+ } else {
+ ctx.stroke();
+ }
+
+ // Draw lines at bounderies if overflowing min or max
+ var overflow_min_start = -1,
+ overflow_max_start = -1;
+ ctx.fillStyle = this.overflow_color;
+ for (var i = 0, len = data.length; i < len; i++) {
+ y = data[i][1];
+ x_scaled = Math.round((data[i][0] - view_start) * w_scale);
+ x_minus_scaled = Math.round((data[i][0] - 1 - view_start) * w_scale);
+
+ // If we are in a min/max run, check if it should be ended
+ if ( overflow_max_start >= 0 && ( y === null || y < max_value ) ) {
+ // Value does not exist or is in valid range, any overflow ends
+ ctx.fillRect( overflow_max_start, 0, x_minus_scaled - overflow_max_start + 1, 2 );
+ overflow_max_start = -1;
+ } else if ( overflow_min_start >= 0 && ( y === null || y > min_value ) ) {
+ // Draw bottom overflow bar
+ ctx.fillRect( overflow_min_start, height - 2, x_minus_scaled - overflow_min_start + 1, 2 );
+ overflow_min_start = -1;
+ }
+
+ // Now check if we should start a new one (this may happen on the same
+ // base as above if switching between min/max)
+ if ( y !== null && y > max_value && overflow_max_start < 0 ) {
+ // Top overflows and we are not already in a run of overflow
+ overflow_max_start = x_scaled;
+ } else if ( y !== null && y < min_value && overflow_min_start < 0 ) {
+ // Bottom overflows and we are not already in a run
+ overflow_min_start = x_scaled;
+ }
+ }
+
+ ctx.restore();
+}
+
+var FeaturePainter = function( data, view_start, view_end, prefs, mode ) {
+ this.data = data;
+ this.view_start = view_start;
+ this.view_end = view_end;
+ this.prefs = prefs;
+ this.mode = mode;
+}
+
+extend( FeaturePainter.prototype, {
+
+ get_required_height: function( rows_required ) {
+ // y_scale is the height per row
+ var required_height = y_scale = this.get_row_height(), mode = this.mode;
+ // If using a packing mode, need to multiply by the number of slots used
+ if (mode === "no_detail" || mode === "Squish" || mode === "Pack") {
+ required_height = rows_required * y_scale;
+ }
+ // Pad bottom by half a row, at least 5 px
+ return required_height + Math.max( Math.round( y_scale / 2 ), 5 );
},
- /**
- * Draw feature.
- */
- draw_element: function(ctx, tile_index, mode, feature, slot, tile_low, tile_high, w_scale, y_scale, width, left_offset) {
- var
- feature_uid = feature[0],
- feature_start = feature[1],
- // -1 b/c intervals are half-open.
- feature_end = feature[2] - 1,
- feature_name = feature[3],
- f_start = Math.floor( Math.max(0, (feature_start - tile_low) * w_scale) ),
- f_end = Math.ceil( Math.min(width, Math.max(0, (feature_end - tile_low) * w_scale)) ),
- y_center = ERROR_PADDING + (mode === "Dense" ? 0 : (0 + slot)) * y_scale,
- thickness, y_start, thick_start = null, thick_end = null,
- block_color = this.prefs.block_color,
- label_color = this.prefs.label_color;
-
- // Dense mode displays the same for all data.
- if (mode === "Dense") {
- ctx.fillStyle = block_color;
- ctx.fillRect(f_start + left_offset, y_center, f_end - f_start, DENSE_FEATURE_HEIGHT);
- }
- else if (mode === "no_detail") {
- // No details for feature, so only one way to display.
- ctx.fillStyle = block_color;
- // TODO: what should width be here?
- ctx.fillRect(f_start + left_offset, y_center + 5, f_end - f_start, DENSE_FEATURE_HEIGHT);
- }
- else { // Mode is either Squish or Pack:
- // Feature details.
- var feature_strand = feature[5],
- feature_ts = feature[6],
- feature_te = feature[7],
- feature_blocks = feature[8];
-
- if (feature_ts && feature_te) {
- thick_start = Math.floor( Math.max(0, (feature_ts - tile_low) * w_scale) );
- thick_end = Math.ceil( Math.min(width, Math.max(0, (feature_te - tile_low) * w_scale)) );
- }
-
- // Set vars that depend on mode.
- var thin_height, thick_height;
- if (mode === "Squish") {
- thin_height = 1;
- thick_height = SQUISH_FEATURE_HEIGHT;
- } else { // mode === "Pack"
- thin_height = 5;
- thick_height = PACK_FEATURE_HEIGHT;
- }
-
- // Draw feature/feature blocks + connectors.
- if (!feature_blocks) {
- // If there are no blocks, treat the feature as one big exon.
- if ( feature.strand ) {
- if (feature.strand === "+") {
- ctx.fillStyle = RIGHT_STRAND_INV;
- } else if (feature.strand === "-") {
- ctx.fillStyle = LEFT_STRAND_INV;
- }
- }
- else { // No strand.
- ctx.fillStyle = block_color;
- }
- ctx.fillRect(f_start + left_offset, y_center, f_end - f_start, thick_height);
- } else {
- // There are feature blocks and mode is either Squish or Pack.
- //
- // Approach: (a) draw whole feature as connector/intron and (b) draw blocks as
- // needed. This ensures that whole feature, regardless of whether it starts with
- // a block, is visible.
- //
+
+ draw: function( ctx, width, height, slots ) {
+
+ var data = this.data, view_start = this.view_start, view_end = this.view_end;
+
+ ctx.save();
+
+ ctx.fillStyle = this.prefs.block_color;
+ ctx.textAlign = "right";
+
+ var view_range = this.view_end - this.view_start,
+ w_scale = width / view_range,
+ y_scale = this.get_row_height();
+
+ for (var i = 0, len = data.length; i < len; i++) {
+ var feature = data[i],
+ feature_uid = feature[0],
+ feature_start = feature[1],
+ feature_end = feature[2],
+ // Slot valid only if features are slotted and this feature is slotted;
+ // feature may not be due to lack of space.
+ slot = (slots && slots[feature_uid] !== undefined ? slots[feature_uid] : null);
- // Draw whole feature as connector/intron.
- var cur_y_center, cur_height;
- if (mode === "Squish") {
- ctx.fillStyle = CONNECTOR_COLOR;
- cur_y_center = y_center + Math.floor(SQUISH_FEATURE_HEIGHT/2) + 1;
- cur_height = 1;
- }
- else { // mode === "Pack"
- if (feature_strand) {
- var cur_y_center = y_center;
- var cur_height = thick_height;
- if (feature_strand === "+") {
- ctx.fillStyle = RIGHT_STRAND;
- } else if (feature_strand === "-") {
- ctx.fillStyle = LEFT_STRAND;
- }
- }
- else {
- ctx.fillStyle = CONNECTOR_COLOR;
- cur_y_center += (SQUISH_FEATURE_HEIGHT/2) + 1;
- cur_height = 1;
- }
- }
- ctx.fillRect(f_start + left_offset, cur_y_center, f_end - f_start, cur_height);
-
- for (var k = 0, k_len = feature_blocks.length; k < k_len; k++) {
- var block = feature_blocks[k],
- block_start = Math.floor( Math.max(0, (block[0] - tile_low) * w_scale) ),
- // -1 b/c intervals are half-open.
- block_end = Math.ceil( Math.min(width, Math.max((block[1] - 1 - tile_low) * w_scale)) );
-
- // Skip drawing if block not on tile.
- if (block_start > block_end) { continue; }
-
- // Draw thin block.
- ctx.fillStyle = block_color;
- ctx.fillRect(block_start + left_offset, y_center + (thick_height-thin_height)/2 + 1,
- block_end - block_start, thin_height);
-
- // If block intersects with thick region, draw block as thick.
- if (thick_start !== undefined && !(block_start > thick_end || block_end < thick_start) ) {
- var block_thick_start = Math.max(block_start, thick_start),
- block_thick_end = Math.min(block_end, thick_end);
- ctx.fillRect(block_thick_start + left_offset, y_center + 1,
- block_thick_end - block_thick_start, thick_height);
- }
- }
- }
-
- // Draw label for Pack mode.
- if (mode === "Pack" && feature_start > tile_low) {
- 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 + left_offset + LABEL_SPACING, y_center + 8);
- } else {
- ctx.textAlign = "right";
- ctx.fillText(feature_name, f_start + left_offset - LABEL_SPACING, y_center + 8);
- }
- ctx.fillStyle = block_color;
+ // Draw feature if there's overlap and mode is dense or feature is slotted (as it must be for all non-dense modes).
+ if ( ( feature_start < view_end && feature_end > view_start ) && (this.mode == "Dense" || slot !== null)) {
+ this.draw_element(ctx, this.mode, feature, slot, view_start, view_end, w_scale, y_scale,
+ width );
}
}
- },
+
+ ctx.restore();
+ }
+});
+
+// Contstants specific to feature tracks moved here (HACKING, these should
+// basically all be configuration options)
+var DENSE_TRACK_HEIGHT = 10,
+ NO_DETAIL_TRACK_HEIGHT = 3,
+ SQUISH_TRACK_HEIGHT = 5,
+ PACK_TRACK_HEIGHT = 10,
+ NO_DETAIL_FEATURE_HEIGHT = 1,
+ DENSE_FEATURE_HEIGHT = 3,
+ SQUISH_FEATURE_HEIGHT = 3,
+ PACK_FEATURE_HEIGHT = 9,
+ LABEL_SPACING = 2,
+ CONNECTOR_COLOR = "#ccc";
+
+var LinkedFeaturePainter = function( data, view_start, view_end, prefs, mode ) {
+ FeaturePainter.call( this, data, view_start, view_end, prefs, mode );
+}
+
+extend( LinkedFeaturePainter.prototype, FeaturePainter.prototype, {
+
/**
- * Returns y_scale based on mode.
+ * Height of a single row, depends on mode
*/
- get_y_scale: function(mode) {
- var y_scale;
- if (mode === "summary_tree") {
- // No scale needed.
- }
- if (mode === "Dense") {
+ get_row_height: function() {
+ var mode = this.mode, y_scale;
+ if (mode === "Dense") {
y_scale = DENSE_TRACK_HEIGHT;
}
else if (mode === "no_detail") {
@@ -2503,174 +2848,172 @@
}
return y_scale;
},
- /**
- * Draw FeatureTrack tile.
- */
- draw_tile: function(result, resolution, tile_index, parent_element, w_scale, ref_seq) {
- var track = this;
- var tile_low = tile_index * DENSITY * resolution,
- tile_high = ( tile_index + 1 ) * DENSITY * resolution,
- tile_span = tile_high - tile_low,
- params = { hda_ldda: track.hda_ldda, dataset_id: track.dataset_id,
- resolution: this.view.resolution, mode: this.mode };
-
- //
- // Create/set/compute some useful vars.
- //
- var width = Math.ceil( tile_span * w_scale ),
- mode = this.mode,
- min_height = 25,
- left_offset = this.left_offset,
- slots, required_height;
+
+ draw_element: function(ctx, mode, feature, slot, tile_low, tile_high, w_scale, y_scale, width ) {
+ var
+ feature_uid = feature[0],
+ feature_start = feature[1],
+ // -1 b/c intervals are half-open.
+ feature_end = feature[2] - 1,
+ feature_name = feature[3],
+ f_start = Math.floor( Math.max(0, (feature_start - tile_low) * w_scale) ),
+ f_end = Math.ceil( Math.min(width, Math.max(0, (feature_end - tile_low) * w_scale)) ),
+ y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale,
+ thickness, y_start, thick_start = null, thick_end = null,
+ block_color = this.prefs.block_color,
+ label_color = this.prefs.label_color;
+
+ // Dense mode displays the same for all data.
+ /*
+ if (mode === "Dense") {
+ ctx.fillStyle = block_color;
+ ctx.fillRect(f_start, y_center, f_end - f_start, DENSE_FEATURE_HEIGHT);
+ }
+ */
- var canvas = document.createElement("canvas");
- if (window.G_vmlCanvasManager) { G_vmlCanvasManager.initElement(canvas); } // EXCANVAS HACK
- canvas = $(canvas);
-
- //
- // Set mode if Auto.
- //
- if (mode === "Auto") {
- if (result.dataset_type === "summary_tree") {
- mode = result.dataset_type;
- } else if (result.extra_info === "no_detail") {
- mode = "no_detail";
- } else {
- // Choose b/t Squish and Pack.
- // Proxy measures for using Squish:
- // (a) error message re: limiting number of features shown;
- // (b) X number of features shown;
- // (c) size of view shown.
- // TODO: cannot use (a) and (b) because it requires coordinating mode across tiles;
- // fix this so that tiles are redrawn as necessary to use the same mode.
- //if ( (result.message && result.message.match(/^Only the first [\d]+/)) ||
- // (result.data && result.data.length > 2000) ||
- var data = result.data;
- if ( (data.length && data.length < 4) ||
- (this.view.high - this.view.low > MIN_SQUISH_VIEW_WIDTH) ) {
- mode = "Squish";
- } else {
- mode = "Pack";
- }
- }
- }
-
- var y_scale = this.get_y_scale(mode);
-
- //
- // Pack reads, set required height.
- //
- if (mode === "summary_tree") {
- required_height = this.summary_draw_height;
- }
- if (mode === "Dense") {
- required_height = min_height;
- }
- else if (mode === "no_detail" || mode === "Squish" || mode === "Pack") {
- // Calculate new slots incrementally for this new chunk of data and update height if necessary.
- required_height = this.incremental_slots(w_scale, result.data, mode) * y_scale + min_height;
- slots = this.inc_slots[w_scale];
+ if ( mode == "Dense" ) {
+ slot = 1;
}
- //
- // Set up for drawing.
- //
- canvas.get(0).width = width + left_offset;
- canvas.get(0).height = required_height;
- if (result.dataset_type === "summary_tree") {
- // Increase canvas height in order to display max label.
- canvas.get(0).height += LABEL_SPACING + CHAR_HEIGHT_PX;
- }
- parent_element.parent().css("height", Math.max(this.height_px, required_height) + "px");
- // console.log(( tile_low - this.view.low ) * w_scale, tile_index, w_scale);
- var ctx = canvas.get(0).getContext("2d");
- ctx.fillStyle = this.prefs.block_color;
- ctx.font = this.default_font;
- ctx.textAlign = "right";
- this.container_div.find(".yaxislabel").remove();
-
- //
- // Draw summary tree. If tree is drawn, canvas is returned.
- //
- if (mode === "summary_tree") {
- this.draw_summary_tree(canvas, result.data, result.delta, result.max, w_scale, required_height,
- tile_low, left_offset);
- return canvas;
- }
-
- //
- // If there is a message, draw it on canvas so that it moves around with canvas, and make the border red
- // to indicate region where message is applicable
- if (result.message) {
- canvas.css({
- "border-top": "1px solid red"
- });
+ if (mode === "no_detail") {
+ // No details for feature, so only one way to display.
+ ctx.fillStyle = block_color;
+ // TODO: what should width be here?
+ ctx.fillRect(f_start, y_center + 5, f_end - f_start, NO_DETAIL_FEATURE_HEIGHT);
+ }
+ else { // Mode is either Squish or Pack:
+ // Feature details.
+ var feature_strand = feature[4],
+ feature_ts = feature[5],
+ feature_te = feature[6],
+ feature_blocks = feature[7];
+
+ if (feature_ts && feature_te) {
+ thick_start = Math.floor( Math.max(0, (feature_ts - tile_low) * w_scale) );
+ thick_end = Math.ceil( Math.min(width, Math.max(0, (feature_te - tile_low) * w_scale)) );
+ }
+
+ // Set vars that depend on mode.
+ var thin_height, thick_height;
+ if (mode === "Squish" || mode === "Dense" ) {
+ thin_height = 1;
+ thick_height = SQUISH_FEATURE_HEIGHT;
+ } else { // mode === "Pack"
+ thin_height = 5;
+ thick_height = PACK_FEATURE_HEIGHT;
+ }
+
+ // Draw feature/feature blocks + connectors.
+ if (!feature_blocks) {
+ // If there are no blocks, treat the feature as one big exon.
+ if ( feature.strand ) {
+ if (feature.strand === "+") {
+ ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand_inv' );
+ } else if (feature.strand === "-") {
+ ctx.fillStyle = ctx.canvas.manager.get_pattern( 'left_strand_inv' );
+ }
+ }
+ else { // No strand.
+ ctx.fillStyle = block_color;
+ }
+ ctx.fillRect(f_start, y_center, f_end - f_start, thick_height);
+ } else {
+ // There are feature blocks and mode is either Squish or Pack.
+ //
+ // Approach: (a) draw whole feature as connector/intron and (b) draw blocks as
+ // needed. This ensures that whole feature, regardless of whether it starts with
+ // a block, is visible.
+ //
+
+ // Draw whole feature as connector/intron.
+ var cur_y_center, cur_height;
+ if (mode === "Squish" || mode === "Dense") {
+ ctx.fillStyle = CONNECTOR_COLOR;
+ cur_y_center = y_center + Math.floor(SQUISH_FEATURE_HEIGHT/2) + 1;
+ cur_height = 1;
+ }
+ else { // mode === "Pack"
+ if (feature_strand) {
+ var cur_y_center = y_center;
+ var cur_height = thick_height;
+ if (feature_strand === "+") {
+ ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand' );
+ } else if (feature_strand === "-") {
+ ctx.fillStyle = ctx.canvas.manager.get_pattern( 'left_strand' );
+ }
+ }
+ else {
+ ctx.fillStyle = CONNECTOR_COLOR;
+ cur_y_center += (SQUISH_FEATURE_HEIGHT/2) + 1;
+ cur_height = 1;
+ }
+ }
+ ctx.fillRect(f_start, cur_y_center, f_end - f_start, cur_height);
+
+ for (var k = 0, k_len = feature_blocks.length; k < k_len; k++) {
+ var block = feature_blocks[k],
+ block_start = Math.floor( Math.max(0, (block[0] - tile_low) * w_scale) ),
+ // -1 b/c intervals are half-open.
+ block_end = Math.ceil( Math.min(width, Math.max((block[1] - 1 - tile_low) * w_scale)) );
- ctx.fillStyle = "red";
- ctx.textAlign = "left";
- var old_base = ctx.textBaseline;
- ctx.textBaseline = "top";
- ctx.fillText(result.message, left_offset, 0);
- ctx.textBaseline = old_base;
+ // Skip drawing if block not on tile.
+ if (block_start > block_end) { continue; }
- // If there's no data, return.
- if (!result.data) {
- return canvas;
+ // Draw thin block.
+ ctx.fillStyle = block_color;
+ ctx.fillRect(block_start, y_center + (thick_height-thin_height)/2 + 1,
+ block_end - block_start, thin_height);
+
+ // If block intersects with thick region, draw block as thick.
+ // - No thick is sometimes encoded as thick_start == thick_end, so don't draw in that case
+ if (thick_start !== undefined && feature_te > feature_ts && !(block_start > thick_end || block_end < thick_start) ) {
+ var block_thick_start = Math.max(block_start, thick_start),
+ block_thick_end = Math.min(block_end, thick_end);
+ ctx.fillRect(block_thick_start, y_center + 1,
+ block_thick_end - block_thick_start, thick_height);
+ if ( feature_blocks.length == 1 && mode == "Pack") {
+ // Exactly one block means we have no introns, but do have a distinct "thick" region,
+ // draw arrows over it if in pack mode
+ if (feature_strand === "+") {
+ ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand_inv' );
+ } else if (feature_strand === "-") {
+ ctx.fillStyle = ctx.canvas.manager.get_pattern( 'left_strand_inv' );
+ }
+ // If region is wide enough in pixels, pad a bit
+ if ( block_thick_start + 14 < block_thick_end ) {
+ block_thick_start += 2;
+ block_thick_end -= 2;
+ }
+ ctx.fillRect( block_thick_start, y_center + 1,
+ block_thick_end - block_thick_start, thick_height );
+ }
+ }
+ }
+ }
+
+ // Draw label for Pack mode.
+ if (mode === "Pack" && feature_start > tile_low) {
+ ctx.fillStyle = label_color;
+ // FIXME: assumption here that the entire view starts at 0
+ if (tile_low === 0 && f_start - ctx.measureText(feature_name).width < 0) {
+ ctx.textAlign = "left";
+ ctx.fillText(feature_name, f_end + LABEL_SPACING, y_center + 8);
+ } else {
+ ctx.textAlign = "right";
+ ctx.fillText(feature_name, f_start - LABEL_SPACING, y_center + 8);
+ }
+ ctx.fillStyle = block_color;
}
}
-
- //
- // Set example feature. This is needed so that track can update its UI based on feature attributes.
- //
- this.example_feature = (result.data.length ? result.data[0] : undefined);
-
- //
- // Draw elements.
- //
- var data = result.data;
- for (var i = 0, len = data.length; i < len; i++) {
- var feature = data[i],
- feature_uid = feature[0],
- feature_start = feature[1],
- feature_end = feature[2],
- // Slot valid only if features are slotted and this feature is slotted;
- // feature may not be due to lack of space.
- slot = (slots && slots[feature_uid] !== undefined ? slots[feature_uid] : null);
-
- // Apply filters to feature.
- var hide_feature = false;
- var filter;
- for (var f = 0; f < this.filters.length; f++) {
- filter = this.filters[f];
- filter.update_attrs( feature );
- if ( !filter.keep( feature ) ) {
- hide_feature = true;
- break;
- }
- }
- if (hide_feature) {
- continue;
- }
-
- // Draw feature if there's overlap and mode is dense or feature is slotted (as it must be for all non-dense modes).
- if (is_overlap([feature_start, feature_end], [tile_low, tile_high]) && (mode == "Dense" || slot !== null)) {
- this.draw_element(ctx, tile_index, mode, feature, slot, tile_low, tile_high, w_scale, y_scale,
- width, left_offset, ref_seq);
- }
- }
- return canvas;
}
});
-var VcfTrack = function(name, view, hda_ldda, dataset_id, prefs, filters) {
- FeatureTrack.call(this, name, view, hda_ldda, dataset_id, prefs, filters);
- this.track_type = "VcfTrack";
-};
-$.extend(VcfTrack.prototype, TiledTrack.prototype, FeatureTrack.prototype, {
- /**
- * Draw a VCF entry.
- */
+var VariantPainter = function( data, view_start, view_end, prefs, mode ) {
+ FeaturePainter.call( this, data, view_start, view_end, prefs, mode );
+}
+
+extend( VariantPainter.prototype, FeaturePainter.prototype, {
draw_element: function(ctx, mode, feature, slot, tile_low, tile_high, w_scale, y_scale, width) {
var feature = data[i],
feature_uid = feature[0],
@@ -2681,7 +3024,7 @@
// All features need a start, end, and vertical center.
f_start = Math.floor( Math.max(0, (feature_start - tile_low) * w_scale) ),
f_end = Math.ceil( Math.min(width, Math.max(0, (feature_end - tile_low) * w_scale)) ),
- y_center = ERROR_PADDING + (mode === "Dense" ? 0 : (0 + slot)) * y_scale,
+ y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale,
thickness, y_start, thick_start = null, thick_end = null;
if (no_label) {
@@ -2700,7 +3043,7 @@
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) {
+ if (tile_low === 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 {
@@ -2722,39 +3065,54 @@
}
});
-var ReadTrack = function (name, view, hda_ldda, dataset_id, prefs, filters) {
- FeatureTrack.call(this, name, view, hda_ldda, dataset_id, prefs, filters);
+/**
+ * Compute the type of overlap between two regions. They are assumed to be on the same chrom/contig.
+ * The overlap is computed relative to the second region; hence, OVERLAP_START indicates that the first
+ * region overlaps the start (but not the end) of the second region.
+ */
+var NO_OVERLAP = 1001, CONTAINS = 1002, OVERLAP_START = 1003, OVERLAP_END = 1004, CONTAINED_BY = 1005;
+var compute_overlap = function(first_region, second_region) {
+ var
+ first_start = first_region[0], first_end = first_region[1],
+ second_start = second_region[0], second_end = second_region[1],
+ overlap;
+ if (first_start < second_start) {
+ if (first_end < second_start) {
+ overlap = NO_OVERLAP;
+ }
+ else if (first_end <= second_end) {
+ overlap = OVERLAP_START;
+ }
+ else { // first_end > second_end
+ overlap = CONTAINS;
+ }
+ }
+ else { // first_start >= second_start
+ if (first_start > second_end) {
+ overlap = NO_OVERLAP;
+ }
+ else if (first_end <= second_end) {
+ overlap = CONTAINED_BY;
+ }
+ else {
+ overlap = OVERLAP_END;
+ }
+ }
- this.track_config = new TrackConfig( {
- track: this,
- params: [
- { key: 'block_color', label: 'Block color', type: 'color', default_value: '#444' },
- { key: 'label_color', label: 'Label color', type: 'color', default_value: 'black' },
- { key: 'show_insertions', label: 'Show insertions', type: 'bool', default_value: false },
- { key: 'show_differences', label: 'Show differences only', type: 'bool', default_value: true },
- { key: 'show_counts', label: 'Show summary counts', type: 'bool', default_value: true },
- { key: 'mode', type: 'string', default_value: this.mode, hidden: true },
- ],
- saved_values: prefs,
- onchange: function() {
- this.track.tile_cache.clear();
- this.track.draw();
- }
- });
- this.prefs = this.track_config.values;
-
- this.track_type = "ReadTrack";
- this.make_name_popup_menu();
-};
-$.extend(ReadTrack.prototype, TiledTrack.prototype, FeatureTrack.prototype, {
+ return overlap;
+}
+
+var ReadPainter = function( data, view_start, view_end, prefs, mode, ref_seq ) {
+ FeaturePainter.call( this, data, view_start, view_end, prefs, mode );
+ this.ref_seq = ref_seq;
+}
+
+extend( ReadPainter.prototype, FeaturePainter.prototype, {
/**
* Returns y_scale based on mode.
*/
- get_y_scale: function(mode) {
- var y_scale;
- if (mode === "summary_tree") {
- // No scale needed.
- }
+ get_row_height: function() {
+ var y_scale, mode = this.mode;
if (mode === "Dense") {
y_scale = DENSE_TRACK_HEIGHT;
}
@@ -2763,7 +3121,7 @@
}
else { // mode === "Pack"
y_scale = PACK_TRACK_HEIGHT;
- if (this.track_config.values.show_insertions) {
+ if (this.prefs.show_insertions) {
y_scale *= 2;
}
}
@@ -2772,20 +3130,22 @@
/**
* Draw a single read.
*/
- draw_read: function(ctx, mode, w_scale, tile_low, tile_high, feature_start, cigar, orig_seq, y_center, ref_seq) {
+ draw_read: function(ctx, mode, w_scale, tile_low, tile_high, feature_start, cigar, orig_seq, y_center) {
ctx.textAlign = "center";
var track = this,
tile_region = [tile_low, tile_high],
base_offset = 0,
seq_offset = 0,
- gap = 0;
+ gap = 0
+ ref_seq = this.ref_seq,
+ char_width_px = ctx.canvas.manager.char_width_px;
// Keep list of items that need to be drawn on top of initial drawing layer.
var draw_last = [];
// Gap is needed so that read is offset and hence first base can be drawn on read.
// TODO-FIX: using this gap offsets reads so that their start is not visually in sync with other tracks.
- if ((mode === "Pack" || this.mode === "Auto") && orig_seq !== undefined && w_scale > CHAR_WIDTH_PX) {
+ if ((mode === "Pack" || this.mode === "Auto") && orig_seq !== undefined && w_scale > char_width_px) {
gap = Math.round(w_scale/2);
}
if (!cigar) {
@@ -2819,12 +3179,12 @@
var seq = orig_seq.slice(seq_offset, seq_offset + cig_len);
if (gap > 0) {
ctx.fillStyle = this.prefs.block_color;
- ctx.fillRect(s_start + this.left_offset - gap, y_center + 1, s_end - s_start, 9);
+ ctx.fillRect(s_start - gap, y_center + 1, s_end - s_start, 9);
ctx.fillStyle = CONNECTOR_COLOR;
// TODO: this can be made much more efficient by computing the complete sequence
// to draw and then drawing it.
for (var c = 0, str_len = seq.length; c < str_len; c++) {
- if (this.track_config.values.show_differences && ref_seq) {
+ if (this.prefs.show_differences && ref_seq) {
var ref_char = ref_seq[seq_start - tile_low + c];
if (!ref_char || ref_char.toLowerCase() === seq[c].toLowerCase()) {
continue;
@@ -2832,16 +3192,13 @@
}
if (seq_start + c >= tile_low && seq_start + c <= tile_high) {
var c_start = Math.floor( Math.max(0, (seq_start + c - tile_low) * w_scale) );
- ctx.fillText(seq[c], c_start + this.left_offset, y_center + 9);
+ ctx.fillText(seq[c], c_start, y_center + 9);
}
}
} else {
ctx.fillStyle = this.prefs.block_color;
// TODO: This is a pretty hack-ish way to fill rectangle based on mode.
- ctx.fillRect(s_start + this.left_offset,
- y_center + (this.mode !== "Dense" ? 4 : 5),
- s_end - s_start,
- (mode !== "Dense" ? SQUISH_FEATURE_HEIGHT : DENSE_FEATURE_HEIGHT) );
+ ctx.fillRect(s_start, y_center + 4, s_end - s_start, SQUISH_FEATURE_HEIGHT);
}
}
seq_offset += cig_len;
@@ -2849,14 +3206,14 @@
break;
case "N": // Skipped bases.
ctx.fillStyle = CONNECTOR_COLOR;
- ctx.fillRect(s_start + this.left_offset - gap, y_center + 5, s_end - s_start, 1);
+ ctx.fillRect(s_start - gap, y_center + 5, s_end - s_start, 1);
//ctx.dashedLine(s_start + this.left_offset, y_center + 5, this.left_offset + s_end, y_center + 5);
// No change in seq_offset because sequence not used when skipping.
base_offset += cig_len;
break;
case "D": // Deletion.
ctx.fillStyle = "red";
- ctx.fillRect(s_start + this.left_offset - gap, y_center + 4, s_end - s_start, 3);
+ ctx.fillRect(s_start - gap, y_center + 4, s_end - s_start, 3);
// TODO: is this true? No change in seq_offset because sequence not used when skipping.
base_offset += cig_len;
break;
@@ -2868,21 +3225,21 @@
// the sequence region and the tile region.
var
seq_tile_overlap = compute_overlap([seq_start, seq_start + cig_len], tile_region),
- insert_x_coord = this.left_offset + s_start - gap;
+ insert_x_coord = s_start - gap;
if (seq_tile_overlap !== NO_OVERLAP) {
var seq = orig_seq.slice(seq_offset, seq_offset + cig_len);
// Insertion point is between the sequence start and the previous base: (-gap) moves
// back from sequence start to insertion point.
- if (this.track_config.values.show_insertions) {
+ if (this.prefs.show_insertions) {
//
// Show inserted sequence above, centered on insertion point.
//
// Draw sequence.
// X center is offset + start - <half_sequence_length>
- var x_center = this.left_offset + s_start - (s_end - s_start)/2;
- if ( (mode === "Pack" || this.mode === "Auto") && orig_seq !== undefined && w_scale > CHAR_WIDTH_PX) {
+ var x_center = s_start - (s_end - s_start)/2;
+ if ( (mode === "Pack" || this.mode === "Auto") && orig_seq !== undefined && w_scale > char_width_px) {
// Draw sequence container.
ctx.fillStyle = "yellow";
ctx.fillRect(x_center - gap, y_center - 9, s_end - s_start, 9);
@@ -2906,7 +3263,7 @@
// Draw sequence.
for (var c = 0, str_len = seq.length; c < str_len; c++) {
var c_start = Math.floor( Math.max(0, (seq_start + c - tile_low) * w_scale) );
- ctx.fillText(seq[c], c_start + this.left_offset - (s_end - s_start)/2, y_center);
+ ctx.fillText(seq[c], c_start - (s_end - s_start)/2, y_center);
}
}
else {
@@ -2918,7 +3275,7 @@
}
}
else {
- if ( (mode === "Pack" || this.mode === "Auto") && orig_seq !== undefined && w_scale > CHAR_WIDTH_PX) {
+ if ( (mode === "Pack" || this.mode === "Auto") && orig_seq !== undefined && w_scale > char_width_px) {
// Show insertions with a single number at the insertion point.
draw_last[draw_last.length] = {type: "text", data: [seq.length, insert_x_coord, y_center + 9]};
}
@@ -2947,31 +3304,37 @@
type = item["type"];
data = item["data"];
if (type === "text") {
- ctx.font = "bold " + DEFAULT_FONT;
+ ctx.save();
+ ctx.font = "bold " + ctx.font;
ctx.fillText(data[0], data[1], data[2]);
- ctx.font = DEFAULT_FONT;
+ ctx.restore();
}
else if (type == "triangle") {
- ctx.drawDownwardEquilateralTriangle(data[0], data[1], data[2]);
+ drawDownwardEquilateralTriangle(ctx, data[0], data[1], data[2]);
}
}
},
/**
- * Draw a complete read.
+ * Draw a complete read pair
*/
- draw_element: function(ctx, tile_index, mode, feature, slot, tile_low, tile_high, w_scale, y_scale, width, left_offset, ref_seq) {
+ draw_element: function(ctx, mode, feature, slot, tile_low, tile_high, w_scale, y_scale, width ) {
// All features need a start, end, and vertical center.
- var
- feature_uid = feature[0],
+ var feature_uid = feature[0],
feature_start = feature[1],
feature_end = feature[2],
feature_name = feature[3],
f_start = Math.floor( Math.max(0, (feature_start - tile_low) * w_scale) ),
f_end = Math.ceil( Math.min(width, Math.max(0, (feature_end - tile_low) * w_scale)) ),
- y_center = (mode === "Dense" ? 1 : (1 + slot)) * y_scale,
+ y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale,
block_color = this.prefs.block_color,
- label_color = this.prefs.label_color;
- gap = 0; // Left-gap for label text since we align chrom text to the position tick
+ label_color = this.prefs.label_color,
+ // Left-gap for label text since we align chrom text to the position tick.
+ gap = 0;
+
+ // TODO: fix gap usage; also see note on gap in draw_read.
+ if ((mode === "Pack" || this.mode === "Auto") && w_scale > ctx.canvas.manager.char_width_px) {
+ var gap = Math.round(w_scale/2);
+ }
// Draw read.
ctx.fillStyle = block_color;
@@ -2984,78 +3347,71 @@
// Draw left/forward read.
if (feature[4][1] >= tile_low && feature[4][0] <= tile_high && feature[4][2]) {
- this.draw_read(ctx, mode, w_scale, tile_low, tile_high, feature[4][0], feature[4][2], feature[4][3], y_center, ref_seq);
+ this.draw_read(ctx, mode, w_scale, tile_low, tile_high, feature[4][0], feature[4][2], feature[4][3], y_center);
}
// Draw right/reverse read.
if (feature[5][1] >= tile_low && feature[5][0] <= tile_high && feature[5][2]) {
- this.draw_read(ctx, mode, w_scale, tile_low, tile_high, feature[5][0], feature[5][2], feature[5][3], y_center, ref_seq);
+ this.draw_read(ctx, mode, w_scale, tile_low, tile_high, feature[5][0], feature[5][2], feature[5][3], y_center);
}
// Draw connector.
if (b2_start > b1_end) {
ctx.fillStyle = CONNECTOR_COLOR;
- //ctx.fillRect(b1_end + left_offset, y_center + 5, b2_start - b1_end, 1);
- ctx.dashedLine(b1_end + left_offset, y_center + 5, left_offset + b2_start, y_center + 5);
+ dashedLine(ctx, b1_end - gap, y_center + 5, b2_start - gap, y_center + 5);
}
} else {
// Read is single.
ctx.fillStyle = block_color;
- this.draw_read(ctx, mode, w_scale, tile_low, tile_high, feature_start, feature[4], feature[5], y_center, ref_seq);
+ this.draw_read(ctx, mode, w_scale, tile_low, tile_high, feature_start, feature[4], feature[5], y_center);
}
if (mode === "Pack" && feature_start > tile_low) {
// Draw label.
ctx.fillStyle = this.prefs.label_color;
- if ( (mode === "Pack" || this.mode === "Auto") && w_scale > CHAR_WIDTH_PX) {
- var gap = Math.round(w_scale/2);
- }
+ // FIXME: eliminate tile_index
+ var tile_index = 1;
if (tile_index === 0 && f_start - ctx.measureText(feature_name).width < 0) {
ctx.textAlign = "left";
- ctx.fillText(feature_name, f_end + left_offset + LABEL_SPACING - gap, y_center + 8);
+ ctx.fillText(feature_name, f_end + LABEL_SPACING - gap, y_center + 8);
} else {
ctx.textAlign = "right";
- ctx.fillText(feature_name, f_start + left_offset - LABEL_SPACING - gap, y_center + 8);
+ ctx.fillText(feature_name, f_start - LABEL_SPACING - gap, y_center + 8);
}
ctx.fillStyle = block_color;
}
}
});
-/**
- * Feature track that displays data generated from tool.
- */
-var ToolDataFeatureTrack = function(name, view, hda_ldda, dataset_id, prefs, filters, parent_track) {
- FeatureTrack.call(this, name, view, hda_ldda, dataset_id, prefs, filters, {}, parent_track);
- this.track_type = "ToolDataFeatureTrack";
-
- // Set up track to fetch initial data from raw data URL when the dataset--not the converted datasets--
- // is ready.
- this.data_url = raw_data_url;
- this.data_query_wait = 1000;
- this.dataset_check_url = dataset_state_url;
+exports.SummaryTreePainter = SummaryTreePainter;
+exports.LinePainter = LinePainter;
+exports.LinkedFeaturePainter = LinkedFeaturePainter;
+exports.ReadPainter = ReadPainter;
+exports.VariantPainter = VariantPainter;
+
+// End painters_module encapsulation
};
-$.extend(ToolDataFeatureTrack.prototype, TiledTrack.prototype, FeatureTrack.prototype, {
- /**
- * For this track type, the predraw init sets up postdraw init.
- */
- predraw_init: function() {
- // Postdraw init: once data has been fetched, reset data url, wait time and start indexing.
- var track = this;
- var post_init = function() {
- if (track.data_cache.size() === 0) {
- // Track still drawing initial data, so do nothing.
- setTimeout(post_init, 300);
- }
- else {
- // Track drawing done: reset dataset check, data URL, wait time and get dataset state to start
- // indexing.
- track.data_url = default_data_url;
- track.data_query_wait = DEFAULT_DATA_QUERY_WAIT;
- track.dataset_state_url = converted_datasets_state_url;
- $.getJSON(track.dataset_state_url, { dataset_id : track.dataset_id, hda_ldda: track.hda_ldda }, function(track_data) {});
- }
- };
- post_init();
+// Finally, compose and export trackster module exports into globals
+// These will be replaced with require statements in CommonJS
+(function(target){
+ // Faking up a CommonJS like loader here, each module gets a require and
+ // and exports. We avoid resolution problems by just ordering carefully.
+ var modules = {};
+ // Provide a require function
+ var require = function( name ) {
+ return modules[name];
+ };
+ // Run module will run the module_function provided and store in the
+ // require dict using key
+ var run_module = function( key, module_function ) {
+ var exports = {};
+ module_function( require, exports );
+ modules[key] = exports;
+ };
+ // Run all modules
+ run_module( 'slotting', slotting_module );
+ run_module( 'painters', painters_module );
+ run_module( 'trackster', trackster_module );
+ // Export trackster stuff
+ for ( key in modules.trackster ) {
+ target[key] = modules.trackster[key];
}
-});
-
-
+})(window);
\ No newline at end of file
--- a/templates/tracks/browser.mako Sun Mar 27 19:50:50 2011 -0400
+++ b/templates/tracks/browser.mako Tue Apr 05 13:57:14 2011 -0400
@@ -69,6 +69,7 @@
chrom_url = "${h.url_for( action='chroms' )}",
dataset_state_url = "${h.url_for( action='dataset_state' )}",
converted_datasets_state_url = "${h.url_for( action='converted_datasets_state' )}",
+ filters_url = "${h.url_for( action='filters' )}",
addable_track_types = { "LineTrack": LineTrack, "FeatureTrack": FeatureTrack, "ReadTrack": ReadTrack },
view;
--- a/test-data/blastp_rhodopsin_vs_four_human.tabular Sun Mar 27 19:50:50 2011 -0400
+++ b/test-data/blastp_rhodopsin_vs_four_human.tabular Tue Apr 05 13:57:14 2011 -0400
@@ -1,6 +1,6 @@
-gi|57163783|ref|NP_001009242.1| Subject_4 96.55 348 12 0 1 348 1 348 0.0 679
-gi|3024260|sp|P56514.1|OPSD_BUFBU Subject_4 83.33 354 53 2 1 354 1 348 6e-178 605
-gi|283855846|gb|ADB45242.1| Subject_4 94.82 328 17 0 1 328 11 338 0.0 630
-gi|283855823|gb|ADB45229.1| Subject_4 94.82 328 17 0 1 328 11 338 0.0 630
-gi|223523|prf||0811197A Subject_4 93.10 348 23 1 1 347 1 348 0.0 651
-gi|12583665|dbj|BAB21486.1| Subject_4 81.09 349 65 1 1 349 1 348 2e-172 587
+gi|57163783|ref|NP_001009242.1| sp|P08100|OPSD_HUMAN 96.55 348 12 0 1 348 1 348 0.0 679
+gi|3024260|sp|P56514.1|OPSD_BUFBU sp|P08100|OPSD_HUMAN 83.33 354 53 2 1 354 1 348 6e-178 605
+gi|283855846|gb|ADB45242.1| sp|P08100|OPSD_HUMAN 94.82 328 17 0 1 328 11 338 0.0 630
+gi|283855823|gb|ADB45229.1| sp|P08100|OPSD_HUMAN 94.82 328 17 0 1 328 11 338 0.0 630
+gi|223523|prf||0811197A sp|P08100|OPSD_HUMAN 93.10 348 23 1 1 347 1 348 0.0 651
+gi|12583665|dbj|BAB21486.1| sp|P08100|OPSD_HUMAN 81.09 349 65 1 1 349 1 348 2e-172 587
--- a/test-data/tblastn_four_human_vs_rhodopsin.tabular Sun Mar 27 19:50:50 2011 -0400
+++ b/test-data/tblastn_four_human_vs_rhodopsin.tabular Tue Apr 05 13:57:14 2011 -0400
@@ -1,10 +1,10 @@
-sp|P08100|OPSD_HUMAN Subject_1 96.55 348 12 0 1 348 1 1044 0.0 732
-sp|P08100|OPSD_HUMAN Subject_2 84.80 342 51 1 1 341 42 1067 0.0 646
-sp|P08100|OPSD_HUMAN Subject_3 93.24 74 5 0 239 312 3147 3368 1e-72 151
-sp|P08100|OPSD_HUMAN Subject_3 91.53 59 5 0 177 235 2855 3031 1e-72 126
-sp|P08100|OPSD_HUMAN Subject_3 96.40 111 4 0 11 121 1 333 1e-64 229
-sp|P08100|OPSD_HUMAN Subject_3 93.22 59 4 0 119 177 1404 1580 1e-32 122
-sp|P08100|OPSD_HUMAN Subject_3 88.46 26 3 0 312 337 4222 4299 6e-13 57.7
-sp|P08100|OPSD_HUMAN Subject_4 95.09 326 16 0 11 336 1 978 0.0 658
-sp|P08100|OPSD_HUMAN Subject_5 93.39 348 23 0 1 348 1 1044 0.0 711
-sp|P08100|OPSD_HUMAN Subject_6 82.16 342 60 1 1 341 23 1048 0.0 626
+sp|P08100|OPSD_HUMAN gi|57163782|ref|NM_001009242.1| 96.55 348 12 0 1 348 1 1044 0.0 732
+sp|P08100|OPSD_HUMAN gi|2734705|gb|U59921.1|BBU59921 84.80 342 51 1 1 341 42 1067 0.0 646
+sp|P08100|OPSD_HUMAN gi|283855845|gb|GQ290303.1| 93.24 74 5 0 239 312 3147 3368 1e-72 151
+sp|P08100|OPSD_HUMAN gi|283855845|gb|GQ290303.1| 91.53 59 5 0 177 235 2855 3031 1e-72 126
+sp|P08100|OPSD_HUMAN gi|283855845|gb|GQ290303.1| 96.40 111 4 0 11 121 1 333 1e-64 229
+sp|P08100|OPSD_HUMAN gi|283855845|gb|GQ290303.1| 93.22 59 4 0 119 177 1404 1580 1e-32 122
+sp|P08100|OPSD_HUMAN gi|283855845|gb|GQ290303.1| 88.46 26 3 0 312 337 4222 4299 6e-13 57.7
+sp|P08100|OPSD_HUMAN gi|283855822|gb|GQ290312.1| 95.09 326 16 0 11 336 1 978 0.0 658
+sp|P08100|OPSD_HUMAN gi|18148870|dbj|AB062417.1| 93.39 348 23 0 1 348 1 1044 0.0 711
+sp|P08100|OPSD_HUMAN gi|12583664|dbj|AB043817.1| 82.16 342 60 1 1 341 23 1048 0.0 626
--- a/tool-data/shared/ucsc/manual_builds.txt Sun Mar 27 19:50:50 2011 -0400
+++ b/tool-data/shared/ucsc/manual_builds.txt Tue Apr 05 13:57:14 2011 -0400
@@ -698,3 +698,5 @@
Hydra_JCVI Hydra magnipapillata str. 105
Araly1 Arabidopsis lyrata
Zea_mays_B73_RefGen_v2 Maize (Zea mays) chr1=301354135,chr2=237068928,chr3=232140222,chr4=241473566,chr5=217872898,chr6=169174371,chr7=176764813,chr8=175793772,chr9=156750718,chr10=150189513,chr11=7140224
+Homo_sapiens_AK1 Korean Man chrM=16571,chr1=247249719,chr2=242951149,chr3=199501827,chr4=191273063,chr5=180857866,chr6=170899992,chr7=158821424,chr8=146274826,chr9=140273252,chr10=135374737,chr11=134452384,chr12=132349534,chr13=114142980,chr14=106368585,chr15=100338915,chr16=88827254,chr17=78774742,chr18=76117153,chr19=63811651,chr20=62435964,chr21=46944323,chr22=49691432,chrX=154913754,chrY=57772954
+Tcas_3.0 Red Flour Beetle (Tribolium castaneum)
--- a/tool_conf.xml.main Sun Mar 27 19:50:50 2011 -0400
+++ b/tool_conf.xml.main Tue Apr 05 13:57:14 2011 -0400
@@ -169,6 +169,12 @@
<!-- <tool file="hyphy/hyphy_dnds_wrapper.xml" /> --><tool file="evolution/mutate_snp_codon.xml" /></section>
+ <section name="Motif Tools" id="motifs">
+ <tool file="rgenetics/rgWebLogo3.xml" />
+ </section>
+ <section name="Multiple Alignments" id="clustal">
+ <tool file="rgenetics/rgClustalw.xml" />
+ </section><section name="Metagenomic analyses" id="tax_manipulation"><tool file="taxonomy/gi2taxonomy.xml" /><tool file="taxonomy/t2t_report.xml" />
--- a/tools/ncbi_blast_plus/ncbi_blastp_wrapper.xml Sun Mar 27 19:50:50 2011 -0400
+++ b/tools/ncbi_blast_plus/ncbi_blastp_wrapper.xml Tue Apr 05 13:57:14 2011 -0400
@@ -133,6 +133,8 @@
<param name="subject" value="rhodopsin_proteins.fasta" ftype="fasta" /><param name="database" value="" /><param name="evalue_cutoff" value="1e-8" />
+ <param name="blast_type" value="blastp" />
+ <param name="out_format" value="6" /><param name="adv_opts_selector" value="advanced" /><param name="filter_query" value="True" /><param name="matrix" value="BLOSUM62" />
--- a/tools/ncbi_blast_plus/ncbi_tblastn_wrapper.xml Sun Mar 27 19:50:50 2011 -0400
+++ b/tools/ncbi_blast_plus/ncbi_tblastn_wrapper.xml Tue Apr 05 13:57:14 2011 -0400
@@ -138,7 +138,7 @@
<output name="output1" file="tblastn_four_human_vs_rhodopsin.tabular" ftype="tabular" /></test><test>
- <!-- Same as above, but parse deflines -->
+ <!-- Same as above, but parse deflines - on BLAST 2.2.25+ makes no difference --><param name="query" value="four_human_proteins.fasta" ftype="fasta" /><param name="db_opts_selector" value="file" /><param name="subject" value="rhodopsin_nucs.fasta" ftype="fasta" />
@@ -151,7 +151,7 @@
<param name="max_hits" value="0" /><param name="word_size" value="0" /><param name="parse_deflines" value="true" />
- <output name="output1" file="tblastn_four_human_vs_rhodopsin_parse_deflines.tabular" ftype="tabular" />
+ <output name="output1" file="tblastn_four_human_vs_rhodopsin.tabular" ftype="tabular" /></test></tests><help>
--- a/tools/new_operations/intersect.xml Sun Mar 27 19:50:50 2011 -0400
+++ b/tools/new_operations/intersect.xml Tue Apr 05 13:57:14 2011 -0400
@@ -28,7 +28,7 @@
<param format="interval,gff" name="input2" type="data" help="Second dataset"><label>that intersect</label></param>
- <param name="min" size="4" type="integer" value="1" help="(bp)">
+ <param name="min" size="4" type="integer" value="1" min="1" help="(bp)"><label>for at least</label></param></inputs>
--- a/tools/new_operations/subtract.xml Sun Mar 27 19:50:50 2011 -0400
+++ b/tools/new_operations/subtract.xml Tue Apr 05 13:57:14 2011 -0400
@@ -31,7 +31,7 @@
<option value="-p">Non-overlapping pieces of intervals</option></param>
- <param name="min" size="4" type="integer" value="1" help="(bp)">
+ <param name="min" size="4" type="integer" value="1" min="1" help="(bp)"><label>where minimal overlap is</label></param></inputs>
--- a/tools/ngs_rna/cufflinks_wrapper.xml Sun Mar 27 19:50:50 2011 -0400
+++ b/tools/ngs_rna/cufflinks_wrapper.xml Tue Apr 05 13:57:14 2011 -0400
@@ -42,7 +42,7 @@
</command><inputs><param format="sam,bam" name="input" type="data" label="SAM or BAM file of aligned RNA-Seq reads" help=""/>
- <param name="max_intron_len" type="integer" value="300000" min="0" max="600000" label="Max Intron Length" help=""/>
+ <param name="max_intron_len" type="integer" value="300000" min="1" max="600000" label="Max Intron Length" help=""/><param name="min_isoform_fraction" type="float" value="0.05" min="0" max="1" label="Min Isoform Fraction" help=""/><param name="pre_mrna_fraction" type="float" value="0.05" min="0" max="1" label="Pre MRNA Fraction" help=""/><param name="min_map_quality" type="integer" value="0" min="0" max="255" label="Min SAM Map Quality" help=""/>
--- a/tools/ngs_rna/tophat_wrapper.py Sun Mar 27 19:50:50 2011 -0400
+++ b/tools/ngs_rna/tophat_wrapper.py Tue Apr 05 13:57:14 2011 -0400
@@ -208,6 +208,10 @@
tmp_stderr.close()
if returncode != 0:
raise Exception, stderr
+
+ # Copy output files from tmp directory to specified files.
+ shutil.copyfile( os.path.join( "tophat_out", "junctions.bed" ), options.junctions_output_file )
+ shutil.copyfile( os.path.join( "tophat_out", "accepted_hits.bam" ), options.accepted_hits_output_file )
# TODO: look for errors in program output.
except Exception, e:
--- a/tools/ngs_rna/tophat_wrapper.xml Sun Mar 27 19:50:50 2011 -0400
+++ b/tools/ngs_rna/tophat_wrapper.xml Tue Apr 05 13:57:14 2011 -0400
@@ -397,8 +397,8 @@
)
</filter></data>
- <data format="bed" name="junctions" label="${tool.name} on ${on_string}: splice junctions" from_work_dir="tophat_out/junctions.bed"/>
- <data format="bam" name="accepted_hits" label="${tool.name} on ${on_string}: accepted_hits" from_work_dir="tophat_out/accepted_hits.bam"/>
+ <data format="bed" name="junctions" label="${tool.name} on ${on_string}: splice junctions"/>
+ <data format="bam" name="accepted_hits" label="${tool.name} on ${on_string}: accepted_hits"/></outputs><tests>
http://bitbucket.org/galaxy/galaxy-central/changeset/b643d662fe14/
changeset: r5344:b643d662fe14
user: fubar
date: 2011-04-05 20:07:10
summary: change to weblogo test jpg comparison and code cleanups to rgCaCo
affected #: 2 files (723 bytes)
--- a/tool_conf.xml.main Tue Apr 05 13:57:14 2011 -0400
+++ b/tool_conf.xml.main Tue Apr 05 14:07:10 2011 -0400
@@ -169,12 +169,6 @@
<!-- <tool file="hyphy/hyphy_dnds_wrapper.xml" /> --><tool file="evolution/mutate_snp_codon.xml" /></section>
- <section name="Motif Tools" id="motifs">
- <tool file="rgenetics/rgWebLogo3.xml" />
- </section>
- <section name="Multiple Alignments" id="clustal">
- <tool file="rgenetics/rgClustalw.xml" />
- </section><section name="Metagenomic analyses" id="tax_manipulation"><tool file="taxonomy/gi2taxonomy.xml" /><tool file="taxonomy/t2t_report.xml" />
--- a/tools/rgenetics/rgWebLogo3.xml Tue Apr 05 13:57:14 2011 -0400
+++ b/tools/rgenetics/rgWebLogo3.xml Tue Apr 05 14:07:10 2011 -0400
@@ -5,7 +5,7 @@
#if $range.mode == 'part'
-l "$range.seqstart" -u "$range.seqend"
#end if
- </command>
+ </command><inputs><page><param format="fasta" name="input" type="data" label="Fasta File" />
@@ -71,7 +71,7 @@
<param name = "mode" value="complete" /><param name = "size" value="medium" /><param name = "colours" value="auto" />
- <output name="output" file="rgWebLogo3_test.jpg" ftype="jpg" />
+ <output name="output" file="rgWebLogo3_test.jpg" ftype="jpg" compare="sim_size" delta="10000" /></test></tests>
@@ -90,6 +90,15 @@
----
+**Warning about input Fasta format files**
+
+The Weblogo3 program used by this tool will fail if your fasta sequences are not all EXACTLY the same length.
+
+Fasta alignments from the companion ClustalW Galaxy tool will work but many other fasta files may cause this tool to fail - please do not file
+a Galaxy bug report - this is a feature of the tool and a problem with your source data - not a tool error - please make certain all your fasta
+sequences are the same length!
+
+----
**Attribution**
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: natefoo: Added clustalw and weblogo tools to Main tool_conf. Thanks Ross.
by Bitbucket 05 Apr '11
by Bitbucket 05 Apr '11
05 Apr '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/d3fd4d73675c/
changeset: r5341:d3fd4d73675c
user: natefoo
date: 2011-04-05 18:08:42
summary: Added clustalw and weblogo tools to Main tool_conf. Thanks Ross.
affected #: 1 file (207 bytes)
--- a/tool_conf.xml.main Tue Apr 05 11:51:48 2011 -0400
+++ b/tool_conf.xml.main Tue Apr 05 12:08:42 2011 -0400
@@ -169,6 +169,12 @@
<!-- <tool file="hyphy/hyphy_dnds_wrapper.xml" /> --><tool file="evolution/mutate_snp_codon.xml" /></section>
+ <section name="Motif Tools" id="motifs">
+ <tool file="rgenetics/rgWebLogo3.xml" />
+ </section>
+ <section name="Multiple Alignments" id="clustal">
+ <tool file="rgenetics/rgClustalw.xml" />
+ </section><section name="Metagenomic analyses" id="tax_manipulation"><tool file="taxonomy/gi2taxonomy.xml" /><tool file="taxonomy/t2t_report.xml" />
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/a98119b07764/
changeset: r5340:a98119b07764
user: jgoecks
date: 2011-04-05 17:51:48
summary: Refactor and enhance trackster visual analytics: (a) move all visual analytics code into Tool class for encapsulation; (b) put tool outputs in appropriate history when user is rerunning his own tool; (c) enable users not logged in to run tools; (d) use tool HTML to display inputs rather than sliders.
affected #: 9 files (4.7 KB)
--- a/lib/galaxy/visualization/tracks/visual_analytics.py Mon Apr 04 23:27:25 2011 -0400
+++ b/lib/galaxy/visualization/tracks/visual_analytics.py Tue Apr 05 11:51:48 2011 -0400
@@ -1,3 +1,5 @@
+import urllib
+
from galaxy.tools.parameters.basic import IntegerToolParameter, FloatToolParameter, SelectToolParameter
from galaxy.tools.parameters.dynamic_options import DynamicOptions
@@ -28,17 +30,19 @@
tool_param_values = dict( [ ( p.name, p.value ) for p in job.parameters ] )
tool_param_values = tool.params_from_strings( tool_param_values, trans.app, ignore_errors=True )
for name, input in tool.inputs.items():
- if type( input ) == IntegerToolParameter:
- tool_params.append( { 'name' : name, 'label' : input.label, \
- 'value' : tool_param_values.get( name, input.value ), \
- 'type' : 'int', 'min' : input.min, 'max' : input.max } )
- elif type( input ) == FloatToolParameter:
- tool_params.append( { 'name' : name, 'label' : input.label, \
- 'value' : tool_param_values.get( name, input.value ), \
- 'type' : 'float', 'min' : input.min, 'max' : input.max } )
+ if type( input ) == IntegerToolParameter or type( input ) == FloatToolParameter:
+ param_dict = { 'name' : name, 'label' : input.label, \
+ 'value' : tool_param_values.get( name, input.value ), \
+ 'type' : 'number', 'init_value' : input.value,
+ 'html' : urllib.quote( input.get_html() ) }
+ if input.min:
+ param_dict['min'] = input.min
+ if input.max:
+ param_dict['max'] = input.max
+ tool_params.append( param_dict )
elif type( input ) == SelectToolParameter and type( input.options ) != DynamicOptions:
tool_params.append( { 'name' : name, 'label' : input.label, 'type' : 'select', \
- 'options' : [ option[:2] for option in input.get_options( trans, None ) ] } )
+ 'html' : urllib.quote( input.get_html() ) } )
# If tool has parameters that can be interactively modified, return tool.
# Return empty set otherwise.
--- a/lib/galaxy/web/controllers/tracks.py Mon Apr 04 23:27:25 2011 -0400
+++ b/lib/galaxy/web/controllers/tracks.py Tue Apr 05 11:51:48 2011 -0400
@@ -201,7 +201,6 @@
return trans.fill_template( "tracks/new_browser.mako", dbkeys=self._get_dbkeys( trans ), default_dbkey=kwargs.get("default_dbkey", None) )
@web.json
- @web.require_login()
def add_track_async(self, trans, hda_id=None, ldda_id=None):
if hda_id:
hda_ldda = "hda"
@@ -707,8 +706,15 @@
# Set input datasets for tool. Input datasets are subsets of full
# datasets and are based on chrom, low, high.
#
- job_history = trans.get_history( create=True )
- hda_permissions = trans.app.security_agent.history_get_default_permissions( job_history )
+
+ # If user is rerunning own tool, put new data in original dataset's
+ # history. If another user is running tool, put new data in current
+ # history.
+ if original_dataset.history.user == trans.user:
+ working_history = original_dataset.history
+ else:
+ working_history = trans.get_history( create=True )
+ hda_permissions = trans.app.security_agent.history_get_default_permissions( working_history )
messages_list = []
for jida in original_job.input_datasets:
input_dataset = jida.dataset
@@ -730,7 +736,7 @@
name="Subset [%s:%i-%i] of data %i" % \
( chrom, low, high, input_dataset.hid ),
visible=False )
- job_history.add_dataset( new_dataset )
+ working_history.add_dataset( new_dataset )
trans.sa_session.add( new_dataset )
trans.app.security_agent.set_all_dataset_permissions( new_dataset.dataset, hda_permissions )
@@ -753,14 +759,14 @@
# Start tool and handle outputs.
#
try:
- subset_job, subset_job_outputs = tool.execute( trans, incoming=tool_params, history=job_history )
+ subset_job, subset_job_outputs = tool.execute( trans, incoming=tool_params, history=working_history )
except Exception, e:
# Lots of things can go wrong when trying to execute tool.
return to_json_string( { "error" : True, "message" : e.__class__.__name__ + ": " + str(e) } )
for output in subset_job_outputs.values():
output.visible = False
trans.sa_session.flush()
-
+
# Return new track that corresponds to the original dataset.
output_name = None
for joda in original_job.output_datasets:
--- a/static/june_2007_style/blue/trackster.css Mon Apr 04 23:27:25 2011 -0400
+++ b/static/june_2007_style/blue/trackster.css Tue Apr 05 11:51:48 2011 -0400
@@ -38,10 +38,12 @@
.top-labeltrack{position:relative;border-bottom:solid #999 1px;}
.nav-labeltrack{border-top:solid #999 1px;border-bottom:solid #333 1px;}
input{font:10px verdana;}
-.dynamic-tool,.filters{width:400px;margin-left:0.25em;padding-bottom:0.5em;}
+.dynamic-tool,.filters{width:410px;margin-left:0.25em;padding-bottom:0.5em;}
.slider-row{margin-top:0.4em;margin-left:1em;}
.slider-label{float:left;font-weight:bold;}
.slider{float:right;width:200px;position:relative;}
.tool-name{font-size:110%;font-weight:bold;}
+.param-row{margin-top:0.2em;margin-left:1em;}
+.param-label{float:left;font-weight:bold;padding-top:0.2em;}
.child-track-icon{background:url('../images/fugue/arrow-000-small-bw.png') no-repeat;width:30px;cursor:move;}
.track-resize{background:white url('../images/visualization/draggable_vertical.png') no-repeat top center;position:absolute;right:3px;bottom:-4px;width:14px;height:7px;border:solid #999 1px;z-index:100;}
--- a/static/june_2007_style/trackster.css.tmpl Mon Apr 04 23:27:25 2011 -0400
+++ b/static/june_2007_style/trackster.css.tmpl Tue Apr 05 11:51:48 2011 -0400
@@ -229,7 +229,7 @@
font: 10px verdana;
}
.dynamic-tool, .filters {
- width: 400px;
+ width: 410px;
margin-left: 0.25em;
padding-bottom:0.5em;
}
@@ -237,7 +237,7 @@
margin-top: 0.4em;
margin-left: 1em;
}
-.slider-label {
+.param-label, .slider-label {
float: left;
font-weight: bold;
}
@@ -250,6 +250,15 @@
font-size: 110%;
font-weight: bold;
}
+.param-row {
+ margin-top: 0.2em;
+ margin-left: 1em;
+}
+.param-label{
+ float: left;
+ font-weight: bold;
+ padding-top: 0.2em;
+}
.child-track-icon {
background:url('../images/fugue/arrow-000-small-bw.png') no-repeat;
width: 30px;
--- a/static/scripts/packed/trackster.js Mon Apr 04 23:27:25 2011 -0400
+++ b/static/scripts/packed/trackster.js Tue Apr 05 11:51:48 2011 -0400
@@ -1,1 +1,1 @@
-CanvasRenderingContext2D.prototype.dashedLine=function(c,j,b,h,f){if(f===undefined){f=4}var e=b-c;var d=h-j;var g=Math.floor(Math.sqrt(e*e+d*d)/f);var l=e/g;var k=d/g;var a;for(a=0;a<g;a++,c+=l,j+=k){if(a%2!==0){continue}this.fillRect(c,j,f,1)}};CanvasRenderingContext2D.prototype.drawDownwardEquilateralTriangle=function(b,a,e){var d=b-e/2,c=b+e/2,f=a-Math.sqrt(e*3/2);this.beginPath();this.moveTo(d,f);this.lineTo(c,f);this.lineTo(b,a);this.lineTo(d,f);this.strokeStyle=this.fillStyle;this.fill();this.stroke();this.closePath()};function sortable(a,b){a.bind("drag",{handle:b,relative:true},function(h,j){var g=$(this).parent();var f=g.children();var c;for(c=0;c<f.length;c++){if(j.offsetY<$(f.get(c)).position().top){break}}if(c===f.length){if(this!==f.get(c-1)){g.append(this)}}else{if(this!==f.get(c)){$(this).insertBefore(f.get(c))}}})}var NO_OVERLAP=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005;function compute_overlap(e,b){var g=e[0],f=e[1],d=b[0],c=b[1],a;if(g<d){if(f<d){a=NO_OVERLAP}else{if(f<=c){a=OVERLAP_START}else{a=CONTAINS}}}else{if(g>c){a=NO_OVERLAP}else{if(f<=c){a=CONTAINED_BY}else{a=OVERLAP_END}}}return a}function is_overlap(b,a){return(compute_overlap(b,a)!==NO_OVERLAP)}function get_slider_step(c,a){var b=a-c;return(b<=1?0.01:(b<=1000?1:5))}var DENSE_TRACK_HEIGHT=10,NO_DETAIL_TRACK_HEIGHT=3,SQUISH_TRACK_HEIGHT=5,PACK_TRACK_HEIGHT=10,NO_DETAIL_FEATURE_HEIGHT=1,DENSE_FEATURE_HEIGHT=1,SQUISH_FEATURE_HEIGHT=3,PACK_FEATURE_HEIGHT=9,ERROR_PADDING=10,LABEL_SPACING=2,PACK_SPACING=5,MIN_SQUISH_VIEW_WIDTH=12000,DEFAULT_FONT="9px Monaco, Lucida Console, monospace",DENSITY=200,FEATURE_LEVELS=10,MAX_FEATURE_DEPTH=100,DEFAULT_DATA_QUERY_WAIT=5000,MAX_CHROMS_SELECTABLE=100,CONNECTOR_COLOR="#ccc",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_CANNOT_RUN_TOOL="Tool cannot be rerun: ",DATA_LOADING="Loading data...",DATA_OK="Ready for display",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=5,CACHED_DATA=5,DUMMY_CANVAS=document.createElement("canvas"),RIGHT_STRAND,LEFT_STRAND;if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(DUMMY_CANVAS)}var CONTEXT=DUMMY_CANVAS.getContext("2d");CONTEXT.font=DEFAULT_FONT;var CHAR_WIDTH_PX=CONTEXT.measureText("A").width,CHAR_HEIGHT_PX=9;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.move_key_to_end(b,a)}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},move_key_to_end:function(b,a){this.key_ary.splice(a,1);this.key_ary.push(b)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var DataManager=function(b,a,c){Cache.call(this,b);this.track=a;this.subset=(c!==undefined?c:true)};$.extend(DataManager.prototype,Cache.prototype,{load_data:function(h,j,d,g,a,f){var c={chrom:h,low:j,high:d,mode:g,resolution:a,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(c,f);var k=[];for(var e=0;e<this.track.filters.length;e++){k[k.length]=this.track.filters[e].name}c.filter_cols=JSON.stringify(k);var b=this;return $.getJSON(this.track.data_url,c,function(l){b.set_data(j,d,g,l)})},get_data:function(j,k,c,h,b,f){var l=this.get(this.gen_key(k,c,h));if(l){return l}if(this.subset){var m,g,a,e,h,l;for(var d=0;d<this.key_ary.length;d++){m=this.key_ary[d];g=this.split_key(m);a=g[0];e=g[1];if(k>=a&&c<=e){l=this.obj_cache[m];if(l.dataset_type!=="summary_tree"&&l.extra_info!=="no_detail"){this.move_key_to_end(m,d);return l}}}}return this.load_data(j,k,c,h,b,f)},set_data:function(b,c,d,a){return this.set(this.gen_key(b,c,d),a)},gen_key:function(a,c,d){var b=a+"_"+c+"_"+d;return b},split_key:function(a){return a.split("_")}});var View=function(a,d,c,b,e){this.container=a;this.chrom=null;this.vis_id=c;this.dbkey=b;this.title=d;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(e);this.canvas_manager=new CanvasManager(a.get(0).ownerDocument);this.reset()};$.extend(View.prototype,{init:function(d){var c=this.container,a=this;this.top_container=$("<div/>").addClass("top-container").appendTo(c);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(c);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(c);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);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_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);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_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var b=function(f){if(f.type==="focusout"||(f.keyCode||f.which)===13||(f.keyCode||f.which)===27){if((f.keyCode||f.which)!==27){a.go_to($(this).val())}$(this).hide();$(this).val("");a.location_span.show();a.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",b).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.bind("click",function(){a.location_span.hide();a.chrom_select.hide();a.nav_input.val(a.chrom+":"+a.low+"-"+a.high);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.nav_controls)}this.zo_link=$("<a id='zoom-out' />").click(function(){a.zoom_out();a.redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){a.zoom_in();a.redraw()}).appendTo(this.nav_controls);this.load_chroms({low:0},d);this.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())});this.intro_div.show();this.content_div.bind("click",function(f){$(this).find("input").trigger("blur")});this.content_div.bind("dblclick",function(f){a.zoom_in(f.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(f,g){this.current_x=g.offsetX}).bind("drag",function(f,h){var j=h.offsetX-this.current_x;this.current_x=h.offsetX;var g=Math.round(j/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-g)});this.overview_close.bind("click",function(){for(var f=0,e=a.tracks.length;f<e;f++){a.tracks[f].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("draginit",function(f,g){if(f.clientX>a.viewport_container.width()-16){return false}}).bind("dragstart",function(f,g){g.original_low=a.low;g.current_height=f.clientY;g.current_x=g.offsetX}).bind("drag",function(h,k){var f=$(this);var l=k.offsetX-k.current_x;var g=f.scrollTop()-(h.clientY-k.current_height);f.scrollTop(g);k.current_height=h.clientY;k.current_x=k.offsetX;var j=Math.round(l/a.viewport_container.width()*(a.high-a.low));a.move_delta(j)}).bind("mousewheel",function(h,k,g,f){if(g){var j=Math.round(-g/a.viewport_container.width()*(a.high-a.low));a.move_delta(j)}});this.top_labeltrack.bind("dragstart",function(f,g){return $("<div />").css({height:a.content_div.height()+a.top_labeltrack.height()+a.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(k,l){$(l.proxy).css({left:Math.min(k.pageX,l.startX),width:Math.abs(k.pageX-l.startX)});var g=Math.min(k.pageX,l.startX)-a.container.offset().left,f=Math.max(k.pageX,l.startX)-a.container.offset().left,j=(a.high-a.low),h=a.viewport_container.width();a.update_location(Math.round(g/h*j)+a.low,Math.round(f/h*j)+a.low)}).bind("dragend",function(l,m){var g=Math.min(l.pageX,m.startX),f=Math.max(l.pageX,m.startX),j=(a.high-a.low),h=a.viewport_container.width(),k=a.low;a.low=Math.round(g/h*j)+k;a.high=Math.round(f/h*j)+k;$(m.proxy).remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack));$(window).bind("resize",function(){a.resize_window()});$(document).bind("redraw",function(){a.redraw()});this.reset();$(window).trigger("resize")},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},load_chroms:function(b,c){b.num=MAX_CHROMS_SELECTABLE;$.extend(b,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var a=this;$.ajax({url:chrom_url,data:b,dataType:"json",success:function(e){if(e.chrom_info.length===0){alert("Invalid chromosome: "+b.chrom);return}if(e.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=e.chrom_info;var h='<option value="">Select Chrom/Contig</option>';for(var g=0,d=a.chrom_data.length;g<d;g++){var f=a.chrom_data[g].chrom;h+='<option value="'+f+'">'+f+"</option>"}if(e.prev_chroms){h+='<option value="previous">Previous '+MAX_CHROMS_SELECTABLE+"</option>"}if(e.next_chroms){h+='<option value="next">Next '+MAX_CHROMS_SELECTABLE+"</option>"}a.chrom_select.html(h);if(c){c()}a.chrom_start_index=e.start_index},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}})},change_chrom:function(e,b,g){if(!e||e==="None"){return}var d=this;if(e==="previous"){d.load_chroms({low:this.chrom_start_index-MAX_CHROMS_SELECTABLE});return}if(e==="next"){d.load_chroms({low:this.chrom_start_index+MAX_CHROMS_SELECTABLE});return}var f=$.grep(d.chrom_data,function(j,k){return j.chrom===e})[0];if(f===undefined){d.load_chroms({chrom:e},function(){d.change_chrom(e,b,g)});return}else{if(e!==d.chrom){d.chrom=e;if(!d.chrom){d.intro_div.show()}else{d.intro_div.hide()}d.chrom_select.val(d.chrom);d.max_high=f.len-1;d.reset();d.redraw(true);for(var h=0,a=d.tracks.length;h<a;h++){var c=d.tracks[h];if(c.init){c.init()}}}if(b!==undefined&&g!==undefined){d.low=Math.max(b,0);d.high=Math.min(g,d.max_high)}d.reset_overview();d.redraw()}},go_to:function(f){var k=this,a,d,b=f.split(":"),h=b[0],j=b[1];if(j!==undefined){try{var g=j.split("-");a=parseInt(g[0].replace(/,/g,""),10);d=parseInt(g[1].replace(/,/g,""),10)}catch(c){return false}}k.change_chrom(h,a,d)},move_fraction:function(c){var a=this;var b=a.high-a.low;this.move_delta(c*b)},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);sortable(a.container_div,".draghandle");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())||0;var e=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;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,width: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(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()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide()}});var Tool=function(g){this.name=g.name;this.params=[];var a=g.params;for(var e=0;e<a.length;e++){var d=a[e],c=d.name,b=d.label,f=d.type;if(f==="int"||f==="float"){this.params[this.params.length]=new NumberParameter(c,b,d.min,d.max,d.value)}else{if(f=="select"){this.params[this.params.length]=new SelectParameter(c,b,d.options)}else{console.log("WARNING: unrecognized tool parameter type:",c,f)}}}};$.extend(Tool.prototype,{get_param_values_dict:function(){var b={};for(var a=0;a<this.params.length;a++){var c=this.params[a];b[c.name]=JSON.stringify(c.value)}return b},get_param_values:function(){var b=[];for(var a=0;a<this.params.length;a++){b[a]=this.params[a].value}return b}});var NumberParameter=function(c,b,e,a,d){this.name=c;this.label=b;this.min=e;this.max=a;this.value=d};var SelectParameter=function(c,b,a){this.name=c;this.label=b;this.options=a;this.value=(a.length!==0?a[0][1]:null)};var Filter=function(b,a,c){this.name=b;this.index=a;this.value=c};var NumberFilter=function(b,a){this.name=b;this.index=a;this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.slider=null;this.slider_label=null};$.extend(NumberFilter.prototype,{applies_to:function(a){if(a.length>this.index){return true}return false},keep:function(a){if(!this.applies_to(a)){return true}return(a[this.index]>=this.low&&a[this.index]<=this.high)},update_attrs:function(b){var a=false;if(!this.applies_to(b)){return a}if(b[this.index]<this.min){this.min=Math.floor(b[this.index]);a=true}if(b[this.index]>this.max){this.max=Math.ceil(b[this.index]);a=true}return a},update_ui_elt:function(){var b=this.slider.slider("option","min"),a=this.slider.slider("option","max");if(this.min<b||this.max>a){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",get_slider_step(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var get_filters_from_dict=function(a){var g=[];for(var d=0;d<a.length;d++){var f=a[d];var c=f.name,e=f.type,b=f.index;if(e==="int"||e==="float"){g[d]=new NumberFilter(c,b)}else{g[d]=new Filter(c,b,e)}}return g};var TrackConfig=function(a){this.track=a.track;this.params=a.params;this.values={};if(a.saved_values){this.restore_values(a.saved_values)}this.onchange=a.onchange};$.extend(TrackConfig.prototype,{restore_values:function(a){var b=this;$.each(this.params,function(c,d){if(a[d.key]!==undefined){b.values[d.key]=a[d.key]}else{b.values[d.key]=d.default_value}})},build_form:function(){var b=this;var a=$("<div />");$.each(this.params,function(f,d){if(!d.hidden){var c="param_"+f;var l=$("<div class='form-row' />").appendTo(a);l.append($("<label />").attr("for",c).text(d.label+":"));if(d.type==="bool"){l.append($('<input type="checkbox" />').attr("id",c).attr("name",c).attr("checked",b.values[d.key]))}else{if(d.type==="color"){var h=b.values[d.key];var g=$("<input />").attr("id",c).attr("name",c).val(h);var j=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var e=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(j);var k=$("<div/>").appendTo(e).farbtastic({width:100,height:100,callback:g,color:h});$("<div />").append(g).append(j).appendTo(l).bind("click",function(m){j.css({left:$(this).position().left+($(g).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){j.hide();$(document).unbind("click.color-picker")});m.stopPropagation()})}else{l.append($("<input />").attr("id",c).attr("name",c).val(b.values[d.key]))}}}});return a},update_from_form:function(a){var c=this;var b=false;$.each(this.params,function(d,f){if(!f.hidden){var g="param_"+d;var e=a.find("#"+g).val();if(f.type==="float"){e=parseFloat(e)}else{if(f.type==="int"){e=parseInt(e)}else{if(f.type==="bool"){e=a.find("#"+g).is(":checked")}}}if(e!==c.values[f.key]){c.values[f.key]=e;b=true}}});if(b){this.onchange()}}});var Tile=function(a,b,c){this.track=a;this.canvas=b;this.histo_max=c};var Track=function(b,a,e,c,d){this.name=b;this.view=a;this.parent_element=e;this.data_url=(c?c:default_data_url);this.data_url_extra_params={};this.data_query_wait=(d?d:DEFAULT_DATA_QUERY_WAIT);this.dataset_check_url=converted_datasets_state_url;this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){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.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)};$.extend(Track.prototype,{init:function(){var a=this;a.enabled=false;a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_div.css("height","auto");a.container_div.removeClass("nodata error pending");if(!a.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:a.hda_ldda,dataset_id:a.dataset_id,chrom:a.view.chrom},function(b){if(!b||b==="error"||b.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(b.message){var d=a.view.tracks.indexOf(a);var c=$(" <a href='javascript:void(0);'></a>").text("View error").bind("click",function(){show_modal("Trackster Error","<pre>"+b.message+"</pre>",{Close:hide_modal})});a.content_div.append(c)}}else{if(b==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(b==="no data"||(b.data!==undefined&&(b.data===null||b.data.length===0))){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(b==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},a.data_query_wait)}else{if(b.status==="data"){if(b.valid_chroms){a.valid_chroms=b.valid_chroms;a.make_name_popup_menu()}a.content_div.text(DATA_OK);if(a.view.chrom){a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;$.when(a.predraw_init()).done(function(){a.draw()})}}}}}}})},predraw_init:function(){},update_name:function(a){this.old_name=this.name;this.name=a;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)}});var TiledTrack=function(b,h,o){var c=this,p=c.view;this.filters=(b!==undefined?get_filters_from_dict(b):[]);this.filters_available=false;this.filters_visible=false;this.tool=(h!==undefined&&obj_length(h)>0?new Tool(h):undefined);this.parent_track=o;this.child_tracks=[];if(c.hidden){return}var k=function(r,s,t){r.click(function(){var u=s.text();max=parseFloat(t.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(t.slider("option","values")){input_size=2*input_size+1;multi_value=true}s.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",u).appendTo(s).focus().select().click(function(v){v.stopPropagation()}).blur(function(){$(this).remove();s.text(u)}).keyup(function(z){if(z.keyCode===27){$(this).trigger("blur")}else{if(z.keyCode===13){var x=t.slider("option","min"),v=t.slider("option","max"),y=function(A){return(isNaN(A)||A>v||A<x)},w=$(this).val();if(!multi_value){w=parseFloat(w);if(y(w)){alert("Parameter value must be in the range ["+x+"-"+v+"]");return $(this)}}else{w=w.split("-");w=[parseFloat(w[0]),parseFloat(w[1])];if(y(w[0])||y(w[1])){alert("Parameter value must be in the range ["+x+"-"+v+"]");return $(this)}}t.slider((multi_value?"values":"value"),w)}}})})};if(this.parent_track){this.header_div.find(".draghandle").removeClass("draghandle").addClass("child-track-icon").addClass("icon-button");this.parent_element.addClass("child-track");this.tool=undefined}this.filters_div=$("<div/>").addClass("filters").hide();this.header_div.after(this.filters_div);this.filters_div.bind("drag",function(r){r.stopPropagation()}).bind("click",function(r){r.stopPropagation()}).bind("dblclick",function(r){r.stopPropagation()});$.each(this.filters,function(x,s){var u=$("<div/>").addClass("slider-row").appendTo(c.filters_div);var r=$("<div/>").addClass("slider-label").appendTo(u);var z=$("<span/>").addClass("slider-name").text(s.name+" ").appendTo(r);var t=$("<span/>");var v=$("<span/>").addClass("slider-value").appendTo(r).append("[").append(t).append("]");var y=$("<div/>").addClass("slider").appendTo(u);s.control_element=$("<div/>").attr("id",s.name+"-filter-control").appendTo(y);var w=[0,0];s.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(A,B){w=B.values;t.text(B.values[0]+"-"+B.values[1]);setTimeout(function(){if(B.values[0]==w[0]&&B.values[1]==w[1]){var C=B.values;t.text(C[0]+"-"+C[1]);s.low=C[0];s.high=C[1];c.draw(true,true)}},50)},change:function(A,B){s.control_element.slider("option","slide").call(s.control_element,A,B)}});s.slider=s.control_element;s.slider_label=t;k(v,t,s.control_element);$("<div style='clear: both;'/>").appendTo(u)});if(this.tool){this.dynamic_tool_div=$("<div/>").addClass("dynamic-tool").hide();this.header_div.after(this.dynamic_tool_div);this.dynamic_tool_div.bind("drag",function(r){r.stopPropagation()}).bind("click",function(r){r.stopPropagation()}).bind("dblclick",function(r){r.stopPropagation()});var n=$("<div class='tool-name'>").appendTo(this.dynamic_tool_div).text(this.tool.name);var m=this.tool.params;var c=this;$.each(this.tool.params,function(A,s){if(s instanceof NumberParameter){var x=$("<div>").addClass("slider-row").appendTo(c.dynamic_tool_div);var u=$("<div>").addClass("slider-label").appendTo(x);var C=$("<span/>").addClass("slider-name").text(s.label+" ").appendTo(u);var t=$("<span/>").text(s.value);var y=$("<span/>").addClass("slider-value").appendTo(u).append("[").append(t).append("]");var B=$("<div/>").addClass("slider").appendTo(x);var r=$("<div id='"+s.name+"-param-control'>").appendTo(B);r.slider({min:s.min,max:s.max,step:get_slider_step(s.min,s.max),value:s.value,slide:function(F,H){var G=H.value;s.value=G;if(0<G&&G<1){G=parseFloat(G).toFixed(2)}t.text(G)},change:function(F,G){r.slider("option","slide").call(r,F,G)}});k(y,t,r);$("<div style='clear: both;'/>").appendTo(x)}else{if(s instanceof SelectParameter){var x=$("<div>").addClass("slider-row").appendTo(c.dynamic_tool_div);var u=$("<div>").addClass("slider-label").appendTo(x);var C=$("<span/>").addClass("slider-name").text(s.label+" ").appendTo(u);var E=$("<div/>").addClass("slider").appendTo(x);var w=$("<select/>").appendTo(E);w.change(function(){s.value=$(this).val()});var D=w.attr("options");for(var z=0;z<s.options.length;z++){var v=s.options[z];D[D.length]=new Option(v[0],v[1])}$("<div style='clear: both;'/>").appendTo(x)}}});var q=$("<div>").addClass("slider-row").appendTo(this.dynamic_tool_div);var l=$("<input type='submit'>").attr("value","Run").appendTo(q);var c=this;l.click(function(){c.run_tool()})}c.child_tracks_container=$("<div/>").addClass("child-tracks-container").hide();c.container_div.append(c.child_tracks_container);if(c.display_modes!==undefined){if(c.mode_div===undefined){c.mode_div=$("<div class='right-float menubutton popup' />").appendTo(c.header_div);var e=(c.track_config&&c.track_config.values.mode?c.track_config.values.mode:c.display_modes[0]);c.mode=e;c.mode_div.text(e);var d=function(r){c.mode_div.text(r);c.mode=r;c.track_config.values.mode=r;c.tile_cache.clear();c.draw()};var a={};for(var f=0,j=c.display_modes.length;f<j;f++){var g=c.display_modes[f];a[g]=function(r){return function(){d(r)}}(g)}make_popupmenu(c.mode_div,a)}else{c.mode_div.hide()}}this.make_name_popup_menu()};$.extend(TiledTrack.prototype,Track.prototype,{make_name_popup_menu:function(){var b=this;var a={};a["Edit configuration"]=function(){var h=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},f=function(){b.track_config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},g=function(j){if((j.keyCode||j.which)===27){h()}else{if((j.keyCode||j.which)===13){f()}}};$(window).bind("keypress.check_enter_esc",g);show_modal("Configure Track",b.track_config.build_form(),{Cancel:h,OK:f})};if(b.filters_available>0){var e=(b.filters_div.is(":visible")?"Hide filters":"Show filters");a[e]=function(){b.filters_visible=(b.filters_div.is(":visible"));b.filters_div.toggle();b.make_name_popup_menu()}}if(b.tool){var e=(b.dynamic_tool_div.is(":visible")?"Hide tool":"Show tool");a[e]=function(){if(!b.dynamic_tool_div.is(":visible")){b.update_name(b.name+b.tool_region_and_parameters_str())}else{menu_option_text="Show dynamic tool";b.revert_name()}b.dynamic_tool_div.toggle();b.make_name_popup_menu()}}if(b.valid_chroms){a["List chrom/contigs with data"]=function(){show_modal("Chrom/contigs with data","<p>"+b.valid_chroms.join("<br/>")+"</p>",{Close:function(){hide_modal()}})}}var c=view;var d=function(){$("#no-tracks").show()};if(this.parent_track){c=this.parent_track;d=function(){}}a.Remove=function(){c.remove_track(b);if(c.num_tracks===0){d()}};make_popupmenu(b.name_div,a)},draw:function(a,d){var s=this.view.low,g=this.view.high,j=g-s,l=this.view.container.width(),f=l/j,m=this.view.resolution,e=$("<div style='position: relative;'></div>");if(!d){this.content_div.children().remove()}this.content_div.append(e);this.max_height=0;var o=Math.floor(s/m/DENSITY);var c={};while((o*DENSITY*m)<g){var r=l+"_"+f+"_"+o;var h=this.tile_cache.get(r);var p=o*DENSITY*this.view.resolution;var b=p+DENSITY*this.view.resolution;if(!a&&h){this.show_tile(h,e,p,f)}else{this.delayed_draw(a,r,p,b,o,m,e,f,c)}o+=1}var k=this;var q=setInterval(function(){if(obj_length(c)===0){clearInterval(q);if(d){var v=k.content_div.children();var u=false;for(var w=v.length-1,t=0;w>=t;w--){var z=$(v[w]);if(u){z.remove()}else{if(z.children().length!==0){u=true}}}}for(var y=0;y<k.filters.length;y++){k.filters[y].update_ui_elt()}var x=false;if(k.example_feature){for(var y=0;y<k.filters.length;y++){if(k.filters[y].applies_to(k.example_feature)){x=true;break}}}if(k.filters_available!==x){k.filters_available=x;if(!k.filters_available){k.filters_div.hide()}k.make_name_popup_menu()}}},50);for(var n=0;n<this.child_tracks.length;n++){this.child_tracks[n].draw(a,d)}},delayed_draw:function(b,j,g,l,c,e,k,m,f){var d=this;var h=function(u,n,p,o,s,t,q){returned_tile=d.draw_tile(n,p,o,s,t,q);var r=$("<div class='track-tile'>").prepend(returned_tile);tile_element=r;d.tile_cache.set(j,tile_element);d.show_tile(tile_element,s,g,t);delete f[u]};var a=setTimeout(function(){if(g<=d.view.high&&l>=d.view.low){var n=(b?undefined:d.tile_cache.get(j));if(n){d.show_tile(n,k,g,m);delete f[a]}else{$.when(d.data_cache.get_data(view.chrom,g,l,d.mode,e,d.data_url_extra_params)).then(function(o){if(view.reference_track&&m>CHAR_WIDTH_PX){$.when(view.reference_track.data_cache.get_data(view.chrom,g,l,d.mode,e,view.reference_track.data_url_extra_params)).then(function(p){h(a,o,e,c,k,m,p)})}else{h(a,o,e,c,k,m)}})}}},50);f[a]=true},show_tile:function(a,f,d,g){var b=this;var c=this.view.high-this.view.low,e=(d-this.view.low)*g;if(this.left_offset){e-=this.left_offset}a.css({position:"absolute",top:0,left:e,height:""});f.append(a);b.max_height=Math.max(b.max_height,a.height());b.content_div.css("height",b.max_height+"px");f.children().css("height",b.max_height+"px")},set_overview:function(){var a=this.view;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")},run_tool:function(){var b={dataset_id:this.original_dataset_id,chrom:this.view.chrom,low:this.view.low,high:this.view.high,tool_id:this.tool.name};$.extend(b,this.tool.get_param_values_dict());var d=this,c=b.tool_id+d.tool_region_and_parameters_str(b.chrom,b.low,b.high),e;if(d.track_type==="FeatureTrack"){e=new ToolDataFeatureTrack(c,view,d.hda_ldda,undefined,{},{},d)}this.add_track(e);e.content_div.text("Starting job.");view.has_changes=true;var a=function(){$.getJSON(run_tool_url,b,function(f){if(f==="no converter"){e.container_div.addClass("error");e.content_div.text(DATA_NOCONVERTER)}else{if(f.error){e.container_div.addClass("error");e.content_div.text(DATA_CANNOT_RUN_TOOL+f.message)}else{if(f==="pending"){e.container_div.addClass("pending");e.content_div.text("Converting input data so that it can be easily reused.");setTimeout(a,2000)}else{e.dataset_id=f.dataset_id;e.content_div.text("Running job.");e.init()}}}})};a()},tool_region_and_parameters_str:function(c,a,d){var b=this,e=(c!==undefined&&a!==undefined&&d!==undefined?c+":"+a+"-"+d:"all");return" - region=["+e+"], parameters=["+b.tool.get_param_values().join(", ")+"]"},add_track:function(a){a.track_id=this.track_id+"_"+this.child_tracks.length;a.container_div.attr("id","track_"+a.track_id);this.child_tracks_container.append(a.container_div);sortable(a.container_div,".child-track-icon");if(!$(this.child_tracks_container).is(":visible")){this.child_tracks_container.show()}this.child_tracks.push(a)},remove_track:function(a){a.container_div.fadeOut("slow",function(){$(this).remove()})}});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.view.container.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);a.reference_track=this;this.left_offset=200;this.height_px=12;this.font=DEFAULT_FONT;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:a.dbkey};this.data_cache=new DataManager(CACHED_DATA,this,false);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.prototype,{draw_tile:function(m,g,b,j,n){var f=this,d=DENSITY*g;if(n>CHAR_WIDTH_PX){if(m===null){f.content_div.css("height","0px");return}var e=this.view.canvas_manager.new_canvas();var l=e.getContext("2d");e.width=Math.ceil(d*n+f.left_offset);e.height=f.height_px;l.font=DEFAULT_FONT;l.textAlign="center";for(var h=0,k=m.length;h<k;h++){var a=Math.round(h*n);l.fillText(m[h],a+f.left_offset,10)}return e}this.content_div.css("height","0px")}});var LineTrack=function(e,c,f,a,d){var b=this;this.track_type="LineTrack";this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";Track.call(this,e,c,c.viewport_container);TiledTrack.call(this);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=f;this.dataset_id=a;this.original_dataset_id=a;this.data_cache=new DataManager(CACHED_DATA,this);this.tile_cache=new Cache(CACHED_TILES_LINE);this.track_config=new TrackConfig({track:this,params:[{key:"color",label:"Color",type:"color",default_value:"black"},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.height_px,hidden:true}],saved_values:d,onchange:function(){b.vertical_range=b.prefs.max_value-b.prefs.min_value;$("#linetrack_"+b.track_id+"_minval").text(b.prefs.min_value);$("#linetrack_"+b.track_id+"_maxval").text(b.prefs.max_value);b.tile_cache.clear();b.draw()}});this.prefs=this.track_config.values;this.height_px=this.track_config.values.height;this.vertical_range=this.track_config.values.max_value-this.track_config.values.min_value;this.add_resize_handle()};$.extend(LineTrack.prototype,TiledTrack.prototype,{add_resize_handle:function(){var a=this;var d=false;var c=false;var b=$("<div class='track-resize'>");$(a.container_div).hover(function(){d=true;b.show()},function(){d=false;if(!c){b.hide()}});b.hide().bind("dragstart",function(f,g){c=true;g.original_height=$(a.content_div).height()}).bind("drag",function(g,h){var f=Math.min(Math.max(h.original_height+h.deltaY,a.min_height_px),a.max_height_px);$(a.content_div).css("height",f);a.height_px=f;a.draw(true)}).bind("dragend",function(f,g){a.tile_cache.clear();c=false;if(!d){b.hide()}a.track_config.values.height=a.height_px}).appendTo(a.container_div)},predraw_init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;return $.getJSON(a.data_url,{stats:true,chrom:a.view.chrom,low:null,high:null,hda_ldda:a.hda_ldda,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");var e=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=e.min;a.prefs.max_value=e.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=e.total_frequency;a.container_div.find(".yaxislabel").remove();var f=$("<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:"24px",left:"10px"});d.prependTo(a.container_div);f.css({position:"absolute",bottom:"2px",left:"10px"});f.prependTo(a.container_div)})},draw_tile:function(m,e,b,j,l){if(this.vertical_range===undefined){return}var f=b*DENSITY*e,d=DENSITY*e,a=Math.ceil(d*l),h=this.height_px;var c=this.view.canvas_manager.new_canvas();c.width=a,c.height=h;var k=c.getContext("2d");var g=new LinePainter(m.data,f,f+d,this.prefs.min_value,this.prefs.max_value,this.prefs.color,this.mode);g.draw(k,a,h);return c}});var FeatureTrack=function(a,f,e,j,h,c,d,g){var b=this;this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];this.track_config=new TrackConfig({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:h,onchange:function(){b.tile_cache.clear();b.draw()}});this.prefs=this.track_config.values;Track.call(this,a,f,f.viewport_container);TiledTrack.call(this,c,d,g);this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=e;this.dataset_id=j;this.original_dataset_id=j;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.default_font=DEFAULT_FONT;this.inc_slots={};this.start_end_dct={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new DataManager(20,this);this.left_offset=200;this.painter=LinkedFeaturePainter};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{incremental_slots:function(d,b,c){var a=this.inc_slots[d];if(!a||(a.mode!==c)){a=new FeatureSlotter(d,c==="Pack",function(e){return CONTEXT.measureText(e)});a.mode=c;this.inc_slots[d]=a}return a.slot_features(b)},get_y_scale:function(b){var a;if(b==="summary_tree"){}if(b==="Dense"){a=DENSE_TRACK_HEIGHT}else{if(b==="no_detail"){a=NO_DETAIL_TRACK_HEIGHT}else{if(b==="Squish"){a=SQUISH_TRACK_HEIGHT}else{a=PACK_TRACK_HEIGHT}}}return a},draw_tile:function(o,w,A,k,m,d){var t=this,C=A*DENSITY*w,b=(A+1)*DENSITY*w,q=b-C,u=Math.ceil(q*m),s=this.mode,G=25,e=this.left_offset,p,g;if(s==="Auto"){if(o.dataset_type==="summary_tree"){s=o.dataset_type}else{if(o.extra_info==="no_detail"){s="no_detail"}else{var F=o.data;if((F.length&&F.length<4)||(this.view.high-this.view.low>MIN_SQUISH_VIEW_WIDTH)){s="Squish"}else{s="Pack"}}}}if(s==="summary_tree"){g=this.summary_draw_height;k.parent().css("height",Math.max(this.height_px,g)+"px");this.container_div.find(".yaxislabel").remove();var a=$("<div />").addClass("yaxislabel");a.text(o.max);a.css({position:"absolute",top:"22px",left:"10px"});a.prependTo(this.container_div);var c=this.view.canvas_manager.new_canvas();c.width=u+e;c.height=g+LABEL_SPACING+CHAR_HEIGHT_PX;var D=new SummaryTreePainter(o.data,o.delta,o.max,C,b,this.prefs.show_counts);var v=c.getContext("2d");v.translate(e,0);D.draw(v,u,g);return c}var p,j=1;if(s==="no_detail"||s==="Squish"||s==="Pack"){j=this.incremental_slots(m,o.data,s);p=this.inc_slots[m].slots}var l=[];if(o.data){for(var x=0,z=o.data.length;x<z;x++){var h=o.data[x];var y=false;var n;for(var B=0,E=this.filters.length;B<E;B++){n=this.filters[B];n.update_attrs(h);if(!n.keep(h)){y=true;break}}if(!y){l.push(h)}}}var D=new (this.painter)(l,C,b,this.prefs,s,d);var g=D.get_required_height(j)+ERROR_PADDING;var c=this.view.canvas_manager.new_canvas();c.width=u+e;c.height=g;k.parent().css("height",Math.max(this.height_px,g)+"px");var v=c.getContext("2d");v.fillStyle=this.prefs.block_color;v.font=this.default_font;v.textAlign="right";this.container_div.find(".yaxislabel").remove();if(o.message){$(c).css({"border-top":"1px solid red"});v.fillStyle="red";v.textAlign="left";var r=v.textBaseline;v.textBaseline="top";v.fillText(o.message,e,0);v.textBaseline=r;if(!o.data){return c}}this.example_feature=(o.data.length?o.data[0]:undefined);v.translate(e,ERROR_PADDING);D.draw(v,u,g,p);return c}});var VcfTrack=function(d,b,f,a,c,e){FeatureTrack.call(this,d,b,f,a,c,e);this.track_type="VcfTrack";this.painter=VariantPainter};$.extend(VcfTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype);var ReadTrack=function(d,b,f,a,c,e){FeatureTrack.call(this,d,b,f,a,c,e);this.track_config=new TrackConfig({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:c,onchange:function(){this.track.tile_cache.clear();this.track.draw()}});this.prefs=this.track_config.values;this.track_type="ReadTrack";this.painter=ReadPainter;this.make_name_popup_menu()};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype);var ToolDataFeatureTrack=function(e,c,g,a,d,f,b){FeatureTrack.call(this,e,c,g,a,d,f,{},b);this.track_type="ToolDataFeatureTrack";this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};$.extend(ToolDataFeatureTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{predraw_init:function(){var b=this;var a=function(){if(b.data_cache.size()===0){setTimeout(a,300)}else{b.data_url=default_data_url;b.data_query_wait=DEFAULT_DATA_QUERY_WAIT;b.dataset_state_url=converted_datasets_state_url;$.getJSON(b.dataset_state_url,{dataset_id:b.dataset_id,hda_ldda:b.hda_ldda},function(c){})}};a()}});var extend=function(){var c=arguments[0];for(var b=1;b<arguments.length;b++){var a=arguments[b];for(key in a){c[key]=a[key]}}};var CanvasManager=function(a){this.document=a};CanvasManager.prototype.new_canvas=function(){var a=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(a)}return a};var FeatureSlotter=function(c,b,a){this.slots={};this.start_end_dct={};this.w_scale=c;this.include_label=b;this.measureText=a};FeatureSlotter.prototype.slot_features=function(g){var k=this.w_scale,n=this.slots,c=this.start_end_dct,t=[],u=[],h=0;for(var r=0,s=g.length;r<s;r++){var e=g[r],j=e[0];if(n[j]!==undefined){h=Math.max(h,n[j]);u.push(n[j])}else{t.push(r)}}var l=function(A,B){for(var z=0;z<=MAX_FEATURE_DEPTH;z++){var x=false,C=c[z];if(C!==undefined){for(var w=0,y=C.length;w<y;w++){var v=C[w];if(B>v[0]&&A<v[1]){x=true;break}}}if(!x){return z}}return -1};for(var r=0,s=t.length;r<s;r++){var e=g[t[r]],j=e[0],p=e[1],a=e[2],m=e[3],b=Math.floor(p*k),f=Math.ceil(a*k),q=this.measureText(m).width,d;if(m!==undefined&&this.include_label){q+=(LABEL_SPACING+PACK_SPACING);if(b-q>=0){b-=q;d="left"}else{f+=q;d="right"}}var o=l(b,f);if(o>=0){if(c[o]===undefined){c[o]=[]}c[o].push([b,f]);n[j]=o;h=Math.max(h,o)}else{}}return h+1};var SummaryTreePainter=function(d,f,b,e,a,c){this.data=d;this.delta=f;this.max=b;this.view_start=e;this.view_end=a;this.show_counts=c};SummaryTreePainter.prototype.draw=function(o,a,n){var f=this.view_start,q=this.view_end-this.view_start,p=a/q;var l=this.data,k=this.delta,h=this.max,c=n+LABEL_SPACING+CHAR_HEIGHT_PX;delta_x_px=Math.ceil(k*p);o.save();for(var d=0,e=l.length;d<e;d++){var j=Math.floor((l[d][0]-f)*p);var g=l[d][1];if(!g){continue}var m=g/h*n;o.fillStyle="black";o.fillRect(j,c-m,delta_x_px,m);var b=4;if(this.show_counts&&(o.measureText(g).width+b)<delta_x_px){o.fillStyle="#666";o.textAlign="center";o.fillText(g,j+(delta_x_px/2),10)}}o.restore()};var LinePainter=function(d,g,a,b,f,c,e){this.data=d;this.view_start=g;this.view_end=a;this.min_value=b;this.max_value=f;this.color=c;this.mode=e};LinePainter.prototype.draw=function(o,n,l){var g=false,h=this.min_value,e=this.max_value,k=e-h,a=l,b=this.view_start,m=this.view_end-this.view_start,c=n/m,j=this.mode,s=this.data;o.save();var t=Math.round(l+h/k*l);if(j!=="Intensity"){o.beginPath();o.moveTo(0,t);o.lineTo(n,t);o.fillStyle="#aaa";o.stroke()}o.beginPath();o.fillStyle=this.color;var r,f,d;if(s.length>1){d=Math.ceil((s[1][0]-s[0][0])*c)}else{d=10}for(var p=0,q=s.length;p<q;p++){r=Math.round((s[p][0]-b)*c);f=s[p][1];if(f===null){if(g&&j==="Filled"){o.lineTo(r,a)}g=false;continue}if(f<h){f=h}else{if(f>e){f=e}}if(j==="Histogram"){f=Math.round(f/k*a);o.fillRect(r,t,d,-f)}else{if(j==="Intensity"){f=255-Math.floor((f-h)/k*255);o.fillStyle="rgb("+f+","+f+","+f+")";o.fillRect(r,0,d,a)}else{f=Math.round(a-(f-h)/k*a);if(g){o.lineTo(r,f)}else{g=true;if(j==="Filled"){o.moveTo(r,a);o.lineTo(r,f)}else{o.moveTo(r,f)}}}}}if(j==="Filled"){if(g){o.lineTo(r,t);o.lineTo(0,t)}o.fill()}else{o.stroke()}o.restore()};var FeaturePainter=function(c,e,a,b,d){this.data=c;this.view_start=e;this.view_end=a;this.prefs=b;this.mode=d};extend(FeaturePainter.prototype,{get_required_height:function(b){var a=y_scale=this.get_row_height(),c=this.mode;if(c==="no_detail"||c==="Squish"||c==="Pack"){a=b*y_scale}return a+Math.round(y_scale/2)},draw:function(n,d,m,j){var g=this.data,k=this.view_start,o=this.view_end;n.save();n.fillStyle=this.prefs.block_color;n.textAlign="right";var r=this.view_end-this.view_start,q=d/r,c=this.get_row_height();for(var f=0,h=g.length;f<h;f++){var p=g[f],e=p[0],a=p[1],b=p[2],l=(j&&j[e]!==undefined?j[e]:null);if(is_overlap([a,b],[k,o])&&(this.mode=="Dense"||l!==null)){this.draw_element(n,this.mode,p,l,k,o,q,c,d)}}n.restore()}});var LinkedFeaturePainter=function(c,e,a,b,d){FeaturePainter.call(this,c,e,a,b,d)};extend(LinkedFeaturePainter.prototype,FeaturePainter.prototype,{get_row_height:function(){var b=this.mode,a;if(b==="summary_tree"){}if(b==="Dense"){a=DENSE_TRACK_HEIGHT}else{if(b==="no_detail"){a=NO_DETAIL_TRACK_HEIGHT}else{if(b==="Squish"){a=SQUISH_TRACK_HEIGHT}else{a=PACK_TRACK_HEIGHT}}}return a},draw_element:function(p,g,x,j,r,H,L,M,a){var u=x[0],J=x[1],B=x[2]-1,s=x[3],C=Math.floor(Math.max(0,(J-r)*L)),q=Math.ceil(Math.min(a,Math.max(0,(B-r)*L))),A=(g==="Dense"?0:(0+j))*M,o,F,t=null,N=null,d=this.prefs.block_color,E=this.prefs.label_color;if(g==="Dense"){p.fillStyle=d;p.fillRect(C,A,q-C,DENSE_FEATURE_HEIGHT)}else{if(g==="no_detail"){p.fillStyle=d;p.fillRect(C,A+5,q-C,DENSE_FEATURE_HEIGHT)}else{var n=x[4],z=x[5],D=x[6],e=x[7];if(z&&D){t=Math.floor(Math.max(0,(z-r)*L));N=Math.ceil(Math.min(a,Math.max(0,(D-r)*L)))}var K,v;if(g==="Squish"){K=1;v=SQUISH_FEATURE_HEIGHT}else{K=5;v=PACK_FEATURE_HEIGHT}if(!e){if(x.strand){if(x.strand==="+"){p.fillStyle=RIGHT_STRAND_INV}else{if(x.strand==="-"){p.fillStyle=LEFT_STRAND_INV}}}else{p.fillStyle=d}p.fillRect(C,A,q-C,v)}else{var m,w;if(g==="Squish"){p.fillStyle=CONNECTOR_COLOR;m=A+Math.floor(SQUISH_FEATURE_HEIGHT/2)+1;w=1}else{if(n){var m=A;var w=v;if(n==="+"){p.fillStyle=RIGHT_STRAND}else{if(n==="-"){p.fillStyle=LEFT_STRAND}}}else{p.fillStyle=CONNECTOR_COLOR;m+=(SQUISH_FEATURE_HEIGHT/2)+1;w=1}}p.fillRect(C,m,q-C,w);for(var I=0,c=e.length;I<c;I++){var h=e[I],b=Math.floor(Math.max(0,(h[0]-r)*L)),y=Math.ceil(Math.min(a,Math.max((h[1]-1-r)*L)));if(b>y){continue}p.fillStyle=d;p.fillRect(b,A+(v-K)/2+1,y-b,K);if(t!==undefined&&!(b>N||y<t)){var G=Math.max(b,t),l=Math.min(y,N);p.fillRect(G,A+1,l-G,v)}}}if(g==="Pack"&&J>r){p.fillStyle=E;var f=1;if(f===0&&C-p.measureText(s).width<0){p.textAlign="left";p.fillText(s,q+LABEL_SPACING,A+8)}else{p.textAlign="right";p.fillText(s,C-LABEL_SPACING,A+8)}p.fillStyle=d}}}}});var VariantPainter=function(c,e,a,b,d){FeaturePainter.call(this,c,e,a,b,d)};extend(VariantPainter.prototype,FeaturePainter.prototype,{draw_element:function(u,p,j,e,x,c,m,v,s){var j=data[i],l=j[0],t=j[1],d=j[2]-1,o=j[3],g=Math.floor(Math.max(0,(t-x)*m)),k=Math.ceil(Math.min(s,Math.max(0,(d-x)*m))),f=(p==="Dense"?0:(0+e))*v,a,y,b=null,n=null;if(no_label){u.fillStyle=block_color;u.fillRect(g+left_offset,f+5,k-g,1)}else{var w=j[4],r=j[5],h=j[6];a=9;y=1;u.fillRect(g+left_offset,f,k-g,a);if(p!=="Dense"&&o!==undefined&&t>x){u.fillStyle=label_color;if(tile_index===0&&g-u.measureText(o).width<0){u.textAlign="left";u.fillText(o,k+2+left_offset,f+8)}else{u.textAlign="right";u.fillText(o,g-2+left_offset,f+8)}u.fillStyle=block_color}var q=w+" / "+r;if(t>x&&u.measureText(q).width<(k-g)){u.fillStyle="white";u.textAlign="center";u.fillText(q,left_offset+g+(k-g)/2,f+8);u.fillStyle=block_color}}}});var ReadPainter=function(d,f,a,c,e,b){FeaturePainter.call(this,d,f,a,c,e);this.ref_seq=b};extend(ReadPainter.prototype,FeaturePainter.prototype,{get_row_height:function(){var a,b=this.mode;if(b==="summary_tree"){}if(b==="Dense"){a=DENSE_TRACK_HEIGHT}else{if(b==="Squish"){a=SQUISH_TRACK_HEIGHT}else{a=PACK_TRACK_HEIGHT;if(this.prefs.show_insertions){a*=2}}}return a},draw_read:function(z,u,p,E,d,y,m,j,h){z.textAlign="center";var x=this,b=[E,d],s=0,A=0,w=0;ref_seq=this.ref_seq;var J=[];if((u==="Pack"||this.mode==="Auto")&&j!==undefined&&p>CHAR_WIDTH_PX){w=Math.round(p/2)}if(!m){m=[[0,j.length]]}for(var q=0,C=m.length;q<C;q++){var n=m[q],e="MIDNSHP=X"[n[0]],r=n[1];if(e==="H"||e==="S"){s-=r}var k=y+s,I=Math.floor(Math.max(0,(k-E)*p)),l=Math.floor(Math.max(0,(k+r-E)*p));switch(e){case"H":break;case"S":case"M":case"=":var t=compute_overlap([k,k+r],b);if(t!==NO_OVERLAP){var v=j.slice(A,A+r);if(w>0){z.fillStyle=this.prefs.block_color;z.fillRect(I-w,h+1,l-I,9);z.fillStyle=CONNECTOR_COLOR;for(var G=0,a=v.length;G<a;G++){if(this.prefs.show_differences&&ref_seq){var o=ref_seq[k-E+G];if(!o||o.toLowerCase()===v[G].toLowerCase()){continue}}if(k+G>=E&&k+G<=d){var H=Math.floor(Math.max(0,(k+G-E)*p));z.fillText(v[G],H,h+9)}}}else{z.fillStyle=this.prefs.block_color;z.fillRect(I,h+(this.mode!=="Dense"?4:5),l-I,(u!=="Dense"?SQUISH_FEATURE_HEIGHT:DENSE_FEATURE_HEIGHT))}}A+=r;s+=r;break;case"N":z.fillStyle=CONNECTOR_COLOR;z.fillRect(I-w,h+5,l-I,1);s+=r;break;case"D":z.fillStyle="red";z.fillRect(I-w,h+4,l-I,3);s+=r;break;case"P":break;case"I":var t=compute_overlap([k,k+r],b),D=I-w;if(t!==NO_OVERLAP){var v=j.slice(A,A+r);if(this.prefs.show_insertions){var g=I-(l-I)/2;if((u==="Pack"||this.mode==="Auto")&&j!==undefined&&p>CHAR_WIDTH_PX){z.fillStyle="yellow";z.fillRect(g-w,h-9,l-I,9);J[J.length]={type:"triangle",data:[D,h+4,5]};z.fillStyle=CONNECTOR_COLOR;switch(t){case (OVERLAP_START):v=v.slice(E-k);break;case (OVERLAP_END):v=v.slice(0,k-d);break;case (CONTAINED_BY):break;case (CONTAINS):v=v.slice(E-k,k-d);break}for(var G=0,a=v.length;G<a;G++){var H=Math.floor(Math.max(0,(k+G-E)*p));z.fillText(v[G],H-(l-I)/2,h)}}else{z.fillStyle="yellow";z.fillRect(g,h+(this.mode!=="Dense"?2:5),l-I,(u!=="Dense"?SQUISH_FEATURE_HEIGHT:DENSE_FEATURE_HEIGHT))}}else{if((u==="Pack"||this.mode==="Auto")&&j!==undefined&&p>CHAR_WIDTH_PX){J[J.length]={type:"text",data:[v.length,D,h+9]}}else{}}}A+=r;break;case"X":A+=r;break}}z.fillStyle="yellow";var F,f,K;for(var B=0;B<J.length;B++){F=J[B];f=F.type;K=F.data;if(f==="text"){z.font="bold "+DEFAULT_FONT;z.fillText(K[0],K[1],K[2]);z.font=DEFAULT_FONT}else{if(f=="triangle"){z.drawDownwardEquilateralTriangle(K[0],K[1],K[2])}}}},draw_element:function(u,p,g,d,x,b,l,v,s){var k=g[0],t=g[1],c=g[2],m=g[3],f=Math.floor(Math.max(0,(t-x)*l)),h=Math.ceil(Math.min(s,Math.max(0,(c-x)*l))),e=(p==="Dense"?1:(1+d))*v,y=this.prefs.block_color,j=this.prefs.label_color,r=0;if((p==="Pack"||this.mode==="Auto")&&l>CHAR_WIDTH_PX){var r=Math.round(l/2)}u.fillStyle=y;if(g[5] instanceof Array){var q=Math.floor(Math.max(0,(g[4][0]-x)*l)),o=Math.ceil(Math.min(s,Math.max(0,(g[4][1]-x)*l))),n=Math.floor(Math.max(0,(g[5][0]-x)*l)),a=Math.ceil(Math.min(s,Math.max(0,(g[5][1]-x)*l)));if(g[4][1]>=x&&g[4][0]<=b&&g[4][2]){this.draw_read(u,p,l,x,b,g[4][0],g[4][2],g[4][3],e)}if(g[5][1]>=x&&g[5][0]<=b&&g[5][2]){this.draw_read(u,p,l,x,b,g[5][0],g[5][2],g[5][3],e)}if(n>o){u.fillStyle=CONNECTOR_COLOR;u.dashedLine(o-r,e+5,n-r,e+5)}}else{u.fillStyle=y;this.draw_read(u,p,l,x,b,t,g[4],g[5],e)}if(p==="Pack"&&t>x){u.fillStyle=this.prefs.label_color;var w=1;if(w===0&&f-u.measureText(m).width<0){u.textAlign="left";u.fillText(m,h+LABEL_SPACING-r,e+8)}else{u.textAlign="right";u.fillText(m,f-LABEL_SPACING-r,e+8)}u.fillStyle=y}}});
\ No newline at end of file
+var extend=function(){var c=arguments[0];for(var b=1;b<arguments.length;b++){var a=arguments[b];for(key in a){c[key]=a[key]}}};var trackster_module=function(f,Q){var o=f("slotting"),G=f("painters");var V=function(W,X){this.document=W;this.default_font=X!==undefined?X:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};extend(V.prototype,{load_pattern:function(W,aa){var X=this.patterns,Y=this.dummy_context,Z=new Image();Z.src=image_path+aa;Z.onload=function(){X[W]=Y.createPattern(Z,"repeat")}},get_pattern:function(W){return this.patterns[W]},new_canvas:function(){var W=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(W)}W.manager=this;return W}});var B=function(W,X){W.bind("drag",{handle:X,relative:true},function(ab,ac){var aa=$(this).parent();var Z=aa.children();var Y;for(Y=0;Y<Z.length;Y++){if(ac.offsetY<$(Z.get(Y)).position().top){break}}if(Y===Z.length){if(this!==Z.get(Y-1)){aa.append(this)}}else{if(this!==Z.get(Y)){$(this).insertBefore(Z.get(Y))}}})};var h=function(Y,W){var X=W-Y;return(X<=2?0.01:(X<=100?1:(X<=1000?5:10)))};var C=9,z=10,L=C+2,w=100,D=12000,J=200,r=10,F=5000,s=100,m="There was an error in indexing this dataset. ",E="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",A="No data for this chrom/contig.",p="Currently indexing... please wait",u="Tool cannot be rerun: ",a="Loading data...",R="Ready for display",d=10,q=5,y=5;function t(W){return Math.round(W*1000)/1000}var c=function(W){this.num_elements=W;this.clear()};extend(c.prototype,{get:function(X){var W=this.key_ary.indexOf(X);if(W!==-1){this.move_key_to_end(X,W)}return this.obj_cache[X]},set:function(X,Y){if(!this.obj_cache[X]){if(this.key_ary.length>=this.num_elements){var W=this.key_ary.shift();delete this.obj_cache[W]}this.key_ary.push(X)}this.obj_cache[X]=Y;return Y},move_key_to_end:function(X,W){this.key_ary.splice(W,1);this.key_ary.push(X)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var K=function(X,W,Y){c.call(this,X);this.track=W;this.subset=(Y!==undefined?Y:true)};extend(K.prototype,c.prototype,{load_data:function(ad,ae,Z,ac,W,ab){var Y={chrom:ad,low:ae,high:Z,mode:ac,resolution:W,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(Y,ab);var af=[];for(var aa=0;aa<this.track.filters.length;aa++){af[af.length]=this.track.filters[aa].name}Y.filter_cols=JSON.stringify(af);var X=this;return $.getJSON(this.track.data_url,Y,function(ag){X.set_data(ae,Z,ac,ag)})},get_data:function(Y,W,ab,ac,X,aa){var Z=this.get(this.gen_key(W,ab,ac));if(Z){return Z}Z=this.load_data(Y,W,ab,ac,X,aa);this.set_data(W,ab,ac,Z);return Z},set_data:function(X,Y,Z,W){return this.set(this.gen_key(X,Y,Z),W)},gen_key:function(W,Y,Z){var X=W+"_"+Y+"_"+Z;return X},split_key:function(W){return W.split("_")}});var U=function(W,Z,Y,X,aa){this.container=W;this.chrom=null;this.vis_id=Y;this.dbkey=X;this.title=Z;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(aa);this.canvas_manager=new V(W.get(0).ownerDocument);this.reset()};extend(U.prototype,{init:function(Z){var Y=this.container,W=this;this.top_container=$("<div/>").addClass("top-container").appendTo(Y);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(Y);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(Y);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);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_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);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_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var X=function(aa){if(aa.type==="focusout"||(aa.keyCode||aa.which)===13||(aa.keyCode||aa.which)===27){if((aa.keyCode||aa.which)!==27){W.go_to($(this).val())}$(this).hide();$(this).val("");W.location_span.show();W.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",X).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.bind("click",function(){W.location_span.hide();W.chrom_select.hide();W.nav_input.val(W.chrom+":"+W.low+"-"+W.high);W.nav_input.css("display","inline-block");W.nav_input.select();W.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a id='zoom-out' />").click(function(){W.zoom_out();W.redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){W.zoom_in();W.redraw()}).appendTo(this.nav_controls);this.load_chroms({low:0},Z);this.chrom_select.bind("change",function(){W.change_chrom(W.chrom_select.val())});this.intro_div.show();this.content_div.bind("click",function(aa){$(this).find("input").trigger("blur")});this.content_div.bind("dblclick",function(aa){W.zoom_in(aa.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(aa,ab){this.current_x=ab.offsetX}).bind("drag",function(aa,ac){var ad=ac.offsetX-this.current_x;this.current_x=ac.offsetX;var ab=Math.round(ad/W.viewport_container.width()*(W.max_high-W.max_low));W.move_delta(-ab)});this.overview_close.bind("click",function(){for(var ab=0,aa=W.tracks.length;ab<aa;ab++){W.tracks[ab].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",W.overview_box.height());W.overview_highlight.hide();$(this).hide()});this.viewport_container.bind("draginit",function(aa,ab){if(aa.clientX>W.viewport_container.width()-16){return false}}).bind("dragstart",function(aa,ab){ab.original_low=W.low;ab.current_height=aa.clientY;ab.current_x=ab.offsetX}).bind("drag",function(ac,ae){var aa=$(this);var af=ae.offsetX-ae.current_x;var ab=aa.scrollTop()-(ac.clientY-ae.current_height);aa.scrollTop(ab);ae.current_height=ac.clientY;ae.current_x=ae.offsetX;var ad=Math.round(af/W.viewport_container.width()*(W.high-W.low));W.move_delta(ad)}).bind("mousewheel",function(ac,ae,ab,aa){if(ab){var ad=Math.round(-ab/W.viewport_container.width()*(W.high-W.low));W.move_delta(ad)}});this.top_labeltrack.bind("dragstart",function(aa,ab){return $("<div />").css({height:W.content_div.height()+W.top_labeltrack.height()+W.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ae,af){$(af.proxy).css({left:Math.min(ae.pageX,af.startX),width:Math.abs(ae.pageX-af.startX)});var ab=Math.min(ae.pageX,af.startX)-W.container.offset().left,aa=Math.max(ae.pageX,af.startX)-W.container.offset().left,ad=(W.high-W.low),ac=W.viewport_container.width();W.update_location(Math.round(ab/ac*ad)+W.low,Math.round(aa/ac*ad)+W.low)}).bind("dragend",function(af,ag){var ab=Math.min(af.pageX,ag.startX),aa=Math.max(af.pageX,ag.startX),ad=(W.high-W.low),ac=W.viewport_container.width(),ae=W.low;W.low=Math.round(ab/ac*ad)+ae;W.high=Math.round(aa/ac*ad)+ae;$(ag.proxy).remove();W.redraw()});this.add_label_track(new T(this,this.top_labeltrack));this.add_label_track(new T(this,this.nav_labeltrack));$(window).bind("resize",function(){W.resize_window()});$(document).bind("redraw",function(){W.redraw()});this.reset();$(window).trigger("resize")},update_location:function(W,X){this.location_span.text(commatize(W)+" - "+commatize(X));this.nav_input.val(this.chrom+":"+commatize(W)+"-"+commatize(X))},load_chroms:function(X,Y){X.num=s;$.extend(X,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var W=this;$.ajax({url:chrom_url,data:X,dataType:"json",success:function(aa){if(aa.chrom_info.length===0){alert("Invalid chromosome: "+X.chrom);return}if(aa.reference){W.add_label_track(new x(W))}W.chrom_data=aa.chrom_info;var ad='<option value="">Select Chrom/Contig</option>';for(var ac=0,Z=W.chrom_data.length;ac<Z;ac++){var ab=W.chrom_data[ac].chrom;ad+='<option value="'+ab+'">'+ab+"</option>"}if(aa.prev_chroms){ad+='<option value="previous">Previous '+s+"</option>"}if(aa.next_chroms){ad+='<option value="next">Next '+s+"</option>"}W.chrom_select.html(ad);if(Y){Y()}W.chrom_start_index=aa.start_index},error:function(){alert("Could not load chroms for this dbkey:",W.dbkey)}})},change_chrom:function(aa,X,ac){if(!aa||aa==="None"){return}var Z=this;if(aa==="previous"){Z.load_chroms({low:this.chrom_start_index-s});return}if(aa==="next"){Z.load_chroms({low:this.chrom_start_index+s});return}var ab=$.grep(Z.chrom_data,function(ae,af){return ae.chrom===aa})[0];if(ab===undefined){Z.load_chroms({chrom:aa},function(){Z.change_chrom(aa,X,ac)});return}else{if(aa!==Z.chrom){Z.chrom=aa;if(!Z.chrom){Z.intro_div.show()}else{Z.intro_div.hide()}Z.chrom_select.val(Z.chrom);Z.max_high=ab.len-1;Z.reset();Z.redraw(true);for(var ad=0,W=Z.tracks.length;ad<W;ad++){var Y=Z.tracks[ad];if(Y.init){Y.init()}}}if(X!==undefined&&ac!==undefined){Z.low=Math.max(X,0);Z.high=Math.min(ac,Z.max_high)}Z.reset_overview();Z.redraw()}},go_to:function(aa){var ae=this,W,Z,X=aa.split(":"),ac=X[0],ad=X[1];if(ad!==undefined){try{var ab=ad.split("-");W=parseInt(ab[0].replace(/,/g,""),10);Z=parseInt(ab[1].replace(/,/g,""),10)}catch(Y){return false}}ae.change_chrom(ac,W,Z)},move_fraction:function(Y){var W=this;var X=W.high-W.low;this.move_delta(Y*X)},move_delta:function(Y){var W=this;var X=W.high-W.low;if(W.low-Y<W.max_low){W.low=W.max_low;W.high=W.max_low+X}else{if(W.high-Y>W.max_high){W.high=W.max_high;W.low=W.max_high-X}else{W.high-=Y;W.low-=Y}}W.redraw()},add_track:function(W){W.view=this;W.track_id=this.track_id_counter;this.tracks.push(W);if(W.init){W.init()}W.container_div.attr("id","track_"+W.track_id);B(W.container_div,".draghandle");this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(W){W.view=this;this.label_tracks.push(W)},remove_track:function(W){this.has_changes=true;W.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(W)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(ad){var ac=this.high-this.low,ab=this.low,X=this.high;if(ab<this.max_low){ab=this.max_low}if(X>this.max_high){X=this.max_high}if(this.high!==0&&ac<this.min_separation){X=ab+this.min_separation}this.low=Math.floor(ab);this.high=Math.ceil(X);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(r,Math.max(0,Math.ceil(Math.log(this.resolution,r)/Math.log(r))));var W=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var aa=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ae=13;this.overview_box.css({left:W,width:Math.max(ae,aa)}).show();if(aa<ae){this.overview_box.css("left",W-(ae-aa)/2)}if(this.overview_highlight){this.overview_highlight.css({left:W,width:aa})}this.update_location(this.low,this.high);if(!ad){for(var Y=0,Z=this.tracks.length;Y<Z;Y++){if(this.tracks[Y]&&this.tracks[Y].enabled){this.tracks[Y].draw()}}for(Y=0,Z=this.label_tracks.length;Y<Z;Y++){this.label_tracks[Y].draw()}}},zoom_in:function(X,Y){if(this.max_high===0||this.high-this.low<this.min_separation){return}var Z=this.high-this.low,aa=Z/2+this.low,W=(Z/this.zoom_factor)/2;if(X){aa=X/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(aa-W);this.high=Math.round(aa+W);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var X=this.high-this.low,Y=X/2+this.low,W=(X*this.zoom_factor)/2;this.low=Math.round(Y-W);this.high=Math.round(Y+W);this.redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide()}});var n=function(X,aa){this.track=X;this.name=aa.name;this.params=[];var ai=aa.params;for(var Y=0;Y<ai.length;Y++){var ad=ai[Y],W=ad.name,ah=ad.label,Z=unescape(ad.html),af=ad.type;if(af==="number"){this.params[this.params.length]=new g(W,ah,Z,ad.min,ad.max)}else{if(af=="select"){this.params[this.params.length]=new I(W,ah,Z)}else{console.log("WARNING: unrecognized tool parameter type:",W,af)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(ak){ak.stopPropagation()}).bind("click",function(ak){ak.stopPropagation()}).bind("dblclick",function(ak){ak.stopPropagation()});var ag=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var ae=this.params;var ab=this;$.each(this.params,function(al,ao){var an=$("<div>").addClass("param-row").appendTo(ab.parent_div);var ak=$("<div>").addClass("param-label").text(ao.label).appendTo(an);var am=$("<div/>").addClass("slider").html(ao.html).appendTo(an);$("<div style='clear: both;'/>").appendTo(an)});this.parent_div.find("input").click(function(){$(this).select()});var aj=$("<div>").addClass("slider-row").appendTo(this.parent_div);var ac=$("<input type='submit'>").attr("value","Run").appendTo(aj);var ab=this;ac.click(function(){ab.run()})};extend(n.prototype,{get_param_values_dict:function(){var W={};this.parent_div.find(":input").each(function(){var X=$(this).attr("name"),Y=$(this).val();W[X]=JSON.stringify(Y)});return W},get_param_values:function(){var X=[];var W={};this.parent_div.find(":input").each(function(){var Y=$(this).attr("name"),Z=$(this).val();if(Y){X[X.length]=Z}});return X},run:function(){var X={dataset_id:this.track.original_dataset_id,chrom:this.track.view.chrom,low:this.track.view.low,high:this.track.view.high,tool_id:this.name};$.extend(X,this.get_param_values_dict());var Z=this.track,Y=X.tool_id+Z.tool_region_and_parameters_str(X.chrom,X.low,X.high),aa;if(Z.track_type==="FeatureTrack"){aa=new N(Y,view,Z.hda_ldda,undefined,{},{},Z)}this.track.add_track(aa);aa.content_div.text("Starting job.");var W=function(){$.getJSON(run_tool_url,X,function(ab){if(ab==="no converter"){aa.container_div.addClass("error");aa.content_div.text(E)}else{if(ab.error){aa.container_div.addClass("error");aa.content_div.text(u+ab.message)}else{if(ab==="pending"){aa.container_div.addClass("pending");aa.content_div.text("Converting input data so that it can be easily reused.");setTimeout(W,2000)}else{aa.dataset_id=ab.dataset_id;aa.content_div.text("Running job.");aa.init()}}}})};W()}});var I=function(X,W,Y){this.name=X;this.label=W;this.html=Y};var g=function(Y,X,aa,Z,W){I.call(this,Y,X,aa);this.min=Z;this.max=W};var j=function(X,W,Y){this.name=X;this.index=W;this.value=Y};var O=function(X,W){this.name=X;this.index=W;this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.slider=null;this.slider_label=null};extend(O.prototype,{applies_to:function(W){if(W.length>this.index){return true}return false},keep:function(W){if(!this.applies_to(W)){return true}return(W[this.index]>=this.low&&W[this.index]<=this.high)},update_attrs:function(X){var W=false;if(!this.applies_to(X)){return W}if(X[this.index]<this.min){this.min=Math.floor(X[this.index]);W=true}if(X[this.index]>this.max){this.max=Math.ceil(X[this.index]);W=true}return W},update_ui_elt:function(){var X=this.slider.slider("option","min"),W=this.slider.slider("option","max");if(this.min<X||this.max>W){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",h(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var v=function(W){var ac=[];for(var Z=0;Z<W.length;Z++){var ab=W[Z];var Y=ab.name,aa=ab.type,X=ab.index;if(aa==="int"||aa==="float"){ac[Z]=new O(Y,X)}else{ac[Z]=new j(Y,X,aa)}}return ac};var S=function(W){this.track=W.track;this.params=W.params;this.values={};if(W.saved_values){this.restore_values(W.saved_values)}this.onchange=W.onchange};extend(S.prototype,{restore_values:function(W){var X=this;$.each(this.params,function(Y,Z){if(W[Z.key]!==undefined){X.values[Z.key]=W[Z.key]}else{X.values[Z.key]=Z.default_value}})},build_form:function(){var X=this;var W=$("<div />");$.each(this.params,function(ab,Z){if(!Z.hidden){var Y="param_"+ab;var ag=$("<div class='form-row' />").appendTo(W);ag.append($("<label />").attr("for",Y).text(Z.label+":"));if(Z.type==="bool"){ag.append($('<input type="checkbox" />').attr("id",Y).attr("name",Y).attr("checked",X.values[Z.key]))}else{if(Z.type==="color"){var ad=X.values[Z.key];var ac=$("<input />").attr("id",Y).attr("name",Y).val(ad);var ae=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var aa=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(ae);var af=$("<div/>").appendTo(aa).farbtastic({width:100,height:100,callback:ac,color:ad});$("<div />").append(ac).append(ae).appendTo(ag).bind("click",function(ah){ae.css({left:$(this).position().left+($(ac).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){ae.hide();$(document).unbind("click.color-picker")});ah.stopPropagation()})}else{ag.append($("<input />").attr("id",Y).attr("name",Y).val(X.values[Z.key]))}}}});return W},update_from_form:function(W){var Y=this;var X=false;$.each(this.params,function(Z,ab){if(!ab.hidden){var ac="param_"+Z;var aa=W.find("#"+ac).val();if(ab.type==="float"){aa=parseFloat(aa)}else{if(ab.type==="int"){aa=parseInt(aa)}else{if(ab.type==="bool"){aa=W.find("#"+ac).is(":checked")}}}if(aa!==Y.values[ab.key]){Y.values[ab.key]=aa;X=true}}});if(X){this.onchange()}}});var b=function(W,X,Y){this.track=W;this.canvas=X;this.histo_max=Y};var k=function(X,W,aa,Y,Z){this.name=X;this.view=W;this.parent_element=aa;this.data_url=(Y?Y:default_data_url);this.data_url_extra_params={};this.data_query_wait=(Z?Z:F);this.dataset_check_url=converted_datasets_state_url;this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){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.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)};extend(k.prototype,{init:function(){var W=this;W.enabled=false;W.tile_cache.clear();W.data_cache.clear();W.initial_canvas=undefined;W.content_div.css("height","auto");W.container_div.removeClass("nodata error pending");if(!W.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:W.hda_ldda,dataset_id:W.dataset_id,chrom:W.view.chrom},function(X){if(!X||X==="error"||X.kind==="error"){W.container_div.addClass("error");W.content_div.text(m);if(X.message){var Z=W.view.tracks.indexOf(W);var Y=$(" <a href='javascript:void(0);'></a>").text("View error").bind("click",function(){show_modal("Trackster Error","<pre>"+X.message+"</pre>",{Close:hide_modal})});W.content_div.append(Y)}}else{if(X==="no converter"){W.container_div.addClass("error");W.content_div.text(E)}else{if(X==="no data"||(X.data!==undefined&&(X.data===null||X.data.length===0))){W.container_div.addClass("nodata");W.content_div.text(A)}else{if(X==="pending"){W.container_div.addClass("pending");W.content_div.text(p);setTimeout(function(){W.init()},W.data_query_wait)}else{if(X.status==="data"){if(X.valid_chroms){W.valid_chroms=X.valid_chroms;W.make_name_popup_menu()}W.content_div.text(R);if(W.view.chrom){W.content_div.text("");W.content_div.css("height",W.height_px+"px");W.enabled=true;$.when(W.predraw_init()).done(function(){W.draw()})}}}}}}})},predraw_init:function(){},update_name:function(W){this.old_name=this.name;this.name=W;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)}});var H=function(X,ad,ag){var Y=this,ah=Y.view;this.filters=(X!==undefined?v(X):[]);this.filters_available=false;this.filters_visible=false;this.tool=(ad!==undefined&&obj_length(ad)>0?new n(this,ad):undefined);this.parent_track=ag;this.child_tracks=[];if(Y.hidden){return}var af=function(ai,aj,ak){ai.click(function(){var al=aj.text();max=parseFloat(ak.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(ak.slider("option","values")){input_size=2*input_size+1;multi_value=true}aj.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",al).appendTo(aj).focus().select().click(function(am){am.stopPropagation()}).blur(function(){$(this).remove();aj.text(al)}).keyup(function(aq){if(aq.keyCode===27){$(this).trigger("blur")}else{if(aq.keyCode===13){var ao=ak.slider("option","min"),am=ak.slider("option","max"),ap=function(ar){return(isNaN(ar)||ar>am||ar<ao)},an=$(this).val();if(!multi_value){an=parseFloat(an);if(ap(an)){alert("Parameter value must be in the range ["+ao+"-"+am+"]");return $(this)}}else{an=an.split("-");an=[parseFloat(an[0]),parseFloat(an[1])];if(ap(an[0])||ap(an[1])){alert("Parameter value must be in the range ["+ao+"-"+am+"]");return $(this)}}ak.slider((multi_value?"values":"value"),an)}}})})};if(this.parent_track){this.header_div.find(".draghandle").removeClass("draghandle").addClass("child-track-icon").addClass("icon-button");this.parent_element.addClass("child-track");this.tool=undefined}this.filters_div=$("<div/>").addClass("filters").hide();this.header_div.after(this.filters_div);this.filters_div.bind("drag",function(ai){ai.stopPropagation()}).bind("click",function(ai){ai.stopPropagation()}).bind("dblclick",function(ai){ai.stopPropagation()});$.each(this.filters,function(ao,aj){var al=$("<div/>").addClass("slider-row").appendTo(Y.filters_div);var ai=$("<div/>").addClass("slider-label").appendTo(al);var aq=$("<span/>").addClass("slider-name").text(aj.name+" ").appendTo(ai);var ak=$("<span/>");var am=$("<span/>").addClass("slider-value").appendTo(ai).append("[").append(ak).append("]");var ap=$("<div/>").addClass("slider").appendTo(al);aj.control_element=$("<div/>").attr("id",aj.name+"-filter-control").appendTo(ap);var an=[0,0];aj.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(ar,at){an=at.values;ak.text(at.values[0]+"-"+at.values[1]);setTimeout(function(){if(at.values[0]==an[0]&&at.values[1]==an[1]){var au=at.values;ak.text(au[0]+"-"+au[1]);aj.low=au[0];aj.high=au[1];Y.draw(true,true)}},50)},change:function(ar,at){aj.control_element.slider("option","slide").call(aj.control_element,ar,at)}});aj.slider=aj.control_element;aj.slider_label=ak;af(am,ak,aj.control_element);$("<div style='clear: both;'/>").appendTo(al)});if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}Y.child_tracks_container=$("<div/>").addClass("child-tracks-container").hide();Y.container_div.append(Y.child_tracks_container);if(Y.display_modes!==undefined){if(Y.mode_div===undefined){Y.mode_div=$("<div class='right-float menubutton popup' />").appendTo(Y.header_div);var aa=(Y.track_config&&Y.track_config.values.mode?Y.track_config.values.mode:Y.display_modes[0]);Y.mode=aa;Y.mode_div.text(aa);var Z=function(ai){Y.mode_div.text(ai);Y.mode=ai;Y.track_config.values.mode=ai;Y.tile_cache.clear();Y.draw()};var W={};for(var ab=0,ae=Y.display_modes.length;ab<ae;ab++){var ac=Y.display_modes[ab];W[ac]=function(ai){return function(){Z(ai)}}(ac)}make_popupmenu(Y.mode_div,W)}else{Y.mode_div.hide()}}this.make_name_popup_menu()};extend(H.prototype,k.prototype,{make_name_popup_menu:function(){var X=this;var W={};W["Edit configuration"]=function(){var ad=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},ab=function(){X.track_config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ac=function(ae){if((ae.keyCode||ae.which)===27){ad()}else{if((ae.keyCode||ae.which)===13){ab()}}};$(window).bind("keypress.check_enter_esc",ac);show_modal("Configure Track",X.track_config.build_form(),{Cancel:ad,OK:ab})};if(X.filters_available>0){var aa=(X.filters_div.is(":visible")?"Hide filters":"Show filters");W[aa]=function(){X.filters_visible=(X.filters_div.is(":visible"));X.filters_div.toggle();X.make_name_popup_menu()}}if(X.tool){var aa=(X.dynamic_tool_div.is(":visible")?"Hide tool":"Show tool");W[aa]=function(){if(!X.dynamic_tool_div.is(":visible")){X.update_name(X.name+X.tool_region_and_parameters_str())}else{menu_option_text="Show dynamic tool";X.revert_name()}X.dynamic_tool_div.toggle();X.make_name_popup_menu()}}if(X.valid_chroms){W["List chrom/contigs with data"]=function(){show_modal("Chrom/contigs with data","<p>"+X.valid_chroms.join("<br/>")+"</p>",{Close:function(){hide_modal()}})}}var Y=view;var Z=function(){$("#no-tracks").show()};if(this.parent_track){Y=this.parent_track;Z=function(){}}W.Remove=function(){Y.remove_track(X);if(Y.num_tracks===0){Z()}};make_popupmenu(X.name_div,W)},draw:function(W,Z){var an=this.view.low,ac=this.view.high,ae=ac-an,ag=this.view.container.width(),ab=ag/ae,ah=this.view.resolution,aa=$("<div style='position: relative;'></div>");if(!Z){this.content_div.children().remove()}this.content_div.append(aa);this.max_height=0;var aj=Math.floor(an/ah/J);var Y={};while((aj*J*ah)<ac){var am=ag+"_"+ab+"_"+aj;var ad=this.tile_cache.get(am);var ak=aj*J*this.view.resolution;var X=ak+J*this.view.resolution;if(!W&&ad){this.show_tile(ad,aa,ak,ab)}else{this.delayed_draw(W,am,ak,X,aj,ah,aa,ab,Y)}aj+=1}var af=this;var al=setInterval(function(){if(obj_length(Y)===0){clearInterval(al);if(Z){var aq=af.content_div.children();var ap=false;for(var ar=aq.length-1,ao=0;ar>=ao;ar--){var av=$(aq[ar]);if(ap){av.remove()}else{if(av.children().length!==0){ap=true}}}}for(var au=0;au<af.filters.length;au++){af.filters[au].update_ui_elt()}var at=false;if(af.example_feature){for(var au=0;au<af.filters.length;au++){if(af.filters[au].applies_to(af.example_feature)){at=true;break}}}if(af.filters_available!==at){af.filters_available=at;if(!af.filters_available){af.filters_div.hide()}af.make_name_popup_menu()}}},50);for(var ai=0;ai<this.child_tracks.length;ai++){this.child_tracks[ai].draw(W,Z)}},delayed_draw:function(X,ae,ac,ag,Y,aa,af,ah,ab){var Z=this;var ad=function(ap,ai,ak,aj,an,ao,al){returned_tile=Z.draw_tile(ai,ak,aj,an,ao,al);var am=$("<div class='track-tile'>").prepend(returned_tile);tile_element=am;Z.tile_cache.set(ae,tile_element);Z.show_tile(tile_element,an,ac,ao);delete ab[ap]};var W=setTimeout(function(){if(ac<=Z.view.high&&ag>=Z.view.low){var ai=(X?undefined:Z.tile_cache.get(ae));if(ai){Z.show_tile(ai,af,ac,ah);delete ab[W]}else{$.when(Z.data_cache.get_data(view.chrom,ac,ag,Z.mode,aa,Z.data_url_extra_params)).then(function(aj){if(view.reference_track&&ah>view.canvas_manager.char_width_px){$.when(view.reference_track.data_cache.get_data(view.chrom,ac,ag,Z.mode,aa,view.reference_track.data_url_extra_params)).then(function(ak){ad(W,aj,aa,Y,af,ah,ak)})}else{ad(W,aj,aa,Y,af,ah)}})}}},50);ab[W]=true},show_tile:function(W,ab,Z,ac){var X=this;var Y=this.view.high-this.view.low,aa=(Z-this.view.low)*ac;if(this.left_offset){aa-=this.left_offset}W.css({position:"absolute",top:0,left:aa,height:""});ab.append(W);X.max_height=Math.max(X.max_height,W.height());X.content_div.css("height",X.max_height+"px");ab.children().css("height",X.max_height+"px")},set_overview:function(){var W=this.view;if(this.initial_canvas&&this.is_overview){W.overview_close.show();W.overview_viewport.append(this.initial_canvas);W.overview_highlight.show().height(this.initial_canvas.height());W.overview_viewport.height(this.initial_canvas.height()+W.overview_box.height())}$(window).trigger("resize")},tool_region_and_parameters_str:function(Y,W,Z){var X=this,aa=(Y!==undefined&&W!==undefined&&Z!==undefined?Y+":"+W+"-"+Z:"all");return" - region=["+aa+"], parameters=["+X.tool.get_param_values().join(", ")+"]"},add_track:function(W){W.track_id=this.track_id+"_"+this.child_tracks.length;W.container_div.attr("id","track_"+W.track_id);this.child_tracks_container.append(W.container_div);B(W.container_div,".child-track-icon");if(!$(this.child_tracks_container).is(":visible")){this.child_tracks_container.show()}this.child_tracks.push(W);this.view.has_changes=true},remove_track:function(W){W.container_div.fadeOut("slow",function(){$(this).remove()})}});var T=function(W,X){this.track_type="LabelTrack";this.hidden=true;k.call(this,null,W,X);this.container_div.addClass("label-track")};extend(T.prototype,k.prototype,{draw:function(){var Y=this.view,Z=Y.high-Y.low,ac=Math.floor(Math.pow(10,Math.floor(Math.log(Z)/Math.log(10)))),W=Math.floor(Y.low/ac)*ac,aa=this.view.container.width(),X=$("<div style='position: relative; height: 1.3em;'></div>");while(W<Y.high){var ab=(W-Y.low)/Z*aa;X.append($("<div class='label'>"+commatize(W)+"</div>").css({position:"absolute",left:ab-1}));W+=ac}this.content_div.children(":first").remove();this.content_div.append(X)}});var x=function(W){this.track_type="ReferenceTrack";this.hidden=true;k.call(this,null,W,W.top_labeltrack);H.call(this);W.reference_track=this;this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:W.dbkey};this.data_cache=new K(y,this,false);this.tile_cache=new c(q)};extend(x.prototype,H.prototype,{draw_tile:function(ag,ab,X,ad,ah){var aa=this,Y=J*ab;if(ah>this.view.canvas_manager.char_width_px){if(ag===null){aa.content_div.css("height","0px");return}var Z=this.view.canvas_manager.new_canvas();var af=Z.getContext("2d");Z.width=Math.ceil(Y*ah+aa.left_offset);Z.height=aa.height_px;af.font=af.canvas.manager.default_font;af.textAlign="center";for(var ac=0,ae=ag.length;ac<ae;ac++){var W=Math.round(ac*ah);af.fillText(ag[ac],W+aa.left_offset,10)}return Z}this.content_div.css("height","0px")}});var l=function(aa,Y,ab,W,Z){var X=this;this.track_type="LineTrack";this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";k.call(this,aa,Y,Y.viewport_container);H.call(this);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=ab;this.dataset_id=W;this.original_dataset_id=W;this.data_cache=new K(y,this);this.tile_cache=new c(q);this.track_config=new S({track:this,params:[{key:"color",label:"Color",type:"color",default_value:"black"},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.height_px,hidden:true}],saved_values:Z,onchange:function(){X.vertical_range=X.prefs.max_value-X.prefs.min_value;$("#linetrack_"+X.track_id+"_minval").text(X.prefs.min_value);$("#linetrack_"+X.track_id+"_maxval").text(X.prefs.max_value);X.tile_cache.clear();X.draw()}});this.prefs=this.track_config.values;this.height_px=this.track_config.values.height;this.vertical_range=this.track_config.values.max_value-this.track_config.values.min_value;this.add_resize_handle()};extend(l.prototype,H.prototype,{add_resize_handle:function(){var W=this;var Z=false;var Y=false;var X=$("<div class='track-resize'>");$(W.container_div).hover(function(){Z=true;X.show()},function(){Z=false;if(!Y){X.hide()}});X.hide().bind("dragstart",function(aa,ab){Y=true;ab.original_height=$(W.content_div).height()}).bind("drag",function(ab,ac){var aa=Math.min(Math.max(ac.original_height+ac.deltaY,W.min_height_px),W.max_height_px);$(W.content_div).css("height",aa);W.height_px=aa;W.draw(true)}).bind("dragend",function(aa,ab){W.tile_cache.clear();Y=false;if(!Z){X.hide()}W.track_config.values.height=W.height_px}).appendTo(W.container_div)},predraw_init:function(){var W=this,X=W.view.tracks.indexOf(W);W.vertical_range=undefined;return $.getJSON(W.data_url,{stats:true,chrom:W.view.chrom,low:null,high:null,hda_ldda:W.hda_ldda,dataset_id:W.dataset_id},function(Y){W.container_div.addClass("line-track");var aa=Y.data;if(isNaN(parseFloat(W.prefs.min_value))||isNaN(parseFloat(W.prefs.max_value))){W.prefs.min_value=aa.min;W.prefs.max_value=aa.max;$("#track_"+X+"_minval").val(W.prefs.min_value);$("#track_"+X+"_maxval").val(W.prefs.max_value)}W.vertical_range=W.prefs.max_value-W.prefs.min_value;W.total_frequency=aa.total_frequency;W.container_div.find(".yaxislabel").remove();var ab=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+X+"_minval").text(t(W.prefs.min_value));var Z=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+X+"_maxval").text(t(W.prefs.max_value));Z.css({position:"absolute",top:"24px",left:"10px"});Z.prependTo(W.container_div);ab.css({position:"absolute",bottom:"2px",left:"10px"});ab.prependTo(W.container_div)})},draw_tile:function(ah,aa,X,ae,ag){if(this.vertical_range===undefined){return}var ab=X*J*aa,Z=J*aa,W=Math.ceil(Z*ag),ad=this.height_px;var Y=this.view.canvas_manager.new_canvas();Y.width=W,Y.height=ad;var af=Y.getContext("2d");var ac=new G.LinePainter(ah.data,ab,ab+Z,this.prefs.min_value,this.prefs.max_value,this.prefs.color,this.mode);ac.draw(af,W,ad);return Y}});var e=function(W,ab,aa,ae,ad,Y,Z,ac){var X=this;this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];this.track_config=new S({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ad,onchange:function(){X.tile_cache.clear();X.draw()}});this.prefs=this.track_config.values;k.call(this,W,ab,ab.viewport_container);H.call(this,Y,Z,ac);this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=aa;this.dataset_id=ae;this.original_dataset_id=ae;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.inc_slots={};this.start_end_dct={};this.tile_cache=new c(d);this.data_cache=new K(20,this);this.left_offset=200;this.painter=G.LinkedFeaturePainter};extend(e.prototype,H.prototype,{update_auto_mode:function(W){if(this.mode=="Auto"){if(W=="no_detail"){W="reduced to feature spans"}else{if(W=="summary_tree"){W="reduced to coverage histogram"}}this.mode_div.text("Auto ("+W+")")}},incremental_slots:function(aa,X,Z){var Y=this.view.canvas_manager.dummy_context,W=this.inc_slots[aa];if(!W||(W.mode!==Z)){W=new (o.FeatureSlotter)(aa,Z==="Pack",w,function(ab){return Y.measureText(ab)});W.mode=Z;this.inc_slots[aa]=W}return W.slot_features(X)},draw_tile:function(ai,aq,av,ae,ag,Z){var an=this,ax=av*J*aq,X=(av+1)*J*aq,ak=X-ax,ao=Math.ceil(ak*ag),am=this.mode,aB=25,aa=this.left_offset,aj,ab;if(am==="Auto"){if(ai.dataset_type==="summary_tree"){am=ai.dataset_type}else{if(ai.extra_info==="no_detail"){am="no_detail"}else{var aA=ai.data;if((aA.length&&aA.length<4)||(this.view.high-this.view.low>D)){am="Squish"}else{am="Pack"}}}this.update_auto_mode(am)}if(am==="summary_tree"){ab=this.summary_draw_height;ae.parent().css("height",Math.max(this.height_px,ab)+"px");this.container_div.find(".yaxislabel").remove();var W=$("<div />").addClass("yaxislabel");W.text(ai.max);W.css({position:"absolute",top:"22px",left:"10px"});W.prependTo(this.container_div);var Y=this.view.canvas_manager.new_canvas();Y.width=ao+aa;Y.height=ab+L;var ay=new G.SummaryTreePainter(ai.data,ai.delta,ai.max,ax,X,this.prefs.show_counts);var ap=Y.getContext("2d");ap.translate(aa,L);ay.draw(ap,ao,ab);return Y}var aj,ad=1;if(am==="no_detail"||am==="Squish"||am==="Pack"){ad=this.incremental_slots(ag,ai.data,am);aj=this.inc_slots[ag].slots}var af=[];if(ai.data){for(var ar=0,au=ai.data.length;ar<au;ar++){var ac=ai.data[ar];var at=false;var ah;for(var aw=0,az=this.filters.length;aw<az;aw++){ah=this.filters[aw];ah.update_attrs(ac);if(!ah.keep(ac)){at=true;break}}if(!at){af.push(ac)}}}var ay=new (this.painter)(af,ax,X,this.prefs,am,Z);var ab=ay.get_required_height(ad)+z;var Y=this.view.canvas_manager.new_canvas();Y.width=ao+aa;Y.height=ab;ae.parent().css("height",Math.max(this.height_px,ab)+"px");var ap=Y.getContext("2d");ap.fillStyle=this.prefs.block_color;ap.font=ap.canvas.manager.default_font;ap.textAlign="right";this.container_div.find(".yaxislabel").remove();if(ai.message){$(Y).css({"border-top":"1px solid red"});ap.fillStyle="red";ap.textAlign="left";var al=ap.textBaseline;ap.textBaseline="top";ap.fillText(ai.message,aa,0);ap.textBaseline=al;if(!ai.data){return Y}}this.example_feature=(ai.data.length?ai.data[0]:undefined);ap.translate(aa,z);ay.draw(ap,ao,ab,aj);return Y}});var M=function(Z,X,ab,W,Y,aa){e.call(this,Z,X,ab,W,Y,aa);this.track_type="VcfTrack";this.painter=G.VariantPainter};extend(M.prototype,H.prototype,e.prototype);var P=function(Z,X,ab,W,Y,aa){e.call(this,Z,X,ab,W,Y,aa);this.track_config=new S({track:this,params:[{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:Y,onchange:function(){this.track.tile_cache.clear();this.track.draw()}});this.prefs=this.track_config.values;this.track_type="ReadTrack";this.painter=G.ReadPainter;this.make_name_popup_menu()};extend(P.prototype,H.prototype,e.prototype);var N=function(aa,Y,ac,W,Z,ab,X){e.call(this,aa,Y,ac,W,Z,ab,{},X);this.track_type="ToolDataFeatureTrack";this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};extend(N.prototype,H.prototype,e.prototype,{predraw_init:function(){var X=this;var W=function(){if(X.data_cache.size()===0){setTimeout(W,300)}else{X.data_url=default_data_url;X.data_query_wait=F;X.dataset_state_url=converted_datasets_state_url;$.getJSON(X.dataset_state_url,{dataset_id:X.dataset_id,hda_ldda:X.hda_ldda},function(Y){})}};W()}});Q.View=U;Q.LineTrack=l;Q.FeatureTrack=e;Q.ReadTrack=P};var slotting_module=function(c,b){var d=2,a=5;b.FeatureSlotter=function(h,g,e,f){this.slots={};this.start_end_dct={};this.w_scale=h;this.include_label=g;this.max_rows=e;this.measureText=f};extend(b.FeatureSlotter.prototype,{slot_features:function(l){var o=this.w_scale,r=this.slots,g=this.start_end_dct,x=[],z=[],m=0,y=this.max_rows;for(var v=0,w=l.length;v<w;v++){var k=l[v],n=k[0];if(r[n]!==undefined){m=Math.max(m,r[n]);z.push(r[n])}else{x.push(v)}}var p=function(F,G){for(var E=0;E<=y;E++){var C=false,H=g[E];if(H!==undefined){for(var B=0,D=H.length;B<D;B++){var A=H[B];if(G>A[0]&&F<A[1]){C=true;break}}}if(!C){return E}}return -1};for(var v=0,w=x.length;v<w;v++){var k=l[x[v]],n=k[0],t=k[1],e=k[2],q=k[3],f=Math.floor(t*o),j=Math.ceil(e*o),u=this.measureText(q).width,h;if(q!==undefined&&this.include_label){u+=(d+a);if(f-u>=0){f-=u;h="left"}else{j+=u;h="right"}}var s=p(f,j);if(s>=0){if(g[s]===undefined){g[s]=[]}g[s].push([f,j]);r[n]=s;m=Math.max(m,s)}else{}}return m+1}})};var painters_module=function(k,A){var q=function(L,D,J,C,I,G){if(G===undefined){G=4}var F=C-D;var E=I-J;var H=Math.floor(Math.sqrt(F*F+E*E)/G);var M=F/H;var K=E/H;var B;for(B=0;B<H;B++,D+=M,J+=K){if(B%2!==0){continue}L.fillRect(D,J,G,1)}};var r=function(D,C,B,G){var F=C-G/2,E=C+G/2,H=B-Math.sqrt(G*3/2);D.beginPath();D.moveTo(F,H);D.lineTo(E,H);D.lineTo(C,B);D.lineTo(F,H);D.strokeStyle=this.fillStyle;D.fill();D.stroke();D.closePath()};var v=function(E,G,C,F,B,D){this.data=E;this.delta=G;this.max=C;this.view_start=F;this.view_end=B;this.show_counts=D};v.prototype.draw=function(O,B,N){var G=this.view_start,Q=this.view_end-this.view_start,P=B/Q;var L=this.data,K=this.delta,I=this.max,D=N;delta_x_px=Math.ceil(K*P);O.save();for(var E=0,F=L.length;E<F;E++){var J=Math.floor((L[E][0]-G)*P);var H=L[E][1];if(!H){continue}var M=H/I*N;O.fillStyle="black";O.fillRect(J,D-M,delta_x_px,M);var C=4;if(this.show_counts&&(O.measureText(H).width+C)<delta_x_px){O.fillStyle="#666";O.textAlign="center";O.fillText(H,J+(delta_x_px/2),10)}}O.restore()};var c=function(E,H,B,C,G,D,F){this.data=E;this.view_start=H;this.view_end=B;this.min_value=C;this.max_value=G;this.color=D;this.mode=F;this.overflow_color="#F66"};c.prototype.draw=function(Q,P,N){var I=false,J=this.min_value,G=this.max_value,M=G-J,C=N,D=this.view_start,O=this.view_end-this.view_start,E=P/O,K=this.mode,U=this.data;Q.save();var V=Math.round(N+J/M*N);if(K!=="Intensity"){Q.fillStyle="#aaa";Q.fillRect(0,V,P,1)}Q.beginPath();Q.fillStyle=this.color;var T,H,F;if(U.length>1){F=Math.ceil((U[1][0]-U[0][0])*E)}else{F=10}for(var R=0,S=U.length;R<S;R++){T=Math.round((U[R][0]-D)*E);H=U[R][1];if(H===null){if(I&&K==="Filled"){Q.lineTo(T,C)}I=false;continue}if(H<J){H=J}else{if(H>G){H=G}}if(K==="Histogram"){H=Math.round(H/M*C);Q.fillRect(T,V,F,-H)}else{if(K==="Intensity"){H=255-Math.floor((H-J)/M*255);Q.fillStyle="rgb("+H+","+H+","+H+")";Q.fillRect(T,0,F,C)}else{H=Math.round(C-(H-J)/M*C);if(I){Q.lineTo(T,H)}else{I=true;if(K==="Filled"){Q.moveTo(T,C);Q.lineTo(T,H)}else{Q.moveTo(T,H)}}}}}if(K==="Filled"){if(I){Q.lineTo(T,V);Q.lineTo(0,V)}Q.fill()}else{Q.stroke()}var B=-1,L=-1;Q.fillStyle=this.overflow_color;for(var R=0,S=U.length;R<S;R++){H=U[R][1];T=Math.round((U[R][0]-D)*E);x_minus_scaled=Math.round((U[R][0]-1-D)*E);if(L>=0&&(H===null||H<G)){Q.fillRect(L,0,x_minus_scaled-L+1,2);L=-1}else{if(B>=0&&(H===null||H>J)){Q.fillRect(B,N-2,x_minus_scaled-B+1,2);B=-1}}if(H!==null&&H>G&&L<0){L=T}else{if(H!==null&&H<J&&B<0){B=T}}}Q.restore()};var p=function(D,F,B,C,E){this.data=D;this.view_start=F;this.view_end=B;this.prefs=C;this.mode=E};extend(p.prototype,{get_required_height:function(C){var B=y_scale=this.get_row_height(),D=this.mode;if(D==="no_detail"||D==="Squish"||D==="Pack"){B=C*y_scale}return B+Math.max(Math.round(y_scale/2),5)},draw:function(N,E,M,J){var H=this.data,K=this.view_start,O=this.view_end;N.save();N.fillStyle=this.prefs.block_color;N.textAlign="right";var R=this.view_end-this.view_start,Q=E/R,D=this.get_row_height();for(var G=0,I=H.length;G<I;G++){var P=H[G],F=P[0],B=P[1],C=P[2],L=(J&&J[F]!==undefined?J[F]:null);if((B<O&&C>K)&&(this.mode=="Dense"||L!==null)){this.draw_element(N,this.mode,P,L,K,O,Q,D,E)}}N.restore()}});var d=10,j=3,n=5,z=10,g=1,t=3,f=3,a=9,o=2,h="#ccc";var s=function(D,F,B,C,E){p.call(this,D,F,B,C,E)};extend(s.prototype,p.prototype,{get_row_height:function(){var C=this.mode,B;if(C==="Dense"){B=d}else{if(C==="no_detail"){B=j}else{if(C==="Squish"){B=n}else{B=z}}}return B},draw_element:function(N,G,V,I,P,af,aj,ak,B){var S=V[0],ah=V[1],Z=V[2]-1,Q=V[3],aa=Math.floor(Math.max(0,(ah-P)*aj)),O=Math.ceil(Math.min(B,Math.max(0,(Z-P)*aj))),Y=(G==="Dense"?0:(0+I))*ak,M,ad,R=null,al=null,E=this.prefs.block_color,ac=this.prefs.label_color;if(G=="Dense"){I=1}if(G==="no_detail"){N.fillStyle=E;N.fillRect(aa,Y+5,O-aa,g)}else{var L=V[4],X=V[5],ab=V[6],F=V[7];if(X&&ab){R=Math.floor(Math.max(0,(X-P)*aj));al=Math.ceil(Math.min(B,Math.max(0,(ab-P)*aj)))}var ai,T;if(G==="Squish"||G==="Dense"){ai=1;T=f}else{ai=5;T=a}if(!F){if(V.strand){if(V.strand==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand_inv")}else{if(V.strand==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand_inv")}}}else{N.fillStyle=E}N.fillRect(aa,Y,O-aa,T)}else{var K,U;if(G==="Squish"||G==="Dense"){N.fillStyle=h;K=Y+Math.floor(f/2)+1;U=1}else{if(L){var K=Y;var U=T;if(L==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand")}else{if(L==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand")}}}else{N.fillStyle=h;K+=(f/2)+1;U=1}}N.fillRect(aa,K,O-aa,U);for(var ag=0,D=F.length;ag<D;ag++){var H=F[ag],C=Math.floor(Math.max(0,(H[0]-P)*aj)),W=Math.ceil(Math.min(B,Math.max((H[1]-1-P)*aj)));if(C>W){continue}N.fillStyle=E;N.fillRect(C,Y+(T-ai)/2+1,W-C,ai);if(R!==undefined&&ab>X&&!(C>al||W<R)){var ae=Math.max(C,R),J=Math.min(W,al);N.fillRect(ae,Y+1,J-ae,T);if(F.length==1&&G=="Pack"){if(L==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand_inv")}else{if(L==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand_inv")}}if(ae+14<J){ae+=2;J-=2}N.fillRect(ae,Y+1,J-ae,T)}}}}if(G==="Pack"&&ah>P){N.fillStyle=ac;if(P===0&&aa-N.measureText(Q).width<0){N.textAlign="left";N.fillText(Q,O+o,Y+8)}else{N.textAlign="right";N.fillText(Q,aa-o,Y+8)}N.fillStyle=E}}}});var b=function(D,F,B,C,E){p.call(this,D,F,B,C,E)};extend(b.prototype,p.prototype,{draw_element:function(U,P,J,F,X,D,M,V,S){var J=data[i],L=J[0],T=J[1],E=J[2]-1,O=J[3],H=Math.floor(Math.max(0,(T-X)*M)),K=Math.ceil(Math.min(S,Math.max(0,(E-X)*M))),G=(P==="Dense"?0:(0+F))*V,B,Y,C=null,N=null;if(no_label){U.fillStyle=block_color;U.fillRect(H+left_offset,G+5,K-H,1)}else{var W=J[4],R=J[5],I=J[6];B=9;Y=1;U.fillRect(H+left_offset,G,K-H,B);if(P!=="Dense"&&O!==undefined&&T>X){U.fillStyle=label_color;if(X===0&&H-U.measureText(O).width<0){U.textAlign="left";U.fillText(O,K+2+left_offset,G+8)}else{U.textAlign="right";U.fillText(O,H-2+left_offset,G+8)}U.fillStyle=block_color}var Q=W+" / "+R;if(T>X&&U.measureText(Q).width<(K-H)){U.fillStyle="white";U.textAlign="center";U.fillText(Q,left_offset+H+(K-H)/2,G+8);U.fillStyle=block_color}}}});var y=1001,m=1002,e=1003,x=1004,l=1005;var w=function(F,C){var H=F[0],G=F[1],E=C[0],D=C[1],B;if(H<E){if(G<E){B=y}else{if(G<=D){B=e}else{B=m}}}else{if(H>D){B=y}else{if(G<=D){B=l}else{B=x}}}return B};var u=function(E,G,B,D,F,C){p.call(this,E,G,B,D,F);this.ref_seq=C};extend(u.prototype,p.prototype,{get_row_height:function(){var B,C=this.mode;if(C==="Dense"){B=d}else{if(C==="Squish"){B=n}else{B=z;if(this.prefs.show_insertions){B*=2}}}return B},draw_read:function(Y,T,O,ad,D,X,L,I,H){Y.textAlign="center";var W=this,C=[ad,D],R=0,Z=0,V=0;ref_seq=this.ref_seq,char_width_px=Y.canvas.manager.char_width_px;var ai=[];if((T==="Pack"||this.mode==="Auto")&&I!==undefined&&O>char_width_px){V=Math.round(O/2)}if(!L){L=[[0,I.length]]}for(var P=0,ab=L.length;P<ab;P++){var M=L[P],E="MIDNSHP=X"[M[0]],Q=M[1];if(E==="H"||E==="S"){R-=Q}var J=X+R,ah=Math.floor(Math.max(0,(J-ad)*O)),K=Math.floor(Math.max(0,(J+Q-ad)*O));switch(E){case"H":break;case"S":case"M":case"=":var S=w([J,J+Q],C);if(S!==y){var U=I.slice(Z,Z+Q);if(V>0){Y.fillStyle=this.prefs.block_color;Y.fillRect(ah-V,H+1,K-ah,9);Y.fillStyle=h;for(var af=0,B=U.length;af<B;af++){if(this.prefs.show_differences&&ref_seq){var N=ref_seq[J-ad+af];if(!N||N.toLowerCase()===U[af].toLowerCase()){continue}}if(J+af>=ad&&J+af<=D){var ag=Math.floor(Math.max(0,(J+af-ad)*O));Y.fillText(U[af],ag,H+9)}}}else{Y.fillStyle=this.prefs.block_color;Y.fillRect(ah,H+4,K-ah,f)}}Z+=Q;R+=Q;break;case"N":Y.fillStyle=h;Y.fillRect(ah-V,H+5,K-ah,1);R+=Q;break;case"D":Y.fillStyle="red";Y.fillRect(ah-V,H+4,K-ah,3);R+=Q;break;case"P":break;case"I":var S=w([J,J+Q],C),ac=ah-V;if(S!==y){var U=I.slice(Z,Z+Q);if(this.prefs.show_insertions){var G=ah-(K-ah)/2;if((T==="Pack"||this.mode==="Auto")&&I!==undefined&&O>char_width_px){Y.fillStyle="yellow";Y.fillRect(G-V,H-9,K-ah,9);ai[ai.length]={type:"triangle",data:[ac,H+4,5]};Y.fillStyle=h;switch(S){case (e):U=U.slice(ad-J);break;case (x):U=U.slice(0,J-D);break;case (l):break;case (m):U=U.slice(ad-J,J-D);break}for(var af=0,B=U.length;af<B;af++){var ag=Math.floor(Math.max(0,(J+af-ad)*O));Y.fillText(U[af],ag-(K-ah)/2,H)}}else{Y.fillStyle="yellow";Y.fillRect(G,H+(this.mode!=="Dense"?2:5),K-ah,(T!=="Dense"?f:t))}}else{if((T==="Pack"||this.mode==="Auto")&&I!==undefined&&O>char_width_px){ai[ai.length]={type:"text",data:[U.length,ac,H+9]}}else{}}}Z+=Q;break;case"X":Z+=Q;break}}Y.fillStyle="yellow";var ae,F,aj;for(var aa=0;aa<ai.length;aa++){ae=ai[aa];F=ae.type;aj=ae.data;if(F==="text"){Y.save();Y.font="bold "+Y.font;Y.fillText(aj[0],aj[1],aj[2]);Y.restore()}else{if(F=="triangle"){r(Y,aj[0],aj[1],aj[2])}}}},draw_element:function(U,P,H,E,X,C,L,V,S){var K=H[0],T=H[1],D=H[2],M=H[3],G=Math.floor(Math.max(0,(T-X)*L)),I=Math.ceil(Math.min(S,Math.max(0,(D-X)*L))),F=(P==="Dense"?0:(0+E))*V,Y=this.prefs.block_color,J=this.prefs.label_color,R=0;if((P==="Pack"||this.mode==="Auto")&&L>U.canvas.manager.char_width_px){var R=Math.round(L/2)}U.fillStyle=Y;if(H[5] instanceof Array){var Q=Math.floor(Math.max(0,(H[4][0]-X)*L)),O=Math.ceil(Math.min(S,Math.max(0,(H[4][1]-X)*L))),N=Math.floor(Math.max(0,(H[5][0]-X)*L)),B=Math.ceil(Math.min(S,Math.max(0,(H[5][1]-X)*L)));if(H[4][1]>=X&&H[4][0]<=C&&H[4][2]){this.draw_read(U,P,L,X,C,H[4][0],H[4][2],H[4][3],F)}if(H[5][1]>=X&&H[5][0]<=C&&H[5][2]){this.draw_read(U,P,L,X,C,H[5][0],H[5][2],H[5][3],F)}if(N>O){U.fillStyle=h;q(U,O-R,F+5,N-R,F+5)}}else{U.fillStyle=Y;this.draw_read(U,P,L,X,C,T,H[4],H[5],F)}if(P==="Pack"&&T>X){U.fillStyle=this.prefs.label_color;var W=1;if(W===0&&G-U.measureText(M).width<0){U.textAlign="left";U.fillText(M,I+o-R,F+8)}else{U.textAlign="right";U.fillText(M,G-o-R,F+8)}U.fillStyle=Y}}});A.SummaryTreePainter=v;A.LinePainter=c;A.LinkedFeaturePainter=s;A.ReadPainter=u;A.VariantPainter=b};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("slotting",slotting_module);a("painters",painters_module);a("trackster",trackster_module);for(key in c.trackster){d[key]=c.trackster[key]}})(window);
\ No newline at end of file
--- a/static/scripts/trackster.js Mon Apr 04 23:27:25 2011 -0400
+++ b/static/scripts/trackster.js Tue Apr 05 11:51:48 2011 -0400
@@ -104,7 +104,7 @@
*/
var get_slider_step = function(min, max) {
var range = max - min;
- return (range <= 1 ? 0.01 : (range <= 1000 ? 1 : 5));
+ return (range <= 2 ? 0.01 : (range <= 100 ? 1 : (range <= 1000 ? 5 : 10)));
}
/**
@@ -756,10 +756,13 @@
});
/**
- * Encapsulation of tools that users can apply to tracks/datasets.
+ * Encapsulation of a tool that users can apply to tracks/datasets.
*/
-var Tool = function(tool_dict) {
- // Unpack tool from dictionary.
+var Tool = function(track, tool_dict) {
+ //
+ // Unpack tool information from dictionary.
+ //
+ this.track = track;
this.name = tool_dict.name;
this.params = [];
var params_dict = tool_dict.params;
@@ -767,56 +770,161 @@
var param_dict = params_dict[i],
name = param_dict.name,
label = param_dict.label,
+ html = unescape(param_dict.html),
type = param_dict.type;
- if (type === "int" || type === "float") {
+ if (type === "number") {
this.params[this.params.length] =
- new NumberParameter(name, label, param_dict.min, param_dict.max, param_dict.value);
+ new NumberParameter(name, label, html, param_dict.min, param_dict.max);
}
else if (type == "select") {
- this.params[this.params.length] = new SelectParameter(name, label, param_dict.options);
+ this.params[this.params.length] = new ToolParameter(name, label, html);
}
else {
console.log("WARNING: unrecognized tool parameter type:", name, type);
}
}
+
+ //
+ // Create div elt for tool UI.
+ //
+ this.parent_div = $("<div/>").addClass("dynamic-tool").hide();
+ // Disable dragging, clicking, double clicking on div so that actions on slider do not impact viz.
+ this.parent_div.bind("drag", function(e) {
+ e.stopPropagation();
+ }).bind("click", function(e) {
+ e.stopPropagation();
+ }).bind("dblclick", function(e) {
+ e.stopPropagation();
+ });
+ var name_div = $("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);
+ var tool_params = this.params;
+ var tool = this;
+ $.each(this.params, function(index, param) {
+ var param_div = $("<div>").addClass("param-row").appendTo(tool.parent_div);
+ // Param label.
+ var label_div = $("<div>").addClass("param-label").text(param.label).appendTo(param_div);
+ // Param HTML.
+ // TODO: either generalize .slider CSS attributes or create new rule for tool input div.
+ var html_div = $("<div/>").addClass("slider").html(param.html).appendTo(param_div);
+
+ // Add to clear floating layout.
+ $("<div style='clear: both;'/>").appendTo(param_div);
+ });
+
+ // Highlight value for inputs for easy replacement.
+ this.parent_div.find("input").click(function() { $(this).select() });
+
+ // Add 'Go' button.
+ var run_tool_row = $("<div>").addClass("slider-row").appendTo(this.parent_div);
+ var run_tool_button = $("<input type='submit'>").attr("value", "Run").appendTo(run_tool_row);
+ var tool = this;
+ run_tool_button.click( function() {
+ tool.run();
+ });
};
extend(Tool.prototype, {
- // Returns a dictionary of parameter values; key is parameter name, value
- // is parameter value.
+ /**
+ * Returns dictionary of parameter name-values.
+ */
get_param_values_dict: function() {
var param_dict = {};
- for (var i = 0; i < this.params.length; i++) {
- var param = this.params[i];
- param_dict[param.name] = JSON.stringify(param.value);
- }
+ this.parent_div.find(":input").each(function() {
+ var name = $(this).attr("name"), value = $(this).val();
+ param_dict[name] = JSON.stringify(value);
+ });
return param_dict;
},
- // Returns an array of parameter values.
+ /**
+ * Returns array of parameter values.
+ */
get_param_values: function() {
var param_values = [];
- for (var i = 0; i < this.params.length; i++) {
- param_values[i] = this.params[i].value;
+ var param_dict = {};
+ this.parent_div.find(":input").each(function() {
+ // Only include inputs with names; this excludes Run button.
+ var name = $(this).attr("name"), value = $(this).val();
+ if (name) {
+ param_values[param_values.length] = value;
+ }
+ });
+ return param_values;
+ },
+ /**
+ * Run tool. This creates a new child track, runs tool, and places tool's output in the new track.
+ */
+ run: function() {
+ // Put together params for running tool.
+ var url_params = {
+ dataset_id: this.track.original_dataset_id,
+ chrom: this.track.view.chrom,
+ low: this.track.view.low,
+ high: this.track.view.high,
+ tool_id: this.name
+ };
+ $.extend(url_params, this.get_param_values_dict());
+
+ //
+ // Create track for tool's output immediately to provide user feedback.
+ //
+ var
+ current_track = this.track,
+ // Set name of track to include tool name, parameters, and region used.
+ track_name = url_params.tool_id +
+ current_track.tool_region_and_parameters_str(url_params.chrom, url_params.low, url_params.high),
+ new_track;
+
+ // TODO: add support for other kinds of tool data tracks.
+ if (current_track.track_type === 'FeatureTrack') {
+ new_track = new ToolDataFeatureTrack(track_name, view, current_track.hda_ldda, undefined, {}, {}, current_track);
}
- return param_values;
+
+ this.track.add_track(new_track);
+ new_track.content_div.text("Starting job.");
+
+ // Run tool.
+ var json_run_tool = function() {
+ $.getJSON(run_tool_url, url_params, function(track_data) {
+ if (track_data === "no converter") {
+ // No converter available for input datasets, so cannot run tool.
+ new_track.container_div.addClass("error");
+ new_track.content_div.text(DATA_NOCONVERTER);
+ }
+ else if (track_data.error) {
+ // General error.
+ new_track.container_div.addClass("error");
+ new_track.content_div.text(DATA_CANNOT_RUN_TOOL + track_data.message);
+ }
+ else if (track_data === "pending") {
+ // Converting/indexing input datasets; show message and try again.
+ new_track.container_div.addClass("pending");
+ new_track.content_div.text("Converting input data so that it can be easily reused.");
+ setTimeout(json_run_tool, 2000);
+ }
+ else {
+ // Job submitted and running.
+ new_track.dataset_id = track_data.dataset_id;
+ new_track.content_div.text("Running job.");
+ new_track.init();
+ }
+ });
+ };
+ json_run_tool();
}
});
/**
* Tool parameters.
*/
-var NumberParameter = function(name, label, min, max, init_value) {
+var ToolParameter = function(name, label, html) {
this.name = name;
this.label = label;
+ this.html = html;
+};
+
+var NumberParameter = function(name, label, html, min, max) {
+ ToolParameter.call(this, name, label, html)
this.min = min;
this.max = max;
- this.value = init_value;
-};
-
-var SelectParameter = function(name, label, options) {
- this.name = name;
- this.label = label;
- this.options = options;
- this.value = (options.length !== 0 ? options[0][1] : null);
};
/**
@@ -1157,7 +1265,7 @@
// filters_available is determined by data, filters_visible is set by user.
this.filters_available = false;
this.filters_visible = false;
- this.tool = (tool_dict !== undefined && obj_length(tool_dict) > 0 ? new Tool(tool_dict) : undefined);
+ this.tool = (tool_dict !== undefined && obj_length(tool_dict) > 0 ? new Tool(this, tool_dict) : undefined);
//
// TODO: Right now there is only the notion of a parent track and multiple child tracks. However,
@@ -1250,7 +1358,7 @@
// Disable dragging, double clicking on div so that actions on slider do not impact viz.
this.filters_div.bind("drag", function(e) {
e.stopPropagation();
- }).bind("click", function( e ) {
+ }).bind("click", function(e) {
e.stopPropagation();
}).bind("dblclick", function(e) {
e.stopPropagation();
@@ -1311,89 +1419,8 @@
// Create dynamic tool div.
//
if (this.tool) {
- // Create div elt for tool UI.
- this.dynamic_tool_div = $("<div/>").addClass("dynamic-tool").hide();
+ this.dynamic_tool_div = this.tool.parent_div;
this.header_div.after(this.dynamic_tool_div);
- // Disable dragging, clicking, double clicking on div so that actions on slider do not impact viz.
- this.dynamic_tool_div.bind( "drag", function(e) {
- e.stopPropagation();
- }).bind("click", function( e ) {
- e.stopPropagation();
- }).bind("dblclick", function( e ) {
- e.stopPropagation();
- });
- var name_div = $("<div class='tool-name'>").appendTo(this.dynamic_tool_div).text(this.tool.name);
- var tool_params = this.tool.params;
- var track = this;
- $.each(this.tool.params, function(index, param) {
-
- if (param instanceof NumberParameter) {
- var param_div = $("<div>").addClass("slider-row").appendTo(track.dynamic_tool_div);
-
- // Slider label.
- var label_div = $("<div>").addClass("slider-label").appendTo(param_div);
- var name_span = $("<span/>").addClass("slider-name").text(param.label + " ").appendTo(label_div);
- var values_span = $("<span/>").text(param.value);
- var values_span_container = $("<span/>").addClass("slider-value").appendTo(label_div).append("[").append(values_span).append("]");
-
- // Slider.
- var slider_div = $("<div/>").addClass("slider").appendTo(param_div);
- var slider = $("<div id='" + param.name + "-param-control'>").appendTo(slider_div);
- // Step must have a value so that (max-min)%step == 0.
- slider.slider({
- min: param.min,
- max: param.max,
- step: get_slider_step(param.min, param.max),
- value: param.value,
- slide: function(event, ui) {
- var value = ui.value;
- param.value = value;
- // Set new value in UI.
- if (0 < value && value < 1) {
- value = parseFloat(value).toFixed(2);
- }
- values_span.text(value);
- },
- change: function(event, ui) {
- slider.slider("option", "slide").call(slider, event, ui);
- }
- });
-
- // Enable users to edit parameter's value via text box.
- edit_slider_values(values_span_container, values_span, slider);
-
- // Add to clear floating layout.
- $("<div style='clear: both;'/>").appendTo(param_div);
- }
- else if (param instanceof SelectParameter) {
- var param_div = $("<div>").addClass("slider-row").appendTo(track.dynamic_tool_div);
-
- // Param label.
- var label_div = $("<div>").addClass("slider-label").appendTo(param_div);
- var name_span = $("<span/>").addClass("slider-name").text(param.label + " ").appendTo(label_div);
-
- // Param selector.
- var select_div = $("<div/>").addClass("slider").appendTo(param_div);
- var select_obj = $("<select/>").appendTo(select_div);
- select_obj.change(function() {param.value = $(this).val();} );
- var options = select_obj.attr("options");
- for (var i = 0; i < param.options.length; i++) {
- var option_data = param.options[i]
- options[options.length] = new Option(option_data[0], option_data[1]);
- }
-
- // Add to clear floating layout.
- $("<div style='clear: both;'/>").appendTo(param_div);
- }
- });
-
- // Add 'Go' button.
- var run_tool_row = $("<div>").addClass("slider-row").appendTo(this.dynamic_tool_div);
- var run_tool_button = $("<input type='submit'>").attr("value", "Run").appendTo(run_tool_row);
- var track = this;
- run_tool_button.click( function() {
- track.run_tool();
- });
}
//
@@ -1767,66 +1794,6 @@
}
$(window).trigger("resize");
},
- // Run track's tool.
- run_tool: function() {
- // Put together params for running tool.
- var url_params = {
- dataset_id: this.original_dataset_id,
- chrom: this.view.chrom,
- low: this.view.low,
- high: this.view.high,
- tool_id: this.tool.name
- };
- $.extend(url_params, this.tool.get_param_values_dict());
-
- //
- // Create track for tool's output immediately to provide user feedback.
- //
- var
- current_track = this,
- // Set name of track to include tool name, parameters, and region used.
- track_name = url_params.tool_id +
- current_track.tool_region_and_parameters_str(url_params.chrom, url_params.low, url_params.high),
- new_track;
-
- // TODO: add support for other kinds of tool data tracks.
- if (current_track.track_type === 'FeatureTrack') {
- new_track = new ToolDataFeatureTrack(track_name, view, current_track.hda_ldda, undefined, {}, {}, current_track);
- }
-
- this.add_track(new_track);
- new_track.content_div.text("Starting job.");
- view.has_changes = true;
-
- // Run tool.
- var json_run_tool = function() {
- $.getJSON(run_tool_url, url_params, function(track_data) {
- if (track_data === "no converter") {
- // No converter available for input datasets, so cannot run tool.
- new_track.container_div.addClass("error");
- new_track.content_div.text(DATA_NOCONVERTER);
- }
- else if (track_data.error) {
- // General error.
- new_track.container_div.addClass("error");
- new_track.content_div.text(DATA_CANNOT_RUN_TOOL + track_data.message);
- }
- else if (track_data === "pending") {
- // Converting/indexing input datasets; show message and try again.
- new_track.container_div.addClass("pending");
- new_track.content_div.text("Converting input data so that it can be easily reused.");
- setTimeout(json_run_tool, 2000);
- }
- else {
- // Job submitted and running.
- new_track.dataset_id = track_data.dataset_id;
- new_track.content_div.text("Running job.");
- new_track.init();
- }
- });
- };
- json_run_tool();
- },
/**
* Utility function that creates a label string describing the region and parameters of a track's tool.
*/
@@ -1850,6 +1817,7 @@
this.child_tracks_container.show();
}
this.child_tracks.push(child_track);
+ this.view.has_changes = true;
},
/**
* Remove a child track from this track.
--- a/tools/new_operations/intersect.xml Mon Apr 04 23:27:25 2011 -0400
+++ b/tools/new_operations/intersect.xml Tue Apr 05 11:51:48 2011 -0400
@@ -28,7 +28,7 @@
<param format="interval,gff" name="input2" type="data" help="Second dataset"><label>that intersect</label></param>
- <param name="min" size="4" type="integer" value="1" min="0" max="600000" help="(bp)">
+ <param name="min" size="4" type="integer" value="1" min="1" help="(bp)"><label>for at least</label></param></inputs>
--- a/tools/new_operations/subtract.xml Mon Apr 04 23:27:25 2011 -0400
+++ b/tools/new_operations/subtract.xml Tue Apr 05 11:51:48 2011 -0400
@@ -31,7 +31,7 @@
<option value="-p">Non-overlapping pieces of intervals</option></param>
- <param name="min" size="4" type="integer" value="1" min="0" max="600000" help="(bp)">
+ <param name="min" size="4" type="integer" value="1" min="1" help="(bp)"><label>where minimal overlap is</label></param></inputs>
--- a/tools/ngs_rna/cufflinks_wrapper.xml Mon Apr 04 23:27:25 2011 -0400
+++ b/tools/ngs_rna/cufflinks_wrapper.xml Tue Apr 05 11:51:48 2011 -0400
@@ -42,7 +42,7 @@
</command><inputs><param format="sam,bam" name="input" type="data" label="SAM or BAM file of aligned RNA-Seq reads" help=""/>
- <param name="max_intron_len" type="integer" value="300000" min="0" max="600000" label="Max Intron Length" help=""/>
+ <param name="max_intron_len" type="integer" value="300000" min="1" max="600000" label="Max Intron Length" help=""/><param name="min_isoform_fraction" type="float" value="0.05" min="0" max="1" label="Min Isoform Fraction" help=""/><param name="pre_mrna_fraction" type="float" value="0.05" min="0" max="1" label="Pre MRNA Fraction" help=""/><param name="min_map_quality" type="integer" value="0" min="0" max="255" label="Min SAM Map Quality" help=""/>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: james_taylor: trackster: draw lines to indicate when line tracks overflow the visible region
by Bitbucket 04 Apr '11
by Bitbucket 04 Apr '11
04 Apr '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/b53f0963bffc/
changeset: r5339:b53f0963bffc
user: james_taylor
date: 2011-04-05 05:27:25
summary: trackster: draw lines to indicate when line tracks overflow the visible region
affected #: 1 file (1.4 KB)
--- a/static/scripts/trackster.js Mon Apr 04 13:40:09 2011 -0400
+++ b/static/scripts/trackster.js Mon Apr 04 23:27:25 2011 -0400
@@ -2668,6 +2668,7 @@
this.max_value = max_value;
this.color = color;
this.mode = mode;
+ this.overflow_color = "#F66";
}
LinePainter.prototype.draw = function( ctx, width, height ) {
@@ -2690,14 +2691,6 @@
// Line at 0.0
if ( mode !== "Intensity" ) {
- /*
- ctx.beginPath();
- ctx.moveTo( 0, y_zero );
- ctx.lineTo( width, y_zero );
- // ctx.lineWidth = 0.5;
- ctx.fillStyle = "#aaa";
- ctx.stroke();
- */
ctx.fillStyle = "#aaa";
ctx.fillRect( 0, y_zero, width, 1 );
}
@@ -2761,6 +2754,37 @@
ctx.stroke();
}
+ // Draw lines at bounderies if overflowing min or max
+ var overflow_min_start = -1,
+ overflow_max_start = -1;
+ ctx.fillStyle = this.overflow_color;
+ for (var i = 0, len = data.length; i < len; i++) {
+ y = data[i][1];
+ x_scaled = Math.round((data[i][0] - view_start) * w_scale);
+ x_minus_scaled = Math.round((data[i][0] - 1 - view_start) * w_scale);
+
+ // If we are in a min/max run, check if it should be ended
+ if ( overflow_max_start >= 0 && ( y === null || y < max_value ) ) {
+ // Value does not exist or is in valid range, any overflow ends
+ ctx.fillRect( overflow_max_start, 0, x_minus_scaled - overflow_max_start + 1, 2 );
+ overflow_max_start = -1;
+ } else if ( overflow_min_start >= 0 && ( y === null || y > min_value ) ) {
+ // Draw bottom overflow bar
+ ctx.fillRect( overflow_min_start, height - 2, x_minus_scaled - overflow_min_start + 1, 2 );
+ overflow_min_start = -1;
+ }
+
+ // Now check if we should start a new one (this may happen on the same
+ // base as above if switching between min/max)
+ if ( y !== null && y > max_value && overflow_max_start < 0 ) {
+ // Top overflows and we are not already in a run of overflow
+ overflow_max_start = x_scaled;
+ } else if ( y !== null && y < min_value && overflow_min_start < 0 ) {
+ // Bottom overflows and we are not already in a run
+ overflow_min_start = x_scaled;
+ }
+ }
+
ctx.restore();
}
@@ -2806,7 +2830,7 @@
// Slot valid only if features are slotted and this feature is slotted;
// feature may not be due to lack of space.
slot = (slots && slots[feature_uid] !== undefined ? slots[feature_uid] : null);
-
+
// Draw feature if there's overlap and mode is dense or feature is slotted (as it must be for all non-dense modes).
if ( ( feature_start < view_end && feature_end > view_start ) && (this.mode == "Dense" || slot !== null)) {
this.draw_element(ctx, this.mode, feature, slot, view_start, view_end, w_scale, y_scale,
@@ -3146,7 +3170,7 @@
seq_offset = 0,
gap = 0
ref_seq = this.ref_seq,
- char_width_px = ctx.canvas.manager.char_width_px;
+ char_width_px = ctx.canvas.manager.char_width_px;
// Keep list of items that need to be drawn on top of initial drawing layer.
var draw_last = [];
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: james_taylor: trackster: fix read track drawing offsets for all modes
by Bitbucket 04 Apr '11
by Bitbucket 04 Apr '11
04 Apr '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/6d80641672e5/
changeset: r5338:6d80641672e5
user: james_taylor
date: 2011-04-04 19:40:09
summary: trackster: fix read track drawing offsets for all modes
affected #: 1 file (484 bytes)
--- a/static/scripts/trackster.js Mon Apr 04 12:55:33 2011 -0400
+++ b/static/scripts/trackster.js Mon Apr 04 13:40:09 2011 -0400
@@ -2779,7 +2779,6 @@
var required_height = y_scale = this.get_row_height(), mode = this.mode;
// If using a packing mode, need to multiply by the number of slots used
if (mode === "no_detail" || mode === "Squish" || mode === "Pack") {
- // Calculate new slots incrementally for this new chunk of data and update height if necessary.
required_height = rows_required * y_scale;
}
// Pad bottom by half a row, at least 5 px
@@ -2807,7 +2806,7 @@
// Slot valid only if features are slotted and this feature is slotted;
// feature may not be due to lack of space.
slot = (slots && slots[feature_uid] !== undefined ? slots[feature_uid] : null);
-
+
// Draw feature if there's overlap and mode is dense or feature is slotted (as it must be for all non-dense modes).
if ( ( feature_start < view_end && feature_end > view_start ) && (this.mode == "Dense" || slot !== null)) {
this.draw_element(ctx, this.mode, feature, slot, view_start, view_end, w_scale, y_scale,
@@ -2843,10 +2842,7 @@
*/
get_row_height: function() {
var mode = this.mode, y_scale;
- if (mode === "summary_tree") {
- // No scale needed.
- }
- if (mode === "Dense") {
+ if (mode === "Dense") {
y_scale = DENSE_TRACK_HEIGHT;
}
else if (mode === "no_detail") {
@@ -3055,7 +3051,7 @@
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) {
+ if (tile_low === 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 {
@@ -3125,9 +3121,6 @@
*/
get_row_height: function() {
var y_scale, mode = this.mode;
- if (mode === "summary_tree") {
- // No scale needed.
- }
if (mode === "Dense") {
y_scale = DENSE_TRACK_HEIGHT;
}
@@ -3213,10 +3206,7 @@
} else {
ctx.fillStyle = this.prefs.block_color;
// TODO: This is a pretty hack-ish way to fill rectangle based on mode.
- ctx.fillRect(s_start,
- y_center + (this.mode !== "Dense" ? 4 : 5),
- s_end - s_start,
- (mode !== "Dense" ? SQUISH_FEATURE_HEIGHT : DENSE_FEATURE_HEIGHT) );
+ ctx.fillRect(s_start, y_center + 4, s_end - s_start, SQUISH_FEATURE_HEIGHT);
}
}
seq_offset += cig_len;
@@ -3343,7 +3333,7 @@
feature_name = feature[3],
f_start = Math.floor( Math.max(0, (feature_start - tile_low) * w_scale) ),
f_end = Math.ceil( Math.min(width, Math.max(0, (feature_end - tile_low) * w_scale)) ),
- y_center = (mode === "Dense" ? 1 : (1 + slot)) * y_scale,
+ y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale,
block_color = this.prefs.block_color,
label_color = this.prefs.label_color,
// Left-gap for label text since we align chrom text to the position tick.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/e12237461b3e/
changeset: r5337:e12237461b3e
user: kanwei
date: 2011-04-04 18:55:33
summary: BLAST test changes
affected #: 4 files (383 bytes)
--- a/test-data/blastp_rhodopsin_vs_four_human.tabular Sun Apr 03 12:47:39 2011 -0400
+++ b/test-data/blastp_rhodopsin_vs_four_human.tabular Mon Apr 04 12:55:33 2011 -0400
@@ -1,6 +1,6 @@
-gi|57163783|ref|NP_001009242.1| Subject_4 96.55 348 12 0 1 348 1 348 0.0 679
-gi|3024260|sp|P56514.1|OPSD_BUFBU Subject_4 83.33 354 53 2 1 354 1 348 6e-178 605
-gi|283855846|gb|ADB45242.1| Subject_4 94.82 328 17 0 1 328 11 338 0.0 630
-gi|283855823|gb|ADB45229.1| Subject_4 94.82 328 17 0 1 328 11 338 0.0 630
-gi|223523|prf||0811197A Subject_4 93.10 348 23 1 1 347 1 348 0.0 651
-gi|12583665|dbj|BAB21486.1| Subject_4 81.09 349 65 1 1 349 1 348 2e-172 587
+gi|57163783|ref|NP_001009242.1| sp|P08100|OPSD_HUMAN 96.55 348 12 0 1 348 1 348 0.0 679
+gi|3024260|sp|P56514.1|OPSD_BUFBU sp|P08100|OPSD_HUMAN 83.33 354 53 2 1 354 1 348 6e-178 605
+gi|283855846|gb|ADB45242.1| sp|P08100|OPSD_HUMAN 94.82 328 17 0 1 328 11 338 0.0 630
+gi|283855823|gb|ADB45229.1| sp|P08100|OPSD_HUMAN 94.82 328 17 0 1 328 11 338 0.0 630
+gi|223523|prf||0811197A sp|P08100|OPSD_HUMAN 93.10 348 23 1 1 347 1 348 0.0 651
+gi|12583665|dbj|BAB21486.1| sp|P08100|OPSD_HUMAN 81.09 349 65 1 1 349 1 348 2e-172 587
--- a/test-data/tblastn_four_human_vs_rhodopsin.tabular Sun Apr 03 12:47:39 2011 -0400
+++ b/test-data/tblastn_four_human_vs_rhodopsin.tabular Mon Apr 04 12:55:33 2011 -0400
@@ -1,10 +1,10 @@
-sp|P08100|OPSD_HUMAN Subject_1 96.55 348 12 0 1 348 1 1044 0.0 732
-sp|P08100|OPSD_HUMAN Subject_2 84.80 342 51 1 1 341 42 1067 0.0 646
-sp|P08100|OPSD_HUMAN Subject_3 93.24 74 5 0 239 312 3147 3368 1e-72 151
-sp|P08100|OPSD_HUMAN Subject_3 91.53 59 5 0 177 235 2855 3031 1e-72 126
-sp|P08100|OPSD_HUMAN Subject_3 96.40 111 4 0 11 121 1 333 1e-64 229
-sp|P08100|OPSD_HUMAN Subject_3 93.22 59 4 0 119 177 1404 1580 1e-32 122
-sp|P08100|OPSD_HUMAN Subject_3 88.46 26 3 0 312 337 4222 4299 6e-13 57.7
-sp|P08100|OPSD_HUMAN Subject_4 95.09 326 16 0 11 336 1 978 0.0 658
-sp|P08100|OPSD_HUMAN Subject_5 93.39 348 23 0 1 348 1 1044 0.0 711
-sp|P08100|OPSD_HUMAN Subject_6 82.16 342 60 1 1 341 23 1048 0.0 626
+sp|P08100|OPSD_HUMAN gi|57163782|ref|NM_001009242.1| 96.55 348 12 0 1 348 1 1044 0.0 732
+sp|P08100|OPSD_HUMAN gi|2734705|gb|U59921.1|BBU59921 84.80 342 51 1 1 341 42 1067 0.0 646
+sp|P08100|OPSD_HUMAN gi|283855845|gb|GQ290303.1| 93.24 74 5 0 239 312 3147 3368 1e-72 151
+sp|P08100|OPSD_HUMAN gi|283855845|gb|GQ290303.1| 91.53 59 5 0 177 235 2855 3031 1e-72 126
+sp|P08100|OPSD_HUMAN gi|283855845|gb|GQ290303.1| 96.40 111 4 0 11 121 1 333 1e-64 229
+sp|P08100|OPSD_HUMAN gi|283855845|gb|GQ290303.1| 93.22 59 4 0 119 177 1404 1580 1e-32 122
+sp|P08100|OPSD_HUMAN gi|283855845|gb|GQ290303.1| 88.46 26 3 0 312 337 4222 4299 6e-13 57.7
+sp|P08100|OPSD_HUMAN gi|283855822|gb|GQ290312.1| 95.09 326 16 0 11 336 1 978 0.0 658
+sp|P08100|OPSD_HUMAN gi|18148870|dbj|AB062417.1| 93.39 348 23 0 1 348 1 1044 0.0 711
+sp|P08100|OPSD_HUMAN gi|12583664|dbj|AB043817.1| 82.16 342 60 1 1 341 23 1048 0.0 626
--- a/tools/ncbi_blast_plus/ncbi_blastp_wrapper.xml Sun Apr 03 12:47:39 2011 -0400
+++ b/tools/ncbi_blast_plus/ncbi_blastp_wrapper.xml Mon Apr 04 12:55:33 2011 -0400
@@ -133,6 +133,8 @@
<param name="subject" value="rhodopsin_proteins.fasta" ftype="fasta" /><param name="database" value="" /><param name="evalue_cutoff" value="1e-8" />
+ <param name="blast_type" value="blastp" />
+ <param name="out_format" value="6" /><param name="adv_opts_selector" value="advanced" /><param name="filter_query" value="True" /><param name="matrix" value="BLOSUM62" />
--- a/tools/ncbi_blast_plus/ncbi_tblastn_wrapper.xml Sun Apr 03 12:47:39 2011 -0400
+++ b/tools/ncbi_blast_plus/ncbi_tblastn_wrapper.xml Mon Apr 04 12:55:33 2011 -0400
@@ -138,7 +138,7 @@
<output name="output1" file="tblastn_four_human_vs_rhodopsin.tabular" ftype="tabular" /></test><test>
- <!-- Same as above, but parse deflines -->
+ <!-- Same as above, but parse deflines - on BLAST 2.2.25+ makes no difference --><param name="query" value="four_human_proteins.fasta" ftype="fasta" /><param name="db_opts_selector" value="file" /><param name="subject" value="rhodopsin_nucs.fasta" ftype="fasta" />
@@ -151,7 +151,7 @@
<param name="max_hits" value="0" /><param name="word_size" value="0" /><param name="parse_deflines" value="true" />
- <output name="output1" file="tblastn_four_human_vs_rhodopsin_parse_deflines.tabular" ftype="tabular" />
+ <output name="output1" file="tblastn_four_human_vs_rhodopsin.tabular" ftype="tabular" /></test></tests><help>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new changesets in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/7deb53694d98/
changeset: r5335:7deb53694d98
user: james_taylor
date: 2011-04-03 18:40:28
summary: trackster: typo
affected #: 1 file (0 bytes)
--- a/static/scripts/trackster.js Sat Apr 02 23:13:38 2011 -0400
+++ b/static/scripts/trackster.js Sun Apr 03 12:40:28 2011 -0400
@@ -2172,7 +2172,7 @@
if ( mode == "no_detail" ) {
mode = "reduced to feature spans";
} else if ( mode == "summary_tree" ) {
- mode = "reduced to foverage histogram";
+ mode = "reduced to coverage histogram";
}
this.mode_div.text( "Auto (" + mode + ")" );
}
http://bitbucket.org/galaxy/galaxy-central/changeset/086c9c2c52b9/
changeset: r5336:086c9c2c52b9
user: james_taylor
date: 2011-04-03 18:47:39
summary: trackster: some fixes for read tracks
affected #: 1 file (119 bytes)
--- a/static/scripts/trackster.js Sun Apr 03 12:40:28 2011 -0400
+++ b/static/scripts/trackster.js Sun Apr 03 12:47:39 2011 -0400
@@ -69,52 +69,6 @@
}
});
-/**
- * Draw a dashed line on a canvas using filled rectangles. This function is based on:
- * http://vetruvet.blogspot.com/2010/10/drawing-dashed-lines-on-html5-canvas.h…
- * However, that approach uses lines, which don't seem to render as well, so use
- * rectangles instead.
- */
-var dashedLine = function(ctx, x1, y1, x2, y2, dashLen) {
- if (dashLen === undefined) { dashLen = 4; }
- var dX = x2 - x1;
- var dY = y2 - y1;
- var dashes = Math.floor(Math.sqrt(dX * dX + dY * dY) / dashLen);
- var dashX = dX / dashes;
- var dashY = dY / dashes;
- var q;
-
- for (q = 0; q < dashes; q++, x1 += dashX, y1 += dashY) {
- if (q % 2 !== 0) {
- continue;
- }
- ctx.fillRect(x1, y1, dashLen, 1);
- }
-};
-
-/**
- * Draw an isosceles triangle that points down.
- */
-var drawDownwardEquilateralTriangle = function(ctx, down_vertex_x, down_vertex_y, side_len) {
- // Compute other two points of triangle.
- var
- x1 = down_vertex_x - side_len/2,
- x2 = down_vertex_x + side_len/2,
- y = down_vertex_y - Math.sqrt( side_len*3/2 );
-
- // Draw and fill.
- ctx.beginPath();
- ctx.moveTo(x1, y);
- ctx.lineTo(x2, y);
- ctx.lineTo(down_vertex_x, down_vertex_y);
- ctx.lineTo(x1, y);
-
- ctx.strokeStyle = this.fillStyle;
- ctx.fill();
- ctx.stroke();
- ctx.closePath();
-};
-
// ---- Web UI specific utilities ----
/**
@@ -1760,7 +1714,7 @@
$.when(track.data_cache.get_data(view.chrom, tile_low, tile_high, track.mode,
resolution, track.data_url_extra_params)).then(function(tile_data) {
// If sequence data needed, get that and draw. Otherwise draw.
- if (view.reference_track && w_scale > CHAR_WIDTH_PX) {
+ if (view.reference_track && w_scale > view.canvas_manager.char_width_px) {
$.when(view.reference_track.data_cache.get_data(view.chrom, tile_low, tile_high,
track.mode, resolution,
view.reference_track.data_url_extra_params)).then(function(seq_data) {
@@ -1959,7 +1913,7 @@
var track = this,
tile_length = DENSITY * resolution;
- if (w_scale > CHAR_WIDTH_PX) {
+ if (w_scale > this.view.canvas_manager.char_width_px) {
if (seq === null) {
track.content_div.css("height", "0px");
return;
@@ -2605,6 +2559,52 @@
var painters_module = function(require, exports){
/**
+ * Draw a dashed line on a canvas using filled rectangles. This function is based on:
+ * http://vetruvet.blogspot.com/2010/10/drawing-dashed-lines-on-html5-canvas.h…
+ * However, that approach uses lines, which don't seem to render as well, so use
+ * rectangles instead.
+ */
+var dashedLine = function(ctx, x1, y1, x2, y2, dashLen) {
+ if (dashLen === undefined) { dashLen = 4; }
+ var dX = x2 - x1;
+ var dY = y2 - y1;
+ var dashes = Math.floor(Math.sqrt(dX * dX + dY * dY) / dashLen);
+ var dashX = dX / dashes;
+ var dashY = dY / dashes;
+ var q;
+
+ for (q = 0; q < dashes; q++, x1 += dashX, y1 += dashY) {
+ if (q % 2 !== 0) {
+ continue;
+ }
+ ctx.fillRect(x1, y1, dashLen, 1);
+ }
+};
+
+/**
+ * Draw an isosceles triangle that points down.
+ */
+var drawDownwardEquilateralTriangle = function(ctx, down_vertex_x, down_vertex_y, side_len) {
+ // Compute other two points of triangle.
+ var
+ x1 = down_vertex_x - side_len/2,
+ x2 = down_vertex_x + side_len/2,
+ y = down_vertex_y - Math.sqrt( side_len*3/2 );
+
+ // Draw and fill.
+ ctx.beginPath();
+ ctx.moveTo(x1, y);
+ ctx.lineTo(x2, y);
+ ctx.lineTo(down_vertex_x, down_vertex_y);
+ ctx.lineTo(x1, y);
+
+ ctx.strokeStyle = this.fillStyle;
+ ctx.fill();
+ ctx.stroke();
+ ctx.closePath();
+};
+
+/**
* SummaryTreePainter, a histogram showing number of intervals in a region
*/
var SummaryTreePainter = function( data, delta, max, view_start, view_end, show_counts ) {
@@ -3152,14 +3152,15 @@
base_offset = 0,
seq_offset = 0,
gap = 0
- ref_seq = this.ref_seq;
+ ref_seq = this.ref_seq,
+ char_width_px = ctx.canvas.manager.char_width_px;
// Keep list of items that need to be drawn on top of initial drawing layer.
var draw_last = [];
// Gap is needed so that read is offset and hence first base can be drawn on read.
// TODO-FIX: using this gap offsets reads so that their start is not visually in sync with other tracks.
- if ((mode === "Pack" || this.mode === "Auto") && orig_seq !== undefined && w_scale > CHAR_WIDTH_PX) {
+ if ((mode === "Pack" || this.mode === "Auto") && orig_seq !== undefined && w_scale > char_width_px) {
gap = Math.round(w_scale/2);
}
if (!cigar) {
@@ -3256,7 +3257,7 @@
// Draw sequence.
// X center is offset + start - <half_sequence_length>
var x_center = s_start - (s_end - s_start)/2;
- if ( (mode === "Pack" || this.mode === "Auto") && orig_seq !== undefined && w_scale > CHAR_WIDTH_PX) {
+ if ( (mode === "Pack" || this.mode === "Auto") && orig_seq !== undefined && w_scale > char_width_px) {
// Draw sequence container.
ctx.fillStyle = "yellow";
ctx.fillRect(x_center - gap, y_center - 9, s_end - s_start, 9);
@@ -3292,7 +3293,7 @@
}
}
else {
- if ( (mode === "Pack" || this.mode === "Auto") && orig_seq !== undefined && w_scale > CHAR_WIDTH_PX) {
+ if ( (mode === "Pack" || this.mode === "Auto") && orig_seq !== undefined && w_scale > char_width_px) {
// Show insertions with a single number at the insertion point.
draw_last[draw_last.length] = {type: "text", data: [seq.length, insert_x_coord, y_center + 9]};
}
@@ -3349,7 +3350,7 @@
gap = 0;
// TODO: fix gap usage; also see note on gap in draw_read.
- if ((mode === "Pack" || this.mode === "Auto") && w_scale > CHAR_WIDTH_PX) {
+ if ((mode === "Pack" || this.mode === "Auto") && w_scale > ctx.canvas.manager.char_width_px) {
var gap = Math.round(w_scale/2);
}
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: james_taylor: trackster: tabs. why won't this editor respect my authority?
by Bitbucket 02 Apr '11
by Bitbucket 02 Apr '11
02 Apr '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/f13780c1674f/
changeset: r5334:f13780c1674f
user: james_taylor
date: 2011-04-03 05:13:38
summary: trackster: tabs. why won't this editor respect my authority?
affected #: 1 file (2.0 KB)
--- a/static/scripts/trackster.js Sat Apr 02 23:12:02 2011 -0400
+++ b/static/scripts/trackster.js Sat Apr 02 23:13:38 2011 -0400
@@ -46,26 +46,26 @@
extend( CanvasManager.prototype, {
load_pattern: function( key, path ) {
- var patterns = this.patterns,
- dummy_context = this.dummy_context,
- image = new Image();
- // FIXME: where does image_path come from? not in browser.mako...
- image.src = image_path + path;
- image.onload = function() {
- patterns[key] = dummy_context.createPattern( image, "repeat" );
- }
+ var patterns = this.patterns,
+ dummy_context = this.dummy_context,
+ image = new Image();
+ // FIXME: where does image_path come from? not in browser.mako...
+ image.src = image_path + path;
+ image.onload = function() {
+ patterns[key] = dummy_context.createPattern( image, "repeat" );
+ }
},
get_pattern: function( key ) {
- return this.patterns[key];
+ return this.patterns[key];
},
new_canvas: function() {
- var canvas = this.document.createElement("canvas");
- // If using excanvas in IE, we need to explicately attach the canvas
- // methods to the DOM element
- if (window.G_vmlCanvasManager) { G_vmlCanvasManager.initElement(canvas); }
- // Keep a reference back to the manager
- canvas.manager = this;
- return canvas;
+ var canvas = this.document.createElement("canvas");
+ // If using excanvas in IE, we need to explicately attach the canvas
+ // methods to the DOM element
+ if (window.G_vmlCanvasManager) { G_vmlCanvasManager.initElement(canvas); }
+ // Keep a reference back to the manager
+ canvas.manager = this;
+ return canvas;
}
});
@@ -291,8 +291,8 @@
// the data was "index" or "data." Also could slice the data so that
// only data points in request are returned.
//
-
- /* Disabling for now, more detailed data is never loaded for line tracks
+
+ /* Disabling for now, more detailed data is never loaded for line tracks
if (this.subset) {
var key, split_key, entry_low, entry_high, mode, entry;
for (var i = 0; i < this.key_ary.length; i++) {
@@ -312,13 +312,13 @@
}
}
}
- */
+ */
// Load data from server. The deferred is immediately saved until the
- // data is ready, it then replaces itself with the actual data
+ // data is ready, it then replaces itself with the actual data
entry = this.load_data(chrom, low, high, mode, resolution, extra_params);
- this.set_data( low, high, mode, entry );
- return entry
+ this.set_data( low, high, mode, entry );
+ return entry
},
set_data: function(low, high, mode, result) {
//console.log("set_data", low, high, mode, result);
@@ -1718,8 +1718,8 @@
var track = this;
// Put a 50ms delay on drawing so that if the user scrolls fast, we don't load extra data
var draw_and_show_tile = function(id, result, resolution, tile_index, parent_element, w_scale, seq_data) {
- // DEBUG: this is still called too many times when moving slowly,
- // console.log( "draw_and_show_tile", resolution, tile_index, w_scale );
+ // DEBUG: this is still called too many times when moving slowly,
+ // console.log( "draw_and_show_tile", resolution, tile_index, w_scale );
returned_tile = track.draw_tile(result, resolution, tile_index, parent_element, w_scale, seq_data)
// Wrap element in div for background
@@ -2111,7 +2111,7 @@
// Paint line onto full canvas
var ctx = canvas.getContext("2d");
var painter = new painters.LinePainter( result.data, tile_low, tile_low + tile_length,
- this.prefs.min_value, this.prefs.max_value, this.prefs.color, this.mode );
+ this.prefs.min_value, this.prefs.max_value, this.prefs.color, this.mode );
painter.draw( ctx, width, height );
return canvas;
@@ -2193,7 +2193,7 @@
inc_slots = this.inc_slots[level];
if (!inc_slots || (inc_slots.mode !== mode)) {
inc_slots = new (slotting.FeatureSlotter)( level, mode === "Pack", MAX_FEATURE_DEPTH, function ( x ) { return dummy_context.measureText( x ) } );
- inc_slots.mode = mode;
+ inc_slots.mode = mode;
this.inc_slots[level] = inc_slots;
}
@@ -2465,135 +2465,135 @@
*/
extend( exports.FeatureSlotter.prototype, {
slot_features: function( features ) {
- var w_scale = this.w_scale, inc_slots = this.slots, start_end_dct = this.start_end_dct,
- undone = [], slotted = [], highest_slot = 0, max_rows = this.max_rows;
-
- // If feature already exists in slots (from previously seen tiles), use the same slot,
- // otherwise if not seen, add to "undone" list for slot calculation.
+ var w_scale = this.w_scale, inc_slots = this.slots, start_end_dct = this.start_end_dct,
+ undone = [], slotted = [], highest_slot = 0, max_rows = this.max_rows;
+
+ // If feature already exists in slots (from previously seen tiles), use the same slot,
+ // otherwise if not seen, add to "undone" list for slot calculation.
- // TODO: Should calculate zoom tile index, which will improve performance
- // by only having to look at a smaller subset
- // if (this.start_end_dct[0] === undefined) { this.start_end_dct[0] = []; }
- for (var i = 0, len = features.length; i < len; i++) {
- var feature = features[i],
- feature_uid = feature[0];
- if (inc_slots[feature_uid] !== undefined) {
- highest_slot = Math.max(highest_slot, inc_slots[feature_uid]);
- slotted.push(inc_slots[feature_uid]);
- } else {
- undone.push(i);
- }
- }
-
- // Slot unslotted features.
-
- // Find the first slot such that current feature doesn't overlap any other features in that slot.
- // Returns -1 if no slot was found.
- var find_slot = function(f_start, f_end) {
- // TODO: Fix constants
- for (var slot_num = 0; slot_num <= max_rows; slot_num++) {
- var has_overlap = false,
- slot = start_end_dct[slot_num];
- if (slot !== undefined) {
- // Iterate through features already in slot to see if current feature will fit.
- for (var k = 0, k_len = slot.length; k < k_len; k++) {
- var s_e = slot[k];
- if (f_end > s_e[0] && f_start < s_e[1]) {
- // There is overlap
- has_overlap = true;
- break;
- }
- }
- }
- if (!has_overlap) {
- return slot_num;
- }
- }
- return -1;
- };
-
- // Do slotting.
- for (var i = 0, len = undone.length; i < len; i++) {
- var feature = features[undone[i]],
- feature_uid = feature[0],
- feature_start = feature[1],
- feature_end = feature[2],
- feature_name = feature[3],
- // Where to start, end drawing on screen.
- f_start = Math.floor( feature_start * w_scale ),
- f_end = Math.ceil( feature_end * w_scale ),
- text_len = this.measureText(feature_name).width,
- text_align;
-
- // Update start, end drawing locations to include feature name.
- // Try to put the name on the left, if not, put on right.
- if (feature_name !== undefined && this.include_label ) {
- // Add gap for label spacing and extra pack space padding
- // TODO: Fix constants
- text_len += (LABEL_SPACING + PACK_SPACING);
- if (f_start - text_len >= 0) {
- f_start -= text_len;
- text_align = "left";
- } else {
- f_end += text_len;
- text_align = "right";
- }
- }
-
- // Find slot.
- var slot_num = find_slot(f_start, f_end);
+ // TODO: Should calculate zoom tile index, which will improve performance
+ // by only having to look at a smaller subset
+ // if (this.start_end_dct[0] === undefined) { this.start_end_dct[0] = []; }
+ for (var i = 0, len = features.length; i < len; i++) {
+ var feature = features[i],
+ feature_uid = feature[0];
+ if (inc_slots[feature_uid] !== undefined) {
+ highest_slot = Math.max(highest_slot, inc_slots[feature_uid]);
+ slotted.push(inc_slots[feature_uid]);
+ } else {
+ undone.push(i);
+ }
+ }
+
+ // Slot unslotted features.
+
+ // Find the first slot such that current feature doesn't overlap any other features in that slot.
+ // Returns -1 if no slot was found.
+ var find_slot = function(f_start, f_end) {
+ // TODO: Fix constants
+ for (var slot_num = 0; slot_num <= max_rows; slot_num++) {
+ var has_overlap = false,
+ slot = start_end_dct[slot_num];
+ if (slot !== undefined) {
+ // Iterate through features already in slot to see if current feature will fit.
+ for (var k = 0, k_len = slot.length; k < k_len; k++) {
+ var s_e = slot[k];
+ if (f_end > s_e[0] && f_start < s_e[1]) {
+ // There is overlap
+ has_overlap = true;
+ break;
+ }
+ }
+ }
+ if (!has_overlap) {
+ return slot_num;
+ }
+ }
+ return -1;
+ };
+
+ // Do slotting.
+ for (var i = 0, len = undone.length; i < len; i++) {
+ var feature = features[undone[i]],
+ feature_uid = feature[0],
+ feature_start = feature[1],
+ feature_end = feature[2],
+ feature_name = feature[3],
+ // Where to start, end drawing on screen.
+ f_start = Math.floor( feature_start * w_scale ),
+ f_end = Math.ceil( feature_end * w_scale ),
+ text_len = this.measureText(feature_name).width,
+ text_align;
+
+ // Update start, end drawing locations to include feature name.
+ // Try to put the name on the left, if not, put on right.
+ if (feature_name !== undefined && this.include_label ) {
+ // Add gap for label spacing and extra pack space padding
+ // TODO: Fix constants
+ text_len += (LABEL_SPACING + PACK_SPACING);
+ if (f_start - text_len >= 0) {
+ f_start -= text_len;
+ text_align = "left";
+ } else {
+ f_end += text_len;
+ text_align = "right";
+ }
+ }
+
+ // Find slot.
+ var slot_num = find_slot(f_start, f_end);
- /*
- if (slot_num < 0) {
-
- TODO: this is not yet working --
- console.log(feature_uid, "looking for slot with text on the right");
- // Slot not found. If text was on left, try on right and see
- // if slot can be found.
- // TODO: are there any checks we need to do to ensure that text
- // will fit on tile?
- if (text_align === "left") {
- f_start -= text_len;
- f_end -= text_len;
- text_align = "right";
- slot_num = find_slot(f_start, f_end);
- }
- if (slot_num >= 0) {
- console.log(feature_uid, "found slot with text on the right");
- }
+ /*
+ if (slot_num < 0) {
+
+ TODO: this is not yet working --
+ console.log(feature_uid, "looking for slot with text on the right");
+ // Slot not found. If text was on left, try on right and see
+ // if slot can be found.
+ // TODO: are there any checks we need to do to ensure that text
+ // will fit on tile?
+ if (text_align === "left") {
+ f_start -= text_len;
+ f_end -= text_len;
+ text_align = "right";
+ slot_num = find_slot(f_start, f_end);
+ }
+ if (slot_num >= 0) {
+ console.log(feature_uid, "found slot with text on the right");
+ }
- }
- */
- // Do slotting.
- if (slot_num >= 0) {
- // Add current feature to slot.
- if (start_end_dct[slot_num] === undefined) {
- start_end_dct[slot_num] = [];
- }
- start_end_dct[slot_num].push([f_start, f_end]);
- inc_slots[feature_uid] = slot_num;
- highest_slot = Math.max(highest_slot, slot_num);
- }
- else {
- // TODO: remove this warning when skipped features are handled.
- // Show warning for skipped feature.
- //console.log("WARNING: not displaying feature", feature_uid, f_start, f_end);
- }
- }
-
- // Debugging: view slots data.
- /*
- for (var i = 0; i < MAX_FEATURE_DEPTH; i++) {
- var slot = start_end_dct[i];
- if (slot !== undefined) {
- console.log(i, "*************");
- for (var k = 0, k_len = slot.length; k < k_len; k++) {
- console.log("\t", slot[k][0], slot[k][1]);
- }
- }
- }
- */
- return highest_slot + 1;
+ }
+ */
+ // Do slotting.
+ if (slot_num >= 0) {
+ // Add current feature to slot.
+ if (start_end_dct[slot_num] === undefined) {
+ start_end_dct[slot_num] = [];
+ }
+ start_end_dct[slot_num].push([f_start, f_end]);
+ inc_slots[feature_uid] = slot_num;
+ highest_slot = Math.max(highest_slot, slot_num);
+ }
+ else {
+ // TODO: remove this warning when skipped features are handled.
+ // Show warning for skipped feature.
+ //console.log("WARNING: not displaying feature", feature_uid, f_start, f_end);
+ }
+ }
+
+ // Debugging: view slots data.
+ /*
+ for (var i = 0; i < MAX_FEATURE_DEPTH; i++) {
+ var slot = start_end_dct[i];
+ if (slot !== undefined) {
+ console.log(i, "*************");
+ for (var k = 0, k_len = slot.length; k < k_len; k++) {
+ console.log("\t", slot[k][0], slot[k][1]);
+ }
+ }
+ }
+ */
+ return highest_slot + 1;
}
});
@@ -2807,7 +2807,7 @@
// Slot valid only if features are slotted and this feature is slotted;
// feature may not be due to lack of space.
slot = (slots && slots[feature_uid] !== undefined ? slots[feature_uid] : null);
-
+
// Draw feature if there's overlap and mode is dense or feature is slotted (as it must be for all non-dense modes).
if ( ( feature_start < view_end && feature_end > view_start ) && (this.mode == "Dense" || slot !== null)) {
this.draw_element(ctx, this.mode, feature, slot, view_start, view_end, w_scale, y_scale,
@@ -2876,17 +2876,17 @@
label_color = this.prefs.label_color;
// Dense mode displays the same for all data.
- /*
+ /*
if (mode === "Dense") {
ctx.fillStyle = block_color;
ctx.fillRect(f_start, y_center, f_end - f_start, DENSE_FEATURE_HEIGHT);
}
- */
-
- if ( mode == "Dense" ) {
- slot = 1;
- }
-
+ */
+
+ if ( mode == "Dense" ) {
+ slot = 1;
+ }
+
if (mode === "no_detail") {
// No details for feature, so only one way to display.
ctx.fillStyle = block_color;
@@ -2983,22 +2983,22 @@
block_thick_end = Math.min(block_end, thick_end);
ctx.fillRect(block_thick_start, y_center + 1,
block_thick_end - block_thick_start, thick_height);
- if ( feature_blocks.length == 1 && mode == "Pack") {
- // Exactly one block means we have no introns, but do have a distinct "thick" region,
- // draw arrows over it if in pack mode
- if (feature_strand === "+") {
- ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand_inv' );
- } else if (feature_strand === "-") {
- ctx.fillStyle = ctx.canvas.manager.get_pattern( 'left_strand_inv' );
- }
- // If region is wide enough in pixels, pad a bit
- if ( block_thick_start + 14 < block_thick_end ) {
- block_thick_start += 2;
- block_thick_end -= 2;
- }
- ctx.fillRect( block_thick_start, y_center + 1,
+ if ( feature_blocks.length == 1 && mode == "Pack") {
+ // Exactly one block means we have no introns, but do have a distinct "thick" region,
+ // draw arrows over it if in pack mode
+ if (feature_strand === "+") {
+ ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand_inv' );
+ } else if (feature_strand === "-") {
+ ctx.fillStyle = ctx.canvas.manager.get_pattern( 'left_strand_inv' );
+ }
+ // If region is wide enough in pixels, pad a bit
+ if ( block_thick_start + 14 < block_thick_end ) {
+ block_thick_start += 2;
+ block_thick_end -= 2;
+ }
+ ctx.fillRect( block_thick_start, y_center + 1,
block_thick_end - block_thick_start, thick_height );
- }
+ }
}
}
}
@@ -3006,7 +3006,7 @@
// Draw label for Pack mode.
if (mode === "Pack" && feature_start > tile_low) {
ctx.fillStyle = label_color;
- // FIXME: assumption here that the entire view starts at 0
+ // FIXME: assumption here that the entire view starts at 0
if (tile_low === 0 && f_start - ctx.measureText(feature_name).width < 0) {
ctx.textAlign = "left";
ctx.fillText(feature_name, f_end + LABEL_SPACING, y_center + 8);
@@ -3414,14 +3414,14 @@
var modules = {};
// Provide a require function
var require = function( name ) {
- return modules[name];
+ return modules[name];
};
// Run module will run the module_function provided and store in the
// require dict using key
var run_module = function( key, module_function ) {
- var exports = {};
- module_function( require, exports );
- modules[key] = exports;
+ var exports = {};
+ module_function( require, exports );
+ modules[key] = exports;
};
// Run all modules
run_module( 'slotting', slotting_module );
@@ -3429,6 +3429,6 @@
run_module( 'trackster', trackster_module );
// Export trackster stuff
for ( key in modules.trackster ) {
- target[key] = modules.trackster[key];
+ target[key] = modules.trackster[key];
}
})(window);
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
02 Apr '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/0b7a4ca37154/
changeset: r5333:0b7a4ca37154
user: james_taylor
date: 2011-04-03 05:12:02
summary: trackster: fix bug with fetching same data many times by putting deferred in data cache immediately, still problematic because many deferred callbacks are queued up and the tile is drawn multiple times, debug statement demonstrates this, needs more refactoring to get it right
affected #: 1 file (292 bytes)
--- a/static/scripts/trackster.js Sat Apr 02 18:30:13 2011 -0400
+++ b/static/scripts/trackster.js Sat Apr 02 23:12:02 2011 -0400
@@ -314,10 +314,11 @@
}
*/
- //
- // Load data from server.
- //
- return this.load_data(chrom, low, high, mode, resolution, extra_params);
+ // Load data from server. The deferred is immediately saved until the
+ // data is ready, it then replaces itself with the actual data
+ entry = this.load_data(chrom, low, high, mode, resolution, extra_params);
+ this.set_data( low, high, mode, entry );
+ return entry
},
set_data: function(low, high, mode, result) {
//console.log("set_data", low, high, mode, result);
@@ -1717,6 +1718,8 @@
var track = this;
// Put a 50ms delay on drawing so that if the user scrolls fast, we don't load extra data
var draw_and_show_tile = function(id, result, resolution, tile_index, parent_element, w_scale, seq_data) {
+ // DEBUG: this is still called too many times when moving slowly,
+ // console.log( "draw_and_show_tile", resolution, tile_index, w_scale );
returned_tile = track.draw_tile(result, resolution, tile_index, parent_element, w_scale, seq_data)
// Wrap element in div for background
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new changesets in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/f8ac9094b145/
changeset: r5331:f8ac9094b145
user: james_taylor
date: 2011-04-02 23:35:27
summary: trackster: drawing labels on left at start of chrom works again, tweaks to feature track padding
affected #: 1 file (0 bytes)
--- a/static/scripts/trackster.js Sat Apr 02 16:43:02 2011 -0400
+++ b/static/scripts/trackster.js Sat Apr 02 17:35:27 2011 -0400
@@ -2776,8 +2776,8 @@
// Calculate new slots incrementally for this new chunk of data and update height if necessary.
required_height = rows_required * y_scale;
}
- // Pad bottom by half a row
- return required_height + Math.round( y_scale / 2 );
+ // Pad bottom by half a row, at least 5 px
+ return required_height + Math.max( Math.round( y_scale / 2 ), 5 );
},
draw: function( ctx, width, height, slots ) {
@@ -3000,9 +3000,8 @@
// Draw label for Pack mode.
if (mode === "Pack" && feature_start > tile_low) {
ctx.fillStyle = label_color;
- // FIXME: do this without tile_index
- var tile_index = 1;
- if (tile_index === 0 && f_start - ctx.measureText(feature_name).width < 0) {
+ // FIXME: assumption here that the entire view starts at 0
+ if (tile_low === 0 && f_start - ctx.measureText(feature_name).width < 0) {
ctx.textAlign = "left";
ctx.fillText(feature_name, f_end + LABEL_SPACING, y_center + 8);
} else {
http://bitbucket.org/galaxy/galaxy-central/changeset/8f250815662e/
changeset: r5332:8f250815662e
user: james_taylor
date: 2011-04-03 00:30:13
summary: trackster: disabling subsetting in data manager, breaks line tracks
affected #: 1 file (80 bytes)
--- a/static/scripts/trackster.js Sat Apr 02 17:35:27 2011 -0400
+++ b/static/scripts/trackster.js Sat Apr 02 18:30:13 2011 -0400
@@ -291,6 +291,8 @@
// the data was "index" or "data." Also could slice the data so that
// only data points in request are returned.
//
+
+ /* Disabling for now, more detailed data is never loaded for line tracks
if (this.subset) {
var key, split_key, entry_low, entry_high, mode, entry;
for (var i = 0; i < this.key_ary.length; i++) {
@@ -310,6 +312,7 @@
}
}
}
+ */
//
// Load data from server.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: jgoecks: Gracefully handle parsing errors in GFFReader and accurately compute raw size of GFF features.
by Bitbucket 02 Apr '11
by Bitbucket 02 Apr '11
02 Apr '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/ddea56886275/
changeset: r5330:ddea56886275
user: jgoecks
date: 2011-04-02 22:43:02
summary: Gracefully handle parsing errors in GFFReader and accurately compute raw size of GFF features.
affected #: 3 files (346 bytes)
--- a/lib/galaxy/datatypes/converters/gff_to_interval_index_converter.py Sat Apr 02 16:02:30 2011 -0400
+++ b/lib/galaxy/datatypes/converters/gff_to_interval_index_converter.py Sat Apr 02 16:43:02 2011 -0400
@@ -32,7 +32,7 @@
convert_gff_coords_to_bed( feature )
index.add( feature.chrom, feature.start, feature.end, offset )
- offset += feature.raw_size()
+ offset += feature.raw_size
index.write( open(out_fname, "w") )
--- a/lib/galaxy/datatypes/util/gff_util.py Sat Apr 02 16:02:30 2011 -0400
+++ b/lib/galaxy/datatypes/util/gff_util.py Sat Apr 02 16:43:02 2011 -0400
@@ -11,7 +11,7 @@
only attribute is 'group.'
"""
def __init__( self, reader, fields, chrom_col, feature_col, start_col, end_col, \
- strand_col, score_col, default_strand, fix_strand=False, raw_line='' ):
+ strand_col, score_col, default_strand, fix_strand=False ):
# HACK: GFF format allows '.' for strand but GenomicInterval does not. To get around this,
# temporarily set strand and then unset after initing GenomicInterval.
unknown_strand = False
@@ -34,8 +34,7 @@
raise MissingFieldError( "No field for score_col (%d)" % score_col )
self.score = self.fields[ self.score_col ]
- # Attributes specific to GFF.
- self.raw_line = raw_line
+ # GFF attributes.
self.attributes = parse_gff_attributes( fields[8] )
class GFFFeature( GFFInterval ):
@@ -43,11 +42,13 @@
A GFF feature, which can include multiple intervals.
"""
def __init__( self, reader, chrom_col, feature_col, start_col, end_col, \
- strand_col, score_col, default_strand, fix_strand=False, intervals=[] ):
+ strand_col, score_col, default_strand, fix_strand=False, intervals=[], \
+ raw_size=0 ):
GFFInterval.__init__( self, reader, intervals[0].fields, chrom_col, feature_col, \
start_col, end_col, strand_col, score_col, default_strand, \
fix_strand=fix_strand )
self.intervals = intervals
+ self.raw_size = raw_size
# Use intervals to set feature attributes.
for interval in self.intervals:
# Error checking. NOTE: intervals need not share the same strand.
@@ -68,20 +69,6 @@
if not name:
name = self.attributes.get( 'group', None )
return name
-
- def raw_size( self ):
- """
- Returns raw size of feature; raw size is the number of bytes that
- comprise feature.
- """
- # Feature length is all intervals/lines that comprise feature.
- feature_len = 0
- for interval in self.intervals:
- # HACK: +1 for EOL char. Need bx-python to provide raw_line itself
- # b/c TableReader strips EOL characters, thus changing the line
- # length.
- feature_len += len( interval.raw_line ) + 1
- return feature_len
class GFFIntervalToBEDReaderWrapper( NiceReaderWrapper ):
"""
@@ -124,7 +111,7 @@
def parse_row( self, line ):
interval = GFFInterval( self, line.split( "\t" ), self.chrom_col, self.feature_col, \
self.start_col, self.end_col, self.strand_col, self.score_col, \
- self.default_strand, fix_strand=self.fix_strand, raw_line=line )
+ self.default_strand, fix_strand=self.fix_strand )
return interval
def next( self ):
@@ -151,7 +138,8 @@
#
# Get next GFFFeature
- #
+ #
+ raw_size = 0
# If there is no seed interval, set one. Also, if there are no more
# intervals to read, this is where iterator dies.
@@ -161,6 +149,8 @@
self.seed_interval = GenomicIntervalReader.next( self )
except ParseError, e:
handle_parse_error( e )
+ finally:
+ raw_size += len( self.current_line )
# If header or comment, clear seed interval and return it.
if isinstance( self.seed_interval, ( Header, Comment ) ):
@@ -187,6 +177,9 @@
break
except ParseError, e:
handle_parse_error( e )
+ continue
+ finally:
+ raw_size += len( self.current_line )
# If interval not associated with feature, break.
group = interval.attributes.get( 'group', None )
@@ -214,7 +207,7 @@
return GFFFeature( self, self.chrom_col, self.feature_col, self.start_col, \
self.end_col, self.strand_col, self.score_col, \
self.default_strand, fix_strand=self.fix_strand, \
- intervals=feature_intervals )
+ intervals=feature_intervals, raw_size=raw_size )
def convert_bed_coords_to_gff( interval ):
--- a/lib/galaxy/visualization/tracks/data_providers.py Sat Apr 02 16:02:30 2011 -0400
+++ b/lib/galaxy/visualization/tracks/data_providers.py Sat Apr 02 16:43:02 2011 -0400
@@ -658,7 +658,7 @@
payload = package_gff_feature( feature )
payload.insert( 0, offset )
results.append( payload )
- offset += feature.raw_size()
+ offset += feature.raw_size
return { 'data': results, 'message': message }
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0