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

commit/galaxy-central: greg: Fix grid operations for use in UserListGrid to allow for Delete, Undelete, Purge of users if the allow_user_deletion config setting is true.
by Bitbucket 10 Nov '11
by Bitbucket 10 Nov '11
10 Nov '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/26da65326612/
changeset: 26da65326612
user: greg
date: 2011-11-11 01:23:44
summary: Fix grid operations for use in UserListGrid to allow for Delete, Undelete, Purge of users if the allow_user_deletion config setting is true.
affected #: 5 files
diff -r 52bf302e209ed6890e37fa49215d8875af7ab1f1 -r 26da65326612232bfc7a0a9beddaeb176c9974ae lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -19,7 +19,6 @@
from Cheetah.Template import Template
-
pkg_resources.require( 'elementtree' )
from elementtree import ElementTree, ElementInclude
from elementtree.ElementTree import Element
@@ -1298,6 +1297,9 @@
group_list_grid = None
quota_list_grid = None
repository_list_grid = None
+ delete_operation = None
+ undelete_operation = None
+ purge_operation = None
@web.expose
@web.require_admin
@@ -2217,6 +2219,13 @@
**kwd ) )
elif operation == "manage roles and groups":
return self.manage_roles_and_groups_for_user( trans, **kwd )
+ if trans.app.config.allow_user_deletion:
+ if self.delete_operation not in self.user_list_grid.operations:
+ self.user_list_grid.operations.append( self.delete_operation )
+ if self.undelete_operation not in self.user_list_grid.operations:
+ self.user_list_grid.operations.append( self.undelete_operation )
+ if self.purge_operation not in self.user_list_grid.operations:
+ self.user_list_grid.operations.append( self.purge_operation )
# Render the list view
return self.user_list_grid( trans, **kwd )
@web.expose
diff -r 52bf302e209ed6890e37fa49215d8875af7ab1f1 -r 26da65326612232bfc7a0a9beddaeb176c9974ae lib/galaxy/web/controllers/admin.py
--- a/lib/galaxy/web/controllers/admin.py
+++ b/lib/galaxy/web/controllers/admin.py
@@ -93,11 +93,6 @@
allow_popup=False,
url_args=dict( webapp="galaxy", action="reset_user_password" ) )
]
- #TODO: enhance to account for trans.app.config.allow_user_deletion here so that we can eliminate these operations if
- # the setting is False
- #operations.append( grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ), allow_multiple=True ) )
- #operations.append( grids.GridOperation( "Undelete", condition=( lambda item: item.deleted and not item.purged ), allow_multiple=True ) )
- #operations.append( grids.GridOperation( "Purge", condition=( lambda item: item.deleted and not item.purged ), allow_multiple=True ) )
standard_filters = [
grids.GridColumnFilter( "Active", args=dict( deleted=False ) ),
grids.GridColumnFilter( "Deleted", args=dict( deleted=True, purged=False ) ),
@@ -443,6 +438,9 @@
group_list_grid = GroupListGrid()
quota_list_grid = QuotaListGrid()
repository_list_grid = RepositoryListGrid()
+ delete_operation = grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ), allow_multiple=True )
+ undelete_operation = grids.GridOperation( "Undelete", condition=( lambda item: item.deleted and not item.purged ), allow_multiple=True )
+ purge_operation = grids.GridOperation( "Purge", condition=( lambda item: item.deleted and not item.purged ), allow_multiple=True )
@web.expose
@web.require_admin
diff -r 52bf302e209ed6890e37fa49215d8875af7ab1f1 -r 26da65326612232bfc7a0a9beddaeb176c9974ae lib/galaxy/webapps/community/config.py
--- a/lib/galaxy/webapps/community/config.py
+++ b/lib/galaxy/webapps/community/config.py
@@ -61,6 +61,7 @@
self.remote_user_logout_href = kwargs.get( "remote_user_logout_href", None )
self.require_login = string_as_bool( kwargs.get( "require_login", "False" ) )
self.allow_user_creation = string_as_bool( kwargs.get( "allow_user_creation", "True" ) )
+ self.allow_user_deletion = string_as_bool( kwargs.get( "allow_user_deletion", "False" ) )
self.enable_openid = string_as_bool( kwargs.get( 'enable_openid', False ) )
self.template_path = resolve_path( kwargs.get( "template_path", "templates" ), self.root )
self.template_cache = resolve_path( kwargs.get( "template_cache_path", "database/compiled_templates/community" ), self.root )
diff -r 52bf302e209ed6890e37fa49215d8875af7ab1f1 -r 26da65326612232bfc7a0a9beddaeb176c9974ae lib/galaxy/webapps/demo_sequencer/config.py
--- a/lib/galaxy/webapps/demo_sequencer/config.py
+++ b/lib/galaxy/webapps/demo_sequencer/config.py
@@ -40,6 +40,7 @@
self.remote_user_logout_href = kwargs.get( "remote_user_logout_href", None )
self.require_login = string_as_bool( kwargs.get( "require_login", "False" ) )
self.allow_user_creation = string_as_bool( kwargs.get( "allow_user_creation", "True" ) )
+ self.allow_user_deletion = string_as_bool( kwargs.get( "allow_user_deletion", "False" ) )
self.template_path = resolve_path( kwargs.get( "template_path", "templates" ), self.root )
self.template_cache = resolve_path( kwargs.get( "template_cache_path", "database/compiled_templates/demo_sequencer" ), self.root )
self.admin_users = kwargs.get( "admin_users", "" )
diff -r 52bf302e209ed6890e37fa49215d8875af7ab1f1 -r 26da65326612232bfc7a0a9beddaeb176c9974ae lib/galaxy/webapps/reports/config.py
--- a/lib/galaxy/webapps/reports/config.py
+++ b/lib/galaxy/webapps/reports/config.py
@@ -31,6 +31,8 @@
self.template_path = resolve_path( kwargs.get( "template_path", "templates" ), self.root )
self.template_cache = resolve_path( kwargs.get( "template_cache_path", "database/compiled_templates/reports" ), self.root )
self.sendmail_path = kwargs.get('sendmail_path',"/usr/sbin/sendmail")
+ self.allow_user_creation = string_as_bool( kwargs.get( "allow_user_creation", "True" ) )
+ self.allow_user_deletion = string_as_bool( kwargs.get( "allow_user_deletion", "False" ) )
self.log_actions = string_as_bool( kwargs.get( 'log_actions', 'False' ) )
self.brand = kwargs.get( 'brand', None )
self.wiki_url = kwargs.get( 'wiki_url', 'http://wiki.g2.bx.psu.edu/FrontPage' )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

10 Nov '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/52bf302e209e/
changeset: 52bf302e209e
user: jgoecks
date: 2011-11-11 01:01:31
summary: Trackster: use icon to set track mode.
affected #: 6 files
diff -r 9dbc82483bd2c72f2def795bf2a7cd5f13886a24 -r 52bf302e209ed6890e37fa49215d8875af7ab1f1 static/images/fugue/chevron-expand-bw.png
Binary file static/images/fugue/chevron-expand-bw.png has changed
diff -r 9dbc82483bd2c72f2def795bf2a7cd5f13886a24 -r 52bf302e209ed6890e37fa49215d8875af7ab1f1 static/images/fugue/toggle-bw.png
Binary file static/images/fugue/toggle-bw.png has changed
diff -r 9dbc82483bd2c72f2def795bf2a7cd5f13886a24 -r 52bf302e209ed6890e37fa49215d8875af7ab1f1 static/images/fugue/toggle-expand-bw.png
Binary file static/images/fugue/toggle-expand-bw.png has changed
diff -r 9dbc82483bd2c72f2def795bf2a7cd5f13886a24 -r 52bf302e209ed6890e37fa49215d8875af7ab1f1 static/june_2007_style/blue/trackster.css
--- a/static/june_2007_style/blue/trackster.css
+++ b/static/june_2007_style/blue/trackster.css
@@ -57,6 +57,8 @@
.param-row{margin-top:0.2em;margin-left:1em;}
.param-label{float:left;font-weight:bold;padding-top:0.2em;}
.menu-button{margin:0px 4px 0px 4px;}
+.chevron-expand{background:transparent url(../images/fugue/chevron-expand-bw.png) no-repeat;}
+.chevron-expand:hover{background:transparent url(../images/fugue/chevron-expand.png) no-repeat;}
.settings-icon{background:transparent url(../images/fugue/gear-bw.png) no-repeat;}
.settings-icon:hover{background:transparent url(../images/fugue/gear.png) no-repeat;}
.overview-icon{background:transparent url(../images/fugue/application-dock-270-bw.png) no-repeat;}
diff -r 9dbc82483bd2c72f2def795bf2a7cd5f13886a24 -r 52bf302e209ed6890e37fa49215d8875af7ab1f1 static/june_2007_style/trackster.css.tmpl
--- a/static/june_2007_style/trackster.css.tmpl
+++ b/static/june_2007_style/trackster.css.tmpl
@@ -297,6 +297,12 @@
.menu-button {
margin: 0px 4px 0px 4px;
}
+.chevron-expand {
+ background: transparent url(../images/fugue/chevron-expand-bw.png) no-repeat;
+}
+.chevron-expand:hover {
+ background:transparent url(../images/fugue/chevron-expand.png) no-repeat;
+}
.settings-icon {
background: transparent url(../images/fugue/gear-bw.png) no-repeat;
}
diff -r 9dbc82483bd2c72f2def795bf2a7cd5f13886a24 -r 52bf302e209ed6890e37fa49215d8875af7ab1f1 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -2381,16 +2381,18 @@
// Create and initialize track header and icons.
if (show_header) {
- this.header_div = $("<div class='track-header' />").appendTo(this.container_div);
+ this.header_div = $("<div class='track-header'/>").appendTo(this.container_div);
if (this.view.editor) { this.drag_div = $("<div/>").addClass(this.drag_handle_class).appendTo(this.header_div); }
this.name_div = $("<div/>").addClass("track-name").appendTo(this.header_div).text(this.name)
.attr( "id", this.name.replace(/\s+/g,'-').replace(/[^a-zA-Z0-9\-]/g,'').toLowerCase() );
this.icons_div = $("<div/>").css("float", "left").appendTo(this.header_div).hide();
// Track icons.
+ this.mode_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Set display mode")
+ .addClass("icon-button chevron-expand").tipsy( {gravity: 's'} ).appendTo(this.icons_div);
this.toggle_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Hide/show track content")
- .addClass("icon-button toggle-contract").tipsy( {gravity: 's'} )
- .appendTo(this.icons_div);
+ .addClass("icon-button toggle-contract").tipsy( {gravity: 's'} )
+ .appendTo(this.icons_div);
this.settings_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Edit settings")
.addClass("icon-button settings-icon").tipsy( {gravity: 's'} )
.appendTo(this.icons_div);
@@ -2407,21 +2409,42 @@
.addClass("icon-button remove-icon").tipsy( {gravity: 's'} )
.appendTo(this.icons_div);
var track = this;
-
+
// Suppress double clicks in header so that they do not impact viz.
this.header_div.dblclick( function(e) { e.stopPropagation(); } );
+
+ // Set up behavior for modes popup.
+ if (track.display_modes !== undefined) {
+ var init_mode = (track.config && track.config.values['mode'] ?
+ track.config.values['mode'] : track.display_modes[0]);
+ track.mode = init_mode;
+ this.mode_icon.attr("title", "Set display mode (now: " + track.mode + ")");
+
+ var mode_mapping = {};
+ for (var i = 0, len = track.display_modes.length; i < len; i++) {
+ var mode = track.display_modes[i];
+ mode_mapping[mode] = function(mode) {
+ return function() {
+ track.change_mode(mode);
+ // HACK: the popup menu messes with the track's hover event, so manually show/hide
+ // icons div for now.
+ track.icons_div.show();
+ track.container_div.mouseleave(function() { track.icons_div.hide(); } ); };
+ }(mode);
+ }
+
+ make_popupmenu(this.mode_icon, mode_mapping);
+ }
- // Toggle icon hides or shows the track content
+ // Toggle icon hides or shows the track content.
this.toggle_icon.click( function() {
if ( track.content_visible ) {
track.toggle_icon.addClass("toggle-expand").removeClass("toggle-contract");
track.hide_contents();
- track.mode_div.hide();
track.content_visible = false;
} else {
track.toggle_icon.addClass("toggle-contract").removeClass("toggle-expand");
track.content_visible = true;
- track.mode_div.show();
track.show_contents();
}
});
@@ -2481,35 +2504,12 @@
$(".tipsy").remove();
track.remove();
});
+
+ // Show icons when users is hovering over track.
+ this.container_div.hover( function() { track.icons_div.show(); }, function() { track.icons_div.hide(); } );
- // Set up behavior for modes popup.
- 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.config && track.config.values['mode'] ?
- track.config.values['mode'] : track.display_modes[0]);
- track.mode = init_mode;
- track.mode_div.text(init_mode);
-
- var mode_mapping = {};
- for (var i = 0, len = track.display_modes.length; i < len; i++) {
- var mode = track.display_modes[i];
- mode_mapping[mode] = function(mode) {
- return function() { track.change_mode(mode); };
- }(mode);
- }
- make_popupmenu(track.mode_div, mode_mapping);
- } else {
- track.mode_div.hide();
- }
-
- this.header_div.append( $("<div/>").css("clear", "both") );
-
- // Set up config icon.
-
- // Show icons when users is hovering over track.
- this.container_div.hover( function() { track.icons_div.show(); }, function() { track.icons_div.hide(); } );
- }
+ // Needed for floating elts in header.
+ $("<div style='clear: both'/>").appendTo(this.container_div);
}
//
@@ -2696,12 +2696,12 @@
*/
change_mode: function(name) {
var track = this;
- track.mode_div.text(name);
// TODO: is it necessary to store the mode in two places (.mode and track_config)?
track.mode = name;
track.config.values['mode'] = name;
track.tile_cache.clear();
track.request_draw();
+ this.mode_icon.attr("title", "Set display mode (now: " + track.mode + ")");
return track;
},
/**
@@ -3405,13 +3405,14 @@
}
},
update_auto_mode: function( mode ) {
+ var mode;
if ( this.mode == "Auto" ) {
if ( mode == "no_detail" ) {
mode = "feature spans";
} else if ( mode == "summary_tree" ) {
mode = "coverage histogram";
}
- this.mode_div.text( "Auto (" + mode + ")" );
+ this.mode_icon.attr("title", "Set display mode (now: Auto/" + mode + ")");
}
},
/**
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: jgoecks: Make toggle icons use black and white and color on hover to match other Trackster icons.
by Bitbucket 10 Nov '11
by Bitbucket 10 Nov '11
10 Nov '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/9dbc82483bd2/
changeset: 9dbc82483bd2
user: jgoecks
date: 2011-11-10 22:16:26
summary: Make toggle icons use black and white and color on hover to match other Trackster icons.
affected #: 5 files
diff -r 6ec2d7f4a64dcf6a1c49415bd8f40c8d4ca907c5 -r 9dbc82483bd2c72f2def795bf2a7cd5f13886a24 static/june_2007_style/base.css.tmpl
--- a/static/june_2007_style/base.css.tmpl
+++ b/static/june_2007_style/base.css.tmpl
@@ -865,10 +865,6 @@
-sprite-group: fugue;
-sprite-image: fugue/toggle-expand.png;
}
-.icon-button.toggle {
- -sprite-group: fugue;
- -sprite-image: fugue/toggle.png;
-}
.icon-button.toggle-contract {
-sprite-group: fugue;
-sprite-image: fugue/toggle.png;
diff -r 6ec2d7f4a64dcf6a1c49415bd8f40c8d4ca907c5 -r 9dbc82483bd2c72f2def795bf2a7cd5f13886a24 static/june_2007_style/blue/base.css
--- a/static/june_2007_style/blue/base.css
+++ b/static/june_2007_style/blue/base.css
@@ -151,9 +151,10 @@
.icon-button.tag{background:url(fugue.png) no-repeat 0px -0px;}
.icon-button.tags{background:url(fugue.png) no-repeat 0px -26px;}
.icon-button.tag--plus{background:url(fugue.png) no-repeat 0px -52px;}
-.icon-button.toggle-expand{background:url(fugue.png) no-repeat 0px -78px;}
-.icon-button.toggle{background:url(fugue.png) no-repeat 0px -104px;}
-.icon-button.toggle-contract{background:url(fugue.png) no-repeat 0px -104px;}
+.icon-button.toggle-expand{background:transparent url(../images/fugue/toggle-expand-bw.png) no-repeat;}
+.icon-button.toggle-expand:hover{background:url(fugue.png) no-repeat 0px -78px;}
+.icon-button.toggle-contract{background:transparent url(../images/fugue/toggle-bw.png) no-repeat;}
+.icon-button.toggle-contract:hover{background:url(fugue.png) no-repeat 0px -104px;}
.icon-button.arrow-circle{background:url(fugue.png) no-repeat 0px -130px;}
.icon-button.chevron{background:url(fugue.png) no-repeat 0px -156px;}
.icon-button.bug{background:url(fugue.png) no-repeat 0px -182px;}
diff -r 6ec2d7f4a64dcf6a1c49415bd8f40c8d4ca907c5 -r 9dbc82483bd2c72f2def795bf2a7cd5f13886a24 static/june_2007_style/blue/trackster.css
--- a/static/june_2007_style/blue/trackster.css
+++ b/static/june_2007_style/blue/trackster.css
@@ -56,7 +56,7 @@
.tool-name{font-size:110%;font-weight:bold;}
.param-row{margin-top:0.2em;margin-left:1em;}
.param-label{float:left;font-weight:bold;padding-top:0.2em;}
-.menu-button{padding:0px 4px 0px 4px;}
+.menu-button{margin:0px 4px 0px 4px;}
.settings-icon{background:transparent url(../images/fugue/gear-bw.png) no-repeat;}
.settings-icon:hover{background:transparent url(../images/fugue/gear.png) no-repeat;}
.overview-icon{background:transparent url(../images/fugue/application-dock-270-bw.png) no-repeat;}
diff -r 6ec2d7f4a64dcf6a1c49415bd8f40c8d4ca907c5 -r 9dbc82483bd2c72f2def795bf2a7cd5f13886a24 static/june_2007_style/trackster.css.tmpl
--- a/static/june_2007_style/trackster.css.tmpl
+++ b/static/june_2007_style/trackster.css.tmpl
@@ -295,7 +295,7 @@
padding-top: 0.2em;
}
.menu-button {
- padding: 0px 4px 0px 4px;
+ margin: 0px 4px 0px 4px;
}
.settings-icon {
background: transparent url(../images/fugue/gear-bw.png) no-repeat;
diff -r 6ec2d7f4a64dcf6a1c49415bd8f40c8d4ca907c5 -r 9dbc82483bd2c72f2def795bf2a7cd5f13886a24 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -2389,7 +2389,7 @@
// Track icons.
this.toggle_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Hide/show track content")
- .addClass("icon-button toggle").tipsy( {gravity: 's'} )
+ .addClass("icon-button toggle-contract").tipsy( {gravity: 's'} )
.appendTo(this.icons_div);
this.settings_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Edit settings")
.addClass("icon-button settings-icon").tipsy( {gravity: 's'} )
@@ -2414,12 +2414,12 @@
// Toggle icon hides or shows the track content
this.toggle_icon.click( function() {
if ( track.content_visible ) {
- track.toggle_icon.addClass("toggle-expand").removeClass("toggle");
+ track.toggle_icon.addClass("toggle-expand").removeClass("toggle-contract");
track.hide_contents();
track.mode_div.hide();
track.content_visible = false;
} else {
- track.toggle_icon.addClass("toggle").removeClass("toggle-expand");
+ track.toggle_icon.addClass("toggle-contract").removeClass("toggle-expand");
track.content_visible = true;
track.mode_div.show();
track.show_contents();
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: dannon: Fix for slug check flag pointed out by Andrew Warren.
by Bitbucket 10 Nov '11
by Bitbucket 10 Nov '11
10 Nov '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/6ec2d7f4a64d/
changeset: 6ec2d7f4a64d
user: dannon
date: 2011-11-10 20:56:35
summary: Fix for slug check flag pointed out by Andrew Warren.
affected #: 1 file
diff -r 429f6b869c71b2aa2df8d6b61b6e12cd22fc8a4d -r 6ec2d7f4a64dcf6a1c49415bd8f40c8d4ca907c5 lib/galaxy/web/controllers/workflow.py
--- a/lib/galaxy/web/controllers/workflow.py
+++ b/lib/galaxy/web/controllers/workflow.py
@@ -149,7 +149,8 @@
# Legacy issue: all shared workflows must have slugs.
slug_set = False
for workflow_assoc in shared_by_others:
- slug_set = self.create_item_slug( trans.sa_session, workflow_assoc.stored_workflow )
+ if self.create_item_slug( trans.sa_session, workflow_assoc.stored_workflow ):
+ slug_set = True
if slug_set:
trans.sa_session.flush()
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: natefoo: Fix an exception class that doesn't exist. Thanks Oleksandr Moskalenko.
by Bitbucket 10 Nov '11
by Bitbucket 10 Nov '11
10 Nov '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/429f6b869c71/
changeset: 429f6b869c71
user: natefoo
date: 2011-11-10 18:49:44
summary: Fix an exception class that doesn't exist. Thanks Oleksandr Moskalenko.
affected #: 1 file
diff -r d9408bcb3cf4bcb81e9dac4ddeda74cbc164e123 -r 429f6b869c71b2aa2df8d6b61b6e12cd22fc8a4d lib/galaxy/util/__init__.py
--- a/lib/galaxy/util/__init__.py
+++ b/lib/galaxy/util/__init__.py
@@ -607,7 +607,7 @@
log.error( "The server didn't accept the username/password combination: %s" % e )
s.close()
raise
- except smtplib.SMTPError, e:
+ except smtplib.SMTPException, e:
log.error( "No suitable authentication method was found: %s" % e )
s.close()
raise
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Eliminate the non-functional PacBio tools from the distribution and the sample tool config.
by Bitbucket 10 Nov '11
by Bitbucket 10 Nov '11
10 Nov '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/d9408bcb3cf4/
changeset: d9408bcb3cf4
user: greg
date: 2011-11-10 18:09:45
summary: Eliminate the non-functional PacBio tools from the distribution and the sample tool config.
affected #: 14 files
diff -r 3565ae97160f4a70b3910b54bcd98c0f4c7d1796 -r d9408bcb3cf4bcb81e9dac4ddeda74cbc164e123 tool_conf.xml.sample
--- a/tool_conf.xml.sample
+++ b/tool_conf.xml.sample
@@ -477,17 +477,6 @@
<tool file="vcf_tools/filter.xml" /><tool file="vcf_tools/extract.xml" /></section>
- <section name="PacBio/Illumina Assembly" id="hybrid">
- <tool file="ilmn_pacbio/quake.xml"/>
- <tool file="ilmn_pacbio/quake_pe.xml"/>
- <tool file="ilmn_pacbio/soap_denovo.xml"/>
- <!--
- Uncomment this tool when we support the HDF5 format
- <tool file="ilmn_pacbio/smrtpipe_filter.xml"/>
- -->
- <tool file="ilmn_pacbio/smrtpipe_hybrid.xml"/>
- <tool file="ilmn_pacbio/assembly_stats.xml"/>
- </section><!--
TODO: uncomment the following EMBOSS section whenever
moving to test, but comment it in .sample to eliminate
diff -r 3565ae97160f4a70b3910b54bcd98c0f4c7d1796 -r d9408bcb3cf4bcb81e9dac4ddeda74cbc164e123 tools/ilmn_pacbio/abyss.xml
--- a/tools/ilmn_pacbio/abyss.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<tool id="abyss" name="ABySS" version="1.0.0">
- <description>Short-read de Bruijn assembly</description>
- <command interpreter="python">
- quake_wrapper.py -k $k -r $input1 -p 8 > $output1
- </command>
- <inputs>
- <param name="input1" format="fastq" type="data" label="Select FASTQ file to correct" />
- <param name="k" type="integer" value="16" label="Size of k-mers to correct" />
- </inputs>
- <outputs>
- <data format="fastq" name="output1" label="Error-corrected reads from ${on_string}" />
- </outputs>
- <help>
-
-**What it does**
-
-TBD. Calls ABySS assembler
-
-**Parameter list**
-
-k
-
-**Output**
-
-Corrected reads
-
- </help>
-</tool>
-
-
diff -r 3565ae97160f4a70b3910b54bcd98c0f4c7d1796 -r d9408bcb3cf4bcb81e9dac4ddeda74cbc164e123 tools/ilmn_pacbio/assembly_stats.py
--- a/tools/ilmn_pacbio/assembly_stats.py
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/usr/bin/env python
-#
-#Copyright (c) 2011, Pacific Biosciences of California, Inc.
-#
-#All rights reserved.
-#
-#Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-# * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
-# * Neither the name of Pacific Biosciences nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-#
-#THIS SOFTWARE IS PROVIDED BY PACIFIC BIOSCIENCES AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PACIFIC BIOSCIENCES OR ITS CONTRIBUTORS BE LIABLE FOR ANY
-#DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-import sys, os
-from optparse import OptionParser
-from galaxy import eggs
-import pkg_resources
-pkg_resources.require( 'bx-python' )
-from bx.seq.fasta import FastaReader
-
-def getStats( fastaFile, genomeLength, minContigLength ):
- lengths = []
- stats = { "Num" : 0,
- "Sum" : 0,
- "Max" : 0,
- "Avg" : 0,
- "N50" : 0,
- "99%" : 0 }
- fasta_reader = FastaReader( open( fastaFile, 'rb' ) )
- while True:
- seq = fasta_reader.next()
- if not seq:
- break
- if seq.length < minContigLength:
- continue
- lengths.append( seq.length )
- if lengths:
- stats[ 'Num' ] = len( lengths )
- stats[ 'Sum' ] = sum( lengths )
- stats[ 'Max' ] = max( lengths )
- stats[ 'Avg' ] = int( sum( lengths ) / float( len( lengths ) ) )
- stats[ 'N50' ] = 0
- stats[ '99%' ] = 0
- if genomeLength == 0:
- genomeLength = sum( lengths )
- lengths.sort()
- lengths.reverse()
- lenSum = 0
- stats[ "99%" ] = len( lengths )
- for idx, length in enumerate( lengths ):
- lenSum += length
- if ( lenSum > genomeLength / 2 ):
- stats[ "N50" ] = length
- break
- lenSum = 0
- for idx, length in enumerate( lengths ):
- lenSum += length
- if lenSum > genomeLength * 0.99:
- stats[ "99%" ] = idx + 1
- break
- return stats
-
-def __main__():
- #Parse Command Line
- usage = 'Usage: %prog input output --minContigLength'
- parser = OptionParser( usage=usage )
- parser.add_option( "--minContigLength", dest="minContigLength", help="Minimum length of contigs to analyze" )
- parser.add_option( "--genomeLength", dest="genomeLength", help="Length of genome for which to calculate N50s" )
- parser.set_defaults( minContigLength=0, genomeLength=0 )
- options, args = parser.parse_args()
- input_fasta_file = args[ 0 ]
- output_tabular_file = args[ 1 ]
- statKeys = "Num Sum Max Avg N50 99%".split( " " )
- stats = getStats( input_fasta_file, int( options.genomeLength ), int( options.minContigLength ) )
- fout = open( output_tabular_file, "w" )
- fout.write( "%s\n" % "\t".join( map( lambda key: str( stats[ key ] ), statKeys ) ) )
- fout.close()
-
-if __name__=="__main__": __main__()
diff -r 3565ae97160f4a70b3910b54bcd98c0f4c7d1796 -r d9408bcb3cf4bcb81e9dac4ddeda74cbc164e123 tools/ilmn_pacbio/assembly_stats.xml
--- a/tools/ilmn_pacbio/assembly_stats.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<tool id="assembly_stats" name="Assembly Statistics" version="1.0.0">
- <description>Calculate common measures of assembly quality</description>
- <command interpreter="python">
- assembly_stats.py $input1 $output1 --minContigLength=${minLength}
- </command>
- <inputs>
- <param name="input1" format="fasta" type="data" label="Select FASTA file containing contigs"/>
- <param name="minLength" type="integer" value="0" label="Minimum length of contigs to consider"/>
- </inputs>
- <outputs>
- <data name="output1" format="tabular" label="Assembly statistics for ${on_string}"/>
- </outputs>
- <tests>
- <test>
- <param name="input1" value="3.fasta" ftype="fasta"/>
- <param name="minLength" value="100"/>
- <output name="output1" ftype="tabular" file="assembly_stats.tabular" />
- </test>
- </tests>
- <help>
-
-**What it does**
-
-Reports standard measures of *de novo* assembly quality such as number of contigs, sum of contigs, mean contig length, and N50.
-
-**Parameter list**
-
-Minimum length
- Only include contigs of this size or greater for calculating statistics.
-
-**Output**
-
-Num contigs
- Total number of contigs in the assembly
-
-Sum of contig lengths
- Total sum of contig lengths
-
-Maximum contig length
- Maximum of the contig lengths
-
-Mean contig length
- Average contig length
-
-N50
- Contig length at which 50% of the assembly is contained in contigs of this size or greater.
-
-99%
- Number of contigs accounting for 99% of the observed assembly.
-
- </help>
-</tool>
-
-
diff -r 3565ae97160f4a70b3910b54bcd98c0f4c7d1796 -r d9408bcb3cf4bcb81e9dac4ddeda74cbc164e123 tools/ilmn_pacbio/cov_model.py
--- a/tools/ilmn_pacbio/cov_model.py
+++ /dev/null
@@ -1,238 +0,0 @@
-#!/usr/bin/env python
-from optparse import OptionParser, SUPPRESS_HELP
-import os, random, quake
-
-############################################################
-# cov_model.py
-#
-# Given a file of kmer counts, reports the cutoff to use
-# to separate trusted/untrusted kmers.
-############################################################
-
-############################################################
-# main
-############################################################
-def main():
- usage = 'usage: %prog [options] <counts file>'
- parser = OptionParser(usage)
- parser.add_option('--int', dest='count_kmers', action='store_true', default=False, help='Kmers were counted as integers w/o the use of quality values [default: %default]')
- parser.add_option('--ratio', dest='ratio', type='int', default=200, help='Likelihood ratio to set trusted/untrusted cutoff [default: %default]')
- parser.add_option('--no_sample', dest='no_sample', action='store_true', default=False, help='Do not sample kmer coverages into kmers.txt because its already done [default: %default]')
- # help='Model kmer coverage as a function of GC content of kmers [default: %default]'
- parser.add_option('--gc', dest='model_gc', action='store_true', default=False, help=SUPPRESS_HELP)
- (options, args) = parser.parse_args()
-
- if len(args) != 1:
- parser.error('Must provide kmers counts file')
- else:
- ctsf = args[0]
-
- if options.count_kmers:
- model_cutoff(ctsf, options.ratio)
- print 'Cutoff: %s' % open('cutoff.txt').readline().rstrip()
-
- else:
- if options.model_gc:
- model_q_gc_cutoffs(ctsf, 25000, options.ratio)
- else:
- model_q_cutoff(ctsf, 50000, options.ratio, options.no_sample)
- print 'Cutoff: %s' % open('cutoff.txt').readline().rstrip()
-
-
-############################################################
-# model_cutoff
-#
-# Make a histogram of kmers to give to R to learn the cutoff
-############################################################
-def model_cutoff(ctsf, ratio):
- # make kmer histogram
- cov_max = 0
- for line in open(ctsf):
- cov = int(line.split()[1])
- if cov > cov_max:
- cov_max = cov
-
- kmer_hist = [0]*cov_max
- for line in open(ctsf):
- cov = int(line.split()[1])
- kmer_hist[cov-1] += 1
-
- cov_out = open('kmers.hist', 'w')
- for cov in range(0,cov_max):
- if kmer_hist[cov]:
- print >> cov_out, '%d\t%d' % (cov+1,kmer_hist[cov])
- cov_out.close()
-
- os.system('R --slave --args %d < %s/cov_model.r 2> r.log' % (ratio,quake.quake_dir))
-
-
-############################################################
-# model_q_cutoff
-#
-# Sample kmers to give to R to learn the cutoff
-# 'div100' is necessary when the number of kmers is too
-# large for random.sample, so we only consider every 100th
-# kmer.
-############################################################
-def model_q_cutoff(ctsf, sample, ratio, no_sample=False):
- if not no_sample:
- # count number of kmer coverages
- num_covs = 0
- for line in open(ctsf):
- num_covs += 1
-
- # choose random kmer coverages
- div100 = False
- if sample >= num_covs:
- rand_covs = range(num_covs)
- else:
- if num_covs > 1000000000:
- div100 = True
- rand_covs = random.sample(xrange(num_covs/100), sample)
- else:
- rand_covs = random.sample(xrange(num_covs), sample)
- rand_covs.sort()
-
- # print to file
- out = open('kmers.txt', 'w')
- kmer_i = 0
- rand_i = 0
- for line in open(ctsf):
- if div100:
- if kmer_i % 100 == 0 and kmer_i/100 == rand_covs[rand_i]:
- print >> out, line.split()[1]
- rand_i += 1
- if rand_i >= sample:
- break
- else:
- if kmer_i == rand_covs[rand_i]:
- print >> out, line.split()[1]
- rand_i += 1
- if rand_i >= sample:
- break
- kmer_i += 1
- out.close()
-
- os.system('R --slave --args %d < %s/cov_model_qmer.r 2> r.log' % (ratio,quake.quake_dir))
-
-
-############################################################
-# model_q_gc_cutoffs
-#
-# Sample kmers to give to R to learn the cutoff for each
-# GC value
-############################################################
-def model_q_gc_cutoffs(ctsf, sample, ratio):
- # count number of kmer coverages at each at
- k = len(open(ctsf).readline().split()[0])
- num_covs_at = [0]*(k+1)
- for line in open(ctsf):
- kmer = line.split()[0]
- num_covs_at[count_at(kmer)] += 1
-
- # for each AT bin
- at_cutoffs = []
- for at in range(1,k):
- # sample covs
- if sample >= num_covs_at[at]:
- rand_covs = range(num_covs_at[at])
- else:
- rand_covs = random.sample(xrange(num_covs_at[at]), sample)
- rand_covs.sort()
-
- # print to file
- out = open('kmers.txt', 'w')
- kmer_i = 0
- rand_i = 0
- for line in open(ctsf):
- (kmer,cov) = line.split()
- if count_at(kmer) == at:
- if kmer_i == rand_covs[rand_i]:
- print >> out, cov
- rand_i += 1
- if rand_i >= sample:
- break
- kmer_i += 1
- out.close()
-
- os.system('R --slave --args %d < %s/cov_model_qmer.r 2> r%d.log' % (ratio,quake.quake_dir,at))
-
- at_cutoffs.append( open('cutoff.txt').readline().rstrip() )
- if at in [1,k-1]: # setting extremes to next closests
- at_cutoffs.append( open('cutoff.txt').readline().rstrip() )
-
- os.system('mv kmers.txt kmers.at%d.txt' % at)
- os.system('mv cutoff.txt cutoff.at%d.txt' % at)
-
- out = open('cutoffs.gc.txt','w')
- print >> out, '\n'.join(at_cutoffs)
- out.close()
-
-
-############################################################
-# model_q_gc_cutoffs_bigmem
-#
-# Sample kmers to give to R to learn the cutoff for each
-# GC value
-############################################################
-def model_q_gc_cutoffs_bigmem(ctsf, sample, ratio):
- # input coverages
- k = 0
- for line in open(ctsf):
- (kmer,cov) = line.split()
- if k == 0:
- k = len(kmer)
- at_covs = ['']*(k+1)
- else:
- at = count_at(kmer)
- if at_covs[at]:
- at_covs[at].append(cov)
- else:
- at_covs[at] = [cov]
-
- for at in range(1,k):
- print '%d %d' % (at,len(at_covs[at]))
-
- # for each AT bin
- at_cutoffs = []
- for at in range(1,k):
- # sample covs
- if sample >= len(at_covs[at]):
- rand_covs = at_covs[at]
- else:
- rand_covs = random.sample(at_covs[at], sample)
-
- # print to file
- out = open('kmers.txt', 'w')
- for rc in rand_covs:
- print >> out, rc
- out.close()
-
- os.system('R --slave --args %d < %s/cov_model_qmer.r 2> r%d.log' % (ratio,quake.quake_dir,at))
-
- at_cutoffs.append( open('cutoff.txt').readline().rstrip() )
- if at in [1,k-1]: # setting extremes to next closests
- at_cutoffs.append( open('cutoff.txt').readline().rstrip() )
-
- os.system('mv kmers.txt kmers.at%d.txt' % at)
- os.system('mv cutoff.txt cutoff.at%d.txt' % at)
-
- out = open('cutoffs.gc.txt','w')
- print >> out, '\n'.join(at_cutoffs)
- out.close()
-
-
-############################################################
-# count_at
-#
-# Count A's and T's in the given sequence
-############################################################
-def count_at(seq):
- return len([nt for nt in seq if nt in ['A','T']])
-
-
-############################################################
-# __main__
-############################################################
-if __name__ == '__main__':
- main()
diff -r 3565ae97160f4a70b3910b54bcd98c0f4c7d1796 -r d9408bcb3cf4bcb81e9dac4ddeda74cbc164e123 tools/ilmn_pacbio/quake.py
--- a/tools/ilmn_pacbio/quake.py
+++ /dev/null
@@ -1,136 +0,0 @@
-#!/usr/bin/env python
-from optparse import OptionParser, SUPPRESS_HELP
-import os, random, sys
-import cov_model
-
-############################################################
-# quake.py
-#
-# Launch pipeline to correct errors in Illumina sequencing
-# reads.
-############################################################
-
-#r_dir = '/nfshomes/dakelley/research/error_correction/bin'
-quake_dir = os.path.abspath(os.path.dirname(sys.argv[0]))
-
-############################################################
-# main
-############################################################
-def main():
- usage = 'usage: %prog [options]'
- parser = OptionParser(usage)
- parser.add_option('-r', dest='readsf', help='Fastq file of reads')
- parser.add_option('-f', dest='reads_listf', help='File containing fastq file names, one per line or two per line for paired end reads.')
- parser.add_option('-k', dest='k', type='int', help='Size of k-mers to correct')
- parser.add_option('-p', dest='proc', type='int', default=4, help='Number of processes [default: %default]')
- parser.add_option('-q', dest='quality_scale', type='int', default=-1, help='Quality value ascii scale, generally 64 or 33. If not specified, it will guess.')
- parser.add_option('--no_count', dest='no_count', action='store_true', default=False, help='Kmers are already counted and in expected file [reads file].qcts or [reads file].cts [default: %default]')
- parser.add_option('--no_cut', dest='no_cut', action='store_true', default=False, help='Coverage model is optimized and cutoff was printed to expected file cutoff.txt [default: %default]')
- parser.add_option('--int', dest='counted_kmers', action='store_true', default=False, help='Kmers were counted as integers w/o the use of quality values [default: %default]')
- parser.add_option('--ratio', dest='ratio', type='int', default=200, help='Likelihood ratio to set trusted/untrusted cutoff. Generally set between 10-1000 with lower numbers suggesting a lower threshold. [default: %default]')
- # help='Model kmer coverage as a function of GC content of kmers [default: %default]'
- parser.add_option('--gc', dest='model_gc', action='store_true', default=False, help=SUPPRESS_HELP)
- parser.add_option('--headers', action='store_true', default=False, help='Output original read headers (i.e. pass --headers to correct)' )
- (options, args) = parser.parse_args()
-
- if not options.readsf and not options.reads_listf:
- parser.error('Must provide fastq file of reads with -r or file with list of fastq files of reads with -f')
- if not options.k:
- parser.error('Must provide k-mer size with -k')
- if options.quality_scale == -1:
- options.quality_scale = guess_quality_scale(options.readsf, options.reads_listf)
-
- if options.counted_kmers:
- cts_suf = 'cts'
- else:
- cts_suf = 'qcts'
- if options.readsf:
- ctsf = '%s.%s' % (os.path.splitext( os.path.split(options.readsf)[1] )[0], cts_suf)
- reads_str = '-r %s' % options.readsf
- else:
- ctsf = '%s.%s' % (os.path.split(options.reads_listf)[1], cts_suf)
- reads_str = '-f %s' % options.reads_listf
-
- if not options.no_count and not options.no_cut:
- count_kmers(options.readsf, options.reads_listf, options.k, ctsf, options.quality_scale)
-
- if not options.no_cut:
- # model coverage
- if options.counted_kmers:
- cov_model.model_cutoff(ctsf, options.ratio)
- else:
- if options.model_gc:
- cov_model.model_q_gc_cutoffs(ctsf, 10000, options.ratio)
- else:
- cov_model.model_q_cutoff(ctsf, 25000, options.ratio)
-
-
- if options.model_gc:
- # run correct C++ code
- os.system('%s/correct %s -k %d -m %s -a cutoffs.gc.txt -p %d -q %d' % (quake_dir,reads_str, options.k, ctsf, options.proc, options.quality_scale))
-
- else:
- cutoff = open('cutoff.txt').readline().rstrip()
-
- # run correct C++ code
- headers = '--headers' if options.headers else ''
- os.system('%s/correct %s %s -k %d -m %s -c %s -p %d -q %d' % (quake_dir,headers, reads_str, options.k, ctsf, cutoff, options.proc, options.quality_scale))
-
-
-################################################################################
-# guess_quality_scale
-# Guess at ascii scale of quality values by examining
-# a bunch of reads and looking for quality values < 64,
-# in which case we set it to 33.
-################################################################################
-def guess_quality_scale(readsf, reads_listf):
- reads_to_check = 1000
- if not readsf:
- readsf = open(reads_listf).readline().split()[0]
-
- fqf = open(readsf)
- reads_checked = 0
- header = fqf.readline()
- while header and reads_checked < reads_to_check:
- seq = fqf.readline()
- mid = fqf.readline()
- qual = fqf.readline().rstrip()
- reads_checked += 1
- for q in qual:
- if ord(q) < 64:
- print 'Guessing quality values are on ascii 33 scale'
- return 33
- header = fqf.readline()
-
- print 'Guessing quality values are on ascii 64 scale'
- return 64
-
-
-
-############################################################
-# count_kmers
-#
-# Count kmers in the reads file using AMOS count-kmers or
-# count-qmers
-############################################################
-def count_kmers(readsf, reads_listf, k, ctsf, quality_scale):
- # find files
- fq_files = []
- if readsf:
- fq_files.append(readsf)
- else:
- for line in open(reads_listf):
- for fqf in line.split():
- fq_files.append(fqf)
-
- if ctsf[-4:] == 'qcts':
- os.system('cat %s | %s/count-qmers -k %d -q %d > %s' % (' '.join(fq_files), quake_dir, k, quality_scale, ctsf))
- else:
- os.system('cat %s | %s/count-kmers -k %d > %s' % (' '.join(fq_files), quake_dir, k, ctsf))
-
-
-############################################################
-# __main__
-############################################################
-if __name__ == '__main__':
- main()
diff -r 3565ae97160f4a70b3910b54bcd98c0f4c7d1796 -r d9408bcb3cf4bcb81e9dac4ddeda74cbc164e123 tools/ilmn_pacbio/quake.xml
--- a/tools/ilmn_pacbio/quake.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<tool id="quake" name="Quake" version="1.0.0">
- <description>Quality-aware error correction</description>
- <command interpreter="python">
- quake_wrapper.py --default_cutoff=10 --headers -k $k -f $fofnfile -p 12 > $output1
- </command>
- <inputs>
- <param name="input1" format="fastq" type="data" label="Select FASTQ file to correct" />
- <param name="k" type="integer" value="16" label="Size of k-mers to correct" />
- </inputs>
- <configfiles>
- <configfile name="fofnfile">
-${input1.file_name}
- </configfile>
- </configfiles>
- <outputs>
- <data format="fastq" name="output1" label="Error-corrected reads from ${on_string}" />
- </outputs>
- <help>
-
-**What it does**
-
-Applies the Quake_ algorithm for quality-aware correction of
-substitution error in short reads.
-
-Kelley DR, Schatz MC, Salzberg SL.
-"Quake: quality-aware detection and correction of sequencing errors."
-*Genome Biol.* 2010;11(11):R116.
-
-.. _Quake: http://www.cbcb.umd.edu/software/quake
-
-**Parameter list**
-
-k
- k-mer size for detecting spurious k-mers versus true k-mers from
- the genome. Recommendations for choosing a value of k can be found
- here_.
-
-.. _here: http://www.cbcb.umd.edu/software/quake/faq.html
-
-**Output**
-
-A FASTQ file of corrected and trimmed reads.
- </help>
-</tool>
diff -r 3565ae97160f4a70b3910b54bcd98c0f4c7d1796 -r d9408bcb3cf4bcb81e9dac4ddeda74cbc164e123 tools/ilmn_pacbio/quake_pe.xml
--- a/tools/ilmn_pacbio/quake_pe.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<tool id="quake_pe" name="Quake PE" version="1.0.0">
- <description>Quality-aware error correction for paired-end reads</description>
- <command interpreter="python">
- quake_wrapper.py --default_cutoff=$cutoff --headers -k $k -f $fofnfile -p 12 --output=$output1,$output2
- </command>
- <inputs>
- <param name="input1" format="fastq" type="data" label="FASTQ file for forward reads" />
- <param name="input2" format="fastq" type="data" label="FASTQ file for reverse reads" />
- <param name="k" type="integer" value="16" label="Size of k-mers to correct" />
- <param name="cutoff" type="integer" value="0" label="Default coverage cutoff if estimation fails"/>
- </inputs>
- <configfiles>
- <configfile name="fofnfile">${input1.file_name} ${input2.file_name}
- </configfile>
- </configfiles>
- <outputs>
- <data format="fastq" name="output1" label="Error-corrected forward reads from ${on_string}" />
- <data format="fastq" name="output2" label="Error-corrected reverse reads from ${on_string}" />
- </outputs>
- <help>
-
-**What it does**
-
-Applies the Quake_ algorithm for quality-aware correction of
-substitution error in short reads. This form of the tool is customized
-for correcting paired-end reads.
-
-Kelley DR, Schatz MC, Salzberg SL.
-"Quake: quality-aware detection and correction of sequencing errors."
-*Genome Biol.* 2010;11(11):R116.
-
-.. _Quake: http://www.cbcb.umd.edu/software/quake
-
-**Parameter list**
-
-K-mer size
- k-mer size for detecting spurious k-mers versus true k-mers from
- the genome. Recommendations for choosing a value of k can be found
- here_.
-
-Default coverage cutoff
- If the appropriate coverage cutoff can not be found then Quake can be
- forced to proceed anyways with the supplied cutoff. In this case,
- the optimal cutoff can be estimated by examining
- the k-mer coverage histogram by eye.
-
-.. _here: http://www.cbcb.umd.edu/software/quake/faq.html
-
-**Output**
-
-A FASTQ file of corrected and trimmed reads.
- </help>
-</tool>
diff -r 3565ae97160f4a70b3910b54bcd98c0f4c7d1796 -r d9408bcb3cf4bcb81e9dac4ddeda74cbc164e123 tools/ilmn_pacbio/quake_wrapper.py
--- a/tools/ilmn_pacbio/quake_wrapper.py
+++ /dev/null
@@ -1,132 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (c) 2011, Pacific Biosciences of California, Inc.
-#
-# All rights reserved.
-#
-#Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-# * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
-# * Neither the name of Pacific Biosciences nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-#
-#THIS SOFTWARE IS PROVIDED BY PACIFIC BIOSCIENCES AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PACIFIC BIOSCIENCES OR ITS CONTRIBUTORS BE LIABLE FOR ANY
-#DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-import sys
-import os
-import subprocess
-
-QUAKE_EXE = os.path.join( os.path.dirname(os.path.abspath(sys.argv[0])), 'quake.py' )
-cmdLine = sys.argv
-cmdLine.pop(0)
-
-#
-# horribly not robust, but it was a pain to rewrite everything with
-# optparse
-#
-j = -1
-cut = 0
-for i,arg in enumerate(cmdLine):
- if '--default_cutoff' in arg:
- j = i
- cut = int(arg.split('=')[1])
-if j>=0:
- cmdLine = cmdLine[:j] + cmdLine[j+1:]
-
-j = -1
-output=''
-for i,arg in enumerate(cmdLine):
- if '--output' in arg:
- j = i
- output = arg.split('=')[1]
-if j>=0:
- cmdLine = cmdLine[:j] + cmdLine[j+1:]
-
-def backticks( cmd, merge_stderr=True ):
- """
- Simulates the perl backticks (``) command with error-handling support
- Returns ( command output as sequence of strings, error code, error message )
- """
- if merge_stderr:
- _stderr = subprocess.STDOUT
- else:
- _stderr = subprocess.PIPE
-
- p = subprocess.Popen( cmd, shell=True, stdin=subprocess.PIPE,
- stdout=subprocess.PIPE, stderr=_stderr,
- close_fds=True )
-
- out = [ l[:-1] for l in p.stdout.readlines() ]
-
- p.stdout.close()
- if not merge_stderr:
- p.stderr.close()
-
- # need to allow process to terminate
- p.wait()
-
- errCode = p.returncode and p.returncode or 0
- if p.returncode>0:
- errorMessage = os.linesep.join(out)
- output = []
- else:
- errorMessage = ''
- output = out
-
- return output, errCode, errorMessage
-
-def to_stdout():
- def toCorFastq(f):
- stem, ext = os.path.splitext( os.path.basename(f) )
- dir = os.path.dirname(f)
- corFastq = os.path.join(dir,'%s.cor%s' % (stem,ext) )
- if not os.path.exists(corFastq):
- print >>sys.stderr, "Can't find path %s" % corFastq
- sys.exit(1)
- return corFastq
- if '-r' in cmdLine:
- fastqFile = cmdLine[ cmdLine.index('-r')+1 ]
- corFastq = toCorFastq(fastqFile)
- infile = open( corFastq, 'r' )
- for line in infile:
- sys.stdout.write( line )
- infile.close()
- else:
- fofnFile = cmdLine[ cmdLine.index('-f')+1 ]
- infile = open(fofnFile,'r')
- for line in infile:
- line = line.strip()
- if len(line)>0:
- fastqFiles = line.split()
- break
- infile.close()
- outs = output.split(',')
- for o,f in zip(outs,fastqFiles):
- cf = toCorFastq(f)
- os.system( 'cp %s %s' % ( cf, o ) )
-
-def run():
- cmd = '%s %s' % ( QUAKE_EXE, " ".join(cmdLine) )
- output, errCode, errMsg = backticks( cmd )
-
- if errCode==0:
- to_stdout()
- else:
- # if Quake exits with an error in cutoff determination we
- # can force correction if requested
- if 'cutoff.txt' in errMsg and cut>0:
- outfile = open( 'cutoff.txt', 'w' )
- print >>outfile, str(cut)
- outfile.close()
- cmd = '%s --no_count --no_cut %s' % ( QUAKE_EXE, " ".join(cmdLine) )
- output, errCode, errMsg = backticks( cmd )
- if errCode==0:
- to_stdout()
- else:
- print >>sys.stderr, errMsg
- sys.exit(1)
-
-if __name__=='__main__': run()
diff -r 3565ae97160f4a70b3910b54bcd98c0f4c7d1796 -r d9408bcb3cf4bcb81e9dac4ddeda74cbc164e123 tools/ilmn_pacbio/smrtpipe.py
--- a/tools/ilmn_pacbio/smrtpipe.py
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/env python
-# EASY-INSTALL-SCRIPT: 'pbpy==0.1','smrtpipe.py'
-__requires__ = 'pbpy==0.1'
-import pkg_resources
-pkg_resources.run_script('pbpy==0.1', 'smrtpipe.py')
diff -r 3565ae97160f4a70b3910b54bcd98c0f4c7d1796 -r d9408bcb3cf4bcb81e9dac4ddeda74cbc164e123 tools/ilmn_pacbio/smrtpipe_filter.xml
--- a/tools/ilmn_pacbio/smrtpipe_filter.xml
+++ /dev/null
@@ -1,67 +0,0 @@
-<tool id="smrtpipe_filter" name="SMRTpipe Filter" version="1.0.0">
- <description>Produce filtered reads from a set of PacBio primary analysis outputs.</description>
- <command interpreter="python">
- smrtpipe_galaxy.py --output=data/filtered_subreads.fasta --galaxy_output=${outfile} ${iniFile}
- </command>
- <inputs>
- <conditional name="source">
- <param name="input_source" type="select" label="Choose the source for the analysis inputs">
- <option value="path">Path to fofn or multiple bas.h5 paths</option>
- <option value="history">History</option>
- </param>
- <when value="path">
- <repeat name="inputFiles" title="Input files">
- <param name="path" type="text" label="File path" size="75"/>
- </repeat>
- </when>
- <when value="history">
- <param name="input1" type="data" format="tabular" label="File containing input paths" />
- </when>
- </conditional>
- <param name="minimum_readlength" type="integer" value="50" label="Minimum raw readlength" />
- <param name="minimum_readscore" type="float" value="0.75" label="Minimum read quality" />
- </inputs>
- <configfiles>
- <configfile name="iniFile">
-[input]
-#if $source.input_source=="history":
-#for $l in open($source.input1.file_name,'r'):
-$l
-#end for
-#else
-#for $p in $source.inputFiles
-${p.path}
-#end for
-#end if
-
-[S_Filter]
-filters=MinRL=${minimum_readlength},MinReadScore=${minimum_readscore}
- </configfile>
- </configfiles>
- <outputs>
- <data name="outfile" format="fasta" label="Filtered subreads" />
- </outputs>
- <help>
-
-**What it does**
-
-Filters PacBio bas.h5 files and produces a FASTA file of filtered subreads.
-
-In PacBio SMRT sequencing, the template format is a SMRTbell: a circular
-molecule with adapters at two locations in the circle. The subreads are the
-portions of the read between adapters.
-
-**Parameter list**
-
-Minimum readlength
- Only keep reads from ZMWs that produced this many bases or more.
-
-Minimum read quality
- Only keep reads with overall quality scores of this value or more. The read quality score is a *de novo* prediction of the accuracy of the read.
-
-**Output**
-
-FASTA file of filtered reads.
-
- </help>
-</tool>
diff -r 3565ae97160f4a70b3910b54bcd98c0f4c7d1796 -r d9408bcb3cf4bcb81e9dac4ddeda74cbc164e123 tools/ilmn_pacbio/smrtpipe_galaxy.py
--- a/tools/ilmn_pacbio/smrtpipe_galaxy.py
+++ /dev/null
@@ -1,265 +0,0 @@
-#!/usr/bin/python
-import sys
-import os
-import subprocess
-import optparse as op
-import xml.etree.cElementTree as et
-
-TRACE=False
-#
-# Turn on tracing to dump out __input__.xml and __settings__.xml somewhere
-#
-#TRACE=True
-#TRACE_PATH='/home/UNIXHOME/jsorenson'
-
-class SmrtpipeGalaxy:
- """Wrapper for running smrtpipe under galaxy"""
- def __init__( self, argv ):
- self.__parseOptions( argv )
-
- def __parseOptions( self, argv ):
- usage = 'Usage: %prog [--help] [options] smrtpipe.ini'
- parser = op.OptionParser( usage=usage, description=SmrtpipeGalaxy.__doc__ )
- parser.add_option( "--output",
- help="Designate a file generated by smrtpipe as the expected output for galaxy" )
- parser.add_option( "--nproc", type="int",
- help="Number of processes to use (-D NPROC)" )
- parser.add_option( "--galaxy_output",
- help="File name provided by galaxy where output should be placed" )
- parser.add_option( "--dry_run", action="store_true",
- help="Create auxiliary XML files and exit" )
- parser.add_option( "--dat_extension",
- help="Soft link .dat files to have this extension (some pipelines require certain extensions)" )
-
- parser.set_defaults( output=None, dry_run=False, galaxy_output=None,
- dat_extension=None, nproc=0 )
- self.options, self.args = parser.parse_args( argv )
-
- if len(self.args)!=2:
- parser.error( 'Expected 1 argument' )
-
- self.configFile = self.args[1]
-
- def __parseConfig( self ):
- infile = open( self.configFile, 'r' )
- section = None
- sections = []
- for line in infile:
- l = line.strip()
- if len(l)==0 or line.startswith('#'):
- continue
- if l.startswith('[') and l.endswith(']'):
- section = section_factory( l[1:-1] )
- sections.append(section)
- continue
- if section is None:
- continue
- if '=' in l:
- section.addParameterLine(l)
- else:
- section.addLine(l)
- infile.close()
- return sections
-
- def transferOutput( self ):
- if not self.options.output or not self.options.galaxy_output:
- return True, ''
- if not os.path.exists(self.options.output):
- return False, "Can't find file %s (job error?)" % self.options.output
- os.system( 'cp %s %s' % (self.options.output, self.options.galaxy_output ))
- return True, ''
-
- def run( self ):
- if not os.path.exists( self.configFile ):
- print >>sys.stderr, "Can't find config file %s" % self.configFile
- return 1
-
- sections = self.__parseConfig()
-
- if len(sections)==0:
- print >>sys.stderr, "No sections found in %s" % self.configFile
- return 1
- if sections[0].name != 'input':
- print >>sys.stderr, "No [input] section found in %s" % self.configFile
- return 1
-
- INPUT_FILE = '__input__.xml'
- SETTINGS_FILE = '__settings__.xml'
-
- sections[0].softLinkDats( self.options.dat_extension )
- inputXml = sections[0].makeXmlElement()
- write_xml_to_file( INPUT_FILE, inputXml )
- if TRACE:
- write_xml_to_file( os.path.join(TRACE_PATH,INPUT_FILE), inputXml )
-
- settings = et.Element( 'smrtpipeSettings' )
- for s in sections[1:]:
- s.makeXmlElement( settings )
-
- write_xml_to_file( SETTINGS_FILE, settings )
- if TRACE:
- write_xml_to_file( os.path.join(TRACE_PATH,SETTINGS_FILE), settings )
-
- nproc = '-D NPROC=%d' % self.options.nproc if self.options.nproc>0 else ''
- cmd = 'smrtpipe.py %s --params=%s xml:%s > smrtpipe.err 2>1' % \
- ( nproc, SETTINGS_FILE, INPUT_FILE )
-
- if self.options.dry_run:
- print 'Command to run:'
- print cmd
- return 0
-
- out, errCode, errMsg = backticks( cmd )
- if errCode!=0:
- print >>sys.stderr, "error while running: %s" % cmd
- print >>sys.stderr, errMsg
- if os.path.exists('log/smrtpipe.log'):
- print >>sys.stderr, 'Log:'
- infile = open('log/smrtpipe.log','r')
- for line in infile: sys.stderr.write(line)
- infile.close()
- return errCode
-
- success, errMsg = self.transferOutput()
- if not success:
- print >>sys.stderr, errMsg
- return 1
-
- return 0
-
-def write_xml_to_file( fileName, root ):
- outfile = open( fileName, 'w' )
- outfile.write( '<?xml version="1.0"?>\n' )
- outfile.write( et.tostring(root) + '\n' )
- outfile.close()
-
-def section_factory( name ):
- if name=='input':
- return InputSection(name)
- else:
- return Section(name)
-
-class Section:
- def __init__( self, name ):
- self._name = name
- self._lines = []
- self._vars = {}
-
- @property
- def name(self):
- return self._name
-
- def addLine( self, line ):
- self._lines.append(line)
-
- def addParameterLine( self, line ):
- self.addLine(line)
- i = line.find( '=' )
- key = line[:i].strip()
- value = line[i+1:].strip()
- self._vars[key] = value
-
- def makeXmlElement( self, settings ):
- if self._name=='global':
- root = et.SubElement( settings, "protocol", {'name':'generic'} )
- else:
- root = et.SubElement( settings, "module", {'name':self._name} )
- for k,v in self._vars.iteritems():
- param = et.SubElement( root, 'param', {'name':k} )
- val = et.SubElement( param, 'value' )
- val.text = v
- return None
-
- def __str__( self ):
- "for debugging"
- buffer = [ 'S { name=' ]
- buffer.append(self._name)
- buffer.append('; lines=%s' % ','.join(self._lines) )
- for k,v in self._vars.iteritems():
- buffer.append('; %s=%s' % (k,v) )
- buffer.append(' }')
- return ''.join(buffer)
-
-class InputSection( Section ):
- def __init__( self, name ):
- Section.__init__(self,name)
-
- def softLinkDats( self, newExtension ):
- if not newExtension:
- return
- newLines = []
- for l in self._lines:
- if ':' in l:
- protocol = l[:l.find(':')+1]
- file = l[l.find(':')+1:]
- else:
- protocol = ''
- file = l
- if os.path.exists(file) and file.endswith('.dat'):
- newFile = '%s.%s' % ( file, newExtension )
- if not os.path.exists(newFile):
- os.system( 'ln -s %s %s' % ( file, newFile ) )
- newLines.append(protocol+newFile)
- else:
- newLines.append(l)
- self._lines = newLines
-
- def makeXmlElement( self, parent=None ):
- root = et.Element( "pacbioAnalysisInputs" )
- data = et.SubElement( root, 'dataReferences' )
- iRef = 0
- for l in self._lines:
- def add(x,iRef):
- if len(x)==0: return iRef
- node = et.SubElement( data, 'url' )
- if ':' in x:
- node.attrib[ 'ref' ] = x
- else:
- node.attrib[ 'ref' ] = 'run:0000000-%04d' % iRef
- node2 = et.SubElement( node, 'location' )
- node2.text = x
- return iRef+1
- if l.endswith('fofn') and os.path.exists(l):
- infile = open(l,'r')
- for j,line in enumerate(infile): iRef=add(line.strip(),iRef)
- infile.close()
- else:
- iRef=add(l,iRef)
- return root
-
-def backticks( cmd, merge_stderr=True ):
- """
- Simulates the perl backticks (``) command with error-handling support
- Returns ( command output as sequence of strings, error code, error message )
- """
- if merge_stderr:
- _stderr = subprocess.STDOUT
- else:
- _stderr = subprocess.PIPE
-
- p = subprocess.Popen( cmd, shell=True, stdin=subprocess.PIPE,
- stdout=subprocess.PIPE, stderr=_stderr,
- close_fds=True )
-
- out = [ l[:-1] for l in p.stdout.readlines() ]
-
- p.stdout.close()
- if not merge_stderr:
- p.stderr.close()
-
- # need to allow process to terminate
- p.wait()
-
- errCode = p.returncode and p.returncode or 0
- if p.returncode>0:
- errorMessage = os.linesep.join(out)
- output = []
- else:
- errorMessage = ''
- output = out
-
- return output, errCode, errorMessage
-
-if __name__=='__main__':
- app = SmrtpipeGalaxy( sys.argv )
- sys.exit( app.run() )
diff -r 3565ae97160f4a70b3910b54bcd98c0f4c7d1796 -r d9408bcb3cf4bcb81e9dac4ddeda74cbc164e123 tools/ilmn_pacbio/smrtpipe_hybrid.xml
--- a/tools/ilmn_pacbio/smrtpipe_hybrid.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<tool id="smrtpipe_hybrid" name="AHA" version="1.0.0">
- <description>Assemble contigs from a set of contigs and PacBio reads.</description>
- <command interpreter="python">
- smrtpipe_galaxy.py --nproc=24 --dat_extension=fasta --output=data/scaffold.fasta --galaxy_output=${outfile} ${iniFile}
- </command>
- <!--
- <command>cp ${iniFile} ${outfile}</command>
- -->
- <inputs>
- <param name="contigs" format="fasta" type="data" label="Starting Contigs"/>
- <param name="reads" format="fasta" type="data" label="PacBio Reads"/>
- <param name="schedule" type="text" value="6,3,75;6,3,75;5,3,75;5,3,75;6,2,75;6,2,75;5,2,75;5,2,75" label="Parameter Schedule" size="60"/>
- </inputs>
- <configfiles>
- <configfile name="iniFile">
-[input]
-assembled_contigs:${contigs}
-file:${reads}
-
-[HybridAssembly]
-instrumentModel=RS
-cleanup=False
-untangler=pacbio
-#set $schedule2 = $schedule.replace('X',';')
-paramSchedule=${schedule2}
-dontFillin=False
-longReadsAsStrobe=True
-exactQueryIds=True
-rm4Opts=-minMatch 7 -minFrac 0.1 -minPctIdentity 65 -bestn 10 -noSplitSubreads
-numberProcesses=16
-cluster=False
-minRepeatLength=100000
- </configfile>
- </configfiles>
- <outputs>
- <data name="outfile" format="fasta" label="Hybrid assembly contigs from ${on_string}"/>
- </outputs>
- <help>
-
-**What it does**
-
-The AHA assembly algorithm is an AMOS_-based pipeline
-for finishing bacterial-sized
-genomes using draft contigs and PacBio reads.
-
-.. _AMOS: http://sourceforge.net/apps/mediawiki/amos
-
-**Parameter list**
-
-Parameter schedule
- The parameter schedule is a semi-colon delimited list of triples. Each triple represents an iteration of hybrid assembly (alignment/scaffolding/gap-filling). The three paremeters for each iteration are the Z-score, number of reads required to define a link, and the minimum length of subreads used in links.
-
-**Output**
-
-FASTA file containing scaffolded and gap-filled contigs resulting from the
-hybrid assembly.
-
- </help>
-</tool>
diff -r 3565ae97160f4a70b3910b54bcd98c0f4c7d1796 -r d9408bcb3cf4bcb81e9dac4ddeda74cbc164e123 tools/ilmn_pacbio/soap_denovo.xml
--- a/tools/ilmn_pacbio/soap_denovo.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-<tool id="soap_denovo" name="SOAPdenovo" version="1.0.0">
- <description>Short-read de novo assembly</description>
- <!--
- # SOAPdenovo-127mer all -s ${soap_config} -o assembly -K ${k} -p 8 -d -D
- # cat ${soap_config} > ${output1}
- # cp ${soap_config} ${output1} &&
- -->
- <command>
- SOAPdenovo-127mer all -s ${soap_config} -o assembly -K ${k} -p 24 -d -D -R
- </command>
- <inputs>
- <conditional name="inputs">
- <param name="read_type" type="select" label="Illumina read type">
- <option value="single">Single fragment</option>
- <option value="paired">Paired-end</option>
- </param>
- <when value="single">
- <param name="input1" format="fastq" type="data" label="FASTQ file for reads"/>
- </when>
- <when value="paired">
- <param name="input1" format="fastq" type="data" label="FASTQ file for forward reads"/>
- <param name="input2" format="fastq" type="data" label="FASTQ file for reverse reads"/>
- <param name="d" type="integer" value="500" label="Estimated insert size for paired-end reads" />
- </when>
- </conditional>
- <param name="k" type="integer" value="23" label="Size of k for forming the de Bruijn overlap graph" />
- </inputs>
- <configfiles>
- <configfile name="soap_config">max_rd_len=105
-[LIB]
-#if $inputs.read_type == "single"
-q=${inputs.input1.file_name}
-#else
-avg_ins=${inputs.d}
-asm_flags=3
-reverse_seq=0
-q1=${inputs.input1.file_name}
-q2=${inputs.input2.file_name}
-#end if
- </configfile>
- </configfiles>
- <outputs>
- <data name="assembled_contigs" format="fasta" from_work_dir="assembly.scafSeq" label="Assembled contigs from ${on_string}" />
- </outputs>
- <help>
-
-**What it does**
-
-Runs SOAPdenovo_ to generate a genome assembly
-using single-fragment or paired-end short reads.
-
-Li R, Zhu H, Ruan J, Qian W, Fang X, Shi Z, Li Y, Li S, Shan G, Kristiansen K, Li S, Yang H, Wang J, Wang J.
-"De novo assembly of human genomes with massively parallel short read sequencing."
-*Genome Res.* 2010 Feb;20(2):265-72.
-
-.. _SOAPdenovo: http://soap.genomics.org.cn/soapdenovo.html
-
-**Parameter list**
-
-k
- k-mer size for constructing the de Bruijn graph. The appropriate size of k is genome and data set dependent, but a good starting choice might be 75% of the read length.
-
-Insert size
- For paired-end libraries, the expected insert size.
-
-**Output**
-
-assembly
-
- </help>
-</tool>
-
-
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/3565ae97160f/
changeset: 3565ae97160f
user: dan
date: 2011-11-10 17:54:50
summary: Update GeneTrack help.
affected #: 2 files
diff -r b62855bbd52e68b7ecac586e3bc329c7e472bc47 -r 3565ae97160f4a70b3910b54bcd98c0f4c7d1796 tools/genetrack/genetrack_indexer.xml
--- a/tools/genetrack/genetrack_indexer.xml
+++ b/tools/genetrack/genetrack_indexer.xml
@@ -49,10 +49,14 @@
When shifting the averaging process in GeneTrack is able correct for longer or shorter
than expected fragment sizes as long as the errors are reasonably random.
+See http://genetrack.bx.psu.edu/ for more information on GeneTrack.
+
------
**Citation**
+For the underlying tool, please cite `Albert I, Wachi S, Jiang C, Pugh BF. GeneTrack--a genomic data processing and visualization framework. Bioinformatics. 2008 May 15;24(10):1305-6. <http://www.ncbi.nlm.nih.gov/pubmed/18388141>`_
+
If you use this tool in Galaxy, please cite Blankenberg D, et al. *In preparation.*
</help>
diff -r b62855bbd52e68b7ecac586e3bc329c7e472bc47 -r 3565ae97160f4a70b3910b54bcd98c0f4c7d1796 tools/genetrack/genetrack_peak_prediction.xml
--- a/tools/genetrack/genetrack_peak_prediction.xml
+++ b/tools/genetrack/genetrack_peak_prediction.xml
@@ -54,10 +54,14 @@
- **Prediction method** the function used to average nearby values
+See http://genetrack.bx.psu.edu/ for more information on GeneTrack.
+
------
**Citation**
+For the underlying tool, please cite `Albert I, Wachi S, Jiang C, Pugh BF. GeneTrack--a genomic data processing and visualization framework. Bioinformatics. 2008 May 15;24(10):1305-6. <http://www.ncbi.nlm.nih.gov/pubmed/18388141>`_
+
If you use this tool in Galaxy, please cite Blankenberg D, et al. *In preparation.*
</help>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/b62855bbd52e/
changeset: b62855bbd52e
user: greg
date: 2011-11-10 16:57:39
summary: Add the ability to enter a new tool panel section label when installing repositories with tools from a tool shed in addition to being able to choose an existing tool panel section for containing the tools. Also clean up code related to message displayed when a local Galaxy instance is missing tools required by an imported workflow.
affected #: 5 files
diff -r 23198e766859394108d48de1489be7052530d38b -r b62855bbd52e68b7ecac586e3bc329c7e472bc47 lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -22,6 +22,7 @@
pkg_resources.require( 'elementtree' )
from elementtree import ElementTree, ElementInclude
+from elementtree.ElementTree import Element
log = logging.getLogger( __name__ )
diff -r 23198e766859394108d48de1489be7052530d38b -r b62855bbd52e68b7ecac586e3bc329c7e472bc47 lib/galaxy/web/controllers/admin.py
--- a/lib/galaxy/web/controllers/admin.py
+++ b/lib/galaxy/web/controllers/admin.py
@@ -3,7 +3,7 @@
from galaxy.model.orm import *
from galaxy.web.framework.helpers import time_ago, iff, grids
from galaxy.tools.search import ToolBoxSearch
-from galaxy.tools import json_fix
+from galaxy.tools import ToolSection, json_fix
import logging
log = logging.getLogger( __name__ )
@@ -403,7 +403,7 @@
def get_value( self, trans, grid, tool_shed_repository ):
return tool_shed_repository.tool_shed
# Grid definition
- title = "Tool shed repositories"
+ title = "Installed tool shed repositories"
model_class = model.ToolShedRepository
template='/admin/tool_shed_repository/grid.mako'
default_sort_key = "name"
@@ -807,28 +807,45 @@
status = kwd.get( 'status', 'done' )
tool_shed_url = kwd[ 'tool_shed_url' ]
repo_info_dict = kwd[ 'repo_info_dict' ]
+ new_tool_panel_section = kwd.get( 'new_tool_panel_section', '' )
+ tool_panel_section = kwd.get( 'tool_panel_section', '' )
if kwd.get( 'select_tool_panel_section_button', False ):
shed_tool_conf = kwd[ 'shed_tool_conf' ]
# Get the tool path.
for k, tool_path in trans.app.toolbox.shed_tool_confs.items():
if k == shed_tool_conf:
break
- if 'tool_panel_section' in kwd:
- section_key = 'section_%s' % kwd[ 'tool_panel_section' ]
- tool_section = trans.app.toolbox.tool_panel[ section_key ]
+ if new_tool_panel_section or tool_panel_section:
+ if new_tool_panel_section:
+ section_id = new_tool_panel_section.lower().replace( ' ', '_' )
+ new_section_key = 'section_%s' % str( section_id )
+ if new_section_key in trans.app.toolbox.tool_panel:
+ # Appending a tool to an existing section in trans.app.toolbox.tool_panel
+ log.debug( "Appending to tool panel section: %s" % new_tool_panel_section )
+ tool_section = trans.app.toolbox.tool_panel[ new_section_key ]
+ else:
+ # Appending a new section to trans.app.toolbox.tool_panel
+ log.debug( "Loading new tool panel section: %s" % new_tool_panel_section )
+ elem = Element( 'section' )
+ elem.attrib[ 'name' ] = new_tool_panel_section
+ elem.attrib[ 'id' ] = section_id
+ tool_section = ToolSection( elem )
+ trans.app.toolbox.tool_panel[ new_section_key ] = tool_section
+ else:
+ section_key = 'section_%s' % tool_panel_section
+ tool_section = trans.app.toolbox.tool_panel[ section_key ]
# Decode the encoded repo_info_dict param value.
repo_info_dict = tool_shed_decode( repo_info_dict )
# Clone the repository to the configured location.
current_working_dir = os.getcwd()
+ installed_repository_names = []
for name, repo_info_tuple in repo_info_dict.items():
description, repository_clone_url, changeset_revision = repo_info_tuple
clone_dir = os.path.join( tool_path, self.__generate_tool_path( repository_clone_url, changeset_revision ) )
if os.path.exists( clone_dir ):
# Repository and revision has already been cloned.
# TODO: implement the ability to re-install or revert an existing repository.
- message += 'Revision <b>%s</b> of repository <b>%s</b> has already been installed. Updating an existing repository is not yet supported.<br/>' % \
- ( changeset_revision, name )
- status = 'error'
+ message += 'Revision <b>%s</b> of repository <b>%s</b> was previously installed.<br/>' % ( changeset_revision, name )
else:
os.makedirs( clone_dir )
log.debug( 'Cloning %s...' % repository_clone_url )
@@ -892,9 +909,7 @@
if trans.app.toolbox_search.enabled:
# If search support for tools is enabled, index the new installed tools.
trans.app.toolbox_search = ToolBoxSearch( trans.app.toolbox )
- message += 'Revision <b>%s</b> of repository <b>%s</b> has been loaded into tool panel section <b>%s</b>.<br/>' % \
- ( changeset_revision, name, tool_section.name )
- #return trans.show_ok_message( message )
+ installed_repository_names.append( name )
else:
tmp_stderr = open( tmp_name, 'rb' )
message += '%s<br/>' % tmp_stderr.read()
@@ -905,6 +920,19 @@
message += '%s<br/>' % tmp_stderr.read()
tmp_stderr.close()
status = 'error'
+ if installed_repository_names:
+ installed_repository_names.sort()
+ message += 'These %d repositories were installed and all tools were loaded into tool panel section <b>%s</b>:<br/>' % \
+ ( len( installed_repository_names ), tool_section.name )
+ for i, repo_name in enumerate( installed_repository_names ):
+ if i == len( installed_repository_names ) -1:
+ message += '%s.<br/>' % repo_name
+ else:
+ message += '%s, ' % repo_name
+ return trans.response.send_redirect( web.url_for( controller='admin',
+ action='browse_tool_shed_repositories',
+ message=message,
+ status=status ) )
else:
message = 'Choose the section in your tool panel to contain the installed tools.'
status = 'error'
@@ -921,6 +949,7 @@
shed_tool_conf=shed_tool_conf,
shed_tool_conf_select_field=shed_tool_conf_select_field,
tool_panel_section_select_field=tool_panel_section_select_field,
+ new_tool_panel_section=new_tool_panel_section,
message=message,
status=status )
@web.expose
diff -r 23198e766859394108d48de1489be7052530d38b -r b62855bbd52e68b7ecac586e3bc329c7e472bc47 lib/galaxy/web/controllers/workflow.py
--- a/lib/galaxy/web/controllers/workflow.py
+++ b/lib/galaxy/web/controllers/workflow.py
@@ -1115,10 +1115,10 @@
workflow_name = tool_shed_decode( workflow_name )
# The following parameters will have a value only if the import originated
# from a tool shed repository installed locally.
- local_file = kwd.get( 'local_file', '' )
+ installed_repository_file = kwd.get( 'installed_repository_file', '' )
repository_id = kwd.get( 'repository_id', '' )
- if local_file and not import_button:
- workflow_file = open( local_file, 'rb' )
+ if installed_repository_file and not import_button:
+ workflow_file = open( installed_repository_file, 'rb' )
workflow_text = workflow_file.read()
workflow_file.close()
import_button = True
@@ -1197,27 +1197,26 @@
if shed_url.endswith( '/' ):
shed_url = shed_url.rstrip( '/' )
url = '%s/repository/find_tools?galaxy_url=%s&webapp=%s' % ( shed_url, trans.request.host, webapp )
+ if missing_tool_tups:
+ url += '&tool_id='
for missing_tool_tup in missing_tool_tups:
missing_tool_id = missing_tool_tup[0]
- url += '&tool_id=%s' % missing_tool_id
+ url += '%s,' % missing_tool_id
message += '<a href="%s">%s</a><br/>' % ( url, shed_name )
status = 'error'
- if local_file or tool_shed_url:
+ if installed_repository_file or tool_shed_url:
# Another Galaxy panels Hack: The request did not originate from the Galaxy
# workflow view, so we don't need to render the Galaxy panels.
- return trans.response.send_redirect( web.url_for( controller='admin',
- action='center',
- webapp='galaxy',
- message=message,
- status=status ) )
+ action = 'center'
else:
# Another Galaxy panels hack: The request originated from the Galaxy
# workflow view, so we need to render the Galaxy panels.
- return trans.response.send_redirect( web.url_for( controller='admin',
- action='index',
- webapp='galaxy',
- message=message,
- status=status ) )
+ action = 'index'
+ return trans.response.send_redirect( web.url_for( controller='admin',
+ action=action,
+ webapp='galaxy',
+ message=message,
+ status=status ) )
else:
# TODO: Figure out what to do here...
pass
@@ -1228,7 +1227,7 @@
url = 'http://%s/workflow/view_workflow?repository_metadata_id=%s&workflow_name=%s&webapp=%s&message=%s' % \
( tool_shed_url, repository_metadata_id, tool_shed_encode( workflow_name ), webapp, message )
return trans.response.send_redirect( url )
- elif local_file:
+ elif installed_repository_file:
# The workflow was read from a file included with an installed tool shed repository.
message = "Workflow <b>%s</b> imported successfully." % workflow.name
return trans.response.send_redirect( web.url_for( controller='admin',
diff -r 23198e766859394108d48de1489be7052530d38b -r b62855bbd52e68b7ecac586e3bc329c7e472bc47 templates/admin/select_tool_panel_section.mako
--- a/templates/admin/select_tool_panel_section.mako
+++ b/templates/admin/select_tool_panel_section.mako
@@ -23,7 +23,7 @@
<br/><div class="toolForm">
- <div class="toolFormTitle">Load tools into tool panel</div>
+ <div class="toolFormTitle">Choose section to load tools into tool panel</div><div class="toolFormBody"><form name="select_tool_panel_section" id="select_tool_panel_section" action="${h.url_for( controller='admin', action='install_tool_shed_repository', tool_shed_url=tool_shed_url, repo_info_dict=repo_info_dict )}" method="post" >
%if shed_tool_conf_select_field:
@@ -40,10 +40,17 @@
<input type="hidden" name="shed_tool_conf" value="${shed_tool_conf}"/>
%endif
<div class="form-row">
- <label>Tool panel section:</label>
+ <label>Add new tool panel section:</label>
+ <input name="new_tool_panel_section" type="textfield" value="${new_tool_panel_section}" size="40"/>
+ <div class="toolParamHelp" style="clear: both;">
+ Add a new tool panel section or choose an existing section in your tool panel below to contain the installed tools.
+ </div>
+ </div>
+ <div class="form-row">
+ <label>Select existing tool panel section:</label>
${tool_panel_section_select_field.get_html()}
<div class="toolParamHelp" style="clear: both;">
- Choose the section in your tool panel to contain the installed tools.
+ Choose an existing section in your tool panel to contain the installed tools.
</div></div><div class="form-row">
diff -r 23198e766859394108d48de1489be7052530d38b -r b62855bbd52e68b7ecac586e3bc329c7e472bc47 templates/admin/tool_shed_repository/browse_repository.mako
--- a/templates/admin/tool_shed_repository/browse_repository.mako
+++ b/templates/admin/tool_shed_repository/browse_repository.mako
@@ -103,7 +103,7 @@
<div class="menubutton" style="float: left;" id="workflow-${index}-popup">
${workflow_name}
<div popupmenu="workflow-${index}-popup">
- <a class="action-button" href="${h.url_for( controller='workflow', action='import_workflow', local_file=full_path, repository_id=trans.security.encode_id( repository.id ) )}">Import to Galaxy</a>
+ <a class="action-button" href="${h.url_for( controller='workflow', action='import_workflow', installed_repository_file=full_path, repository_id=trans.security.encode_id( repository.id ) )}">Import to Galaxy</a></div></div></td>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/23198e766859/
changeset: 23198e766859
user: dannon
date: 2011-11-10 14:54:23
summary: Repack of .js
affected #: 3 files
diff -r a4df07ccecdb70ae45982e596d2e360bdc9ab217 -r 23198e766859394108d48de1489be7052530d38b static/scripts/packed/galaxy.panels.js
--- a/static/scripts/packed/galaxy.panels.js
+++ b/static/scripts/packed/galaxy.panels.js
@@ -1,1 +1,1 @@
-function ensure_dd_helper(){if($("#DD-helper").length==0){$("<div id='DD-helper'/>").css({background:"white",opacity:0,zIndex:9000,position:"absolute",top:0,left:0,width:"100%",height:"100%"}).appendTo("body").hide()}}var MIN_PANEL_WIDTH=100,MAX_PANEL_WIDTH=1000;function make_left_panel(h,c,e){var g=false;var f=null;var d=function(i){var j=i;if(i<0){i=0}$(h).css("width",i);$(e).css("left",j);$(c).css("left",i+7);if(document.recalc){document.recalc()}};var a=function(){if(g){$(e).removeClass("hover");$(e).animate({left:f},"fast");$(h).css("left",-f).show().animate({left:0},"fast",function(){d(f);$(e).removeClass("hidden")});g=false}else{f=$(e).position().left;$(c).css("left",$(e).innerWidth());if(document.recalc){document.recalc()}$(e).removeClass("hover");$(h).animate({left:-f},"fast");$(e).animate({left:-1},"fast",function(){$(this).addClass("hidden")});g=true}};$(e).bind("dragstart",function(){$("#DD-helper").show()}).bind("dragend",function(){$("#DD-helper").hide()}).bind("drag",function(i,j){x=j.offsetX;x=Math.min(MAX_PANEL_WIDTH,Math.max(MIN_PANEL_WIDTH,x));if(g){$(h).css("left",0);$(e).removeClass("hidden");g=false}d(x)}).bind("dragclickonly",function(){a()}).find("div").show();var b=function(i){if((g&&i=="show")||(!g&&i=="hide")){a()}};return{force_panel:b}}function make_right_panel(a,e,h){var j=false,g=false,c=null;var d=function(k){$(a).css("width",k);$(e).css("right",k+9);$(h).css("right",k).css("left","");if(document.recalc){document.recalc()}};var i=function(){if(j){$(h).removeClass("hover");$(h).animate({right:c},"fast");$(a).css("right",-c).show().animate({right:0},"fast",function(){d(c);$(h).removeClass("hidden")});j=false}else{c=$(document).width()-$(h).position().left-$(h).outerWidth();$(e).css("right",$(h).innerWidth()+1);if(document.recalc){document.recalc()}$(h).removeClass("hover");$(a).animate({right:-c},"fast");$(h).animate({right:-1},"fast",function(){$(this).addClass("hidden")});j=true}g=false};var b=function(k){var l=$(e).width()-(j?c:0);if(l<k){if(!j){i();g=true}}else{if(g){i();g=false}}};$(h).hover(function(){$(this).addClass("hover")},function(){$(this).removeClass("hover")}).bind("dragstart",function(){$("#DD-helper").show()}).bind("dragend",function(){$("#DD-helper").hide()}).bind("drag",function(k,l){x=l.offsetX;w=$(window).width();x=Math.min(w-MIN_PANEL_WIDTH,x);x=Math.max(w-MAX_PANEL_WIDTH,x);if(j){$(a).css("right",0);$(h).removeClass("hidden");j=false}d(w-x-$(this).outerWidth())}).bind("dragclickonly",function(){i()}).find("div").show();var f=function(k){if((j&&k=="show")||(!j&&k=="hide")){i()}};return{handle_minwidth_hint:b,force_panel:f}}function hide_modal(){$(".dialog-box-container").fadeOut(function(){$("#overlay").hide();$(".dialog-box").find(".body").children().remove()})}function show_modal(h,c,f,d,g){if(h){$(".dialog-box").find(".title").html(h);$(".dialog-box").find(".unified-panel-header").show()}else{$(".dialog-box").find(".unified-panel-header").hide()}var a=$(".dialog-box").find(".buttons").html("");if(f){$.each(f,function(b,i){a.append($("<button/>").text(b).click(i));a.append(" ")});a.show()}else{a.hide()}var a=$(".dialog-box").find(".extra_buttons").html("");if(d){$.each(d,function(b,i){a.append($("<button/>").text(b).click(i));a.append(" ")});a.show()}else{a.hide()}if(c=="progress"){c=$("<img/>").attr("src",image_path+"/yui/rel_interstitial_loading.gif")}var e=$(".dialog-box").find(".body");e.css("min-width","");$(".dialog-box").find(".body").html(c);if(!$(".dialog-box-container").is(":visible")){$("#overlay").show();$(".dialog-box-container").fadeIn()}e.css("min-width",e.width());if(g){g()}}function show_in_overlay(c){var d=c.width||"600";var b=c.height||"400";var a=c.scroll||"auto";$("#overlay-background").bind("click.overlay",function(){hide_modal();$("#overlay-background").unbind("click.overlay")});show_modal(null,$("<div style='margin: -5px;'><img id='close_button' style='position:absolute;right:-17px;top:-15px;src='"+image_path+"/closebox.png'><iframe style='margin: 0; padding: 0;' src='"+c.url+"' width='"+d+"' height='"+b+"' scrolling='"+a+"' frameborder='0'></iframe></div>"));$("#close_button").bind("click",function(){hide_modal()})}$(function(){$(".tab").each(function(){var a=$(this).children(".submenu");if(a.length>0){if($.browser.msie){a.prepend("<iframe style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; filter:Alpha(Opacity='0');\"></iframe>")}$(this).hover(function(){a.show()},function(){a.hide()});a.click(function(){a.hide()})}})});function user_changed(a,b){if(a){$(".loggedin-only").show();$(".loggedout-only").hide();$("#user-email").text(a);if(b){$(".admin-only").show()}}else{$(".loggedin-only").hide();$(".loggedout-only").show();$(".admin-only").hide()}};
\ No newline at end of file
+function ensure_dd_helper(){if($("#DD-helper").length==0){$("<div id='DD-helper'/>").css({background:"white",opacity:0,zIndex:9000,position:"absolute",top:0,left:0,width:"100%",height:"100%"}).appendTo("body").hide()}}var MIN_PANEL_WIDTH=100,MAX_PANEL_WIDTH=1000;function make_left_panel(h,c,e){var g=false;var f=null;var d=function(i){var j=i;if(i<0){i=0}$(h).css("width",i);$(e).css("left",j);$(c).css("left",i+7);if(document.recalc){document.recalc()}};var a=function(){if(g){$(e).removeClass("hover");$(e).animate({left:f},"fast");$(h).css("left",-f).show().animate({left:0},"fast",function(){d(f);$(e).removeClass("hidden")});g=false}else{f=$(e).position().left;$(c).css("left",$(e).innerWidth());if(document.recalc){document.recalc()}$(e).removeClass("hover");$(h).animate({left:-f},"fast");$(e).animate({left:-1},"fast",function(){$(this).addClass("hidden")});g=true}};$(e).bind("dragstart",function(){$("#DD-helper").show()}).bind("dragend",function(){$("#DD-helper").hide()}).bind("drag",function(i,j){x=j.offsetX;x=Math.min(MAX_PANEL_WIDTH,Math.max(MIN_PANEL_WIDTH,x));if(g){$(h).css("left",0);$(e).removeClass("hidden");g=false}d(x)}).bind("dragclickonly",function(){a()}).find("div").show();var b=function(i){if((g&&i=="show")||(!g&&i=="hide")){a()}};return{force_panel:b}}function make_right_panel(a,e,h){var j=false,g=false,c=null;var d=function(k){$(a).css("width",k);$(e).css("right",k+9);$(h).css("right",k).css("left","");if(document.recalc){document.recalc()}};var i=function(){if(j){$(h).removeClass("hover");$(h).animate({right:c},"fast");$(a).css("right",-c).show().animate({right:0},"fast",function(){d(c);$(h).removeClass("hidden")});j=false}else{c=$(document).width()-$(h).position().left-$(h).outerWidth();$(e).css("right",$(h).innerWidth()+1);if(document.recalc){document.recalc()}$(h).removeClass("hover");$(a).animate({right:-c},"fast");$(h).animate({right:-1},"fast",function(){$(this).addClass("hidden")});j=true}g=false};var b=function(k){var l=$(e).width()-(j?c:0);if(l<k){if(!j){i();g=true}}else{if(g){i();g=false}}};$(h).hover(function(){$(this).addClass("hover")},function(){$(this).removeClass("hover")}).bind("dragstart",function(){$("#DD-helper").show()}).bind("dragend",function(){$("#DD-helper").hide()}).bind("drag",function(k,l){x=l.offsetX;w=$(window).width();x=Math.min(w-MIN_PANEL_WIDTH,x);x=Math.max(w-MAX_PANEL_WIDTH,x);if(j){$(a).css("right",0);$(h).removeClass("hidden");j=false}d(w-x-$(this).outerWidth())}).bind("dragclickonly",function(){i()}).find("div").show();var f=function(k){if((j&&k=="show")||(!j&&k=="hide")){i()}};return{handle_minwidth_hint:b,force_panel:f}}function hide_modal(){$(".dialog-box-container").hide(0,function(){$("#overlay").hide();$("#overlay").removeClass("modal");$(".dialog-box").find(".body").children().remove()})}function show_modal(){$("#overlay").addClass("modal");_show_modal.apply(this,arguments)}function show_message(){_show_modal.apply(this,arguments)}function _show_modal(h,c,f,d,g){if(h){$(".dialog-box").find(".title").html(h);$(".dialog-box").find(".unified-panel-header").show()}else{$(".dialog-box").find(".unified-panel-header").hide()}var a=$(".dialog-box").find(".buttons").html("");if(f){$.each(f,function(b,i){a.append($("<button/>").text(b).click(i));a.append(" ")});a.show()}else{a.hide()}var a=$(".dialog-box").find(".extra_buttons").html("");if(d){$.each(d,function(b,i){a.append($("<button/>").text(b).click(i));a.append(" ")});a.show()}else{a.hide()}if(c=="progress"){c=$("<img/>").attr("src",image_path+"/yui/rel_interstitial_loading.gif")}var e=$(".dialog-box").find(".body");e.css("min-width","");$(".dialog-box").find(".body").html(c);if(!$(".dialog-box-container").is(":visible")){$("#overlay").show();$(".dialog-box-container").show()}e.css("min-width",e.width());if(g){g()}}function show_in_overlay(c){var d=c.width||"600";var b=c.height||"400";var a=c.scroll||"auto";$("#overlay-background").bind("click.overlay",function(){hide_modal();$("#overlay-background").unbind("click.overlay")});show_modal(null,$("<div style='margin: -5px;'><img id='close_button' style='position:absolute;right:-17px;top:-15px;src='"+image_path+"/closebox.png'><iframe style='margin: 0; padding: 0;' src='"+c.url+"' width='"+d+"' height='"+b+"' scrolling='"+a+"' frameborder='0'></iframe></div>"));$("#close_button").bind("click",function(){hide_modal()})}$(function(){$(".tab").each(function(){var a=$(this).children(".submenu");if(a.length>0){if($.browser.msie){a.prepend("<iframe style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; filter:Alpha(Opacity='0');\"></iframe>")}$(this).hover(function(){a.show()},function(){a.hide()});a.click(function(){a.hide()})}})});function user_changed(a,b){if(a){$(".loggedin-only").show();$(".loggedout-only").hide();$("#user-email").text(a);if(b){$(".admin-only").show()}}else{$(".loggedin-only").hide();$(".loggedout-only").show();$(".admin-only").hide()}};
\ No newline at end of file
diff -r a4df07ccecdb70ae45982e596d2e360bdc9ab217 -r 23198e766859394108d48de1489be7052530d38b static/scripts/packed/trackster.js
--- a/static/scripts/packed/trackster.js
+++ b/static/scripts/packed/trackster.js
@@ -1,1 +1,1 @@
-var class_module=function(b,a){var c=function(){var f=arguments[0];for(var e=1;e<arguments.length;e++){var d=arguments[e];for(key in d){f[key]=d[key]}}return f};a.extend=c};var requestAnimationFrame=(function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(b,a){window.setTimeout(b,1000/60)}})();var BEFORE=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005,AFTER=1006;var compute_overlap=function(e,b){var g=e[0],f=e[1],d=b[0],c=b[1],a;if(g<d){if(f<d){a=BEFORE}else{if(f<=c){a=OVERLAP_START}else{a=CONTAINS}}}else{if(g>c){a=AFTER}else{if(f<=c){a=CONTAINED_BY}else{a=OVERLAP_END}}}return a};var is_overlap=function(c,b){var a=compute_overlap(c,b);return(a!==BEFORE&&a!==AFTER)};var get_random_color=function(a){if(!a){a="#ffffff"}if(typeof(a)==="string"){a=[a]}for(var j=0;j<a.length;j++){a[j]=parseInt(a[j].slice(1),16)}var m=function(t,s,i){return((t*299)+(s*587)+(i*114))/1000};var e=function(u,t,v,r,i,s){return(Math.max(u,r)-Math.min(u,r))+(Math.max(t,i)-Math.min(t,i))+(Math.max(v,s)-Math.min(v,s))};var g,n,f,k,p,h,q,c,d,b,o,l=false;do{g=Math.random()*16777215;n=g|16711680;f=g|65280;k=g|255;d=m(n,f,k);l=true;for(var j=0;j<a.length;j++){p=a[j];h=p|16711680;q=p|65280;c=p|255;b=m(h,q,c);o=e(n,f,k,h,q,c);if((Math.abs(d-b)<125)||(o<500)){l=false;break}}}while(!l);return"#"+(16777216+g).toString(16).substr(1,6)};var trackster_module=function(f,X){var p=f("class").extend,s=f("slotting"),M=f("painters");var ae=function(af,ag){this.document=af;this.default_font=ag!==undefined?ag:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};p(ae.prototype,{load_pattern:function(af,aj){var ag=this.patterns,ah=this.dummy_context,ai=new Image();ai.src=image_path+aj;ai.onload=function(){ag[af]=ah.createPattern(ai,"repeat")}},get_pattern:function(af){return this.patterns[af]},new_canvas:function(){var af=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(af)}af.manager=this;return af}});var n={};var l=function(af,ag){n[af.attr("id")]=ag};var m=function(af,ah,aj,ai){aj=".group";var ag={};n[af.attr("id")]=ai;af.bind("drag",{handle:"."+ah,relative:true},function(ar,at){var aq=$(this);var aw=$(this).parent(),an=aw.children(),ap=n[$(this).attr("id")],am,al,au,ak,ao;al=$(this).parents(aj);if(al.length!==0){au=al.position().top;ak=au+al.outerHeight();if(at.offsetY<au){$(this).insertBefore(al);var av=n[al.attr("id")];av.remove_drawable(ap);av.container.add_drawable_before(ap,av);return}else{if(at.offsetY>ak){$(this).insertAfter(al);var av=n[al.attr("id")];av.remove_drawable(ap);av.container.add_drawable(ap);return}}}al=null;for(ao=0;ao<an.length;ao++){am=$(an.get(ao));au=am.position().top;ak=au+am.outerHeight();if(am.is(aj)&&this!==am.get(0)&&at.offsetY>=au&&at.offsetY<=ak){if(at.offsetY-au<ak-at.offsetY){am.find(".content-div").prepend(this)}else{am.find(".content-div").append(this)}if(ap.container){ap.container.remove_drawable(ap)}n[am.attr("id")].add_drawable(ap);return}}for(ao=0;ao<an.length;ao++){if(at.offsetY<$(an.get(ao)).position().top){break}}if(ao===an.length){if(this!==an.get(ao-1)){aw.append(this);n[aw.attr("id")].move_drawable(ap,ao)}}else{if(this!==an.get(ao)){$(this).insertBefore(an.get(ao));n[aw.attr("id")].move_drawable(ap,(at.deltaY>0?ao-1:ao))}}}).bind("dragstart",function(){ag["border-top"]=af.css("border-top");ag["border-bottom"]=af.css("border-bottom");$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css(ag)})};X.moveable=m;var ad=16,H=9,E=20,T=H+2,z=100,J=12000,R=200,C=5,v=10,L=5000,w=100,o="There was an error in indexing this dataset. ",K="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",F="No data for this chrom/contig.",t="Currently indexing... please wait",x="Tool cannot be rerun: ",a="Loading data...",Y="Ready for display",d=10,u=5,B=5;function Z(ag,af){if(!af){af=0}var ah=Math.pow(10,af);return Math.round(ag*ah)/ah}var c=function(af){this.num_elements=af;this.clear()};p(c.prototype,{get:function(ag){var af=this.key_ary.indexOf(ag);if(af!==-1){if(this.obj_cache[ag].stale){this.key_ary.splice(af,1);delete this.obj_cache[ag]}else{this.move_key_to_end(ag,af)}}return this.obj_cache[ag]},set:function(ag,ah){if(!this.obj_cache[ag]){if(this.key_ary.length>=this.num_elements){var af=this.key_ary.shift();delete this.obj_cache[af]}this.key_ary.push(ag)}this.obj_cache[ag]=ah;return ah},move_key_to_end:function(ag,af){this.key_ary.splice(af,1);this.key_ary.push(ag)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var S=function(ag,af,ah){c.call(this,ag);this.track=af;this.subset=(ah!==undefined?ah:true)};p(S.prototype,c.prototype,{load_data:function(ao,aj,am,ag,al){var an=this.track.view.chrom,ai={chrom:an,low:ao,high:aj,mode:am,resolution:ag,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(ai,al);if(this.track.filters_manager){var ap=[];var af=this.track.filters_manager.filters;for(var ak=0;ak<af.length;ak++){ap[ap.length]=af[ak].name}ai.filter_cols=JSON.stringify(ap)}var ah=this;return $.getJSON(this.track.data_url,ai,function(aq){ah.set_data(ao,aj,am,aq)})},get_data:function(af,aj,ak,ag,ai){var ah=this.get_data_from_cache(af,aj,ak);if(ah){return ah}ah=this.load_data(af,aj,ak,ag,ai);this.set_data(af,aj,ak,ah);return ah},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(an,ai,am,ah,al,aj){var ao=this.get_data_from_cache(an,ai,am);if(!ao){console.log("ERROR: no current data for: ",this.track,an,ai,am,ah,al);return}ao.stale=true;var ag=an;if(aj===this.DEEP_DATA_REQ){$.extend(al,{start_val:ao.data.length+1})}else{if(aj===this.BROAD_DATA_REQ){ag=(ao.max_high?ao.max_high:ao.data[ao.data.length-1][2])+1}}var af=this,ak=this.load_data(ag,ai,am,ah,al);new_data_available=$.Deferred();this.set_data(an,ai,am,new_data_available);$.when(ak).then(function(ap){if(ap.data){ap.data=ao.data.concat(ap.data);if(ap.max_low){ap.max_low=ao.max_low}if(ap.message){ap.message=ap.message.replace(/[0-9]+/,ap.data.length)}}af.set_data(an,ai,am,ap);new_data_available.resolve(ap)});return new_data_available},get_data_from_cache:function(af,ag,ah){return this.get(this.gen_key(af,ag,ah))},set_data:function(ag,ah,ai,af){return this.set(this.gen_key(ag,ah,ai),af)},gen_key:function(af,ah,ai){var ag=af+"_"+ah+"_"+ai;return ag},split_key:function(af){return af.split("_")}});var I=function(ag,af,ah){S.call(this,ag,af,ah)};p(I.prototype,S.prototype,c.prototype,{load_data:function(af,ai,aj,ag,ah){if(ag>1){return{data:null}}return S.prototype.load_data.call(this,af,ai,aj,ag,ah)}});var q=function(ai,ag,af,ah,aj){this.name=ai;this.view=ag;this.container=af;this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ai}],saved_values:ah,onchange:function(){this.track.set_name(this.track.config.values.name)}});this.prefs=this.config.values;this.drag_handle_class=aj;this.is_overview=false};p(q.prototype,{init:function(){},request_draw:function(){},_draw:function(){},to_json:function(){},update_track_icons:function(){},set_name:function(af){this.old_name=this.name;this.name=af;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)},remove:function(){this.container.remove_drawable(this);this.container_div.fadeOut("slow",function(){$(this).remove();view.update_intro_div();view.has_changes=true})}});var y=function(aj,ai,ag,af,ah,ak){q.call(this,ai,ag,af,ah,ak);this.obj_type=aj;this.drawables=[]};p(y.prototype,q.prototype,{init:function(){for(var af=0;af<this.drawables.length;af++){this.drawables[af].init()}},_draw:function(){for(var af=0;af<this.drawables.length;af++){this.drawables[af]._draw()}},to_json:function(){var ag=[];for(var af=0;af<this.drawables.length;af++){ag.push(this.drawables[af].to_json())}return{name:this.name,prefs:this.prefs,obj_type:this.obj_type,drawables:ag}},add_drawable:function(af){this.drawables.push(af);af.container=this},add_drawable_before:function(ah,af){var ag=this.drawables.indexOf(af);if(ag!=-1){this.drawables.splice(ag,0,ah);return true}return false},remove_drawable:function(ag){var af=this.drawables.indexOf(ag);if(af!=-1){this.drawables.splice(af,1);ag.container=null;return true}return false},move_drawable:function(ag,ah){var af=this.drawables.indexOf(ag);if(af!=-1){this.drawables.splice(af,1);this.drawables.splice(ah,0,ag);return true}return false}});var Q=function(ai,ag,af,ah){y.call(this,"DrawableGroup",ai,ag,af,ah,"group-handle");if(!Q.id_counter){Q.id_counter=0}var aj=Q.id_counter++;this.container_div=$("<div/>").addClass("group").attr("id","group_"+aj).appendTo(this.container.content_div);this.header_div=$("<div/>").addClass("track-header").appendTo(this.container_div);this.header_div.append($("<div/>").addClass(this.drag_handle_class));this.name_div=$("<div/>").addClass("group-name menubutton popup").text(this.name).appendTo(this.header_div);this.content_div=$("<div/>").addClass("content-div").attr("id","group_"+aj+"_content_div").appendTo(this.container_div);l(this.container_div,this);l(this.content_div,this);m(this.container_div,this.drag_handle_class,".group",this);this.update_track_icons()};p(Q.prototype,q.prototype,y.prototype,{update_track_icons:function(){var ag=this;var af={};af["Edit configuration"]=function(){var aj=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},ah=function(){ag.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ai=function(ak){if((ak.keyCode||ak.which)===27){aj()}else{if((ak.keyCode||ak.which)===13){ah()}}};$(window).bind("keypress.check_enter_esc",ai);show_modal("Configure Group",ag.config.build_form(),{Cancel:aj,OK:ah})};af.Remove=function(){ag.remove()};make_popupmenu(ag.name_div,af)}});var ac=function(af,ai,ah,ag){y.call(this,"View");this.container=af;this.chrom=null;this.vis_id=ah;this.dbkey=ag;this.title=ai;this.label_tracks=[];this.tracks_to_be_redrawn=[];this.max_low=0;this.max_high=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.load_chroms_deferred=null;this.init();this.canvas_manager=new ae(af.get(0).ownerDocument);this.reset()};p(ac.prototype,y.prototype,{init:function(){var ah=this.container,af=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ah);this.browser_content_div=$("<div/>").addClass("content").css("position","relative").appendTo(ah);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ah);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").attr("id","viewport-container").appendTo(this.browser_content_div);this.content_div=this.viewport_container;l(this.viewport_container,af);this.intro_div=$("<div/>").addClass("intro");var ai=$("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function(){add_tracks()});this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a/>").attr("href","javascript:void(0);").attr("title","Close overview").addClass("icon-button overview-close tooltip").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var ag=function(aj){if(aj.type==="focusout"||(aj.keyCode||aj.which)===13||(aj.keyCode||aj.which)===27){if((aj.keyCode||aj.which)!==27){af.go_to($(this).val())}$(this).hide();$(this).val("");af.location_span.show();af.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ag).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.click(function(){af.location_span.hide();af.chrom_select.hide();af.nav_input.val(af.chrom+":"+af.low+"-"+af.high);af.nav_input.css("display","inline-block");af.nav_input.select();af.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a id='zoom-out' />").click(function(){af.zoom_out();af.request_redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){af.zoom_in();af.request_redraw()}).appendTo(this.nav_controls);this.load_chroms_deferred=this.load_chroms({low:0});this.chrom_select.bind("change",function(){af.change_chrom(af.chrom_select.val())});this.browser_content_div.click(function(aj){$(this).find("input").trigger("blur")});this.browser_content_div.bind("dblclick",function(aj){af.zoom_in(aj.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(aj,ak){this.current_x=ak.offsetX}).bind("drag",function(aj,al){var am=al.offsetX-this.current_x;this.current_x=al.offsetX;var ak=Math.round(am/af.viewport_container.width()*(af.max_high-af.max_low));af.move_delta(-ak)});this.overview_close.click(function(){af.reset_overview()});this.viewport_container.bind("draginit",function(aj,ak){if(aj.clientX>af.viewport_container.width()-16){return false}}).bind("dragstart",function(aj,ak){ak.original_low=af.low;ak.current_height=aj.clientY;ak.current_x=ak.offsetX}).bind("drag",function(al,an){var aj=$(this);var ao=an.offsetX-an.current_x;var ak=aj.scrollTop()-(al.clientY-an.current_height);aj.scrollTop(ak);an.current_height=al.clientY;an.current_x=an.offsetX;var am=Math.round(ao/af.viewport_container.width()*(af.high-af.low));af.move_delta(am)}).bind("mousewheel",function(al,an,ak,aj){if(ak){var am=Math.round(-ak/af.viewport_container.width()*(af.high-af.low));af.move_delta(am)}});this.top_labeltrack.bind("dragstart",function(aj,ak){return $("<div />").css({height:af.browser_content_div.height()+af.top_labeltrack.height()+af.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(an,ao){$(ao.proxy).css({left:Math.min(an.pageX,ao.startX),width:Math.abs(an.pageX-ao.startX)});var ak=Math.min(an.pageX,ao.startX)-af.container.offset().left,aj=Math.max(an.pageX,ao.startX)-af.container.offset().left,am=(af.high-af.low),al=af.viewport_container.width();af.update_location(Math.round(ak/al*am)+af.low,Math.round(aj/al*am)+af.low)}).bind("dragend",function(ao,ap){var ak=Math.min(ao.pageX,ap.startX),aj=Math.max(ao.pageX,ap.startX),am=(af.high-af.low),al=af.viewport_container.width(),an=af.low;af.low=Math.round(ak/al*am)+an;af.high=Math.round(aj/al*am)+an;$(ap.proxy).remove();af.request_redraw()});this.add_label_track(new ab(this,{content_div:this.top_labeltrack}));this.add_label_track(new ab(this,{content_div:this.nav_labeltrack}));$(window).bind("resize",function(){af.resize_window()});$(document).bind("redraw",function(){af.redraw()});this.reset();$(window).trigger("resize");this.update_intro_div()},update_intro_div:function(){if(this.num_tracks===0){this.intro_div.appendTo(this.viewport_container)}else{this.intro_div.remove()}},update_location:function(af,ag){this.location_span.text(commatize(af)+" - "+commatize(ag));this.nav_input.val(this.chrom+":"+commatize(af)+"-"+commatize(ag))},load_chroms:function(ah){ah.num=w;$.extend(ah,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var af=this,ag=$.Deferred();$.ajax({url:chrom_url,data:ah,dataType:"json",success:function(aj){if(aj.chrom_info.length===0){alert("Invalid chromosome: "+ah.chrom);return}if(aj.reference){af.add_label_track(new A(af))}af.chrom_data=aj.chrom_info;var am='<option value="">Select Chrom/Contig</option>';for(var al=0,ai=af.chrom_data.length;al<ai;al++){var ak=af.chrom_data[al].chrom;am+='<option value="'+ak+'">'+ak+"</option>"}if(aj.prev_chroms){am+='<option value="previous">Previous '+w+"</option>"}if(aj.next_chroms){am+='<option value="next">Next '+w+"</option>"}af.chrom_select.html(am);af.chrom_start_index=aj.start_index;ag.resolve(aj)},error:function(){alert("Could not load chroms for this dbkey:",af.dbkey)}});return ag},change_chrom:function(ak,ag,am){if(!ak||ak==="None"){return}var ah=this;if(ak==="previous"){ah.load_chroms({low:this.chrom_start_index-w});return}if(ak==="next"){ah.load_chroms({low:this.chrom_start_index+w});return}var al=$.grep(ah.chrom_data,function(an,ao){return an.chrom===ak})[0];if(al===undefined){ah.load_chroms({chrom:ak},function(){ah.change_chrom(ak,ag,am)});return}else{if(ak!==ah.chrom){ah.chrom=ak;ah.chrom_select.val(ah.chrom);ah.max_high=al.len-1;ah.reset();ah.request_redraw(true);for(var aj=0,af=ah.drawables.length;aj<af;aj++){var ai=ah.drawables[aj];if(ai.init){ai.init()}}}if(ag!==undefined&&am!==undefined){ah.low=Math.max(ag,0);ah.high=Math.min(am,ah.max_high)}ah.reset_overview();ah.request_redraw()}},go_to:function(aj){aj=aj.replace(/ |,/g,"");var an=this,af,ai,ag=aj.split(":"),al=ag[0],am=ag[1];if(am!==undefined){try{var ak=am.split("-");af=parseInt(ak[0],10);ai=parseInt(ak[1],10)}catch(ah){return false}}an.change_chrom(al,af,ai)},move_fraction:function(ah){var af=this;var ag=af.high-af.low;this.move_delta(ah*ag)},move_delta:function(ah){var af=this;var ag=af.high-af.low;if(af.low-ah<af.max_low){af.low=af.max_low;af.high=af.max_low+ag}else{if(af.high-ah>af.max_high){af.high=af.max_high;af.low=af.max_high-ag}else{af.high-=ah;af.low-=ah}}af.request_redraw()},add_drawable:function(af){y.prototype.add_drawable.call(this,af);af.init();this.has_changes=true;this.update_intro_div()},add_label_track:function(af){af.view=this;af.init();this.label_tracks.push(af)},remove_drawable:function(ah,ag){y.prototype.remove_drawable.call(this,ah);if(ag){var af=this;ah.container_div.fadeOut("slow",function(){$(this).remove();af.update_intro_div()});this.has_changes=true}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},request_redraw:function(an,af,am,ag){var al=this,aj=(ag?[ag]:al.drawables),ah;var ag;for(var ak=0;ak<aj.length;ak++){ag=aj[ak];ah=-1;for(var ai=0;ai<al.tracks_to_be_redrawn.length;ai++){if(al.tracks_to_be_redrawn[ai][0]===ag){ah=ai;break}}if(ah<0){al.tracks_to_be_redrawn.push([ag,af,am])}else{al.tracks_to_be_redrawn[ak][1]=af;al.tracks_to_be_redrawn[ak][2]=am}}requestAnimationFrame(function(){al._redraw(an)})},_redraw:function(ap){var am=this.low,ai=this.high;if(am<this.max_low){am=this.max_low}if(ai>this.max_high){ai=this.max_high}var ao=this.high-this.low;if(this.high!==0&&ao<this.min_separation){ai=am+this.min_separation}this.low=Math.floor(am);this.high=Math.ceil(ai);this.resolution=Math.pow(C,Math.ceil(Math.log((this.high-this.low)/R)/Math.log(C)));this.zoom_res=Math.pow(v,Math.max(0,Math.ceil(Math.log(this.resolution,v)/Math.log(v))));var af=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var al=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var aq=13;this.overview_box.css({left:af,width:Math.max(aq,al)}).show();if(al<aq){this.overview_box.css("left",af-(aq-al)/2)}if(this.overview_highlight){this.overview_highlight.css({left:af,width:al})}this.update_location(this.low,this.high);if(!ap){var ah,ag,an;for(var aj=0,ak=this.tracks_to_be_redrawn.length;aj<ak;aj++){ah=this.tracks_to_be_redrawn[aj][0];ag=this.tracks_to_be_redrawn[aj][1];an=this.tracks_to_be_redrawn[aj][2];if(ah){ah._draw(ag,an)}}this.tracks_to_be_redrawn=[];for(aj=0,ak=this.label_tracks.length;aj<ak;aj++){this.label_tracks[aj]._draw()}}},zoom_in:function(ag,ah){if(this.max_high===0||this.high-this.low<this.min_separation){return}var ai=this.high-this.low,aj=ai/2+this.low,af=(ai/this.zoom_factor)/2;if(ag){aj=ag/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(aj-af);this.high=Math.round(aj+af);this.request_redraw()},zoom_out:function(){if(this.max_high===0){return}var ag=this.high-this.low,ah=ag/2+this.low,af=(ag*this.zoom_factor)/2;this.low=Math.round(ah-af);this.high=Math.round(ah+af);this.request_redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.request_redraw()},set_overview:function(ah){if(this.overview_drawable){if(this.overview_drawable.dataset_id===ah.dataset_id){return}this.overview_viewport.find(".track").remove()}var ag=ah.copy({content_div:this.overview_viewport}),af=this;ag.header_div.hide();ag.is_overview=true;af.overview_drawable=ag;this.overview_drawable.postdraw_actions=function(){af.overview_highlight.show().height(af.overview_drawable.content_div.height());af.overview_viewport.height(af.overview_drawable.content_div.height()+af.overview_box.outerHeight());af.overview_close.show();af.resize_window()};this.overview_drawable.init();af.has_changes=true},reset_overview:function(){$(".tipsy").remove();this.overview_viewport.find(".track-tile").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide();view.resize_window();view.overview_drawable=null}});var r=function(ah,al){this.track=ah;this.name=al.name;this.params=[];var at=al.params;for(var ai=0;ai<at.length;ai++){var an=at[ai],ag=an.name,ar=an.label,aj=unescape(an.html),au=an.value,ap=an.type;if(ap==="number"){this.params[this.params.length]=new g(ag,ar,aj,au,an.min,an.max)}else{if(ap=="select"){this.params[this.params.length]=new O(ag,ar,aj,au)}else{console.log("WARNING: unrecognized tool parameter type:",ag,ap)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(aw){aw.stopPropagation()}).click(function(aw){aw.stopPropagation()}).bind("dblclick",function(aw){aw.stopPropagation()});var aq=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var ao=this.params;var am=this;$.each(this.params,function(ax,aA){var az=$("<div>").addClass("param-row").appendTo(am.parent_div);var aw=$("<div>").addClass("param-label").text(aA.label).appendTo(az);var ay=$("<div/>").addClass("slider").html(aA.html).appendTo(az);ay.find(":input").val(aA.value);$("<div style='clear: both;'/>").appendTo(az)});this.parent_div.find("input").click(function(){$(this).select()});var av=$("<div>").addClass("param-row").appendTo(this.parent_div);var ak=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(av);var af=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(av);var am=this;af.click(function(){am.run_on_region()});ak.click(function(){am.run_on_dataset()})};p(r.prototype,{get_param_values_dict:function(){var af={};this.parent_div.find(":input").each(function(){var ag=$(this).attr("name"),ah=$(this).val();af[ag]=JSON.stringify(ah)});return af},get_param_values:function(){var ag=[];var af={};this.parent_div.find(":input").each(function(){var ah=$(this).attr("name"),ai=$(this).val();if(ah){ag[ag.length]=ai}});return ag},run_on_dataset:function(){var af=this;af.run({dataset_id:this.track.original_dataset_id,tool_id:af.name},null,function(ag){show_modal(af.name+" is Running",af.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var ag={dataset_id:this.track.original_dataset_id,chrom:this.track.view.chrom,low:this.track.view.low,high:this.track.view.high,tool_id:this.name},aj=this.track,ah=ag.tool_id+aj.tool_region_and_parameters_str(ag.chrom,ag.low,ag.high),af;if(aj.container===view){var ai=new Q(this.name,this.track.view,this.track.container);aj.container.add_drawable(ai);aj.container.remove_drawable(aj);ai.add_drawable(aj);aj.container_div.appendTo(ai.content_div);af=ai}else{af=aj.container}var ak=new aj.constructor(ah,view,af,"hda");ak.init_for_tool_data();ak.change_mode(aj.mode);af.add_drawable(ak);ak.content_div.text("Starting job.");this.run(ag,ak,function(al){ak.dataset_id=al.dataset_id;ak.content_div.text("Running job.");ak.init()})},run:function(ag,ah,ai){$.extend(ag,this.get_param_values_dict());var af=function(){$.getJSON(rerun_tool_url,ag,function(aj){if(aj==="no converter"){ah.container_div.addClass("error");ah.content_div.text(K)}else{if(aj.error){ah.container_div.addClass("error");ah.content_div.text(x+aj.message)}else{if(aj==="pending"){ah.container_div.addClass("pending");ah.content_div.text("Converting input data so that it can be used quickly with tool.");setTimeout(af,2000)}else{ai(aj)}}}})};af()}});var O=function(ag,af,ah,ai){this.name=ag;this.label=af;this.html=ah;this.value=ai};var g=function(ah,ag,aj,ak,ai,af){O.call(this,ah,ag,aj,ak);this.min=ai;this.max=af};var h=function(ag,af,ah,ai){this.name=ag;this.index=af;this.tool_id=ah;this.tool_exp_name=ai};var V=function(ag,af,ah,ai){h.call(this,ag,af,ah,ai);this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.container=null;this.slider=null;this.slider_label=null};p(V.prototype,{applies_to:function(af){if(af.length>this.index){return true}return false},keep:function(af){if(!this.applies_to(af)){return true}var ag=af[this.index];return(isNaN(ag)||(ag>=this.low&&ag<=this.high))},update_attrs:function(ag){var af=false;if(!this.applies_to(ag)){return af}if(ag[this.index]<this.min){this.min=Math.floor(ag[this.index]);af=true}if(ag[this.index]>this.max){this.max=Math.ceil(ag[this.index]);af=true}return af},update_ui_elt:function(){if(this.min!=this.max){this.container.show()}else{this.container.hide()}var ah=function(ak,ai){var aj=ai-ak;return(aj<=2?0.01:1)};var ag=this.slider.slider("option","min"),af=this.slider.slider("option","max");if(this.min<ag||this.max>af){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",ah(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var aa=function(aq,ay){this.track=aq;this.filters=[];for(var at=0;at<ay.length;at++){var au=ay[at],az=au.name,af=au.type,ah=au.index,ax=au.tool_id,aw=au.tool_exp_name;if(af==="int"||af==="float"){this.filters[at]=new V(az,ah,ax,aw)}else{console.log("ERROR: unsupported filter: ",az,af)}}var ai=function(aA,aB,aC){aA.click(function(){var aD=aB.text();max=parseFloat(aC.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(aC.slider("option","values")){input_size=2*input_size+1;multi_value=true}aB.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",aD).appendTo(aB).focus().select().click(function(aE){aE.stopPropagation()}).blur(function(){$(this).remove();aB.text(aD)}).keyup(function(aI){if(aI.keyCode===27){$(this).trigger("blur")}else{if(aI.keyCode===13){var aG=aC.slider("option","min"),aE=aC.slider("option","max"),aH=function(aJ){return(isNaN(aJ)||aJ>aE||aJ<aG)},aF=$(this).val();if(!multi_value){aF=parseFloat(aF);if(aH(aF)){alert("Parameter value must be in the range ["+aG+"-"+aE+"]");return $(this)}}else{aF=aF.split("-");aF=[parseFloat(aF[0]),parseFloat(aF[1])];if(aH(aF[0])||aH(aF[1])){alert("Parameter value must be in the range ["+aG+"-"+aE+"]");return $(this)}}aC.slider((multi_value?"values":"value"),aF)}}})})};this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(aA){aA.stopPropagation()}).click(function(aA){aA.stopPropagation()}).bind("dblclick",function(aA){aA.stopPropagation()}).bind("keydown",function(aA){aA.stopPropagation()});var av=$("<div/>").addClass("sliders").appendTo(this.parent_div);var an=this;$.each(this.filters,function(aD,aF){aF.container=$("<div/>").addClass("filter-row slider-row").appendTo(av);var aE=$("<div/>").addClass("elt-label").appendTo(aF.container);var aC=$("<span/>").addClass("slider-name").text(aF.name+" ").appendTo(aE);var aB=$("<span/>");var aH=$("<span/>").addClass("slider-value").appendTo(aE).append("[").append(aB).append("]");var aA=$("<div/>").addClass("slider").appendTo(aF.container);aF.control_element=$("<div/>").attr("id",aF.name+"-filter-control").appendTo(aA);var aG=[0,0];aF.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(aJ,aK){var aI=aK.values;aB.text(aI[0]+"-"+aI[1]);aF.low=aI[0];aF.high=aI[1];an.track.request_draw(true,true)},change:function(aI,aJ){aF.control_element.slider("option","slide").call(aF.control_element,aI,aJ)}});aF.slider=aF.control_element;aF.slider_label=aB;ai(aH,aB,aF.control_element);$("<div style='clear: both;'/>").appendTo(aF.container)});if(this.filters.length!==0){var ak=$("<div/>").addClass("param-row").appendTo(av);var am=$("<input type='submit'/>").attr("value","Run on complete dataset").appendTo(ak);var ag=this;am.click(function(){ag.run_on_dataset()})}var ap=$("<div/>").addClass("display-controls").appendTo(this.parent_div),ar,al,ao,aj={Transparency:function(aA){an.alpha_filter=aA},Height:function(aA){an.height_filter=aA}};$.each(aj,function(aC,aB){ar=$("<div/>").addClass("filter-row").appendTo(ap),al=$("<span/>").addClass("elt-label").text(aC+":").appendTo(ar),ao=$("<select/>").attr("name",aC+"_dropdown").css("float","right").appendTo(ar);$("<option/>").attr("value",-1).text("== None ==").appendTo(ao);for(var aA=0;aA<an.filters.length;aA++){$("<option/>").attr("value",aA).text(an.filters[aA].name).appendTo(ao)}ao.change(function(){$(this).children("option:selected").each(function(){var aD=parseInt($(this).val());aj[aC]((aD>=0?an.filters[aD]:null));an.track.request_draw(true,true)})});$("<div style='clear: both;'/>").appendTo(ar)});$("<div style='clear: both;'/>").appendTo(this.parent_div)};p(aa.prototype,{reset_filters:function(){for(var af=0;af<this.filters.length;af++){filter=this.filters[af];filter.slider.slider("option","values",[filter.min,filter.max])}this.alpha_filter=null;this.height_filter=null},run_on_dataset:function(){var an=function(ar,ap,aq){if(!(ap in ar)){ar[ap]=aq}return ar[ap]};var ah={},af,ag,ai;for(var aj=0;aj<this.filters.length;aj++){af=this.filters[aj];if(af.tool_id){if(af.min!=af.low){ag=an(ah,af.tool_id,[]);ag[ag.length]=af.tool_exp_name+" >= "+af.low}if(af.max!=af.high){ag=an(ah,af.tool_id,[]);ag[ag.length]=af.tool_exp_name+" <= "+af.high}}}var al=[];for(var ao in ah){al[al.length]=[ao,ah[ao]]}var am=al.length;(function ak(aw,at){var aq=at[0],ar=aq[0],av=aq[1],au="("+av.join(") and (")+")",ap={cond:au,input:aw,target_dataset_id:aw,tool_id:ar},at=at.slice(1);$.getJSON(run_tool_url,ap,function(ax){if(ax.error){show_modal("Filter Dataset","Error running tool "+ar,{Close:hide_modal})}else{if(at.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{ak(ax.dataset_id,at)}}})})(this.track.dataset_id,al)}});var D=function(af,ag){M.Scaler.call(this,ag);this.filter=af};D.prototype.gen_val=function(af){if(this.filter.high===Number.MAX_VALUE||this.filter.low===-Number.MAX_VALUE||this.filter.low===this.filter.high){return this.default_val}return((parseFloat(af[this.filter.index])-this.filter.low)/(this.filter.high-this.filter.low))};var G=function(af){this.track=af.track;this.params=af.params;this.values={};this.restore_values((af.saved_values?af.saved_values:{}));this.onchange=af.onchange};p(G.prototype,{restore_values:function(af){var ag=this;$.each(this.params,function(ah,ai){if(af[ai.key]!==undefined){ag.values[ai.key]=af[ai.key]}else{ag.values[ai.key]=ai.default_value}})},build_form:function(){var ag=this;var af=$("<div />");$.each(this.params,function(ak,ai){if(!ai.hidden){var ah="param_"+ak;var am=ag.values[ai.key];var ap=$("<div class='form-row' />").appendTo(af);ap.append($("<label />").attr("for",ah).text(ai.label+":"));if(ai.type==="bool"){ap.append($('<input type="checkbox" />').attr("id",ah).attr("name",ah).attr("checked",am))}else{if(ai.type==="text"){ap.append($('<input type="text"/>').attr("id",ah).val(am).click(function(){$(this).select()}))}else{if(ai.type==="color"){var al=$("<input />").attr("id",ah).attr("name",ah).val(am);var an=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var aj=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(an);var ao=$("<div/>").appendTo(aj).farbtastic({width:100,height:100,callback:al,color:am});$("<div />").append(al).append(an).appendTo(ap).bind("click",function(aq){an.css({left:$(this).position().left+($(al).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){an.hide();$(document).unbind("click.color-picker")});aq.stopPropagation()})}else{ap.append($("<input />").attr("id",ah).attr("name",ah).val(am))}}}}});return af},update_from_form:function(af){var ah=this;var ag=false;$.each(this.params,function(ai,ak){if(!ak.hidden){var al="param_"+ai;var aj=af.find("#"+al).val();if(ak.type==="float"){aj=parseFloat(aj)}else{if(ak.type==="int"){aj=parseInt(aj)}else{if(ak.type==="bool"){aj=af.find("#"+al).is(":checked")}}}if(aj!==ah.values[ak.key]){ah.values[ak.key]=aj;ag=true}}});if(ag){this.onchange()}}});var b=function(af,ai,ah,ag,aj){this.track=af;this.index=ai;this.low=ai*R*ah;this.high=(ai+1)*R*ah;this.resolution=ah;this.canvas=$("<div class='track-tile'/>").append(ag);this.data=aj;this.stale=false};b.prototype.predisplay_actions=function(){};var k=function(af,ai,ah,ag,aj,ak){b.call(this,af,ai,ah,ag,aj);this.max_val=ak};p(k.prototype,b.prototype);var P=function(af,aj,ai,ah,al,am,ak,ag){b.call(this,af,aj,ai,ah,al);this.mode=am;this.message=ak;this.feature_mapper=ag};p(P.prototype,b.prototype);P.prototype.predisplay_actions=function(){var ag=this,af={};if(ag.mode!=="Pack"){return}$(this.canvas).mousemove(function(ar){var am=$(this).offset(),aq=ar.pageX-am.left,ap=ar.pageY-am.top,aw=ag.feature_mapper.get_feature_data(aq,ap),an=(aw?aw[0]:null);$(this).siblings(".feature-popup").each(function(){if(!an||$(this).attr("id")!==an.toString()){$(this).remove()}});if(aw){var ai=af[an];if(!ai){var an=aw[0],at={name:aw[3],start:aw[1],end:aw[2],strand:aw[4]},al=ag.track.filters_manager.filters,ak;for(var ao=0;ao<al.length;ao++){ak=al[ao];at[ak.name]=aw[ak.index]}var ai=$("<div/>").attr("id",an).addClass("feature-popup"),av,au,ax=$("<table/>").appendTo(ai),ay;for(av in at){au=at[av];ay=$("<tr/>").appendTo(ax);$("<th/>").appendTo(ay).text(av);$("<td/>").attr("align","left").appendTo(ay).text(typeof(au)=="number"?Z(au,2):au)}af[an]=ai}ai.appendTo($(ag.canvas).parent());var aj=aq+parseInt(ag.canvas.css("left"))+7,ah=ap+parseInt(ag.canvas.css("top"))+7;ai.css("left",aj+"px").css("top",ah+"px")}else{if(!ar.isPropagationStopped()){ar.stopPropagation();$(this).siblings().each(function(){$(this).trigger(ar)})}}}).mouseleave(function(){$(this).siblings(".feature-popup").remove()})};var i=function(ai,aq,aj,am,ar,ah,ag){q.call(this,ai,aq,aj,{},"draghandle");this.data_url=(ah?ah:default_data_url);this.data_url_extra_params={};this.data_query_wait=(ag?ag:L);this.dataset_check_url=converted_datasets_state_url;if(!i.id_counter){i.id_counter=0}this.id=i.id_counter++;this.container_div=$("<div />").addClass("track").attr("id","track_"+this.id).css("position","relative");if(am){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div/>").addClass(this.drag_handle_class).appendTo(this.header_div)}this.name_div=$("<div/>").addClass("track-name").appendTo(this.header_div).text(this.name).attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase());this.icons_div=$("<div/>").css("float","left").appendTo(this.header_div).hide();this.settings_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Edit settings").addClass("icon-button settings-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);this.overview_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Set as overview").addClass("icon-button overview-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);this.filters_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Filters").addClass("icon-button filters-icon").tipsy({gravity:"s"}).appendTo(this.icons_div).hide();this.tools_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Tools").addClass("icon-button tools-icon").tipsy({gravity:"s"}).appendTo(this.icons_div).hide();this.remove_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Remove").addClass("icon-button remove-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);var ak=this;this.header_div.dblclick(function(at){at.stopPropagation()});this.settings_icon.click(function(){var av=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},at=function(){ak.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},au=function(aw){if((aw.keyCode||aw.which)===27){av()}else{if((aw.keyCode||aw.which)===13){at()}}};$(window).bind("keypress.check_enter_esc",au);show_modal("Configure Track",ak.config.build_form(),{Cancel:av,OK:at})});this.overview_icon.click(function(){ak.view.set_overview(ak)});this.filters_icon.click(function(){ak.filters_div.toggle();ak.filters_manager.reset_filters()});this.tools_icon.click(function(){ak.dynamic_tool_div.toggle();if(ak.dynamic_tool_div.is(":visible")){ak.set_name(ak.name+ak.tool_region_and_parameters_str())}else{ak.revert_name()}$(".tipsy").remove()});this.remove_icon.click(function(){$(".tipsy").remove();ak.remove()});if(ak.display_modes!==undefined){if(ak.mode_div===undefined){ak.mode_div=$("<div class='right-float menubutton popup' />").appendTo(ak.header_div);var al=(ak.config&&ak.config.values.mode?ak.config.values.mode:ak.display_modes[0]);ak.mode=al;ak.mode_div.text(al);var af={};for(var an=0,ap=ak.display_modes.length;an<ap;an++){var ao=ak.display_modes[an];af[ao]=function(at){return function(){ak.change_mode(at)}}(ao)}make_popupmenu(ak.mode_div,af)}else{ak.mode_div.hide()}this.header_div.append($("<div/>").css("clear","both"));this.container_div.hover(function(){ak.icons_div.show()},function(){ak.icons_div.hide()})}}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.container.content_div.append(this.container_div)};p(i.prototype,q.prototype,{get_type:function(){if(this instanceof ab){return"LabelTrack"}else{if(this instanceof A){return"ReferenceTrack"}else{if(this instanceof j){return"LineTrack"}else{if(this instanceof W){return"ReadTrack"}else{if(this instanceof U){return"VcfTrack"}else{if(this instanceof e){return"FeatureTrack"}}}}}}return""},init:function(){var af=this;af.enabled=false;af.tile_cache.clear();af.data_manager.clear();af.initial_canvas=undefined;af.content_div.css("height","auto");af.container_div.removeClass("nodata error pending");if(!af.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:af.hda_ldda,dataset_id:af.dataset_id,chrom:af.view.chrom},function(ag){if(!ag||ag==="error"||ag.kind==="error"){af.container_div.addClass("error");af.content_div.text(o);if(ag.message){var ah=$(" <a href='javascript:void(0);'></a>").text("View error").click(function(){show_modal("Trackster Error","<pre>"+ag.message+"</pre>",{Close:hide_modal})});af.content_div.append(ah)}}else{if(ag==="no converter"){af.container_div.addClass("error");af.content_div.text(K)}else{if(ag==="no data"||(ag.data!==undefined&&(ag.data===null||ag.data.length===0))){af.container_div.addClass("nodata");af.content_div.text(F)}else{if(ag==="pending"){af.container_div.addClass("pending");af.content_div.text(t);setTimeout(function(){af.init()},af.data_query_wait)}else{if(ag.status==="data"){if(ag.valid_chroms){af.valid_chroms=ag.valid_chroms;af.update_track_icons()}af.content_div.text(Y);if(af.view.chrom){af.content_div.text("");af.content_div.css("height",af.height_px+"px");af.enabled=true;$.when(af.predraw_init()).done(function(){af.container_div.removeClass("nodata error pending");af.request_draw()})}}}}}}});this.update_track_icons()},predraw_init:function(){}});var N=function(aj,ah,ag,am,ai,al,ak){i.call(this,aj,ah,ag,am,ai);var af=this,ah=af.view;m(af.container_div,af.drag_handle_class,".group",af);this.filters_manager=new aa(this,(al!==undefined?al:{}));this.filters_available=false;this.filters_visible=false;this.tool=(ak!==undefined&&obj_length(ak)>0?new r(this,ak):undefined);if(this.header_div){if(this.filters_manager){this.filters_div=this.filters_manager.parent_div;this.header_div.after(this.filters_div)}if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}}};p(N.prototype,q.prototype,i.prototype,{copy:function(af){return new this.constructor(this.name,this.view,af,this.hda_ldda,this.dataset_id,this.prefs,this.filters,this.tool)},to_json:function(){return{track_type:this.get_type(),name:this.name,hda_ldda:this.hda_ldda,dataset_id:this.dataset_id,prefs:this.prefs,mode:this.mode,}},change_mode:function(ag){var af=this;af.mode_div.text(ag);af.mode=ag;af.config.values.mode=ag;af.tile_cache.clear();af.request_draw();return af},update_track_icons:function(){var af=this;if(af.filters_available>0){af.filters_icon.show()}else{af.filters_icon.hide()}if(af.tool){af.tools_icon.show()}else{af.tools_icon.hide()}},_gen_tile_cache_key:function(ag,ah,af){return ag+"_"+ah+"_"+af},request_draw:function(ag,af){this.view.request_redraw(false,ag,af,this)},_draw:function(ah,ap){if(!this.enabled){return}if(!(this instanceof A)&&(!this.dataset_id)){return}var ao=this.view.low,al=this.view.high,am=al-ao,ai=this.view.container.width(),at=ai/am,ak=this.view.resolution,ar=$("<div style='position: relative;'></div>");if(this.is_overview){ao=this.view.max_low;al=this.view.max_high;ak=Math.pow(C,Math.ceil(Math.log((view.max_high-view.max_low)/R)/Math.log(C)));at=ai/(view.max_high-view.max_low)}if(!ap){this.content_div.children().remove()}this.content_div.append(ar);this.max_height=0;var ag=Math.floor(ao/ak/R);var an=true;var aq=[];var af=0;while((ag*R*ak)<al){tile=this.draw_helper(ah,ai,ag,ak,ar,at);if(tile){aq.push(tile)}else{an=false}ag+=1;af++}var aj=this;if(an){aj.postdraw_actions(aq,ai,at,ap)}},postdraw_actions:function(aj,ak,al,af){var ah=this;var ai=false;for(var ag=0;ag<aj.length;ag++){if(aj[ag].message){ai=true;break}}if(ai){for(var ag=0;ag<aj.length;ag++){tile=aj[ag];if(!tile.message){tile.canvas.css("padding-top",E)}}}},draw_helper:function(ag,ah,ai,al,ar,aw,at,am){var aj=this,aq=this._gen_tile_cache_key(ah,aw,ai),an=ai*R*al,av=an+R*al;var ao=(ag?undefined:aj.tile_cache.get(aq));if(ao){aj.show_tile(ao,ar,aw);return ao}var ap=function(ax){return("isResolved" in ax)};var ak=true;var af=aj.data_manager.get_data(an,av,aj.mode,al,aj.data_url_extra_params);if(ap(af)){ak=false}var au;if(view.reference_track&&aw>view.canvas_manager.char_width_px){au=view.reference_track.data_manager.get_data(an,av,aj.mode,al,view.reference_track.data_url_extra_params);if(ap(au)){ak=false}}if(ak){p(af,am);var ao=aj.draw_tile(af,aj.mode,al,ai,aw,au);if(ao!==undefined){aj.tile_cache.set(aq,ao);aj.show_tile(ao,ar,aw)}return ao}$.when(af,au).then(function(){view.request_redraw(false,false,false,aj)});return null},show_tile:function(al,an,ao){var ah=this,ag=al.canvas,ak=ag;if(al.message){var ap=$("<div/>"),am=$("<div/>").addClass("tile-message").text(al.message).css({height:E-1,width:al.canvas.width}).appendTo(ap),aj=$("<a href='javascript:void(0);'/>").addClass("icon more-down").appendTo(am),af=$("<a href='javascript:void(0);'/>").addClass("icon more-across").appendTo(am);ap.append(ag);ak=ap;aj.click(function(){al.stale=true;ah.data_manager.get_more_data(al.low,al.high,ah.mode,al.resolution,{},ah.data_manager.DEEP_DATA_REQ);ah.request_draw()}).dblclick(function(aq){aq.stopPropagation()});af.click(function(){al.stale=true;ah.data_manager.get_more_data(al.low,al.high,ah.mode,al.resolution,{},ah.data_manager.BROAD_DATA_REQ);ah.request_draw()}).dblclick(function(aq){aq.stopPropagation()})}al.predisplay_actions();var ai=(al.low-(this.is_overview?this.view.max_low:this.view.low))*ao;if(this.left_offset){ai-=this.left_offset}ak.css({position:"absolute",top:0,left:ai,height:""});an.append(ak);ah.max_height=Math.max(ah.max_height,ak.height());ah.content_div.css("height",ah.max_height+"px");an.children().css("height",ah.max_height+"px")},_get_tile_bounds:function(af,ag){var ai=af*R*ag,aj=R*ag,ah=(ai+aj<=this.view.max_high?ai+aj:this.view.max_high);return[ai,ah]},tool_region_and_parameters_str:function(ah,af,ai){var ag=this,aj=(ah!==undefined&&af!==undefined&&ai!==undefined?ah+":"+af+"-"+ai:"all");return" - region=["+aj+"], parameters=["+ag.tool.get_param_values().join(", ")+"]"},init_for_tool_data:function(){this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url;this.predraw_init=function(){var ag=this;var af=function(){if(ag.data_manager.size()===0){setTimeout(af,300)}else{ag.data_url=default_data_url;ag.data_query_wait=L;ag.dataset_state_url=converted_datasets_state_url;$.getJSON(ag.dataset_state_url,{dataset_id:ag.dataset_id,hda_ldda:ag.hda_ldda},function(ah){})}};af()}}});var ab=function(ag,af){i.call(this,"label",ag,af,false,{});this.container_div.addClass("label-track")};p(ab.prototype,i.prototype,{init:function(){this.enabled=true},_draw:function(){var ah=this.view,ai=ah.high-ah.low,al=Math.floor(Math.pow(10,Math.floor(Math.log(ai)/Math.log(10)))),af=Math.floor(ah.low/al)*al,aj=this.view.container.width(),ag=$("<div style='position: relative; height: 1.3em;'></div>");while(af<ah.high){var ak=(af-ah.low)/ai*aj;ag.append($("<div class='label'>"+commatize(af)+"</div>").css({position:"absolute",left:ak-1}));af+=al}this.content_div.children(":first").remove();this.content_div.append(ag)}});var A=function(af){N.call(this,"reference",af,{content_div:af.top_labeltrack},false,{});af.reference_track=this;this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:af.dbkey};this.data_manager=new I(B,this,false);this.tile_cache=new c(u)};p(A.prototype,q.prototype,N.prototype,{init:function(){this.enabled=true},draw_tile:function(ap,al,ak,ag,aq){var aj=this,ah=R*ak;if(aq>this.view.canvas_manager.char_width_px){if(ap.data===null){aj.content_div.css("height","0px");return}var ai=this.view.canvas_manager.new_canvas();var ao=ai.getContext("2d");ai.width=Math.ceil(ah*aq+aj.left_offset);ai.height=aj.height_px;ao.font=ao.canvas.manager.default_font;ao.textAlign="center";ap=ap.data;for(var am=0,an=ap.length;am<an;am++){var af=Math.round(am*aq);ao.fillText(ap[am],af+aj.left_offset,10)}return new b(aj,ag,ak,ai,ap)}this.content_div.css("height","0px")}});var j=function(ak,ai,ah,al,af,aj){var ag=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";N.call(this,ak,ai,ah,true,aj);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=al;this.dataset_id=af;this.original_dataset_id=af;this.data_manager=new S(B,this);this.tile_cache=new c(u);this.left_offset=0;this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ak},{key:"color",label:"Color",type:"color",default_value:get_random_color()},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.height_px,hidden:true}],saved_values:aj,onchange:function(){ag.set_name(ag.prefs.name);ag.vertical_range=ag.prefs.max_value-ag.prefs.min_value;$("#linetrack_"+ag.dataset_id+"_minval").text(ag.prefs.min_value);$("#linetrack_"+ag.dataset_id+"_maxval").text(ag.prefs.max_value);ag.tile_cache.clear();ag.request_draw()}});this.prefs=this.config.values;this.height_px=this.config.values.height;this.vertical_range=this.config.values.max_value-this.config.values.min_value;this.add_resize_handle()};p(j.prototype,q.prototype,N.prototype,{add_resize_handle:function(){var af=this;var ai=false;var ah=false;var ag=$("<div class='track-resize'>");$(af.container_div).hover(function(){ai=true;ag.show()},function(){ai=false;if(!ah){ag.hide()}});ag.hide().bind("dragstart",function(aj,ak){ah=true;ak.original_height=$(af.content_div).height()}).bind("drag",function(ak,al){var aj=Math.min(Math.max(al.original_height+al.deltaY,af.min_height_px),af.max_height_px);$(af.content_div).css("height",aj);af.height_px=aj;af.request_draw(true)}).bind("dragend",function(aj,ak){af.tile_cache.clear();ah=false;if(!ai){ag.hide()}af.config.values.height=af.height_px}).appendTo(af.container_div)},predraw_init:function(){var af=this;af.vertical_range=undefined;return $.getJSON(af.data_url,{stats:true,chrom:af.view.chrom,low:null,high:null,hda_ldda:af.hda_ldda,dataset_id:af.dataset_id},function(ag){af.container_div.addClass("line-track");var ai=ag.data;if(isNaN(parseFloat(af.prefs.min_value))||isNaN(parseFloat(af.prefs.max_value))){af.prefs.min_value=ai.min;af.prefs.max_value=ai.max;$("#track_"+af.dataset_id+"_minval").val(af.prefs.min_value);$("#track_"+af.dataset_id+"_maxval").val(af.prefs.max_value)}af.vertical_range=af.prefs.max_value-af.prefs.min_value;af.total_frequency=ai.total_frequency;af.container_div.find(".yaxislabel").remove();var aj=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+af.dataset_id+"_minval").text(Z(af.prefs.min_value,3));var ah=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+af.dataset_id+"_maxval").text(Z(af.prefs.max_value,3));ah.css({position:"absolute",top:"24px",left:"10px"});ah.prependTo(af.container_div);aj.css({position:"absolute",bottom:"2px",left:"10px"});aj.prependTo(af.container_div)})},draw_tile:function(ar,ak,aj,ah,aq){if(this.vertical_range===undefined){return}var af=this._get_tile_bounds(ah,aj),al=af[0],ap=af[1],ag=Math.ceil((ap-al)*aq),an=this.height_px;var ai=this.view.canvas_manager.new_canvas();ai.width=ag,ai.height=an;var ao=ai.getContext("2d");var am=new M.LinePainter(ar.data,al,ap,this.prefs,ak);am.draw(ao,ag,an);return new b(this.track,ah,aj,ai,ar.data)}});var e=function(af,al,ag,ak,an,am,ai,aj){var ah=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];N.call(this,af,al,ag,true,am,ai,aj);this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:af},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:am,onchange:function(){ah.set_name(ah.prefs.name);ah.tile_cache.clear();ah.request_draw()}});this.prefs=this.config.values;this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=ak;this.dataset_id=an;this.original_dataset_id=an;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.inc_slots={};this.start_end_dct={};this.tile_cache=new c(d);this.data_manager=new S(20,this);this.left_offset=200;this.painter=M.LinkedFeaturePainter};p(e.prototype,q.prototype,N.prototype,{postdraw_actions:function(av,af,aw,au){N.prototype.postdraw_actions.call(this,av,au);var ai=this;if(au){var ak=ai.content_div.children();var al=false;for(var aj=ak.length-1,ap=0;aj>=ap;aj--){var ah=$(ak[aj]);if(al){ah.remove()}else{if(ah.children().length!==0){al=true}}}}if(ai.mode=="Histogram"){var ao=-1;for(var aj=0;aj<av.length;aj++){var at=av[aj].max_val;if(at>ao){ao=at}}for(var aj=0;aj<av.length;aj++){var ar=av[aj];if(ar.max_val!==ao){ar.canvas.remove();ai.draw_helper(true,af,ar.index,ar.resolution,ar.canvas.parent(),aw,[],{max:ao})}}}if(ai.filters_manager){var ag=ai.filters_manager.filters;for(var an=0;an<ag.length;an++){ag[an].update_ui_elt()}var am=false,aq;for(var aj=0;aj<av.length;aj++){if(av[aj].data.length){aq=av[aj].data[0];for(var an=0;an<ag.length;an++){if(ag[an].applies_to(aq)){am=true;break}}}}if(ai.filters_available!==am){ai.filters_available=am;if(!ai.filters_available){ai.filters_div.hide()}ai.update_track_icons()}}},update_auto_mode:function(af){if(this.mode=="Auto"){if(af=="no_detail"){af="feature spans"}else{if(af=="summary_tree"){af="coverage histogram"}}this.mode_div.text("Auto ("+af+")")}},incremental_slots:function(aj,ag,ai){var ah=this.view.canvas_manager.dummy_context,af=this.inc_slots[aj];if(!af||(af.mode!==ai)){af=new (s.FeatureSlotter)(aj,ai==="Pack",z,function(ak){return ah.measureText(ak)});af.mode=ai;this.inc_slots[aj]=af}return af.slot_features(ag)},get_summary_tree_data:function(aj,am,ah,av){if(av>ah-am){av=ah-am}var aq=Math.floor((ah-am)/av),au=[],ai=0;var ak=0,al=0,ap,at=0,an=[],ar,ao;var ag=function(ay,ax,az,aw){ay[0]=ax+az*aw;ay[1]=ax+(az+1)*aw};while(at<av&&ak!==aj.length){var af=false;for(;at<av&&!af;at++){ag(an,am,at,aq);for(al=ak;al<aj.length;al++){ap=aj[al].slice(1,3);if(is_overlap(ap,an)){af=true;break}}if(af){break}}data_start_index=al;au[au.length]=ar=[an[0],0];for(;al<aj.length;al++){ap=aj[al].slice(1,3);if(is_overlap(ap,an)){ar[1]++}else{break}}if(ar[1]>ai){ai=ar[1]}at++}return{max:ai,delta:aq,data:au}},draw_tile:function(au,ax,aB,aF,ap,ai){var ay=this,ak=ay._get_tile_bounds(aF,aB),aI=ak[0],ag=ak[1],aw=ag-aI,az=Math.ceil(aw*ap),aO=25,aj=this.left_offset,av,al;if(ax==="Auto"){if(au.dataset_type==="summary_tree"){ax=au.dataset_type}else{if(au.extra_info==="no_detail"||ay.is_overview){ax="no_detail"}else{var aN=au.data;if(this.view.high-this.view.low>J){ax="Squish"}else{ax="Pack"}}}this.update_auto_mode(ax)}if(ax==="summary_tree"||ax==="Histogram"){al=this.summary_draw_height;this.container_div.find(".yaxislabel").remove();var af=$("<div />").addClass("yaxislabel");af.text(au.max);af.css({position:"absolute",top:"24px",left:"10px",color:this.prefs.label_color});af.prependTo(this.container_div);var ah=this.view.canvas_manager.new_canvas();ah.width=az+aj;ah.height=al+T;if(au.dataset_type!="summary_tree"){var aq=this.get_summary_tree_data(au.data,aI,ag,200);if(au.max){aq.max=au.max}au=aq}var aK=new M.SummaryTreePainter(au,aI,ag,this.prefs);var aA=ah.getContext("2d");aA.translate(aj,T);aK.draw(aA,az,al);return new k(ay,aF,aB,ah,au.data,au.max)}var av,an=1;if(ax==="no_detail"||ax==="Squish"||ax==="Pack"){an=this.incremental_slots(ap,au.data,ax);av=this.inc_slots[ap].slots}var ao=[];if(au.data){var ar=this.filters_manager.filters;for(var aC=0,aE=au.data.length;aC<aE;aC++){var am=au.data[aC];var aD=false;var at;for(var aH=0,aM=ar.length;aH<aM;aH++){at=ar[aH];at.update_attrs(am);if(!at.keep(am)){aD=true;break}}if(!aD){ao.push(am)}}}var aL=(this.filters_manager.alpha_filter?new D(this.filters_manager.alpha_filter):null);var aJ=(this.filters_manager.height_filter?new D(this.filters_manager.height_filter):null);var aK=new (this.painter)(ao,aI,ag,this.prefs,ax,aL,aJ,ai);var al=Math.max(ad,aK.get_required_height(an));var ah=this.view.canvas_manager.new_canvas();var aG=null;ah.width=az+aj;ah.height=al;var aA=ah.getContext("2d");aA.fillStyle=this.prefs.block_color;aA.font=aA.canvas.manager.default_font;aA.textAlign="right";this.container_div.find(".yaxislabel").remove();if(au.data){aA.translate(aj,0);aG=aK.draw(aA,az,al,av);aG.translation=-aj}return new P(ay,aF,aB,ah,au.data,ax,au.message,aG)}});var U=function(ak,ah,ag,am,af,aj,al,ai){e.call(this,ak,ah,ag,am,af,aj,al,ai);this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ak},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:aj,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=M.ReadPainter};p(U.prototype,q.prototype,N.prototype,e.prototype);var W=function(aj,ah,ag,al,af,ai,ak){e.call(this,aj,ah,ag,al,af,ai,ak);this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:aj},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ai,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=M.ReadPainter;this.update_track_icons()};p(W.prototype,q.prototype,N.prototype,e.prototype);X.View=ac;X.DrawableGroup=Q;X.LineTrack=j;X.FeatureTrack=e;X.ReadTrack=W;X.VcfTrack=U};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(i,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=i;this.include_label=h;this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,s=this.slots,h=this.start_end_dct,y=[],A=[],n=0,z=this.max_rows;for(var w=0,x=m.length;w<x;w++){var l=m[w],o=l[0];if(s[o]!==undefined){n=Math.max(n,s[o]);A.push(s[o])}else{y.push(w)}}var q=function(F,G){for(var E=0;E<=z;E++){var C=false,H=h[E];if(H!==undefined){for(var B=0,D=H.length;B<D;B++){var i=H[B];if(G>i[0]&&F<i[1]){C=true;break}}}if(!C){return E}}return -1};for(var w=0,x=y.length;w<x;w++){var l=m[y[w]],o=l[0],u=l[1],f=l[2],r=l[3],g=Math.floor(u*p),k=Math.ceil(f*p),v=this.measureText(r).width,j;if(r!==undefined&&this.include_label){v+=(d+a);if(g-v>=0){g-=v;j="left"}else{k+=v;j="right"}}var t=q(g,k);if(t>=0){if(h[t]===undefined){h[t]=[]}h[t].push([g,k]);s[o]=t;n=Math.max(n,t)}else{}}return n+1}})};var painters_module=function(i,w){var t=i("class").extend;var o=function(H,z,F,y,E,C){if(C===undefined){C=4}var B=y-z;var A=E-F;var D=Math.floor(Math.sqrt(B*B+A*A)/C);var I=B/D;var G=A/D;var x;for(x=0;x<D;x++,z+=I,F+=G){if(x%2!==0){continue}H.fillRect(z,F,C,1)}};var p=function(A,z,x,D){var C=z-D/2,B=z+D/2,E=x-Math.sqrt(D*3/2);A.beginPath();A.moveTo(C,E);A.lineTo(B,E);A.lineTo(z,x);A.lineTo(C,E);A.strokeStyle=this.fillStyle;A.fill();A.stroke();A.closePath()};var d=function(x){this.default_val=(x?x:1)};d.prototype.gen_val=function(x){return this.default_val};var l=function(z,B,x,y,A){this.data=z;this.view_start=B;this.view_end=x;this.prefs=t({},this.default_prefs,y);this.mode=A};l.prototype.default_prefs={};var u=function(z,B,x,y,A){l.call(this,z,B,x,y,A)};u.prototype.default_prefs={show_counts:false};u.prototype.draw=function(M,z,L){var E=this.view_start,O=this.view_end-this.view_start,N=z/O;var J=this.data.data,I=this.data.delta,G=this.data.max,B=L;delta_x_px=Math.ceil(I*N);M.save();for(var C=0,D=J.length;C<D;C++){var H=Math.floor((J[C][0]-E)*N);var F=J[C][1];if(!F){continue}var K=F/G*L;if(F!==0&&K<1){K=1}M.fillStyle=this.prefs.block_color;M.fillRect(H,B-K,delta_x_px,K);var A=4;if(this.prefs.show_counts&&(M.measureText(F).width+A)<delta_x_px){M.fillStyle=this.prefs.label_color;M.textAlign="center";M.fillText(F,H+(delta_x_px/2),10)}}M.restore()};var b=function(x,B,D,E,z){l.call(this,x,B,D,E,z);if(this.prefs.min_value===undefined){var F=Infinity;for(var y=0,A=this.data.length;y<A;y++){F=Math.min(F,this.data[y][1])}this.prefs.min_value=F}if(this.prefs.max_value===undefined){var C=-Infinity;for(var y=0,A=this.data.length;y<A;y++){C=Math.max(C,this.data[y][1])}this.prefs.max_value=C}};b.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};b.prototype.draw=function(M,L,J){var E=false,G=this.prefs.min_value,C=this.prefs.max_value,I=C-G,x=J,z=this.view_start,K=this.view_end-this.view_start,A=L/K,H=this.mode,S=this.data;M.save();var T=Math.round(J+G/I*J);if(H!=="Intensity"){M.fillStyle="#aaa";M.fillRect(0,T,L,1)}M.beginPath();var Q,D,B;if(S.length>1){B=Math.ceil((S[1][0]-S[0][0])*A)}else{B=10}for(var N=0,O=S.length;N<O;N++){M.fillStyle=this.prefs.color;Q=Math.round((S[N][0]-z)*A);D=S[N][1];var P=false,F=false;if(D===null){if(E&&H==="Filled"){M.lineTo(Q,x)}E=false;continue}if(D<G){F=true;D=G}else{if(D>C){P=true;D=C}}if(H==="Histogram"){D=Math.round(D/I*x);M.fillRect(Q,T,B,-D)}else{if(H==="Intensity"){D=255-Math.floor((D-G)/I*255);M.fillStyle="rgb("+D+","+D+","+D+")";M.fillRect(Q,0,B,x)}else{D=Math.round(x-(D-G)/I*x);if(E){M.lineTo(Q,D)}else{E=true;if(H==="Filled"){M.moveTo(Q,x);M.lineTo(Q,D)}else{M.moveTo(Q,D)}}}}M.fillStyle=this.prefs.overflow_color;if(P||F){var R;if(H==="Histogram"||H==="Intensity"){R=B}else{Q-=2;R=4}if(P){M.fillRect(Q,0,R,3)}if(F){M.fillRect(Q,x-3,R,3)}}M.fillStyle=this.prefs.color}if(H==="Filled"){if(E){M.lineTo(Q,T);M.lineTo(0,T)}M.fill()}else{M.stroke()}M.restore()};var m=function(x){this.feature_positions={};this.slot_height=x;this.translation=0};m.prototype.map_feature_data=function(y,A,x,z){if(!this.feature_positions[A]){this.feature_positions[A]=[]}this.feature_positions[A].push({data:y,x_start:x,x_end:z})};m.prototype.get_feature_data=function(z,D){var C=Math.floor(D/this.slot_height),B;if(!this.feature_positions[C]){return null}z+=this.translation;for(var A=0;A<this.feature_positions[C].length;A++){B=this.feature_positions[C][A];if(z>=B.x_start&&z<=B.x_end){return B.data}}};var n=function(z,C,x,y,B,D,A){l.call(this,z,C,x,y,B);this.alpha_scaler=(D?D:new d());this.height_scaler=(A?A:new d())};n.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};t(n.prototype,{get_required_height:function(y){var x=y_scale=this.get_row_height(),z=this.mode;if(z==="no_detail"||z==="Squish"||z==="Pack"){x=y*y_scale}return x+Math.max(Math.round(y_scale/2),5)},draw:function(J,H,F,E){var P=this.data,C=this.view_start,L=this.view_end;J.save();J.fillStyle=this.prefs.block_color;J.textAlign="right";var G=this.view_end-this.view_start,D=H/G,K=this.get_row_height(),O=new m(K),A;for(var M=0,N=P.length;M<N;M++){var z=P[M],B=z[0],I=z[1],x=z[2],y=(E&&E[B]!==undefined?E[B]:null);if((I<L&&x>C)&&(this.mode=="Dense"||y!==null)){A=this.draw_element(J,this.mode,z,y,C,L,D,K,H);O.map_feature_data(z,y,A[0],A[1])}}J.restore();return O},draw_element:function(D,z,F,B,A,C,E,y,x){console.log("WARNING: Unimplemented function.");return[0,0]}});var c=10,h=3,k=5,v=10,f=1,r=3,e=3,a=9,j=2,g="#ccc";var q=function(z,C,x,y,B,D,A){n.call(this,z,C,x,y,B,D,A)};t(q.prototype,n.prototype,{get_row_height:function(){var y=this.mode,x;if(y==="Dense"){x=c}else{if(y==="no_detail"){x=h}else{if(y==="Squish"){x=k}else{x=v}}}return x},draw_element:function(L,C,U,G,N,af,aj,al,x){var R=U[0],ah=U[1],Z=U[2],P=U[3],aa=Math.floor(Math.max(0,(ah-N)*aj)),M=Math.ceil(Math.min(x,Math.max(0,(Z-N)*aj))),Y=aa,ak=M,X=(C==="Dense"?0:(0+G))*al,K,ad,Q=null,an=null,A=this.prefs.block_color,ac=this.prefs.label_color;L.globalAlpha=this.alpha_scaler.gen_val(U);if(C==="Dense"){G=1}if(C==="no_detail"){L.fillStyle=A;L.fillRect(aa,X+5,M-aa,f)}else{var J=U[4],W=U[5],ab=U[6],B=U[7];if(W&&ab){Q=Math.floor(Math.max(0,(W-N)*aj));an=Math.ceil(Math.min(x,Math.max(0,(ab-N)*aj)))}var ai,S;if(C==="Squish"||C==="Dense"){ai=1;S=e}else{ai=5;S=a}if(!B){if(U.strand){if(U.strand==="+"){L.fillStyle=L.canvas.manager.get_pattern("right_strand_inv")}else{if(U.strand==="-"){L.fillStyle=L.canvas.manager.get_pattern("left_strand_inv")}}}else{L.fillStyle=A}L.fillRect(aa,X,M-aa,S)}else{var I,T;if(C==="Squish"||C==="Dense"){L.fillStyle=g;I=X+Math.floor(e/2)+1;T=1}else{if(J){var I=X;var T=S;if(J==="+"){L.fillStyle=L.canvas.manager.get_pattern("right_strand")}else{if(J==="-"){L.fillStyle=L.canvas.manager.get_pattern("left_strand")}}}else{L.fillStyle=g;I+=(e/2)+1;T=1}}L.fillRect(aa,I,M-aa,T);var D;for(var ag=0,z=B.length;ag<z;ag++){var E=B[ag],y=Math.floor(Math.max(0,(E[0]-N)*aj)),V=Math.ceil(Math.min(x,Math.max((E[1]-N)*aj)));if(y>V){continue}L.fillStyle=A;L.fillRect(y,X+(S-ai)/2+1,V-y,ai);if(Q!==undefined&&ab>W&&!(y>an||V<Q)){var ae=Math.max(y,Q),H=Math.min(V,an);L.fillRect(ae,X+1,H-ae,S);if(B.length==1&&C=="Pack"){if(J==="+"){L.fillStyle=L.canvas.manager.get_pattern("right_strand_inv")}else{if(J==="-"){L.fillStyle=L.canvas.manager.get_pattern("left_strand_inv")}}if(ae+14<H){ae+=2;H-=2}L.fillRect(ae,X+1,H-ae,S)}}}if(C==="Pack"){L.globalAlpha=1;L.fillStyle="white";var F=this.height_scaler.gen_val(U),O=Math.ceil(S*F),am=Math.round((S-O)/2);if(F!==1){L.fillRect(aa,I+1,M-aa,am);L.fillRect(aa,I+S-am+1,M-aa,am)}}}L.globalAlpha=1;if(C==="Pack"&&ah>N){L.fillStyle=ac;if(N===0&&aa-L.measureText(P).width<0){L.textAlign="left";L.fillText(P,M+j,X+8);ak+=L.measureText(P).width+j}else{L.textAlign="right";L.fillText(P,aa-j,X+8);Y-=L.measureText(P).width+j}}}L.globalAlpha=1;return[Y,ak]}});var s=function(A,D,x,z,C,E,B,y){n.call(this,A,D,x,z,C,E,B);this.ref_seq=(y?y.data:null)};s.prototype.default_prefs=t({},n.prototype.default_prefs,{show_insertions:false});t(s.prototype,n.prototype,{get_row_height:function(){var x,y=this.mode;if(y==="Dense"){x=c}else{if(y==="Squish"){x=k}else{x=v;if(this.prefs.show_insertions){x*=2}}}return x},draw_read:function(U,P,L,Z,A,T,I,F,E){U.textAlign="center";var S=this,z=[Z,A],O=0,V=0,R=0,x=U.canvas.manager.char_width_px;var ae=[];if((P==="Pack"||this.mode==="Auto")&&F!==undefined&&L>x){R=Math.round(L/2)}if(!I){I=[[0,F.length]]}for(var M=0,X=I.length;M<X;M++){var J=I[M],B="MIDNSHP=X"[J[0]],N=J[1];if(B==="H"||B==="S"){O-=N}var G=T+O,ad=Math.floor(Math.max(0,(G-Z)*L)),H=Math.floor(Math.max(0,(G+N-Z)*L));if(ad===H){H+=1}switch(B){case"H":break;case"S":case"M":case"=":if(is_overlap([G,G+N],z)){var Q=F.slice(V,V+N);if(R>0){U.fillStyle=this.prefs.block_color;U.fillRect(ad-R,E+1,H-ad,9);U.fillStyle=g;for(var ab=0,y=Q.length;ab<y;ab++){if(this.prefs.show_differences&&this.ref_seq){var K=this.ref_seq[G-Z+ab];if(!K||K.toLowerCase()===Q[ab].toLowerCase()){continue}}if(G+ab>=Z&&G+ab<=A){var ac=Math.floor(Math.max(0,(G+ab-Z)*L));U.fillText(Q[ab],ac,E+9)}}}else{U.fillStyle=this.prefs.block_color;U.fillRect(ad,E+4,H-ad,e)}}V+=N;O+=N;break;case"N":U.fillStyle=g;U.fillRect(ad-R,E+5,H-ad,1);O+=N;break;case"D":U.fillStyle="red";U.fillRect(ad-R,E+4,H-ad,3);O+=N;break;case"P":break;case"I":var Y=ad-R;if(is_overlap([G,G+N],z)){var Q=F.slice(V,V+N);if(this.prefs.show_insertions){var D=ad-(H-ad)/2;if((P==="Pack"||this.mode==="Auto")&&F!==undefined&&L>x){U.fillStyle="yellow";U.fillRect(D-R,E-9,H-ad,9);ae[ae.length]={type:"triangle",data:[Y,E+4,5]};U.fillStyle=g;switch(compute_overlap([G,G+N],z)){case (OVERLAP_START):Q=Q.slice(Z-G);break;case (OVERLAP_END):Q=Q.slice(0,G-A);break;case (CONTAINED_BY):break;case (CONTAINS):Q=Q.slice(Z-G,G-A);break}for(var ab=0,y=Q.length;ab<y;ab++){var ac=Math.floor(Math.max(0,(G+ab-Z)*L));U.fillText(Q[ab],ac-(H-ad)/2,E)}}else{U.fillStyle="yellow";U.fillRect(D,E+(this.mode!=="Dense"?2:5),H-ad,(P!=="Dense"?e:r))}}else{if((P==="Pack"||this.mode==="Auto")&&F!==undefined&&L>x){ae.push({type:"text",data:[Q.length,Y,E+9]})}else{}}}V+=N;break;case"X":V+=N;break}}U.fillStyle="yellow";var aa,C,af;for(var W=0;W<ae.length;W++){aa=ae[W];C=aa.type;af=aa.data;if(C==="text"){U.save();U.font="bold "+U.font;U.fillText(af[0],af[1],af[2]);U.restore()}else{if(C=="triangle"){p(U,af[0],af[1],af[2])}}}},draw_element:function(Q,L,D,A,T,y,H,R,O){var G=D[0],P=D[1],z=D[2],I=D[3],C=Math.floor(Math.max(0,(P-T)*H)),E=Math.ceil(Math.min(O,Math.max(0,(z-T)*H))),B=(L==="Dense"?0:(0+A))*R,U=this.prefs.block_color,F=this.prefs.label_color,N=0;if((L==="Pack"||this.mode==="Auto")&&H>Q.canvas.manager.char_width_px){var N=Math.round(H/2)}Q.fillStyle=U;if(D[5] instanceof Array){var M=Math.floor(Math.max(0,(D[4][0]-T)*H)),K=Math.ceil(Math.min(O,Math.max(0,(D[4][1]-T)*H))),J=Math.floor(Math.max(0,(D[5][0]-T)*H)),x=Math.ceil(Math.min(O,Math.max(0,(D[5][1]-T)*H)));if(D[4][1]>=T&&D[4][0]<=y&&D[4][2]){this.draw_read(Q,L,H,T,y,D[4][0],D[4][2],D[4][3],B)}if(D[5][1]>=T&&D[5][0]<=y&&D[5][2]){this.draw_read(Q,L,H,T,y,D[5][0],D[5][2],D[5][3],B)}if(J>K){Q.fillStyle=g;o(Q,K-N,B+5,J-N,B+5)}}else{Q.fillStyle=U;this.draw_read(Q,L,H,T,y,P,D[4],D[5],B)}if(L==="Pack"&&P>T&&I!=="."){Q.fillStyle=this.prefs.label_color;var S=1;if(S===0&&C-Q.measureText(I).width<0){Q.textAlign="left";Q.fillText(I,E+j-N,B+8)}else{Q.textAlign="right";Q.fillText(I,C-j-N,B+8)}Q.fillStyle=U}return[0,0]}});w.Scaler=d;w.SummaryTreePainter=u;w.LinePainter=b;w.LinkedFeaturePainter=q;w.ReadPainter=s};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("class",class_module);a("slotting",slotting_module);a("painters",painters_module);a("trackster",trackster_module);for(key in c.trackster){d[key]=c.trackster[key]}})(window);
\ No newline at end of file
+var class_module=function(b,a){var c=function(){var f=arguments[0];for(var e=1;e<arguments.length;e++){var d=arguments[e];for(key in d){f[key]=d[key]}}return f};a.extend=c};var requestAnimationFrame=(function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(b,a){window.setTimeout(b,1000/60)}})();var BEFORE=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005,AFTER=1006;var compute_overlap=function(e,b){var g=e[0],f=e[1],d=b[0],c=b[1],a;if(g<d){if(f<d){a=BEFORE}else{if(f<=c){a=OVERLAP_START}else{a=CONTAINS}}}else{if(g>c){a=AFTER}else{if(f<=c){a=CONTAINED_BY}else{a=OVERLAP_END}}}return a};var is_overlap=function(c,b){var a=compute_overlap(c,b);return(a!==BEFORE&&a!==AFTER)};var get_random_color=function(a){if(!a){a="#ffffff"}if(typeof(a)==="string"){a=[a]}for(var j=0;j<a.length;j++){a[j]=parseInt(a[j].slice(1),16)}var m=function(t,s,i){return((t*299)+(s*587)+(i*114))/1000};var e=function(u,t,v,r,i,s){return(Math.max(u,r)-Math.min(u,r))+(Math.max(t,i)-Math.min(t,i))+(Math.max(v,s)-Math.min(v,s))};var g,n,f,k,p,h,q,c,d,b,o,l=false;do{g=Math.random()*16777215;n=g|16711680;f=g|65280;k=g|255;d=m(n,f,k);l=true;for(var j=0;j<a.length;j++){p=a[j];h=p|16711680;q=p|65280;c=p|255;b=m(h,q,c);o=e(n,f,k,h,q,c);if((Math.abs(d-b)<125)||(o<500)){l=false;break}}}while(!l);return"#"+(16777216+g).toString(16).substr(1,6)};var trackster_module=function(f,X){var p=f("class").extend,s=f("slotting"),M=f("painters");var ae=function(af,ag){this.document=af;this.default_font=ag!==undefined?ag:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};p(ae.prototype,{load_pattern:function(af,aj){var ag=this.patterns,ah=this.dummy_context,ai=new Image();ai.src=image_path+aj;ai.onload=function(){ag[af]=ah.createPattern(ai,"repeat")}},get_pattern:function(af){return this.patterns[af]},new_canvas:function(){var af=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(af)}af.manager=this;return af}});var n={};var l=function(af,ag){n[af.attr("id")]=ag};var m=function(af,ah,aj,ai){aj=".group";var ag={};n[af.attr("id")]=ai;af.bind("drag",{handle:"."+ah,relative:true},function(ar,at){var aq=$(this);var aw=$(this).parent(),an=aw.children(),ap=n[$(this).attr("id")],am,al,au,ak,ao;al=$(this).parents(aj);if(al.length!==0){au=al.position().top;ak=au+al.outerHeight();if(at.offsetY<au){$(this).insertBefore(al);var av=n[al.attr("id")];av.remove_drawable(ap);av.container.add_drawable_before(ap,av);return}else{if(at.offsetY>ak){$(this).insertAfter(al);var av=n[al.attr("id")];av.remove_drawable(ap);av.container.add_drawable(ap);return}}}al=null;for(ao=0;ao<an.length;ao++){am=$(an.get(ao));au=am.position().top;ak=au+am.outerHeight();if(am.is(aj)&&this!==am.get(0)&&at.offsetY>=au&&at.offsetY<=ak){if(at.offsetY-au<ak-at.offsetY){am.find(".content-div").prepend(this)}else{am.find(".content-div").append(this)}if(ap.container){ap.container.remove_drawable(ap)}n[am.attr("id")].add_drawable(ap);return}}for(ao=0;ao<an.length;ao++){if(at.offsetY<$(an.get(ao)).position().top){break}}if(ao===an.length){if(this!==an.get(ao-1)){aw.append(this);n[aw.attr("id")].move_drawable(ap,ao)}}else{if(this!==an.get(ao)){$(this).insertBefore(an.get(ao));n[aw.attr("id")].move_drawable(ap,(at.deltaY>0?ao-1:ao))}}}).bind("dragstart",function(){ag["border-top"]=af.css("border-top");ag["border-bottom"]=af.css("border-bottom");$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css(ag)})};X.moveable=m;var ad=16,H=9,E=20,T=H+2,z=100,J=12000,R=200,C=5,v=10,L=5000,w=100,o="There was an error in indexing this dataset. ",K="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",F="No data for this chrom/contig.",t="Currently indexing... please wait",x="Tool cannot be rerun: ",a="Loading data...",Y="Ready for display",d=10,u=5,B=5;function Z(ag,af){if(!af){af=0}var ah=Math.pow(10,af);return Math.round(ag*ah)/ah}var c=function(af){this.num_elements=af;this.clear()};p(c.prototype,{get:function(ag){var af=this.key_ary.indexOf(ag);if(af!==-1){if(this.obj_cache[ag].stale){this.key_ary.splice(af,1);delete this.obj_cache[ag]}else{this.move_key_to_end(ag,af)}}return this.obj_cache[ag]},set:function(ag,ah){if(!this.obj_cache[ag]){if(this.key_ary.length>=this.num_elements){var af=this.key_ary.shift();delete this.obj_cache[af]}this.key_ary.push(ag)}this.obj_cache[ag]=ah;return ah},move_key_to_end:function(ag,af){this.key_ary.splice(af,1);this.key_ary.push(ag)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var S=function(ag,af,ah){c.call(this,ag);this.track=af;this.subset=(ah!==undefined?ah:true)};p(S.prototype,c.prototype,{load_data:function(ao,aj,am,ag,al){var an=this.track.view.chrom,ai={chrom:an,low:ao,high:aj,mode:am,resolution:ag,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(ai,al);if(this.track.filters_manager){var ap=[];var af=this.track.filters_manager.filters;for(var ak=0;ak<af.length;ak++){ap[ap.length]=af[ak].name}ai.filter_cols=JSON.stringify(ap)}var ah=this;return $.getJSON(this.track.data_url,ai,function(aq){ah.set_data(ao,aj,am,aq)})},get_data:function(af,aj,ak,ag,ai){var ah=this.get_data_from_cache(af,aj,ak);if(ah){return ah}ah=this.load_data(af,aj,ak,ag,ai);this.set_data(af,aj,ak,ah);return ah},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(an,ai,am,ah,al,aj){var ao=this.get_data_from_cache(an,ai,am);if(!ao){console.log("ERROR: no current data for: ",this.track,an,ai,am,ah,al);return}ao.stale=true;var ag=an;if(aj===this.DEEP_DATA_REQ){$.extend(al,{start_val:ao.data.length+1})}else{if(aj===this.BROAD_DATA_REQ){ag=(ao.max_high?ao.max_high:ao.data[ao.data.length-1][2])+1}}var af=this,ak=this.load_data(ag,ai,am,ah,al);new_data_available=$.Deferred();this.set_data(an,ai,am,new_data_available);$.when(ak).then(function(ap){if(ap.data){ap.data=ao.data.concat(ap.data);if(ap.max_low){ap.max_low=ao.max_low}if(ap.message){ap.message=ap.message.replace(/[0-9]+/,ap.data.length)}}af.set_data(an,ai,am,ap);new_data_available.resolve(ap)});return new_data_available},get_data_from_cache:function(af,ag,ah){return this.get(this.gen_key(af,ag,ah))},set_data:function(ag,ah,ai,af){return this.set(this.gen_key(ag,ah,ai),af)},gen_key:function(af,ah,ai){var ag=af+"_"+ah+"_"+ai;return ag},split_key:function(af){return af.split("_")}});var I=function(ag,af,ah){S.call(this,ag,af,ah)};p(I.prototype,S.prototype,c.prototype,{load_data:function(af,ai,aj,ag,ah){if(ag>1){return{data:null}}return S.prototype.load_data.call(this,af,ai,aj,ag,ah)}});var q=function(ai,ag,af,ah,aj){if(!q.id_counter){q.id_counter=0}this.id=q.id_counter++;this.name=ai;this.view=ag;this.container=af;this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ai}],saved_values:ah,onchange:function(){this.track.set_name(this.track.config.values.name)}});this.prefs=this.config.values;this.drag_handle_class=aj;this.is_overview=false};p(q.prototype,{init:function(){},request_draw:function(){},_draw:function(){},to_json:function(){},update_icons:function(){},set_name:function(af){this.old_name=this.name;this.name=af;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)},remove:function(){this.container.remove_drawable(this);this.container_div.hide(0,function(){$(this).remove();view.update_intro_div();view.has_changes=true})}});var y=function(aj,ai,ag,af,ah,ak){q.call(this,ai,ag,af,ah,ak);this.obj_type=aj;this.drawables=[]};p(y.prototype,q.prototype,{init:function(){for(var af=0;af<this.drawables.length;af++){this.drawables[af].init()}},_draw:function(){for(var af=0;af<this.drawables.length;af++){this.drawables[af]._draw()}},to_json:function(){var ag=[];for(var af=0;af<this.drawables.length;af++){ag.push(this.drawables[af].to_json())}return{name:this.name,prefs:this.prefs,obj_type:this.obj_type,drawables:ag}},add_drawable:function(af){this.drawables.push(af);af.container=this},add_drawable_before:function(ah,af){var ag=this.drawables.indexOf(af);if(ag!=-1){this.drawables.splice(ag,0,ah);return true}return false},remove_drawable:function(ag){var af=this.drawables.indexOf(ag);if(af!=-1){this.drawables.splice(af,1);ag.container=null;return true}return false},move_drawable:function(ag,ah){var af=this.drawables.indexOf(ag);if(af!=-1){this.drawables.splice(af,1);this.drawables.splice(ah,0,ag);return true}return false}});var Q=function(ai,ag,af,ah){y.call(this,"DrawableGroup",ai,ag,af,ah,"group-handle");this.container_div=$("<div/>").addClass("group").attr("id","group_"+this.id).appendTo(this.container.content_div);this.header_div=$("<div/>").addClass("track-header").appendTo(this.container_div);this.header_div.append($("<div/>").addClass(this.drag_handle_class));this.name_div=$("<div/>").addClass("group-name menubutton popup").text(this.name).appendTo(this.header_div);this.content_div=$("<div/>").addClass("content-div").attr("id","group_"+this.id+"_content_div").appendTo(this.container_div);l(this.container_div,this);l(this.content_div,this);m(this.container_div,this.drag_handle_class,".group",this);this.update_icons()};p(Q.prototype,q.prototype,y.prototype,{update_icons:function(){var ag=this;var af={};af["Edit configuration"]=function(){var aj=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},ah=function(){ag.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ai=function(ak){if((ak.keyCode||ak.which)===27){aj()}else{if((ak.keyCode||ak.which)===13){ah()}}};$(window).bind("keypress.check_enter_esc",ai);show_modal("Configure Group",ag.config.build_form(),{Cancel:aj,OK:ah})};af.Remove=function(){ag.remove()};make_popupmenu(ag.name_div,af)}});var ac=function(af,ai,ah,ag){y.call(this,"View");this.container=af;this.chrom=null;this.vis_id=ah;this.dbkey=ag;this.title=ai;this.label_tracks=[];this.tracks_to_be_redrawn=[];this.max_low=0;this.max_high=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.load_chroms_deferred=null;this.init();this.canvas_manager=new ae(af.get(0).ownerDocument);this.reset()};p(ac.prototype,y.prototype,{init:function(){var ah=this.container,af=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ah);this.browser_content_div=$("<div/>").addClass("content").css("position","relative").appendTo(ah);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ah);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").attr("id","viewport-container").appendTo(this.browser_content_div);this.content_div=this.viewport_container;l(this.viewport_container,af);this.intro_div=$("<div/>").addClass("intro");var ai=$("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function(){add_tracks()});this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a/>").attr("href","javascript:void(0);").attr("title","Close overview").addClass("icon-button overview-close tooltip").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var ag=function(aj){if(aj.type==="focusout"||(aj.keyCode||aj.which)===13||(aj.keyCode||aj.which)===27){if((aj.keyCode||aj.which)!==27){af.go_to($(this).val())}$(this).hide();$(this).val("");af.location_span.show();af.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ag).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").attr("original-title","Click to change location").tipsy({gravity:"n"}).appendTo(this.nav_controls);this.location_span.click(function(){af.location_span.hide();af.chrom_select.hide();af.nav_input.val(af.chrom+":"+af.low+"-"+af.high);af.nav_input.css("display","inline-block");af.nav_input.select();af.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a/>").attr("id","zoom-out").attr("title","Zoom out").tipsy({gravity:"n"}).click(function(){af.zoom_out();af.request_redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a/>").attr("id","zoom-in").attr("title","Zoom in").tipsy({gravity:"n"}).click(function(){af.zoom_in();af.request_redraw()}).appendTo(this.nav_controls);this.load_chroms_deferred=this.load_chroms({low:0});this.chrom_select.bind("change",function(){af.change_chrom(af.chrom_select.val())});this.browser_content_div.click(function(aj){$(this).find("input").trigger("blur")});this.browser_content_div.bind("dblclick",function(aj){af.zoom_in(aj.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(aj,ak){this.current_x=ak.offsetX}).bind("drag",function(aj,al){var am=al.offsetX-this.current_x;this.current_x=al.offsetX;var ak=Math.round(am/af.viewport_container.width()*(af.max_high-af.max_low));af.move_delta(-ak)});this.overview_close.click(function(){af.reset_overview()});this.viewport_container.bind("draginit",function(aj,ak){if(aj.clientX>af.viewport_container.width()-16){return false}}).bind("dragstart",function(aj,ak){ak.original_low=af.low;ak.current_height=aj.clientY;ak.current_x=ak.offsetX}).bind("drag",function(al,an){var aj=$(this);var ao=an.offsetX-an.current_x;var ak=aj.scrollTop()-(al.clientY-an.current_height);aj.scrollTop(ak);an.current_height=al.clientY;an.current_x=an.offsetX;var am=Math.round(ao/af.viewport_container.width()*(af.high-af.low));af.move_delta(am)}).bind("mousewheel",function(al,an,ak,aj){if(ak){ak*=50;var am=Math.round(-ak/af.viewport_container.width()*(af.high-af.low));af.move_delta(am)}});this.top_labeltrack.bind("dragstart",function(aj,ak){return $("<div />").css({height:af.browser_content_div.height()+af.top_labeltrack.height()+af.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(an,ao){$(ao.proxy).css({left:Math.min(an.pageX,ao.startX),width:Math.abs(an.pageX-ao.startX)});var ak=Math.min(an.pageX,ao.startX)-af.container.offset().left,aj=Math.max(an.pageX,ao.startX)-af.container.offset().left,am=(af.high-af.low),al=af.viewport_container.width();af.update_location(Math.round(ak/al*am)+af.low,Math.round(aj/al*am)+af.low)}).bind("dragend",function(ao,ap){var ak=Math.min(ao.pageX,ap.startX),aj=Math.max(ao.pageX,ap.startX),am=(af.high-af.low),al=af.viewport_container.width(),an=af.low;af.low=Math.round(ak/al*am)+an;af.high=Math.round(aj/al*am)+an;$(ap.proxy).remove();af.request_redraw()});this.add_label_track(new ab(this,{content_div:this.top_labeltrack}));this.add_label_track(new ab(this,{content_div:this.nav_labeltrack}));$(window).bind("resize",function(){af.resize_window()});$(document).bind("redraw",function(){af.redraw()});this.reset();$(window).trigger("resize")},update_intro_div:function(){if(this.drawables.length===0){this.intro_div.appendTo(this.viewport_container)}else{this.intro_div.remove()}},update_location:function(af,ag){this.location_span.text(commatize(af)+" - "+commatize(ag));this.nav_input.val(this.chrom+":"+commatize(af)+"-"+commatize(ag))},load_chroms:function(ah){ah.num=w;$.extend(ah,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var af=this,ag=$.Deferred();$.ajax({url:chrom_url,data:ah,dataType:"json",success:function(aj){if(aj.chrom_info.length===0){alert("Invalid chromosome: "+ah.chrom);return}if(aj.reference){af.add_label_track(new A(af))}af.chrom_data=aj.chrom_info;var am='<option value="">Select Chrom/Contig</option>';for(var al=0,ai=af.chrom_data.length;al<ai;al++){var ak=af.chrom_data[al].chrom;am+='<option value="'+ak+'">'+ak+"</option>"}if(aj.prev_chroms){am+='<option value="previous">Previous '+w+"</option>"}if(aj.next_chroms){am+='<option value="next">Next '+w+"</option>"}af.chrom_select.html(am);af.chrom_start_index=aj.start_index;ag.resolve(aj)},error:function(){alert("Could not load chroms for this dbkey:",af.dbkey)}});return ag},change_chrom:function(ak,ag,am){if(!ak||ak==="None"){return}var ah=this;if(ak==="previous"){ah.load_chroms({low:this.chrom_start_index-w});return}if(ak==="next"){ah.load_chroms({low:this.chrom_start_index+w});return}var al=$.grep(ah.chrom_data,function(an,ao){return an.chrom===ak})[0];if(al===undefined){ah.load_chroms({chrom:ak},function(){ah.change_chrom(ak,ag,am)});return}else{if(ak!==ah.chrom){ah.chrom=ak;ah.chrom_select.val(ah.chrom);ah.max_high=al.len-1;ah.reset();ah.request_redraw(true);for(var aj=0,af=ah.drawables.length;aj<af;aj++){var ai=ah.drawables[aj];if(ai.init){ai.init()}}}if(ag!==undefined&&am!==undefined){ah.low=Math.max(ag,0);ah.high=Math.min(am,ah.max_high)}ah.reset_overview();ah.request_redraw()}},go_to:function(aj){aj=aj.replace(/ |,/g,"");var an=this,af,ai,ag=aj.split(":"),al=ag[0],am=ag[1];if(am!==undefined){try{var ak=am.split("-");af=parseInt(ak[0],10);ai=parseInt(ak[1],10)}catch(ah){return false}}an.change_chrom(al,af,ai)},move_fraction:function(ah){var af=this;var ag=af.high-af.low;this.move_delta(ah*ag)},move_delta:function(ah){var af=this;var ag=af.high-af.low;if(af.low-ah<af.max_low){af.low=af.max_low;af.high=af.max_low+ag}else{if(af.high-ah>af.max_high){af.high=af.max_high;af.low=af.max_high-ag}else{af.high-=ah;af.low-=ah}}af.request_redraw()},add_drawable:function(af){y.prototype.add_drawable.call(this,af);af.init();this.has_changes=true;this.update_intro_div()},add_label_track:function(af){af.view=this;af.init();this.label_tracks.push(af)},remove_drawable:function(ah,ag){y.prototype.remove_drawable.call(this,ah);if(ag){var af=this;ah.container_div.hide(0,function(){$(this).remove();af.update_intro_div()});this.has_changes=true}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},request_redraw:function(an,af,am,ag){var al=this,aj=(ag?[ag]:al.drawables),ah;var ag;for(var ak=0;ak<aj.length;ak++){ag=aj[ak];ah=-1;for(var ai=0;ai<al.tracks_to_be_redrawn.length;ai++){if(al.tracks_to_be_redrawn[ai][0]===ag){ah=ai;break}}if(ah<0){al.tracks_to_be_redrawn.push([ag,af,am])}else{al.tracks_to_be_redrawn[ak][1]=af;al.tracks_to_be_redrawn[ak][2]=am}}requestAnimationFrame(function(){al._redraw(an)})},_redraw:function(ap){var am=this.low,ai=this.high;if(am<this.max_low){am=this.max_low}if(ai>this.max_high){ai=this.max_high}var ao=this.high-this.low;if(this.high!==0&&ao<this.min_separation){ai=am+this.min_separation}this.low=Math.floor(am);this.high=Math.ceil(ai);this.resolution=Math.pow(C,Math.ceil(Math.log((this.high-this.low)/R)/Math.log(C)));this.zoom_res=Math.pow(v,Math.max(0,Math.ceil(Math.log(this.resolution,v)/Math.log(v))));var af=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var al=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var aq=13;this.overview_box.css({left:af,width:Math.max(aq,al)}).show();if(al<aq){this.overview_box.css("left",af-(aq-al)/2)}if(this.overview_highlight){this.overview_highlight.css({left:af,width:al})}this.update_location(this.low,this.high);if(!ap){var ah,ag,an;for(var aj=0,ak=this.tracks_to_be_redrawn.length;aj<ak;aj++){ah=this.tracks_to_be_redrawn[aj][0];ag=this.tracks_to_be_redrawn[aj][1];an=this.tracks_to_be_redrawn[aj][2];if(ah){ah._draw(ag,an)}}this.tracks_to_be_redrawn=[];for(aj=0,ak=this.label_tracks.length;aj<ak;aj++){this.label_tracks[aj]._draw()}}},zoom_in:function(ag,ah){if(this.max_high===0||this.high-this.low<this.min_separation){return}var ai=this.high-this.low,aj=ai/2+this.low,af=(ai/this.zoom_factor)/2;if(ag){aj=ag/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(aj-af);this.high=Math.round(aj+af);this.request_redraw()},zoom_out:function(){if(this.max_high===0){return}var ag=this.high-this.low,ah=ag/2+this.low,af=(ag*this.zoom_factor)/2;this.low=Math.round(ah-af);this.high=Math.round(ah+af);this.request_redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.request_redraw()},set_overview:function(ah){if(this.overview_drawable){if(this.overview_drawable.dataset_id===ah.dataset_id){return}this.overview_viewport.find(".track").remove()}var ag=ah.copy({content_div:this.overview_viewport}),af=this;ag.header_div.hide();ag.is_overview=true;af.overview_drawable=ag;this.overview_drawable.postdraw_actions=function(){af.overview_highlight.show().height(af.overview_drawable.content_div.height());af.overview_viewport.height(af.overview_drawable.content_div.height()+af.overview_box.outerHeight());af.overview_close.show();af.resize_window()};this.overview_drawable.init();af.has_changes=true},reset_overview:function(){$(".tipsy").remove();this.overview_viewport.find(".track-tile").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide();view.resize_window();view.overview_drawable=null}});var r=function(ah,al){this.track=ah;this.name=al.name;this.params=[];var at=al.params;for(var ai=0;ai<at.length;ai++){var an=at[ai],ag=an.name,ar=an.label,aj=unescape(an.html),au=an.value,ap=an.type;if(ap==="number"){this.params[this.params.length]=new g(ag,ar,aj,au,an.min,an.max)}else{if(ap=="select"){this.params[this.params.length]=new O(ag,ar,aj,au)}else{console.log("WARNING: unrecognized tool parameter type:",ag,ap)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(aw){aw.stopPropagation()}).click(function(aw){aw.stopPropagation()}).bind("dblclick",function(aw){aw.stopPropagation()});var aq=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var ao=this.params;var am=this;$.each(this.params,function(ax,aA){var az=$("<div>").addClass("param-row").appendTo(am.parent_div);var aw=$("<div>").addClass("param-label").text(aA.label).appendTo(az);var ay=$("<div/>").addClass("slider").html(aA.html).appendTo(az);ay.find(":input").val(aA.value);$("<div style='clear: both;'/>").appendTo(az)});this.parent_div.find("input").click(function(){$(this).select()});var av=$("<div>").addClass("param-row").appendTo(this.parent_div);var ak=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(av);var af=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(av);var am=this;af.click(function(){am.run_on_region()});ak.click(function(){am.run_on_dataset()})};p(r.prototype,{get_param_values_dict:function(){var af={};this.parent_div.find(":input").each(function(){var ag=$(this).attr("name"),ah=$(this).val();af[ag]=JSON.stringify(ah)});return af},get_param_values:function(){var ag=[];var af={};this.parent_div.find(":input").each(function(){var ah=$(this).attr("name"),ai=$(this).val();if(ah){ag[ag.length]=ai}});return ag},run_on_dataset:function(){var af=this;af.run({dataset_id:this.track.original_dataset_id,tool_id:af.name},null,function(ag){show_modal(af.name+" is Running",af.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var ag={dataset_id:this.track.original_dataset_id,chrom:this.track.view.chrom,low:this.track.view.low,high:this.track.view.high,tool_id:this.name},aj=this.track,ah=ag.tool_id+aj.tool_region_and_parameters_str(ag.chrom,ag.low,ag.high),af;if(aj.container===view){var ai=new Q(this.name,this.track.view,this.track.container);aj.container.add_drawable(ai);aj.container.remove_drawable(aj);ai.add_drawable(aj);aj.container_div.appendTo(ai.content_div);af=ai}else{af=aj.container}var ak=new aj.constructor(ah,view,af,"hda");ak.init_for_tool_data();ak.change_mode(aj.mode);af.add_drawable(ak);ak.content_div.text("Starting job.");this.run(ag,ak,function(al){ak.dataset_id=al.dataset_id;ak.content_div.text("Running job.");ak.init()})},run:function(ag,ah,ai){$.extend(ag,this.get_param_values_dict());var af=function(){$.getJSON(rerun_tool_url,ag,function(aj){if(aj==="no converter"){ah.container_div.addClass("error");ah.content_div.text(K)}else{if(aj.error){ah.container_div.addClass("error");ah.content_div.text(x+aj.message)}else{if(aj==="pending"){ah.container_div.addClass("pending");ah.content_div.text("Converting input data so that it can be used quickly with tool.");setTimeout(af,2000)}else{ai(aj)}}}})};af()}});var O=function(ag,af,ah,ai){this.name=ag;this.label=af;this.html=ah;this.value=ai};var g=function(ah,ag,aj,ak,ai,af){O.call(this,ah,ag,aj,ak);this.min=ai;this.max=af};var h=function(ag,af,ah,ai){this.name=ag;this.index=af;this.tool_id=ah;this.tool_exp_name=ai};var V=function(ag,af,ah,ai){h.call(this,ag,af,ah,ai);this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.container=null;this.slider=null;this.slider_label=null};p(V.prototype,{applies_to:function(af){if(af.length>this.index){return true}return false},keep:function(af){if(!this.applies_to(af)){return true}var ag=af[this.index];return(isNaN(ag)||(ag>=this.low&&ag<=this.high))},update_attrs:function(ag){var af=false;if(!this.applies_to(ag)){return af}if(ag[this.index]<this.min){this.min=Math.floor(ag[this.index]);af=true}if(ag[this.index]>this.max){this.max=Math.ceil(ag[this.index]);af=true}return af},update_ui_elt:function(){if(this.min!=this.max){this.container.show()}else{this.container.hide()}var ah=function(ak,ai){var aj=ai-ak;return(aj<=2?0.01:1)};var ag=this.slider.slider("option","min"),af=this.slider.slider("option","max");if(this.min<ag||this.max>af){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",ah(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var aa=function(aq,ay){this.track=aq;this.filters=[];for(var at=0;at<ay.length;at++){var au=ay[at],az=au.name,af=au.type,ah=au.index,ax=au.tool_id,aw=au.tool_exp_name;if(af==="int"||af==="float"){this.filters[at]=new V(az,ah,ax,aw)}else{console.log("ERROR: unsupported filter: ",az,af)}}var ai=function(aA,aB,aC){aA.click(function(){var aD=aB.text();max=parseFloat(aC.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(aC.slider("option","values")){input_size=2*input_size+1;multi_value=true}aB.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",aD).appendTo(aB).focus().select().click(function(aE){aE.stopPropagation()}).blur(function(){$(this).remove();aB.text(aD)}).keyup(function(aI){if(aI.keyCode===27){$(this).trigger("blur")}else{if(aI.keyCode===13){var aG=aC.slider("option","min"),aE=aC.slider("option","max"),aH=function(aJ){return(isNaN(aJ)||aJ>aE||aJ<aG)},aF=$(this).val();if(!multi_value){aF=parseFloat(aF);if(aH(aF)){alert("Parameter value must be in the range ["+aG+"-"+aE+"]");return $(this)}}else{aF=aF.split("-");aF=[parseFloat(aF[0]),parseFloat(aF[1])];if(aH(aF[0])||aH(aF[1])){alert("Parameter value must be in the range ["+aG+"-"+aE+"]");return $(this)}}aC.slider((multi_value?"values":"value"),aF)}}})})};this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(aA){aA.stopPropagation()}).click(function(aA){aA.stopPropagation()}).bind("dblclick",function(aA){aA.stopPropagation()}).bind("keydown",function(aA){aA.stopPropagation()});var av=$("<div/>").addClass("sliders").appendTo(this.parent_div);var an=this;$.each(this.filters,function(aD,aF){aF.container=$("<div/>").addClass("filter-row slider-row").appendTo(av);var aE=$("<div/>").addClass("elt-label").appendTo(aF.container);var aC=$("<span/>").addClass("slider-name").text(aF.name+" ").appendTo(aE);var aB=$("<span/>");var aH=$("<span/>").addClass("slider-value").appendTo(aE).append("[").append(aB).append("]");var aA=$("<div/>").addClass("slider").appendTo(aF.container);aF.control_element=$("<div/>").attr("id",aF.name+"-filter-control").appendTo(aA);var aG=[0,0];aF.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(aJ,aK){var aI=aK.values;aB.text(aI[0]+"-"+aI[1]);aF.low=aI[0];aF.high=aI[1];an.track.request_draw(true,true)},change:function(aI,aJ){aF.control_element.slider("option","slide").call(aF.control_element,aI,aJ)}});aF.slider=aF.control_element;aF.slider_label=aB;ai(aH,aB,aF.control_element);$("<div style='clear: both;'/>").appendTo(aF.container)});if(this.filters.length!==0){var ak=$("<div/>").addClass("param-row").appendTo(av);var am=$("<input type='submit'/>").attr("value","Run on complete dataset").appendTo(ak);var ag=this;am.click(function(){ag.run_on_dataset()})}var ap=$("<div/>").addClass("display-controls").appendTo(this.parent_div),ar,al,ao,aj={Transparency:function(aA){an.alpha_filter=aA},Height:function(aA){an.height_filter=aA}};$.each(aj,function(aC,aB){ar=$("<div/>").addClass("filter-row").appendTo(ap),al=$("<span/>").addClass("elt-label").text(aC+":").appendTo(ar),ao=$("<select/>").attr("name",aC+"_dropdown").css("float","right").appendTo(ar);$("<option/>").attr("value",-1).text("== None ==").appendTo(ao);for(var aA=0;aA<an.filters.length;aA++){$("<option/>").attr("value",aA).text(an.filters[aA].name).appendTo(ao)}ao.change(function(){$(this).children("option:selected").each(function(){var aD=parseInt($(this).val());aj[aC]((aD>=0?an.filters[aD]:null));an.track.request_draw(true,true)})});$("<div style='clear: both;'/>").appendTo(ar)});$("<div style='clear: both;'/>").appendTo(this.parent_div)};p(aa.prototype,{reset_filters:function(){for(var af=0;af<this.filters.length;af++){filter=this.filters[af];filter.slider.slider("option","values",[filter.min,filter.max])}this.alpha_filter=null;this.height_filter=null},run_on_dataset:function(){var an=function(ar,ap,aq){if(!(ap in ar)){ar[ap]=aq}return ar[ap]};var ah={},af,ag,ai;for(var aj=0;aj<this.filters.length;aj++){af=this.filters[aj];if(af.tool_id){if(af.min!=af.low){ag=an(ah,af.tool_id,[]);ag[ag.length]=af.tool_exp_name+" >= "+af.low}if(af.max!=af.high){ag=an(ah,af.tool_id,[]);ag[ag.length]=af.tool_exp_name+" <= "+af.high}}}var al=[];for(var ao in ah){al[al.length]=[ao,ah[ao]]}var am=al.length;(function ak(aw,at){var aq=at[0],ar=aq[0],av=aq[1],au="("+av.join(") and (")+")",ap={cond:au,input:aw,target_dataset_id:aw,tool_id:ar},at=at.slice(1);$.getJSON(run_tool_url,ap,function(ax){if(ax.error){show_modal("Filter Dataset","Error running tool "+ar,{Close:hide_modal})}else{if(at.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{ak(ax.dataset_id,at)}}})})(this.track.dataset_id,al)}});var D=function(af,ag){M.Scaler.call(this,ag);this.filter=af};D.prototype.gen_val=function(af){if(this.filter.high===Number.MAX_VALUE||this.filter.low===-Number.MAX_VALUE||this.filter.low===this.filter.high){return this.default_val}return((parseFloat(af[this.filter.index])-this.filter.low)/(this.filter.high-this.filter.low))};var G=function(af){this.track=af.track;this.params=af.params;this.values={};this.restore_values((af.saved_values?af.saved_values:{}));this.onchange=af.onchange};p(G.prototype,{restore_values:function(af){var ag=this;$.each(this.params,function(ah,ai){if(af[ai.key]!==undefined){ag.values[ai.key]=af[ai.key]}else{ag.values[ai.key]=ai.default_value}})},build_form:function(){var ai=this;var af=$("<div />");var ah;function ag(am,aj){for(var ao=0;ao<am.length;ao++){ah=am[ao];if(ah.hidden){continue}var ak="param_"+ao;var at=ai.values[ah.key];var av=$("<div class='form-row' />").appendTo(aj);av.append($("<label />").attr("for",ak).text(ah.label+":"));if(ah.type==="bool"){av.append($('<input type="checkbox" />').attr("id",ak).attr("name",ak).attr("checked",at))}else{if(ah.type==="text"){av.append($('<input type="text"/>').attr("id",ak).val(at).click(function(){$(this).select()}))}else{if(ah.type=="select"){var aq=$("<select />").attr("id",ak);for(var an=0;an<ah.options.length;an++){$("<option/>").text(ah.options[an].label).attr("value",ah.options[an].value).appendTo(aq)}aq.val(at);av.append(aq)}else{if(ah.type==="color"){var ap=$("<input />").attr("id",ak).attr("name",ak).val(at);var ar=$("<div class='tipsy tipsy-west' style='position: absolute;' />").hide();var al=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(ar);var au=$("<div/>").appendTo(al).farbtastic({width:100,height:100,callback:ap,color:at});$("<div />").append(ap).append(ar).appendTo(av).bind("click",function(aw){ar.css({left:$(this).position().left+$(ap).width()+5,top:$(this).position().top-($(ar).height()/2)+($(ap).height()/2)}).show();$(document).bind("click.color-picker",function(){ar.hide();$(document).unbind("click.color-picker")});aw.stopPropagation()})}else{av.append($("<input />").attr("id",ak).attr("name",ak).val(at))}}}}if(ah.help){av.append($("<div class='help'/>").text(ah.help))}}}ag(this.params,af);return af},update_from_form:function(af){var ah=this;var ag=false;$.each(this.params,function(ai,ak){if(!ak.hidden){var al="param_"+ai;var aj=af.find("#"+al).val();if(ak.type==="float"){aj=parseFloat(aj)}else{if(ak.type==="int"){aj=parseInt(aj)}else{if(ak.type==="bool"){aj=af.find("#"+al).is(":checked")}}}if(aj!==ah.values[ak.key]){ah.values[ak.key]=aj;ag=true}}});if(ag){this.onchange()}}});var b=function(af,ai,ah,ag,aj){this.track=af;this.index=ai;this.low=ai*R*ah;this.high=(ai+1)*R*ah;this.resolution=ah;this.canvas=$("<div class='track-tile'/>").append(ag);this.data=aj;this.stale=false};b.prototype.predisplay_actions=function(){};var k=function(af,ai,ah,ag,aj,ak){b.call(this,af,ai,ah,ag,aj);this.max_val=ak};p(k.prototype,b.prototype);var P=function(af,aj,ai,ah,al,am,ak,ag){b.call(this,af,aj,ai,ah,al);this.mode=am;this.message=ak;this.feature_mapper=ag};p(P.prototype,b.prototype);P.prototype.predisplay_actions=function(){var ag=this,af={};if(ag.mode!=="Pack"){return}$(this.canvas).hover(function(){this.hovered=true;$(this).mousemove()},function(){this.hovered=false;$(this).siblings(".feature-popup").remove()}).mousemove(function(ar){if(!this.hovered){return}var am=$(this).offset(),aq=ar.pageX-am.left,ap=ar.pageY-am.top,aw=ag.feature_mapper.get_feature_data(aq,ap),an=(aw?aw[0]:null);$(this).siblings(".feature-popup").each(function(){if(!an||$(this).attr("id")!==an.toString()){$(this).remove()}});if(aw){var ai=af[an];if(!ai){var an=aw[0],at={name:aw[3],start:aw[1],end:aw[2],strand:aw[4]},al=ag.track.filters_manager.filters,ak;for(var ao=0;ao<al.length;ao++){ak=al[ao];at[ak.name]=aw[ak.index]}var ai=$("<div/>").attr("id",an).addClass("feature-popup"),ax=$("<table/>"),av,au,ay;for(av in at){au=at[av];ay=$("<tr/>").appendTo(ax);$("<th/>").appendTo(ay).text(av);$("<td/>").attr("align","left").appendTo(ay).text(typeof(au)=="number"?Z(au,2):au)}ai.append($("<div class='feature-popup-inner'>").append(ax));af[an]=ai}ai.appendTo($(ag.canvas).parent());var aj=aq+parseInt(ag.canvas.css("left"))-ai.width()/2,ah=ap+parseInt(ag.canvas.css("top"))+7;ai.css("left",aj+"px").css("top",ah+"px")}else{if(!ar.isPropagationStopped()){ar.stopPropagation();$(this).siblings().each(function(){$(this).trigger(ar)})}}}).mouseleave(function(){$(this).siblings(".feature-popup").remove()})};var i=function(ai,aq,aj,am,ar,ah,ag){q.call(this,ai,aq,aj,{},"draghandle");this.data_url=(ah?ah:default_data_url);this.data_url_extra_params={};this.data_query_wait=(ag?ag:L);this.dataset_check_url=converted_datasets_state_url;this.content_visible=true;if(!i.id_counter){i.id_counter=0}this.id=i.id_counter++;this.container_div=$("<div />").addClass("track").attr("id","track_"+this.id).css("position","relative");if(am){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div/>").addClass(this.drag_handle_class).appendTo(this.header_div)}this.name_div=$("<div/>").addClass("track-name").appendTo(this.header_div).text(this.name).attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase());this.icons_div=$("<div/>").css("float","left").appendTo(this.header_div).hide();this.toggle_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Hide/show track content").addClass("icon-button toggle").tipsy({gravity:"s"}).appendTo(this.icons_div);this.settings_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Edit settings").addClass("icon-button settings-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);this.overview_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Set as overview").addClass("icon-button overview-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);this.filters_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Filters").addClass("icon-button filters-icon").tipsy({gravity:"s"}).appendTo(this.icons_div).hide();this.tools_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Tools").addClass("icon-button tools-icon").tipsy({gravity:"s"}).appendTo(this.icons_div).hide();this.remove_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Remove").addClass("icon-button remove-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);var ak=this;this.header_div.dblclick(function(at){at.stopPropagation()});this.toggle_icon.click(function(){if(ak.content_visible){ak.toggle_icon.addClass("toggle-expand").removeClass("toggle");ak.hide_contents();ak.mode_div.hide();ak.content_visible=false}else{ak.toggle_icon.addClass("toggle").removeClass("toggle-expand");ak.content_visible=true;ak.mode_div.show();ak.show_contents()}});this.settings_icon.click(function(){var av=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},at=function(){ak.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},au=function(aw){if((aw.keyCode||aw.which)===27){av()}else{if((aw.keyCode||aw.which)===13){at()}}};$(window).bind("keypress.check_enter_esc",au);show_modal("Configure Track",ak.config.build_form(),{Cancel:av,OK:at})});this.overview_icon.click(function(){ak.view.set_overview(ak)});this.filters_icon.click(function(){ak.filters_div.toggle();ak.filters_manager.reset_filters()});this.tools_icon.click(function(){ak.dynamic_tool_div.toggle();if(ak.dynamic_tool_div.is(":visible")){ak.set_name(ak.name+ak.tool_region_and_parameters_str())}else{ak.revert_name()}$(".tipsy").remove()});this.remove_icon.click(function(){$(".tipsy").remove();ak.remove()});if(ak.display_modes!==undefined){if(ak.mode_div===undefined){ak.mode_div=$("<div class='right-float menubutton popup' />").appendTo(ak.header_div);var al=(ak.config&&ak.config.values.mode?ak.config.values.mode:ak.display_modes[0]);ak.mode=al;ak.mode_div.text(al);var af={};for(var an=0,ap=ak.display_modes.length;an<ap;an++){var ao=ak.display_modes[an];af[ao]=function(at){return function(){ak.change_mode(at)}}(ao)}make_popupmenu(ak.mode_div,af)}else{ak.mode_div.hide()}this.header_div.append($("<div/>").css("clear","both"));this.container_div.hover(function(){ak.icons_div.show()},function(){ak.icons_div.hide()})}}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.container.content_div.append(this.container_div)};p(i.prototype,q.prototype,{get_type:function(){if(this instanceof ab){return"LabelTrack"}else{if(this instanceof A){return"ReferenceTrack"}else{if(this instanceof j){return"LineTrack"}else{if(this instanceof W){return"ReadTrack"}else{if(this instanceof U){return"VcfTrack"}else{if(this instanceof e){return"FeatureTrack"}}}}}}return""},init:function(){var af=this;af.enabled=false;af.tile_cache.clear();af.data_manager.clear();af.initial_canvas=undefined;af.content_div.css("height","auto");af.container_div.removeClass("nodata error pending");if(!af.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:af.hda_ldda,dataset_id:af.dataset_id,chrom:af.view.chrom},function(ag){if(!ag||ag==="error"||ag.kind==="error"){af.container_div.addClass("error");af.content_div.text(o);if(ag.message){var ah=$(" <a href='javascript:void(0);'></a>").text("View error").click(function(){show_modal("Trackster Error","<pre>"+ag.message+"</pre>",{Close:hide_modal})});af.content_div.append(ah)}}else{if(ag==="no converter"){af.container_div.addClass("error");af.content_div.text(K)}else{if(ag==="no data"||(ag.data!==undefined&&(ag.data===null||ag.data.length===0))){af.container_div.addClass("nodata");af.content_div.text(F)}else{if(ag==="pending"){af.container_div.addClass("pending");af.content_div.text(t);setTimeout(function(){af.init()},af.data_query_wait)}else{if(ag.status==="data"){if(ag.valid_chroms){af.valid_chroms=ag.valid_chroms;af.update_icons()}af.content_div.text(Y);if(af.view.chrom){af.content_div.text("");af.content_div.css("height",af.height_px+"px");af.enabled=true;$.when(af.predraw_init()).done(function(){af.container_div.removeClass("nodata error pending");af.request_draw()})}}}}}}});this.update_icons()},hide_contents:function(){this.content_div.children().remove();this.content_div.hide();this.container_div.find(".yaxislabel, .track-resize").hide()},show_contents:function(){this.content_div.show();this.container_div.find(".yaxislabel, .track-resize").show();this.request_draw()},predraw_init:function(){}});var N=function(aj,ah,ag,am,ai,al,ak){i.call(this,aj,ah,ag,am,ai);var af=this,ah=af.view;m(af.container_div,af.drag_handle_class,".group",af);this.filters_manager=new aa(this,(al!==undefined?al:{}));this.filters_available=false;this.filters_visible=false;this.tool=(ak!==undefined&&obj_length(ak)>0?new r(this,ak):undefined);if(this.header_div){if(this.filters_manager){this.filters_div=this.filters_manager.parent_div;this.header_div.after(this.filters_div)}if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}}};p(N.prototype,q.prototype,i.prototype,{copy:function(af){return new this.constructor(this.name,this.view,af,this.hda_ldda,this.dataset_id,this.prefs,this.filters,this.tool)},to_json:function(){return{track_type:this.get_type(),name:this.name,hda_ldda:this.hda_ldda,dataset_id:this.dataset_id,prefs:this.prefs,mode:this.mode,}},change_mode:function(ag){var af=this;af.mode_div.text(ag);af.mode=ag;af.config.values.mode=ag;af.tile_cache.clear();af.request_draw();return af},update_icons:function(){var af=this;if(af.filters_available>0){af.filters_icon.show()}else{af.filters_icon.hide()}if(af.tool){af.tools_icon.show()}else{af.tools_icon.hide()}},_gen_tile_cache_key:function(ag,ah,af){return ag+"_"+ah+"_"+af},request_draw:function(ag,af){this.view.request_redraw(false,ag,af,this)},_draw:function(ah,ap){if(!this.enabled){return}if(!this.content_visible){return}if(!(this instanceof A)&&(!this.dataset_id)){return}var ao=this.view.low,al=this.view.high,am=al-ao,ai=this.view.container.width(),at=ai/am,ak=this.view.resolution,ar=$("<div style='position: relative;'></div>");if(this.is_overview){ao=this.view.max_low;al=this.view.max_high;ak=Math.pow(C,Math.ceil(Math.log((view.max_high-view.max_low)/R)/Math.log(C)));at=ai/(view.max_high-view.max_low)}if(!ap){this.content_div.children().remove()}this.content_div.append(ar);this.max_height=0;var ag=Math.floor(ao/ak/R);var an=true;var aq=[];var af=0;while((ag*R*ak)<al){tile=this.draw_helper(ah,ai,ag,ak,ar,at);if(tile){aq.push(tile)}else{an=false}ag+=1;af++}var aj=this;if(an){aj.postdraw_actions(aq,ai,at,ap)}},postdraw_actions:function(aj,ak,al,af){var ah=this;var ai=false;for(var ag=0;ag<aj.length;ag++){if(aj[ag].message){ai=true;break}}if(ai){for(var ag=0;ag<aj.length;ag++){tile=aj[ag];if(!tile.message){tile.canvas.css("padding-top",E)}}}},draw_helper:function(ag,ah,ai,al,ar,aw,at,am){var aj=this,aq=this._gen_tile_cache_key(ah,aw,ai),an=ai*R*al,av=an+R*al;var ao=(ag?undefined:aj.tile_cache.get(aq));if(ao){aj.show_tile(ao,ar,aw);return ao}var ap=function(ax){return("isResolved" in ax)};var ak=true;var af=aj.data_manager.get_data(an,av,aj.mode,al,aj.data_url_extra_params);if(ap(af)){ak=false}var au;if(view.reference_track&&aw>view.canvas_manager.char_width_px){au=view.reference_track.data_manager.get_data(an,av,aj.mode,al,view.reference_track.data_url_extra_params);if(ap(au)){ak=false}}if(ak){p(af,am);var ao=aj.draw_tile(af,aj.mode,al,ai,aw,au);if(ao!==undefined){aj.tile_cache.set(aq,ao);aj.show_tile(ao,ar,aw)}return ao}$.when(af,au).then(function(){view.request_redraw(false,false,false,aj)});return null},show_tile:function(al,an,ao){var ah=this,ag=al.canvas,ak=ag;if(al.message){var ap=$("<div/>"),am=$("<div/>").addClass("tile-message").text(al.message).css({height:E-1,width:al.canvas.width}).appendTo(ap),aj=$("<a href='javascript:void(0);'/>").addClass("icon more-down").appendTo(am),af=$("<a href='javascript:void(0);'/>").addClass("icon more-across").appendTo(am);ap.append(ag);ak=ap;aj.click(function(){al.stale=true;ah.data_manager.get_more_data(al.low,al.high,ah.mode,al.resolution,{},ah.data_manager.DEEP_DATA_REQ);ah.request_draw()}).dblclick(function(aq){aq.stopPropagation()});af.click(function(){al.stale=true;ah.data_manager.get_more_data(al.low,al.high,ah.mode,al.resolution,{},ah.data_manager.BROAD_DATA_REQ);ah.request_draw()}).dblclick(function(aq){aq.stopPropagation()})}al.predisplay_actions();var ai=(al.low-(this.is_overview?this.view.max_low:this.view.low))*ao;if(this.left_offset){ai-=this.left_offset}ak.css({position:"absolute",top:0,left:ai,height:""});an.append(ak);ah.max_height=Math.max(ah.max_height,ak.height());ah.content_div.css("height",ah.max_height+"px");an.children().css("height",ah.max_height+"px")},_get_tile_bounds:function(af,ag){var ai=af*R*ag,aj=R*ag,ah=(ai+aj<=this.view.max_high?ai+aj:this.view.max_high);return[ai,ah]},tool_region_and_parameters_str:function(ah,af,ai){var ag=this,aj=(ah!==undefined&&af!==undefined&&ai!==undefined?ah+":"+af+"-"+ai:"all");return" - region=["+aj+"], parameters=["+ag.tool.get_param_values().join(", ")+"]"},init_for_tool_data:function(){this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url;this.predraw_init=function(){var ag=this;var af=function(){if(ag.data_manager.size()===0){setTimeout(af,300)}else{ag.data_url=default_data_url;ag.data_query_wait=L;ag.dataset_state_url=converted_datasets_state_url;$.getJSON(ag.dataset_state_url,{dataset_id:ag.dataset_id,hda_ldda:ag.hda_ldda},function(ah){})}};af()}}});var ab=function(ag,af){i.call(this,"label",ag,af,false,{});this.container_div.addClass("label-track")};p(ab.prototype,i.prototype,{init:function(){this.enabled=true},_draw:function(){var ah=this.view,ai=ah.high-ah.low,al=Math.floor(Math.pow(10,Math.floor(Math.log(ai)/Math.log(10)))),af=Math.floor(ah.low/al)*al,aj=this.view.container.width(),ag=$("<div style='position: relative; height: 1.3em;'></div>");while(af<ah.high){var ak=(af-ah.low)/ai*aj;ag.append($("<div class='label'>"+commatize(af)+"</div>").css({position:"absolute",left:ak-1}));af+=al}this.content_div.children(":first").remove();this.content_div.append(ag)}});var A=function(af){N.call(this,"reference",af,{content_div:af.top_labeltrack},false,{});af.reference_track=this;this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:af.dbkey};this.data_manager=new I(B,this,false);this.tile_cache=new c(u)};p(A.prototype,q.prototype,N.prototype,{init:function(){this.enabled=true},draw_tile:function(ap,al,ak,ag,aq){var aj=this,ah=R*ak;if(aq>this.view.canvas_manager.char_width_px){if(ap.data===null){aj.content_div.css("height","0px");return}var ai=this.view.canvas_manager.new_canvas();var ao=ai.getContext("2d");ai.width=Math.ceil(ah*aq+aj.left_offset);ai.height=aj.height_px;ao.font=ao.canvas.manager.default_font;ao.textAlign="center";ap=ap.data;for(var am=0,an=ap.length;am<an;am++){var af=Math.round(am*aq);ao.fillText(ap[am],af+aj.left_offset,10)}return new b(aj,ag,ak,ai,ap)}this.content_div.css("height","0px")}});var j=function(ak,ai,ah,al,af,aj){var ag=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";N.call(this,ak,ai,ah,true,aj);this.min_height_px=16;this.max_height_px=400;this.height_px=32;this.hda_ldda=al;this.dataset_id=af;this.original_dataset_id=af;this.data_manager=new S(B,this);this.tile_cache=new c(u);this.left_offset=0;this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ak},{key:"color",label:"Color",type:"color",default_value:get_random_color()},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.height_px,hidden:true}],saved_values:aj,onchange:function(){ag.set_name(ag.prefs.name);ag.vertical_range=ag.prefs.max_value-ag.prefs.min_value;$("#linetrack_"+ag.dataset_id+"_minval").text(ag.prefs.min_value);$("#linetrack_"+ag.dataset_id+"_maxval").text(ag.prefs.max_value);ag.tile_cache.clear();ag.request_draw()}});this.prefs=this.config.values;this.height_px=this.config.values.height;this.vertical_range=this.config.values.max_value-this.config.values.min_value;this.add_resize_handle()};p(j.prototype,q.prototype,N.prototype,{add_resize_handle:function(){var af=this;var ai=false;var ah=false;var ag=$("<div class='track-resize'>");$(af.container_div).hover(function(){if(af.content_visible){ai=true;ag.show()}},function(){ai=false;if(!ah){ag.hide()}});ag.hide().bind("dragstart",function(aj,ak){ah=true;ak.original_height=$(af.content_div).height()}).bind("drag",function(ak,al){var aj=Math.min(Math.max(al.original_height+al.deltaY,af.min_height_px),af.max_height_px);$(af.content_div).css("height",aj);af.height_px=aj;af.request_draw(true)}).bind("dragend",function(aj,ak){af.tile_cache.clear();ah=false;if(!ai){ag.hide()}af.config.values.height=af.height_px}).appendTo(af.container_div)},predraw_init:function(){var af=this;af.vertical_range=undefined;return $.getJSON(af.data_url,{stats:true,chrom:af.view.chrom,low:null,high:null,hda_ldda:af.hda_ldda,dataset_id:af.dataset_id},function(ag){af.container_div.addClass("line-track");var aj=ag.data;if(isNaN(parseFloat(af.prefs.min_value))||isNaN(parseFloat(af.prefs.max_value))){var ah=aj.min;var al=aj.max;ah=Math.floor(Math.min(0,Math.max(ah,aj.mean-2*aj.sd)));al=Math.ceil(Math.max(0,Math.min(al,aj.mean+2*aj.sd)));af.prefs.min_value=ah;af.prefs.max_value=al;$("#track_"+af.dataset_id+"_minval").val(af.prefs.min_value);$("#track_"+af.dataset_id+"_maxval").val(af.prefs.max_value)}af.vertical_range=af.prefs.max_value-af.prefs.min_value;af.total_frequency=aj.total_frequency;af.container_div.find(".yaxislabel").remove();var ak=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+af.dataset_id+"_minval").text(Z(af.prefs.min_value,3));var ai=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+af.dataset_id+"_maxval").text(Z(af.prefs.max_value,3));ai.css({position:"absolute",top:"24px",left:"10px"});ai.prependTo(af.container_div);ak.css({position:"absolute",bottom:"2px",left:"10px"});ak.prependTo(af.container_div)})},draw_tile:function(ar,ak,aj,ah,aq){if(this.vertical_range===undefined){return}var af=this._get_tile_bounds(ah,aj),al=af[0],ap=af[1],ag=Math.ceil((ap-al)*aq),an=this.height_px;var ai=this.view.canvas_manager.new_canvas();ai.width=ag,ai.height=an;var ao=ai.getContext("2d");var am=new M.LinePainter(ar.data,al,ap,this.prefs,ak);am.draw(ao,ag,an);return new b(this.track,ah,aj,ai,ar.data)}});var e=function(af,al,ag,ak,an,am,ai,aj){var ah=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];N.call(this,af,al,ag,true,am,ai,aj);this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:af},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true,help:"Show the number of items in each bin when drawing summary histogram"},{key:"connector_style",label:"Connector style",type:"select",default_value:"fishbones",options:[{label:"Line with arrows",value:"fishbone"},{label:"Arcs",value:"arcs"}]},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:am,onchange:function(){ah.set_name(ah.prefs.name);ah.tile_cache.clear();ah.set_painter_from_config();ah.request_draw()}});this.prefs=this.config.values;this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=ak;this.dataset_id=an;this.original_dataset_id=an;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.inc_slots={};this.start_end_dct={};this.tile_cache=new c(d);this.data_manager=new S(20,this);this.left_offset=200;this.set_painter_from_config()};p(e.prototype,q.prototype,N.prototype,{set_painter_from_config:function(){if(this.config.values.connector_style=="arcs"){this.painter=M.ArcLinkedFeaturePainter}else{this.painter=M.LinkedFeaturePainter}},postdraw_actions:function(av,af,aw,au){N.prototype.postdraw_actions.call(this,av,au);var ai=this;if(au){var ak=ai.content_div.children();var al=false;for(var aj=ak.length-1,ap=0;aj>=ap;aj--){var ah=$(ak[aj]);if(al){ah.remove()}else{if(ah.children().length!==0){al=true}}}}if(ai.mode=="Histogram"){var ao=-1;for(var aj=0;aj<av.length;aj++){var at=av[aj].max_val;if(at>ao){ao=at}}for(var aj=0;aj<av.length;aj++){var ar=av[aj];if(ar.max_val!==ao){ar.canvas.remove();ai.draw_helper(true,af,ar.index,ar.resolution,ar.canvas.parent(),aw,[],{max:ao})}}}if(ai.filters_manager){var ag=ai.filters_manager.filters;for(var an=0;an<ag.length;an++){ag[an].update_ui_elt()}var am=false,aq;for(var aj=0;aj<av.length;aj++){if(av[aj].data.length){aq=av[aj].data[0];for(var an=0;an<ag.length;an++){if(ag[an].applies_to(aq)){am=true;break}}}}if(ai.filters_available!==am){ai.filters_available=am;if(!ai.filters_available){ai.filters_div.hide()}ai.update_icons()}}},update_auto_mode:function(af){if(this.mode=="Auto"){if(af=="no_detail"){af="feature spans"}else{if(af=="summary_tree"){af="coverage histogram"}}this.mode_div.text("Auto ("+af+")")}},incremental_slots:function(aj,ag,ai){var ah=this.view.canvas_manager.dummy_context,af=this.inc_slots[aj];if(!af||(af.mode!==ai)){af=new (s.FeatureSlotter)(aj,ai==="Pack",z,function(ak){return ah.measureText(ak)});af.mode=ai;this.inc_slots[aj]=af}return af.slot_features(ag)},get_summary_tree_data:function(aj,am,ah,av){if(av>ah-am){av=ah-am}var aq=Math.floor((ah-am)/av),au=[],ai=0;var ak=0,al=0,ap,at=0,an=[],ar,ao;var ag=function(ay,ax,az,aw){ay[0]=ax+az*aw;ay[1]=ax+(az+1)*aw};while(at<av&&ak!==aj.length){var af=false;for(;at<av&&!af;at++){ag(an,am,at,aq);for(al=ak;al<aj.length;al++){ap=aj[al].slice(1,3);if(is_overlap(ap,an)){af=true;break}}if(af){break}}data_start_index=al;au[au.length]=ar=[an[0],0];for(;al<aj.length;al++){ap=aj[al].slice(1,3);if(is_overlap(ap,an)){ar[1]++}else{break}}if(ar[1]>ai){ai=ar[1]}at++}return{max:ai,delta:aq,data:au}},draw_tile:function(au,ax,aB,aF,ap,ai){var ay=this,ak=ay._get_tile_bounds(aF,aB),aI=ak[0],ag=ak[1],aw=ag-aI,az=Math.ceil(aw*ap),aO=25,aj=this.left_offset,av,al;if(ax==="Auto"){if(au.dataset_type==="summary_tree"){ax=au.dataset_type}else{if(au.extra_info==="no_detail"||ay.is_overview){ax="no_detail"}else{var aN=au.data;if(this.view.high-this.view.low>J){ax="Squish"}else{ax="Pack"}}}this.update_auto_mode(ax)}if(ax==="summary_tree"||ax==="Histogram"){al=this.summary_draw_height;this.container_div.find(".yaxislabel").remove();var af=$("<div />").addClass("yaxislabel");af.text(au.max);af.css({position:"absolute",top:"24px",left:"10px",color:this.prefs.label_color});af.prependTo(this.container_div);var ah=this.view.canvas_manager.new_canvas();ah.width=az+aj;ah.height=al+T;if(au.dataset_type!="summary_tree"){var aq=this.get_summary_tree_data(au.data,aI,ag,200);if(au.max){aq.max=au.max}au=aq}var aK=new M.SummaryTreePainter(au,aI,ag,this.prefs);var aA=ah.getContext("2d");aA.translate(aj,T);aK.draw(aA,az,al);return new k(ay,aF,aB,ah,au.data,au.max)}var av,an=1;if(ax==="no_detail"||ax==="Squish"||ax==="Pack"){an=this.incremental_slots(ap,au.data,ax);av=this.inc_slots[ap].slots}var ao=[];if(au.data){var ar=this.filters_manager.filters;for(var aC=0,aE=au.data.length;aC<aE;aC++){var am=au.data[aC];var aD=false;var at;for(var aH=0,aM=ar.length;aH<aM;aH++){at=ar[aH];at.update_attrs(am);if(!at.keep(am)){aD=true;break}}if(!aD){ao.push(am)}}}var aL=(this.filters_manager.alpha_filter?new D(this.filters_manager.alpha_filter):null);var aJ=(this.filters_manager.height_filter?new D(this.filters_manager.height_filter):null);var aK=new (this.painter)(ao,aI,ag,this.prefs,ax,aL,aJ,ai);var al=Math.max(ad,aK.get_required_height(an,az));var ah=this.view.canvas_manager.new_canvas();var aG=null;ah.width=az+aj;ah.height=al;var aA=ah.getContext("2d");aA.fillStyle=this.prefs.block_color;aA.font=aA.canvas.manager.default_font;aA.textAlign="right";this.container_div.find(".yaxislabel").remove();if(au.data){aA.translate(aj,0);aG=aK.draw(aA,az,al,av);aG.translation=-aj}return new P(ay,aF,aB,ah,au.data,ax,au.message,aG)}});var U=function(ak,ah,ag,am,af,aj,al,ai){e.call(this,ak,ah,ag,am,af,aj,al,ai);this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ak},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:aj,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=M.ReadPainter};p(U.prototype,q.prototype,N.prototype,e.prototype);var W=function(af,ak,ag,aj,an,am,ah){e.call(this,af,ak,ag,aj,an,am,ah);var ai=get_random_color(),al=get_random_color([ai,"#ffffff"]);this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:af},{key:"block_color",label:"Block and sense strand color",type:"color",default_value:ai},{key:"reverse_strand_color",label:"Antisense strand color",type:"color",default_value:al},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:am,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=M.ReadPainter;this.update_icons()};p(W.prototype,q.prototype,N.prototype,e.prototype);X.View=ac;X.DrawableGroup=Q;X.LineTrack=j;X.FeatureTrack=e;X.ReadTrack=W;X.VcfTrack=U};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(i,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=i;this.include_label=h;this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,s=this.slots,h=this.start_end_dct,y=[],A=[],n=0,z=this.max_rows;for(var w=0,x=m.length;w<x;w++){var l=m[w],o=l[0];if(s[o]!==undefined){n=Math.max(n,s[o]);A.push(s[o])}else{y.push(w)}}var q=function(F,G){for(var E=0;E<=z;E++){var C=false,H=h[E];if(H!==undefined){for(var B=0,D=H.length;B<D;B++){var i=H[B];if(G>i[0]&&F<i[1]){C=true;break}}}if(!C){return E}}return -1};for(var w=0,x=y.length;w<x;w++){var l=m[y[w]],o=l[0],u=l[1],f=l[2],r=l[3],g=Math.floor(u*p),k=Math.ceil(f*p),v=this.measureText(r).width,j;if(r!==undefined&&this.include_label){v+=(d+a);if(g-v>=0){g-=v;j="left"}else{k+=v;j="right"}}var t=q(g,k);if(t>=0){if(h[t]===undefined){h[t]=[]}h[t].push([g,k]);s[o]=t;n=Math.max(n,t)}else{}}return n+1}})};var painters_module=function(i,x){var u=i("class").extend;var p=function(I,A,G,z,F,D){if(D===undefined){D=4}var C=z-A;var B=F-G;var E=Math.floor(Math.sqrt(C*C+B*B)/D);var J=C/E;var H=B/E;var y;for(y=0;y<E;y++,A+=J,G+=H){if(y%2!==0){continue}I.fillRect(A,G,D,1)}};var q=function(B,A,z,E){var D=A-E/2,C=A+E/2,F=z-Math.sqrt(E*3/2);B.beginPath();B.moveTo(D,F);B.lineTo(C,F);B.lineTo(A,z);B.lineTo(D,F);B.strokeStyle=this.fillStyle;B.fill();B.stroke();B.closePath()};var d=function(y){this.default_val=(y?y:1)};d.prototype.gen_val=function(y){return this.default_val};var l=function(A,C,y,z,B){this.data=A;this.view_start=C;this.view_end=y;this.prefs=u({},this.default_prefs,z);this.mode=B};l.prototype.default_prefs={};var v=function(A,C,y,z,B){l.call(this,A,C,y,z,B)};v.prototype.default_prefs={show_counts:false};v.prototype.draw=function(M,z,L){var E=this.view_start,O=this.view_end-this.view_start,N=z/O;var J=this.data.data,I=this.data.delta,G=this.data.max,B=L;delta_x_px=Math.ceil(I*N);M.save();for(var C=0,D=J.length;C<D;C++){var H=Math.floor((J[C][0]-E)*N);var F=J[C][1];if(!F){continue}var K=F/G*L;if(F!==0&&K<1){K=1}M.fillStyle=this.prefs.block_color;M.fillRect(H,B-K,delta_x_px,K);var A=4;if(this.prefs.show_counts&&(M.measureText(F).width+A)<delta_x_px){M.fillStyle=this.prefs.label_color;M.textAlign="center";M.fillText(F,H+(delta_x_px/2),10)}}M.restore()};var b=function(y,C,E,F,A){l.call(this,y,C,E,F,A);if(this.prefs.min_value===undefined){var G=Infinity;for(var z=0,B=this.data.length;z<B;z++){G=Math.min(G,this.data[z][1])}this.prefs.min_value=G}if(this.prefs.max_value===undefined){var D=-Infinity;for(var z=0,B=this.data.length;z<B;z++){D=Math.max(D,this.data[z][1])}this.prefs.max_value=D}};b.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};b.prototype.draw=function(N,M,K){var F=false,H=this.prefs.min_value,D=this.prefs.max_value,J=D-H,z=K,A=this.view_start,L=this.view_end-this.view_start,B=M/L,I=this.mode,T=this.data;N.save();var U=Math.round(K+H/J*K);if(I!=="Intensity"){N.fillStyle="#aaa";N.fillRect(0,U,M,1)}N.beginPath();var R,E,C;if(T.length>1){C=Math.ceil((T[1][0]-T[0][0])*B)}else{C=10}for(var O=0,P=T.length;O<P;O++){N.fillStyle=this.prefs.color;R=Math.round((T[O][0]-A)*B);E=T[O][1];var Q=false,G=false;if(E===null){if(F&&I==="Filled"){N.lineTo(R,z)}F=false;continue}if(E<H){G=true;E=H}else{if(E>D){Q=true;E=D}}if(I==="Histogram"){E=Math.round(E/J*z);N.fillRect(R,U,C,-E)}else{if(I==="Intensity"){E=255-Math.floor((E-H)/J*255);N.fillStyle="rgb("+E+","+E+","+E+")";N.fillRect(R,0,C,z)}else{E=Math.round(z-(E-H)/J*z);if(F){N.lineTo(R,E)}else{F=true;if(I==="Filled"){N.moveTo(R,z);N.lineTo(R,E)}else{N.moveTo(R,E)}}}}N.fillStyle=this.prefs.overflow_color;if(Q||G){var S;if(I==="Histogram"||I==="Intensity"){S=C}else{R-=2;S=4}if(Q){N.fillRect(R,0,S,3)}if(G){N.fillRect(R,z-3,S,3)}}N.fillStyle=this.prefs.color}if(I==="Filled"){if(F){N.lineTo(R,U);N.lineTo(0,U)}N.fill()}else{N.stroke()}N.restore()};var m=function(y){this.feature_positions={};this.slot_height=y;this.translation=0;this.y_translation=0};m.prototype.map_feature_data=function(z,B,y,A){if(!this.feature_positions[B]){this.feature_positions[B]=[]}this.feature_positions[B].push({data:z,x_start:y,x_end:A})};m.prototype.get_feature_data=function(z,D){var C=Math.floor((D-this.y_translation)/this.slot_height),B;if(!this.feature_positions[C]){return null}z+=this.translation;for(var A=0;A<this.feature_positions[C].length;A++){B=this.feature_positions[C][A];if(z>=B.x_start&&z<=B.x_end){return B.data}}};var o=function(A,D,y,z,C,E,B){l.call(this,A,D,y,z,C);this.alpha_scaler=(E?E:new d());this.height_scaler=(B?B:new d())};o.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};u(o.prototype,{get_required_height:function(A,z){var y=y_scale=this.get_row_height(),B=this.mode;if(B==="no_detail"||B==="Squish"||B==="Pack"){y=A*y_scale}return y+this.get_top_padding(z)+this.get_bottom_padding(z)},get_top_padding:function(y){return 0},get_bottom_padding:function(y){return Math.max(Math.round(this.get_row_height()/2),5)},draw:function(K,I,G,F){var Q=this.data,D=this.view_start,M=this.view_end;K.save();K.fillStyle=this.prefs.block_color;K.textAlign="right";var H=this.view_end-this.view_start,E=I/H,L=this.get_row_height(),P=new m(L),B;for(var N=0,O=Q.length;N<O;N++){var A=Q[N],C=A[0],J=A[1],y=A[2],z=(F&&F[C]!==undefined?F[C]:null);if((J<M&&y>D)&&(this.mode=="Dense"||z!==null)){B=this.draw_element(K,this.mode,A,z,D,M,E,L,I);P.map_feature_data(A,z,B[0],B[1])}}K.restore();P.y_translation=this.get_top_padding(I);return P},draw_element:function(E,A,G,C,B,D,F,z,y){console.log("WARNING: Unimplemented function.");return[0,0]}});var c=10,h=3,k=5,w=10,f=1,s=9,e=3,a=9,j=2,g="#ccc";var r=function(A,D,y,z,C,E,B){o.call(this,A,D,y,z,C,E,B);this.draw_background_connector=true;this.draw_individual_connectors=false};u(r.prototype,o.prototype,{get_row_height:function(){var z=this.mode,y;if(z==="Dense"){y=c}else{if(z==="no_detail"){y=h}else{if(z==="Squish"){y=k}else{y=w}}}return y},draw_element:function(M,D,X,H,O,aj,an,ap,y){var T=X[0],al=X[1],ad=X[2],Q=X[3],ae=Math.floor(Math.max(0,(al-O)*an)),N=Math.ceil(Math.min(y,Math.max(0,(ad-O)*an))),ac=ae,ao=N,aa=(D==="Dense"?0:(0+H))*ap+this.get_top_padding(y),L,ah,R=null,ar=null,B=this.prefs.block_color,ag=this.prefs.label_color;M.globalAlpha=this.alpha_scaler.gen_val(X);if(D==="Dense"){H=1}if(D==="no_detail"){M.fillStyle=B;M.fillRect(ae,aa+5,N-ae,f)}else{var K=X[4],Z=X[5],af=X[6],C=X[7],V=true;if(Z&&af){R=Math.floor(Math.max(0,(Z-O)*an));ar=Math.ceil(Math.min(y,Math.max(0,(af-O)*an)))}var am,U;if(D==="Squish"){am=1;U=e;V=false}else{if(D==="Dense"){am=5;U=s}else{am=5;U=a}}if(!C){M.fillStyle=B;M.fillRect(ae,aa+1,N-ae,U);if(K&&V){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand_inv")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand_inv")}}M.fillRect(ae,aa+1,N-ae,U)}}else{var J,W;if(D==="Squish"||D==="Dense"){J=aa+Math.floor(e/2)+1;W=1}else{if(K){J=aa;W=U}else{J+=(e/2)+1;W=1}}if(this.draw_background_connector){if(D==="Squish"||D==="Dense"){M.fillStyle=g}else{if(K){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand")}}}else{M.fillStyle=g}}M.fillRect(ae,J,N-ae,W)}var E;for(var ak=0,A=C.length;ak<A;ak++){var F=C[ak],z=Math.floor(Math.max(0,(F[0]-O)*an)),Y=Math.ceil(Math.min(y,Math.max((F[1]-O)*an))),S,ab;if(z>Y){continue}M.fillStyle=B;M.fillRect(z,aa+(U-am)/2+1,Y-z,am);if(R!==undefined&&af>Z&&!(z>ar||Y<R)){var ai=Math.max(z,R),I=Math.min(Y,ar);M.fillRect(ai,aa+1,I-ai,U);if(C.length==1&&D=="Pack"){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand_inv")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand_inv")}}if(ai+14<I){ai+=2;I-=2}M.fillRect(ai,aa+1,I-ai,U)}}if(this.draw_individual_connectors&&S){this.draw_connector(M,S,ab,z,Y,aa)}S=z;ab=Y}if(D==="Pack"){M.globalAlpha=1;M.fillStyle="white";var G=this.height_scaler.gen_val(X),P=Math.ceil(U*G),aq=Math.round((U-P)/2);if(G!==1){M.fillRect(ae,J+1,N-ae,aq);M.fillRect(ae,J+U-aq+1,N-ae,aq)}}}M.globalAlpha=1;if(D==="Pack"&&al>O){M.fillStyle=ag;if(O===0&&ae-M.measureText(Q).width<0){M.textAlign="left";M.fillText(Q,N+j,aa+8);ao+=M.measureText(Q).width+j}else{M.textAlign="right";M.fillText(Q,ae-j,aa+8);ac-=M.measureText(Q).width+j}}}M.globalAlpha=1;return[ac,ao]}});var t=function(B,E,y,A,D,F,C,z){o.call(this,B,E,y,A,D,F,C);this.ref_seq=(z?z.data:null)};u(t.prototype,o.prototype,{get_row_height:function(){var y,z=this.mode;if(z==="Dense"){y=c}else{if(z==="Squish"){y=k}else{y=w;if(this.prefs.show_insertions){y*=2}}}return y},draw_read:function(K,A,ag,V,L,aa,ad,C,B,M){K.textAlign="center";var J=this,R=[L,aa],Z=0,W=0,D=0,F=K.canvas.manager.char_width_px,y=(B==="+"?this.prefs.block_color:this.prefs.reverse_strand_color);var O=[];if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){D=Math.round(ag/2)}if(!C){C=[[0,M.length]]}for(var G=0,I=C.length;G<I;G++){var z=C[G],E="MIDNSHP=X"[z[0]],S=z[1];if(E==="H"||E==="S"){Z-=S}var U=ad+Z,Y=Math.floor(Math.max(0,(U-L)*ag)),ab=Math.floor(Math.max(0,(U+S-L)*ag));if(Y===ab){ab+=1}switch(E){case"H":break;case"S":case"M":case"=":if(is_overlap([U,U+S],R)){var N=M.slice(W,W+S);if(D>0){K.fillStyle=y;K.fillRect(Y-D,V+1,ab-Y,9);K.fillStyle=g;for(var af=0,H=N.length;af<H;af++){if(this.prefs.show_differences&&this.ref_seq){var P=this.ref_seq[U-L+af];if(!P||P.toLowerCase()===N[af].toLowerCase()){continue}}if(U+af>=L&&U+af<=aa){var X=Math.floor(Math.max(0,(U+af-L)*ag));K.fillText(N[af],X,V+9)}}}else{K.fillStyle=y;K.fillRect(Y,V+4,ab-Y,e)}}W+=S;Z+=S;break;case"N":K.fillStyle=g;K.fillRect(Y-D,V+5,ab-Y,1);Z+=S;break;case"D":K.fillStyle="red";K.fillRect(Y-D,V+4,ab-Y,3);Z+=S;break;case"P":break;case"I":var ah=Y-D;if(is_overlap([U,U+S],R)){var N=M.slice(W,W+S);if(this.prefs.show_insertions){var T=Y-(ab-Y)/2;if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){K.fillStyle="yellow";K.fillRect(T-D,V-9,ab-Y,9);O[O.length]={type:"triangle",data:[ah,V+4,5]};K.fillStyle=g;switch(compute_overlap([U,U+S],R)){case (OVERLAP_START):N=N.slice(L-U);break;case (OVERLAP_END):N=N.slice(0,U-aa);break;case (CONTAINED_BY):break;case (CONTAINS):N=N.slice(L-U,U-aa);break}for(var af=0,H=N.length;af<H;af++){var X=Math.floor(Math.max(0,(U+af-L)*ag));K.fillText(N[af],X-(ab-Y)/2,V)}}else{K.fillStyle="yellow";K.fillRect(T,V+(this.mode!=="Dense"?2:5),ab-Y,(A!=="Dense"?e:s))}}else{if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){O.push({type:"text",data:[N.length,ah,V+9]})}else{}}}W+=S;break;case"X":W+=S;break}}K.fillStyle="yellow";var Q,ai,ae;for(var ac=0;ac<O.length;ac++){Q=O[ac];ai=Q.type;ae=Q.data;if(ai==="text"){K.save();K.font="bold "+K.font;K.fillText(ae[0],ae[1],ae[2]);K.restore()}else{if(ai=="triangle"){q(K,ae[0],ae[1],ae[2])}}}},draw_element:function(R,M,E,B,U,z,I,S,P){var H=E[0],Q=E[1],A=E[2],J=E[3],D=Math.floor(Math.max(0,(Q-U)*I)),F=Math.ceil(Math.min(P,Math.max(0,(A-U)*I))),C=(M==="Dense"?0:(0+B))*S,G=this.prefs.label_color,O=0;if((M==="Pack"||this.mode==="Auto")&&I>R.canvas.manager.char_width_px){var O=Math.round(I/2)}if(E[5] instanceof Array){var N=Math.floor(Math.max(0,(E[4][0]-U)*I)),L=Math.ceil(Math.min(P,Math.max(0,(E[4][1]-U)*I))),K=Math.floor(Math.max(0,(E[5][0]-U)*I)),y=Math.ceil(Math.min(P,Math.max(0,(E[5][1]-U)*I)));if(E[4][1]>=U&&E[4][0]<=z&&E[4][2]){this.draw_read(R,M,I,C,U,z,E[4][0],E[4][2],E[4][3],E[4][4])}if(E[5][1]>=U&&E[5][0]<=z&&E[5][2]){this.draw_read(R,M,I,C,U,z,E[5][0],E[5][2],E[5][3],E[5][4])}if(K>L){R.fillStyle=g;p(R,L-O,C+5,K-O,C+5)}}else{this.draw_read(R,M,I,C,U,z,Q,E[4],E[5],E[6])}if(M==="Pack"&&Q>U&&J!=="."){R.fillStyle=this.prefs.label_color;var T=1;if(T===0&&D-R.measureText(J).width<0){R.textAlign="left";R.fillText(J,F+j-O,C+8)}else{R.textAlign="right";R.fillText(J,D-j-O,C+8)}}return[0,0]}});var n=function(A,D,y,z,C,E,B){r.call(this,A,D,y,z,C,E,B);this.longest_feature_length=this.calculate_longest_feature_length();this.draw_background_connector=false;this.draw_individual_connectors=true};u(n.prototype,o.prototype,r.prototype,{calculate_longest_feature_length:function(){var z=0;for(var C=0,y=this.data.length;C<y;C++){var B=this.data[C],A=B[1],D=B[2];z=Math.max(z,D-A)}return z},get_top_padding:function(z){var y=this.view_end-this.view_start,A=z/y;return Math.min(128,Math.ceil((this.longest_feature_length/2)*A))},draw_connector:function(G,B,F,H,E,D){var y=(F+H)/2,C=H-y;var A=Math.PI,z=0;if(C>0){G.beginPath();G.arc(y,D,H-y,Math.PI,0);G.stroke()}}});x.Scaler=d;x.SummaryTreePainter=v;x.LinePainter=b;x.LinkedFeaturePainter=r;x.ReadPainter=t;x.ArcLinkedFeaturePainter=n};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("class",class_module);a("slotting",slotting_module);a("painters",painters_module);a("trackster",trackster_module);for(key in c.trackster){d[key]=c.trackster[key]}})(window);
\ No newline at end of file
diff -r a4df07ccecdb70ae45982e596d2e360bdc9ab217 -r 23198e766859394108d48de1489be7052530d38b static/scripts/packed/trackster_ui.js
--- a/static/scripts/packed/trackster_ui.js
+++ b/static/scripts/packed/trackster_ui.js
@@ -1,1 +1,1 @@
-var add_bookmark=function(b,a){var g=$("#bookmarks-container"),d=$("<div/>").addClass("bookmark").appendTo(g),c=$("<div/>").addClass("delete-icon-container").appendTo(d).click(function(){d.slideUp("fast");d.remove();view.has_changes=true;return false}),e=$("<a href=''/>").addClass("icon-button delete").appendTo(c),f=$("<div/>").addClass("position").appendTo(d),h=$("<a href=''/>").text(b).appendTo(f).click(function(){view.go_to(b);return false});annotation_div=get_editable_text_elt(a,true).addClass("annotation").appendTo(d);view.has_changes=true;return d};var addable_objects={LineTrack:LineTrack,FeatureTrack:FeatureTrack,VcfTrack:VcfTrack,ReadTrack:ReadTrack,DrawableGroup:DrawableGroup};var track_from_dict=function(c,b){var a=new addable_objects[c.track_type](c.name,view,b,c.hda_ldda,c.dataset_id,c.prefs,c.filters,c.tool);if(c.mode){a.change_mode(c.mode)}return a};var drawable_collection_from_dict=function(f,a){var e=new addable_objects[f.obj_type](f.name,view,a,f.prefs,view.viewport_container,view);for(var d=0;d<f.drawables.length;d++){var b=f.drawables[d],c;if(b.track_type){c=track_from_dict(b,e)}else{c=drawable_collection_from_dict(b)}e.add_drawable(c);e.content_div.append(c.container_div)}return e};var drawable_from_dict=function(b,a){return(b.track_type?track_from_dict(b,a):drawable_collection_from_dict(b,a))};var create_visualization=function(b,e,g,c,a,d,f){view=new View(b,e,g,c);view.editor=true;$.when(view.load_chroms_deferred).then(function(){if(a){var k=a.chrom,p=a.start,h=a.end,m=a.overview;if(k&&(p!==undefined)&&h){view.change_chrom(k,p,h)}}if(d){var o;for(var j=0;j<d.length;j++){o=d[j];view.add_drawable(drawable_from_dict(o,view))}}var n;for(var j=0;j<view.drawables.length;j++){if(view.drawables[j].name===m){view.set_overview(view.drawables[j]);break}}if(f){var l;for(var j=0;j<f.length;j++){l=f[j];add_bookmark(l.position,l.annotation)}}view.has_changes=false});return view};var init_keyboard_nav=function(a){$(document).keydown(function(b){if($(b.srcElement).is(":input")){return}switch(b.which){case 37:a.move_fraction(0.25);break;case 38:var c=Math.round(a.viewport_container.height()/15);a.viewport_container.scrollTo("-="+c+"px");break;case 39:a.move_fraction(-0.25);break;case 40:var c=Math.round(a.viewport_container.height()/15);a.viewport_container.scrollTo("+="+c+"px");break}})};
\ No newline at end of file
+var add_bookmark=function(b,a){var g=$("#bookmarks-container"),d=$("<div/>").addClass("bookmark").appendTo(g),c=$("<div/>").addClass("delete-icon-container").appendTo(d).click(function(){d.slideUp("fast");d.remove();view.has_changes=true;return false}),e=$("<a href=''/>").addClass("icon-button delete").appendTo(c),f=$("<div/>").addClass("position").appendTo(d),h=$("<a href=''/>").text(b).appendTo(f).click(function(){view.go_to(b);return false});annotation_div=get_editable_text_elt(a,true).addClass("annotation").appendTo(d);view.has_changes=true;return d};var addable_objects={LineTrack:LineTrack,FeatureTrack:FeatureTrack,VcfTrack:VcfTrack,ReadTrack:ReadTrack,DrawableGroup:DrawableGroup};var track_from_dict=function(c,b){var a=new addable_objects[c.track_type](c.name,view,b,c.hda_ldda,c.dataset_id,c.prefs,c.filters,c.tool);if(c.mode){a.change_mode(c.mode)}return a};var drawable_collection_from_dict=function(f,a){var e=new addable_objects[f.obj_type](f.name,view,a,f.prefs,view.viewport_container,view);for(var d=0;d<f.drawables.length;d++){var b=f.drawables[d],c;if(b.track_type){c=track_from_dict(b,e)}else{c=drawable_collection_from_dict(b)}e.add_drawable(c);e.content_div.append(c.container_div)}return e};var drawable_from_dict=function(b,a){return(b.track_type?track_from_dict(b,a):drawable_collection_from_dict(b,a))};var create_visualization=function(b,e,g,c,a,d,f){view=new View(b,e,g,c);view.editor=true;$.when(view.load_chroms_deferred).then(function(){if(a){var k=a.chrom,p=a.start,h=a.end,m=a.overview;if(k&&(p!==undefined)&&h){view.change_chrom(k,p,h)}}if(d){var o;for(var j=0;j<d.length;j++){o=d[j];view.add_drawable(drawable_from_dict(o,view))}}view.update_intro_div();var n;for(var j=0;j<view.drawables.length;j++){if(view.drawables[j].name===m){view.set_overview(view.drawables[j]);break}}if(f){var l;for(var j=0;j<f.length;j++){l=f[j];add_bookmark(l.position,l.annotation)}}view.has_changes=false});return view};var init_keyboard_nav=function(a){$(document).keydown(function(b){if($(b.srcElement).is(":input")){return}switch(b.which){case 37:a.move_fraction(0.25);break;case 38:var c=Math.round(a.viewport_container.height()/15);a.viewport_container.scrollTop(a.viewport_container.scrollTop()-20);break;case 39:a.move_fraction(-0.25);break;case 40:var c=Math.round(a.viewport_container.height()/15);a.viewport_container.scrollTop(a.viewport_container.scrollTop()+20);break}})};
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: John Duddy: Fix copy/paste errors in histry contents API
by Bitbucket 09 Nov '11
by Bitbucket 09 Nov '11
09 Nov '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/fa97a5c307d2/
changeset: fa97a5c307d2
user: John Duddy
date: 2011-10-31 21:13:12
summary: Fix copy/paste errors in histry contents API
affected #: 2 files
diff -r 22d844537368bff2acb8eb50bce6561a673002ef -r fa97a5c307d228cd53673eca55fce0c9f12cfe4e lib/galaxy/web/api/history_contents.py
--- a/lib/galaxy/web/api/history_contents.py
+++ b/lib/galaxy/web/api/history_contents.py
@@ -50,7 +50,9 @@
"""
content_id = id
try:
- content = self.get_history_dataset_association( trans, content_id, check_ownership=True, check_accessible=True )
+ # get the history just for the access checks
+ history = self.get_history( trans, history_id, check_ownership=True, check_accessible=True, deleted=False )
+ content = self.get_history_dataset_association( trans, history, content_id, check_ownership=True, check_accessible=True )
except Exception, e:
return str( e )
try:
diff -r 22d844537368bff2acb8eb50bce6561a673002ef -r fa97a5c307d228cd53673eca55fce0c9f12cfe4e lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -233,16 +233,18 @@
else:
error( "You are not allowed to access this dataset" )
return data
- def get_history_dataset_association( self, trans, dataset_id, check_ownership=True, check_accessible=False ):
+ def get_history_dataset_association( self, trans, history, dataset_id, check_ownership=True, check_accessible=False ):
"""Get a HistoryDatasetAssociation from the database by id, verifying ownership."""
- hda = self.get_object( trans, id, 'HistoryDatasetAssociation', check_ownership=check_ownership, check_accessible=check_accessible, deleted=deleted )
- self.security_check( trans, history, check_ownership=check_ownership, check_accessible=False ) # check accessibility here
+ self.security_check( trans, history, check_ownership=check_ownership, check_accessible=check_accessible )
+ hda = self.get_object( trans, dataset_id, 'HistoryDatasetAssociation', check_ownership=False, check_accessible=False, deleted=False )
+
if check_accessible:
if trans.app.security_agent.can_access_dataset( trans.get_current_user_roles(), hda.dataset ):
if hda.state == trans.model.Dataset.states.UPLOAD:
error( "Please wait until this dataset finishes uploading before attempting to view it." )
else:
error( "You are not allowed to access this dataset" )
+ return hda
def get_data( self, dataset, preview=True ):
""" Gets a dataset's data. """
# Get data from file, truncating if necessary.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: dan: Remove "-targetNotSorted" argument from GATK indel realigner: vanished without warning or notice.
by Bitbucket 09 Nov '11
by Bitbucket 09 Nov '11
09 Nov '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/5f63ee75a786/
changeset: 5f63ee75a786
user: dan
date: 2011-11-09 15:41:12
summary: Remove "-targetNotSorted" argument from GATK indel realigner: vanished without warning or notice.
affected #: 1 file
diff -r a77cd7bbe375eb7884cfa5ff38d078033f89c1ab -r 5f63ee75a7862d1747a39c878849f9c04bd5a1d5 tools/gatk/indel_realigner.xml
--- a/tools/gatk/indel_realigner.xml
+++ b/tools/gatk/indel_realigner.xml
@@ -1,4 +1,4 @@
-<tool id="gatk_indel_realigner" name="Indel Realigner" version="0.0.3">
+<tool id="gatk_indel_realigner" name="Indel Realigner" version="0.0.4"><description>- perform local realignment</description><requirements><requirement type="package" version="1.2">gatk</requirement>
@@ -90,7 +90,6 @@
##start analysis specific options
-d "-targetIntervals" "${target_intervals}" "${target_intervals.ext}" "gatk_target_intervals"
-p '
- -targetNotSorted ##always resort input intervals
--disable_bam_indexing
'
#if $analysis_param_type.analysis_param_type_selector == "advanced":
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: dan: Update FASTQ Groomer tool help to indicate that Illumina 1.8+ is Sanger encoded.
by Bitbucket 08 Nov '11
by Bitbucket 08 Nov '11
08 Nov '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/a77cd7bbe375/
changeset: a77cd7bbe375
user: dan
date: 2011-11-08 22:53:19
summary: Update FASTQ Groomer tool help to indicate that Illumina 1.8+ is Sanger encoded.
affected #: 1 file
diff -r bc399a95e31ea30ef80893b3bc318f45cda3241a -r a77cd7bbe375eb7884cfa5ff38d078033f89c1ab tools/fastq/fastq_groomer.xml
--- a/tools/fastq/fastq_groomer.xml
+++ b/tools/fastq/fastq_groomer.xml
@@ -16,7 +16,7 @@
<param name="input_file" type="data" format="fastq" label="File to groom" /><param name="input_type" type="select" label="Input FASTQ quality scores type"><option value="solexa">Solexa</option>
- <option value="illumina">Illumina 1.3+</option>
+ <option value="illumina">Illumina 1.3-1.7</option><option value="sanger" selected="True">Sanger</option><option value="cssanger">Color Space Sanger</option></param>
@@ -358,6 +358,10 @@
Diagram adapted from http://en.wikipedia.org/wiki/FASTQ_format
+.. class:: infomark
+
+Output from Illumina 1.8+ pipelines are Sanger encoded.
+
------
**Citation**
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Add locale files for Chinese provided by hanfeisun.
by Bitbucket 08 Nov '11
by Bitbucket 08 Nov '11
08 Nov '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/bc399a95e31e/
changeset: bc399a95e31e
user: greg
date: 2011-11-08 22:35:48
summary: Add locale files for Chinese provided by hanfeisun.
affected #: 4 files
diff -r fa29a49205a226fa872601b4aac577973468e486 -r bc399a95e31ea30ef80893b3bc318f45cda3241a locale/zh/LC_MESSAGES/ginga.mo
Binary file locale/zh/LC_MESSAGES/ginga.mo has changed
diff -r fa29a49205a226fa872601b4aac577973468e486 -r bc399a95e31ea30ef80893b3bc318f45cda3241a locale/zh/LC_MESSAGES/ginga.po
--- /dev/null
+++ b/locale/zh/LC_MESSAGES/ginga.po
@@ -0,0 +1,597 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: yinhe 1.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2011-10-15 13:58+0800\n"
+"PO-Revision-Date: 2011-11-04 19:13+0900\n"
+"Last-Translator: Hanfei Sun <hfsun.tju(a)gmail.com> Juan Wang <jinling8(a)gmail.com>\n"
+"Language-Team: Chinese\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#:
+msgid "iso-8859-1"
+msgstr "utf-8"
+
+#:
+msgid "lang=\"en\""
+msgstr "lang=\"zh\""
+
+
+#: templates/base_panels.mako:5
+msgid "Galaxy"
+msgstr "Galaxy"
+
+#: templates/history/options.mako:24
+msgid "Are you sure you want to delete the current history?"
+msgstr "确认要删除当前的历史记录吗?"
+
+
+#: templates/root/history.mako:38
+msgid "collapse all"
+msgstr "全部收缩"
+
+
+#: templates/root/index.mako:5
+msgid "Tools"
+msgstr "工具"
+
+
+#: tools/**.xml
+msgid "Get Data"
+msgstr "获取数据"
+
+msgid "Get ENCODE Data"
+msgstr "获取ENCODE数据"
+
+msgid "ENCODE Tools"
+msgstr "ENCODE工具"
+
+msgid "Lift-Over"
+msgstr "版本转换"
+
+
+msgid "Text Manipulation"
+msgstr "文本操作"
+
+msgid "Filter and Sort"
+msgstr "过滤和排序"
+
+msgid "Join, Subtract and Group"
+msgstr "结合,差集与分组"
+
+msgid "Convert Formats"
+msgstr "格式转换"
+
+msgid "Extract Features"
+msgstr "特征提取"
+
+msgid "Fetch Sequences"
+msgstr "获取序列"
+
+msgid "Fetch Alignments"
+msgstr "获取比对上的序列"
+
+msgid "Get Genomic Scores"
+msgstr "获得基因组分数"
+
+msgid "Operate on Genomic Intervals"
+msgstr "基因组区间操作"
+
+msgid "Statistics"
+msgstr "统计量"
+
+msgid "Graph/Display Data"
+msgstr "图形/数据"
+
+msgid "Regional Variation"
+msgstr "区域多态性"
+
+msgid "Evolution: HyPhy"
+msgstr "进化: HyPhy"
+
+msgid "Taxonomy manipulation"
+msgstr "分类处理"
+
+msgid "Solexa tools"
+msgstr "Solexa工具"
+
+msgid "FASTA manipulation"
+msgstr "FASTA处理"
+
+msgid "Short Read QC and Manipulation"
+msgstr "短片段数据质量控制及处理"
+
+msgid "Short Read Mapping"
+msgstr "短片段回贴"
+
+
+#: templates/admin_main.mako:3 templates/admin_main.mako:8
+msgid "Galaxy Administration"
+msgstr "Galaxy 管理"
+
+#: templates/admin_main.mako:17
+msgid "Admin password: "
+msgstr "管理员密码: "
+
+#: templates/admin_main.mako:19
+msgid "Reload tool: "
+msgstr "重新载入工具"
+
+#: templates/admin_main.mako:35
+msgid "Reload"
+msgstr "重新载入"
+
+#: templates/dataset/edit_attributes.mako:2
+msgid "History Item Attributes"
+msgstr "历史项目属性"
+
+#: templates/dataset/edit_attributes.mako:19
+msgid "Edit Attributes"
+msgstr "编辑属性"
+
+#: templates/dataset/edit_attributes.mako:64
+msgid ""
+"This will inspect the dataset and attempt to correct the above column values "
+"if they are not accurate."
+msgstr "数据集检查,若有错误,更正上述栏中的值。"
+
+#: templates/dataset/edit_attributes.mako:68
+msgid ""
+"Required metadata values are missing. Some of these values may not be "
+"editable by the user. Selecting \"Auto-detect\" will attempt to fix these "
+"values."
+msgstr "所需元数据值缺失。其中一些值可能无法被用户编辑。选择“自动检测”将修正这些值。"
+
+#: templates/dataset/edit_attributes.mako:78
+msgid "Convert to new format"
+msgstr "转换成新格式"
+
+#: templates/dataset/edit_attributes.mako:84
+msgid "Convert to"
+msgstr "转换"
+
+#: templates/dataset/edit_attributes.mako:95
+msgid ""
+"This will create a new dataset with the contents of this dataset converted "
+"to a new format."
+msgstr "这将创建一个新的数据集,内容是转换后的数据集。"
+
+#: templates/dataset/edit_attributes.mako:111
+msgid "Change data type"
+msgstr "改变数据类型"
+
+#: templates/dataset/edit_attributes.mako:117
+msgid "New Type"
+msgstr "新类型"
+
+#: templates/dataset/edit_attributes.mako:124
+msgid ""
+"This will change the datatype of the existing dataset but <i>not</i> modify "
+"its contents. Use this if Galaxy has incorrectly guessed the type of your "
+"dataset."
+msgstr "这将改变已有数据集的数据类型,但是<i>不</i>改变其内容。当Galaxy不能正确判断你的数据类型时,设置该参数。"
+
+#: templates/dataset/edit_attributes.mako:137
+msgid "Copy History Item"
+msgstr "复制历史记录项"
+
+#: templates/history/list.mako:3
+msgid "Saved Histories"
+msgstr "保存的历史记录"
+
+#: templates/history/list.mako:19
+msgid "Stored Histories"
+msgstr "存储的历史记录"
+
+#: templates/history/list.mako:21 templates/root/history.mako:239
+msgid "hide deleted"
+msgstr "隐藏已删除"
+
+#: templates/history/list.mako:23
+msgid "show deleted"
+msgstr "显示已删除"
+
+#: templates/history/list.mako:27
+msgid "Name"
+msgstr "名称"
+
+#: templates/history/list.mako:27
+msgid "Size"
+msgstr "大小"
+
+#: templates/history/list.mako:27
+msgid "Last modified"
+msgstr "最后修改"
+
+#: templates/history/list.mako:27
+msgid "Actions"
+msgstr "操作"
+
+#: templates/history/list.mako:45
+msgid "rename"
+msgstr "重命名"
+
+#: templates/history/list.mako:46
+msgid "switch to"
+msgstr "切换到"
+
+#: templates/history/list.mako:47
+msgid "delete"
+msgstr "删除"
+
+#: templates/history/list.mako:49
+msgid "undelete"
+msgstr "取消删除"
+
+#: templates/history/list.mako:55
+msgid "Action"
+msgstr "操作"
+
+#: templates/history/list.mako:56 templates/history/options.mako:21
+msgid "Share"
+msgstr "共享"
+
+#: templates/history/list.mako:56 templates/history/options.mako:15
+msgid "Rename"
+msgstr "重命名"
+
+#: templates/history/list.mako:56 templates/history/options.mako:24
+msgid "Delete"
+msgstr "删除"
+
+#: templates/history/list.mako:58
+msgid "Undelete"
+msgstr "取消删除"
+
+#: templates/history/list.mako:65
+msgid "You have no stored histories"
+msgstr "没有存储的历史记录"
+
+#: templates/history/options.mako:5
+msgid "History Options"
+msgstr "历史记录选项"
+
+#: templates/history/options.mako:9
+msgid "You must be "
+msgstr "你必须"
+
+#: templates/history/options.mako:9
+msgid "logged in"
+msgstr "登录"
+
+#: templates/history/options.mako:9
+msgid " to store or switch histories."
+msgstr "以存储或切换历史记录"
+
+#: templates/history/options.mako:15
+#, python-format
+msgid " current history (stored as \"%s\")"
+msgstr " 当前历史(以\"%s\"形式存储)"
+
+#: templates/history/options.mako:16
+msgid "List"
+msgstr "列表"
+
+#: templates/history/options.mako:16
+msgid " previously stored histories"
+msgstr " 以前存储的历史记录"
+
+#: templates/history/options.mako:18
+msgid "Create"
+msgstr "创建"
+
+#: templates/history/options.mako:18
+msgid " a new empty history"
+msgstr " 一个新的空历史记录"
+
+#: templates/history/options.mako:20
+msgid "Construct workflow"
+msgstr "构建工作流程"
+
+#: templates/history/options.mako:20
+msgid " from the current history"
+msgstr " 来源于当前历史"
+
+#: templates/history/options.mako:21 templates/history/options.mako:24
+msgid " current history"
+msgstr " 当前历史"
+
+#: templates/history/options.mako:23
+msgid "Show deleted"
+msgstr "显示已删除"
+
+#: templates/history/options.mako:23
+msgid " datasets in history"
+msgstr " 历史中的数据集"
+
+#: templates/history/rename.mako:3 templates/history/rename.mako:6
+msgid "Rename History"
+msgstr "重命名历史"
+
+
+msgid "Rename Histories"
+msgstr "重命名历史记录"
+
+msgid "Perform Action"
+msgstr "运行操作"
+
+msgid "Submit"
+msgstr "提交"
+
+
+
+#: templates/history/rename.mako:10
+msgid "Current Name"
+msgstr "当前名称"
+
+#: templates/history/rename.mako:10
+msgid "New Name"
+msgstr "新名称"
+
+#: templates/history/share.mako:3
+msgid "Share histories"
+msgstr "共享历史记录"
+
+#: templates/history/share.mako:6
+msgid "Share Histories"
+msgstr "共享历史记录"
+
+#: templates/history/share.mako:9
+msgid "History Name:"
+msgstr "历史名称"
+
+#: templates/history/share.mako:9
+msgid "Number of Datasets:"
+msgstr "数据集数量"
+
+#: templates/history/share.mako:9
+msgid "Share Link"
+msgstr "共享链接"
+
+#: templates/history/share.mako:15
+msgid "This history contains no data."
+msgstr "这项历史中没有数据"
+
+#: templates/history/share.mako:21
+msgid "copy link to share"
+msgstr "复制链接以共享"
+
+#: templates/history/share.mako:24
+msgid "Email of User to share with:"
+msgstr "发送到这些Email地址进行分享"
+
+#: templates/root/history.mako:7
+msgid "Galaxy History"
+msgstr "Galaxy 历史"
+
+#: templates/root/history.mako:237
+msgid "refresh"
+msgstr "刷新"
+
+#: templates/root/history.mako:245
+msgid "You are currently viewing a deleted history!"
+msgstr "正在查看已删除的历史"
+
+#: templates/root/history.mako:289
+msgid "Your history is empty. Click 'Get Data' on the left pane to start"
+msgstr "历史已空,请单击左边窗格中‘获取数据’"
+
+#: templates/root/history_common.mako:41
+msgid "Job is waiting to run"
+msgstr "等待运行的进程"
+
+#: templates/root/history_common.mako:43
+msgid "Job is currently running"
+msgstr "正在运行的进程"
+
+#: templates/root/history_common.mako:46
+msgid "An error occurred running this job: "
+msgstr "进程运行时出错 "
+
+#: templates/root/history_common.mako:47
+msgid "report this error"
+msgstr "报告错误"
+
+#: templates/root/history_common.mako:54
+msgid "No data: "
+msgstr "没有数据: "
+
+#: templates/root/history_common.mako:58
+msgid "format: "
+msgstr "格式: "
+
+#: templates/root/history_common.mako:59
+msgid "database: "
+msgstr "数据库: "
+
+#: templates/root/history_common.mako:66 templates/root/masthead.mako:20
+msgid "Info: "
+msgstr "信息: "
+
+#: templates/root/history_common.mako:85
+#, python-format
+msgid "Error: unknown dataset state \"%s\"."
+msgstr "错误:未知的数据集状态 \"%s\"。"
+
+
+msgid "Options"
+msgstr "选项"
+
+msgid "History"
+msgstr "历史"
+
+#: templates/root/masthead.mako:20
+msgid "report bugs"
+msgstr "错误报告"
+
+#: templates/root/masthead.mako:21
+msgid "wiki"
+msgstr "wiki"
+
+#: templates/root/masthead.mako:22
+msgid "screencasts"
+msgstr "演示视频"
+
+
+#: templates/root/masthead.mako:23
+msgid "blog"
+msgstr "博客"
+
+#: templates/root/masthead.mako:31
+#, python-format
+msgid "Logged in as %s: "
+msgstr "以%s的身份登录: "
+
+#: templates/root/masthead.mako:31
+msgid "manage"
+msgstr "管理"
+
+#: templates/root/masthead.mako:32
+msgid "logout"
+msgstr "注销"
+
+#: templates/root/masthead.mako:34
+msgid "Account: "
+msgstr "帐户: "
+
+#: templates/root/masthead.mako:34
+msgid "create"
+msgstr "创建"
+
+#: templates/root/masthead.mako:35
+msgid "login"
+msgstr "登录"
+
+#: templates/root/tool_menu.mako:52
+msgid "Galaxy Tools"
+msgstr "Galaxy 工具"
+
+#: templates/root/tool_menu.mako:129
+msgid "Workflow"
+msgstr "工作流程"
+
+#: templates/root/tool_menu.mako:134
+msgid "Manage"
+msgstr "管理"
+
+#: templates/root/tool_menu.mako:134
+msgid "workflows"
+msgstr "工作流程"
+
+#: templates/user/index.mako:2 templates/user/index.mako:4
+msgid "Account settings"
+msgstr "帐户设置"
+
+#: templates/user/index.mako:7
+#, python-format
+msgid "You are currently logged in as %s."
+msgstr "当前以%s的身份登录"
+
+#: templates/user/index.mako:9
+msgid "Change your password"
+msgstr "修改密码"
+
+#: templates/user/index.mako:10
+msgid "Update your email address"
+msgstr "更新电子邮件地址"
+
+#: templates/user/index.mako:11
+msgid "Logout"
+msgstr "注销"
+
+#: templates/user/index.mako:16
+msgid "Login"
+msgstr "登录"
+
+#: templates/user/index.mako:17
+msgid "Create new account"
+msgstr "创建新帐户"
+
+msgid "Show Tool Search"
+msgstr "显示工具搜索"
+
+msgid "Analyze Data"
+msgstr "分析数据"
+
+msgid "analysis"
+msgstr "分析"
+
+msgid "History Lists"
+msgstr "历史记录清单"
+
+msgid "Histories Shared with Me"
+msgstr "共享的数据"
+
+msgid "Current History"
+msgstr "当前历史记录"
+
+msgid "Create New"
+msgstr "创建"
+
+msgid "Clone"
+msgstr "复制"
+
+msgid "Share or Publish"
+msgstr "共享或发布"
+
+msgid "Extract Workflow"
+msgstr "提取工作流程"
+
+msgid "Dataset Security"
+msgstr "数据安全性"
+
+
+msgid "Show Deleted Datasets"
+msgstr "显示已删除数据"
+
+msgid "Show Hidden Datasets"
+msgstr "显示隐藏数据"
+
+msgid "Show Structure"
+msgstr "显示结构"
+
+msgid "Export to File"
+msgstr "导出为文件"
+
+msgid "Other Actions"
+msgstr "其他"
+
+msgid "Import from File"
+msgstr "导入文件"
+
+msgid "Shared Data"
+msgstr "数据共享"
+
+msgid "Data Libraries"
+msgstr "数据仓库"
+
+msgid "Published Histories"
+msgstr "已发布的历史记录"
+
+msgid "Published Workflows"
+msgstr "已发布的工作流程"
+
+msgid "Published Pages"
+msgstr "已发布的页面"
+
+msgid "Help"
+msgstr "帮助"
+
+msgid "Email comments, bug reports, or suggestions"
+msgstr "发邮件进行意见反馈或错误报告"
+
+
+msgid "User"
+msgstr "用户"
+
+
+msgid "Register"
+msgstr "注册"
\ No newline at end of file
diff -r fa29a49205a226fa872601b4aac577973468e486 -r bc399a95e31ea30ef80893b3bc318f45cda3241a locale/zh/LC_MESSAGES/tools.mo
Binary file locale/zh/LC_MESSAGES/tools.mo has changed
diff -r fa29a49205a226fa872601b4aac577973468e486 -r bc399a95e31ea30ef80893b3bc318f45cda3241a locale/zh/LC_MESSAGES/tools.po
--- /dev/null
+++ b/locale/zh/LC_MESSAGES/tools.po
@@ -0,0 +1,84 @@
+# Japanese translations for PROJECT.
+# Copyright (C) 2009 ORGANIZATION
+# This file is distributed under the same license as the PROJECT project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2009-03-17 04:06-0400\n"
+"PO-Revision-Date: 2009-03-17 04:06-0400\n"
+"Last-Translator: Hanfei Sun <hfsun.tju(a)gmail.com>\n"
+"Language-Team: zh <hfsun.tju(a)gmail.com>\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.4\n"
+
+msgid "Get Data"
+msgstr "获取数据"
+
+msgid "Get ENCODE Data"
+msgstr ""
+
+msgid "ENCODE Tools"
+msgstr ""
+
+msgid "Lift-Over"
+msgstr ""
+
+msgid "Text Manipulation"
+msgstr ""
+
+msgid "Filter and Sort"
+msgstr ""
+
+msgid "Join, Subtract and Group"
+msgstr ""
+
+msgid "Convert Formats"
+msgstr ""
+
+msgid "Extract Features"
+msgstr ""
+
+msgid "Fetch Sequences"
+msgstr ""
+
+msgid "Fetch Alignments"
+msgstr ""
+
+msgid "Get Genomic Scores"
+msgstr ""
+
+msgid "Operate on Genomic Intervals"
+msgstr ""
+
+msgid "Statistics"
+msgstr ""
+
+msgid "Graph/Display Data"
+msgstr ""
+
+msgid "Regional Variation"
+msgstr ""
+
+msgid "Evolution: HyPhy"
+msgstr ""
+
+msgid "Taxonomy manipulation"
+msgstr ""
+
+msgid "Solexa tools"
+msgstr ""
+
+msgid "FASTA manipulation"
+msgstr ""
+
+msgid "Short Read QC and Manipulation"
+msgstr ""
+
+msgid "Short Read Mapping"
+msgstr ""
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Fix for generating metadata in tool shed repositories for a tool that does not use a tool_data_table entry for a dynamic SelectField input parameter.
by Bitbucket 08 Nov '11
by Bitbucket 08 Nov '11
08 Nov '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/fa29a49205a2/
changeset: fa29a49205a2
user: greg
date: 2011-11-08 21:18:24
summary: Fix for generating metadata in tool shed repositories for a tool that does not use a tool_data_table entry for a dynamic SelectField input parameter.
affected #: 2 files
diff -r 9ee23aa36ec3807092ce1b8f3031ba751f1368e6 -r fa29a49205a226fa872601b4aac577973468e486 lib/galaxy/web/controllers/admin.py
--- a/lib/galaxy/web/controllers/admin.py
+++ b/lib/galaxy/web/controllers/admin.py
@@ -1147,21 +1147,20 @@
def __get_repository_tools_and_sample_files( self, trans, tool_path, repo_files_dir ):
# The sample_files list contains all files whose name ends in .sample
sample_files = []
+ # Find all special .sample files first.
+ for root, dirs, files in os.walk( repo_files_dir ):
+ if root.find( '.hg' ) < 0:
+ for name in files:
+ if name.endswith( '.sample' ):
+ sample_files.append( os.path.abspath( os.path.join( root, name ) ) )
# The repository_tools_tups list contains tuples of ( relative_path_to_tool_config, tool ) pairs
repository_tools_tups = []
for root, dirs, files in os.walk( repo_files_dir ):
- if not root.find( '.hg' ) >= 0 and not root.find( 'hgrc' ) >= 0:
+ if root.find( '.hg' ) < 0 and root.find( 'hgrc' ) < 0:
if '.hg' in dirs:
- # Don't visit .hg directories - should be impossible since we don't
- # allow uploaded archives that contain .hg dirs, but just in case...
dirs.remove( '.hg' )
if 'hgrc' in files:
- # Don't include hgrc files in commit.
files.remove( 'hgrc' )
- # Find all special .sample files first.
- for name in files:
- if name.endswith( '.sample' ):
- sample_files.append( os.path.abspath( os.path.join( root, name ) ) )
for name in files:
# Find all tool configs.
if name.endswith( '.xml' ):
diff -r 9ee23aa36ec3807092ce1b8f3031ba751f1368e6 -r fa29a49205a226fa872601b4aac577973468e486 lib/galaxy/webapps/community/controllers/common.py
--- a/lib/galaxy/webapps/community/controllers/common.py
+++ b/lib/galaxy/webapps/community/controllers/common.py
@@ -214,7 +214,8 @@
copy_sample_loc_file( trans, sample_file )
options.index_file = index_tail
options.missing_index_file = None
- options.tool_data_table.missing_index_file = None
+ if options.tool_data_table:
+ options.tool_data_table.missing_index_file = None
sample_found = True
break
if not sample_found:
@@ -325,8 +326,14 @@
if ctx is not None:
metadata_dict = {}
if changeset_revision == repository.tip:
+ # Find all special .sample files first.
for root, dirs, files in os.walk( repo_dir ):
- if not root.find( '.hg' ) >= 0 and not root.find( 'hgrc' ) >= 0:
+ if root.find( '.hg' ) < 0:
+ for name in files:
+ if name.endswith( '.sample' ):
+ sample_files.append( os.path.abspath( os.path.join( root, name ) ) )
+ for root, dirs, files in os.walk( repo_dir ):
+ if root.find( '.hg' ) < 0 and root.find( 'hgrc' ) < 0:
if '.hg' in dirs:
# Don't visit .hg directories - should be impossible since we don't
# allow uploaded archives that contain .hg dirs, but just in case...
@@ -334,10 +341,6 @@
if 'hgrc' in files:
# Don't include hgrc files in commit.
files.remove( 'hgrc' )
- # Find all special .sample files first.
- for name in files:
- if name.endswith( '.sample' ):
- sample_files.append( os.path.abspath( os.path.join( root, name ) ) )
for name in files:
# Find all tool configs.
if name.endswith( '.xml' ):
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Fix importing library datasets into multiple histories - library datasets will now only be imported into those checked.
by Bitbucket 08 Nov '11
by Bitbucket 08 Nov '11
08 Nov '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/9ee23aa36ec3/
changeset: 9ee23aa36ec3
user: greg
date: 2011-11-08 17:59:36
summary: Fix importing library datasets into multiple histories - library datasets will now only be imported into those checked.
affected #: 3 files
diff -r 542aa2dab591d6df036096547c6f615a2a412dce -r 9ee23aa36ec3807092ce1b8f3031ba751f1368e6 lib/galaxy/web/controllers/library_common.py
--- a/lib/galaxy/web/controllers/library_common.py
+++ b/lib/galaxy/web/controllers/library_common.py
@@ -1855,7 +1855,7 @@
status=status )
@web.expose
- def import_datasets_to_histories( self, trans, cntrller, library_id='', folder_id='', ldda_ids='', target_history_ids='', new_history_name='', **kwd ):
+ def import_datasets_to_histories( self, trans, cntrller, library_id='', folder_id='', ldda_ids='', target_history_id='', target_history_ids='', new_history_name='', **kwd ):
# This method is called from one of the following places:
# - a menu option for a library dataset ( ldda_ids is a single ldda id )
# - a menu option for a library folder ( folder_id has a value )
@@ -1870,7 +1870,6 @@
action = params.get( 'do_action', None )
user = trans.get_user()
current_history = trans.get_history()
- selected_history_id = params.get( 'selected_history_id', trans.security.encode_id( current_history.id ) )
if library_id:
library = trans.sa_session.query( trans.model.Library ).get( trans.security.decode_id( library_id ) )
else:
@@ -1882,9 +1881,11 @@
ldda_ids = util.listify( ldda_ids )
if ldda_ids:
ldda_ids = map( trans.security.decode_id, ldda_ids )
- target_history_ids = util.listify( target_history_ids )
if target_history_ids:
- target_history_ids = [ trans.security.decode_id( target_history_id ) for target_history_id in target_history_ids if target_history_id ]
+ target_history_ids = util.listify( target_history_ids )
+ target_history_ids = set( [ trans.security.decode_id( target_history_id ) for target_history_id in target_history_ids if target_history_id ] )
+ elif target_history_id:
+ target_history_ids = [ trans.security.decode_id( target_history_id ) ]
if params.get( 'import_datasets_to_histories_button', False ):
invalid_datasets = 0
if not ldda_ids or not ( target_history_ids or new_history_name ):
@@ -1965,7 +1966,7 @@
library=library,
current_history=current_history,
ldda_ids=ldda_ids,
- selected_history_id=selected_history_id,
+ target_history_id=target_history_id,
target_history_ids=target_history_ids,
source_lddas=source_lddas,
target_histories=target_histories,
diff -r 542aa2dab591d6df036096547c6f615a2a412dce -r 9ee23aa36ec3807092ce1b8f3031ba751f1368e6 lib/galaxy/webapps/community/controllers/repository.py
--- a/lib/galaxy/webapps/community/controllers/repository.py
+++ b/lib/galaxy/webapps/community/controllers/repository.py
@@ -236,7 +236,7 @@
template='/webapps/community/repository/grid.mako'
default_sort_key = "Repository.name"
columns = [
- NameColumn( "Name",
+ NameColumn( "Repository name",
link=( lambda item: dict( operation="view_or_manage_repository",
id=item.id,
webapp="community" ) ),
@@ -588,17 +588,17 @@
match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) )
else:
ok = False
- if workflow_names:
+ elif workflow_names:
if 'workflows' in metadata:
workflows = metadata[ 'workflows' ]
else:
workflows = []
for workflow_dict in workflows:
for workflow_name in workflow_names:
- if self.__in_workflow_dict( workflow_dict, exact_matches_checked, workflow_name=workflow_name ):
+ if self.__in_workflow_dict( workflow_dict, exact_matches_checked, workflow_name ):
match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) )
return ok, match_tuples
- def __in_workflow_dict( self, workflow_dict, exact_matches_checked, workflow_name=None ):
+ def __in_workflow_dict( self, workflow_dict, exact_matches_checked, workflow_name ):
workflow_dict_workflow_name = workflow_dict[ 'name' ].lower()
return ( workflow_name == workflow_dict_workflow_name ) or \
( not exact_matches_checked and workflow_dict_workflow_name.find( workflow_name ) >= 0 )
diff -r 542aa2dab591d6df036096547c6f615a2a412dce -r 9ee23aa36ec3807092ce1b8f3031ba751f1368e6 templates/library/common/import_datasets_to_histories.mako
--- a/templates/library/common/import_datasets_to_histories.mako
+++ b/templates/library/common/import_datasets_to_histories.mako
@@ -49,12 +49,12 @@
<div class="toolFormTitle">Destination Histories:</div><div class="toolFormBody"><div class="form-row" id="single-destination">
- <select id="single-dest-select" name="target_history_ids">
+ <select id="single-dest-select" name="target_history_id">
%for i, target_history in enumerate( target_histories ):
<%
encoded_id = trans.security.encode_id( target_history.id )
- if encoded_id == selected_history_id:
- selected_text = " selected"
+ if encoded_id == target_history_id:
+ selected_text = " selected='selected'"
else:
selected_text = ""
if target_history == current_history:
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: james_taylor: Trackster: dense mode features are full height again, don't draw strand indicators when drawing squished features.
by Bitbucket 08 Nov '11
by Bitbucket 08 Nov '11
08 Nov '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/542aa2dab591/
changeset: 542aa2dab591
user: james_taylor
date: 2011-11-08 17:37:12
summary: Trackster: dense mode features are full height again, don't draw strand indicators when drawing squished features.
affected #: 1 file
diff -r 132798922d53213d6ca4e1596619f254bdd582d0 -r 542aa2dab591d6df036096547c6f615a2a412dce static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -4292,7 +4292,7 @@
SQUISH_TRACK_HEIGHT = 5,
PACK_TRACK_HEIGHT = 10,
NO_DETAIL_FEATURE_HEIGHT = 1,
- DENSE_FEATURE_HEIGHT = 3,
+ DENSE_FEATURE_HEIGHT = 9,
SQUISH_FEATURE_HEIGHT = 3,
PACK_FEATURE_HEIGHT = 9,
LABEL_SPACING = 2,
@@ -4365,7 +4365,9 @@
var feature_strand = feature[4],
feature_ts = feature[5],
feature_te = feature[6],
- feature_blocks = feature[7];
+ feature_blocks = feature[7],
+ // Whether we are drawing full height or squished features
+ full_height = true;
if (feature_ts && feature_te) {
thick_start = Math.floor( Math.max(0, (feature_ts - tile_low) * w_scale) );
@@ -4374,9 +4376,13 @@
// Set vars that depend on mode.
var thin_height, thick_height;
- if (mode === "Squish" || mode === "Dense" ) {
+ if (mode === "Squish" ) {
thin_height = 1;
thick_height = SQUISH_FEATURE_HEIGHT;
+ full_height = false;
+ } else if ( mode === "Dense" ) {
+ thin_height = 5;
+ thick_height = DENSE_FEATURE_HEIGHT;
} else { // mode === "Pack"
thin_height = 5;
thick_height = PACK_FEATURE_HEIGHT;
@@ -4388,7 +4394,7 @@
ctx.fillStyle = block_color;
ctx.fillRect(f_start, y_center + 1, f_end - f_start, thick_height);
// If strand is specified, draw arrows over feature
- if ( feature_strand ) {
+ if ( feature_strand && full_height ) {
if (feature_strand === "+") {
ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand_inv' );
} else if (feature_strand === "-") {
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
24 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/471c9a7d9ed2/
changeset: 471c9a7d9ed2
user: james_taylor
date: 2011-10-30 23:12:22
summary: Modal dialogs now dim the entire page, show_message can be used for the old behavior (but should only be used for messages that do not require interaction)
affected #: 6 files
diff -r 147f55e7161ceb4ea9fd3d08bd5dedd19fccbec0 -r 471c9a7d9ed2eca4110bf59961ce21307344a982 static/june_2007_style/blue/panel_layout.css
--- a/static/june_2007_style/blue/panel_layout.css
+++ b/static/june_2007_style/blue/panel_layout.css
@@ -23,9 +23,11 @@
.panel-header-button:hover{color:black;background-color:#ccc;}
.panel-header-button:active{color:white;background-color:#aaaaaa;}
#overlay{position:fixed;top:0;left:0;width:100%;height:100%;z-index:20000;}
+#overlay.modal #overlay-background{background:rgba(0,0,0,0.5);}
.dialog-box-container{position:relative;margin-top:80px;margin-right:auto;margin-left:auto;}
.dialog-box-wrapper{position:relative;padding:1em;background-color:rgba(0,0,0,0.5);-moz-border-radius:1em;-webkit-border-radius:1em;}
.dialog-box{border:solid #999 1px;background:white;z-index:80000;}
+#overlay.modal .dialog-box .body{min-width:600px;}
.dialog-box .body{padding:5px;overflow:auto;max-height:500px;min-width:300px;}
.dialog-box .buttons{padding:5px;}
.panel-error-message,.panel-warning-message,.panel-done-message,.panel-info-message{height:24px;line-height:24px;color:#303030;padding:0px;padding-left:26px;background-color:#FFCCCC;background-image:url(error_small.png);background-repeat:no-repeat;background-position:6px 50%;}
diff -r 147f55e7161ceb4ea9fd3d08bd5dedd19fccbec0 -r 471c9a7d9ed2eca4110bf59961ce21307344a982 static/june_2007_style/blue/trackster.css
--- a/static/june_2007_style/blue/trackster.css
+++ b/static/june_2007_style/blue/trackster.css
@@ -3,30 +3,9 @@
.content{font:10px verdana;}
.nav-controls{text-align:center;padding:1px 0;}
.nav-controls input{margin:0 5px;}
-.menu-button{padding: 0px 4px 0px 4px;}
#zoom-in,#zoom-out{display:inline-block;height:16px;width:16px;margin-bottom:-3px;cursor:pointer;}
#zoom-out{background:transparent url(../images/fugue/magnifier-zoom-out.png) center center no-repeat;}
#zoom-in{margin-left:10px;background:transparent url(../images/fugue/magnifier-zoom.png) center center no-repeat;}
-.overview-icon{background:transparent url(../images/fugue/application-dock-270-bw.png) no-repeat;}
-.overview-icon:hover{background:transparent url(../images/fugue/application-dock-270.png) no-repeat;}
-.settings-icon{background:transparent url(../images/fugue/gear-bw.png) no-repeat;}
-.settings-icon:hover{background:transparent url(../images/fugue/gear.png) no-repeat;}
-.tools-icon{background:transparent url(../images/fugue/toolbox-bw.png) no-repeat;}
-.tools-icon:hover{background:transparent url(../images/fugue/toolbox.png) no-repeat;}
-.filters-icon{background:transparent url(../images/fugue/ui-slider-050-bw.png) no-repeat;}
-.filters-icon:hover{background:transparent url(../images/fugue/ui-slider-050.png) no-repeat;}
-.remove-icon,.overview-close{background:transparent url(../images/fugue/cross-small-bw.png) no-repeat;}
-.remove-icon:hover,.overview-close:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
-#close-icon{background:transparent url(../images/fugue/cross-circle-bw.png) no-repeat;margin-right:0px;}
-#close-icon:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
-#add-tracks-icon{background:transparent url(../images/fugue/plus-button-bw.png) no-repeat;}
-#add-tracks-icon:hover{background:transparent url(../images/fugue/plus-button.png) no-repeat;}
-#add-group-icon{background:transparent url(../images/fugue/block--plus-bw.png) no-repeat;}
-#add-group-icon:hover{background:transparent url(../images/fugue/block--plus.png) no-repeat;}
-#bookmarks-icon{background:transparent url(../images/fugue/bookmarks-bw.png) no-repeat;}
-#bookmarks-icon:hover{background:transparent url(../images/fugue/bookmarks.png) no-repeat;}
-#save-icon{background:transparent url(../images/fugue/disk--arrow-bw.png) no-repeat;}
-#save-icon:hover{background:transparent url(../images/fugue/disk--arrow.png) no-repeat;}
.nav-input{font-size:12px;width:30em;z-index:1000;}
.location{display:inline-block;width:15em;margin:0 10px;}
.draghandle{margin-top:2px;cursor:move;float:left;background:transparent url(../images/visualization/draggable_horizontal.png) center center no-repeat;width:10px;height:12px;}
@@ -65,16 +44,39 @@
input{font:10px verdana;}
.dynamic-tool,.filters{margin-left:0.25em;padding-bottom:0.5em;}
.dynamic-tool{width:410px;}
-.filters>.sliders,.display-controls{float:left;margin:1em;}
+.filters > .sliders,.display-controls{float:left;margin:1em;}
.sliders{width:410px;}
-.display-controls{border-left:solid 2px #DDDDDD;padding-left:1em}
-.filter-row{margin-top:0.4em;}
+.display-controls{border-left:solid 2px #DDDDDD;padding-left:1em
+}
+.filter-row {
+ margin-top:0.4em;}
.slider-row{margin-left:1em;}
.elt-label{float:left;font-weight:bold;margin-right:1em;}
.slider{float:right;width:200px;position:relative;}
.tool-name{font-size:110%;font-weight:bold;}
.param-row{margin-top:0.2em;margin-left:1em;}
.param-label{float:left;font-weight:bold;padding-top:0.2em;}
+.menu-button{padding:0px 4px 0px 4px;}
+.settings-icon{background:transparent url(../images/fugue/gear-bw.png) no-repeat;}
+.settings-icon:hover{background:transparent url(../images/fugue/gear.png) no-repeat;}
+.overview-icon{background:transparent url(../images/fugue/application-dock-270-bw.png) no-repeat;}
+.overview-icon:hover{background:transparent url(../images/fugue/application-dock-270.png) no-repeat;}
+.tools-icon{background:transparent url(../images/fugue/toolbox-bw.png) no-repeat;}
+.tools-icon:hover{background:transparent url(../images/fugue/toolbox.png) no-repeat;}
+.filters-icon{background:transparent url(../images/fugue/ui-slider-050-bw.png) no-repeat;}
+.filters-icon:hover{background:transparent url(../images/fugue/ui-slider-050.png) no-repeat;}
+.remove-icon,.overview-close{background:transparent url(../images/fugue/cross-small-bw.png) no-repeat;}
+.remove-icon:hover,.overview-close:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
+#close-icon{background:transparent url(../images/fugue/cross-circle-bw.png) no-repeat;margin-right:0px;}
+#close-icon:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
+#add-tracks-icon{background:transparent url(../images/fugue/plus-button-bw.png) no-repeat;}
+#add-tracks-icon:hover{background:transparent url(../images/fugue/plus-button.png) no-repeat;}
+#add-group-icon{background:transparent url(../images/fugue/block--plus-bw.png) no-repeat;}
+#add-group-icon:hover{background:transparent url(../images/fugue/block--plus.png) no-repeat;}
+#bookmarks-icon{background:transparent url(../images/fugue/bookmarks-bw.png) no-repeat;}
+#bookmarks-icon:hover{background:transparent url(../images/fugue/bookmarks.png) no-repeat;}
+#save-icon{background:transparent url(../images/fugue/disk--arrow-bw.png) no-repeat;}
+#save-icon:hover{background:transparent url(../images/fugue/disk--arrow.png) no-repeat;}
.child-track-icon{background:url('../images/fugue/arrow-000-small-bw.png') no-repeat;width:30px;cursor:move;}
.track-resize{background:white url('../images/visualization/draggable_vertical.png') no-repeat top center;position:absolute;right:3px;bottom:-4px;width:14px;height:7px;border:solid #999 1px;z-index:100;}
.bookmark{background:white;border:solid #999 1px;border-right:none;margin:0.5em;margin-right:0;padding:0.5em;}
@@ -85,4 +87,4 @@
.icon.more-across{background:url('../images/fugue/arrow-transition-bw.png') no-repeat 0px 0px;}
.intro{padding:1em;}
.intro > .action-button{background-color:#CCC;padding:1em;}
-.feature-popup{background-color:#DDD;position:absolute;z-index:1000}
+.feature-popup{background-color:#DDD;position:absolute;z-index:1000;}
diff -r 147f55e7161ceb4ea9fd3d08bd5dedd19fccbec0 -r 471c9a7d9ed2eca4110bf59961ce21307344a982 static/june_2007_style/panel_layout.css.tmpl
--- a/static/june_2007_style/panel_layout.css.tmpl
+++ b/static/june_2007_style/panel_layout.css.tmpl
@@ -161,6 +161,10 @@
z-index: 20000;
}
+#overlay.modal #overlay-background {
+ background: rgba(0,0,0,0.5);
+}
+
.dialog-box-container {
position: relative;
margin-top: 80px;
@@ -182,6 +186,10 @@
z-index: 80000;
}
+#overlay.modal .dialog-box .body {
+ min-width: 600px;
+}
+
.dialog-box .body {
padding: 5px;
overflow: auto;
diff -r 147f55e7161ceb4ea9fd3d08bd5dedd19fccbec0 -r 471c9a7d9ed2eca4110bf59961ce21307344a982 static/june_2007_style/trackster.css.tmpl
--- a/static/june_2007_style/trackster.css.tmpl
+++ b/static/june_2007_style/trackster.css.tmpl
@@ -405,8 +405,8 @@
background-color: #CCC;
padding: 1em;
}
-.feature-popup{
+.feature-popup {
background-color: #DDD;
position: absolute;
- z-index: 1000
+ z-index: 1000;
}
diff -r 147f55e7161ceb4ea9fd3d08bd5dedd19fccbec0 -r 471c9a7d9ed2eca4110bf59961ce21307344a982 static/scripts/galaxy.panels.js
--- a/static/scripts/galaxy.panels.js
+++ b/static/scripts/galaxy.panels.js
@@ -163,13 +163,23 @@
// Modal dialog boxes
function hide_modal() {
- $(".dialog-box-container" ).fadeOut( function() {
+ $(".dialog-box-container" ).hide( 0, function() {
$("#overlay").hide();
+ $("#overlay").removeClass( "modal" );
$( ".dialog-box" ).find( ".body" ).children().remove();
} );
};
-function show_modal( title, body, buttons, extra_buttons, init_fn ) {
+function show_modal() {
+ $("#overlay").addClass( "modal" );
+ _show_modal.apply( this, arguments );
+}
+
+function show_message() {
+ _show_modal.apply( this, arguments );
+}
+
+function _show_modal( title, body, buttons, extra_buttons, init_fn ) {
if ( title ) {
$( ".dialog-box" ).find( ".title" ).html( title );
$( ".dialog-box" ).find( ".unified-panel-header" ).show();
@@ -205,7 +215,7 @@
$( ".dialog-box" ).find( ".body" ).html( body );
if ( ! $(".dialog-box-container").is( ":visible" ) ) {
$("#overlay").show();
- $(".dialog-box-container").fadeIn();
+ $(".dialog-box-container").show();
}
// Fix min-width so that modal cannot shrink considerably if
// new content is loaded.
diff -r 147f55e7161ceb4ea9fd3d08bd5dedd19fccbec0 -r 471c9a7d9ed2eca4110bf59961ce21307344a982 templates/workflow/editor.mako
--- a/templates/workflow/editor.mako
+++ b/templates/workflow/editor.mako
@@ -213,7 +213,7 @@
show_workflow_parameters();
},
beforeSubmit: function( data ) {
- show_modal( "Loading workflow", "progress" );
+ show_message( "Loading workflow", "progress" );
}
});
}
@@ -650,7 +650,7 @@
};
var save_current_workflow = function ( eventObj, success_callback ) {
- show_modal( "Saving workflow", "progress" );
+ show_message( "Saving workflow", "progress" );
workflow.check_changes_in_active_form();
if (!workflow.has_changes) {
hide_modal();
https://bitbucket.org/galaxy/galaxy-central/changeset/f5961b41a0d4/
changeset: f5961b41a0d4
user: james_taylor
date: 2011-10-30 23:59:05
summary: Trackster: fixes for bigwig data -- updated bx-python
affected #: 5 files
diff -r 471c9a7d9ed2eca4110bf59961ce21307344a982 -r f5961b41a0d4a7c7b1f21dc8829644573c9e5448 eggs.ini
--- a/eggs.ini
+++ b/eggs.ini
@@ -12,7 +12,7 @@
no_auto = pbs_python DRMAA_python
[eggs:platform]
-bx_python = 0.7.0
+bx_python = 0.7.1
Cheetah = 2.2.2
ctypes = 1.0.2
DRMAA_python = 0.2
@@ -67,7 +67,7 @@
psycopg2 = _8.4.2_static
pysqlite = _3.6.17_static
MySQL_python = _5.1.41_static
-bx_python = _494c2d1d68b3_rebuild1
+; bx_python = _494c2d1d68b3_rebuild1
GeneTrack = _dev_48da9e998f0caf01c5be731e926f4b0481f658f0
SQLAlchemy = _dev_r6498
pysam = _kanwei_b10f6e722e9a
diff -r 471c9a7d9ed2eca4110bf59961ce21307344a982 -r f5961b41a0d4a7c7b1f21dc8829644573c9e5448 lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
--- a/lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
+++ b/lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
@@ -50,4 +50,4 @@
st.write(out_fname)
if __name__ == "__main__":
- main()
\ No newline at end of file
+ main()
diff -r 471c9a7d9ed2eca4110bf59961ce21307344a982 -r f5961b41a0d4a7c7b1f21dc8829644573c9e5448 lib/galaxy/visualization/tracks/data_providers.py
--- a/lib/galaxy/visualization/tracks/data_providers.py
+++ b/lib/galaxy/visualization/tracks/data_providers.py
@@ -434,40 +434,55 @@
# Bigwig has the possibility of it being a standalone bigwig file, in which case we use
# original_dataset, or coming from wig->bigwig conversion in which we use converted_dataset
f, bbi = self._get_dataset()
-
+
+ # If the stats kwarg was provide, we compute overall summary data for the entire chromosome,
+ # but no reduced data -- currently only providing min/max which is used by trackster to
+ # determine the default range
if 'stats' in kwargs:
- all_dat = bbi.query(chrom, 0, 2147483647, 1)
+ # FIXME: use actual chromosome size
+ summary = bbi.summarize( chrom, 0, 214783647, 1 )
f.close()
- if all_dat is None:
+ if summary is None:
return None
-
- all_dat = all_dat[0] # only 1 summary
- return { 'data' : { 'max': float( all_dat['max'] ), \
- 'min': float( all_dat['min'] ), \
- 'total_frequency': float( all_dat['coverage'] ) } \
- }
-
+ else:
+ return dict( data=dict( min=summary.min_val[0], max=summary.max_val[0] ) )
+
start = int(start)
end = int(end)
+
+ # The following seems not to work very well, for example it will only return one
+ # data point if the tile is 1280px wide. Not sure what the intent is.
+
# The first zoom level for BBI files is 640. If too much is requested, it will look at each block instead
# of summaries. The calculation done is: zoom <> (end-start)/num_points/2.
# Thus, the optimal number of points is (end-start)/num_points/2 = 640
# num_points = (end-start) / 1280
- num_points = (end-start) / 1280
- if num_points < 1:
- num_points = end - start
- else:
- num_points = min(num_points, 500)
+ #num_points = (end-start) / 1280
+ #if num_points < 1:
+ # num_points = end - start
+ #else:
+ # num_points = min(num_points, 500)
- data = bbi.query(chrom, start, end, num_points)
+ # For now, we'll do 1000 data points by default However, the summaries
+ # don't seem to work when a summary pixel corresponds to less than one
+ # datapoint, so we prevent that.
+ # FIXME: need to switch over to using the full data at high levels of
+ # detail.
+ num_points = min( 1000, end - start )
+
+ summary = bbi.summarize( chrom, start, end, num_points )
f.close()
+
+ result = []
+
+ if summary:
+ mean = summary.sum_data / summary.valid_count
- pos = start
- step_size = (end - start) / num_points
- result = []
- if data:
- for dat_dict in data:
- result.append( (pos, float_nan(dat_dict['mean']) ) )
+ pos = start
+ step_size = (end - start) / num_points
+
+ for value in mean:
+ result.append( (pos, float_nan(value) ) )
pos += step_size
return { 'data': result }
diff -r 471c9a7d9ed2eca4110bf59961ce21307344a982 -r f5961b41a0d4a7c7b1f21dc8829644573c9e5448 lib/galaxy/web/controllers/tracks.py
--- a/lib/galaxy/web/controllers/tracks.py
+++ b/lib/galaxy/web/controllers/tracks.py
@@ -524,6 +524,7 @@
if not standalone_provider.has_data( chrom ):
return messages.NO_DATA
valid_chroms = standalone_provider.valid_chroms()
+
# Have data if we get here
return { "status": messages.DATA, "valid_chroms": valid_chroms }
@@ -990,4 +991,4 @@
return_message = message
elif return_message == None and message == messages.PENDING:
return_message = message
- return return_message
\ No newline at end of file
+ return return_message
diff -r 471c9a7d9ed2eca4110bf59961ce21307344a982 -r f5961b41a0d4a7c7b1f21dc8829644573c9e5448 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -699,7 +699,7 @@
remove: function() {
this.container.remove_drawable(this);
- this.container_div.fadeOut('slow', function() {
+ this.container_div.hide(0, function() {
$(this).remove();
// HACK: is there a better way to update the view?
view.update_intro_div();
@@ -1253,7 +1253,7 @@
DrawableCollection.prototype.remove_drawable.call(this, drawable);
if (hide) {
var view = this;
- drawable.container_div.fadeOut('slow', function() {
+ drawable.container_div.hide(0, function() {
$(this).remove();
view.update_intro_div();
});
@@ -2699,7 +2699,7 @@
w_scale = width / range,
resolution = this.view.resolution,
parent_element = $("<div style='position: relative;'></div>");
-
+
// For overview, adjust high, low, resolution, and w_scale.
if (this.is_overview) {
low = this.view.max_low;
@@ -4759,4 +4759,4 @@
for ( key in modules.trackster ) {
target[key] = modules.trackster[key];
}
-})(window);
\ No newline at end of file
+})(window);
https://bitbucket.org/galaxy/galaxy-central/changeset/aa241b7e0138/
changeset: aa241b7e0138
user: james_taylor
date: 2011-10-31 23:06:30
summary: Trackster: for line tracks, compute default range using +/- two standard deviations around mean, for feature tracks, make feature popup look more like other tooltips
affected #: 4 files
diff -r f5961b41a0d4a7c7b1f21dc8829644573c9e5448 -r aa241b7e0138f5f107219666dc2e21daa76f3c87 lib/galaxy/visualization/tracks/data_providers.py
--- a/lib/galaxy/visualization/tracks/data_providers.py
+++ b/lib/galaxy/visualization/tracks/data_providers.py
@@ -2,8 +2,8 @@
Data providers for tracks visualizations.
"""
-import sys
-from math import ceil, log
+import sys, time
+from math import ceil, log, sqrt
import pkg_resources
pkg_resources.require( "bx-python" )
if sys.version_info[:2] == (2, 4):
@@ -435,9 +435,9 @@
# original_dataset, or coming from wig->bigwig conversion in which we use converted_dataset
f, bbi = self._get_dataset()
- # If the stats kwarg was provide, we compute overall summary data for the entire chromosome,
- # but no reduced data -- currently only providing min/max which is used by trackster to
- # determine the default range
+ # If the stats kwarg was provide, we compute overall summary data for
+ # the entire chromosome, but no reduced data -- currently only
+ # providing values used by trackster to determine the default range
if 'stats' in kwargs:
# FIXME: use actual chromosome size
summary = bbi.summarize( chrom, 0, 214783647, 1 )
@@ -445,7 +445,20 @@
if summary is None:
return None
else:
- return dict( data=dict( min=summary.min_val[0], max=summary.max_val[0] ) )
+ # Does the summary contain any defined values?
+ valid_count = summary.valid_count[0]
+ if summary.valid_count < 1:
+ return None
+
+ # Compute $\mu \pm 2\sigma$ to provide an estimate for upper and lower
+ # bounds that contain ~95% of the data.
+ mean = summary.sum_data[0] / valid_count
+ var = summary.sum_squares[0] - mean
+ if valid_count > 1:
+ var /= valid_count - 1
+ sd = sqrt( var )
+
+ return dict( data=dict( min=summary.min_val[0], max=summary.max_val[0], mean=mean, sd=sd ) )
start = int(start)
end = int(end)
diff -r f5961b41a0d4a7c7b1f21dc8829644573c9e5448 -r aa241b7e0138f5f107219666dc2e21daa76f3c87 static/june_2007_style/blue/trackster.css
--- a/static/june_2007_style/blue/trackster.css
+++ b/static/june_2007_style/blue/trackster.css
@@ -87,4 +87,5 @@
.icon.more-across{background:url('../images/fugue/arrow-transition-bw.png') no-repeat 0px 0px;}
.intro{padding:1em;}
.intro > .action-button{background-color:#CCC;padding:1em;}
-.feature-popup{background-color:#DDD;position:absolute;z-index:1000;}
+.feature-popup{position:absolute;z-index:1000;padding:5px;font-size:10px;filter:alpha(opacity=80);background-repeat:no-repeat;background-image:url(../images/tipsy.gif);background-position:top center;}
+.feature-popup-inner{padding:5px 8px 4px 8px;background-color:black;color:white;}
diff -r f5961b41a0d4a7c7b1f21dc8829644573c9e5448 -r aa241b7e0138f5f107219666dc2e21daa76f3c87 static/june_2007_style/trackster.css.tmpl
--- a/static/june_2007_style/trackster.css.tmpl
+++ b/static/june_2007_style/trackster.css.tmpl
@@ -405,8 +405,19 @@
background-color: #CCC;
padding: 1em;
}
-.feature-popup {
- background-color: #DDD;
+
+.feature-popup {
position: absolute;
z-index: 1000;
+ padding: 5px;
+ font-size: 10px;
+ filter: alpha(opacity=80);
+ background-repeat: no-repeat;
+ background-image: url(../images/tipsy.gif);
+ background-position: top center;
}
+.feature-popup-inner {
+ padding: 5px 8px 4px 8px;
+ background-color: black;
+ color: white;
+}
diff -r f5961b41a0d4a7c7b1f21dc8829644573c9e5448 -r aa241b7e0138f5f107219666dc2e21daa76f3c87 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -2268,8 +2268,8 @@
// Build popup.
var popup = $("<div/>").attr("id", feature_uid).addClass("feature-popup"),
- key, value,
- table = $("<table/>").appendTo(popup), row;
+ table = $("<table/>"),
+ key, value, row;
for (key in feature_dict) {
value = feature_dict[key];
row = $("<tr/>").appendTo(table);
@@ -2277,6 +2277,7 @@
$("<td/>").attr("align", "left").appendTo(row)
.text(typeof(value) == 'number' ? round(value, 2) : value);
}
+ popup.append( $("<div class='feature-popup-inner'>").append( table ) );
popups[feature_uid] = popup;
}
@@ -2287,7 +2288,7 @@
// parseInt strips "px" from left, top measurements. +7 so that mouse pointer does not
// overlap popup.
var
- popupX = offsetX + parseInt( tile.canvas.css("left") ) + 7,
+ popupX = offsetX + parseInt( tile.canvas.css("left") ) - popup.width() / 2,
popupY = offsetY + parseInt( tile.canvas.css("top") ) + 7;
popup.css("left", popupX + "px").css("top", popupY + "px")
}
@@ -3080,9 +3081,20 @@
track.container_div.addClass( "line-track" );
var data = result.data;
if ( isNaN(parseFloat(track.prefs.min_value)) || isNaN(parseFloat(track.prefs.max_value)) ) {
- track.prefs.min_value = data.min;
- track.prefs.max_value = data.max;
+ // Compute default minimum and maximum values
+ var min_value = data.min
+ var max_value = data.max
+ // If mean and sd are present, use them to compute a ~95% window
+ // but only if it would shrink the range on one side
+ min_value = Math.floor( Math.min( 0, Math.max( min_value, data.mean - 2 * data.sd ) ) )
+ max_value = Math.ceil( Math.max( 0, Math.min( max_value, data.mean + 2 * data.sd ) ) )
+ // Update the prefs
+ track.prefs.min_value = min_value;
+ track.prefs.max_value = max_value;
// Update the config
+ // FIXME: we should probably only save this when the user explicately sets it
+ // since we lose the ability to compute it on the fly (when changing
+ // chromosomes for example).
$('#track_' + track.dataset_id + '_minval').val(track.prefs.min_value);
$('#track_' + track.dataset_id + '_maxval').val(track.prefs.max_value);
}
https://bitbucket.org/galaxy/galaxy-central/changeset/6db378a732b3/
changeset: 6db378a732b3
user: james_taylor
date: 2011-10-31 23:06:39
summary: Automated merge with https://bitbucket.org/galaxy/galaxy-central
affected #: 11 files
diff -r ef39a111210018fb50282a352182b298c23be8f7 -r 6db378a732b382143bf2c8992d298ab278ffc8f9 eggs.ini
--- a/eggs.ini
+++ b/eggs.ini
@@ -12,7 +12,7 @@
no_auto = pbs_python DRMAA_python
[eggs:platform]
-bx_python = 0.7.0
+bx_python = 0.7.1
Cheetah = 2.2.2
ctypes = 1.0.2
DRMAA_python = 0.2
@@ -67,7 +67,7 @@
psycopg2 = _8.4.2_static
pysqlite = _3.6.17_static
MySQL_python = _5.1.41_static
-bx_python = _494c2d1d68b3_rebuild1
+; bx_python = _494c2d1d68b3_rebuild1
GeneTrack = _dev_48da9e998f0caf01c5be731e926f4b0481f658f0
SQLAlchemy = _dev_r6498
pysam = _kanwei_b10f6e722e9a
diff -r ef39a111210018fb50282a352182b298c23be8f7 -r 6db378a732b382143bf2c8992d298ab278ffc8f9 lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
--- a/lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
+++ b/lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
@@ -50,4 +50,4 @@
st.write(out_fname)
if __name__ == "__main__":
- main()
\ No newline at end of file
+ main()
diff -r ef39a111210018fb50282a352182b298c23be8f7 -r 6db378a732b382143bf2c8992d298ab278ffc8f9 lib/galaxy/visualization/tracks/data_providers.py
--- a/lib/galaxy/visualization/tracks/data_providers.py
+++ b/lib/galaxy/visualization/tracks/data_providers.py
@@ -2,8 +2,8 @@
Data providers for tracks visualizations.
"""
-import sys
-from math import ceil, log
+import sys, time
+from math import ceil, log, sqrt
import pkg_resources
pkg_resources.require( "bx-python" )
if sys.version_info[:2] == (2, 4):
@@ -434,40 +434,68 @@
# Bigwig has the possibility of it being a standalone bigwig file, in which case we use
# original_dataset, or coming from wig->bigwig conversion in which we use converted_dataset
f, bbi = self._get_dataset()
-
+
+ # If the stats kwarg was provide, we compute overall summary data for
+ # the entire chromosome, but no reduced data -- currently only
+ # providing values used by trackster to determine the default range
if 'stats' in kwargs:
- all_dat = bbi.query(chrom, 0, 2147483647, 1)
+ # FIXME: use actual chromosome size
+ summary = bbi.summarize( chrom, 0, 214783647, 1 )
f.close()
- if all_dat is None:
+ if summary is None:
return None
-
- all_dat = all_dat[0] # only 1 summary
- return { 'data' : { 'max': float( all_dat['max'] ), \
- 'min': float( all_dat['min'] ), \
- 'total_frequency': float( all_dat['coverage'] ) } \
- }
-
+ else:
+ # Does the summary contain any defined values?
+ valid_count = summary.valid_count[0]
+ if summary.valid_count < 1:
+ return None
+
+ # Compute $\mu \pm 2\sigma$ to provide an estimate for upper and lower
+ # bounds that contain ~95% of the data.
+ mean = summary.sum_data[0] / valid_count
+ var = summary.sum_squares[0] - mean
+ if valid_count > 1:
+ var /= valid_count - 1
+ sd = sqrt( var )
+
+ return dict( data=dict( min=summary.min_val[0], max=summary.max_val[0], mean=mean, sd=sd ) )
+
start = int(start)
end = int(end)
+
+ # The following seems not to work very well, for example it will only return one
+ # data point if the tile is 1280px wide. Not sure what the intent is.
+
# The first zoom level for BBI files is 640. If too much is requested, it will look at each block instead
# of summaries. The calculation done is: zoom <> (end-start)/num_points/2.
# Thus, the optimal number of points is (end-start)/num_points/2 = 640
# num_points = (end-start) / 1280
- num_points = (end-start) / 1280
- if num_points < 1:
- num_points = end - start
- else:
- num_points = min(num_points, 500)
+ #num_points = (end-start) / 1280
+ #if num_points < 1:
+ # num_points = end - start
+ #else:
+ # num_points = min(num_points, 500)
- data = bbi.query(chrom, start, end, num_points)
+ # For now, we'll do 1000 data points by default However, the summaries
+ # don't seem to work when a summary pixel corresponds to less than one
+ # datapoint, so we prevent that.
+ # FIXME: need to switch over to using the full data at high levels of
+ # detail.
+ num_points = min( 1000, end - start )
+
+ summary = bbi.summarize( chrom, start, end, num_points )
f.close()
+
+ result = []
+
+ if summary:
+ mean = summary.sum_data / summary.valid_count
- pos = start
- step_size = (end - start) / num_points
- result = []
- if data:
- for dat_dict in data:
- result.append( (pos, float_nan(dat_dict['mean']) ) )
+ pos = start
+ step_size = (end - start) / num_points
+
+ for value in mean:
+ result.append( (pos, float_nan(value) ) )
pos += step_size
return { 'data': result }
diff -r ef39a111210018fb50282a352182b298c23be8f7 -r 6db378a732b382143bf2c8992d298ab278ffc8f9 lib/galaxy/web/controllers/tracks.py
--- a/lib/galaxy/web/controllers/tracks.py
+++ b/lib/galaxy/web/controllers/tracks.py
@@ -524,6 +524,7 @@
if not standalone_provider.has_data( chrom ):
return messages.NO_DATA
valid_chroms = standalone_provider.valid_chroms()
+
# Have data if we get here
return { "status": messages.DATA, "valid_chroms": valid_chroms }
@@ -990,4 +991,4 @@
return_message = message
elif return_message == None and message == messages.PENDING:
return_message = message
- return return_message
\ No newline at end of file
+ return return_message
diff -r ef39a111210018fb50282a352182b298c23be8f7 -r 6db378a732b382143bf2c8992d298ab278ffc8f9 static/june_2007_style/blue/panel_layout.css
--- a/static/june_2007_style/blue/panel_layout.css
+++ b/static/june_2007_style/blue/panel_layout.css
@@ -23,9 +23,11 @@
.panel-header-button:hover{color:black;background-color:#ccc;}
.panel-header-button:active{color:white;background-color:#aaaaaa;}
#overlay{position:fixed;top:0;left:0;width:100%;height:100%;z-index:20000;}
+#overlay.modal #overlay-background{background:rgba(0,0,0,0.5);}
.dialog-box-container{position:relative;margin-top:80px;margin-right:auto;margin-left:auto;}
.dialog-box-wrapper{position:relative;padding:1em;background-color:rgba(0,0,0,0.5);-moz-border-radius:1em;-webkit-border-radius:1em;}
.dialog-box{border:solid #999 1px;background:white;z-index:80000;}
+#overlay.modal .dialog-box .body{min-width:600px;}
.dialog-box .body{padding:5px;overflow:auto;max-height:500px;min-width:300px;}
.dialog-box .buttons{padding:5px;}
.panel-error-message,.panel-warning-message,.panel-done-message,.panel-info-message{height:24px;line-height:24px;color:#303030;padding:0px;padding-left:26px;background-color:#FFCCCC;background-image:url(error_small.png);background-repeat:no-repeat;background-position:6px 50%;}
diff -r ef39a111210018fb50282a352182b298c23be8f7 -r 6db378a732b382143bf2c8992d298ab278ffc8f9 static/june_2007_style/blue/trackster.css
--- a/static/june_2007_style/blue/trackster.css
+++ b/static/june_2007_style/blue/trackster.css
@@ -3,30 +3,9 @@
.content{font:10px verdana;}
.nav-controls{text-align:center;padding:1px 0;}
.nav-controls input{margin:0 5px;}
-.menu-button{padding: 0px 4px 0px 4px;}
#zoom-in,#zoom-out{display:inline-block;height:16px;width:16px;margin-bottom:-3px;cursor:pointer;}
#zoom-out{background:transparent url(../images/fugue/magnifier-zoom-out.png) center center no-repeat;}
#zoom-in{margin-left:10px;background:transparent url(../images/fugue/magnifier-zoom.png) center center no-repeat;}
-.overview-icon{background:transparent url(../images/fugue/application-dock-270-bw.png) no-repeat;}
-.overview-icon:hover{background:transparent url(../images/fugue/application-dock-270.png) no-repeat;}
-.settings-icon{background:transparent url(../images/fugue/gear-bw.png) no-repeat;}
-.settings-icon:hover{background:transparent url(../images/fugue/gear.png) no-repeat;}
-.tools-icon{background:transparent url(../images/fugue/toolbox-bw.png) no-repeat;}
-.tools-icon:hover{background:transparent url(../images/fugue/toolbox.png) no-repeat;}
-.filters-icon{background:transparent url(../images/fugue/ui-slider-050-bw.png) no-repeat;}
-.filters-icon:hover{background:transparent url(../images/fugue/ui-slider-050.png) no-repeat;}
-.remove-icon,.overview-close{background:transparent url(../images/fugue/cross-small-bw.png) no-repeat;}
-.remove-icon:hover,.overview-close:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
-#close-icon{background:transparent url(../images/fugue/cross-circle-bw.png) no-repeat;margin-right:0px;}
-#close-icon:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
-#add-tracks-icon{background:transparent url(../images/fugue/plus-button-bw.png) no-repeat;}
-#add-tracks-icon:hover{background:transparent url(../images/fugue/plus-button.png) no-repeat;}
-#add-group-icon{background:transparent url(../images/fugue/block--plus-bw.png) no-repeat;}
-#add-group-icon:hover{background:transparent url(../images/fugue/block--plus.png) no-repeat;}
-#bookmarks-icon{background:transparent url(../images/fugue/bookmarks-bw.png) no-repeat;}
-#bookmarks-icon:hover{background:transparent url(../images/fugue/bookmarks.png) no-repeat;}
-#save-icon{background:transparent url(../images/fugue/disk--arrow-bw.png) no-repeat;}
-#save-icon:hover{background:transparent url(../images/fugue/disk--arrow.png) no-repeat;}
.nav-input{font-size:12px;width:30em;z-index:1000;}
.location{display:inline-block;width:15em;margin:0 10px;}
.draghandle{margin-top:2px;cursor:move;float:left;background:transparent url(../images/visualization/draggable_horizontal.png) center center no-repeat;width:10px;height:12px;}
@@ -65,16 +44,39 @@
input{font:10px verdana;}
.dynamic-tool,.filters{margin-left:0.25em;padding-bottom:0.5em;}
.dynamic-tool{width:410px;}
-.filters>.sliders,.display-controls{float:left;margin:1em;}
+.filters > .sliders,.display-controls{float:left;margin:1em;}
.sliders{width:410px;}
-.display-controls{border-left:solid 2px #DDDDDD;padding-left:1em}
-.filter-row{margin-top:0.4em;}
+.display-controls{border-left:solid 2px #DDDDDD;padding-left:1em
+}
+.filter-row {
+ margin-top:0.4em;}
.slider-row{margin-left:1em;}
.elt-label{float:left;font-weight:bold;margin-right:1em;}
.slider{float:right;width:200px;position:relative;}
.tool-name{font-size:110%;font-weight:bold;}
.param-row{margin-top:0.2em;margin-left:1em;}
.param-label{float:left;font-weight:bold;padding-top:0.2em;}
+.menu-button{padding:0px 4px 0px 4px;}
+.settings-icon{background:transparent url(../images/fugue/gear-bw.png) no-repeat;}
+.settings-icon:hover{background:transparent url(../images/fugue/gear.png) no-repeat;}
+.overview-icon{background:transparent url(../images/fugue/application-dock-270-bw.png) no-repeat;}
+.overview-icon:hover{background:transparent url(../images/fugue/application-dock-270.png) no-repeat;}
+.tools-icon{background:transparent url(../images/fugue/toolbox-bw.png) no-repeat;}
+.tools-icon:hover{background:transparent url(../images/fugue/toolbox.png) no-repeat;}
+.filters-icon{background:transparent url(../images/fugue/ui-slider-050-bw.png) no-repeat;}
+.filters-icon:hover{background:transparent url(../images/fugue/ui-slider-050.png) no-repeat;}
+.remove-icon,.overview-close{background:transparent url(../images/fugue/cross-small-bw.png) no-repeat;}
+.remove-icon:hover,.overview-close:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
+#close-icon{background:transparent url(../images/fugue/cross-circle-bw.png) no-repeat;margin-right:0px;}
+#close-icon:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
+#add-tracks-icon{background:transparent url(../images/fugue/plus-button-bw.png) no-repeat;}
+#add-tracks-icon:hover{background:transparent url(../images/fugue/plus-button.png) no-repeat;}
+#add-group-icon{background:transparent url(../images/fugue/block--plus-bw.png) no-repeat;}
+#add-group-icon:hover{background:transparent url(../images/fugue/block--plus.png) no-repeat;}
+#bookmarks-icon{background:transparent url(../images/fugue/bookmarks-bw.png) no-repeat;}
+#bookmarks-icon:hover{background:transparent url(../images/fugue/bookmarks.png) no-repeat;}
+#save-icon{background:transparent url(../images/fugue/disk--arrow-bw.png) no-repeat;}
+#save-icon:hover{background:transparent url(../images/fugue/disk--arrow.png) no-repeat;}
.child-track-icon{background:url('../images/fugue/arrow-000-small-bw.png') no-repeat;width:30px;cursor:move;}
.track-resize{background:white url('../images/visualization/draggable_vertical.png') no-repeat top center;position:absolute;right:3px;bottom:-4px;width:14px;height:7px;border:solid #999 1px;z-index:100;}
.bookmark{background:white;border:solid #999 1px;border-right:none;margin:0.5em;margin-right:0;padding:0.5em;}
@@ -85,4 +87,5 @@
.icon.more-across{background:url('../images/fugue/arrow-transition-bw.png') no-repeat 0px 0px;}
.intro{padding:1em;}
.intro > .action-button{background-color:#CCC;padding:1em;}
-.feature-popup{background-color:#DDD;position:absolute;z-index:1000}
+.feature-popup{position:absolute;z-index:1000;padding:5px;font-size:10px;filter:alpha(opacity=80);background-repeat:no-repeat;background-image:url(../images/tipsy.gif);background-position:top center;}
+.feature-popup-inner{padding:5px 8px 4px 8px;background-color:black;color:white;}
diff -r ef39a111210018fb50282a352182b298c23be8f7 -r 6db378a732b382143bf2c8992d298ab278ffc8f9 static/june_2007_style/panel_layout.css.tmpl
--- a/static/june_2007_style/panel_layout.css.tmpl
+++ b/static/june_2007_style/panel_layout.css.tmpl
@@ -161,6 +161,10 @@
z-index: 20000;
}
+#overlay.modal #overlay-background {
+ background: rgba(0,0,0,0.5);
+}
+
.dialog-box-container {
position: relative;
margin-top: 80px;
@@ -182,6 +186,10 @@
z-index: 80000;
}
+#overlay.modal .dialog-box .body {
+ min-width: 600px;
+}
+
.dialog-box .body {
padding: 5px;
overflow: auto;
diff -r ef39a111210018fb50282a352182b298c23be8f7 -r 6db378a732b382143bf2c8992d298ab278ffc8f9 static/june_2007_style/trackster.css.tmpl
--- a/static/june_2007_style/trackster.css.tmpl
+++ b/static/june_2007_style/trackster.css.tmpl
@@ -405,8 +405,19 @@
background-color: #CCC;
padding: 1em;
}
-.feature-popup{
- background-color: #DDD;
+
+.feature-popup {
position: absolute;
- z-index: 1000
+ z-index: 1000;
+ padding: 5px;
+ font-size: 10px;
+ filter: alpha(opacity=80);
+ background-repeat: no-repeat;
+ background-image: url(../images/tipsy.gif);
+ background-position: top center;
}
+.feature-popup-inner {
+ padding: 5px 8px 4px 8px;
+ background-color: black;
+ color: white;
+}
diff -r ef39a111210018fb50282a352182b298c23be8f7 -r 6db378a732b382143bf2c8992d298ab278ffc8f9 static/scripts/galaxy.panels.js
--- a/static/scripts/galaxy.panels.js
+++ b/static/scripts/galaxy.panels.js
@@ -163,13 +163,23 @@
// Modal dialog boxes
function hide_modal() {
- $(".dialog-box-container" ).fadeOut( function() {
+ $(".dialog-box-container" ).hide( 0, function() {
$("#overlay").hide();
+ $("#overlay").removeClass( "modal" );
$( ".dialog-box" ).find( ".body" ).children().remove();
} );
};
-function show_modal( title, body, buttons, extra_buttons, init_fn ) {
+function show_modal() {
+ $("#overlay").addClass( "modal" );
+ _show_modal.apply( this, arguments );
+}
+
+function show_message() {
+ _show_modal.apply( this, arguments );
+}
+
+function _show_modal( title, body, buttons, extra_buttons, init_fn ) {
if ( title ) {
$( ".dialog-box" ).find( ".title" ).html( title );
$( ".dialog-box" ).find( ".unified-panel-header" ).show();
@@ -205,7 +215,7 @@
$( ".dialog-box" ).find( ".body" ).html( body );
if ( ! $(".dialog-box-container").is( ":visible" ) ) {
$("#overlay").show();
- $(".dialog-box-container").fadeIn();
+ $(".dialog-box-container").show();
}
// Fix min-width so that modal cannot shrink considerably if
// new content is loaded.
diff -r ef39a111210018fb50282a352182b298c23be8f7 -r 6db378a732b382143bf2c8992d298ab278ffc8f9 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -699,7 +699,7 @@
remove: function() {
this.container.remove_drawable(this);
- this.container_div.fadeOut('slow', function() {
+ this.container_div.hide(0, function() {
$(this).remove();
// HACK: is there a better way to update the view?
view.update_intro_div();
@@ -1253,7 +1253,7 @@
DrawableCollection.prototype.remove_drawable.call(this, drawable);
if (hide) {
var view = this;
- drawable.container_div.fadeOut('slow', function() {
+ drawable.container_div.hide(0, function() {
$(this).remove();
view.update_intro_div();
});
@@ -2268,8 +2268,8 @@
// Build popup.
var popup = $("<div/>").attr("id", feature_uid).addClass("feature-popup"),
- key, value,
- table = $("<table/>").appendTo(popup), row;
+ table = $("<table/>"),
+ key, value, row;
for (key in feature_dict) {
value = feature_dict[key];
row = $("<tr/>").appendTo(table);
@@ -2277,6 +2277,7 @@
$("<td/>").attr("align", "left").appendTo(row)
.text(typeof(value) == 'number' ? round(value, 2) : value);
}
+ popup.append( $("<div class='feature-popup-inner'>").append( table ) );
popups[feature_uid] = popup;
}
@@ -2287,7 +2288,7 @@
// parseInt strips "px" from left, top measurements. +7 so that mouse pointer does not
// overlap popup.
var
- popupX = offsetX + parseInt( tile.canvas.css("left") ) + 7,
+ popupX = offsetX + parseInt( tile.canvas.css("left") ) - popup.width() / 2,
popupY = offsetY + parseInt( tile.canvas.css("top") ) + 7;
popup.css("left", popupX + "px").css("top", popupY + "px")
}
@@ -2699,7 +2700,7 @@
w_scale = width / range,
resolution = this.view.resolution,
parent_element = $("<div style='position: relative;'></div>");
-
+
// For overview, adjust high, low, resolution, and w_scale.
if (this.is_overview) {
low = this.view.max_low;
@@ -3080,9 +3081,20 @@
track.container_div.addClass( "line-track" );
var data = result.data;
if ( isNaN(parseFloat(track.prefs.min_value)) || isNaN(parseFloat(track.prefs.max_value)) ) {
- track.prefs.min_value = data.min;
- track.prefs.max_value = data.max;
+ // Compute default minimum and maximum values
+ var min_value = data.min
+ var max_value = data.max
+ // If mean and sd are present, use them to compute a ~95% window
+ // but only if it would shrink the range on one side
+ min_value = Math.floor( Math.min( 0, Math.max( min_value, data.mean - 2 * data.sd ) ) )
+ max_value = Math.ceil( Math.max( 0, Math.min( max_value, data.mean + 2 * data.sd ) ) )
+ // Update the prefs
+ track.prefs.min_value = min_value;
+ track.prefs.max_value = max_value;
// Update the config
+ // FIXME: we should probably only save this when the user explicately sets it
+ // since we lose the ability to compute it on the fly (when changing
+ // chromosomes for example).
$('#track_' + track.dataset_id + '_minval').val(track.prefs.min_value);
$('#track_' + track.dataset_id + '_maxval').val(track.prefs.max_value);
}
@@ -4721,4 +4733,4 @@
for ( key in modules.trackster ) {
target[key] = modules.trackster[key];
}
-})(window);
\ No newline at end of file
+})(window);
diff -r ef39a111210018fb50282a352182b298c23be8f7 -r 6db378a732b382143bf2c8992d298ab278ffc8f9 templates/workflow/editor.mako
--- a/templates/workflow/editor.mako
+++ b/templates/workflow/editor.mako
@@ -213,7 +213,7 @@
show_workflow_parameters();
},
beforeSubmit: function( data ) {
- show_modal( "Loading workflow", "progress" );
+ show_message( "Loading workflow", "progress" );
}
});
}
@@ -650,7 +650,7 @@
};
var save_current_workflow = function ( eventObj, success_callback ) {
- show_modal( "Saving workflow", "progress" );
+ show_message( "Saving workflow", "progress" );
workflow.check_changes_in_active_form();
if (!workflow.has_changes) {
hide_modal();
https://bitbucket.org/galaxy/galaxy-central/changeset/19fd9fccebb9/
changeset: 19fd9fccebb9
user: james_taylor
date: 2011-10-31 23:31:15
summary: Trackster: faster x axis drag/wheel scrolling, seems to work across browsers, but hard to tell across platforms, report your experiences
affected #: 1 file
diff -r 6db378a732b382143bf2c8992d298ab278ffc8f9 -r 19fd9fccebb9af1150ab409da94f74bdf2246fb6 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -1024,6 +1024,7 @@
// Only act on x axis scrolling if we see if, y will be i
// handled by the browser when the event bubbles up
if ( dx ) {
+ dx *= 50;
var delta_chrom = Math.round( - dx / view.viewport_container.width() * (view.high - view.low) );
view.move_delta( delta_chrom );
}
https://bitbucket.org/galaxy/galaxy-central/changeset/89b2abe925ba/
changeset: 89b2abe925ba
user: james_taylor
date: 2011-11-01 19:54:11
summary: Trackster: set min/max values for wiggle tracks using standard deviation. Add a new FeaturePainter that uses Arcs to connect blocks. Allow FeaturePainters to provide (computed) top and bottom padding around the rows where features are drawn.
affected #: 2 files
diff -r 19fd9fccebb9af1150ab409da94f74bdf2246fb6 -r 89b2abe925baa41872656df183125d5185004111 lib/galaxy/visualization/tracks/data_providers.py
--- a/lib/galaxy/visualization/tracks/data_providers.py
+++ b/lib/galaxy/visualization/tracks/data_providers.py
@@ -10,6 +10,7 @@
pkg_resources.require( "ctypes" )
pkg_resources.require( "pysam" )
pkg_resources.require( "numpy" )
+from numpy import *
from galaxy.datatypes.util.gff_util import *
from galaxy.util.json import from_json_string
from bx.interval_index_file import Indexes
@@ -490,12 +491,17 @@
if summary:
mean = summary.sum_data / summary.valid_count
+
+ ## Standard deviation by bin, not yet used
+ ## var = summary.sum_squares - mean
+ ## var /= minimum( valid_count - 1, 1 )
+ ## sd = sqrt( var )
pos = start
step_size = (end - start) / num_points
- for value in mean:
- result.append( (pos, float_nan(value) ) )
+ for i in range( num_points ):
+ result.append( (pos, float_nan( mean[i] ) ) )
pos += step_size
return { 'data': result }
diff -r 19fd9fccebb9af1150ab409da94f74bdf2246fb6 -r 89b2abe925baa41872656df183125d5185004111 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -3512,7 +3512,7 @@
var filter_height_scaler = (this.filters_manager.height_filter ? new FilterScaler(this.filters_manager.height_filter) : null);
// HACK: ref_seq will only be defined for ReadTracks, and only the ReadPainter accepts that argument
var painter = new (this.painter)(filtered, tile_low, tile_high, this.prefs, mode, filter_alpha_scaler, filter_height_scaler, ref_seq);
- var required_height = Math.max(MIN_TRACK_HEIGHT, painter.get_required_height(slots_required));
+ var required_height = Math.max(MIN_TRACK_HEIGHT, painter.get_required_height(slots_required,width));
var canvas = this.view.canvas_manager.new_canvas();
var feature_mapper = null;
@@ -4078,6 +4078,7 @@
this.feature_positions = {};
this.slot_height = slot_height;
this.translation = 0;
+ this.y_translation = 0;
};
/**
@@ -4099,7 +4100,7 @@
*/
FeaturePositionMapper.prototype.get_feature_data = function(x, y) {
// Find slot using Y.
- var slot = Math.floor( y/this.slot_height ),
+ var slot = Math.floor( (y-this.y_translation)/this.slot_height ),
feature_dict;
// May not be over a slot due to padding, margin, etc.
@@ -4129,15 +4130,23 @@
FeaturePainter.prototype.default_prefs = { block_color: "#FFF", connector_color: "#FFF" };
extend(FeaturePainter.prototype, {
- get_required_height: function(rows_required) {
+ get_required_height: function(rows_required, width) {
// y_scale is the height per row
var required_height = y_scale = this.get_row_height(), mode = this.mode;
// If using a packing mode, need to multiply by the number of slots used
if (mode === "no_detail" || mode === "Squish" || mode === "Pack") {
required_height = rows_required * y_scale;
}
+ return required_height + this.get_top_padding(width) + this.get_bottom_padding(width);
+ },
+ /** Extra padding before first row of features */
+ get_top_padding: function(width) {
+ return 0;
+ },
+ /** Extra padding after last row of features */
+ get_bottom_padding: function(width) {
// Pad bottom by half a row, at least 5 px
- return required_height + Math.max( Math.round( y_scale / 2 ), 5 );
+ return Math.max( Math.round( this.get_row_height() / 2 ), 5 )
},
/**
* Draw data on ctx using slots and within the rectangle defined by width and height. Returns
@@ -4174,6 +4183,7 @@
}
ctx.restore();
+ feature_mapper.y_translation = this.get_top_padding(width);
return feature_mapper;
},
/**
@@ -4200,6 +4210,10 @@
var LinkedFeaturePainter = function(data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler) {
FeaturePainter.call(this, data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler);
+ // Whether to draw a single connector in the background that spans the entire feature (the intron fishbone)
+ this.draw_background_connector = true;
+ // Whether to call draw_connector for every pair of blocks
+ this.draw_individual_connectors = false;
};
extend(LinkedFeaturePainter.prototype, FeaturePainter.prototype, {
@@ -4237,7 +4251,7 @@
f_end = Math.ceil( Math.min(width, Math.max(0, (feature_end - tile_low) * w_scale)) ),
draw_start = f_start,
draw_end = f_end,
- y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale,
+ y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale + this.get_top_padding(width),
thickness, y_start, thick_start = null, thick_end = null,
// TODO: is there any reason why block, label color cannot be set at the Painter level?
block_color = this.prefs.block_color,
@@ -4300,38 +4314,51 @@
// needed. This ensures that whole feature, regardless of whether it starts with
// a block, is visible.
//
-
- // Draw whole feature as connector/intron.
+
+ // Compute y axis center position and height
var cur_y_center, cur_height;
if (mode === "Squish" || mode === "Dense") {
- ctx.fillStyle = CONNECTOR_COLOR;
cur_y_center = y_center + Math.floor(SQUISH_FEATURE_HEIGHT/2) + 1;
cur_height = 1;
}
else { // mode === "Pack"
if (feature_strand) {
- var cur_y_center = y_center;
- var cur_height = thick_height;
- if (feature_strand === "+") {
- ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand' );
- } else if (feature_strand === "-") {
- ctx.fillStyle = ctx.canvas.manager.get_pattern( 'left_strand' );
- }
+ cur_y_center = y_center;
+ cur_height = thick_height;
}
else {
- ctx.fillStyle = CONNECTOR_COLOR;
cur_y_center += (SQUISH_FEATURE_HEIGHT/2) + 1;
cur_height = 1;
}
}
- ctx.fillRect(f_start, cur_y_center, f_end - f_start, cur_height);
+
+ // Draw whole feature as connector/intron.
+ if ( this.draw_background_connector ) {
+ if (mode === "Squish" || mode === "Dense") {
+ ctx.fillStyle = CONNECTOR_COLOR;
+ }
+ else { // mode === "Pack"
+ if (feature_strand) {
+ if (feature_strand === "+") {
+ ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand' );
+ } else if (feature_strand === "-") {
+ ctx.fillStyle = ctx.canvas.manager.get_pattern( 'left_strand' );
+ }
+ }
+ else {
+ ctx.fillStyle = CONNECTOR_COLOR;
+ }
+ }
+ ctx.fillRect(f_start, cur_y_center, f_end - f_start, cur_height);
+ }
// Draw blocks.
var start_and_height;
for (var k = 0, k_len = feature_blocks.length; k < k_len; k++) {
var block = feature_blocks[k],
block_start = Math.floor( Math.max(0, (block[0] - tile_low) * w_scale) ),
- block_end = Math.ceil( Math.min(width, Math.max((block[1] - tile_low) * w_scale)) );
+ block_end = Math.ceil( Math.min(width, Math.max((block[1] - tile_low) * w_scale)) ),
+ last_block_start, last_block_end;
// Skip drawing if block not on tile.
if (block_start > block_end) { continue; }
@@ -4362,6 +4389,12 @@
ctx.fillRect(block_thick_start, y_center + 1, block_thick_end - block_thick_start, thick_height );
}
}
+ // Draw individual connectors if required
+ if ( this.draw_individual_connectors && last_block_start ) {
+ this.draw_connector( ctx, last_block_start, last_block_end, block_start, block_end, y_center );
+ }
+ last_block_start = block_start;
+ last_block_end = block_end;
}
// FIXME: Height scaling only works in Pack mode right now.
@@ -4699,11 +4732,54 @@
}
});
+var ArcLinkedFeaturePainter = function(data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler) {
+ LinkedFeaturePainter.call(this, data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler);
+ // Need to know the longest feature length for adding spacing
+ this.longest_feature_length = this.calculate_longest_feature_length();
+ this.draw_background_connector = false;
+ this.draw_individual_connectors = true;
+};
+
+extend(ArcLinkedFeaturePainter.prototype, FeaturePainter.prototype, LinkedFeaturePainter.prototype, {
+
+ calculate_longest_feature_length: function () {
+ var longest_feature_length = 0;
+ for (var i = 0, len = this.data.length; i < len; i++) {
+ var feature = this.data[i], feature_start = feature[1], feature_end = feature[2];
+ longest_feature_length = Math.max( longest_feature_length, feature_end - feature_start );
+ }
+ return longest_feature_length;
+ },
+
+ get_top_padding: function( width ) {
+ var view_range = this.view_end - this.view_start,
+ w_scale = width / view_range;
+ return Math.min( 128, Math.ceil( ( this.longest_feature_length / 2 ) * w_scale ) );
+ },
+
+ draw_connector: function( ctx, block1_start, block1_end, block2_start, block2_end, y_center ) {
+ // Arc drawing -- from closest endpoints
+ var x_center = ( block1_end + block2_start ) / 2,
+ radius = block2_start - x_center;
+ // For full half circles
+ var angle1 = Math.PI, angle2 = 0;
+ if ( radius > 0 ) {
+ ctx.beginPath();
+ ctx.arc( x_center, y_center, block2_start - x_center, Math.PI, 0 );
+ ctx.stroke();
+ }
+ }
+});
+
+
+
+
exports.Scaler = Scaler;
exports.SummaryTreePainter = SummaryTreePainter;
exports.LinePainter = LinePainter;
exports.LinkedFeaturePainter = LinkedFeaturePainter;
exports.ReadPainter = ReadPainter;
+exports.ArcLinkedFeaturePainter = ArcLinkedFeaturePainter;
// End painters_module encapsulation
};
https://bitbucket.org/galaxy/galaxy-central/changeset/0f5d6b2b13f7/
changeset: 0f5d6b2b13f7
user: james_taylor
date: 2011-11-01 19:54:25
summary: Automated merge with https://bitbucket.org/galaxy/galaxy-central
affected #: 11 files
diff -r 33e2ae31dddd0f494841aaa7f408aac9312b031b -r 0f5d6b2b13f78e164550420d620e569e681ed8bc eggs.ini
--- a/eggs.ini
+++ b/eggs.ini
@@ -12,7 +12,7 @@
no_auto = pbs_python DRMAA_python
[eggs:platform]
-bx_python = 0.7.0
+bx_python = 0.7.1
Cheetah = 2.2.2
ctypes = 1.0.2
DRMAA_python = 0.2
@@ -67,7 +67,7 @@
psycopg2 = _8.4.2_static
pysqlite = _3.6.17_static
MySQL_python = _5.1.41_static
-bx_python = _494c2d1d68b3_rebuild1
+; bx_python = _494c2d1d68b3_rebuild1
GeneTrack = _dev_48da9e998f0caf01c5be731e926f4b0481f658f0
SQLAlchemy = _dev_r6498
pysam = _kanwei_b10f6e722e9a
diff -r 33e2ae31dddd0f494841aaa7f408aac9312b031b -r 0f5d6b2b13f78e164550420d620e569e681ed8bc lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
--- a/lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
+++ b/lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
@@ -50,4 +50,4 @@
st.write(out_fname)
if __name__ == "__main__":
- main()
\ No newline at end of file
+ main()
diff -r 33e2ae31dddd0f494841aaa7f408aac9312b031b -r 0f5d6b2b13f78e164550420d620e569e681ed8bc lib/galaxy/visualization/tracks/data_providers.py
--- a/lib/galaxy/visualization/tracks/data_providers.py
+++ b/lib/galaxy/visualization/tracks/data_providers.py
@@ -2,14 +2,15 @@
Data providers for tracks visualizations.
"""
-import sys
-from math import ceil, log
+import sys, time
+from math import ceil, log, sqrt
import pkg_resources
pkg_resources.require( "bx-python" )
if sys.version_info[:2] == (2, 4):
pkg_resources.require( "ctypes" )
pkg_resources.require( "pysam" )
pkg_resources.require( "numpy" )
+from numpy import *
from galaxy.datatypes.util.gff_util import *
from galaxy.util.json import from_json_string
from bx.interval_index_file import Indexes
@@ -720,40 +721,73 @@
# Bigwig has the possibility of it being a standalone bigwig file, in which case we use
# original_dataset, or coming from wig->bigwig conversion in which we use converted_dataset
f, bbi = self._get_dataset()
-
+
+ # If the stats kwarg was provide, we compute overall summary data for
+ # the entire chromosome, but no reduced data -- currently only
+ # providing values used by trackster to determine the default range
if 'stats' in kwargs:
- all_dat = bbi.query(chrom, 0, 2147483647, 1)
+ # FIXME: use actual chromosome size
+ summary = bbi.summarize( chrom, 0, 214783647, 1 )
f.close()
- if all_dat is None:
+ if summary is None:
return None
-
- all_dat = all_dat[0] # only 1 summary
- return { 'data' : { 'max': float( all_dat['max'] ), \
- 'min': float( all_dat['min'] ), \
- 'total_frequency': float( all_dat['coverage'] ) } \
- }
-
+ else:
+ # Does the summary contain any defined values?
+ valid_count = summary.valid_count[0]
+ if summary.valid_count < 1:
+ return None
+
+ # Compute $\mu \pm 2\sigma$ to provide an estimate for upper and lower
+ # bounds that contain ~95% of the data.
+ mean = summary.sum_data[0] / valid_count
+ var = summary.sum_squares[0] - mean
+ if valid_count > 1:
+ var /= valid_count - 1
+ sd = sqrt( var )
+
+ return dict( data=dict( min=summary.min_val[0], max=summary.max_val[0], mean=mean, sd=sd ) )
+
start = int(start)
end = int(end)
+
+ # The following seems not to work very well, for example it will only return one
+ # data point if the tile is 1280px wide. Not sure what the intent is.
+
# The first zoom level for BBI files is 640. If too much is requested, it will look at each block instead
# of summaries. The calculation done is: zoom <> (end-start)/num_points/2.
# Thus, the optimal number of points is (end-start)/num_points/2 = 640
# num_points = (end-start) / 1280
- num_points = (end-start) / 1280
- if num_points < 1:
- num_points = end - start
- else:
- num_points = min(num_points, 500)
+ #num_points = (end-start) / 1280
+ #if num_points < 1:
+ # num_points = end - start
+ #else:
+ # num_points = min(num_points, 500)
- data = bbi.query(chrom, start, end, num_points)
+ # For now, we'll do 1000 data points by default However, the summaries
+ # don't seem to work when a summary pixel corresponds to less than one
+ # datapoint, so we prevent that.
+ # FIXME: need to switch over to using the full data at high levels of
+ # detail.
+ num_points = min( 1000, end - start )
+
+ summary = bbi.summarize( chrom, start, end, num_points )
f.close()
+
+ result = []
+
+ if summary:
+ mean = summary.sum_data / summary.valid_count
+
+ ## Standard deviation by bin, not yet used
+ ## var = summary.sum_squares - mean
+ ## var /= minimum( valid_count - 1, 1 )
+ ## sd = sqrt( var )
- pos = start
- step_size = (end - start) / num_points
- result = []
- if data:
- for dat_dict in data:
- result.append( (pos, float_nan(dat_dict['mean']) ) )
+ pos = start
+ step_size = (end - start) / num_points
+
+ for i in range( num_points ):
+ result.append( (pos, float_nan( mean[i] ) ) )
pos += step_size
return { 'data': result }
diff -r 33e2ae31dddd0f494841aaa7f408aac9312b031b -r 0f5d6b2b13f78e164550420d620e569e681ed8bc lib/galaxy/web/controllers/tracks.py
--- a/lib/galaxy/web/controllers/tracks.py
+++ b/lib/galaxy/web/controllers/tracks.py
@@ -528,6 +528,7 @@
if not standalone_provider.has_data( chrom ):
return messages.NO_DATA
valid_chroms = standalone_provider.valid_chroms()
+
# Have data if we get here
return { "status": messages.DATA, "valid_chroms": valid_chroms }
@@ -1041,4 +1042,4 @@
return_message = message
elif return_message == None and message == messages.PENDING:
return_message = message
- return return_message
\ No newline at end of file
+ return return_message
diff -r 33e2ae31dddd0f494841aaa7f408aac9312b031b -r 0f5d6b2b13f78e164550420d620e569e681ed8bc static/june_2007_style/blue/panel_layout.css
--- a/static/june_2007_style/blue/panel_layout.css
+++ b/static/june_2007_style/blue/panel_layout.css
@@ -23,9 +23,11 @@
.panel-header-button:hover{color:black;background-color:#ccc;}
.panel-header-button:active{color:white;background-color:#aaaaaa;}
#overlay{position:fixed;top:0;left:0;width:100%;height:100%;z-index:20000;}
+#overlay.modal #overlay-background{background:rgba(0,0,0,0.5);}
.dialog-box-container{position:relative;margin-top:80px;margin-right:auto;margin-left:auto;}
.dialog-box-wrapper{position:relative;padding:1em;background-color:rgba(0,0,0,0.5);-moz-border-radius:1em;-webkit-border-radius:1em;}
.dialog-box{border:solid #999 1px;background:white;z-index:80000;}
+#overlay.modal .dialog-box .body{min-width:600px;}
.dialog-box .body{padding:5px;overflow:auto;max-height:500px;min-width:300px;}
.dialog-box .buttons{padding:5px;}
.panel-error-message,.panel-warning-message,.panel-done-message,.panel-info-message{height:24px;line-height:24px;color:#303030;padding:0px;padding-left:26px;background-color:#FFCCCC;background-image:url(error_small.png);background-repeat:no-repeat;background-position:6px 50%;}
diff -r 33e2ae31dddd0f494841aaa7f408aac9312b031b -r 0f5d6b2b13f78e164550420d620e569e681ed8bc static/june_2007_style/blue/trackster.css
--- a/static/june_2007_style/blue/trackster.css
+++ b/static/june_2007_style/blue/trackster.css
@@ -3,30 +3,9 @@
.content{font:10px verdana;}
.nav-controls{text-align:center;padding:1px 0;}
.nav-controls input{margin:0 5px;}
-.menu-button{padding: 0px 4px 0px 4px;}
#zoom-in,#zoom-out{display:inline-block;height:16px;width:16px;margin-bottom:-3px;cursor:pointer;}
#zoom-out{background:transparent url(../images/fugue/magnifier-zoom-out.png) center center no-repeat;}
#zoom-in{margin-left:10px;background:transparent url(../images/fugue/magnifier-zoom.png) center center no-repeat;}
-.overview-icon{background:transparent url(../images/fugue/application-dock-270-bw.png) no-repeat;}
-.overview-icon:hover{background:transparent url(../images/fugue/application-dock-270.png) no-repeat;}
-.settings-icon{background:transparent url(../images/fugue/gear-bw.png) no-repeat;}
-.settings-icon:hover{background:transparent url(../images/fugue/gear.png) no-repeat;}
-.tools-icon{background:transparent url(../images/fugue/toolbox-bw.png) no-repeat;}
-.tools-icon:hover{background:transparent url(../images/fugue/toolbox.png) no-repeat;}
-.filters-icon{background:transparent url(../images/fugue/ui-slider-050-bw.png) no-repeat;}
-.filters-icon:hover{background:transparent url(../images/fugue/ui-slider-050.png) no-repeat;}
-.remove-icon,.overview-close{background:transparent url(../images/fugue/cross-small-bw.png) no-repeat;}
-.remove-icon:hover,.overview-close:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
-#close-icon{background:transparent url(../images/fugue/cross-circle-bw.png) no-repeat;margin-right:0px;}
-#close-icon:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
-#add-tracks-icon{background:transparent url(../images/fugue/plus-button-bw.png) no-repeat;}
-#add-tracks-icon:hover{background:transparent url(../images/fugue/plus-button.png) no-repeat;}
-#add-group-icon{background:transparent url(../images/fugue/block--plus-bw.png) no-repeat;}
-#add-group-icon:hover{background:transparent url(../images/fugue/block--plus.png) no-repeat;}
-#bookmarks-icon{background:transparent url(../images/fugue/bookmarks-bw.png) no-repeat;}
-#bookmarks-icon:hover{background:transparent url(../images/fugue/bookmarks.png) no-repeat;}
-#save-icon{background:transparent url(../images/fugue/disk--arrow-bw.png) no-repeat;}
-#save-icon:hover{background:transparent url(../images/fugue/disk--arrow.png) no-repeat;}
.nav-input{font-size:12px;width:30em;z-index:1000;}
.location{display:inline-block;width:15em;margin:0 10px;}
.draghandle{margin-top:2px;cursor:move;float:left;background:transparent url(../images/visualization/draggable_horizontal.png) center center no-repeat;width:10px;height:12px;}
@@ -65,16 +44,39 @@
input{font:10px verdana;}
.dynamic-tool,.filters{margin-left:0.25em;padding-bottom:0.5em;}
.dynamic-tool{width:410px;}
-.filters>.sliders,.display-controls{float:left;margin:1em;}
+.filters > .sliders,.display-controls{float:left;margin:1em;}
.sliders{width:410px;}
-.display-controls{border-left:solid 2px #DDDDDD;padding-left:1em}
-.filter-row{margin-top:0.4em;}
+.display-controls{border-left:solid 2px #DDDDDD;padding-left:1em
+}
+.filter-row {
+ margin-top:0.4em;}
.slider-row{margin-left:1em;}
.elt-label{float:left;font-weight:bold;margin-right:1em;}
.slider{float:right;width:200px;position:relative;}
.tool-name{font-size:110%;font-weight:bold;}
.param-row{margin-top:0.2em;margin-left:1em;}
.param-label{float:left;font-weight:bold;padding-top:0.2em;}
+.menu-button{padding:0px 4px 0px 4px;}
+.settings-icon{background:transparent url(../images/fugue/gear-bw.png) no-repeat;}
+.settings-icon:hover{background:transparent url(../images/fugue/gear.png) no-repeat;}
+.overview-icon{background:transparent url(../images/fugue/application-dock-270-bw.png) no-repeat;}
+.overview-icon:hover{background:transparent url(../images/fugue/application-dock-270.png) no-repeat;}
+.tools-icon{background:transparent url(../images/fugue/toolbox-bw.png) no-repeat;}
+.tools-icon:hover{background:transparent url(../images/fugue/toolbox.png) no-repeat;}
+.filters-icon{background:transparent url(../images/fugue/ui-slider-050-bw.png) no-repeat;}
+.filters-icon:hover{background:transparent url(../images/fugue/ui-slider-050.png) no-repeat;}
+.remove-icon,.overview-close{background:transparent url(../images/fugue/cross-small-bw.png) no-repeat;}
+.remove-icon:hover,.overview-close:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
+#close-icon{background:transparent url(../images/fugue/cross-circle-bw.png) no-repeat;margin-right:0px;}
+#close-icon:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
+#add-tracks-icon{background:transparent url(../images/fugue/plus-button-bw.png) no-repeat;}
+#add-tracks-icon:hover{background:transparent url(../images/fugue/plus-button.png) no-repeat;}
+#add-group-icon{background:transparent url(../images/fugue/block--plus-bw.png) no-repeat;}
+#add-group-icon:hover{background:transparent url(../images/fugue/block--plus.png) no-repeat;}
+#bookmarks-icon{background:transparent url(../images/fugue/bookmarks-bw.png) no-repeat;}
+#bookmarks-icon:hover{background:transparent url(../images/fugue/bookmarks.png) no-repeat;}
+#save-icon{background:transparent url(../images/fugue/disk--arrow-bw.png) no-repeat;}
+#save-icon:hover{background:transparent url(../images/fugue/disk--arrow.png) no-repeat;}
.child-track-icon{background:url('../images/fugue/arrow-000-small-bw.png') no-repeat;width:30px;cursor:move;}
.track-resize{background:white url('../images/visualization/draggable_vertical.png') no-repeat top center;position:absolute;right:3px;bottom:-4px;width:14px;height:7px;border:solid #999 1px;z-index:100;}
.bookmark{background:white;border:solid #999 1px;border-right:none;margin:0.5em;margin-right:0;padding:0.5em;}
@@ -85,4 +87,5 @@
.icon.more-across{background:url('../images/fugue/arrow-transition-bw.png') no-repeat 0px 0px;}
.intro{padding:1em;}
.intro > .action-button{background-color:#CCC;padding:1em;}
-.feature-popup{background-color:#DDD;position:absolute;z-index:1000}
+.feature-popup{position:absolute;z-index:1000;padding:5px;font-size:10px;filter:alpha(opacity=80);background-repeat:no-repeat;background-image:url(../images/tipsy.gif);background-position:top center;}
+.feature-popup-inner{padding:5px 8px 4px 8px;background-color:black;color:white;}
diff -r 33e2ae31dddd0f494841aaa7f408aac9312b031b -r 0f5d6b2b13f78e164550420d620e569e681ed8bc static/june_2007_style/panel_layout.css.tmpl
--- a/static/june_2007_style/panel_layout.css.tmpl
+++ b/static/june_2007_style/panel_layout.css.tmpl
@@ -161,6 +161,10 @@
z-index: 20000;
}
+#overlay.modal #overlay-background {
+ background: rgba(0,0,0,0.5);
+}
+
.dialog-box-container {
position: relative;
margin-top: 80px;
@@ -182,6 +186,10 @@
z-index: 80000;
}
+#overlay.modal .dialog-box .body {
+ min-width: 600px;
+}
+
.dialog-box .body {
padding: 5px;
overflow: auto;
diff -r 33e2ae31dddd0f494841aaa7f408aac9312b031b -r 0f5d6b2b13f78e164550420d620e569e681ed8bc static/june_2007_style/trackster.css.tmpl
--- a/static/june_2007_style/trackster.css.tmpl
+++ b/static/june_2007_style/trackster.css.tmpl
@@ -405,8 +405,19 @@
background-color: #CCC;
padding: 1em;
}
-.feature-popup{
- background-color: #DDD;
+
+.feature-popup {
position: absolute;
- z-index: 1000
+ z-index: 1000;
+ padding: 5px;
+ font-size: 10px;
+ filter: alpha(opacity=80);
+ background-repeat: no-repeat;
+ background-image: url(../images/tipsy.gif);
+ background-position: top center;
}
+.feature-popup-inner {
+ padding: 5px 8px 4px 8px;
+ background-color: black;
+ color: white;
+}
diff -r 33e2ae31dddd0f494841aaa7f408aac9312b031b -r 0f5d6b2b13f78e164550420d620e569e681ed8bc static/scripts/galaxy.panels.js
--- a/static/scripts/galaxy.panels.js
+++ b/static/scripts/galaxy.panels.js
@@ -163,13 +163,23 @@
// Modal dialog boxes
function hide_modal() {
- $(".dialog-box-container" ).fadeOut( function() {
+ $(".dialog-box-container" ).hide( 0, function() {
$("#overlay").hide();
+ $("#overlay").removeClass( "modal" );
$( ".dialog-box" ).find( ".body" ).children().remove();
} );
};
-function show_modal( title, body, buttons, extra_buttons, init_fn ) {
+function show_modal() {
+ $("#overlay").addClass( "modal" );
+ _show_modal.apply( this, arguments );
+}
+
+function show_message() {
+ _show_modal.apply( this, arguments );
+}
+
+function _show_modal( title, body, buttons, extra_buttons, init_fn ) {
if ( title ) {
$( ".dialog-box" ).find( ".title" ).html( title );
$( ".dialog-box" ).find( ".unified-panel-header" ).show();
@@ -205,7 +215,7 @@
$( ".dialog-box" ).find( ".body" ).html( body );
if ( ! $(".dialog-box-container").is( ":visible" ) ) {
$("#overlay").show();
- $(".dialog-box-container").fadeIn();
+ $(".dialog-box-container").show();
}
// Fix min-width so that modal cannot shrink considerably if
// new content is loaded.
diff -r 33e2ae31dddd0f494841aaa7f408aac9312b031b -r 0f5d6b2b13f78e164550420d620e569e681ed8bc static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -699,7 +699,7 @@
remove: function() {
this.container.remove_drawable(this);
- this.container_div.fadeOut('slow', function() {
+ this.container_div.hide(0, function() {
$(this).remove();
// HACK: is there a better way to update the view?
view.update_intro_div();
@@ -1024,6 +1024,7 @@
// Only act on x axis scrolling if we see if, y will be i
// handled by the browser when the event bubbles up
if ( dx ) {
+ dx *= 50;
var delta_chrom = Math.round( - dx / view.viewport_container.width() * (view.high - view.low) );
view.move_delta( delta_chrom );
}
@@ -1253,7 +1254,7 @@
DrawableCollection.prototype.remove_drawable.call(this, drawable);
if (hide) {
var view = this;
- drawable.container_div.fadeOut('slow', function() {
+ drawable.container_div.hide(0, function() {
$(this).remove();
view.update_intro_div();
});
@@ -2268,8 +2269,8 @@
// Build popup.
var popup = $("<div/>").attr("id", feature_uid).addClass("feature-popup"),
- key, value,
- table = $("<table/>").appendTo(popup), row;
+ table = $("<table/>"),
+ key, value, row;
for (key in feature_dict) {
value = feature_dict[key];
row = $("<tr/>").appendTo(table);
@@ -2277,6 +2278,7 @@
$("<td/>").attr("align", "left").appendTo(row)
.text(typeof(value) == 'number' ? round(value, 2) : value);
}
+ popup.append( $("<div class='feature-popup-inner'>").append( table ) );
popups[feature_uid] = popup;
}
@@ -2287,7 +2289,7 @@
// parseInt strips "px" from left, top measurements. +7 so that mouse pointer does not
// overlap popup.
var
- popupX = offsetX + parseInt( tile.canvas.css("left") ) + 7,
+ popupX = offsetX + parseInt( tile.canvas.css("left") ) - popup.width() / 2,
popupY = offsetY + parseInt( tile.canvas.css("top") ) + 7;
popup.css("left", popupX + "px").css("top", popupY + "px")
}
@@ -2695,7 +2697,7 @@
w_scale = width / range,
resolution = this.view.resolution,
parent_element = $("<div style='position: relative;'></div>");
-
+
// For overview, adjust high, low, resolution, and w_scale.
if (this.is_overview) {
low = this.view.max_low;
@@ -3109,9 +3111,20 @@
track.container_div.addClass( "line-track" );
var data = result.data;
if ( isNaN(parseFloat(track.prefs.min_value)) || isNaN(parseFloat(track.prefs.max_value)) ) {
- track.prefs.min_value = data.min;
- track.prefs.max_value = data.max;
+ // Compute default minimum and maximum values
+ var min_value = data.min
+ var max_value = data.max
+ // If mean and sd are present, use them to compute a ~95% window
+ // but only if it would shrink the range on one side
+ min_value = Math.floor( Math.min( 0, Math.max( min_value, data.mean - 2 * data.sd ) ) )
+ max_value = Math.ceil( Math.max( 0, Math.min( max_value, data.mean + 2 * data.sd ) ) )
+ // Update the prefs
+ track.prefs.min_value = min_value;
+ track.prefs.max_value = max_value;
// Update the config
+ // FIXME: we should probably only save this when the user explicately sets it
+ // since we lose the ability to compute it on the fly (when changing
+ // chromosomes for example).
$('#track_' + track.dataset_id + '_minval').val(track.prefs.min_value);
$('#track_' + track.dataset_id + '_maxval').val(track.prefs.max_value);
}
@@ -3528,7 +3541,7 @@
var filter_height_scaler = (this.filters_manager.height_filter ? new FilterScaler(this.filters_manager.height_filter) : null);
// HACK: ref_seq will only be defined for ReadTracks, and only the ReadPainter accepts that argument
var painter = new (this.painter)(filtered, tile_low, tile_high, this.prefs, mode, filter_alpha_scaler, filter_height_scaler, ref_seq);
- var required_height = Math.max(MIN_TRACK_HEIGHT, painter.get_required_height(slots_required));
+ var required_height = Math.max(MIN_TRACK_HEIGHT, painter.get_required_height(slots_required,width));
var canvas = this.view.canvas_manager.new_canvas();
var feature_mapper = null;
@@ -4054,6 +4067,7 @@
this.feature_positions = {};
this.slot_height = slot_height;
this.translation = 0;
+ this.y_translation = 0;
};
/**
@@ -4075,7 +4089,7 @@
*/
FeaturePositionMapper.prototype.get_feature_data = function(x, y) {
// Find slot using Y.
- var slot = Math.floor( y/this.slot_height ),
+ var slot = Math.floor( (y-this.y_translation)/this.slot_height ),
feature_dict;
// May not be over a slot due to padding, margin, etc.
@@ -4105,15 +4119,23 @@
FeaturePainter.prototype.default_prefs = { block_color: "#FFF", connector_color: "#FFF" };
extend(FeaturePainter.prototype, {
- get_required_height: function(rows_required) {
+ get_required_height: function(rows_required, width) {
// y_scale is the height per row
var required_height = y_scale = this.get_row_height(), mode = this.mode;
// If using a packing mode, need to multiply by the number of slots used
if (mode === "no_detail" || mode === "Squish" || mode === "Pack") {
required_height = rows_required * y_scale;
}
+ return required_height + this.get_top_padding(width) + this.get_bottom_padding(width);
+ },
+ /** Extra padding before first row of features */
+ get_top_padding: function(width) {
+ return 0;
+ },
+ /** Extra padding after last row of features */
+ get_bottom_padding: function(width) {
// Pad bottom by half a row, at least 5 px
- return required_height + Math.max( Math.round( y_scale / 2 ), 5 );
+ return Math.max( Math.round( this.get_row_height() / 2 ), 5 )
},
/**
* Draw data on ctx using slots and within the rectangle defined by width and height. Returns
@@ -4150,6 +4172,7 @@
}
ctx.restore();
+ feature_mapper.y_translation = this.get_top_padding(width);
return feature_mapper;
},
/**
@@ -4176,6 +4199,10 @@
var LinkedFeaturePainter = function(data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler) {
FeaturePainter.call(this, data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler);
+ // Whether to draw a single connector in the background that spans the entire feature (the intron fishbone)
+ this.draw_background_connector = true;
+ // Whether to call draw_connector for every pair of blocks
+ this.draw_individual_connectors = false;
};
extend(LinkedFeaturePainter.prototype, FeaturePainter.prototype, {
@@ -4213,7 +4240,7 @@
f_end = Math.ceil( Math.min(width, Math.max(0, (feature_end - tile_low) * w_scale)) ),
draw_start = f_start,
draw_end = f_end,
- y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale,
+ y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale + this.get_top_padding(width),
thickness, y_start, thick_start = null, thick_end = null,
// TODO: is there any reason why block, label color cannot be set at the Painter level?
block_color = this.prefs.block_color,
@@ -4276,38 +4303,51 @@
// needed. This ensures that whole feature, regardless of whether it starts with
// a block, is visible.
//
-
- // Draw whole feature as connector/intron.
+
+ // Compute y axis center position and height
var cur_y_center, cur_height;
if (mode === "Squish" || mode === "Dense") {
- ctx.fillStyle = CONNECTOR_COLOR;
cur_y_center = y_center + Math.floor(SQUISH_FEATURE_HEIGHT/2) + 1;
cur_height = 1;
}
else { // mode === "Pack"
if (feature_strand) {
- var cur_y_center = y_center;
- var cur_height = thick_height;
- if (feature_strand === "+") {
- ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand' );
- } else if (feature_strand === "-") {
- ctx.fillStyle = ctx.canvas.manager.get_pattern( 'left_strand' );
- }
+ cur_y_center = y_center;
+ cur_height = thick_height;
}
else {
- ctx.fillStyle = CONNECTOR_COLOR;
cur_y_center += (SQUISH_FEATURE_HEIGHT/2) + 1;
cur_height = 1;
}
}
- ctx.fillRect(f_start, cur_y_center, f_end - f_start, cur_height);
+
+ // Draw whole feature as connector/intron.
+ if ( this.draw_background_connector ) {
+ if (mode === "Squish" || mode === "Dense") {
+ ctx.fillStyle = CONNECTOR_COLOR;
+ }
+ else { // mode === "Pack"
+ if (feature_strand) {
+ if (feature_strand === "+") {
+ ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand' );
+ } else if (feature_strand === "-") {
+ ctx.fillStyle = ctx.canvas.manager.get_pattern( 'left_strand' );
+ }
+ }
+ else {
+ ctx.fillStyle = CONNECTOR_COLOR;
+ }
+ }
+ ctx.fillRect(f_start, cur_y_center, f_end - f_start, cur_height);
+ }
// Draw blocks.
var start_and_height;
for (var k = 0, k_len = feature_blocks.length; k < k_len; k++) {
var block = feature_blocks[k],
block_start = Math.floor( Math.max(0, (block[0] - tile_low) * w_scale) ),
- block_end = Math.ceil( Math.min(width, Math.max((block[1] - tile_low) * w_scale)) );
+ block_end = Math.ceil( Math.min(width, Math.max((block[1] - tile_low) * w_scale)) ),
+ last_block_start, last_block_end;
// Skip drawing if block not on tile.
if (block_start > block_end) { continue; }
@@ -4338,6 +4378,12 @@
ctx.fillRect(block_thick_start, y_center + 1, block_thick_end - block_thick_start, thick_height );
}
}
+ // Draw individual connectors if required
+ if ( this.draw_individual_connectors && last_block_start ) {
+ this.draw_connector( ctx, last_block_start, last_block_end, block_start, block_end, y_center );
+ }
+ last_block_start = block_start;
+ last_block_end = block_end;
}
// FIXME: Height scaling only works in Pack mode right now.
@@ -4675,11 +4721,54 @@
}
});
+var ArcLinkedFeaturePainter = function(data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler) {
+ LinkedFeaturePainter.call(this, data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler);
+ // Need to know the longest feature length for adding spacing
+ this.longest_feature_length = this.calculate_longest_feature_length();
+ this.draw_background_connector = false;
+ this.draw_individual_connectors = true;
+};
+
+extend(ArcLinkedFeaturePainter.prototype, FeaturePainter.prototype, LinkedFeaturePainter.prototype, {
+
+ calculate_longest_feature_length: function () {
+ var longest_feature_length = 0;
+ for (var i = 0, len = this.data.length; i < len; i++) {
+ var feature = this.data[i], feature_start = feature[1], feature_end = feature[2];
+ longest_feature_length = Math.max( longest_feature_length, feature_end - feature_start );
+ }
+ return longest_feature_length;
+ },
+
+ get_top_padding: function( width ) {
+ var view_range = this.view_end - this.view_start,
+ w_scale = width / view_range;
+ return Math.min( 128, Math.ceil( ( this.longest_feature_length / 2 ) * w_scale ) );
+ },
+
+ draw_connector: function( ctx, block1_start, block1_end, block2_start, block2_end, y_center ) {
+ // Arc drawing -- from closest endpoints
+ var x_center = ( block1_end + block2_start ) / 2,
+ radius = block2_start - x_center;
+ // For full half circles
+ var angle1 = Math.PI, angle2 = 0;
+ if ( radius > 0 ) {
+ ctx.beginPath();
+ ctx.arc( x_center, y_center, block2_start - x_center, Math.PI, 0 );
+ ctx.stroke();
+ }
+ }
+});
+
+
+
+
exports.Scaler = Scaler;
exports.SummaryTreePainter = SummaryTreePainter;
exports.LinePainter = LinePainter;
exports.LinkedFeaturePainter = LinkedFeaturePainter;
exports.ReadPainter = ReadPainter;
+exports.ArcLinkedFeaturePainter = ArcLinkedFeaturePainter;
// End painters_module encapsulation
};
@@ -4710,4 +4799,4 @@
for ( key in modules.trackster ) {
target[key] = modules.trackster[key];
}
-})(window);
\ No newline at end of file
+})(window);
diff -r 33e2ae31dddd0f494841aaa7f408aac9312b031b -r 0f5d6b2b13f78e164550420d620e569e681ed8bc templates/workflow/editor.mako
--- a/templates/workflow/editor.mako
+++ b/templates/workflow/editor.mako
@@ -213,7 +213,7 @@
show_workflow_parameters();
},
beforeSubmit: function( data ) {
- show_modal( "Loading workflow", "progress" );
+ show_message( "Loading workflow", "progress" );
}
});
}
@@ -650,7 +650,7 @@
};
var save_current_workflow = function ( eventObj, success_callback ) {
- show_modal( "Saving workflow", "progress" );
+ show_message( "Saving workflow", "progress" );
workflow.check_changes_in_active_form();
if (!workflow.has_changes) {
hide_modal();
https://bitbucket.org/galaxy/galaxy-central/changeset/ebbf0f5e259c/
changeset: ebbf0f5e259c
user: james_taylor
date: 2011-11-01 23:56:34
summary: Make default height for LineTracks smaller, 32px seems more reasonable. Possibly it should be larger if there is both positive and negative data?
affected #: 1 file
diff -r 0f5d6b2b13f78e164550420d620e569e681ed8bc -r ebbf0f5e259cae099fcdcd6ac92697869b3b4bca static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -3031,7 +3031,8 @@
this.min_height_px = 16;
this.max_height_px = 400;
- this.height_px = 80;
+ // Default height for new tracks, should be a defined constant?
+ this.height_px = 32;
this.hda_ldda = hda_ldda;
this.dataset_id = dataset_id;
this.original_dataset_id = dataset_id;
https://bitbucket.org/galaxy/galaxy-central/changeset/ee0b898a2604/
changeset: ee0b898a2604
user: james_taylor
date: 2011-11-02 18:29:26
summary: Trackster: don't import all of numpy in data provider (problem with numpy's log un summary tree handling)
affected #: 1 file
diff -r ebbf0f5e259cae099fcdcd6ac92697869b3b4bca -r ee0b898a2604ce4c1896059fb56147be3ea2a674 lib/galaxy/visualization/tracks/data_providers.py
--- a/lib/galaxy/visualization/tracks/data_providers.py
+++ b/lib/galaxy/visualization/tracks/data_providers.py
@@ -10,7 +10,7 @@
pkg_resources.require( "ctypes" )
pkg_resources.require( "pysam" )
pkg_resources.require( "numpy" )
-from numpy import *
+import numpy
from galaxy.datatypes.util.gff_util import *
from galaxy.util.json import from_json_string
from bx.interval_index_file import Indexes
@@ -743,7 +743,7 @@
var = summary.sum_squares[0] - mean
if valid_count > 1:
var /= valid_count - 1
- sd = sqrt( var )
+ sd = numpy.sqrt( var )
return dict( data=dict( min=summary.min_val[0], max=summary.max_val[0], mean=mean, sd=sd ) )
https://bitbucket.org/galaxy/galaxy-central/changeset/5d3b2955f12e/
changeset: 5d3b2955f12e
user: james_taylor
date: 2011-11-02 18:37:24
summary: Trackster: allow configuration elements to have help text
affected #: 3 files
diff -r ee0b898a2604ce4c1896059fb56147be3ea2a674 -r 5d3b2955f12e08067d9a1ecd3f110777c7a83caf static/june_2007_style/base.css.tmpl
--- a/static/june_2007_style/base.css.tmpl
+++ b/static/june_2007_style/base.css.tmpl
@@ -231,6 +231,10 @@
padding: 3px 0 0 1em;
}
+.form-row .help {
+ color: #666;
+}
+
select, input, textarea {
font: inherit;
}
diff -r ee0b898a2604ce4c1896059fb56147be3ea2a674 -r 5d3b2955f12e08067d9a1ecd3f110777c7a83caf static/june_2007_style/blue/base.css
--- a/static/june_2007_style/blue/base.css
+++ b/static/june_2007_style/blue/base.css
@@ -43,6 +43,7 @@
div.form-row-input{float:left;}
div.form-row-input label{font-weight:normal;display:inline;}
div.form-row-error-message{width:300px;float:left;color:red;font-weight:bold;padding:3px 0 0 1em;}
+.form-row .help{color:#666;}
select,input,textarea{font:inherit;}
select,textarea,input[type="text"],input[type="file"],input[type="password"]{-webkit-box-sizing:border-box;max-width:300px;}
.errormessagelarge,.warningmessagelarge,.donemessagelarge,.infomessagelarge{padding:10px;padding-left:52px;min-height:32px;border:1px solid #AA6666;background-color:#FFCCCC;background-image:url(error_message_icon.png);background-repeat:no-repeat;background-position:10px 10px;}
diff -r ee0b898a2604ce4c1896059fb56147be3ea2a674 -r 5d3b2955f12e08067d9a1ecd3f110777c7a83caf static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -2149,6 +2149,10 @@
else {
row.append( $('<input />').attr("id", id ).attr("name", id ).val( value ) );
}
+ // Help text
+ if ( param.help ) {
+ row.append( $("<div class='help'/>").text( param.help ) );
+ }
}
});
return container;
@@ -3194,7 +3198,8 @@
{ key: 'name', label: 'Name', type: 'text', default_value: name },
{ key: 'block_color', label: 'Block color', type: 'color', default_value: get_random_color() },
{ key: 'label_color', label: 'Label color', type: 'color', default_value: 'black' },
- { key: 'show_counts', label: 'Show summary counts', type: 'bool', default_value: true },
+ { key: 'show_counts', label: 'Show summary counts', type: 'bool', default_value: true,
+ help: 'Show the number of items in each bin when drawing summary histogram' },
{ key: 'mode', type: 'string', default_value: this.mode, hidden: true },
],
saved_values: prefs,
https://bitbucket.org/galaxy/galaxy-central/changeset/5027d6f9ca30/
changeset: 5027d6f9ca30
user: james_taylor
date: 2011-11-02 22:53:00
summary: Trackster: allow track contents to be hidden without removing track. Hidden tracks are condensed and not drawn. TODO: whether a track is hidden is not currently saved. No easy way to inherit prefs right now.
affected #: 1 file
diff -r 5d3b2955f12e08067d9a1ecd3f110777c7a83caf -r 5027d6f9ca30432d0dc09d8e7598c1679d75aaed static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -2335,6 +2335,8 @@
this.data_url_extra_params = {}
this.data_query_wait = (data_query_wait ? data_query_wait : DEFAULT_DATA_QUERY_WAIT);
this.dataset_check_url = converted_datasets_state_url;
+ // FIXME: this should be a saved setting
+ this.content_visible = true;
if (!Track.id_counter) { Track.id_counter = 0; }
this.id = Track.id_counter++;
@@ -2353,6 +2355,9 @@
this.icons_div = $("<div/>").css("float", "left").appendTo(this.header_div).hide();
// Track icons.
+ this.toggle_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Hide/show track content")
+ .addClass("icon-button toggle").tipsy( {gravity: 's'} )
+ .appendTo(this.icons_div);
this.settings_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Edit settings")
.addClass("icon-button settings-icon").tipsy( {gravity: 's'} )
.appendTo(this.icons_div);
@@ -2372,6 +2377,21 @@
// Suppress double clicks in header so that they do not impact viz.
this.header_div.dblclick( function(e) { e.stopPropagation(); } );
+
+ // Toggle icon hides or shows the track content
+ this.toggle_icon.click( function() {
+ if ( track.content_visible ) {
+ track.toggle_icon.addClass("toggle-expand").removeClass("toggle");
+ track.hide_contents();
+ track.mode_div.hide();
+ track.content_visible = false;
+ } else {
+ track.toggle_icon.addClass("toggle").removeClass("toggle-expand");
+ track.content_visible = true;
+ track.mode_div.show();
+ track.show_contents();
+ }
+ });
// Clicking on settings icon opens track config.
this.settings_icon.click( function() {
@@ -2559,6 +2579,26 @@
this.update_track_icons();
},
/**
+ * Hide any elements that are part of the tracks contents area. Should
+ * remove as approprite, the track will be redrawn by show_contents.
+ */
+ hide_contents : function () {
+ // Clear contents by removing any elements that are contained in
+ // the tracks content_div
+ this.content_div.children().remove();
+ // Hide the content div
+ this.content_div.hide();
+ // And any y axis labels (common to several track types)
+ this.container_div.find(".yaxislabel, .track-resize").hide()
+ },
+ show_contents : function() {
+ // Show the contents div and labels (if present)
+ this.content_div.show();
+ this.container_div.find(".yaxislabel, .track-resize").show()
+ // Request a redraw of the content
+ this.request_draw();
+ },
+ /**
* Additional initialization required before drawing track for the first time.
*/
predraw_init: function() {}
@@ -2689,6 +2729,11 @@
*/
_draw: function(force, clear_after) {
if (!this.enabled) { return; }
+
+ // TODO: There should probably be a general way to disable content drawing
+ // for all drawables. However the button to toggle this is currently
+ // only present for Track instances.
+ if (!this.content_visible) { return; }
// HACK: ReferenceTrack can draw without dataset ID, but other tracks cannot.
if ( !(this instanceof ReferenceTrack) && (!this.dataset_id) ) { return; }
@@ -3084,8 +3129,10 @@
var drag_control = $( "<div class='track-resize'>" )
// Control shows on hover over track, stays while dragging
$(track.container_div).hover( function() {
- in_handle = true;
- drag_control.show();
+ if ( track.content_visible ) {
+ in_handle = true;
+ drag_control.show();
+ }
}, function() {
in_handle = false;
if ( ! in_drag ) { drag_control.hide(); }
https://bitbucket.org/galaxy/galaxy-central/changeset/b3900db4f77c/
changeset: b3900db4f77c
user: james_taylor
date: 2011-11-02 23:07:28
summary: Trackster: show color pickers to left of input rather than underneath
affected #: 1 file
diff -r 5027d6f9ca30432d0dc09d8e7598c1679d75aaed -r b3900db4f77c46687ae8aa2eb81a7aeaf7bfa751 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -2126,7 +2126,7 @@
} else if ( param.type === 'color' ) {
var input = $('<input />').attr("id", id ).attr("name", id ).val( value );
// Color picker in tool tip style float
- var tip = $( "<div class='tipsy tipsy-north' style='position: absolute;' />" ).hide();
+ var tip = $( "<div class='tipsy tipsy-west' style='position: absolute;' />" ).hide();
// Inner div for padding purposes
var tip_inner = $("<div style='background-color: black; padding: 10px;'></div>").appendTo(tip);
var farb_container = $("<div/>")
@@ -2136,8 +2136,10 @@
// Outer div container input and tip for hover to work
$("<div />").append( input ).append( tip ).appendTo( row ).bind( "click", function ( e ) {
tip.css( {
- left: $(this).position().left + ( $(input).width() / 2 ) - 60,
- top: $(this).position().top + $(this.height)
+ // left: $(this).position().left + ( $(input).width() / 2 ) - 60,
+ // top: $(this).position().top + $(this.height)
+ left: $(this).position().left + $(input).width() + 5,
+ top: $(this).position().top - ( $(tip).height() / 2 ) + ( $(input).height() / 2 )
} ).show();
$(document).bind( "click.color-picker", function() {
tip.hide();
https://bitbucket.org/galaxy/galaxy-central/changeset/62b7482496c2/
changeset: 62b7482496c2
user: james_taylor
date: 2011-11-05 19:55:11
summary: Trackster: making config form generation for parameters a function so it can be used recursively (for conditional configuration, not yet implemented)
affected #: 1 file
diff -r b3900db4f77c46687ae8aa2eb81a7aeaf7bfa751 -r 62b7482496c231f3ba0ea6f5682692ccc242fa14 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -2113,8 +2113,14 @@
build_form: function() {
var track_config = this;
var container = $("<div />");
- $.each( this.params, function( index, param ) {
- if ( ! param.hidden ) {
+ var param;
+ // Function to process parameters recursively
+ function handle_params( params, container ) {
+ for ( var index = 0; index < params.length; index++ ) {
+ param = params[index];
+ // Hidden params have no representation in the form
+ if ( param.hidden ) { continue; }
+ // Build row for param
var id = 'param_' + index;
var value = track_config.values[ param.key ];
var row = $("<div class='form-row' />").appendTo( container );
@@ -2132,7 +2138,6 @@
var farb_container = $("<div/>")
.appendTo(tip_inner)
.farbtastic( { width: 100, height: 100, callback: input, color: value });
-
// Outer div container input and tip for hover to work
$("<div />").append( input ).append( tip ).appendTo( row ).bind( "click", function ( e ) {
tip.css( {
@@ -2156,7 +2161,10 @@
row.append( $("<div class='help'/>").text( param.help ) );
}
}
- });
+ }
+ // Handle top level parameters in order
+ handle_params( this.params, container );
+ // Return element containing constructed form
return container;
},
update_from_form: function( container ) {
https://bitbucket.org/galaxy/galaxy-central/changeset/4db2b2230f7e/
changeset: 4db2b2230f7e
user: james_taylor
date: 2011-11-07 16:21:17
summary: Trackster: use hover event for feature track popups
affected #: 3 files
diff -r 62b7482496c231f3ba0ea6f5682692ccc242fa14 -r 4db2b2230f7e1dc075f696a4c6083956da02a4c4 eggs.ini
--- a/eggs.ini
+++ b/eggs.ini
@@ -12,7 +12,7 @@
no_auto = pbs_python DRMAA_python
[eggs:platform]
-bx_python = 0.7.1
+bx_python = 0.7.0
Cheetah = 2.2.2
ctypes = 1.0.2
DRMAA_python = 0.2
@@ -67,7 +67,7 @@
psycopg2 = _8.4.2_static
pysqlite = _3.6.17_static
MySQL_python = _5.1.41_static
-; bx_python = _494c2d1d68b3_rebuild1
+bx_python = _494c2d1d68b3_rebuild1
GeneTrack = _dev_48da9e998f0caf01c5be731e926f4b0481f658f0
SQLAlchemy = _dev_r6498
pysam = _kanwei_b10f6e722e9a
diff -r 62b7482496c231f3ba0ea6f5682692ccc242fa14 -r 4db2b2230f7e1dc075f696a4c6083956da02a4c4 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -2242,7 +2242,16 @@
// Only show popups in Pack mode.
if (tile.mode !== "Pack") { return; }
- $(this.canvas).mousemove(function (e) {
+ $(this.canvas).hover( function() {
+ this.hovered = true;
+ $(this).mousemove();
+ }, function() {
+ this.hovered = false;
+ // Clear popup if it is still hanging around (this is probably not needed)
+ $(this).siblings(".feature-popup").remove();
+ } ).mousemove(function (e) {
+ // Use the hover plugin to get a delay before showing popup
+ if ( !this.hovered ) { return; }
// Get feature data for position.
var
this_offset = $(this).offset(),
diff -r 62b7482496c231f3ba0ea6f5682692ccc242fa14 -r 4db2b2230f7e1dc075f696a4c6083956da02a4c4 templates/tracks/browser.mako
--- a/templates/tracks/browser.mako
+++ b/templates/tracks/browser.mako
@@ -42,7 +42,7 @@
<script type='text/javascript' src="${h.url_for('/static/scripts/excanvas.js')}"></script><![endif]-->
-${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.event.drag", "jquery.mousewheel", "jquery.autocomplete", "trackster", "trackster_ui", "jquery.ui.sortable.slider", "jquery.scrollTo", "farbtastic", "jquery.tipsy" )}
+${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.event.drag", "jquery.event.hover", "jquery.event.hover", "jquery.mousewheel", "jquery.autocomplete", "trackster", "trackster_ui", "jquery.ui.sortable.slider", "jquery.scrollTo", "farbtastic", "jquery.tipsy" )}
<script type="text/javascript">
//
https://bitbucket.org/galaxy/galaxy-central/changeset/4e9db728d9ea/
changeset: 4e9db728d9ea
user: james_taylor
date: 2011-11-07 16:27:50
summary: merge
affected #: 14 files
diff -r 545288e40ee10ed48d422eb772b734ace1422451 -r 4e9db728d9ea2553f387b53e6d25230b69a2789a lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
--- a/lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
+++ b/lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
@@ -50,4 +50,4 @@
st.write(out_fname)
if __name__ == "__main__":
- main()
\ No newline at end of file
+ main()
diff -r 545288e40ee10ed48d422eb772b734ace1422451 -r 4e9db728d9ea2553f387b53e6d25230b69a2789a lib/galaxy/visualization/tracks/data_providers.py
--- a/lib/galaxy/visualization/tracks/data_providers.py
+++ b/lib/galaxy/visualization/tracks/data_providers.py
@@ -2,14 +2,15 @@
Data providers for tracks visualizations.
"""
-import sys
-from math import ceil, log
+import sys, time
+from math import ceil, log, sqrt
import pkg_resources
pkg_resources.require( "bx-python" )
if sys.version_info[:2] == (2, 4):
pkg_resources.require( "ctypes" )
pkg_resources.require( "pysam" )
pkg_resources.require( "numpy" )
+import numpy
from galaxy.datatypes.util.gff_util import *
from galaxy.util.json import from_json_string
from bx.interval_index_file import Indexes
@@ -740,40 +741,73 @@
# Bigwig has the possibility of it being a standalone bigwig file, in which case we use
# original_dataset, or coming from wig->bigwig conversion in which we use converted_dataset
f, bbi = self._get_dataset()
-
+
+ # If the stats kwarg was provide, we compute overall summary data for
+ # the entire chromosome, but no reduced data -- currently only
+ # providing values used by trackster to determine the default range
if 'stats' in kwargs:
- all_dat = bbi.query(chrom, 0, 2147483647, 1)
+ # FIXME: use actual chromosome size
+ summary = bbi.summarize( chrom, 0, 214783647, 1 )
f.close()
- if all_dat is None:
+ if summary is None:
return None
-
- all_dat = all_dat[0] # only 1 summary
- return { 'data' : { 'max': float( all_dat['max'] ), \
- 'min': float( all_dat['min'] ), \
- 'total_frequency': float( all_dat['coverage'] ) } \
- }
-
+ else:
+ # Does the summary contain any defined values?
+ valid_count = summary.valid_count[0]
+ if summary.valid_count < 1:
+ return None
+
+ # Compute $\mu \pm 2\sigma$ to provide an estimate for upper and lower
+ # bounds that contain ~95% of the data.
+ mean = summary.sum_data[0] / valid_count
+ var = summary.sum_squares[0] - mean
+ if valid_count > 1:
+ var /= valid_count - 1
+ sd = numpy.sqrt( var )
+
+ return dict( data=dict( min=summary.min_val[0], max=summary.max_val[0], mean=mean, sd=sd ) )
+
start = int(start)
end = int(end)
+
+ # The following seems not to work very well, for example it will only return one
+ # data point if the tile is 1280px wide. Not sure what the intent is.
+
# The first zoom level for BBI files is 640. If too much is requested, it will look at each block instead
# of summaries. The calculation done is: zoom <> (end-start)/num_points/2.
# Thus, the optimal number of points is (end-start)/num_points/2 = 640
# num_points = (end-start) / 1280
- num_points = (end-start) / 1280
- if num_points < 1:
- num_points = end - start
- else:
- num_points = min(num_points, 500)
+ #num_points = (end-start) / 1280
+ #if num_points < 1:
+ # num_points = end - start
+ #else:
+ # num_points = min(num_points, 500)
- data = bbi.query(chrom, start, end, num_points)
+ # For now, we'll do 1000 data points by default However, the summaries
+ # don't seem to work when a summary pixel corresponds to less than one
+ # datapoint, so we prevent that.
+ # FIXME: need to switch over to using the full data at high levels of
+ # detail.
+ num_points = min( 1000, end - start )
+
+ summary = bbi.summarize( chrom, start, end, num_points )
f.close()
+
+ result = []
+
+ if summary:
+ mean = summary.sum_data / summary.valid_count
+
+ ## Standard deviation by bin, not yet used
+ ## var = summary.sum_squares - mean
+ ## var /= minimum( valid_count - 1, 1 )
+ ## sd = sqrt( var )
- pos = start
- step_size = (end - start) / num_points
- result = []
- if data:
- for dat_dict in data:
- result.append( (pos, float_nan(dat_dict['mean']) ) )
+ pos = start
+ step_size = (end - start) / num_points
+
+ for i in range( num_points ):
+ result.append( (pos, float_nan( mean[i] ) ) )
pos += step_size
return { 'data': result }
diff -r 545288e40ee10ed48d422eb772b734ace1422451 -r 4e9db728d9ea2553f387b53e6d25230b69a2789a lib/galaxy/web/controllers/tracks.py
--- a/lib/galaxy/web/controllers/tracks.py
+++ b/lib/galaxy/web/controllers/tracks.py
@@ -528,6 +528,7 @@
if not standalone_provider.has_data( chrom ):
return messages.NO_DATA
valid_chroms = standalone_provider.valid_chroms()
+
# Have data if we get here
return { "status": messages.DATA, "valid_chroms": valid_chroms }
@@ -1041,4 +1042,4 @@
return_message = message
elif return_message == None and message == messages.PENDING:
return_message = message
- return return_message
\ No newline at end of file
+ return return_message
diff -r 545288e40ee10ed48d422eb772b734ace1422451 -r 4e9db728d9ea2553f387b53e6d25230b69a2789a static/june_2007_style/base.css.tmpl
--- a/static/june_2007_style/base.css.tmpl
+++ b/static/june_2007_style/base.css.tmpl
@@ -231,6 +231,10 @@
padding: 3px 0 0 1em;
}
+.form-row .help {
+ color: #666;
+}
+
select, input, textarea {
font: inherit;
}
diff -r 545288e40ee10ed48d422eb772b734ace1422451 -r 4e9db728d9ea2553f387b53e6d25230b69a2789a static/june_2007_style/blue/base.css
--- a/static/june_2007_style/blue/base.css
+++ b/static/june_2007_style/blue/base.css
@@ -43,6 +43,7 @@
div.form-row-input{float:left;}
div.form-row-input label{font-weight:normal;display:inline;}
div.form-row-error-message{width:300px;float:left;color:red;font-weight:bold;padding:3px 0 0 1em;}
+.form-row .help{color:#666;}
select,input,textarea{font:inherit;}
select,textarea,input[type="text"],input[type="file"],input[type="password"]{-webkit-box-sizing:border-box;max-width:300px;}
.errormessagelarge,.warningmessagelarge,.donemessagelarge,.infomessagelarge{padding:10px;padding-left:52px;min-height:32px;border:1px solid #AA6666;background-color:#FFCCCC;background-image:url(error_message_icon.png);background-repeat:no-repeat;background-position:10px 10px;}
diff -r 545288e40ee10ed48d422eb772b734ace1422451 -r 4e9db728d9ea2553f387b53e6d25230b69a2789a static/june_2007_style/blue/panel_layout.css
--- a/static/june_2007_style/blue/panel_layout.css
+++ b/static/june_2007_style/blue/panel_layout.css
@@ -23,9 +23,11 @@
.panel-header-button:hover{color:black;background-color:#ccc;}
.panel-header-button:active{color:white;background-color:#aaaaaa;}
#overlay{position:fixed;top:0;left:0;width:100%;height:100%;z-index:20000;}
+#overlay.modal #overlay-background{background:rgba(0,0,0,0.5);}
.dialog-box-container{position:relative;margin-top:80px;margin-right:auto;margin-left:auto;}
.dialog-box-wrapper{position:relative;padding:1em;background-color:rgba(0,0,0,0.5);-moz-border-radius:1em;-webkit-border-radius:1em;}
.dialog-box{border:solid #999 1px;background:white;z-index:80000;}
+#overlay.modal .dialog-box .body{min-width:600px;}
.dialog-box .body{padding:5px;overflow:auto;max-height:500px;min-width:300px;}
.dialog-box .buttons{padding:5px;}
.panel-error-message,.panel-warning-message,.panel-done-message,.panel-info-message{height:24px;line-height:24px;color:#303030;padding:0px;padding-left:26px;background-color:#FFCCCC;background-image:url(error_small.png);background-repeat:no-repeat;background-position:6px 50%;}
diff -r 545288e40ee10ed48d422eb772b734ace1422451 -r 4e9db728d9ea2553f387b53e6d25230b69a2789a static/june_2007_style/blue/trackster.css
--- a/static/june_2007_style/blue/trackster.css
+++ b/static/june_2007_style/blue/trackster.css
@@ -3,30 +3,9 @@
.content{font:10px verdana;}
.nav-controls{text-align:center;padding:1px 0;}
.nav-controls input{margin:0 5px;}
-.menu-button{padding: 0px 4px 0px 4px;}
#zoom-in,#zoom-out{display:inline-block;height:16px;width:16px;margin-bottom:-3px;cursor:pointer;}
#zoom-out{background:transparent url(../images/fugue/magnifier-zoom-out.png) center center no-repeat;}
#zoom-in{margin-left:10px;background:transparent url(../images/fugue/magnifier-zoom.png) center center no-repeat;}
-.overview-icon{background:transparent url(../images/fugue/application-dock-270-bw.png) no-repeat;}
-.overview-icon:hover{background:transparent url(../images/fugue/application-dock-270.png) no-repeat;}
-.settings-icon{background:transparent url(../images/fugue/gear-bw.png) no-repeat;}
-.settings-icon:hover{background:transparent url(../images/fugue/gear.png) no-repeat;}
-.tools-icon{background:transparent url(../images/fugue/toolbox-bw.png) no-repeat;}
-.tools-icon:hover{background:transparent url(../images/fugue/toolbox.png) no-repeat;}
-.filters-icon{background:transparent url(../images/fugue/ui-slider-050-bw.png) no-repeat;}
-.filters-icon:hover{background:transparent url(../images/fugue/ui-slider-050.png) no-repeat;}
-.remove-icon,.overview-close{background:transparent url(../images/fugue/cross-small-bw.png) no-repeat;}
-.remove-icon:hover,.overview-close:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
-#close-icon{background:transparent url(../images/fugue/cross-circle-bw.png) no-repeat;margin-right:0px;}
-#close-icon:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
-#add-tracks-icon{background:transparent url(../images/fugue/plus-button-bw.png) no-repeat;}
-#add-tracks-icon:hover{background:transparent url(../images/fugue/plus-button.png) no-repeat;}
-#add-group-icon{background:transparent url(../images/fugue/block--plus-bw.png) no-repeat;}
-#add-group-icon:hover{background:transparent url(../images/fugue/block--plus.png) no-repeat;}
-#bookmarks-icon{background:transparent url(../images/fugue/bookmarks-bw.png) no-repeat;}
-#bookmarks-icon:hover{background:transparent url(../images/fugue/bookmarks.png) no-repeat;}
-#save-icon{background:transparent url(../images/fugue/disk--arrow-bw.png) no-repeat;}
-#save-icon:hover{background:transparent url(../images/fugue/disk--arrow.png) no-repeat;}
.nav-input{font-size:12px;width:30em;z-index:1000;}
.location{display:inline-block;width:15em;margin:0 10px;}
.draghandle{margin-top:2px;cursor:move;float:left;background:transparent url(../images/visualization/draggable_horizontal.png) center center no-repeat;width:10px;height:12px;}
@@ -65,16 +44,39 @@
input{font:10px verdana;}
.dynamic-tool,.filters{margin-left:0.25em;padding-bottom:0.5em;}
.dynamic-tool{width:410px;}
-.filters>.sliders,.display-controls{float:left;margin:1em;}
+.filters > .sliders,.display-controls{float:left;margin:1em;}
.sliders{width:410px;}
-.display-controls{border-left:solid 2px #DDDDDD;padding-left:1em}
-.filter-row{margin-top:0.4em;}
+.display-controls{border-left:solid 2px #DDDDDD;padding-left:1em
+}
+.filter-row {
+ margin-top:0.4em;}
.slider-row{margin-left:1em;}
.elt-label{float:left;font-weight:bold;margin-right:1em;}
.slider{float:right;width:200px;position:relative;}
.tool-name{font-size:110%;font-weight:bold;}
.param-row{margin-top:0.2em;margin-left:1em;}
.param-label{float:left;font-weight:bold;padding-top:0.2em;}
+.menu-button{padding:0px 4px 0px 4px;}
+.settings-icon{background:transparent url(../images/fugue/gear-bw.png) no-repeat;}
+.settings-icon:hover{background:transparent url(../images/fugue/gear.png) no-repeat;}
+.overview-icon{background:transparent url(../images/fugue/application-dock-270-bw.png) no-repeat;}
+.overview-icon:hover{background:transparent url(../images/fugue/application-dock-270.png) no-repeat;}
+.tools-icon{background:transparent url(../images/fugue/toolbox-bw.png) no-repeat;}
+.tools-icon:hover{background:transparent url(../images/fugue/toolbox.png) no-repeat;}
+.filters-icon{background:transparent url(../images/fugue/ui-slider-050-bw.png) no-repeat;}
+.filters-icon:hover{background:transparent url(../images/fugue/ui-slider-050.png) no-repeat;}
+.remove-icon,.overview-close{background:transparent url(../images/fugue/cross-small-bw.png) no-repeat;}
+.remove-icon:hover,.overview-close:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
+#close-icon{background:transparent url(../images/fugue/cross-circle-bw.png) no-repeat;margin-right:0px;}
+#close-icon:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
+#add-tracks-icon{background:transparent url(../images/fugue/plus-button-bw.png) no-repeat;}
+#add-tracks-icon:hover{background:transparent url(../images/fugue/plus-button.png) no-repeat;}
+#add-group-icon{background:transparent url(../images/fugue/block--plus-bw.png) no-repeat;}
+#add-group-icon:hover{background:transparent url(../images/fugue/block--plus.png) no-repeat;}
+#bookmarks-icon{background:transparent url(../images/fugue/bookmarks-bw.png) no-repeat;}
+#bookmarks-icon:hover{background:transparent url(../images/fugue/bookmarks.png) no-repeat;}
+#save-icon{background:transparent url(../images/fugue/disk--arrow-bw.png) no-repeat;}
+#save-icon:hover{background:transparent url(../images/fugue/disk--arrow.png) no-repeat;}
.child-track-icon{background:url('../images/fugue/arrow-000-small-bw.png') no-repeat;width:30px;cursor:move;}
.track-resize{background:white url('../images/visualization/draggable_vertical.png') no-repeat top center;position:absolute;right:3px;bottom:-4px;width:14px;height:7px;border:solid #999 1px;z-index:100;}
.bookmark{background:white;border:solid #999 1px;border-right:none;margin:0.5em;margin-right:0;padding:0.5em;}
@@ -85,4 +87,5 @@
.icon.more-across{background:url('../images/fugue/arrow-transition-bw.png') no-repeat 0px 0px;}
.intro{padding:1em;}
.intro > .action-button{background-color:#CCC;padding:1em;}
-.feature-popup{background-color:#DDD;position:absolute;z-index:1000}
+.feature-popup{position:absolute;z-index:1000;padding:5px;font-size:10px;filter:alpha(opacity=80);background-repeat:no-repeat;background-image:url(../images/tipsy.gif);background-position:top center;}
+.feature-popup-inner{padding:5px 8px 4px 8px;background-color:black;color:white;}
diff -r 545288e40ee10ed48d422eb772b734ace1422451 -r 4e9db728d9ea2553f387b53e6d25230b69a2789a static/june_2007_style/panel_layout.css.tmpl
--- a/static/june_2007_style/panel_layout.css.tmpl
+++ b/static/june_2007_style/panel_layout.css.tmpl
@@ -161,6 +161,10 @@
z-index: 20000;
}
+#overlay.modal #overlay-background {
+ background: rgba(0,0,0,0.5);
+}
+
.dialog-box-container {
position: relative;
margin-top: 80px;
@@ -182,6 +186,10 @@
z-index: 80000;
}
+#overlay.modal .dialog-box .body {
+ min-width: 600px;
+}
+
.dialog-box .body {
padding: 5px;
overflow: auto;
diff -r 545288e40ee10ed48d422eb772b734ace1422451 -r 4e9db728d9ea2553f387b53e6d25230b69a2789a static/june_2007_style/trackster.css.tmpl
--- a/static/june_2007_style/trackster.css.tmpl
+++ b/static/june_2007_style/trackster.css.tmpl
@@ -405,8 +405,19 @@
background-color: #CCC;
padding: 1em;
}
-.feature-popup{
- background-color: #DDD;
+
+.feature-popup {
position: absolute;
- z-index: 1000
+ z-index: 1000;
+ padding: 5px;
+ font-size: 10px;
+ filter: alpha(opacity=80);
+ background-repeat: no-repeat;
+ background-image: url(../images/tipsy.gif);
+ background-position: top center;
}
+.feature-popup-inner {
+ padding: 5px 8px 4px 8px;
+ background-color: black;
+ color: white;
+}
diff -r 545288e40ee10ed48d422eb772b734ace1422451 -r 4e9db728d9ea2553f387b53e6d25230b69a2789a static/scripts/galaxy.panels.js
--- a/static/scripts/galaxy.panels.js
+++ b/static/scripts/galaxy.panels.js
@@ -163,13 +163,23 @@
// Modal dialog boxes
function hide_modal() {
- $(".dialog-box-container" ).fadeOut( function() {
+ $(".dialog-box-container" ).hide( 0, function() {
$("#overlay").hide();
+ $("#overlay").removeClass( "modal" );
$( ".dialog-box" ).find( ".body" ).children().remove();
} );
};
-function show_modal( title, body, buttons, extra_buttons, init_fn ) {
+function show_modal() {
+ $("#overlay").addClass( "modal" );
+ _show_modal.apply( this, arguments );
+}
+
+function show_message() {
+ _show_modal.apply( this, arguments );
+}
+
+function _show_modal( title, body, buttons, extra_buttons, init_fn ) {
if ( title ) {
$( ".dialog-box" ).find( ".title" ).html( title );
$( ".dialog-box" ).find( ".unified-panel-header" ).show();
@@ -205,7 +215,7 @@
$( ".dialog-box" ).find( ".body" ).html( body );
if ( ! $(".dialog-box-container").is( ":visible" ) ) {
$("#overlay").show();
- $(".dialog-box-container").fadeIn();
+ $(".dialog-box-container").show();
}
// Fix min-width so that modal cannot shrink considerably if
// new content is loaded.
diff -r 545288e40ee10ed48d422eb772b734ace1422451 -r 4e9db728d9ea2553f387b53e6d25230b69a2789a static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -701,7 +701,7 @@
remove: function() {
this.container.remove_drawable(this);
- this.container_div.fadeOut('slow', function() {
+ this.container_div.hide(0, function() {
$(this).remove();
// HACK: is there a better way to update the view?
view.update_intro_div();
@@ -1027,6 +1027,7 @@
// Only act on x axis scrolling if we see if, y will be i
// handled by the browser when the event bubbles up
if ( dx ) {
+ dx *= 50;
var delta_chrom = Math.round( - dx / view.viewport_container.width() * (view.high - view.low) );
view.move_delta( delta_chrom );
}
@@ -1255,7 +1256,7 @@
DrawableCollection.prototype.remove_drawable.call(this, drawable);
if (hide) {
var view = this;
- drawable.container_div.fadeOut('slow', function() {
+ drawable.container_div.hide(0, function() {
$(this).remove();
view.update_intro_div();
});
@@ -2114,8 +2115,14 @@
build_form: function() {
var track_config = this;
var container = $("<div />");
- $.each( this.params, function( index, param ) {
- if ( ! param.hidden ) {
+ var param;
+ // Function to process parameters recursively
+ function handle_params( params, container ) {
+ for ( var index = 0; index < params.length; index++ ) {
+ param = params[index];
+ // Hidden params have no representation in the form
+ if ( param.hidden ) { continue; }
+ // Build row for param
var id = 'param_' + index;
var value = track_config.values[ param.key ];
var row = $("<div class='form-row' />").appendTo( container );
@@ -2127,18 +2134,19 @@
} else if ( param.type === 'color' ) {
var input = $('<input />').attr("id", id ).attr("name", id ).val( value );
// Color picker in tool tip style float
- var tip = $( "<div class='tipsy tipsy-north' style='position: absolute;' />" ).hide();
+ var tip = $( "<div class='tipsy tipsy-west' style='position: absolute;' />" ).hide();
// Inner div for padding purposes
var tip_inner = $("<div style='background-color: black; padding: 10px;'></div>").appendTo(tip);
var farb_container = $("<div/>")
.appendTo(tip_inner)
.farbtastic( { width: 100, height: 100, callback: input, color: value });
-
// Outer div container input and tip for hover to work
$("<div />").append( input ).append( tip ).appendTo( row ).bind( "click", function ( e ) {
tip.css( {
- left: $(this).position().left + ( $(input).width() / 2 ) - 60,
- top: $(this).position().top + $(this.height)
+ // left: $(this).position().left + ( $(input).width() / 2 ) - 60,
+ // top: $(this).position().top + $(this.height)
+ left: $(this).position().left + $(input).width() + 5,
+ top: $(this).position().top - ( $(tip).height() / 2 ) + ( $(input).height() / 2 )
} ).show();
$(document).bind( "click.color-picker", function() {
tip.hide();
@@ -2150,8 +2158,15 @@
else {
row.append( $('<input />').attr("id", id ).attr("name", id ).val( value ) );
}
+ // Help text
+ if ( param.help ) {
+ row.append( $("<div class='help'/>").text( param.help ) );
+ }
}
- });
+ }
+ // Handle top level parameters in order
+ handle_params( this.params, container );
+ // Return element containing constructed form
return container;
},
update_from_form: function( container ) {
@@ -2229,7 +2244,16 @@
// Only show popups in Pack mode.
if (tile.mode !== "Pack") { return; }
- $(this.canvas).mousemove(function (e) {
+ $(this.canvas).hover( function() {
+ this.hovered = true;
+ $(this).mousemove();
+ }, function() {
+ this.hovered = false;
+ // Clear popup if it is still hanging around (this is probably not needed)
+ $(this).siblings(".feature-popup").remove();
+ } ).mousemove(function (e) {
+ // Use the hover plugin to get a delay before showing popup
+ if ( !this.hovered ) { return; }
// Get feature data for position.
var
this_offset = $(this).offset(),
@@ -2270,8 +2294,8 @@
// Build popup.
var popup = $("<div/>").attr("id", feature_uid).addClass("feature-popup"),
- key, value,
- table = $("<table/>").appendTo(popup), row;
+ table = $("<table/>"),
+ key, value, row;
for (key in feature_dict) {
value = feature_dict[key];
row = $("<tr/>").appendTo(table);
@@ -2279,6 +2303,7 @@
$("<td/>").attr("align", "left").appendTo(row)
.text(typeof(value) == 'number' ? round(value, 2) : value);
}
+ popup.append( $("<div class='feature-popup-inner'>").append( table ) );
popups[feature_uid] = popup;
}
@@ -2289,7 +2314,7 @@
// parseInt strips "px" from left, top measurements. +7 so that mouse pointer does not
// overlap popup.
var
- popupX = offsetX + parseInt( tile.canvas.css("left") ) + 7,
+ popupX = offsetX + parseInt( tile.canvas.css("left") ) - popup.width() / 2,
popupY = offsetY + parseInt( tile.canvas.css("top") ) + 7;
popup.css("left", popupX + "px").css("top", popupY + "px")
}
@@ -2331,6 +2356,12 @@
this.data_url_extra_params = {}
this.data_query_wait = (data_query_wait ? data_query_wait : DEFAULT_DATA_QUERY_WAIT);
this.dataset_check_url = converted_datasets_state_url;
+
+ // FIXME: this should be a saved setting
+ this.content_visible = true;
+
+ if (!Track.id_counter) { Track.id_counter = 0; }
+ this.id = Track.id_counter++;
//
// Create HTML element structure for track.
@@ -2346,6 +2377,9 @@
this.icons_div = $("<div/>").css("float", "left").appendTo(this.header_div).hide();
// Track icons.
+ this.toggle_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Hide/show track content")
+ .addClass("icon-button toggle").tipsy( {gravity: 's'} )
+ .appendTo(this.icons_div);
this.settings_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Edit settings")
.addClass("icon-button settings-icon").tipsy( {gravity: 's'} )
.appendTo(this.icons_div);
@@ -2365,6 +2399,21 @@
// Suppress double clicks in header so that they do not impact viz.
this.header_div.dblclick( function(e) { e.stopPropagation(); } );
+
+ // Toggle icon hides or shows the track content
+ this.toggle_icon.click( function() {
+ if ( track.content_visible ) {
+ track.toggle_icon.addClass("toggle-expand").removeClass("toggle");
+ track.hide_contents();
+ track.mode_div.hide();
+ track.content_visible = false;
+ } else {
+ track.toggle_icon.addClass("toggle").removeClass("toggle-expand");
+ track.content_visible = true;
+ track.mode_div.show();
+ track.show_contents();
+ }
+ });
// Clicking on settings icon opens track config.
this.settings_icon.click( function() {
@@ -2552,6 +2601,26 @@
this.update_icons();
},
/**
+ * Hide any elements that are part of the tracks contents area. Should
+ * remove as approprite, the track will be redrawn by show_contents.
+ */
+ hide_contents : function () {
+ // Clear contents by removing any elements that are contained in
+ // the tracks content_div
+ this.content_div.children().remove();
+ // Hide the content div
+ this.content_div.hide();
+ // And any y axis labels (common to several track types)
+ this.container_div.find(".yaxislabel, .track-resize").hide()
+ },
+ show_contents : function() {
+ // Show the contents div and labels (if present)
+ this.content_div.show();
+ this.container_div.find(".yaxislabel, .track-resize").show()
+ // Request a redraw of the content
+ this.request_draw();
+ },
+ /**
* Additional initialization required before drawing track for the first time.
*/
predraw_init: function() {}
@@ -2682,6 +2751,11 @@
*/
_draw: function(force, clear_after) {
if (!this.enabled) { return; }
+
+ // TODO: There should probably be a general way to disable content drawing
+ // for all drawables. However the button to toggle this is currently
+ // only present for Track instances.
+ if (!this.content_visible) { return; }
// HACK: ReferenceTrack can draw without dataset ID, but other tracks cannot.
if ( !(this instanceof ReferenceTrack) && (!this.dataset_id) ) { return; }
@@ -2694,7 +2768,7 @@
w_scale = width / range,
resolution = this.view.resolution,
parent_element = $("<div style='position: relative;'></div>");
-
+
// For overview, adjust high, low, resolution, and w_scale.
if (this.is_overview) {
low = this.view.max_low;
@@ -3028,7 +3102,8 @@
this.min_height_px = 16;
this.max_height_px = 400;
- this.height_px = 80;
+ // Default height for new tracks, should be a defined constant?
+ this.height_px = 32;
this.hda_ldda = hda_ldda;
this.dataset_id = dataset_id;
this.original_dataset_id = dataset_id;
@@ -3076,8 +3151,10 @@
var drag_control = $( "<div class='track-resize'>" )
// Control shows on hover over track, stays while dragging
$(track.container_div).hover( function() {
- in_handle = true;
- drag_control.show();
+ if ( track.content_visible ) {
+ in_handle = true;
+ drag_control.show();
+ }
}, function() {
in_handle = false;
if ( ! in_drag ) { drag_control.hide(); }
@@ -3108,9 +3185,20 @@
track.container_div.addClass( "line-track" );
var data = result.data;
if ( isNaN(parseFloat(track.prefs.min_value)) || isNaN(parseFloat(track.prefs.max_value)) ) {
- track.prefs.min_value = data.min;
- track.prefs.max_value = data.max;
+ // Compute default minimum and maximum values
+ var min_value = data.min
+ var max_value = data.max
+ // If mean and sd are present, use them to compute a ~95% window
+ // but only if it would shrink the range on one side
+ min_value = Math.floor( Math.min( 0, Math.max( min_value, data.mean - 2 * data.sd ) ) )
+ max_value = Math.ceil( Math.max( 0, Math.min( max_value, data.mean + 2 * data.sd ) ) )
+ // Update the prefs
+ track.prefs.min_value = min_value;
+ track.prefs.max_value = max_value;
// Update the config
+ // FIXME: we should probably only save this when the user explicately sets it
+ // since we lose the ability to compute it on the fly (when changing
+ // chromosomes for example).
$('#track_' + track.dataset_id + '_minval').val(track.prefs.min_value);
$('#track_' + track.dataset_id + '_maxval').val(track.prefs.max_value);
}
@@ -3179,7 +3267,8 @@
{ key: 'name', label: 'Name', type: 'text', default_value: name },
{ key: 'block_color', label: 'Block color', type: 'color', default_value: get_random_color() },
{ key: 'label_color', label: 'Label color', type: 'color', default_value: 'black' },
- { key: 'show_counts', label: 'Show summary counts', type: 'bool', default_value: true },
+ { key: 'show_counts', label: 'Show summary counts', type: 'bool', default_value: true,
+ help: 'Show the number of items in each bin when drawing summary histogram' },
{ key: 'mode', type: 'string', default_value: this.mode, hidden: true },
],
saved_values: prefs,
@@ -3527,7 +3616,7 @@
var filter_height_scaler = (this.filters_manager.height_filter ? new FilterScaler(this.filters_manager.height_filter) : null);
// HACK: ref_seq will only be defined for ReadTracks, and only the ReadPainter accepts that argument
var painter = new (this.painter)(filtered, tile_low, tile_high, this.prefs, mode, filter_alpha_scaler, filter_height_scaler, ref_seq);
- var required_height = Math.max(MIN_TRACK_HEIGHT, painter.get_required_height(slots_required));
+ var required_height = Math.max(MIN_TRACK_HEIGHT, painter.get_required_height(slots_required,width));
var canvas = this.view.canvas_manager.new_canvas();
var feature_mapper = null;
@@ -4057,6 +4146,7 @@
this.feature_positions = {};
this.slot_height = slot_height;
this.translation = 0;
+ this.y_translation = 0;
};
/**
@@ -4078,7 +4168,7 @@
*/
FeaturePositionMapper.prototype.get_feature_data = function(x, y) {
// Find slot using Y.
- var slot = Math.floor( y/this.slot_height ),
+ var slot = Math.floor( (y-this.y_translation)/this.slot_height ),
feature_dict;
// May not be over a slot due to padding, margin, etc.
@@ -4108,15 +4198,23 @@
FeaturePainter.prototype.default_prefs = { block_color: "#FFF", connector_color: "#FFF" };
extend(FeaturePainter.prototype, {
- get_required_height: function(rows_required) {
+ get_required_height: function(rows_required, width) {
// y_scale is the height per row
var required_height = y_scale = this.get_row_height(), mode = this.mode;
// If using a packing mode, need to multiply by the number of slots used
if (mode === "no_detail" || mode === "Squish" || mode === "Pack") {
required_height = rows_required * y_scale;
}
+ return required_height + this.get_top_padding(width) + this.get_bottom_padding(width);
+ },
+ /** Extra padding before first row of features */
+ get_top_padding: function(width) {
+ return 0;
+ },
+ /** Extra padding after last row of features */
+ get_bottom_padding: function(width) {
// Pad bottom by half a row, at least 5 px
- return required_height + Math.max( Math.round( y_scale / 2 ), 5 );
+ return Math.max( Math.round( this.get_row_height() / 2 ), 5 )
},
/**
* Draw data on ctx using slots and within the rectangle defined by width and height. Returns
@@ -4153,6 +4251,7 @@
}
ctx.restore();
+ feature_mapper.y_translation = this.get_top_padding(width);
return feature_mapper;
},
/**
@@ -4179,6 +4278,10 @@
var LinkedFeaturePainter = function(data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler) {
FeaturePainter.call(this, data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler);
+ // Whether to draw a single connector in the background that spans the entire feature (the intron fishbone)
+ this.draw_background_connector = true;
+ // Whether to call draw_connector for every pair of blocks
+ this.draw_individual_connectors = false;
};
extend(LinkedFeaturePainter.prototype, FeaturePainter.prototype, {
@@ -4216,7 +4319,7 @@
f_end = Math.ceil( Math.min(width, Math.max(0, (feature_end - tile_low) * w_scale)) ),
draw_start = f_start,
draw_end = f_end,
- y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale,
+ y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale + this.get_top_padding(width),
thickness, y_start, thick_start = null, thick_end = null,
// TODO: is there any reason why block, label color cannot be set at the Painter level?
block_color = this.prefs.block_color,
@@ -4279,38 +4382,51 @@
// needed. This ensures that whole feature, regardless of whether it starts with
// a block, is visible.
//
-
- // Draw whole feature as connector/intron.
+
+ // Compute y axis center position and height
var cur_y_center, cur_height;
if (mode === "Squish" || mode === "Dense") {
- ctx.fillStyle = CONNECTOR_COLOR;
cur_y_center = y_center + Math.floor(SQUISH_FEATURE_HEIGHT/2) + 1;
cur_height = 1;
}
else { // mode === "Pack"
if (feature_strand) {
- var cur_y_center = y_center;
- var cur_height = thick_height;
- if (feature_strand === "+") {
- ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand' );
- } else if (feature_strand === "-") {
- ctx.fillStyle = ctx.canvas.manager.get_pattern( 'left_strand' );
- }
+ cur_y_center = y_center;
+ cur_height = thick_height;
}
else {
- ctx.fillStyle = CONNECTOR_COLOR;
cur_y_center += (SQUISH_FEATURE_HEIGHT/2) + 1;
cur_height = 1;
}
}
- ctx.fillRect(f_start, cur_y_center, f_end - f_start, cur_height);
+
+ // Draw whole feature as connector/intron.
+ if ( this.draw_background_connector ) {
+ if (mode === "Squish" || mode === "Dense") {
+ ctx.fillStyle = CONNECTOR_COLOR;
+ }
+ else { // mode === "Pack"
+ if (feature_strand) {
+ if (feature_strand === "+") {
+ ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand' );
+ } else if (feature_strand === "-") {
+ ctx.fillStyle = ctx.canvas.manager.get_pattern( 'left_strand' );
+ }
+ }
+ else {
+ ctx.fillStyle = CONNECTOR_COLOR;
+ }
+ }
+ ctx.fillRect(f_start, cur_y_center, f_end - f_start, cur_height);
+ }
// Draw blocks.
var start_and_height;
for (var k = 0, k_len = feature_blocks.length; k < k_len; k++) {
var block = feature_blocks[k],
block_start = Math.floor( Math.max(0, (block[0] - tile_low) * w_scale) ),
- block_end = Math.ceil( Math.min(width, Math.max((block[1] - tile_low) * w_scale)) );
+ block_end = Math.ceil( Math.min(width, Math.max((block[1] - tile_low) * w_scale)) ),
+ last_block_start, last_block_end;
// Skip drawing if block not on tile.
if (block_start > block_end) { continue; }
@@ -4341,6 +4457,12 @@
ctx.fillRect(block_thick_start, y_center + 1, block_thick_end - block_thick_start, thick_height );
}
}
+ // Draw individual connectors if required
+ if ( this.draw_individual_connectors && last_block_start ) {
+ this.draw_connector( ctx, last_block_start, last_block_end, block_start, block_end, y_center );
+ }
+ last_block_start = block_start;
+ last_block_end = block_end;
}
// FIXME: Height scaling only works in Pack mode right now.
@@ -4673,11 +4795,54 @@
}
});
+var ArcLinkedFeaturePainter = function(data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler) {
+ LinkedFeaturePainter.call(this, data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler);
+ // Need to know the longest feature length for adding spacing
+ this.longest_feature_length = this.calculate_longest_feature_length();
+ this.draw_background_connector = false;
+ this.draw_individual_connectors = true;
+};
+
+extend(ArcLinkedFeaturePainter.prototype, FeaturePainter.prototype, LinkedFeaturePainter.prototype, {
+
+ calculate_longest_feature_length: function () {
+ var longest_feature_length = 0;
+ for (var i = 0, len = this.data.length; i < len; i++) {
+ var feature = this.data[i], feature_start = feature[1], feature_end = feature[2];
+ longest_feature_length = Math.max( longest_feature_length, feature_end - feature_start );
+ }
+ return longest_feature_length;
+ },
+
+ get_top_padding: function( width ) {
+ var view_range = this.view_end - this.view_start,
+ w_scale = width / view_range;
+ return Math.min( 128, Math.ceil( ( this.longest_feature_length / 2 ) * w_scale ) );
+ },
+
+ draw_connector: function( ctx, block1_start, block1_end, block2_start, block2_end, y_center ) {
+ // Arc drawing -- from closest endpoints
+ var x_center = ( block1_end + block2_start ) / 2,
+ radius = block2_start - x_center;
+ // For full half circles
+ var angle1 = Math.PI, angle2 = 0;
+ if ( radius > 0 ) {
+ ctx.beginPath();
+ ctx.arc( x_center, y_center, block2_start - x_center, Math.PI, 0 );
+ ctx.stroke();
+ }
+ }
+});
+
+
+
+
exports.Scaler = Scaler;
exports.SummaryTreePainter = SummaryTreePainter;
exports.LinePainter = LinePainter;
exports.LinkedFeaturePainter = LinkedFeaturePainter;
exports.ReadPainter = ReadPainter;
+exports.ArcLinkedFeaturePainter = ArcLinkedFeaturePainter;
// End painters_module encapsulation
};
@@ -4708,4 +4873,4 @@
for ( key in modules.trackster ) {
target[key] = modules.trackster[key];
}
-})(window);
\ No newline at end of file
+})(window);
diff -r 545288e40ee10ed48d422eb772b734ace1422451 -r 4e9db728d9ea2553f387b53e6d25230b69a2789a templates/tracks/browser.mako
--- a/templates/tracks/browser.mako
+++ b/templates/tracks/browser.mako
@@ -42,7 +42,7 @@
<script type='text/javascript' src="${h.url_for('/static/scripts/excanvas.js')}"></script><![endif]-->
-${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.event.drag", "jquery.mousewheel", "jquery.autocomplete", "trackster", "trackster_ui", "jquery.ui.sortable.slider", "farbtastic", "jquery.tipsy" )}
+${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.event.drag", "jquery.event.hover","jquery.mousewheel", "jquery.autocomplete", "trackster", "trackster_ui", "jquery.ui.sortable.slider", "farbtastic", "jquery.tipsy" )}
<script type="text/javascript">
//
diff -r 545288e40ee10ed48d422eb772b734ace1422451 -r 4e9db728d9ea2553f387b53e6d25230b69a2789a templates/workflow/editor.mako
--- a/templates/workflow/editor.mako
+++ b/templates/workflow/editor.mako
@@ -213,7 +213,7 @@
show_workflow_parameters();
},
beforeSubmit: function( data ) {
- show_modal( "Loading workflow", "progress" );
+ show_message( "Loading workflow", "progress" );
}
});
}
@@ -650,7 +650,7 @@
};
var save_current_workflow = function ( eventObj, success_callback ) {
- show_modal( "Saving workflow", "progress" );
+ show_message( "Saving workflow", "progress" );
workflow.check_changes_in_active_form();
if (!workflow.has_changes) {
hide_modal();
https://bitbucket.org/galaxy/galaxy-central/changeset/9c80e9985d71/
changeset: 9c80e9985d71
user: james_taylor
date: 2011-11-07 16:32:18
summary: Move bx-python version to 0.7.1 (again)
affected #: 1 file
diff -r 4db2b2230f7e1dc075f696a4c6083956da02a4c4 -r 9c80e9985d71939dfcda96a1c21c9be85983620f eggs.ini
--- a/eggs.ini
+++ b/eggs.ini
@@ -12,7 +12,7 @@
no_auto = pbs_python DRMAA_python
[eggs:platform]
-bx_python = 0.7.0
+bx_python = 0.7.1
Cheetah = 2.2.2
ctypes = 1.0.2
DRMAA_python = 0.2
@@ -67,7 +67,7 @@
psycopg2 = _8.4.2_static
pysqlite = _3.6.17_static
MySQL_python = _5.1.41_static
-bx_python = _494c2d1d68b3_rebuild1
+; bx_python = _494c2d1d68b3_rebuild1
GeneTrack = _dev_48da9e998f0caf01c5be731e926f4b0481f658f0
SQLAlchemy = _dev_r6498
pysam = _kanwei_b10f6e722e9a
https://bitbucket.org/galaxy/galaxy-central/changeset/7e45efd017bd/
changeset: 7e45efd017bd
user: james_taylor
date: 2011-11-07 16:32:53
summary: Automated merge with ssh://bitbucket.org/james_taylor/galaxy-central
affected #: 1 file
diff -r 4e9db728d9ea2553f387b53e6d25230b69a2789a -r 7e45efd017bdb4d6ea0af86e80b3ae9d2a029c67 eggs.ini
--- a/eggs.ini
+++ b/eggs.ini
@@ -12,7 +12,7 @@
no_auto = pbs_python DRMAA_python
[eggs:platform]
-bx_python = 0.7.0
+bx_python = 0.7.1
Cheetah = 2.2.2
ctypes = 1.0.2
DRMAA_python = 0.2
@@ -67,7 +67,7 @@
psycopg2 = _8.4.2_static
pysqlite = _3.6.17_static
MySQL_python = _5.1.41_static
-bx_python = _494c2d1d68b3_rebuild1
+; bx_python = _494c2d1d68b3_rebuild1
GeneTrack = _dev_48da9e998f0caf01c5be731e926f4b0481f658f0
SQLAlchemy = _dev_r6498
pysam = _kanwei_b10f6e722e9a
https://bitbucket.org/galaxy/galaxy-central/changeset/54f19d6736c0/
changeset: 54f19d6736c0
user: james_taylor
date: 2011-11-07 21:31:32
summary: Eggs: add revision string for new bx-python
affected #: 1 file
diff -r 7e45efd017bdb4d6ea0af86e80b3ae9d2a029c67 -r 54f19d6736c0d5f55a841b76f4a72e32e490df38 eggs.ini
--- a/eggs.ini
+++ b/eggs.ini
@@ -67,7 +67,7 @@
psycopg2 = _8.4.2_static
pysqlite = _3.6.17_static
MySQL_python = _5.1.41_static
-; bx_python = _494c2d1d68b3_rebuild1
+bx_python = _7b95ff194725
GeneTrack = _dev_48da9e998f0caf01c5be731e926f4b0481f658f0
SQLAlchemy = _dev_r6498
pysam = _kanwei_b10f6e722e9a
https://bitbucket.org/galaxy/galaxy-central/changeset/de594b3589e5/
changeset: de594b3589e5
user: james_taylor
date: 2011-11-07 21:31:41
summary: Automated merge with https://bitbucket.org/galaxy/galaxy-central
affected #: 14 files
diff -r ba739e96c1a14d649c37655cecfc5b835ab343d2 -r de594b3589e575e3347c75a2d3fad33b01db35dd eggs.ini
--- a/eggs.ini
+++ b/eggs.ini
@@ -12,7 +12,7 @@
no_auto = pbs_python DRMAA_python
[eggs:platform]
-bx_python = 0.7.0
+bx_python = 0.7.1
Cheetah = 2.2.2
ctypes = 1.0.2
DRMAA_python = 0.2
@@ -67,7 +67,7 @@
psycopg2 = _8.4.2_static
pysqlite = _3.6.17_static
MySQL_python = _5.1.41_static
-bx_python = _494c2d1d68b3_rebuild1
+bx_python = _7b95ff194725
GeneTrack = _dev_48da9e998f0caf01c5be731e926f4b0481f658f0
SQLAlchemy = _dev_r6498
pysam = _kanwei_b10f6e722e9a
diff -r ba739e96c1a14d649c37655cecfc5b835ab343d2 -r de594b3589e575e3347c75a2d3fad33b01db35dd lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
--- a/lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
+++ b/lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
@@ -50,4 +50,4 @@
st.write(out_fname)
if __name__ == "__main__":
- main()
\ No newline at end of file
+ main()
diff -r ba739e96c1a14d649c37655cecfc5b835ab343d2 -r de594b3589e575e3347c75a2d3fad33b01db35dd lib/galaxy/visualization/tracks/data_providers.py
--- a/lib/galaxy/visualization/tracks/data_providers.py
+++ b/lib/galaxy/visualization/tracks/data_providers.py
@@ -2,14 +2,15 @@
Data providers for tracks visualizations.
"""
-import sys
-from math import ceil, log
+import sys, time
+from math import ceil, log, sqrt
import pkg_resources
pkg_resources.require( "bx-python" )
if sys.version_info[:2] == (2, 4):
pkg_resources.require( "ctypes" )
pkg_resources.require( "pysam" )
pkg_resources.require( "numpy" )
+import numpy
from galaxy.datatypes.util.gff_util import *
from galaxy.util.json import from_json_string
from bx.interval_index_file import Indexes
@@ -740,40 +741,73 @@
# Bigwig has the possibility of it being a standalone bigwig file, in which case we use
# original_dataset, or coming from wig->bigwig conversion in which we use converted_dataset
f, bbi = self._get_dataset()
-
+
+ # If the stats kwarg was provide, we compute overall summary data for
+ # the entire chromosome, but no reduced data -- currently only
+ # providing values used by trackster to determine the default range
if 'stats' in kwargs:
- all_dat = bbi.query(chrom, 0, 2147483647, 1)
+ # FIXME: use actual chromosome size
+ summary = bbi.summarize( chrom, 0, 214783647, 1 )
f.close()
- if all_dat is None:
+ if summary is None:
return None
-
- all_dat = all_dat[0] # only 1 summary
- return { 'data' : { 'max': float( all_dat['max'] ), \
- 'min': float( all_dat['min'] ), \
- 'total_frequency': float( all_dat['coverage'] ) } \
- }
-
+ else:
+ # Does the summary contain any defined values?
+ valid_count = summary.valid_count[0]
+ if summary.valid_count < 1:
+ return None
+
+ # Compute $\mu \pm 2\sigma$ to provide an estimate for upper and lower
+ # bounds that contain ~95% of the data.
+ mean = summary.sum_data[0] / valid_count
+ var = summary.sum_squares[0] - mean
+ if valid_count > 1:
+ var /= valid_count - 1
+ sd = numpy.sqrt( var )
+
+ return dict( data=dict( min=summary.min_val[0], max=summary.max_val[0], mean=mean, sd=sd ) )
+
start = int(start)
end = int(end)
+
+ # The following seems not to work very well, for example it will only return one
+ # data point if the tile is 1280px wide. Not sure what the intent is.
+
# The first zoom level for BBI files is 640. If too much is requested, it will look at each block instead
# of summaries. The calculation done is: zoom <> (end-start)/num_points/2.
# Thus, the optimal number of points is (end-start)/num_points/2 = 640
# num_points = (end-start) / 1280
- num_points = (end-start) / 1280
- if num_points < 1:
- num_points = end - start
- else:
- num_points = min(num_points, 500)
+ #num_points = (end-start) / 1280
+ #if num_points < 1:
+ # num_points = end - start
+ #else:
+ # num_points = min(num_points, 500)
- data = bbi.query(chrom, start, end, num_points)
+ # For now, we'll do 1000 data points by default However, the summaries
+ # don't seem to work when a summary pixel corresponds to less than one
+ # datapoint, so we prevent that.
+ # FIXME: need to switch over to using the full data at high levels of
+ # detail.
+ num_points = min( 1000, end - start )
+
+ summary = bbi.summarize( chrom, start, end, num_points )
f.close()
+
+ result = []
+
+ if summary:
+ mean = summary.sum_data / summary.valid_count
+
+ ## Standard deviation by bin, not yet used
+ ## var = summary.sum_squares - mean
+ ## var /= minimum( valid_count - 1, 1 )
+ ## sd = sqrt( var )
- pos = start
- step_size = (end - start) / num_points
- result = []
- if data:
- for dat_dict in data:
- result.append( (pos, float_nan(dat_dict['mean']) ) )
+ pos = start
+ step_size = (end - start) / num_points
+
+ for i in range( num_points ):
+ result.append( (pos, float_nan( mean[i] ) ) )
pos += step_size
return { 'data': result }
diff -r ba739e96c1a14d649c37655cecfc5b835ab343d2 -r de594b3589e575e3347c75a2d3fad33b01db35dd lib/galaxy/web/controllers/tracks.py
--- a/lib/galaxy/web/controllers/tracks.py
+++ b/lib/galaxy/web/controllers/tracks.py
@@ -528,6 +528,7 @@
if not standalone_provider.has_data( chrom ):
return messages.NO_DATA
valid_chroms = standalone_provider.valid_chroms()
+
# Have data if we get here
return { "status": messages.DATA, "valid_chroms": valid_chroms }
@@ -1041,4 +1042,4 @@
return_message = message
elif return_message == None and message == messages.PENDING:
return_message = message
- return return_message
\ No newline at end of file
+ return return_message
diff -r ba739e96c1a14d649c37655cecfc5b835ab343d2 -r de594b3589e575e3347c75a2d3fad33b01db35dd static/june_2007_style/base.css.tmpl
--- a/static/june_2007_style/base.css.tmpl
+++ b/static/june_2007_style/base.css.tmpl
@@ -231,6 +231,10 @@
padding: 3px 0 0 1em;
}
+.form-row .help {
+ color: #666;
+}
+
select, input, textarea {
font: inherit;
}
diff -r ba739e96c1a14d649c37655cecfc5b835ab343d2 -r de594b3589e575e3347c75a2d3fad33b01db35dd static/june_2007_style/blue/base.css
--- a/static/june_2007_style/blue/base.css
+++ b/static/june_2007_style/blue/base.css
@@ -43,6 +43,7 @@
div.form-row-input{float:left;}
div.form-row-input label{font-weight:normal;display:inline;}
div.form-row-error-message{width:300px;float:left;color:red;font-weight:bold;padding:3px 0 0 1em;}
+.form-row .help{color:#666;}
select,input,textarea{font:inherit;}
select,textarea,input[type="text"],input[type="file"],input[type="password"]{-webkit-box-sizing:border-box;max-width:300px;}
.errormessagelarge,.warningmessagelarge,.donemessagelarge,.infomessagelarge{padding:10px;padding-left:52px;min-height:32px;border:1px solid #AA6666;background-color:#FFCCCC;background-image:url(error_message_icon.png);background-repeat:no-repeat;background-position:10px 10px;}
diff -r ba739e96c1a14d649c37655cecfc5b835ab343d2 -r de594b3589e575e3347c75a2d3fad33b01db35dd static/june_2007_style/blue/panel_layout.css
--- a/static/june_2007_style/blue/panel_layout.css
+++ b/static/june_2007_style/blue/panel_layout.css
@@ -23,9 +23,11 @@
.panel-header-button:hover{color:black;background-color:#ccc;}
.panel-header-button:active{color:white;background-color:#aaaaaa;}
#overlay{position:fixed;top:0;left:0;width:100%;height:100%;z-index:20000;}
+#overlay.modal #overlay-background{background:rgba(0,0,0,0.5);}
.dialog-box-container{position:relative;margin-top:80px;margin-right:auto;margin-left:auto;}
.dialog-box-wrapper{position:relative;padding:1em;background-color:rgba(0,0,0,0.5);-moz-border-radius:1em;-webkit-border-radius:1em;}
.dialog-box{border:solid #999 1px;background:white;z-index:80000;}
+#overlay.modal .dialog-box .body{min-width:600px;}
.dialog-box .body{padding:5px;overflow:auto;max-height:500px;min-width:300px;}
.dialog-box .buttons{padding:5px;}
.panel-error-message,.panel-warning-message,.panel-done-message,.panel-info-message{height:24px;line-height:24px;color:#303030;padding:0px;padding-left:26px;background-color:#FFCCCC;background-image:url(error_small.png);background-repeat:no-repeat;background-position:6px 50%;}
diff -r ba739e96c1a14d649c37655cecfc5b835ab343d2 -r de594b3589e575e3347c75a2d3fad33b01db35dd static/june_2007_style/blue/trackster.css
--- a/static/june_2007_style/blue/trackster.css
+++ b/static/june_2007_style/blue/trackster.css
@@ -3,30 +3,9 @@
.content{font:10px verdana;}
.nav-controls{text-align:center;padding:1px 0;}
.nav-controls input{margin:0 5px;}
-.menu-button{padding: 0px 4px 0px 4px;}
#zoom-in,#zoom-out{display:inline-block;height:16px;width:16px;margin-bottom:-3px;cursor:pointer;}
#zoom-out{background:transparent url(../images/fugue/magnifier-zoom-out.png) center center no-repeat;}
#zoom-in{margin-left:10px;background:transparent url(../images/fugue/magnifier-zoom.png) center center no-repeat;}
-.overview-icon{background:transparent url(../images/fugue/application-dock-270-bw.png) no-repeat;}
-.overview-icon:hover{background:transparent url(../images/fugue/application-dock-270.png) no-repeat;}
-.settings-icon{background:transparent url(../images/fugue/gear-bw.png) no-repeat;}
-.settings-icon:hover{background:transparent url(../images/fugue/gear.png) no-repeat;}
-.tools-icon{background:transparent url(../images/fugue/toolbox-bw.png) no-repeat;}
-.tools-icon:hover{background:transparent url(../images/fugue/toolbox.png) no-repeat;}
-.filters-icon{background:transparent url(../images/fugue/ui-slider-050-bw.png) no-repeat;}
-.filters-icon:hover{background:transparent url(../images/fugue/ui-slider-050.png) no-repeat;}
-.remove-icon,.overview-close{background:transparent url(../images/fugue/cross-small-bw.png) no-repeat;}
-.remove-icon:hover,.overview-close:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
-#close-icon{background:transparent url(../images/fugue/cross-circle-bw.png) no-repeat;margin-right:0px;}
-#close-icon:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
-#add-tracks-icon{background:transparent url(../images/fugue/plus-button-bw.png) no-repeat;}
-#add-tracks-icon:hover{background:transparent url(../images/fugue/plus-button.png) no-repeat;}
-#add-group-icon{background:transparent url(../images/fugue/block--plus-bw.png) no-repeat;}
-#add-group-icon:hover{background:transparent url(../images/fugue/block--plus.png) no-repeat;}
-#bookmarks-icon{background:transparent url(../images/fugue/bookmarks-bw.png) no-repeat;}
-#bookmarks-icon:hover{background:transparent url(../images/fugue/bookmarks.png) no-repeat;}
-#save-icon{background:transparent url(../images/fugue/disk--arrow-bw.png) no-repeat;}
-#save-icon:hover{background:transparent url(../images/fugue/disk--arrow.png) no-repeat;}
.nav-input{font-size:12px;width:30em;z-index:1000;}
.location{display:inline-block;width:15em;margin:0 10px;}
.draghandle{margin-top:2px;cursor:move;float:left;background:transparent url(../images/visualization/draggable_horizontal.png) center center no-repeat;width:10px;height:12px;}
@@ -65,16 +44,39 @@
input{font:10px verdana;}
.dynamic-tool,.filters{margin-left:0.25em;padding-bottom:0.5em;}
.dynamic-tool{width:410px;}
-.filters>.sliders,.display-controls{float:left;margin:1em;}
+.filters > .sliders,.display-controls{float:left;margin:1em;}
.sliders{width:410px;}
-.display-controls{border-left:solid 2px #DDDDDD;padding-left:1em}
-.filter-row{margin-top:0.4em;}
+.display-controls{border-left:solid 2px #DDDDDD;padding-left:1em
+}
+.filter-row {
+ margin-top:0.4em;}
.slider-row{margin-left:1em;}
.elt-label{float:left;font-weight:bold;margin-right:1em;}
.slider{float:right;width:200px;position:relative;}
.tool-name{font-size:110%;font-weight:bold;}
.param-row{margin-top:0.2em;margin-left:1em;}
.param-label{float:left;font-weight:bold;padding-top:0.2em;}
+.menu-button{padding:0px 4px 0px 4px;}
+.settings-icon{background:transparent url(../images/fugue/gear-bw.png) no-repeat;}
+.settings-icon:hover{background:transparent url(../images/fugue/gear.png) no-repeat;}
+.overview-icon{background:transparent url(../images/fugue/application-dock-270-bw.png) no-repeat;}
+.overview-icon:hover{background:transparent url(../images/fugue/application-dock-270.png) no-repeat;}
+.tools-icon{background:transparent url(../images/fugue/toolbox-bw.png) no-repeat;}
+.tools-icon:hover{background:transparent url(../images/fugue/toolbox.png) no-repeat;}
+.filters-icon{background:transparent url(../images/fugue/ui-slider-050-bw.png) no-repeat;}
+.filters-icon:hover{background:transparent url(../images/fugue/ui-slider-050.png) no-repeat;}
+.remove-icon,.overview-close{background:transparent url(../images/fugue/cross-small-bw.png) no-repeat;}
+.remove-icon:hover,.overview-close:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
+#close-icon{background:transparent url(../images/fugue/cross-circle-bw.png) no-repeat;margin-right:0px;}
+#close-icon:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
+#add-tracks-icon{background:transparent url(../images/fugue/plus-button-bw.png) no-repeat;}
+#add-tracks-icon:hover{background:transparent url(../images/fugue/plus-button.png) no-repeat;}
+#add-group-icon{background:transparent url(../images/fugue/block--plus-bw.png) no-repeat;}
+#add-group-icon:hover{background:transparent url(../images/fugue/block--plus.png) no-repeat;}
+#bookmarks-icon{background:transparent url(../images/fugue/bookmarks-bw.png) no-repeat;}
+#bookmarks-icon:hover{background:transparent url(../images/fugue/bookmarks.png) no-repeat;}
+#save-icon{background:transparent url(../images/fugue/disk--arrow-bw.png) no-repeat;}
+#save-icon:hover{background:transparent url(../images/fugue/disk--arrow.png) no-repeat;}
.child-track-icon{background:url('../images/fugue/arrow-000-small-bw.png') no-repeat;width:30px;cursor:move;}
.track-resize{background:white url('../images/visualization/draggable_vertical.png') no-repeat top center;position:absolute;right:3px;bottom:-4px;width:14px;height:7px;border:solid #999 1px;z-index:100;}
.bookmark{background:white;border:solid #999 1px;border-right:none;margin:0.5em;margin-right:0;padding:0.5em;}
@@ -85,4 +87,5 @@
.icon.more-across{background:url('../images/fugue/arrow-transition-bw.png') no-repeat 0px 0px;}
.intro{padding:1em;}
.intro > .action-button{background-color:#CCC;padding:1em;}
-.feature-popup{background-color:#DDD;position:absolute;z-index:1000}
+.feature-popup{position:absolute;z-index:1000;padding:5px;font-size:10px;filter:alpha(opacity=80);background-repeat:no-repeat;background-image:url(../images/tipsy.gif);background-position:top center;}
+.feature-popup-inner{padding:5px 8px 4px 8px;background-color:black;color:white;}
diff -r ba739e96c1a14d649c37655cecfc5b835ab343d2 -r de594b3589e575e3347c75a2d3fad33b01db35dd static/june_2007_style/panel_layout.css.tmpl
--- a/static/june_2007_style/panel_layout.css.tmpl
+++ b/static/june_2007_style/panel_layout.css.tmpl
@@ -161,6 +161,10 @@
z-index: 20000;
}
+#overlay.modal #overlay-background {
+ background: rgba(0,0,0,0.5);
+}
+
.dialog-box-container {
position: relative;
margin-top: 80px;
@@ -182,6 +186,10 @@
z-index: 80000;
}
+#overlay.modal .dialog-box .body {
+ min-width: 600px;
+}
+
.dialog-box .body {
padding: 5px;
overflow: auto;
diff -r ba739e96c1a14d649c37655cecfc5b835ab343d2 -r de594b3589e575e3347c75a2d3fad33b01db35dd static/june_2007_style/trackster.css.tmpl
--- a/static/june_2007_style/trackster.css.tmpl
+++ b/static/june_2007_style/trackster.css.tmpl
@@ -405,8 +405,19 @@
background-color: #CCC;
padding: 1em;
}
-.feature-popup{
- background-color: #DDD;
+
+.feature-popup {
position: absolute;
- z-index: 1000
+ z-index: 1000;
+ padding: 5px;
+ font-size: 10px;
+ filter: alpha(opacity=80);
+ background-repeat: no-repeat;
+ background-image: url(../images/tipsy.gif);
+ background-position: top center;
}
+.feature-popup-inner {
+ padding: 5px 8px 4px 8px;
+ background-color: black;
+ color: white;
+}
diff -r ba739e96c1a14d649c37655cecfc5b835ab343d2 -r de594b3589e575e3347c75a2d3fad33b01db35dd static/scripts/galaxy.panels.js
--- a/static/scripts/galaxy.panels.js
+++ b/static/scripts/galaxy.panels.js
@@ -163,13 +163,23 @@
// Modal dialog boxes
function hide_modal() {
- $(".dialog-box-container" ).fadeOut( function() {
+ $(".dialog-box-container" ).hide( 0, function() {
$("#overlay").hide();
+ $("#overlay").removeClass( "modal" );
$( ".dialog-box" ).find( ".body" ).children().remove();
} );
};
-function show_modal( title, body, buttons, extra_buttons, init_fn ) {
+function show_modal() {
+ $("#overlay").addClass( "modal" );
+ _show_modal.apply( this, arguments );
+}
+
+function show_message() {
+ _show_modal.apply( this, arguments );
+}
+
+function _show_modal( title, body, buttons, extra_buttons, init_fn ) {
if ( title ) {
$( ".dialog-box" ).find( ".title" ).html( title );
$( ".dialog-box" ).find( ".unified-panel-header" ).show();
@@ -205,7 +215,7 @@
$( ".dialog-box" ).find( ".body" ).html( body );
if ( ! $(".dialog-box-container").is( ":visible" ) ) {
$("#overlay").show();
- $(".dialog-box-container").fadeIn();
+ $(".dialog-box-container").show();
}
// Fix min-width so that modal cannot shrink considerably if
// new content is loaded.
diff -r ba739e96c1a14d649c37655cecfc5b835ab343d2 -r de594b3589e575e3347c75a2d3fad33b01db35dd static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -701,7 +701,7 @@
remove: function() {
this.container.remove_drawable(this);
- this.container_div.fadeOut('slow', function() {
+ this.container_div.hide(0, function() {
$(this).remove();
// HACK: is there a better way to update the view?
view.update_intro_div();
@@ -1027,6 +1027,7 @@
// Only act on x axis scrolling if we see if, y will be i
// handled by the browser when the event bubbles up
if ( dx ) {
+ dx *= 50;
var delta_chrom = Math.round( - dx / view.viewport_container.width() * (view.high - view.low) );
view.move_delta( delta_chrom );
}
@@ -1255,7 +1256,7 @@
DrawableCollection.prototype.remove_drawable.call(this, drawable);
if (hide) {
var view = this;
- drawable.container_div.fadeOut('slow', function() {
+ drawable.container_div.hide(0, function() {
$(this).remove();
view.update_intro_div();
});
@@ -2114,8 +2115,14 @@
build_form: function() {
var track_config = this;
var container = $("<div />");
- $.each( this.params, function( index, param ) {
- if ( ! param.hidden ) {
+ var param;
+ // Function to process parameters recursively
+ function handle_params( params, container ) {
+ for ( var index = 0; index < params.length; index++ ) {
+ param = params[index];
+ // Hidden params have no representation in the form
+ if ( param.hidden ) { continue; }
+ // Build row for param
var id = 'param_' + index;
var value = track_config.values[ param.key ];
var row = $("<div class='form-row' />").appendTo( container );
@@ -2127,18 +2134,19 @@
} else if ( param.type === 'color' ) {
var input = $('<input />').attr("id", id ).attr("name", id ).val( value );
// Color picker in tool tip style float
- var tip = $( "<div class='tipsy tipsy-north' style='position: absolute;' />" ).hide();
+ var tip = $( "<div class='tipsy tipsy-west' style='position: absolute;' />" ).hide();
// Inner div for padding purposes
var tip_inner = $("<div style='background-color: black; padding: 10px;'></div>").appendTo(tip);
var farb_container = $("<div/>")
.appendTo(tip_inner)
.farbtastic( { width: 100, height: 100, callback: input, color: value });
-
// Outer div container input and tip for hover to work
$("<div />").append( input ).append( tip ).appendTo( row ).bind( "click", function ( e ) {
tip.css( {
- left: $(this).position().left + ( $(input).width() / 2 ) - 60,
- top: $(this).position().top + $(this.height)
+ // left: $(this).position().left + ( $(input).width() / 2 ) - 60,
+ // top: $(this).position().top + $(this.height)
+ left: $(this).position().left + $(input).width() + 5,
+ top: $(this).position().top - ( $(tip).height() / 2 ) + ( $(input).height() / 2 )
} ).show();
$(document).bind( "click.color-picker", function() {
tip.hide();
@@ -2150,8 +2158,15 @@
else {
row.append( $('<input />').attr("id", id ).attr("name", id ).val( value ) );
}
+ // Help text
+ if ( param.help ) {
+ row.append( $("<div class='help'/>").text( param.help ) );
+ }
}
- });
+ }
+ // Handle top level parameters in order
+ handle_params( this.params, container );
+ // Return element containing constructed form
return container;
},
update_from_form: function( container ) {
@@ -2229,7 +2244,16 @@
// Only show popups in Pack mode.
if (tile.mode !== "Pack") { return; }
- $(this.canvas).mousemove(function (e) {
+ $(this.canvas).hover( function() {
+ this.hovered = true;
+ $(this).mousemove();
+ }, function() {
+ this.hovered = false;
+ // Clear popup if it is still hanging around (this is probably not needed)
+ $(this).siblings(".feature-popup").remove();
+ } ).mousemove(function (e) {
+ // Use the hover plugin to get a delay before showing popup
+ if ( !this.hovered ) { return; }
// Get feature data for position.
var
this_offset = $(this).offset(),
@@ -2270,8 +2294,8 @@
// Build popup.
var popup = $("<div/>").attr("id", feature_uid).addClass("feature-popup"),
- key, value,
- table = $("<table/>").appendTo(popup), row;
+ table = $("<table/>"),
+ key, value, row;
for (key in feature_dict) {
value = feature_dict[key];
row = $("<tr/>").appendTo(table);
@@ -2279,6 +2303,7 @@
$("<td/>").attr("align", "left").appendTo(row)
.text(typeof(value) == 'number' ? round(value, 2) : value);
}
+ popup.append( $("<div class='feature-popup-inner'>").append( table ) );
popups[feature_uid] = popup;
}
@@ -2289,7 +2314,7 @@
// parseInt strips "px" from left, top measurements. +7 so that mouse pointer does not
// overlap popup.
var
- popupX = offsetX + parseInt( tile.canvas.css("left") ) + 7,
+ popupX = offsetX + parseInt( tile.canvas.css("left") ) - popup.width() / 2,
popupY = offsetY + parseInt( tile.canvas.css("top") ) + 7;
popup.css("left", popupX + "px").css("top", popupY + "px")
}
@@ -2331,6 +2356,12 @@
this.data_url_extra_params = {}
this.data_query_wait = (data_query_wait ? data_query_wait : DEFAULT_DATA_QUERY_WAIT);
this.dataset_check_url = converted_datasets_state_url;
+
+ // FIXME: this should be a saved setting
+ this.content_visible = true;
+
+ if (!Track.id_counter) { Track.id_counter = 0; }
+ this.id = Track.id_counter++;
//
// Create HTML element structure for track.
@@ -2346,6 +2377,9 @@
this.icons_div = $("<div/>").css("float", "left").appendTo(this.header_div).hide();
// Track icons.
+ this.toggle_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Hide/show track content")
+ .addClass("icon-button toggle").tipsy( {gravity: 's'} )
+ .appendTo(this.icons_div);
this.settings_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Edit settings")
.addClass("icon-button settings-icon").tipsy( {gravity: 's'} )
.appendTo(this.icons_div);
@@ -2365,6 +2399,21 @@
// Suppress double clicks in header so that they do not impact viz.
this.header_div.dblclick( function(e) { e.stopPropagation(); } );
+
+ // Toggle icon hides or shows the track content
+ this.toggle_icon.click( function() {
+ if ( track.content_visible ) {
+ track.toggle_icon.addClass("toggle-expand").removeClass("toggle");
+ track.hide_contents();
+ track.mode_div.hide();
+ track.content_visible = false;
+ } else {
+ track.toggle_icon.addClass("toggle").removeClass("toggle-expand");
+ track.content_visible = true;
+ track.mode_div.show();
+ track.show_contents();
+ }
+ });
// Clicking on settings icon opens track config.
this.settings_icon.click( function() {
@@ -2552,6 +2601,26 @@
this.update_icons();
},
/**
+ * Hide any elements that are part of the tracks contents area. Should
+ * remove as approprite, the track will be redrawn by show_contents.
+ */
+ hide_contents : function () {
+ // Clear contents by removing any elements that are contained in
+ // the tracks content_div
+ this.content_div.children().remove();
+ // Hide the content div
+ this.content_div.hide();
+ // And any y axis labels (common to several track types)
+ this.container_div.find(".yaxislabel, .track-resize").hide()
+ },
+ show_contents : function() {
+ // Show the contents div and labels (if present)
+ this.content_div.show();
+ this.container_div.find(".yaxislabel, .track-resize").show()
+ // Request a redraw of the content
+ this.request_draw();
+ },
+ /**
* Additional initialization required before drawing track for the first time.
*/
predraw_init: function() {}
@@ -2682,6 +2751,11 @@
*/
_draw: function(force, clear_after) {
if (!this.enabled) { return; }
+
+ // TODO: There should probably be a general way to disable content drawing
+ // for all drawables. However the button to toggle this is currently
+ // only present for Track instances.
+ if (!this.content_visible) { return; }
// HACK: ReferenceTrack can draw without dataset ID, but other tracks cannot.
if ( !(this instanceof ReferenceTrack) && (!this.dataset_id) ) { return; }
@@ -2694,7 +2768,7 @@
w_scale = width / range,
resolution = this.view.resolution,
parent_element = $("<div style='position: relative;'></div>");
-
+
// For overview, adjust high, low, resolution, and w_scale.
if (this.is_overview) {
low = this.view.max_low;
@@ -3028,7 +3102,8 @@
this.min_height_px = 16;
this.max_height_px = 400;
- this.height_px = 80;
+ // Default height for new tracks, should be a defined constant?
+ this.height_px = 32;
this.hda_ldda = hda_ldda;
this.dataset_id = dataset_id;
this.original_dataset_id = dataset_id;
@@ -3076,8 +3151,10 @@
var drag_control = $( "<div class='track-resize'>" )
// Control shows on hover over track, stays while dragging
$(track.container_div).hover( function() {
- in_handle = true;
- drag_control.show();
+ if ( track.content_visible ) {
+ in_handle = true;
+ drag_control.show();
+ }
}, function() {
in_handle = false;
if ( ! in_drag ) { drag_control.hide(); }
@@ -3108,9 +3185,20 @@
track.container_div.addClass( "line-track" );
var data = result.data;
if ( isNaN(parseFloat(track.prefs.min_value)) || isNaN(parseFloat(track.prefs.max_value)) ) {
- track.prefs.min_value = data.min;
- track.prefs.max_value = data.max;
+ // Compute default minimum and maximum values
+ var min_value = data.min
+ var max_value = data.max
+ // If mean and sd are present, use them to compute a ~95% window
+ // but only if it would shrink the range on one side
+ min_value = Math.floor( Math.min( 0, Math.max( min_value, data.mean - 2 * data.sd ) ) )
+ max_value = Math.ceil( Math.max( 0, Math.min( max_value, data.mean + 2 * data.sd ) ) )
+ // Update the prefs
+ track.prefs.min_value = min_value;
+ track.prefs.max_value = max_value;
// Update the config
+ // FIXME: we should probably only save this when the user explicately sets it
+ // since we lose the ability to compute it on the fly (when changing
+ // chromosomes for example).
$('#track_' + track.dataset_id + '_minval').val(track.prefs.min_value);
$('#track_' + track.dataset_id + '_maxval').val(track.prefs.max_value);
}
@@ -3179,7 +3267,8 @@
{ key: 'name', label: 'Name', type: 'text', default_value: name },
{ key: 'block_color', label: 'Block color', type: 'color', default_value: get_random_color() },
{ key: 'label_color', label: 'Label color', type: 'color', default_value: 'black' },
- { key: 'show_counts', label: 'Show summary counts', type: 'bool', default_value: true },
+ { key: 'show_counts', label: 'Show summary counts', type: 'bool', default_value: true,
+ help: 'Show the number of items in each bin when drawing summary histogram' },
{ key: 'mode', type: 'string', default_value: this.mode, hidden: true },
],
saved_values: prefs,
@@ -3527,7 +3616,7 @@
var filter_height_scaler = (this.filters_manager.height_filter ? new FilterScaler(this.filters_manager.height_filter) : null);
// HACK: ref_seq will only be defined for ReadTracks, and only the ReadPainter accepts that argument
var painter = new (this.painter)(filtered, tile_low, tile_high, this.prefs, mode, filter_alpha_scaler, filter_height_scaler, ref_seq);
- var required_height = Math.max(MIN_TRACK_HEIGHT, painter.get_required_height(slots_required));
+ var required_height = Math.max(MIN_TRACK_HEIGHT, painter.get_required_height(slots_required,width));
var canvas = this.view.canvas_manager.new_canvas();
var feature_mapper = null;
@@ -4057,6 +4146,7 @@
this.feature_positions = {};
this.slot_height = slot_height;
this.translation = 0;
+ this.y_translation = 0;
};
/**
@@ -4078,7 +4168,7 @@
*/
FeaturePositionMapper.prototype.get_feature_data = function(x, y) {
// Find slot using Y.
- var slot = Math.floor( y/this.slot_height ),
+ var slot = Math.floor( (y-this.y_translation)/this.slot_height ),
feature_dict;
// May not be over a slot due to padding, margin, etc.
@@ -4108,15 +4198,23 @@
FeaturePainter.prototype.default_prefs = { block_color: "#FFF", connector_color: "#FFF" };
extend(FeaturePainter.prototype, {
- get_required_height: function(rows_required) {
+ get_required_height: function(rows_required, width) {
// y_scale is the height per row
var required_height = y_scale = this.get_row_height(), mode = this.mode;
// If using a packing mode, need to multiply by the number of slots used
if (mode === "no_detail" || mode === "Squish" || mode === "Pack") {
required_height = rows_required * y_scale;
}
+ return required_height + this.get_top_padding(width) + this.get_bottom_padding(width);
+ },
+ /** Extra padding before first row of features */
+ get_top_padding: function(width) {
+ return 0;
+ },
+ /** Extra padding after last row of features */
+ get_bottom_padding: function(width) {
// Pad bottom by half a row, at least 5 px
- return required_height + Math.max( Math.round( y_scale / 2 ), 5 );
+ return Math.max( Math.round( this.get_row_height() / 2 ), 5 )
},
/**
* Draw data on ctx using slots and within the rectangle defined by width and height. Returns
@@ -4153,6 +4251,7 @@
}
ctx.restore();
+ feature_mapper.y_translation = this.get_top_padding(width);
return feature_mapper;
},
/**
@@ -4179,6 +4278,10 @@
var LinkedFeaturePainter = function(data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler) {
FeaturePainter.call(this, data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler);
+ // Whether to draw a single connector in the background that spans the entire feature (the intron fishbone)
+ this.draw_background_connector = true;
+ // Whether to call draw_connector for every pair of blocks
+ this.draw_individual_connectors = false;
};
extend(LinkedFeaturePainter.prototype, FeaturePainter.prototype, {
@@ -4216,7 +4319,7 @@
f_end = Math.ceil( Math.min(width, Math.max(0, (feature_end - tile_low) * w_scale)) ),
draw_start = f_start,
draw_end = f_end,
- y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale,
+ y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale + this.get_top_padding(width),
thickness, y_start, thick_start = null, thick_end = null,
// TODO: is there any reason why block, label color cannot be set at the Painter level?
block_color = this.prefs.block_color,
@@ -4279,38 +4382,51 @@
// needed. This ensures that whole feature, regardless of whether it starts with
// a block, is visible.
//
-
- // Draw whole feature as connector/intron.
+
+ // Compute y axis center position and height
var cur_y_center, cur_height;
if (mode === "Squish" || mode === "Dense") {
- ctx.fillStyle = CONNECTOR_COLOR;
cur_y_center = y_center + Math.floor(SQUISH_FEATURE_HEIGHT/2) + 1;
cur_height = 1;
}
else { // mode === "Pack"
if (feature_strand) {
- var cur_y_center = y_center;
- var cur_height = thick_height;
- if (feature_strand === "+") {
- ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand' );
- } else if (feature_strand === "-") {
- ctx.fillStyle = ctx.canvas.manager.get_pattern( 'left_strand' );
- }
+ cur_y_center = y_center;
+ cur_height = thick_height;
}
else {
- ctx.fillStyle = CONNECTOR_COLOR;
cur_y_center += (SQUISH_FEATURE_HEIGHT/2) + 1;
cur_height = 1;
}
}
- ctx.fillRect(f_start, cur_y_center, f_end - f_start, cur_height);
+
+ // Draw whole feature as connector/intron.
+ if ( this.draw_background_connector ) {
+ if (mode === "Squish" || mode === "Dense") {
+ ctx.fillStyle = CONNECTOR_COLOR;
+ }
+ else { // mode === "Pack"
+ if (feature_strand) {
+ if (feature_strand === "+") {
+ ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand' );
+ } else if (feature_strand === "-") {
+ ctx.fillStyle = ctx.canvas.manager.get_pattern( 'left_strand' );
+ }
+ }
+ else {
+ ctx.fillStyle = CONNECTOR_COLOR;
+ }
+ }
+ ctx.fillRect(f_start, cur_y_center, f_end - f_start, cur_height);
+ }
// Draw blocks.
var start_and_height;
for (var k = 0, k_len = feature_blocks.length; k < k_len; k++) {
var block = feature_blocks[k],
block_start = Math.floor( Math.max(0, (block[0] - tile_low) * w_scale) ),
- block_end = Math.ceil( Math.min(width, Math.max((block[1] - tile_low) * w_scale)) );
+ block_end = Math.ceil( Math.min(width, Math.max((block[1] - tile_low) * w_scale)) ),
+ last_block_start, last_block_end;
// Skip drawing if block not on tile.
if (block_start > block_end) { continue; }
@@ -4341,6 +4457,12 @@
ctx.fillRect(block_thick_start, y_center + 1, block_thick_end - block_thick_start, thick_height );
}
}
+ // Draw individual connectors if required
+ if ( this.draw_individual_connectors && last_block_start ) {
+ this.draw_connector( ctx, last_block_start, last_block_end, block_start, block_end, y_center );
+ }
+ last_block_start = block_start;
+ last_block_end = block_end;
}
// FIXME: Height scaling only works in Pack mode right now.
@@ -4673,11 +4795,54 @@
}
});
+var ArcLinkedFeaturePainter = function(data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler) {
+ LinkedFeaturePainter.call(this, data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler);
+ // Need to know the longest feature length for adding spacing
+ this.longest_feature_length = this.calculate_longest_feature_length();
+ this.draw_background_connector = false;
+ this.draw_individual_connectors = true;
+};
+
+extend(ArcLinkedFeaturePainter.prototype, FeaturePainter.prototype, LinkedFeaturePainter.prototype, {
+
+ calculate_longest_feature_length: function () {
+ var longest_feature_length = 0;
+ for (var i = 0, len = this.data.length; i < len; i++) {
+ var feature = this.data[i], feature_start = feature[1], feature_end = feature[2];
+ longest_feature_length = Math.max( longest_feature_length, feature_end - feature_start );
+ }
+ return longest_feature_length;
+ },
+
+ get_top_padding: function( width ) {
+ var view_range = this.view_end - this.view_start,
+ w_scale = width / view_range;
+ return Math.min( 128, Math.ceil( ( this.longest_feature_length / 2 ) * w_scale ) );
+ },
+
+ draw_connector: function( ctx, block1_start, block1_end, block2_start, block2_end, y_center ) {
+ // Arc drawing -- from closest endpoints
+ var x_center = ( block1_end + block2_start ) / 2,
+ radius = block2_start - x_center;
+ // For full half circles
+ var angle1 = Math.PI, angle2 = 0;
+ if ( radius > 0 ) {
+ ctx.beginPath();
+ ctx.arc( x_center, y_center, block2_start - x_center, Math.PI, 0 );
+ ctx.stroke();
+ }
+ }
+});
+
+
+
+
exports.Scaler = Scaler;
exports.SummaryTreePainter = SummaryTreePainter;
exports.LinePainter = LinePainter;
exports.LinkedFeaturePainter = LinkedFeaturePainter;
exports.ReadPainter = ReadPainter;
+exports.ArcLinkedFeaturePainter = ArcLinkedFeaturePainter;
// End painters_module encapsulation
};
@@ -4708,4 +4873,4 @@
for ( key in modules.trackster ) {
target[key] = modules.trackster[key];
}
-})(window);
\ No newline at end of file
+})(window);
diff -r ba739e96c1a14d649c37655cecfc5b835ab343d2 -r de594b3589e575e3347c75a2d3fad33b01db35dd templates/tracks/browser.mako
--- a/templates/tracks/browser.mako
+++ b/templates/tracks/browser.mako
@@ -42,7 +42,7 @@
<script type='text/javascript' src="${h.url_for('/static/scripts/excanvas.js')}"></script><![endif]-->
-${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.event.drag", "jquery.mousewheel", "jquery.autocomplete", "trackster", "trackster_ui", "jquery.ui.sortable.slider", "farbtastic", "jquery.tipsy" )}
+${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.event.drag", "jquery.event.hover","jquery.mousewheel", "jquery.autocomplete", "trackster", "trackster_ui", "jquery.ui.sortable.slider", "farbtastic", "jquery.tipsy" )}
<script type="text/javascript">
//
diff -r ba739e96c1a14d649c37655cecfc5b835ab343d2 -r de594b3589e575e3347c75a2d3fad33b01db35dd templates/workflow/editor.mako
--- a/templates/workflow/editor.mako
+++ b/templates/workflow/editor.mako
@@ -213,7 +213,7 @@
show_workflow_parameters();
},
beforeSubmit: function( data ) {
- show_modal( "Loading workflow", "progress" );
+ show_message( "Loading workflow", "progress" );
}
});
}
@@ -650,7 +650,7 @@
};
var save_current_workflow = function ( eventObj, success_callback ) {
- show_modal( "Saving workflow", "progress" );
+ show_message( "Saving workflow", "progress" );
workflow.check_changes_in_active_form();
if (!workflow.has_changes) {
hide_modal();
https://bitbucket.org/galaxy/galaxy-central/changeset/a9f7d94aedb5/
changeset: a9f7d94aedb5
user: james_taylor
date: 2011-11-07 18:34:23
summary: Trackster: allow selecting the arc connector style for feature tracks, add support for select config parameter type
affected #: 1 file
diff -r de594b3589e575e3347c75a2d3fad33b01db35dd -r a9f7d94aedb5ec5a7fe6e9f832b98c45a4c473d3 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -2127,10 +2127,21 @@
var value = track_config.values[ param.key ];
var row = $("<div class='form-row' />").appendTo( container );
row.append( $('<label />').attr("for", id ).text( param.label + ":" ) );
+ // Draw parameter as checkbox
if ( param.type === 'bool' ) {
row.append( $('<input type="checkbox" />').attr("id", id ).attr("name", id ).attr( 'checked', value ) );
+ // Draw parameter as textbox
} else if ( param.type === 'text' ) {
row.append( $('<input type="text"/>').attr("id", id ).val(value).click( function() { $(this).select() }));
+ // Draw paramter as select area
+ } else if ( param.type == 'select' ) {
+ var select = $('<select />').attr("id", id);
+ for ( var i = 0; i < param.options.length; i++ ) {
+ $("<option/>").text( param.options[i].label ).attr( "value", param.options[i].value ).appendTo( select );
+ }
+ select.val( value );
+ row.append( select );
+ // Draw parameter as color picker
} else if ( param.type === 'color' ) {
var input = $('<input />').attr("id", id ).attr("name", id ).val( value );
// Color picker in tool tip style float
@@ -3269,12 +3280,15 @@
{ key: 'label_color', label: 'Label color', type: 'color', default_value: 'black' },
{ key: 'show_counts', label: 'Show summary counts', type: 'bool', default_value: true,
help: 'Show the number of items in each bin when drawing summary histogram' },
+ { key: 'connector_style', label: 'Connector style', type: 'select', default_value: 'fishbones',
+ options: [ { label: 'Line with arrows', value: 'fishbone' }, { label: 'Arcs', value: 'arcs' } ] },
{ key: 'mode', type: 'string', default_value: this.mode, hidden: true },
],
saved_values: prefs,
onchange: function() {
track.set_name(track.prefs.name);
track.tile_cache.clear();
+ track.set_painter_from_config();
track.request_draw();
}
});
@@ -3297,6 +3311,14 @@
this.painter = painters.LinkedFeaturePainter;
};
extend(FeatureTrack.prototype, Drawable.prototype, TiledTrack.prototype, {
+ set_painter_from_config: function() {
+ console.log( this, this.config );
+ if ( this.config.values['connector_style'] == 'arcs' ) {
+ this.painter = painters.ArcLinkedFeaturePainter;
+ } else {
+ this.painter = painters.LinkedFeaturePainter;
+ }
+ },
/**
* Actions to be taken after draw has been completed. Draw is completed when all tiles have been
* drawn/fetched and shown.
https://bitbucket.org/galaxy/galaxy-central/changeset/0f5ab41da4bd/
changeset: 0f5ab41da4bd
user: james_taylor
date: 2011-11-07 21:36:46
summary: Trackster: fix loading of track connector style when initializing from saved
affected #: 1 file
diff -r a9f7d94aedb5ec5a7fe6e9f832b98c45a4c473d3 -r 0f5ab41da4bd2e605b9f0785a1e35a7a0d5983d6 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -3308,7 +3308,8 @@
this.data_manager = new DataManager(20, this);
this.left_offset = 200;
- this.painter = painters.LinkedFeaturePainter;
+ // this.painter = painters.LinkedFeaturePainter;
+ this.set_painter_from_config();
};
extend(FeatureTrack.prototype, Drawable.prototype, TiledTrack.prototype, {
set_painter_from_config: function() {
https://bitbucket.org/galaxy/galaxy-central/changeset/0c65c410ccc4/
changeset: 0c65c410ccc4
user: james_taylor
date: 2011-11-07 22:59:15
summary: Trackster: code for adding multiple bookmarks from a dataset. Currently the button is commented out until this can be made more usable
affected #: 7 files
diff -r 0f5ab41da4bd2e605b9f0785a1e35a7a0d5983d6 -r 0c65c410ccc4b15c72fcb50a5c3c3e982f0b446b lib/galaxy/visualization/tracks/data_providers.py
--- a/lib/galaxy/visualization/tracks/data_providers.py
+++ b/lib/galaxy/visualization/tracks/data_providers.py
@@ -363,14 +363,18 @@
for large datasets.
"""
- def get_iterator( self, chrom, start, end ):
+ def get_iterator( self, chrom=None, start=None, end=None ):
def line_filter_iter():
for line in open( self.original_dataset.file_name ):
+ if line.startswith( "track" ) or line.startswith( "browser" ):
+ continue
feature = line.split()
feature_chrom = feature[0]
feature_start = int( feature[1] )
feature_end = int( feature[2] )
- if feature_chrom != chrom or feature_start > int( end ) or feature_end < int( start ):
+ if ( chrom is not None and feature_chrom != chrom ) \
+ or ( start is not None and feature_start > int( end ) ) \
+ or ( end is not None and feature_end < int( start ) ):
continue
yield line
return line_filter_iter()
diff -r 0f5ab41da4bd2e605b9f0785a1e35a7a0d5983d6 -r 0c65c410ccc4b15c72fcb50a5c3c3e982f0b446b lib/galaxy/web/controllers/tracks.py
--- a/lib/galaxy/web/controllers/tracks.py
+++ b/lib/galaxy/web/controllers/tracks.py
@@ -13,7 +13,7 @@
from galaxy.web.framework import simplejson
from galaxy.web.framework.helpers import time_ago, grids
from galaxy.util.bunch import Bunch
-from galaxy.datatypes.interval import Gff
+from galaxy.datatypes.interval import Gff, Bed
from galaxy.model import NoConverterException, ConverterDependencyException
from galaxy.visualization.tracks.data_providers import *
from galaxy.visualization.tracks.visual_analytics import get_tool_def, get_dataset_job
@@ -246,6 +246,27 @@
"tool": get_tool_def( trans, dataset )
}
return track
+
+ @web.json
+ def bookmarks_from_dataset( self, trans, hda_id=None, ldda_id=None ):
+ if hda_id:
+ hda_ldda = "hda"
+ dataset = self.get_dataset( trans, hda_id, check_ownership=False, check_accessible=True )
+ elif ldda_id:
+ hda_ldda = "ldda"
+ dataset = trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ).get( trans.security.decode_id( ldda_id ) )
+ rows = []
+ if isinstance( dataset.datatype, Bed ):
+ data = RawBedDataProvider( original_dataset=dataset ).get_iterator()
+ for i, line in enumerate( data ):
+ if ( i > 500 ): break
+ fields = line.split()
+ location = name = "%s:%s-%s" % ( fields[0], fields[1], fields[2] )
+ if len( fields ) > 3:
+ name = fields[4]
+ rows.append( [location, name] )
+ return { 'data': rows }
+
@web.expose
@web.require_login()
diff -r 0f5ab41da4bd2e605b9f0785a1e35a7a0d5983d6 -r 0c65c410ccc4b15c72fcb50a5c3c3e982f0b446b static/june_2007_style/base.css.tmpl
--- a/static/june_2007_style/base.css.tmpl
+++ b/static/june_2007_style/base.css.tmpl
@@ -909,6 +909,14 @@
-sprite-group: fugue;
-sprite-image: fugue/plus-circle.png;
}
+.icon-button.plus-button {
+ -sprite-group: fugue;
+ -sprite-image: fugue/plus-button.png;
+}
+.icon-button.gear {
+ -sprite-group: fugue;
+ -sprite-image: fugue/gear.png;
+}
.tipsy {
padding: 5px;
diff -r 0f5ab41da4bd2e605b9f0785a1e35a7a0d5983d6 -r 0c65c410ccc4b15c72fcb50a5c3c3e982f0b446b static/june_2007_style/blue/base.css
--- a/static/june_2007_style/blue/base.css
+++ b/static/june_2007_style/blue/base.css
@@ -163,6 +163,8 @@
.icon-button.vis-chart{background:url(fugue.png) no-repeat 0px -286px;}
.icon-button.go-to-full-screen{background:url(fugue.png) no-repeat 0px -312px;}
.icon-button.import{background:url(fugue.png) no-repeat 0px -338px;}
+.icon-button.plus-button{background:url(fugue.png) no-repeat 0px -364px;}
+.icon-button.gear{background:url(fugue.png) no-repeat 0px -390px;}
.tipsy{padding:5px;font-size:10px;filter:alpha(opacity=80);background-repeat:no-repeat;background-image:url(../images/tipsy.gif);}
.tipsy-inner{padding:5px 8px 4px 8px;background-color:black;color:white;max-width:200px;text-align:center;}
.tipsy-north{background-position:top center;}
@@ -171,7 +173,7 @@
.tipsy-west{background-position:left center;}
.editable-text{cursor:pointer;}
.editable-text:hover{cursor:text;border:dotted #999999 1px;}
-.text-and-autocomplete-select{background:url(fugue.png) no-repeat right -364px;}
+.text-and-autocomplete-select{background:url(fugue.png) no-repeat right -416px;}
.icon-button.multiinput{background:url(../images/documents-stack.png) no-repeat;cursor:pointer;float:none;display:inline-block;margin-left:10px;}
.icon-button.multiinput.disabled{background:url(../images/documents-stack-faded.png) no-repeat;cursor:auto;}
.workflow-invocation-complete{border:solid 1px #6A6;border-left-width:5px;margin:10px 0;padding-left:5px;}
diff -r 0f5ab41da4bd2e605b9f0785a1e35a7a0d5983d6 -r 0c65c410ccc4b15c72fcb50a5c3c3e982f0b446b static/june_2007_style/blue/fugue.png
Binary file static/june_2007_style/blue/fugue.png has changed
diff -r 0f5ab41da4bd2e605b9f0785a1e35a7a0d5983d6 -r 0c65c410ccc4b15c72fcb50a5c3c3e982f0b446b static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -3313,7 +3313,6 @@
};
extend(FeatureTrack.prototype, Drawable.prototype, TiledTrack.prototype, {
set_painter_from_config: function() {
- console.log( this, this.config );
if ( this.config.values['connector_style'] == 'arcs' ) {
this.painter = painters.ArcLinkedFeaturePainter;
} else {
diff -r 0f5ab41da4bd2e605b9f0785a1e35a7a0d5983d6 -r 0c65c410ccc4b15c72fcb50a5c3c3e982f0b446b templates/tracks/browser.mako
--- a/templates/tracks/browser.mako
+++ b/templates/tracks/browser.mako
@@ -110,6 +110,52 @@
}
});
};
+
+ /**
+ * Use a popup grid to bookmarks from a dataset.
+ */
+ var add_bookmarks = function() {
+ show_modal( "Select dataset for new bookmarks", "progress" );
+ $.ajax({
+ url: "${h.url_for( action='list_histories' )}",
+ data: { "f-dbkey": view.dbkey },
+ error: function() { alert( "Grid failed" ); },
+ success: function(table_html) {
+ show_modal(
+ "Select dataset for new bookmarks",
+ table_html, {
+ "Cancel": function() {
+ hide_modal();
+ },
+ "Insert": function() {
+ // Just use the first selected
+ $('input[name=id]:checked,input[name=ldda_ids]:checked').first().each(function(){
+ var data, id = $(this).val();
+ if ($(this).attr("name") === "id") {
+ data = { hda_id: id };
+ } else {
+ data = { ldda_id: id};
+ }
+
+ $.ajax({
+ url: "${h.url_for( action='bookmarks_from_dataset' )}",
+ data: data,
+ dataType: "json",
+ }).then( function(data) {
+ for( i = 0; i < data.data.length; i++ ) {
+ var row = data.data[i];
+ console.log( row[0], row[1] );
+ add_bookmark( row[0], row[1] );
+ }
+ });
+ });
+ hide_modal();
+ }
+ }
+ );
+ }
+ });
+ };
$(function() {
// Manual tipsy config because default gravity is S and cannot be changed.
@@ -240,7 +286,13 @@
annotation = "Bookmark description";
return add_bookmark(position, annotation);
});
-
+
+ // make_popupmenu( $("#bookmarks-more-button"), {
+ // "Add from BED dataset": function() {
+ // add_bookmarks();
+ // }
+ // });
+
init_keyboard_nav(view);
};
@@ -271,14 +323,15 @@
<div class="unified-panel-header" unselectable="on"><div class="unified-panel-header-inner">
+ <div style="float: right">
+ <a id="add-bookmark-button" class='icon-button menu-button plus-button' href="javascript:void(0);" title="Add bookmark"></a>
+ ## <a id="bookmarks-more-button" class='icon-button menu-button gear popup' href="javascript:void(0);" title="More actions"></a>
+ </div>
Bookmarks
</div></div><div class="unified-panel-body" style="overflow: auto;"><div id="bookmarks-container"></div>
- <div>
- <a class="icon-button import" style="margin-left: .5em; width: 100%" original-title="Add Bookmark" id="add-bookmark-button" href="javascript:void(0);">Add Bookmark</a>
- </div></div></%def>
https://bitbucket.org/galaxy/galaxy-central/changeset/8b91dd6872df/
changeset: 8b91dd6872df
user: james_taylor
date: 2011-11-08 00:22:47
summary: Trackster: fix strand drawing for single blocks with no thin/thick part
affected #: 1 file
diff -r 0c65c410ccc4b15c72fcb50a5c3c3e982f0b446b -r 8b91dd6872df54ef7d479b8c814241e2aabf12f4 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -4385,17 +4385,17 @@
// Draw feature/feature blocks + connectors.
if (!feature_blocks) {
// If there are no blocks, treat the feature as one big exon.
- if ( feature.strand ) {
- if (feature.strand === "+") {
+ ctx.fillStyle = block_color;
+ ctx.fillRect(f_start, y_center + 1, f_end - f_start, thick_height);
+ // If strand is specified, draw arrows over feature
+ if ( feature_strand ) {
+ if (feature_strand === "+") {
ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand_inv' );
- } else if (feature.strand === "-") {
+ } else if (feature_strand === "-") {
ctx.fillStyle = ctx.canvas.manager.get_pattern( 'left_strand_inv' );
}
+ ctx.fillRect(f_start, y_center + 1, f_end - f_start, thick_height);
}
- else { // No strand.
- ctx.fillStyle = block_color;
- }
- ctx.fillRect(f_start, y_center, f_end - f_start, thick_height);
} else {
//
// There are feature blocks and mode is either Squish or Pack.
https://bitbucket.org/galaxy/galaxy-central/changeset/132798922d53/
changeset: 132798922d53
user: james_taylor
date: 2011-11-08 17:18:24
summary: Automated merge with ssh://bitbucket.org/galaxy/galaxy-central
affected #: 15 files
diff -r d161bb98374369c0cc3aa77eed4e162273e64bb3 -r 132798922d53213d6ca4e1596619f254bdd582d0 eggs.ini
--- a/eggs.ini
+++ b/eggs.ini
@@ -12,7 +12,7 @@
no_auto = pbs_python DRMAA_python
[eggs:platform]
-bx_python = 0.7.0
+bx_python = 0.7.1
Cheetah = 2.2.2
ctypes = 1.0.2
DRMAA_python = 0.2
@@ -67,7 +67,7 @@
psycopg2 = _8.4.2_static
pysqlite = _3.6.17_static
MySQL_python = _5.1.41_static
-bx_python = _494c2d1d68b3_rebuild1
+bx_python = _7b95ff194725
GeneTrack = _dev_48da9e998f0caf01c5be731e926f4b0481f658f0
SQLAlchemy = _dev_r6498
pysam = _kanwei_b10f6e722e9a
diff -r d161bb98374369c0cc3aa77eed4e162273e64bb3 -r 132798922d53213d6ca4e1596619f254bdd582d0 lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
--- a/lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
+++ b/lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
@@ -50,4 +50,4 @@
st.write(out_fname)
if __name__ == "__main__":
- main()
\ No newline at end of file
+ main()
diff -r d161bb98374369c0cc3aa77eed4e162273e64bb3 -r 132798922d53213d6ca4e1596619f254bdd582d0 lib/galaxy/visualization/tracks/data_providers.py
--- a/lib/galaxy/visualization/tracks/data_providers.py
+++ b/lib/galaxy/visualization/tracks/data_providers.py
@@ -2,14 +2,15 @@
Data providers for tracks visualizations.
"""
-import sys
-from math import ceil, log
+import sys, time
+from math import ceil, log, sqrt
import pkg_resources
pkg_resources.require( "bx-python" )
if sys.version_info[:2] == (2, 4):
pkg_resources.require( "ctypes" )
pkg_resources.require( "pysam" )
pkg_resources.require( "numpy" )
+import numpy
from galaxy.datatypes.util.gff_util import *
from galaxy.util.json import from_json_string
from bx.interval_index_file import Indexes
@@ -362,14 +363,18 @@
for large datasets.
"""
- def get_iterator( self, chrom, start, end ):
+ def get_iterator( self, chrom=None, start=None, end=None ):
def line_filter_iter():
for line in open( self.original_dataset.file_name ):
+ if line.startswith( "track" ) or line.startswith( "browser" ):
+ continue
feature = line.split()
feature_chrom = feature[0]
feature_start = int( feature[1] )
feature_end = int( feature[2] )
- if feature_chrom != chrom or feature_start > int( end ) or feature_end < int( start ):
+ if ( chrom is not None and feature_chrom != chrom ) \
+ or ( start is not None and feature_start > int( end ) ) \
+ or ( end is not None and feature_end < int( start ) ):
continue
yield line
return line_filter_iter()
@@ -740,40 +745,73 @@
# Bigwig has the possibility of it being a standalone bigwig file, in which case we use
# original_dataset, or coming from wig->bigwig conversion in which we use converted_dataset
f, bbi = self._get_dataset()
-
+
+ # If the stats kwarg was provide, we compute overall summary data for
+ # the entire chromosome, but no reduced data -- currently only
+ # providing values used by trackster to determine the default range
if 'stats' in kwargs:
- all_dat = bbi.query(chrom, 0, 2147483647, 1)
+ # FIXME: use actual chromosome size
+ summary = bbi.summarize( chrom, 0, 214783647, 1 )
f.close()
- if all_dat is None:
+ if summary is None:
return None
-
- all_dat = all_dat[0] # only 1 summary
- return { 'data' : { 'max': float( all_dat['max'] ), \
- 'min': float( all_dat['min'] ), \
- 'total_frequency': float( all_dat['coverage'] ) } \
- }
-
+ else:
+ # Does the summary contain any defined values?
+ valid_count = summary.valid_count[0]
+ if summary.valid_count < 1:
+ return None
+
+ # Compute $\mu \pm 2\sigma$ to provide an estimate for upper and lower
+ # bounds that contain ~95% of the data.
+ mean = summary.sum_data[0] / valid_count
+ var = summary.sum_squares[0] - mean
+ if valid_count > 1:
+ var /= valid_count - 1
+ sd = numpy.sqrt( var )
+
+ return dict( data=dict( min=summary.min_val[0], max=summary.max_val[0], mean=mean, sd=sd ) )
+
start = int(start)
end = int(end)
+
+ # The following seems not to work very well, for example it will only return one
+ # data point if the tile is 1280px wide. Not sure what the intent is.
+
# The first zoom level for BBI files is 640. If too much is requested, it will look at each block instead
# of summaries. The calculation done is: zoom <> (end-start)/num_points/2.
# Thus, the optimal number of points is (end-start)/num_points/2 = 640
# num_points = (end-start) / 1280
- num_points = (end-start) / 1280
- if num_points < 1:
- num_points = end - start
- else:
- num_points = min(num_points, 500)
+ #num_points = (end-start) / 1280
+ #if num_points < 1:
+ # num_points = end - start
+ #else:
+ # num_points = min(num_points, 500)
- data = bbi.query(chrom, start, end, num_points)
+ # For now, we'll do 1000 data points by default However, the summaries
+ # don't seem to work when a summary pixel corresponds to less than one
+ # datapoint, so we prevent that.
+ # FIXME: need to switch over to using the full data at high levels of
+ # detail.
+ num_points = min( 1000, end - start )
+
+ summary = bbi.summarize( chrom, start, end, num_points )
f.close()
+
+ result = []
+
+ if summary:
+ mean = summary.sum_data / summary.valid_count
+
+ ## Standard deviation by bin, not yet used
+ ## var = summary.sum_squares - mean
+ ## var /= minimum( valid_count - 1, 1 )
+ ## sd = sqrt( var )
- pos = start
- step_size = (end - start) / num_points
- result = []
- if data:
- for dat_dict in data:
- result.append( (pos, float_nan(dat_dict['mean']) ) )
+ pos = start
+ step_size = (end - start) / num_points
+
+ for i in range( num_points ):
+ result.append( (pos, float_nan( mean[i] ) ) )
pos += step_size
return { 'data': result }
diff -r d161bb98374369c0cc3aa77eed4e162273e64bb3 -r 132798922d53213d6ca4e1596619f254bdd582d0 lib/galaxy/web/controllers/tracks.py
--- a/lib/galaxy/web/controllers/tracks.py
+++ b/lib/galaxy/web/controllers/tracks.py
@@ -13,7 +13,7 @@
from galaxy.web.framework import simplejson
from galaxy.web.framework.helpers import time_ago, grids
from galaxy.util.bunch import Bunch
-from galaxy.datatypes.interval import Gff
+from galaxy.datatypes.interval import Gff, Bed
from galaxy.model import NoConverterException, ConverterDependencyException
from galaxy.visualization.tracks.data_providers import *
from galaxy.visualization.tracks.visual_analytics import get_tool_def, get_dataset_job
@@ -246,6 +246,27 @@
"tool": get_tool_def( trans, dataset )
}
return track
+
+ @web.json
+ def bookmarks_from_dataset( self, trans, hda_id=None, ldda_id=None ):
+ if hda_id:
+ hda_ldda = "hda"
+ dataset = self.get_dataset( trans, hda_id, check_ownership=False, check_accessible=True )
+ elif ldda_id:
+ hda_ldda = "ldda"
+ dataset = trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ).get( trans.security.decode_id( ldda_id ) )
+ rows = []
+ if isinstance( dataset.datatype, Bed ):
+ data = RawBedDataProvider( original_dataset=dataset ).get_iterator()
+ for i, line in enumerate( data ):
+ if ( i > 500 ): break
+ fields = line.split()
+ location = name = "%s:%s-%s" % ( fields[0], fields[1], fields[2] )
+ if len( fields ) > 3:
+ name = fields[4]
+ rows.append( [location, name] )
+ return { 'data': rows }
+
@web.expose
@web.require_login()
@@ -528,6 +549,7 @@
if not standalone_provider.has_data( chrom ):
return messages.NO_DATA
valid_chroms = standalone_provider.valid_chroms()
+
# Have data if we get here
return { "status": messages.DATA, "valid_chroms": valid_chroms }
@@ -1041,4 +1063,4 @@
return_message = message
elif return_message == None and message == messages.PENDING:
return_message = message
- return return_message
\ No newline at end of file
+ return return_message
diff -r d161bb98374369c0cc3aa77eed4e162273e64bb3 -r 132798922d53213d6ca4e1596619f254bdd582d0 static/june_2007_style/base.css.tmpl
--- a/static/june_2007_style/base.css.tmpl
+++ b/static/june_2007_style/base.css.tmpl
@@ -231,6 +231,10 @@
padding: 3px 0 0 1em;
}
+.form-row .help {
+ color: #666;
+}
+
select, input, textarea {
font: inherit;
}
@@ -905,6 +909,14 @@
-sprite-group: fugue;
-sprite-image: fugue/plus-circle.png;
}
+.icon-button.plus-button {
+ -sprite-group: fugue;
+ -sprite-image: fugue/plus-button.png;
+}
+.icon-button.gear {
+ -sprite-group: fugue;
+ -sprite-image: fugue/gear.png;
+}
.tipsy {
padding: 5px;
diff -r d161bb98374369c0cc3aa77eed4e162273e64bb3 -r 132798922d53213d6ca4e1596619f254bdd582d0 static/june_2007_style/blue/base.css
--- a/static/june_2007_style/blue/base.css
+++ b/static/june_2007_style/blue/base.css
@@ -43,6 +43,7 @@
div.form-row-input{float:left;}
div.form-row-input label{font-weight:normal;display:inline;}
div.form-row-error-message{width:300px;float:left;color:red;font-weight:bold;padding:3px 0 0 1em;}
+.form-row .help{color:#666;}
select,input,textarea{font:inherit;}
select,textarea,input[type="text"],input[type="file"],input[type="password"]{-webkit-box-sizing:border-box;max-width:300px;}
.errormessagelarge,.warningmessagelarge,.donemessagelarge,.infomessagelarge{padding:10px;padding-left:52px;min-height:32px;border:1px solid #AA6666;background-color:#FFCCCC;background-image:url(error_message_icon.png);background-repeat:no-repeat;background-position:10px 10px;}
@@ -162,6 +163,8 @@
.icon-button.vis-chart{background:url(fugue.png) no-repeat 0px -286px;}
.icon-button.go-to-full-screen{background:url(fugue.png) no-repeat 0px -312px;}
.icon-button.import{background:url(fugue.png) no-repeat 0px -338px;}
+.icon-button.plus-button{background:url(fugue.png) no-repeat 0px -364px;}
+.icon-button.gear{background:url(fugue.png) no-repeat 0px -390px;}
.tipsy{padding:5px;font-size:10px;filter:alpha(opacity=80);background-repeat:no-repeat;background-image:url(../images/tipsy.gif);}
.tipsy-inner{padding:5px 8px 4px 8px;background-color:black;color:white;max-width:200px;text-align:center;}
.tipsy-north{background-position:top center;}
@@ -170,7 +173,7 @@
.tipsy-west{background-position:left center;}
.editable-text{cursor:pointer;}
.editable-text:hover{cursor:text;border:dotted #999999 1px;}
-.text-and-autocomplete-select{background:url(fugue.png) no-repeat right -364px;}
+.text-and-autocomplete-select{background:url(fugue.png) no-repeat right -416px;}
.icon-button.multiinput{background:url(../images/documents-stack.png) no-repeat;cursor:pointer;float:none;display:inline-block;margin-left:10px;}
.icon-button.multiinput.disabled{background:url(../images/documents-stack-faded.png) no-repeat;cursor:auto;}
.workflow-invocation-complete{border:solid 1px #6A6;border-left-width:5px;margin:10px 0;padding-left:5px;}
diff -r d161bb98374369c0cc3aa77eed4e162273e64bb3 -r 132798922d53213d6ca4e1596619f254bdd582d0 static/june_2007_style/blue/fugue.png
Binary file static/june_2007_style/blue/fugue.png has changed
diff -r d161bb98374369c0cc3aa77eed4e162273e64bb3 -r 132798922d53213d6ca4e1596619f254bdd582d0 static/june_2007_style/blue/panel_layout.css
--- a/static/june_2007_style/blue/panel_layout.css
+++ b/static/june_2007_style/blue/panel_layout.css
@@ -23,9 +23,11 @@
.panel-header-button:hover{color:black;background-color:#ccc;}
.panel-header-button:active{color:white;background-color:#aaaaaa;}
#overlay{position:fixed;top:0;left:0;width:100%;height:100%;z-index:20000;}
+#overlay.modal #overlay-background{background:rgba(0,0,0,0.5);}
.dialog-box-container{position:relative;margin-top:80px;margin-right:auto;margin-left:auto;}
.dialog-box-wrapper{position:relative;padding:1em;background-color:rgba(0,0,0,0.5);-moz-border-radius:1em;-webkit-border-radius:1em;}
.dialog-box{border:solid #999 1px;background:white;z-index:80000;}
+#overlay.modal .dialog-box .body{min-width:600px;}
.dialog-box .body{padding:5px;overflow:auto;max-height:500px;min-width:300px;}
.dialog-box .buttons{padding:5px;}
.panel-error-message,.panel-warning-message,.panel-done-message,.panel-info-message{height:24px;line-height:24px;color:#303030;padding:0px;padding-left:26px;background-color:#FFCCCC;background-image:url(error_small.png);background-repeat:no-repeat;background-position:6px 50%;}
diff -r d161bb98374369c0cc3aa77eed4e162273e64bb3 -r 132798922d53213d6ca4e1596619f254bdd582d0 static/june_2007_style/blue/trackster.css
--- a/static/june_2007_style/blue/trackster.css
+++ b/static/june_2007_style/blue/trackster.css
@@ -3,30 +3,9 @@
.content{font:10px verdana;}
.nav-controls{text-align:center;padding:1px 0;}
.nav-controls input{margin:0 5px;}
-.menu-button{padding: 0px 4px 0px 4px;}
#zoom-in,#zoom-out{display:inline-block;height:16px;width:16px;margin-bottom:-3px;cursor:pointer;}
#zoom-out{background:transparent url(../images/fugue/magnifier-zoom-out.png) center center no-repeat;}
#zoom-in{margin-left:10px;background:transparent url(../images/fugue/magnifier-zoom.png) center center no-repeat;}
-.overview-icon{background:transparent url(../images/fugue/application-dock-270-bw.png) no-repeat;}
-.overview-icon:hover{background:transparent url(../images/fugue/application-dock-270.png) no-repeat;}
-.settings-icon{background:transparent url(../images/fugue/gear-bw.png) no-repeat;}
-.settings-icon:hover{background:transparent url(../images/fugue/gear.png) no-repeat;}
-.tools-icon{background:transparent url(../images/fugue/toolbox-bw.png) no-repeat;}
-.tools-icon:hover{background:transparent url(../images/fugue/toolbox.png) no-repeat;}
-.filters-icon{background:transparent url(../images/fugue/ui-slider-050-bw.png) no-repeat;}
-.filters-icon:hover{background:transparent url(../images/fugue/ui-slider-050.png) no-repeat;}
-.remove-icon,.overview-close{background:transparent url(../images/fugue/cross-small-bw.png) no-repeat;}
-.remove-icon:hover,.overview-close:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
-#close-icon{background:transparent url(../images/fugue/cross-circle-bw.png) no-repeat;margin-right:0px;}
-#close-icon:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
-#add-tracks-icon{background:transparent url(../images/fugue/plus-button-bw.png) no-repeat;}
-#add-tracks-icon:hover{background:transparent url(../images/fugue/plus-button.png) no-repeat;}
-#add-group-icon{background:transparent url(../images/fugue/block--plus-bw.png) no-repeat;}
-#add-group-icon:hover{background:transparent url(../images/fugue/block--plus.png) no-repeat;}
-#bookmarks-icon{background:transparent url(../images/fugue/bookmarks-bw.png) no-repeat;}
-#bookmarks-icon:hover{background:transparent url(../images/fugue/bookmarks.png) no-repeat;}
-#save-icon{background:transparent url(../images/fugue/disk--arrow-bw.png) no-repeat;}
-#save-icon:hover{background:transparent url(../images/fugue/disk--arrow.png) no-repeat;}
.nav-input{font-size:12px;width:30em;z-index:1000;}
.location{display:inline-block;width:15em;margin:0 10px;}
.draghandle{margin-top:2px;cursor:move;float:left;background:transparent url(../images/visualization/draggable_horizontal.png) center center no-repeat;width:10px;height:12px;}
@@ -65,16 +44,39 @@
input{font:10px verdana;}
.dynamic-tool,.filters{margin-left:0.25em;padding-bottom:0.5em;}
.dynamic-tool{width:410px;}
-.filters>.sliders,.display-controls{float:left;margin:1em;}
+.filters > .sliders,.display-controls{float:left;margin:1em;}
.sliders{width:410px;}
-.display-controls{border-left:solid 2px #DDDDDD;padding-left:1em}
-.filter-row{margin-top:0.4em;}
+.display-controls{border-left:solid 2px #DDDDDD;padding-left:1em
+}
+.filter-row {
+ margin-top:0.4em;}
.slider-row{margin-left:1em;}
.elt-label{float:left;font-weight:bold;margin-right:1em;}
.slider{float:right;width:200px;position:relative;}
.tool-name{font-size:110%;font-weight:bold;}
.param-row{margin-top:0.2em;margin-left:1em;}
.param-label{float:left;font-weight:bold;padding-top:0.2em;}
+.menu-button{padding:0px 4px 0px 4px;}
+.settings-icon{background:transparent url(../images/fugue/gear-bw.png) no-repeat;}
+.settings-icon:hover{background:transparent url(../images/fugue/gear.png) no-repeat;}
+.overview-icon{background:transparent url(../images/fugue/application-dock-270-bw.png) no-repeat;}
+.overview-icon:hover{background:transparent url(../images/fugue/application-dock-270.png) no-repeat;}
+.tools-icon{background:transparent url(../images/fugue/toolbox-bw.png) no-repeat;}
+.tools-icon:hover{background:transparent url(../images/fugue/toolbox.png) no-repeat;}
+.filters-icon{background:transparent url(../images/fugue/ui-slider-050-bw.png) no-repeat;}
+.filters-icon:hover{background:transparent url(../images/fugue/ui-slider-050.png) no-repeat;}
+.remove-icon,.overview-close{background:transparent url(../images/fugue/cross-small-bw.png) no-repeat;}
+.remove-icon:hover,.overview-close:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
+#close-icon{background:transparent url(../images/fugue/cross-circle-bw.png) no-repeat;margin-right:0px;}
+#close-icon:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;}
+#add-tracks-icon{background:transparent url(../images/fugue/plus-button-bw.png) no-repeat;}
+#add-tracks-icon:hover{background:transparent url(../images/fugue/plus-button.png) no-repeat;}
+#add-group-icon{background:transparent url(../images/fugue/block--plus-bw.png) no-repeat;}
+#add-group-icon:hover{background:transparent url(../images/fugue/block--plus.png) no-repeat;}
+#bookmarks-icon{background:transparent url(../images/fugue/bookmarks-bw.png) no-repeat;}
+#bookmarks-icon:hover{background:transparent url(../images/fugue/bookmarks.png) no-repeat;}
+#save-icon{background:transparent url(../images/fugue/disk--arrow-bw.png) no-repeat;}
+#save-icon:hover{background:transparent url(../images/fugue/disk--arrow.png) no-repeat;}
.child-track-icon{background:url('../images/fugue/arrow-000-small-bw.png') no-repeat;width:30px;cursor:move;}
.track-resize{background:white url('../images/visualization/draggable_vertical.png') no-repeat top center;position:absolute;right:3px;bottom:-4px;width:14px;height:7px;border:solid #999 1px;z-index:100;}
.bookmark{background:white;border:solid #999 1px;border-right:none;margin:0.5em;margin-right:0;padding:0.5em;}
@@ -85,4 +87,5 @@
.icon.more-across{background:url('../images/fugue/arrow-transition-bw.png') no-repeat 0px 0px;}
.intro{padding:1em;}
.intro > .action-button{background-color:#CCC;padding:1em;}
-.feature-popup{background-color:#DDD;position:absolute;z-index:1000}
+.feature-popup{position:absolute;z-index:1000;padding:5px;font-size:10px;filter:alpha(opacity=80);background-repeat:no-repeat;background-image:url(../images/tipsy.gif);background-position:top center;}
+.feature-popup-inner{padding:5px 8px 4px 8px;background-color:black;color:white;}
diff -r d161bb98374369c0cc3aa77eed4e162273e64bb3 -r 132798922d53213d6ca4e1596619f254bdd582d0 static/june_2007_style/panel_layout.css.tmpl
--- a/static/june_2007_style/panel_layout.css.tmpl
+++ b/static/june_2007_style/panel_layout.css.tmpl
@@ -161,6 +161,10 @@
z-index: 20000;
}
+#overlay.modal #overlay-background {
+ background: rgba(0,0,0,0.5);
+}
+
.dialog-box-container {
position: relative;
margin-top: 80px;
@@ -182,6 +186,10 @@
z-index: 80000;
}
+#overlay.modal .dialog-box .body {
+ min-width: 600px;
+}
+
.dialog-box .body {
padding: 5px;
overflow: auto;
diff -r d161bb98374369c0cc3aa77eed4e162273e64bb3 -r 132798922d53213d6ca4e1596619f254bdd582d0 static/june_2007_style/trackster.css.tmpl
--- a/static/june_2007_style/trackster.css.tmpl
+++ b/static/june_2007_style/trackster.css.tmpl
@@ -405,8 +405,19 @@
background-color: #CCC;
padding: 1em;
}
-.feature-popup{
- background-color: #DDD;
+
+.feature-popup {
position: absolute;
- z-index: 1000
+ z-index: 1000;
+ padding: 5px;
+ font-size: 10px;
+ filter: alpha(opacity=80);
+ background-repeat: no-repeat;
+ background-image: url(../images/tipsy.gif);
+ background-position: top center;
}
+.feature-popup-inner {
+ padding: 5px 8px 4px 8px;
+ background-color: black;
+ color: white;
+}
diff -r d161bb98374369c0cc3aa77eed4e162273e64bb3 -r 132798922d53213d6ca4e1596619f254bdd582d0 static/scripts/galaxy.panels.js
--- a/static/scripts/galaxy.panels.js
+++ b/static/scripts/galaxy.panels.js
@@ -163,13 +163,23 @@
// Modal dialog boxes
function hide_modal() {
- $(".dialog-box-container" ).fadeOut( function() {
+ $(".dialog-box-container" ).hide( 0, function() {
$("#overlay").hide();
+ $("#overlay").removeClass( "modal" );
$( ".dialog-box" ).find( ".body" ).children().remove();
} );
};
-function show_modal( title, body, buttons, extra_buttons, init_fn ) {
+function show_modal() {
+ $("#overlay").addClass( "modal" );
+ _show_modal.apply( this, arguments );
+}
+
+function show_message() {
+ _show_modal.apply( this, arguments );
+}
+
+function _show_modal( title, body, buttons, extra_buttons, init_fn ) {
if ( title ) {
$( ".dialog-box" ).find( ".title" ).html( title );
$( ".dialog-box" ).find( ".unified-panel-header" ).show();
@@ -205,7 +215,7 @@
$( ".dialog-box" ).find( ".body" ).html( body );
if ( ! $(".dialog-box-container").is( ":visible" ) ) {
$("#overlay").show();
- $(".dialog-box-container").fadeIn();
+ $(".dialog-box-container").show();
}
// Fix min-width so that modal cannot shrink considerably if
// new content is loaded.
diff -r d161bb98374369c0cc3aa77eed4e162273e64bb3 -r 132798922d53213d6ca4e1596619f254bdd582d0 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -701,7 +701,7 @@
remove: function() {
this.container.remove_drawable(this);
- this.container_div.fadeOut('slow', function() {
+ this.container_div.hide(0, function() {
$(this).remove();
// HACK: is there a better way to update the view?
view.update_intro_div();
@@ -1027,6 +1027,7 @@
// Only act on x axis scrolling if we see if, y will be i
// handled by the browser when the event bubbles up
if ( dx ) {
+ dx *= 50;
var delta_chrom = Math.round( - dx / view.viewport_container.width() * (view.high - view.low) );
view.move_delta( delta_chrom );
}
@@ -1255,7 +1256,7 @@
DrawableCollection.prototype.remove_drawable.call(this, drawable);
if (hide) {
var view = this;
- drawable.container_div.fadeOut('slow', function() {
+ drawable.container_div.hide(0, function() {
$(this).remove();
view.update_intro_div();
});
@@ -2114,31 +2115,49 @@
build_form: function() {
var track_config = this;
var container = $("<div />");
- $.each( this.params, function( index, param ) {
- if ( ! param.hidden ) {
+ var param;
+ // Function to process parameters recursively
+ function handle_params( params, container ) {
+ for ( var index = 0; index < params.length; index++ ) {
+ param = params[index];
+ // Hidden params have no representation in the form
+ if ( param.hidden ) { continue; }
+ // Build row for param
var id = 'param_' + index;
var value = track_config.values[ param.key ];
var row = $("<div class='form-row' />").appendTo( container );
row.append( $('<label />').attr("for", id ).text( param.label + ":" ) );
+ // Draw parameter as checkbox
if ( param.type === 'bool' ) {
row.append( $('<input type="checkbox" />').attr("id", id ).attr("name", id ).attr( 'checked', value ) );
+ // Draw parameter as textbox
} else if ( param.type === 'text' ) {
row.append( $('<input type="text"/>').attr("id", id ).val(value).click( function() { $(this).select() }));
+ // Draw paramter as select area
+ } else if ( param.type == 'select' ) {
+ var select = $('<select />').attr("id", id);
+ for ( var i = 0; i < param.options.length; i++ ) {
+ $("<option/>").text( param.options[i].label ).attr( "value", param.options[i].value ).appendTo( select );
+ }
+ select.val( value );
+ row.append( select );
+ // Draw parameter as color picker
} else if ( param.type === 'color' ) {
var input = $('<input />').attr("id", id ).attr("name", id ).val( value );
// Color picker in tool tip style float
- var tip = $( "<div class='tipsy tipsy-north' style='position: absolute;' />" ).hide();
+ var tip = $( "<div class='tipsy tipsy-west' style='position: absolute;' />" ).hide();
// Inner div for padding purposes
var tip_inner = $("<div style='background-color: black; padding: 10px;'></div>").appendTo(tip);
var farb_container = $("<div/>")
.appendTo(tip_inner)
.farbtastic( { width: 100, height: 100, callback: input, color: value });
-
// Outer div container input and tip for hover to work
$("<div />").append( input ).append( tip ).appendTo( row ).bind( "click", function ( e ) {
tip.css( {
- left: $(this).position().left + ( $(input).width() / 2 ) - 60,
- top: $(this).position().top + $(this.height)
+ // left: $(this).position().left + ( $(input).width() / 2 ) - 60,
+ // top: $(this).position().top + $(this.height)
+ left: $(this).position().left + $(input).width() + 5,
+ top: $(this).position().top - ( $(tip).height() / 2 ) + ( $(input).height() / 2 )
} ).show();
$(document).bind( "click.color-picker", function() {
tip.hide();
@@ -2150,8 +2169,15 @@
else {
row.append( $('<input />').attr("id", id ).attr("name", id ).val( value ) );
}
+ // Help text
+ if ( param.help ) {
+ row.append( $("<div class='help'/>").text( param.help ) );
+ }
}
- });
+ }
+ // Handle top level parameters in order
+ handle_params( this.params, container );
+ // Return element containing constructed form
return container;
},
update_from_form: function( container ) {
@@ -2229,7 +2255,16 @@
// Only show popups in Pack mode.
if (tile.mode !== "Pack") { return; }
- $(this.canvas).mousemove(function (e) {
+ $(this.canvas).hover( function() {
+ this.hovered = true;
+ $(this).mousemove();
+ }, function() {
+ this.hovered = false;
+ // Clear popup if it is still hanging around (this is probably not needed)
+ $(this).siblings(".feature-popup").remove();
+ } ).mousemove(function (e) {
+ // Use the hover plugin to get a delay before showing popup
+ if ( !this.hovered ) { return; }
// Get feature data for position.
var
this_offset = $(this).offset(),
@@ -2270,8 +2305,8 @@
// Build popup.
var popup = $("<div/>").attr("id", feature_uid).addClass("feature-popup"),
- key, value,
- table = $("<table/>").appendTo(popup), row;
+ table = $("<table/>"),
+ key, value, row;
for (key in feature_dict) {
value = feature_dict[key];
row = $("<tr/>").appendTo(table);
@@ -2279,6 +2314,7 @@
$("<td/>").attr("align", "left").appendTo(row)
.text(typeof(value) == 'number' ? round(value, 2) : value);
}
+ popup.append( $("<div class='feature-popup-inner'>").append( table ) );
popups[feature_uid] = popup;
}
@@ -2289,7 +2325,7 @@
// parseInt strips "px" from left, top measurements. +7 so that mouse pointer does not
// overlap popup.
var
- popupX = offsetX + parseInt( tile.canvas.css("left") ) + 7,
+ popupX = offsetX + parseInt( tile.canvas.css("left") ) - popup.width() / 2,
popupY = offsetY + parseInt( tile.canvas.css("top") ) + 7;
popup.css("left", popupX + "px").css("top", popupY + "px")
}
@@ -2331,6 +2367,12 @@
this.data_url_extra_params = {}
this.data_query_wait = (data_query_wait ? data_query_wait : DEFAULT_DATA_QUERY_WAIT);
this.dataset_check_url = converted_datasets_state_url;
+
+ // FIXME: this should be a saved setting
+ this.content_visible = true;
+
+ if (!Track.id_counter) { Track.id_counter = 0; }
+ this.id = Track.id_counter++;
//
// Create HTML element structure for track.
@@ -2346,6 +2388,9 @@
this.icons_div = $("<div/>").css("float", "left").appendTo(this.header_div).hide();
// Track icons.
+ this.toggle_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Hide/show track content")
+ .addClass("icon-button toggle").tipsy( {gravity: 's'} )
+ .appendTo(this.icons_div);
this.settings_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Edit settings")
.addClass("icon-button settings-icon").tipsy( {gravity: 's'} )
.appendTo(this.icons_div);
@@ -2365,6 +2410,21 @@
// Suppress double clicks in header so that they do not impact viz.
this.header_div.dblclick( function(e) { e.stopPropagation(); } );
+
+ // Toggle icon hides or shows the track content
+ this.toggle_icon.click( function() {
+ if ( track.content_visible ) {
+ track.toggle_icon.addClass("toggle-expand").removeClass("toggle");
+ track.hide_contents();
+ track.mode_div.hide();
+ track.content_visible = false;
+ } else {
+ track.toggle_icon.addClass("toggle").removeClass("toggle-expand");
+ track.content_visible = true;
+ track.mode_div.show();
+ track.show_contents();
+ }
+ });
// Clicking on settings icon opens track config.
this.settings_icon.click( function() {
@@ -2552,6 +2612,26 @@
this.update_icons();
},
/**
+ * Hide any elements that are part of the tracks contents area. Should
+ * remove as approprite, the track will be redrawn by show_contents.
+ */
+ hide_contents : function () {
+ // Clear contents by removing any elements that are contained in
+ // the tracks content_div
+ this.content_div.children().remove();
+ // Hide the content div
+ this.content_div.hide();
+ // And any y axis labels (common to several track types)
+ this.container_div.find(".yaxislabel, .track-resize").hide()
+ },
+ show_contents : function() {
+ // Show the contents div and labels (if present)
+ this.content_div.show();
+ this.container_div.find(".yaxislabel, .track-resize").show()
+ // Request a redraw of the content
+ this.request_draw();
+ },
+ /**
* Additional initialization required before drawing track for the first time.
*/
predraw_init: function() {}
@@ -2682,6 +2762,11 @@
*/
_draw: function(force, clear_after) {
if (!this.enabled) { return; }
+
+ // TODO: There should probably be a general way to disable content drawing
+ // for all drawables. However the button to toggle this is currently
+ // only present for Track instances.
+ if (!this.content_visible) { return; }
// HACK: ReferenceTrack can draw without dataset ID, but other tracks cannot.
if ( !(this instanceof ReferenceTrack) && (!this.dataset_id) ) { return; }
@@ -2694,7 +2779,7 @@
w_scale = width / range,
resolution = this.view.resolution,
parent_element = $("<div style='position: relative;'></div>");
-
+
// For overview, adjust high, low, resolution, and w_scale.
if (this.is_overview) {
low = this.view.max_low;
@@ -3028,7 +3113,8 @@
this.min_height_px = 16;
this.max_height_px = 400;
- this.height_px = 80;
+ // Default height for new tracks, should be a defined constant?
+ this.height_px = 32;
this.hda_ldda = hda_ldda;
this.dataset_id = dataset_id;
this.original_dataset_id = dataset_id;
@@ -3076,8 +3162,10 @@
var drag_control = $( "<div class='track-resize'>" )
// Control shows on hover over track, stays while dragging
$(track.container_div).hover( function() {
- in_handle = true;
- drag_control.show();
+ if ( track.content_visible ) {
+ in_handle = true;
+ drag_control.show();
+ }
}, function() {
in_handle = false;
if ( ! in_drag ) { drag_control.hide(); }
@@ -3108,9 +3196,20 @@
track.container_div.addClass( "line-track" );
var data = result.data;
if ( isNaN(parseFloat(track.prefs.min_value)) || isNaN(parseFloat(track.prefs.max_value)) ) {
- track.prefs.min_value = data.min;
- track.prefs.max_value = data.max;
+ // Compute default minimum and maximum values
+ var min_value = data.min
+ var max_value = data.max
+ // If mean and sd are present, use them to compute a ~95% window
+ // but only if it would shrink the range on one side
+ min_value = Math.floor( Math.min( 0, Math.max( min_value, data.mean - 2 * data.sd ) ) )
+ max_value = Math.ceil( Math.max( 0, Math.min( max_value, data.mean + 2 * data.sd ) ) )
+ // Update the prefs
+ track.prefs.min_value = min_value;
+ track.prefs.max_value = max_value;
// Update the config
+ // FIXME: we should probably only save this when the user explicately sets it
+ // since we lose the ability to compute it on the fly (when changing
+ // chromosomes for example).
$('#track_' + track.dataset_id + '_minval').val(track.prefs.min_value);
$('#track_' + track.dataset_id + '_maxval').val(track.prefs.max_value);
}
@@ -3179,13 +3278,17 @@
{ key: 'name', label: 'Name', type: 'text', default_value: name },
{ key: 'block_color', label: 'Block color', type: 'color', default_value: get_random_color() },
{ key: 'label_color', label: 'Label color', type: 'color', default_value: 'black' },
- { key: 'show_counts', label: 'Show summary counts', type: 'bool', default_value: true },
+ { key: 'show_counts', label: 'Show summary counts', type: 'bool', default_value: true,
+ help: 'Show the number of items in each bin when drawing summary histogram' },
+ { key: 'connector_style', label: 'Connector style', type: 'select', default_value: 'fishbones',
+ options: [ { label: 'Line with arrows', value: 'fishbone' }, { label: 'Arcs', value: 'arcs' } ] },
{ key: 'mode', type: 'string', default_value: this.mode, hidden: true },
],
saved_values: prefs,
onchange: function() {
track.set_name(track.prefs.name);
track.tile_cache.clear();
+ track.set_painter_from_config();
track.request_draw();
}
});
@@ -3205,9 +3308,17 @@
this.data_manager = new DataManager(20, this);
this.left_offset = 200;
- this.painter = painters.LinkedFeaturePainter;
+ // this.painter = painters.LinkedFeaturePainter;
+ this.set_painter_from_config();
};
extend(FeatureTrack.prototype, Drawable.prototype, TiledTrack.prototype, {
+ set_painter_from_config: function() {
+ if ( this.config.values['connector_style'] == 'arcs' ) {
+ this.painter = painters.ArcLinkedFeaturePainter;
+ } else {
+ this.painter = painters.LinkedFeaturePainter;
+ }
+ },
/**
* Actions to be taken after draw has been completed. Draw is completed when all tiles have been
* drawn/fetched and shown.
@@ -3527,7 +3638,7 @@
var filter_height_scaler = (this.filters_manager.height_filter ? new FilterScaler(this.filters_manager.height_filter) : null);
// HACK: ref_seq will only be defined for ReadTracks, and only the ReadPainter accepts that argument
var painter = new (this.painter)(filtered, tile_low, tile_high, this.prefs, mode, filter_alpha_scaler, filter_height_scaler, ref_seq);
- var required_height = Math.max(MIN_TRACK_HEIGHT, painter.get_required_height(slots_required));
+ var required_height = Math.max(MIN_TRACK_HEIGHT, painter.get_required_height(slots_required,width));
var canvas = this.view.canvas_manager.new_canvas();
var feature_mapper = null;
@@ -4057,6 +4168,7 @@
this.feature_positions = {};
this.slot_height = slot_height;
this.translation = 0;
+ this.y_translation = 0;
};
/**
@@ -4078,7 +4190,7 @@
*/
FeaturePositionMapper.prototype.get_feature_data = function(x, y) {
// Find slot using Y.
- var slot = Math.floor( y/this.slot_height ),
+ var slot = Math.floor( (y-this.y_translation)/this.slot_height ),
feature_dict;
// May not be over a slot due to padding, margin, etc.
@@ -4108,15 +4220,23 @@
FeaturePainter.prototype.default_prefs = { block_color: "#FFF", connector_color: "#FFF" };
extend(FeaturePainter.prototype, {
- get_required_height: function(rows_required) {
+ get_required_height: function(rows_required, width) {
// y_scale is the height per row
var required_height = y_scale = this.get_row_height(), mode = this.mode;
// If using a packing mode, need to multiply by the number of slots used
if (mode === "no_detail" || mode === "Squish" || mode === "Pack") {
required_height = rows_required * y_scale;
}
+ return required_height + this.get_top_padding(width) + this.get_bottom_padding(width);
+ },
+ /** Extra padding before first row of features */
+ get_top_padding: function(width) {
+ return 0;
+ },
+ /** Extra padding after last row of features */
+ get_bottom_padding: function(width) {
// Pad bottom by half a row, at least 5 px
- return required_height + Math.max( Math.round( y_scale / 2 ), 5 );
+ return Math.max( Math.round( this.get_row_height() / 2 ), 5 )
},
/**
* Draw data on ctx using slots and within the rectangle defined by width and height. Returns
@@ -4153,6 +4273,7 @@
}
ctx.restore();
+ feature_mapper.y_translation = this.get_top_padding(width);
return feature_mapper;
},
/**
@@ -4179,6 +4300,10 @@
var LinkedFeaturePainter = function(data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler) {
FeaturePainter.call(this, data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler);
+ // Whether to draw a single connector in the background that spans the entire feature (the intron fishbone)
+ this.draw_background_connector = true;
+ // Whether to call draw_connector for every pair of blocks
+ this.draw_individual_connectors = false;
};
extend(LinkedFeaturePainter.prototype, FeaturePainter.prototype, {
@@ -4216,7 +4341,7 @@
f_end = Math.ceil( Math.min(width, Math.max(0, (feature_end - tile_low) * w_scale)) ),
draw_start = f_start,
draw_end = f_end,
- y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale,
+ y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale + this.get_top_padding(width),
thickness, y_start, thick_start = null, thick_end = null,
// TODO: is there any reason why block, label color cannot be set at the Painter level?
block_color = this.prefs.block_color,
@@ -4260,17 +4385,17 @@
// Draw feature/feature blocks + connectors.
if (!feature_blocks) {
// If there are no blocks, treat the feature as one big exon.
- if ( feature.strand ) {
- if (feature.strand === "+") {
+ ctx.fillStyle = block_color;
+ ctx.fillRect(f_start, y_center + 1, f_end - f_start, thick_height);
+ // If strand is specified, draw arrows over feature
+ if ( feature_strand ) {
+ if (feature_strand === "+") {
ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand_inv' );
- } else if (feature.strand === "-") {
+ } else if (feature_strand === "-") {
ctx.fillStyle = ctx.canvas.manager.get_pattern( 'left_strand_inv' );
}
+ ctx.fillRect(f_start, y_center + 1, f_end - f_start, thick_height);
}
- else { // No strand.
- ctx.fillStyle = block_color;
- }
- ctx.fillRect(f_start, y_center, f_end - f_start, thick_height);
} else {
//
// There are feature blocks and mode is either Squish or Pack.
@@ -4279,38 +4404,51 @@
// needed. This ensures that whole feature, regardless of whether it starts with
// a block, is visible.
//
-
- // Draw whole feature as connector/intron.
+
+ // Compute y axis center position and height
var cur_y_center, cur_height;
if (mode === "Squish" || mode === "Dense") {
- ctx.fillStyle = CONNECTOR_COLOR;
cur_y_center = y_center + Math.floor(SQUISH_FEATURE_HEIGHT/2) + 1;
cur_height = 1;
}
else { // mode === "Pack"
if (feature_strand) {
- var cur_y_center = y_center;
- var cur_height = thick_height;
- if (feature_strand === "+") {
- ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand' );
- } else if (feature_strand === "-") {
- ctx.fillStyle = ctx.canvas.manager.get_pattern( 'left_strand' );
- }
+ cur_y_center = y_center;
+ cur_height = thick_height;
}
else {
- ctx.fillStyle = CONNECTOR_COLOR;
cur_y_center += (SQUISH_FEATURE_HEIGHT/2) + 1;
cur_height = 1;
}
}
- ctx.fillRect(f_start, cur_y_center, f_end - f_start, cur_height);
+
+ // Draw whole feature as connector/intron.
+ if ( this.draw_background_connector ) {
+ if (mode === "Squish" || mode === "Dense") {
+ ctx.fillStyle = CONNECTOR_COLOR;
+ }
+ else { // mode === "Pack"
+ if (feature_strand) {
+ if (feature_strand === "+") {
+ ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand' );
+ } else if (feature_strand === "-") {
+ ctx.fillStyle = ctx.canvas.manager.get_pattern( 'left_strand' );
+ }
+ }
+ else {
+ ctx.fillStyle = CONNECTOR_COLOR;
+ }
+ }
+ ctx.fillRect(f_start, cur_y_center, f_end - f_start, cur_height);
+ }
// Draw blocks.
var start_and_height;
for (var k = 0, k_len = feature_blocks.length; k < k_len; k++) {
var block = feature_blocks[k],
block_start = Math.floor( Math.max(0, (block[0] - tile_low) * w_scale) ),
- block_end = Math.ceil( Math.min(width, Math.max((block[1] - tile_low) * w_scale)) );
+ block_end = Math.ceil( Math.min(width, Math.max((block[1] - tile_low) * w_scale)) ),
+ last_block_start, last_block_end;
// Skip drawing if block not on tile.
if (block_start > block_end) { continue; }
@@ -4341,6 +4479,12 @@
ctx.fillRect(block_thick_start, y_center + 1, block_thick_end - block_thick_start, thick_height );
}
}
+ // Draw individual connectors if required
+ if ( this.draw_individual_connectors && last_block_start ) {
+ this.draw_connector( ctx, last_block_start, last_block_end, block_start, block_end, y_center );
+ }
+ last_block_start = block_start;
+ last_block_end = block_end;
}
// FIXME: Height scaling only works in Pack mode right now.
@@ -4673,11 +4817,54 @@
}
});
+var ArcLinkedFeaturePainter = function(data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler) {
+ LinkedFeaturePainter.call(this, data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler);
+ // Need to know the longest feature length for adding spacing
+ this.longest_feature_length = this.calculate_longest_feature_length();
+ this.draw_background_connector = false;
+ this.draw_individual_connectors = true;
+};
+
+extend(ArcLinkedFeaturePainter.prototype, FeaturePainter.prototype, LinkedFeaturePainter.prototype, {
+
+ calculate_longest_feature_length: function () {
+ var longest_feature_length = 0;
+ for (var i = 0, len = this.data.length; i < len; i++) {
+ var feature = this.data[i], feature_start = feature[1], feature_end = feature[2];
+ longest_feature_length = Math.max( longest_feature_length, feature_end - feature_start );
+ }
+ return longest_feature_length;
+ },
+
+ get_top_padding: function( width ) {
+ var view_range = this.view_end - this.view_start,
+ w_scale = width / view_range;
+ return Math.min( 128, Math.ceil( ( this.longest_feature_length / 2 ) * w_scale ) );
+ },
+
+ draw_connector: function( ctx, block1_start, block1_end, block2_start, block2_end, y_center ) {
+ // Arc drawing -- from closest endpoints
+ var x_center = ( block1_end + block2_start ) / 2,
+ radius = block2_start - x_center;
+ // For full half circles
+ var angle1 = Math.PI, angle2 = 0;
+ if ( radius > 0 ) {
+ ctx.beginPath();
+ ctx.arc( x_center, y_center, block2_start - x_center, Math.PI, 0 );
+ ctx.stroke();
+ }
+ }
+});
+
+
+
+
exports.Scaler = Scaler;
exports.SummaryTreePainter = SummaryTreePainter;
exports.LinePainter = LinePainter;
exports.LinkedFeaturePainter = LinkedFeaturePainter;
exports.ReadPainter = ReadPainter;
+exports.ArcLinkedFeaturePainter = ArcLinkedFeaturePainter;
// End painters_module encapsulation
};
@@ -4708,4 +4895,4 @@
for ( key in modules.trackster ) {
target[key] = modules.trackster[key];
}
-})(window);
\ No newline at end of file
+})(window);
diff -r d161bb98374369c0cc3aa77eed4e162273e64bb3 -r 132798922d53213d6ca4e1596619f254bdd582d0 templates/tracks/browser.mako
--- a/templates/tracks/browser.mako
+++ b/templates/tracks/browser.mako
@@ -42,7 +42,7 @@
<script type='text/javascript' src="${h.url_for('/static/scripts/excanvas.js')}"></script><![endif]-->
-${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.event.drag", "jquery.mousewheel", "jquery.autocomplete", "trackster", "trackster_ui", "jquery.ui.sortable.slider", "farbtastic", "jquery.tipsy" )}
+${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.event.drag", "jquery.event.hover","jquery.mousewheel", "jquery.autocomplete", "trackster", "trackster_ui", "jquery.ui.sortable.slider", "farbtastic", "jquery.tipsy" )}
<script type="text/javascript">
//
@@ -110,6 +110,52 @@
}
});
};
+
+ /**
+ * Use a popup grid to bookmarks from a dataset.
+ */
+ var add_bookmarks = function() {
+ show_modal( "Select dataset for new bookmarks", "progress" );
+ $.ajax({
+ url: "${h.url_for( action='list_histories' )}",
+ data: { "f-dbkey": view.dbkey },
+ error: function() { alert( "Grid failed" ); },
+ success: function(table_html) {
+ show_modal(
+ "Select dataset for new bookmarks",
+ table_html, {
+ "Cancel": function() {
+ hide_modal();
+ },
+ "Insert": function() {
+ // Just use the first selected
+ $('input[name=id]:checked,input[name=ldda_ids]:checked').first().each(function(){
+ var data, id = $(this).val();
+ if ($(this).attr("name") === "id") {
+ data = { hda_id: id };
+ } else {
+ data = { ldda_id: id};
+ }
+
+ $.ajax({
+ url: "${h.url_for( action='bookmarks_from_dataset' )}",
+ data: data,
+ dataType: "json",
+ }).then( function(data) {
+ for( i = 0; i < data.data.length; i++ ) {
+ var row = data.data[i];
+ console.log( row[0], row[1] );
+ add_bookmark( row[0], row[1] );
+ }
+ });
+ });
+ hide_modal();
+ }
+ }
+ );
+ }
+ });
+ };
$(function() {
// Manual tipsy config because default gravity is S and cannot be changed.
@@ -240,7 +286,13 @@
annotation = "Bookmark description";
return add_bookmark(position, annotation);
});
-
+
+ // make_popupmenu( $("#bookmarks-more-button"), {
+ // "Add from BED dataset": function() {
+ // add_bookmarks();
+ // }
+ // });
+
init_keyboard_nav(view);
};
@@ -271,14 +323,15 @@
<div class="unified-panel-header" unselectable="on"><div class="unified-panel-header-inner">
+ <div style="float: right">
+ <a id="add-bookmark-button" class='icon-button menu-button plus-button' href="javascript:void(0);" title="Add bookmark"></a>
+ ## <a id="bookmarks-more-button" class='icon-button menu-button gear popup' href="javascript:void(0);" title="More actions"></a>
+ </div>
Bookmarks
</div></div><div class="unified-panel-body" style="overflow: auto;"><div id="bookmarks-container"></div>
- <div>
- <a class="icon-button import" style="margin-left: .5em; width: 100%" original-title="Add Bookmark" id="add-bookmark-button" href="javascript:void(0);">Add Bookmark</a>
- </div></div></%def>
diff -r d161bb98374369c0cc3aa77eed4e162273e64bb3 -r 132798922d53213d6ca4e1596619f254bdd582d0 templates/workflow/editor.mako
--- a/templates/workflow/editor.mako
+++ b/templates/workflow/editor.mako
@@ -213,7 +213,7 @@
show_workflow_parameters();
},
beforeSubmit: function( data ) {
- show_modal( "Loading workflow", "progress" );
+ show_message( "Loading workflow", "progress" );
}
});
}
@@ -650,7 +650,7 @@
};
var save_current_workflow = function ( eventObj, success_callback ) {
- show_modal( "Saving workflow", "progress" );
+ show_message( "Saving workflow", "progress" );
workflow.check_changes_in_active_form();
if (!workflow.has_changes) {
hide_modal();
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: dan: Squash SAMTools stderr chatter when using FreeBayes which would cause error state. FreeBayes should be updated to e.g. have access to built-in reference genomes, etc.
by Bitbucket 08 Nov '11
by Bitbucket 08 Nov '11
08 Nov '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/d161bb983743/
changeset: d161bb983743
user: dan
date: 2011-11-08 16:59:27
summary: Squash SAMTools stderr chatter when using FreeBayes which would cause error state. FreeBayes should be updated to e.g. have access to built-in reference genomes, etc.
affected #: 1 file
diff -r d09e2505fc105eaf9e04c4c973df613f873f6dca -r d161bb98374369c0cc3aa77eed4e162273e64bb3 tools/human_genome_variation/freebayes.xml
--- a/tools/human_genome_variation/freebayes.xml
+++ b/tools/human_genome_variation/freebayes.xml
@@ -5,11 +5,11 @@
</requirements><description>Bayesian genetic variant detector</description><command>
- ln -s $reference localref.fa;
- ln -s $bamfile localbam.bam;
- samtools faidx localref.fa;
- samtools sort localbam.bam localbam.bam;
- samtools index localbam.bam;
+ ln -s $reference localref.fa &&
+ ln -s $bamfile localbam.bam &&
+ samtools faidx localref.fa 2>&1 || echo "Error running samtools faidx for FreeBayes" >&2 &&
+ samtools sort localbam.bam localbam.bam 2>&1 || echo "Error running samtools sort for FreeBayes" >&2 &&
+ samtools index localbam.bam 2>&1 || echo "Error running samtools index for FreeBayes" >&2 &&
freebayes --fasta-reference localref.fa localbam.bam --vcf $output
#if $params.source_select == "full":
$params.showRefRepeats
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: natefoo: Invalidate other Galaxy sessions upon password change. Thanks Bob Harris!
by Bitbucket 08 Nov '11
by Bitbucket 08 Nov '11
08 Nov '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/d09e2505fc10/
changeset: d09e2505fc10
user: natefoo
date: 2011-11-08 16:23:52
summary: Invalidate other Galaxy sessions upon password change. Thanks Bob Harris!
affected #: 1 file
diff -r ba739e96c1a14d649c37655cecfc5b835ab343d2 -r d09e2505fc105eaf9e04c4c973df613f873f6dca lib/galaxy/web/controllers/user.py
--- a/lib/galaxy/web/controllers/user.py
+++ b/lib/galaxy/web/controllers/user.py
@@ -753,7 +753,7 @@
password = kwd.get( 'password', '' )
confirm = kwd.get( 'confirm', '' )
ok = True
- if not webapp == 'galaxy' and not is_admin:
+ if not is_admin:
# If the current user is changing their own password, validate their current password
current = kwd.get( 'current', '' )
if not trans.user.check_password( current ):
@@ -768,10 +768,17 @@
else:
# Save new password
user.set_password_cleartext( password )
+ # Invalidate all other sessions
+ for other_galaxy_session in trans.sa_session.query( trans.app.model.GalaxySession ) \
+ .filter( and_( trans.app.model.GalaxySession.table.c.user_id==trans.user.id,
+ trans.app.model.GalaxySession.table.c.is_valid==True,
+ trans.app.model.GalaxySession.table.c.id!=trans.galaxy_session.id ) ):
+ other_galaxy_session.is_valid = False
+ trans.sa_session.add( other_galaxy_session )
trans.sa_session.add( user )
trans.sa_session.flush()
trans.log_event( "User change password" )
- message = 'The password has been changed.'
+ message = 'The password has been changed and any other existing Galaxy sessions have been logged out (but jobs in histories in those sessions will not be interrupted).'
elif user and params.get( 'edit_user_info_button', False ):
# Edit user information - webapp MUST BE 'galaxy'
user_type_fd_id = params.get( 'user_type_fd_id', 'none' )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: natefoo: Actually send error reports to the creator instead of lying and saying that we did.
by Bitbucket 07 Nov '11
by Bitbucket 07 Nov '11
07 Nov '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/ba739e96c1a1/
changeset: ba739e96c1a1
user: natefoo
date: 2011-11-07 21:27:43
summary: Actually send error reports to the creator instead of lying and saying that we did.
affected #: 1 file
diff -r 0cdd7bb67d95efd4a5cfc9219a36f4f6232a243a -r ba739e96c1a14d649c37655cecfc5b835ab343d2 lib/galaxy/util/__init__.py
--- a/lib/galaxy/util/__init__.py
+++ b/lib/galaxy/util/__init__.py
@@ -574,11 +574,9 @@
"""
Sends an email.
"""
- header_to = to
- if isinstance( to, list ):
- header_to = ', '.join( to )
+ to = listify( to )
msg = MIMEText( body )
- msg[ 'To' ] = header_to
+ msg[ 'To' ] = ', '.join( to )
msg[ 'From' ] = frm
msg[ 'Subject' ] = subject
if config.smtp_server is None:
@@ -613,8 +611,6 @@
log.error( "No suitable authentication method was found: %s" % e )
s.close()
raise
- if isinstance( to, basestring ):
- to = [ to ]
s.sendmail( frm, to, msg.as_string() )
s.quit()
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: dannon: Fix bug introduced in 0ba260ea43c4 for displaying workflows.
by Bitbucket 07 Nov '11
by Bitbucket 07 Nov '11
07 Nov '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/0cdd7bb67d95/
changeset: 0cdd7bb67d95
user: dannon
date: 2011-11-07 18:46:14
summary: Fix bug introduced in 0ba260ea43c4 for displaying workflows.
affected #: 1 file
diff -r a6f7e5024f40ae2cb177c636e52c46962a3f0d91 -r 0cdd7bb67d95efd4a5cfc9219a36f4f6232a243a templates/workflow/display.mako
--- a/templates/workflow/display.mako
+++ b/templates/workflow/display.mako
@@ -1,8 +1,8 @@
<%inherit file="/display_base.mako"/><%namespace file="/display_common.mako" import="render_message" />
-<%
- from galaxy.tools.parameters import DataToolParameter, RuntimeValue
+<%!
+ from galaxy.tools.parameters import DataToolParameter, RuntimeValue
from galaxy.web import form_builder
%>
@@ -118,4 +118,4 @@
</tr>
%endfor
</table>
-</%def>
\ No newline at end of file
+</%def>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: dan: Fix for implicit dataset conversion that was broken in 1827729ed37e.
by Bitbucket 07 Nov '11
by Bitbucket 07 Nov '11
07 Nov '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/a6f7e5024f40/
changeset: a6f7e5024f40
user: dan
date: 2011-11-07 17:19:07
summary: Fix for implicit dataset conversion that was broken in 1827729ed37e.
affected #: 2 files
diff -r 545288e40ee10ed48d422eb772b734ace1422451 -r a6f7e5024f40ae2cb177c636e52c46962a3f0d91 lib/galaxy/datatypes/display_applications/parameters.py
--- a/lib/galaxy/datatypes/display_applications/parameters.py
+++ b/lib/galaxy/datatypes/display_applications/parameters.py
@@ -94,13 +94,11 @@
if target_ext and not converted_dataset:
if isinstance( data, DisplayDataValueWrapper ):
data = data.value
- assoc = trans.app.model.ImplicitlyConvertedDatasetAssociation( parent = data, file_type = target_ext, metadata_safe = False )
new_data = data.datatype.convert_dataset( trans, data, target_ext, return_output = True, visible = False ).values()[0]
new_data.hid = data.hid
new_data.name = data.name
trans.sa_session.add( new_data )
- trans.sa_session.flush()
- assoc.dataset = new_data
+ assoc = trans.app.model.ImplicitlyConvertedDatasetAssociation( parent = data, file_type = target_ext, dataset = new_data, metadata_safe = False )
trans.sa_session.add( assoc )
trans.sa_session.flush()
elif converted_dataset and converted_dataset.state == converted_dataset.states.ERROR:
diff -r 545288e40ee10ed48d422eb772b734ace1422451 -r a6f7e5024f40ae2cb177c636e52c46962a3f0d91 lib/galaxy/tools/actions/__init__.py
--- a/lib/galaxy/tools/actions/__init__.py
+++ b/lib/galaxy/tools/actions/__init__.py
@@ -43,13 +43,11 @@
data = converted_dataset
else:
#run converter here
- assoc = trans.app.model.ImplicitlyConvertedDatasetAssociation( parent = data, file_type = target_ext, metadata_safe = False )
new_data = data.datatype.convert_dataset( trans, data, target_ext, return_output = True, visible = False ).values()[0]
new_data.hid = data.hid
new_data.name = data.name
trans.sa_session.add( new_data )
- trans.sa_session.flush()
- assoc.dataset = new_data
+ assoc = trans.app.model.ImplicitlyConvertedDatasetAssociation( parent = data, file_type = target_ext, dataset = new_data, metadata_safe = False )
trans.sa_session.add( assoc )
trans.sa_session.flush()
data = new_data
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/b80ca015c305/
changeset: b80ca015c305
user: jgoecks
date: 2011-11-05 23:21:38
summary: Trackster: color reads based on strand aligned to.
affected #: 2 files
diff -r 21138a4a1fead60fd3c364658a1dabbde870646b -r b80ca015c305cc0768de10dbf60c38bd91abca50 lib/galaxy/visualization/tracks/data_providers.py
--- a/lib/galaxy/visualization/tracks/data_providers.py
+++ b/lib/galaxy/visualization/tracks/data_providers.py
@@ -462,8 +462,10 @@
# ID:
feature[2],
cigar,
+ # TODO? VCF does not have strand, so default to positive.
+ "+",
new_seq,
- float( feature[5] )]
+ float( feature[5] ) ]
rval.append(payload)
return { 'data': rval, 'message': message }
@@ -609,11 +611,11 @@
data - a list of reads with the format
[<guid>, <start>, <end>, <name>, <read_1>, <read_2>]
where <read_1> has the format
- [<start>, <end>, <cigar>, ?<read_seq>?]
+ [<start>, <end>, <cigar>, <strand>, ?<read_seq>?]
and <read_2> has the format
- [<start>, <end>, <cigar>, ?<read_seq>?]
+ [<start>, <end>, <cigar>, <strand>, ?<read_seq>?]
For single-end reads, read has format:
- [<guid>, <start>, <end>, <name>, cigar, seq]
+ [<guid>, <start>, <end>, <name>, <cigar>, <strand>, <seq>]
NOTE: read end and sequence data are not valid for reads outside of
requested region and should not be used.
@@ -641,17 +643,34 @@
else:
return None
+ # Decode strand from read flag.
+ def decode_strand( read_flag, mask ):
+ strand_flag = ( read_flag & mask == 0 )
+ if strand_flag:
+ return "+"
+ else:
+ return "-"
+
# Encode reads as list of lists.
results = []
paired_pending = {}
+ unmapped = 0
for count, read in enumerate( data ):
if count < start_val:
continue
- if count-start_val >= max_vals:
+ if ( count - start_val - unmapped ) >= max_vals:
message = ERROR_MAX_VALS % ( max_vals, "reads" )
break
+
+ # If not mapped, skip read.
+ is_mapped = ( read.flag & 0x0004 == 0 )
+ if not is_mapped:
+ unmapped += 1
+ continue
+
qname = read.qname
seq = read.seq
+ strand = decode_strand( read.flag, 0x0010 )
if read.cigar is not None:
read_len = sum( [cig[1] for cig in read.cigar] ) # Use cigar to determine length
else:
@@ -664,14 +683,15 @@
pair['start'],
read.pos + read_len,
qname,
- [ pair['start'], pair['end'], pair['cigar'], pair['seq'] ],
- [ read.pos, read.pos + read_len, read.cigar, seq ]
+ [ pair['start'], pair['end'], pair['cigar'], pair['strand'], pair['seq'] ],
+ [ read.pos, read.pos + read_len, read.cigar, strand, seq ]
] )
del paired_pending[qname]
else:
- paired_pending[qname] = { 'start': read.pos, 'end': read.pos + read_len, 'seq': seq, 'mate_start': read.mpos, 'rlen': read_len, 'cigar': read.cigar }
+ paired_pending[qname] = { 'start': read.pos, 'end': read.pos + read_len, 'seq': seq, 'mate_start': read.mpos,
+ 'rlen': read_len, 'strand': strand, 'cigar': read.cigar }
else:
- results.append( [ "%i_%s" % ( read.pos, qname ), read.pos, read.pos + read_len, qname, read.cigar, read.seq] )
+ results.append( [ "%i_%s" % ( read.pos, qname ), read.pos, read.pos + read_len, qname, read.cigar, strand, read.seq] )
# Take care of reads whose mates are out of range.
# TODO: count paired reads when adhering to max_vals?
@@ -683,14 +703,14 @@
# Make read_1 start=end so that length is 0 b/c we don't know
# read length.
r1 = [ read['mate_start'], read['mate_start'] ]
- r2 = [ read['start'], read['end'], read['cigar'], read['seq'] ]
+ r2 = [ read['start'], read['end'], read['cigar'], read['strand'], read['seq'] ]
else:
# Mate is after read.
read_start = read['start']
# Make read_2 start=end so that length is 0 b/c we don't know
# read length. Hence, end of read is start of read_2.
read_end = read['mate_start']
- r1 = [ read['start'], read['end'], read['cigar'], read['seq'] ]
+ r1 = [ read['start'], read['end'], read['cigar'], read['strand'], read['seq'] ]
r2 = [ read['mate_start'], read['mate_start'] ]
results.append( [ "%i_%s" % ( read_start, qname ), read_start, read_end, qname, r1, r2 ] )
diff -r 21138a4a1fead60fd3c364658a1dabbde870646b -r b80ca015c305cc0768de10dbf60c38bd91abca50 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -3580,11 +3580,15 @@
var ReadTrack = function (name, view, container, hda_ldda, dataset_id, prefs, filters) {
FeatureTrack.call(this, name, view, container, hda_ldda, dataset_id, prefs, filters);
+ var
+ block_color = get_random_color(),
+ reverse_strand_color = get_random_color( [ block_color, "#ffffff" ] );
this.config = new DrawableConfig( {
track: this,
params: [
{ key: 'name', label: 'Name', type: 'text', default_value: name },
- { key: 'block_color', label: 'Block color', type: 'color', default_value: get_random_color() },
+ { key: 'block_color', label: 'Block and sense strand color', type: 'color', default_value: block_color },
+ { key: 'reverse_strand_color', label: 'Antisense strand color', type: 'color', default_value: reverse_strand_color },
{ key: 'label_color', label: 'Label color', type: 'color', default_value: 'black' },
{ key: 'show_insertions', label: 'Show insertions', type: 'bool', default_value: false },
{ key: 'show_differences', label: 'Show differences only', type: 'bool', default_value: true },
@@ -4388,8 +4392,6 @@
this.ref_seq = (ref_seq ? ref_seq.data : null);
};
-ReadPainter.prototype.default_prefs = extend({}, FeaturePainter.prototype.default_prefs, { show_insertions: false });
-
extend(ReadPainter.prototype, FeaturePainter.prototype, {
/**
* Returns height based on mode.
@@ -4414,14 +4416,15 @@
/**
* Draw a single read.
*/
- draw_read: function(ctx, mode, w_scale, tile_low, tile_high, feature_start, cigar, orig_seq, y_center) {
+ draw_read: function(ctx, mode, w_scale, y_center, tile_low, tile_high, feature_start, cigar, strand, orig_seq) {
ctx.textAlign = "center";
var track = this,
tile_region = [tile_low, tile_high],
base_offset = 0,
seq_offset = 0,
gap = 0,
- char_width_px = ctx.canvas.manager.char_width_px;
+ char_width_px = ctx.canvas.manager.char_width_px,
+ block_color = (strand === "+" ? this.prefs.block_color : this.prefs.reverse_strand_color);
// Keep list of items that need to be drawn on top of initial drawing layer.
var draw_last = [];
@@ -4468,7 +4471,7 @@
// Draw.
var seq = orig_seq.slice(seq_offset, seq_offset + cig_len);
if (gap > 0) {
- ctx.fillStyle = this.prefs.block_color;
+ ctx.fillStyle = block_color;
ctx.fillRect(s_start - gap, y_center + 1, s_end - s_start, 9);
ctx.fillStyle = CONNECTOR_COLOR;
// TODO: this can be made much more efficient by computing the complete sequence
@@ -4486,7 +4489,7 @@
}
}
} else {
- ctx.fillStyle = this.prefs.block_color;
+ ctx.fillStyle = block_color;
// TODO: This is a pretty hack-ish way to fill rectangle based on mode.
ctx.fillRect(s_start, y_center + 4, s_end - s_start, SQUISH_FEATURE_HEIGHT);
}
@@ -4615,7 +4618,6 @@
f_start = Math.floor( Math.max(0, (feature_start - tile_low) * w_scale) ),
f_end = Math.ceil( Math.min(width, Math.max(0, (feature_end - tile_low) * w_scale)) ),
y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale,
- block_color = this.prefs.block_color,
label_color = this.prefs.label_color,
// Left-gap for label text since we align chrom text to the position tick.
gap = 0;
@@ -4626,7 +4628,6 @@
}
// Draw read.
- ctx.fillStyle = block_color;
if (feature[5] instanceof Array) {
// Read is paired.
var b1_start = Math.floor( Math.max(0, (feature[4][0] - tile_low) * w_scale) ),
@@ -4635,12 +4636,12 @@
b2_end = Math.ceil( Math.min(width, Math.max(0, (feature[5][1] - tile_low) * w_scale)) );
// Draw left/forward read.
- if (feature[4][1] >= tile_low && feature[4][0] <= tile_high && feature[4][2]) {
- this.draw_read(ctx, mode, w_scale, tile_low, tile_high, feature[4][0], feature[4][2], feature[4][3], y_center);
+ if (feature[4][1] >= tile_low && feature[4][0] <= tile_high && feature[4][2]) {
+ this.draw_read(ctx, mode, w_scale, y_center, tile_low, tile_high, feature[4][0], feature[4][2], feature[4][3], feature[4][4]);
}
// Draw right/reverse read.
if (feature[5][1] >= tile_low && feature[5][0] <= tile_high && feature[5][2]) {
- this.draw_read(ctx, mode, w_scale, tile_low, tile_high, feature[5][0], feature[5][2], feature[5][3], y_center);
+ this.draw_read(ctx, mode, w_scale, y_center, tile_low, tile_high, feature[5][0], feature[5][2], feature[5][3], feature[5][4]);
}
// Draw connector.
if (b2_start > b1_end) {
@@ -4649,8 +4650,7 @@
}
} else {
// Read is single.
- ctx.fillStyle = block_color;
- this.draw_read(ctx, mode, w_scale, tile_low, tile_high, feature_start, feature[4], feature[5], y_center);
+ this.draw_read(ctx, mode, w_scale, y_center, tile_low, tile_high, feature_start, feature[4], feature[5], feature[6]);
}
if (mode === "Pack" && feature_start > tile_low && feature_name !== ".") {
// Draw label.
@@ -4664,7 +4664,6 @@
ctx.textAlign = "right";
ctx.fillText(feature_name, f_start - LABEL_SPACING - gap, y_center + 8);
}
- ctx.fillStyle = block_color;
}
// FIXME: provide actual coordinates for drawn read.
https://bitbucket.org/galaxy/galaxy-central/changeset/545288e40ee1/
changeset: 545288e40ee1
user: jgoecks
date: 2011-11-06 00:12:07
summary: Trackster: tooltips for navigational elements and better showing/hiding of add tracks button.
affected #: 2 files
diff -r b80ca015c305cc0768de10dbf60c38bd91abca50 -r 545288e40ee10ed48d422eb772b734ace1422451 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -941,7 +941,7 @@
}
};
this.nav_input = $("<input/>").addClass("nav-input").hide().bind("keyup focusout", submit_nav).appendTo(this.nav_controls);
- this.location_span = $("<span/>").addClass("location").appendTo(this.nav_controls);
+ this.location_span = $("<span/>").addClass("location").attr('original-title', 'Click to change location').tipsy( { gravity: 'n' } ).appendTo(this.nav_controls);
this.location_span.click(function() {
view.location_span.hide();
view.chrom_select.hide();
@@ -953,8 +953,11 @@
if (this.vis_id !== undefined) {
this.hidden_input = $("<input/>").attr("type", "hidden").val(this.vis_id).appendTo(this.nav_controls);
}
- this.zo_link = $("<a id='zoom-out' />").click(function() { view.zoom_out(); view.request_redraw(); }).appendTo(this.nav_controls);
- this.zi_link = $("<a id='zoom-in' />").click(function() { view.zoom_in(); view.request_redraw(); }).appendTo(this.nav_controls);
+
+ this.zo_link = $("<a/>").attr("id", "zoom-out").attr("title", "Zoom out").tipsy( {gravity: 'n'} )
+ .click(function() { view.zoom_out(); view.request_redraw(); }).appendTo(this.nav_controls);
+ this.zi_link = $("<a/>").attr("id", "zoom-in").attr("title", "Zoom in").tipsy( {gravity: 'n'} )
+ .click(function() { view.zoom_in(); view.request_redraw(); }).appendTo(this.nav_controls);
// Get initial set of chroms.
this.load_chroms_deferred = this.load_chroms({low: 0});
@@ -1069,7 +1072,6 @@
this.reset();
$(window).trigger("resize");
- this.update_intro_div();
},
/** Add or remove intro div depending on view state. */
update_intro_div: function() {
diff -r b80ca015c305cc0768de10dbf60c38bd91abca50 -r 545288e40ee10ed48d422eb772b734ace1422451 static/scripts/trackster_ui.js
--- a/static/scripts/trackster_ui.js
+++ b/static/scripts/trackster_ui.js
@@ -111,6 +111,9 @@
}
}
+ // Need to update intro div after drawables have been added.
+ view.update_intro_div();
+
// Set overview.
var overview_track;
for (var i = 0; i < view.drawables.length; i++) {
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: jgoecks: Use panels when adding a build from a new track browser.
by Bitbucket 03 Nov '11
by Bitbucket 03 Nov '11
03 Nov '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/21138a4a1fea/
changeset: 21138a4a1fea
user: jgoecks
date: 2011-11-03 21:54:45
summary: Use panels when adding a build from a new track browser.
affected #: 1 file
diff -r 6e286e6d1b0dda77ef2187aedee0ded555b1fe74 -r 21138a4a1fead60fd3c364658a1dabbde870646b templates/tracks/new_browser.mako
--- a/templates/tracks/new_browser.mako
+++ b/templates/tracks/new_browser.mako
@@ -19,7 +19,7 @@
</div><div class="form-row">
Is the build not listed here?
- <a href="${h.url_for( controller='user', action='dbkeys', panels=True )}">Add a Custom Build</a>
+ <a href="${h.url_for( controller='user', action='dbkeys', use_panels=True )}">Add a Custom Build</a></div>
%if default_dbkey is not None:
<script type="text/javascript">
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: jgoecks: Improve Cufflinks' documentation for gene annotation dataset parameters.
by Bitbucket 03 Nov '11
by Bitbucket 03 Nov '11
03 Nov '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/6e286e6d1b0d/
changeset: 6e286e6d1b0d
user: jgoecks
date: 2011-11-03 21:45:44
summary: Improve Cufflinks' documentation for gene annotation dataset parameters.
affected #: 1 file
diff -r e96f8c994bb629cd0b3b0cb5387a6db84c7c2857 -r 6e286e6d1b0dda77ef2187aedee0ded555b1fe74 tools/ngs_rna/cufflinks_wrapper.xml
--- a/tools/ngs_rna/cufflinks_wrapper.xml
+++ b/tools/ngs_rna/cufflinks_wrapper.xml
@@ -61,10 +61,10 @@
</param><when value="No"></when><when value="Use reference annotation">
- <param format="gff3,gtf" name="reference_annotation_file" type="data" label="Reference Annotation" help="Make sure your annotation file is in GTF format and that Galaxy knows that your file is GTF--not GFF."/>
+ <param format="gff3,gtf" name="reference_annotation_file" type="data" label="Reference Annotation" help="Gene annotation dataset in GTF or GFF3 format."/></when><when value="Use reference annotation guide">
- <param format="gff3,gtf" name="reference_annotation_guide_file" type="data" label="Reference Annotation" help="Make sure your annotation file is in GTF format and that Galaxy knows that your file is GTF--not GFF."/>
+ <param format="gff3,gtf" name="reference_annotation_guide_file" type="data" label="Reference Annotation" help="Gene annotation dataset in GTF or GFF3 format."/></when></conditional><conditional name="bias_correction">
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0