lists.galaxyproject.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2023
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
List overview
Download
galaxy-commits
September 2010
----- 2023 -----
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
galaxy-commits@lists.galaxyproject.org
1 participants
70 discussions
Start a n
N
ew thread
galaxy-dist commit 188f2cd3173d: trackster: make "go-to" navigation inline, activated when chrom position is clicked. Drag-zoom overlay should now cover entire viewport (was missing a bit at bottom)
by commits-noreply@bitbucket.org
08 Sep '10
08 Sep '10
# HG changeset patch --
Bitbucket.org
# Project galaxy-dist # URL
http://bitbucket.org/galaxy/galaxy-dist/overview
# User Kanwei Li <kanwei(a)gmail.com> # Date 1282863895 14400 # Node ID 188f2cd3173dbdc183580e5d8b7beeba779ad9d0 # Parent 39484914b8920148a4ac845570f7e2f743122f2f trackster: make "go-to" navigation inline, activated when chrom position is clicked. Drag-zoom overlay should now cover entire viewport (was missing a bit at bottom) --- a/static/scripts/trackster.js +++ b/static/scripts/trackster.js @@ -112,19 +112,28 @@ var View = function( container, chrom, t this.nav_controls = $("<div/>").addClass("nav-controls").appendTo(this.nav); this.chrom_form = $("<form/>").attr("action", function() { void(0); } ).appendTo(this.nav_controls); this.chrom_select = $("<select/>").attr({ "name": "chrom"}).css("width", "15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form); - this.nav_input = $("<input/>").addClass("nav-input").hide().bind("keypress", function(e) { - if ((e.keyCode || e.which) === 13) { - view.go_to( $(this).val() ); + var submit_nav = function(e) { + if (e.type === "focusout" || (e.keyCode || e.which) === 13 || (e.keyCode || e.which) === 27 ) { + if ((e.keyCode || e.which) !== 27) { // Not escape key + view.go_to( $(this).val() ); + } $(this).hide(); + view.location_span.show(); + view.chrom_select.show(); return false; } - - }).appendTo(this.chrom_form); + }; + this.nav_input = $("<input/>").addClass("nav-input").hide().bind("keypress focusout", submit_nav).appendTo(this.chrom_form); this.location_span = $("<span/>").addClass("location").appendTo(this.chrom_form); + this.location_span.bind("click", function() { + view.location_span.hide(); + view.chrom_select.hide(); + view.nav_input.css("display", "inline-block"); + view.nav_input.focus(); + }); if (this.vis_id !== undefined) { this.hidden_input = $("<input/>").attr("type", "hidden").val(this.vis_id).appendTo(this.chrom_form); } - this.goto_link = $("<a/>").click(function() { view.nav_input.toggle(); view.nav_input.focus(); }).html('<img src="'+image_path+'/fugue/navigation.png" />').appendTo(this.chrom_form); this.zo_link = $("<a/>").click(function() { view.zoom_out(); view.redraw() }).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form); this.zi_link = $("<a/>").click(function() { view.zoom_in(); view.redraw() }).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form); @@ -205,7 +214,7 @@ var View = function( container, chrom, t this.drag_origin_x = e.clientX; this.drag_origin_pos = e.clientX / view.viewport_container.width() * (view.high - view.low) + view.low; this.drag_div = $("<div />").css( { - "height": view.content_div.height(), "top": "0px", "position": "absolute", + "height": view.content_div.height()+30, "top": "0px", "position": "absolute", "background-color": "#cfc", "border": "1px solid #6a6", "opacity": 0.5, "z-index": 1000 } ).appendTo( $(this) ); }).bind( "drag", function(e) { @@ -245,24 +254,26 @@ var View = function( container, chrom, t // Invalid chrom return; } - view.chrom = chrom; - if (view.chrom === "") { - // No chrom selected - view.intro_div.show(); - view.content_div.hide(); - } else { - view.intro_div.hide(); - view.content_div.show(); - } - view.chrom_select.val(view.chrom); - view.max_high = found.len; - view.reset(); - view.redraw(true); + if (chrom !== view.chrom) { + view.chrom = chrom; + if (view.chrom === "") { + // No chrom selected + view.intro_div.show(); + view.content_div.hide(); + } else { + view.intro_div.hide(); + view.content_div.show(); + } + view.chrom_select.val(view.chrom); + view.max_high = found.len; + view.reset(); + view.redraw(true); - for (var track_id in view.tracks) { - var track = view.tracks[track_id]; - if (track.init) { - track.init(); + for (var track_id in view.tracks) { + var track = view.tracks[track_id]; + if (track.init) { + track.init(); + } } } if (low !== undefined && high !== undefined) { --- a/static/june_2007_style/blue/trackster.css +++ b/static/june_2007_style/blue/trackster.css @@ -4,7 +4,7 @@ .nav-controls{text-align:center;position:relative;background:#cccccc;background-image:url(panel_header_bg.png);background-position:top center;background-repeat:repeat-x;padding:2px 0;} .nav-controls input{margin:0 5px;} .nav-controls a{padding:0 0.4em;} -.nav-input{font-size:12px;position:absolute;right:0px;bottom:25px;width:20em;z-index:1000;} +.nav-input{font-size:12px;width:30em;z-index:1000;} .location{display:inline-block;width:15em;margin:0px 10px;} .intro{position:absolute;top:50%;left:30%;color:#555;font-size:16px;} .overview{width:100%;margin:0px;color:white;} --- a/static/june_2007_style/trackster.css.tmpl +++ b/static/june_2007_style/trackster.css.tmpl @@ -26,10 +26,7 @@ } .nav-input { font-size: 12px; - position: absolute; - right: 0px; - bottom: 25px; - width: 20em; + width: 30em; z-index: 1000; } .location { --- a/static/scripts/packed/trackster.js +++ b/static/scripts/packed/trackster.js @@ -1,1 +1,1 @@ -var DENSITY=200,FEATURE_LEVELS=10,DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),PX_PER_CHAR=CONTEXT.measureText("A").width,RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/strand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONT EXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,c,e,d,b){this.container=a;this.vis_id=d;this.dbkey=b;this.title=e;this.chrom=c;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this .has_changes=false;this.init();this.reset()};$.extend(View.prototype,{init:function(){var b=this.container,a=this;this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(b);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(b);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide().appendTo(b);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.nav_container=$("<div/>").addClass("nav-container").appendTo(b);this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.nav);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_o verview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){void (0)}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keypress",function(c){if((c.keyCode||c.which)===13){a.go_to($(this).val());$(this).hide();return false}}).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.goto_link=$("<a/>").click(function(){a.nav_input.toggle();a.nav_input.focus()}).html('<img src="'+image_path+'/fugue/navigation.png" />').appendTo(this.chrom_form);this.zo_link=$("<a/>").click(function() {a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);this.zi_link=$("<a/>").click(function(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(c){if(c.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=c.chrom_info;var e='<option value="">Select Chrom/Contig</option>';for(i in a.chrom_data){var d=a.chrom_data[i]["chrom"];e+='<option value="'+d+'">'+d+"</option>"}a.chrom_select.html(e);a.intro_div.show();a.content_div.hide();a.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())})},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("dblclick",function(c){a.zoom_in(c.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(c){ this.current_x=c.offsetX}).bind("drag",function(c){var f=c.offsetX-this.current_x;this.current_x=c.offsetX;var d=Math.round(f/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-d)});this.viewport_container.bind("dragstart",function(c){this.original_low=a.low;this.current_height=c.clientY;this.current_x=c.offsetX;this.active=(c.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(f){if(!this.active){return}var c=$(this);var h=f.offsetX-this.current_x;var d=c.scrollTop()-(f.clientY-this.current_height);c.scrollTop(d);this.current_height=f.clientY;this.current_x=f.offsetX;var g=Math.round(h/a.viewport_container.width()*(a.high-a.low));a.move_delta(g)});this.top_labeltrack.bind("dragstart",function(c){this.drag_origin_x=c.clientX;this.drag_origin_pos=c.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_div=$("<div />").css({height:a.content_div.height(),top:"0px",position:"absolute","background-color":"#cfc",border:"1px soli d #6a6",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(h){var d=Math.min(h.clientX,this.drag_origin_x)-a.container.offset().left,c=Math.max(h.clientX,this.drag_origin_x)-a.container.offset().left,g=(a.high-a.low),f=a.viewport_container.width();a.update_location(Math.round(d/f*g)+a.low,Math.round(c/f*g)+a.low);this.drag_div.css({left:d+"px",width:(c-d)+"px"})}).bind("dragend",function(j){var d=Math.min(j.clientX,this.drag_origin_x),c=Math.max(j.clientX,this.drag_origin_x),g=(a.high-a.low),f=a.viewport_container.width(),h=a.low;a.low=Math.round(d/f*g)+h;a.high=Math.round(c/f*g)+h;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack))},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(d,a,f){var c=this;var e=$.grep(c.chrom_data ,function(h,j){return h.chrom===d})[0];if(e===undefined){return}c.chrom=d;if(c.chrom===""){c.intro_div.show();c.content_div.hide()}else{c.intro_div.hide();c.content_div.show()}c.chrom_select.val(c.chrom);c.max_high=e.len;c.reset();c.redraw(true);for(var g in c.tracks){var b=c.tracks[g];if(b.init){b.init()}}if(a!==undefined&&f!==undefined){c.low=Math.max(a,0);c.high=Math.min(f,c.max_high)}c.overview_viewport.find("canvas").remove();c.redraw()},go_to:function(f){var k=this,b=f.split(":"),h=b[0],j=b[1];if(j!==undefined){try{var g=j.split("-"),a=parseInt(g[0].replace(/,/g,"")),d=parseInt(g[1].replace(/,/g,""))}catch(c){return false}}k.change_chrom(h,a,d)},move_delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.high-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.contain er_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},update_options:function(){this.has_changes=true;var b=$("ul#sortable-ul").sortable("toArray");for(var c in b){var e=b[c].split("_li")[0].split("track_")[1];this.viewport.append($("#track_"+e))}for(var d in view.tracks){var a=view.tracks[d];if(a&&a.update_options){a.update_options(d)}}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(f){var d=this.high-this.low,b=this.low,e=this.high;if(b<this.max_low){b=this.max_low}if(e>this.max_high){e=this.max_high}if(this.high!==0&&d<this.min_separation){e=b+this.min_separation}this.low=Math.floor(b);this.high=Math.ceil(e);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))));this.overview_box.css({left:(this.low/(this.max_high-this.max_low))*this.overview_viewport.width(),width:Math.max(12,(this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())}).show();this.update_location(this.low,this.high);if(!f){for(var c=0,a=this.tracks.length;c<a;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,a=this.label_tracks.length;c<a;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b= this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()}});var Track=function(b,a,c){this.name=b;this.parent_element=c;this.view=a;this.init_global()};$.extend(Track.prototype,{init_global:function(){this.header_div=$("<div class='track-header'>").text(this.name);this.content_div=$("<div class='track-content'>");this.container_div=$("<div />").addClass("track").append(this.header_div).append(this.content_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.vie w.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){var c=this,b=c.view;if(c.display_modes!==undefined){if(c.mode_div===undefined){c.mode_div=$("<div class='right-float menubutton popup' />").appendTo(c.header_di v);var g=c.display_modes[0];c.mode=g;c.mode_div.text(g);var a=function(h){c.mode_div.text(h);c.mode=h;c.tile_cache.clear();c.draw()};var e={};for(var d in c.display_modes){var f=c.display_modes[d];e[f]=function(h){return function(){a(h)}}(f)}make_popupmenu(c.mode_div,e)}else{c.mode_div.hide()}}if(c.overview_check_div===undefined){c.overview_check_div=$("<div class='right-float' />").css("margin-top","-3px").appendTo(c.header_div);c.overview_check=$("<input type='checkbox' class='overview_check' />").appendTo(c.overview_check_div);c.overview_check.bind("click",function(){var h=this;b.overview_viewport.find("canvas").remove();c.set_overview();$(".overview_check").each(function(){if(this!==h){$(this).attr("checked",false)}})});c.overview_check_div.append($("<label />").text("Overview"))}};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(){var j=this.view.low,e=this.view.high,f=e-j,d=this.view.resolution;var l=$("<div style='position: relative;'></div>"),m=this.conte nt_div.width()/f,h;this.content_div.children(":first").remove();this.content_div.append(l),this.max_height=0;var a=Math.floor(j/d/DENSITY);while((a*DENSITY*d)<e){var k=this.content_div.width()+"_"+m+"_"+a;var c=this.tile_cache.get(k);if(c){var g=a*DENSITY*d;var b=(g-j)*m;if(this.left_offset){b-=this.left_offset}c.css({left:b});l.append(c);this.max_height=Math.max(this.max_height,c.height());this.content_div.css("height",this.max_height+"px")}else{this.delayed_draw(this,k,j,e,a,d,l,m)}a+=1}},delayed_draw:function(c,e,a,f,b,d,g,h){setTimeout(function(){if(!(a>c.view.high||f<c.view.low)){tile_element=c.draw_tile(d,b,g,h);if(tile_element){if(!c.initial_canvas){c.initial_canvas=$(tile_element).clone();var l=tile_element.get(0).getContext("2d");var j=c.initial_canvas.get(0).getContext("2d");var k=l.getImageData(0,0,l.canvas.width,l.canvas.height);j.putImageData(k,0,0);c.set_overview()}c.tile_cache.set(e,tile_element);c.max_height=Math.max(c.max_height,tile_element.height());c.cont ent_div.css("height",c.max_height+"px")}}},50)},set_overview:function(){var a=this.view;a.overview_viewport.height(a.default_overview_height);a.overview_box.height(a.default_overview_height);if(this.initial_canvas&&this.overview_check.is(":checked")){a.overview_viewport.append(this.initial_canvas);a.overview_viewport.height(this.initial_canvas.height());a.overview_box.height(this.initial_canvas.height())}$(window).trigger("resize")}});var LabelTrack=function(a,b){Track.call(this,null,a,b);this.track_type="LabelTrack";this.hidden=true;this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g} this.content_div.children(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.hidden=true;this.height_px=12;this.container_div.addClass("reference-track");this.dummy_canvas=$("<canvas></canvas>").get(0).getContext("2d");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.prototype,{get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(f,b,k,o){var g=b*DENSITY*f,d=DENSITY*f,e=$("<canvas class='tile'></canvas>"),n=e.get(0).getContext("2d"),j=f+"_"+b;i f(o>PX_PER_CHAR){if(this.data_cache.get(j)===undefined){this.get_data(f,b);return}var m=this.data_cache.get(j);if(m===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*o+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*o-this.left_offset});for(var h=0,l=m.length;h<l;h++){var a=Math.round(h*o);n.fillText(m[h],a+this.left_offset,10)}k.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=function(d,b,a,c){this.track_type="LineTrack";this.display_modes=["Line","Filled","Intensity"];this.mode="Line";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=80;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={min_value:undefined,max_value:undefined,mode:"Line"};if(c.min_value!==undefined){this.prefs.min_value=c.min_value}if(c.max_value!==undefined){this.prefs.max_value=c.max_value}};$.extend(Line Track.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;$("#linetrack_"+b+"_minval").remove();$("#linetrack_"+b+"_maxval").remove();var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"relative",top:"32px",left:"10px"});d.prependTo(a.container_div);e.css({posi tion:"relative",top:a.height_px+32+"px",left:"10px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(p,r,c,e){if(this.vertical_range===undefined){return}var s=r*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),v=p+"_"+r;if(this.data_cache.get(v)===undefined){this.get_data(p,r);return}var j=this.data_cache.get(v);if(j===null){return}b.css({position:"absolute",top:0,left:(s-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,t=this.total_freque ncy,d=this.height_px,m=this.mode;o.beginPath();if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}var u,h;for(var q=0;q<data.length;q++){u=(data[q][0]-s)*e;h=data[q][1];if(m=="Intensity"){if(h===null){continue}if(h<=l){h=l}else{if(h>=g){h=g}}h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")";o.fillRect(u,0,f,this.height_px)}else{if(h===null){if(k&&m==="Filled"){o.lineTo(u,d)}k=false;continue}else{if(h<=l){h=l}else{if(h>=g){h=g}}h=Math.round(d-(h-l)/n*d);if(k){o.lineTo(u,h)}else{k=true;if(m==="Filled"){o.moveTo(u,d);o.lineTo(u,h)}else{o.moveTo(u,h)}}}}}if(m==="Filled"){if(k){o.lineTo(u,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(k){var a=$("<div />").addClass("form-row");var e="track_"+k+"_minval",h=$("<label></label>").attr("for",e).text("Min value:"),b=(this.prefs.min_value===undefined?"":this.prefs.min_value),j=$("<input></input>").attr("id",e).val(b),g="track_"+k+"_maxval",d=$("<label></label>").attr("for" ,g).text("Max value:"),f=(this.prefs.max_value===undefined?"":this.prefs.max_value),c=$("<input></input>").attr("id",g).val(f);return a.append(h).append(j).append(d).append(c)},update_options:function(c){var a=$("#track_"+c+"_minval").val(),b=$("#track_"+c+"_maxval").val();if(a!==this.prefs.min_value||b!==this.prefs.max_value){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(b);this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+c+"_minval").text(this.prefs.min_value);$("#linetrack_"+c+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,c){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_ nodetail_px=2;this.summary_draw_height=20;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.left_offset=200;this.prefs={block_color:"black",label_color:"black",show_counts:true};if(c.block_color!==undefined){this.prefs.block_color=c.block_color}if(c.label_color!==undefined){this.prefs.label_color=c.label_color}if(c.show_counts!==undefined){this.prefs.show_counts=c.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b="initial";this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution},function(c){a.mode_div.show();a.data_cache.set(b,c);a.draw()})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolutio n:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=1/a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(this.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.measureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(true){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_til e[a][v].length;u<A;u++){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=[]}this.s_e_by_tile[a][v].push([e,f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(n,o,f,m,b,d,k,e,h){n.textAlign="center";var j=Math.round(o/2);if((this.mode==="Pack"||this.mode==="Auto")&&d!==undefined&&o>PX_PER_CHAR){n.fillStyle=this.prefs.block_color;n.fillRect(k,h+1,e,9);n.fillStyle="#eee";for(var g=0,l=d.length;g<l;g++){if(b+g>=f&&b+g<=m){var a=Math.floor(Math.max(0,(b+g-f)*o));n.fillText(d[g],a+this.left_offset+j,h+9)}}}else{n.fillStyle=this.prefs.block_color;n.fillRect(k,h+4,e,3)}},draw_tile:function(Y,l,o,al){var F=l*DENSITY*Y,ae=(l+1)*DENSITY*Y,E=ae-F;var af=(!this.initial_canvas?"initial":F+"_"+ae);var A=this.data_cache.get(af);var d;if(A===undefined){this.data_queue[[F,ae]]=true;this.get_data(F,ae);return}var a=Math.ceil(E*al),M=$("<canvas class='tile'></canvas>"),aa=thi s.prefs.label_color,g=this.prefs.block_color,n=this.mode,W=(n==="Squish")||(n==="Dense")&&(n!=="Pack")||(n==="Auto"&&(A.extra_info==="no_detail")),Q=this.left_offset,ak,t,am;if(A.dataset_type==="summary_tree"){t=this.summary_draw_height}else{if(n==="Dense"){t=15;am=10}else{am=(W?this.vertical_nodetail_px:this.vertical_detail_px);t=this.incremental_slots(this.view.zoom_res,A.data,W,n)*am+15;ak=this.inc_slots[this.view.zoom_res]}}M.css({position:"absolute",top:0,left:(F-this.view.low)*al-Q});M.get(0).width=a+Q;M.get(0).height=t;o.parent().css("height",Math.max(this.height_px,t)+"px");var B=M.get(0).getContext("2d");B.fillStyle=g;B.font=this.default_font;B.textAlign="right";if(A.dataset_type=="summary_tree"){var L,I=55,ad=255-I,h=ad*2/3,S=A.data,D=A.max,m=A.avg,b=Math.ceil(A.delta*al);for(var ah=0,z=S.length;ah<z;ah++){var U=Math.floor((S[ah][0]-F)*al);var T=S[ah][1];if(!T){continue}L=Math.floor(ad-(T/D)*ad);B.fillStyle="rgb("+L+","+L+","+L+")";B.fillRect(U+Q,0,b,this.summary_d raw_height);if(this.prefs.show_counts&&B.measureText(T).width<b){if(L>h){B.fillStyle="black"}else{B.fillStyle="#ddd"}B.textAlign="center";B.fillText(T,U+Q+(b/2),12)}}d="Summary";o.append(M);return M}var aj=A.data;var ag=0;for(var ah=0,z=aj.length;ah<z;ah++){var N=aj[ah],K=N[0],ai=N[1],V=N[2],G=N[3];if(ai<=ae&&V>=F){var X=Math.floor(Math.max(0,(ai-F)*al)),C=Math.ceil(Math.min(a,Math.max(0,(V-F)*al))),R=(n==="Dense"?0:ak[K]*am);if(A.dataset_type==="bai"){B.fillStyle=g;if(N[4] instanceof Array){var u=Math.floor(Math.max(0,(N[4][0]-F)*al)),J=Math.ceil(Math.min(a,Math.max(0,(N[4][1]-F)*al))),s=Math.floor(Math.max(0,(N[5][0]-F)*al)),q=Math.ceil(Math.min(a,Math.max(0,(N[5][1]-F)*al)));if(N[4][1]>=F&&N[4][0]<=ae){this.rect_or_text(B,al,F,ae,N[4][0],N[4][2],u+Q,J-u,R)}if(N[5][1]>=F&&N[5][0]<=ae){this.rect_or_text(B,al,F,ae,N[5][0],N[5][2],s+Q,q-s,R)}if(s>J){B.fillStyle="#999";B.fillRect(J+Q,R+5,s-J,1)}}else{B.fillStyle=g;this.rect_or_text(B,al,F,ae,ai,G,X+Q,C-X,R)}if(n!=="Dense"&&!W& &ai>F){B.fillStyle=this.prefs.label_color;if(l===0&&X-B.measureText(G).width<0){B.textAlign="left";B.fillText(K,C+2+Q,R+8)}else{B.textAlign="right";B.fillText(K,X-2+Q,R+8)}B.fillStyle=g}}else{if(A.dataset_type==="interval_index"){if(W){B.fillRect(X+Q,R+5,C-X,1)}else{var w=N[4],P=N[5],Z=N[6],f=N[7];var v,ab,H=null,an=null;if(P&&Z){H=Math.floor(Math.max(0,(P-F)*al));an=Math.ceil(Math.min(a,Math.max(0,(Z-F)*al)))}if(n!=="Dense"&&G!==undefined&&ai>F){B.fillStyle=aa;if(l===0&&X-B.measureText(G).width<0){B.textAlign="left";B.fillText(G,C+2+Q,R+8)}else{B.textAlign="right";B.fillText(G,X-2+Q,R+8)}B.fillStyle=g}if(f){if(w){if(w=="+"){B.fillStyle=RIGHT_STRAND}else{if(w=="-"){B.fillStyle=LEFT_STRAND}}B.fillRect(X+Q,R,C-X,10);B.fillStyle=g}for(var af=0,e=f.length;af<e;af++){var p=f[af],c=Math.floor(Math.max(0,(p[0]-F)*al)),O=Math.ceil(Math.min(a,Math.max((p[1]-F)*al)));if(c>O){continue}v=5;ab=3;B.fillRect(c+Q,R+ab,O-c,v);if(H!==undefined&&!(c>an||O<H)){v=9;ab=1;var ac=Math.max(c,H),r=Ma th.min(O,an);B.fillRect(ac+Q,R+ab,r-ac,v)}}}else{v=9;ab=1;B.fillRect(X+Q,R+ab,C-X,v);if(N.strand){if(N.strand=="+"){B.fillStyle=RIGHT_STRAND_INV}else{if(N.strand=="-"){B.fillStyle=LEFT_STRAND_INV}}B.fillRect(X+Q,R,C-X,10);B.fillStyle=prefs.block_color}}}}}ag++}}o.append(M);return M},gen_options:function(j){var a=$("<div />").addClass("form-row");var e="track_"+j+"_block_color",l=$("<label />").attr("for",e).text("Block color:"),m=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),k="track_"+j+"_label_color",g=$("<label />").attr("for",k).text("Text color:"),h=$("<input />").attr("id",k).attr("name",k).val(this.prefs.label_color),f="track_"+j+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(l).append(m).append(g).append(h).append(d)},update_options:function(e ){var b=$("#track_"+e+"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,c){FeatureTrack.call(this,d,b,a,c);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{}); +var DENSITY=200,FEATURE_LEVELS=10,DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),PX_PER_CHAR=CONTEXT.measureText("A").width,RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/strand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONT EXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,c,e,d,b){this.container=a;this.vis_id=d;this.dbkey=b;this.title=e;this.chrom=c;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this .has_changes=false;this.init();this.reset()};$.extend(View.prototype,{init:function(){var c=this.container,a=this;this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(c);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(c);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide().appendTo(c);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.nav_container=$("<div/>").addClass("nav-container").appendTo(c);this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.nav);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_o verview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){void (0)}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);var b=function(d){if(d.type==="focusout"||(d.keyCode||d.which)===13||(d.keyCode||d.which)===27){if((d.keyCode||d.which)!==27){a.go_to($(this).val())}$(this).hide();a.location_span.show();a.chrom_select.show();return false}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keypress focusout",b).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);this.location_span.bind("click",function(){a.location_span.hide();a.chrom_select.hide();a.nav_input.css("display","inline-block");a.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_i nput=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.zo_link=$("<a/>").click(function(){a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);this.zi_link=$("<a/>").click(function(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(d){if(d.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=d.chrom_info;var f='<option value="">Select Chrom/Contig</option>';for(i in a.chrom_data){var e=a.chrom_data[i]["chrom"];f+='<option value="'+e+'">'+e+"</option>"}a.chrom_select.html(f);a.intro_div.show();a.content_div.hide();a.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())})},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_d iv.bind("dblclick",function(d){a.zoom_in(d.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(d){this.current_x=d.offsetX}).bind("drag",function(d){var g=d.offsetX-this.current_x;this.current_x=d.offsetX;var f=Math.round(g/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-f)});this.viewport_container.bind("dragstart",function(d){this.original_low=a.low;this.current_height=d.clientY;this.current_x=d.offsetX;this.active=(d.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(g){if(!this.active){return}var d=$(this);var j=g.offsetX-this.current_x;var f=d.scrollTop()-(g.clientY-this.current_height);d.scrollTop(f);this.current_height=g.clientY;this.current_x=g.offsetX;var h=Math.round(j/a.viewport_container.width()*(a.high-a.low));a.move_delta(h)});this.top_labeltrack.bind("dragstart",function(d){this.drag_origin_x=d.clientX;this.drag_origin_pos=d.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_d iv=$("<div />").css({height:a.content_div.height()+30,top:"0px",position:"absolute","background-color":"#cfc",border:"1px solid #6a6",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(j){var f=Math.min(j.clientX,this.drag_origin_x)-a.container.offset().left,d=Math.max(j.clientX,this.drag_origin_x)-a.container.offset().left,h=(a.high-a.low),g=a.viewport_container.width();a.update_location(Math.round(f/g*h)+a.low,Math.round(d/g*h)+a.low);this.drag_div.css({left:f+"px",width:(d-f)+"px"})}).bind("dragend",function(k){var f=Math.min(k.clientX,this.drag_origin_x),d=Math.max(k.clientX,this.drag_origin_x),h=(a.high-a.low),g=a.viewport_container.width(),j=a.low;a.low=Math.round(f/g*h)+j;a.high=Math.round(d/g*h)+j;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack))},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this. nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(d,a,f){var c=this;var e=$.grep(c.chrom_data,function(h,j){return h.chrom===d})[0];if(e===undefined){return}if(d!==c.chrom){c.chrom=d;if(c.chrom===""){c.intro_div.show();c.content_div.hide()}else{c.intro_div.hide();c.content_div.show()}c.chrom_select.val(c.chrom);c.max_high=e.len;c.reset();c.redraw(true);for(var g in c.tracks){var b=c.tracks[g];if(b.init){b.init()}}}if(a!==undefined&&f!==undefined){c.low=Math.max(a,0);c.high=Math.min(f,c.max_high)}c.overview_viewport.find("canvas").remove();c.redraw()},go_to:function(f){var k=this,b=f.split(":"),h=b[0],j=b[1];if(j!==undefined){try{var g=j.split("-"),a=parseInt(g[0].replace(/,/g,"")),d=parseInt(g[1].replace(/,/g,""))}catch(c){return false}}k.change_chrom(h,a,d)},move_delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.hig h-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},update_options:function(){this.has_changes=true;var b=$("ul#sortable-ul").sortable("toArray");for(var c in b){var e=b[c].split("_li")[0].split("track_")[1];this.viewport.append($("#track_"+e))}for(var d in view.tracks){var a=view.tracks[d];if(a&&a.update_options){a.update_options(d)}}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(f){var d=this.high-this.low,b=this.low,e=this.high;if(b<this.max_low){b=this.max_low}if(e>this.max_high){ e=this.max_high}if(this.high!==0&&d<this.min_separation){e=b+this.min_separation}this.low=Math.floor(b);this.high=Math.ceil(e);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))));this.overview_box.css({left:(this.low/(this.max_high-this.max_low))*this.overview_viewport.width(),width:Math.max(12,(this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())}).show();this.update_location(this.low,this.high);if(!f){for(var c=0,a=this.tracks.length;c<a;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,a=this.label_tracks.length;c<a;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.hi gh-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b=this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()}});var Track=function(b,a,c){this.name=b;this.parent_element=c;this.view=a;this.init_global()};$.extend(Track.prototype,{init_global:function(){this.header_div=$("<div class='track-header'>").text(this.name);this.content_div=$("<div class='track-content'>");this.container_div=$("<div />").addClass("track").append(this.header_div).append(this.content_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url ,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.view.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){var c=this,b=c.vi ew;if(c.display_modes!==undefined){if(c.mode_div===undefined){c.mode_div=$("<div class='right-float menubutton popup' />").appendTo(c.header_div);var g=c.display_modes[0];c.mode=g;c.mode_div.text(g);var a=function(h){c.mode_div.text(h);c.mode=h;c.tile_cache.clear();c.draw()};var e={};for(var d in c.display_modes){var f=c.display_modes[d];e[f]=function(h){return function(){a(h)}}(f)}make_popupmenu(c.mode_div,e)}else{c.mode_div.hide()}}if(c.overview_check_div===undefined){c.overview_check_div=$("<div class='right-float' />").css("margin-top","-3px").appendTo(c.header_div);c.overview_check=$("<input type='checkbox' class='overview_check' />").appendTo(c.overview_check_div);c.overview_check.bind("click",function(){var h=this;b.overview_viewport.find("canvas").remove();c.set_overview();$(".overview_check").each(function(){if(this!==h){$(this).attr("checked",false)}})});c.overview_check_div.append($("<label />").text("Overview"))}};$.extend(TiledTrack.prototype,Track.prototype,{dr aw:function(){var j=this.view.low,e=this.view.high,f=e-j,d=this.view.resolution;var l=$("<div style='position: relative;'></div>"),m=this.content_div.width()/f,h;this.content_div.children(":first").remove();this.content_div.append(l),this.max_height=0;var a=Math.floor(j/d/DENSITY);while((a*DENSITY*d)<e){var k=this.content_div.width()+"_"+m+"_"+a;var c=this.tile_cache.get(k);if(c){var g=a*DENSITY*d;var b=(g-j)*m;if(this.left_offset){b-=this.left_offset}c.css({left:b});l.append(c);this.max_height=Math.max(this.max_height,c.height());this.content_div.css("height",this.max_height+"px")}else{this.delayed_draw(this,k,j,e,a,d,l,m)}a+=1}},delayed_draw:function(c,e,a,f,b,d,g,h){setTimeout(function(){if(!(a>c.view.high||f<c.view.low)){tile_element=c.draw_tile(d,b,g,h);if(tile_element){if(!c.initial_canvas){c.initial_canvas=$(tile_element).clone();var l=tile_element.get(0).getContext("2d");var j=c.initial_canvas.get(0).getContext("2d");var k=l.getImageData(0,0,l.canvas.width,l.canvas.h eight);j.putImageData(k,0,0);c.set_overview()}c.tile_cache.set(e,tile_element);c.max_height=Math.max(c.max_height,tile_element.height());c.content_div.css("height",c.max_height+"px")}}},50)},set_overview:function(){var a=this.view;a.overview_viewport.height(a.default_overview_height);a.overview_box.height(a.default_overview_height);if(this.initial_canvas&&this.overview_check.is(":checked")){a.overview_viewport.append(this.initial_canvas);a.overview_viewport.height(this.initial_canvas.height());a.overview_box.height(this.initial_canvas.height())}$(window).trigger("resize")}});var LabelTrack=function(a,b){Track.call(this,null,a,b);this.track_type="LabelTrack";this.hidden=true;this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'> </div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.hidden=true;this.height_px=12;this.container_div.addClass("reference-track");this.dummy_canvas=$("<canvas></canvas>").get(0).getContext("2d");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.prototype,{get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g, j)}})}},draw_tile:function(f,b,k,o){var g=b*DENSITY*f,d=DENSITY*f,e=$("<canvas class='tile'></canvas>"),n=e.get(0).getContext("2d"),j=f+"_"+b;if(o>PX_PER_CHAR){if(this.data_cache.get(j)===undefined){this.get_data(f,b);return}var m=this.data_cache.get(j);if(m===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*o+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*o-this.left_offset});for(var h=0,l=m.length;h<l;h++){var a=Math.round(h*o);n.fillText(m[h],a+this.left_offset,10)}k.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=function(d,b,a,c){this.track_type="LineTrack";this.display_modes=["Line","Filled","Intensity"];this.mode="Line";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=80;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={min_value:undefined,max_value:undefined,mode:"L ine"};if(c.min_value!==undefined){this.prefs.min_value=c.min_value}if(c.max_value!==undefined){this.prefs.max_value=c.max_value}};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;$("#linetrack_"+b+"_minval").remove();$("#linetrack_"+b+"_maxval").remove();var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_ "+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"relative",top:"32px",left:"10px"});d.prependTo(a.container_div);e.css({position:"relative",top:a.height_px+32+"px",left:"10px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(p,r,c,e){if(this.vertical_range===undefined){return}var s=r*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),v=p+"_"+r;if(this.data_cache.get(v)===undefined){this.get_data(p,r);return}var j=this.data_cache.get(v);if(j===null){return}b.css({position:"absolute",top:0,left:(s-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height =this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,t=this.total_frequency,d=this.height_px,m=this.mode;o.beginPath();if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}var u,h;for(var q=0;q<data.length;q++){u=(data[q][0]-s)*e;h=data[q][1];if(m=="Intensity"){if(h===null){continue}if(h<=l){h=l}else{if(h>=g){h=g}}h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")";o.fillRect(u,0,f,this.height_px)}else{if(h===null){if(k&&m==="Filled"){o.lineTo(u,d)}k=false;continue}else{if(h<=l){h=l}else{if(h>=g){h=g}}h=Math.round(d-(h-l)/n*d);if(k){o.lineTo(u,h)}else{k=true;if(m==="Filled"){o.moveTo(u,d);o.lineTo(u,h)}else{o.moveTo(u,h)}}}}}if(m==="Filled"){if(k){o.lineTo(u,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(k){var a=$("<div />").addClass("form-row");var e="track_"+k+"_minval",h=$("<label></label>").attr("for",e).text("Min value:"),b=(this.prefs.min _value===undefined?"":this.prefs.min_value),j=$("<input></input>").attr("id",e).val(b),g="track_"+k+"_maxval",d=$("<label></label>").attr("for",g).text("Max value:"),f=(this.prefs.max_value===undefined?"":this.prefs.max_value),c=$("<input></input>").attr("id",g).val(f);return a.append(h).append(j).append(d).append(c)},update_options:function(c){var a=$("#track_"+c+"_minval").val(),b=$("#track_"+c+"_maxval").val();if(a!==this.prefs.min_value||b!==this.prefs.max_value){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(b);this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+c+"_minval").text(this.prefs.min_value);$("#linetrack_"+c+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,c){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("featu re-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=2;this.summary_draw_height=20;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.left_offset=200;this.prefs={block_color:"black",label_color:"black",show_counts:true};if(c.block_color!==undefined){this.prefs.block_color=c.block_color}if(c.label_color!==undefined){this.prefs.label_color=c.label_color}if(c.show_counts!==undefined){this.prefs.show_counts=c.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b="initial";this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution},function(c){a.mode_div.show();a.data_cache.set(b,c);a.draw()})},get_data:function(a,d){var b =this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=1/a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(this.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.mea sureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(true){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_tile[a][v].length;u<A;u++){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=[]}this.s_e_by_tile[a][v].push([e,f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(n,o,f,m,b,d,k,e,h){n.textAlign="center";var j=Math.round(o/2);if((this.mode==="Pack"||this.mode==="Auto")&&d!==undefined&&o>PX_PER_CHAR){n.fillStyle=this.prefs.block_color;n.fillRect(k,h+1,e,9);n.fillStyle="#eee";for(var g=0,l=d.length;g<l;g++){if(b+g>=f&&b+g<=m){var a=Math.floor(Math.max(0,(b+g-f)*o));n.fillText(d[g],a+this.left_offset+j,h+9)}}}else{n.fillStyle=this.prefs.block_color;n.fillRect(k,h+4,e,3)}},draw_tile:function(Y,l,o,al){var F=l*DENSITY*Y,ae=(l+1)*DENSITY*Y,E=ae-F;var af=(!this.initial_canvas?"initial":F+"_"+ae);var A=this.data_cache.get(af);var d;if(A===undefined){this.data_queue[[F,ae]]=true;this.get_data(F,ae);return}var a=Math.ceil(E*al),M=$("<canvas class='tile'></canvas>"),aa=this.prefs.label_color,g=this.prefs.block_color,n=this.mode,W=(n==="Squish")||(n==="Dense")&&(n!=="Pack")||(n==="Auto"&&(A.extra_info==="no_detail")),Q=this.left_offset,ak,t,am;if(A.dataset_type==="summary_tree"){t=this.summary_draw_height}else{if(n==="Dense"){t=15;am=10}else{am=(W?this.vertical_nodetail_px:this.vertical_detail_px);t=this.incremental_slots(this.view.zoom_res,A.data,W,n)*am+15;ak=this.inc_slots[this.view.zoom_res]}}M.css({position:"absolute",top:0,left:(F-this.view.low)*al-Q});M.get(0).width=a+Q;M.get(0).height=t;o.parent().css("height",Math.max(this.height_px,t)+"px");var B=M.get(0).getContext("2d");B.fillStyle=g;B.font=this.default_font;B.textAlign="right";if(A.dataset_type=="summary_tree"){var L,I=55,ad=255-I,h=ad*2/3,S=A.data,D=A.max,m=A.avg,b=Math.ceil(A.delta*al);for(var ah=0,z=S.length;ah<z;ah++){var U=Math.floor(( S[ah][0]-F)*al);var T=S[ah][1];if(!T){continue}L=Math.floor(ad-(T/D)*ad);B.fillStyle="rgb("+L+","+L+","+L+")";B.fillRect(U+Q,0,b,this.summary_draw_height);if(this.prefs.show_counts&&B.measureText(T).width<b){if(L>h){B.fillStyle="black"}else{B.fillStyle="#ddd"}B.textAlign="center";B.fillText(T,U+Q+(b/2),12)}}d="Summary";o.append(M);return M}var aj=A.data;var ag=0;for(var ah=0,z=aj.length;ah<z;ah++){var N=aj[ah],K=N[0],ai=N[1],V=N[2],G=N[3];if(ai<=ae&&V>=F){var X=Math.floor(Math.max(0,(ai-F)*al)),C=Math.ceil(Math.min(a,Math.max(0,(V-F)*al))),R=(n==="Dense"?0:ak[K]*am);if(A.dataset_type==="bai"){B.fillStyle=g;if(N[4] instanceof Array){var u=Math.floor(Math.max(0,(N[4][0]-F)*al)),J=Math.ceil(Math.min(a,Math.max(0,(N[4][1]-F)*al))),s=Math.floor(Math.max(0,(N[5][0]-F)*al)),q=Math.ceil(Math.min(a,Math.max(0,(N[5][1]-F)*al)));if(N[4][1]>=F&&N[4][0]<=ae){this.rect_or_text(B,al,F,ae,N[4][0],N[4][2],u+Q,J-u,R)}if(N[5][1]>=F&&N[5][0]<=ae){this.rect_or_text(B,al,F,ae,N[5][0],N[5][2],s+Q, q-s,R)}if(s>J){B.fillStyle="#999";B.fillRect(J+Q,R+5,s-J,1)}}else{B.fillStyle=g;this.rect_or_text(B,al,F,ae,ai,G,X+Q,C-X,R)}if(n!=="Dense"&&!W&&ai>F){B.fillStyle=this.prefs.label_color;if(l===0&&X-B.measureText(G).width<0){B.textAlign="left";B.fillText(K,C+2+Q,R+8)}else{B.textAlign="right";B.fillText(K,X-2+Q,R+8)}B.fillStyle=g}}else{if(A.dataset_type==="interval_index"){if(W){B.fillRect(X+Q,R+5,C-X,1)}else{var w=N[4],P=N[5],Z=N[6],f=N[7];var v,ab,H=null,an=null;if(P&&Z){H=Math.floor(Math.max(0,(P-F)*al));an=Math.ceil(Math.min(a,Math.max(0,(Z-F)*al)))}if(n!=="Dense"&&G!==undefined&&ai>F){B.fillStyle=aa;if(l===0&&X-B.measureText(G).width<0){B.textAlign="left";B.fillText(G,C+2+Q,R+8)}else{B.textAlign="right";B.fillText(G,X-2+Q,R+8)}B.fillStyle=g}if(f){if(w){if(w=="+"){B.fillStyle=RIGHT_STRAND}else{if(w=="-"){B.fillStyle=LEFT_STRAND}}B.fillRect(X+Q,R,C-X,10);B.fillStyle=g}for(var af=0,e=f.length;af<e;af++){var p=f[af],c=Math.floor(Math.max(0,(p[0]-F)*al)),O=Math.ceil(Math.min(a, Math.max((p[1]-F)*al)));if(c>O){continue}v=5;ab=3;B.fillRect(c+Q,R+ab,O-c,v);if(H!==undefined&&!(c>an||O<H)){v=9;ab=1;var ac=Math.max(c,H),r=Math.min(O,an);B.fillRect(ac+Q,R+ab,r-ac,v)}}}else{v=9;ab=1;B.fillRect(X+Q,R+ab,C-X,v);if(N.strand){if(N.strand=="+"){B.fillStyle=RIGHT_STRAND_INV}else{if(N.strand=="-"){B.fillStyle=LEFT_STRAND_INV}}B.fillRect(X+Q,R,C-X,10);B.fillStyle=prefs.block_color}}}}}ag++}}o.append(M);return M},gen_options:function(j){var a=$("<div />").addClass("form-row");var e="track_"+j+"_block_color",l=$("<label />").attr("for",e).text("Block color:"),m=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),k="track_"+j+"_label_color",g=$("<label />").attr("for",k).text("Text color:"),h=$("<input />").attr("id",k).attr("name",k).val(this.prefs.label_color),f="track_"+j+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",t his.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(l).append(m).append(g).append(h).append(d)},update_options:function(e){var b=$("#track_"+e+"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,c){FeatureTrack.call(this,d,b,a,c);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
1
0
0
0
galaxy-dist commit 1d373ebcef62: Repack js
by commits-noreply@bitbucket.org
08 Sep '10
08 Sep '10
# HG changeset patch --
Bitbucket.org
# Project galaxy-dist # URL
http://bitbucket.org/galaxy/galaxy-dist/overview
# User Kanwei Li <kanwei(a)gmail.com> # Date 1282839244 14400 # Node ID 1d373ebcef62fbe016d893d247eb6023cf705d05 # Parent 2ac11399c20ed6b844f563b77de089b9ddff657e Repack js --- a/static/scripts/packed/galaxy.workflow_editor.canvas.js +++ b/static/scripts/packed/galaxy.workflow_editor.canvas.js @@ -1,1 +1,1 @@ -function Terminal(a){this.element=a;this.connectors=[]}$.extend(Terminal.prototype,{connect:function(a){this.connectors.push(a);if(this.node){this.node.changed()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.changed()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})}});function OutputTerminal(a,b){Terminal.call(this,a);this.datatypes=b}OutputTerminal.prototype=new Terminal();function InputTerminal(a,b){Terminal.call(this,a);this.datatypes=b}InputTerminal.prototype=new Terminal();$.extend(InputTerminal.prototype,{can_accept:function(a){if(this.connectors.length<1){for(var c in this.datatypes){for(var b in a.datatypes){if(a.datatypes[b]=="input"||issubtype(a.datatypes[b],this.datatypes[c])){return true}}}}return false}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_col or="#D8B365";if(b&&a){this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;this.handle1.connect(this);this.handle2=a;this.handle2.connect(this)},destroy:function(){if(this.handle1){this.handle1.disconnect(this)}if(this.handle2){this.handle2.disconnect(this)}$(this.canvas).remove()},redraw:function(){var d=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}d.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var n=function(c){return $(c).offset().left-d.offset().left};var i=function(c){return $(c).offset().top-d.offset().top};var h=n(this.handle1.element)+5;var g=i(this.handle1.element)+5;var p=n(this.handle2.element)+5;var m=i(this.handle2.element)+5;var f=100;var k=Math.min(h,p);var a=Math.max(h,p);var j=Math.min(g,m);var t=Math.max(g,m);var b=Math.min(Math.max(Math.abs(t-j)/2,100),300);var o=k-f;var s=j-f;var q=a -k+2*f;var l=t-j+2*f;this.canvas.style.left=o+"px";this.canvas.style.top=s+"px";this.canvas.setAttribute("width",q);this.canvas.setAttribute("height",l);h-=o;g-=s;p-=o;m-=s;var r=this.canvas.getContext("2d");r.lineCap="round";r.strokeStyle=this.outer_color;r.lineWidth=7;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke();r.strokeStyle=this.inner_color;r.lineWidth=5;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke()}});function Node(a){this.element=a;this.input_terminals={};this.output_terminals={};this.tool_errors={}}$.extend(Node.prototype,{enable_input_terminal:function(d,a,b){var c=this;$(d).each(function(){var f=this.terminal=new InputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dropstart",function(g){g.dragProxy.terminal.connectors[0].inner_color="#BBFFBB"}).bind("dropend",function(g){g.dragProxy.terminal.connectors[0].inner_color="#FFFFFF"}).bind("drop",function(g){(new Connector(g.dragTarget.terminal,g.dropTarget.terminal)) .redraw()}).bind("hover",function(){if(f.connectors.length>0){var g=$("<div class='callout'></div>").css({display:"none"}).appendTo("body").append($("<div class='buttons'></div>").append($("<img/>").attr("src",image_path+"/delete_icon.png").click(function(){$.each(f.connectors,function(i,h){h.destroy()});g.remove()}))).bind("mouseleave",function(){$(this).remove()});g.css({top:$(this).offset().top-2,left:$(this).offset().left-g.width(),"padding-right":$(this).width()}).show()}});c.input_terminals[a]=f})},enable_output_terminal:function(d,a,b){var c=this;$(d).each(function(){var g=this;var f=this.terminal=new OutputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dragstart",function(j){var i=$('<div class="drag-terminal" style="position: absolute;"></div>').appendTo("#canvas-container").get(0);i.terminal=new OutputTerminal(i);var k=new Connector();k.dragging=true;k.connect(this.terminal,i.terminal);$.dropManage({filter:function(h){return this.terminal.can_accept(f)}}).addClas s("input-terminal-active");return i}).bind("drag",function(i){var h=function(){var k=$(i.dragProxy).offsetParent().offset(),j=i.offsetX-k.left,l=i.offsetY-k.top;$(i.dragProxy).css({left:j,top:l});i.dragProxy.terminal.redraw();canvas_manager.update_viewport_overlay()};h();$("#canvas-container").get(0).scroll_panel.test(i,h)}).bind("dragend",function(h){h.dragProxy.terminal.connectors[0].destroy();$(h.dragProxy).remove();$.dropManage().removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()});c.output_terminals[a]=f})},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);( function(b){b.removeChild(a);b.appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(g){var d=this.element;if(g.type){this.type=g.type}this.name=g.name;this.form_html=g.form_html;this.tool_state=g.tool_state;this.tool_errors=g.tool_errors;this.tooltip=g.tooltip?g.tooltip:"";this.annotation=g.annotation;this.post_job_actions=g.post_job_actions;this.workflow_outputs=g.workflow_outputs;if(this.tool_errors){d.addClass("tool-node-error")}else{d.removeClass("tool-node-error")}var c=this;var a=d.find(".toolFormBody");a.find("div").remove();var h=$("<div class='inputs'></div>").appendTo(a);$.each(g.data_inputs,function(j,b){var f=$("<div class='terminal input-terminal'></div>");c.enable_input_terminal(f,b.name,b.extensions);h.append($("<div class='form-row dataRow input-data-row' name='"+b.name+"'>"+b.label+"</div>").prepend(f))});if((g.data_inputs.length>0)&&(g.data_outputs.length>0)){a.append($("<div class='rule'></div>"))}$.each(g.data_outpu ts,function(k,b){var j=$("<div class='terminal output-terminal'></div>");c.enable_output_terminal(j,b.name,b.extensions);var f=b.name;if(b.extensions.indexOf("input")<0){f=f+" ("+b.extensions+")"}a.append($("<div class='form-row dataRow'>"+f+"</div>").append(j))});workflow.node_changed(this)},update_field_data:function(f){var c=$(this.element),d=this;this.tool_state=f.tool_state;this.form_html=f.form_html;this.tool_errors=f.tool_errors;this.annotation=f.annotation;this.post_job_actions=$.parseJSON(f.post_job_actions);if(this.tool_errors){c.addClass("tool-node-error")}else{c.removeClass("tool-node-error")}var g=c.find("div.inputs");var b=$("<div class='inputs'></div>");var a=g.find("div.input-data-row");$.each(f.data_inputs,function(k,h){var j=$("<div class='terminal input-terminal'></div>");d.enable_input_terminal(j,h.name,h.extensions);g.find("div[name="+h.name+"]").each(function(){$(this).find(".input-terminal").each(function(){var i=this.terminal.connectors[0];if(i){j[0]. terminal.connectors[0]=i;i.handle2=j[0].terminal}});$(this).remove()});b.append($("<div class='form-row dataRow input-data-row' name='"+h.name+"'>"+h.label+"</div>").prepend(j))});g.replaceWith(b);g.find("div.input-data-row > .terminal").each(function(){this.terminal.destroy()});this.changed();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="<div style='color: red; text-style: italic;'>"+d+"</div>";this.form_html=c;a.html(c);workflow.node_changed(this)},changed:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false;this.active_form_has_changes=false}$.extend(Workflow.prototype,{add_node:function(a){a.id=this.id_counter;a.element.attr("id","wf-node-step-"+a.id);this.id_counter++;this.nodes[a.id]=a;this.has_changes=true;a.workflow=this},remove_node:function(a){if(this.active_node==a){this.clear_active_node()}delete this .nodes[a.id];this.has_changes=true},remove_all:function(){wf=this;$.each(this.nodes,function(b,a){a.destroy();wf.remove_node(a)})},to_simple:function(){var a={};$.each(this.nodes,function(c,f){var g={};$.each(f.input_terminals,function(h,i){g[i.name]=null;$.each(i.connectors,function(j,k){g[i.name]={id:k.handle1.node.id,output_name:k.handle1.name}})});var b={};if(f.post_job_actions){$.each(f.post_job_actions,function(j,h){var k={job_id:h.id,action_type:h.action_type,output_name:h.output_name,action_arguments:h.action_arguments};b[h.type+h.output_name]=null;b[h.type+h.output_name]=k})}if(!f.workflow_outputs){f.workflow_outputs=[]}var d={id:f.id,type:f.type,tool_id:f.tool_id,tool_state:f.tool_state,tool_errors:f.tool_errors,input_connections:g,position:$(f.element).position(),annotation:f.annotation,post_job_actions:f.post_job_actions,workflow_outputs:f.workflow_outputs};a[f.id]=d});return{steps:a}},from_simple:function(a){wf=this;var b=0;wf.name=a.name;$.each(a.steps,function (f,d){var c=prebuild_node("tool",d.name,d.tool_id);c.init_field_data(d);if(d.position){c.element.css({top:d.position.top,left:d.position.left})}c.id=d.id;wf.nodes[c.id]=c;b=Math.max(b,parseInt(f))});wf.id_counter=b+1;$.each(a.steps,function(f,d){var c=wf.nodes[f];$.each(d.input_connections,function(h,g){if(g){var i=wf.nodes[g.id];var j=new Connector();j.connect(i.output_terminals[g.output_name],c.input_terminals[h]);j.redraw()}})})},check_changes_in_active_form:function(){if(this.active_form_has_changes){this.has_changes=true;$("#right-content").find("form").submit();this.active_form_has_changes=false}},clear_active_node:function(){if(this.active_node){this.active_node.make_inactive();this.active_node=null}parent.show_form_for_tool("<div>No node selected</div>")},activate_node:function(a){if(this.active_node!=a){this.check_changes_in_active_form();this.clear_active_node();parent.show_form_for_tool(a.form_html+a.tooltip,a);a.make_active();this.active_node=a}},node_changed:fun ction(a){this.has_changes=true;if(this.active_node==a){this.check_changes_in_active_form();parent.show_form_for_tool(a.form_html+a.tooltip,a)}},layout:function(){this.check_changes_in_active_form();this.has_changes=true;var i={};var b={};$.each(this.nodes,function(l,k){if(i[l]===undefined){i[l]=0}if(b[l]===undefined){b[l]=[]}});$.each(this.nodes,function(l,k){$.each(k.input_terminals,function(m,n){$.each(n.connectors,function(p,q){var o=q.handle1.node;i[k.id]+=1;b[o.id].push(k.id)})})});node_ids_by_level=[];while(true){level_parents=[];for(var a in i){if(i[a]==0){level_parents.push(a)}}if(level_parents.length==0){break}node_ids_by_level.push(level_parents);for(var f in level_parents){var j=level_parents[f];delete i[j];for(var g in b[j]){i[b[j][g]]-=1}}}if(i.length){return}var d=this.nodes;var h=80;v_pad=30;var c=h;$.each(node_ids_by_level,function(k,l){l.sort(function(p,o){return $(d[p].element).position().top-$(d[o].element).position().top});var m=0;var n=v_pad;$.each(l,fun ction(o,r){var q=d[r];var p=$(q.element);$(p).css({top:n,left:c});m=Math.max(m,$(p).width());n+=$(p).height()+v_pad});c+=m+h});$.each(d,function(k,l){l.redraw()})},bounds_for_all_nodes:function(){var d=Infinity,b=-Infinity,c=Infinity,a=-Infinity,f;$.each(this.nodes,function(h,g){e=$(g.element);f=e.position();d=Math.min(d,f.left);b=Math.max(b,f.left+e.width());c=Math.min(c,f.top);a=Math.max(a,f.top+e.width())});return{xmin:d,xmax:b,ymin:c,ymax:a}},fit_canvas_to_nodes:function(){var a=this.bounds_for_all_nodes();var f=this.canvas_container.position();var i=this.canvas_container.parent();var d=fix_delta(a.xmin,100);var h=fix_delta(a.ymin,100);d=Math.max(d,f.left);h=Math.max(h,f.top);var c=f.left-d;var g=f.top-h;var b=round_up(a.xmax+100,100)+d;var j=round_up(a.ymax+100,100)+h;b=Math.max(b,-c+i.width());j=Math.max(j,-g+i.height());this.canvas_container.css({left:c,top:g,width:b,height:j});this.canvas_container.children().each(function(){var k=$(this).position();$(this).css("left ",k.left+d);$(this).css("top",k.top+h)})}});function fix_delta(a,b){if(a<b||a>3*b){new_pos=(Math.ceil(((a%b))/b)+1)*b;return(-(a-new_pos))}return 0}function round_up(a,b){return Math.ceil(a/b)*b}function prebuild_node(l,j,r){var i=$("<div class='toolForm toolFormInCanvas'></div>");var g=new Node(i);g.type=l;if(l=="tool"){g.tool_id=r}var n=$("<div class='toolFormTitle unselectable'>"+j+"</div>");i.append(n);i.css("left",$(window).scrollLeft()+20);i.css("top",$(window).scrollTop()+20);var m=$("<div class='toolFormBody'></div>");var h="<div><img height='16' align='middle' src='"+image_path+"/loading_small_white_bg.gif'/> loading tool info...</div>";m.append(h);g.form_html=h;i.append(m);var k=$("<div class='buttons' style='float: right;'></div>");k.append($("<img/>").attr("src",image_path+"/delete_icon.png").click(function(b){g.destroy()}).hover(function(){$(this).attr("src",image_path+"/delete_icon_dark.png")},function(){$(this).attr("src",image_path+"/delete_icon.png")}));i.ap pendTo("#canvas-container");var d=$("#canvas-container").position();var c=$("#canvas-container").parent();var a=i.width();var q=i.height();i.css({left:(-d.left)+(c.width()/2)-(a/2),top:(-d.top)+(c.height()/2)-(q/2)});k.prependTo(n);a+=(k.width()+10);i.css("width",a);$(i).bind("dragstart",function(){workflow.activate_node(g)}).bind("dragend",function(){workflow.node_changed(this);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview()}).bind("dragclickonly",function(){workflow.activate_node(g)}).bind("drag",function(o){var f=$(this).offsetParent().offset(),b=o.offsetX-f.left,p=o.offsetY-f.top;$(this).css({left:b,top:p});$(this).find(".terminal").each(function(){this.terminal.redraw()})});return g}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}function ScrollPanel(a){this.p anel=a}$.extend(ScrollPanel.prototype,{test:function(v,d){clearTimeout(this.timeout);var k=v.pageX,j=v.pageY,l=$(this.panel),c=l.position(),b=l.width(),i=l.height(),w=l.parent(),s=w.width(),a=w.height(),r=w.offset(),p=r.left,m=r.top,A=p+w.width(),u=m+w.height(),B=-(b-(s/2)),z=-(i-(a/2)),g=(s/2),f=(a/2),h=false,q=5,o=23;if(k-q<p){if(c.left<g){var n=Math.min(o,g-c.left);l.css("left",c.left+n);h=true}}else{if(k+q>A){if(c.left>B){var n=Math.min(o,c.left-B);l.css("left",c.left-n);h=true}}else{if(j-q<m){if(c.top<f){var n=Math.min(o,f-c.top);l.css("top",c.top+n);h=true}}else{if(j+q>u){if(c.top>z){var n=Math.min(o,c.top-B);l.css("top",(c.top-n)+"px");h=true}}}}}if(h){d();var l=this;this.timeout=setTimeout(function(){l.test(v,d)},50)}},stop:function(b,a){clearTimeout(this.timeout)}});function CanvasManager(b,a){this.cv=b;this.cc=this.cv.find("#canvas-container");this.oc=a.find("#overview-canvas");this.ov=a.find("#overview-viewport");this.init_drag()}$.extend(CanvasManager.prototype,{ init_drag:function(){var b=this;var a=function(f,g){f=Math.min(f,b.cv.width()/2);f=Math.max(f,-b.cc.width()+b.cv.width()/2);g=Math.min(g,b.cv.height()/2);g=Math.max(g,-b.cc.height()+b.cv.height()/2);b.cc.css({left:f,top:g});b.update_viewport_overlay()};this.cc.each(function(){this.scroll_panel=new ScrollPanel(this)});var d,c;this.cv.bind("dragstart",function(g){var h=$(this).offset();var f=b.cc.position();c=f.top-h.top;d=f.left-h.left}).bind("drag",function(f){a(f.offsetX+d,f.offsetY+c)}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});this.ov.bind("drag",function(k){var j=b.cc.width(),g=b.cc.height(),f=b.oc.width(),h=b.oc.height(),i=$(this).offsetParent().offset(),m=k.offsetX-i.left,l=k.offsetY-i.top;a(-(m/f*j),-(l/h*g))}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});$("#overview-border").bind("drag",function(g){var i=$(this).offsetParent();var h=i.offset();var f=Math.max(i.width()-(g.offsetX-h.left),i.height()-(g .offsetY-h.top));$(this).css({width:f,height:f});b.draw_overview()});$("#overview-border div").bind("drag",function(f){})},update_viewport_overlay:function(){var b=this.cc,f=this.cv,a=this.oc,c=this.ov,d=b.width(),j=b.height(),i=a.width(),g=a.height(),h=b.position();c.css({left:-(h.left/d*i),top:-(h.top/j*g),width:(f.width()/d*i)-2,height:(f.height()/j*g)-2})},draw_overview:function(){var j=$("#overview-canvas"),m=j.parent().parent().width(),i=j.get(0).getContext("2d"),d=$("#canvas-container").width(),l=$("#canvas-container").height();var g,a,k,f;var h=this.cv.width();var b=this.cv.height();if(d<h&&l<b){k=d/h*m;f=(m-k)/2;g=l/b*m;a=(m-g)/2}else{if(d<l){a=0;g=m;k=Math.ceil(g*d/l);f=(m-k)/2}else{k=m;f=0;g=Math.ceil(k*l/d);a=(m-g)/2}}j.parent().css({left:f,top:a,width:k,height:g});j.attr("width",k);j.attr("height",g);i.fillStyle="#D2C099";i.strokeStyle="#D8B365";i.lineWidth=1;$.each(workflow.nodes,function(t,q){var s=$(q.element),n=s.position(),c=n.left/d*k,r=n.top/l*g,o=s.width ()/d*k,p=s.height()/l*g;i.fillRect(c,r,o,p);i.strokeRect(c,r,o,p)});this.update_viewport_overlay()}}); +function Terminal(a){this.element=a;this.connectors=[]}$.extend(Terminal.prototype,{connect:function(a){this.connectors.push(a);if(this.node){this.node.changed()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.changed()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})}});function OutputTerminal(a,b){Terminal.call(this,a);this.datatypes=b}OutputTerminal.prototype=new Terminal();function InputTerminal(a,b){Terminal.call(this,a);this.datatypes=b}InputTerminal.prototype=new Terminal();$.extend(InputTerminal.prototype,{can_accept:function(a){if(this.connectors.length<1){for(var c in this.datatypes){for(var b in a.datatypes){if(a.datatypes[b]=="input"||issubtype(a.datatypes[b],this.datatypes[c])){return true}}}}return false}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_col or="#D8B365";if(b&&a){this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;this.handle1.connect(this);this.handle2=a;this.handle2.connect(this)},destroy:function(){if(this.handle1){this.handle1.disconnect(this)}if(this.handle2){this.handle2.disconnect(this)}$(this.canvas).remove()},redraw:function(){var d=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}d.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var n=function(c){return $(c).offset().left-d.offset().left};var i=function(c){return $(c).offset().top-d.offset().top};var h=n(this.handle1.element)+5;var g=i(this.handle1.element)+5;var p=n(this.handle2.element)+5;var m=i(this.handle2.element)+5;var f=100;var k=Math.min(h,p);var a=Math.max(h,p);var j=Math.min(g,m);var t=Math.max(g,m);var b=Math.min(Math.max(Math.abs(t-j)/2,100),300);var o=k-f;var s=j-f;var q=a -k+2*f;var l=t-j+2*f;this.canvas.style.left=o+"px";this.canvas.style.top=s+"px";this.canvas.setAttribute("width",q);this.canvas.setAttribute("height",l);h-=o;g-=s;p-=o;m-=s;var r=this.canvas.getContext("2d");r.lineCap="round";r.strokeStyle=this.outer_color;r.lineWidth=7;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke();r.strokeStyle=this.inner_color;r.lineWidth=5;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke()}});function Node(a){this.element=a;this.input_terminals={};this.output_terminals={};this.tool_errors={}}$.extend(Node.prototype,{enable_input_terminal:function(d,a,b){var c=this;$(d).each(function(){var f=this.terminal=new InputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dropstart",function(g){g.dragProxy.terminal.connectors[0].inner_color="#BBFFBB"}).bind("dropend",function(g){g.dragProxy.terminal.connectors[0].inner_color="#FFFFFF"}).bind("drop",function(g){(new Connector(g.dragTarget.terminal,g.dropTarget.terminal)) .redraw()}).bind("hover",function(){if(f.connectors.length>0){var g=$("<div class='callout'></div>").css({display:"none"}).appendTo("body").append($("<div class='buttons'></div>").append($("<img/>").attr("src",image_path+"/delete_icon.png").click(function(){$.each(f.connectors,function(i,h){h.destroy()});g.remove()}))).bind("mouseleave",function(){$(this).remove()});g.css({top:$(this).offset().top-2,left:$(this).offset().left-g.width(),"padding-right":$(this).width()}).show()}});c.input_terminals[a]=f})},enable_output_terminal:function(d,a,b){var c=this;$(d).each(function(){var g=this;var f=this.terminal=new OutputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dragstart",function(j){var i=$('<div class="drag-terminal" style="position: absolute;"></div>').appendTo("#canvas-container").get(0);i.terminal=new OutputTerminal(i);var k=new Connector();k.dragging=true;k.connect(this.terminal,i.terminal);$.dropManage({filter:function(h){return this.terminal.can_accept(f)}}).addClas s("input-terminal-active");return i}).bind("drag",function(i){var h=function(){var k=$(i.dragProxy).offsetParent().offset(),j=i.offsetX-k.left,l=i.offsetY-k.top;$(i.dragProxy).css({left:j,top:l});i.dragProxy.terminal.redraw();canvas_manager.update_viewport_overlay()};h();$("#canvas-container").get(0).scroll_panel.test(i,h)}).bind("dragend",function(h){h.dragProxy.terminal.connectors[0].destroy();$(h.dragProxy).remove();$.dropManage().removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()});c.output_terminals[a]=f})},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);( function(b){b.removeChild(a);b.appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(g){var d=this.element;if(g.type){this.type=g.type}this.name=g.name;this.form_html=g.form_html;this.tool_state=g.tool_state;this.tool_errors=g.tool_errors;this.tooltip=g.tooltip?g.tooltip:"";this.annotation=g.annotation;this.post_job_actions=g.post_job_actions;this.workflow_outputs=g.workflow_outputs;if(this.tool_errors){d.addClass("tool-node-error")}else{d.removeClass("tool-node-error")}var c=this;var a=d.find(".toolFormBody");a.find("div").remove();var h=$("<div class='inputs'></div>").appendTo(a);$.each(g.data_inputs,function(j,b){var f=$("<div class='terminal input-terminal'></div>");c.enable_input_terminal(f,b.name,b.extensions);h.append($("<div class='form-row dataRow input-data-row' name='"+b.name+"'>"+b.label+"</div>").prepend(f))});if((g.data_inputs.length>0)&&(g.data_outputs.length>0)){a.append($("<div class='rule'></div>"))}$.each(g.data_outpu ts,function(k,b){var j=$("<div class='terminal output-terminal'></div>");c.enable_output_terminal(j,b.name,b.extensions);var f=b.name;if(b.extensions.indexOf("input")<0){f=f+" ("+b.extensions+")"}a.append($("<div class='form-row dataRow'>"+f+"</div>").append(j))});workflow.node_changed(this)},update_field_data:function(f){var c=$(this.element),d=this;this.tool_state=f.tool_state;this.form_html=f.form_html;this.tool_errors=f.tool_errors;this.annotation=f.annotation;this.post_job_actions=$.parseJSON(f.post_job_actions);if(this.tool_errors){c.addClass("tool-node-error")}else{c.removeClass("tool-node-error")}var g=c.find("div.inputs");var b=$("<div class='inputs'></div>");var a=g.find("div.input-data-row");$.each(f.data_inputs,function(k,h){var j=$("<div class='terminal input-terminal'></div>");d.enable_input_terminal(j,h.name,h.extensions);g.find("div[name="+h.name+"]").each(function(){$(this).find(".input-terminal").each(function(){var i=this.terminal.connectors[0];if(i){j[0]. terminal.connectors[0]=i;i.handle2=j[0].terminal}});$(this).remove()});b.append($("<div class='form-row dataRow input-data-row' name='"+h.name+"'>"+h.label+"</div>").prepend(j))});g.replaceWith(b);g.find("div.input-data-row > .terminal").each(function(){this.terminal.destroy()});this.changed();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="<div style='color: red; text-style: italic;'>"+d+"</div>";this.form_html=c;a.html(c);workflow.node_changed(this)},changed:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false;this.active_form_has_changes=false}$.extend(Workflow.prototype,{add_node:function(a){a.id=this.id_counter;a.element.attr("id","wf-node-step-"+a.id);this.id_counter++;this.nodes[a.id]=a;this.has_changes=true;a.workflow=this},remove_node:function(a){if(this.active_node==a){this.clear_active_node()}delete this .nodes[a.id];this.has_changes=true},remove_all:function(){wf=this;$.each(this.nodes,function(b,a){a.destroy();wf.remove_node(a)})},to_simple:function(){var a={};$.each(this.nodes,function(c,f){var g={};$.each(f.input_terminals,function(h,i){g[i.name]=null;$.each(i.connectors,function(j,k){g[i.name]={id:k.handle1.node.id,output_name:k.handle1.name}})});var b={};if(f.post_job_actions){$.each(f.post_job_actions,function(j,h){var k={job_id:h.id,action_type:h.action_type,output_name:h.output_name,action_arguments:h.action_arguments};b[h.action_type+h.output_name]=null;b[h.action_type+h.output_name]=k})}if(!f.workflow_outputs){f.workflow_outputs=[]}var d={id:f.id,type:f.type,tool_id:f.tool_id,tool_state:f.tool_state,tool_errors:f.tool_errors,input_connections:g,position:$(f.element).position(),annotation:f.annotation,post_job_actions:f.post_job_actions,workflow_outputs:f.workflow_outputs};a[f.id]=d});return{steps:a}},from_simple:function(a){wf=this;var b=0;wf.name=a.name;$.each(a. steps,function(f,d){var c=prebuild_node("tool",d.name,d.tool_id);c.init_field_data(d);if(d.position){c.element.css({top:d.position.top,left:d.position.left})}c.id=d.id;wf.nodes[c.id]=c;b=Math.max(b,parseInt(f))});wf.id_counter=b+1;$.each(a.steps,function(f,d){var c=wf.nodes[f];$.each(d.input_connections,function(h,g){if(g){var i=wf.nodes[g.id];var j=new Connector();j.connect(i.output_terminals[g.output_name],c.input_terminals[h]);j.redraw()}})})},check_changes_in_active_form:function(){if(this.active_form_has_changes){this.has_changes=true;$("#right-content").find("form").submit();this.active_form_has_changes=false}},clear_active_node:function(){if(this.active_node){this.active_node.make_inactive();this.active_node=null}parent.show_form_for_tool("<div>No node selected</div>")},activate_node:function(a){if(this.active_node!=a){this.check_changes_in_active_form();this.clear_active_node();parent.show_form_for_tool(a.form_html+a.tooltip,a);a.make_active();this.active_node=a}},no de_changed:function(a){this.has_changes=true;if(this.active_node==a){this.check_changes_in_active_form();parent.show_form_for_tool(a.form_html+a.tooltip,a)}},layout:function(){this.check_changes_in_active_form();this.has_changes=true;var i={};var b={};$.each(this.nodes,function(l,k){if(i[l]===undefined){i[l]=0}if(b[l]===undefined){b[l]=[]}});$.each(this.nodes,function(l,k){$.each(k.input_terminals,function(m,n){$.each(n.connectors,function(p,q){var o=q.handle1.node;i[k.id]+=1;b[o.id].push(k.id)})})});node_ids_by_level=[];while(true){level_parents=[];for(var a in i){if(i[a]==0){level_parents.push(a)}}if(level_parents.length==0){break}node_ids_by_level.push(level_parents);for(var f in level_parents){var j=level_parents[f];delete i[j];for(var g in b[j]){i[b[j][g]]-=1}}}if(i.length){return}var d=this.nodes;var h=80;v_pad=30;var c=h;$.each(node_ids_by_level,function(k,l){l.sort(function(p,o){return $(d[p].element).position().top-$(d[o].element).position().top});var m=0;var n=v_pa d;$.each(l,function(o,r){var q=d[r];var p=$(q.element);$(p).css({top:n,left:c});m=Math.max(m,$(p).width());n+=$(p).height()+v_pad});c+=m+h});$.each(d,function(k,l){l.redraw()})},bounds_for_all_nodes:function(){var d=Infinity,b=-Infinity,c=Infinity,a=-Infinity,f;$.each(this.nodes,function(h,g){e=$(g.element);f=e.position();d=Math.min(d,f.left);b=Math.max(b,f.left+e.width());c=Math.min(c,f.top);a=Math.max(a,f.top+e.width())});return{xmin:d,xmax:b,ymin:c,ymax:a}},fit_canvas_to_nodes:function(){var a=this.bounds_for_all_nodes();var f=this.canvas_container.position();var i=this.canvas_container.parent();var d=fix_delta(a.xmin,100);var h=fix_delta(a.ymin,100);d=Math.max(d,f.left);h=Math.max(h,f.top);var c=f.left-d;var g=f.top-h;var b=round_up(a.xmax+100,100)+d;var j=round_up(a.ymax+100,100)+h;b=Math.max(b,-c+i.width());j=Math.max(j,-g+i.height());this.canvas_container.css({left:c,top:g,width:b,height:j});this.canvas_container.children().each(function(){var k=$(this).position();$(t his).css("left",k.left+d);$(this).css("top",k.top+h)})}});function fix_delta(a,b){if(a<b||a>3*b){new_pos=(Math.ceil(((a%b))/b)+1)*b;return(-(a-new_pos))}return 0}function round_up(a,b){return Math.ceil(a/b)*b}function prebuild_node(l,j,r){var i=$("<div class='toolForm toolFormInCanvas'></div>");var g=new Node(i);g.type=l;if(l=="tool"){g.tool_id=r}var n=$("<div class='toolFormTitle unselectable'>"+j+"</div>");i.append(n);i.css("left",$(window).scrollLeft()+20);i.css("top",$(window).scrollTop()+20);var m=$("<div class='toolFormBody'></div>");var h="<div><img height='16' align='middle' src='"+image_path+"/loading_small_white_bg.gif'/> loading tool info...</div>";m.append(h);g.form_html=h;i.append(m);var k=$("<div class='buttons' style='float: right;'></div>");k.append($("<img/>").attr("src",image_path+"/delete_icon.png").click(function(b){g.destroy()}).hover(function(){$(this).attr("src",image_path+"/delete_icon_dark.png")},function(){$(this).attr("src",image_path+"/delete_icon .png")}));i.appendTo("#canvas-container");var d=$("#canvas-container").position();var c=$("#canvas-container").parent();var a=i.width();var q=i.height();i.css({left:(-d.left)+(c.width()/2)-(a/2),top:(-d.top)+(c.height()/2)-(q/2)});k.prependTo(n);a+=(k.width()+10);i.css("width",a);$(i).bind("dragstart",function(){workflow.activate_node(g)}).bind("dragend",function(){workflow.node_changed(this);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview()}).bind("dragclickonly",function(){workflow.activate_node(g)}).bind("drag",function(o){var f=$(this).offsetParent().offset(),b=o.offsetX-f.left,p=o.offsetY-f.top;$(this).css({left:b,top:p});$(this).find(".terminal").each(function(){this.terminal.redraw()})});return g}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}function ScrollP anel(a){this.panel=a}$.extend(ScrollPanel.prototype,{test:function(v,d){clearTimeout(this.timeout);var k=v.pageX,j=v.pageY,l=$(this.panel),c=l.position(),b=l.width(),i=l.height(),w=l.parent(),s=w.width(),a=w.height(),r=w.offset(),p=r.left,m=r.top,A=p+w.width(),u=m+w.height(),B=-(b-(s/2)),z=-(i-(a/2)),g=(s/2),f=(a/2),h=false,q=5,o=23;if(k-q<p){if(c.left<g){var n=Math.min(o,g-c.left);l.css("left",c.left+n);h=true}}else{if(k+q>A){if(c.left>B){var n=Math.min(o,c.left-B);l.css("left",c.left-n);h=true}}else{if(j-q<m){if(c.top<f){var n=Math.min(o,f-c.top);l.css("top",c.top+n);h=true}}else{if(j+q>u){if(c.top>z){var n=Math.min(o,c.top-B);l.css("top",(c.top-n)+"px");h=true}}}}}if(h){d();var l=this;this.timeout=setTimeout(function(){l.test(v,d)},50)}},stop:function(b,a){clearTimeout(this.timeout)}});function CanvasManager(b,a){this.cv=b;this.cc=this.cv.find("#canvas-container");this.oc=a.find("#overview-canvas");this.ov=a.find("#overview-viewport");this.init_drag()}$.extend(CanvasManag er.prototype,{init_drag:function(){var b=this;var a=function(f,g){f=Math.min(f,b.cv.width()/2);f=Math.max(f,-b.cc.width()+b.cv.width()/2);g=Math.min(g,b.cv.height()/2);g=Math.max(g,-b.cc.height()+b.cv.height()/2);b.cc.css({left:f,top:g});b.update_viewport_overlay()};this.cc.each(function(){this.scroll_panel=new ScrollPanel(this)});var d,c;this.cv.bind("dragstart",function(g){var h=$(this).offset();var f=b.cc.position();c=f.top-h.top;d=f.left-h.left}).bind("drag",function(f){a(f.offsetX+d,f.offsetY+c)}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});this.ov.bind("drag",function(k){var j=b.cc.width(),g=b.cc.height(),f=b.oc.width(),h=b.oc.height(),i=$(this).offsetParent().offset(),m=k.offsetX-i.left,l=k.offsetY-i.top;a(-(m/f*j),-(l/h*g))}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});$("#overview-border").bind("drag",function(g){var i=$(this).offsetParent();var h=i.offset();var f=Math.max(i.width()-(g.offsetX-h.left) ,i.height()-(g.offsetY-h.top));$(this).css({width:f,height:f});b.draw_overview()});$("#overview-border div").bind("drag",function(f){})},update_viewport_overlay:function(){var b=this.cc,f=this.cv,a=this.oc,c=this.ov,d=b.width(),j=b.height(),i=a.width(),g=a.height(),h=b.position();c.css({left:-(h.left/d*i),top:-(h.top/j*g),width:(f.width()/d*i)-2,height:(f.height()/j*g)-2})},draw_overview:function(){var j=$("#overview-canvas"),m=j.parent().parent().width(),i=j.get(0).getContext("2d"),d=$("#canvas-container").width(),l=$("#canvas-container").height();var g,a,k,f;var h=this.cv.width();var b=this.cv.height();if(d<h&&l<b){k=d/h*m;f=(m-k)/2;g=l/b*m;a=(m-g)/2}else{if(d<l){a=0;g=m;k=Math.ceil(g*d/l);f=(m-k)/2}else{k=m;f=0;g=Math.ceil(k*l/d);a=(m-g)/2}}j.parent().css({left:f,top:a,width:k,height:g});j.attr("width",k);j.attr("height",g);i.fillStyle="#D2C099";i.strokeStyle="#D8B365";i.lineWidth=1;$.each(workflow.nodes,function(t,q){var s=$(q.element),n=s.position(),c=n.left/d*k,r=n.top /l*g,o=s.width()/d*k,p=s.height()/l*g;i.fillRect(c,r,o,p);i.strokeRect(c,r,o,p)});this.update_viewport_overlay()}}); --- a/static/scripts/packed/trackster.js +++ b/static/scripts/packed/trackster.js @@ -1,1 +1,1 @@ -var DENSITY=200,FEATURE_LEVELS=10,DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),PX_PER_CHAR=CONTEXT.measureText("A").width,RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/strand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONT EXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,c,e,d,b){this.container=a;this.vis_id=d;this.dbkey=b;this.title=e;this.chrom=c;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this .has_changes=false;this.init();this.reset()};$.extend(View.prototype,{init:function(){var b=this.container,a=this;this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(b);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(b);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide().appendTo(b);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.nav_container=$("<div/>").addClass("nav-container").appendTo(b);this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.nav);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_o verview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){void (0)}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keypress",function(c){if((c.keyCode||c.which)===13){a.go_to($(this).val());$(this).hide();return false}}).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.goto_link=$("<a/>").click(function(){a.nav_input.toggle();a.nav_input.focus()}).html('<img src="'+image_path+'/fugue/navigation.png" />').appendTo(this.chrom_form);this.zo_link=$("<a/>").click(function() {a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);this.zi_link=$("<a/>").click(function(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(c){if(c.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=c.chrom_info;var e='<option value="">Select Chrom/Contig</option>';for(i in a.chrom_data){var d=a.chrom_data[i]["chrom"];e+='<option value="'+d+'">'+d+"</option>"}a.chrom_select.html(e);a.intro_div.show();a.content_div.hide();a.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())})},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("dblclick",function(c){a.zoom_in(c.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(c){ this.current_x=c.offsetX}).bind("drag",function(c){var f=c.offsetX-this.current_x;this.current_x=c.offsetX;var d=Math.round(f/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-d)});this.viewport_container.bind("dragstart",function(c){this.original_low=a.low;this.current_height=c.clientY;this.current_x=c.offsetX;this.active=(c.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(f){if(!this.active){return}var c=$(this);var h=f.offsetX-this.current_x;var d=c.scrollTop()-(f.clientY-this.current_height);c.scrollTop(d);this.current_height=f.clientY;this.current_x=f.offsetX;var g=Math.round(h/a.viewport_container.width()*(a.high-a.low));a.move_delta(g)});this.top_labeltrack.bind("dragstart",function(c){this.drag_origin_x=c.clientX;this.drag_origin_pos=c.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_div=$("<div />").css({height:a.content_div.height(),top:"0px",position:"absolute","background-color":"#cfc",border:"1px soli d #6a6",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(h){var d=Math.min(h.clientX,this.drag_origin_x)-a.container.offset().left,c=Math.max(h.clientX,this.drag_origin_x)-a.container.offset().left,g=(a.high-a.low),f=a.viewport_container.width();a.update_location(Math.round(d/f*g)+a.low,Math.round(c/f*g)+a.low);this.drag_div.css({left:d+"px",width:(c-d)+"px"})}).bind("dragend",function(j){var d=Math.min(j.clientX,this.drag_origin_x),c=Math.max(j.clientX,this.drag_origin_x),g=(a.high-a.low),f=a.viewport_container.width(),h=a.low;a.low=Math.round(d/f*g)+h;a.high=Math.round(c/f*g)+h;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack))},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(d,a,f){var c=this;var e=$.grep(c.chrom_data ,function(h,j){return h.chrom===d})[0];if(e===undefined){return}c.chrom=d;if(c.chrom===""){c.intro_div.show();c.content_div.hide()}else{c.intro_div.hide();c.content_div.show()}c.chrom_select.val(c.chrom);c.max_high=e.len;c.reset();c.redraw(true);for(var g in c.tracks){var b=c.tracks[g];if(b.init){b.init()}}if(a!==undefined&&f!==undefined){c.low=Math.max(a,0);c.high=Math.min(f,c.max_high)}c.overview_viewport.find("canvas").remove();c.redraw()},go_to:function(f){var k=this,b=f.split(":"),h=b[0],j=b[1];if(j!==undefined){try{var g=j.split("-"),a=parseInt(g[0].replace(/,/g,"")),d=parseInt(g[1].replace(/,/g,""))}catch(c){return false}}k.change_chrom(h,a,d)},move_delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.high-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.contain er_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},update_options:function(){this.has_changes=true;var b=$("ul#sortable-ul").sortable("toArray");for(var c in b){var e=b[c].split("_li")[0].split("track_")[1];this.viewport.append($("#track_"+e))}for(var d in view.tracks){var a=view.tracks[d];if(a&&a.update_options){a.update_options(d)}}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(f){var d=this.high-this.low,b=this.low,e=this.high;if(b<this.max_low){b=this.max_low}if(e>this.max_high){e=this.max_high}if(this.high!==0&&d<this.min_separation){e=b+this.min_separation}this.low=Math.floor(b);this.high=Math.ceil(e);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))));this.overview_box.css({left:(this.low/(this.max_high-this.max_low))*this.overview_viewport.width(),width:Math.max(12,(this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())}).show();this.update_location(this.low,this.high);if(!f){for(var c=0,a=this.tracks.length;c<a;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,a=this.label_tracks.length;c<a;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b= this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()}});var Track=function(b,a,c){this.name=b;this.parent_element=c;this.view=a;this.init_global()};$.extend(Track.prototype,{init_global:function(){this.header_div=$("<div class='track-header'>").text(this.name);this.content_div=$("<div class='track-content'>");this.container_div=$("<div />").addClass("track").append(this.header_div).append(this.content_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.vie w.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){var c=this,b=c.view;if(c.display_modes!==undefined){if(c.mode_div===undefined){c.mode_div=$("<div class='right-float menubutton popup' />").appendTo(c.header_di v);var g=c.display_modes[0];c.mode=g;c.mode_div.text(g);var a=function(h){c.mode_div.text(h);c.mode=h;c.tile_cache.clear();c.draw()};var e={};for(var d in c.display_modes){var f=c.display_modes[d];e[f]=function(h){return function(){a(h)}}(f)}make_popupmenu(c.mode_div,e)}else{c.mode_div.hide()}}if(c.overview_check_div===undefined){c.overview_check_div=$("<div class='right-float' />").css("margin-top","-3px").appendTo(c.header_div);c.overview_check=$("<input type='checkbox' class='overview_check' />").appendTo(c.overview_check_div);c.overview_check.bind("click",function(){var h=this;b.overview_viewport.find("canvas").remove();c.set_overview();$(".overview_check").each(function(){if(this!==h){$(this).attr("checked",false)}})});c.overview_check_div.append($("<label />").text("Overview"))}};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(){var j=this.view.low,e=this.view.high,f=e-j,d=this.view.resolution;var l=$("<div style='position: relative;'></div>"),m=this.conte nt_div.width()/f,h;this.content_div.children(":first").remove();this.content_div.append(l),this.max_height=0;var a=Math.floor(j/d/DENSITY);while((a*DENSITY*d)<e){var k=this.content_div.width()+"_"+m+"_"+a;var c=this.tile_cache.get(k);if(c){var g=a*DENSITY*d;var b=(g-j)*m;if(this.left_offset){b-=this.left_offset}c.css({left:b});l.append(c);this.max_height=Math.max(this.max_height,c.height());this.content_div.css("height",this.max_height+"px")}else{this.delayed_draw(this,k,j,e,a,d,l,m)}a+=1}},delayed_draw:function(c,e,a,f,b,d,g,h){setTimeout(function(){if(!(a>c.view.high||f<c.view.low)){tile_element=c.draw_tile(d,b,g,h);if(tile_element){if(!c.initial_canvas){c.initial_canvas=$(tile_element).clone();var l=tile_element.get(0).getContext("2d");var j=c.initial_canvas.get(0).getContext("2d");var k=l.getImageData(0,0,l.canvas.width,l.canvas.height);j.putImageData(k,0,0);c.set_overview()}c.tile_cache.set(e,tile_element);c.max_height=Math.max(c.max_height,tile_element.height());c.cont ent_div.css("height",c.max_height+"px")}}},50)},set_overview:function(){var a=this.view;a.overview_viewport.height(a.default_overview_height);a.overview_box.height(a.default_overview_height);if(this.overview_check.is(":checked")){a.overview_viewport.append(this.initial_canvas);a.overview_viewport.height(this.initial_canvas.height());a.overview_box.height(this.initial_canvas.height())}$(window).trigger("resize")}});var LabelTrack=function(a,b){Track.call(this,null,a,b);this.track_type="LabelTrack";this.hidden=true;this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.chil dren(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.hidden=true;this.height_px=12;this.container_div.addClass("reference-track");this.dummy_canvas=$("<canvas></canvas>").get(0).getContext("2d");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.prototype,{get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(f,b,k,o){var g=b*DENSITY*f,d=DENSITY*f,e=$("<canvas class='tile'></canvas>"),n=e.get(0).getContext("2d"),j=f+"_"+b;if(o>PX_PER_CHAR){if(t his.data_cache.get(j)===undefined){this.get_data(f,b);return}var m=this.data_cache.get(j);if(m===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*o+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*o-this.left_offset});for(var h=0,l=m.length;h<l;h++){var a=Math.round(h*o);n.fillText(m[h],a+this.left_offset,10)}k.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=function(d,b,a,c){this.track_type="LineTrack";this.display_modes=["Line","Filled","Intensity"];this.mode="Line";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=80;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={min_value:undefined,max_value:undefined,mode:"Line"};if(c.min_value!==undefined){this.prefs.min_value=c.min_value}if(c.max_value!==undefined){this.prefs.max_value=c.max_value}};$.extend(LineTrack.prototype,Tiled Track.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;$("#linetrack_"+b+"_minval").remove();$("#linetrack_"+b+"_maxval").remove();var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"relative",top:"32px",left:"10px"});d.prependTo(a.container_div);e.css({position:"relative",top:a .height_px+32+"px",left:"10px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(p,r,c,e){if(this.vertical_range===undefined){return}var s=r*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),v=p+"_"+r;if(this.data_cache.get(v)===undefined){this.get_data(p,r);return}var j=this.data_cache.get(v);if(j===null){return}b.css({position:"absolute",top:0,left:(s-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,t=this.total_frequency,d=this.height_px, m=this.mode;o.beginPath();if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}var u,h;for(var q=0;q<data.length;q++){u=(data[q][0]-s)*e;h=data[q][1];if(m=="Intensity"){if(h===null){continue}if(h<=l){h=l}else{if(h>=g){h=g}}h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")";o.fillRect(u,0,f,this.height_px)}else{if(h===null){if(k&&m==="Filled"){o.lineTo(u,d)}k=false;continue}else{if(h<=l){h=l}else{if(h>=g){h=g}}h=Math.round(d-(h-l)/n*d);if(k){o.lineTo(u,h)}else{k=true;if(m==="Filled"){o.moveTo(u,d);o.lineTo(u,h)}else{o.moveTo(u,h)}}}}}if(m==="Filled"){if(k){o.lineTo(u,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(k){var a=$("<div />").addClass("form-row");var e="track_"+k+"_minval",h=$("<label></label>").attr("for",e).text("Min value:"),b=(this.prefs.min_value===undefined?"":this.prefs.min_value),j=$("<input></input>").attr("id",e).val(b),g="track_"+k+"_maxval",d=$("<label></label>").attr("for",g).text("Max value:" ),f=(this.prefs.max_value===undefined?"":this.prefs.max_value),c=$("<input></input>").attr("id",g).val(f);return a.append(h).append(j).append(d).append(c)},update_options:function(c){var a=$("#track_"+c+"_minval").val(),b=$("#track_"+c+"_maxval").val();if(a!==this.prefs.min_value||b!==this.prefs.max_value){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(b);this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+c+"_minval").text(this.prefs.min_value);$("#linetrack_"+c+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,c){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=2;this.su mmary_draw_height=20;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.left_offset=200;this.prefs={block_color:"black",label_color:"black",show_counts:true};if(c.block_color!==undefined){this.prefs.block_color=c.block_color}if(c.label_color!==undefined){this.prefs.label_color=c.label_color}if(c.show_counts!==undefined){this.prefs.show_counts=c.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b="initial";this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution},function(c){a.mode_div.show();a.data_cache.set(b,c);a.draw()})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolutio n,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=1/a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(this.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.measureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(true){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_tile[a][v].length;u<A;u+ +){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=[]}this.s_e_by_tile[a][v].push([e,f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(n,o,f,m,b,d,k,e,h){n.textAlign="center";var j=Math.round(o/2);if((this.mode==="Pack"||this.mode==="Auto")&&d!==undefined&&o>PX_PER_CHAR){n.fillStyle=this.prefs.block_color;n.fillRect(k,h+1,e,9);n.fillStyle="#eee";for(var g=0,l=d.length;g<l;g++){if(b+g>=f&&b+g<=m){var a=Math.floor(Math.max(0,(b+g-f)*o));n.fillText(d[g],a+this.left_offset+j,h+9)}}}else{n.fillStyle=this.prefs.block_color;n.fillRect(k,h+4,e,3)}},draw_tile:function(Y,l,o,al){var F=l*DENSITY*Y,ae=(l+1)*DENSITY*Y,E=ae-F;var af=(!this.initial_canvas?"initial":F+"_"+ae);var A=this.data_cache.get(af);var d;if(A===undefined){this.data_queue[[F,ae]]=true;this.get_data(F,ae);return}var a=Math.ceil(E*al),M=$("<canvas class='tile'></canvas>"),aa=this.prefs.label_color,g =this.prefs.block_color,n=this.mode,W=(n==="Squish")||(n==="Dense")&&(n!=="Pack")||(n==="Auto"&&(A.extra_info==="no_detail")),Q=this.left_offset,ak,t,am;if(A.dataset_type==="summary_tree"){t=this.summary_draw_height}else{if(n==="Dense"){t=15;am=10}else{am=(W?this.vertical_nodetail_px:this.vertical_detail_px);t=this.incremental_slots(this.view.zoom_res,A.data,W,n)*am+15;ak=this.inc_slots[this.view.zoom_res]}}M.css({position:"absolute",top:0,left:(F-this.view.low)*al-Q});M.get(0).width=a+Q;M.get(0).height=t;o.parent().css("height",Math.max(this.height_px,t)+"px");var B=M.get(0).getContext("2d");B.fillStyle=g;B.font=this.default_font;B.textAlign="right";if(A.dataset_type=="summary_tree"){var L,I=55,ad=255-I,h=ad*2/3,S=A.data,D=A.max,m=A.avg,b=Math.ceil(A.delta*al);for(var ah=0,z=S.length;ah<z;ah++){var U=Math.floor((S[ah][0]-F)*al);var T=S[ah][1];if(!T){continue}L=Math.floor(ad-(T/D)*ad);B.fillStyle="rgb("+L+","+L+","+L+")";B.fillRect(U+Q,0,b,this.summary_draw_height);if(this.p refs.show_counts&&B.measureText(T).width<b){if(L>h){B.fillStyle="black"}else{B.fillStyle="#ddd"}B.textAlign="center";B.fillText(T,U+Q+(b/2),12)}}d="Summary";o.append(M);return M}var aj=A.data;var ag=0;for(var ah=0,z=aj.length;ah<z;ah++){var N=aj[ah],K=N[0],ai=N[1],V=N[2],G=N[3];if(ai<=ae&&V>=F){var X=Math.floor(Math.max(0,(ai-F)*al)),C=Math.ceil(Math.min(a,Math.max(0,(V-F)*al))),R=(n==="Dense"?0:ak[K]*am);if(A.dataset_type==="bai"){B.fillStyle=g;if(N[4] instanceof Array){var u=Math.floor(Math.max(0,(N[4][0]-F)*al)),J=Math.ceil(Math.min(a,Math.max(0,(N[4][1]-F)*al))),s=Math.floor(Math.max(0,(N[5][0]-F)*al)),q=Math.ceil(Math.min(a,Math.max(0,(N[5][1]-F)*al)));if(N[4][1]>=F&&N[4][0]<=ae){this.rect_or_text(B,al,F,ae,N[4][0],N[4][2],u+Q,J-u,R)}if(N[5][1]>=F&&N[5][0]<=ae){this.rect_or_text(B,al,F,ae,N[5][0],N[5][2],s+Q,q-s,R)}if(s>J){B.fillStyle="#999";B.fillRect(J+Q,R+5,s-J,1)}}else{B.fillStyle=g;this.rect_or_text(B,al,F,ae,ai,G,X+Q,C-X,R)}if(n!=="Dense"&&!W&&ai>F){B.fillStyle=th is.prefs.label_color;if(l===0&&X-B.measureText(G).width<0){B.textAlign="left";B.fillText(K,C+2+Q,R+8)}else{B.textAlign="right";B.fillText(K,X-2+Q,R+8)}B.fillStyle=g}}else{if(A.dataset_type==="interval_index"){if(W){B.fillRect(X+Q,R+5,C-X,1)}else{var w=N[4],P=N[5],Z=N[6],f=N[7];var v,ab,H=null,an=null;if(P&&Z){H=Math.floor(Math.max(0,(P-F)*al));an=Math.ceil(Math.min(a,Math.max(0,(Z-F)*al)))}if(n!=="Dense"&&G!==undefined&&ai>F){B.fillStyle=aa;if(l===0&&X-B.measureText(G).width<0){B.textAlign="left";B.fillText(G,C+2+Q,R+8)}else{B.textAlign="right";B.fillText(G,X-2+Q,R+8)}B.fillStyle=g}if(f){if(w){if(w=="+"){B.fillStyle=RIGHT_STRAND}else{if(w=="-"){B.fillStyle=LEFT_STRAND}}B.fillRect(X+Q,R,C-X,10);B.fillStyle=g}for(var af=0,e=f.length;af<e;af++){var p=f[af],c=Math.floor(Math.max(0,(p[0]-F)*al)),O=Math.ceil(Math.min(a,Math.max((p[1]-F)*al)));if(c>O){continue}v=5;ab=3;B.fillRect(c+Q,R+ab,O-c,v);if(H!==undefined&&!(c>an||O<H)){v=9;ab=1;var ac=Math.max(c,H),r=Math.min(O,an);B.fillRe ct(ac+Q,R+ab,r-ac,v)}}}else{v=9;ab=1;B.fillRect(X+Q,R+ab,C-X,v);if(N.strand){if(N.strand=="+"){B.fillStyle=RIGHT_STRAND_INV}else{if(N.strand=="-"){B.fillStyle=LEFT_STRAND_INV}}B.fillRect(X+Q,R,C-X,10);B.fillStyle=prefs.block_color}}}}}ag++}}o.append(M);return M},gen_options:function(j){var a=$("<div />").addClass("form-row");var e="track_"+j+"_block_color",l=$("<label />").attr("for",e).text("Block color:"),m=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),k="track_"+j+"_label_color",g=$("<label />").attr("for",k).text("Text color:"),h=$("<input />").attr("id",k).attr("name",k).val(this.prefs.label_color),f="track_"+j+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(l).append(m).append(g).append(h).append(d)},update_options:function(e){var b=$("#track_"+e +"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,c){FeatureTrack.call(this,d,b,a,c);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{}); +var DENSITY=200,FEATURE_LEVELS=10,DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),PX_PER_CHAR=CONTEXT.measureText("A").width,RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/strand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONT EXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,c,e,d,b){this.container=a;this.vis_id=d;this.dbkey=b;this.title=e;this.chrom=c;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this .has_changes=false;this.init();this.reset()};$.extend(View.prototype,{init:function(){var b=this.container,a=this;this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(b);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(b);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide().appendTo(b);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.nav_container=$("<div/>").addClass("nav-container").appendTo(b);this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.nav);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_o verview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){void (0)}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keypress",function(c){if((c.keyCode||c.which)===13){a.go_to($(this).val());$(this).hide();return false}}).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.goto_link=$("<a/>").click(function(){a.nav_input.toggle();a.nav_input.focus()}).html('<img src="'+image_path+'/fugue/navigation.png" />').appendTo(this.chrom_form);this.zo_link=$("<a/>").click(function() {a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);this.zi_link=$("<a/>").click(function(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(c){if(c.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=c.chrom_info;var e='<option value="">Select Chrom/Contig</option>';for(i in a.chrom_data){var d=a.chrom_data[i]["chrom"];e+='<option value="'+d+'">'+d+"</option>"}a.chrom_select.html(e);a.intro_div.show();a.content_div.hide();a.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())})},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("dblclick",function(c){a.zoom_in(c.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(c){ this.current_x=c.offsetX}).bind("drag",function(c){var f=c.offsetX-this.current_x;this.current_x=c.offsetX;var d=Math.round(f/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-d)});this.viewport_container.bind("dragstart",function(c){this.original_low=a.low;this.current_height=c.clientY;this.current_x=c.offsetX;this.active=(c.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(f){if(!this.active){return}var c=$(this);var h=f.offsetX-this.current_x;var d=c.scrollTop()-(f.clientY-this.current_height);c.scrollTop(d);this.current_height=f.clientY;this.current_x=f.offsetX;var g=Math.round(h/a.viewport_container.width()*(a.high-a.low));a.move_delta(g)});this.top_labeltrack.bind("dragstart",function(c){this.drag_origin_x=c.clientX;this.drag_origin_pos=c.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_div=$("<div />").css({height:a.content_div.height(),top:"0px",position:"absolute","background-color":"#cfc",border:"1px soli d #6a6",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(h){var d=Math.min(h.clientX,this.drag_origin_x)-a.container.offset().left,c=Math.max(h.clientX,this.drag_origin_x)-a.container.offset().left,g=(a.high-a.low),f=a.viewport_container.width();a.update_location(Math.round(d/f*g)+a.low,Math.round(c/f*g)+a.low);this.drag_div.css({left:d+"px",width:(c-d)+"px"})}).bind("dragend",function(j){var d=Math.min(j.clientX,this.drag_origin_x),c=Math.max(j.clientX,this.drag_origin_x),g=(a.high-a.low),f=a.viewport_container.width(),h=a.low;a.low=Math.round(d/f*g)+h;a.high=Math.round(c/f*g)+h;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack))},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(d,a,f){var c=this;var e=$.grep(c.chrom_data ,function(h,j){return h.chrom===d})[0];if(e===undefined){return}c.chrom=d;if(c.chrom===""){c.intro_div.show();c.content_div.hide()}else{c.intro_div.hide();c.content_div.show()}c.chrom_select.val(c.chrom);c.max_high=e.len;c.reset();c.redraw(true);for(var g in c.tracks){var b=c.tracks[g];if(b.init){b.init()}}if(a!==undefined&&f!==undefined){c.low=Math.max(a,0);c.high=Math.min(f,c.max_high)}c.overview_viewport.find("canvas").remove();c.redraw()},go_to:function(f){var k=this,b=f.split(":"),h=b[0],j=b[1];if(j!==undefined){try{var g=j.split("-"),a=parseInt(g[0].replace(/,/g,"")),d=parseInt(g[1].replace(/,/g,""))}catch(c){return false}}k.change_chrom(h,a,d)},move_delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.high-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.contain er_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},update_options:function(){this.has_changes=true;var b=$("ul#sortable-ul").sortable("toArray");for(var c in b){var e=b[c].split("_li")[0].split("track_")[1];this.viewport.append($("#track_"+e))}for(var d in view.tracks){var a=view.tracks[d];if(a&&a.update_options){a.update_options(d)}}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(f){var d=this.high-this.low,b=this.low,e=this.high;if(b<this.max_low){b=this.max_low}if(e>this.max_high){e=this.max_high}if(this.high!==0&&d<this.min_separation){e=b+this.min_separation}this.low=Math.floor(b);this.high=Math.ceil(e);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))));this.overview_box.css({left:(this.low/(this.max_high-this.max_low))*this.overview_viewport.width(),width:Math.max(12,(this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())}).show();this.update_location(this.low,this.high);if(!f){for(var c=0,a=this.tracks.length;c<a;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,a=this.label_tracks.length;c<a;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b= this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()}});var Track=function(b,a,c){this.name=b;this.parent_element=c;this.view=a;this.init_global()};$.extend(Track.prototype,{init_global:function(){this.header_div=$("<div class='track-header'>").text(this.name);this.content_div=$("<div class='track-content'>");this.container_div=$("<div />").addClass("track").append(this.header_div).append(this.content_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.vie w.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){var c=this,b=c.view;if(c.display_modes!==undefined){if(c.mode_div===undefined){c.mode_div=$("<div class='right-float menubutton popup' />").appendTo(c.header_di v);var g=c.display_modes[0];c.mode=g;c.mode_div.text(g);var a=function(h){c.mode_div.text(h);c.mode=h;c.tile_cache.clear();c.draw()};var e={};for(var d in c.display_modes){var f=c.display_modes[d];e[f]=function(h){return function(){a(h)}}(f)}make_popupmenu(c.mode_div,e)}else{c.mode_div.hide()}}if(c.overview_check_div===undefined){c.overview_check_div=$("<div class='right-float' />").css("margin-top","-3px").appendTo(c.header_div);c.overview_check=$("<input type='checkbox' class='overview_check' />").appendTo(c.overview_check_div);c.overview_check.bind("click",function(){var h=this;b.overview_viewport.find("canvas").remove();c.set_overview();$(".overview_check").each(function(){if(this!==h){$(this).attr("checked",false)}})});c.overview_check_div.append($("<label />").text("Overview"))}};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(){var j=this.view.low,e=this.view.high,f=e-j,d=this.view.resolution;var l=$("<div style='position: relative;'></div>"),m=this.conte nt_div.width()/f,h;this.content_div.children(":first").remove();this.content_div.append(l),this.max_height=0;var a=Math.floor(j/d/DENSITY);while((a*DENSITY*d)<e){var k=this.content_div.width()+"_"+m+"_"+a;var c=this.tile_cache.get(k);if(c){var g=a*DENSITY*d;var b=(g-j)*m;if(this.left_offset){b-=this.left_offset}c.css({left:b});l.append(c);this.max_height=Math.max(this.max_height,c.height());this.content_div.css("height",this.max_height+"px")}else{this.delayed_draw(this,k,j,e,a,d,l,m)}a+=1}},delayed_draw:function(c,e,a,f,b,d,g,h){setTimeout(function(){if(!(a>c.view.high||f<c.view.low)){tile_element=c.draw_tile(d,b,g,h);if(tile_element){if(!c.initial_canvas){c.initial_canvas=$(tile_element).clone();var l=tile_element.get(0).getContext("2d");var j=c.initial_canvas.get(0).getContext("2d");var k=l.getImageData(0,0,l.canvas.width,l.canvas.height);j.putImageData(k,0,0);c.set_overview()}c.tile_cache.set(e,tile_element);c.max_height=Math.max(c.max_height,tile_element.height());c.cont ent_div.css("height",c.max_height+"px")}}},50)},set_overview:function(){var a=this.view;a.overview_viewport.height(a.default_overview_height);a.overview_box.height(a.default_overview_height);if(this.initial_canvas&&this.overview_check.is(":checked")){a.overview_viewport.append(this.initial_canvas);a.overview_viewport.height(this.initial_canvas.height());a.overview_box.height(this.initial_canvas.height())}$(window).trigger("resize")}});var LabelTrack=function(a,b){Track.call(this,null,a,b);this.track_type="LabelTrack";this.hidden=true;this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g} this.content_div.children(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.hidden=true;this.height_px=12;this.container_div.addClass("reference-track");this.dummy_canvas=$("<canvas></canvas>").get(0).getContext("2d");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.prototype,{get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(f,b,k,o){var g=b*DENSITY*f,d=DENSITY*f,e=$("<canvas class='tile'></canvas>"),n=e.get(0).getContext("2d"),j=f+"_"+b;i f(o>PX_PER_CHAR){if(this.data_cache.get(j)===undefined){this.get_data(f,b);return}var m=this.data_cache.get(j);if(m===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*o+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*o-this.left_offset});for(var h=0,l=m.length;h<l;h++){var a=Math.round(h*o);n.fillText(m[h],a+this.left_offset,10)}k.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=function(d,b,a,c){this.track_type="LineTrack";this.display_modes=["Line","Filled","Intensity"];this.mode="Line";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=80;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={min_value:undefined,max_value:undefined,mode:"Line"};if(c.min_value!==undefined){this.prefs.min_value=c.min_value}if(c.max_value!==undefined){this.prefs.max_value=c.max_value}};$.extend(Line Track.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;$("#linetrack_"+b+"_minval").remove();$("#linetrack_"+b+"_maxval").remove();var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"relative",top:"32px",left:"10px"});d.prependTo(a.container_div);e.css({posi tion:"relative",top:a.height_px+32+"px",left:"10px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(p,r,c,e){if(this.vertical_range===undefined){return}var s=r*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),v=p+"_"+r;if(this.data_cache.get(v)===undefined){this.get_data(p,r);return}var j=this.data_cache.get(v);if(j===null){return}b.css({position:"absolute",top:0,left:(s-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,t=this.total_freque ncy,d=this.height_px,m=this.mode;o.beginPath();if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}var u,h;for(var q=0;q<data.length;q++){u=(data[q][0]-s)*e;h=data[q][1];if(m=="Intensity"){if(h===null){continue}if(h<=l){h=l}else{if(h>=g){h=g}}h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")";o.fillRect(u,0,f,this.height_px)}else{if(h===null){if(k&&m==="Filled"){o.lineTo(u,d)}k=false;continue}else{if(h<=l){h=l}else{if(h>=g){h=g}}h=Math.round(d-(h-l)/n*d);if(k){o.lineTo(u,h)}else{k=true;if(m==="Filled"){o.moveTo(u,d);o.lineTo(u,h)}else{o.moveTo(u,h)}}}}}if(m==="Filled"){if(k){o.lineTo(u,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(k){var a=$("<div />").addClass("form-row");var e="track_"+k+"_minval",h=$("<label></label>").attr("for",e).text("Min value:"),b=(this.prefs.min_value===undefined?"":this.prefs.min_value),j=$("<input></input>").attr("id",e).val(b),g="track_"+k+"_maxval",d=$("<label></label>").attr("for" ,g).text("Max value:"),f=(this.prefs.max_value===undefined?"":this.prefs.max_value),c=$("<input></input>").attr("id",g).val(f);return a.append(h).append(j).append(d).append(c)},update_options:function(c){var a=$("#track_"+c+"_minval").val(),b=$("#track_"+c+"_maxval").val();if(a!==this.prefs.min_value||b!==this.prefs.max_value){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(b);this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+c+"_minval").text(this.prefs.min_value);$("#linetrack_"+c+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,c){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_ nodetail_px=2;this.summary_draw_height=20;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.left_offset=200;this.prefs={block_color:"black",label_color:"black",show_counts:true};if(c.block_color!==undefined){this.prefs.block_color=c.block_color}if(c.label_color!==undefined){this.prefs.label_color=c.label_color}if(c.show_counts!==undefined){this.prefs.show_counts=c.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b="initial";this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution},function(c){a.mode_div.show();a.data_cache.set(b,c);a.draw()})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolutio n:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=1/a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(this.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.measureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(true){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_til e[a][v].length;u<A;u++){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=[]}this.s_e_by_tile[a][v].push([e,f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(n,o,f,m,b,d,k,e,h){n.textAlign="center";var j=Math.round(o/2);if((this.mode==="Pack"||this.mode==="Auto")&&d!==undefined&&o>PX_PER_CHAR){n.fillStyle=this.prefs.block_color;n.fillRect(k,h+1,e,9);n.fillStyle="#eee";for(var g=0,l=d.length;g<l;g++){if(b+g>=f&&b+g<=m){var a=Math.floor(Math.max(0,(b+g-f)*o));n.fillText(d[g],a+this.left_offset+j,h+9)}}}else{n.fillStyle=this.prefs.block_color;n.fillRect(k,h+4,e,3)}},draw_tile:function(Y,l,o,al){var F=l*DENSITY*Y,ae=(l+1)*DENSITY*Y,E=ae-F;var af=(!this.initial_canvas?"initial":F+"_"+ae);var A=this.data_cache.get(af);var d;if(A===undefined){this.data_queue[[F,ae]]=true;this.get_data(F,ae);return}var a=Math.ceil(E*al),M=$("<canvas class='tile'></canvas>"),aa=thi s.prefs.label_color,g=this.prefs.block_color,n=this.mode,W=(n==="Squish")||(n==="Dense")&&(n!=="Pack")||(n==="Auto"&&(A.extra_info==="no_detail")),Q=this.left_offset,ak,t,am;if(A.dataset_type==="summary_tree"){t=this.summary_draw_height}else{if(n==="Dense"){t=15;am=10}else{am=(W?this.vertical_nodetail_px:this.vertical_detail_px);t=this.incremental_slots(this.view.zoom_res,A.data,W,n)*am+15;ak=this.inc_slots[this.view.zoom_res]}}M.css({position:"absolute",top:0,left:(F-this.view.low)*al-Q});M.get(0).width=a+Q;M.get(0).height=t;o.parent().css("height",Math.max(this.height_px,t)+"px");var B=M.get(0).getContext("2d");B.fillStyle=g;B.font=this.default_font;B.textAlign="right";if(A.dataset_type=="summary_tree"){var L,I=55,ad=255-I,h=ad*2/3,S=A.data,D=A.max,m=A.avg,b=Math.ceil(A.delta*al);for(var ah=0,z=S.length;ah<z;ah++){var U=Math.floor((S[ah][0]-F)*al);var T=S[ah][1];if(!T){continue}L=Math.floor(ad-(T/D)*ad);B.fillStyle="rgb("+L+","+L+","+L+")";B.fillRect(U+Q,0,b,this.summary_d raw_height);if(this.prefs.show_counts&&B.measureText(T).width<b){if(L>h){B.fillStyle="black"}else{B.fillStyle="#ddd"}B.textAlign="center";B.fillText(T,U+Q+(b/2),12)}}d="Summary";o.append(M);return M}var aj=A.data;var ag=0;for(var ah=0,z=aj.length;ah<z;ah++){var N=aj[ah],K=N[0],ai=N[1],V=N[2],G=N[3];if(ai<=ae&&V>=F){var X=Math.floor(Math.max(0,(ai-F)*al)),C=Math.ceil(Math.min(a,Math.max(0,(V-F)*al))),R=(n==="Dense"?0:ak[K]*am);if(A.dataset_type==="bai"){B.fillStyle=g;if(N[4] instanceof Array){var u=Math.floor(Math.max(0,(N[4][0]-F)*al)),J=Math.ceil(Math.min(a,Math.max(0,(N[4][1]-F)*al))),s=Math.floor(Math.max(0,(N[5][0]-F)*al)),q=Math.ceil(Math.min(a,Math.max(0,(N[5][1]-F)*al)));if(N[4][1]>=F&&N[4][0]<=ae){this.rect_or_text(B,al,F,ae,N[4][0],N[4][2],u+Q,J-u,R)}if(N[5][1]>=F&&N[5][0]<=ae){this.rect_or_text(B,al,F,ae,N[5][0],N[5][2],s+Q,q-s,R)}if(s>J){B.fillStyle="#999";B.fillRect(J+Q,R+5,s-J,1)}}else{B.fillStyle=g;this.rect_or_text(B,al,F,ae,ai,G,X+Q,C-X,R)}if(n!=="Dense"&&!W& &ai>F){B.fillStyle=this.prefs.label_color;if(l===0&&X-B.measureText(G).width<0){B.textAlign="left";B.fillText(K,C+2+Q,R+8)}else{B.textAlign="right";B.fillText(K,X-2+Q,R+8)}B.fillStyle=g}}else{if(A.dataset_type==="interval_index"){if(W){B.fillRect(X+Q,R+5,C-X,1)}else{var w=N[4],P=N[5],Z=N[6],f=N[7];var v,ab,H=null,an=null;if(P&&Z){H=Math.floor(Math.max(0,(P-F)*al));an=Math.ceil(Math.min(a,Math.max(0,(Z-F)*al)))}if(n!=="Dense"&&G!==undefined&&ai>F){B.fillStyle=aa;if(l===0&&X-B.measureText(G).width<0){B.textAlign="left";B.fillText(G,C+2+Q,R+8)}else{B.textAlign="right";B.fillText(G,X-2+Q,R+8)}B.fillStyle=g}if(f){if(w){if(w=="+"){B.fillStyle=RIGHT_STRAND}else{if(w=="-"){B.fillStyle=LEFT_STRAND}}B.fillRect(X+Q,R,C-X,10);B.fillStyle=g}for(var af=0,e=f.length;af<e;af++){var p=f[af],c=Math.floor(Math.max(0,(p[0]-F)*al)),O=Math.ceil(Math.min(a,Math.max((p[1]-F)*al)));if(c>O){continue}v=5;ab=3;B.fillRect(c+Q,R+ab,O-c,v);if(H!==undefined&&!(c>an||O<H)){v=9;ab=1;var ac=Math.max(c,H),r=Ma th.min(O,an);B.fillRect(ac+Q,R+ab,r-ac,v)}}}else{v=9;ab=1;B.fillRect(X+Q,R+ab,C-X,v);if(N.strand){if(N.strand=="+"){B.fillStyle=RIGHT_STRAND_INV}else{if(N.strand=="-"){B.fillStyle=LEFT_STRAND_INV}}B.fillRect(X+Q,R,C-X,10);B.fillStyle=prefs.block_color}}}}}ag++}}o.append(M);return M},gen_options:function(j){var a=$("<div />").addClass("form-row");var e="track_"+j+"_block_color",l=$("<label />").attr("for",e).text("Block color:"),m=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),k="track_"+j+"_label_color",g=$("<label />").attr("for",k).text("Text color:"),h=$("<input />").attr("id",k).attr("name",k).val(this.prefs.label_color),f="track_"+j+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(l).append(m).append(g).append(h).append(d)},update_options:function(e ){var b=$("#track_"+e+"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,c){FeatureTrack.call(this,d,b,a,c);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
1
0
0
0
galaxy-dist commit cf04a4c57207: enable sff extractor tool on main
by commits-noreply@bitbucket.org
08 Sep '10
08 Sep '10
# HG changeset patch --
Bitbucket.org
# Project galaxy-dist # URL
http://bitbucket.org/galaxy/galaxy-dist/overview
# User rc # Date 1282836960 14400 # Node ID cf04a4c5720705b8d0cd336f3f87cc9acd8960e3 # Parent cd88e599e8fe64bf86ac059c61b130c8cbaf1b52 enable sff extractor tool on main --- a/tool_conf.xml.main +++ b/tool_conf.xml.main @@ -53,6 +53,7 @@ <tool file="maf/maf_to_fasta.xml" /><tool file="fasta_tools/tabular_to_fasta.xml" /><tool file="fastq/fastq_to_fasta.xml" /> + <tool file="filters/sff_extractor.xml" /></section><section name="FASTA manipulation" id="fasta_manipulation"><tool file="fasta_tools/fasta_compute_length.xml" />
1
0
0
0
galaxy-dist commit 2ac11399c20e: trackster: Overview track, viz cloning, "Go-to" specific location, UI fixes
by commits-noreply@bitbucket.org
08 Sep '10
08 Sep '10
# HG changeset patch --
Bitbucket.org
# Project galaxy-dist # URL
http://bitbucket.org/galaxy/galaxy-dist/overview
# User Kanwei Li <kanwei(a)gmail.com> # Date 1282839152 14400 # Node ID 2ac11399c20ed6b844f563b77de089b9ddff657e # Parent 291183d3896bcedef4d632a91fe7169d07bd8154 trackster: Overview track, viz cloning, "Go-to" specific location, UI fixes - Each track now has an Overview checkbox that will set the initial chromosome-wide view of that track to become the overview - Visualizations that users own or are shared with can now be cloned - Go-to feature lets users go directly to a certain chrom (eg "chr1"), or chrom and position ("chr1:1-100,000,000") - Fix double flushing when creating converter - Line tracks display mode is now inline - Use smaller font for tracks - Fix web-kit bug where using scrollbar would also trigger viewport dragging - Fix Line tracks jumping around when changing position - Made default Line track height 80px from 100px - Fix drag-zoom overlay appearing at top of header instead of Label track - Minor grid refactoring --- a/templates/tracks/browser.mako +++ b/templates/tracks/browser.mako @@ -115,7 +115,7 @@ // To adjust the size of the viewport to fit the fixed-height footer var refresh = function() { if (view !== undefined) { - view.viewport_container.height( $("#center").height() - 110 ); + view.viewport_container.height( $("#center").height() - $(".nav-container").height() - 40 ); view.nav_container.width( $("#center").width() ); view.redraw(); } --- a/lib/galaxy/web/base/controller.py +++ b/lib/galaxy/web/base/controller.py @@ -204,12 +204,6 @@ class UsesVisualization( SharableItemSec latest_revision = visualization.latest_revision tracks = [] - # Set dbkey. - try: - dbkey = latest_revision.dbkey - except KeyError: - dbkey = None - # Set tracks. if 'tracks' in latest_revision.config: hda_query = trans.sa_session.query( trans.model.HistoryDatasetAssociation ) @@ -227,12 +221,9 @@ class UsesVisualization( SharableItemSec "dataset_id": dataset.id, "prefs": simplejson.dumps(prefs), } ) - if dbkey is None: dbkey = dataset.dbkey # Hack for backward compat - - ## TODO: chrom needs to be able to be set; right now it's empty. config = { "title": visualization.title, "vis_id": trans.security.encode_id( visualization.id ), - "tracks": tracks, "chrom": "", "dbkey": dbkey } + "tracks": tracks, "chrom": "", "dbkey": visualization.dbkey } return config Binary file static/images/fugue/navigation.png has changed --- a/static/scripts/packed/trackster.js +++ b/static/scripts/packed/trackster.js @@ -1,1 +1,1 @@ -var DENSITY=200,FEATURE_LEVELS=10,DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),PX_PER_CHAR=CONTEXT.measureText("A").width,RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/strand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONT EXT.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")};var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,c,e,d,b){this.container=a;this.vis_id=d;this.dbkey=b;this.title=e;this.chrom=c;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.init();this.reset()};$.extend( View.prototype,{init:function(){var b=this.container,a=this;this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(b);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(b);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide().appendTo(b);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.viewport=$("<div/>").addClass("viewport").appendTo(this.viewport_container);this.nav_container=$("<div/>").addClass("nav-container").appendTo(b);this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.nav);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overvi ew_viewport);this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){void (0)}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);this.low_input=$("<input/>").addClass("low").css("width","10em").appendTo(this.chrom_form);$("<span/>").text(" - ").appendTo(this.chrom_form);this.high_input=$("<input/>").addClass("high").css("width","10em").appendTo(this.chrom_form);if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.zi_link=$("<a/>").click(function(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);this.zo_link=$("<a/>").click(function(){a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.pn g" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(c){if(c.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=c.chrom_info;var f='<option value="">Select Chrom/Contig</option>';for(i in a.chrom_data){var e=a.chrom_data[i]["chrom"];f+='<option value="'+e+'">'+e+"</option>"}a.chrom_select.html(f);var d=function(){if(a.chrom_select.val()===""){a.intro_div.show();a.content_div.hide()}else{a.intro_div.hide();a.content_div.show()}a.chrom=a.chrom_select.val();var h=$.grep(a.chrom_data,function(k,l){return k.chrom===a.chrom})[0];a.max_high=(h!==undefined?h.len:0);a.reset();a.redraw(true);for(var j in a.tracks){var g=a.tracks[j];if(g.init){g.init()}}a.redraw()};a.chrom_select.bind("change",d);d()},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("dblclick",function(c){a.zoom_in(c.pageX,this.viewport_container)});thi s.overview_box.bind("dragstart",function(c){this.current_x=c.offsetX}).bind("drag",function(c){var f=c.offsetX-this.current_x;this.current_x=c.offsetX;var d=Math.round(f/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-d)});this.viewport_container.bind("dragstart",function(c){this.original_low=a.low;this.current_height=c.clientY;this.current_x=c.offsetX}).bind("drag",function(f){var c=$(this);var h=f.offsetX-this.current_x;var d=c.scrollTop()-(f.clientY-this.current_height);c.scrollTop(d);this.current_height=f.clientY;this.current_x=f.offsetX;var g=Math.round(h/a.viewport_container.width()*(a.high-a.low));a.move_delta(g)});this.top_labeltrack.bind("dragstart",function(c){this.drag_origin_x=c.clientX;this.drag_origin_pos=c.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_div=$("<div />").css({height:a.viewport_container.height(),top:"0px",position:"absolute","background-color":"#cfc",border:"1px solid #6a6",opacity:0.5,"z-index":1000}).app endTo($(this))}).bind("drag",function(h){var d=Math.min(h.clientX,this.drag_origin_x)-a.container.offset().left,c=Math.max(h.clientX,this.drag_origin_x)-a.container.offset().left,g=(a.high-a.low),f=a.viewport_container.width();a.low_input.val(commatize(Math.round(d/f*g)+a.low));a.high_input.val(commatize(Math.round(c/f*g)+a.low));this.drag_div.css({left:d+"px",width:(c-d)+"px"})}).bind("dragend",function(j){var d=Math.min(j.clientX,this.drag_origin_x),c=Math.max(j.clientX,this.drag_origin_x),g=(a.high-a.low),f=a.viewport_container.width(),h=a.low;a.low=Math.round(d/f*g)+h;a.high=Math.round(c/f*g)+h;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack))},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_tra ck:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},update_options:function(){this.has_changes=true;var b=$("ul#sortable-ul").sortable("toArray");for(var c in b){var e=b[c].split("_li")[0].split("track_")[1];this.viewport.append($("#track_"+e))}for(var d in view.tracks){var a=view.tracks[d];if(a&&a.update_options){a.update_options(d)}}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(f){var d=this.high-this.low,b=this.low,e=this.high;if(b<this.max_low){b=this.max_low}if(e>this.max_high){e=this.max_high}if(this.high!==0&& d<this.min_separation){e=b+this.min_separation}this.low=Math.floor(b);this.high=Math.ceil(e);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))));this.overview_box.css({left:(this.low/(this.max_high-this.max_low))*this.overview_viewport.width(),width:Math.max(12,(this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())}).show();this.low_input.val(commatize(this.low));this.high_input.val(commatize(this.high));if(!f){for(var c=0,a=this.tracks.length;c<a;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,a=this.label_tracks.length;c<a;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*( this.high-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b=this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()}});var Track=function(b,a,c){this.name=b;this.parent_element=c;this.view=a;this.init_global()};$.extend(Track.prototype,{init_global:function(){this.header_div=$("<div class='track-header'>").text(this.name);this.content_div=$("<div class='track-content'>");this.container_div=$("<div />").addClass("track").append(this.header_div).append(this.content_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.content_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d ||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.view.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){this.left_offset=200};$.extend(TiledT rack.prototype,Track.prototype,{draw:function(){var j=this.view.low,e=this.view.high,f=e-j,d=this.view.resolution;var l=$("<div style='position: relative;'></div>"),m=this.content_div.width()/f,h;this.content_div.children(":first").remove();this.content_div.append(l),this.max_height=0;var a=Math.floor(j/d/DENSITY);while((a*DENSITY*d)<e){var k=this.content_div.width()+"_"+m+"_"+a;var c=this.tile_cache.get(k);if(c){var g=a*DENSITY*d;var b=(g-j)*m;if(this.left_offset){b-=this.left_offset}c.css({left:b});l.append(c);this.max_height=Math.max(this.max_height,c.height());this.content_div.css("height",this.max_height+"px")}else{this.delayed_draw(this,k,j,e,a,d,l,m)}a+=1}},delayed_draw:function(c,e,a,f,b,d,g,h){setTimeout(function(){if(!(a>c.view.high||f<c.view.low)){tile_element=c.draw_tile(d,b,g,h);if(tile_element){c.tile_cache.set(e,tile_element);c.max_height=Math.max(c.max_height,tile_element.height());c.content_div.css("height",c.max_height+"px")}}},50)}});var LabelTrack=functio n(a,b){Track.call(this,null,a,b);this.track_type="LabelTrack";this.hidden=true;this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.hidden=true;this.height_px=12;this.container_div.addClass("reference-track");this.dummy_canvas=$("<canvas></canvas>").get(0).getContext("2d");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend (ReferenceTrack.prototype,TiledTrack.prototype,{get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(f,b,k,o){var g=b*DENSITY*f,d=DENSITY*f,e=$("<canvas class='tile'></canvas>"),n=e.get(0).getContext("2d"),j=f+"_"+b;if(o>PX_PER_CHAR){if(this.data_cache.get(j)===undefined){this.get_data(f,b);return}var m=this.data_cache.get(j);if(m===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*o+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*o-this.left_offset});for(var h=0,l=m.length;h<l;h++){var a=Math.round(h*o);n.fillText(m[h],a+this.left_offset,10)}k.append(e);return e}this.content_div.css("he ight","0px")}});var LineTrack=function(d,b,a,c){this.track_type="LineTrack";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=100;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={min_value:undefined,max_value:undefined,mode:"Line"};if(c.min_value!==undefined){this.prefs.min_value=c.min_value}if(c.max_value!==undefined){this.prefs.max_value=c.max_value}if(c.mode!==undefined){this.prefs.mode=c.mode}};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").va l(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;$("#linetrack_"+b+"_minval").remove();$("#linetrack_"+b+"_maxval").remove();var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(a.prefs.min_value);var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(a.prefs.max_value);d.css({position:"relative",top:"25px",left:"10px"});d.prependTo(a.container_div);e.css({position:"relative",top:a.height_px+55+"px",left:"10px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(p,r,c,e ){if(this.vertical_range===undefined){return}var s=r*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),v=p+"_"+r;if(this.data_cache.get(v)===undefined){this.get_data(p,r);return}var j=this.data_cache.get(v);if(j===null){return}b.css({position:"absolute",top:0,left:(s-this.view.low)*e});b.get(0).width=Math.ceil(a*e+this.left_offset);b.get(0).height=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,t=this.total_frequency,d=this.height_px,m=this.prefs.mode;o.beginPath();if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}var u,h;for(var q=0;q<data.length;q++){u=(data[q][0]-s)*e;h=data[q][1];if(m=="Intensity"){if(h===null){continue}if(h<=l){h=l}else{if(h>=g){h=g}}h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")";o.fillRect(u,0,f,this.height_px)}else{if(h===null){if(k&&m==="Filled"){o.lineTo(u,d)}k=false;continue}else{if(h<=l){h=l}else{if(h>=g){h=g}}h=Math.ro und(d-(h-l)/n*d);if(k){o.lineTo(u,h)}else{k=true;if(m==="Filled"){o.moveTo(u,d);o.lineTo(u,h)}else{o.moveTo(u,h)}}}}}if(m==="Filled"){if(k){o.lineTo(u,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(o){var a=$("<div />").addClass("form-row");var h="track_"+o+"_minval",m=$("<label></label>").attr("for",h).text("Min value:"),b=(this.prefs.min_value===undefined?"":this.prefs.min_value),n=$("<input></input>").attr("id",h).val(b),l="track_"+o+"_maxval",g=$("<label></label>").attr("for",l).text("Max value:"),k=(this.prefs.max_value===undefined?"":this.prefs.max_value),f=$("<input></input>").attr("id",l).val(k),e="track_"+o+"_mode",d=$("<label></label>").attr("for",e).text("Display mode:"),j=(this.prefs.mode===undefined?"Line":this.prefs.mode),c=$('<select id="'+e+'"><option value="Line" id="mode_Line">Line</option><option value="Filled" id="mode_Filled">Filled</option><option value="Intensity" id="mode_Intensity">Intensity</option></select>');c.children("#mo de_"+j).attr("selected","selected");return a.append(m).append(n).append(g).append(f).append(d).append(c)},update_options:function(d){var a=$("#track_"+d+"_minval").val(),c=$("#track_"+d+"_maxval").val(),b=$("#track_"+d+"_mode option:selected").val();if(a!==this.prefs.min_value||c!==this.prefs.max_value||b!==this.prefs.mode){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(c);this.prefs.mode=b;this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+d+"_minval").text(this.prefs.min_value);$("#linetrack_"+d+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,c){this.track_type="FeatureTrack";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=3;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.prefs={block_color:"black",label_color:"black",show_counts:true};if(c.block_color!==undefined){this.prefs.block_color=c.block_color}if(c.label_color!==undefined){this.prefs.label_color=c.label_color}if(c.show_counts!==undefined){this.prefs.show_counts=c.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var b=this,c=b.view.max_low+"_"+b.view.max_high;if(b.mode_div===undefined){b.mode_div=$("<div class='right-float menubutton popup' />").text("Display Mode").appendTo(b.header_div);b.mode="Auto";var a=function(d){b.mode_div.text(d);b.mode=d;b.tile_cache.clear();b.draw()};make_popupmenu(b.mode_div,{Auto:function(){a("Auto")},Dense:function(){a("Dense")},Squish:function(){a("Squish")},Pack:function(){a("Pack")}})}else{b.mode_div.hide()}this.init_each({low:b.view.max_low,high :b.view.max_high,dataset_id:b.dataset_id,chrom:b.view.chrom,resolution:this.view.resolution},function(d){b.mode_div.show();b.data_cache.set(c,d);b.draw()})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=1/a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(thi s.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.measureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(true){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_tile[a][v].length;u<A;u++){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=[]}this.s_e_by_tile[a][v].push([e,f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(n,o,f,m,b,d,k,e,h){n.textAlign="center";var j=Math.round(o/2);if((this.mode==="Pack"||this.mode==="Auto")&&d!==undefined&&o>PX_PER_CHAR){n.fillStyle=this.prefs.block_color;n.fillRect(k,h+1,e,9);n.fillStyle="#eee";for(var g=0,l=d.length;g<l;g++){if(b+g>=f&&b+g<=m){var a=Math.floor(Math.max(0,(b+g-f)*o));n.fillText(d[g],a+this.left_offset+j,h+9)}}}else{n.fillStyle=this.prefs.block_ color;n.fillRect(k,h+4,e,3)}},draw_tile:function(X,h,n,ak){var E=h*DENSITY*X,ad=(h+1)*DENSITY*X,D=DENSITY*X;var ae=E+"_"+ad;var z=this.data_cache.get(ae);if(z===undefined){this.data_queue[[E,ad]]=true;this.get_data(E,ad);return}var a=Math.ceil(D*ak),L=$("<canvas class='tile'></canvas>"),Z=this.prefs.label_color,f=this.prefs.block_color,m=this.mode,V=(m==="Squish")||(m==="Dense")&&(m!=="Pack")||(m==="Auto"&&(z.extra_info==="no_detail")),P=this.left_offset,aj,s,al;if(z.dataset_type==="summary_tree"){s=30}else{if(m==="Dense"){s=15;al=10}else{al=(V?this.vertical_nodetail_px:this.vertical_detail_px);s=this.incremental_slots(this.view.zoom_res,z.data,V,m)*al+15;aj=this.inc_slots[this.view.zoom_res]}}L.css({position:"absolute",top:0,left:(E-this.view.low)*ak-P});L.get(0).width=a+P;L.get(0).height=s;n.parent().css("height",Math.max(this.height_px,s)+"px");var A=L.get(0).getContext("2d");A.fillStyle=f;A.font=this.default_font;A.textAlign="right";if(z.dataset_type=="summary_tree"){var K,H=55,ac=255-H,g=ac*2/3,R=z.data,C=z.max,l=z.avg,b=Math.ceil(z.delta*ak);for(var ag=0,w=R.length;ag<w;ag++){var T=Math.floor((R[ag][0]-E)*ak);var S=R[ag][1];if(!S){continue}K=Math.floor(ac-(S/C)*ac);A.fillStyle="rgb("+K+","+K+","+K+")";A.fillRect(T+P,0,b,20);if(this.prefs.show_counts&&A.measureText(S).width<b){if(K>g){A.fillStyle="black"}else{A.fillStyle="#ddd"}A.textAlign="center";A.fillText(S,T+P+(b/2),12)}}n.append(L);return L}var ai=z.data;var af=0;for(var ag=0,w=ai.length;ag<w;ag++){var M=ai[ag],J=M[0],ah=M[1],U=M[2],F=M[3];if(ah<=ad&&U>=E){var W=Math.floor(Math.max(0,(ah-E)*ak)),B=Math.ceil(Math.min(a,Math.max(0,(U-E)*ak))),Q=(m==="Dense"?0:aj[J]*al);if(z.dataset_type==="bai"){A.fillStyle=f;if(M[4] instanceof Array){var t=Math.floor(Math.max(0,(M[4][0]-E)*ak)),I=Math.ceil(Math.min(a,Math.max(0,(M[4][1]-E)*ak))),r=Math.floor(Math.max(0,(M[5][0]-E)*ak)),p=Math.ceil(Math.min(a,Math.max(0,(M[5][1]-E)*ak)));if(M[4][1]>=E&&M[4][0]<=ad){this.rect_or_text(A,ak,E,ad,M[4][0],M [4][2],t+P,I-t,Q)}if(M[5][1]>=E&&M[5][0]<=ad){this.rect_or_text(A,ak,E,ad,M[5][0],M[5][2],r+P,p-r,Q)}if(r>I){A.fillStyle="#999";A.fillRect(I+P,Q+5,r-I,1)}}else{A.fillStyle=f;this.rect_or_text(A,ak,E,ad,ah,F,W+P,B-W,Q)}if(m!=="Dense"&&!V&&ah>E){A.fillStyle=this.prefs.label_color;if(h===0&&W-A.measureText(F).width<0){A.textAlign="left";A.fillText(J,B+2+P,Q+8)}else{A.textAlign="right";A.fillText(J,W-2+P,Q+8)}A.fillStyle=f}}else{if(z.dataset_type==="interval_index"){if(V){A.fillRect(W+P,Q+5,B-W,1)}else{var v=M[4],O=M[5],Y=M[6],e=M[7];var u,aa,G=null,am=null;if(O&&Y){G=Math.floor(Math.max(0,(O-E)*ak));am=Math.ceil(Math.min(a,Math.max(0,(Y-E)*ak)))}if(m!=="Dense"&&F!==undefined&&ah>E){A.fillStyle=Z;if(h===0&&W-A.measureText(F).width<0){A.textAlign="left";A.fillText(F,B+2+P,Q+8)}else{A.textAlign="right";A.fillText(F,W-2+P,Q+8)}A.fillStyle=f}if(e){if(v){if(v=="+"){A.fillStyle=RIGHT_STRAND}else{if(v=="-"){A.fillStyle=LEFT_STRAND}}A.fillRect(W+P,Q,B-W,10);A.fillStyle=f}for(var ae=0,d= e.length;ae<d;ae++){var o=e[ae],c=Math.floor(Math.max(0,(o[0]-E)*ak)),N=Math.ceil(Math.min(a,Math.max((o[1]-E)*ak)));if(c>N){continue}u=5;aa=3;A.fillRect(c+P,Q+aa,N-c,u);if(G!==undefined&&!(c>am||N<G)){u=9;aa=1;var ab=Math.max(c,G),q=Math.min(N,am);A.fillRect(ab+P,Q+aa,q-ab,u)}}}else{u=9;aa=1;A.fillRect(W+P,Q+aa,B-W,u);if(M.strand){if(M.strand=="+"){A.fillStyle=RIGHT_STRAND_INV}else{if(M.strand=="-"){A.fillStyle=LEFT_STRAND_INV}}A.fillRect(W+P,Q,B-W,10);A.fillStyle=prefs.block_color}}}}}af++}}n.append(L);return L},gen_options:function(j){var a=$("<div />").addClass("form-row");var e="track_"+j+"_block_color",l=$("<label />").attr("for",e).text("Block color:"),m=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),k="track_"+j+"_label_color",g=$("<label />").attr("for",k).text("Text color:"),h=$("<input />").attr("id",k).attr("name",k).val(this.prefs.label_color),f="track_"+j+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<inpu t type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(l).append(m).append(g).append(h).append(d)},update_options:function(e){var b=$("#track_"+e+"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,c){FeatureTrack.call(this,d,b,a,c);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{}); +var DENSITY=200,FEATURE_LEVELS=10,DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),PX_PER_CHAR=CONTEXT.measureText("A").width,RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/strand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONT EXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,c,e,d,b){this.container=a;this.vis_id=d;this.dbkey=b;this.title=e;this.chrom=c;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this .has_changes=false;this.init();this.reset()};$.extend(View.prototype,{init:function(){var b=this.container,a=this;this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(b);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(b);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide().appendTo(b);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.nav_container=$("<div/>").addClass("nav-container").appendTo(b);this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.nav);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_o verview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){void (0)}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keypress",function(c){if((c.keyCode||c.which)===13){a.go_to($(this).val());$(this).hide();return false}}).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.goto_link=$("<a/>").click(function(){a.nav_input.toggle();a.nav_input.focus()}).html('<img src="'+image_path+'/fugue/navigation.png" />').appendTo(this.chrom_form);this.zo_link=$("<a/>").click(function() {a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);this.zi_link=$("<a/>").click(function(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(c){if(c.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=c.chrom_info;var e='<option value="">Select Chrom/Contig</option>';for(i in a.chrom_data){var d=a.chrom_data[i]["chrom"];e+='<option value="'+d+'">'+d+"</option>"}a.chrom_select.html(e);a.intro_div.show();a.content_div.hide();a.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())})},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("dblclick",function(c){a.zoom_in(c.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(c){ this.current_x=c.offsetX}).bind("drag",function(c){var f=c.offsetX-this.current_x;this.current_x=c.offsetX;var d=Math.round(f/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-d)});this.viewport_container.bind("dragstart",function(c){this.original_low=a.low;this.current_height=c.clientY;this.current_x=c.offsetX;this.active=(c.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(f){if(!this.active){return}var c=$(this);var h=f.offsetX-this.current_x;var d=c.scrollTop()-(f.clientY-this.current_height);c.scrollTop(d);this.current_height=f.clientY;this.current_x=f.offsetX;var g=Math.round(h/a.viewport_container.width()*(a.high-a.low));a.move_delta(g)});this.top_labeltrack.bind("dragstart",function(c){this.drag_origin_x=c.clientX;this.drag_origin_pos=c.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_div=$("<div />").css({height:a.content_div.height(),top:"0px",position:"absolute","background-color":"#cfc",border:"1px soli d #6a6",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(h){var d=Math.min(h.clientX,this.drag_origin_x)-a.container.offset().left,c=Math.max(h.clientX,this.drag_origin_x)-a.container.offset().left,g=(a.high-a.low),f=a.viewport_container.width();a.update_location(Math.round(d/f*g)+a.low,Math.round(c/f*g)+a.low);this.drag_div.css({left:d+"px",width:(c-d)+"px"})}).bind("dragend",function(j){var d=Math.min(j.clientX,this.drag_origin_x),c=Math.max(j.clientX,this.drag_origin_x),g=(a.high-a.low),f=a.viewport_container.width(),h=a.low;a.low=Math.round(d/f*g)+h;a.high=Math.round(c/f*g)+h;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack))},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(d,a,f){var c=this;var e=$.grep(c.chrom_data ,function(h,j){return h.chrom===d})[0];if(e===undefined){return}c.chrom=d;if(c.chrom===""){c.intro_div.show();c.content_div.hide()}else{c.intro_div.hide();c.content_div.show()}c.chrom_select.val(c.chrom);c.max_high=e.len;c.reset();c.redraw(true);for(var g in c.tracks){var b=c.tracks[g];if(b.init){b.init()}}if(a!==undefined&&f!==undefined){c.low=Math.max(a,0);c.high=Math.min(f,c.max_high)}c.overview_viewport.find("canvas").remove();c.redraw()},go_to:function(f){var k=this,b=f.split(":"),h=b[0],j=b[1];if(j!==undefined){try{var g=j.split("-"),a=parseInt(g[0].replace(/,/g,"")),d=parseInt(g[1].replace(/,/g,""))}catch(c){return false}}k.change_chrom(h,a,d)},move_delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.high-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.contain er_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},update_options:function(){this.has_changes=true;var b=$("ul#sortable-ul").sortable("toArray");for(var c in b){var e=b[c].split("_li")[0].split("track_")[1];this.viewport.append($("#track_"+e))}for(var d in view.tracks){var a=view.tracks[d];if(a&&a.update_options){a.update_options(d)}}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(f){var d=this.high-this.low,b=this.low,e=this.high;if(b<this.max_low){b=this.max_low}if(e>this.max_high){e=this.max_high}if(this.high!==0&&d<this.min_separation){e=b+this.min_separation}this.low=Math.floor(b);this.high=Math.ceil(e);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))));this.overview_box.css({left:(this.low/(this.max_high-this.max_low))*this.overview_viewport.width(),width:Math.max(12,(this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())}).show();this.update_location(this.low,this.high);if(!f){for(var c=0,a=this.tracks.length;c<a;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,a=this.label_tracks.length;c<a;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b= this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()}});var Track=function(b,a,c){this.name=b;this.parent_element=c;this.view=a;this.init_global()};$.extend(Track.prototype,{init_global:function(){this.header_div=$("<div class='track-header'>").text(this.name);this.content_div=$("<div class='track-content'>");this.container_div=$("<div />").addClass("track").append(this.header_div).append(this.content_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.vie w.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){var c=this,b=c.view;if(c.display_modes!==undefined){if(c.mode_div===undefined){c.mode_div=$("<div class='right-float menubutton popup' />").appendTo(c.header_di v);var g=c.display_modes[0];c.mode=g;c.mode_div.text(g);var a=function(h){c.mode_div.text(h);c.mode=h;c.tile_cache.clear();c.draw()};var e={};for(var d in c.display_modes){var f=c.display_modes[d];e[f]=function(h){return function(){a(h)}}(f)}make_popupmenu(c.mode_div,e)}else{c.mode_div.hide()}}if(c.overview_check_div===undefined){c.overview_check_div=$("<div class='right-float' />").css("margin-top","-3px").appendTo(c.header_div);c.overview_check=$("<input type='checkbox' class='overview_check' />").appendTo(c.overview_check_div);c.overview_check.bind("click",function(){var h=this;b.overview_viewport.find("canvas").remove();c.set_overview();$(".overview_check").each(function(){if(this!==h){$(this).attr("checked",false)}})});c.overview_check_div.append($("<label />").text("Overview"))}};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(){var j=this.view.low,e=this.view.high,f=e-j,d=this.view.resolution;var l=$("<div style='position: relative;'></div>"),m=this.conte nt_div.width()/f,h;this.content_div.children(":first").remove();this.content_div.append(l),this.max_height=0;var a=Math.floor(j/d/DENSITY);while((a*DENSITY*d)<e){var k=this.content_div.width()+"_"+m+"_"+a;var c=this.tile_cache.get(k);if(c){var g=a*DENSITY*d;var b=(g-j)*m;if(this.left_offset){b-=this.left_offset}c.css({left:b});l.append(c);this.max_height=Math.max(this.max_height,c.height());this.content_div.css("height",this.max_height+"px")}else{this.delayed_draw(this,k,j,e,a,d,l,m)}a+=1}},delayed_draw:function(c,e,a,f,b,d,g,h){setTimeout(function(){if(!(a>c.view.high||f<c.view.low)){tile_element=c.draw_tile(d,b,g,h);if(tile_element){if(!c.initial_canvas){c.initial_canvas=$(tile_element).clone();var l=tile_element.get(0).getContext("2d");var j=c.initial_canvas.get(0).getContext("2d");var k=l.getImageData(0,0,l.canvas.width,l.canvas.height);j.putImageData(k,0,0);c.set_overview()}c.tile_cache.set(e,tile_element);c.max_height=Math.max(c.max_height,tile_element.height());c.cont ent_div.css("height",c.max_height+"px")}}},50)},set_overview:function(){var a=this.view;a.overview_viewport.height(a.default_overview_height);a.overview_box.height(a.default_overview_height);if(this.overview_check.is(":checked")){a.overview_viewport.append(this.initial_canvas);a.overview_viewport.height(this.initial_canvas.height());a.overview_box.height(this.initial_canvas.height())}$(window).trigger("resize")}});var LabelTrack=function(a,b){Track.call(this,null,a,b);this.track_type="LabelTrack";this.hidden=true;this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.chil dren(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.hidden=true;this.height_px=12;this.container_div.addClass("reference-track");this.dummy_canvas=$("<canvas></canvas>").get(0).getContext("2d");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.prototype,{get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(f,b,k,o){var g=b*DENSITY*f,d=DENSITY*f,e=$("<canvas class='tile'></canvas>"),n=e.get(0).getContext("2d"),j=f+"_"+b;if(o>PX_PER_CHAR){if(t his.data_cache.get(j)===undefined){this.get_data(f,b);return}var m=this.data_cache.get(j);if(m===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*o+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*o-this.left_offset});for(var h=0,l=m.length;h<l;h++){var a=Math.round(h*o);n.fillText(m[h],a+this.left_offset,10)}k.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=function(d,b,a,c){this.track_type="LineTrack";this.display_modes=["Line","Filled","Intensity"];this.mode="Line";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=80;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={min_value:undefined,max_value:undefined,mode:"Line"};if(c.min_value!==undefined){this.prefs.min_value=c.min_value}if(c.max_value!==undefined){this.prefs.max_value=c.max_value}};$.extend(LineTrack.prototype,Tiled Track.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;$("#linetrack_"+b+"_minval").remove();$("#linetrack_"+b+"_maxval").remove();var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"relative",top:"32px",left:"10px"});d.prependTo(a.container_div);e.css({position:"relative",top:a .height_px+32+"px",left:"10px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(p,r,c,e){if(this.vertical_range===undefined){return}var s=r*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),v=p+"_"+r;if(this.data_cache.get(v)===undefined){this.get_data(p,r);return}var j=this.data_cache.get(v);if(j===null){return}b.css({position:"absolute",top:0,left:(s-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,t=this.total_frequency,d=this.height_px, m=this.mode;o.beginPath();if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}var u,h;for(var q=0;q<data.length;q++){u=(data[q][0]-s)*e;h=data[q][1];if(m=="Intensity"){if(h===null){continue}if(h<=l){h=l}else{if(h>=g){h=g}}h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")";o.fillRect(u,0,f,this.height_px)}else{if(h===null){if(k&&m==="Filled"){o.lineTo(u,d)}k=false;continue}else{if(h<=l){h=l}else{if(h>=g){h=g}}h=Math.round(d-(h-l)/n*d);if(k){o.lineTo(u,h)}else{k=true;if(m==="Filled"){o.moveTo(u,d);o.lineTo(u,h)}else{o.moveTo(u,h)}}}}}if(m==="Filled"){if(k){o.lineTo(u,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(k){var a=$("<div />").addClass("form-row");var e="track_"+k+"_minval",h=$("<label></label>").attr("for",e).text("Min value:"),b=(this.prefs.min_value===undefined?"":this.prefs.min_value),j=$("<input></input>").attr("id",e).val(b),g="track_"+k+"_maxval",d=$("<label></label>").attr("for",g).text("Max value:" ),f=(this.prefs.max_value===undefined?"":this.prefs.max_value),c=$("<input></input>").attr("id",g).val(f);return a.append(h).append(j).append(d).append(c)},update_options:function(c){var a=$("#track_"+c+"_minval").val(),b=$("#track_"+c+"_maxval").val();if(a!==this.prefs.min_value||b!==this.prefs.max_value){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(b);this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+c+"_minval").text(this.prefs.min_value);$("#linetrack_"+c+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,c){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=2;this.su mmary_draw_height=20;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.left_offset=200;this.prefs={block_color:"black",label_color:"black",show_counts:true};if(c.block_color!==undefined){this.prefs.block_color=c.block_color}if(c.label_color!==undefined){this.prefs.label_color=c.label_color}if(c.show_counts!==undefined){this.prefs.show_counts=c.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b="initial";this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution},function(c){a.mode_div.show();a.data_cache.set(b,c);a.draw()})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolutio n,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=1/a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(this.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.measureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(true){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_tile[a][v].length;u<A;u+ +){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=[]}this.s_e_by_tile[a][v].push([e,f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(n,o,f,m,b,d,k,e,h){n.textAlign="center";var j=Math.round(o/2);if((this.mode==="Pack"||this.mode==="Auto")&&d!==undefined&&o>PX_PER_CHAR){n.fillStyle=this.prefs.block_color;n.fillRect(k,h+1,e,9);n.fillStyle="#eee";for(var g=0,l=d.length;g<l;g++){if(b+g>=f&&b+g<=m){var a=Math.floor(Math.max(0,(b+g-f)*o));n.fillText(d[g],a+this.left_offset+j,h+9)}}}else{n.fillStyle=this.prefs.block_color;n.fillRect(k,h+4,e,3)}},draw_tile:function(Y,l,o,al){var F=l*DENSITY*Y,ae=(l+1)*DENSITY*Y,E=ae-F;var af=(!this.initial_canvas?"initial":F+"_"+ae);var A=this.data_cache.get(af);var d;if(A===undefined){this.data_queue[[F,ae]]=true;this.get_data(F,ae);return}var a=Math.ceil(E*al),M=$("<canvas class='tile'></canvas>"),aa=this.prefs.label_color,g =this.prefs.block_color,n=this.mode,W=(n==="Squish")||(n==="Dense")&&(n!=="Pack")||(n==="Auto"&&(A.extra_info==="no_detail")),Q=this.left_offset,ak,t,am;if(A.dataset_type==="summary_tree"){t=this.summary_draw_height}else{if(n==="Dense"){t=15;am=10}else{am=(W?this.vertical_nodetail_px:this.vertical_detail_px);t=this.incremental_slots(this.view.zoom_res,A.data,W,n)*am+15;ak=this.inc_slots[this.view.zoom_res]}}M.css({position:"absolute",top:0,left:(F-this.view.low)*al-Q});M.get(0).width=a+Q;M.get(0).height=t;o.parent().css("height",Math.max(this.height_px,t)+"px");var B=M.get(0).getContext("2d");B.fillStyle=g;B.font=this.default_font;B.textAlign="right";if(A.dataset_type=="summary_tree"){var L,I=55,ad=255-I,h=ad*2/3,S=A.data,D=A.max,m=A.avg,b=Math.ceil(A.delta*al);for(var ah=0,z=S.length;ah<z;ah++){var U=Math.floor((S[ah][0]-F)*al);var T=S[ah][1];if(!T){continue}L=Math.floor(ad-(T/D)*ad);B.fillStyle="rgb("+L+","+L+","+L+")";B.fillRect(U+Q,0,b,this.summary_draw_height);if(this.p refs.show_counts&&B.measureText(T).width<b){if(L>h){B.fillStyle="black"}else{B.fillStyle="#ddd"}B.textAlign="center";B.fillText(T,U+Q+(b/2),12)}}d="Summary";o.append(M);return M}var aj=A.data;var ag=0;for(var ah=0,z=aj.length;ah<z;ah++){var N=aj[ah],K=N[0],ai=N[1],V=N[2],G=N[3];if(ai<=ae&&V>=F){var X=Math.floor(Math.max(0,(ai-F)*al)),C=Math.ceil(Math.min(a,Math.max(0,(V-F)*al))),R=(n==="Dense"?0:ak[K]*am);if(A.dataset_type==="bai"){B.fillStyle=g;if(N[4] instanceof Array){var u=Math.floor(Math.max(0,(N[4][0]-F)*al)),J=Math.ceil(Math.min(a,Math.max(0,(N[4][1]-F)*al))),s=Math.floor(Math.max(0,(N[5][0]-F)*al)),q=Math.ceil(Math.min(a,Math.max(0,(N[5][1]-F)*al)));if(N[4][1]>=F&&N[4][0]<=ae){this.rect_or_text(B,al,F,ae,N[4][0],N[4][2],u+Q,J-u,R)}if(N[5][1]>=F&&N[5][0]<=ae){this.rect_or_text(B,al,F,ae,N[5][0],N[5][2],s+Q,q-s,R)}if(s>J){B.fillStyle="#999";B.fillRect(J+Q,R+5,s-J,1)}}else{B.fillStyle=g;this.rect_or_text(B,al,F,ae,ai,G,X+Q,C-X,R)}if(n!=="Dense"&&!W&&ai>F){B.fillStyle=th is.prefs.label_color;if(l===0&&X-B.measureText(G).width<0){B.textAlign="left";B.fillText(K,C+2+Q,R+8)}else{B.textAlign="right";B.fillText(K,X-2+Q,R+8)}B.fillStyle=g}}else{if(A.dataset_type==="interval_index"){if(W){B.fillRect(X+Q,R+5,C-X,1)}else{var w=N[4],P=N[5],Z=N[6],f=N[7];var v,ab,H=null,an=null;if(P&&Z){H=Math.floor(Math.max(0,(P-F)*al));an=Math.ceil(Math.min(a,Math.max(0,(Z-F)*al)))}if(n!=="Dense"&&G!==undefined&&ai>F){B.fillStyle=aa;if(l===0&&X-B.measureText(G).width<0){B.textAlign="left";B.fillText(G,C+2+Q,R+8)}else{B.textAlign="right";B.fillText(G,X-2+Q,R+8)}B.fillStyle=g}if(f){if(w){if(w=="+"){B.fillStyle=RIGHT_STRAND}else{if(w=="-"){B.fillStyle=LEFT_STRAND}}B.fillRect(X+Q,R,C-X,10);B.fillStyle=g}for(var af=0,e=f.length;af<e;af++){var p=f[af],c=Math.floor(Math.max(0,(p[0]-F)*al)),O=Math.ceil(Math.min(a,Math.max((p[1]-F)*al)));if(c>O){continue}v=5;ab=3;B.fillRect(c+Q,R+ab,O-c,v);if(H!==undefined&&!(c>an||O<H)){v=9;ab=1;var ac=Math.max(c,H),r=Math.min(O,an);B.fillRe ct(ac+Q,R+ab,r-ac,v)}}}else{v=9;ab=1;B.fillRect(X+Q,R+ab,C-X,v);if(N.strand){if(N.strand=="+"){B.fillStyle=RIGHT_STRAND_INV}else{if(N.strand=="-"){B.fillStyle=LEFT_STRAND_INV}}B.fillRect(X+Q,R,C-X,10);B.fillStyle=prefs.block_color}}}}}ag++}}o.append(M);return M},gen_options:function(j){var a=$("<div />").addClass("form-row");var e="track_"+j+"_block_color",l=$("<label />").attr("for",e).text("Block color:"),m=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),k="track_"+j+"_label_color",g=$("<label />").attr("for",k).text("Text color:"),h=$("<input />").attr("id",k).attr("name",k).val(this.prefs.label_color),f="track_"+j+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(l).append(m).append(g).append(h).append(d)},update_options:function(e){var b=$("#track_"+e +"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,c){FeatureTrack.call(this,d,b,a,c);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{}); --- a/static/scripts/trackster.js +++ b/static/scripts/trackster.js @@ -37,6 +37,10 @@ left_img_inv.onload = function() { LEFT_STRAND_INV = CONTEXT.createPattern(left_img_inv, "repeat"); }; +function round_1000(num) { + return Math.round(num * 1000) / 1000; +} + var Cache = function( num_elements ) { this.num_elements = num_elements; this.clear(); @@ -96,7 +100,6 @@ var View = function( container, chrom, t this.content_div = $("<div/>").addClass("content").css("position", "relative").appendTo(parent_element); this.intro_div = $("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide().appendTo(parent_element); this.viewport_container = $("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div); - this.viewport = $("<div/>").addClass("viewport").appendTo(this.viewport_container); this.nav_container = $("<div/>").addClass("nav-container").appendTo(parent_element); this.nav_labeltrack = $("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container); @@ -104,18 +107,26 @@ var View = function( container, chrom, t this.overview = $("<div/>").addClass("overview").appendTo(this.nav); this.overview_viewport = $("<div/>").addClass("overview-viewport").appendTo(this.overview); this.overview_box = $("<div/>").addClass("overview-box").appendTo(this.overview_viewport); + this.default_overview_height = this.overview_box.height(); this.nav_controls = $("<div/>").addClass("nav-controls").appendTo(this.nav); this.chrom_form = $("<form/>").attr("action", function() { void(0); } ).appendTo(this.nav_controls); this.chrom_select = $("<select/>").attr({ "name": "chrom"}).css("width", "15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form); - this.low_input = $("<input/>").addClass("low").css("width", "10em").appendTo(this.chrom_form); - $("<span/>").text(" - ").appendTo(this.chrom_form); - this.high_input = $("<input/>").addClass("high").css("width", "10em").appendTo(this.chrom_form); + this.nav_input = $("<input/>").addClass("nav-input").hide().bind("keypress", function(e) { + if ((e.keyCode || e.which) === 13) { + view.go_to( $(this).val() ); + $(this).hide(); + return false; + } + + }).appendTo(this.chrom_form); + this.location_span = $("<span/>").addClass("location").appendTo(this.chrom_form); if (this.vis_id !== undefined) { this.hidden_input = $("<input/>").attr("type", "hidden").val(this.vis_id).appendTo(this.chrom_form); } - this.zi_link = $("<a/>").click(function() { view.zoom_in(); view.redraw() }).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form); - this.zo_link = $("<a/>").click(function() { view.zoom_out(); view.redraw() }).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);; + this.goto_link = $("<a/>").click(function() { view.nav_input.toggle(); view.nav_input.focus(); }).html('<img src="'+image_path+'/fugue/navigation.png" />').appendTo(this.chrom_form); + this.zo_link = $("<a/>").click(function() { view.zoom_out(); view.redraw() }).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form); + this.zi_link = $("<a/>").click(function() { view.zoom_in(); view.redraw() }).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form); $.ajax({ url: chrom_url, @@ -132,34 +143,11 @@ var View = function( container, chrom, t chrom_options += '<option value="' + chrom + '">' + chrom + '</option>'; } view.chrom_select.html(chrom_options); - - var change_chrom = function () { - if (view.chrom_select.val() === "") { - // No chrom selected - view.intro_div.show(); - view.content_div.hide(); - } else { - view.intro_div.hide(); - view.content_div.show(); - } - view.chrom = view.chrom_select.val(); - var found = $.grep(view.chrom_data, function(v, i) { - return v.chrom === view.chrom; - })[0]; - view.max_high = (found !== undefined ? found.len : 0); - view.reset(); - view.redraw(true); - - for (var track_id in view.tracks) { - var track = view.tracks[track_id]; - if (track.init) { - track.init(); - } - } - view.redraw(); - }; - view.chrom_select.bind( "change", change_chrom ); - change_chrom(); + view.intro_div.show(); + view.content_div.hide(); + view.chrom_select.bind("change", function() { + view.change_chrom(view.chrom_select.val()); + }); }, error: function() { alert( "Could not load chroms for this dbkey:", view.dbkey ); @@ -199,13 +187,13 @@ var View = function( container, chrom, t this.original_low = view.low; this.current_height = e.clientY; this.current_x = e.offsetX; + this.active = (e.clientX < view.viewport_container.width() - 16) ? true : false; // Fix webkit scrollbar }).bind( "drag", function( e ) { + if (!this.active) { return; } var container = $(this); var delta = e.offsetX - this.current_x; var new_scroll = container.scrollTop() - (e.clientY - this.current_height); - // if ( new_scroll < container.get(0).scrollHeight - container.height() ) { - container.scrollTop(new_scroll); - // } + container.scrollTop(new_scroll); this.current_height = e.clientY; this.current_x = e.offsetX; @@ -217,7 +205,7 @@ var View = function( container, chrom, t this.drag_origin_x = e.clientX; this.drag_origin_pos = e.clientX / view.viewport_container.width() * (view.high - view.low) + view.low; this.drag_div = $("<div />").css( { - "height": view.viewport_container.height(), "top": "0px", "position": "absolute", + "height": view.content_div.height(), "top": "0px", "position": "absolute", "background-color": "#cfc", "border": "1px solid #6a6", "opacity": 0.5, "z-index": 1000 } ).appendTo( $(this) ); }).bind( "drag", function(e) { @@ -226,8 +214,7 @@ var View = function( container, chrom, t span = (view.high - view.low), width = view.viewport_container.width(); - view.low_input.val(commatize(Math.round(min / width * span) + view.low)); - view.high_input.val(commatize(Math.round(max / width * span) + view.low)); + view.update_location(Math.round(min / width * span) + view.low, Math.round(max / width * span) + view.low); this.drag_div.css( { "left": min + "px", "width": (max - min) + "px" } ); }).bind( "dragend", function(e) { var min = Math.min(e.clientX, this.drag_origin_x), @@ -245,6 +232,64 @@ var View = function( container, chrom, t this.add_label_track( new LabelTrack( this, this.top_labeltrack ) ); this.add_label_track( new LabelTrack( this, this.nav_labeltrack ) ); }, + update_location: function(low, high) { + this.location_span.text( commatize(low) + ' - ' + commatize(high) ); + this.nav_input.val( this.chrom + ':' + commatize(low) + '-' + commatize(high) ); + }, + change_chrom: function(chrom, low, high) { + var view = this; + var found = $.grep(view.chrom_data, function(v, i) { + return v.chrom === chrom; + })[0]; + if (found === undefined) { + // Invalid chrom + return; + } + view.chrom = chrom; + if (view.chrom === "") { + // No chrom selected + view.intro_div.show(); + view.content_div.hide(); + } else { + view.intro_div.hide(); + view.content_div.show(); + } + view.chrom_select.val(view.chrom); + view.max_high = found.len; + view.reset(); + view.redraw(true); + + for (var track_id in view.tracks) { + var track = view.tracks[track_id]; + if (track.init) { + track.init(); + } + } + if (low !== undefined && high !== undefined) { + view.low = Math.max(low, 0); + view.high = Math.min(high, view.max_high); + } + view.overview_viewport.find("canvas").remove(); + view.redraw(); + + }, + go_to: function(str) { + var view = this, + chrom_pos = str.split(":"), + chrom = chrom_pos[0], + pos = chrom_pos[1]; + + if (pos !== undefined) { + try { + var pos_split = pos.split("-"), + new_low = parseInt(pos_split[0].replace(/,/g, "")), + new_high = parseInt(pos_split[1].replace(/,/g, "")); + } catch (e) { + return false; + } + } + view.change_chrom(chrom, new_low, new_high); + }, move_delta: function(delta_chrom) { var view = this; var current_chrom_span = view.high - view.low; @@ -327,8 +372,7 @@ var View = function( container, chrom, t // Minimum width for usability width: Math.max( 12, (this.high - this.low)/(this.max_high - this.max_low) * this.overview_viewport.width() ) }).show(); - this.low_input.val( commatize(this.low) ); - this.high_input.val( commatize(this.high) ); + this.update_location(this.low, this.high); if (!nodraw) { for (var i = 0, len = this.tracks.length; i < len; i++) { if (this.tracks[i] && this.tracks[i].enabled) { @@ -386,6 +430,7 @@ var Track = function (name, view, parent track.data_queue = {}; track.tile_cache.clear(); track.data_cache.clear(); + track.initial_canvas = undefined; track.content_div.css( "height", "auto" ); if (!track.content_div.text()) { track.content_div.text(DATA_LOADING); @@ -432,7 +477,49 @@ var Track = function (name, view, parent }); var TiledTrack = function() { - this.left_offset = 200; + var track = this, + view = track.view; + + if (track.display_modes !== undefined) { + if (track.mode_div === undefined) { + track.mode_div = $("<div class='right-float menubutton popup' />").appendTo(track.header_div); + var init_mode = track.display_modes[0]; + track.mode = init_mode; + track.mode_div.text(init_mode); + + var change_mode = function(name) { + track.mode_div.text(name); + track.mode = name; + track.tile_cache.clear(); + track.draw(); + }; + var mode_mapping = {}; + for (var i in track.display_modes) { + var mode = track.display_modes[i]; + mode_mapping[mode] = function(mode) { + return function() { change_mode(mode); } + }(mode); + } + make_popupmenu(track.mode_div, mode_mapping); + } else { + track.mode_div.hide(); + } + } + if (track.overview_check_div === undefined) { + track.overview_check_div = $("<div class='right-float' />").css("margin-top", "-3px").appendTo(track.header_div); + track.overview_check = $("<input type='checkbox' class='overview_check' />").appendTo(track.overview_check_div); + track.overview_check.bind("click", function() { + var curr = this; + view.overview_viewport.find("canvas").remove(); + track.set_overview(); + $(".overview_check").each(function() { + if (this !== curr) { + $(this).attr("checked", false); + } + }); + }); + track.overview_check_div.append( $("<label />").text("Overview") ); + } }; $.extend( TiledTrack.prototype, Track.prototype, { draw: function() { @@ -476,13 +563,33 @@ var TiledTrack = function() { setTimeout(function() { if ( !(low > track.view.high || high < track.view.low) ) { tile_element = track.draw_tile( resolution, tile_index, parent_element, w_scale ); - if ( tile_element ) { + if (tile_element) { + // Store initial canvas in we need to use it for overview + if (!track.initial_canvas) { + track.initial_canvas = $(tile_element).clone(); + var src_ctx = tile_element.get(0).getContext("2d"); + var tgt_ctx = track.initial_canvas.get(0).getContext("2d"); + var data = src_ctx.getImageData(0, 0, src_ctx.canvas.width, src_ctx.canvas.height); + tgt_ctx.putImageData(data, 0, 0); + track.set_overview(); + } track.tile_cache.set(key, tile_element); track.max_height = Math.max( track.max_height, tile_element.height() ); track.content_div.css("height", track.max_height + "px"); } } }, 50); + }, set_overview: function() { + var view = this.view; + view.overview_viewport.height(view.default_overview_height); + view.overview_box.height(view.default_overview_height); + + if (this.initial_canvas && this.overview_check.is(":checked")) { + view.overview_viewport.append(this.initial_canvas); + view.overview_viewport.height(this.initial_canvas.height()); + view.overview_box.height(this.initial_canvas.height()); + } + $(window).trigger("resize"); } }); @@ -580,7 +687,7 @@ var ReferenceTrack = function (view) { var c_start = Math.round(c * w_scale); ctx.fillText(seq[c], c_start + this.left_offset, 10); } - parent_element.append( canvas ); + parent_element.append(canvas); return canvas; } this.content_div.css("height", "0px"); @@ -589,17 +696,18 @@ var ReferenceTrack = function (view) { var LineTrack = function ( name, view, dataset_id, prefs ) { this.track_type = "LineTrack"; + this.display_modes = ["Line", "Filled", "Intensity"]; + this.mode = "Line"; Track.call( this, name, view, view.viewport_container ); TiledTrack.call( this ); - this.height_px = 100; + this.height_px = 80; this.dataset_id = dataset_id; this.data_cache = new Cache(CACHED_DATA); this.tile_cache = new Cache(CACHED_TILES_LINE); this.prefs = { 'min_value': undefined, 'max_value': undefined, 'mode': 'Line' }; if (prefs.min_value !== undefined) { this.prefs.min_value = prefs.min_value; } if (prefs.max_value !== undefined) { this.prefs.max_value = prefs.max_value; } - if (prefs.mode !== undefined) { this.prefs.mode = prefs.mode; } }; $.extend( LineTrack.prototype, TiledTrack.prototype, { init: function() { @@ -626,13 +734,13 @@ var LineTrack = function ( name, view, d $('#linetrack_' + track_id + '_minval').remove(); $('#linetrack_' + track_id + '_maxval').remove(); - var min_label = $("<div />").addClass('yaxislabel').attr("id", 'linetrack_' + track_id + '_minval').text(track.prefs.min_value); - var max_label = $("<div />").addClass('yaxislabel').attr("id", 'linetrack_' + track_id + '_maxval').text(track.prefs.max_value); + var min_label = $("<div />").addClass('yaxislabel').attr("id", 'linetrack_' + track_id + '_minval').text(round_1000(track.prefs.min_value)); + var max_label = $("<div />").addClass('yaxislabel').attr("id", 'linetrack_' + track_id + '_maxval').text(round_1000(track.prefs.max_value)); - max_label.css({ position: "relative", top: "25px", left: "10px" }); + max_label.css({ position: "relative", top: "32px", left: "10px" }); max_label.prependTo(track.container_div); - min_label.css({ position: "relative", top: track.height_px + 55 + "px", left: "10px" }); + min_label.css({ position: "relative", top: track.height_px + 32 + "px", left: "10px" }); min_label.prependTo(track.container_div); }); }, @@ -689,7 +797,7 @@ var LineTrack = function ( name, view, d left: ( tile_low - this.view.low ) * w_scale }); - canvas.get(0).width = Math.ceil( tile_length * w_scale + this.left_offset); + canvas.get(0).width = Math.ceil( tile_length * w_scale ); canvas.get(0).height = this.height_px; var ctx = canvas.get(0).getContext("2d"), in_path = false, @@ -698,7 +806,7 @@ var LineTrack = function ( name, view, d vertical_range = this.vertical_range, total_frequency = this.total_frequency, height_px = this.height_px, - mode = this.prefs.mode; + mode = this.mode; ctx.beginPath(); @@ -768,7 +876,7 @@ var LineTrack = function ( name, view, d } else { ctx.stroke(); } - parent_element.append( canvas ); + parent_element.append(canvas); return canvas; }, gen_options: function(track_id) { var container = $("<div />").addClass("form-row"); @@ -780,23 +888,15 @@ var LineTrack = function ( name, view, d maxval = 'track_' + track_id + '_maxval', max_label = $('<label></label>').attr("for", maxval).text("Max value:"), max_val = (this.prefs.max_value === undefined ? "" : this.prefs.max_value), - max_input = $('<input></input>').attr("id", maxval).val(max_val), - mode = 'track_' + track_id + '_mode', - mode_label = $('<label></label>').attr("for", mode).text("Display mode:"), - mode_val = (this.prefs.mode === undefined ? "Line" : this.prefs.mode), - mode_input = $('<select id="' +mode+ '"><option value="Line" id="mode_Line">Line</option><option value="Filled" id="mode_Filled">Filled</option><option value="Intensity" id="mode_Intensity">Intensity</option></select>'); - - mode_input.children("#mode_"+mode_val).attr('selected', 'selected'); - - return container.append(min_label).append(min_input).append(max_label).append(max_input).append(mode_label).append(mode_input); + max_input = $('<input></input>').attr("id", maxval).val(max_val); + + return container.append(min_label).append(min_input).append(max_label).append(max_input); }, update_options: function(track_id) { var min_value = $('#track_' + track_id + '_minval').val(), - max_value = $('#track_' + track_id + '_maxval').val(), - mode = $('#track_' + track_id + '_mode option:selected').val(); - if ( min_value !== this.prefs.min_value || max_value !== this.prefs.max_value || mode !== this.prefs.mode ) { + max_value = $('#track_' + track_id + '_maxval').val(); + if ( min_value !== this.prefs.min_value || max_value !== this.prefs.max_value ) { this.prefs.min_value = parseFloat(min_value); this.prefs.max_value = parseFloat(max_value); - this.prefs.mode = mode; this.vertical_range = this.prefs.max_value - this.prefs.min_value; // Update the y-axis $('#linetrack_' + track_id + '_minval').text(this.prefs.min_value); @@ -809,6 +909,7 @@ var LineTrack = function ( name, view, d var FeatureTrack = function ( name, view, dataset_id, prefs ) { this.track_type = "FeatureTrack"; + this.display_modes = ["Auto", "Dense", "Squish", "Pack"]; Track.call( this, name, view, view.viewport_container ); TiledTrack.call( this ); @@ -819,13 +920,15 @@ var FeatureTrack = function ( name, view this.show_labels_scale = 0.001; this.showing_details = false; this.vertical_detail_px = 10; - this.vertical_nodetail_px = 3; + this.vertical_nodetail_px = 2; + this.summary_draw_height = 20; this.default_font = "9px Monaco, Lucida Console, monospace"; this.inc_slots = {}; this.data_queue = {}; this.s_e_by_tile = {}; this.tile_cache = new Cache(CACHED_TILES_FEATURE); this.data_cache = new Cache(20); + this.left_offset = 200; this.prefs = { 'block_color': 'black', 'label_color': 'black', 'show_counts': true }; if (prefs.block_color !== undefined) { this.prefs.block_color = prefs.block_color; } @@ -835,39 +938,11 @@ var FeatureTrack = function ( name, view $.extend( FeatureTrack.prototype, TiledTrack.prototype, { init: function() { var track = this, - key = track.view.max_low + '_' + track.view.max_high; - if (track.mode_div === undefined) { - track.mode_div = $("<div class='right-float menubutton popup' />").text("Display Mode").appendTo(track.header_div); - track.mode = "Auto"; - - var change_mode = function(name) { - track.mode_div.text(name); - track.mode = name; - track.tile_cache.clear(); - track.draw(); - }; - make_popupmenu(track.mode_div, { - "Auto": function() { - change_mode("Auto"); - }, - "Dense": function() { - change_mode("Dense"); - }, - "Squish": function() { - change_mode("Squish"); - }, - "Pack": function() { - change_mode("Pack"); - } - }); - } else { - track.mode_div.hide(); - } + key = "initial"; - this.init_each({ low: track.view.max_low, - high: track.view.max_high, dataset_id: track.dataset_id, - chrom: track.view.chrom, resolution: this.view.resolution }, function (result) { - + this.init_each({ low: track.view.max_low, + high: track.view.max_high, dataset_id: track.dataset_id, + chrom: track.view.chrom, resolution: this.view.resolution }, function (result) { track.mode_div.show(); track.data_cache.set(key, result); track.draw(); @@ -993,8 +1068,8 @@ var FeatureTrack = function ( name, view draw_tile: function( resolution, tile_index, parent_element, w_scale ) { var tile_low = tile_index * DENSITY * resolution, tile_high = ( tile_index + 1 ) * DENSITY * resolution, - tile_span = DENSITY * resolution; - // console.log("drawing " + tile_index); + tile_span = tile_high - tile_low; + // console.log("drawing " + tile_low + " to " + tile_high); /*for (var k in this.data_cache.obj_cache) { var k_split = k.split("_"), k_low = k_split[0], k_high = k_split[1]; @@ -1004,9 +1079,9 @@ var FeatureTrack = function ( name, view } }*/ - // var k = this.view.low + '_' + this.view.high; - var k = tile_low + '_' + tile_high; + var k = (!this.initial_canvas ? "initial" : tile_low + '_' + tile_high); var result = this.data_cache.get(k); + var cur_mode; if (result === undefined) { this.data_queue[ [tile_low, tile_high] ] = true; @@ -1024,7 +1099,7 @@ var FeatureTrack = function ( name, view slots, required_height, y_scale; if (result.dataset_type === "summary_tree") { - required_height = 30; + required_height = this.summary_draw_height; } else if (mode === "Dense") { required_height = 15; y_scale = 10; @@ -1066,7 +1141,7 @@ var FeatureTrack = function ( name, view if (!y) { continue; } color = Math.floor( color_span - (y / max) * color_span ); ctx.fillStyle = "rgb(" +color+ "," +color+ "," +color+ ")"; - ctx.fillRect(x + left_offset, 0, delta_x_px, 20); + ctx.fillRect(x + left_offset, 0, delta_x_px, this.summary_draw_height); if (this.prefs.show_counts && ctx.measureText(y).width < delta_x_px) { if (color > color_cutoff) { @@ -1078,7 +1153,7 @@ var FeatureTrack = function ( name, view ctx.fillText(y, x + left_offset + (delta_x_px/2), 12); } } - + cur_mode = "Summary"; parent_element.append( new_canvas ); return new_canvas; } --- a/lib/galaxy/model/__init__.py +++ b/lib/galaxy/model/__init__.py @@ -661,11 +661,11 @@ class DatasetInstance( object ): new_dataset = self.datatype.convert_dataset( trans, self, target_ext, return_output=True, visible=False, deps=deps ).values()[0] new_dataset.hid = self.hid new_dataset.name = self.name - trans.sa_session.add( new_dataset ) - trans.sa_session.flush() + session = trans.sa_session + session.add( new_dataset ) assoc.dataset = new_dataset - trans.sa_session.add( assoc ) - trans.sa_session.flush() + session.add( assoc ) + session.flush() return None def clear_associated_files( self, metadata_safe = False, purge = False ): raise 'Unimplemented' --- a/lib/galaxy/web/controllers/visualization.py +++ b/lib/galaxy/web/controllers/visualization.py @@ -30,8 +30,9 @@ class VisualizationListGrid( grids.Grid grids.GridAction( "Create new visualization", dict( action='create' ) ) ] operations = [ - grids.GridOperation( "View", allow_multiple=False, url_args=dict( controller='tracks', action='browser' ) ), + grids.GridOperation( "View/Edit", allow_multiple=False, url_args=dict( controller='tracks', action='browser' ) ), grids.GridOperation( "Edit Attributes", allow_multiple=False, url_args=dict( action='edit') ), + grids.GridOperation( "Clone", allow_multiple=False, condition=( lambda item: not item.deleted ), async_compatible=False, url_args=dict( action='clone') ), grids.GridOperation( "Share or Publish", allow_multiple=False, condition=( lambda item: not item.deleted ), async_compatible=False ), grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ), async_compatible=True, confirm="Are you sure you want to delete this visualization?" ), ] @@ -86,6 +87,34 @@ class VisualizationController( BaseContr return self.list( trans, args, kwargs ) @web.expose + @web.require_login() + def clone(self, trans, id, *args, **kwargs): + viz = self.get_visualization( trans, id, check_ownership=False ) + user = trans.get_user() + if viz.user == user: + owner = True + else: + if trans.sa_session.query( model.VisualizationUserShareAssociation ) \ + .filter_by( user=user, visualization=viz ).count() == 0: + error( "Visualization is not owned by or shared with current user" ) + owner = False + new_viz = model.Visualization() + new_viz.title = "Clone of '%s'" % viz.title + new_viz.dbkey = viz.dbkey + new_viz.type = viz.type + new_viz.latest_revision = viz.latest_revision + if not owner: + new_viz.title += " shared by '%s'" % viz.user.email + new_viz.user = user + # Persist + session = trans.sa_session + session.add( new_viz ) + session.flush() + # Display the management page + trans.set_message( 'Clone created with name "%s"' % new_viz.title ) + return self.list( trans ) + + @web.expose @web.require_login( "use Galaxy visualizations", use_panels=True ) def list( self, trans, *args, **kwargs ): # Handle operation --- a/static/june_2007_style/blue/trackster.css +++ b/static/june_2007_style/blue/trackster.css @@ -1,13 +1,15 @@ .viewport-container{overflow-x:hidden;overflow-y:auto;} .nav{padding:0 0;color:#333;font-weight:bold;} -.nav-controls{text-align:center;background:#cccccc;background-image:url(panel_header_bg.png);background-position:top center;background-repeat:repeat-x;padding:2px 0;} +.content{font:9px verdana;} +.nav-controls{text-align:center;position:relative;background:#cccccc;background-image:url(panel_header_bg.png);background-position:top center;background-repeat:repeat-x;padding:2px 0;} .nav-controls input{margin:0 5px;} .nav-controls a{padding:0 0.4em;} +.nav-input{font-size:12px;position:absolute;right:0px;bottom:25px;width:20em;z-index:1000;} +.location{display:inline-block;width:15em;margin:0px 10px;} .intro{position:absolute;top:50%;left:30%;color:#555;font-size:16px;} .overview{width:100%;margin:0px;color:white;} .overview-viewport{position:relative;height:14px;background:white;border-bottom:solid gray 1px;margin:0;} -.overview-box{position:absolute;margin-top:0px;height:14px;background:#ddd url(../images/visualization/draggable_horizontal.png) center center no-repeat;} -.viewport{background-color:#fff;} +.overview-box{opacity:0.5;z-index:100;position:absolute;margin-top:0px;height:14px;background:#cfc url(../images/visualization/draggable_horizontal.png) center center no-repeat;border-style:solid;border-color:#6a6;border-width:0px 2px;} .viewport-canvas{width:100%;height:100px;} .yaxislabel{color:#777;} .line-track .track-content{border-top:1px solid #ddd;border-bottom:1px solid #ddd;} @@ -20,5 +22,5 @@ .label-track{} .label-track .label{border-left:solid #999 1px;padding:1px;display:inline-block;} .right-float{float:right;margin-left:5px;} -.top-labeltrack{border-bottom:solid #999 1px;} +.top-labeltrack{position:relative;border-bottom:solid #999 1px;} .nav-labeltrack{border-top:solid #999 1px;border-bottom:solid #999 1px;} --- a/static/june_2007_style/trackster.css.tmpl +++ b/static/june_2007_style/trackster.css.tmpl @@ -2,17 +2,16 @@ overflow-x: hidden; overflow-y: auto; } - -/*canvas{ - border-left: 1px solid green; - border-right: 1px solid red; } /* debugging */ .nav { padding: 0 0; color:#333;font-weight:bold; } - +.content { + font: 9px verdana; +} .nav-controls { text-align: center; + position: relative; background:#cccccc; background-image:url(panel_header_bg.png); background-position:top center; @@ -25,7 +24,20 @@ .nav-controls a { padding: 0 0.4em; } -.intro{ +.nav-input { + font-size: 12px; + position: absolute; + right: 0px; + bottom: 25px; + width: 20em; + z-index: 1000; +} +.location { + display: inline-block; + width: 15em; + margin: 0px 10px; +} +.intro { position: absolute; top: 50%; left: 30%; @@ -37,7 +49,6 @@ margin: 0px; color: white; } - .overview-viewport { position: relative; height: 14px; @@ -48,20 +59,16 @@ margin: 0; } .overview-box { + opacity: 0.5; + z-index: 100; position: absolute; margin-top: 0px; height: 14px; - background: #ddd url(../images/visualization/draggable_horizontal.png) center center no-repeat; - /*border-style: outset;*/ + background: #cfc url(../images/visualization/draggable_horizontal.png) center center no-repeat; + border-style: solid; + border-color: #6a6; + border-width: 0px 2px; } - -.viewport { -/* overflow-x: hidden;*/ - background-color: #fff; -/* overflow: scroll;*/ -/* border-bottom: 2px solid black;*/ -} - .viewport-canvas { width: 100%; height: 100px; @@ -121,6 +128,7 @@ } .top-labeltrack { + position: relative; border-bottom: solid #999 1px; } --- a/templates/visualization/display.mako +++ b/templates/visualization/display.mako @@ -10,7 +10,7 @@ // To adjust the size of the viewport to fit the fixed-height footer var refresh = function( e ) { if (view !== undefined) { - view.viewport_container.height( $(window).height() - 100 ); + view.viewport_container.height( $("#center").height() - $(".nav-container").height() - 40 ); view.nav_container.width( $("#center").width() ); view.redraw(); } --- a/static/june_2007_style/process_css.py +++ b/static/june_2007_style/process_css.py @@ -84,7 +84,7 @@ def build_stylesheet_parser(): # Just match anything that looks like a selector, including element, class, # id, attribute, and pseudoclass. Attributes are not handled properly (spaces, # and even newlines in the quoted string are legal). - simple_selector = Word( alphanums + ".#*:()[]|=\"'_-" ) + simple_selector = Word( alphanums + "@.#*:()[]|=\"'_-" ) combinator = Literal( ">" ) | Literal( "+" ) selector = Group( simple_selector + ZeroOrMore( Optional( combinator ) + simple_selector ) ) selectors = Group( delimitedList( selector ) ) --- a/tools/regVariation/compute_q_values.xml +++ b/tools/regVariation/compute_q_values.xml @@ -46,7 +46,7 @@ **What it does** -This program computes the q-values based on the p-values of multiple simultaneous tests. The q-valules are computed using a specific R package, created by John Storey and Alan Dabney, called "qvalue". The program takes five inputs: +This program computes the q-values based on the p-values of multiple simultaneous tests. The q-values are computed using a specific R package, created by John Storey and Alan Dabney, called "qvalue". The program takes five inputs: - The first input is a TABULAR format file consisting of one column only that represents the p-values of multiple simultaneous tests, one line for every p-value. - The second input is the lambda parameter. The user can choose either the default: seq(0, 0.95, 0.05) or a decimal number between 0.0 and 1.0. @@ -103,7 +103,7 @@ Let us have the first input file of p-va 0.904129283 0.031152635 -Runnig the program will give the following output:: +Running the program will give the following output:: pi0: 0.140311054 --- a/templates/grid_base.mako +++ b/templates/grid_base.mako @@ -97,10 +97,8 @@ // Operations that are async (AJAX) compatible. var async_ops = {}; - %for operation in grid.operations: - %if operation.async_compatible: - async_ops['${operation.label.lower()}'] = "True"; - %endif + %for operation in [op for op in grid.operations if op.async_compatible]: + async_ops['${operation.label.lower()}'] = "True"; %endfor // Initialize grid controls @@ -108,15 +106,13 @@ // Initialize operation buttons. $('input[name=operation]:submit').each(function() { $(this).click( function() { - // Get the webapp var webapp = $("input[name=webapp]").attr("value"); - // Get operation name. - var operation_name = $(this).attr("value"); + var operation_name = $(this).val(); // For some reason, $('input[name=id]:checked').val() does not return all ids for checked boxes. // The code below performs this function. var item_ids = []; $('input[name=id]:checked').each(function() { - item_ids[item_ids.length] = $(this).val(); + item_ids.push( $(this).val() ); }); do_operation(webapp, operation_name, item_ids); }); @@ -133,28 +129,24 @@ $(this).mouseup( function() { $(this).removeClass('gray-background'); }); - }); // Initialize sort links. $('.sort-link').each( function() { - var sort_key = $(this).attr('sort_key'); $(this).click( function() { - set_sort_condition(sort_key); - return false; + set_sort_condition( $(this).attr('sort_key') ); + return false; }); - }); // Initialize page links. $('.page-link > a').each( function() { - var page_num = $(this).attr('page_num'); $(this).click( function() { - set_page(page_num); - return false; + set_page( $(this).attr('page_num') ); + return false; }); - }); + $('#show-all-link').click( function() { set_page('all'); return false; @@ -163,9 +155,7 @@ // Initialize categorical filters. $('.categorical-filter > a').each( function() { $(this).click( function() { - var filter_key = $(this).attr('filter_key'); - var filter_val = $(this).attr('filter_val'); - set_categorical_filter(filter_key, filter_val); + set_categorical_filter( $(this).attr('filter_key'), $(this).attr('filter_val') ); return false; }); }); @@ -179,15 +169,15 @@ text_input_obj.val(''); add_filter_condition(column_key, text_input, true); return false; - }); + }); }); - + // Initialize autocomplete for text inputs in search UI. var t = $("#input-tags-filter"); if (t.length) { t.autocomplete( "${h.url_for( controller='tag', action='tag_autocomplete_data', item_class='History' )}", { selectFirst: false, autoFill: false, highlight: false, mustMatch: false }); - } + } var t2 = $("#input-name-filter"); if (t2.length) { @@ -209,14 +199,15 @@ // Initialize grid selection checkboxes. $(".grid").each( function() { var checkboxes = $(this).find("input.grid-row-select-checkbox"); - var update = $(this).find( "span.grid-selected-count" ); - update.text(""); + var check_count = $(this).find("span.grid-selected-count"); + var update_checked = function() { + check_count.text( $(checkboxes).filter(":checked").length ); + }; + $(checkboxes).each( function() { - $(this).change( function() { - var n = $(checkboxes).filter("[checked]").size(); - update.text( n ); - }); + $(this).change(update_checked); }); + update_checked(); }); // Initialize item labels.
1
0
0
0
galaxy-dist commit 291183d3896b: Add tool 'gff_filter_by_feature_count', create 'GFF' subheading under Tool Menu's Filter category for GFF filtering tools, and rename 'gff_filtering' tool 'gff_filter_by_attribute.'
by commits-noreply@bitbucket.org
08 Sep '10
08 Sep '10
# HG changeset patch --
Bitbucket.org
# Project galaxy-dist # URL
http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu> # Date 1282838441 14400 # Node ID 291183d3896bcedef4d632a91fe7169d07bd8154 # Parent cf04a4c5720705b8d0cd336f3f87cc9acd8960e3 Add tool 'gff_filter_by_feature_count', create 'GFF' subheading under Tool Menu's Filter category for GFF filtering tools, and rename 'gff_filtering' tool 'gff_filter_by_attribute.' gff_filter_by_feature_count tool filters a GFF file using conditions based on transcripts' features counts; for example, it is possible to filter for transcripts that have a minimum number of exons or transcripts that have 3' UTRs. Added GFF subheading to Tool Menu under Filtering and placed all GFF filtering tools under this heading. --- /dev/null +++ b/test-data/gff_filter_by_feature_count_out1.gff @@ -0,0 +1,42 @@ +chr13 Cufflinks transcript 3565855 3566203 1000 - . gene_id "CUFF.50195"; transcript_id "CUFF.50195.1"; FPKM "29.8710998584"; frac "1.000000"; conf_lo "7.290671"; conf_hi "52.451529"; cov "1.909091"; +chr13 Cufflinks exon 3565855 3565913 1000 - . gene_id "CUFF.50195"; transcript_id "CUFF.50195.1"; exon_number "1"; FPKM "29.8710998584"; frac "1.000000"; conf_lo "7.290671"; conf_hi "52.451529"; cov "1.909091"; +chr13 Cufflinks exon 3566164 3566203 1000 - . gene_id "CUFF.50195"; transcript_id "CUFF.50195.1"; exon_number "2"; FPKM "29.8710998584"; frac "1.000000"; conf_lo "7.290671"; conf_hi "52.451529"; cov "1.909091"; +chr13 Cufflinks transcript 3606116 3613028 1000 - . gene_id "CUFF.50207"; transcript_id "CUFF.50207.1"; FPKM "19.6171377865"; frac "1.000000"; conf_lo "0.936995"; conf_hi "38.297281"; cov "1.253750"; +chr13 Cufflinks exon 3606116 3606146 1000 - . gene_id "CUFF.50207"; transcript_id "CUFF.50207.1"; exon_number "1"; FPKM "19.6171377865"; frac "1.000000"; conf_lo "0.936995"; conf_hi "38.297281"; cov "1.253750"; +chr13 Cufflinks exon 3612965 3613028 1000 - . gene_id "CUFF.50207"; transcript_id "CUFF.50207.1"; exon_number "2"; FPKM "19.6171377865"; frac "1.000000"; conf_lo "0.936995"; conf_hi "38.297281"; cov "1.253750"; +chr13 Cufflinks transcript 4594319 4594938 1000 - . gene_id "CUFF.50261"; transcript_id "CUFF.50261.1"; FPKM "29.3887094260"; frac "1.000000"; conf_lo "8.607754"; conf_hi "50.169665"; cov "1.878261"; +chr13 Cufflinks exon 4594319 4594400 1000 - . gene_id "CUFF.50261"; transcript_id "CUFF.50261.1"; exon_number "1"; FPKM "29.3887094260"; frac "1.000000"; conf_lo "8.607754"; conf_hi "50.169665"; cov "1.878261"; +chr13 Cufflinks exon 4594906 4594938 1000 - . gene_id "CUFF.50261"; transcript_id "CUFF.50261.1"; exon_number "2"; FPKM "29.3887094260"; frac "1.000000"; conf_lo "8.607754"; conf_hi "50.169665"; cov "1.878261"; +chr13 Cufflinks transcript 4596799 4598059 1000 - . gene_id "CUFF.50263"; transcript_id "CUFF.50263.1"; FPKM "22.8358215134"; frac "1.000000"; conf_lo "0.000000"; conf_hi "45.671643"; cov "1.459459"; +chr13 Cufflinks exon 4596799 4596828 1000 - . gene_id "CUFF.50263"; transcript_id "CUFF.50263.1"; exon_number "1"; FPKM "22.8358215134"; frac "1.000000"; conf_lo "0.000000"; conf_hi "45.671643"; cov "1.459459"; +chr13 Cufflinks exon 4598016 4598059 1000 - . gene_id "CUFF.50263"; transcript_id "CUFF.50263.1"; exon_number "2"; FPKM "22.8358215134"; frac "1.000000"; conf_lo "0.000000"; conf_hi "45.671643"; cov "1.459459"; +chr13 Cufflinks transcript 5861035 5872268 1000 - . gene_id "CUFF.50289"; transcript_id "CUFF.50289.1"; FPKM "7.5439767500"; frac "1.000000"; conf_lo "0.000000"; conf_hi "18.212771"; cov "0.482143"; +chr13 Cufflinks exon 5861035 5861117 1000 - . gene_id "CUFF.50289"; transcript_id "CUFF.50289.1"; exon_number "1"; FPKM "7.5439767500"; frac "1.000000"; conf_lo "0.000000"; conf_hi "18.212771"; cov "0.482143"; +chr13 Cufflinks exon 5872240 5872268 1000 - . gene_id "CUFF.50289"; transcript_id "CUFF.50289.1"; exon_number "2"; FPKM "7.5439767500"; frac "1.000000"; conf_lo "0.000000"; conf_hi "18.212771"; cov "0.482143"; +chr13 Cufflinks transcript 5865442 5866941 1000 + . gene_id "CUFF.50297"; transcript_id "CUFF.50297.1"; FPKM "13.2019593124"; frac "1.000000"; conf_lo "0.000000"; conf_hi "28.446269"; cov "0.843750"; +chr13 Cufflinks exon 5865442 5865510 1000 + . gene_id "CUFF.50297"; transcript_id "CUFF.50297.1"; exon_number "1"; FPKM "13.2019593124"; frac "1.000000"; conf_lo "0.000000"; conf_hi "28.446269"; cov "0.843750"; +chr13 Cufflinks exon 5866915 5866941 1000 + . gene_id "CUFF.50297"; transcript_id "CUFF.50297.1"; exon_number "2"; FPKM "13.2019593124"; frac "1.000000"; conf_lo "0.000000"; conf_hi "28.446269"; cov "0.843750"; +chr13 Cufflinks transcript 6583845 6585843 1000 - . gene_id "CUFF.50339"; transcript_id "CUFF.50339.1"; FPKM "163.2242242265"; frac "1.000000"; conf_lo "127.815919"; conf_hi "198.632530"; cov "10.431818"; +chr13 Cufflinks exon 6583845 6583946 1000 - . gene_id "CUFF.50339"; transcript_id "CUFF.50339.1"; exon_number "1"; FPKM "163.2242242265"; frac "1.000000"; conf_lo "127.815919"; conf_hi "198.632530"; cov "10.431818"; +chr13 Cufflinks exon 6585726 6585843 1000 - . gene_id "CUFF.50339"; transcript_id "CUFF.50339.1"; exon_number "2"; FPKM "163.2242242265"; frac "1.000000"; conf_lo "127.815919"; conf_hi "198.632530"; cov "10.431818"; +chr13 Cufflinks transcript 6586295 6587966 1000 - . gene_id "CUFF.50341"; transcript_id "CUFF.50341.1"; FPKM "82.5011329424"; frac "1.000000"; conf_lo "60.835274"; conf_hi "104.166992"; cov "5.272727"; +chr13 Cufflinks exon 6586295 6586359 1000 - . gene_id "CUFF.50341"; transcript_id "CUFF.50341.1"; exon_number "1"; FPKM "82.5011329424"; frac "1.000000"; conf_lo "60.835274"; conf_hi "104.166992"; cov "5.272727"; +chr13 Cufflinks exon 6587735 6587966 1000 - . gene_id "CUFF.50341"; transcript_id "CUFF.50341.1"; exon_number "2"; FPKM "82.5011329424"; frac "1.000000"; conf_lo "60.835274"; conf_hi "104.166992"; cov "5.272727"; +chr13 Cufflinks transcript 6580385 6581757 1000 - . gene_id "CUFF.50365"; transcript_id "CUFF.50365.1"; FPKM "324.9135847836"; frac "1.000000"; conf_lo "293.684884"; conf_hi "356.142286"; cov "20.765542"; +chr13 Cufflinks exon 6580385 6580838 1000 - . gene_id "CUFF.50365"; transcript_id "CUFF.50365.1"; exon_number "1"; FPKM "324.9135847836"; frac "1.000000"; conf_lo "293.684884"; conf_hi "356.142286"; cov "20.765542"; +chr13 Cufflinks exon 6581649 6581757 1000 - . gene_id "CUFF.50365"; transcript_id "CUFF.50365.1"; exon_number "2"; FPKM "324.9135847836"; frac "1.000000"; conf_lo "293.684884"; conf_hi "356.142286"; cov "20.765542"; +chr13 Cufflinks transcript 8803760 8819743 1000 + . gene_id "CUFF.50481"; transcript_id "CUFF.50481.1"; FPKM "15.1783005269"; frac "1.000000"; conf_lo "2.785270"; conf_hi "27.571331"; cov "0.970060"; +chr13 Cufflinks exon 8803760 8803879 1000 + . gene_id "CUFF.50481"; transcript_id "CUFF.50481.1"; exon_number "1"; FPKM "15.1783005269"; frac "1.000000"; conf_lo "2.785270"; conf_hi "27.571331"; cov "0.970060"; +chr13 Cufflinks exon 8819697 8819743 1000 + . gene_id "CUFF.50481"; transcript_id "CUFF.50481.1"; exon_number "2"; FPKM "15.1783005269"; frac "1.000000"; conf_lo "2.785270"; conf_hi "27.571331"; cov "0.970060"; +chr13 Cufflinks transcript 8855128 8864773 1000 - . gene_id "CUFF.50497"; transcript_id "CUFF.50497.1"; FPKM "6.4009499697"; frac "1.000000"; conf_lo "0.000000"; conf_hi "19.202850"; cov "0.409091"; +chr13 Cufflinks exon 8855128 8855158 1000 - . gene_id "CUFF.50497"; transcript_id "CUFF.50497.1"; exon_number "1"; FPKM "6.4009499697"; frac "1.000000"; conf_lo "0.000000"; conf_hi "19.202850"; cov "0.409091"; +chr13 Cufflinks exon 8864739 8864773 1000 - . gene_id "CUFF.50497"; transcript_id "CUFF.50497.1"; exon_number "2"; FPKM "6.4009499697"; frac "1.000000"; conf_lo "0.000000"; conf_hi "19.202850"; cov "0.409091"; +chr13 Cufflinks transcript 9169898 9172437 1000 + . gene_id "CUFF.50509"; transcript_id "CUFF.50509.1"; FPKM "41.4918721248"; frac "1.000000"; conf_lo "16.471332"; conf_hi "66.512412"; cov "2.651786"; +chr13 Cufflinks exon 9169898 9169928 1000 + . gene_id "CUFF.50509"; transcript_id "CUFF.50509.1"; exon_number "1"; FPKM "41.4918721248"; frac "1.000000"; conf_lo "16.471332"; conf_hi "66.512412"; cov "2.651786"; +chr13 Cufflinks exon 9172357 9172437 1000 + . gene_id "CUFF.50509"; transcript_id "CUFF.50509.1"; exon_number "2"; FPKM "41.4918721248"; frac "1.000000"; conf_lo "16.471332"; conf_hi "66.512412"; cov "2.651786"; +chr13 Cufflinks transcript 9353602 9373527 1000 - . gene_id "CUFF.50527"; transcript_id "CUFF.50527.1"; FPKM "16.2485653076"; frac "1.000000"; conf_lo "0.000000"; conf_hi "35.010792"; cov "1.038462"; +chr13 Cufflinks exon 9353602 9353648 1000 - . gene_id "CUFF.50527"; transcript_id "CUFF.50527.1"; exon_number "1"; FPKM "16.2485653076"; frac "1.000000"; conf_lo "0.000000"; conf_hi "35.010792"; cov "1.038462"; +chr13 Cufflinks exon 9373497 9373527 1000 - . gene_id "CUFF.50527"; transcript_id "CUFF.50527.1"; exon_number "2"; FPKM "16.2485653076"; frac "1.000000"; conf_lo "0.000000"; conf_hi "35.010792"; cov "1.038462"; +chr13 Cufflinks transcript 9586173 9593034 1000 - . gene_id "CUFF.50563"; transcript_id "CUFF.50563.1"; FPKM "10.3039682439"; frac "1.000000"; conf_lo "0.000000"; conf_hi "24.875980"; cov "0.658537"; +chr13 Cufflinks exon 9586173 9586218 1000 - . gene_id "CUFF.50563"; transcript_id "CUFF.50563.1"; exon_number "1"; FPKM "10.3039682439"; frac "1.000000"; conf_lo "0.000000"; conf_hi "24.875980"; cov "0.658537"; +chr13 Cufflinks exon 9592999 9593034 1000 - . gene_id "CUFF.50563"; transcript_id "CUFF.50563.1"; exon_number "2"; FPKM "10.3039682439"; frac "1.000000"; conf_lo "0.000000"; conf_hi "24.875980"; cov "0.658537"; --- /dev/null +++ b/tools/filters/gff/gff_filter_by_attribute.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python +# This tool takes a gff file as input and creates filters on attributes based on certain properties. +# The tool will skip over invalid lines within the file, informing the user about the number of lines skipped. +# TODO: much of this code is copied from the Filter1 tool (filtering.py in tools/stats/). The commonalities should be +# abstracted and leveraged in each filtering tool. + +from __future__ import division +import sys, re, os.path + +# Older py compatibility +try: + set() +except: + from sets import Set as set + +assert sys.version_info[:2] >= ( 2, 4 ) + +def get_operands( filter_condition ): + # Note that the order of all_operators is important + items_to_strip = ['+', '-', '**', '*', '//', '/', '%', '<<', '>>', '&', '|', '^', '~', '<=', '<', '>=', '>', '==', '!=', '<>', ' and ', ' or ', ' not ', ' is ', ' is not ', ' in ', ' not in '] + for item in items_to_strip: + if filter_condition.find( item ) >= 0: + filter_condition = filter_condition.replace( item, ' ' ) + operands = set( filter_condition.split( ' ' ) ) + return operands + +def stop_err( msg ): + sys.stderr.write( msg ) + sys.exit() + +in_fname = sys.argv[1] +out_fname = sys.argv[2] +attribute_type = sys.argv[3] +attribute_name = sys.argv[4] +cond_text = sys.argv[5] + +# Unescape if input has been escaped +mapped_str = { + '__lt__': '<', + '__le__': '<=', + '__eq__': '==', + '__ne__': '!=', + '__gt__': '>', + '__ge__': '>=', + '__sq__': '\'', + '__dq__': '"', +} +for key, value in mapped_str.items(): + cond_text = cond_text.replace( key, value ) + +# Condition text is 'attribute meets condition.' +cond_text = attribute_name + cond_text + +# Attempt to determine if the condition includes executable stuff and, if so, exit +secured = dir() +operands = get_operands(cond_text) +for operand in operands: + try: + check = int( operand ) + except: + if operand in secured: + stop_err( "Illegal value '%s' in condition '%s'" % ( operand, cond_text ) ) + +# Set up assignment. +assignment = "%s = attributes.get('%s', None)" % ( attribute_name, attribute_name ) + +# Set up type casting based on attribute type. +type_cast = "%s = %s(%s)" % ( attribute_name, attribute_type, attribute_name) + +# Stats +skipped_lines = 0 +first_invalid_line = 0 +invalid_line = None +lines_kept = 0 +total_lines = 0 +out = open( out_fname, 'wt' ) + +# Read and filter input file, skipping invalid lines +code = ''' +for i, line in enumerate( file( in_fname ) ): + total_lines += 1 + line = line.rstrip( '\\r\\n' ) + if not line or line.startswith( '#' ): + skipped_lines += 1 + if not invalid_line: + first_invalid_line = i + 1 + invalid_line = line + continue + try: + # GTF format: chrom source, name, chromStart, chromEnd, score, strand, frame, attributes. + # Attributes format: name1 "value1" ; name2 "value2" ; ... + elems = line.split( '\t' ) + attributes_list = elems[8].split(";") + attributes = {} + for name_value_pair in attributes_list: + pair = name_value_pair.strip().split(" ") + if pair == '': + continue + name = pair[0].strip() + if name == '': + continue + # Need to strip double quote from values + value = pair[1].strip(" \\"") + attributes[name] = value + %s + if %s: + %s + if %s: + lines_kept += 1 + print >> out, line + except Exception, e: + skipped_lines += 1 + if not invalid_line: + first_invalid_line = i + 1 + invalid_line = line +''' % ( assignment, attribute_name, type_cast, cond_text ) + + +valid_filter = True +try: + exec code +except Exception, e: + out.close() + if str( e ).startswith( 'invalid syntax' ): + valid_filter = False + stop_err( 'Filter condition "%s" likely invalid. See tool tips, syntax and examples.' % cond_text ) + else: + stop_err( str( e ) ) + +if valid_filter: + out.close() + valid_lines = total_lines - skipped_lines + print 'Filtering with %s, ' % ( cond_text ) + if valid_lines > 0: + print 'kept %4.2f%% of %d lines.' % ( 100.0*lines_kept/valid_lines, total_lines ) + else: + print 'Possible invalid filter condition "%s" or non-existent column referenced. See tool tips, syntax and examples.' % cond_text + if skipped_lines > 0: + print 'Skipped %d invalid lines starting at line #%d: "%s"' % ( skipped_lines, first_invalid_line, invalid_line ) --- a/tools/ngs_rna/gff_filtering.xml +++ /dev/null @@ -1,62 +0,0 @@ -<tool id="gff_filtering" name="Filter GFF" version="0.1"> - <description>file on any attribute using simple expressions</description> - <command interpreter="python"> - gff_filtering.py $input $out_file1 "$attribute_type" "$attribute_name" "$cond" - </command> - <inputs> - <param format="gff" name="input" type="data" label="Filter" help="Query missing? See TIP below."/> - <param name="attribute_name" type="select" label="Attribute name" help=""> - <options from_dataset="input"> - <column name="name" index="8"/> - <column name="value" index="8"/> - <filter type="attribute_value_splitter" pair_separator=";" column="8"/> - </options> - </param> - <param name="attribute_type" type="select" label="Attribute type"> - <option value="float">Float</option> - <option value="int">Integer</option> - <option value="str">String</option> - </param> - <param name="cond" size="40" type="text" value=">0" label="With following condition" help="Double equal signs, ==, must be used as shown above. To filter for an arbitrary string, use the Select tool."> - <validator type="empty_field" message="Enter a valid filtering condition, see syntax and examples below."/> - </param> - </inputs> - <outputs> - <data format="input" name="out_file1" metadata_source="input"/> - </outputs> - <tests> - <test> - <param name="input" value="gff_filtering_in1.gff"/> - <param name="attribute_name" value="conf_lo"/> - <param name="attribute_type" value="float"/> - <param name="cond" value=">0"/> - <output name="out_file1" file="gff_filtering_out1.gff"/> - </test> - </tests> - - <help> - -.. class:: warningmark - -Double equal signs, ==, must be used as *"equal to"* (e.g., **c1 == 'chr22'**) - -.. class:: infomark - -**TIP:** Attempting to apply a filtering condition may throw exceptions if the data type (e.g., string, integer) in every line of the attribute being filtered is not appropriate for the condition (e.g., attempting certain numerical calculations on strings). If an exception is thrown when applying the condition to a line, that line is skipped as invalid for the filter condition. The number of invalid skipped lines is documented in the resulting history item as a "Condition/data issue". - -.. class:: infomark - -**TIP:** If your data is not TAB delimited, use *Text Manipulation->Convert* - ------ - -**Syntax** - -The filter tool allows you to restrict the dataset using simple conditional statements. - -- Make sure that multi-character operators contain no white space ( e.g., **<=** is valid while **< =** is not valid ) -- When using 'equal-to' operator **double equal sign '==' must be used** ( e.g., **attribute_name=='chr1'** ) -- Non-numerical values must be included in single or double quotes ( e.g., **attribute_name=='XX22'** ) - -</help> -</tool> --- a/tools/extract/extract_GFF_Features.xml +++ /dev/null @@ -1,114 +0,0 @@ -<tool id="Extract_features1" name="Extract features"> - <description> from GFF file</description> - <command interpreter="python">extract_GFF_Features.py $input1 $out_file1 ${column_choice.col} ${column_choice.feature}</command> - <inputs> - <param format="gff" name="input1" type="data" label="Select GFF data"/> - <conditional name="column_choice"> - <param name="col" type="select" label="From"> - <option value="0" selected="true">Column 1 / Sequence name</option> - <option value="1">Column 2 / Source</option> - <option value="2">Column 3 / Feature</option> - <option value="6">Column 7 / Strand</option> - <option value="7">Column 8 / Frame</option> - </param> - <when value="0"> - <param name="feature" type="select" multiple="true" label="Extract features" help="Multi-select list - hold the appropriate key while clicking to select multiple columns"> - <options from_dataset="input1"> - <column name="name" index="0"/> - <column name="value" index="0"/> - <filter type="unique_value" name="unique" column="0"/> - </options> - </param> - </when> - <when value="1"> - <param name="feature" type="select" multiple="true" label="Extract features" help="Multi-select list - hold the appropriate key while clicking to select multiple columns"> - <options from_dataset="input1"> - <column name="name" index="1"/> - <column name="value" index="1"/> - <filter type="unique_value" name="unique" column="1"/> - </options> - </param> - </when> - <when value="2"> - <param name="feature" type="select" multiple="true" label="Extract features" help="Multi-select list - hold the appropriate key while clicking to select multiple columns"> - <options from_dataset="input1"> - <column name="name" index="2"/> - <column name="value" index="2"/> - <filter type="unique_value" name="unique" column="2"/> - </options> - </param> - </when> - <when value="6"> - <param name="feature" type="select" multiple="true" label="Extract features" help="Multi-select list - hold the appropriate key while clicking to select multiple columns"> - <options from_dataset="input1"> - <column name="name" index="6"/> - <column name="value" index="6"/> - <filter type="unique_value" name="unique" column="6"/> - </options> - </param> - </when> - <when value="7"> - <param name="feature" type="select" multiple="true" label="Extract features" help="Multi-select list - hold the appropriate key while clicking to select multiple columns"> - <options from_dataset="input1"> - <column name="name" index="7"/> - <column name="value" index="7"/> - <filter type="unique_value" name="unique" column="7"/> - </options> - </param> - </when> - </conditional> - </inputs> - <outputs> - <data format="gff" name="out_file1" /> - </outputs> - <tests> - <test> - <param name="input1" value="5.gff"/> - <param name="col" value="0" /> - <param name="feature" value="chr5,chr6,chr7,chr8" /> - <output name="out_file1" file="Extract_features1_out.gff"/> - </test> - </tests> - <help> - -**What it does** - -This tool extracts selected features from GFF data. - ------ - -**Example** - -Selecting **promoter** from the following GFF data:: - - chr22 GeneA enhancer 10000000 10001000 500 + . TGA - chr22 GeneA promoter 10010000 10010100 900 + . TGA - chr22 GeneB promoter 10020000 10025000 400 - . TGB - chr22 GeneB CCDS2220 10030000 10065000 800 - . TGB - -will produce the following output:: - - chr22 GeneA promoter 10010000 10010100 900 + . TGA - chr22 GeneB promoter 10020000 10025000 400 - . TGB - ----- - -.. class:: infomark - -**About formats** - -**GFF format** General Feature Format is a format for describing genes and other features associated with DNA, RNA and Protein sequences. GFF lines have nine tab-separated fields:: - - 1. seqname - Must be a chromosome or scaffold. - 2. source - The program that generated this feature. - 3. feature - The name of this type of feature. Some examples of standard feature types are "CDS", "start_codon", "stop_codon", and "exon". - 4. start - The starting position of the feature in the sequence. The first base is numbered 1. - 5. end - The ending position of the feature (inclusive). - 6. score - A score between 0 and 1000. If there is no score value, enter ".". - 7. strand - Valid entries include '+', '-', or '.' (for don't know/care). - 8. frame - If the feature is a coding exon, frame should be a number between 0-2 that represents the reading frame of the first base. If the feature is not a coding exon, the value should be '.'. - 9. group - All lines with the same group are linked together into a single item. - - - </help> -</tool> --- a/test-data/gff_filtering_in1.gff +++ /dev/null @@ -1,200 +0,0 @@ -chr1 Cufflinks exon 21199802 21199861 1000 + . gene_id "CUFF.1383"; transcript_id "CUFF.1383.1"; exon_number "1"; FPKM "5.0037092300"; frac "1.000000"; conf_lo "0.000000"; conf_hi "15.011128"; cov "0.284211"; -chr1 Cufflinks transcript 55716264 55716295 1000 . . gene_id "CUFF.5021"; transcript_id "CUFF.5021.1"; FPKM "29.7095235531"; frac "1.000000"; conf_lo "0.000000"; conf_hi "71.725135"; cov "1.687500"; -chr1 Cufflinks transcript 74904128 74904154 1000 . . gene_id "CUFF.7563"; transcript_id "CUFF.7563.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr1 Cufflinks exon 134487086 134487123 1000 . . gene_id "CUFF.11837"; transcript_id "CUFF.11837.1"; exon_number "1"; FPKM "25.0185461500"; frac "1.000000"; conf_lo "0.000000"; conf_hi "60.400113"; cov "1.421053"; -chr1 Cufflinks exon 136200923 136200959 1000 . . gene_id "CUFF.12099"; transcript_id "CUFF.12099.1"; exon_number "1"; FPKM "38.5420846095"; frac "1.000000"; conf_lo "0.000000"; conf_hi "83.046650"; cov "2.189189"; -chr1 Cufflinks transcript 138116837 138116866 1000 . . gene_id "CUFF.12557"; transcript_id "CUFF.12557.1"; FPKM "31.6901584567"; frac "1.000000"; conf_lo "0.000000"; conf_hi "76.506810"; cov "1.800000"; -chr1 Cufflinks exon 152240694 152240779 1000 . . gene_id "CUFF.13107"; transcript_id "CUFF.13107.1"; exon_number "1"; FPKM "16.5820596576"; frac "1.000000"; conf_lo "0.000000"; conf_hi "35.729373"; cov "0.941860"; -chr1 Cufflinks exon 157633998 157634024 1000 . . gene_id "CUFF.13967"; transcript_id "CUFF.13967.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr1 Cufflinks exon 167704819 167704854 1000 . . gene_id "CUFF.15347"; transcript_id "CUFF.15347.1"; exon_number "1"; FPKM "26.4084653806"; frac "1.000000"; conf_lo "0.000000"; conf_hi "63.755675"; cov "1.500000"; -chr1 Cufflinks transcript 184245403 184245429 1000 . . gene_id "CUFF.17679"; transcript_id "CUFF.17679.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr10 Cufflinks exon 12731734 12731826 1000 . . gene_id "CUFF.19287"; transcript_id "CUFF.19287.1"; exon_number "1"; FPKM "10.2226317602"; frac "1.000000"; conf_lo "0.000000"; conf_hi "24.679616"; cov "0.580645"; -chr10 Cufflinks transcript 42305464 42305515 1000 . . gene_id "CUFF.21709"; transcript_id "CUFF.21709.1"; FPKM "18.2827837250"; frac "1.000000"; conf_lo "0.000000"; conf_hi "44.138544"; cov "1.038462"; -chr10 Cufflinks exon 52431636 52431662 1000 . . gene_id "CUFF.22495"; transcript_id "CUFF.22495.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr10 Cufflinks transcript 62044837 62045189 1000 . . gene_id "CUFF.23531"; transcript_id "CUFF.23531.1"; FPKM "19.5178121606"; frac "1.000000"; conf_lo "9.264456"; conf_hi "29.771168"; cov "1.108611"; -chr10 Cufflinks transcript 75372919 75373002 1000 . . gene_id "CUFF.24985"; transcript_id "CUFF.24985.1"; FPKM "124.4970510798"; frac "1.000000"; conf_lo "71.411330"; conf_hi "177.582772"; cov "7.071429"; -chr10 Cufflinks transcript 80362428 80363292 1000 - . gene_id "CUFF.26065"; transcript_id "CUFF.26065.1"; FPKM "43.6170921216"; frac "1.000000"; conf_lo "32.260169"; conf_hi "54.974016"; cov "2.477449"; -chr10 Cufflinks exon 87908564 87908597 1000 + . gene_id "CUFF.27209"; transcript_id "CUFF.27209.1"; exon_number "2"; FPKM "11.4913582411"; frac "1.000000"; conf_lo "0.000000"; conf_hi "30.264098"; cov "0.652709"; -chr10 Cufflinks exon 89142681 89142707 1000 . . gene_id "CUFF.27307"; transcript_id "CUFF.27307.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr10 Cufflinks exon 93425781 93425807 1000 . . gene_id "CUFF.28101"; transcript_id "CUFF.28101.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr10 Cufflinks exon 108207916 108207986 1000 . . gene_id "CUFF.29319"; transcript_id "CUFF.29319.1"; exon_number "1"; FPKM "13.3902077986"; frac "1.000000"; conf_lo "0.000000"; conf_hi "32.326821"; cov "0.760563"; -chr10 Cufflinks transcript 117583959 117584039 1000 . . gene_id "CUFF.30522"; transcript_id "CUFF.30522.1"; FPKM "17.6056435870"; frac "1.000000"; conf_lo "0.000000"; conf_hi "37.934890"; cov "1.000000"; -chr11 Cufflinks transcript 3357264 3357347 1000 . . gene_id "CUFF.32520"; transcript_id "CUFF.32520.1"; FPKM "16.9768706018"; frac "1.000000"; conf_lo "0.000000"; conf_hi "36.580072"; cov "0.964286"; -chr11 Cufflinks transcript 5005248 5005351 1000 . . gene_id "CUFF.33024"; transcript_id "CUFF.33024.1"; FPKM "9.1413918625"; frac "1.000000"; conf_lo "0.000000"; conf_hi "22.069272"; cov "0.519231"; -chr11 Cufflinks transcript 7904565 7904642 1000 . . gene_id "CUFF.33508"; transcript_id "CUFF.33508.1"; FPKM "61.6484988869"; frac "1.000000"; conf_lo "22.882428"; conf_hi "100.414569"; cov "3.501633"; -chr11 Cufflinks exon 49932116 49932142 1000 . . gene_id "CUFF.37546"; transcript_id "CUFF.37546.1"; exon_number "1"; FPKM "17.6056435870"; frac "1.000000"; conf_lo "0.000000"; conf_hi "52.816931"; cov "1.000000"; -chr11 Cufflinks transcript 60046420 60046446 1000 . . gene_id "CUFF.39152"; transcript_id "CUFF.39152.1"; FPKM "52.8169307611"; frac "1.000000"; conf_lo "0.000000"; conf_hi "113.804669"; cov "3.000000"; -chr11 Cufflinks exon 78140156 78140259 1000 . . gene_id "CUFF.43148"; transcript_id "CUFF.43148.1"; exon_number "1"; FPKM "54.8483511750"; frac "1.000000"; conf_lo "23.181641"; conf_hi "86.515061"; cov "3.115385"; -chr11 Cufflinks transcript 79846512 79846547 1000 . . gene_id "CUFF.43570"; transcript_id "CUFF.43570.1"; FPKM "26.4084653806"; frac "1.000000"; conf_lo "0.000000"; conf_hi "63.755675"; cov "1.500000"; -chr11 Cufflinks transcript 85583926 85583952 1000 . . gene_id "CUFF.44478"; transcript_id "CUFF.44478.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr11 Cufflinks transcript 98554214 98554301 1000 . . gene_id "CUFF.46823"; transcript_id "CUFF.46823.1"; FPKM "10.8034631102"; frac "1.000000"; conf_lo "0.000000"; conf_hi "26.081867"; cov "0.613636"; -chr11 Cufflinks transcript 100797512 100797539 1000 . . gene_id "CUFF.47191"; transcript_id "CUFF.47191.1"; FPKM "33.9537412036"; frac "1.000000"; conf_lo "0.000000"; conf_hi "81.971583"; cov "1.928571"; -chr11 Cufflinks exon 105616462 105616737 1000 . . gene_id "CUFF.48385"; transcript_id "CUFF.48385.1"; exon_number "1"; FPKM "18.9452034252"; frac "1.000000"; conf_lo "7.520816"; conf_hi "30.369591"; cov "1.076087"; -chr11 Cufflinks transcript 106985457 106985483 1000 . . gene_id "CUFF.48949"; transcript_id "CUFF.48949.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr11 Cufflinks exon 120257794 120257821 1000 . . gene_id "CUFF.51205"; transcript_id "CUFF.51205.1"; exon_number "1"; FPKM "50.9306118054"; frac "1.000000"; conf_lo "0.000000"; conf_hi "109.740217"; cov "2.892857"; -chr12 Cufflinks transcript 16542765 16542791 1000 . . gene_id "CUFF.52907"; transcript_id "CUFF.52907.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr12 Cufflinks exon 21319385 21319483 1000 . . gene_id "CUFF.53189"; transcript_id "CUFF.53189.1"; exon_number "1"; FPKM "9.6030783202"; frac "1.000000"; conf_lo "0.000000"; conf_hi "23.183882"; cov "0.545455"; -chr12 Cufflinks transcript 30469129 30469156 1000 . . gene_id "CUFF.53733"; transcript_id "CUFF.53733.1"; FPKM "33.9537412036"; frac "1.000000"; conf_lo "0.000000"; conf_hi "81.971583"; cov "1.928571"; -chr12 Cufflinks transcript 30557416 30557442 1000 . . gene_id "CUFF.53863"; transcript_id "CUFF.53863.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr12 Cufflinks exon 30701762 30702509 1000 . . gene_id "CUFF.53897"; transcript_id "CUFF.53897.1"; exon_number "1"; FPKM "48.9333329111"; frac "1.000000"; conf_lo "37.780391"; conf_hi "60.086275"; cov "2.779412"; -chr12 Cufflinks transcript 56895077 56895103 1000 . . gene_id "CUFF.55817"; transcript_id "CUFF.55817.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr12 Cufflinks transcript 81915713 81915797 1000 . . gene_id "CUFF.58203"; transcript_id "CUFF.58203.1"; FPKM "22.3695236165"; frac "1.000000"; conf_lo "0.000000"; conf_hi "44.739047"; cov "1.270588"; -chr12 Cufflinks transcript 118458135 118458232 1000 . . gene_id "CUFF.63640"; transcript_id "CUFF.63640.1"; FPKM "9.7010689153"; frac "1.000000"; conf_lo "0.000000"; conf_hi "23.420452"; cov "0.551020"; -chr13 Cufflinks exon 8262302 8262372 1000 . . gene_id "CUFF.64064"; transcript_id "CUFF.64064.1"; exon_number "1"; FPKM "13.3902077986"; frac "1.000000"; conf_lo "0.000000"; conf_hi "32.326821"; cov "0.760563"; -chr13 Cufflinks transcript 14110852 14110956 1000 . . gene_id "CUFF.64684"; transcript_id "CUFF.64684.1"; FPKM "13.5814964814"; frac "1.000000"; conf_lo "0.000000"; conf_hi "29.264058"; cov "0.771429"; -chr13 Cufflinks transcript 14146567 14146593 1000 . . gene_id "CUFF.64702"; transcript_id "CUFF.64702.1"; FPKM "17.6056435870"; frac "1.000000"; conf_lo "0.000000"; conf_hi "52.816931"; cov "1.000000"; -chr13 Cufflinks transcript 14564150 14564243 1000 . . gene_id "CUFF.64894"; transcript_id "CUFF.64894.1"; FPKM "15.1708205378"; frac "1.000000"; conf_lo "0.000000"; conf_hi "32.688575"; cov "0.861702"; -chr13 Cufflinks transcript 17823162 17823188 1000 . . gene_id "CUFF.65082"; transcript_id "CUFF.65082.1"; FPKM "52.8169307611"; frac "1.000000"; conf_lo "0.000000"; conf_hi "113.804669"; cov "3.000000"; -chr13 Cufflinks transcript 29757640 29757666 1000 . . gene_id "CUFF.65972"; transcript_id "CUFF.65972.1"; FPKM "70.4225743482"; frac "1.000000"; conf_lo "0.000000"; conf_hi "140.845149"; cov "4.000000"; -chr13 Cufflinks transcript 42402998 42403051 1000 . . gene_id "CUFF.66816"; transcript_id "CUFF.66816.1"; FPKM "26.4084653806"; frac "1.000000"; conf_lo "0.000000"; conf_hi "56.902335"; cov "1.500000"; -chr13 Cufflinks transcript 42853325 42853406 1000 . . gene_id "CUFF.66850"; transcript_id "CUFF.66850.1"; FPKM "17.3909406165"; frac "1.000000"; conf_lo "0.000000"; conf_hi "37.472269"; cov "0.987805"; -chr13 Cufflinks exon 42990504 42990546 1000 . . gene_id "CUFF.66994"; transcript_id "CUFF.66994.1"; exon_number "1"; FPKM "33.1641193151"; frac "1.000000"; conf_lo "0.000000"; conf_hi "71.458746"; cov "1.883721"; -chr13 Cufflinks exon 49159496 49159569 1000 . . gene_id "CUFF.67788"; transcript_id "CUFF.67788.1"; exon_number "1"; FPKM "44.9657653777"; frac "1.000000"; conf_lo "10.974842"; conf_hi "78.956689"; cov "2.554054"; -chr13 Cufflinks exon 49243161 49243187 1000 + . gene_id "CUFF.67842"; transcript_id "CUFF.67842.1"; exon_number "2"; FPKM "17.3246767151"; frac "1.000000"; conf_lo "0.000000"; conf_hi "35.848677"; cov "0.984041"; -chr13 Cufflinks transcript 74671517 74671579 1000 . . gene_id "CUFF.70454"; transcript_id "CUFF.70454.1"; FPKM "18.8363155420"; frac "1.000000"; conf_lo "0.000000"; conf_hi "42.679570"; cov "1.069902"; -chr13 Cufflinks exon 100759121 100759147 1000 . . gene_id "CUFF.72728"; transcript_id "CUFF.72728.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr13 Cufflinks transcript 100200304 100200330 1000 . . gene_id "CUFF.73108"; transcript_id "CUFF.73108.1"; FPKM "123.2395051093"; frac "1.000000"; conf_lo "30.079196"; conf_hi "216.399814"; cov "7.000000"; -chr13 Cufflinks exon 107766857 107766915 1000 . . gene_id "CUFF.73428"; transcript_id "CUFF.73428.1"; exon_number "1"; FPKM "16.1136398932"; frac "1.000000"; conf_lo "0.000000"; conf_hi "38.901768"; cov "0.915254"; -chr13 Cufflinks transcript 115623552 115623640 1000 . . gene_id "CUFF.74362"; transcript_id "CUFF.74362.1"; FPKM "21.3641517686"; frac "1.000000"; conf_lo "0.000000"; conf_hi "42.728304"; cov "1.213483"; -chr14 Cufflinks transcript 31651249 31651275 1000 . . gene_id "CUFF.77182"; transcript_id "CUFF.77182.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr14 Cufflinks transcript 31949103 31949152 1000 . . gene_id "CUFF.77316"; transcript_id "CUFF.77316.1"; FPKM "85.5634278330"; frac "1.000000"; conf_lo "28.521143"; conf_hi "142.605713"; cov "4.860000"; -chr14 Cufflinks transcript 32190589 32190685 1000 . . gene_id "CUFF.77438"; transcript_id "CUFF.77438.1"; FPKM "14.7016199026"; frac "1.000000"; conf_lo "0.000000"; conf_hi "31.677588"; cov "0.835052"; -chr14 Cufflinks exon 55013239 55013265 1000 . . gene_id "CUFF.79372"; transcript_id "CUFF.79372.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr14 Cufflinks exon 55250464 55250514 1000 . . gene_id "CUFF.79616"; transcript_id "CUFF.79616.1"; exon_number "1"; FPKM "18.6412696804"; frac "1.000000"; conf_lo "0.000000"; conf_hi "45.004006"; cov "1.058824"; -chr14 Cufflinks exon 67604227 67604668 1000 . . gene_id "CUFF.81446"; transcript_id "CUFF.81446.1"; exon_number "1"; FPKM "123.6776546104"; frac "1.000000"; conf_lo "100.611653"; conf_hi "146.743656"; cov "7.024887"; -chr14 Cufflinks exon 75165582 75165744 1000 . . gene_id "CUFF.82088"; transcript_id "CUFF.82088.1"; exon_number "1"; FPKM "20.4139057543"; frac "1.000000"; conf_lo "4.982443"; conf_hi "35.845368"; cov "1.159509"; -chr15 Cufflinks transcript 8254591 8254734 1000 . . gene_id "CUFF.85556"; transcript_id "CUFF.85556.1"; FPKM "13.2042326903"; frac "1.000000"; conf_lo "0.000000"; conf_hi "26.408465"; cov "0.750000"; -chr15 Cufflinks transcript 34371407 34371433 1000 . . gene_id "CUFF.87246"; transcript_id "CUFF.87246.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr15 Cufflinks exon 65980225 65980255 1000 + . gene_id "CUFF.89502"; transcript_id "CUFF.89502.1"; exon_number "2"; FPKM "14.1193775302"; frac "1.000000"; conf_lo "0.000000"; conf_hi "30.423030"; cov "0.801980"; -chr15 Cufflinks transcript 85895971 85896018 1000 . . gene_id "CUFF.92834"; transcript_id "CUFF.92834.1"; FPKM "19.8063490354"; frac "1.000000"; conf_lo "0.000000"; conf_hi "47.816756"; cov "1.125000"; -chr15 Cufflinks exon 90828279 90828371 1000 . . gene_id "CUFF.93426"; transcript_id "CUFF.93426.1"; exon_number "1"; FPKM "15.3339476403"; frac "1.000000"; conf_lo "0.000000"; conf_hi "33.040065"; cov "0.870968"; -chr15 Cufflinks exon 99013431 99013472 1000 . . gene_id "CUFF.94604"; transcript_id "CUFF.94604.1"; exon_number "1"; FPKM "22.6358274691"; frac "1.000000"; conf_lo "0.000000"; conf_hi "54.647722"; cov "1.285714"; -chr15 Cufflinks transcript 102336976 102337075 1000 . . gene_id "CUFF.95298"; transcript_id "CUFF.95298.1"; FPKM "9.5070475370"; frac "1.000000"; conf_lo "0.000000"; conf_hi "22.952043"; cov "0.540000"; -chr16 Cufflinks transcript 10417989 10425202 1000 - . gene_id "CUFF.97232"; transcript_id "CUFF.97232.1"; FPKM "21.1642179587"; frac "1.000000"; conf_lo "0.000000"; conf_hi "44.805591"; cov "1.202127"; -chr16 Cufflinks transcript 40788986 40789084 1000 . . gene_id "CUFF.101774"; transcript_id "CUFF.101774.1"; FPKM "9.6030783202"; frac "1.000000"; conf_lo "0.000000"; conf_hi "23.183882"; cov "0.545455"; -chr16 Cufflinks transcript 57154027 57154067 1000 . . gene_id "CUFF.103364"; transcript_id "CUFF.103364.1"; FPKM "162.3154457537"; frac "1.000000"; conf_lo "75.554191"; conf_hi "249.076701"; cov "9.219512"; -chr16 Cufflinks exon 74862302 74862560 1000 . . gene_id "CUFF.105450"; transcript_id "CUFF.105450.1"; exon_number "1"; FPKM "11.0120241741"; frac "1.000000"; conf_lo "2.020744"; conf_hi "20.003304"; cov "0.625483"; -chr16 Cufflinks exon 91023578 91023669 1000 . . gene_id "CUFF.106912"; transcript_id "CUFF.106912.1"; exon_number "1"; FPKM "10.3337473228"; frac "1.000000"; conf_lo "0.000000"; conf_hi "24.947873"; cov "0.586957"; -chr16 Cufflinks transcript 98168779 98168914 1000 . . gene_id "CUFF.107834"; transcript_id "CUFF.107834.1"; FPKM "24.4666664555"; frac "1.000000"; conf_lo "5.971605"; conf_hi "42.961728"; cov "1.389706"; -chr17 Cufflinks exon 8483212 8483268 1000 . . gene_id "CUFF.108498"; transcript_id "CUFF.108498.1"; exon_number "1"; FPKM "50.0370923000"; frac "1.000000"; conf_lo "9.181978"; conf_hi "90.892207"; cov "2.842105"; -chr17 Cufflinks transcript 17478023 17478102 1000 . . gene_id "CUFF.109264"; transcript_id "CUFF.109264.1"; FPKM "23.7676188425"; frac "1.000000"; conf_lo "0.000000"; conf_hi "47.535238"; cov "1.350000"; -chr17 Cufflinks exon 24611086 24611151 1000 . . gene_id "CUFF.110088"; transcript_id "CUFF.110088.1"; exon_number "1"; FPKM "21.6069262205"; frac "1.000000"; conf_lo "0.000000"; conf_hi "46.556456"; cov "1.227273"; -chr17 Cufflinks exon 30355791 30355913 1000 . . gene_id "CUFF.111759"; transcript_id "CUFF.111759.1"; exon_number "1"; FPKM "19.3232673516"; frac "1.000000"; conf_lo "2.040012"; conf_hi "36.606523"; cov "1.097561"; -chr17 Cufflinks exon 31608702 31608787 1000 . . gene_id "CUFF.111943"; transcript_id "CUFF.111943.1"; exon_number "1"; FPKM "16.5820596576"; frac "1.000000"; conf_lo "0.000000"; conf_hi "35.729373"; cov "0.941860"; -chr17 Cufflinks transcript 32414547 32414573 1000 . . gene_id "CUFF.112117"; transcript_id "CUFF.112117.1"; FPKM "52.8169307611"; frac "1.000000"; conf_lo "0.000000"; conf_hi "113.804669"; cov "3.000000"; -chr17 Cufflinks transcript 33245409 33245463 1000 . . gene_id "CUFF.112363"; transcript_id "CUFF.112363.1"; FPKM "17.2855409764"; frac "1.000000"; conf_lo "0.000000"; conf_hi "41.730987"; cov "0.981818"; -chr17 Cufflinks transcript 56750339 56750374 1000 . . gene_id "CUFF.115617"; transcript_id "CUFF.115617.1"; FPKM "52.8169307611"; frac "1.000000"; conf_lo "0.000000"; conf_hi "105.633862"; cov "3.000000"; -chr17 Cufflinks transcript 57144800 57144939 1000 . . gene_id "CUFF.115679"; transcript_id "CUFF.115679.1"; FPKM "13.5814964814"; frac "1.000000"; conf_lo "0.000000"; conf_hi "27.162993"; cov "0.771429"; -chr17 Cufflinks exon 71694628 71694708 1000 . . gene_id "CUFF.117117"; transcript_id "CUFF.117117.1"; exon_number "1"; FPKM "23.4741914494"; frac "1.000000"; conf_lo "0.000000"; conf_hi "46.948383"; cov "1.333333"; -chr17 Cufflinks transcript 71698227 71698263 1000 . . gene_id "CUFF.117119"; transcript_id "CUFF.117119.1"; FPKM "25.6947230730"; frac "1.000000"; conf_lo "0.000000"; conf_hi "62.032549"; cov "1.459459"; -chr17 Cufflinks exon 87862079 87862105 1000 . . gene_id "CUFF.118851"; transcript_id "CUFF.118851.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr18 Cufflinks transcript 39571718 39571880 1000 . . gene_id "CUFF.123569"; transcript_id "CUFF.123569.1"; FPKM "20.4139057543"; frac "1.000000"; conf_lo "4.982443"; conf_hi "35.845368"; cov "1.159509"; -chr18 Cufflinks exon 46452826 46452864 1000 . . gene_id "CUFF.124197"; transcript_id "CUFF.124197.1"; exon_number "1"; FPKM "48.7540899334"; frac "1.000000"; conf_lo "0.000000"; conf_hi "97.508180"; cov "2.769231"; -chr18 Cufflinks exon 50151390 50151416 1000 . . gene_id "CUFF.124439"; transcript_id "CUFF.124439.1"; exon_number "1"; FPKM "17.5638395629"; frac "1.000000"; conf_lo "0.000000"; conf_hi "52.733298"; cov "0.997626"; -chr18 Cufflinks exon 65106749 65106787 1000 . . gene_id "CUFF.125675"; transcript_id "CUFF.125675.1"; exon_number "1"; FPKM "48.7540899334"; frac "1.000000"; conf_lo "0.000000"; conf_hi "97.508180"; cov "2.769231"; -chr18 Cufflinks transcript 65202282 65202424 1000 . . gene_id "CUFF.125729"; transcript_id "CUFF.125729.1"; FPKM "13.2965699818"; frac "1.000000"; conf_lo "0.000000"; conf_hi "26.593140"; cov "0.755245"; -chr18 Cufflinks exon 69735254 69735280 1000 . . gene_id "CUFF.126371"; transcript_id "CUFF.126371.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr19 Cufflinks transcript 5370466 5370492 1000 . . gene_id "CUFF.129319"; transcript_id "CUFF.129319.1"; FPKM "52.8169307611"; frac "1.000000"; conf_lo "0.000000"; conf_hi "113.804669"; cov "3.000000"; -chr19 Cufflinks exon 17633088 17633203 1000 . . gene_id "CUFF.131333"; transcript_id "CUFF.131333.1"; exon_number "1"; FPKM "20.4893265884"; frac "1.000000"; conf_lo "2.163116"; conf_hi "38.815537"; cov "1.163793"; -chr19 Cufflinks transcript 41997624 41997859 1000 . . gene_id "CUFF.133569"; transcript_id "CUFF.133569.1"; FPKM "28.1988698132"; frac "1.000000"; conf_lo "13.125940"; conf_hi "43.271800"; cov "1.601695"; -chr19 Cufflinks transcript 53311236 53311262 1000 . . gene_id "CUFF.134885"; transcript_id "CUFF.134885.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr19 Cufflinks exon 56516515 56516684 1000 . . gene_id "CUFF.135203"; transcript_id "CUFF.135203.1"; exon_number "1"; FPKM "33.5542854247"; frac "1.000000"; conf_lo "14.181710"; conf_hi "52.926861"; cov "1.905882"; -chr2 Cufflinks transcript 3246910 3246936 1000 . . gene_id "CUFF.136019"; transcript_id "CUFF.136019.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr2 Cufflinks transcript 4543774 4543977 1000 . . gene_id "CUFF.136435"; transcript_id "CUFF.136435.1"; FPKM "37.2825393608"; frac "1.000000"; conf_lo "18.641270"; conf_hi "55.923809"; cov "2.117647"; -chr2 Cufflinks exon 7271328 7271354 1000 . . gene_id "CUFF.137407"; transcript_id "CUFF.137407.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr2 Cufflinks exon 11509202 11509287 1000 . . gene_id "CUFF.137559"; transcript_id "CUFF.137559.1"; exon_number "1"; FPKM "22.1094128768"; frac "1.000000"; conf_lo "0.000000"; conf_hi "44.218826"; cov "1.255814"; -chr2 Cufflinks transcript 30200331 30200938 1000 . . gene_id "CUFF.140289"; transcript_id "CUFF.140289.1"; FPKM "100.0741846001"; frac "1.000000"; conf_lo "82.383401"; conf_hi "117.764968"; cov "5.684211"; -chr2 Cufflinks transcript 49559781 49559842 1000 . . gene_id "CUFF.143035"; transcript_id "CUFF.143035.1"; FPKM "15.3339476403"; frac "1.000000"; conf_lo "0.000000"; conf_hi "37.019424"; cov "0.870968"; -chr2 Cufflinks transcript 78736720 78736746 1000 . . gene_id "CUFF.146383"; transcript_id "CUFF.146383.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr2 Cufflinks transcript 97470595 97470703 1000 . . gene_id "CUFF.148117"; transcript_id "CUFF.148117.1"; FPKM "17.4441239211"; frac "1.000000"; conf_lo "0.000000"; conf_hi "34.888248"; cov "0.990826"; -chr2 Cufflinks transcript 106644220 106644341 1000 . . gene_id "CUFF.148977"; transcript_id "CUFF.148977.1"; FPKM "27.2743167045"; frac "1.000000"; conf_lo "6.656871"; conf_hi "47.891762"; cov "1.549180"; -chr2 Cufflinks transcript 118960859 118961004 1000 . . gene_id "CUFF.150015"; transcript_id "CUFF.150015.1"; FPKM "9.7675145928"; frac "1.000000"; conf_lo "0.000000"; conf_hi "21.046069"; cov "0.554795"; -chr2 Cufflinks exon 125388931 125389219 1000 . . gene_id "CUFF.151331"; transcript_id "CUFF.151331.1"; exon_number "1"; FPKM "23.0274507817"; frac "1.000000"; conf_lo "10.718761"; conf_hi "35.336141"; cov "1.307958"; -chr2 Cufflinks transcript 145141669 145141755 1000 . . gene_id "CUFF.153993"; transcript_id "CUFF.153993.1"; FPKM "10.9276408471"; frac "1.000000"; conf_lo "0.000000"; conf_hi "26.381659"; cov "0.620690"; -chr2 Cufflinks exon 178035510 178035611 1000 . . gene_id "CUFF.158329"; transcript_id "CUFF.158329.1"; exon_number "1"; FPKM "9.3206348402"; frac "1.000000"; conf_lo "0.000000"; conf_hi "22.502003"; cov "0.529412"; -chr2 Cufflinks transcript 181047445 181047471 1000 . . gene_id "CUFF.158989"; transcript_id "CUFF.158989.1"; FPKM "17.6056435870"; frac "1.000000"; conf_lo "0.000000"; conf_hi "52.816931"; cov "1.000000"; -chr3 Cufflinks transcript 55664118 55664197 1000 . . gene_id "CUFF.163141"; transcript_id "CUFF.163141.1"; FPKM "11.8838094213"; frac "1.000000"; conf_lo "0.000000"; conf_hi "28.690054"; cov "0.675000"; -chr3 Cufflinks exon 66896354 66896433 1000 . . gene_id "CUFF.163935"; transcript_id "CUFF.163935.1"; exon_number "1"; FPKM "5.9419047106"; frac "1.000000"; conf_lo "0.000000"; conf_hi "17.825714"; cov "0.337500"; -chr3 Cufflinks transcript 80648745 80648771 1000 . . gene_id "CUFF.164995"; transcript_id "CUFF.164995.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr3 Cufflinks exon 107424385 107424452 1000 . . gene_id "CUFF.169311"; transcript_id "CUFF.169311.1"; exon_number "1"; FPKM "13.9809522603"; frac "1.000000"; conf_lo "0.000000"; conf_hi "33.753005"; cov "0.794118"; -chr3 Cufflinks transcript 130936639 130936898 1000 . . gene_id "CUFF.171349"; transcript_id "CUFF.171349.1"; FPKM "20.1110620975"; frac "1.000000"; conf_lo "7.983635"; conf_hi "32.238489"; cov "1.142308"; -chr3 Cufflinks exon 136592671 136592771 1000 . . gene_id "CUFF.171861"; transcript_id "CUFF.171861.1"; exon_number "1"; FPKM "32.9452142371"; frac "1.000000"; conf_lo "8.040973"; conf_hi "57.849455"; cov "1.871287"; -chr3 Cufflinks transcript 152641383 152641451 1000 . . gene_id "CUFF.172987"; transcript_id "CUFF.172987.1"; FPKM "20.6674946457"; frac "1.000000"; conf_lo "0.000000"; conf_hi "44.532262"; cov "1.173913"; -chr3 Cufflinks transcript 152861374 152861508 1000 . . gene_id "CUFF.173007"; transcript_id "CUFF.173007.1"; FPKM "24.6479010219"; frac "1.000000"; conf_lo "6.015839"; conf_hi "43.279963"; cov "1.400000"; -chr3 Cufflinks transcript 157698536 157698562 1000 . . gene_id "CUFF.173579"; transcript_id "CUFF.173579.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr4 Cufflinks exon 13715310 13715630 1000 . . gene_id "CUFF.174817"; transcript_id "CUFF.174817.1"; exon_number "1"; FPKM "19.2510308382"; frac "1.000000"; conf_lo "8.572480"; conf_hi "29.929581"; cov "1.093458"; -chr4 Cufflinks transcript 62063768 62063821 1000 . . gene_id "CUFF.179577"; transcript_id "CUFF.179577.1"; FPKM "26.3875633685"; frac "1.000000"; conf_lo "0.000000"; conf_hi "56.869362"; cov "1.498813"; -chr4 Cufflinks transcript 77180436 77180462 1000 . . gene_id "CUFF.181019"; transcript_id "CUFF.181019.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr4 Cufflinks transcript 102112070 102112096 1000 . . gene_id "CUFF.183381"; transcript_id "CUFF.183381.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr4 Cufflinks exon 117233771 117233830 1000 + . gene_id "CUFF.185373"; transcript_id "CUFF.185373.1"; exon_number "1"; FPKM "4.8015391601"; frac "1.000000"; conf_lo "0.000000"; conf_hi "14.404617"; cov "0.272727"; -chr4 Cufflinks exon 135563059 135563110 1000 . . gene_id "CUFF.189099"; transcript_id "CUFF.189099.1"; exon_number "1"; FPKM "18.2827837250"; frac "1.000000"; conf_lo "0.000000"; conf_hi "44.138544"; cov "1.038462"; -chr4 Cufflinks exon 147515029 147515097 1000 . . gene_id "CUFF.190627"; transcript_id "CUFF.190627.1"; exon_number "1"; FPKM "34.4458244094"; frac "1.000000"; conf_lo "3.636542"; conf_hi "65.255106"; cov "1.956522"; -chr5 Cufflinks exon 3949522 3949685 1000 . . gene_id "CUFF.192485"; transcript_id "CUFF.192485.1"; exon_number "1"; FPKM "23.1879208220"; frac "1.000000"; conf_lo "6.791585"; conf_hi "39.584257"; cov "1.317073"; -chr5 Cufflinks exon 22635516 22635542 1000 . . gene_id "CUFF.194445"; transcript_id "CUFF.194445.1"; exon_number "1"; FPKM "52.8169307611"; frac "1.000000"; conf_lo "0.000000"; conf_hi "113.804669"; cov "3.000000"; -chr5 Cufflinks exon 34172212 34172238 1000 . . gene_id "CUFF.196463"; transcript_id "CUFF.196463.1"; exon_number "1"; FPKM "17.6056435870"; frac "1.000000"; conf_lo "0.000000"; conf_hi "52.816931"; cov "1.000000"; -chr5 Cufflinks transcript 35362816 35362905 1000 . . gene_id "CUFF.196905"; transcript_id "CUFF.196905.1"; FPKM "10.5633861522"; frac "1.000000"; conf_lo "0.000000"; conf_hi "25.502270"; cov "0.600000"; -chr5 Cufflinks transcript 37083127 37083166 1000 . . gene_id "CUFF.197139"; transcript_id "CUFF.197139.1"; FPKM "23.7676188425"; frac "1.000000"; conf_lo "0.000000"; conf_hi "57.380108"; cov "1.350000"; -chr5 Cufflinks transcript 68089694 68089831 1000 . . gene_id "CUFF.199409"; transcript_id "CUFF.199409.1"; FPKM "17.2229122047"; frac "1.000000"; conf_lo "1.818271"; conf_hi "32.627553"; cov "0.978261"; -chr5 Cufflinks exon 98615179 98615254 1000 . . gene_id "CUFF.201693"; transcript_id "CUFF.201693.1"; exon_number "1"; FPKM "12.5092730750"; frac "1.000000"; conf_lo "0.000000"; conf_hi "30.200057"; cov "0.710526"; -chr5 Cufflinks exon 105915104 105915181 1000 . . gene_id "CUFF.202385"; transcript_id "CUFF.202385.1"; exon_number "1"; FPKM "12.1885224833"; frac "1.000000"; conf_lo "0.000000"; conf_hi "29.425696"; cov "0.692308"; -chr5 Cufflinks transcript 116136788 116136814 1000 . . gene_id "CUFF.204349"; transcript_id "CUFF.204349.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr5 Cufflinks exon 122819526 122819619 1000 . . gene_id "CUFF.205487"; transcript_id "CUFF.205487.1"; exon_number "1"; FPKM "25.2486782797"; frac "1.000000"; conf_lo "2.649470"; conf_hi "47.847887"; cov "1.434124"; -chr5 Cufflinks exon 132055557 132055583 1000 . . gene_id "CUFF.207163"; transcript_id "CUFF.207163.1"; exon_number "1"; FPKM "52.8169307611"; frac "1.000000"; conf_lo "0.000000"; conf_hi "113.804669"; cov "3.000000"; -chr5 Cufflinks transcript 145619548 145619710 1000 . . gene_id "CUFF.209965"; transcript_id "CUFF.209965.1"; FPKM "40.8278115086"; frac "1.000000"; conf_lo "19.004428"; conf_hi "62.651195"; cov "2.319018"; -chr6 Cufflinks exon 48466822 48466848 1000 . . gene_id "CUFF.215907"; transcript_id "CUFF.215907.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr6 Cufflinks exon 63803818 63803844 1000 . . gene_id "CUFF.217337"; transcript_id "CUFF.217337.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr6 Cufflinks transcript 77393088 77393138 1000 . . gene_id "CUFF.218387"; transcript_id "CUFF.218387.1"; FPKM "18.6412696804"; frac "1.000000"; conf_lo "0.000000"; conf_hi "45.004006"; cov "1.058824"; -chr6 Cufflinks transcript 82379452 82379478 1000 . . gene_id "CUFF.218947"; transcript_id "CUFF.218947.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr6 Cufflinks exon 83928984 83929105 1000 . . gene_id "CUFF.219317"; transcript_id "CUFF.219317.1"; exon_number "1"; FPKM "46.7559714935"; frac "1.000000"; conf_lo "19.761399"; conf_hi "73.750544"; cov "2.655738"; -chr6 Cufflinks exon 103658447 103658521 1000 . . gene_id "CUFF.221849"; transcript_id "CUFF.221849.1"; exon_number "1"; FPKM "19.0140950740"; frac "1.000000"; conf_lo "0.000000"; conf_hi "40.969681"; cov "1.080000"; -chr6 Cufflinks exon 113781332 113781358 1000 . . gene_id "CUFF.222775"; transcript_id "CUFF.222775.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr6 Cufflinks exon 118857949 118858148 1000 . . gene_id "CUFF.223543"; transcript_id "CUFF.223543.1"; exon_number "1"; FPKM "19.0140950740"; frac "1.000000"; conf_lo "5.569100"; conf_hi "32.459091"; cov "1.080000"; -chr6 Cufflinks transcript 124996314 124996340 1000 . . gene_id "CUFF.224545"; transcript_id "CUFF.224545.1"; FPKM "17.6056435870"; frac "1.000000"; conf_lo "0.000000"; conf_hi "52.816931"; cov "1.000000"; -chr6 Cufflinks transcript 127077329 127077364 1000 . . gene_id "CUFF.225409"; transcript_id "CUFF.225409.1"; FPKM "52.8169307611"; frac "1.000000"; conf_lo "0.000000"; conf_hi "105.633862"; cov "3.000000"; -chr6 Cufflinks exon 136038245 136038304 1000 . . gene_id "CUFF.225521"; transcript_id "CUFF.225521.1"; exon_number "1"; FPKM "23.7676188425"; frac "1.000000"; conf_lo "0.000000"; conf_hi "51.212101"; cov "1.350000"; -chr7 Cufflinks exon 13845893 13845919 1000 . . gene_id "CUFF.227869"; transcript_id "CUFF.227869.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr7 Cufflinks exon 56060938 56061023 1000 . . gene_id "CUFF.232920"; transcript_id "CUFF.232920.1"; exon_number "1"; FPKM "11.0547064384"; frac "1.000000"; conf_lo "0.000000"; conf_hi "26.688422"; cov "0.627907"; -chr7 Cufflinks exon 71484947 71484992 1000 . . gene_id "CUFF.234766"; transcript_id "CUFF.234766.1"; exon_number "1"; FPKM "20.6674946457"; frac "1.000000"; conf_lo "0.000000"; conf_hi "49.895746"; cov "1.173913"; -chr7 Cufflinks transcript 71784522 71784548 1000 . . gene_id "CUFF.234810"; transcript_id "CUFF.234810.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr7 Cufflinks exon 72605044 72605070 1000 . . gene_id "CUFF.234948"; transcript_id "CUFF.234948.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr7 Cufflinks transcript 85554210 85554343 1000 . . gene_id "CUFF.235778"; transcript_id "CUFF.235778.1"; FPKM "17.7370289869"; frac "1.000000"; conf_lo "1.872548"; conf_hi "33.601510"; cov "1.007463"; -chr7 Cufflinks transcript 98723325 98723416 1000 . . gene_id "CUFF.237594"; transcript_id "CUFF.237594.1"; FPKM "10.3337473228"; frac "1.000000"; conf_lo "0.000000"; conf_hi "24.947873"; cov "0.586957"; -chr7 Cufflinks exon 104055491 104055589 1000 . . gene_id "CUFF.238474"; transcript_id "CUFF.238474.1"; exon_number "1"; FPKM "28.8092349606"; frac "1.000000"; conf_lo "5.286593"; conf_hi "52.331877"; cov "1.636364"; -chr7 Cufflinks exon 107603711 107603748 1000 . . gene_id "CUFF.239180"; transcript_id "CUFF.239180.1"; exon_number "1"; FPKM "25.0185461500"; frac "1.000000"; conf_lo "0.000000"; conf_hi "60.400113"; cov "1.421053"; -chr7 Cufflinks exon 133792511 133792572 1000 . . gene_id "CUFF.242136"; transcript_id "CUFF.242136.1"; exon_number "1"; FPKM "15.3339476403"; frac "1.000000"; conf_lo "0.000000"; conf_hi "37.019424"; cov "0.870968"; -chr8 Cufflinks exon 9970398 9970545 1000 . . gene_id "CUFF.245320"; transcript_id "CUFF.245320.1"; exon_number "1"; FPKM "22.4828826889"; frac "1.000000"; conf_lo "5.487421"; conf_hi "39.478345"; cov "1.277027"; -chr8 Cufflinks transcript 10425062 10425088 1000 . . gene_id "CUFF.245408"; transcript_id "CUFF.245408.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr8 Cufflinks transcript 13018897 13018981 1000 . . gene_id "CUFF.245840"; transcript_id "CUFF.245840.1"; FPKM "16.7771427124"; frac "1.000000"; conf_lo "0.000000"; conf_hi "36.149718"; cov "0.952941"; -chr8 Cufflinks transcript 14745123 14745149 1000 . . gene_id "CUFF.246146"; transcript_id "CUFF.246146.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr8 Cufflinks exon 29820895 29820930 1000 . . gene_id "CUFF.247504"; transcript_id "CUFF.247504.1"; exon_number "1"; FPKM "26.4084653806"; frac "1.000000"; conf_lo "0.000000"; conf_hi "63.755675"; cov "1.500000"; -chr8 Cufflinks transcript 36676568 36676665 1000 . . gene_id "CUFF.248480"; transcript_id "CUFF.248480.1"; FPKM "9.7010689153"; frac "1.000000"; conf_lo "0.000000"; conf_hi "23.420452"; cov "0.551020"; -chr8 Cufflinks transcript 50146533 50146584 1000 . . gene_id "CUFF.249617"; transcript_id "CUFF.249617.1"; FPKM "27.4241755875"; frac "1.000000"; conf_lo "0.000000"; conf_hi "59.090886"; cov "1.557692"; -chr8 Cufflinks exon 51010775 51010850 1000 . . gene_id "CUFF.249695"; transcript_id "CUFF.249695.1"; exon_number "1"; FPKM "18.7639096125"; frac "1.000000"; conf_lo "0.000000"; conf_hi "40.430606"; cov "1.065789"; -chr8 Cufflinks exon 63391023 63391095 1000 . . gene_id "CUFF.250329"; transcript_id "CUFF.250329.1"; exon_number "1"; FPKM "13.0233527904"; frac "1.000000"; conf_lo "0.000000"; conf_hi "31.441155"; cov "0.739726"; -chr8 Cufflinks transcript 73858591 73858706 1000 . . gene_id "CUFF.251697"; transcript_id "CUFF.251697.1"; FPKM "12.2935959530"; frac "1.000000"; conf_lo "0.000000"; conf_hi "26.489018"; cov "0.698276"; -chr8 Cufflinks transcript 75514699 75514725 1000 . . gene_id "CUFF.252263"; transcript_id "CUFF.252263.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr8 Cufflinks exon 86101515 86101548 1000 . . gene_id "CUFF.252891"; transcript_id "CUFF.252891.1"; exon_number "1"; FPKM "27.9619045206"; frac "1.000000"; conf_lo "0.000000"; conf_hi "67.506009"; cov "1.588235"; -chr8 Cufflinks transcript 93627215 93627241 1000 . . gene_id "CUFF.254225"; transcript_id "CUFF.254225.1"; FPKM "52.8169307611"; frac "1.000000"; conf_lo "0.000000"; conf_hi "113.804669"; cov "3.000000"; -chr8 Cufflinks exon 108148187 108148357 1000 . . gene_id "CUFF.255477"; transcript_id "CUFF.255477.1"; exon_number "1"; FPKM "11.1193538445"; frac "1.000000"; conf_lo "0.000000"; conf_hi "22.238708"; cov "0.631579"; -chr8 Cufflinks exon 108190587 108190664 1000 . . gene_id "CUFF.255507"; transcript_id "CUFF.255507.1"; exon_number "1"; FPKM "12.1885224833"; frac "1.000000"; conf_lo "0.000000"; conf_hi "29.425696"; cov "0.692308"; -chr8 Cufflinks exon 120931685 120931769 1000 . . gene_id "CUFF.257375"; transcript_id "CUFF.257375.1"; exon_number "1"; FPKM "16.7771427124"; frac "1.000000"; conf_lo "0.000000"; conf_hi "36.149718"; cov "0.952941"; -chr9 Cufflinks transcript 20449846 20449932 1000 . . gene_id "CUFF.260747"; transcript_id "CUFF.260747.1"; FPKM "234.9313045507"; frac "1.000000"; conf_lo "163.275950"; conf_hi "306.586659"; cov "13.344091"; -chr9 Cufflinks exon 25083606 25083643 1000 . . gene_id "CUFF.261551"; transcript_id "CUFF.261551.1"; exon_number "1"; FPKM "25.0185461500"; frac "1.000000"; conf_lo "0.000000"; conf_hi "60.400113"; cov "1.421053"; -chr9 Cufflinks transcript 27906894 27906964 1000 . . gene_id "CUFF.261925"; transcript_id "CUFF.261925.1"; FPKM "26.7804155972"; frac "1.000000"; conf_lo "0.000000"; conf_hi "53.560831"; cov "1.521127"; -chr9 Cufflinks transcript 34418034 34418065 1000 . . gene_id "CUFF.262975"; transcript_id "CUFF.262975.1"; FPKM "29.7095235531"; frac "1.000000"; conf_lo "0.000000"; conf_hi "71.725135"; cov "1.687500"; -chr9 Cufflinks exon 34710789 34710815 1000 . . gene_id "CUFF.263065"; transcript_id "CUFF.263065.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr9 Cufflinks transcript 40823051 40823090 1000 . . gene_id "CUFF.263747"; transcript_id "CUFF.263747.1"; FPKM "23.7676188425"; frac "1.000000"; conf_lo "0.000000"; conf_hi "57.380108"; cov "1.350000"; -chr9 Cufflinks exon 59236547 59236671 1000 . . gene_id "CUFF.267045"; transcript_id "CUFF.267045.1"; exon_number "1"; FPKM "12.1905895442"; frac "1.000000"; conf_lo "0.000000"; conf_hi "25.808020"; cov "0.692425"; -chr9 Cufflinks transcript 66418162 66418188 1000 . . gene_id "CUFF.268423"; transcript_id "CUFF.268423.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr9 Cufflinks transcript 95913236 95913262 1000 . . gene_id "CUFF.270957"; transcript_id "CUFF.270957.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; -chr9 Cufflinks exon 103101949 103102030 1000 . . gene_id "CUFF.271979"; transcript_id "CUFF.271979.1"; exon_number "1"; FPKM "11.5939604110"; frac "1.000000"; conf_lo "0.000000"; conf_hi "27.990296"; cov "0.658537"; -chr9 Cufflinks transcript 105579135 105579173 1000 . . gene_id "CUFF.272347"; transcript_id "CUFF.272347.1"; FPKM "24.3770449667"; frac "1.000000"; conf_lo "0.000000"; conf_hi "58.851393"; cov "1.384615"; -chr9 Cufflinks exon 107445870 107445930 1000 . . gene_id "CUFF.272761"; transcript_id "CUFF.272761.1"; exon_number "1"; FPKM "38.9633095779"; frac "1.000000"; conf_lo "4.113466"; conf_hi "73.813153"; cov "2.213115"; -chr9 Cufflinks exon 113779194 113779220 1000 . . gene_id "CUFF.274445"; transcript_id "CUFF.274445.1"; exon_number "1"; FPKM "52.8169307611"; frac "1.000000"; conf_lo "0.000000"; conf_hi "113.804669"; cov "3.000000"; -chr9 Cufflinks transcript 120860476 120860606 1000 . . gene_id "CUFF.275115"; transcript_id "CUFF.275115.1"; FPKM "25.4005086867"; frac "1.000000"; conf_lo "6.199529"; conf_hi "44.601488"; cov "1.442748"; -chrX Cufflinks exon 10274057 10274087 1000 . . gene_id "CUFF.276147"; transcript_id "CUFF.276147.1"; exon_number "1"; FPKM "99.5432248142"; frac "1.000000"; conf_lo "21.405127"; conf_hi "177.681323"; cov "5.654052"; -chrX Cufflinks transcript 39881431 39881678 1000 . . gene_id "CUFF.277419"; transcript_id "CUFF.277419.1"; FPKM "42.1683560109"; frac "1.000000"; conf_lo "24.187709"; conf_hi "60.149003"; cov "2.395161"; -chrX Cufflinks transcript 90114645 90131913 1000 - . gene_id "CUFF.279771"; transcript_id "CUFF.279771.1"; FPKM "6.8891648819"; frac "1.000000"; conf_lo "0.000000"; conf_hi "20.667495"; cov "0.391304"; -chrX Cufflinks transcript 148249672 148249713 1000 . . gene_id "CUFF.282847"; transcript_id "CUFF.282847.1"; FPKM "56.5895686726"; frac "1.000000"; conf_lo "5.974320"; conf_hi "107.204818"; cov "3.214286"; -chrX Cufflinks transcript 148481505 148482455 1000 + . gene_id "CUFF.282965"; transcript_id "CUFF.282965.1"; FPKM "40.1706233958"; frac "1.000000"; conf_lo "16.978103"; conf_hi "63.363144"; cov "2.281690"; -chrX Cufflinks transcript 158986411 158986471 1000 . . gene_id "CUFF.283831"; transcript_id "CUFF.283831.1"; FPKM "15.5853238312"; frac "1.000000"; conf_lo "0.000000"; conf_hi "37.626300"; cov "0.885246"; --- /dev/null +++ b/tools/filters/gff/extract_GFF_Features.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python +#Guruprasad Ananda +""" +Extract features from GFF file. + +usage: %prog input1 out_file1 column features +""" + +import sys, os + +from galaxy import eggs +import pkg_resources; pkg_resources.require( "bx-python" ) +from bx.cookbook import doc_optparse + +assert sys.version_info[:2] >= ( 2, 4 ) + +def stop_err( msg ): + sys.stderr.write( msg ) + sys.exit() + +def main(): + # Parsing Command Line here + options, args = doc_optparse.parse( __doc__ ) + + try: + inp_file, out_file, column, features = args + except: + stop_err( "One or more arguments is missing or invalid.\nUsage: prog input output column features" ) + try: + column = int( column ) + except: + stop_err( "Column %s is an invalid column." % column ) + + if features == None: + stop_err( "Column %d has no features to display, select another column." %( column + 1 ) ) + + fo=open( out_file, 'w' ) + for i, line in enumerate( file( inp_file ) ): + line = line.rstrip( '\r\n' ) + if line and line.startswith( '#' ): + # Keep valid comment lines in the output + fo.write( "%s\n" % line ) + else: + try: + if line.split( '\t' )[column] in features.split( ',' ): + fo.write( "%s\n" % line ) + except: + pass + fo.close() + + print 'Column %d features: %s' %( column + 1, features ) + +if __name__ == "__main__": + main() --- /dev/null +++ b/tools/filters/gff/extract_GFF_Features.xml @@ -0,0 +1,114 @@ +<tool id="Extract_features1" name="Extract features"> + <description> from GFF file</description> + <command interpreter="python">extract_GFF_Features.py $input1 $out_file1 ${column_choice.col} ${column_choice.feature}</command> + <inputs> + <param format="gff" name="input1" type="data" label="Select GFF data"/> + <conditional name="column_choice"> + <param name="col" type="select" label="From"> + <option value="0" selected="true">Column 1 / Sequence name</option> + <option value="1">Column 2 / Source</option> + <option value="2">Column 3 / Feature</option> + <option value="6">Column 7 / Strand</option> + <option value="7">Column 8 / Frame</option> + </param> + <when value="0"> + <param name="feature" type="select" multiple="true" label="Extract features" help="Multi-select list - hold the appropriate key while clicking to select multiple columns"> + <options from_dataset="input1"> + <column name="name" index="0"/> + <column name="value" index="0"/> + <filter type="unique_value" name="unique" column="0"/> + </options> + </param> + </when> + <when value="1"> + <param name="feature" type="select" multiple="true" label="Extract features" help="Multi-select list - hold the appropriate key while clicking to select multiple columns"> + <options from_dataset="input1"> + <column name="name" index="1"/> + <column name="value" index="1"/> + <filter type="unique_value" name="unique" column="1"/> + </options> + </param> + </when> + <when value="2"> + <param name="feature" type="select" multiple="true" label="Extract features" help="Multi-select list - hold the appropriate key while clicking to select multiple columns"> + <options from_dataset="input1"> + <column name="name" index="2"/> + <column name="value" index="2"/> + <filter type="unique_value" name="unique" column="2"/> + </options> + </param> + </when> + <when value="6"> + <param name="feature" type="select" multiple="true" label="Extract features" help="Multi-select list - hold the appropriate key while clicking to select multiple columns"> + <options from_dataset="input1"> + <column name="name" index="6"/> + <column name="value" index="6"/> + <filter type="unique_value" name="unique" column="6"/> + </options> + </param> + </when> + <when value="7"> + <param name="feature" type="select" multiple="true" label="Extract features" help="Multi-select list - hold the appropriate key while clicking to select multiple columns"> + <options from_dataset="input1"> + <column name="name" index="7"/> + <column name="value" index="7"/> + <filter type="unique_value" name="unique" column="7"/> + </options> + </param> + </when> + </conditional> + </inputs> + <outputs> + <data format="gff" name="out_file1" /> + </outputs> + <tests> + <test> + <param name="input1" value="5.gff"/> + <param name="col" value="0" /> + <param name="feature" value="chr5,chr6,chr7,chr8" /> + <output name="out_file1" file="Extract_features1_out.gff"/> + </test> + </tests> + <help> + +**What it does** + +This tool extracts selected features from GFF data. + +----- + +**Example** + +Selecting **promoter** from the following GFF data:: + + chr22 GeneA enhancer 10000000 10001000 500 + . TGA + chr22 GeneA promoter 10010000 10010100 900 + . TGA + chr22 GeneB promoter 10020000 10025000 400 - . TGB + chr22 GeneB CCDS2220 10030000 10065000 800 - . TGB + +will produce the following output:: + + chr22 GeneA promoter 10010000 10010100 900 + . TGA + chr22 GeneB promoter 10020000 10025000 400 - . TGB + +---- + +.. class:: infomark + +**About formats** + +**GFF format** General Feature Format is a format for describing genes and other features associated with DNA, RNA and Protein sequences. GFF lines have nine tab-separated fields:: + + 1. seqname - Must be a chromosome or scaffold. + 2. source - The program that generated this feature. + 3. feature - The name of this type of feature. Some examples of standard feature types are "CDS", "start_codon", "stop_codon", and "exon". + 4. start - The starting position of the feature in the sequence. The first base is numbered 1. + 5. end - The ending position of the feature (inclusive). + 6. score - A score between 0 and 1000. If there is no score value, enter ".". + 7. strand - Valid entries include '+', '-', or '.' (for don't know/care). + 8. frame - If the feature is a coding exon, frame should be a number between 0-2 that represents the reading frame of the first base. If the feature is not a coding exon, the value should be '.'. + 9. group - All lines with the same group are linked together into a single item. + + + </help> +</tool> --- /dev/null +++ b/tools/filters/gff/gff_filter_by_feature_count.xml @@ -0,0 +1,45 @@ +<tool id="gff_filter_by_feature_count" name="Filter GFF file by feature count" version="0.1"> + <description>using simple expressions</description> + <command interpreter="python"> + gff_filter_by_feature_count.py $input_file1 $out_file1 "$feature_name" "$cond" + </command> + <inputs> + <param format="gff" name="input_file1" type="data" label="Filter"/> + <param name="feature_name" type="select" label="Using feature name"> + <options from_dataset="input_file1"> + <column name="name" index="2"/> + <column name="value" index="2"/> + <filter type="unique_value" name="unique" column="2"/> + </options> + </param> + <param name="cond" size="40" type="text" value=">0" label="With following condition"> + <validator type="empty_field" message="Enter a valid filtering condition, see syntax and examples below."/> + </param> + </inputs> + <outputs> + <data format="input_file1" name="out_file1" metadata_source="input_file1"/> + </outputs> + <tests> + <test> + <param name="input_file1" value="gops_subtract_in1.gff"/> + <param name="feature_name" value="exon"/> + <param name="cond" value=">1"/> + <output name="out_file1" file="gff_filter_by_feature_count_out1.gff"/> + </test> + </tests> + + <help> + + +.. class:: infomark + +Valid comparison operators are: > < >=, <=, !=, and == + +----- + +**Syntax** + +The filter tool allows you to restrict the dataset based on transcripts' feature counts. + +</help> +</tool> --- /dev/null +++ b/tools/filters/gff/gff_filter_by_feature_count.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python +""" +Filter a gff file using a criterion based on feature counts for a transcript. + +Usage: +%prog input_name output_name feature_name condition +""" +import sys +from galaxy import eggs +from galaxy.tools.util.gff_util import parse_gff_attributes + +assert sys.version_info[:2] >= ( 2, 4 ) + +# Escape sequences for valid operators. +mapped_ops = { + '__lt__': '<', + '__le__': '<=', + '__eq__': '==', + '__ne__': '!=', + '__gt__': '>', + '__ge__': '>=', +} + + +def __main__(): + # Get args. + input_name = sys.argv[1] + output_name = sys.argv[2] + feature_name = sys.argv[3] + condition = sys.argv[4] + + # Unescape operations in condition str. + for key, value in mapped_ops.items(): + condition = condition.replace( key, value ) + + # Error checking: condition should be of the form <operator><number> + for op in mapped_ops.itervalues(): + if op in condition: + empty, number_str = condition.split( op ) + try: + number = float( number_str ) + except: + number = None + if empty != "" or not number: + print >> sys.stderr, "Invalid condition: %s, cannot filter." % condition + return + + # Do filtering. + kept_lines = 0 + skipped_lines = 0 + first_skipped_line = 0 + out = open( output_name, 'w' ) + i = 0 + cur_transcript_id = None + cur_transcript_lines = [] + cur_transcript_feature_counts = {} # Key is feature name, value is feature count. + for i, line in enumerate( file( input_name ) ): + line = line.rstrip( '\r\n' ) + if line and not line.startswith( '#' ): + try: + # GFF format: chrom, source, feature, chromStart, chromEnd, score, strand, attributes + elems = line.split( '\t' ) + feature = elems[2] + start = str( long( elems[3] ) - 1 ) + coords = [ long( start ), long( elems[4] ) ] + strand = elems[6] + attributes = parse_gff_attributes( elems[8] ) + t_id = attributes.get( "transcript_id", None ) + + if not t_id: + # No transcript id, so pass line to output. + out.write( line ) + kept_lines += 1 + continue + + # There is a transcript ID, so process line at transcript level. + if t_id == cur_transcript_id: + # Line is element of transcript; increment feature count. + if not feature in cur_transcript_feature_counts: + cur_transcript_feature_counts[feature] = 0 + cur_transcript_feature_counts[feature] += 1 + cur_transcript_lines.append( line ) + continue + + # + # Line is part of new transcript; filter previous transcript. + # + + # Filter/write previous transcript. + result = eval( '%s %s' % ( cur_transcript_feature_counts.get( feature_name, 0 ), condition ) ) + if cur_transcript_id and result: + # Transcript passes filter; write transcript line to file." + out.write( "\n".join( cur_transcript_lines ) + "\n" ) + kept_lines += len( cur_transcript_lines ) + + # Start new transcript. + cur_transcript_id = t_id + cur_transcript_feature_counts = {} + cur_transcript_feature_counts[feature] = 1 + cur_transcript_lines = [ line ] + except Exception, e: + print e + skipped_lines += 1 + if not first_skipped_line: + first_skipped_line = i + 1 + else: + skipped_lines += 1 + if not first_skipped_line: + first_skipped_line = i + 1 + + # Write last transcript. + if cur_transcript_id and eval( '%s %s' % ( cur_transcript_feature_counts[feature_name], condition ) ): + # Transcript passes filter; write transcript lints to file. + out.write( "\n".join( cur_transcript_lines ) + "\n" ) + kept_lines += len( cur_transcript_lines ) + + # Clean up. + out.close() + info_msg = "%i lines kept (%.2f%%) using condition %s. " % ( kept_lines, float(kept_lines)/i, feature_name + condition ) + if skipped_lines > 0: + info_msg += "Skipped %d blank/comment/invalid lines starting with line #%d." %( skipped_lines, first_skipped_line ) + print info_msg + +if __name__ == "__main__": __main__() --- a/tool_conf.xml.sample +++ b/tool_conf.xml.sample @@ -60,6 +60,10 @@ <tool file="stats/filtering.xml" /><tool file="filters/sorter.xml" /><tool file="filters/grep.xml" /> + <label text="GFF files" id="gff" /> + <tool file="filters/gff/extract_GFF_Features.xml" /> + <tool file="filters/gff/gff_filter_by_attribute.xml" /> + <tool file="filters/gff/gff_filter_by_feature_count.xml" /></section><section name="Join, Subtract and Group" id="group"><tool file="filters/joiner.xml" /> @@ -87,7 +91,6 @@ </section><section name="Extract Features" id="features"><tool file="filters/ucsc_gene_bed_to_exon_bed.xml" /> - <tool file="extract/extract_GFF_Features.xml" /></section><section name="Fetch Sequences" id="fetchSeq"><tool file="extract/extract_genomic_dna.xml" /> @@ -278,7 +281,6 @@ <tool file="ngs_rna/cuffdiff_wrapper.xml" /><label text="Filtering" id="filtering" /><tool file="ngs_rna/filter_transcripts_via_tracking.xml" /> - <tool file="ngs_rna/gff_filtering.xml" /></section><section name="NGS: SAM Tools" id="samtools"><tool file="samtools/sam_bitwise_flag_filter.xml" /> --- /dev/null +++ b/test-data/gff_filter_attr_in1.gff @@ -0,0 +1,200 @@ +chr1 Cufflinks exon 21199802 21199861 1000 + . gene_id "CUFF.1383"; transcript_id "CUFF.1383.1"; exon_number "1"; FPKM "5.0037092300"; frac "1.000000"; conf_lo "0.000000"; conf_hi "15.011128"; cov "0.284211"; +chr1 Cufflinks transcript 55716264 55716295 1000 . . gene_id "CUFF.5021"; transcript_id "CUFF.5021.1"; FPKM "29.7095235531"; frac "1.000000"; conf_lo "0.000000"; conf_hi "71.725135"; cov "1.687500"; +chr1 Cufflinks transcript 74904128 74904154 1000 . . gene_id "CUFF.7563"; transcript_id "CUFF.7563.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr1 Cufflinks exon 134487086 134487123 1000 . . gene_id "CUFF.11837"; transcript_id "CUFF.11837.1"; exon_number "1"; FPKM "25.0185461500"; frac "1.000000"; conf_lo "0.000000"; conf_hi "60.400113"; cov "1.421053"; +chr1 Cufflinks exon 136200923 136200959 1000 . . gene_id "CUFF.12099"; transcript_id "CUFF.12099.1"; exon_number "1"; FPKM "38.5420846095"; frac "1.000000"; conf_lo "0.000000"; conf_hi "83.046650"; cov "2.189189"; +chr1 Cufflinks transcript 138116837 138116866 1000 . . gene_id "CUFF.12557"; transcript_id "CUFF.12557.1"; FPKM "31.6901584567"; frac "1.000000"; conf_lo "0.000000"; conf_hi "76.506810"; cov "1.800000"; +chr1 Cufflinks exon 152240694 152240779 1000 . . gene_id "CUFF.13107"; transcript_id "CUFF.13107.1"; exon_number "1"; FPKM "16.5820596576"; frac "1.000000"; conf_lo "0.000000"; conf_hi "35.729373"; cov "0.941860"; +chr1 Cufflinks exon 157633998 157634024 1000 . . gene_id "CUFF.13967"; transcript_id "CUFF.13967.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr1 Cufflinks exon 167704819 167704854 1000 . . gene_id "CUFF.15347"; transcript_id "CUFF.15347.1"; exon_number "1"; FPKM "26.4084653806"; frac "1.000000"; conf_lo "0.000000"; conf_hi "63.755675"; cov "1.500000"; +chr1 Cufflinks transcript 184245403 184245429 1000 . . gene_id "CUFF.17679"; transcript_id "CUFF.17679.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr10 Cufflinks exon 12731734 12731826 1000 . . gene_id "CUFF.19287"; transcript_id "CUFF.19287.1"; exon_number "1"; FPKM "10.2226317602"; frac "1.000000"; conf_lo "0.000000"; conf_hi "24.679616"; cov "0.580645"; +chr10 Cufflinks transcript 42305464 42305515 1000 . . gene_id "CUFF.21709"; transcript_id "CUFF.21709.1"; FPKM "18.2827837250"; frac "1.000000"; conf_lo "0.000000"; conf_hi "44.138544"; cov "1.038462"; +chr10 Cufflinks exon 52431636 52431662 1000 . . gene_id "CUFF.22495"; transcript_id "CUFF.22495.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr10 Cufflinks transcript 62044837 62045189 1000 . . gene_id "CUFF.23531"; transcript_id "CUFF.23531.1"; FPKM "19.5178121606"; frac "1.000000"; conf_lo "9.264456"; conf_hi "29.771168"; cov "1.108611"; +chr10 Cufflinks transcript 75372919 75373002 1000 . . gene_id "CUFF.24985"; transcript_id "CUFF.24985.1"; FPKM "124.4970510798"; frac "1.000000"; conf_lo "71.411330"; conf_hi "177.582772"; cov "7.071429"; +chr10 Cufflinks transcript 80362428 80363292 1000 - . gene_id "CUFF.26065"; transcript_id "CUFF.26065.1"; FPKM "43.6170921216"; frac "1.000000"; conf_lo "32.260169"; conf_hi "54.974016"; cov "2.477449"; +chr10 Cufflinks exon 87908564 87908597 1000 + . gene_id "CUFF.27209"; transcript_id "CUFF.27209.1"; exon_number "2"; FPKM "11.4913582411"; frac "1.000000"; conf_lo "0.000000"; conf_hi "30.264098"; cov "0.652709"; +chr10 Cufflinks exon 89142681 89142707 1000 . . gene_id "CUFF.27307"; transcript_id "CUFF.27307.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr10 Cufflinks exon 93425781 93425807 1000 . . gene_id "CUFF.28101"; transcript_id "CUFF.28101.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr10 Cufflinks exon 108207916 108207986 1000 . . gene_id "CUFF.29319"; transcript_id "CUFF.29319.1"; exon_number "1"; FPKM "13.3902077986"; frac "1.000000"; conf_lo "0.000000"; conf_hi "32.326821"; cov "0.760563"; +chr10 Cufflinks transcript 117583959 117584039 1000 . . gene_id "CUFF.30522"; transcript_id "CUFF.30522.1"; FPKM "17.6056435870"; frac "1.000000"; conf_lo "0.000000"; conf_hi "37.934890"; cov "1.000000"; +chr11 Cufflinks transcript 3357264 3357347 1000 . . gene_id "CUFF.32520"; transcript_id "CUFF.32520.1"; FPKM "16.9768706018"; frac "1.000000"; conf_lo "0.000000"; conf_hi "36.580072"; cov "0.964286"; +chr11 Cufflinks transcript 5005248 5005351 1000 . . gene_id "CUFF.33024"; transcript_id "CUFF.33024.1"; FPKM "9.1413918625"; frac "1.000000"; conf_lo "0.000000"; conf_hi "22.069272"; cov "0.519231"; +chr11 Cufflinks transcript 7904565 7904642 1000 . . gene_id "CUFF.33508"; transcript_id "CUFF.33508.1"; FPKM "61.6484988869"; frac "1.000000"; conf_lo "22.882428"; conf_hi "100.414569"; cov "3.501633"; +chr11 Cufflinks exon 49932116 49932142 1000 . . gene_id "CUFF.37546"; transcript_id "CUFF.37546.1"; exon_number "1"; FPKM "17.6056435870"; frac "1.000000"; conf_lo "0.000000"; conf_hi "52.816931"; cov "1.000000"; +chr11 Cufflinks transcript 60046420 60046446 1000 . . gene_id "CUFF.39152"; transcript_id "CUFF.39152.1"; FPKM "52.8169307611"; frac "1.000000"; conf_lo "0.000000"; conf_hi "113.804669"; cov "3.000000"; +chr11 Cufflinks exon 78140156 78140259 1000 . . gene_id "CUFF.43148"; transcript_id "CUFF.43148.1"; exon_number "1"; FPKM "54.8483511750"; frac "1.000000"; conf_lo "23.181641"; conf_hi "86.515061"; cov "3.115385"; +chr11 Cufflinks transcript 79846512 79846547 1000 . . gene_id "CUFF.43570"; transcript_id "CUFF.43570.1"; FPKM "26.4084653806"; frac "1.000000"; conf_lo "0.000000"; conf_hi "63.755675"; cov "1.500000"; +chr11 Cufflinks transcript 85583926 85583952 1000 . . gene_id "CUFF.44478"; transcript_id "CUFF.44478.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr11 Cufflinks transcript 98554214 98554301 1000 . . gene_id "CUFF.46823"; transcript_id "CUFF.46823.1"; FPKM "10.8034631102"; frac "1.000000"; conf_lo "0.000000"; conf_hi "26.081867"; cov "0.613636"; +chr11 Cufflinks transcript 100797512 100797539 1000 . . gene_id "CUFF.47191"; transcript_id "CUFF.47191.1"; FPKM "33.9537412036"; frac "1.000000"; conf_lo "0.000000"; conf_hi "81.971583"; cov "1.928571"; +chr11 Cufflinks exon 105616462 105616737 1000 . . gene_id "CUFF.48385"; transcript_id "CUFF.48385.1"; exon_number "1"; FPKM "18.9452034252"; frac "1.000000"; conf_lo "7.520816"; conf_hi "30.369591"; cov "1.076087"; +chr11 Cufflinks transcript 106985457 106985483 1000 . . gene_id "CUFF.48949"; transcript_id "CUFF.48949.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr11 Cufflinks exon 120257794 120257821 1000 . . gene_id "CUFF.51205"; transcript_id "CUFF.51205.1"; exon_number "1"; FPKM "50.9306118054"; frac "1.000000"; conf_lo "0.000000"; conf_hi "109.740217"; cov "2.892857"; +chr12 Cufflinks transcript 16542765 16542791 1000 . . gene_id "CUFF.52907"; transcript_id "CUFF.52907.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr12 Cufflinks exon 21319385 21319483 1000 . . gene_id "CUFF.53189"; transcript_id "CUFF.53189.1"; exon_number "1"; FPKM "9.6030783202"; frac "1.000000"; conf_lo "0.000000"; conf_hi "23.183882"; cov "0.545455"; +chr12 Cufflinks transcript 30469129 30469156 1000 . . gene_id "CUFF.53733"; transcript_id "CUFF.53733.1"; FPKM "33.9537412036"; frac "1.000000"; conf_lo "0.000000"; conf_hi "81.971583"; cov "1.928571"; +chr12 Cufflinks transcript 30557416 30557442 1000 . . gene_id "CUFF.53863"; transcript_id "CUFF.53863.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr12 Cufflinks exon 30701762 30702509 1000 . . gene_id "CUFF.53897"; transcript_id "CUFF.53897.1"; exon_number "1"; FPKM "48.9333329111"; frac "1.000000"; conf_lo "37.780391"; conf_hi "60.086275"; cov "2.779412"; +chr12 Cufflinks transcript 56895077 56895103 1000 . . gene_id "CUFF.55817"; transcript_id "CUFF.55817.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr12 Cufflinks transcript 81915713 81915797 1000 . . gene_id "CUFF.58203"; transcript_id "CUFF.58203.1"; FPKM "22.3695236165"; frac "1.000000"; conf_lo "0.000000"; conf_hi "44.739047"; cov "1.270588"; +chr12 Cufflinks transcript 118458135 118458232 1000 . . gene_id "CUFF.63640"; transcript_id "CUFF.63640.1"; FPKM "9.7010689153"; frac "1.000000"; conf_lo "0.000000"; conf_hi "23.420452"; cov "0.551020"; +chr13 Cufflinks exon 8262302 8262372 1000 . . gene_id "CUFF.64064"; transcript_id "CUFF.64064.1"; exon_number "1"; FPKM "13.3902077986"; frac "1.000000"; conf_lo "0.000000"; conf_hi "32.326821"; cov "0.760563"; +chr13 Cufflinks transcript 14110852 14110956 1000 . . gene_id "CUFF.64684"; transcript_id "CUFF.64684.1"; FPKM "13.5814964814"; frac "1.000000"; conf_lo "0.000000"; conf_hi "29.264058"; cov "0.771429"; +chr13 Cufflinks transcript 14146567 14146593 1000 . . gene_id "CUFF.64702"; transcript_id "CUFF.64702.1"; FPKM "17.6056435870"; frac "1.000000"; conf_lo "0.000000"; conf_hi "52.816931"; cov "1.000000"; +chr13 Cufflinks transcript 14564150 14564243 1000 . . gene_id "CUFF.64894"; transcript_id "CUFF.64894.1"; FPKM "15.1708205378"; frac "1.000000"; conf_lo "0.000000"; conf_hi "32.688575"; cov "0.861702"; +chr13 Cufflinks transcript 17823162 17823188 1000 . . gene_id "CUFF.65082"; transcript_id "CUFF.65082.1"; FPKM "52.8169307611"; frac "1.000000"; conf_lo "0.000000"; conf_hi "113.804669"; cov "3.000000"; +chr13 Cufflinks transcript 29757640 29757666 1000 . . gene_id "CUFF.65972"; transcript_id "CUFF.65972.1"; FPKM "70.4225743482"; frac "1.000000"; conf_lo "0.000000"; conf_hi "140.845149"; cov "4.000000"; +chr13 Cufflinks transcript 42402998 42403051 1000 . . gene_id "CUFF.66816"; transcript_id "CUFF.66816.1"; FPKM "26.4084653806"; frac "1.000000"; conf_lo "0.000000"; conf_hi "56.902335"; cov "1.500000"; +chr13 Cufflinks transcript 42853325 42853406 1000 . . gene_id "CUFF.66850"; transcript_id "CUFF.66850.1"; FPKM "17.3909406165"; frac "1.000000"; conf_lo "0.000000"; conf_hi "37.472269"; cov "0.987805"; +chr13 Cufflinks exon 42990504 42990546 1000 . . gene_id "CUFF.66994"; transcript_id "CUFF.66994.1"; exon_number "1"; FPKM "33.1641193151"; frac "1.000000"; conf_lo "0.000000"; conf_hi "71.458746"; cov "1.883721"; +chr13 Cufflinks exon 49159496 49159569 1000 . . gene_id "CUFF.67788"; transcript_id "CUFF.67788.1"; exon_number "1"; FPKM "44.9657653777"; frac "1.000000"; conf_lo "10.974842"; conf_hi "78.956689"; cov "2.554054"; +chr13 Cufflinks exon 49243161 49243187 1000 + . gene_id "CUFF.67842"; transcript_id "CUFF.67842.1"; exon_number "2"; FPKM "17.3246767151"; frac "1.000000"; conf_lo "0.000000"; conf_hi "35.848677"; cov "0.984041"; +chr13 Cufflinks transcript 74671517 74671579 1000 . . gene_id "CUFF.70454"; transcript_id "CUFF.70454.1"; FPKM "18.8363155420"; frac "1.000000"; conf_lo "0.000000"; conf_hi "42.679570"; cov "1.069902"; +chr13 Cufflinks exon 100759121 100759147 1000 . . gene_id "CUFF.72728"; transcript_id "CUFF.72728.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr13 Cufflinks transcript 100200304 100200330 1000 . . gene_id "CUFF.73108"; transcript_id "CUFF.73108.1"; FPKM "123.2395051093"; frac "1.000000"; conf_lo "30.079196"; conf_hi "216.399814"; cov "7.000000"; +chr13 Cufflinks exon 107766857 107766915 1000 . . gene_id "CUFF.73428"; transcript_id "CUFF.73428.1"; exon_number "1"; FPKM "16.1136398932"; frac "1.000000"; conf_lo "0.000000"; conf_hi "38.901768"; cov "0.915254"; +chr13 Cufflinks transcript 115623552 115623640 1000 . . gene_id "CUFF.74362"; transcript_id "CUFF.74362.1"; FPKM "21.3641517686"; frac "1.000000"; conf_lo "0.000000"; conf_hi "42.728304"; cov "1.213483"; +chr14 Cufflinks transcript 31651249 31651275 1000 . . gene_id "CUFF.77182"; transcript_id "CUFF.77182.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr14 Cufflinks transcript 31949103 31949152 1000 . . gene_id "CUFF.77316"; transcript_id "CUFF.77316.1"; FPKM "85.5634278330"; frac "1.000000"; conf_lo "28.521143"; conf_hi "142.605713"; cov "4.860000"; +chr14 Cufflinks transcript 32190589 32190685 1000 . . gene_id "CUFF.77438"; transcript_id "CUFF.77438.1"; FPKM "14.7016199026"; frac "1.000000"; conf_lo "0.000000"; conf_hi "31.677588"; cov "0.835052"; +chr14 Cufflinks exon 55013239 55013265 1000 . . gene_id "CUFF.79372"; transcript_id "CUFF.79372.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr14 Cufflinks exon 55250464 55250514 1000 . . gene_id "CUFF.79616"; transcript_id "CUFF.79616.1"; exon_number "1"; FPKM "18.6412696804"; frac "1.000000"; conf_lo "0.000000"; conf_hi "45.004006"; cov "1.058824"; +chr14 Cufflinks exon 67604227 67604668 1000 . . gene_id "CUFF.81446"; transcript_id "CUFF.81446.1"; exon_number "1"; FPKM "123.6776546104"; frac "1.000000"; conf_lo "100.611653"; conf_hi "146.743656"; cov "7.024887"; +chr14 Cufflinks exon 75165582 75165744 1000 . . gene_id "CUFF.82088"; transcript_id "CUFF.82088.1"; exon_number "1"; FPKM "20.4139057543"; frac "1.000000"; conf_lo "4.982443"; conf_hi "35.845368"; cov "1.159509"; +chr15 Cufflinks transcript 8254591 8254734 1000 . . gene_id "CUFF.85556"; transcript_id "CUFF.85556.1"; FPKM "13.2042326903"; frac "1.000000"; conf_lo "0.000000"; conf_hi "26.408465"; cov "0.750000"; +chr15 Cufflinks transcript 34371407 34371433 1000 . . gene_id "CUFF.87246"; transcript_id "CUFF.87246.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr15 Cufflinks exon 65980225 65980255 1000 + . gene_id "CUFF.89502"; transcript_id "CUFF.89502.1"; exon_number "2"; FPKM "14.1193775302"; frac "1.000000"; conf_lo "0.000000"; conf_hi "30.423030"; cov "0.801980"; +chr15 Cufflinks transcript 85895971 85896018 1000 . . gene_id "CUFF.92834"; transcript_id "CUFF.92834.1"; FPKM "19.8063490354"; frac "1.000000"; conf_lo "0.000000"; conf_hi "47.816756"; cov "1.125000"; +chr15 Cufflinks exon 90828279 90828371 1000 . . gene_id "CUFF.93426"; transcript_id "CUFF.93426.1"; exon_number "1"; FPKM "15.3339476403"; frac "1.000000"; conf_lo "0.000000"; conf_hi "33.040065"; cov "0.870968"; +chr15 Cufflinks exon 99013431 99013472 1000 . . gene_id "CUFF.94604"; transcript_id "CUFF.94604.1"; exon_number "1"; FPKM "22.6358274691"; frac "1.000000"; conf_lo "0.000000"; conf_hi "54.647722"; cov "1.285714"; +chr15 Cufflinks transcript 102336976 102337075 1000 . . gene_id "CUFF.95298"; transcript_id "CUFF.95298.1"; FPKM "9.5070475370"; frac "1.000000"; conf_lo "0.000000"; conf_hi "22.952043"; cov "0.540000"; +chr16 Cufflinks transcript 10417989 10425202 1000 - . gene_id "CUFF.97232"; transcript_id "CUFF.97232.1"; FPKM "21.1642179587"; frac "1.000000"; conf_lo "0.000000"; conf_hi "44.805591"; cov "1.202127"; +chr16 Cufflinks transcript 40788986 40789084 1000 . . gene_id "CUFF.101774"; transcript_id "CUFF.101774.1"; FPKM "9.6030783202"; frac "1.000000"; conf_lo "0.000000"; conf_hi "23.183882"; cov "0.545455"; +chr16 Cufflinks transcript 57154027 57154067 1000 . . gene_id "CUFF.103364"; transcript_id "CUFF.103364.1"; FPKM "162.3154457537"; frac "1.000000"; conf_lo "75.554191"; conf_hi "249.076701"; cov "9.219512"; +chr16 Cufflinks exon 74862302 74862560 1000 . . gene_id "CUFF.105450"; transcript_id "CUFF.105450.1"; exon_number "1"; FPKM "11.0120241741"; frac "1.000000"; conf_lo "2.020744"; conf_hi "20.003304"; cov "0.625483"; +chr16 Cufflinks exon 91023578 91023669 1000 . . gene_id "CUFF.106912"; transcript_id "CUFF.106912.1"; exon_number "1"; FPKM "10.3337473228"; frac "1.000000"; conf_lo "0.000000"; conf_hi "24.947873"; cov "0.586957"; +chr16 Cufflinks transcript 98168779 98168914 1000 . . gene_id "CUFF.107834"; transcript_id "CUFF.107834.1"; FPKM "24.4666664555"; frac "1.000000"; conf_lo "5.971605"; conf_hi "42.961728"; cov "1.389706"; +chr17 Cufflinks exon 8483212 8483268 1000 . . gene_id "CUFF.108498"; transcript_id "CUFF.108498.1"; exon_number "1"; FPKM "50.0370923000"; frac "1.000000"; conf_lo "9.181978"; conf_hi "90.892207"; cov "2.842105"; +chr17 Cufflinks transcript 17478023 17478102 1000 . . gene_id "CUFF.109264"; transcript_id "CUFF.109264.1"; FPKM "23.7676188425"; frac "1.000000"; conf_lo "0.000000"; conf_hi "47.535238"; cov "1.350000"; +chr17 Cufflinks exon 24611086 24611151 1000 . . gene_id "CUFF.110088"; transcript_id "CUFF.110088.1"; exon_number "1"; FPKM "21.6069262205"; frac "1.000000"; conf_lo "0.000000"; conf_hi "46.556456"; cov "1.227273"; +chr17 Cufflinks exon 30355791 30355913 1000 . . gene_id "CUFF.111759"; transcript_id "CUFF.111759.1"; exon_number "1"; FPKM "19.3232673516"; frac "1.000000"; conf_lo "2.040012"; conf_hi "36.606523"; cov "1.097561"; +chr17 Cufflinks exon 31608702 31608787 1000 . . gene_id "CUFF.111943"; transcript_id "CUFF.111943.1"; exon_number "1"; FPKM "16.5820596576"; frac "1.000000"; conf_lo "0.000000"; conf_hi "35.729373"; cov "0.941860"; +chr17 Cufflinks transcript 32414547 32414573 1000 . . gene_id "CUFF.112117"; transcript_id "CUFF.112117.1"; FPKM "52.8169307611"; frac "1.000000"; conf_lo "0.000000"; conf_hi "113.804669"; cov "3.000000"; +chr17 Cufflinks transcript 33245409 33245463 1000 . . gene_id "CUFF.112363"; transcript_id "CUFF.112363.1"; FPKM "17.2855409764"; frac "1.000000"; conf_lo "0.000000"; conf_hi "41.730987"; cov "0.981818"; +chr17 Cufflinks transcript 56750339 56750374 1000 . . gene_id "CUFF.115617"; transcript_id "CUFF.115617.1"; FPKM "52.8169307611"; frac "1.000000"; conf_lo "0.000000"; conf_hi "105.633862"; cov "3.000000"; +chr17 Cufflinks transcript 57144800 57144939 1000 . . gene_id "CUFF.115679"; transcript_id "CUFF.115679.1"; FPKM "13.5814964814"; frac "1.000000"; conf_lo "0.000000"; conf_hi "27.162993"; cov "0.771429"; +chr17 Cufflinks exon 71694628 71694708 1000 . . gene_id "CUFF.117117"; transcript_id "CUFF.117117.1"; exon_number "1"; FPKM "23.4741914494"; frac "1.000000"; conf_lo "0.000000"; conf_hi "46.948383"; cov "1.333333"; +chr17 Cufflinks transcript 71698227 71698263 1000 . . gene_id "CUFF.117119"; transcript_id "CUFF.117119.1"; FPKM "25.6947230730"; frac "1.000000"; conf_lo "0.000000"; conf_hi "62.032549"; cov "1.459459"; +chr17 Cufflinks exon 87862079 87862105 1000 . . gene_id "CUFF.118851"; transcript_id "CUFF.118851.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr18 Cufflinks transcript 39571718 39571880 1000 . . gene_id "CUFF.123569"; transcript_id "CUFF.123569.1"; FPKM "20.4139057543"; frac "1.000000"; conf_lo "4.982443"; conf_hi "35.845368"; cov "1.159509"; +chr18 Cufflinks exon 46452826 46452864 1000 . . gene_id "CUFF.124197"; transcript_id "CUFF.124197.1"; exon_number "1"; FPKM "48.7540899334"; frac "1.000000"; conf_lo "0.000000"; conf_hi "97.508180"; cov "2.769231"; +chr18 Cufflinks exon 50151390 50151416 1000 . . gene_id "CUFF.124439"; transcript_id "CUFF.124439.1"; exon_number "1"; FPKM "17.5638395629"; frac "1.000000"; conf_lo "0.000000"; conf_hi "52.733298"; cov "0.997626"; +chr18 Cufflinks exon 65106749 65106787 1000 . . gene_id "CUFF.125675"; transcript_id "CUFF.125675.1"; exon_number "1"; FPKM "48.7540899334"; frac "1.000000"; conf_lo "0.000000"; conf_hi "97.508180"; cov "2.769231"; +chr18 Cufflinks transcript 65202282 65202424 1000 . . gene_id "CUFF.125729"; transcript_id "CUFF.125729.1"; FPKM "13.2965699818"; frac "1.000000"; conf_lo "0.000000"; conf_hi "26.593140"; cov "0.755245"; +chr18 Cufflinks exon 69735254 69735280 1000 . . gene_id "CUFF.126371"; transcript_id "CUFF.126371.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr19 Cufflinks transcript 5370466 5370492 1000 . . gene_id "CUFF.129319"; transcript_id "CUFF.129319.1"; FPKM "52.8169307611"; frac "1.000000"; conf_lo "0.000000"; conf_hi "113.804669"; cov "3.000000"; +chr19 Cufflinks exon 17633088 17633203 1000 . . gene_id "CUFF.131333"; transcript_id "CUFF.131333.1"; exon_number "1"; FPKM "20.4893265884"; frac "1.000000"; conf_lo "2.163116"; conf_hi "38.815537"; cov "1.163793"; +chr19 Cufflinks transcript 41997624 41997859 1000 . . gene_id "CUFF.133569"; transcript_id "CUFF.133569.1"; FPKM "28.1988698132"; frac "1.000000"; conf_lo "13.125940"; conf_hi "43.271800"; cov "1.601695"; +chr19 Cufflinks transcript 53311236 53311262 1000 . . gene_id "CUFF.134885"; transcript_id "CUFF.134885.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr19 Cufflinks exon 56516515 56516684 1000 . . gene_id "CUFF.135203"; transcript_id "CUFF.135203.1"; exon_number "1"; FPKM "33.5542854247"; frac "1.000000"; conf_lo "14.181710"; conf_hi "52.926861"; cov "1.905882"; +chr2 Cufflinks transcript 3246910 3246936 1000 . . gene_id "CUFF.136019"; transcript_id "CUFF.136019.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr2 Cufflinks transcript 4543774 4543977 1000 . . gene_id "CUFF.136435"; transcript_id "CUFF.136435.1"; FPKM "37.2825393608"; frac "1.000000"; conf_lo "18.641270"; conf_hi "55.923809"; cov "2.117647"; +chr2 Cufflinks exon 7271328 7271354 1000 . . gene_id "CUFF.137407"; transcript_id "CUFF.137407.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr2 Cufflinks exon 11509202 11509287 1000 . . gene_id "CUFF.137559"; transcript_id "CUFF.137559.1"; exon_number "1"; FPKM "22.1094128768"; frac "1.000000"; conf_lo "0.000000"; conf_hi "44.218826"; cov "1.255814"; +chr2 Cufflinks transcript 30200331 30200938 1000 . . gene_id "CUFF.140289"; transcript_id "CUFF.140289.1"; FPKM "100.0741846001"; frac "1.000000"; conf_lo "82.383401"; conf_hi "117.764968"; cov "5.684211"; +chr2 Cufflinks transcript 49559781 49559842 1000 . . gene_id "CUFF.143035"; transcript_id "CUFF.143035.1"; FPKM "15.3339476403"; frac "1.000000"; conf_lo "0.000000"; conf_hi "37.019424"; cov "0.870968"; +chr2 Cufflinks transcript 78736720 78736746 1000 . . gene_id "CUFF.146383"; transcript_id "CUFF.146383.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr2 Cufflinks transcript 97470595 97470703 1000 . . gene_id "CUFF.148117"; transcript_id "CUFF.148117.1"; FPKM "17.4441239211"; frac "1.000000"; conf_lo "0.000000"; conf_hi "34.888248"; cov "0.990826"; +chr2 Cufflinks transcript 106644220 106644341 1000 . . gene_id "CUFF.148977"; transcript_id "CUFF.148977.1"; FPKM "27.2743167045"; frac "1.000000"; conf_lo "6.656871"; conf_hi "47.891762"; cov "1.549180"; +chr2 Cufflinks transcript 118960859 118961004 1000 . . gene_id "CUFF.150015"; transcript_id "CUFF.150015.1"; FPKM "9.7675145928"; frac "1.000000"; conf_lo "0.000000"; conf_hi "21.046069"; cov "0.554795"; +chr2 Cufflinks exon 125388931 125389219 1000 . . gene_id "CUFF.151331"; transcript_id "CUFF.151331.1"; exon_number "1"; FPKM "23.0274507817"; frac "1.000000"; conf_lo "10.718761"; conf_hi "35.336141"; cov "1.307958"; +chr2 Cufflinks transcript 145141669 145141755 1000 . . gene_id "CUFF.153993"; transcript_id "CUFF.153993.1"; FPKM "10.9276408471"; frac "1.000000"; conf_lo "0.000000"; conf_hi "26.381659"; cov "0.620690"; +chr2 Cufflinks exon 178035510 178035611 1000 . . gene_id "CUFF.158329"; transcript_id "CUFF.158329.1"; exon_number "1"; FPKM "9.3206348402"; frac "1.000000"; conf_lo "0.000000"; conf_hi "22.502003"; cov "0.529412"; +chr2 Cufflinks transcript 181047445 181047471 1000 . . gene_id "CUFF.158989"; transcript_id "CUFF.158989.1"; FPKM "17.6056435870"; frac "1.000000"; conf_lo "0.000000"; conf_hi "52.816931"; cov "1.000000"; +chr3 Cufflinks transcript 55664118 55664197 1000 . . gene_id "CUFF.163141"; transcript_id "CUFF.163141.1"; FPKM "11.8838094213"; frac "1.000000"; conf_lo "0.000000"; conf_hi "28.690054"; cov "0.675000"; +chr3 Cufflinks exon 66896354 66896433 1000 . . gene_id "CUFF.163935"; transcript_id "CUFF.163935.1"; exon_number "1"; FPKM "5.9419047106"; frac "1.000000"; conf_lo "0.000000"; conf_hi "17.825714"; cov "0.337500"; +chr3 Cufflinks transcript 80648745 80648771 1000 . . gene_id "CUFF.164995"; transcript_id "CUFF.164995.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr3 Cufflinks exon 107424385 107424452 1000 . . gene_id "CUFF.169311"; transcript_id "CUFF.169311.1"; exon_number "1"; FPKM "13.9809522603"; frac "1.000000"; conf_lo "0.000000"; conf_hi "33.753005"; cov "0.794118"; +chr3 Cufflinks transcript 130936639 130936898 1000 . . gene_id "CUFF.171349"; transcript_id "CUFF.171349.1"; FPKM "20.1110620975"; frac "1.000000"; conf_lo "7.983635"; conf_hi "32.238489"; cov "1.142308"; +chr3 Cufflinks exon 136592671 136592771 1000 . . gene_id "CUFF.171861"; transcript_id "CUFF.171861.1"; exon_number "1"; FPKM "32.9452142371"; frac "1.000000"; conf_lo "8.040973"; conf_hi "57.849455"; cov "1.871287"; +chr3 Cufflinks transcript 152641383 152641451 1000 . . gene_id "CUFF.172987"; transcript_id "CUFF.172987.1"; FPKM "20.6674946457"; frac "1.000000"; conf_lo "0.000000"; conf_hi "44.532262"; cov "1.173913"; +chr3 Cufflinks transcript 152861374 152861508 1000 . . gene_id "CUFF.173007"; transcript_id "CUFF.173007.1"; FPKM "24.6479010219"; frac "1.000000"; conf_lo "6.015839"; conf_hi "43.279963"; cov "1.400000"; +chr3 Cufflinks transcript 157698536 157698562 1000 . . gene_id "CUFF.173579"; transcript_id "CUFF.173579.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr4 Cufflinks exon 13715310 13715630 1000 . . gene_id "CUFF.174817"; transcript_id "CUFF.174817.1"; exon_number "1"; FPKM "19.2510308382"; frac "1.000000"; conf_lo "8.572480"; conf_hi "29.929581"; cov "1.093458"; +chr4 Cufflinks transcript 62063768 62063821 1000 . . gene_id "CUFF.179577"; transcript_id "CUFF.179577.1"; FPKM "26.3875633685"; frac "1.000000"; conf_lo "0.000000"; conf_hi "56.869362"; cov "1.498813"; +chr4 Cufflinks transcript 77180436 77180462 1000 . . gene_id "CUFF.181019"; transcript_id "CUFF.181019.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr4 Cufflinks transcript 102112070 102112096 1000 . . gene_id "CUFF.183381"; transcript_id "CUFF.183381.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr4 Cufflinks exon 117233771 117233830 1000 + . gene_id "CUFF.185373"; transcript_id "CUFF.185373.1"; exon_number "1"; FPKM "4.8015391601"; frac "1.000000"; conf_lo "0.000000"; conf_hi "14.404617"; cov "0.272727"; +chr4 Cufflinks exon 135563059 135563110 1000 . . gene_id "CUFF.189099"; transcript_id "CUFF.189099.1"; exon_number "1"; FPKM "18.2827837250"; frac "1.000000"; conf_lo "0.000000"; conf_hi "44.138544"; cov "1.038462"; +chr4 Cufflinks exon 147515029 147515097 1000 . . gene_id "CUFF.190627"; transcript_id "CUFF.190627.1"; exon_number "1"; FPKM "34.4458244094"; frac "1.000000"; conf_lo "3.636542"; conf_hi "65.255106"; cov "1.956522"; +chr5 Cufflinks exon 3949522 3949685 1000 . . gene_id "CUFF.192485"; transcript_id "CUFF.192485.1"; exon_number "1"; FPKM "23.1879208220"; frac "1.000000"; conf_lo "6.791585"; conf_hi "39.584257"; cov "1.317073"; +chr5 Cufflinks exon 22635516 22635542 1000 . . gene_id "CUFF.194445"; transcript_id "CUFF.194445.1"; exon_number "1"; FPKM "52.8169307611"; frac "1.000000"; conf_lo "0.000000"; conf_hi "113.804669"; cov "3.000000"; +chr5 Cufflinks exon 34172212 34172238 1000 . . gene_id "CUFF.196463"; transcript_id "CUFF.196463.1"; exon_number "1"; FPKM "17.6056435870"; frac "1.000000"; conf_lo "0.000000"; conf_hi "52.816931"; cov "1.000000"; +chr5 Cufflinks transcript 35362816 35362905 1000 . . gene_id "CUFF.196905"; transcript_id "CUFF.196905.1"; FPKM "10.5633861522"; frac "1.000000"; conf_lo "0.000000"; conf_hi "25.502270"; cov "0.600000"; +chr5 Cufflinks transcript 37083127 37083166 1000 . . gene_id "CUFF.197139"; transcript_id "CUFF.197139.1"; FPKM "23.7676188425"; frac "1.000000"; conf_lo "0.000000"; conf_hi "57.380108"; cov "1.350000"; +chr5 Cufflinks transcript 68089694 68089831 1000 . . gene_id "CUFF.199409"; transcript_id "CUFF.199409.1"; FPKM "17.2229122047"; frac "1.000000"; conf_lo "1.818271"; conf_hi "32.627553"; cov "0.978261"; +chr5 Cufflinks exon 98615179 98615254 1000 . . gene_id "CUFF.201693"; transcript_id "CUFF.201693.1"; exon_number "1"; FPKM "12.5092730750"; frac "1.000000"; conf_lo "0.000000"; conf_hi "30.200057"; cov "0.710526"; +chr5 Cufflinks exon 105915104 105915181 1000 . . gene_id "CUFF.202385"; transcript_id "CUFF.202385.1"; exon_number "1"; FPKM "12.1885224833"; frac "1.000000"; conf_lo "0.000000"; conf_hi "29.425696"; cov "0.692308"; +chr5 Cufflinks transcript 116136788 116136814 1000 . . gene_id "CUFF.204349"; transcript_id "CUFF.204349.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr5 Cufflinks exon 122819526 122819619 1000 . . gene_id "CUFF.205487"; transcript_id "CUFF.205487.1"; exon_number "1"; FPKM "25.2486782797"; frac "1.000000"; conf_lo "2.649470"; conf_hi "47.847887"; cov "1.434124"; +chr5 Cufflinks exon 132055557 132055583 1000 . . gene_id "CUFF.207163"; transcript_id "CUFF.207163.1"; exon_number "1"; FPKM "52.8169307611"; frac "1.000000"; conf_lo "0.000000"; conf_hi "113.804669"; cov "3.000000"; +chr5 Cufflinks transcript 145619548 145619710 1000 . . gene_id "CUFF.209965"; transcript_id "CUFF.209965.1"; FPKM "40.8278115086"; frac "1.000000"; conf_lo "19.004428"; conf_hi "62.651195"; cov "2.319018"; +chr6 Cufflinks exon 48466822 48466848 1000 . . gene_id "CUFF.215907"; transcript_id "CUFF.215907.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr6 Cufflinks exon 63803818 63803844 1000 . . gene_id "CUFF.217337"; transcript_id "CUFF.217337.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr6 Cufflinks transcript 77393088 77393138 1000 . . gene_id "CUFF.218387"; transcript_id "CUFF.218387.1"; FPKM "18.6412696804"; frac "1.000000"; conf_lo "0.000000"; conf_hi "45.004006"; cov "1.058824"; +chr6 Cufflinks transcript 82379452 82379478 1000 . . gene_id "CUFF.218947"; transcript_id "CUFF.218947.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr6 Cufflinks exon 83928984 83929105 1000 . . gene_id "CUFF.219317"; transcript_id "CUFF.219317.1"; exon_number "1"; FPKM "46.7559714935"; frac "1.000000"; conf_lo "19.761399"; conf_hi "73.750544"; cov "2.655738"; +chr6 Cufflinks exon 103658447 103658521 1000 . . gene_id "CUFF.221849"; transcript_id "CUFF.221849.1"; exon_number "1"; FPKM "19.0140950740"; frac "1.000000"; conf_lo "0.000000"; conf_hi "40.969681"; cov "1.080000"; +chr6 Cufflinks exon 113781332 113781358 1000 . . gene_id "CUFF.222775"; transcript_id "CUFF.222775.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr6 Cufflinks exon 118857949 118858148 1000 . . gene_id "CUFF.223543"; transcript_id "CUFF.223543.1"; exon_number "1"; FPKM "19.0140950740"; frac "1.000000"; conf_lo "5.569100"; conf_hi "32.459091"; cov "1.080000"; +chr6 Cufflinks transcript 124996314 124996340 1000 . . gene_id "CUFF.224545"; transcript_id "CUFF.224545.1"; FPKM "17.6056435870"; frac "1.000000"; conf_lo "0.000000"; conf_hi "52.816931"; cov "1.000000"; +chr6 Cufflinks transcript 127077329 127077364 1000 . . gene_id "CUFF.225409"; transcript_id "CUFF.225409.1"; FPKM "52.8169307611"; frac "1.000000"; conf_lo "0.000000"; conf_hi "105.633862"; cov "3.000000"; +chr6 Cufflinks exon 136038245 136038304 1000 . . gene_id "CUFF.225521"; transcript_id "CUFF.225521.1"; exon_number "1"; FPKM "23.7676188425"; frac "1.000000"; conf_lo "0.000000"; conf_hi "51.212101"; cov "1.350000"; +chr7 Cufflinks exon 13845893 13845919 1000 . . gene_id "CUFF.227869"; transcript_id "CUFF.227869.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr7 Cufflinks exon 56060938 56061023 1000 . . gene_id "CUFF.232920"; transcript_id "CUFF.232920.1"; exon_number "1"; FPKM "11.0547064384"; frac "1.000000"; conf_lo "0.000000"; conf_hi "26.688422"; cov "0.627907"; +chr7 Cufflinks exon 71484947 71484992 1000 . . gene_id "CUFF.234766"; transcript_id "CUFF.234766.1"; exon_number "1"; FPKM "20.6674946457"; frac "1.000000"; conf_lo "0.000000"; conf_hi "49.895746"; cov "1.173913"; +chr7 Cufflinks transcript 71784522 71784548 1000 . . gene_id "CUFF.234810"; transcript_id "CUFF.234810.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr7 Cufflinks exon 72605044 72605070 1000 . . gene_id "CUFF.234948"; transcript_id "CUFF.234948.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr7 Cufflinks transcript 85554210 85554343 1000 . . gene_id "CUFF.235778"; transcript_id "CUFF.235778.1"; FPKM "17.7370289869"; frac "1.000000"; conf_lo "1.872548"; conf_hi "33.601510"; cov "1.007463"; +chr7 Cufflinks transcript 98723325 98723416 1000 . . gene_id "CUFF.237594"; transcript_id "CUFF.237594.1"; FPKM "10.3337473228"; frac "1.000000"; conf_lo "0.000000"; conf_hi "24.947873"; cov "0.586957"; +chr7 Cufflinks exon 104055491 104055589 1000 . . gene_id "CUFF.238474"; transcript_id "CUFF.238474.1"; exon_number "1"; FPKM "28.8092349606"; frac "1.000000"; conf_lo "5.286593"; conf_hi "52.331877"; cov "1.636364"; +chr7 Cufflinks exon 107603711 107603748 1000 . . gene_id "CUFF.239180"; transcript_id "CUFF.239180.1"; exon_number "1"; FPKM "25.0185461500"; frac "1.000000"; conf_lo "0.000000"; conf_hi "60.400113"; cov "1.421053"; +chr7 Cufflinks exon 133792511 133792572 1000 . . gene_id "CUFF.242136"; transcript_id "CUFF.242136.1"; exon_number "1"; FPKM "15.3339476403"; frac "1.000000"; conf_lo "0.000000"; conf_hi "37.019424"; cov "0.870968"; +chr8 Cufflinks exon 9970398 9970545 1000 . . gene_id "CUFF.245320"; transcript_id "CUFF.245320.1"; exon_number "1"; FPKM "22.4828826889"; frac "1.000000"; conf_lo "5.487421"; conf_hi "39.478345"; cov "1.277027"; +chr8 Cufflinks transcript 10425062 10425088 1000 . . gene_id "CUFF.245408"; transcript_id "CUFF.245408.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr8 Cufflinks transcript 13018897 13018981 1000 . . gene_id "CUFF.245840"; transcript_id "CUFF.245840.1"; FPKM "16.7771427124"; frac "1.000000"; conf_lo "0.000000"; conf_hi "36.149718"; cov "0.952941"; +chr8 Cufflinks transcript 14745123 14745149 1000 . . gene_id "CUFF.246146"; transcript_id "CUFF.246146.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr8 Cufflinks exon 29820895 29820930 1000 . . gene_id "CUFF.247504"; transcript_id "CUFF.247504.1"; exon_number "1"; FPKM "26.4084653806"; frac "1.000000"; conf_lo "0.000000"; conf_hi "63.755675"; cov "1.500000"; +chr8 Cufflinks transcript 36676568 36676665 1000 . . gene_id "CUFF.248480"; transcript_id "CUFF.248480.1"; FPKM "9.7010689153"; frac "1.000000"; conf_lo "0.000000"; conf_hi "23.420452"; cov "0.551020"; +chr8 Cufflinks transcript 50146533 50146584 1000 . . gene_id "CUFF.249617"; transcript_id "CUFF.249617.1"; FPKM "27.4241755875"; frac "1.000000"; conf_lo "0.000000"; conf_hi "59.090886"; cov "1.557692"; +chr8 Cufflinks exon 51010775 51010850 1000 . . gene_id "CUFF.249695"; transcript_id "CUFF.249695.1"; exon_number "1"; FPKM "18.7639096125"; frac "1.000000"; conf_lo "0.000000"; conf_hi "40.430606"; cov "1.065789"; +chr8 Cufflinks exon 63391023 63391095 1000 . . gene_id "CUFF.250329"; transcript_id "CUFF.250329.1"; exon_number "1"; FPKM "13.0233527904"; frac "1.000000"; conf_lo "0.000000"; conf_hi "31.441155"; cov "0.739726"; +chr8 Cufflinks transcript 73858591 73858706 1000 . . gene_id "CUFF.251697"; transcript_id "CUFF.251697.1"; FPKM "12.2935959530"; frac "1.000000"; conf_lo "0.000000"; conf_hi "26.489018"; cov "0.698276"; +chr8 Cufflinks transcript 75514699 75514725 1000 . . gene_id "CUFF.252263"; transcript_id "CUFF.252263.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr8 Cufflinks exon 86101515 86101548 1000 . . gene_id "CUFF.252891"; transcript_id "CUFF.252891.1"; exon_number "1"; FPKM "27.9619045206"; frac "1.000000"; conf_lo "0.000000"; conf_hi "67.506009"; cov "1.588235"; +chr8 Cufflinks transcript 93627215 93627241 1000 . . gene_id "CUFF.254225"; transcript_id "CUFF.254225.1"; FPKM "52.8169307611"; frac "1.000000"; conf_lo "0.000000"; conf_hi "113.804669"; cov "3.000000"; +chr8 Cufflinks exon 108148187 108148357 1000 . . gene_id "CUFF.255477"; transcript_id "CUFF.255477.1"; exon_number "1"; FPKM "11.1193538445"; frac "1.000000"; conf_lo "0.000000"; conf_hi "22.238708"; cov "0.631579"; +chr8 Cufflinks exon 108190587 108190664 1000 . . gene_id "CUFF.255507"; transcript_id "CUFF.255507.1"; exon_number "1"; FPKM "12.1885224833"; frac "1.000000"; conf_lo "0.000000"; conf_hi "29.425696"; cov "0.692308"; +chr8 Cufflinks exon 120931685 120931769 1000 . . gene_id "CUFF.257375"; transcript_id "CUFF.257375.1"; exon_number "1"; FPKM "16.7771427124"; frac "1.000000"; conf_lo "0.000000"; conf_hi "36.149718"; cov "0.952941"; +chr9 Cufflinks transcript 20449846 20449932 1000 . . gene_id "CUFF.260747"; transcript_id "CUFF.260747.1"; FPKM "234.9313045507"; frac "1.000000"; conf_lo "163.275950"; conf_hi "306.586659"; cov "13.344091"; +chr9 Cufflinks exon 25083606 25083643 1000 . . gene_id "CUFF.261551"; transcript_id "CUFF.261551.1"; exon_number "1"; FPKM "25.0185461500"; frac "1.000000"; conf_lo "0.000000"; conf_hi "60.400113"; cov "1.421053"; +chr9 Cufflinks transcript 27906894 27906964 1000 . . gene_id "CUFF.261925"; transcript_id "CUFF.261925.1"; FPKM "26.7804155972"; frac "1.000000"; conf_lo "0.000000"; conf_hi "53.560831"; cov "1.521127"; +chr9 Cufflinks transcript 34418034 34418065 1000 . . gene_id "CUFF.262975"; transcript_id "CUFF.262975.1"; FPKM "29.7095235531"; frac "1.000000"; conf_lo "0.000000"; conf_hi "71.725135"; cov "1.687500"; +chr9 Cufflinks exon 34710789 34710815 1000 . . gene_id "CUFF.263065"; transcript_id "CUFF.263065.1"; exon_number "1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr9 Cufflinks transcript 40823051 40823090 1000 . . gene_id "CUFF.263747"; transcript_id "CUFF.263747.1"; FPKM "23.7676188425"; frac "1.000000"; conf_lo "0.000000"; conf_hi "57.380108"; cov "1.350000"; +chr9 Cufflinks exon 59236547 59236671 1000 . . gene_id "CUFF.267045"; transcript_id "CUFF.267045.1"; exon_number "1"; FPKM "12.1905895442"; frac "1.000000"; conf_lo "0.000000"; conf_hi "25.808020"; cov "0.692425"; +chr9 Cufflinks transcript 66418162 66418188 1000 . . gene_id "CUFF.268423"; transcript_id "CUFF.268423.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr9 Cufflinks transcript 95913236 95913262 1000 . . gene_id "CUFF.270957"; transcript_id "CUFF.270957.1"; FPKM "35.2112871741"; frac "1.000000"; conf_lo "0.000000"; conf_hi "85.007567"; cov "2.000000"; +chr9 Cufflinks exon 103101949 103102030 1000 . . gene_id "CUFF.271979"; transcript_id "CUFF.271979.1"; exon_number "1"; FPKM "11.5939604110"; frac "1.000000"; conf_lo "0.000000"; conf_hi "27.990296"; cov "0.658537"; +chr9 Cufflinks transcript 105579135 105579173 1000 . . gene_id "CUFF.272347"; transcript_id "CUFF.272347.1"; FPKM "24.3770449667"; frac "1.000000"; conf_lo "0.000000"; conf_hi "58.851393"; cov "1.384615"; +chr9 Cufflinks exon 107445870 107445930 1000 . . gene_id "CUFF.272761"; transcript_id "CUFF.272761.1"; exon_number "1"; FPKM "38.9633095779"; frac "1.000000"; conf_lo "4.113466"; conf_hi "73.813153"; cov "2.213115"; +chr9 Cufflinks exon 113779194 113779220 1000 . . gene_id "CUFF.274445"; transcript_id "CUFF.274445.1"; exon_number "1"; FPKM "52.8169307611"; frac "1.000000"; conf_lo "0.000000"; conf_hi "113.804669"; cov "3.000000"; +chr9 Cufflinks transcript 120860476 120860606 1000 . . gene_id "CUFF.275115"; transcript_id "CUFF.275115.1"; FPKM "25.4005086867"; frac "1.000000"; conf_lo "6.199529"; conf_hi "44.601488"; cov "1.442748"; +chrX Cufflinks exon 10274057 10274087 1000 . . gene_id "CUFF.276147"; transcript_id "CUFF.276147.1"; exon_number "1"; FPKM "99.5432248142"; frac "1.000000"; conf_lo "21.405127"; conf_hi "177.681323"; cov "5.654052"; +chrX Cufflinks transcript 39881431 39881678 1000 . . gene_id "CUFF.277419"; transcript_id "CUFF.277419.1"; FPKM "42.1683560109"; frac "1.000000"; conf_lo "24.187709"; conf_hi "60.149003"; cov "2.395161"; +chrX Cufflinks transcript 90114645 90131913 1000 - . gene_id "CUFF.279771"; transcript_id "CUFF.279771.1"; FPKM "6.8891648819"; frac "1.000000"; conf_lo "0.000000"; conf_hi "20.667495"; cov "0.391304"; +chrX Cufflinks transcript 148249672 148249713 1000 . . gene_id "CUFF.282847"; transcript_id "CUFF.282847.1"; FPKM "56.5895686726"; frac "1.000000"; conf_lo "5.974320"; conf_hi "107.204818"; cov "3.214286"; +chrX Cufflinks transcript 148481505 148482455 1000 + . gene_id "CUFF.282965"; transcript_id "CUFF.282965.1"; FPKM "40.1706233958"; frac "1.000000"; conf_lo "16.978103"; conf_hi "63.363144"; cov "2.281690"; +chrX Cufflinks transcript 158986411 158986471 1000 . . gene_id "CUFF.283831"; transcript_id "CUFF.283831.1"; FPKM "15.5853238312"; frac "1.000000"; conf_lo "0.000000"; conf_hi "37.626300"; cov "0.885246"; --- /dev/null +++ b/tools/filters/gff/gff_filter_by_attribute.xml @@ -0,0 +1,62 @@ +<tool id="gff_filter_by_attribute" name="Filter GFF file by attribute" version="0.1"> + <description>using simple expressions</description> + <command interpreter="python"> + gff_filter_by_attribute.py $input $out_file1 "$attribute_type" "$attribute_name" "$cond" + </command> + <inputs> + <param format="gff" name="input" type="data" label="Filter" help="Query missing? See TIP below."/> + <param name="attribute_name" type="select" label="Attribute name" help=""> + <options from_dataset="input"> + <column name="name" index="8"/> + <column name="value" index="8"/> + <filter type="attribute_value_splitter" pair_separator=";" column="8"/> + </options> + </param> + <param name="attribute_type" type="select" label="Attribute type"> + <option value="float">Float</option> + <option value="int">Integer</option> + <option value="str">String</option> + </param> + <param name="cond" size="40" type="text" value=">0" label="With following condition" help="Double equal signs, ==, must be used as shown above. To filter for an arbitrary string, use the Select tool."> + <validator type="empty_field" message="Enter a valid filtering condition, see syntax and examples below."/> + </param> + </inputs> + <outputs> + <data format="input" name="out_file1" metadata_source="input"/> + </outputs> + <tests> + <test> + <param name="input" value="gff_filter_attr_in1.gff"/> + <param name="attribute_name" value="conf_lo"/> + <param name="attribute_type" value="float"/> + <param name="cond" value=">0"/> + <output name="out_file1" file="gff_filter_by_attribute_out1.gff"/> + </test> + </tests> + + <help> + +.. class:: warningmark + +Double equal signs, ==, must be used as *"equal to"* (e.g., **c1 == 'chr22'**) + +.. class:: infomark + +**TIP:** Attempting to apply a filtering condition may throw exceptions if the data type (e.g., string, integer) in every line of the attribute being filtered is not appropriate for the condition (e.g., attempting certain numerical calculations on strings). If an exception is thrown when applying the condition to a line, that line is skipped as invalid for the filter condition. The number of invalid skipped lines is documented in the resulting history item as a "Condition/data issue". + +.. class:: infomark + +**TIP:** If your data is not TAB delimited, use *Text Manipulation->Convert* + +----- + +**Syntax** + +The filter tool allows you to restrict the dataset using simple conditional statements. + +- Make sure that multi-character operators contain no white space ( e.g., **<=** is valid while **< =** is not valid ) +- When using 'equal-to' operator **double equal sign '==' must be used** ( e.g., **attribute_name=='chr1'** ) +- Non-numerical values must be included in single or double quotes ( e.g., **attribute_name=='XX22'** ) + +</help> +</tool> --- /dev/null +++ b/test-data/gff_filter_by_attribute_out1.gff @@ -0,0 +1,46 @@ +chr10 Cufflinks transcript 62044837 62045189 1000 . . gene_id "CUFF.23531"; transcript_id "CUFF.23531.1"; FPKM "19.5178121606"; frac "1.000000"; conf_lo "9.264456"; conf_hi "29.771168"; cov "1.108611"; +chr10 Cufflinks transcript 75372919 75373002 1000 . . gene_id "CUFF.24985"; transcript_id "CUFF.24985.1"; FPKM "124.4970510798"; frac "1.000000"; conf_lo "71.411330"; conf_hi "177.582772"; cov "7.071429"; +chr10 Cufflinks transcript 80362428 80363292 1000 - . gene_id "CUFF.26065"; transcript_id "CUFF.26065.1"; FPKM "43.6170921216"; frac "1.000000"; conf_lo "32.260169"; conf_hi "54.974016"; cov "2.477449"; +chr11 Cufflinks transcript 7904565 7904642 1000 . . gene_id "CUFF.33508"; transcript_id "CUFF.33508.1"; FPKM "61.6484988869"; frac "1.000000"; conf_lo "22.882428"; conf_hi "100.414569"; cov "3.501633"; +chr11 Cufflinks exon 78140156 78140259 1000 . . gene_id "CUFF.43148"; transcript_id "CUFF.43148.1"; exon_number "1"; FPKM "54.8483511750"; frac "1.000000"; conf_lo "23.181641"; conf_hi "86.515061"; cov "3.115385"; +chr11 Cufflinks exon 105616462 105616737 1000 . . gene_id "CUFF.48385"; transcript_id "CUFF.48385.1"; exon_number "1"; FPKM "18.9452034252"; frac "1.000000"; conf_lo "7.520816"; conf_hi "30.369591"; cov "1.076087"; +chr12 Cufflinks exon 30701762 30702509 1000 . . gene_id "CUFF.53897"; transcript_id "CUFF.53897.1"; exon_number "1"; FPKM "48.9333329111"; frac "1.000000"; conf_lo "37.780391"; conf_hi "60.086275"; cov "2.779412"; +chr13 Cufflinks exon 49159496 49159569 1000 . . gene_id "CUFF.67788"; transcript_id "CUFF.67788.1"; exon_number "1"; FPKM "44.9657653777"; frac "1.000000"; conf_lo "10.974842"; conf_hi "78.956689"; cov "2.554054"; +chr13 Cufflinks transcript 100200304 100200330 1000 . . gene_id "CUFF.73108"; transcript_id "CUFF.73108.1"; FPKM "123.2395051093"; frac "1.000000"; conf_lo "30.079196"; conf_hi "216.399814"; cov "7.000000"; +chr14 Cufflinks transcript 31949103 31949152 1000 . . gene_id "CUFF.77316"; transcript_id "CUFF.77316.1"; FPKM "85.5634278330"; frac "1.000000"; conf_lo "28.521143"; conf_hi "142.605713"; cov "4.860000"; +chr14 Cufflinks exon 67604227 67604668 1000 . . gene_id "CUFF.81446"; transcript_id "CUFF.81446.1"; exon_number "1"; FPKM "123.6776546104"; frac "1.000000"; conf_lo "100.611653"; conf_hi "146.743656"; cov "7.024887"; +chr14 Cufflinks exon 75165582 75165744 1000 . . gene_id "CUFF.82088"; transcript_id "CUFF.82088.1"; exon_number "1"; FPKM "20.4139057543"; frac "1.000000"; conf_lo "4.982443"; conf_hi "35.845368"; cov "1.159509"; +chr16 Cufflinks transcript 57154027 57154067 1000 . . gene_id "CUFF.103364"; transcript_id "CUFF.103364.1"; FPKM "162.3154457537"; frac "1.000000"; conf_lo "75.554191"; conf_hi "249.076701"; cov "9.219512"; +chr16 Cufflinks exon 74862302 74862560 1000 . . gene_id "CUFF.105450"; transcript_id "CUFF.105450.1"; exon_number "1"; FPKM "11.0120241741"; frac "1.000000"; conf_lo "2.020744"; conf_hi "20.003304"; cov "0.625483"; +chr16 Cufflinks transcript 98168779 98168914 1000 . . gene_id "CUFF.107834"; transcript_id "CUFF.107834.1"; FPKM "24.4666664555"; frac "1.000000"; conf_lo "5.971605"; conf_hi "42.961728"; cov "1.389706"; +chr17 Cufflinks exon 8483212 8483268 1000 . . gene_id "CUFF.108498"; transcript_id "CUFF.108498.1"; exon_number "1"; FPKM "50.0370923000"; frac "1.000000"; conf_lo "9.181978"; conf_hi "90.892207"; cov "2.842105"; +chr17 Cufflinks exon 30355791 30355913 1000 . . gene_id "CUFF.111759"; transcript_id "CUFF.111759.1"; exon_number "1"; FPKM "19.3232673516"; frac "1.000000"; conf_lo "2.040012"; conf_hi "36.606523"; cov "1.097561"; +chr18 Cufflinks transcript 39571718 39571880 1000 . . gene_id "CUFF.123569"; transcript_id "CUFF.123569.1"; FPKM "20.4139057543"; frac "1.000000"; conf_lo "4.982443"; conf_hi "35.845368"; cov "1.159509"; +chr19 Cufflinks exon 17633088 17633203 1000 . . gene_id "CUFF.131333"; transcript_id "CUFF.131333.1"; exon_number "1"; FPKM "20.4893265884"; frac "1.000000"; conf_lo "2.163116"; conf_hi "38.815537"; cov "1.163793"; +chr19 Cufflinks transcript 41997624 41997859 1000 . . gene_id "CUFF.133569"; transcript_id "CUFF.133569.1"; FPKM "28.1988698132"; frac "1.000000"; conf_lo "13.125940"; conf_hi "43.271800"; cov "1.601695"; +chr19 Cufflinks exon 56516515 56516684 1000 . . gene_id "CUFF.135203"; transcript_id "CUFF.135203.1"; exon_number "1"; FPKM "33.5542854247"; frac "1.000000"; conf_lo "14.181710"; conf_hi "52.926861"; cov "1.905882"; +chr2 Cufflinks transcript 4543774 4543977 1000 . . gene_id "CUFF.136435"; transcript_id "CUFF.136435.1"; FPKM "37.2825393608"; frac "1.000000"; conf_lo "18.641270"; conf_hi "55.923809"; cov "2.117647"; +chr2 Cufflinks transcript 30200331 30200938 1000 . . gene_id "CUFF.140289"; transcript_id "CUFF.140289.1"; FPKM "100.0741846001"; frac "1.000000"; conf_lo "82.383401"; conf_hi "117.764968"; cov "5.684211"; +chr2 Cufflinks transcript 106644220 106644341 1000 . . gene_id "CUFF.148977"; transcript_id "CUFF.148977.1"; FPKM "27.2743167045"; frac "1.000000"; conf_lo "6.656871"; conf_hi "47.891762"; cov "1.549180"; +chr2 Cufflinks exon 125388931 125389219 1000 . . gene_id "CUFF.151331"; transcript_id "CUFF.151331.1"; exon_number "1"; FPKM "23.0274507817"; frac "1.000000"; conf_lo "10.718761"; conf_hi "35.336141"; cov "1.307958"; +chr3 Cufflinks transcript 130936639 130936898 1000 . . gene_id "CUFF.171349"; transcript_id "CUFF.171349.1"; FPKM "20.1110620975"; frac "1.000000"; conf_lo "7.983635"; conf_hi "32.238489"; cov "1.142308"; +chr3 Cufflinks exon 136592671 136592771 1000 . . gene_id "CUFF.171861"; transcript_id "CUFF.171861.1"; exon_number "1"; FPKM "32.9452142371"; frac "1.000000"; conf_lo "8.040973"; conf_hi "57.849455"; cov "1.871287"; +chr3 Cufflinks transcript 152861374 152861508 1000 . . gene_id "CUFF.173007"; transcript_id "CUFF.173007.1"; FPKM "24.6479010219"; frac "1.000000"; conf_lo "6.015839"; conf_hi "43.279963"; cov "1.400000"; +chr4 Cufflinks exon 13715310 13715630 1000 . . gene_id "CUFF.174817"; transcript_id "CUFF.174817.1"; exon_number "1"; FPKM "19.2510308382"; frac "1.000000"; conf_lo "8.572480"; conf_hi "29.929581"; cov "1.093458"; +chr4 Cufflinks exon 147515029 147515097 1000 . . gene_id "CUFF.190627"; transcript_id "CUFF.190627.1"; exon_number "1"; FPKM "34.4458244094"; frac "1.000000"; conf_lo "3.636542"; conf_hi "65.255106"; cov "1.956522"; +chr5 Cufflinks exon 3949522 3949685 1000 . . gene_id "CUFF.192485"; transcript_id "CUFF.192485.1"; exon_number "1"; FPKM "23.1879208220"; frac "1.000000"; conf_lo "6.791585"; conf_hi "39.584257"; cov "1.317073"; +chr5 Cufflinks transcript 68089694 68089831 1000 . . gene_id "CUFF.199409"; transcript_id "CUFF.199409.1"; FPKM "17.2229122047"; frac "1.000000"; conf_lo "1.818271"; conf_hi "32.627553"; cov "0.978261"; +chr5 Cufflinks exon 122819526 122819619 1000 . . gene_id "CUFF.205487"; transcript_id "CUFF.205487.1"; exon_number "1"; FPKM "25.2486782797"; frac "1.000000"; conf_lo "2.649470"; conf_hi "47.847887"; cov "1.434124"; +chr5 Cufflinks transcript 145619548 145619710 1000 . . gene_id "CUFF.209965"; transcript_id "CUFF.209965.1"; FPKM "40.8278115086"; frac "1.000000"; conf_lo "19.004428"; conf_hi "62.651195"; cov "2.319018"; +chr6 Cufflinks exon 83928984 83929105 1000 . . gene_id "CUFF.219317"; transcript_id "CUFF.219317.1"; exon_number "1"; FPKM "46.7559714935"; frac "1.000000"; conf_lo "19.761399"; conf_hi "73.750544"; cov "2.655738"; +chr6 Cufflinks exon 118857949 118858148 1000 . . gene_id "CUFF.223543"; transcript_id "CUFF.223543.1"; exon_number "1"; FPKM "19.0140950740"; frac "1.000000"; conf_lo "5.569100"; conf_hi "32.459091"; cov "1.080000"; +chr7 Cufflinks transcript 85554210 85554343 1000 . . gene_id "CUFF.235778"; transcript_id "CUFF.235778.1"; FPKM "17.7370289869"; frac "1.000000"; conf_lo "1.872548"; conf_hi "33.601510"; cov "1.007463"; +chr7 Cufflinks exon 104055491 104055589 1000 . . gene_id "CUFF.238474"; transcript_id "CUFF.238474.1"; exon_number "1"; FPKM "28.8092349606"; frac "1.000000"; conf_lo "5.286593"; conf_hi "52.331877"; cov "1.636364"; +chr8 Cufflinks exon 9970398 9970545 1000 . . gene_id "CUFF.245320"; transcript_id "CUFF.245320.1"; exon_number "1"; FPKM "22.4828826889"; frac "1.000000"; conf_lo "5.487421"; conf_hi "39.478345"; cov "1.277027"; +chr9 Cufflinks transcript 20449846 20449932 1000 . . gene_id "CUFF.260747"; transcript_id "CUFF.260747.1"; FPKM "234.9313045507"; frac "1.000000"; conf_lo "163.275950"; conf_hi "306.586659"; cov "13.344091"; +chr9 Cufflinks exon 107445870 107445930 1000 . . gene_id "CUFF.272761"; transcript_id "CUFF.272761.1"; exon_number "1"; FPKM "38.9633095779"; frac "1.000000"; conf_lo "4.113466"; conf_hi "73.813153"; cov "2.213115"; +chr9 Cufflinks transcript 120860476 120860606 1000 . . gene_id "CUFF.275115"; transcript_id "CUFF.275115.1"; FPKM "25.4005086867"; frac "1.000000"; conf_lo "6.199529"; conf_hi "44.601488"; cov "1.442748"; +chrX Cufflinks exon 10274057 10274087 1000 . . gene_id "CUFF.276147"; transcript_id "CUFF.276147.1"; exon_number "1"; FPKM "99.5432248142"; frac "1.000000"; conf_lo "21.405127"; conf_hi "177.681323"; cov "5.654052"; +chrX Cufflinks transcript 39881431 39881678 1000 . . gene_id "CUFF.277419"; transcript_id "CUFF.277419.1"; FPKM "42.1683560109"; frac "1.000000"; conf_lo "24.187709"; conf_hi "60.149003"; cov "2.395161"; +chrX Cufflinks transcript 148249672 148249713 1000 . . gene_id "CUFF.282847"; transcript_id "CUFF.282847.1"; FPKM "56.5895686726"; frac "1.000000"; conf_lo "5.974320"; conf_hi "107.204818"; cov "3.214286"; +chrX Cufflinks transcript 148481505 148482455 1000 + . gene_id "CUFF.282965"; transcript_id "CUFF.282965.1"; FPKM "40.1706233958"; frac "1.000000"; conf_lo "16.978103"; conf_hi "63.363144"; cov "2.281690"; --- a/tools/extract/extract_GFF_Features.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python -#Guruprasad Ananda -""" -Extract features from GFF file. - -usage: %prog input1 out_file1 column features -""" - -import sys, os - -from galaxy import eggs -import pkg_resources; pkg_resources.require( "bx-python" ) -from bx.cookbook import doc_optparse - -assert sys.version_info[:2] >= ( 2, 4 ) - -def stop_err( msg ): - sys.stderr.write( msg ) - sys.exit() - -def main(): - # Parsing Command Line here - options, args = doc_optparse.parse( __doc__ ) - - try: - inp_file, out_file, column, features = args - except: - stop_err( "One or more arguments is missing or invalid.\nUsage: prog input output column features" ) - try: - column = int( column ) - except: - stop_err( "Column %s is an invalid column." % column ) - - if features == None: - stop_err( "Column %d has no features to display, select another column." %( column + 1 ) ) - - fo=open( out_file, 'w' ) - for i, line in enumerate( file( inp_file ) ): - line = line.rstrip( '\r\n' ) - if line and line.startswith( '#' ): - # Keep valid comment lines in the output - fo.write( "%s\n" % line ) - else: - try: - if line.split( '\t' )[column] in features.split( ',' ): - fo.write( "%s\n" % line ) - except: - pass - fo.close() - - print 'Column %d features: %s' %( column + 1, features ) - -if __name__ == "__main__": - main() --- a/tools/ngs_rna/gff_filtering.py +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/env python -# This tool takes a gff file as input and creates filters on attributes based on certain properties. -# The tool will skip over invalid lines within the file, informing the user about the number of lines skipped. -# TODO: much of this code is copied from the Filter1 tool (filtering.py in tools/stats/). The commonalities should be -# abstracted and leveraged in each filtering tool. - -from __future__ import division -import sys, re, os.path - -# Older py compatibility -try: - set() -except: - from sets import Set as set - -assert sys.version_info[:2] >= ( 2, 4 ) - -def get_operands( filter_condition ): - # Note that the order of all_operators is important - items_to_strip = ['+', '-', '**', '*', '//', '/', '%', '<<', '>>', '&', '|', '^', '~', '<=', '<', '>=', '>', '==', '!=', '<>', ' and ', ' or ', ' not ', ' is ', ' is not ', ' in ', ' not in '] - for item in items_to_strip: - if filter_condition.find( item ) >= 0: - filter_condition = filter_condition.replace( item, ' ' ) - operands = set( filter_condition.split( ' ' ) ) - return operands - -def stop_err( msg ): - sys.stderr.write( msg ) - sys.exit() - -in_fname = sys.argv[1] -out_fname = sys.argv[2] -attribute_type = sys.argv[3] -attribute_name = sys.argv[4] -cond_text = sys.argv[5] - -# Unescape if input has been escaped -mapped_str = { - '__lt__': '<', - '__le__': '<=', - '__eq__': '==', - '__ne__': '!=', - '__gt__': '>', - '__ge__': '>=', - '__sq__': '\'', - '__dq__': '"', -} -for key, value in mapped_str.items(): - cond_text = cond_text.replace( key, value ) - -# Condition text is 'attribute meets condition.' -cond_text = attribute_name + cond_text - -# Attempt to determine if the condition includes executable stuff and, if so, exit -secured = dir() -operands = get_operands(cond_text) -for operand in operands: - try: - check = int( operand ) - except: - if operand in secured: - stop_err( "Illegal value '%s' in condition '%s'" % ( operand, cond_text ) ) - -# Set up assignment. -assignment = "%s = attributes.get('%s', None)" % ( attribute_name, attribute_name ) - -# Set up type casting based on attribute type. -type_cast = "%s = %s(%s)" % ( attribute_name, attribute_type, attribute_name) - -# Stats -skipped_lines = 0 -first_invalid_line = 0 -invalid_line = None -lines_kept = 0 -total_lines = 0 -out = open( out_fname, 'wt' ) - -# Read and filter input file, skipping invalid lines -code = ''' -for i, line in enumerate( file( in_fname ) ): - total_lines += 1 - line = line.rstrip( '\\r\\n' ) - if not line or line.startswith( '#' ): - skipped_lines += 1 - if not invalid_line: - first_invalid_line = i + 1 - invalid_line = line - continue - try: - # GTF format: chrom source, name, chromStart, chromEnd, score, strand, frame, attributes. - # Attributes format: name1 "value1" ; name2 "value2" ; ... - elems = line.split( '\t' ) - attributes_list = elems[8].split(";") - attributes = {} - for name_value_pair in attributes_list: - pair = name_value_pair.strip().split(" ") - if pair == '': - continue - name = pair[0].strip() - if name == '': - continue - # Need to strip double quote from values - value = pair[1].strip(" \\"") - attributes[name] = value - %s - if %s: - %s - if %s: - lines_kept += 1 - print >> out, line - except Exception, e: - skipped_lines += 1 - if not invalid_line: - first_invalid_line = i + 1 - invalid_line = line -''' % ( assignment, attribute_name, type_cast, cond_text ) - - -valid_filter = True -try: - exec code -except Exception, e: - out.close() - if str( e ).startswith( 'invalid syntax' ): - valid_filter = False - stop_err( 'Filter condition "%s" likely invalid. See tool tips, syntax and examples.' % cond_text ) - else: - stop_err( str( e ) ) - -if valid_filter: - out.close() - valid_lines = total_lines - skipped_lines - print 'Filtering with %s, ' % ( cond_text ) - if valid_lines > 0: - print 'kept %4.2f%% of %d lines.' % ( 100.0*lines_kept/valid_lines, total_lines ) - else: - print 'Possible invalid filter condition "%s" or non-existent column referenced. See tool tips, syntax and examples.' % cond_text - if skipped_lines > 0: - print 'Skipped %d invalid lines starting at line #%d: "%s"' % ( skipped_lines, first_invalid_line, invalid_line ) --- a/test-data/gff_filtering_out1.gff +++ /dev/null @@ -1,46 +0,0 @@ -chr10 Cufflinks transcript 62044837 62045189 1000 . . gene_id "CUFF.23531"; transcript_id "CUFF.23531.1"; FPKM "19.5178121606"; frac "1.000000"; conf_lo "9.264456"; conf_hi "29.771168"; cov "1.108611"; -chr10 Cufflinks transcript 75372919 75373002 1000 . . gene_id "CUFF.24985"; transcript_id "CUFF.24985.1"; FPKM "124.4970510798"; frac "1.000000"; conf_lo "71.411330"; conf_hi "177.582772"; cov "7.071429"; -chr10 Cufflinks transcript 80362428 80363292 1000 - . gene_id "CUFF.26065"; transcript_id "CUFF.26065.1"; FPKM "43.6170921216"; frac "1.000000"; conf_lo "32.260169"; conf_hi "54.974016"; cov "2.477449"; -chr11 Cufflinks transcript 7904565 7904642 1000 . . gene_id "CUFF.33508"; transcript_id "CUFF.33508.1"; FPKM "61.6484988869"; frac "1.000000"; conf_lo "22.882428"; conf_hi "100.414569"; cov "3.501633"; -chr11 Cufflinks exon 78140156 78140259 1000 . . gene_id "CUFF.43148"; transcript_id "CUFF.43148.1"; exon_number "1"; FPKM "54.8483511750"; frac "1.000000"; conf_lo "23.181641"; conf_hi "86.515061"; cov "3.115385"; -chr11 Cufflinks exon 105616462 105616737 1000 . . gene_id "CUFF.48385"; transcript_id "CUFF.48385.1"; exon_number "1"; FPKM "18.9452034252"; frac "1.000000"; conf_lo "7.520816"; conf_hi "30.369591"; cov "1.076087"; -chr12 Cufflinks exon 30701762 30702509 1000 . . gene_id "CUFF.53897"; transcript_id "CUFF.53897.1"; exon_number "1"; FPKM "48.9333329111"; frac "1.000000"; conf_lo "37.780391"; conf_hi "60.086275"; cov "2.779412"; -chr13 Cufflinks exon 49159496 49159569 1000 . . gene_id "CUFF.67788"; transcript_id "CUFF.67788.1"; exon_number "1"; FPKM "44.9657653777"; frac "1.000000"; conf_lo "10.974842"; conf_hi "78.956689"; cov "2.554054"; -chr13 Cufflinks transcript 100200304 100200330 1000 . . gene_id "CUFF.73108"; transcript_id "CUFF.73108.1"; FPKM "123.2395051093"; frac "1.000000"; conf_lo "30.079196"; conf_hi "216.399814"; cov "7.000000"; -chr14 Cufflinks transcript 31949103 31949152 1000 . . gene_id "CUFF.77316"; transcript_id "CUFF.77316.1"; FPKM "85.5634278330"; frac "1.000000"; conf_lo "28.521143"; conf_hi "142.605713"; cov "4.860000"; -chr14 Cufflinks exon 67604227 67604668 1000 . . gene_id "CUFF.81446"; transcript_id "CUFF.81446.1"; exon_number "1"; FPKM "123.6776546104"; frac "1.000000"; conf_lo "100.611653"; conf_hi "146.743656"; cov "7.024887"; -chr14 Cufflinks exon 75165582 75165744 1000 . . gene_id "CUFF.82088"; transcript_id "CUFF.82088.1"; exon_number "1"; FPKM "20.4139057543"; frac "1.000000"; conf_lo "4.982443"; conf_hi "35.845368"; cov "1.159509"; -chr16 Cufflinks transcript 57154027 57154067 1000 . . gene_id "CUFF.103364"; transcript_id "CUFF.103364.1"; FPKM "162.3154457537"; frac "1.000000"; conf_lo "75.554191"; conf_hi "249.076701"; cov "9.219512"; -chr16 Cufflinks exon 74862302 74862560 1000 . . gene_id "CUFF.105450"; transcript_id "CUFF.105450.1"; exon_number "1"; FPKM "11.0120241741"; frac "1.000000"; conf_lo "2.020744"; conf_hi "20.003304"; cov "0.625483"; -chr16 Cufflinks transcript 98168779 98168914 1000 . . gene_id "CUFF.107834"; transcript_id "CUFF.107834.1"; FPKM "24.4666664555"; frac "1.000000"; conf_lo "5.971605"; conf_hi "42.961728"; cov "1.389706"; -chr17 Cufflinks exon 8483212 8483268 1000 . . gene_id "CUFF.108498"; transcript_id "CUFF.108498.1"; exon_number "1"; FPKM "50.0370923000"; frac "1.000000"; conf_lo "9.181978"; conf_hi "90.892207"; cov "2.842105"; -chr17 Cufflinks exon 30355791 30355913 1000 . . gene_id "CUFF.111759"; transcript_id "CUFF.111759.1"; exon_number "1"; FPKM "19.3232673516"; frac "1.000000"; conf_lo "2.040012"; conf_hi "36.606523"; cov "1.097561"; -chr18 Cufflinks transcript 39571718 39571880 1000 . . gene_id "CUFF.123569"; transcript_id "CUFF.123569.1"; FPKM "20.4139057543"; frac "1.000000"; conf_lo "4.982443"; conf_hi "35.845368"; cov "1.159509"; -chr19 Cufflinks exon 17633088 17633203 1000 . . gene_id "CUFF.131333"; transcript_id "CUFF.131333.1"; exon_number "1"; FPKM "20.4893265884"; frac "1.000000"; conf_lo "2.163116"; conf_hi "38.815537"; cov "1.163793"; -chr19 Cufflinks transcript 41997624 41997859 1000 . . gene_id "CUFF.133569"; transcript_id "CUFF.133569.1"; FPKM "28.1988698132"; frac "1.000000"; conf_lo "13.125940"; conf_hi "43.271800"; cov "1.601695"; -chr19 Cufflinks exon 56516515 56516684 1000 . . gene_id "CUFF.135203"; transcript_id "CUFF.135203.1"; exon_number "1"; FPKM "33.5542854247"; frac "1.000000"; conf_lo "14.181710"; conf_hi "52.926861"; cov "1.905882"; -chr2 Cufflinks transcript 4543774 4543977 1000 . . gene_id "CUFF.136435"; transcript_id "CUFF.136435.1"; FPKM "37.2825393608"; frac "1.000000"; conf_lo "18.641270"; conf_hi "55.923809"; cov "2.117647"; -chr2 Cufflinks transcript 30200331 30200938 1000 . . gene_id "CUFF.140289"; transcript_id "CUFF.140289.1"; FPKM "100.0741846001"; frac "1.000000"; conf_lo "82.383401"; conf_hi "117.764968"; cov "5.684211"; -chr2 Cufflinks transcript 106644220 106644341 1000 . . gene_id "CUFF.148977"; transcript_id "CUFF.148977.1"; FPKM "27.2743167045"; frac "1.000000"; conf_lo "6.656871"; conf_hi "47.891762"; cov "1.549180"; -chr2 Cufflinks exon 125388931 125389219 1000 . . gene_id "CUFF.151331"; transcript_id "CUFF.151331.1"; exon_number "1"; FPKM "23.0274507817"; frac "1.000000"; conf_lo "10.718761"; conf_hi "35.336141"; cov "1.307958"; -chr3 Cufflinks transcript 130936639 130936898 1000 . . gene_id "CUFF.171349"; transcript_id "CUFF.171349.1"; FPKM "20.1110620975"; frac "1.000000"; conf_lo "7.983635"; conf_hi "32.238489"; cov "1.142308"; -chr3 Cufflinks exon 136592671 136592771 1000 . . gene_id "CUFF.171861"; transcript_id "CUFF.171861.1"; exon_number "1"; FPKM "32.9452142371"; frac "1.000000"; conf_lo "8.040973"; conf_hi "57.849455"; cov "1.871287"; -chr3 Cufflinks transcript 152861374 152861508 1000 . . gene_id "CUFF.173007"; transcript_id "CUFF.173007.1"; FPKM "24.6479010219"; frac "1.000000"; conf_lo "6.015839"; conf_hi "43.279963"; cov "1.400000"; -chr4 Cufflinks exon 13715310 13715630 1000 . . gene_id "CUFF.174817"; transcript_id "CUFF.174817.1"; exon_number "1"; FPKM "19.2510308382"; frac "1.000000"; conf_lo "8.572480"; conf_hi "29.929581"; cov "1.093458"; -chr4 Cufflinks exon 147515029 147515097 1000 . . gene_id "CUFF.190627"; transcript_id "CUFF.190627.1"; exon_number "1"; FPKM "34.4458244094"; frac "1.000000"; conf_lo "3.636542"; conf_hi "65.255106"; cov "1.956522"; -chr5 Cufflinks exon 3949522 3949685 1000 . . gene_id "CUFF.192485"; transcript_id "CUFF.192485.1"; exon_number "1"; FPKM "23.1879208220"; frac "1.000000"; conf_lo "6.791585"; conf_hi "39.584257"; cov "1.317073"; -chr5 Cufflinks transcript 68089694 68089831 1000 . . gene_id "CUFF.199409"; transcript_id "CUFF.199409.1"; FPKM "17.2229122047"; frac "1.000000"; conf_lo "1.818271"; conf_hi "32.627553"; cov "0.978261"; -chr5 Cufflinks exon 122819526 122819619 1000 . . gene_id "CUFF.205487"; transcript_id "CUFF.205487.1"; exon_number "1"; FPKM "25.2486782797"; frac "1.000000"; conf_lo "2.649470"; conf_hi "47.847887"; cov "1.434124"; -chr5 Cufflinks transcript 145619548 145619710 1000 . . gene_id "CUFF.209965"; transcript_id "CUFF.209965.1"; FPKM "40.8278115086"; frac "1.000000"; conf_lo "19.004428"; conf_hi "62.651195"; cov "2.319018"; -chr6 Cufflinks exon 83928984 83929105 1000 . . gene_id "CUFF.219317"; transcript_id "CUFF.219317.1"; exon_number "1"; FPKM "46.7559714935"; frac "1.000000"; conf_lo "19.761399"; conf_hi "73.750544"; cov "2.655738"; -chr6 Cufflinks exon 118857949 118858148 1000 . . gene_id "CUFF.223543"; transcript_id "CUFF.223543.1"; exon_number "1"; FPKM "19.0140950740"; frac "1.000000"; conf_lo "5.569100"; conf_hi "32.459091"; cov "1.080000"; -chr7 Cufflinks transcript 85554210 85554343 1000 . . gene_id "CUFF.235778"; transcript_id "CUFF.235778.1"; FPKM "17.7370289869"; frac "1.000000"; conf_lo "1.872548"; conf_hi "33.601510"; cov "1.007463"; -chr7 Cufflinks exon 104055491 104055589 1000 . . gene_id "CUFF.238474"; transcript_id "CUFF.238474.1"; exon_number "1"; FPKM "28.8092349606"; frac "1.000000"; conf_lo "5.286593"; conf_hi "52.331877"; cov "1.636364"; -chr8 Cufflinks exon 9970398 9970545 1000 . . gene_id "CUFF.245320"; transcript_id "CUFF.245320.1"; exon_number "1"; FPKM "22.4828826889"; frac "1.000000"; conf_lo "5.487421"; conf_hi "39.478345"; cov "1.277027"; -chr9 Cufflinks transcript 20449846 20449932 1000 . . gene_id "CUFF.260747"; transcript_id "CUFF.260747.1"; FPKM "234.9313045507"; frac "1.000000"; conf_lo "163.275950"; conf_hi "306.586659"; cov "13.344091"; -chr9 Cufflinks exon 107445870 107445930 1000 . . gene_id "CUFF.272761"; transcript_id "CUFF.272761.1"; exon_number "1"; FPKM "38.9633095779"; frac "1.000000"; conf_lo "4.113466"; conf_hi "73.813153"; cov "2.213115"; -chr9 Cufflinks transcript 120860476 120860606 1000 . . gene_id "CUFF.275115"; transcript_id "CUFF.275115.1"; FPKM "25.4005086867"; frac "1.000000"; conf_lo "6.199529"; conf_hi "44.601488"; cov "1.442748"; -chrX Cufflinks exon 10274057 10274087 1000 . . gene_id "CUFF.276147"; transcript_id "CUFF.276147.1"; exon_number "1"; FPKM "99.5432248142"; frac "1.000000"; conf_lo "21.405127"; conf_hi "177.681323"; cov "5.654052"; -chrX Cufflinks transcript 39881431 39881678 1000 . . gene_id "CUFF.277419"; transcript_id "CUFF.277419.1"; FPKM "42.1683560109"; frac "1.000000"; conf_lo "24.187709"; conf_hi "60.149003"; cov "2.395161"; -chrX Cufflinks transcript 148249672 148249713 1000 . . gene_id "CUFF.282847"; transcript_id "CUFF.282847.1"; FPKM "56.5895686726"; frac "1.000000"; conf_lo "5.974320"; conf_hi "107.204818"; cov "3.214286"; -chrX Cufflinks transcript 148481505 148482455 1000 + . gene_id "CUFF.282965"; transcript_id "CUFF.282965.1"; FPKM "40.1706233958"; frac "1.000000"; conf_lo "16.978103"; conf_hi "63.363144"; cov "2.281690";
1
0
0
0
galaxy-dist commit cd88e599e8fe: removed print stmt
by commits-noreply@bitbucket.org
08 Sep '10
08 Sep '10
# HG changeset patch --
Bitbucket.org
# Project galaxy-dist # URL
http://bitbucket.org/galaxy/galaxy-dist/overview
# User rc # Date 1282836100 14400 # Node ID cd88e599e8fe64bf86ac059c61b130c8cbaf1b52 # Parent 7b9f46307153d0bba1b2253204ad28695d373313 removed print stmt --- a/lib/galaxy/model/migrate/versions/0057_request_notify.py +++ b/lib/galaxy/model/migrate/versions/0057_request_notify.py @@ -53,9 +53,7 @@ def upgrade(): cmd = "SELECT id, notification FROM request" result = db_session.execute( cmd ) for r in result: - print r, str(r[1]) rr = from_json_string(str(r[1])) - print r[0], type(rr), rr, rr['email'], rr['sample_states'] # remove the 'notify' column try:
1
0
0
0
galaxy-dist commit d24fca10862b: Add support for all Galaxy form widget types to data library templates ( library templates now support SelectField, AddressField, CheckboxField, WorkflowField in addition to previously supported TextArea and TextField ).
by commits-noreply@bitbucket.org
08 Sep '10
08 Sep '10
# HG changeset patch --
Bitbucket.org
# Project galaxy-dist # URL
http://bitbucket.org/galaxy/galaxy-dist/overview
# User Greg Von Kuster <greg(a)bx.psu.edu> # Date 1282834547 14400 # Node ID d24fca10862b5b36ba3dbe8a9f318e2e77ef60f2 # Parent af3ee1e9f9e3c0e51b7b18a323b3fa80460aa864 Add support for all Galaxy form widget types to data library templates ( library templates now support SelectField, AddressField, CheckboxField, WorkflowField in addition to previously supported TextArea and TextField ). Create a new UsesFormDefinitionWidgets base controller class for use with all inheriting controllers that use Galaxy forms. Clean up some of the existing code by re-using mehtods in this new controller. Fix bugs related to new user address creation and editing existing user addresses: (1) form contents are now actually checked and if required, error messages are displayed (2) since there is only 1 "address" row in the UserAddress table, eliminate the address1 / address2 form field combination that was appened together for storage in the table ( ther eis now only 1 address line on all forms ). Fix functional tests to reflect above changes. --- a/templates/mobile/manage_library.mako +++ b/templates/mobile/manage_library.mako @@ -1,7 +1,7 @@ <%inherit file="/base.mako"/><%namespace file="/message.mako" import="render_msg" /><%namespace file="/dataset/security_common.mako" import="render_permission_form" /> -<%namespace file="/library/common/common.mako" import="render_template_info" /> +<%namespace file="/library/common/common.mako" import="render_template_fields" /><% current_user_roles = trans.get_current_user_roles() %> @@ -59,7 +59,7 @@ </div><div style="clear: both"></div><div class="toolForm"> - ${render_template_info( 'mobile', library, library.id, 'library' )} + ${render_template_fields( 'mobile', 'library', trans.security.encode_id( library.id ), widgets, widget_fields_have_contents, info_association, inherited )} </div></div> %endif @@ -69,5 +69,5 @@ %endif %if widgets: - ${render_template_info( 'mobile', library, trans.security.encode_id( library.id ), 'edit_library_information', widgets )} + ${render_template_fields( 'mobile', 'library', trans.security.encode_id( library.id ), widgets, widget_fields_have_contents, info_association inherited )} %endif --- a/templates/library/common/library_dataset_info.mako +++ b/templates/library/common/library_dataset_info.mako @@ -1,6 +1,34 @@ <%inherit file="/base.mako"/><%namespace file="/message.mako" import="render_msg" /> -<%namespace file="/library/common/common.mako" import="render_template_info" /> +<%namespace file="/library/common/common.mako" import="render_template_fields" /> + +<%def name="javascripts()"> + ${parent.javascripts()} + <script type="text/javascript"> + $( function() { + $( "select[refresh_on_change='true']").change( function() { + var refresh = false; + var refresh_on_change_values = $( this )[0].attributes.getNamedItem( 'refresh_on_change_values' ) + if ( refresh_on_change_values ) { + refresh_on_change_values = refresh_on_change_values.value.split( ',' ); + var last_selected_value = $( this )[0].attributes.getNamedItem( 'last_selected_value' ); + for( i= 0; i < refresh_on_change_values.length; i++ ) { + if ( $( this )[0].value == refresh_on_change_values[i] || ( last_selected_value && last_selected_value.value == refresh_on_change_values[i] ) ){ + refresh = true; + break; + } + } + } + else { + refresh = true; + } + if ( refresh ){ + $( "#edit_info" ).submit(); + } + }); + }); + </script> +</%def> %if library_dataset == library_dataset.library_dataset_dataset_association.library_dataset: <b><i>This is the latest version of this library dataset</i></b> @@ -63,5 +91,5 @@ %if widgets: ## Templates are not currently supported for library_datasets, only the associated ldda. - ${render_template_info( cntrller, 'library_dataset', library_id, widgets, info_association=None, inherited=False, editable=False )} + ${render_template_fields( cntrller, 'library_dataset', library_id, widgets, widget_fields_have_contents, info_association=None, inherited=False, editable=False )} %endif --- a/templates/library/common/folder_info.mako +++ b/templates/library/common/folder_info.mako @@ -1,6 +1,34 @@ <%inherit file="/base.mako"/><%namespace file="/message.mako" import="render_msg" /> -<%namespace file="/library/common/common.mako" import="render_template_info" /> +<%namespace file="/library/common/common.mako" import="render_template_fields" /> + +<%def name="javascripts()"> + ${parent.javascripts()} + <script type="text/javascript"> + $( function() { + $( "select[refresh_on_change='true']").change( function() { + var refresh = false; + var refresh_on_change_values = $( this )[0].attributes.getNamedItem( 'refresh_on_change_values' ) + if ( refresh_on_change_values ) { + refresh_on_change_values = refresh_on_change_values.value.split( ',' ); + var last_selected_value = $( this )[0].attributes.getNamedItem( 'last_selected_value' ); + for( i= 0; i < refresh_on_change_values.length; i++ ) { + if ( $( this )[0].value == refresh_on_change_values[i] || ( last_selected_value && last_selected_value.value == refresh_on_change_values[i] ) ){ + refresh = true; + break; + } + } + } + else { + refresh = true; + } + if ( refresh ){ + $( "#edit_info" ).submit(); + } + }); + }); + </script> +</%def><% from cgi import escape @@ -53,5 +81,5 @@ </div></div> %if widgets: - ${render_template_info( cntrller=cntrller, item_type='folder', library_id=library_id, widgets=widgets, info_association=info_association, inherited=inherited, folder_id=trans.security.encode_id( folder.id ) )} + ${render_template_fields( cntrller=cntrller, item_type='folder', library_id=library_id, widgets=widgets, widget_fields_have_contents=widget_fields_have_contents, info_association=info_association, inherited=inherited, folder_id=trans.security.encode_id( folder.id ) )} %endif --- a/lib/galaxy/web/form_builder.py +++ b/lib/galaxy/web/form_builder.py @@ -384,8 +384,7 @@ class AddressField(BaseField): return [ ( "short_desc", "Short address description"), ( "name", "Name" ), ( "institution", "Institution" ), - ( "address1", "Address Line 1" ), - ( "address2", "Address Line 2" ), + ( "address", "Address" ), ( "city", "City" ), ( "state", "State/Province/Region" ), ( "postal_code", "Postal Code" ), @@ -437,8 +436,7 @@ class AddressField(BaseField): else: self.select_address.add_option('Add a new address', 'new') return self.select_address.get_html()+address_html - - + class WorkflowField(BaseField): def __init__(self, name, user=None, value=None, params=None): self.name = name --- a/lib/galaxy/web/base/controller.py +++ b/lib/galaxy/web/base/controller.py @@ -8,6 +8,7 @@ from galaxy.web import error, form, url_ from galaxy.model.orm import * from galaxy.workflow.modules import * from galaxy.web.framework import simplejson +from galaxy.web.form_builder import AddressField, CheckboxField, SelectField, TextArea, TextField, WorkflowField from Cheetah.Template import Template @@ -290,7 +291,57 @@ class UsesHistory( SharableItemSecurity if not show_deleted: query = query.filter( trans.model.HistoryDatasetAssociation.deleted == False ) return query.all() - + +class UsesFormDefinitionWidgets: + """Mixin for controllers that use Galaxy form objects.""" + def widget_fields_have_contents( self, widgets ): + # Return True if any of the fields in widgets contain contents, widgets is a list of dictionaries that looks something like: + # [{'widget': <galaxy.web.form_builder.TextField object at 0x10867aa10>, 'helptext': 'Field 0 help (Optional)', 'label': 'Field 0'}] + for i, field in enumerate( widgets ): + if ( isinstance( field[ 'widget' ], TextArea ) or isinstance( field[ 'widget' ], TextField ) ) and field[ 'widget' ].value: + return True + if isinstance( field[ 'widget' ], SelectField ) and field[ 'widget' ].options: + for option_label, option_value, selected in field['widget'].options: + if selected: + return True + if isinstance( field[ 'widget' ], CheckboxField ) and field[ 'widget' ].checked: + return True + if isinstance( field[ 'widget' ], WorkflowField ) and field[ 'widget' ].value not in [ 'none', 'None', None ]: + return True + if isinstance( field[ 'widget' ], AddressField ) and field[ 'widget' ].value not in [ 'none', 'None', None ]: + return True + return False + def clean_field_contents( self, widgets, **kwd ): + params = util.Params( kwd ) + field_contents = [] + for index in range( len( widgets ) ): + widget = widgets[ index ][ 'widget' ] + field_value = params.get( 'field_%i' % ( index ), '' ) + if isinstance( widget, CheckboxField ): + # CheckboxField values are lists if the checkbox is checked + field_value = str( widget.is_checked( field_value ) ).lower() + elif isinstance( widget, AddressField ): + # If the address was new, is has already been saved and widget.value is the new address.id + field_value = widget.value + field_contents.append( util.restore_text( field_value ) ) + return field_contents + def save_widget_field( self, trans, field_obj, index, **kwd ): + # Save a form_builder field object + # TODO: Add support for other field types ( e.g., WorkflowField ) + params = util.Params( kwd ) + if isinstance( field_obj, trans.model.UserAddress ): + field_obj.desc = util.restore_text( params.get( 'field_%i_short_desc' % index, '' ) ) + field_obj.name = util.restore_text( params.get( 'field_%i_name' % index, '' ) ) + field_obj.institution = util.restore_text( params.get( 'field_%i_institution' % index, '' ) ) + field_obj.address = util.restore_text( params.get( 'field_%i_address' % index, '' ) ) + field_obj.city = util.restore_text( params.get( 'field_%i_city' % index, '' ) ) + field_obj.state = util.restore_text( params.get( 'field_%i_state' % index, '' ) ) + field_obj.postal_code = util.restore_text( params.get( 'field_%i_postal_code' % index, '' ) ) + field_obj.country = util.restore_text( params.get( 'field_%i_country' % index, '' ) ) + field_obj.phone = util.restore_text( params.get( 'field_%i_phone' % index, '' ) ) + trans.sa_session.add( field_obj ) + trans.sa_session.flush() + class Sharable: """ Mixin for a controller that manages an item that can be shared. """ # Implemented methods. --- a/test/functional/test_forms_and_requests.py +++ b/test/functional/test_forms_and_requests.py @@ -13,17 +13,15 @@ request_type_name = 'Test Requestype' sample_states = [ ( 'New', 'Sample entered into the system' ), ( 'Received', 'Sample tube received' ), ( 'Done', 'Sequence run complete' ) ] -address1 = dict( short_desc="Office", - name="James+Bond", - institution="MI6" , - address1="MI6+Headquarters", - address2="", - city="London", - state="London", - postal_code="007", - country="United+Kingdom", - phone="007-007-0007" ) - +address_dict = dict( short_desc="Office", + name="James+Bond", + institution="MI6" , + address="MI6+Headquarters", + city="London", + state="London", + postal_code="007", + country="United+Kingdom", + phone="007-007-0007" ) def get_latest_form(form_name): fdc_list = sa_session.query( galaxy.model.FormDefinitionCurrent ) \ @@ -36,7 +34,6 @@ def get_latest_form(form_name): return fdc.latest_form return None - class TestFormsAndRequests( TwillTestCase ): def test_000_initiate_users( self ): """Ensuring all required user accounts exist""" @@ -114,7 +111,7 @@ class TestFormsAndRequests( TwillTestCas def test_010_create_form( self ): """Testing creating a new form and editing it""" self.logout() - self.login( email='test(a)bx.psu.edu' ) + self.login( email=admin_user.email ) # create a form global form_one_name desc = "This is Form One's description" @@ -197,7 +194,6 @@ class TestFormsAndRequests( TwillTestCas pass self.logout() self.login( email=admin_user.email ) - def test_030_create_address_and_library( self ): """Testing address & library creation""" # first create a library for the request so that it can be submitted later @@ -249,22 +245,15 @@ class TestFormsAndRequests( TwillTestCas assert folder_one is not None, 'Problem retrieving library folder named "%s" from the database' % name # create address self.logout() - self.login( email='test1(a)bx.psu.edu', username='regular-user1' ) - self.add_user_address( regular_user1.id, address1 ) - global regular_user - regular_user = sa_session.query( galaxy.model.User ) \ - .filter( galaxy.model.User.table.c.email=='test1(a)bx.psu.edu' ) \ - .first() + self.login( email=regular_user1.email ) + self.add_user_address( regular_user1.id, address_dict ) global user_address - user_address = sa_session.query( galaxy.model.UserAddress ) \ - .filter( and_( galaxy.model.UserAddress.table.c.desc==address1[ 'short_desc' ], - galaxy.model.UserAddress.table.c.deleted==False ) ) \ - .first() + user_address = get_user_address( regular_user1, address_dict[ 'short_desc' ] ) def test_035_create_request( self ): """Testing creating, editing and submitting a request as a regular user""" # login as a regular user self.logout() - self.login( email='test1(a)bx.psu.edu', username='regular-user1' ) + self.login( email=regular_user1.email ) # set field values fields = ['option1', str(user_address.id), 'field three value'] # create the request @@ -302,7 +291,7 @@ class TestFormsAndRequests( TwillTestCas """Testing request lifecycle as it goes through all the states""" # goto admin manage requests page self.logout() - self.login( email='test(a)bx.psu.edu' ) + self.login( email=admin_user.email ) self.check_request_admin_grid(state=request_one.states.SUBMITTED, request_name=request_one.name) self.visit_url( "%s/requests_admin/list?operation=show&id=%s" \ % ( self.url, self.security.encode_id( request_one.id ) )) @@ -317,7 +306,7 @@ class TestFormsAndRequests( TwillTestCas self.home() sa_session.refresh( request_one ) self.logout() - self.login( email='test1(a)bx.psu.edu', username='regular-user1' ) + self.login( email=regular_user1.email ) # check if the request's state is now set to 'complete' self.check_request_grid(state='Complete', request_name=request_one.name) assert request_one.state is not request_one.states.COMPLETE, "The state of the request '%s' should be set to '%s'" \ @@ -325,11 +314,11 @@ class TestFormsAndRequests( TwillTestCas def test_045_admin_create_request_on_behalf_of_regular_user( self ): """Testing creating and submitting a request as an admin on behalf of a regular user""" self.logout() - self.login( email='test(a)bx.psu.edu' ) + self.login( email=admin_user.email ) request_name = "RequestTwo" # simulate request creation url_str = '%s/requests_common/new?cntrller=requests_admin&create_request_button=Save&select_request_type=%i&select_user=%i&name=%s&refresh=True&field_2=%s&field_0=%s&field_1=%i' \ - % ( self.url, request_type.id, regular_user.id, request_name, "field_2_value", 'option1', user_address.id ) + % ( self.url, request_type.id, regular_user1.id, request_name, "field_2_value", 'option1', user_address.id ) print url_str self.home() self.visit_url( url_str ) @@ -363,7 +352,7 @@ class TestFormsAndRequests( TwillTestCas def test_050_reject_request( self ): '''Testing rejecting a request''' self.logout() - self.login( email='test(a)bx.psu.edu' ) + self.login( email=admin_user.email ) self.reject_request( request_two.id, request_two.name, "Rejection test comment" ) sa_session.refresh( request_two ) # check if the request is showing in the 'rejected' filter --- a/templates/library/common/library_info.mako +++ b/templates/library/common/library_info.mako @@ -1,6 +1,34 @@ <%inherit file="/base.mako"/><%namespace file="/message.mako" import="render_msg" /> -<%namespace file="/library/common/common.mako" import="render_template_info" /> +<%namespace file="/library/common/common.mako" import="render_template_fields" /> + +<%def name="javascripts()"> + ${parent.javascripts()} + <script type="text/javascript"> + $( function() { + $( "select[refresh_on_change='true']").change( function() { + var refresh = false; + var refresh_on_change_values = $( this )[0].attributes.getNamedItem( 'refresh_on_change_values' ) + if ( refresh_on_change_values ) { + refresh_on_change_values = refresh_on_change_values.value.split( ',' ); + var last_selected_value = $( this )[0].attributes.getNamedItem( 'last_selected_value' ); + for( i= 0; i < refresh_on_change_values.length; i++ ) { + if ( $( this )[0].value == refresh_on_change_values[i] || ( last_selected_value && last_selected_value.value == refresh_on_change_values[i] ) ){ + refresh = true; + break; + } + } + } + else { + refresh = true; + } + if ( refresh ){ + $( "#edit_info" ).submit(); + } + }); + }); + </script> +</%def><% from cgi import escape @@ -107,5 +135,5 @@ </div> %if widgets: - ${render_template_info( cntrller=cntrller, item_type='library', library_id=trans.security.encode_id( library.id ), widgets=widgets, info_association=info_association, inherited=inherited, editable=not( library.deleted ) )} + ${render_template_fields( cntrller=cntrller, item_type='library', library_id=trans.security.encode_id( library.id ), widgets=widgets, widget_fields_have_contents=widget_fields_have_contents, info_association=info_association, inherited=inherited, editable=not( library.deleted ) )} %endif --- a/lib/galaxy/web/controllers/user.py +++ b/lib/galaxy/web/controllers/user.py @@ -26,7 +26,7 @@ require_login_creation_template = requir VALID_USERNAME_RE = re.compile( "^[a-z0-9\-]+$" ) -class User( BaseController ): +class User( BaseController, UsesFormDefinitionWidgets ): @web.expose def index( self, trans, webapp='galaxy', **kwd ): return trans.fill_template( '/user/index.mako', webapp=webapp ) @@ -263,17 +263,7 @@ class User( BaseController ): if value == 'new': # save this new address in the list of this user's addresses user_address = trans.app.model.UserAddress( user=user ) - user_address.desc = util.restore_text(params.get('field_%i_short_desc' % index, '')) - user_address.name = util.restore_text(params.get('field_%i_name' % index, '')) - user_address.institution = util.restore_text(params.get('field_%i_institution' % index, '')) - user_address.address = util.restore_text(params.get('field_%i_address1' % index, ''))+' '+util.restore_text(params.get('field_%i_address2' % index, '')) - user_address.city = util.restore_text(params.get('field_%i_city' % index, '')) - user_address.state = util.restore_text(params.get('field_%i_state' % index, '')) - user_address.postal_code = util.restore_text(params.get('field_%i_postal_code' % index, '')) - user_address.country = util.restore_text(params.get('field_%i_country' % index, '')) - user_address.phone = util.restore_text(params.get('field_%i_phone' % index, '')) - trans.sa_session.add( user_address ) - trans.sa_session.flush() + self.save_widget_field( trans, user_address, index, **kwd ) trans.sa_session.refresh( user ) values.append(int(user_address.id)) elif value == unicode('none'): @@ -673,8 +663,7 @@ class User( BaseController ): return trans.fill_template( 'user/permissions.mako' ) else: # User not logged in, history group must be only public - return trans.show_error_message( "You must be logged in to change your default permitted actions." ) - + return trans.show_error_message( "You must be logged in to change your default permitted actions." ) @web.expose @web.require_login( "to get most recently used tool" ) @web.json_pretty @@ -697,8 +686,7 @@ class User( BaseController ): "minsizehint" : tool.uihints.get( 'minwidth', -1 ), "description" : tool.description } - return tool_info - + return tool_info @web.expose def manage_addresses(self, trans, **kwd): if trans.user: @@ -726,123 +714,151 @@ class User( BaseController ): message = util.restore_text( params.get( 'message', '' ) ) status = params.get( 'status', 'done' ) admin_view = util.string_as_bool( params.get( 'admin_view', False ) ) - error = '' - user = trans.sa_session.query( trans.app.model.User ).get( int( params.get( 'user_id', None ) ) ) + user_id = params.get( 'user_id', False ) + if not user_id: + # User must be logged in to create a new address + return trans.show_error_message( "You must be logged in to create a new address." ) + user = trans.sa_session.query( trans.app.model.User ).get( int( user_id ) ) + short_desc = util.restore_text( params.get( 'short_desc', '' ) ) + name = util.restore_text( params.get( 'name', '' ) ) + institution = util.restore_text( params.get( 'institution', '' ) ) + address = util.restore_text( params.get( 'address', '' ) ) + city = util.restore_text( params.get( 'city', '' ) ) + state = util.restore_text( params.get( 'state', '' ) ) + postal_code = util.restore_text( params.get( 'postal_code', '' ) ) + country = util.restore_text( params.get( 'country', '' ) ) + phone = util.restore_text( params.get( 'phone', '' ) ) + ok = True if not trans.app.config.allow_user_creation and not trans.user_is_admin(): return trans.show_error_message( 'User registration is disabled. Please contact your Galaxy administrator for an account.' ) - if params.get( 'save_new_address_button', None ) == 'Save': - if not len( util.restore_text( params.get( 'short_desc', '' ) ) ): - error = 'Enter a short description for this address' - elif not len( util.restore_text( params.get( 'name', '' ) ) ): - error = 'Enter the full name' - elif not len( util.restore_text( params.get( 'institution', '' ) ) ): - error = 'Enter the institution associated with the user' - elif not len ( util.restore_text( params.get( 'address1', '' ) ) ): - error = 'Enter the address' - elif not len( util.restore_text( params.get( 'city', '' ) ) ): - error = 'Enter the city' - elif not len( util.restore_text( params.get( 'state', '' ) ) ): - error = 'Enter the state/province/region' - elif not len( util.restore_text( params.get( 'postal_code', '' ) ) ): - error = 'Enter the postal code' - elif not len( util.restore_text( params.get( 'country', '' ) ) ): - error = 'Enter the country' - else: - user_address = trans.app.model.UserAddress( user=user ) - user_address.desc = util.restore_text( params.get( 'short_desc', '' ) ) - user_address.name = util.restore_text( params.get( 'name', '' ) ) - user_address.institution = util.restore_text( params.get( 'institution', '' ) ) - user_address.address = util.restore_text( params.get( 'address1', '' ) )+' '+util.restore_text( params.get( 'address2', '' ) ) - user_address.city = util.restore_text( params.get( 'city', '' ) ) - user_address.state = util.restore_text( params.get( 'state', '' ) ) - user_address.postal_code = util.restore_text( params.get( 'postal_code', '' ) ) - user_address.country = util.restore_text( params.get( 'country', '' ) ) - user_address.phone = util.restore_text( params.get( 'phone', '' ) ) + if params.get( 'new_address_button', False ): + if not short_desc: + ok = False + message = 'Enter a short description for this address' + elif not name: + ok = False + message = 'Enter the name' + elif not institution: + ok = False + message = 'Enter the institution associated with the user' + elif not address: + ok = False + message = 'Enter the address' + elif not city: + ok = False + message = 'Enter the city' + elif not state: + ok = False + message = 'Enter the state/province/region' + elif not postal_code: + ok = False + message = 'Enter the postal code' + elif not country: + ok = False + message = 'Enter the country' + if ok: + user_address = trans.model.UserAddress( user=user, + desc=short_desc, + name=name, + institution=institution, + address=address, + city=city, + state=state, + postal_code=postal_code, + country=country, + phone=phone ) trans.sa_session.add( user_address ) trans.sa_session.flush() - message = 'Address <b>%s</b> has been added' % user_address.desc + message = 'Address (%s) has been added' % user_address.desc if admin_view: return trans.response.send_redirect( web.url_for( controller='user', action='show_info', admin_view=admin_view, user_id=user.id, message=message, - status='done') ) + status='done' ) ) return trans.response.send_redirect( web.url_for( controller='user', action='show_info', message=message, - status='done') ) - else: - # show the address form with the current values filled in - # create the widgets for each address field - widgets = [] - widgets.append(dict(label='Short description', - widget=TextField( 'short_desc', 40, '' ) ) ) - widgets.append(dict(label='Name', - widget=TextField( 'name', 40, '' ) ) ) - widgets.append(dict(label='Institution', - widget=TextField( 'institution', 40, '' ) ) ) - widgets.append(dict(label='Address Line 1', - widget=TextField( 'address1', 40, '' ) ) ) - widgets.append(dict(label='Address Line 2', - widget=TextField( 'address2', 40, '' ) ) ) - widgets.append(dict(label='City', - widget=TextField( 'city', 40, '' ) ) ) - widgets.append(dict(label='State', - widget=TextField( 'state', 40, '' ) ) ) - widgets.append(dict(label='Postal Code', - widget=TextField( 'postal_code', 40, '' ) ) ) - widgets.append(dict(label='Country', - widget=TextField( 'country', 40, '' ) ) ) - widgets.append(dict(label='Phone', - widget=TextField( 'phone', 40, '' ) ) ) - return trans.fill_template( 'user/new_address.mako', - user=user, - admin_view=admin_view, - widgets=widgets, - message=message, - status=status) + status='done' ) ) + # Display the address form with the current values filled in + return trans.fill_template( 'user/new_address.mako', + user=user, + admin_view=admin_view, + short_desc=short_desc, + name=name, + institution=institution, + address=address, + city=city, + state=state, + postal_code=postal_code, + country=country, + phone=phone, + message=message, + status=status ) @web.expose def edit_address( self, trans, **kwd ): params = util.Params( kwd ) - user_id = params.get( 'user_id', None ) - address_id = params.get( 'address_id', None ) message = util.restore_text( params.get( 'message', '' ) ) status = params.get( 'status', 'done' ) admin_view = util.string_as_bool( params.get( 'admin_view', False ) ) - error = '' + user_id = params.get( 'user_id', False ) + if not user_id: + # User must be logged in to create a new address + return trans.show_error_message( "You must be logged in to create a new address." ) user = trans.sa_session.query( trans.app.model.User ).get( int( user_id ) ) - user_address = trans.sa_session.query( trans.app.model.UserAddress ).get( int( address_id ) ) - if params.get( 'edit_address_button', None ) == 'Save changes': - if not len( util.restore_text( params.get( 'short_desc', '' ) ) ): - error = 'Enter a short description for this address' - elif not len( util.restore_text( params.get( 'name', '' ) ) ): - error = 'Enter the full name' - elif not len( util.restore_text( params.get( 'institution', '' ) ) ): - error = 'Enter the institution associated with the user' - elif not len ( util.restore_text( params.get( 'address1', '' ) ) ): - error = 'Enter the address' - elif not len( util.restore_text( params.get( 'city', '' ) ) ): - error = 'Enter the city' - elif not len( util.restore_text( params.get( 'state', '' ) ) ): - error = 'Enter the state/province/region' - elif not len( util.restore_text( params.get( 'postal_code', '' ) ) ): - error = 'Enter the postal code' - elif not len( util.restore_text( params.get( 'country', '' ) ) ): - error = 'Enter the country' - else: - user_address.desc = util.restore_text( params.get( 'short_desc', '' ) ) - user_address.name = util.restore_text( params.get( 'name', '' ) ) - user_address.institution = util.restore_text( params.get( 'institution', '' ) ) - user_address.address = util.restore_text( params.get( 'address1', '' ) )+' '+util.restore_text( params.get( 'address2', '' ) ) - user_address.city = util.restore_text( params.get( 'city', '' ) ) - user_address.state = util.restore_text( params.get( 'state', '' ) ) - user_address.postal_code = util.restore_text( params.get( 'postal_code', '' ) ) - user_address.country = util.restore_text( params.get( 'country', '' ) ) - user_address.phone = util.restore_text( params.get( 'phone', '' ) ) - trans.sa_session.add( user_address ) + address_id = params.get( 'address_id', None ) + if not address_id: + return trans.show_error_message( "No address_id received for editing." ) + address_obj = trans.sa_session.query( trans.app.model.UserAddress ).get( int( address_id ) ) + if params.get( 'edit_address_button', False ): + short_desc = util.restore_text( params.get( 'short_desc', '' ) ) + name = util.restore_text( params.get( 'name', '' ) ) + institution = util.restore_text( params.get( 'institution', '' ) ) + address = util.restore_text( params.get( 'address', '' ) ) + city = util.restore_text( params.get( 'city', '' ) ) + state = util.restore_text( params.get( 'state', '' ) ) + postal_code = util.restore_text( params.get( 'postal_code', '' ) ) + country = util.restore_text( params.get( 'country', '' ) ) + phone = util.restore_text( params.get( 'phone', '' ) ) + ok = True + if not short_desc: + ok = False + message = 'Enter a short description for this address' + elif not name: + ok = False + message = 'Enter the name' + elif not institution: + ok = False + message = 'Enter the institution associated with the user' + elif not address: + ok = False + message = 'Enter the address' + elif not city: + ok = False + message = 'Enter the city' + elif not state: + ok = False + message = 'Enter the state/province/region' + elif not postal_code: + ok = False + message = 'Enter the postal code' + elif not country: + ok = False + message = 'Enter the country' + if ok: + address_obj.desc = short_desc + address_obj.name = name + address_obj.institution = institution + address_obj.address = address + address_obj.city = city + address_obj.state = state + address_obj.postal_code = postal_code + address_obj.country = country + address_obj.phone = phone + trans.sa_session.add( address_obj ) trans.sa_session.flush() - message = 'Changes made to address <b>%s</b> are saved.' % user_address.desc + message = 'Address (%s) has been updated.' % address_obj.desc if admin_view: return trans.response.send_redirect( web.url_for( controller='user', action='show_info', @@ -853,38 +869,14 @@ class User( BaseController ): return trans.response.send_redirect( web.url_for( controller='user', action='show_info', message=message, - status='done') ) - else: - # show the address form with the current values filled in - # create the widgets for each address field - widgets = [] - widgets.append(dict(label='Short description', - widget=TextField( 'short_desc', 40, user_address.desc ) ) ) - widgets.append(dict(label='Name', - widget=TextField( 'name', 40, user_address.name ) ) ) - widgets.append(dict(label='Institution', - widget=TextField( 'institution', 40, user_address.institution ) ) ) - widgets.append(dict(label='Address Line 1', - widget=TextField( 'address1', 40, user_address.address ) ) ) - widgets.append(dict(label='Address Line 2', - widget=TextField( 'address2', 40, '' ) ) ) - widgets.append(dict(label='City', - widget=TextField( 'city', 40, user_address.city ) ) ) - widgets.append(dict(label='State', - widget=TextField( 'state', 40, user_address.state ) ) ) - widgets.append(dict(label='Postal Code', - widget=TextField( 'postal_code', 40, user_address.postal_code ) ) ) - widgets.append(dict(label='Country', - widget=TextField( 'country', 40, user_address.country ) ) ) - widgets.append(dict(label='Phone', - widget=TextField( 'phone', 40, user_address.phone ) ) ) - return trans.fill_template( 'user/edit_address.mako', - user=user, - address=user_address, - admin_view=admin_view, - widgets=widgets, - message=message, - status=status) + status='done' ) ) + # Display the address form with the current values filled in + return trans.fill_template( 'user/edit_address.mako', + user=user, + address_obj=address_obj, + admin_view=admin_view, + message=message, + status=status ) @web.expose def delete_address( self, trans, address_id=None, user_id=None, admin_view=False ): try: @@ -897,12 +889,13 @@ class User( BaseController ): message='Invalid address ID', status='error' ) ) user_address.deleted = True + trans.sa_session.add( user_address ) trans.sa_session.flush() return trans.response.send_redirect( web.url_for( controller='user', action='show_info', admin_view=admin_view, user_id=user_id, - message='Address <b>%s</b> deleted' % user_address.desc, + message='Address (%s) deleted' % user_address.desc, status='done') ) @web.expose def undelete_address( self, trans, address_id=None, user_id=None, admin_view=False ): @@ -921,9 +914,8 @@ class User( BaseController ): action='show_info', admin_view=admin_view, user_id=user_id, - message='Address <b>%s</b> undeleted' % user_address.desc, + message='Address (%s) undeleted' % user_address.desc, status='done') ) - @web.expose def set_user_pref_async( self, trans, pref_name, pref_value ): """ Set a user preference asynchronously. If user is not logged in, do nothing. """ @@ -931,13 +923,11 @@ class User( BaseController ): trans.log_action( trans.get_user(), "set_user_pref", "", { pref_name : pref_value } ) trans.user.preferences[pref_name] = pref_value trans.sa_session.flush() - @web.expose def log_user_action_async( self, trans, action, context, params ): """ Log a user action asynchronously. If user is not logged in, do nothing. """ if trans.user: trans.log_action( trans.get_user(), action, context, params ) - @web.expose @web.require_login() def dbkeys( self, trans, **kwds ): @@ -999,9 +989,7 @@ class User( BaseController ): user=user, dbkeys=dbkeys, message=message, - lines_skipped=lines_skipped ) - - + lines_skipped=lines_skipped ) @web.expose def api_keys( self, trans, **kwd ): params = util.Params( kwd ) --- a/lib/galaxy/web/controllers/requests_common.py +++ b/lib/galaxy/web/controllers/requests_common.py @@ -17,7 +17,7 @@ import csv log = logging.getLogger( __name__ ) -class RequestsCommon( BaseController ): +class RequestsCommon( BaseController, UsesFormDefinitionWidgets ): @web.json def sample_state_updates( self, trans, ids=None, states=None, cntrller=None ): @@ -207,17 +207,7 @@ class RequestsCommon( BaseController ): if value == 'new': # save this new address in the list of this user's addresses user_address = trans.app.model.UserAddress( user=user ) - user_address.desc = util.restore_text(params.get('field_%i_short_desc' % index, '')) - user_address.name = util.restore_text(params.get('field_%i_name' % index, '')) - user_address.institution = util.restore_text(params.get('field_%i_institution' % index, '')) - user_address.address = util.restore_text(params.get('field_%i_address1' % index, ''))+' '+util.restore_text(params.get('field_%i_address2' % index, '')) - user_address.city = util.restore_text(params.get('field_%i_city' % index, '')) - user_address.state = util.restore_text(params.get('field_%i_state' % index, '')) - user_address.postal_code = util.restore_text(params.get('field_%i_postal_code' % index, '')) - user_address.country = util.restore_text(params.get('field_%i_country' % index, '')) - user_address.phone = util.restore_text(params.get('field_%i_phone' % index, '')) - trans.sa_session.add( user_address ) - trans.sa_session.flush() + self.save_widget_field( trans, user_address, index, **kwd ) trans.sa_session.refresh( user ) values.append(int(user_address.id)) elif value == unicode('none'): --- a/templates/library/common/new_folder.mako +++ b/templates/library/common/new_folder.mako @@ -1,6 +1,5 @@ <%inherit file="/base.mako"/><%namespace file="/message.mako" import="render_msg" /> -<%namespace file="/library/common/common.mako" import="render_template_info" /><br/<br/><ul class="manage-table-actions"> --- a/templates/user/edit_address.mako +++ b/templates/user/edit_address.mako @@ -1,7 +1,6 @@ <%inherit file="/base.mako"/><%namespace file="/message.mako" import="render_msg" /> - %if message: ${render_msg( message, status )} %endif @@ -11,23 +10,87 @@ <ul class="manage-table-actions"><li> - <a class="action-button" href="${h.url_for( controller='user', action='show_info', admin_view=admin_view, user_id=user.id)}"> - <span>Manage User Information</span></a> + <a class="action-button" href="${h.url_for( controller='user', action='show_info', admin_view=admin_view, user_id=user.id)}">Manage user information</a></li></ul><div class="toolForm"> -<form name="login_info" id="login_info" action="${h.url_for( controller='user', action='edit_address', admin_view=admin_view, address_id=address.id, user_id=user.id )}" method="post" ><div class="toolFormTitle">Edit address</div><div class="toolFormBody"> - %for field in widgets: + <form name="login_info" id="login_info" action="${h.url_for( controller='user', action='edit_address', admin_view=admin_view, address_id=address_obj.id, user_id=user.id )}" method="post" ><div class="form-row"> - <label>${field[ 'label' ]}</label> - ${field[ 'widget' ].get_html()} + <label>Short Description:</label> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="text" name="short_desc" value="${address_obj.desc}" size="40"> + </div> + <div class="toolParamHelp" style="clear: both;">Required</div> + <div style="clear: both"></div></div> - %endfor - <div class="form-row"> - <input type="submit" name="edit_address_button" value="Save changes"> - </div> + <div class="form-row"> + <label>Name:</label> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="text" name="name" value="${address_obj.name}" size="40"> + </div> + <div class="toolParamHelp" style="clear: both;">Required</div> + <div style="clear: both"></div> + </div> + <div class="form-row"> + <label>Institution:</label> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="text" name="institution" value="${address_obj.institution}" size="40"> + </div> + <div class="toolParamHelp" style="clear: both;">Required</div> + <div style="clear: both"></div> + </div> + <div class="form-row"> + <label>Address Line 1:</label> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="text" name="address" value="${address_obj.address}" size="40"> + </div> + <div class="toolParamHelp" style="clear: both;">Required</div> + <div style="clear: both"></div> + </div> + <div class="form-row"> + <label>City:</label> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="text" name="city" value="${address_obj.city}" size="40"> + </div> + <div class="toolParamHelp" style="clear: both;">Required</div> + <div style="clear: both"></div> + </div> + <div class="form-row"> + <label>State/Province/Region:</label> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="text" name="state" value="${address_obj.state}" size="40"> + </div> + <div class="toolParamHelp" style="clear: both;">Required</div> + <div style="clear: both"></div> + </div> + <div class="form-row"> + <label>Postal Code:</label> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="text" name="postal_code" value="${address_obj.postal_code}" size="40"> + </div> + <div class="toolParamHelp" style="clear: both;">Required</div> + <div style="clear: both"></div> + </div> + <div class="form-row"> + <label>Country:</label> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="text" name="country" value="${address_obj.country}" size="40"> + </div> + <div class="toolParamHelp" style="clear: both;">Required</div> + <div style="clear: both"></div> + </div> + <div class="form-row"> + <label>Phone:</label> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="text" name="phone" value="${address_obj.phone}" size="40"> + </div> + <div style="clear: both"></div> + </div> + <div class="form-row"> + <input type="submit" name="edit_address_button" value="Save changes"> + </div> + </form></div> -</form></div> --- a/templates/user/new_address.mako +++ b/templates/user/new_address.mako @@ -1,13 +1,12 @@ <%inherit file="/base.mako"/><%namespace file="/message.mako" import="render_msg" /> - %if message: ${render_msg( message, status )} %endif </br></br> -<h3>New address</h3> +<h3>Add new address</h3><ul class="manage-table-actions"><li> @@ -16,18 +15,83 @@ </li></ul><div class="toolForm"> -<form name="login_info" id="login_info" action="${h.url_for( controller='user', action='new_address', admin_view=admin_view, user_id=user.id )}" method="post" > - <div class="toolFormTitle">New address</div> + <div class="toolFormTitle">Add new address</div><div class="toolFormBody"> - %for field in widgets: + <form name="login_info" id="login_info" action="${h.url_for( controller='user', action='new_address', admin_view=admin_view, user_id=user.id )}" method="post" ><div class="form-row"> - <label>${field[ 'label' ]}</label> - ${field[ 'widget' ].get_html()} + <label>Short Description:</label> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="text" name="short_desc" value="${short_desc}" size="40"> + </div> + <div class="toolParamHelp" style="clear: both;">Required</div> + <div style="clear: both"></div></div> - %endfor - <div class="form-row"> - <input type="submit" name="save_new_address_button" value="Save"> - </div> + <div class="form-row"> + <label>Name:</label> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="text" name="name" value="${name}" size="40"> + </div> + <div class="toolParamHelp" style="clear: both;">Required</div> + <div style="clear: both"></div> + </div> + <div class="form-row"> + <label>Institution:</label> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="text" name="institution" value="${institution}" size="40"> + </div> + <div class="toolParamHelp" style="clear: both;">Required</div> + <div style="clear: both"></div> + </div> + <div class="form-row"> + <label>Address Line 1:</label> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="text" name="address" value="${address}" size="40"> + </div> + <div class="toolParamHelp" style="clear: both;">Required</div> + <div style="clear: both"></div> + </div> + <div class="form-row"> + <label>City:</label> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="text" name="city" value="${city}" size="40"> + </div> + <div class="toolParamHelp" style="clear: both;">Required</div> + <div style="clear: both"></div> + </div> + <div class="form-row"> + <label>State/Province/Region:</label> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="text" name="state" value="${state}" size="40"> + </div> + <div class="toolParamHelp" style="clear: both;">Required</div> + <div style="clear: both"></div> + </div> + <div class="form-row"> + <label>Postal Code:</label> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="text" name="postal_code" value="${postal_code}" size="40"> + </div> + <div class="toolParamHelp" style="clear: both;">Required</div> + <div style="clear: both"></div> + </div> + <div class="form-row"> + <label>Country:</label> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="text" name="country" value="${country}" size="40"> + </div> + <div class="toolParamHelp" style="clear: both;">Required</div> + <div style="clear: both"></div> + </div> + <div class="form-row"> + <label>Phone:</label> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="text" name="phone" value="${phone}" size="40"> + </div> + <div style="clear: both"></div> + </div> + <div class="form-row"> + <input type="submit" name="new_address_button" value="Save"> + </div> + </form></div> -</form></div> --- a/test/base/twilltestcase.py +++ b/test/base/twilltestcase.py @@ -1573,19 +1573,19 @@ class TwillTestCase( unittest.TestCase ) def add_user_address( self, user_id, address_dict ): self.home() self.visit_url( "%s/user/new_address?admin_view=False&user_id=%i" % ( self.url, user_id ) ) - self.check_page_for_string( 'New address' ) + self.check_page_for_string( 'Add new address' ) for field_name, value in address_dict.items(): tc.fv( "1", field_name, value ) - tc.submit( "save_new_address_button" ) - self.check_page_for_string( 'Address <b>%s</b> has been added' % address_dict[ 'short_desc' ] ) + tc.submit( "new_address_button" ) + self.check_page_for_string( 'Address (%s) has been added' % address_dict[ 'short_desc' ] ) def add_user_address_as_admin( self, user_id, address_dict ): self.home() self.visit_url( "%s/user/new_address?admin_view=True&user_id=%i" % ( self.url, user_id ) ) - self.check_page_for_string( 'New address' ) + self.check_page_for_string( 'Add new address' ) for field_name, value in address_dict.items(): tc.fv( "1", field_name, value ) - tc.submit( "save_new_address_button" ) - self.check_page_for_string( 'Address <b>%s</b> has been added' % address_dict[ 'short_desc' ] ) + tc.submit( "new_address_button" ) + self.check_page_for_string( 'Address (%s) has been added' % address_dict[ 'short_desc' ] ) # Library stuff def add_library_template( self, cntrller, item_type, library_id, form_id, form_name, folder_id=None, ldda_id=None ): --- a/templates/library/common/common.mako +++ b/templates/library/common/common.mako @@ -1,5 +1,61 @@ -<%def name="render_template_info( cntrller, item_type, library_id, widgets, info_association, inherited, folder_id=None, ldda_id=None, editable=True )"> +<%def name="render_template_field( field )"><% + from galaxy.web.form_builder import AddressField, CheckboxField, SelectField, TextArea, TextField, WorkflowField + + has_contents = False + value = '' + if isinstance( field[ 'widget' ], TextArea ) and field[ 'widget' ].value: + has_contents = True + label = field[ 'label' ] + value = '<pre>%s</pre>' % field[ 'widget' ].value + elif isinstance( field[ 'widget' ], TextField ) and field[ 'widget' ].value: + has_contents = True + label = field[ 'label' ] + value = field[ 'widget' ].value + elif isinstance( field[ 'widget' ], SelectField ) and field[ 'widget' ].options: + for option_label, option_value, selected in field['widget'].options: + if selected: + has_contents = True + label = field[ 'label' ] + value = option_value + elif isinstance( field[ 'widget' ], CheckboxField ) and field[ 'widget' ].checked: + has_contents = True + label = field[ 'label' ] + value = 'checked' + elif isinstance( field[ 'widget' ], WorkflowField ) and field[ 'widget' ].value not in [ 'none', 'None', None ]: + has_contents = True + label = field[ 'label' ] + widget = field[ 'widget' ] + workflow_user = widget.user + if workflow_user: + for workflow in workflow_user.stored_workflows: + if not workflow.deleted and str( widget.value ) == str( workflow.id ): + value = workflow.name + break + else: + # If we didn't find the selected workflow option above, we'll just print the value + value = field[ 'widget' ].value + elif isinstance( field[ 'widget' ], AddressField ) and field[ 'widget' ].value not in [ 'none', 'None', None ]: + has_contents = True + widget = field[ 'widget' ] + address = trans.sa_session.query( trans.model.UserAddress ).get( int( widget.value ) ) + label = address.desc + value = address.get_html() + %> + %if has_contents: + <div class="form-row"> + <label>${label}</label> + ${value} + <div class="toolParamHelp" style="clear: both;"> + ${field[ 'helptext' ]} + </div> + <div style="clear: both"></div> + </div> + %endif +</%def> + +<%def name="render_template_fields( cntrller, item_type, library_id, widgets, widget_fields_have_contents, info_association, inherited, folder_id=None, ldda_id=None, editable=True )"> + <% if item_type == 'library': item = trans.sa_session.query( trans.app.model.Library ).get( trans.security.decode_id( library_id ) ) elif item_type == 'folder': @@ -41,7 +97,7 @@ %endif </div><div class="toolFormBody"> - <form name="edit_info" action="${h.url_for( controller='library_common', action='edit_template_info', cntrller=cntrller, item_type=item_type, library_id=library_id, num_widgets=len( widgets ), folder_id=folder_id, ldda_id=ldda_id, show_deleted=show_deleted )}" method="post"> + <form name="edit_info" id="edit_info" action="${h.url_for( controller='library_common', action='edit_template_info', cntrller=cntrller, item_type=item_type, library_id=library_id, folder_id=folder_id, ldda_id=ldda_id, show_deleted=show_deleted )}" method="post"> %for i, field in enumerate( widgets ): <div class="form-row"><label>${field[ 'label' ]}</label> @@ -59,37 +115,17 @@ </div></div><p/> - %else: - <% contents = False %> - %for i, field in enumerate( widgets ): - %if field[ 'widget' ].value: - <% - contents = True - break - %> - %endif - %endfor - %if contents: - <p/> - <div class="toolForm"> - <div class="toolFormTitle">Other information about ${item.name}</div> - <div class="toolFormBody"> - %for i, field in enumerate( widgets ): - %if field[ 'widget' ].value: - <div class="form-row"> - <label>${field[ 'label' ]}</label> - <pre>${field[ 'widget' ].value}</pre> - <div class="toolParamHelp" style="clear: both;"> - ${field[ 'helptext' ]} - </div> - <div style="clear: both"></div> - </div> - %endif - %endfor - </div> + %elif widget_fields_have_contents: + <p/> + <div class="toolForm"> + <div class="toolFormTitle">Other information about ${item.name}</div> + <div class="toolFormBody"> + %for i, field in enumerate( widgets ): + ${render_template_field( field )} + %endfor </div> - <p/> - %endif + </div> + <p/> %endif %endif </%def> --- a/lib/galaxy/web/controllers/library_common.py +++ b/lib/galaxy/web/controllers/library_common.py @@ -6,7 +6,6 @@ from galaxy.security import RBACAgent from galaxy.util.json import to_json_string from galaxy.tools.actions import upload_common from galaxy.web.controllers.forms import get_all_forms -from galaxy.web.form_builder import SelectField, CheckboxField from galaxy.model.orm import * from galaxy.util.streamball import StreamBall import logging, tempfile, zipfile, tarfile, os, sys @@ -52,7 +51,7 @@ except OSError: pass os.rmdir( tmpd ) -class LibraryCommon( BaseController ): +class LibraryCommon( BaseController, UsesFormDefinitionWidgets ): @web.json def library_item_updates( self, trans, ids=None, states=None ): # Avoid caching @@ -160,9 +159,6 @@ class LibraryCommon( BaseController ): use_panels=use_panels, message=util.sanitize_text( message ), status='error' ) ) - # See if we have any associated templates - info_association, inherited = library.get_info_association() - widgets = library.get_template_widgets( trans ) if params.get( 'library_info_button', False ): # Deny modification if the user is not an admin and does not have the LIBRARY_MODIFY permission. if not ( is_admin or trans.app.security_agent.can_modify_library_item( current_user_roles, library ) ): @@ -201,11 +197,16 @@ class LibraryCommon( BaseController ): show_deleted=show_deleted, message=util.sanitize_text( message ), status='done' ) ) + # See if we have any associated templates + info_association, inherited = library.get_info_association() + widgets = library.get_template_widgets( trans ) + widget_fields_have_contents = self.widget_fields_have_contents( widgets ) return trans.fill_template( '/library/common/library_info.mako', cntrller=cntrller, use_panels=use_panels, library=library, widgets=widgets, + widget_fields_have_contents=widget_fields_have_contents, current_user_roles=current_user_roles, show_deleted=show_deleted, info_association=info_association, @@ -402,11 +403,6 @@ class LibraryCommon( BaseController ): show_deleted=show_deleted, message=util.sanitize_text( message ), status='error' ) ) - # See if we have any associated templates - widgets = [] - info_association, inherited = folder.get_info_association() - if info_association and ( not( inherited ) or info_association.inheritable ): - widgets = folder.get_template_widgets( trans ) if params.get( 'rename_folder_button', False ): # Deny modification if the user is not an admin and does not have the LIBRARY_MODIFY permission if not ( is_admin or trans.app.security_agent.can_modify_library_item( current_user_roles, folder ) ): @@ -439,12 +435,20 @@ class LibraryCommon( BaseController ): show_deleted=show_deleted, message=util.sanitize_text( message ), status='done' ) ) + # See if we have any associated templates + widgets = [] + widget_fields_have_contents = False + info_association, inherited = folder.get_info_association() + if info_association and ( not( inherited ) or info_association.inheritable ): + widgets = folder.get_template_widgets( trans ) + widget_fields_have_contents = self.widget_fields_have_contents( widgets ) return trans.fill_template( '/library/common/folder_info.mako', cntrller=cntrller, use_panels=use_panels, folder=folder, library_id=library_id, widgets=widgets, + widget_fields_have_contents=widget_fields_have_contents, current_user_roles=current_user_roles, show_deleted=show_deleted, info_association=info_association, @@ -677,9 +681,11 @@ class LibraryCommon( BaseController ): associated_lddas = [] # See if we have any associated templates widgets = [] + widget_fields_have_contents = False info_association, inherited = ldda.get_info_association() if info_association and ( not( inherited ) or info_association.inheritable ): widgets = ldda.get_template_widgets( trans ) + widget_fields_have_contents = self.widget_fields_have_contents( widgets ) return trans.fill_template( '/library/common/ldda_info.mako', cntrller=cntrller, use_panels=use_panels, @@ -689,6 +695,7 @@ class LibraryCommon( BaseController ): associated_lddas=associated_lddas, show_deleted=show_deleted, widgets=widgets, + widget_fields_have_contents=widget_fields_have_contents, current_user_roles=current_user_roles, info_association=info_association, inherited=inherited, @@ -1524,11 +1531,6 @@ class LibraryCommon( BaseController ): show_deleted=show_deleted, message=util.sanitize_text( message ), status='error' ) ) - # See if we have any associated templates - widgets = [] - info_association, inherited = library_dataset.library_dataset_dataset_association.get_info_association() - if info_association and ( not( inherited ) or info_association.inheritable ): - widgets = library_dataset.library_dataset_dataset_association.get_template_widgets( trans ) if params.get( 'edit_attributes_button', False ): # Deny access if the user is not an admin and does not have the LIBRARY_MODIFY permission. if not ( is_admin or trans.app.security_agent.can_modify_library_item( current_user_roles, library_dataset ) ): @@ -1553,6 +1555,13 @@ class LibraryCommon( BaseController ): trans.sa_session.flush() message = "Information updated for library dataset '%s'." % library_dataset.name status = 'done' + # See if we have any associated templates + widgets = [] + widget_fields_have_contents = False + info_association, inherited = library_dataset.library_dataset_dataset_association.get_info_association() + if info_association and ( not( inherited ) or info_association.inheritable ): + widgets = library_dataset.library_dataset_dataset_association.get_template_widgets( trans ) + widget_fields_have_contents = self.widget_fields_have_contents( widgets ) return trans.fill_template( '/library/common/library_dataset_info.mako', cntrller=cntrller, use_panels=use_panels, @@ -1562,6 +1571,7 @@ class LibraryCommon( BaseController ): info_association=info_association, inherited=inherited, widgets=widgets, + widget_fields_have_contents=widget_fields_have_contents, show_deleted=show_deleted, message=message, status=status ) @@ -2134,7 +2144,7 @@ class LibraryCommon( BaseController ): **kwd ) ) return trans.response.send_redirect( web.url_for( controller='forms', action='edit', **vars ) ) @web.expose - def edit_template_info( self, trans, cntrller, item_type, library_id, num_widgets, folder_id=None, ldda_id=None, **kwd ): + def edit_template_info( self, trans, cntrller, item_type, library_id, folder_id=None, ldda_id=None, **kwd ): # Edit the contents of the template fields without altering the template itself. params = util.Params( kwd ) show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) ) @@ -2156,10 +2166,28 @@ class LibraryCommon( BaseController ): show_deleted=show_deleted, message=util.sanitize_text( message ), status='error' ) ) + # We need the type of each template field widget + widgets = item.get_template_widgets( trans ) + # The list of widgets may include an AddressField which we need to save if it is new + for index, widget_dict in enumerate( widgets ): + widget = widget_dict[ 'widget' ] + if isinstance( widget, AddressField ): + value = util.restore_text( params.get( 'field_%i' % index, '' ) ) + if value == 'new': + if params.get( 'edit_info_button', False ): + # Save the new address + address = trans.app.model.UserAddress( user=trans.user ) + self.save_widget_field( trans, address, index, **kwd ) + widget.value = str( address.id ) + else: + # Form was submitted via refresh_on_change + widget.value = 'new' + elif value == unicode( 'none' ): + widget.value = '' + else: + widget.value = value # Save updated template field contents - field_contents = [] - for index in range( int( num_widgets ) ): - field_contents.append( util.restore_text( params.get( 'field_%i' % ( index ), '' ) ) ) + field_contents = self.clean_field_contents( widgets, **kwd ) if field_contents: # Since information templates are inherited, the template fields can be displayed on the information # page for a folder or ldda when it has no info_association object. If the user has added --- a/templates/library/common/ldda_info.mako +++ b/templates/library/common/ldda_info.mako @@ -1,6 +1,6 @@ <%inherit file="/base.mako"/><%namespace file="/message.mako" import="render_msg" /> -<%namespace file="/library/common/common.mako" import="render_template_info" /> +<%namespace file="/library/common/common.mako" import="render_template_fields" /><% from galaxy import util from galaxy.web.controllers.library_common import branch_deleted, get_containing_library_from_library_dataset @@ -23,6 +23,34 @@ can_modify = can_manage = False %> +<%def name="javascripts()"> + ${parent.javascripts()} + <script type="text/javascript"> + $( function() { + $( "select[refresh_on_change='true']").change( function() { + var refresh = false; + var refresh_on_change_values = $( this )[0].attributes.getNamedItem( 'refresh_on_change_values' ) + if ( refresh_on_change_values ) { + refresh_on_change_values = refresh_on_change_values.value.split( ',' ); + var last_selected_value = $( this )[0].attributes.getNamedItem( 'last_selected_value' ); + for( i= 0; i < refresh_on_change_values.length; i++ ) { + if ( $( this )[0].value == refresh_on_change_values[i] || ( last_selected_value && last_selected_value.value == refresh_on_change_values[i] ) ){ + refresh = true; + break; + } + } + } + else { + refresh = true; + } + if ( refresh ){ + $( "#edit_info" ).submit(); + } + }); + }); + </script> +</%def> + %if current_version: <b><i>This is the latest version of this library dataset</i></b> %else: @@ -134,7 +162,7 @@ </div></div> %if widgets: - ${render_template_info( cntrller=cntrller, item_type='ldda', library_id=library_id, widgets=widgets, info_association=info_association, inherited=inherited, folder_id=trans.security.encode_id( ldda.library_dataset.folder.id ), ldda_id=trans.security.encode_id( ldda.id ), editable=False )} + ${render_template_fields( cntrller=cntrller, item_type='ldda', library_id=library_id, widgets=widgets, widget_fields_have_contents=widget_fields_have_contents, info_association=info_association, inherited=inherited, folder_id=trans.security.encode_id( ldda.library_dataset.folder.id ), ldda_id=trans.security.encode_id( ldda.id ), editable=False )} %endif %if trans.user_is_admin() and cntrller == 'library_admin': %if associated_hdas: --- a/test/base/test_db_util.py +++ b/test/base/test_db_util.py @@ -109,6 +109,13 @@ def get_user( email ): return sa_session.query( galaxy.model.User ) \ .filter( galaxy.model.User.table.c.email==email ) \ .first() +def get_user_address( user, short_desc ): + return sa_session.query( galaxy.model.UserAddress ) \ + .filter( and_( galaxy.model.UserAddress.table.c.user_id==user.id, + galaxy.model.UserAddress.table.c.desc==short_desc, + galaxy.model.UserAddress.table.c.deleted==False ) ) \ + .order_by( desc( galaxy.model.UserAddress.table.c.create_time ) ) \ + .first() def get_user_group_associations_by_group( group ): return sa_session.query( galaxy.model.UserGroupAssociation ) \ .filter( galaxy.model.UserGroupAssociation.table.c.group_id == group.id ) \ --- a/templates/library/common/ldda_edit_info.mako +++ b/templates/library/common/ldda_edit_info.mako @@ -1,11 +1,35 @@ <%inherit file="/base.mako"/><%namespace file="/message.mako" import="render_msg" /> -<%namespace file="/library/common/common.mako" import="render_template_info" /> +<%namespace file="/library/common/common.mako" import="render_template_fields" /><% from galaxy import util %><%def name="javascripts()"> ${parent.javascripts()} ${h.js("jquery.autocomplete", "autocomplete_tagging" )} + <script type="text/javascript"> + $( function() { + $( "select[refresh_on_change='true']").change( function() { + var refresh = false; + var refresh_on_change_values = $( this )[0].attributes.getNamedItem( 'refresh_on_change_values' ) + if ( refresh_on_change_values ) { + refresh_on_change_values = refresh_on_change_values.value.split( ',' ); + var last_selected_value = $( this )[0].attributes.getNamedItem( 'last_selected_value' ); + for( i= 0; i < refresh_on_change_values.length; i++ ) { + if ( $( this )[0].value == refresh_on_change_values[i] || ( last_selected_value && last_selected_value.value == refresh_on_change_values[i] ) ){ + refresh = true; + break; + } + } + } + else { + refresh = true; + } + if ( refresh ){ + $( "#edit_info" ).submit(); + } + }); + }); + </script></%def><%def name="stylesheets()"> @@ -155,5 +179,5 @@ </div> %endif %if widgets: - ${render_template_info( cntrller=cntrller, item_type='ldda', library_id=library_id, widgets=widgets, info_association=info_association, inherited=inherited, folder_id=trans.security.encode_id( ldda.library_dataset.folder.id ), ldda_id=trans.security.encode_id( ldda.id ) )} + ${render_template_fields( cntrller=cntrller, item_type='ldda', library_id=library_id, widgets=widgets, widget_fields_have_contents=widget_fields_have_contents, info_association=info_association, inherited=inherited, folder_id=trans.security.encode_id( ldda.library_dataset.folder.id ), ldda_id=trans.security.encode_id( ldda.id ) )} %endif
1
0
0
0
galaxy-dist commit 7b9f46307153: lims: email notification enhancements
by commits-noreply@bitbucket.org
08 Sep '10
08 Sep '10
# HG changeset patch --
Bitbucket.org
# Project galaxy-dist # URL
http://bitbucket.org/galaxy/galaxy-dist/overview
# User rc # Date 1282835869 14400 # Node ID 7b9f46307153d0bba1b2253204ad28695d373313 # Parent d24fca10862b5b36ba3dbe8a9f318e2e77ef60f2 lims: email notification enhancements - changed the notify field in the request table to JSONType to store recipient email address and other config details - notification of specific sample state changes - changes made to barcode scan AMQP handler to update sample state to also send email when required - notification to multiple recipients - request events history records notifications - UI enhancements to the edit request page to allow users to change notification configurations UI enhancements to the request page to show the request type state, user & notification details --- a/scripts/galaxy_messaging/server/galaxyweb_interface.py +++ b/scripts/galaxy_messaging/server/galaxyweb_interface.py @@ -105,3 +105,19 @@ class GalaxyWebInterface(object): s = ( "!" * ( 8 - len(s) % 8 ) ) + s # Encrypt return id_cipher.encrypt( s ).encode( 'hex' ) + + def update_request_state(self, request_id, sample_id): + params = urllib.urlencode(dict( cntrller='requests_admin', + request_id=request_id, + sample_id=sample_id)) + url = self.base_url + "/requests_admin/update_request_state" + f = self.opener.open(url, params) + print url + print params + x = f.read() + + + + + + --- a/templates/requests/common/new_request.mako +++ b/templates/requests/common/new_request.mako @@ -85,7 +85,7 @@ </div><div style="clear: both"></div></div> - </form> - </div> + </form> + </div></div> %endif --- a/scripts/galaxy_messaging/server/amqp_consumer.py +++ b/scripts/galaxy_messaging/server/amqp_consumer.py @@ -16,11 +16,18 @@ import xml.dom.minidom import subprocess from galaxydb_interface import GalaxyDbInterface +new_path = [ os.path.join( os.getcwd(), "scripts/galaxy_messaging/server" ) ] +new_path.extend( sys.path[1:] ) # remove scripts/ from the path +sys.path = new_path +from galaxyweb_interface import GalaxyWebInterface + assert sys.version_info[:2] >= ( 2, 4 ) new_path = [ os.path.join( os.getcwd(), "lib" ) ] new_path.extend( sys.path[1:] ) # remove scripts/ from the path sys.path = new_path + + from galaxy import eggs import pkg_resources pkg_resources.require( "amqplib" ) @@ -66,6 +73,7 @@ def get_value_index(dom, tag_name, index def recv_callback(msg): global config + global webconfig # check the meesage type. msg_type = msg.properties['application_headers'].get('msg_type') log.debug('\nMESSAGE RECVD: '+str(msg_type)) @@ -88,12 +96,20 @@ def recv_callback(msg): log.debug('Barcode: '+barcode) log.debug('State: '+state) # update the galaxy db - galaxy = GalaxyDbInterface(dbconnstr) - sample_id = galaxy.get_sample_id(field_name='bar_code', value=barcode) + galaxydb = GalaxyDbInterface(dbconnstr) + sample_id = galaxydb.get_sample_id(field_name='bar_code', value=barcode) if sample_id == -1: log.debug('Invalid barcode.') return - galaxy.change_state(sample_id, state) + galaxydb.change_state(sample_id, state) + # update the request state + galaxyweb = GalaxyWebInterface(webconfig.get("universe_wsgi_config", "host"), + webconfig.get("universe_wsgi_config", "port"), + webconfig.get("data_transfer_user_login_info", "email"), + webconfig.get("data_transfer_user_login_info", "password"), + config.get("app:main", "id_secret")) + galaxyweb.update_request_state(galaxydb.get_request_id(sample_id), sample_id) + galaxyweb.logout() def main(): if len(sys.argv) < 2: @@ -108,6 +124,15 @@ def main(): for option in config.options("galaxy_amqp"): amqp_config[option] = config.get("galaxy_amqp", option) log.debug(str(amqp_config)) + # web server config + global webconfig + webconfig = ConfigParser.ConfigParser() + webconfig.read('transfer_datasets.ini') + + + + + conn = amqp.Connection(host=amqp_config['host']+":"+amqp_config['port'], userid=amqp_config['userid'], password=amqp_config['password'], --- a/templates/requests/common/sample_events.mako +++ b/templates/requests/common/sample_events.mako @@ -17,6 +17,13 @@ %endif <div class="toolForm"> + <div class="form-row"> + <div class="toolParamHelp" style="clear: both;"> + <b>Possible states: </b> + <% states = " > ".join([ ss.name for ss in sample.request.type.states ]) %> + ${states} + </div> + </div><table class="grid"><thead><tr> --- a/templates/requests/common/edit_request.mako +++ b/templates/requests/common/edit_request.mako @@ -37,48 +37,86 @@ <a class="action-button" href="${h.url_for( controller=cntrller, action='list', operation='show', id=trans.security.encode_id(request.id))}"><span>Browse this request</span></a></li> + <li> + <a class="action-button" href="${h.url_for( controller=cntrller, action='list')}"> + <span>Browse all requests</span></a> + </li></ul><div class="toolForm"> - <div class="toolFormTitle">Edit request "${request.name}"</div> - %if len(select_request_type.options) == 1: - There are no request types created for a new request. - %else: - <div class="toolFormBody"> - <form name="edit_request" id="edit_request" action="${h.url_for( controller='requests_common', cntrller=cntrller, action='edit', id=trans.security.encode_id(request.id))}" method="post" > + <div class="toolFormTitle">Edit sequencing request "${request.name}"</div> + <div class="toolFormBody"> + <form name="edit_request" id="edit_request" action="${h.url_for( controller='requests_common', cntrller=cntrller, action='edit', id=trans.security.encode_id(request.id))}" method="post" > + %for i, field in enumerate(widgets): <div class="form-row"> - <label> - Select Request Type: - </label> - ${select_request_type.get_html()} + <label>${field['label']}</label> + ${field['widget'].get_html()} + %if field['label'] == 'Data library' and new_library: + ${new_library.get_html()} + %endif + <div class="toolParamHelp" style="clear: both;"> + ${field['helptext']} + </div> + <div style="clear: both"></div></div> - - %if select_request_type.get_selected() != ('Select one', 'none'): - %for i, field in enumerate(widgets): - <div class="form-row"> - <label>${field['label']}</label> - ${field['widget'].get_html()} - %if field['label'] == 'Data library' and new_library: - ${new_library.get_html()} - %endif - <div class="toolParamHelp" style="clear: both;"> - ${field['helptext']} - </div> - <div style="clear: both"></div> - </div> - %endfor - <div class="form-row"> - <div style="float: left; width: 250px; margin-right: 10px;"> - <input type="hidden" name="refresh" value="true" size="40"/> - </div> - <div style="clear: both"></div> - </div> - <div class="form-row"> - <input type="submit" name="save_changes_request_button" value="Save changes"/> - ##<input type="submit" name="edit_samples_button" value="Edit samples"/> - </div> - %endif + %endfor + <div class="form-row"> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="hidden" name="refresh" value="true" size="40"/> + </div> + <div style="clear: both"></div> + </div> + <div class="form-row"> + <input type="submit" name="save_changes_request_button" value="Save"/> + </div></form></div> + <div class="toolFormTitle">Email notification settings</div> + <div class="toolFormBody"> + <form name="settings" id="settings" action="${h.url_for( controller='requests_common', cntrller=cntrller, action='email_settings', id=trans.security.encode_id(request.id))}" method="post" > + <% + email_user = '' + email_additional = [] + for e in request.notification['email']: + if e == request.user.email: + email_user = 'checked' + else: + email_additional.append(e) + emails = '\r\n'.join(email_additional) + + %> + + <div class="form-row"> + <label>Send to:</label> + <input type="checkbox" name="email_user" value="true" ${email_user}>${request.user.email} (Sequencing request owner)<input type="hidden" name="email_user" value="true"> + </div> + <div class="form-row"> + <label>Additional email addresses:</label> + <textarea name="email_additional" rows="3" cols="40">${emails}</textarea> + <div class="toolParamHelp" style="clear: both;"> + Enter one email address per line + </div> + </div> + <div class="form-row"> + <label>Select sample state(s) to send email notification:</label> + %for ss in request.type.states: + <% + email_state = '' + if ss.id in request.notification['sample_states']: + email_state = 'checked' + %> + <input type="checkbox" name=sample_state_${ss.id} value="true" ${email_state} >${ss.name}<input type="hidden" name=sample_state_${ss.id} value="true"> + <br/> + %endfor + <div class="toolParamHelp" style="clear: both;"> + Email notification would be sent when all the samples of this sequencing request are in the selected state(s). + </div> + </div> + + <div class="form-row"> + <input type="submit" name="save_button" value="Save"/> + </div> + </form> + </div> + </div> -%endif --- a/lib/galaxy/model/__init__.py +++ b/lib/galaxy/model/__init__.py @@ -15,7 +15,7 @@ from galaxy.datatypes.metadata import Me from galaxy.security import RBACAgent, get_permitted_actions from galaxy.util.hash_util import * from galaxy.web.form_builder import * -import logging +import logging, smtplib, socket log = logging.getLogger( __name__ ) from sqlalchemy.orm import object_session import pexpect @@ -1520,18 +1520,27 @@ class Request( object ): REJECTED = 'Rejected', COMPLETE = 'Complete' ) def __init__(self, name=None, desc=None, request_type=None, user=None, - form_values=None, notify=None): + form_values=None, notification=None): self.name = name self.desc = desc self.type = request_type self.values = form_values self.user = user - self.notify = notify + self.notification = notification self.samples_list = [] def state(self): if self.events: return self.events[0].state return None + def common_state(self): + ''' + This method returns the state of this request's sample when they are all + in one common state. If not this returns None + ''' + for s in self.samples: + if s.current_state().id != self.samples[0].current_state().id: + return False + return self.samples[0].current_state() def last_comment(self): if self.events: if self.events[0].comment: @@ -1560,7 +1569,66 @@ class Request( object ): if not s.library: samples.append(s.name) return samples + def send_email_notification(self, trans, common_state, final_state=False): + # check if an email notification is configured to be sent when the samples + # are in this state + if common_state.id not in self.notification['sample_states']: + return + comments = '' + # send email + if self.notification['email'] and trans.app.config.smtp_server is not None: + host = trans.request.host.split(':')[0] + if host in ['localhost', '127.0.0.1']: + host = socket.getfqdn() + + body = """ +Galaxy Sample Tracking Notification +=================================== +User: %(user)s + +Sequencing request: %(request_name)s +Sequencing request type: %(request_type)s +Sequencing request state: %(request_state)s + +Number of samples: %(num_samples)s +All samples in state: %(sample_state)s + +""" + values = dict(user=self.user.email, + request_name=self.name, + request_type=self.type.name, + request_state=self.state(), + num_samples=str(len(self.samples)), + sample_state=common_state.name, + create_time=self.create_time, + submit_time=self.create_time) + body = body % values + # check if this is the final state of the samples + if final_state: + txt = "Sample Name -> Data Library/Folder\r\n" + for s in self.samples: + txt = txt + "%s -> %s/%s\r\n" % (s.name, s.library.name, s.folder.name) + body = body + txt + to = self.notification['email'] + frm = 'galaxy-no-reply@' + host + subject = "Galaxy Sample Tracking notification: '%s' sequencing request" % self.name + message = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s" % (frm, ", ".join(to), subject, body) + try: + s = smtplib.SMTP() + s.connect(trans.app.config.smtp_server) + s.sendmail(frm, to, message) + s.quit() + comments = "Email notification sent to %s." % ", ".join(to).strip().strip(',') + except: + comments = "Email notification failed." + # update the request history with the email notification event + elif not trans.app.config.smtp_server: + comments = "Email notification failed as SMTP server not set in config file" + if comments: + event = trans.app.model.RequestEvent(self, self.state(), comments) + trans.sa_session.add(event) + trans.sa_session.flush() class RequestEvent( object ): def __init__(self, request=None, request_state=None, comment=''): @@ -1581,6 +1649,8 @@ class RequestType( object ): self.request_form = request_form self.sample_form = sample_form self.datatx_info = datatx_info + def last_state(self): + return self.states[-1] class RequestTypePermissions( object ): def __init__( self, action, request_type, role ): --- a/lib/galaxy/web/controllers/requests_common.py +++ b/lib/galaxy/web/controllers/requests_common.py @@ -13,7 +13,7 @@ from sqlalchemy.sql import select import pexpect import ConfigParser, threading, time from amqplib import client_0_8 as amqp -import csv +import csv, smtplib, socket log = logging.getLogger( __name__ ) @@ -151,9 +151,6 @@ class RequestsCommon( BaseController, Us util.restore_text( params.get( 'desc', '' ) )), helptext='(Optional)')) widgets = widgets + request_type.request_form.get_widgets( user, **kwd ) - widgets.append(dict(label='Send email notification when the sequencing request is complete', - widget=CheckboxField('email_notify', False), - helptext='Email would be sent to the lab admin and the user for whom this request has been created.')) return trans.fill_template( '/requests/common/new_request.mako', cntrller=cntrller, select_request_type=select_request_type, @@ -188,17 +185,18 @@ class RequestsCommon( BaseController, Us ''' params = util.Params( kwd ) cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) ) - request_type = trans.sa_session.query( trans.app.model.RequestType ).get( int( params.select_request_type ) ) if request: user = request.user + request_type = request.type else: + request_type = trans.sa_session.query( trans.app.model.RequestType ).get( int( params.select_request_type ) ) if cntrller == 'requests_admin' and trans.user_is_admin(): user = trans.sa_session.query( trans.app.model.User ).get( int( params.get( 'select_user', '' ) ) ) elif cntrller == 'requests': user = trans.user name = util.restore_text(params.get('name', '')) desc = util.restore_text(params.get('desc', '')) - notify = CheckboxField.is_checked( params.get('email_notify', '') ) + notification = dict(email=[user.email], sample_states=[request_type.last_state().id], body='', subject='') # fields values = [] for index, field in enumerate(request_type.request_form.fields): @@ -223,7 +221,7 @@ class RequestsCommon( BaseController, Us trans.sa_session.flush() if not request: request = trans.app.model.Request(name, desc, request_type, - user, form_values, notify) + user, form_values, notification) trans.sa_session.add( request ) trans.sa_session.flush() trans.sa_session.refresh( request ) @@ -240,12 +238,66 @@ class RequestsCommon( BaseController, Us request.desc = desc request.type = request_type request.user = user - request.notify = notify + request.notification = notification request.values = form_values trans.sa_session.add( request ) trans.sa_session.flush() return request - + @web.expose + @web.require_login( "create/submit sequencing requests" ) + def email_settings(self, trans, **kwd): + params = util.Params( kwd ) + cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) ) + message = util.restore_text( params.get( 'message', '' ) ) + status = params.get( 'status', 'done' ) + try: + request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id( params.get( 'id', None ) ) ) + except: + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + status='error', + message="Invalid request ID") ) + email_user = CheckboxField.is_checked( params.get('email_user', '') ) + email_additional = params.get('email_additional', '').split('\r\n') + if email_user or email_additional: + emails = [] + if email_user: + emails.append(request.user.email) + for e in email_additional: + emails.append(util.restore_text(e)) + # check if valid email addresses + invalid = '' + for e in emails: + if len( e ) == 0 or "@" not in e or "." not in e: + invalid = e + break + if invalid: + message = "<b>%s</b> is not a valid email address." % invalid + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller=cntrller, + action='edit', + show=True, + id=trans.security.encode_id(request.id), + message=message , + status='error' ) ) + else: + email_states = [] + for i, ss in enumerate(request.type.states): + if CheckboxField.is_checked( params.get('sample_state_%i' % ss.id, '') ): + email_states.append(ss.id) + request.notification = dict(email=emails, sample_states=email_states, + body='', subject='') + trans.sa_session.flush() + trans.sa_session.refresh( request ) + message = 'The changes made to the sequencing request has been saved' + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller=cntrller, + action='show', + id=trans.security.encode_id(request.id), + message=message , + status='done') ) + + @web.expose @web.require_login( "create/submit sequencing requests" ) def edit(self, trans, **kwd): @@ -262,9 +314,8 @@ class RequestsCommon( BaseController, Us message="Invalid request ID") ) if params.get('show', False) == 'True': return self.__edit_request(trans, **kwd) - elif params.get('save_changes_request_button', False) == 'Save changes' \ + elif params.get('save_changes_request_button', False) == 'Save' \ or params.get('edit_samples_button', False) == 'Edit samples': - request_type = trans.sa_session.query( trans.app.model.RequestType ).get( int( params.select_request_type ) ) if not util.restore_text(params.get('name', '')): message = 'Please enter the <b>Name</b> of the request' kwd['status'] = 'error' @@ -276,7 +327,7 @@ class RequestsCommon( BaseController, Us **kwd) ) request = self.__save_request(trans, request, **kwd) message = 'The changes made to the request named %s has been saved' % request.name - if params.get('save_changes_request_button', False) == 'Save changes': + if params.get('save_changes_request_button', False) == 'Save': return trans.response.send_redirect( web.url_for( controller=cntrller, cntrller=cntrller, action='list', @@ -310,7 +361,7 @@ class RequestsCommon( BaseController, Us cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) ) message = util.restore_text( params.get( 'message', '' ) ) status = params.get( 'status', 'done' ) - select_request_type = self.__select_request_type(trans, request.type.id) + #select_request_type = self.__select_request_type(trans, request.type.id) # list of widgets to be rendered on the request form widgets = [] if util.restore_text( params.get( 'name', '' ) ): @@ -328,12 +379,9 @@ class RequestsCommon( BaseController, Us widget=TextField('desc', 40, desc), helptext='(Optional)')) widgets = widgets + request.type.request_form.get_widgets( request.user, request.values.content, **kwd ) - widgets.append(dict(label='Send email notification once the sequencing request is complete', - widget=CheckboxField('email_notify', request.notify), - helptext='')) return trans.fill_template( 'requests/common/edit_request.mako', cntrller=cntrller, - select_request_type=select_request_type, + #select_request_type=select_request_type, request_type=request.type, request=request, widgets=widgets, @@ -399,6 +447,7 @@ class RequestsCommon( BaseController, Us trans.sa_session.add( event ) trans.sa_session.add( request ) trans.sa_session.flush() + request.send_email_notification(trans, new_state) return trans.response.send_redirect( web.url_for( controller=cntrller, action='list', id=trans.security.encode_id(request.id), @@ -486,6 +535,22 @@ class RequestsCommon( BaseController, Us events_list=events_list, request=request) @web.expose @web.require_login( "create/submit sequencing requests" ) + def settings(self, trans, **kwd): + params = util.Params( kwd ) + message = util.restore_text( params.get( 'message', '' ) ) + cntrller = params.get( 'cntrller', 'requests' ) + try: + request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(kwd['id']) ) + except: + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + status='error', + message="Invalid request ID") ) + return trans.fill_template( '/requests/common/settings.mako', + cntrller=cntrller, request=request) + + @web.expose + @web.require_login( "create/submit sequencing requests" ) def show(self, trans, **kwd): params = util.Params( kwd ) message = util.restore_text( params.get( 'message', '' ) ) @@ -807,6 +872,17 @@ class RequestsCommon( BaseController, Us 'Sample added to the system') trans.sa_session.add( event ) trans.sa_session.flush() + # now check if all the samples' barcode has been entered. + # If yes then send notification email if configured + common_state = request.common_state() + if common_state: + if common_state.id == request.type.states[1].id: + event = trans.app.model.RequestEvent(request, + request.states.SUBMITTED, + "All samples are in %s state." % common_state.name) + trans.sa_session.add( event ) + trans.sa_session.flush() + request.send_email_notification(trans, request.type.states[1]) sample.bar_code = current_samples[sample_index]['barcode'] trans.sa_session.add( sample ) trans.sa_session.flush() @@ -962,21 +1038,16 @@ class RequestsCommon( BaseController, Us # list of widgets to be rendered on the request form request_details = [] # main details - request_details.append(dict(label='User', - value=str(request.user.email), - helptext='')) request_details.append(dict(label='Description', value=request.desc, helptext='')) - request_details.append(dict(label='Type', - value=request.type.name, - helptext='')) - request_details.append(dict(label='State', - value=request.state(), - helptext='')) request_details.append(dict(label='Date created', value=request.create_time, helptext='')) + request_details.append(dict(label='Date updated', + value=request.update_time, + helptext='')) + # form fields for index, field in enumerate(request.type.request_form.fields): if field['required']: @@ -996,13 +1067,6 @@ class RequestsCommon( BaseController, Us request_details.append(dict(label=field['label'], value=request.values.content[index], helptext=field['helptext']+' ('+req+')')) - if request.notify: - notify = 'Yes' - else: - notify = 'No' - request_details.append(dict(label='Send email notification once the sequencing request is complete', - value=notify, - helptext='')) return request_details @web.expose @web.require_login( "create/submit sequencing requests" ) @@ -1089,3 +1153,5 @@ class RequestsCommon( BaseController, Us dataset_files=sample.datasets, message=message, status=status, files=[], folder_path=folder_path ) + + --- a/templates/requests/common/show_request.mako +++ b/templates/requests/common/show_request.mako @@ -131,21 +131,35 @@ function showContent(vThis) document.onkeypress = stopRKey </script> -%if request.submitted(): - <% samples_not_ready = request.sequence_run_ready() %> - %if samples_not_ready: - ${render_msg( "Select a target library and folder for all the samples before starting the sequence run", "warning" )} - %endif +<% samples_not_ready = request.sequence_run_ready() %> +%if samples_not_ready: + ${render_msg( "Select a target data library and folder for all the samples before starting the sequence run", "warning" )} %endif %if request.rejected(): ${render_msg( "Reason for rejection: "+request.last_comment(), "warning" )} %endif +%if message: + ${render_msg( message, status )} +%endif + <div class="grid-header"><h2>Sequencing Request "${request.name}"</h2> + <div class="toolParamHelp" style="clear: both;"> + <b>Type</b>: ${request.type.name} + %if cntrller == 'requests_admin': + | <b>User</b>: ${request.user.email} + %endif + %if request.state() == request.states.SUBMITTED: + | <b>State</b>: <i>${request.state()}</i> + %else: + | <b>State</b>: ${request.state()} + %endif + </div> + </div> - +<br/><ul class="manage-table-actions"><li><a class="action-button" id="seqreq-${request.id}-popup" class="menubutton">Sequencing Request Actions</a></li><div popupmenu="seqreq-${request.id}-popup"> @@ -153,10 +167,10 @@ function showContent(vThis) <a class="action-button" confirm="More samples cannot be added to this request once it is submitted. Click OK to submit." href="${h.url_for( controller=cntrller, action='list', operation='Submit', id=trans.security.encode_id(request.id) )}"><span>Submit</span></a> %endif + <a class="action-button" href="${h.url_for( controller=cntrller, action='list', operation='events', id=trans.security.encode_id(request.id) )}"> + <span>History</span></a><a class="action-button" href="${h.url_for( controller=cntrller, action='list', operation='Edit', id=trans.security.encode_id(request.id))}"><span>Edit</span></a> - <a class="action-button" href="${h.url_for( controller=cntrller, action='list', operation='events', id=trans.security.encode_id(request.id) )}"> - <span>History</span></a> %if cntrller == 'requests_admin' and trans.user_is_admin(): %if request.submitted(): <a class="action-button" href="${h.url_for( controller=cntrller, action='list', operation='reject', id=trans.security.encode_id(request.id))}"> @@ -173,41 +187,71 @@ function showContent(vThis) </ul> -%if message: - ${render_msg( message, status )} -%endif <div> -<h3><img src="/static/images/fugue/toggle-expand.png" alt="Show" onclick="showContent(this);" style="cursor:pointer;"/> Request Information</h3> -<div style="display:none;" > - %for index, rd in enumerate(request_details): - <div class="form-row"> - <label>${rd['label']}</label> - %if not rd['value']: - <i>None</i> - %else: - %if rd['label'] == 'State': - <a href="${h.url_for( controller=cntrller, action='list', operation='events', id=trans.security.encode_id(request.id) )}">${rd['value']}</a> - %else: - ${rd['value']} - %endif - %endif - </div> - <div style="clear: both"></div> - %endfor - <div class="form-row"> - <ul class="manage-table-actions"> - <li> - <a class="action-button" href="${h.url_for( controller=cntrller, action='list', operation='Edit', id=trans.security.encode_id(request.id))}"> - <span>Edit request details</span></a> - </li> - </ul> - </div> + <h4><img src="/static/images/fugue/toggle-expand.png" alt="Show" onclick="showContent(this);" style="cursor:pointer;"/> Request Information</h4> + <div style="display:none;" > + <table class="grid" border="0"> + <tbody> + <tr> + <td valign="top" width="50%"> + %for index, rd in enumerate(request_details): + <div class="form-row"> + <label>${rd['label']}:</label> + %if not rd['value']: + <i>None</i> + %else: + %if rd['label'] == 'State': + <a href="${h.url_for( controller=cntrller, action='list', operation='events', id=trans.security.encode_id(request.id) )}">${rd['value']}</a> + %else: + ${rd['value']} + %endif + %endif + </div> + <div style="clear: both"></div> + %endfor + </td> + <td valign="top" width="50%"> + <div class="form-row"> + <label>Email notification recipient(s):</label> + <% emails = ', '.join(request.notification['email']) %> + %if emails: + ${emails} + %else: + <i>None</i> + %endif + </div> + <div style="clear: both"></div> + <div class="form-row"> + <label>Email notification on sample state(s):</label> + <% + states = [] + for ss in request.type.states: + if ss.id in request.notification['sample_states']: + states.append(ss.name) + states = ', '.join(states) + %> + %if states: + ${states} + %else: + <i>None</i> + %endif + </div> + <div style="clear: both"></div> + </td> + </tr> + </tbody> + </table> + <div class="form-row"> + <ul class="manage-table-actions"> + <li> + <a class="action-button" href="${h.url_for( controller=cntrller, action='list', operation='Edit', id=trans.security.encode_id(request.id))}"> + <span>Edit request information</span></a> + </li> + </ul> + </div> + </div></div> -</div> - - - <br/> @@ -395,12 +439,7 @@ function showContent(vThis) <td>${info['name']}</td><td>${info['barcode']}</td> %if sample.request.unsubmitted(): - ##<td>Unsubmitted</td> - <td> - <div id="history-name-container"> - <div id="history-name" class="tooltip editable-text" title="Click to rename history">Unsubmitted</div> - </div> - </td> + <td>Unsubmitted</td> %else: <td id="sampleState-${sample.id}">${render_sample_state( cntrller, sample )}</td> %endif --- a/lib/galaxy/web/controllers/requests_admin.py +++ b/lib/galaxy/web/controllers/requests_admin.py @@ -136,6 +136,7 @@ class RequestsGrid( grids.Grid ): grids.GridOperation( "Reject", allow_multiple=False, condition=( lambda item: not item.deleted and item.submitted() ) ), grids.GridOperation( "Delete", allow_multiple=True, condition=( lambda item: not item.deleted ) ), grids.GridOperation( "Undelete", condition=( lambda item: item.deleted ) ), + grids.GridOperation( "Purge", allow_multiple=False, confirm="This will permanently delete the sequencing request. Click OK to proceed.", condition=( lambda item: item.deleted ) ), ] global_actions = [ grids.GridAction( "Create new request", dict( controller='requests_common', @@ -317,11 +318,6 @@ class RequestsAdmin( BaseController ): cntrller='requests_admin', action='events', **kwd ) ) - if operation == "settings": - return trans.response.send_redirect( web.url_for( controller='requests_common', - cntrller='requests_admin', - action='settings', - **kwd ) ) elif operation == "reject": return self.__reject_request( trans, **kwd ) elif operation == "view_type": @@ -514,41 +510,52 @@ class RequestsAdmin( BaseController ): id=trans.security.encode_id(request.id), message='Bar codes have been saved for this request', status='done')) - def __set_request_state( self, trans, request ): - # check if all the samples of the current request are in the final state - complete = True - for s in request.samples: - if s.current_state().id != request.type.states[-1].id: - complete = False - if request.complete() and not complete: - comments = "One or more samples moved back from the %s state" % request.type.states[-1].name - event = trans.app.model.RequestEvent(request, request.states.SUBMITTED, comments) - trans.sa_session.add( event ) - trans.sa_session.flush() - elif complete: - # change the request state to 'Complete' - comments = "All samples of this request are in the last sample state (%s)." % request.type.states[-1].name - event = trans.app.model.RequestEvent(request, request.states.COMPLETE, comments) - trans.sa_session.add( event ) - trans.sa_session.flush() - # now that the request is complete send the email notification to the - # the user - if request.notify and trans.app.config.smtp_server is not None: - host = trans.request.host.split(':')[0] - if host == 'localhost': - host = socket.getfqdn() - body = "The '%s' sequencing request (type: %s) is now complete. Datasets from all the samples are now available for analysis or download from the respective data libraries in Galaxy." % ( request.name, request.type.name ) - to = [request.user.email] - frm = 'galaxy-no-reply@' + host - subject = "Galaxy Sample Tracking: '%s' sequencing request in complete." % request.name - message = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s" % (frm, ", ".join(to), subject, body) - try: - s = smtplib.SMTP() - s.connect( trans.app.config.smtp_server ) - s.sendmail( frm, [ to ], message ) - s.close() - except: - pass + @web.expose + @web.require_admin + def update_request_state( self, trans, **kwd ): + params = util.Params( kwd ) + try: + request = trans.sa_session.query( trans.app.model.Request ).get( int( params.get( 'request_id', None ) ) ) + sample_id = int(params.get('sample_id', False)) + except: + return trans.response.send_redirect( web.url_for( controller='requests_admin', + action='list', + status='error', + message="Invalid request ID", + **kwd) ) + # check if all the samples of the current request are in the sample state + common_state = request.common_state() + if not common_state: + # if the current request state is complete and one of its samples moved from + # the final sample state, then move the request state to In-progress + if request.complete(): + event = trans.app.model.RequestEvent(request, request.states.SUBMITTED, "One or more samples' state moved from the final sample state.") + trans.sa_session.add( event ) + trans.sa_session.flush() + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller='requests_admin', + action='sample_events', + sample_id=sample_id)) + final_state = False + if common_state.id == request.type.last_state().id: + # since all the samples are in the final state, change the request state to 'Complete' + comments = "All samples of this request are in the last sample state (%s)." % request.type.last_state().name + state = request.states.COMPLETE + final_state = True + else: + comments = "All samples are in %s state." % common_state.name + state = request.states.SUBMITTED + event = trans.app.model.RequestEvent(request, state, comments) + trans.sa_session.add( event ) + trans.sa_session.flush() + # check if an email notification is configured to be sent when the samples + # are in this state +# if common_state.id in request.notification['sample_states']: + request.send_email_notification(trans, common_state, final_state) + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller='requests_admin', + action='sample_events', + sample_id=sample_id)) @web.expose @web.require_admin @@ -573,10 +580,10 @@ class RequestsAdmin( BaseController ): event = trans.app.model.SampleEvent(sample, new_state, comments) trans.sa_session.add( event ) trans.sa_session.flush() - self.__set_request_state( trans, sample.request ) - return trans.response.send_redirect( web.url_for( controller='requests_common', + return trans.response.send_redirect( web.url_for( controller='requests_admin', cntrller='requests_admin', - action='sample_events', + action='update_request_state', + request_id=sample.request.id, sample_id=sample.id)) # # Data transfer from sequencer @@ -1290,3 +1297,6 @@ class RequestsAdmin( BaseController ): roles=roles, status=status, message=message) + + + --- a/test/base/twilltestcase.py +++ b/test/base/twilltestcase.py @@ -1503,7 +1503,7 @@ class TwillTestCase( unittest.TestCase ) def edit_request( self, request_id, name, new_name, new_desc, new_fields): self.home() self.visit_url( "%s/requests/list?operation=Edit&id=%s" % (self.url, self.security.encode_id(request_id) ) ) - self.check_page_for_string( 'Edit request "%s"' % name ) + self.check_page_for_string( 'Edit sequencing request "%s"' % name ) tc.fv( "1", "name", new_name ) tc.fv( "1", "desc", new_desc ) for index, field_value in enumerate(new_fields): --- a/lib/galaxy/model/mapping.py +++ b/lib/galaxy/model/mapping.py @@ -560,7 +560,7 @@ Request.table = Table('request', metadat Column( "update_time", DateTime, default=now, onupdate=now ), Column( "name", TrimmedString( 255 ), nullable=False ), Column( "desc", TEXT ), - Column( "notify", Boolean, default=False ), + Column( "notification", JSONType() ), Column( "form_values_id", Integer, ForeignKey( "form_values.id" ), index=True ), Column( "request_type_id", Integer, ForeignKey( "request_type.id" ), index=True ), Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True ), --- /dev/null +++ b/lib/galaxy/model/migrate/versions/0057_request_notify.py @@ -0,0 +1,69 @@ +""" +Migration script to modify the 'notify' field in the 'request' table from a boolean +to a JSONType +""" + +from sqlalchemy import * +from sqlalchemy.orm import * +from migrate import * +from migrate.changeset import * +from sqlalchemy.exc import * + +from galaxy.model.custom_types import * +from galaxy.util.json import from_json_string, to_json_string + +import datetime +now = datetime.datetime.utcnow + +import logging +log = logging.getLogger( __name__ ) + +metadata = MetaData( migrate_engine ) +db_session = scoped_session( sessionmaker( bind=migrate_engine, autoflush=False, autocommit=True ) ) + + +def upgrade(): + print __doc__ + metadata.reflect() + try: + Request_table = Table( "request", metadata, autoload=True ) + except NoSuchTableError, e: + Request_table = None + log.debug( "Failed loading table 'request'" ) + + + if Request_table: + # create the column again as JSONType + try: + col = Column( "notification", JSONType() ) + col.create( Request_table ) + assert col is Request_table.c.notification + except Exception, e: + log.debug( "Creating column 'notification' in the 'request' table failed: %s" % ( str( e ) ) ) + + cmd = "SELECT id, user_id, notify FROM request" + result = db_session.execute( cmd ) + for r in result: + id = int(r[0]) + notify_old = r[1] + notify_new = dict(email=[], sample_states=[], body='', subject='') + cmd = "update request set notification='%s' where id=%i" % (to_json_string(notify_new), id) + db_session.execute( cmd ) + + cmd = "SELECT id, notification FROM request" + result = db_session.execute( cmd ) + for r in result: + print r, str(r[1]) + rr = from_json_string(str(r[1])) + print r[0], type(rr), rr, rr['email'], rr['sample_states'] + + # remove the 'notify' column + try: + Request_table.c.notify.drop() + except Exception, e: + log.debug( "Deleting column 'notify' from the 'request' table failed: %s" % ( str( e ) ) ) + + + +def downgrade(): + pass --- a/scripts/galaxy_messaging/server/galaxydb_interface.py +++ b/scripts/galaxy_messaging/server/galaxydb_interface.py @@ -57,6 +57,12 @@ class GalaxyDbInterface(object): #log.debug('Sample ID: %i' % sample_id) return sample_id return -1 + + def get_request_id(self, sample_id): + query = select(columns=[self.sample_table.c.request_id], + whereclause=self.sample_table.c.id==sample_id) + request_id = query.execute().fetchall()[0][0] + return request_id def current_state(self, sample_id): '''
1
0
0
0
galaxy-dist commit e95e14f5e7a0: Fix for the issue where multiple of the same action on separate outputs of a single tool were being overwritten as one.
by commits-noreply@bitbucket.org
08 Sep '10
08 Sep '10
# HG changeset patch --
Bitbucket.org
# Project galaxy-dist # URL
http://bitbucket.org/galaxy/galaxy-dist/overview
# User Dannon Baker <dannonbaker(a)me.com> # Date 1282824612 14400 # Node ID e95e14f5e7a0db167a276570495e38f044b17092 # Parent 170229de46ca0b9ca21ea555d5085dd5224dcd79 Fix for the issue where multiple of the same action on separate outputs of a single tool were being overwritten as one. --- a/lib/galaxy/jobs/actions/post.py +++ b/lib/galaxy/jobs/actions/post.py @@ -341,16 +341,17 @@ class ActionBox(object): for key, val in incoming.iteritems(): if key.startswith('pja'): sp = key.split('__') + ao_key = sp[2] + sp[1] # flag / output_name / pjatype / desc - if not sp[2] in npd: - npd[sp[2]] = {'action_type' : sp[2], + if not ao_key in npd: + npd[ao_key] = {'action_type' : sp[2], 'output_name' : sp[1], 'action_arguments' : {}} if len(sp) > 3: if sp[3] == 'output_name': - npd[sp[2]]['output_name'] = val + npd[ao_key]['output_name'] = val else: - npd[sp[2]]['action_arguments'][sp[3]] = val + npd[ao_key]['action_arguments'][sp[3]] = val else: # Not pja stuff. pass --- a/static/scripts/galaxy.workflow_editor.canvas.js +++ b/static/scripts/galaxy.workflow_editor.canvas.js @@ -413,8 +413,8 @@ function Workflow( canvas_container ) { output_name : act.output_name, action_arguments : act.action_arguments } - post_job_actions[ act.type + act.output_name ] = null; - post_job_actions[ act.type + act.output_name ] = pja; + post_job_actions[ act.action_type + act.output_name ] = null; + post_job_actions[ act.action_type + act.output_name ] = pja; }); } if (!node.workflow_outputs){
1
0
0
0
galaxy-dist commit af3ee1e9f9e3: Removing accidentally leftover test line from Tophat wrapper
by commits-noreply@bitbucket.org
08 Sep '10
08 Sep '10
# HG changeset patch --
Bitbucket.org
# Project galaxy-dist # URL
http://bitbucket.org/galaxy/galaxy-dist/overview
# User Kelly Vincent <kpvincent(a)bx.psu.edu> # Date 1282832971 14400 # Node ID af3ee1e9f9e3c0e51b7b18a323b3fa80460aa864 # Parent e95e14f5e7a0db167a276570495e38f044b17092 Removing accidentally leftover test line from Tophat wrapper --- a/tools/ngs_rna/tophat_wrapper.py +++ b/tools/ngs_rna/tophat_wrapper.py @@ -180,7 +180,6 @@ def __main__(): # Copy SAM File. shutil.copyfile( tmp_output_dir + "/accepted_hits.sam", options.accepted_hits_output_file ) - shutil.copyfile(tmp_output_dir + "/accepted_hits.sam", '/afs/bx.psu.edu/user/kpvincent/galaxy-commit/tophat_out.sam') except Exception, e: stop_err( 'Error in tophat:\n' + str( e ) ) finally:
1
0
0
0
← Newer
1
2
3
4
5
6
7
Older →
Jump to page:
1
2
3
4
5
6
7
Results per page:
10
25
50
100
200