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
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/c3582a9913fa/
changeset: c3582a9913fa
user: greg
date: 2011-10-28 20:05:14
summary: Add basic UI for managng tool shed repositories installed into a local Galaxy instance from a tool shed. Add the ability to view the list of tools and workflows included in installed tool shed repositories. Ad the ability to import a workflow from an installed tool shed repository into the local Galaxy instance.
affected #: 7 files
diff -r 07f3f601d645f07b76b196879ecd6d1c68c5b5d4 -r c3582a9913fad4d41b7b7e151163fa4a45371bc1 lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -2443,13 +2443,6 @@
id = trans.security.decode_id( id )
quota = trans.sa_session.query( trans.model.Quota ).get( id )
return quota
-def get_tool_shed_repository( trans, tool_shed, name, owner, changeset_revision ):
- return trans.sa_session.query( trans.model.ToolShedRepository ) \
- .filter( and_( trans.model.ToolShedRepository.table.c.tool_shed == tool_shed,
- trans.model.ToolShedRepository.table.c.name == name,
- trans.model.ToolShedRepository.table.c.owner == owner,
- trans.model.ToolShedRepository.table.c.changeset_revision == changeset_revision ) ) \
- .first()
def handle_sample_tool_data_table_conf_file( trans, filename ):
"""
Parse the incoming filename and add new entries to the in-memory
diff -r 07f3f601d645f07b76b196879ecd6d1c68c5b5d4 -r c3582a9913fad4d41b7b7e151163fa4a45371bc1 lib/galaxy/web/controllers/admin.py
--- a/lib/galaxy/web/controllers/admin.py
+++ b/lib/galaxy/web/controllers/admin.py
@@ -410,7 +410,8 @@
columns = [
NameColumn( "Name",
key="name",
- attach_popup=True ),
+ link=( lambda item: dict( operation="manage_repository", id=item.id, webapp="galaxy" ) ),
+ attach_popup=False ),
DescriptionColumn( "Description" ),
OwnerColumn( "Owner" ),
RevisionColumn( "Revision" ),
@@ -426,17 +427,14 @@
key="free-text-search",
visible=False,
filterable="standard" ) )
- operations = [ grids.GridOperation( "Get updates",
- allow_multiple=False,
- condition=( lambda item: not item.deleted ),
- async_compatible=False ) ]
standard_filters = []
default_filter = dict( deleted="False" )
num_rows_per_page = 50
preserve_state = False
use_paging = True
def build_initial_query( self, trans, **kwd ):
- return trans.sa_session.query( self.model_class )
+ return trans.sa_session.query( self.model_class ) \
+ .filter( self.model_class.table.c.deleted == False )
class AdminGalaxy( BaseUIController, Admin, AdminActions, UsesQuota, QuotaParamParser ):
@@ -678,11 +676,88 @@
return quota, params
@web.expose
@web.require_admin
- def browse_repositories( self, trans, **kwd ):
+ def browse_tool_shed_repository( self, trans, **kwd ):
+ params = util.Params( kwd )
+ message = util.restore_text( params.get( 'message', '' ) )
+ status = params.get( 'status', 'done' )
+ repository = get_repository( trans, kwd[ 'id' ] )
+ relative_install_dir = self.__get_relative_install_dir( trans, repository )
+ repo_files_dir = os.path.abspath( os.path.join( relative_install_dir, repository.name ) )
+ tool_dicts = []
+ workflow_dicts = []
+ for root, dirs, files in os.walk( repo_files_dir ):
+ if not root.find( '.hg' ) >= 0 and not root.find( 'hgrc' ) >= 0:
+ if '.hg' in dirs:
+ # Don't visit .hg directories.
+ dirs.remove( '.hg' )
+ if 'hgrc' in files:
+ # Don't include hgrc files.
+ files.remove( 'hgrc' )
+ for name in files:
+ # Find all tool configs.
+ if name.endswith( '.xml' ):
+ try:
+ full_path = os.path.abspath( os.path.join( root, name ) )
+ tool = trans.app.toolbox.load_tool( full_path )
+ if tool is not None:
+ tool_config = os.path.join( root, name )
+ # Handle tool.requirements.
+ tool_requirements = []
+ for tr in tool.requirements:
+ name=tr.name
+ type=tr.type
+ if type == 'fabfile':
+ version = None
+ fabfile = tr.fabfile
+ method = tr.method
+ else:
+ version = tr.version
+ fabfile = None
+ method = None
+ requirement_dict = dict( name=name,
+ type=type,
+ version=version,
+ fabfile=fabfile,
+ method=method )
+ tool_requirements.append( requirement_dict )
+ tool_dict = dict( id=tool.id,
+ old_id=tool.old_id,
+ name=tool.name,
+ version=tool.version,
+ description=tool.description,
+ requirements=tool_requirements,
+ tool_config=tool_config )
+ tool_dicts.append( tool_dict )
+ except Exception, e:
+ # The file is not a Galaxy tool config.
+ pass
+ # Find all exported workflows
+ elif name.endswith( '.ga' ):
+ try:
+ full_path = os.path.abspath( os.path.join( root, name ) )
+ # Convert workflow data from json
+ fp = open( full_path, 'rb' )
+ workflow_text = fp.read()
+ fp.close()
+ workflow_dict = from_json_string( workflow_text )
+ if workflow_dict[ 'a_galaxy_workflow' ] == 'true':
+ workflow_dicts.append( dict( full_path=full_path, workflow_dict=workflow_dict ) )
+ except Exception, e:
+ # The file is not a Galaxy workflow.
+ pass
+ return trans.fill_template( '/admin/tool_shed_repository/browse_repository.mako',
+ repository=repository,
+ tool_dicts=tool_dicts,
+ workflow_dicts=workflow_dicts,
+ message=message,
+ status=status )
+ @web.expose
+ @web.require_admin
+ def browse_tool_shed_repositories( self, trans, **kwd ):
if 'operation' in kwd:
- operation = kwd.pop('operation').lower()
- if operation == "get updates":
- return self.check_for_updates( trans, **kwd )
+ operation = kwd.pop( 'operation' ).lower()
+ if operation == "manage_repository":
+ return self.manage_tool_shed_repository( trans, **kwd )
# Render the list view
return self.repository_list_grid( trans, **kwd )
@web.expose
@@ -850,10 +925,35 @@
status=status )
@web.expose
@web.require_admin
+ def manage_tool_shed_repository( self, trans, **kwd ):
+ params = util.Params( kwd )
+ message = util.restore_text( params.get( 'message', '' ) )
+ status = params.get( 'status', 'done' )
+ repository_id = params.get( 'id', None )
+ repository = get_repository( trans, repository_id )
+ description = util.restore_text( params.get( 'description', repository.description ) )
+ if params.get( 'edit_repository_button', False ):
+ if description != repository.description:
+ repository.description = description
+ trans.sa_session.add( repository )
+ trans.sa_session.flush()
+ message = "The repository information has been updated."
+ relative_install_dir = self.__get_relative_install_dir( trans, repository )
+ if relative_install_dir:
+ repo_files_dir = os.path.abspath( os.path.join( relative_install_dir, repository.name ) )
+ else:
+ repo_files_dir = 'unknown'
+ return trans.fill_template( '/admin/tool_shed_repository/manage_repository.mako',
+ repository=repository,
+ description=description,
+ repo_files_dir=repo_files_dir,
+ message=message,
+ status=status )
+ @web.expose
+ @web.require_admin
def check_for_updates( self, trans, **kwd ):
params = util.Params( kwd )
- repository_id = params.get( 'id', None )
- repository = get_repository( trans, repository_id )
+ repository = get_repository( trans, kwd[ 'id' ] )
galaxy_url = trans.request.host
# Send a request to the relevant tool shed to see if there are any updates.
# TODO: support https in the following url.
@@ -872,26 +972,16 @@
owner = params.get( 'owner', None )
changeset_revision = params.get( 'changeset_revision', None )
latest_changeset_revision = params.get( 'latest_changeset_revision', None )
+ repository = get_repository_by_shed_name_owner_changeset_revision( trans, tool_shed_url, name, owner, changeset_revision )
if changeset_revision and latest_changeset_revision:
if changeset_revision == latest_changeset_revision:
message = "The cloned tool shed repository named '%s' is current (there are no updates available)." % name
else:
- repository = get_repository_by_name_owner_changeset_revision( trans, name, owner, changeset_revision )
current_working_dir = os.getcwd()
- # Get the directory where the repository is cloned.
- cleaned_tool_shed_url = self.__clean_tool_shed_url( tool_shed_url )
- partial_cloned_dir = '%s/repos/%s/%s/%s' % ( cleaned_tool_shed_url, owner, name, changeset_revision )
- # Get the relative tool installation paths from each of the shed tool configs.
- shed_tool_confs = trans.app.toolbox.shed_tool_confs
- relative_cloned_dir = None
- # The shed_tool_confs dictionary contains shed_conf_filename : tool_path pairs.
- for shed_conf_filename, tool_path in shed_tool_confs.items():
- relative_cloned_dir = os.path.join( tool_path, partial_cloned_dir )
- if os.path.isdir( relative_cloned_dir ):
- break
- if relative_cloned_dir:
+ relative_install_dir = self.__get_relative_install_dir( trans, repository )
+ if relative_install_dir:
# Update the cloned repository to changeset_revision.
- repo_files_dir = os.path.join( relative_cloned_dir, name )
+ repo_files_dir = os.path.join( relative_install_dir, name )
log.debug( "Updating cloned repository named '%s' from revision '%s' to revision '%s'..." % \
( name, changeset_revision, latest_changeset_revision ) )
cmd = 'hg pull'
@@ -935,9 +1025,23 @@
message = "The latest changeset revision could not be retrieved for the repository named '%s'." % name
status = 'error'
return trans.response.send_redirect( web.url_for( controller='admin',
- action='browse_repositories',
+ action='manage_tool_shed_repository',
+ id=trans.security.encode_id( repository.id ),
message=message,
status=status ) )
+ def __get_relative_install_dir( self, trans, repository ):
+ # Get the directory where the repository is install.
+ tool_shed = self.__clean_tool_shed_url( repository.tool_shed )
+ partial_install_dir = '%s/repos/%s/%s/%s' % ( tool_shed, repository.owner, repository.name, repository.changeset_revision )
+ # Get the relative tool installation paths from each of the shed tool configs.
+ shed_tool_confs = trans.app.toolbox.shed_tool_confs
+ relative_install_dir = None
+ # The shed_tool_confs dictionary contains { shed_conf_filename : tool_path } pairs.
+ for shed_conf_filename, tool_path in shed_tool_confs.items():
+ relative_install_dir = os.path.join( tool_path, partial_install_dir )
+ if os.path.isdir( relative_install_dir ):
+ break
+ return relative_install_dir
def __handle_missing_data_table_entry( self, trans, tool_path, sample_files, repository_tools_tups ):
# Inspect each tool to see if any have input parameters that are dynamically
# generated select lists that require entries in the tool_data_table_conf.xml file.
@@ -1057,7 +1161,7 @@
tool_shed = tmp_url.split( 'repos' )[ 0 ].rstrip( '/' )
owner = self.__get_repository_owner( tmp_url )
flush_needed = False
- tool_shed_repository = get_tool_shed_repository( trans, tool_shed, name, owner, changeset_revision )
+ tool_shed_repository = get_repository_by_shed_name_owner_changeset_revision( trans, tool_shed, name, owner, changeset_revision )
if tool_shed_repository:
if tool_shed_repository.deleted:
tool_shed_repository.deleted = False
@@ -1200,3 +1304,11 @@
trans.model.ToolShedRepository.table.c.owner == owner,
trans.model.ToolShedRepository.table.c.changeset_revision == changeset_revision ) ) \
.first()
+def get_repository_by_shed_name_owner_changeset_revision( trans, tool_shed, name, owner, changeset_revision ):
+ return trans.sa_session.query( trans.model.ToolShedRepository ) \
+ .filter( and_( trans.model.ToolShedRepository.table.c.tool_shed == tool_shed,
+ trans.model.ToolShedRepository.table.c.name == name,
+ trans.model.ToolShedRepository.table.c.owner == owner,
+ trans.model.ToolShedRepository.table.c.changeset_revision == changeset_revision ) ) \
+ .first()
+
diff -r 07f3f601d645f07b76b196879ecd6d1c68c5b5d4 -r c3582a9913fad4d41b7b7e151163fa4a45371bc1 lib/galaxy/web/controllers/workflow.py
--- a/lib/galaxy/web/controllers/workflow.py
+++ b/lib/galaxy/web/controllers/workflow.py
@@ -1095,8 +1095,8 @@
@web.expose
def import_workflow( self, trans, **kwd ):
"""
- Import a workflow by reading an url, uploading a file, or receiving the textual
- representation of a workflow.
+ Import a workflow by reading an url, uploading a file, opening and reading the contents
+ of a local file, or receiving the textual representation of a workflow via http.
"""
url = kwd.get( 'url', '' )
workflow_text = kwd.get( 'workflow_text', '' )
@@ -1104,6 +1104,8 @@
message = kwd.get( 'message', '' )
status = kwd.get( 'status', 'done' )
import_button = kwd.get( 'import_button', False )
+ # The following parameters will have values only if the workflow
+ # id being imported from a Galaxy tool shed repository.
tool_shed_url = kwd.get( 'tool_shed_url', '' )
repository_metadata_id = kwd.get( 'repository_metadata_id', '' )
# The workflow_name parameter is in the request only if the import originated
@@ -1111,6 +1113,15 @@
workflow_name = kwd.get( 'workflow_name', '' )
if workflow_name:
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', '' )
+ repository_id = kwd.get( 'repository_id', '' )
+ if local_file and not import_button:
+ workflow_file = open( local_file, 'rb' )
+ workflow_text = workflow_file.read()
+ workflow_file.close()
+ import_button = True
if tool_shed_url and not import_button:
# Use urllib (send another request to the tool shed) to retrieve the workflow.
workflow_url = 'http://%s/workflow/import_workflow?repository_metadata_id=%s&workflow_name=%s&webapp=%s&open_for_url=true' % \
@@ -1118,7 +1129,6 @@
response = urllib2.urlopen( workflow_url )
workflow_text = response.read()
response.close()
- workflow_text = workflow_text
import_button = True
if import_button:
workflow_data = None
@@ -1131,6 +1141,7 @@
message = "Failed to open URL: <b>%s</b><br>Exception: %s" % ( url, str( e ) )
status = 'error'
elif workflow_text:
+ # This case occurs when the workflow_text was sent via http from the tool shed.
workflow_data = workflow_text
else:
# Load workflow from browsed file.
@@ -1170,7 +1181,7 @@
message += "Imported, but this workflow contains cycles. "
status = "error"
else:
- message += "Workflow '%s' imported successfully. " % workflow.name
+ message += "Workflow <b>%s</b> imported successfully. " % workflow.name
if missing_tool_tups:
if trans.user_is_admin():
# A required tool is not available in the local Galaxy instance.
@@ -1201,11 +1212,19 @@
pass
if tool_shed_url:
# We've received the textual representation of a workflow from a Galaxy tool shed.
- message = "This workflow has been successfully imported into your local Galaxy instance."
+ message = "Workflow <b>%s</b> imported successfully." % workflow.name
# TODO: support https in the following url.
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:
+ # 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',
+ action='browse_tool_shed_repository',
+ id=repository_id,
+ message=message,
+ status=status ) )
return self.list( trans )
return trans.fill_template( "workflow/import.mako",
url=url,
diff -r 07f3f601d645f07b76b196879ecd6d1c68c5b5d4 -r c3582a9913fad4d41b7b7e151163fa4a45371bc1 lib/galaxy/webapps/community/controllers/common.py
--- a/lib/galaxy/webapps/community/controllers/common.py
+++ b/lib/galaxy/webapps/community/controllers/common.py
@@ -361,8 +361,9 @@
workflow_text = fp.read()
fp.close()
exported_workflow_dict = from_json_string( workflow_text )
- # Update the list of metadata dictionaries for workflows in metadata_dict.
- metadata_dict = generate_workflow_metadata( trans, id, changeset_revision, exported_workflow_dict, metadata_dict )
+ if exported_workflow_dict[ 'a_galaxy_workflow' ] == 'true':
+ # Update the list of metadata dictionaries for workflows in metadata_dict.
+ metadata_dict = generate_workflow_metadata( trans, id, changeset_revision, exported_workflow_dict, metadata_dict )
except Exception, e:
invalid_files.append( ( name, str( e ) ) )
else:
diff -r 07f3f601d645f07b76b196879ecd6d1c68c5b5d4 -r c3582a9913fad4d41b7b7e151163fa4a45371bc1 templates/admin/tool_shed_repository/browse_repository.mako
--- /dev/null
+++ b/templates/admin/tool_shed_repository/browse_repository.mako
@@ -0,0 +1,127 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+<% from galaxy.web.base.controller import tool_shed_encode, tool_shed_decode %>
+
+<br/><br/>
+<ul class="manage-table-actions">
+ <li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Repository Actions</a></li>
+ <div popupmenu="repository-${repository.id}-popup">
+ <a class="action-button" href="${h.url_for( controller='admin', action='manage_tool_shed_repository', id=trans.security.encode_id( repository.id ) )}">Manage repository</a>
+ <a class="action-button" href="${h.url_for( controller='admin', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get updates</a>
+ </div>
+</ul>
+
+%if message:
+ ${render_msg( message, status )}
+%endif
+
+<div class="toolForm">
+ <div class="toolFormTitle">Installed tool shed repository '${repository.name}'</div>
+ <div class="toolFormBody">
+
+ %if tool_dicts:
+ <div class="form-row">
+ <table width="100%">
+ <tr bgcolor="#D8D8D8" width="100%">
+ <td><b>Tools</b></td>
+ </tr>
+ </table>
+ </div>
+ <div class="form-row">
+ <table class="grid">
+ <tr>
+ <td><b>name</b></td>
+ <td><b>description</b></td>
+ <td><b>version</b></td>
+ <td><b>requirements</b></td>
+ </tr>
+ %for tool_dict in tool_dicts:
+ <tr>
+ <td>${tool_dict[ 'name' ]}</div>
+ </td>
+ <td>${tool_dict[ 'description' ]}</td>
+ <td>${tool_dict[ 'version' ]}</td>
+ <td>
+ <%
+ if 'requirements' in tool_dict:
+ requirements = tool_dict[ 'requirements' ]
+ else:
+ requirements = None
+ %>
+ %if requirements:
+ <%
+ requirements_str = ''
+ for requirement_dict in tool_dict[ 'requirements' ]:
+ requirements_str += '%s (%s), ' % ( requirement_dict[ 'name' ], requirement_dict[ 'type' ] )
+ requirements_str = requirements_str.rstrip( ', ' )
+ %>
+ ${requirements_str}
+ %else:
+ none
+ %endif
+ </td>
+ </tr>
+ %endfor
+ </table>
+ </div>
+ <div style="clear: both"></div>
+ %endif
+ %if workflow_dicts:
+ <div class="form-row">
+ <table width="100%">
+ <tr bgcolor="#D8D8D8" width="100%">
+ <td><b>Workflows</b></td>
+ </tr>
+ </table>
+ </div>
+ <div style="clear: both"></div>
+ <div class="form-row">
+ <table class="grid">
+ <tr>
+ <td><b>name</b></td>
+ <td><b>steps</b></td>
+ <td><b>format-version</b></td>
+ <td><b>annotation</b></td>
+ </tr>
+ <% index = 0 %>
+ %for wf_dict in workflow_dicts:
+ <%
+ full_path = wf_dict[ 'full_path' ]
+ workflow_dict = wf_dict[ 'workflow_dict' ]
+ workflow_name = workflow_dict[ 'name' ]
+ if 'steps' in workflow_dict:
+ ## Initially steps were not stored in the metadata record.
+ steps = workflow_dict[ 'steps' ]
+ else:
+ steps = []
+ format_version = workflow_dict[ 'format-version' ]
+ annotation = workflow_dict[ 'annotation' ]
+ %>
+ <tr>
+ <td>
+ <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>
+ </div>
+ </div>
+ </td>
+ <td>
+ %if 'steps' in workflow_dict:
+ ${len( steps )}
+ %else:
+ unknown
+ %endif
+ </td>
+ <td>${format_version}</td>
+ <td>${annotation}</td>
+ </tr>
+ <% index += 1 %>
+ %endfor
+ </table>
+ </div>
+ <div style="clear: both"></div>
+ %endif
+ </div>
+</div>
diff -r 07f3f601d645f07b76b196879ecd6d1c68c5b5d4 -r c3582a9913fad4d41b7b7e151163fa4a45371bc1 templates/admin/tool_shed_repository/manage_repository.mako
--- /dev/null
+++ b/templates/admin/tool_shed_repository/manage_repository.mako
@@ -0,0 +1,57 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+<br/><br/>
+<ul class="manage-table-actions">
+ <li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Repository Actions</a></li>
+ <div popupmenu="repository-${repository.id}-popup">
+ <a class="action-button" href="${h.url_for( controller='admin', action='browse_tool_shed_repository', id=trans.security.encode_id( repository.id ) )}">Browse repository</a>
+ <a class="action-button" href="${h.url_for( controller='admin', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get updates</a>
+ </div>
+</ul>
+
+%if message:
+ ${render_msg( message, status )}
+%endif
+
+<div class="toolForm">
+ <div class="toolFormTitle">${repository.name}</div>
+ <div class="toolFormBody">
+ <form name="edit_repository" id="edit_repository" action="${h.url_for( controller='admin', action='manage_tool_shed_repository', id=trans.security.encode_id( repository.id ) )}" method="post" >
+ <div class="form-row">
+ <label>Tool shed:</label>
+ ${repository.tool_shed}
+ <div style="clear: both"></div>
+ </div>
+ <div class="form-row">
+ <label>Name:</label>
+ ${repository.name}
+ <div style="clear: both"></div>
+ </div>
+ <div class="form-row">
+ <label>Description:</label>
+ <input name="description" type="textfield" value="${description}" size="80"/>
+ <div style="clear: both"></div>
+ </div>
+ <div class="form-row">
+ <label>Revision:</label>
+ ${repository.changeset_revision}
+ </div>
+ <div class="form-row">
+ <label>Owner:</label>
+ ${repository.owner}
+ </div>
+ <div class="form-row">
+ <label>Location:</label>
+ ${repo_files_dir}
+ </div>
+ <div class="form-row">
+ <label>Deleted:</label>
+ ${repository.deleted}
+ </div>
+ <div class="form-row">
+ <input type="submit" name="edit_repository_button" value="Save"/>
+ </div>
+ </form>
+ </div>
+</div>
diff -r 07f3f601d645f07b76b196879ecd6d1c68c5b5d4 -r c3582a9913fad4d41b7b7e151163fa4a45371bc1 templates/webapps/galaxy/admin/index.mako
--- a/templates/webapps/galaxy/admin/index.mako
+++ b/templates/webapps/galaxy/admin/index.mako
@@ -64,7 +64,7 @@
<div class="toolTitle"><a href="${h.url_for( controller='admin', action='memdump' )}" target="galaxy_main">Profile memory usage</a></div><div class="toolTitle"><a href="${h.url_for( controller='admin', action='jobs' )}" target="galaxy_main">Manage jobs</a></div>
%if cloned_repositories:
- <div class="toolTitle"><a href="${h.url_for( controller='admin', action='browse_repositories' )}" target="galaxy_main">Manage installed tool shed repositories</a></div>
+ <div class="toolTitle"><a href="${h.url_for( controller='admin', action='browse_tool_shed_repositories' )}" target="galaxy_main">Manage installed tool shed repositories</a></div>
%endif
</div></div>
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 refresh on change in workflow run interface triggering actual running of workflow.
by Bitbucket 28 Oct '11
by Bitbucket 28 Oct '11
28 Oct '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/07f3f601d645/
changeset: 07f3f601d645
user: dan
date: 2011-10-28 17:38:55
summary: Fix for refresh on change in workflow run interface triggering actual running of workflow.
affected #: 1 file
diff -r 9a6e51c4efeb1b901cb4cc5b2c494577b5f11ad8 -r 07f3f601d645f07b76b196879ecd6d1c68c5b5d4 lib/galaxy/web/controllers/workflow.py
--- a/lib/galaxy/web/controllers/workflow.py
+++ b/lib/galaxy/web/controllers/workflow.py
@@ -1480,10 +1480,10 @@
trans.sa_session.add( workflow_invocation )
invocations.append({'outputs': outputs,
'new_history': new_history})
- trans.sa_session.flush()
- return trans.fill_template( "workflow/run_complete.mako",
- workflow=stored,
- invocations=invocations )
+ trans.sa_session.flush()
+ return trans.fill_template( "workflow/run_complete.mako",
+ workflow=stored,
+ invocations=invocations )
else:
# Prepare each step
missing_tools = []
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: Create a new ToolShedRepository record only if necessary - if one already exists for the installed repository but is marked deleted, mark the exisint record undeleted.
by Bitbucket 27 Oct '11
by Bitbucket 27 Oct '11
27 Oct '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/9a6e51c4efeb/
changeset: 9a6e51c4efeb
user: greg
date: 2011-10-27 21:08:07
summary: Create a new ToolShedRepository record only if necessary - if one already exists for the installed repository but is marked deleted, mark the exisint record undeleted.
affected #: 2 files
diff -r 786a5d6c56c77b592598df8e32b227cb6e5cb63f -r 9a6e51c4efeb1b901cb4cc5b2c494577b5f11ad8 lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -2443,6 +2443,13 @@
id = trans.security.decode_id( id )
quota = trans.sa_session.query( trans.model.Quota ).get( id )
return quota
+def get_tool_shed_repository( trans, tool_shed, name, owner, changeset_revision ):
+ return trans.sa_session.query( trans.model.ToolShedRepository ) \
+ .filter( and_( trans.model.ToolShedRepository.table.c.tool_shed == tool_shed,
+ trans.model.ToolShedRepository.table.c.name == name,
+ trans.model.ToolShedRepository.table.c.owner == owner,
+ trans.model.ToolShedRepository.table.c.changeset_revision == changeset_revision ) ) \
+ .first()
def handle_sample_tool_data_table_conf_file( trans, filename ):
"""
Parse the incoming filename and add new entries to the in-memory
diff -r 786a5d6c56c77b592598df8e32b227cb6e5cb63f -r 9a6e51c4efeb1b901cb4cc5b2c494577b5f11ad8 lib/galaxy/web/controllers/admin.py
--- a/lib/galaxy/web/controllers/admin.py
+++ b/lib/galaxy/web/controllers/admin.py
@@ -766,12 +766,9 @@
os.chdir( current_working_dir )
tmp_stderr.close()
if returncode == 0:
- # Add a new record to the tool_shed_repository table.
- tool_shed_repository = self.__create_tool_shed_repository( trans,
- name,
- description,
- changeset_revision,
- repository_clone_url )
+ # Add a new record to the tool_shed_repository table if one doesn't
+ # already exist. If one exists but is marked deleted, undelete it.
+ self.__create_or_undelete_tool_shed_repository( trans, name, description, changeset_revision, repository_clone_url )
# Update the cloned repository to changeset_revision.
repo_files_dir = os.path.join( clone_dir, name )
log.debug( 'Updating cloned repository to revision "%s"...' % changeset_revision )
@@ -1055,17 +1052,26 @@
# We have an invalid .xml file, so not a tool config.
log.debug( "Ignoring invalid tool config (%s). Error: %s" % ( str( relative_path ), str( e ) ) )
return sample_files, repository_tools_tups
- def __create_tool_shed_repository( self, trans, name, description, changeset_revision, repository_clone_url ):
+ def __create_or_undelete_tool_shed_repository( self, trans, name, description, changeset_revision, repository_clone_url ):
tmp_url = self.__clean_repository_clone_url( repository_clone_url )
tool_shed = tmp_url.split( 'repos' )[ 0 ].rstrip( '/' )
owner = self.__get_repository_owner( tmp_url )
- tool_shed_repository = trans.model.ToolShedRepository( tool_shed=tool_shed,
- name=name,
- description=description,
- owner=owner,
- changeset_revision=changeset_revision )
- trans.sa_session.add( tool_shed_repository )
- trans.sa_session.flush()
+ flush_needed = False
+ tool_shed_repository = get_tool_shed_repository( trans, tool_shed, name, owner, changeset_revision )
+ if tool_shed_repository:
+ if tool_shed_repository.deleted:
+ tool_shed_repository.deleted = False
+ flush_needed = True
+ else:
+ tool_shed_repository = trans.model.ToolShedRepository( tool_shed=tool_shed,
+ name=name,
+ description=description,
+ owner=owner,
+ changeset_revision=changeset_revision )
+ flush_needed = True
+ if flush_needed:
+ trans.sa_session.add( tool_shed_repository )
+ trans.sa_session.flush()
def __add_shed_tool_conf_entry( self, trans, shed_tool_conf, new_tool_section ):
# Add an entry in the shed_tool_conf file. An entry looks something like:
# <section name="Filter and Sort" id="filter">
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 forgotten (and not wanted) PostJobAction code when generating a workflow it's dict representation for rendering as an svg image in the tool shed.
by Bitbucket 27 Oct '11
by Bitbucket 27 Oct '11
27 Oct '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/786a5d6c56c7/
changeset: 786a5d6c56c7
user: greg
date: 2011-10-27 19:52:05
summary: Eliminate forgotten (and not wanted) PostJobAction code when generating a workflow it's dict representation for rendering as an svg image in the tool shed.
affected #: 1 file
diff -r 753196399060239c365040aa6ecb18cba345b69e -r 786a5d6c56c77b592598df8e32b227cb6e5cb63f lib/galaxy/webapps/community/controllers/workflow.py
--- a/lib/galaxy/webapps/community/controllers/workflow.py
+++ b/lib/galaxy/webapps/community/controllers/workflow.py
@@ -339,12 +339,6 @@
workflow.has_errors = True
# Stick this in the step temporarily.
step.temp_input_connections = step_dict[ 'input_connections' ]
- # Unpack and add post-job actions.
- post_job_actions = step_dict.get( 'post_job_actions', {} )
- for name, pja_dict in post_job_actions.items():
- pja = PostJobAction( pja_dict[ 'action_type' ],
- step, pja_dict[ 'output_name' ],
- pja_dict[ 'action_arguments' ] )
steps.append( step )
steps_by_external_id[ step_dict[ 'id' ] ] = step
# Second pass to deal with connections between steps.
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

27 Oct '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/753196399060/
changeset: 753196399060
user: greg
date: 2011-10-27 19:37:48
summary: Fix for rendering workflow metadata.
affected #: 1 file
diff -r c528fab7ea8c89ab55cb9977d5916c72e5170546 -r 753196399060239c365040aa6ecb18cba345b69e templates/webapps/community/repository/common.mako
--- a/templates/webapps/community/repository/common.mako
+++ b/templates/webapps/community/repository/common.mako
@@ -168,7 +168,11 @@
%for workflow_dict in workflow_dicts:
<%
workflow_name = workflow_dict[ 'name' ]
- steps = workflow_dict[ 'steps' ]
+ if 'steps' in workflow_dict:
+ ## Initially steps were not stored in the metadata record.
+ steps = workflow_dict[ 'steps' ]
+ else:
+ steps = []
format_version = workflow_dict[ 'format-version' ]
annotation = workflow_dict[ 'annotation' ]
%>
@@ -178,7 +182,6 @@
</td><td>
%if 'steps' in workflow_dict:
- ## Initially steps were not stored in the metadata record.
${len( steps )}
%else:
unknown
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 the ability to search for workflows by name in a Galalxy tool shed, either within the tool shed itself or in a local Galaxy instance configured to communicate with the tool shed.
by Bitbucket 27 Oct '11
by Bitbucket 27 Oct '11
27 Oct '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/c528fab7ea8c/
changeset: c528fab7ea8c
user: greg
date: 2011-10-27 19:26:43
summary: Add the ability to search for workflows by name in a Galalxy tool shed, either within the tool shed itself or in a local Galaxy instance configured to communicate with the tool shed.
affected #: 13 files
diff -r 216d4f09480468bb01ee56df9a393c5b740fe51d -r c528fab7ea8c89ab55cb9977d5916c72e5170546 lib/galaxy/web/controllers/admin.py
--- a/lib/galaxy/web/controllers/admin.py
+++ b/lib/galaxy/web/controllers/admin.py
@@ -704,6 +704,13 @@
return trans.response.send_redirect( url )
@web.expose
@web.require_admin
+ def find_workflows_in_tool_shed( self, trans, **kwd ):
+ tool_shed_url = kwd[ 'tool_shed_url' ]
+ galaxy_url = trans.request.host
+ url = '%s/repository/find_workflows?galaxy_url=%s&webapp=galaxy' % ( tool_shed_url, galaxy_url )
+ return trans.response.send_redirect( url )
+ @web.expose
+ @web.require_admin
def browse_tool_shed( self, trans, **kwd ):
tool_shed_url = kwd[ 'tool_shed_url' ]
galaxy_url = trans.request.host
diff -r 216d4f09480468bb01ee56df9a393c5b740fe51d -r c528fab7ea8c89ab55cb9977d5916c72e5170546 lib/galaxy/webapps/community/controllers/repository.py
--- a/lib/galaxy/webapps/community/controllers/repository.py
+++ b/lib/galaxy/webapps/community/controllers/repository.py
@@ -231,7 +231,7 @@
return repository_metadata.repository.user.username
return 'no user'
# Grid definition
- title = "Repositories with matching tools"
+ title = "Matching repositories"
model_class = model.RepositoryMetadata
template='/webapps/community/repository/grid.mako'
default_sort_key = "Repository.name"
@@ -375,6 +375,83 @@
# Render the list view
return self.valid_repository_list_grid( trans, **kwd )
@web.expose
+ def find_workflows( self, trans, **kwd ):
+ params = util.Params( kwd )
+ message = util.restore_text( params.get( 'message', '' ) )
+ status = params.get( 'status', 'done' )
+ webapp = params.get( 'webapp', 'community' )
+ galaxy_url = kwd.get( 'galaxy_url', None )
+ if galaxy_url:
+ trans.set_cookie( galaxy_url, name='toolshedgalaxyurl' )
+ if 'operation' in kwd:
+ item_id = kwd.get( 'id', '' )
+ if item_id:
+ operation = kwd[ 'operation' ].lower()
+ is_admin = trans.user_is_admin()
+ if operation == "view_or_manage_repository":
+ # The received id is a RepositoryMetadata id, so we have to get the repository id.
+ repository_metadata = get_repository_metadata_by_id( trans, item_id )
+ repository_id = trans.security.encode_id( repository_metadata.repository.id )
+ repository = get_repository( trans, repository_id )
+ kwd[ 'id' ] = repository_id
+ kwd[ 'changeset_revision' ] = repository_metadata.changeset_revision
+ if webapp == 'community' and ( is_admin or repository.user == trans.user ):
+ a = 'manage_repository'
+ else:
+ a = 'view_repository'
+ return trans.response.send_redirect( web.url_for( controller='repository',
+ action=a,
+ **kwd ) )
+ if operation == "install":
+ galaxy_url = trans.get_cookie( name='toolshedgalaxyurl' )
+ encoded_repo_info_dict = self.__encode_repo_info_dict( trans, webapp, util.listify( item_id ) )
+ # TODO: support https in the following url.
+ url = 'http://%s/admin/install_tool_shed_repository?tool_shed_url=%s&webapp=%s&repo_info_dict=%s' % \
+ ( galaxy_url, trans.request.host, webapp, encoded_repo_info_dict )
+ return trans.response.send_redirect( url )
+ else:
+ # This can only occur when there is a multi-select grid with check boxes and an operation,
+ # and the user clicked the operation button without checking any of the check boxes.
+ return trans.show_error_message( "No items were selected." )
+ workflow_names = [ item.lower() for item in util.listify( kwd.get( 'workflow_name', '' ) ) ]
+ exact_matches = params.get( 'exact_matches', '' )
+ exact_matches_checked = CheckboxField.is_checked( exact_matches )
+ match_tuples = []
+ ok = True
+ if workflow_names:
+ ok, match_tuples = self.__search_repository_metadata( trans, exact_matches_checked, workflow_names=workflow_names )
+ if ok:
+ kwd[ 'match_tuples' ] = match_tuples
+ # Render the list view
+ if webapp == 'galaxy':
+ # Our initial request originated from a Galaxy instance.
+ global_actions = [ grids.GridAction( "Browse valid repositories",
+ dict( controller='repository', action='browse_valid_repositories', webapp=webapp ) ),
+ grids.GridAction( "Search for valid tools",
+ dict( controller='repository', action='find_tools', webapp=webapp ) ),
+ grids.GridAction( "Search for workflows",
+ dict( controller='repository', action='find_workflows', webapp=webapp ) ) ]
+ self.install_matched_repository_list_grid.global_actions = global_actions
+ install_url_args = dict( controller='repository', action='find_workflows', webapp=webapp )
+ operations = [ grids.GridOperation( "Install", url_args=install_url_args, allow_multiple=True, async_compatible=False ) ]
+ self.install_matched_repository_list_grid.operations = operations
+ return self.install_matched_repository_list_grid( trans, **kwd )
+ else:
+ kwd[ 'message' ] = "workflow name: <b>%s</b><br/>exact matches only: <b>%s</b>" % \
+ ( self.__stringify( workflow_names ), str( exact_matches_checked ) )
+ self.matched_repository_list_grid.title = "Repositories with matching workflows"
+ return self.matched_repository_list_grid( trans, **kwd )
+ else:
+ message = "No search performed - each field must contain the same number of comma-separated items."
+ status = "error"
+ exact_matches_check_box = CheckboxField( 'exact_matches', checked=exact_matches_checked )
+ return trans.fill_template( '/webapps/community/repository/find_workflows.mako',
+ webapp=webapp,
+ workflow_name=self.__stringify( workflow_names ),
+ exact_matches_check_box=exact_matches_check_box,
+ message=message,
+ status=status )
+ @web.expose
def find_tools( self, trans, **kwd ):
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
@@ -421,7 +498,7 @@
match_tuples = []
ok = True
if tool_ids or tool_names or tool_versions:
- ok, match_tuples = self.__search_repository_metadata( trans, tool_ids, tool_names, tool_versions, exact_matches_checked )
+ ok, match_tuples = self.__search_repository_metadata( trans, exact_matches_checked, tool_ids=tool_ids, tool_names=tool_names, tool_versions=tool_versions )
if ok:
kwd[ 'match_tuples' ] = match_tuples
# Render the list view
@@ -430,7 +507,9 @@
global_actions = [ grids.GridAction( "Browse valid repositories",
dict( controller='repository', action='browse_valid_repositories', webapp=webapp ) ),
grids.GridAction( "Search for valid tools",
- dict( controller='repository', action='find_tools', webapp=webapp ) ) ]
+ dict( controller='repository', action='find_tools', webapp=webapp ) ),
+ grids.GridAction( "Search for workflows",
+ dict( controller='repository', action='find_workflows', webapp=webapp ) ) ]
self.install_matched_repository_list_grid.global_actions = global_actions
install_url_args = dict( controller='repository', action='find_tools', webapp=webapp )
operations = [ grids.GridOperation( "Install", url_args=install_url_args, allow_multiple=True, async_compatible=False ) ]
@@ -439,6 +518,7 @@
else:
kwd[ 'message' ] = "tool id: <b>%s</b><br/>tool name: <b>%s</b><br/>tool version: <b>%s</b><br/>exact matches only: <b>%s</b>" % \
( self.__stringify( tool_ids ), self.__stringify( tool_names ), self.__stringify( tool_versions ), str( exact_matches_checked ) )
+ self.matched_repository_list_grid.title = "Repositories with matching tools"
return self.matched_repository_list_grid( trans, **kwd )
else:
message = "No search performed - each field must contain the same number of comma-separated items."
@@ -452,62 +532,76 @@
exact_matches_check_box=exact_matches_check_box,
message=message,
status=status )
- def __search_repository_metadata( self, trans, tool_ids, tool_names, tool_versions, exact_matches_checked ):
+ def __search_repository_metadata( self, trans, exact_matches_checked, tool_ids='', tool_names='', tool_versions='', workflow_names='' ):
match_tuples = []
ok = True
for repository_metadata in trans.sa_session.query( model.RepositoryMetadata ):
metadata = repository_metadata.metadata
- if 'tools' in metadata:
- tools = metadata[ 'tools' ]
- else:
- tools = []
- for tool_dict in tools:
- if tool_ids and not tool_names and not tool_versions:
- for tool_id in tool_ids:
- if self.__in_tool_dict( tool_dict, exact_matches_checked, tool_id=tool_id ):
+ if tool_ids or tool_names or tool_versions:
+ if 'tools' in metadata:
+ tools = metadata[ 'tools' ]
+ else:
+ tools = []
+ for tool_dict in tools:
+ if tool_ids and not tool_names and not tool_versions:
+ for tool_id in tool_ids:
+ if self.__in_tool_dict( tool_dict, exact_matches_checked, tool_id=tool_id ):
+ match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) )
+ elif tool_names and not tool_ids and not tool_versions:
+ for tool_name in tool_names:
+ if self.__in_tool_dict( tool_dict, exact_matches_checked, tool_name=tool_name ):
+ match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) )
+ elif tool_versions and not tool_ids and not tool_names:
+ for tool_version in tool_versions:
+ if self.__in_tool_dict( tool_dict, exact_matches_checked, tool_version=tool_version ):
+ match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) )
+ elif tool_ids and tool_names and not tool_versions:
+ if len( tool_ids ) == len( tool_names ):
+ match_tuples = self.__search_ids_names( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_ids, tool_names )
+ elif len( tool_ids ) == 1 or len( tool_names ) == 1:
+ tool_ids, tool_names = self.__make_same_length( tool_ids, tool_names )
+ match_tuples = self.__search_ids_names( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_ids, tool_names )
+ else:
+ ok = False
+ elif tool_ids and tool_versions and not tool_names:
+ if len( tool_ids ) == len( tool_versions ):
+ match_tuples = self.__search_ids_versions( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_ids, tool_versions )
+ elif len( tool_ids ) == 1 or len( tool_versions ) == 1:
+ tool_ids, tool_versions = self.__make_same_length( tool_ids, tool_versions )
+ match_tuples = self.__search_ids_versions( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_ids, tool_versions )
+ else:
+ ok = False
+ elif tool_versions and tool_names and not tool_ids:
+ if len( tool_versions ) == len( tool_names ):
+ match_tuples = self.__search_names_versions( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_names, tool_versions )
+ elif len( tool_versions ) == 1 or len( tool_names ) == 1:
+ tool_versions, tool_names = self.__make_same_length( tool_versions, tool_names )
+ match_tuples = self.__search_names_versions( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_names, tool_versions )
+ else:
+ ok = False
+ elif tool_versions and tool_names and tool_ids:
+ if len( tool_versions ) == len( tool_names ) and len( tool_names ) == len( tool_ids ):
+ for i, tool_version in enumerate( tool_versions ):
+ tool_name = tool_names[ i ]
+ tool_id = tool_ids[ i ]
+ if self.__in_tool_dict( tool_dict, exact_matches_checked, tool_id=tool_id, tool_name=tool_name, tool_version=tool_version ):
+ match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) )
+ else:
+ ok = False
+ if 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 ):
match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) )
- elif tool_names and not tool_ids and not tool_versions:
- for tool_name in tool_names:
- if self.__in_tool_dict( tool_dict, exact_matches_checked, tool_name=tool_name ):
- match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) )
- elif tool_versions and not tool_ids and not tool_names:
- for tool_version in tool_versions:
- if self.__in_tool_dict( tool_dict, exact_matches_checked, tool_version=tool_version ):
- match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) )
- elif tool_ids and tool_names and not tool_versions:
- if len( tool_ids ) == len( tool_names ):
- match_tuples = self.__search_ids_names( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_ids, tool_names )
- elif len( tool_ids ) == 1 or len( tool_names ) == 1:
- tool_ids, tool_names = self.__make_same_length( tool_ids, tool_names )
- match_tuples = self.__search_ids_names( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_ids, tool_names )
- else:
- ok = False
- elif tool_ids and tool_versions and not tool_names:
- if len( tool_ids ) == len( tool_versions ):
- match_tuples = self.__search_ids_versions( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_ids, tool_versions )
- elif len( tool_ids ) == 1 or len( tool_versions ) == 1:
- tool_ids, tool_versions = self.__make_same_length( tool_ids, tool_versions )
- match_tuples = self.__search_ids_versions( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_ids, tool_versions )
- else:
- ok = False
- elif tool_versions and tool_names and not tool_ids:
- if len( tool_versions ) == len( tool_names ):
- match_tuples = self.__search_names_versions( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_names, tool_versions )
- elif len( tool_versions ) == 1 or len( tool_names ) == 1:
- tool_versions, tool_names = self.__make_same_length( tool_versions, tool_names )
- match_tuples = self.__search_names_versions( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_names, tool_versions )
- else:
- ok = False
- elif tool_versions and tool_names and tool_ids:
- if len( tool_versions ) == len( tool_names ) and len( tool_names ) == len( tool_ids ):
- for i, tool_version in enumerate( tool_versions ):
- tool_name = tool_names[ i ]
- tool_id = tool_ids[ i ]
- if self.__in_tool_dict( tool_dict, exact_matches_checked, tool_id=tool_id, tool_name=tool_name, tool_version=tool_version ):
- match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) )
- else:
- ok = False
return ok, match_tuples
+ def __in_workflow_dict( self, workflow_dict, exact_matches_checked, workflow_name=None ):
+ 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 )
def __in_tool_dict( self, tool_dict, exact_matches_checked, tool_id=None, tool_name=None, tool_version=None ):
found = False
if tool_id and not tool_name and not tool_version:
diff -r 216d4f09480468bb01ee56df9a393c5b740fe51d -r c528fab7ea8c89ab55cb9977d5916c72e5170546 templates/grid_base.mako
--- a/templates/grid_base.mako
+++ b/templates/grid_base.mako
@@ -744,7 +744,7 @@
%if grid.global_actions:
<ul class="manage-table-actions">
- %if len( grid.global_actions ) < 4:
+ %if len( grid.global_actions ) < 3:
%for action in grid.global_actions:
<li><a class="action-button" href="${h.url_for( **action.url_args )}">${action.label}</a></li>
%endfor
diff -r 216d4f09480468bb01ee56df9a393c5b740fe51d -r c528fab7ea8c89ab55cb9977d5916c72e5170546 templates/webapps/community/index.mako
--- a/templates/webapps/community/index.mako
+++ b/templates/webapps/community/index.mako
@@ -44,6 +44,20 @@
<div class="page-container" style="padding: 10px;"><div class="toolMenu"><div class="toolSectionList">
+ %if repository_metadata:
+ <div class="toolSectionPad"></div>
+ <div class="toolSectionTitle">
+ Search
+ </div>
+ <div class="toolSectionBody">
+ <div class="toolTitle">
+ <a target="galaxy_main" href="${h.url_for( controller='repository', action='find_tools', webapp='community' )}">Search for valid tools</a>
+ </div>
+ <div class="toolTitle">
+ <a target="galaxy_main" href="${h.url_for( controller='repository', action='find_workflows', webapp='community' )}">Search for workflows</a>
+ </div>
+ </div>
+ %endif
<div class="toolSectionPad"></div><div class="toolSectionTitle">
Repositories
@@ -61,11 +75,6 @@
<a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories', operation='my_repositories', webapp='community' )}">Browse my repositories</a></div>
%endif
- %if repository_metadata:
- <div class="toolTitle">
- <a target="galaxy_main" href="${h.url_for( controller='repository', action='find_tools', webapp='community' )}">Search for valid tools</a>
- </div>
- %endif
</div></div><div class="toolSectionBody">
diff -r 216d4f09480468bb01ee56df9a393c5b740fe51d -r c528fab7ea8c89ab55cb9977d5916c72e5170546 templates/webapps/community/repository/find_tools.mako
--- a/templates/webapps/community/repository/find_tools.mako
+++ b/templates/webapps/community/repository/find_tools.mako
@@ -14,6 +14,7 @@
<br/><br/><ul class="manage-table-actions"><li><a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a></li>
+ <li><a class="action-button" href="${h.url_for( controller='repository', action='find_workflows', webapp=webapp )}">Search for workflows</a></li></ul>
%endif
diff -r 216d4f09480468bb01ee56df9a393c5b740fe51d -r c528fab7ea8c89ab55cb9977d5916c72e5170546 templates/webapps/community/repository/find_workflows.mako
--- /dev/null
+++ b/templates/webapps/community/repository/find_workflows.mako
@@ -0,0 +1,53 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+<%!
+ def inherit(context):
+ if context.get('use_panels'):
+ return '/webapps/community/base_panels.mako'
+ else:
+ return '/base.mako'
+%>
+<%inherit file="${inherit(context)}"/>
+
+%if webapp == 'galaxy':
+ <br/><br/>
+ <ul class="manage-table-actions">
+ <li><a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a></li>
+ <a class="action-button" href="${h.url_for( controller='repository', action='find_tools', webapp=webapp )}">Search for valid tools</a>
+ </ul>
+%endif
+
+%if message:
+ ${render_msg( message, status )}
+%endif
+
+<div class="toolForm">
+ <div class="toolFormTitle">Search repositories for workflows</div>
+ <div class="toolFormBody">
+ <div class="form-row">
+ Enter a workflow name to find repositories that contain workflows matching the search criteria.<br/><br/>
+ Comma-separated strings may be entered to expand search criteria.
+ </div>
+ <div style="clear: both"></div>
+ <form name="find_workflows" id="find_workflows" action="${h.url_for( controller='repository', action='find_workflows', webapp=webapp )}" method="post" >
+ <div style="clear: both"></div>
+ <div class="form-row">
+ <label>Workflow name:</label>
+ <input name="workflow_name" type="textfield" value="${workflow_name}" size="40"/>
+ </div>
+ <div style="clear: both"></div>
+ <div class="form-row">
+ <label>Exact matches only:</label>
+ ${exact_matches_check_box.get_html()}
+ <div class="toolParamHelp" style="clear: both;">
+ Check the box to match text exactly (text case doesn't matter as all strings are forced to lower case).
+ </div>
+ </div>
+ <div style="clear: both"></div>
+ <div class="form-row">
+ <input type="submit" value="Search repositories"/>
+ </div>
+ </form>
+ </div>
+</div>
diff -r 216d4f09480468bb01ee56df9a393c5b740fe51d -r c528fab7ea8c89ab55cb9977d5916c72e5170546 templates/webapps/community/repository/preview_tools_in_changeset.mako
--- a/templates/webapps/community/repository/preview_tools_in_changeset.mako
+++ b/templates/webapps/community/repository/preview_tools_in_changeset.mako
@@ -69,6 +69,7 @@
<div popupmenu="repository-${repository.id}-popup"><a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a><a class="action-button" href="${h.url_for( controller='repository', action='find_tools', webapp=webapp )}">Search for valid tools</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='find_workflows', webapp=webapp )}">Search for workflows</a></div></ul>
diff -r 216d4f09480468bb01ee56df9a393c5b740fe51d -r c528fab7ea8c89ab55cb9977d5916c72e5170546 templates/webapps/community/repository/tool_form.mako
--- a/templates/webapps/community/repository/tool_form.mako
+++ b/templates/webapps/community/repository/tool_form.mako
@@ -116,6 +116,7 @@
<div popupmenu="repository-${repository.id}-popup"><a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a><a class="action-button" href="${h.url_for( controller='repository', action='find_tools', webapp=webapp )}">Search for valid tools</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='find_workflows', webapp=webapp )}">Search for workflows</a></div>
%else:
%if is_new:
diff -r 216d4f09480468bb01ee56df9a393c5b740fe51d -r c528fab7ea8c89ab55cb9977d5916c72e5170546 templates/webapps/community/repository/view_repository.mako
--- a/templates/webapps/community/repository/view_repository.mako
+++ b/templates/webapps/community/repository/view_repository.mako
@@ -99,6 +99,7 @@
<div popupmenu="repository-${repository.id}-popup"><a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a><a class="action-button" href="${h.url_for( controller='repository', action='find_tools', webapp=webapp )}">Search for valid tools</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='find_workflows', webapp=webapp )}">Search for workflows</a></div>
%endif
</ul>
diff -r 216d4f09480468bb01ee56df9a393c5b740fe51d -r c528fab7ea8c89ab55cb9977d5916c72e5170546 templates/webapps/community/repository/view_tool_metadata.mako
--- a/templates/webapps/community/repository/view_tool_metadata.mako
+++ b/templates/webapps/community/repository/view_tool_metadata.mako
@@ -39,6 +39,7 @@
<div popupmenu="repository-${repository.id}-popup"><a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a><a class="action-button" href="${h.url_for( controller='repository', action='find_tools', webapp=webapp )}">Search for valid tools</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='find_workflows', webapp=webapp )}">Search for workflows</a></div>
%else:
%if is_new:
diff -r 216d4f09480468bb01ee56df9a393c5b740fe51d -r c528fab7ea8c89ab55cb9977d5916c72e5170546 templates/webapps/community/repository/view_workflow.mako
--- a/templates/webapps/community/repository/view_workflow.mako
+++ b/templates/webapps/community/repository/view_workflow.mako
@@ -84,6 +84,7 @@
<div popupmenu="toolshed-${repository.id}-popup"><a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a><a class="action-button" href="${h.url_for( controller='repository', action='find_tools', webapp=webapp )}">Search for valid tools</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='find_workflows', webapp=webapp )}">Search for workflows</a></div>
%endif
</ul>
@@ -92,10 +93,12 @@
${render_msg( message, status )}
%endif
-<br/>
-<b>Boxes are red when tools are not available in this repository</b>
-<div class="toolParamHelp" style="clear: both;">
- (this page displays SVG graphics)
+<div class="toolFormTitle">${workflow_name}</div>
+<div class="form-row">
+ <b>Boxes are red when tools are not available in this repository</b>
+ <div class="toolParamHelp" style="clear: both;">
+ (this page displays SVG graphics)
+ </div></div><br clear="left"/>
diff -r 216d4f09480468bb01ee56df9a393c5b740fe51d -r c528fab7ea8c89ab55cb9977d5916c72e5170546 templates/webapps/galaxy/admin/index.mako
--- a/templates/webapps/galaxy/admin/index.mako
+++ b/templates/webapps/galaxy/admin/index.mako
@@ -73,7 +73,7 @@
<div class="toolSectionTitle">Tool sheds</div><div class="toolSectionBody"><div class="toolSectionBg">
- <div class="toolTitle"><a href="${h.url_for( controller='admin', action='browse_tool_sheds' )}" target="galaxy_main">Browse tool sheds</a></div>
+ <div class="toolTitle"><a href="${h.url_for( controller='admin', action='browse_tool_sheds' )}" target="galaxy_main">Search and browse tool sheds</a></div></div></div>
%endif
diff -r 216d4f09480468bb01ee56df9a393c5b740fe51d -r c528fab7ea8c89ab55cb9977d5916c72e5170546 templates/webapps/galaxy/admin/tool_sheds.mako
--- a/templates/webapps/galaxy/admin/tool_sheds.mako
+++ b/templates/webapps/galaxy/admin/tool_sheds.mako
@@ -27,6 +27,7 @@
<div popupmenu="dataset-${shed_id}-popup"><a class="action-button" href="${h.url_for( controller='admin', action='browse_tool_shed', tool_shed_url=url )}">Browse valid repositories</a><a class="action-button" href="${h.url_for( controller='admin', action='find_tools_in_tool_shed', tool_shed_url=url )}">Search for valid tools</a>
+ <a class="action-button" href="${h.url_for( controller='admin', action='find_workflows_in_tool_shed', tool_shed_url=url )}">Search for workflows</a></div></td></tr>
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: Have Picard MergeSamFiles use return code to determine tool error.
by Bitbucket 27 Oct '11
by Bitbucket 27 Oct '11
27 Oct '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/216d4f094804/
changeset: 216d4f094804
user: dan
date: 2011-10-27 16:54:42
summary: Have Picard MergeSamFiles use return code to determine tool error.
affected #: 1 file
diff -r 0ba260ea43c4e9613965e9f32705a118bab7c3ec -r 216d4f09480468bb01ee56df9a393c5b740fe51d tools/samtools/sam_merge.xml
--- a/tools/samtools/sam_merge.xml
+++ b/tools/samtools/sam_merge.xml
@@ -9,6 +9,7 @@
I=${i.input}
#end for
2> $outlog
+ || echo "Error running Picard MergeSamFiles" >&2
</command><inputs><param name="title" label="Name for the output merged bam file" type="text" default="Merged.bam"
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/0ba260ea43c4/
changeset: 0ba260ea43c4
user: greg
date: 2011-10-26 22:11:49
summary: Add the ability to view workflows contained in a tool shed repository as svg images. Add the ability to import a specific workflow from a Galaxy tool shed repository to a loacl Galaxy instance. Fix bugs when displaying or running a workflow that requires tools that use the old Galaxy tool id, but the local Galaxy instance uses tools installed from a tool shed.
affected #: 17 files
diff -r 37fb9b1fb62de6a304c6c500d9610b7eea2cf2aa -r 0ba260ea43c4e9613965e9f32705a118bab7c3ec lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -1,10 +1,11 @@
"""
Contains functionality needed in every web interface
"""
-import os, time, logging, re, string, sys, glob, shutil, tempfile, subprocess
+import os, time, logging, re, string, sys, glob, shutil, tempfile, subprocess, binascii
from datetime import date, datetime, timedelta
from time import strftime
from galaxy import config, tools, web, util
+from galaxy.util.hash_util import *
from galaxy.web import error, form, url_for
from galaxy.model.orm import *
from galaxy.workflow.modules import *
@@ -2484,3 +2485,32 @@
message = "The required file named tool_data_table_conf.xml does not exist in the Galaxy install directory."
error = True
return error, message
+def tool_shed_encode( val ):
+ if isinstance( val, dict ):
+ value = simplejson.dumps( val )
+ else:
+ value = val
+ a = hmac_new( 'ToolShedAndGalaxyMustHaveThisSameKey', value )
+ b = binascii.hexlify( value )
+ return "%s:%s" % ( a, b )
+def tool_shed_decode( value ):
+ # Extract and verify hash
+ a, b = value.split( ":" )
+ value = binascii.unhexlify( b )
+ test = hmac_new( 'ToolShedAndGalaxyMustHaveThisSameKey', value )
+ assert a == test
+ # Restore from string
+ values = None
+ try:
+ values = simplejson.loads( value )
+ except Exception, e:
+ log.debug( "Decoding json value from tool shed threw exception: %s" % str( e ) )
+ if values is not None:
+ try:
+ return json_fix( values )
+ except Exception, e:
+ log.debug( "Fixing decoded json value from tool shed threw exception: %s" % str( e ) )
+ fixed_values = values
+ if values is None:
+ values = value
+ return values
diff -r 37fb9b1fb62de6a304c6c500d9610b7eea2cf2aa -r 0ba260ea43c4e9613965e9f32705a118bab7c3ec lib/galaxy/web/controllers/admin.py
--- a/lib/galaxy/web/controllers/admin.py
+++ b/lib/galaxy/web/controllers/admin.py
@@ -4,8 +4,7 @@
from galaxy.web.framework.helpers import time_ago, iff, grids
from galaxy.tools.search import ToolBoxSearch
from galaxy.tools import json_fix
-from galaxy.util.hash_util import *
-import simplejson, binascii, logging
+import logging
log = logging.getLogger( __name__ )
from galaxy.actions.admin import AdminActions
@@ -736,7 +735,7 @@
section_key = 'section_%s' % kwd[ 'tool_panel_section' ]
tool_section = trans.app.toolbox.tool_panel[ section_key ]
# Decode the encoded repo_info_dict param value.
- repo_info_dict = self.__decode( repo_info_dict )
+ repo_info_dict = tool_shed_decode( repo_info_dict )
# Clone the repository to the configured location.
current_working_dir = os.getcwd()
for name, repo_info_tuple in repo_info_dict.items():
@@ -1157,15 +1156,6 @@
section_str += ' </tool>\n'
section_str += ' </section>\n'
return section_str
- def __decode( self, value ):
- # Extract and verify hash
- a, b = value.split( ":" )
- value = binascii.unhexlify( b )
- test = hmac_new( 'ToolShedAndGalaxyMustHaveThisSameKey', value )
- assert a == test
- # Restore from string
- values = json_fix( simplejson.loads( value ) )
- return values
## ---- Utility methods -------------------------------------------------------
diff -r 37fb9b1fb62de6a304c6c500d9610b7eea2cf2aa -r 0ba260ea43c4e9613965e9f32705a118bab7c3ec lib/galaxy/web/controllers/workflow.py
--- a/lib/galaxy/web/controllers/workflow.py
+++ b/lib/galaxy/web/controllers/workflow.py
@@ -4,7 +4,7 @@
pkg_resources.require( "simplejson" )
pkg_resources.require( "SVGFig" )
import simplejson
-import base64, httplib, urllib2, sgmllib, svgfig
+import base64, httplib, urllib2, sgmllib, svgfig, urllib, urllib2
import math
from galaxy.web.framework.helpers import time_ago, grids
from galaxy.tools.parameters import *
@@ -1092,13 +1092,35 @@
trans.response.headers["Content-Disposition"] = "attachment; filename=Galaxy-Workflow-%s.ga" % ( sname )
trans.response.set_content_type( 'application/galaxy-archive' )
return stored_dict
-
@web.expose
def import_workflow( self, trans, **kwd ):
+ """
+ Import a workflow by reading an url, uploading a file, or receiving the textual
+ representation of a workflow.
+ """
url = kwd.get( 'url', '' )
+ workflow_text = kwd.get( 'workflow_text', '' )
+ webapp = kwd.get( 'webapp', 'galaxy' )
message = kwd.get( 'message', '' )
status = kwd.get( 'status', 'done' )
- if kwd.get( 'import_button', False ):
+ import_button = kwd.get( 'import_button', False )
+ tool_shed_url = kwd.get( 'tool_shed_url', '' )
+ repository_metadata_id = kwd.get( 'repository_metadata_id', '' )
+ # The workflow_name parameter is in the request only if the import originated
+ # from a Galaxy tool shed, in which case the value was encoded.
+ workflow_name = kwd.get( 'workflow_name', '' )
+ if workflow_name:
+ workflow_name = tool_shed_decode( workflow_name )
+ if tool_shed_url and not import_button:
+ # Use urllib (send another request to the tool shed) to retrieve the workflow.
+ workflow_url = 'http://%s/workflow/import_workflow?repository_metadata_id=%s&workflow_name=%s&webapp=%s&open_for_url=true' % \
+ ( tool_shed_url, repository_metadata_id, tool_shed_encode( workflow_name ), webapp )
+ response = urllib2.urlopen( workflow_url )
+ workflow_text = response.read()
+ response.close()
+ workflow_text = workflow_text
+ import_button = True
+ if import_button:
workflow_data = None
if url:
# Load workflow from external URL
@@ -1108,6 +1130,8 @@
except Exception, e:
message = "Failed to open URL: <b>%s</b><br>Exception: %s" % ( url, str( e ) )
status = 'error'
+ elif workflow_text:
+ workflow_data = workflow_text
else:
# Load workflow from browsed file.
file_data = kwd.get( 'file_data', '' )
@@ -1175,6 +1199,13 @@
else:
# TODO: Figure out what to do here...
pass
+ if tool_shed_url:
+ # We've received the textual representation of a workflow from a Galaxy tool shed.
+ message = "This workflow has been successfully imported into your local Galaxy instance."
+ # TODO: support https in the following url.
+ 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 )
return self.list( trans )
return trans.fill_template( "workflow/import.mako",
url=url,
diff -r 37fb9b1fb62de6a304c6c500d9610b7eea2cf2aa -r 0ba260ea43c4e9613965e9f32705a118bab7c3ec lib/galaxy/webapps/community/app.py
--- a/lib/galaxy/webapps/community/app.py
+++ b/lib/galaxy/webapps/community/app.py
@@ -35,6 +35,8 @@
self.tag_handler = CommunityTagHandler()
# Tool data tables
self.tool_data_tables = galaxy.tools.data.ToolDataTableManager( self.config.tool_data_table_config_path )
+ # The tool shed has no toolbox, but this attribute is still required.
+ self.toolbox = None
# Load security policy
self.security_agent = self.model.security_agent
self.quota_agent = galaxy.quota.NoQuotaAgent( self.model )
diff -r 37fb9b1fb62de6a304c6c500d9610b7eea2cf2aa -r 0ba260ea43c4e9613965e9f32705a118bab7c3ec lib/galaxy/webapps/community/controllers/admin.py
--- a/lib/galaxy/webapps/community/controllers/admin.py
+++ b/lib/galaxy/webapps/community/controllers/admin.py
@@ -332,13 +332,13 @@
if 'tools' in metadata:
metadata_str += '<b>Tools:</b><br/>'
for tool_metadata_dict in metadata[ 'tools' ]:
- metadata_str += '%s <b>%s</b><br/>' % \
- ( tool_metadata_dict[ 'id' ], tool_metadata_dict[ 'version' ] )
+ metadata_str += '%s <b>%s</b><br/>' % ( tool_metadata_dict[ 'id' ],
+ tool_metadata_dict[ 'version' ] )
if 'workflows' in metadata:
metadata_str += '<b>Workflows:</b><br/>'
for workflow_metadata_dict in metadata[ 'workflows' ]:
- metadata_str += '%s <b>%s</b><br/>' % \
- ( workflow_metadata_dict[ 'name' ], workflow_metadata_dict[ 'format-version' ] )
+ metadata_str += '%s <b>%s</b><br/>' % ( workflow_metadata_dict[ 'name' ],
+ workflow_metadata_dict[ 'format-version' ] )
return metadata_str
class MaliciousColumn( grids.BooleanColumn ):
def get_value( self, trans, grid, repository_metadata ):
diff -r 37fb9b1fb62de6a304c6c500d9610b7eea2cf2aa -r 0ba260ea43c4e9613965e9f32705a118bab7c3ec lib/galaxy/webapps/community/controllers/common.py
--- a/lib/galaxy/webapps/community/controllers/common.py
+++ b/lib/galaxy/webapps/community/controllers/common.py
@@ -1,8 +1,9 @@
-import os, string, socket, logging
+import os, string, socket, logging, simplejson, binascii
from time import strftime
from datetime import *
from galaxy.tools import *
from galaxy.util.json import from_json_string, to_json_string
+from galaxy.util.hash_util import *
from galaxy.web.base.controller import *
from galaxy.webapps.community import model
from galaxy.model.orm import *
@@ -126,23 +127,18 @@
def generate_workflow_metadata( trans, id, changeset_revision, exported_workflow_dict, metadata_dict ):
"""
Update the received metadata_dict with changes that have been applied
- to the received exported_workflow_dict. Store everything except the
- workflow steps in the database.
+ to the received exported_workflow_dict. Store everything in the database.
"""
- workflow_dict = { 'a_galaxy_workflow' : exported_workflow_dict[ 'a_galaxy_workflow' ],
- 'name' :exported_workflow_dict[ 'name' ],
- 'annotation' : exported_workflow_dict[ 'annotation' ],
- 'format-version' : exported_workflow_dict[ 'format-version' ] }
if 'workflows' in metadata_dict:
- metadata_dict[ 'workflows' ].append( workflow_dict )
+ metadata_dict[ 'workflows' ].append( exported_workflow_dict )
else:
- metadata_dict[ 'workflows' ] = [ workflow_dict ]
+ metadata_dict[ 'workflows' ] = [ exported_workflow_dict ]
return metadata_dict
def new_workflow_metadata_required( trans, id, metadata_dict ):
"""
- TODO: Currently everything about an exported workflow except the name is hard-coded, so
- there's no real way to differentiate versions of exported workflows. If this changes at
- some future time, this method should be enhanced accordingly...
+ Currently everything about an exported workflow except the name is hard-coded, so there's
+ no real way to differentiate versions of exported workflows. If this changes at some future
+ time, this method should be enhanced accordingly.
"""
if 'workflows' in metadata_dict:
repository_metadata = get_latest_repository_metadata( trans, id )
@@ -425,18 +421,20 @@
trans.sa_session.add( repository_metadata )
trans.sa_session.flush()
else:
- message = "Change set revision '%s' includes no tools or exported workflows for which metadata can be set." % str( changeset_revision )
+ message = "Revision '%s' includes no tools or exported workflows for which metadata can be defined " % str( changeset_revision )
+ message += "so this revision cannot be automatically installed into a local Galaxy instance."
status = "error"
else:
# change_set is None
- message = "Repository does not include change set revision '%s'." % str( changeset_revision )
+ message = "This repository does not include revision '%s'." % str( changeset_revision )
status = 'error'
if invalid_files:
if metadata_dict:
- message = "Metadata was defined for some items in change set revision '%s'. " % str( changeset_revision )
+ message = "Metadata was defined for some items in revision '%s'. " % str( changeset_revision )
message += "Correct the following problems if necessary and reset metadata.<br/>"
else:
- message = "Metadata cannot be defined for change set revision '%s'. Correct the following problems and reset metadata.<br/>" % str( changeset_revision )
+ message = "Metadata cannot be defined for revision '%s' so this revision cannot be automatically " % str( changeset_revision )
+ message += "installed into a local Galaxy instance. Correct the following problems and reset metadata.<br/>"
for itc_tup in invalid_files:
tool_file, exception_msg = itc_tup
if exception_msg.find( 'No such file or directory' ) >= 0:
@@ -619,3 +617,24 @@
selected = selected_value and option_tup[1] == selected_value
select_field.add_option( option_tup[0], option_tup[1], selected=selected )
return select_field
+def encode( val ):
+ if isinstance( val, dict ):
+ value = simplejson.dumps( val )
+ else:
+ value = val
+ a = hmac_new( 'ToolShedAndGalaxyMustHaveThisSameKey', value )
+ b = binascii.hexlify( value )
+ return "%s:%s" % ( a, b )
+def decode( value ):
+ # Extract and verify hash
+ a, b = value.split( ":" )
+ value = binascii.unhexlify( b )
+ test = hmac_new( 'ToolShedAndGalaxyMustHaveThisSameKey', value )
+ assert a == test
+ # Restore from string
+ try:
+ values = json_fix( simplejson.loads( value ) )
+ except Exception, e:
+ # We do not have a json string
+ values = value
+ return values
diff -r 37fb9b1fb62de6a304c6c500d9610b7eea2cf2aa -r 0ba260ea43c4e9613965e9f32705a118bab7c3ec lib/galaxy/webapps/community/controllers/repository.py
--- a/lib/galaxy/webapps/community/controllers/repository.py
+++ b/lib/galaxy/webapps/community/controllers/repository.py
@@ -9,7 +9,6 @@
from galaxy.webapps.community.model import directory_hash_id
from galaxy.web.framework.helpers import time_ago, iff, grids
from galaxy.util.json import from_json_string, to_json_string
-from galaxy.util.hash_util import *
from galaxy.model.orm import *
from common import *
from mercurial import hg, ui, patch, commands
@@ -458,7 +457,10 @@
ok = True
for repository_metadata in trans.sa_session.query( model.RepositoryMetadata ):
metadata = repository_metadata.metadata
- tools = metadata[ 'tools' ]
+ if 'tools' in metadata:
+ tools = metadata[ 'tools' ]
+ else:
+ tools = []
for tool_dict in tools:
if tool_ids and not tool_names and not tool_versions:
for tool_id in tool_ids:
@@ -588,15 +590,7 @@
changeset_revision = repository_metadata.changeset_revision
repository_clone_url = generate_clone_url( trans, repository_id )
repo_info_dict[ repository.name ] = ( repository.description, repository_clone_url, changeset_revision )
- return self.__encode( repo_info_dict )
- def __encode( self, val ):
- if isinstance( val, dict ):
- value = simplejson.dumps( val )
- else:
- value = val
- a = hmac_new( 'ToolShedAndGalaxyMustHaveThisSameKey', value )
- b = binascii.hexlify( value )
- return "%s:%s" % ( a, b )
+ return encode( repo_info_dict )
@web.expose
def preview_tools_in_changeset( self, trans, repository_id, **kwd ):
params = util.Params( kwd )
@@ -607,8 +601,10 @@
changeset_revision = util.restore_text( params.get( 'changeset_revision', repository.tip ) )
repository_metadata = get_repository_metadata_by_changeset_revision( trans, repository_id, changeset_revision )
if repository_metadata:
+ repository_metadata_id = trans.security.encode_id( repository_metadata.id ),
metadata = repository_metadata.metadata
else:
+ repository_metadata_id = None
metadata = None
revision_label = get_revision_label( trans, repository, changeset_revision )
changeset_revision_select_field = build_changeset_revision_select_field( trans,
@@ -617,6 +613,7 @@
add_id_to_name=False )
return trans.fill_template( '/webapps/community/repository/preview_tools_in_changeset.mako',
repository=repository,
+ repository_metadata_id=repository_metadata_id,
changeset_revision=changeset_revision,
revision_label=revision_label,
changeset_revision_select_field=changeset_revision_select_field,
@@ -636,7 +633,7 @@
changeset_revision = util.restore_text( params.get( 'changeset_revision', repository.tip ) )
repo_info_dict = {}
repo_info_dict[ repository.name ] = ( repository.description, repository_clone_url, changeset_revision )
- encoded_repo_info_dict = self.__encode( repo_info_dict )
+ encoded_repo_info_dict = encode( repo_info_dict )
# Redirect back to local Galaxy to perform install.
# TODO: support https in the following url.
url = 'http://%s/admin/install_tool_shed_repository?tool_shed_url=%s&repo_info_dict=%s' % \
@@ -1159,8 +1156,10 @@
revision_label = get_revision_label( trans, repository, changeset_revision )
repository_metadata = get_repository_metadata_by_changeset_revision( trans, id, changeset_revision )
if repository_metadata:
+ repository_metadata_id = trans.security.encode_id( repository_metadata.id ),
metadata = repository_metadata.metadata
else:
+ repository_metadata_id = None
metadata = None
is_malicious = change_set_is_malicious( trans, id, repository.tip )
if is_malicious:
@@ -1172,6 +1171,7 @@
return trans.fill_template( '/webapps/community/repository/view_repository.mako',
repo=repo,
repository=repository,
+ repository_metadata_id=repository_metadata_id,
metadata=metadata,
avg_rating=avg_rating,
display_reviews=display_reviews,
@@ -1299,9 +1299,11 @@
revision_label = get_revision_label( trans, repository, changeset_revision )
repository_metadata = get_repository_metadata_by_changeset_revision( trans, id, changeset_revision )
if repository_metadata:
+ repository_metadata_id = trans.security.encode_id( repository_metadata.id )
metadata = repository_metadata.metadata
is_malicious = repository_metadata.malicious
else:
+ repository_metadata_id = None
metadata = None
is_malicious = False
if is_malicious:
@@ -1321,6 +1323,7 @@
allow_push_select_field=allow_push_select_field,
repo=repo,
repository=repository,
+ repository_metadata_id=repository_metadata_id,
changeset_revision=changeset_revision,
changeset_revision_select_field=changeset_revision_select_field,
revision_label=revision_label,
diff -r 37fb9b1fb62de6a304c6c500d9610b7eea2cf2aa -r 0ba260ea43c4e9613965e9f32705a118bab7c3ec lib/galaxy/webapps/community/controllers/workflow.py
--- /dev/null
+++ b/lib/galaxy/webapps/community/controllers/workflow.py
@@ -0,0 +1,395 @@
+import pkg_resources
+pkg_resources.require( "simplejson" )
+pkg_resources.require( "SVGFig" )
+import os, logging, ConfigParser, tempfile, shutil, svgfig
+from galaxy.webapps.community import model
+from galaxy.web.framework.helpers import time_ago, iff, grids
+from galaxy.util.json import from_json_string, to_json_string
+from galaxy.workflow.modules import InputDataModule, ToolModule, WorkflowModuleFactory
+from galaxy.tools import DefaultToolState
+from galaxy.web.controllers.workflow import attach_ordered_steps
+from galaxy.model.orm import *
+from common import *
+
+class RepoInputDataModule( InputDataModule ):
+
+ type = "data_input"
+ name = "Input dataset"
+
+ @classmethod
+ def new( Class, trans, tools_metadata=None, tool_id=None ):
+ module = Class( trans )
+ module.state = dict( name="Input Dataset" )
+ return module
+ @classmethod
+ def from_dict( Class, trans, d, tools_metadata=None, secure=True ):
+ module = Class( trans )
+ state = from_json_string( d[ "tool_state" ] )
+ module.state = dict( name=state.get( "name", "Input Dataset" ) )
+ return module
+ @classmethod
+ def from_workflow_step( Class, trans, tools_metadata, step ):
+ module = Class( trans )
+ module.state = dict( name="Input Dataset" )
+ if step.tool_inputs and "name" in step.tool_inputs:
+ module.state[ 'name' ] = step.tool_inputs[ 'name' ]
+ return module
+
+class RepoToolModule( ToolModule ):
+
+ type = "tool"
+
+ def __init__( self, trans, tools_metadata, tool_id ):
+ self.trans = trans
+ self.tools_metadata = tools_metadata
+ self.tool_id = tool_id
+ self.tool = None
+ for tool_dict in tools_metadata:
+ if self.tool_id in [ tool_dict[ 'id' ], tool_dict[ 'guid' ] ]:
+ self.tool = load_tool( trans, os.path.abspath( tool_dict[ 'tool_config' ] ) )
+ self.post_job_actions = {}
+ self.workflow_outputs = []
+ self.state = None
+ self.errors = None
+ @classmethod
+ def new( Class, trans, tools_metadata, tool_id=None ):
+ module = Class( trans, tools_metadata, tool_id )
+ module.state = module.tool.new_state( trans, all_pages=True )
+ return module
+ @classmethod
+ def from_dict( Class, trans, d, tools_metadata, secure=True ):
+ tool_id = d[ 'tool_id' ]
+ module = Class( trans, tools_metadata, tool_id )
+ module.state = DefaultToolState()
+ if module.tool is not None:
+ module.state.decode( d[ "tool_state" ], module.tool, module.trans.app, secure=secure )
+ module.errors = d.get( "tool_errors", None )
+ return module
+ @classmethod
+ def from_workflow_step( Class, trans, tools_metadata, step ):
+ module = Class( trans, tools_metadata, step.tool_id )
+ module.state = DefaultToolState()
+ if module.tool:
+ module.state.inputs = module.tool.params_from_strings( step.tool_inputs, trans.app, ignore_errors=True )
+ else:
+ module.state.inputs = {}
+ module.errors = step.tool_errors
+ return module
+ def get_data_inputs( self ):
+ data_inputs = []
+ def callback( input, value, prefixed_name, prefixed_label ):
+ if isinstance( input, DataToolParameter ):
+ data_inputs.append( dict( name=prefixed_name,
+ label=prefixed_label,
+ extensions=input.extensions ) )
+ if self.tool:
+ visit_input_values( self.tool.inputs, self.state.inputs, callback )
+ return data_inputs
+ def get_data_outputs( self ):
+ data_outputs = []
+ if self.tool:
+ data_inputs = None
+ for name, tool_output in self.tool.outputs.iteritems():
+ if tool_output.format_source != None:
+ # Default to special name "input" which remove restrictions on connections
+ formats = [ 'input' ]
+ if data_inputs == None:
+ data_inputs = self.get_data_inputs()
+ # Find the input parameter referenced by format_source
+ for di in data_inputs:
+ # Input names come prefixed with conditional and repeat names separated by '|',
+ # so remove prefixes when comparing with format_source.
+ if di[ 'name' ] != None and di[ 'name' ].split( '|' )[ -1 ] == tool_output.format_source:
+ formats = di[ 'extensions' ]
+ else:
+ formats = [ tool_output.format ]
+ for change_elem in tool_output.change_format:
+ for when_elem in change_elem.findall( 'when' ):
+ format = when_elem.get( 'format', None )
+ if format and format not in formats:
+ formats.append( format )
+ data_outputs.append( dict( name=name, extensions=formats ) )
+ return data_outputs
+
+class RepoWorkflowModuleFactory( WorkflowModuleFactory ):
+ def __init__( self, module_types ):
+ self.module_types = module_types
+ def new( self, trans, type, tools_metadata=None, tool_id=None ):
+ """Return module for type and (optional) tool_id intialized with new / default state."""
+ assert type in self.module_types
+ return self.module_types[type].new( trans, tool_id )
+ def from_dict( self, trans, d, **kwargs ):
+ """Return module initialized from the data in dictionary `d`."""
+ type = d[ 'type' ]
+ assert type in self.module_types
+ return self.module_types[ type ].from_dict( trans, d, **kwargs )
+ def from_workflow_step( self, trans, tools_metadata, step ):
+ """Return module initialized from the WorkflowStep object `step`."""
+ type = step.type
+ return self.module_types[ type ].from_workflow_step( trans, tools_metadata, step )
+
+module_factory = RepoWorkflowModuleFactory( dict( data_input=RepoInputDataModule, tool=RepoToolModule ) )
+
+class WorkflowController( BaseUIController ):
+ @web.expose
+ def view_workflow( self, trans, **kwd ):
+ repository_metadata_id = kwd.get( 'repository_metadata_id', '' )
+ workflow_name = kwd.get( 'workflow_name', '' )
+ if workflow_name:
+ workflow_name = decode( workflow_name )
+ webapp = kwd.get( 'webapp', 'community' )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ repository_metadata = get_repository_metadata_by_id( trans, repository_metadata_id )
+ repository = get_repository( trans, trans.security.encode_id( repository_metadata.repository_id ) )
+ return trans.fill_template( "/webapps/community/repository/view_workflow.mako",
+ repository=repository,
+ changeset_revision=repository_metadata.changeset_revision,
+ repository_metadata_id=repository_metadata_id,
+ workflow_name=workflow_name,
+ webapp=webapp,
+ message=message,
+ status=status )
+ @web.expose
+ def generate_workflow_image( self, trans, repository_metadata_id, workflow_name, webapp='community' ):
+ repository_metadata = get_repository_metadata_by_id( trans, repository_metadata_id )
+ metadata = repository_metadata.metadata
+ workflow_name = decode( workflow_name )
+ for workflow_dict in metadata[ 'workflows' ]:
+ if workflow_dict[ 'name' ] == workflow_name:
+ break
+ if 'tools' in metadata:
+ tools_metadata = metadata[ 'tools' ]
+ else:
+ tools_metadata = []
+ workflow, missing_tool_tups = self.__workflow_from_dict( trans, workflow_dict, tools_metadata )
+ data = []
+ canvas = svgfig.canvas( style="stroke:black; fill:none; stroke-width:1px; stroke-linejoin:round; text-anchor:left" )
+ text = svgfig.SVG( "g" )
+ connectors = svgfig.SVG( "g" )
+ boxes = svgfig.SVG( "g" )
+ svgfig.Text.defaults[ "font-size" ] = "10px"
+ in_pos = {}
+ out_pos = {}
+ margin = 5
+ # Spacing between input/outputs.
+ line_px = 16
+ # Store px width for boxes of each step.
+ widths = {}
+ max_width, max_x, max_y = 0, 0, 0
+ for step in workflow.steps:
+ step.upgrade_messages = {}
+ module = module_factory.from_workflow_step( trans, tools_metadata, step )
+ tool_errors = module.type == 'tool' and not module.tool
+ module_data_inputs = self.__get_data_inputs( step, module )
+ module_data_outputs = self.__get_data_outputs( step, module, workflow.steps )
+ step_dict = {
+ 'id' : step.order_index,
+ 'data_inputs' : module_data_inputs,
+ 'data_outputs' : module_data_outputs,
+ 'position' : step.position,
+ 'tool_errors' : tool_errors
+ }
+ input_conn_dict = {}
+ for conn in step.input_connections:
+ input_conn_dict[ conn.input_name ] = dict( id=conn.output_step.order_index, output_name=conn.output_name )
+ step_dict[ 'input_connections' ] = input_conn_dict
+ data.append( step_dict )
+ x, y = step.position[ 'left' ], step.position[ 'top' ]
+ count = 0
+ module_name = self.__get_name( module, missing_tool_tups )
+ max_len = len( module_name ) * 1.5
+ text.append( svgfig.Text( x, y + 20, module_name, **{ "font-size": "14px" } ).SVG() )
+ y += 45
+ for di in module_data_inputs:
+ cur_y = y + count * line_px
+ if step.order_index not in in_pos:
+ in_pos[ step.order_index ] = {}
+ in_pos[ step.order_index ][ di[ 'name' ] ] = ( x, cur_y )
+ text.append( svgfig.Text( x, cur_y, di[ 'label' ] ).SVG() )
+ count += 1
+ max_len = max( max_len, len( di[ 'label' ] ) )
+ if len( module.get_data_inputs() ) > 0:
+ y += 15
+ for do in module_data_outputs:
+ cur_y = y + count * line_px
+ if step.order_index not in out_pos:
+ out_pos[ step.order_index ] = {}
+ out_pos[ step.order_index ][ do[ 'name' ] ] = ( x, cur_y )
+ text.append( svgfig.Text( x, cur_y, do[ 'name' ] ).SVG() )
+ count += 1
+ max_len = max( max_len, len( do['name' ] ) )
+ widths[ step.order_index ] = max_len * 5.5
+ max_x = max( max_x, step.position[ 'left' ] )
+ max_y = max( max_y, step.position[ 'top' ] )
+ max_width = max( max_width, widths[ step.order_index ] )
+ for step_dict in data:
+ tool_unavailable = step_dict[ 'tool_errors' ]
+ width = widths[ step_dict[ 'id' ] ]
+ x, y = step_dict[ 'position' ][ 'left' ], step_dict[ 'position' ][ 'top' ]
+ if tool_unavailable:
+ fill = "#EBBCB2"
+ else:
+ fill = "#EBD9B2"
+ boxes.append( svgfig.Rect( x - margin, y, x + width - margin, y + 30, fill=fill ).SVG() )
+ box_height = ( len( step_dict[ 'data_inputs' ] ) + len( step_dict[ 'data_outputs' ] ) ) * line_px + margin
+ # Draw separator line.
+ if len( step_dict[ 'data_inputs' ] ) > 0:
+ box_height += 15
+ sep_y = y + len( step_dict[ 'data_inputs' ] ) * line_px + 40
+ text.append( svgfig.Line( x - margin, sep_y, x + width - margin, sep_y ).SVG() )
+ # Define an input/output box.
+ boxes.append( svgfig.Rect( x - margin, y + 30, x + width - margin, y + 30 + box_height, fill="#ffffff" ).SVG() )
+ for conn, output_dict in step_dict[ 'input_connections' ].iteritems():
+ in_coords = in_pos[ step_dict[ 'id' ] ][ conn ]
+ out_conn_pos = out_pos[ output_dict[ 'id' ] ][ output_dict[ 'output_name' ] ]
+ adjusted = ( out_conn_pos[ 0 ] + widths[ output_dict[ 'id' ] ], out_conn_pos[ 1 ] )
+ text.append( svgfig.SVG( "circle",
+ cx=out_conn_pos[ 0 ] + widths[ output_dict[ 'id' ] ] - margin,
+ cy=out_conn_pos[ 1 ] - margin,
+ r = 5,
+ fill="#ffffff" ) )
+ connectors.append( svgfig.Line( adjusted[ 0 ],
+ adjusted[ 1 ] - margin,
+ in_coords[ 0 ] - 10,
+ in_coords[ 1 ],
+ arrow_end = "true" ).SVG() )
+ canvas.append( connectors )
+ canvas.append( boxes )
+ canvas.append( text )
+ width, height = ( max_x + max_width + 50 ), max_y + 300
+ canvas[ 'width' ] = "%s px" % width
+ canvas[ 'height' ] = "%s px" % height
+ canvas[ 'viewBox' ] = "0 0 %s %s" % ( width, height )
+ trans.response.set_content_type( "image/svg+xml" )
+ return canvas.standalone_xml()
+ def __get_name( self, module, missing_tool_tups ):
+ module_name = module.get_name()
+ if module.type == 'tool' and module_name == 'unavailable':
+ for missing_tool_tup in missing_tool_tups:
+ missing_tool_id, missing_tool_name, missing_tool_version = missing_tool_tup
+ if missing_tool_id == module.tool_id:
+ module_name = '%s' % missing_tool_name
+ return module_name
+ def __get_data_inputs( self, step, module ):
+ if module.type == 'tool':
+ if module.tool:
+ return module.get_data_inputs()
+ else:
+ data_inputs = []
+ for wfsc in step.input_connections:
+ data_inputs_dict = {}
+ data_inputs_dict[ 'extensions' ] = [ '' ]
+ data_inputs_dict[ 'name' ] = wfsc.input_name
+ data_inputs_dict[ 'label' ] = 'Unknown'
+ data_inputs.append( data_inputs_dict )
+ return data_inputs
+ return module.get_data_inputs()
+ def __get_data_outputs( self, step, module, steps ):
+ if module.type == 'tool':
+ if module.tool:
+ return module.get_data_outputs()
+ else:
+ data_outputs = []
+ data_outputs_dict = {}
+ data_outputs_dict[ 'extensions' ] = [ 'input' ]
+ found = False
+ for workflow_step in steps:
+ for wfsc in workflow_step.input_connections:
+ if step.name == wfsc.output_step.name:
+ data_outputs_dict[ 'name' ] = wfsc.output_name
+ found = True
+ break
+ if found:
+ break
+ if not found:
+ # We're at the last step of the workflow.
+ data_outputs_dict[ 'name' ] = 'output'
+ data_outputs.append( data_outputs_dict )
+ return data_outputs
+ return module.get_data_outputs()
+ def __workflow_from_dict( self, trans, data, tools_metadata ):
+ """Creates and returns workflow object from a dictionary."""
+ trans.workflow_building_mode = True
+ workflow = model.Workflow()
+ workflow.name = data[ 'name' ]
+ workflow.has_errors = False
+ steps = []
+ # Keep ids for each step that we need to use to make connections.
+ steps_by_external_id = {}
+ # Keep track of tools required by the workflow that are not available in
+ # the tool shed repository. Each tuple in the list of missing_tool_tups
+ # will be ( tool_id, tool_name, tool_version ).
+ missing_tool_tups = []
+ # First pass to build step objects and populate basic values
+ for key, step_dict in data[ 'steps' ].iteritems():
+ # Create the model class for the step
+ step = model.WorkflowStep()
+ step.name = step_dict[ 'name' ]
+ step.position = step_dict[ 'position' ]
+ module = module_factory.from_dict( trans, step_dict, tools_metadata=tools_metadata, secure=False )
+ if module.type == 'tool' and module.tool is None:
+ # A required tool is not available in the current repository.
+ step.tool_errors = 'unavailable'
+ missing_tool_tup = ( step_dict[ 'tool_id' ], step_dict[ 'name' ], step_dict[ 'tool_version' ] )
+ if missing_tool_tup not in missing_tool_tups:
+ missing_tool_tups.append( missing_tool_tup )
+ module.save_to_step( step )
+ if step.tool_errors:
+ workflow.has_errors = True
+ # Stick this in the step temporarily.
+ step.temp_input_connections = step_dict[ 'input_connections' ]
+ # Unpack and add post-job actions.
+ post_job_actions = step_dict.get( 'post_job_actions', {} )
+ for name, pja_dict in post_job_actions.items():
+ pja = PostJobAction( pja_dict[ 'action_type' ],
+ step, pja_dict[ 'output_name' ],
+ pja_dict[ 'action_arguments' ] )
+ steps.append( step )
+ steps_by_external_id[ step_dict[ 'id' ] ] = step
+ # Second pass to deal with connections between steps.
+ for step in steps:
+ # Input connections.
+ for input_name, conn_dict in step.temp_input_connections.iteritems():
+ if conn_dict:
+ output_step = steps_by_external_id[ conn_dict[ 'id' ] ]
+ conn = model.WorkflowStepConnection()
+ conn.input_step = step
+ conn.input_name = input_name
+ conn.output_step = output_step
+ conn.output_name = conn_dict[ 'output_name' ]
+ step.input_connections.append( conn )
+ del step.temp_input_connections
+ # Order the steps if possible.
+ attach_ordered_steps( workflow, steps )
+ return workflow, missing_tool_tups
+ @web.expose
+ def import_workflow( self, trans, **kwd ):
+ repository_metadata_id = kwd.get( 'repository_metadata_id', '' )
+ workflow_name = kwd.get( 'workflow_name', '' )
+ if workflow_name:
+ workflow_name = decode( workflow_name )
+ webapp = kwd.get( 'webapp', 'community' )
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ repository_metadata = get_repository_metadata_by_id( trans, repository_metadata_id )
+ workflows = repository_metadata.metadata[ 'workflows' ]
+ workflow_data = None
+ for workflow_data in workflows:
+ if workflow_data[ 'name' ] == workflow_name:
+ break
+ if workflow_data:
+ if kwd.get( 'open_for_url', False ):
+ tmp_fd, tmp_fname = tempfile.mkstemp()
+ to_file = open( tmp_fname, 'wb' )
+ to_file.write( to_json_string( workflow_data ) )
+ return open( tmp_fname )
+ galaxy_url = trans.get_cookie( name='toolshedgalaxyurl' )
+ # TODO: support https in the following url.
+ url = 'http://%s/workflow/import_workflow?tool_shed_url=%s&repository_metadata_id=%s&workflow_name=%s&webapp=%s' % \
+ ( galaxy_url, trans.request.host, repository_metadata_id, encode( workflow_name ), webapp )
+ return trans.response.send_redirect( url )
+ return trans.response.send_redirect( web.url_for( controller='workflow',
+ action='view_workflow',
+ message=message,
+ status=status ) )
diff -r 37fb9b1fb62de6a304c6c500d9610b7eea2cf2aa -r 0ba260ea43c4e9613965e9f32705a118bab7c3ec lib/galaxy/webapps/community/model/__init__.py
--- a/lib/galaxy/webapps/community/model/__init__.py
+++ b/lib/galaxy/webapps/community/model/__init__.py
@@ -204,6 +204,34 @@
self.value = None
self.user_value = None
+class Workflow( object ):
+ def __init__( self ):
+ self.user = None
+ self.name = None
+ self.has_cycles = None
+ self.has_errors = None
+ self.steps = []
+
+class WorkflowStep( object ):
+ def __init__( self ):
+ self.id = None
+ self.type = None
+ self.name = None
+ self.tool_id = None
+ self.tool_inputs = None
+ self.tool_errors = None
+ self.position = None
+ self.input_connections = []
+ #self.output_connections = []
+ self.config = None
+
+class WorkflowStepConnection( object ):
+ def __init__( self ):
+ self.output_step = None
+ self.output_name = None
+ self.input_step = None
+ self.input_name = None
+
## ---- Utility methods -------------------------------------------------------
def sort_by_attr( seq, attr ):
"""
diff -r 37fb9b1fb62de6a304c6c500d9610b7eea2cf2aa -r 0ba260ea43c4e9613965e9f32705a118bab7c3ec lib/galaxy/workflow/modules.py
--- a/lib/galaxy/workflow/modules.py
+++ b/lib/galaxy/workflow/modules.py
@@ -205,14 +205,14 @@
def from_workflow_step( Class, trans, step ):
tool_id = step.tool_id
install_tool_id = None
- if tool_id not in trans.app.toolbox.tools_by_id:
+ if trans.app.toolbox and tool_id not in trans.app.toolbox.tools_by_id:
# The id value of tools installed from a Galaxy tool shed is a guid, but
# these tool's old_id attribute should contain what we're looking for.
for available_tool_id, available_tool in trans.app.toolbox.tools_by_id.items():
if tool_id == available_tool.old_id:
install_tool_id = available_tool_id
break
- if tool_id in trans.app.toolbox.tools_by_id or install_tool_id:
+ if ( trans.app.toolbox and tool_id in trans.app.toolbox.tools_by_id ) or install_tool_id:
module = Class( trans, tool_id )
module.state = DefaultToolState()
module.state.inputs = module.tool.params_from_strings( step.tool_inputs, trans.app, ignore_errors=True )
@@ -247,7 +247,9 @@
action_arguments = None
n_p = PostJobAction(v['action_type'], step, output_name, action_arguments)
def get_name( self ):
- return self.tool.name
+ if self.tool:
+ return self.tool.name
+ return 'unavailable'
def get_tool_id( self ):
return self.tool_id
def get_tool_version( self ):
diff -r 37fb9b1fb62de6a304c6c500d9610b7eea2cf2aa -r 0ba260ea43c4e9613965e9f32705a118bab7c3ec templates/webapps/community/repository/common.mako
--- a/templates/webapps/community/repository/common.mako
+++ b/templates/webapps/community/repository/common.mako
@@ -83,7 +83,8 @@
hg clone <a href="${clone_str}">${clone_str}</a></%def>
-<%def name="render_repository_tools_and_workflows( metadata, can_set_metadata=False, webapp='community' )">
+<%def name="render_repository_tools_and_workflows( repository_metadata_id, metadata, can_set_metadata=False, webapp='community' )">
+ <% from galaxy.webapps.community.controllers.common import encode, decode %>
%if metadata or can_set_metadata:
<p/><div class="toolForm">
@@ -160,14 +161,31 @@
<table class="grid"><tr><td><b>name</b></td>
+ <td><b>steps</b></td><td><b>format-version</b></td><td><b>annotation</b></td></tr>
%for workflow_dict in workflow_dicts:
+ <%
+ workflow_name = workflow_dict[ 'name' ]
+ steps = workflow_dict[ 'steps' ]
+ format_version = workflow_dict[ 'format-version' ]
+ annotation = workflow_dict[ 'annotation' ]
+ %><tr>
- <td>${workflow_dict[ 'name' ]}</td>
- <td>${workflow_dict[ 'format-version' ]}</td>
- <td>${workflow_dict[ 'annotation' ]}</td>
+ <td>
+ <a href="${h.url_for( controller='workflow', action='view_workflow', repository_metadata_id=repository_metadata_id, workflow_name=encode( workflow_name ), webapp=webapp )}">${workflow_name}</a>
+ </td>
+ <td>
+ %if 'steps' in workflow_dict:
+ ## Initially steps were not stored in the metadata record.
+ ${len( steps )}
+ %else:
+ unknown
+ %endif
+ </td>
+ <td>${format_version}</td>
+ <td>${annotation}</td></tr>
%endfor
</table>
diff -r 37fb9b1fb62de6a304c6c500d9610b7eea2cf2aa -r 0ba260ea43c4e9613965e9f32705a118bab7c3ec templates/webapps/community/repository/manage_repository.mako
--- a/templates/webapps/community/repository/manage_repository.mako
+++ b/templates/webapps/community/repository/manage_repository.mako
@@ -184,7 +184,7 @@
</form></div></div>
-${render_repository_tools_and_workflows( metadata, can_set_metadata=True )}
+${render_repository_tools_and_workflows( repository_metadata_id, metadata, can_set_metadata=True )}
<p/><div class="toolForm"><div class="toolFormTitle">Manage categories</div>
diff -r 37fb9b1fb62de6a304c6c500d9610b7eea2cf2aa -r 0ba260ea43c4e9613965e9f32705a118bab7c3ec templates/webapps/community/repository/preview_tools_in_changeset.mako
--- a/templates/webapps/community/repository/preview_tools_in_changeset.mako
+++ b/templates/webapps/community/repository/preview_tools_in_changeset.mako
@@ -103,4 +103,4 @@
</div></div><p/>
-${render_repository_tools_and_workflows( metadata, webapp=webapp )}
+${render_repository_tools_and_workflows( repository_metadata_id, metadata, webapp=webapp )}
diff -r 37fb9b1fb62de6a304c6c500d9610b7eea2cf2aa -r 0ba260ea43c4e9613965e9f32705a118bab7c3ec templates/webapps/community/repository/view_repository.mako
--- a/templates/webapps/community/repository/view_repository.mako
+++ b/templates/webapps/community/repository/view_repository.mako
@@ -185,7 +185,7 @@
%endif
</div></div>
-${render_repository_tools_and_workflows( metadata, webapp=webapp )}
+${render_repository_tools_and_workflows( repository_metadata_id, metadata, webapp=webapp )}
%if repository.categories:
<p/><div class="toolForm">
diff -r 37fb9b1fb62de6a304c6c500d9610b7eea2cf2aa -r 0ba260ea43c4e9613965e9f32705a118bab7c3ec templates/webapps/community/repository/view_workflow.mako
--- /dev/null
+++ b/templates/webapps/community/repository/view_workflow.mako
@@ -0,0 +1,102 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+<%namespace file="/webapps/community/common/common.mako" import="*" />
+<%namespace file="/webapps/community/repository/common.mako" import="*" />
+
+<%
+ from galaxy.web.framework.helpers import time_ago
+ from galaxy.webapps.community.controllers.common import encode
+
+ in_tool_shed = webapp == 'community'
+ is_admin = trans.user_is_admin()
+ is_new = repository.is_new
+ can_manage = is_admin or trans.user == repository.user
+ can_contact_owner = in_tool_shed and trans.user and trans.user != repository.user
+ can_push = in_tool_shed and trans.app.security_agent.can_push( trans.user, repository )
+ can_upload = can_push
+ can_download = in_tool_shed and not is_new and ( not is_malicious or can_push )
+ can_browse_contents = in_tool_shed and not is_new
+ can_set_metadata = in_tool_shed and not is_new
+ can_rate = in_tool_shed and not is_new and trans.user and repository.user != trans.user
+ can_view_change_log = in_tool_shed and not is_new
+ if can_push:
+ browse_label = 'Browse or delete repository files'
+ else:
+ browse_label = 'Browse repository files'
+%>
+
+<%!
+ def inherit(context):
+ if context.get('use_panels'):
+ return '/webapps/community/base_panels.mako'
+ else:
+ return '/base.mako'
+%>
+<%inherit file="${inherit(context)}"/>
+
+<%def name="render_workflow( repository_metadata_id, workflow_name, webapp )">
+ <% center_url = h.url_for( controller='workflow', action='generate_workflow_image', repository_metadata_id=repository_metadata_id, workflow_name=encode( workflow_name ), webapp=webapp ) %>
+ <iframe name="galaxy_main" id="galaxy_main" frameborder="0" style="position: absolute; width: 100%; height: 100%;" src="${center_url}"></iframe>
+</%def>
+
+<br/><br/>
+<ul class="manage-table-actions">
+ %if in_tool_shed:
+ %if is_new and can_upload:
+ <a class="action-button" href="${h.url_for( controller='upload', action='upload', repository_id=trans.security.encode_id( repository.id ), webapp='community' )}">Upload files to repository</a>
+ %else:
+ <li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Repository Actions</a></li>
+ <div popupmenu="repository-${repository.id}-popup">
+ %if can_upload:
+ <a class="action-button" href="${h.url_for( controller='upload', action='upload', repository_id=trans.security.encode_id( repository.id ), webapp='community' )}">Upload files to repository</a>
+ %endif
+ %if can_manage:
+ <a class="action-button" href="${h.url_for( controller='repository', action='manage_repository', id=trans.app.security.encode_id( repository.id ), changeset_revision=repository.tip )}">Manage repository</a>
+ %else:
+ <a class="action-button" href="${h.url_for( controller='repository', action='view_repository', id=trans.app.security.encode_id( repository.id ), changeset_revision=repository.tip, webapp='community' )}">View repository</a>
+ %endif
+ %if can_view_change_log:
+ <a class="action-button" href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ), webapp='community' )}">View change log</a>
+ %endif
+ %if can_rate:
+ <a class="action-button" href="${h.url_for( controller='repository', action='rate_repository', id=trans.app.security.encode_id( repository.id ) )}">Rate repository</a>
+ %endif
+ %if can_browse_contents:
+ <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ), webapp='community' )}">${browse_label}</a>
+ %endif
+ %if can_contact_owner:
+ <a class="action-button" href="${h.url_for( controller='repository', action='contact_owner', id=trans.security.encode_id( repository.id ), webapp='community' )}">Contact repository owner</a>
+ %endif
+ %if can_download:
+ <a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision, file_type='gz' )}">Download as a .tar.gz file</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision, file_type='bz2' )}">Download as a .tar.bz2 file</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision, file_type='zip' )}">Download as a zip file</a>
+ %endif
+ </div>
+ %endif
+ %else:
+ <li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Repository Actions</a></li>
+ <div popupmenu="repository-${repository.id}-popup">
+ <li><a class="action-button" href="${h.url_for( controller='workflow', action='import_workflow', repository_metadata_id=repository_metadata_id, workflow_name=encode( workflow_name ), webapp=webapp )}">Import workflow to local Galaxy</a></li>
+ <li><a class="action-button" href="${h.url_for( controller='repository', action='install_repository_revision', repository_id=trans.security.encode_id( repository.id ), webapp=webapp, changeset_revision=changeset_revision )}">Install repository to local Galaxy</a></li>
+ </div>
+ <li><a class="action-button" id="toolshed-${repository.id}-popup" class="menubutton">Tool Shed Actions</a></li>
+ <div popupmenu="toolshed-${repository.id}-popup">
+ <a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='find_tools', webapp=webapp )}">Search for valid tools</a>
+ </div>
+ %endif
+</ul>
+
+%if message:
+ ${render_msg( message, status )}
+%endif
+
+<br/>
+<b>Boxes are red when tools are not available in this repository</b>
+<div class="toolParamHelp" style="clear: both;">
+ (this page displays SVG graphics)
+</div>
+<br clear="left"/>
+
+${render_workflow( repository_metadata_id, workflow_name, webapp )}
diff -r 37fb9b1fb62de6a304c6c500d9610b7eea2cf2aa -r 0ba260ea43c4e9613965e9f32705a118bab7c3ec templates/workflow/display.mako
--- a/templates/workflow/display.mako
+++ b/templates/workflow/display.mako
@@ -1,7 +1,7 @@
<%inherit file="/display_base.mako"/><%namespace file="/display_common.mako" import="render_message" />
-<%!
+<%
from galaxy.tools.parameters import DataToolParameter, RuntimeValue
from galaxy.web import form_builder
%>
@@ -82,7 +82,17 @@
%for i, step in enumerate( steps ):
<tr><td>
%if step.type == 'tool' or step.type is None:
- <% tool = app.toolbox.tools_by_id[step.tool_id] %>
+ <%
+ try:
+ tool = trans.app.toolbox.tools_by_id[ step.tool_id ]
+ except KeyError, e:
+ # The id value of tools installed from a Galaxy tool shed is a guid, but
+ # these tool's old_id attribute should contain what we're looking for.
+ for available_tool_id, available_tool in trans.app.toolbox.tools_by_id.items():
+ if step.tool_id == available_tool.old_id:
+ tool = available_tool
+ break
+ %><div class="toolForm"><div class="toolFormTitle">Step ${int(step.order_index)+1}: ${tool.name}</div><div class="toolFormBody">
diff -r 37fb9b1fb62de6a304c6c500d9610b7eea2cf2aa -r 0ba260ea43c4e9613965e9f32705a118bab7c3ec templates/workflow/run.mako
--- a/templates/workflow/run.mako
+++ b/templates/workflow/run.mako
@@ -363,7 +363,17 @@
%endif
%for i, step in enumerate( steps ):
%if step.type == 'tool' or step.type is None:
- <% tool = app.toolbox.tools_by_id[step.tool_id] %>
+ <%
+ try:
+ tool = trans.app.toolbox.tools_by_id[ step.tool_id ]
+ except KeyError, e:
+ # The id value of tools installed from a Galaxy tool shed is a guid, but
+ # these tool's old_id attribute should contain what we're looking for.
+ for available_tool_id, available_tool in trans.app.toolbox.tools_by_id.items():
+ if step.tool_id == available_tool.old_id:
+ tool = available_tool
+ break
+ %><input type="hidden" name="${step.id}|tool_state" value="${step.state.encode( tool, app )}"><div class="toolForm"><div class="toolFormTitle">
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: Allow Picard based Merge BAM Files tool to work on sam inputs as well as the previously accepted bam.
by Bitbucket 26 Oct '11
by Bitbucket 26 Oct '11
26 Oct '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/37fb9b1fb62d/
changeset: 37fb9b1fb62d
user: dan
date: 2011-10-26 22:03:47
summary: Allow Picard based Merge BAM Files tool to work on sam inputs as well as the previously accepted bam.
affected #: 1 file
diff -r f335b8bbb91f575f1ffac466c53b907e8623a9a8 -r 37fb9b1fb62de6a304c6c500d9610b7eea2cf2aa tools/samtools/sam_merge.xml
--- a/tools/samtools/sam_merge.xml
+++ b/tools/samtools/sam_merge.xml
@@ -16,10 +16,10 @@
<param name="mergeSD" value="true" type="boolean" label="Merge all component bam file headers into the merged bam file"
truevalue="true" falsevalue="false" checked="yes"
help="Control the MERGE_SEQUENCE_DICTIONARIES flag for Picard MergeSamFiles. Default (true) correctly propagates read groups and other important metadata" />
- <param name="input1" label="First file" type="data" format="bam" />
- <param name="input2" label="with file" type="data" format="bam" help="Need to add more files? Use controls below." />
+ <param name="input1" label="First file" type="data" format="bam,sam" />
+ <param name="input2" label="with file" type="data" format="bam,sam" help="Need to add more files? Use controls below." /><repeat name="inputs" title="Input Files">
- <param name="input" label="Add file" type="data" format="bam" />
+ <param name="input" label="Add file" type="data" format="bam,sam" /></repeat></inputs><outputs>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: dan: "Merge BAM Files" under SAM Tools section(???) calls Picard MergeSamFiles.jar. Update to new jar location.
by Bitbucket 26 Oct '11
by Bitbucket 26 Oct '11
26 Oct '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/f335b8bbb91f/
changeset: f335b8bbb91f
user: dan
date: 2011-10-26 19:35:17
summary: "Merge BAM Files" under SAM Tools section(???) calls Picard MergeSamFiles.jar. Update to new jar location.
affected #: 1 file
diff -r 34fffbf01183c5ae9a9037e4a13501c9cf5b8b8d -r f335b8bbb91f575f1ffac466c53b907e8623a9a8 tools/samtools/sam_merge.xml
--- a/tools/samtools/sam_merge.xml
+++ b/tools/samtools/sam_merge.xml
@@ -4,7 +4,7 @@
<requirement type="package">picard</requirement></requirements><command>
-java -Xmx2G -jar ${GALAXY_DATA_INDEX_DIR}/shared/jars/MergeSamFiles.jar MSD=$mergeSD VALIDATION_STRINGENCY=LENIENT O=$output1 I=$input1 I=$input2
+java -Xmx2G -jar ${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/MergeSamFiles.jar MSD=$mergeSD VALIDATION_STRINGENCY=LENIENT O=$output1 I=$input1 I=$input2
#for $i in $inputs
I=${i.input}
#end for
@@ -36,7 +36,7 @@
<param name="input1" value="sam_merge_in1.bam" ftype="bam" /><param name="input2" value="sam_merge_in2.bam" ftype="bam" /><output name="output1" file="sam_merge_out1.bam" ftype="bam" />
- <output name="outlog" file="sam_merge_out1.log" ftype="txt" lines_diff="10"/>
+ <output name="outlog" file="sam_merge_out1.log" ftype="txt" lines_diff="11"/></test><test><param name="title" value="test2" />
@@ -45,7 +45,7 @@
<param name="input2" value="sam_merge_in2.bam" ftype="bam" /><param name="input" value="sam_merge_in3.bam" ftype="bam" /><output name="output1" file="sam_merge_out2.bam" ftype="bam" />
- <output name="outlog" file="sam_merge_out2.log" ftype="txt" lines_diff="10"/>
+ <output name="outlog" file="sam_merge_out2.log" ftype="txt" lines_diff="11"/></test></tests><help>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: dan: Add metadata validator to force input bam files to have bam_index metadata files for GATK tools.
by Bitbucket 25 Oct '11
by Bitbucket 25 Oct '11
25 Oct '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/34fffbf01183/
changeset: 34fffbf01183
user: dan
date: 2011-10-25 21:43:04
summary: Add metadata validator to force input bam files to have bam_index metadata files for GATK tools.
affected #: 6 files
diff -r 33bdfafacc0064e3975beb10dd2694d8240bf23a -r 34fffbf01183c5ae9a9037e4a13501c9cf5b8b8d tools/gatk/count_covariates.xml
--- a/tools/gatk/count_covariates.xml
+++ b/tools/gatk/count_covariates.xml
@@ -138,6 +138,7 @@
<when value="cached"><param name="input_bam" type="data" format="bam" label="BAM file"><validator type="unspecified_build" />
+ <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/><validator type="dataset_metadata_in_file" filename="picard_index.loc" metadata_name="dbkey" metadata_column="1" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --></param><param name="ref_file" type="select" label="Using reference genome">
@@ -147,7 +148,9 @@
</param></when><when value="history"><!-- FIX ME!!!! -->
- <param name="input_bam" type="data" format="bam" label="BAM file" />
+ <param name="input_bam" type="data" format="bam" label="BAM file" >
+ <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/>
+ </param><param name="ref_file" type="data" format="fasta" label="Using reference file" /></when></conditional>
diff -r 33bdfafacc0064e3975beb10dd2694d8240bf23a -r 34fffbf01183c5ae9a9037e4a13501c9cf5b8b8d tools/gatk/indel_realigner.xml
--- a/tools/gatk/indel_realigner.xml
+++ b/tools/gatk/indel_realigner.xml
@@ -107,6 +107,7 @@
<when value="cached"><param name="input_bam" type="data" format="bam" label="BAM file"><validator type="unspecified_build" />
+ <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/><validator type="dataset_metadata_in_data_table" table_name="picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --></param><param name="ref_file" type="select" label="Using reference genome">
@@ -116,7 +117,9 @@
</param></when><when value="history"><!-- FIX ME!!!! -->
- <param name="input_bam" type="data" format="bam" label="BAM file" />
+ <param name="input_bam" type="data" format="bam" label="BAM file" >
+ <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/>
+ </param><param name="ref_file" type="data" format="fasta" label="Using reference file"><options><filter type="data_meta" key="dbkey" ref="input_bam" /><!-- FIX ME!!!! -->
diff -r 33bdfafacc0064e3975beb10dd2694d8240bf23a -r 34fffbf01183c5ae9a9037e4a13501c9cf5b8b8d tools/gatk/realigner_target_creator.xml
--- a/tools/gatk/realigner_target_creator.xml
+++ b/tools/gatk/realigner_target_creator.xml
@@ -103,6 +103,7 @@
<when value="cached"><param name="input_bam" type="data" format="bam" label="BAM file"><validator type="unspecified_build" />
+ <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/><validator type="dataset_metadata_in_data_table" table_name="picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --></param><param name="ref_file" type="select" label="Using reference genome">
@@ -112,7 +113,9 @@
</param></when><when value="history">
- <param name="input_bam" type="data" format="bam" label="BAM file" />
+ <param name="input_bam" type="data" format="bam" label="BAM file" >
+ <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/>
+ </param><param name="ref_file" type="data" format="fasta" label="Using reference file"><options><filter type="data_meta" key="dbkey" ref="input_bam" /><!-- FIX ME!!!! -->
diff -r 33bdfafacc0064e3975beb10dd2694d8240bf23a -r 34fffbf01183c5ae9a9037e4a13501c9cf5b8b8d tools/gatk/table_recalibration.xml
--- a/tools/gatk/table_recalibration.xml
+++ b/tools/gatk/table_recalibration.xml
@@ -117,6 +117,7 @@
<when value="cached"><param name="input_bam" type="data" format="bam" label="BAM file"><validator type="unspecified_build" />
+ <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/><validator type="dataset_metadata_in_data_table" table_name="picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --></param><param name="ref_file" type="select" label="Using reference genome">
@@ -126,7 +127,9 @@
</param></when><when value="history"><!-- FIX ME!!!! -->
- <param name="input_bam" type="data" format="bam" label="BAM file" />
+ <param name="input_bam" type="data" format="bam" label="BAM file" >
+ <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/>
+ </param><param name="ref_file" type="data" format="fasta" label="Using reference file" /></when></conditional>
diff -r 33bdfafacc0064e3975beb10dd2694d8240bf23a -r 34fffbf01183c5ae9a9037e4a13501c9cf5b8b8d tools/gatk/unified_genotyper.xml
--- a/tools/gatk/unified_genotyper.xml
+++ b/tools/gatk/unified_genotyper.xml
@@ -135,6 +135,7 @@
<repeat name="input_bams" title="Sample BAM file" min="1"><param name="input_bam" type="data" format="bam" label="BAM file"><validator type="unspecified_build" />
+ <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/><validator type="dataset_metadata_in_data_table" table_name="picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --></param></repeat>
@@ -146,7 +147,9 @@
</when><when value="history"><!-- FIX ME!!!! --><repeat name="input_bams" title="Sample BAM file" min="1">
- <param name="input_bam" type="data" format="bam" label="BAM file" />
+ <param name="input_bam" type="data" format="bam" label="BAM file" >
+ <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/>
+ </param></repeat><param name="ref_file" type="data" format="fasta" label="Using reference file" /></when>
diff -r 33bdfafacc0064e3975beb10dd2694d8240bf23a -r 34fffbf01183c5ae9a9037e4a13501c9cf5b8b8d tools/gatk/variant_annotator.xml
--- a/tools/gatk/variant_annotator.xml
+++ b/tools/gatk/variant_annotator.xml
@@ -145,6 +145,7 @@
<param name="input_variant_bti" type="boolean" truevalue="-BTI variant" falsevalue="" label="Increase efficiency for small variant files." /><param name="input_bam" type="data" format="bam" label="BAM file" optional="True" help="Not needed for all annotations." ><validator type="unspecified_build" />
+ <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/><validator type="dataset_metadata_in_data_table" table_name="picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --></param><param name="ref_file" type="select" label="Using reference genome">
@@ -156,7 +157,9 @@
<when value="history"><!-- FIX ME!!!! --><param name="input_variant" type="data" format="vcf" label="Variant file to annotate" /><param name="input_variant_bti" type="boolean" truevalue="-BTI variant" falsevalue="" label="Increase efficiency for small variant files." />
- <param name="input_bam" type="data" format="bam" label="BAM file" optional="True" />
+ <param name="input_bam" type="data" format="bam" label="BAM file" optional="True" >
+ <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/>
+ </param><param name="ref_file" type="data" format="fasta" label="Using reference file" /></when></conditional>
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: Set URL for visualization when it is first saved.
by Bitbucket 25 Oct '11
by Bitbucket 25 Oct '11
25 Oct '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/33bdfafacc00/
changeset: 33bdfafacc00
user: jgoecks
date: 2011-10-25 21:23:45
summary: Set URL for visualization when it is first saved.
affected #: 2 files
diff -r 8c7f2c84bbbd084bfbc3edfe64e5a159080145dd -r 33bdfafacc0064e3975beb10dd2694d8240bf23a lib/galaxy/web/controllers/tracks.py
--- a/lib/galaxy/web/controllers/tracks.py
+++ b/lib/galaxy/web/controllers/tracks.py
@@ -663,7 +663,8 @@
vis.latest_revision = vis_rev
session.add( vis_rev )
session.flush()
- return trans.security.encode_id(vis.id)
+ encoded_id = trans.security.encode_id(vis.id)
+ return { "id": encoded_id, "url": url_for( action='browser', id=encoded_id ) }
@web.expose
@web.require_login( "see all available libraries" )
diff -r 8c7f2c84bbbd084bfbc3edfe64e5a159080145dd -r 33bdfafacc0064e3975beb10dd2694d8240bf23a templates/tracks/browser.mako
--- a/templates/tracks/browser.mako
+++ b/templates/tracks/browser.mako
@@ -212,10 +212,14 @@
'dbkey': view.dbkey,
'payload': JSON.stringify(payload)
},
- success: function(vis_id) {
- view.vis_id = vis_id;
+ dataType: "json",
+ success: function(vis_info) {
+ hide_modal();
+ view.vis_id = vis_info.vis_id;
view.has_changes = false;
- hide_modal();
+
+ // Needed to set URL when first saving a visualization.
+ window.history.pushState({}, "", vis_info.url);
},
error: function() { alert("Could not save visualization"); }
});
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: jgoecks: Trackster: automatically remove spaces from an entered location.
by Bitbucket 25 Oct '11
by Bitbucket 25 Oct '11
25 Oct '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/8c7f2c84bbbd/
changeset: 8c7f2c84bbbd
user: jgoecks
date: 2011-10-25 20:59:19
summary: Trackster: automatically remove spaces from an entered location.
affected #: 1 file
diff -r 6010fcf5e6773a4f06b148420bf046d3d8a22b4d -r 8c7f2c84bbbd084bfbc3edfe64e5a159080145dd static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -1189,6 +1189,10 @@
}
},
go_to: function(str) {
+ // Preprocess str to remove spaces and commas.
+ str = str.replace(/ |,/g, "");
+
+ // Go to new location.
var view = this,
new_low,
new_high,
@@ -1199,8 +1203,8 @@
if (pos !== undefined) {
try {
var pos_split = pos.split("-");
- new_low = parseInt(pos_split[0].replace(/,/g, ""), 10);
- new_high = parseInt(pos_split[1].replace(/,/g, ""), 10);
+ new_low = parseInt(pos_split[0], 10);
+ new_high = parseInt(pos_split[1], 10);
} catch (e) {
return false;
}
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 some debug prints from GATK unified genotyper.
by Bitbucket 25 Oct '11
by Bitbucket 25 Oct '11
25 Oct '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/6010fcf5e677/
changeset: 6010fcf5e677
user: dan
date: 2011-10-25 20:21:49
summary: Remove some debug prints from GATK unified genotyper.
affected #: 1 file
diff -r b0967259b2905e58bc0e75ba8ada7a0cd8974b7d -r 6010fcf5e6773a4f06b148420bf046d3d8a22b4d tools/gatk/unified_genotyper.xml
--- a/tools/gatk/unified_genotyper.xml
+++ b/tools/gatk/unified_genotyper.xml
@@ -7,8 +7,6 @@
--max_jvm_heap_fraction "1"
--stdout "${output_log}"
#for $i, $input_bam in enumerate( $reference_source.input_bams ):
- ${dir( $input_bam.input_bam )}
- ${dir( $input_bam.input_bam.dataset )}
-d "-I" "${input_bam.input_bam}" "${input_bam.input_bam.ext}" "gatk_input_${i}"
-d "" "${input_bam.input_bam.metadata.bam_index}" "bam_index" "gatk_input_${i}" ##hardcode galaxy ext type as bam_index
#end for
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: Show dataset size of non-purged error state history items.
by Bitbucket 25 Oct '11
by Bitbucket 25 Oct '11
25 Oct '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/b0967259b290/
changeset: b0967259b290
user: dan
date: 2011-10-25 19:58:08
summary: Show dataset size of non-purged error state history items.
affected #: 1 file
diff -r 4d1e525e1594a63221c099c5f84ca5765775533b -r b0967259b2905e58bc0e75ba8ada7a0cd8974b7d templates/root/history_common.mako
--- a/templates/root/history_common.mako
+++ b/templates/root/history_common.mako
@@ -96,7 +96,7 @@
display_url = h.url_for( controller='dataset', action='display', dataset_id=dataset_id, preview=True, filename='' )
%>
%if data.purged:
- <span class="icon-button display_disabled tooltip" title="Cannoy display datasets removed from disk"></span>
+ <span class="icon-button display_disabled tooltip" title="Cannot display datasets removed from disk"></span>
%else:
<a class="icon-button display tooltip" title="Display data in browser" href="${display_url}"
%if for_editing:
@@ -150,6 +150,9 @@
%endif
</div>
%elif data_state == "error":
+ %if not data.purged:
+ <div>${data.get_size( nice_size=True )}</div>
+ %endif
<div>
An error occurred running this job: <i>${data.display_info().strip()}</i></div>
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

25 Oct '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/4d1e525e1594/
changeset: 4d1e525e1594
user: dan
date: 2011-10-25 19:51:56
summary: Allow picard_SamToFastq to use input BAM files.
affected #: 1 file
diff -r 5ed5bcad57015ab0b412dcc2648cbfbf1e11bf9e -r 4d1e525e1594a63221c099c5f84ca5765775533b tools/picard/picard_SamToFastq.xml
--- a/tools/picard/picard_SamToFastq.xml
+++ b/tools/picard/picard_SamToFastq.xml
@@ -42,11 +42,11 @@
|| echo "Error running SamToFastq" >&2
</command><inputs>
- <param name="input_sam" type="data" format="sam" label="SAM file" />
+ <param name="input_sam" type="data" format="sam,bam" label="BAM/SAM file" /><param name="read1_trim" type="integer" value="" optional="True" label="The number of bases to trim from the beginning of read 1." /><param name="read1_max_bases_to_write" type="integer" optional="True" value="" label="The maximum number of bases to write from read 1 after trimming." /><param name="output_per_read_group_selector" type="select" label="Output per read group">
- <option value="per_sam_file" selected="True">Per SAM file</option>
+ <option value="per_sam_file" selected="True">Per BAM/SAM file</option><!-- <option value="per_read_group">Per Read Group</option> --><validator type="expression" message="Per Read Group selection is not yet implemented">value == 'per_sam_file'</validator></param>
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/4421e535870a/
changeset: 4421e535870a
branch: fastq-deinterlacer-memfix
user: natefoo
date: 2011-10-25 16:52:43
summary: Closed fastq-deinterlacer-memfix
affected #: 0 files
https://bitbucket.org/galaxy/galaxy-central/changeset/5ed5bcad5701/
changeset: 5ed5bcad5701
user: natefoo
date: 2011-10-25 16:54:17
summary: Fix Python versions in README.txt
affected #: 1 file
diff -r 18f2b18d48e845b49332c3fa7d6316cbadae15ef -r 5ed5bcad57015ab0b412dcc2648cbfbf1e11bf9e README.txt
--- a/README.txt
+++ b/README.txt
@@ -7,7 +7,7 @@
HOW TO START
============
-Galaxy requires Python 2.4, 2.5 or 2.6. To check your python version, run:
+Galaxy requires Python 2.5, 2.6 or 2.7. To check your python version, run:
% python -V
Python 2.4.4
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 Picard tools to use tool-data/shared/jars/picard/* instead of just tool-data/shared/jars/*.
by Bitbucket 25 Oct '11
by Bitbucket 25 Oct '11
25 Oct '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/18f2b18d48e8/
changeset: 18f2b18d48e8
user: dan
date: 2011-10-25 16:34:35
summary: Update Picard tools to use tool-data/shared/jars/picard/* instead of just tool-data/shared/jars/*.
affected #: 14 files
diff -r beb1986edd2838251441fcc47d7474ac1ed24d27 -r 18f2b18d48e845b49332c3fa7d6316cbadae15ef tools/picard/picard_AddOrReplaceReadGroups.xml
--- a/tools/picard/picard_AddOrReplaceReadGroups.xml
+++ b/tools/picard/picard_AddOrReplaceReadGroups.xml
@@ -1,4 +1,4 @@
-<tool name="Add or Replace Groups" id="picard_ARRG" version="0.2.0">
+<tool name="Add or Replace Groups" id="picard_ARRG" version="0.2.1"><requirements><requirement type="package">picard</requirement></requirements><command interpreter="python">
picard_wrapper.py
@@ -15,7 +15,7 @@
#end if
--output-format=$outputFormat
--output=$outFile
- -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/AddOrReplaceReadGroups.jar"
+ -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/AddOrReplaceReadGroups.jar"
</command><inputs><param format="bam,sam" name="inputFile" type="data" label="SAM/BAM dataset to add or replace read groups in"
diff -r beb1986edd2838251441fcc47d7474ac1ed24d27 -r 18f2b18d48e845b49332c3fa7d6316cbadae15ef tools/picard/picard_BamIndexStats.xml
--- a/tools/picard/picard_BamIndexStats.xml
+++ b/tools/picard/picard_BamIndexStats.xml
@@ -1,4 +1,4 @@
-<tool name="BAM Index Statistics" id="picard_BamIndexStats" version="0.2.0">
+<tool name="BAM Index Statistics" id="picard_BamIndexStats" version="0.2.1"><requirements><requirement type="package">picard</requirement></requirements><command interpreter="python">
picard_wrapper.py
@@ -6,7 +6,7 @@
--bai-file "$input_file.metadata.bam_index"
-t "$htmlfile"
-d "$htmlfile.files_path"
- -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/BamIndexStats.jar"
+ -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/BamIndexStats.jar"
</command><inputs><param format="bam" name="input_file" type="data" label="BAM dataset to generate statistics for"
diff -r beb1986edd2838251441fcc47d7474ac1ed24d27 -r 18f2b18d48e845b49332c3fa7d6316cbadae15ef tools/picard/picard_FastqToSam.xml
--- a/tools/picard/picard_FastqToSam.xml
+++ b/tools/picard/picard_FastqToSam.xml
@@ -1,5 +1,6 @@
<tool id="picard_FastqToSam" name="FASTQ to BAM" version="0.0.1"><description>creates an unaligned BAM file</description>
+ <requirements><requirement type="package">picard</requirement></requirements><command>java -XX:DefaultMaxRAMFraction=1 -XX:+UseParallelGC
-jar "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/FastqToSam.jar"
FASTQ="${input_fastq1}"
diff -r beb1986edd2838251441fcc47d7474ac1ed24d27 -r 18f2b18d48e845b49332c3fa7d6316cbadae15ef tools/picard/picard_MarkDuplicates.xml
--- a/tools/picard/picard_MarkDuplicates.xml
+++ b/tools/picard/picard_MarkDuplicates.xml
@@ -1,4 +1,4 @@
-<tool name="Mark Duplicates" id="picard_MarkDuplicates" version="0.01">
+<tool name="Mark Duplicates" id="picard_MarkDuplicates" version="0.01.1"><command interpreter="python">
picard_wrapper.py
--input="$input_file"
@@ -20,7 +20,7 @@
--output-sam=$outFileBamMarked
#end if
#end if
- -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/"
+ -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/"
--picard-cmd="MarkDuplicates"
</command><inputs>
diff -r beb1986edd2838251441fcc47d7474ac1ed24d27 -r 18f2b18d48e845b49332c3fa7d6316cbadae15ef tools/picard/picard_ReorderSam.xml
--- a/tools/picard/picard_ReorderSam.xml
+++ b/tools/picard/picard_ReorderSam.xml
@@ -1,4 +1,4 @@
-<tool name="Reorder SAM/BAM" id="picard_ReorderSam" version="0.3.0">
+<tool name="Reorder SAM/BAM" id="picard_ReorderSam" version="0.3.1"><requirements><requirement type="package">picard</requirement></requirements><command interpreter="python">
picard_wrapper.py
@@ -15,7 +15,7 @@
--allow-contig-len-discord=$allowContigLenDiscord
--output-format=$outputFormat
--output=$outFile
- -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/ReorderSam.jar"
+ -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/ReorderSam.jar"
</command><inputs><param format="bam,sam" name="inputFile" type="data" label="SAM/BAM dataset to be reordered"
diff -r beb1986edd2838251441fcc47d7474ac1ed24d27 -r 18f2b18d48e845b49332c3fa7d6316cbadae15ef tools/picard/picard_ReplaceSamHeader.xml
--- a/tools/picard/picard_ReplaceSamHeader.xml
+++ b/tools/picard/picard_ReplaceSamHeader.xml
@@ -1,4 +1,4 @@
-<tool name="Replace SAM/BAM Header" id="picard_ReplaceSamHeader" version="0.2.0">
+<tool name="Replace SAM/BAM Header" id="picard_ReplaceSamHeader" version="0.2.1"><requirements><requirement type="package">picard</requirement></requirements><command interpreter="python">
picard_wrapper.py
@@ -6,7 +6,7 @@
-o $outFile
--header-file $headerFile
--output-format $outputFormat
- -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/ReplaceSamHeader.jar"
+ -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/ReplaceSamHeader.jar"
--tmpdir "${__new_file_path__}"
</command><inputs>
diff -r beb1986edd2838251441fcc47d7474ac1ed24d27 -r 18f2b18d48e845b49332c3fa7d6316cbadae15ef tools/picard/picard_SamToFastq.xml
--- a/tools/picard/picard_SamToFastq.xml
+++ b/tools/picard/picard_SamToFastq.xml
@@ -1,5 +1,6 @@
<tool id="picard_SamToFastq" name="SAM to FASTQ" version="0.0.1"><description>creates a FASTQ file</description>
+ <requirements><requirement type="package">picard</requirement></requirements><command>java -XX:DefaultMaxRAMFraction=1 -XX:+UseParallelGC
-jar "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/SamToFastq.jar"
INPUT="${input_sam}"
diff -r beb1986edd2838251441fcc47d7474ac1ed24d27 -r 18f2b18d48e845b49332c3fa7d6316cbadae15ef tools/picard/rgPicardASMetrics.xml
--- a/tools/picard/rgPicardASMetrics.xml
+++ b/tools/picard/rgPicardASMetrics.xml
@@ -1,8 +1,8 @@
-<tool name="SAM/BAM Alignment Summary Metrics" id="PicardASMetrics" version="0.03">
+<tool name="SAM/BAM Alignment Summary Metrics" id="PicardASMetrics" version="0.03.1"><command interpreter="python">
picard_wrapper.py -i "$input_file" -d "$html_file.files_path" -t "$html_file"
--assumesorted "$sorted" -b "$bisulphite" --adaptors "$adaptors" --maxinsert "$maxinsert" -n "$out_prefix"
- -j ${GALAXY_DATA_INDEX_DIR}/shared/jars/CollectAlignmentSummaryMetrics.jar
+ -j ${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/CollectAlignmentSummaryMetrics.jar
#if $genomeSource.refGenomeSource == "history":
--ref-file "$genomeSource.ownFile"
#else
diff -r beb1986edd2838251441fcc47d7474ac1ed24d27 -r 18f2b18d48e845b49332c3fa7d6316cbadae15ef tools/picard/rgPicardFixMate.xml
--- a/tools/picard/rgPicardFixMate.xml
+++ b/tools/picard/rgPicardFixMate.xml
@@ -1,8 +1,8 @@
-<tool name="Paired Read Mate Fixer" id="rgPicFixMate" version="0.2.0">
+<tool name="Paired Read Mate Fixer" id="rgPicFixMate" version="0.2.1"><description>for paired data</description><command interpreter="python">
picard_wrapper.py -i "$input_file" -o "$out_file" --tmpdir "${__new_file_path__}" -n "$out_prefix"
- --output-format "$outputFormat" -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/FixMateInformation.jar" --sortorder "$sortOrder"
+ --output-format "$outputFormat" -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/FixMateInformation.jar" --sortorder "$sortOrder"
</command><requirements><requirement type="package">picard</requirement></requirements><inputs>
diff -r beb1986edd2838251441fcc47d7474ac1ed24d27 -r 18f2b18d48e845b49332c3fa7d6316cbadae15ef tools/picard/rgPicardGCBiasMetrics.xml
--- a/tools/picard/rgPicardGCBiasMetrics.xml
+++ b/tools/picard/rgPicardGCBiasMetrics.xml
@@ -1,8 +1,8 @@
-<tool name="SAM/BAM GC Bias Metrics" id="PicardGCBiasMetrics" version="0.02">
+<tool name="SAM/BAM GC Bias Metrics" id="PicardGCBiasMetrics" version="0.02.1"><command interpreter="python">
picard_wrapper.py -i "$input_file" -d "$html_file.files_path" -t "$html_file"
--windowsize "$windowsize" --mingenomefrac "$mingenomefrac" -n "$out_prefix" --tmpdir "${__new_file_path__}"
- -j ${GALAXY_DATA_INDEX_DIR}/shared/jars/CollectGcBiasMetrics.jar
+ -j ${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/CollectGcBiasMetrics.jar
#if $genomeSource.refGenomeSource == "history":
--ref-file "$genomeSource.ownFile"
#else:
diff -r beb1986edd2838251441fcc47d7474ac1ed24d27 -r 18f2b18d48e845b49332c3fa7d6316cbadae15ef tools/picard/rgPicardHsMetrics.xml
--- a/tools/picard/rgPicardHsMetrics.xml
+++ b/tools/picard/rgPicardHsMetrics.xml
@@ -1,10 +1,10 @@
-<tool name="SAM/BAM Hybrid Selection Metrics" id="PicardHsMetrics" version="0.02">
+<tool name="SAM/BAM Hybrid Selection Metrics" id="PicardHsMetrics" version="0.02.1"><description>for targeted resequencing data</description><command interpreter="python">
picard_wrapper.py -i "$input_file" -d "$html_file.files_path" -t "$html_file" --datatype "$input_file.ext"
--baitbed "$bait_bed" --targetbed "$target_bed" -n "$out_prefix" --tmpdir "${__new_file_path__}"
- -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/CalculateHsMetrics.jar"
+ -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/CalculateHsMetrics.jar"
</command><requirements><requirement type="package">picard</requirement></requirements>
diff -r beb1986edd2838251441fcc47d7474ac1ed24d27 -r 18f2b18d48e845b49332c3fa7d6316cbadae15ef tools/picard/rgPicardInsertSize.xml
--- a/tools/picard/rgPicardInsertSize.xml
+++ b/tools/picard/rgPicardInsertSize.xml
@@ -1,10 +1,10 @@
-<tool name="Insertion size metrics" id="PicardInsertSize" version="0.3.0">
+<tool name="Insertion size metrics" id="PicardInsertSize" version="0.3.1"><description>for PAIRED data</description><requirements><requirement type="package">picard</requirement></requirements><command interpreter="python">
picard_wrapper.py -i "$input_file" -n "$out_prefix" --tmpdir "${__new_file_path__}" --taillimit "$tailLimit"
--histwidth "$histWidth" --minpct "$minPct"
- -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/CollectInsertSizeMetrics.jar" -d "$html_file.files_path" -t "$html_file"
+ -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/CollectInsertSizeMetrics.jar" -d "$html_file.files_path" -t "$html_file"
</command><inputs><param format="bam,sam" name="input_file" type="data" label="SAM/BAM dataset to generate statistics for"
diff -r beb1986edd2838251441fcc47d7474ac1ed24d27 -r 18f2b18d48e845b49332c3fa7d6316cbadae15ef tools/picard/rgPicardLibComplexity.xml
--- a/tools/picard/rgPicardLibComplexity.xml
+++ b/tools/picard/rgPicardLibComplexity.xml
@@ -1,8 +1,8 @@
-<tool name="Estimate Library Complexity" id="rgEstLibComp" version="0.01">
+<tool name="Estimate Library Complexity" id="rgEstLibComp" version="0.01.1"><command interpreter="python">
picard_wrapper.py -i "$input_file" -n "$out_prefix" --tmpdir "${__new_file_path__}" --minid "$minIDbases"
--maxdiff "$maxDiff" --minmeanq "$minMeanQ" --readregex "$readRegex" --optdupdist "$optDupeDist"
- -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/EstimateLibraryComplexity.jar" -d "$html_file.files_path" -t "$html_file"
+ -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/EstimateLibraryComplexity.jar" -d "$html_file.files_path" -t "$html_file"
</command><inputs><param format="bam,sam" name="input_file" type="data" label="SAM/BAM dataset"
diff -r beb1986edd2838251441fcc47d7474ac1ed24d27 -r 18f2b18d48e845b49332c3fa7d6316cbadae15ef tools/picard/rgPicardMarkDups.xml
--- a/tools/picard/rgPicardMarkDups.xml
+++ b/tools/picard/rgPicardMarkDups.xml
@@ -1,8 +1,8 @@
-<tool name="Mark Duplicate reads" id="rgPicardMarkDups" version="0.01">
+<tool name="Mark Duplicate reads" id="rgPicardMarkDups" version="0.01.1"><command interpreter="python">
picard_wrapper.py -i "$input_file" -n "$out_prefix" --tmpdir "${__new_file_path__}" -o "$out_file"
--remdups "$remDups" --assumesorted "$assumeSorted" --readregex "$readRegex" --optdupdist "$optDupeDist"
- -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/MarkDuplicates.jar" -d "$html_file.files_path" -t "$html_file" -e "$input_file.ext"
+ -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/MarkDuplicates.jar" -d "$html_file.files_path" -t "$html_file" -e "$input_file.ext"
</command><requirements><requirement type="package">picard</requirement></requirements><inputs>
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

25 Oct '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/beb1986edd28/
changeset: beb1986edd28
user: dan
date: 2011-10-25 15:40:26
summary: Minor cleanup in picard_SamToFastq.xml
affected #: 1 file
diff -r 1b05c45a0c1ac22c4bac8c2f8685eae32ca67ce6 -r beb1986edd2838251441fcc47d7474ac1ed24d27 tools/picard/picard_SamToFastq.xml
--- a/tools/picard/picard_SamToFastq.xml
+++ b/tools/picard/picard_SamToFastq.xml
@@ -39,7 +39,6 @@
#end if
2>&1
|| echo "Error running SamToFastq" >&2
- ##&& echo "die die die" >&2
</command><inputs><param name="input_sam" type="data" format="sam" label="SAM file" />
@@ -85,6 +84,7 @@
<param name="read1_max_bases_to_write" value="" /><param name="re_reverse" value="True" /><param name="include_non_pf_reads" value="False" />
+ <param name="clipping_action" value="" /><param name="clipping_attribute" value="" /><param name="include_non_primary_alignments" value="False" /><output name="output_fastq1" file="random_phiX_1.fastqsanger"/>
@@ -99,6 +99,7 @@
<param name="read2_max_bases_to_write" value="" /><param name="re_reverse" value="True" /><param name="include_non_pf_reads" value="False" />
+ <param name="clipping_action" value="" /><param name="clipping_attribute" value="" /><param name="include_non_primary_alignments" value="False" /><output name="output_fastq1" file="bwa_wrapper_in2.fastqsanger" lines_diff="64"/><!-- 16 unaligned fastq blocks not present in original sam 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
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/b1134c82e101/
changeset: b1134c82e101
user: jgoecks
date: 2011-10-25 02:28:28
summary: Trackster: refactor constructor code for cleaner initialization.
affected #: 1 file
diff -r d0842bf94ff95b7b34cb46f5dbcc9a25167110c7 -r b1134c82e101b47545531f2318a9b060342c9fd2 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -2558,7 +2558,9 @@
predraw_init: function() {}
});
-var TiledTrack = function(filters_list, tool_dict) {
+var TiledTrack = function(name, view, container, show_header, prefs, filters_list, tool_dict, data_url, data_query_wait) {
+ Track.call(this, name, view, container, show_header, prefs, data_url, data_query_wait);
+
var track = this,
view = track.view;
@@ -2938,8 +2940,7 @@
});
var ReferenceTrack = function (view) {
- Track.call(this, "reference", view, { content_div: view.top_labeltrack }, false, {});
- TiledTrack.call(this);
+ TiledTrack.call(this, "reference", view, { content_div: view.top_labeltrack }, false, {});
view.reference_track = this;
this.left_offset = 200;
@@ -2991,8 +2992,7 @@
var track = this;
this.display_modes = ["Histogram", "Line", "Filled", "Intensity"];
this.mode = "Histogram";
- Track.call( this, name, view, container, prefs );
- TiledTrack.call( this );
+ TiledTrack.call( this, name, view, container, true, prefs );
this.min_height_px = 16;
this.max_height_px = 400;
@@ -3137,11 +3137,8 @@
//
// Initialization.
- //
-
- // FIXME: cleaner init needed; should just be able to call TiledTrack()
- Track.call(this, name, view, container, true, prefs);
- TiledTrack.call(this, filters, tool);
+ //
+ TiledTrack.call(this, name, view, container, true, prefs, filters, tool);
// Define and restore track configuration.
this.config = new DrawableConfig( {
https://bitbucket.org/galaxy/galaxy-central/changeset/1b05c45a0c1a/
changeset: 1b05c45a0c1a
user: jgoecks
date: 2011-10-25 04:08:57
summary: Merge.
affected #: 3 files
diff -r b1134c82e101b47545531f2318a9b060342c9fd2 -r 1b05c45a0c1ac22c4bac8c2f8685eae32ca67ce6 tools/gatk/variant_apply_recalibration.xml
--- a/tools/gatk/variant_apply_recalibration.xml
+++ b/tools/gatk/variant_apply_recalibration.xml
@@ -102,9 +102,9 @@
<param name="input_recal" type="data" format="gatk_recal" label="Variant Recalibration file" /><param name="input_tranches" type="data" format="gatk_tranche" label="Variant Tranches file" /><param name="ref_file" type="select" label="Using reference genome">
- <!-- <options from_data_table="picard_indexes">
- <filter type="data_meta" key="dbkey" ref="variants[0].input_variants" column="dbkey"/>
- </options> -->
+ <options from_data_table="picard_indexes">
+ <!-- <filter type="data_meta" key="dbkey" ref="variants[0].input_variants" column="dbkey"/> -->
+ </options></param></when><when value="history"><!-- FIX ME!!!! -->
diff -r b1134c82e101b47545531f2318a9b060342c9fd2 -r 1b05c45a0c1ac22c4bac8c2f8685eae32ca67ce6 tools/gatk/variant_eval.xml
--- a/tools/gatk/variant_eval.xml
+++ b/tools/gatk/variant_eval.xml
@@ -159,9 +159,9 @@
<param name="input_variant" type="data" format="vcf" label="Input variant file" /></repeat><param name="ref_file" type="select" label="Using reference genome">
- <!--<options from_data_table="picard_indexes">
- <filter type="data_meta" key="dbkey" ref="input_variant" column="dbkey"/>
- </options>-->
+ <options from_data_table="picard_indexes">
+ <!-- <filter type="data_meta" key="dbkey" ref="input_variant" column="dbkey"/> -->
+ </options></param></when><when value="history"><!-- FIX ME!!!! -->
diff -r b1134c82e101b47545531f2318a9b060342c9fd2 -r 1b05c45a0c1ac22c4bac8c2f8685eae32ca67ce6 tools/gatk/variant_recalibrator.xml
--- a/tools/gatk/variant_recalibrator.xml
+++ b/tools/gatk/variant_recalibrator.xml
@@ -152,9 +152,9 @@
<param name="input_variants" type="data" format="vcf" label="Variant file to recalibrate" /></repeat><param name="ref_file" type="select" label="Using reference genome">
- <!-- <options from_data_table="picard_indexes">
- <filter type="data_meta" key="dbkey" ref="variants[0].input_variants" column="dbkey"/>
- </options> -->
+ <options from_data_table="picard_indexes">
+ <!-- <filter type="data_meta" key="dbkey" ref="variants[0].input_variants" column="dbkey"/> -->
+ </options></param></when><when value="history"><!-- FIX ME!!!! -->
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/a019781b2a3b/
changeset: a019781b2a3b
user: dan
date: 2011-10-24 23:54:48
summary: GATK updates.
affected #: 3 files
diff -r d0842bf94ff95b7b34cb46f5dbcc9a25167110c7 -r a019781b2a3b0a7e1f25e278f1c234ae1eab4897 tools/gatk/variant_apply_recalibration.xml
--- a/tools/gatk/variant_apply_recalibration.xml
+++ b/tools/gatk/variant_apply_recalibration.xml
@@ -102,9 +102,9 @@
<param name="input_recal" type="data" format="gatk_recal" label="Variant Recalibration file" /><param name="input_tranches" type="data" format="gatk_tranche" label="Variant Tranches file" /><param name="ref_file" type="select" label="Using reference genome">
- <!-- <options from_data_table="picard_indexes">
- <filter type="data_meta" key="dbkey" ref="variants[0].input_variants" column="dbkey"/>
- </options> -->
+ <options from_data_table="picard_indexes">
+ <!-- <filter type="data_meta" key="dbkey" ref="variants[0].input_variants" column="dbkey"/> -->
+ </options></param></when><when value="history"><!-- FIX ME!!!! -->
diff -r d0842bf94ff95b7b34cb46f5dbcc9a25167110c7 -r a019781b2a3b0a7e1f25e278f1c234ae1eab4897 tools/gatk/variant_eval.xml
--- a/tools/gatk/variant_eval.xml
+++ b/tools/gatk/variant_eval.xml
@@ -159,9 +159,9 @@
<param name="input_variant" type="data" format="vcf" label="Input variant file" /></repeat><param name="ref_file" type="select" label="Using reference genome">
- <!--<options from_data_table="picard_indexes">
- <filter type="data_meta" key="dbkey" ref="input_variant" column="dbkey"/>
- </options>-->
+ <options from_data_table="picard_indexes">
+ <!-- <filter type="data_meta" key="dbkey" ref="input_variant" column="dbkey"/> -->
+ </options></param></when><when value="history"><!-- FIX ME!!!! -->
diff -r d0842bf94ff95b7b34cb46f5dbcc9a25167110c7 -r a019781b2a3b0a7e1f25e278f1c234ae1eab4897 tools/gatk/variant_recalibrator.xml
--- a/tools/gatk/variant_recalibrator.xml
+++ b/tools/gatk/variant_recalibrator.xml
@@ -152,9 +152,9 @@
<param name="input_variants" type="data" format="vcf" label="Variant file to recalibrate" /></repeat><param name="ref_file" type="select" label="Using reference genome">
- <!-- <options from_data_table="picard_indexes">
- <filter type="data_meta" key="dbkey" ref="variants[0].input_variants" column="dbkey"/>
- </options> -->
+ <options from_data_table="picard_indexes">
+ <!-- <filter type="data_meta" key="dbkey" ref="variants[0].input_variants" column="dbkey"/> -->
+ </options></param></when><when value="history"><!-- FIX ME!!!! -->
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: jgoecks: Trackster: set new track color randomly using W3C metrics.
by Bitbucket 24 Oct '11
by Bitbucket 24 Oct '11
24 Oct '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/d0842bf94ff9/
changeset: d0842bf94ff9
user: jgoecks
date: 2011-10-24 23:47:50
summary: Trackster: set new track color randomly using W3C metrics.
affected #: 2 files
diff -r b009d6f136421d196ab735e8cd81224ca537d764 -r d0842bf94ff95b7b34cb46f5dbcc9a25167110c7 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 trackster_module=function(f,Z){var q=f("class").extend,t=f("slotting"),N=f("painters");var ag=function(ah,ai){this.document=ah;this.default_font=ai!==undefined?ai:"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")};q(ag.prototype,{load_pattern:function(ah,al){var ai=this.patterns,aj=this.dummy_context,ak=new Image();ak.src=image_path+al;ak.onload=function(){ai[ah]=aj.createPattern(ak,"repeat")}},get_pattern:function(ah){return this.patterns[ah]},new_canvas:function(){var ah=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(ah)}ah.manager=this;return ah}});var o={};var m=function(ah,ai){o[ah.attr("id")]=ai};var n=function(ah,aj,al,ak){al=".group";var ai={};o[ah.attr("id")]=ak;ah.bind("drag",{handle:"."+aj,relative:true},function(au,av){var at=$(this);var ay=$(this).parent(),ap=ay.children(),ar=o[$(this).attr("id")],ao,an,aw,am,aq;an=$(this).parents(al);if(an.length!==0){aw=an.position().top;am=aw+an.outerHeight();if(av.offsetY<aw){$(this).insertBefore(an);var ax=o[an.attr("id")];ax.remove_drawable(ar);ax.container.add_drawable_before(ar,ax);return}else{if(av.offsetY>am){$(this).insertAfter(an);var ax=o[an.attr("id")];ax.remove_drawable(ar);ax.container.add_drawable(ar);return}}}an=null;for(aq=0;aq<ap.length;aq++){ao=$(ap.get(aq));aw=ao.position().top;am=aw+ao.outerHeight();if(ao.is(al)&&this!==ao.get(0)&&av.offsetY>=aw&&av.offsetY<=am){if(av.offsetY-aw<am-av.offsetY){ao.find(".content-div").prepend(this)}else{ao.find(".content-div").append(this)}if(ar.container){ar.container.remove_drawable(ar)}o[ao.attr("id")].add_drawable(ar);return}}for(aq=0;aq<ap.length;aq++){if(av.offsetY<$(ap.get(aq)).position().top){break}}if(aq===ap.length){if(this!==ap.get(aq-1)){ay.append(this);o[ay.attr("id")].move_drawable(ar,aq)}}else{if(this!==ap.get(aq)){$(this).insertBefore(ap.get(aq));o[ay.attr("id")].move_drawable(ar,(av.deltaY>0?aq-1:aq))}}}).bind("dragstart",function(){ai["border-top"]=ah.css("border-top");ai["border-bottom"]=ah.css("border-bottom");$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css(ai)})};Z.moveable=n;var af=16,I=9,F=20,U=I+2,A=100,K=12000,S=200,D=5,w=10,M=5000,x=100,p="There was an error in indexing this dataset. ",L="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",G="No data for this chrom/contig.",u="Currently indexing... please wait",y="Tool cannot be rerun: ",a="Loading data...",aa="Ready for display",d=10,v=5,C=5;function ab(ai,ah){if(!ah){ah=0}var aj=Math.pow(10,ah);return Math.round(ai*aj)/aj}var c=function(ah){this.num_elements=ah;this.clear()};q(c.prototype,{get:function(ai){var ah=this.key_ary.indexOf(ai);if(ah!==-1){if(this.obj_cache[ai].stale){this.key_ary.splice(ah,1);delete this.obj_cache[ai]}else{this.move_key_to_end(ai,ah)}}return this.obj_cache[ai]},set:function(ai,aj){if(!this.obj_cache[ai]){if(this.key_ary.length>=this.num_elements){var ah=this.key_ary.shift();delete this.obj_cache[ah]}this.key_ary.push(ai)}this.obj_cache[ai]=aj;return aj},move_key_to_end:function(ai,ah){this.key_ary.splice(ah,1);this.key_ary.push(ai)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var T=function(ai,ah,aj){c.call(this,ai);this.track=ah;this.subset=(aj!==undefined?aj:true)};q(T.prototype,c.prototype,{load_data:function(aq,al,ao,ai,an){var ap=this.track.view.chrom,ak={chrom:ap,low:aq,high:al,mode:ao,resolution:ai,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(ak,an);if(this.track.filters_manager){var ar=[];var ah=this.track.filters_manager.filters;for(var am=0;am<ah.length;am++){ar[ar.length]=ah[am].name}ak.filter_cols=JSON.stringify(ar)}var aj=this;return $.getJSON(this.track.data_url,ak,function(at){aj.set_data(aq,al,ao,at)})},get_data:function(ah,al,am,ai,ak){var aj=this.get_data_from_cache(ah,al,am);if(aj){return aj}aj=this.load_data(ah,al,am,ai,ak);this.set_data(ah,al,am,aj);return aj},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(ap,ak,ao,aj,an,al){var aq=this.get_data_from_cache(ap,ak,ao);if(!aq){console.log("ERROR: no current data for: ",this.track,ap,ak,ao,aj,an);return}aq.stale=true;var ai=ap;if(al===this.DEEP_DATA_REQ){$.extend(an,{start_val:aq.data.length+1})}else{if(al===this.BROAD_DATA_REQ){ai=(aq.max_high?aq.max_high:aq.data[aq.data.length-1][2])+1}}var ah=this,am=this.load_data(ai,ak,ao,aj,an);new_data_available=$.Deferred();this.set_data(ap,ak,ao,new_data_available);$.when(am).then(function(ar){if(ar.data){ar.data=aq.data.concat(ar.data);if(ar.max_low){ar.max_low=aq.max_low}if(ar.message){ar.message=ar.message.replace(/[0-9]+/,ar.data.length)}}ah.set_data(ap,ak,ao,ar);new_data_available.resolve(ar)});return new_data_available},get_data_from_cache:function(ah,ai,aj){return this.get(this.gen_key(ah,ai,aj))},set_data:function(ai,aj,ak,ah){return this.set(this.gen_key(ai,aj,ak),ah)},gen_key:function(ah,aj,ak){var ai=ah+"_"+aj+"_"+ak;return ai},split_key:function(ah){return ah.split("_")}});var J=function(ai,ah,aj){T.call(this,ai,ah,aj)};q(J.prototype,T.prototype,c.prototype,{load_data:function(ah,ak,al,ai,aj){if(ai>1){return{data:null}}return T.prototype.load_data.call(this,ah,ak,al,ai,aj)}});var r=function(ak,ai,ah,aj,al){this.name=ak;this.view=ai;this.container=ah;this.config=new H({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ak}],saved_values:aj,onchange:function(){this.track.set_name(this.track.config.values.name)}});this.prefs=this.config.values;this.drag_handle_class=al;this.is_overview=false};q(r.prototype,{init:function(){},request_draw:function(){},_draw:function(){},to_json:function(){},update_track_icons:function(){},set_name:function(ah){this.old_name=this.name;this.name=ah;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 z=function(al,ak,ai,ah,aj,am){r.call(this,ak,ai,ah,aj,am);this.obj_type=al;this.drawables=[]};q(z.prototype,r.prototype,{init:function(){for(var ah=0;ah<this.drawables.length;ah++){this.drawables[ah].init()}},_draw:function(){for(var ah=0;ah<this.drawables.length;ah++){this.drawables[ah]._draw()}},to_json:function(){var ai=[];for(var ah=0;ah<this.drawables.length;ah++){ai.push(this.drawables[ah].to_json())}return{name:this.name,prefs:this.prefs,obj_type:this.obj_type,drawables:ai}},add_drawable:function(ah){this.drawables.push(ah);ah.container=this},add_drawable_before:function(aj,ah){var ai=this.drawables.indexOf(ah);if(ai!=-1){this.drawables.splice(ai,0,aj);return true}return false},remove_drawable:function(ai){var ah=this.drawables.indexOf(ai);if(ah!=-1){this.drawables.splice(ah,1);ai.container=null;return true}return false},move_drawable:function(ai,aj){var ah=this.drawables.indexOf(ai);if(ah!=-1){this.drawables.splice(ah,1);this.drawables.splice(aj,0,ai);return true}return false}});var R=function(ak,ai,ah,aj){z.call(this,"DrawableGroup",ak,ai,ah,aj,"group-handle");if(!R.id_counter){R.id_counter=0}var al=R.id_counter++;this.container_div=$("<div/>").addClass("group").attr("id","group_"+al).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_"+al+"_content_div").appendTo(this.container_div);m(this.container_div,this);m(this.content_div,this);n(this.container_div,this.drag_handle_class,".group",this);this.update_track_icons()};q(R.prototype,r.prototype,z.prototype,{update_track_icons:function(){var ai=this;var ah={};ah["Edit configuration"]=function(){var al=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},aj=function(){ai.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ak=function(am){if((am.keyCode||am.which)===27){al()}else{if((am.keyCode||am.which)===13){aj()}}};$(window).bind("keypress.check_enter_esc",ak);show_modal("Configure Group",ai.config.build_form(),{Cancel:al,OK:aj})};ah.Remove=function(){ai.remove()};make_popupmenu(ai.name_div,ah)}});var ae=function(ah,ak,aj,ai){z.call(this,"View");this.container=ah;this.chrom=null;this.vis_id=aj;this.dbkey=ai;this.title=ak;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 ag(ah.get(0).ownerDocument);this.reset()};q(ae.prototype,z.prototype,{init:function(){var aj=this.container,ah=this;this.top_container=$("<div/>").addClass("top-container").appendTo(aj);this.browser_content_div=$("<div/>").addClass("content").css("position","relative").appendTo(aj);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(aj);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;m(this.viewport_container,ah);this.intro_div=$("<div/>").addClass("intro");var ak=$("<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 ai=function(al){if(al.type==="focusout"||(al.keyCode||al.which)===13||(al.keyCode||al.which)===27){if((al.keyCode||al.which)!==27){ah.go_to($(this).val())}$(this).hide();$(this).val("");ah.location_span.show();ah.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ai).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.click(function(){ah.location_span.hide();ah.chrom_select.hide();ah.nav_input.val(ah.chrom+":"+ah.low+"-"+ah.high);ah.nav_input.css("display","inline-block");ah.nav_input.select();ah.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(){ah.zoom_out();ah.request_redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){ah.zoom_in();ah.request_redraw()}).appendTo(this.nav_controls);this.load_chroms_deferred=this.load_chroms({low:0});this.chrom_select.bind("change",function(){ah.change_chrom(ah.chrom_select.val())});this.browser_content_div.click(function(al){$(this).find("input").trigger("blur")});this.browser_content_div.bind("dblclick",function(al){ah.zoom_in(al.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(al,am){this.current_x=am.offsetX}).bind("drag",function(al,an){var ao=an.offsetX-this.current_x;this.current_x=an.offsetX;var am=Math.round(ao/ah.viewport_container.width()*(ah.max_high-ah.max_low));ah.move_delta(-am)});this.overview_close.click(function(){ah.reset_overview()});this.viewport_container.bind("draginit",function(al,am){if(al.clientX>ah.viewport_container.width()-16){return false}}).bind("dragstart",function(al,am){am.original_low=ah.low;am.current_height=al.clientY;am.current_x=am.offsetX}).bind("drag",function(an,ap){var al=$(this);var aq=ap.offsetX-ap.current_x;var am=al.scrollTop()-(an.clientY-ap.current_height);al.scrollTop(am);ap.current_height=an.clientY;ap.current_x=ap.offsetX;var ao=Math.round(aq/ah.viewport_container.width()*(ah.high-ah.low));ah.move_delta(ao)}).bind("mousewheel",function(an,ap,am,al){if(am){var ao=Math.round(-am/ah.viewport_container.width()*(ah.high-ah.low));ah.move_delta(ao)}});this.top_labeltrack.bind("dragstart",function(al,am){return $("<div />").css({height:ah.browser_content_div.height()+ah.top_labeltrack.height()+ah.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ap,aq){$(aq.proxy).css({left:Math.min(ap.pageX,aq.startX),width:Math.abs(ap.pageX-aq.startX)});var am=Math.min(ap.pageX,aq.startX)-ah.container.offset().left,al=Math.max(ap.pageX,aq.startX)-ah.container.offset().left,ao=(ah.high-ah.low),an=ah.viewport_container.width();ah.update_location(Math.round(am/an*ao)+ah.low,Math.round(al/an*ao)+ah.low)}).bind("dragend",function(aq,ar){var am=Math.min(aq.pageX,ar.startX),al=Math.max(aq.pageX,ar.startX),ao=(ah.high-ah.low),an=ah.viewport_container.width(),ap=ah.low;ah.low=Math.round(am/an*ao)+ap;ah.high=Math.round(al/an*ao)+ap;$(ar.proxy).remove();ah.request_redraw()});this.add_label_track(new ad(this,{content_div:this.top_labeltrack}));this.add_label_track(new ad(this,{content_div:this.nav_labeltrack}));$(window).bind("resize",function(){ah.resize_window()});$(document).bind("redraw",function(){ah.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(ah,ai){this.location_span.text(commatize(ah)+" - "+commatize(ai));this.nav_input.val(this.chrom+":"+commatize(ah)+"-"+commatize(ai))},load_chroms:function(aj){aj.num=x;$.extend(aj,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var ah=this,ai=$.Deferred();$.ajax({url:chrom_url,data:aj,dataType:"json",success:function(al){if(al.chrom_info.length===0){alert("Invalid chromosome: "+aj.chrom);return}if(al.reference){ah.add_label_track(new B(ah))}ah.chrom_data=al.chrom_info;var ao='<option value="">Select Chrom/Contig</option>';for(var an=0,ak=ah.chrom_data.length;an<ak;an++){var am=ah.chrom_data[an].chrom;ao+='<option value="'+am+'">'+am+"</option>"}if(al.prev_chroms){ao+='<option value="previous">Previous '+x+"</option>"}if(al.next_chroms){ao+='<option value="next">Next '+x+"</option>"}ah.chrom_select.html(ao);ah.chrom_start_index=al.start_index;ai.resolve(al)},error:function(){alert("Could not load chroms for this dbkey:",ah.dbkey)}});return ai},change_chrom:function(am,ai,ao){if(!am||am==="None"){return}var aj=this;if(am==="previous"){aj.load_chroms({low:this.chrom_start_index-x});return}if(am==="next"){aj.load_chroms({low:this.chrom_start_index+x});return}var an=$.grep(aj.chrom_data,function(ap,aq){return ap.chrom===am})[0];if(an===undefined){aj.load_chroms({chrom:am},function(){aj.change_chrom(am,ai,ao)});return}else{if(am!==aj.chrom){aj.chrom=am;aj.chrom_select.val(aj.chrom);aj.max_high=an.len-1;aj.reset();aj.request_redraw(true);for(var al=0,ah=aj.drawables.length;al<ah;al++){var ak=aj.drawables[al];if(ak.init){ak.init()}}}if(ai!==undefined&&ao!==undefined){aj.low=Math.max(ai,0);aj.high=Math.min(ao,aj.max_high)}aj.reset_overview();aj.request_redraw()}},go_to:function(al){var ap=this,ah,ak,ai=al.split(":"),an=ai[0],ao=ai[1];if(ao!==undefined){try{var am=ao.split("-");ah=parseInt(am[0].replace(/,/g,""),10);ak=parseInt(am[1].replace(/,/g,""),10)}catch(aj){return false}}ap.change_chrom(an,ah,ak)},move_fraction:function(aj){var ah=this;var ai=ah.high-ah.low;this.move_delta(aj*ai)},move_delta:function(aj){var ah=this;var ai=ah.high-ah.low;if(ah.low-aj<ah.max_low){ah.low=ah.max_low;ah.high=ah.max_low+ai}else{if(ah.high-aj>ah.max_high){ah.high=ah.max_high;ah.low=ah.max_high-ai}else{ah.high-=aj;ah.low-=aj}}ah.request_redraw()},add_drawable:function(ah){z.prototype.add_drawable.call(this,ah);ah.init();this.has_changes=true;this.update_intro_div()},add_label_track:function(ah){ah.view=this;ah.init();this.label_tracks.push(ah)},remove_drawable:function(aj,ai){z.prototype.remove_drawable.call(this,aj);if(ai){var ah=this;aj.container_div.fadeOut("slow",function(){$(this).remove();ah.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(ap,ah,ao,ai){var an=this,al=(ai?[ai]:an.drawables),aj;var ai;for(var am=0;am<al.length;am++){ai=al[am];aj=-1;for(var ak=0;ak<an.tracks_to_be_redrawn.length;ak++){if(an.tracks_to_be_redrawn[ak][0]===ai){aj=ak;break}}if(aj<0){an.tracks_to_be_redrawn.push([ai,ah,ao])}else{an.tracks_to_be_redrawn[am][1]=ah;an.tracks_to_be_redrawn[am][2]=ao}}requestAnimationFrame(function(){an._redraw(ap)})},_redraw:function(ar){var ao=this.low,ak=this.high;if(ao<this.max_low){ao=this.max_low}if(ak>this.max_high){ak=this.max_high}var aq=this.high-this.low;if(this.high!==0&&aq<this.min_separation){ak=ao+this.min_separation}this.low=Math.floor(ao);this.high=Math.ceil(ak);this.resolution=Math.pow(D,Math.ceil(Math.log((this.high-this.low)/S)/Math.log(D)));this.zoom_res=Math.pow(w,Math.max(0,Math.ceil(Math.log(this.resolution,w)/Math.log(w))));var ah=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var an=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var at=13;this.overview_box.css({left:ah,width:Math.max(at,an)}).show();if(an<at){this.overview_box.css("left",ah-(at-an)/2)}if(this.overview_highlight){this.overview_highlight.css({left:ah,width:an})}this.update_location(this.low,this.high);if(!ar){var aj,ai,ap;for(var al=0,am=this.tracks_to_be_redrawn.length;al<am;al++){aj=this.tracks_to_be_redrawn[al][0];ai=this.tracks_to_be_redrawn[al][1];ap=this.tracks_to_be_redrawn[al][2];if(aj){aj._draw(ai,ap)}}this.tracks_to_be_redrawn=[];for(al=0,am=this.label_tracks.length;al<am;al++){this.label_tracks[al]._draw()}}},zoom_in:function(ai,aj){if(this.max_high===0||this.high-this.low<this.min_separation){return}var ak=this.high-this.low,al=ak/2+this.low,ah=(ak/this.zoom_factor)/2;if(ai){al=ai/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(al-ah);this.high=Math.round(al+ah);this.request_redraw()},zoom_out:function(){if(this.max_high===0){return}var ai=this.high-this.low,aj=ai/2+this.low,ah=(ai*this.zoom_factor)/2;this.low=Math.round(aj-ah);this.high=Math.round(aj+ah);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(aj){if(this.overview_drawable){if(this.overview_drawable.dataset_id===aj.dataset_id){return}this.overview_viewport.find(".track").remove()}var ai=aj.copy({content_div:this.overview_viewport}),ah=this;ai.header_div.hide();ai.is_overview=true;ah.overview_drawable=ai;this.overview_drawable.postdraw_actions=function(){ah.overview_highlight.show().height(ah.overview_drawable.content_div.height());ah.overview_viewport.height(ah.overview_drawable.content_div.height()+ah.overview_box.outerHeight());ah.overview_close.show();ah.resize_window()};this.overview_drawable.init();ah.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 s=function(aj,an){this.track=aj;this.name=an.name;this.params=[];var av=an.params;for(var ak=0;ak<av.length;ak++){var ap=av[ak],ai=ap.name,au=ap.label,al=unescape(ap.html),aw=ap.value,ar=ap.type;if(ar==="number"){this.params[this.params.length]=new g(ai,au,al,aw,ap.min,ap.max)}else{if(ar=="select"){this.params[this.params.length]=new P(ai,au,al,aw)}else{console.log("WARNING: unrecognized tool parameter type:",ai,ar)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(ay){ay.stopPropagation()}).click(function(ay){ay.stopPropagation()}).bind("dblclick",function(ay){ay.stopPropagation()});var at=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var aq=this.params;var ao=this;$.each(this.params,function(az,aC){var aB=$("<div>").addClass("param-row").appendTo(ao.parent_div);var ay=$("<div>").addClass("param-label").text(aC.label).appendTo(aB);var aA=$("<div/>").addClass("slider").html(aC.html).appendTo(aB);aA.find(":input").val(aC.value);$("<div style='clear: both;'/>").appendTo(aB)});this.parent_div.find("input").click(function(){$(this).select()});var ax=$("<div>").addClass("param-row").appendTo(this.parent_div);var am=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(ax);var ah=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(ax);var ao=this;ah.click(function(){ao.run_on_region()});am.click(function(){ao.run_on_dataset()})};q(s.prototype,{get_param_values_dict:function(){var ah={};this.parent_div.find(":input").each(function(){var ai=$(this).attr("name"),aj=$(this).val();ah[ai]=JSON.stringify(aj)});return ah},get_param_values:function(){var ai=[];var ah={};this.parent_div.find(":input").each(function(){var aj=$(this).attr("name"),ak=$(this).val();if(aj){ai[ai.length]=ak}});return ai},run_on_dataset:function(){var ah=this;ah.run({dataset_id:this.track.original_dataset_id,tool_id:ah.name},null,function(ai){show_modal(ah.name+" is Running",ah.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var ai={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},al=this.track,aj=ai.tool_id+al.tool_region_and_parameters_str(ai.chrom,ai.low,ai.high),ah,am;if(al.container===view){var ak=new R(this.name,this.track.view,this.track.container);al.container.add_drawable(ak);al.container.remove_drawable(al);ak.add_drawable(al);al.container_div.appendTo(ak.content_div);ah=ak}else{ah=al.container}if(al instanceof e){am=new W(aj,view,ah,"hda");am.change_mode(al.mode);ah.add_drawable(am)}am.content_div.text("Starting job.");this.run(ai,am,function(an){am.dataset_id=an.dataset_id;am.content_div.text("Running job.");am.init()})},run:function(ai,aj,ak){$.extend(ai,this.get_param_values_dict());var ah=function(){$.getJSON(rerun_tool_url,ai,function(al){if(al==="no converter"){aj.container_div.addClass("error");aj.content_div.text(L)}else{if(al.error){aj.container_div.addClass("error");aj.content_div.text(y+al.message)}else{if(al==="pending"){aj.container_div.addClass("pending");aj.content_div.text("Converting input data so that it can be used quickly with tool.");setTimeout(ah,2000)}else{ak(al)}}}})};ah()}});var P=function(ai,ah,aj,ak){this.name=ai;this.label=ah;this.html=aj;this.value=ak};var g=function(aj,ai,al,am,ak,ah){P.call(this,aj,ai,al,am);this.min=ak;this.max=ah};var h=function(ai,ah,aj,ak){this.name=ai;this.index=ah;this.tool_id=aj;this.tool_exp_name=ak};var X=function(ai,ah,aj,ak){h.call(this,ai,ah,aj,ak);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};q(X.prototype,{applies_to:function(ah){if(ah.length>this.index){return true}return false},keep:function(ah){if(!this.applies_to(ah)){return true}var ai=ah[this.index];return(isNaN(ai)||(ai>=this.low&&ai<=this.high))},update_attrs:function(ai){var ah=false;if(!this.applies_to(ai)){return ah}if(ai[this.index]<this.min){this.min=Math.floor(ai[this.index]);ah=true}if(ai[this.index]>this.max){this.max=Math.ceil(ai[this.index]);ah=true}return ah},update_ui_elt:function(){if(this.min!=this.max){this.container.show()}else{this.container.hide()}var aj=function(am,ak){var al=ak-am;return(al<=2?0.01:1)};var ai=this.slider.slider("option","min"),ah=this.slider.slider("option","max");if(this.min<ai||this.max>ah){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",aj(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var ac=function(at,aA){this.track=at;this.filters=[];for(var av=0;av<aA.length;av++){var aw=aA[av],aB=aw.name,ah=aw.type,aj=aw.index,az=aw.tool_id,ay=aw.tool_exp_name;if(ah==="int"||ah==="float"){this.filters[av]=new X(aB,aj,az,ay)}else{console.log("ERROR: unsupported filter: ",aB,ah)}}var ak=function(aC,aD,aE){aC.click(function(){var aF=aD.text();max=parseFloat(aE.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(aE.slider("option","values")){input_size=2*input_size+1;multi_value=true}aD.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",aF).appendTo(aD).focus().select().click(function(aG){aG.stopPropagation()}).blur(function(){$(this).remove();aD.text(aF)}).keyup(function(aK){if(aK.keyCode===27){$(this).trigger("blur")}else{if(aK.keyCode===13){var aI=aE.slider("option","min"),aG=aE.slider("option","max"),aJ=function(aL){return(isNaN(aL)||aL>aG||aL<aI)},aH=$(this).val();if(!multi_value){aH=parseFloat(aH);if(aJ(aH)){alert("Parameter value must be in the range ["+aI+"-"+aG+"]");return $(this)}}else{aH=aH.split("-");aH=[parseFloat(aH[0]),parseFloat(aH[1])];if(aJ(aH[0])||aJ(aH[1])){alert("Parameter value must be in the range ["+aI+"-"+aG+"]");return $(this)}}aE.slider((multi_value?"values":"value"),aH)}}})})};this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(aC){aC.stopPropagation()}).click(function(aC){aC.stopPropagation()}).bind("dblclick",function(aC){aC.stopPropagation()}).bind("keydown",function(aC){aC.stopPropagation()});var ax=$("<div/>").addClass("sliders").appendTo(this.parent_div);var ap=this;$.each(this.filters,function(aF,aH){aH.container=$("<div/>").addClass("filter-row slider-row").appendTo(ax);var aG=$("<div/>").addClass("elt-label").appendTo(aH.container);var aE=$("<span/>").addClass("slider-name").text(aH.name+" ").appendTo(aG);var aD=$("<span/>");var aJ=$("<span/>").addClass("slider-value").appendTo(aG).append("[").append(aD).append("]");var aC=$("<div/>").addClass("slider").appendTo(aH.container);aH.control_element=$("<div/>").attr("id",aH.name+"-filter-control").appendTo(aC);var aI=[0,0];aH.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(aL,aM){var aK=aM.values;aD.text(aK[0]+"-"+aK[1]);aH.low=aK[0];aH.high=aK[1];ap.track.request_draw(true,true)},change:function(aK,aL){aH.control_element.slider("option","slide").call(aH.control_element,aK,aL)}});aH.slider=aH.control_element;aH.slider_label=aD;ak(aJ,aD,aH.control_element);$("<div style='clear: both;'/>").appendTo(aH.container)});if(this.filters.length!==0){var am=$("<div/>").addClass("param-row").appendTo(ax);var ao=$("<input type='submit'/>").attr("value","Run on complete dataset").appendTo(am);var ai=this;ao.click(function(){ai.run_on_dataset()})}var ar=$("<div/>").addClass("display-controls").appendTo(this.parent_div),au,an,aq,al={Transparency:function(aC){ap.alpha_filter=aC},Height:function(aC){ap.height_filter=aC}};$.each(al,function(aE,aD){au=$("<div/>").addClass("filter-row").appendTo(ar),an=$("<span/>").addClass("elt-label").text(aE+":").appendTo(au),aq=$("<select/>").attr("name",aE+"_dropdown").css("float","right").appendTo(au);$("<option/>").attr("value",-1).text("== None ==").appendTo(aq);for(var aC=0;aC<ap.filters.length;aC++){$("<option/>").attr("value",aC).text(ap.filters[aC].name).appendTo(aq)}aq.change(function(){$(this).children("option:selected").each(function(){var aF=parseInt($(this).val());al[aE]((aF>=0?ap.filters[aF]:null));ap.track.request_draw(true,true)})});$("<div style='clear: both;'/>").appendTo(au)});$("<div style='clear: both;'/>").appendTo(this.parent_div)};q(ac.prototype,{reset_filters:function(){for(var ah=0;ah<this.filters.length;ah++){filter=this.filters[ah];filter.slider.slider("option","values",[filter.min,filter.max])}this.alpha_filter=null;this.height_filter=null},run_on_dataset:function(){var ap=function(au,ar,at){if(!(ar in au)){au[ar]=at}return au[ar]};var aj={},ah,ai,ak;for(var al=0;al<this.filters.length;al++){ah=this.filters[al];if(ah.tool_id){if(ah.min!=ah.low){ai=ap(aj,ah.tool_id,[]);ai[ai.length]=ah.tool_exp_name+" >= "+ah.low}if(ah.max!=ah.high){ai=ap(aj,ah.tool_id,[]);ai[ai.length]=ah.tool_exp_name+" <= "+ah.high}}}var an=[];for(var aq in aj){an[an.length]=[aq,aj[aq]]}var ao=an.length;(function am(ay,av){var at=av[0],au=at[0],ax=at[1],aw="("+ax.join(") and (")+")",ar={cond:aw,input:ay,target_dataset_id:ay,tool_id:au},av=av.slice(1);$.getJSON(run_tool_url,ar,function(az){if(az.error){show_modal("Filter Dataset","Error running tool "+au,{Close:hide_modal})}else{if(av.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{am(az.dataset_id,av)}}})})(this.track.dataset_id,an)}});var E=function(ah,ai){N.Scaler.call(this,ai);this.filter=ah};E.prototype.gen_val=function(ah){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(ah[this.filter.index])-this.filter.low)/(this.filter.high-this.filter.low))};var H=function(ah){this.track=ah.track;this.params=ah.params;this.values={};this.restore_values((ah.saved_values?ah.saved_values:{}));this.onchange=ah.onchange};q(H.prototype,{restore_values:function(ah){var ai=this;$.each(this.params,function(aj,ak){if(ah[ak.key]!==undefined){ai.values[ak.key]=ah[ak.key]}else{ai.values[ak.key]=ak.default_value}})},build_form:function(){var ai=this;var ah=$("<div />");$.each(this.params,function(am,ak){if(!ak.hidden){var aj="param_"+am;var ao=ai.values[ak.key];var ar=$("<div class='form-row' />").appendTo(ah);ar.append($("<label />").attr("for",aj).text(ak.label+":"));if(ak.type==="bool"){ar.append($('<input type="checkbox" />').attr("id",aj).attr("name",aj).attr("checked",ao))}else{if(ak.type==="text"){ar.append($('<input type="text"/>').attr("id",aj).val(ao).click(function(){$(this).select()}))}else{if(ak.type==="color"){var an=$("<input />").attr("id",aj).attr("name",aj).val(ao);var ap=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var al=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(ap);var aq=$("<div/>").appendTo(al).farbtastic({width:100,height:100,callback:an,color:ao});$("<div />").append(an).append(ap).appendTo(ar).bind("click",function(at){ap.css({left:$(this).position().left+($(an).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){ap.hide();$(document).unbind("click.color-picker")});at.stopPropagation()})}else{ar.append($("<input />").attr("id",aj).attr("name",aj).val(ao))}}}}});return ah},update_from_form:function(ah){var aj=this;var ai=false;$.each(this.params,function(ak,am){if(!am.hidden){var an="param_"+ak;var al=ah.find("#"+an).val();if(am.type==="float"){al=parseFloat(al)}else{if(am.type==="int"){al=parseInt(al)}else{if(am.type==="bool"){al=ah.find("#"+an).is(":checked")}}}if(al!==aj.values[am.key]){aj.values[am.key]=al;ai=true}}});if(ai){this.onchange()}}});var b=function(ah,ak,aj,ai,al){this.track=ah;this.index=ak;this.low=ak*S*aj;this.high=(ak+1)*S*aj;this.resolution=aj;this.canvas=$("<div class='track-tile'/>").append(ai);this.data=al;this.stale=false};b.prototype.predisplay_actions=function(){};var l=function(ah,ak,aj,ai,al,am){b.call(this,ah,ak,aj,ai,al);this.max_val=am};q(l.prototype,b.prototype);var Q=function(ah,al,ak,aj,an,ao,am,ai){b.call(this,ah,al,ak,aj,an);this.mode=ao;this.message=am;this.feature_mapper=ai};q(Q.prototype,b.prototype);Q.prototype.predisplay_actions=function(){var ai=this,ah={};if(ai.mode!=="Pack"){return}$(this.canvas).mousemove(function(au){var ao=$(this).offset(),at=au.pageX-ao.left,ar=au.pageY-ao.top,ay=ai.feature_mapper.get_feature_data(at,ar),ap=(ay?ay[0]:null);$(this).siblings(".feature-popup").each(function(){if(!ap||$(this).attr("id")!==ap.toString()){$(this).remove()}});if(ay){var ak=ah[ap];if(!ak){var ap=ay[0],av={name:ay[3],start:ay[1],end:ay[2],strand:ay[4]},an=ai.track.filters_manager.filters,am;for(var aq=0;aq<an.length;aq++){am=an[aq];av[am.name]=ay[am.index]}var ak=$("<div/>").attr("id",ap).addClass("feature-popup"),ax,aw,az=$("<table/>").appendTo(ak),aA;for(ax in av){aw=av[ax];aA=$("<tr/>").appendTo(az);$("<th/>").appendTo(aA).text(ax);$("<td/>").attr("align","left").appendTo(aA).text(typeof(aw)=="number"?ab(aw,2):aw)}ah[ap]=ak}ak.appendTo($(ai.canvas).parent());var al=at+parseInt(ai.canvas.css("left"))+7,aj=ar+parseInt(ai.canvas.css("top"))+7;ak.css("left",al+"px").css("top",aj+"px")}else{if(!au.isPropagationStopped()){au.stopPropagation();$(this).siblings().each(function(){$(this).trigger(au)})}}}).mouseleave(function(){$(this).siblings(".feature-popup").remove()})};var j=function(ak,at,al,ao,au,aj,ai){r.call(this,ak,at,al,{},"draghandle");this.data_url=(aj?aj:default_data_url);this.data_url_extra_params={};this.data_query_wait=(ai?ai:M);this.dataset_check_url=converted_datasets_state_url;if(!j.id_counter){j.id_counter=0}this.id=j.id_counter++;this.container_div=$("<div />").addClass("track").attr("id","track_"+this.id).css("position","relative");if(ao){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 am=this;this.header_div.dblclick(function(av){av.stopPropagation()});this.settings_icon.click(function(){var ax=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},av=function(){am.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},aw=function(ay){if((ay.keyCode||ay.which)===27){ax()}else{if((ay.keyCode||ay.which)===13){av()}}};$(window).bind("keypress.check_enter_esc",aw);show_modal("Configure Track",am.config.build_form(),{Cancel:ax,OK:av})});this.overview_icon.click(function(){am.view.set_overview(am)});this.filters_icon.click(function(){am.filters_div.toggle();am.filters_manager.reset_filters()});this.tools_icon.click(function(){am.dynamic_tool_div.toggle();if(am.dynamic_tool_div.is(":visible")){am.set_name(am.name+am.tool_region_and_parameters_str())}else{am.revert_name()}$(".tipsy").remove()});this.remove_icon.click(function(){$(".tipsy").remove();am.remove()});if(am.display_modes!==undefined){if(am.mode_div===undefined){am.mode_div=$("<div class='right-float menubutton popup' />").appendTo(am.header_div);var an=(am.config&&am.config.values.mode?am.config.values.mode:am.display_modes[0]);am.mode=an;am.mode_div.text(an);var ah={};for(var ap=0,ar=am.display_modes.length;ap<ar;ap++){var aq=am.display_modes[ap];ah[aq]=function(av){return function(){am.change_mode(av)}}(aq)}make_popupmenu(am.mode_div,ah)}else{am.mode_div.hide()}this.header_div.append($("<div/>").css("clear","both"));this.container_div.hover(function(){am.icons_div.show()},function(){am.icons_div.hide()})}}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.container.content_div.append(this.container_div)};q(j.prototype,r.prototype,{get_type:function(){if(this instanceof ad){return"LabelTrack"}else{if(this instanceof B){return"ReferenceTrack"}else{if(this instanceof k){return"LineTrack"}else{if(this instanceof Y){return"ReadTrack"}else{if(this instanceof W){return"ToolDataFeatureTrack"}else{if(this instanceof V){return"VcfTrack"}else{if(this instanceof e){return"FeatureTrack"}}}}}}}return""},init:function(){var ah=this;ah.enabled=false;ah.tile_cache.clear();ah.data_manager.clear();ah.initial_canvas=undefined;ah.content_div.css("height","auto");ah.container_div.removeClass("nodata error pending");if(!ah.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:ah.hda_ldda,dataset_id:ah.dataset_id,chrom:ah.view.chrom},function(ai){if(!ai||ai==="error"||ai.kind==="error"){ah.container_div.addClass("error");ah.content_div.text(p);if(ai.message){var aj=$(" <a href='javascript:void(0);'></a>").text("View error").click(function(){show_modal("Trackster Error","<pre>"+ai.message+"</pre>",{Close:hide_modal})});ah.content_div.append(aj)}}else{if(ai==="no converter"){ah.container_div.addClass("error");ah.content_div.text(L)}else{if(ai==="no data"||(ai.data!==undefined&&(ai.data===null||ai.data.length===0))){ah.container_div.addClass("nodata");ah.content_div.text(G)}else{if(ai==="pending"){ah.container_div.addClass("pending");ah.content_div.text(u);setTimeout(function(){ah.init()},ah.data_query_wait)}else{if(ai.status==="data"){if(ai.valid_chroms){ah.valid_chroms=ai.valid_chroms;ah.update_track_icons()}ah.content_div.text(aa);if(ah.view.chrom){ah.content_div.text("");ah.content_div.css("height",ah.height_px+"px");ah.enabled=true;$.when(ah.predraw_init()).done(function(){ah.container_div.removeClass("nodata error pending");ah.request_draw()})}}}}}}});this.update_track_icons()},predraw_init:function(){}});var O=function(ak,aj){var ai=this,ah=ai.view;n(ai.container_div,ai.drag_handle_class,".group",ai);this.filters_manager=new ac(this,(ak!==undefined?ak:{}));this.filters_available=false;this.filters_visible=false;this.tool=(aj!==undefined&&obj_length(aj)>0?new s(this,aj):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)}}};q(O.prototype,r.prototype,j.prototype,{copy:function(ah){return new this.constructor(this.name,this.view,ah,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(ai){var ah=this;ah.mode_div.text(ai);ah.mode=ai;ah.config.values.mode=ai;ah.tile_cache.clear();ah.request_draw();return ah},update_track_icons:function(){var ah=this;if(ah.filters_available>0){ah.filters_icon.show()}else{ah.filters_icon.hide()}if(ah.tool){ah.tools_icon.show()}else{ah.tools_icon.hide()}},_gen_tile_cache_key:function(ai,aj,ah){return ai+"_"+aj+"_"+ah},request_draw:function(ai,ah){this.view.request_redraw(false,ai,ah,this)},_draw:function(aj,ar){if(!this.enabled){return}if(!(this instanceof B)&&(!this.dataset_id)){return}var aq=this.view.low,an=this.view.high,ao=an-aq,ak=this.view.container.width(),av=ak/ao,am=this.view.resolution,au=$("<div style='position: relative;'></div>");if(this.is_overview){aq=this.view.max_low;an=this.view.max_high;am=Math.pow(D,Math.ceil(Math.log((view.max_high-view.max_low)/S)/Math.log(D)));av=ak/(view.max_high-view.max_low)}if(!ar){this.content_div.children().remove()}this.content_div.append(au);this.max_height=0;var ai=Math.floor(aq/am/S);var ap=true;var at=[];var ah=0;while((ai*S*am)<an){tile=this.draw_helper(aj,ak,ai,am,au,av);if(tile){at.push(tile)}else{ap=false}ai+=1;ah++}var al=this;if(ap){al.postdraw_actions(at,ak,av,ar)}},postdraw_actions:function(al,am,an,ah){var aj=this;var ak=false;for(var ai=0;ai<al.length;ai++){if(al[ai].message){ak=true;break}}if(ak){for(var ai=0;ai<al.length;ai++){tile=al[ai];if(!tile.message){tile.canvas.css("padding-top",F)}}}},draw_helper:function(ai,aj,ak,an,au,ay,av,ao){var al=this,at=this._gen_tile_cache_key(aj,ay,ak),ap=ak*S*an,ax=ap+S*an;var aq=(ai?undefined:al.tile_cache.get(at));if(aq){al.show_tile(aq,au,ay);return aq}var ar=function(az){return("isResolved" in az)};var am=true;var ah=al.data_manager.get_data(ap,ax,al.mode,an,al.data_url_extra_params);if(ar(ah)){am=false}var aw;if(view.reference_track&&ay>view.canvas_manager.char_width_px){aw=view.reference_track.data_manager.get_data(ap,ax,al.mode,an,view.reference_track.data_url_extra_params);if(ar(aw)){am=false}}if(am){q(ah,ao);var aq=al.draw_tile(ah,al.mode,an,ak,ay,aw);if(aq!==undefined){al.tile_cache.set(at,aq);al.show_tile(aq,au,ay)}return aq}$.when(ah,aw).then(function(){view.request_redraw(false,false,false,al)});return null},show_tile:function(an,ap,aq){var aj=this,ai=an.canvas,am=ai;if(an.message){var ar=$("<div/>"),ao=$("<div/>").addClass("tile-message").text(an.message).css({height:F-1,width:an.canvas.width}).appendTo(ar),al=$("<a href='javascript:void(0);'/>").addClass("icon more-down").appendTo(ao),ah=$("<a href='javascript:void(0);'/>").addClass("icon more-across").appendTo(ao);ar.append(ai);am=ar;al.click(function(){an.stale=true;aj.data_manager.get_more_data(an.low,an.high,aj.mode,an.resolution,{},aj.data_manager.DEEP_DATA_REQ);aj.request_draw()}).dblclick(function(at){at.stopPropagation()});ah.click(function(){an.stale=true;aj.data_manager.get_more_data(an.low,an.high,aj.mode,an.resolution,{},aj.data_manager.BROAD_DATA_REQ);aj.request_draw()}).dblclick(function(at){at.stopPropagation()})}an.predisplay_actions();var ak=(an.low-(this.is_overview?this.view.max_low:this.view.low))*aq;if(this.left_offset){ak-=this.left_offset}am.css({position:"absolute",top:0,left:ak,height:""});ap.append(am);aj.max_height=Math.max(aj.max_height,am.height());aj.content_div.css("height",aj.max_height+"px");ap.children().css("height",aj.max_height+"px")},_get_tile_bounds:function(ah,ai){var ak=ah*S*ai,al=S*ai,aj=(ak+al<=this.view.max_high?ak+al:this.view.max_high);return[ak,aj]},tool_region_and_parameters_str:function(aj,ah,ak){var ai=this,al=(aj!==undefined&&ah!==undefined&&ak!==undefined?aj+":"+ah+"-"+ak:"all");return" - region=["+al+"], parameters=["+ai.tool.get_param_values().join(", ")+"]"}});var ad=function(ai,ah){j.call(this,"label",ai,ah,false,{});this.container_div.addClass("label-track")};q(ad.prototype,j.prototype,{init:function(){this.enabled=true},_draw:function(){var aj=this.view,ak=aj.high-aj.low,an=Math.floor(Math.pow(10,Math.floor(Math.log(ak)/Math.log(10)))),ah=Math.floor(aj.low/an)*an,al=this.view.container.width(),ai=$("<div style='position: relative; height: 1.3em;'></div>");while(ah<aj.high){var am=(ah-aj.low)/ak*al;ai.append($("<div class='label'>"+commatize(ah)+"</div>").css({position:"absolute",left:am-1}));ah+=an}this.content_div.children(":first").remove();this.content_div.append(ai)}});var B=function(ah){j.call(this,"reference",ah,{content_div:ah.top_labeltrack},false,{});O.call(this);ah.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:ah.dbkey};this.data_manager=new J(C,this,false);this.tile_cache=new c(v)};q(B.prototype,r.prototype,O.prototype,{init:function(){this.enabled=true},draw_tile:function(ar,an,am,ai,at){var al=this,aj=S*am;if(at>this.view.canvas_manager.char_width_px){if(ar.data===null){al.content_div.css("height","0px");return}var ak=this.view.canvas_manager.new_canvas();var aq=ak.getContext("2d");ak.width=Math.ceil(aj*at+al.left_offset);ak.height=al.height_px;aq.font=aq.canvas.manager.default_font;aq.textAlign="center";ar=ar.data;for(var ao=0,ap=ar.length;ao<ap;ao++){var ah=Math.round(ao*at);aq.fillText(ar[ao],ah+al.left_offset,10)}return new b(al,ai,am,ak,ar)}this.content_div.css("height","0px")}});var k=function(am,ak,aj,an,ah,al){var ai=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";j.call(this,am,ak,aj,al);O.call(this);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=an;this.dataset_id=ah;this.original_dataset_id=ah;this.data_manager=new T(C,this);this.tile_cache=new c(v);this.left_offset=0;this.config=new H({track:this,params:[{key:"name",label:"Name",type:"text",default_value:am},{key:"color",label:"Color",type:"color",default_value:"black"},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.height_px,hidden:true}],saved_values:al,onchange:function(){ai.set_name(ai.prefs.name);ai.vertical_range=ai.prefs.max_value-ai.prefs.min_value;$("#linetrack_"+ai.dataset_id+"_minval").text(ai.prefs.min_value);$("#linetrack_"+ai.dataset_id+"_maxval").text(ai.prefs.max_value);ai.tile_cache.clear();ai.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()};q(k.prototype,r.prototype,O.prototype,{add_resize_handle:function(){var ah=this;var ak=false;var aj=false;var ai=$("<div class='track-resize'>");$(ah.container_div).hover(function(){ak=true;ai.show()},function(){ak=false;if(!aj){ai.hide()}});ai.hide().bind("dragstart",function(al,am){aj=true;am.original_height=$(ah.content_div).height()}).bind("drag",function(am,an){var al=Math.min(Math.max(an.original_height+an.deltaY,ah.min_height_px),ah.max_height_px);$(ah.content_div).css("height",al);ah.height_px=al;ah.request_draw(true)}).bind("dragend",function(al,am){ah.tile_cache.clear();aj=false;if(!ak){ai.hide()}ah.config.values.height=ah.height_px}).appendTo(ah.container_div)},predraw_init:function(){var ah=this;ah.vertical_range=undefined;return $.getJSON(ah.data_url,{stats:true,chrom:ah.view.chrom,low:null,high:null,hda_ldda:ah.hda_ldda,dataset_id:ah.dataset_id},function(ai){ah.container_div.addClass("line-track");var ak=ai.data;if(isNaN(parseFloat(ah.prefs.min_value))||isNaN(parseFloat(ah.prefs.max_value))){ah.prefs.min_value=ak.min;ah.prefs.max_value=ak.max;$("#track_"+ah.dataset_id+"_minval").val(ah.prefs.min_value);$("#track_"+ah.dataset_id+"_maxval").val(ah.prefs.max_value)}ah.vertical_range=ah.prefs.max_value-ah.prefs.min_value;ah.total_frequency=ak.total_frequency;ah.container_div.find(".yaxislabel").remove();var al=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ah.dataset_id+"_minval").text(ab(ah.prefs.min_value,3));var aj=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ah.dataset_id+"_maxval").text(ab(ah.prefs.max_value,3));aj.css({position:"absolute",top:"24px",left:"10px"});aj.prependTo(ah.container_div);al.css({position:"absolute",bottom:"2px",left:"10px"});al.prependTo(ah.container_div)})},draw_tile:function(au,am,al,aj,at){if(this.vertical_range===undefined){return}var ah=this._get_tile_bounds(aj,al),an=ah[0],ar=ah[1],ai=Math.ceil((ar-an)*at),ap=this.height_px;var ak=this.view.canvas_manager.new_canvas();ak.width=ai,ak.height=ap;var aq=ak.getContext("2d");var ao=new N.LinePainter(au.data,an,ar,this.prefs,am);ao.draw(aq,ai,ap);return new b(this.track,aj,al,ak,au.data)}});var e=function(ah,an,ai,am,ap,ao,ak,al){var aj=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];j.call(this,ah,an,ai,true,ao);O.call(this,ak,al);this.config=new H({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ah},{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ao,onchange:function(){aj.set_name(aj.prefs.name);aj.tile_cache.clear();aj.request_draw()}});this.prefs=this.config.values;this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=am;this.dataset_id=ap;this.original_dataset_id=ap;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 T(20,this);this.left_offset=200;this.painter=N.LinkedFeaturePainter};q(e.prototype,r.prototype,O.prototype,{postdraw_actions:function(ax,ah,ay,aw){O.prototype.postdraw_actions.call(this,ax,aw);var ak=this;if(aw){var am=ak.content_div.children();var an=false;for(var al=am.length-1,ar=0;al>=ar;al--){var aj=$(am[al]);if(an){aj.remove()}else{if(aj.children().length!==0){an=true}}}}if(ak.mode=="Histogram"){var aq=-1;for(var al=0;al<ax.length;al++){var av=ax[al].max_val;if(av>aq){aq=av}}for(var al=0;al<ax.length;al++){var au=ax[al];if(au.max_val!==aq){au.canvas.remove();ak.draw_helper(true,ah,au.index,au.resolution,au.canvas.parent(),ay,[],{max:aq})}}}if(ak.filters_manager){var ai=ak.filters_manager.filters;for(var ap=0;ap<ai.length;ap++){ai[ap].update_ui_elt()}var ao=false,at;for(var al=0;al<ax.length;al++){if(ax[al].data.length){at=ax[al].data[0];for(var ap=0;ap<ai.length;ap++){if(ai[ap].applies_to(at)){ao=true;break}}}}if(ak.filters_available!==ao){ak.filters_available=ao;if(!ak.filters_available){ak.filters_div.hide()}ak.update_track_icons()}}},update_auto_mode:function(ah){if(this.mode=="Auto"){if(ah=="no_detail"){ah="feature spans"}else{if(ah=="summary_tree"){ah="coverage histogram"}}this.mode_div.text("Auto ("+ah+")")}},incremental_slots:function(al,ai,ak){var aj=this.view.canvas_manager.dummy_context,ah=this.inc_slots[al];if(!ah||(ah.mode!==ak)){ah=new (t.FeatureSlotter)(al,ak==="Pack",A,function(am){return aj.measureText(am)});ah.mode=ak;this.inc_slots[al]=ah}return ah.slot_features(ai)},get_summary_tree_data:function(al,ao,aj,ax){if(ax>aj-ao){ax=aj-ao}var at=Math.floor((aj-ao)/ax),aw=[],ak=0;var am=0,an=0,ar,av=0,ap=[],au,aq;var ai=function(aA,az,aB,ay){aA[0]=az+aB*ay;aA[1]=az+(aB+1)*ay};while(av<ax&&am!==al.length){var ah=false;for(;av<ax&&!ah;av++){ai(ap,ao,av,at);for(an=am;an<al.length;an++){ar=al[an].slice(1,3);if(is_overlap(ar,ap)){ah=true;break}}if(ah){break}}data_start_index=an;aw[aw.length]=au=[ap[0],0];for(;an<al.length;an++){ar=al[an].slice(1,3);if(is_overlap(ar,ap)){au[1]++}else{break}}if(au[1]>ak){ak=au[1]}av++}return{max:ak,delta:at,data:aw}},draw_tile:function(aw,az,aD,aH,ar,ak){var aA=this,am=aA._get_tile_bounds(aH,aD),aK=am[0],ai=am[1],ay=ai-aK,aB=Math.ceil(ay*ar),aQ=25,al=this.left_offset,ax,an;if(az==="Auto"){if(aw.dataset_type==="summary_tree"){az=aw.dataset_type}else{if(aw.extra_info==="no_detail"||aA.is_overview){az="no_detail"}else{var aP=aw.data;if(this.view.high-this.view.low>K){az="Squish"}else{az="Pack"}}}this.update_auto_mode(az)}if(az==="summary_tree"||az==="Histogram"){an=this.summary_draw_height;this.container_div.find(".yaxislabel").remove();var ah=$("<div />").addClass("yaxislabel");ah.text(aw.max);ah.css({position:"absolute",top:"24px",left:"10px",color:this.prefs.label_color});ah.prependTo(this.container_div);var aj=this.view.canvas_manager.new_canvas();aj.width=aB+al;aj.height=an+U;if(aw.dataset_type!="summary_tree"){var at=this.get_summary_tree_data(aw.data,aK,ai,200);if(aw.max){at.max=aw.max}aw=at}var aM=new N.SummaryTreePainter(aw,aK,ai,this.prefs);var aC=aj.getContext("2d");aC.translate(al,U);aM.draw(aC,aB,an);return new l(aA,aH,aD,aj,aw.data,aw.max)}var ax,ap=1;if(az==="no_detail"||az==="Squish"||az==="Pack"){ap=this.incremental_slots(ar,aw.data,az);ax=this.inc_slots[ar].slots}var aq=[];if(aw.data){var au=this.filters_manager.filters;for(var aE=0,aG=aw.data.length;aE<aG;aE++){var ao=aw.data[aE];var aF=false;var av;for(var aJ=0,aO=au.length;aJ<aO;aJ++){av=au[aJ];av.update_attrs(ao);if(!av.keep(ao)){aF=true;break}}if(!aF){aq.push(ao)}}}var aN=(this.filters_manager.alpha_filter?new E(this.filters_manager.alpha_filter):null);var aL=(this.filters_manager.height_filter?new E(this.filters_manager.height_filter):null);var aM=new (this.painter)(aq,aK,ai,this.prefs,az,aN,aL,ak);var an=Math.max(af,aM.get_required_height(ap));var aj=this.view.canvas_manager.new_canvas();var aI=null;aj.width=aB+al;aj.height=an;var aC=aj.getContext("2d");aC.fillStyle=this.prefs.block_color;aC.font=aC.canvas.manager.default_font;aC.textAlign="right";this.container_div.find(".yaxislabel").remove();if(aw.data){aC.translate(al,0);aI=aM.draw(aC,aB,an,ax);aI.translation=-al}return new Q(aA,aH,aD,aj,aw.data,az,aw.message,aI)}});var V=function(al,aj,ai,an,ah,ak,am){e.call(this,al,aj,ai,an,ah,ak,am);this.painter=N.VariantPainter};q(V.prototype,r.prototype,O.prototype,e.prototype);var Y=function(al,aj,ai,an,ah,ak,am){e.call(this,al,aj,ai,an,ah,ak,am);this.config=new H({track:this,params:[{key:"name",label:"Name",type:"text",default_value:al},{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ak,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=N.ReadPainter;this.update_track_icons()};q(Y.prototype,r.prototype,O.prototype,e.prototype);var W=function(al,aj,ai,an,ah,ak,am){e.call(this,al,aj,ai,an,ah,ak,am,{});this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};q(W.prototype,r.prototype,O.prototype,e.prototype,{predraw_init:function(){var ai=this;var ah=function(){if(ai.data_manager.size()===0){setTimeout(ah,300)}else{ai.data_url=default_data_url;ai.data_query_wait=M;ai.dataset_state_url=converted_datasets_state_url;$.getJSON(ai.dataset_state_url,{dataset_id:ai.dataset_id,hda_ldda:ai.hda_ldda},function(aj){})}};ah()}});Z.View=ae;Z.DrawableGroup=R;Z.LineTrack=k;Z.FeatureTrack=e;Z.ReadTrack=Y};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(j,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=j;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(G,H){for(var F=0;F<=z;F++){var D=false,I=h[F];if(I!==undefined){for(var C=0,E=I.length;C<E;C++){var B=I[C];if(H>B[0]&&G<B[1]){D=true;break}}}if(!D){return F}}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(k,y){var v=k("class").extend;var q=function(J,B,H,A,G,E){if(E===undefined){E=4}var D=A-B;var C=G-H;var F=Math.floor(Math.sqrt(D*D+C*C)/E);var K=D/F;var I=C/F;var z;for(z=0;z<F;z++,B+=K,H+=I){if(z%2!==0){continue}J.fillRect(B,H,E,1)}};var r=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 e=function(z){this.default_val=(z?z:1)};e.prototype.gen_val=function(z){return this.default_val};var n=function(B,D,z,A,C){this.data=B;this.view_start=D;this.view_end=z;this.prefs=v({},this.default_prefs,A);this.mode=C};n.prototype.default_prefs={};var w=function(B,D,z,A,C){n.call(this,B,D,z,A,C)};w.prototype.default_prefs={show_counts:false};w.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 c=function(z,D,F,G,B){n.call(this,z,D,F,G,B);if(this.prefs.min_value===undefined){var H=Infinity;for(var A=0,C=this.data.length;A<C;A++){H=Math.min(H,this.data[A][1])}this.prefs.min_value=H}if(this.prefs.max_value===undefined){var E=-Infinity;for(var A=0,C=this.data.length;A<C;A++){E=Math.max(E,this.data[A][1])}this.prefs.max_value=E}};c.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};c.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 o=function(z){this.feature_positions={};this.slot_height=z;this.translation=0};o.prototype.map_feature_data=function(A,C,z,B){if(!this.feature_positions[C]){this.feature_positions[C]=[]}this.feature_positions[C].push({data:A,x_start:z,x_end:B})};o.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 p=function(B,E,z,A,D,F,C){n.call(this,B,E,z,A,D);this.alpha_scaler=(F?F:new e());this.height_scaler=(C?C:new e())};p.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};v(p.prototype,{get_required_height:function(A){var z=y_scale=this.get_row_height(),B=this.mode;if(B==="no_detail"||B==="Squish"||B==="Pack"){z=A*y_scale}return z+Math.max(Math.round(y_scale/2),5)},draw:function(L,J,H,G){var R=this.data,E=this.view_start,N=this.view_end;L.save();L.fillStyle=this.prefs.block_color;L.textAlign="right";var I=this.view_end-this.view_start,F=J/I,M=this.get_row_height(),Q=new o(M),C;for(var O=0,P=R.length;O<P;O++){var B=R[O],D=B[0],K=B[1],z=B[2],A=(G&&G[D]!==undefined?G[D]:null);if((K<N&&z>E)&&(this.mode=="Dense"||A!==null)){C=this.draw_element(L,this.mode,B,A,E,N,F,M,J);Q.map_feature_data(B,A,C[0],C[1])}}L.restore();return Q},draw_element:function(F,B,H,D,C,E,G,A,z){console.log("WARNING: Unimplemented function.");return[0,0]}});var d=10,j=3,m=5,x=10,g=1,t=3,f=3,a=9,l=2,h="#ccc";var s=function(B,E,z,A,D,F,C){p.call(this,B,E,z,A,D,F,C)};v(s.prototype,p.prototype,{get_row_height:function(){var A=this.mode,z;if(A==="Dense"){z=d}else{if(A==="no_detail"){z=j}else{if(A==="Squish"){z=m}else{z=x}}}return z},draw_element:function(N,E,W,I,P,ah,al,an,z){var T=W[0],aj=W[1],ab=W[2],R=W[3],ac=Math.floor(Math.max(0,(aj-P)*al)),O=Math.ceil(Math.min(z,Math.max(0,(ab-P)*al))),aa=ac,am=O,Z=(E==="Dense"?0:(0+I))*an,M,af,S=null,ap=null,C=this.prefs.block_color,ae=this.prefs.label_color;N.globalAlpha=this.alpha_scaler.gen_val(W);if(E=="Dense"){I=1}if(E==="no_detail"){N.fillStyle=C;N.fillRect(ac,Z+5,O-ac,g)}else{var L=W[4],Y=W[5],ad=W[6],D=W[7];if(Y&&ad){S=Math.floor(Math.max(0,(Y-P)*al));ap=Math.ceil(Math.min(z,Math.max(0,(ad-P)*al)))}var ak,U;if(E==="Squish"||E==="Dense"){ak=1;U=f}else{ak=5;U=a}if(!D){if(W.strand){if(W.strand==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand_inv")}else{if(W.strand==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand_inv")}}}else{N.fillStyle=C}N.fillRect(ac,Z,O-ac,U)}else{var K,V;if(E==="Squish"||E==="Dense"){N.fillStyle=h;K=Z+Math.floor(f/2)+1;V=1}else{if(L){var K=Z;var V=U;if(L==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand")}else{if(L==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand")}}}else{N.fillStyle=h;K+=(f/2)+1;V=1}}N.fillRect(ac,K,O-ac,V);var F;for(var ai=0,B=D.length;ai<B;ai++){var G=D[ai],A=Math.floor(Math.max(0,(G[0]-P)*al)),X=Math.ceil(Math.min(z,Math.max((G[1]-P)*al)));if(A>X){continue}N.fillStyle=C;N.fillRect(A,Z+(U-ak)/2+1,X-A,ak);if(S!==undefined&&ad>Y&&!(A>ap||X<S)){var ag=Math.max(A,S),J=Math.min(X,ap);N.fillRect(ag,Z+1,J-ag,U);if(D.length==1&&E=="Pack"){if(L==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand_inv")}else{if(L==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand_inv")}}if(ag+14<J){ag+=2;J-=2}N.fillRect(ag,Z+1,J-ag,U)}}}if(E==="Pack"){N.globalAlpha=1;N.fillStyle="white";var H=this.height_scaler.gen_val(W),Q=Math.ceil(U*H),ao=Math.round((U-Q)/2);if(H!==1){N.fillRect(ac,K+1,O-ac,ao);N.fillRect(ac,K+U-ao+1,O-ac,ao)}}}N.globalAlpha=1;if(E==="Pack"&&aj>P){N.fillStyle=ae;if(P===0&&ac-N.measureText(R).width<0){N.textAlign="left";N.fillText(R,O+l,Z+8);am+=N.measureText(R).width+l}else{N.textAlign="right";N.fillText(R,ac-l,Z+8);aa-=N.measureText(R).width+l}}}N.globalAlpha=1;return[aa,am]}});var b=function(B,E,z,A,D,F,C){p.call(this,B,E,z,A,D,F,C)};v(b.prototype,p.prototype,{draw_element:function(S,N,H,D,V,B,K,T,Q){var H=data[i],J=H[0],R=H[1],C=H[2],M=H[3],F=Math.floor(Math.max(0,(R-V)*K)),I=Math.ceil(Math.min(Q,Math.max(0,(C-V)*K))),E=(N==="Dense"?0:(0+D))*T,z,W,A=null,L=null;if(no_label){S.fillStyle=block_color;S.fillRect(F+left_offset,E+5,I-F,1)}else{var U=H[4],P=H[5],G=H[6];z=9;W=1;S.fillRect(F+left_offset,E,I-F,z);if(N!=="Dense"&&M!==undefined&&R>V){S.fillStyle=label_color;if(V===0&&F-S.measureText(M).width<0){S.textAlign="left";S.fillText(M,I+2+left_offset,E+8)}else{S.textAlign="right";S.fillText(M,F-2+left_offset,E+8)}S.fillStyle=block_color}var O=U+" / "+P;if(R>V&&S.measureText(O).width<(I-F)){S.fillStyle="white";S.textAlign="center";S.fillText(O,left_offset+F+(I-F)/2,E+8);S.fillStyle=block_color}}return[F,I]}});var u=function(C,F,z,B,E,G,D,A){p.call(this,C,F,z,B,E,G,D);this.ref_seq=(A?A.data:null)};u.prototype.default_prefs=v({},p.prototype.default_prefs,{show_insertions:false});v(u.prototype,p.prototype,{get_row_height:function(){var z,A=this.mode;if(A==="Dense"){z=d}else{if(A==="Squish"){z=m}else{z=x;if(this.prefs.show_insertions){z*=2}}}return z},draw_read:function(W,R,N,ab,C,V,K,H,G){W.textAlign="center";var U=this,B=[ab,C],Q=0,X=0,T=0,z=W.canvas.manager.char_width_px;var ag=[];if((R==="Pack"||this.mode==="Auto")&&H!==undefined&&N>z){T=Math.round(N/2)}if(!K){K=[[0,H.length]]}for(var O=0,Z=K.length;O<Z;O++){var L=K[O],D="MIDNSHP=X"[L[0]],P=L[1];if(D==="H"||D==="S"){Q-=P}var I=V+Q,af=Math.floor(Math.max(0,(I-ab)*N)),J=Math.floor(Math.max(0,(I+P-ab)*N));if(af===J){J+=1}switch(D){case"H":break;case"S":case"M":case"=":if(is_overlap([I,I+P],B)){var S=H.slice(X,X+P);if(T>0){W.fillStyle=this.prefs.block_color;W.fillRect(af-T,G+1,J-af,9);W.fillStyle=h;for(var ad=0,A=S.length;ad<A;ad++){if(this.prefs.show_differences&&this.ref_seq){var M=this.ref_seq[I-ab+ad];if(!M||M.toLowerCase()===S[ad].toLowerCase()){continue}}if(I+ad>=ab&&I+ad<=C){var ae=Math.floor(Math.max(0,(I+ad-ab)*N));W.fillText(S[ad],ae,G+9)}}}else{W.fillStyle=this.prefs.block_color;W.fillRect(af,G+4,J-af,f)}}X+=P;Q+=P;break;case"N":W.fillStyle=h;W.fillRect(af-T,G+5,J-af,1);Q+=P;break;case"D":W.fillStyle="red";W.fillRect(af-T,G+4,J-af,3);Q+=P;break;case"P":break;case"I":var aa=af-T;if(is_overlap([I,I+P],B)){var S=H.slice(X,X+P);if(this.prefs.show_insertions){var F=af-(J-af)/2;if((R==="Pack"||this.mode==="Auto")&&H!==undefined&&N>z){W.fillStyle="yellow";W.fillRect(F-T,G-9,J-af,9);ag[ag.length]={type:"triangle",data:[aa,G+4,5]};W.fillStyle=h;switch(seq_tile_overlap){case (OVERLAP_START):S=S.slice(ab-I);break;case (OVERLAP_END):S=S.slice(0,I-C);break;case (CONTAINED_BY):break;case (CONTAINS):S=S.slice(ab-I,I-C);break}for(var ad=0,A=S.length;ad<A;ad++){var ae=Math.floor(Math.max(0,(I+ad-ab)*N));W.fillText(S[ad],ae-(J-af)/2,G)}}else{W.fillStyle="yellow";W.fillRect(F,G+(this.mode!=="Dense"?2:5),J-af,(R!=="Dense"?f:t))}}else{if((R==="Pack"||this.mode==="Auto")&&H!==undefined&&N>z){ag[ag.length]={type:"text",data:[S.length,aa,G+9]}}else{}}}X+=P;break;case"X":X+=P;break}}W.fillStyle="yellow";var ac,E,ah;for(var Y=0;Y<ag.length;Y++){ac=ag[Y];E=ac.type;ah=ac.data;if(E==="text"){W.save();W.font="bold "+W.font;W.fillText(ah[0],ah[1],ah[2]);W.restore()}else{if(E=="triangle"){r(W,ah[0],ah[1],ah[2])}}}},draw_element:function(S,N,F,C,V,A,J,T,Q){var I=F[0],R=F[1],B=F[2],K=F[3],E=Math.floor(Math.max(0,(R-V)*J)),G=Math.ceil(Math.min(Q,Math.max(0,(B-V)*J))),D=(N==="Dense"?0:(0+C))*T,W=this.prefs.block_color,H=this.prefs.label_color,P=0;if((N==="Pack"||this.mode==="Auto")&&J>S.canvas.manager.char_width_px){var P=Math.round(J/2)}S.fillStyle=W;if(F[5] instanceof Array){var O=Math.floor(Math.max(0,(F[4][0]-V)*J)),M=Math.ceil(Math.min(Q,Math.max(0,(F[4][1]-V)*J))),L=Math.floor(Math.max(0,(F[5][0]-V)*J)),z=Math.ceil(Math.min(Q,Math.max(0,(F[5][1]-V)*J)));if(F[4][1]>=V&&F[4][0]<=A&&F[4][2]){this.draw_read(S,N,J,V,A,F[4][0],F[4][2],F[4][3],D)}if(F[5][1]>=V&&F[5][0]<=A&&F[5][2]){this.draw_read(S,N,J,V,A,F[5][0],F[5][2],F[5][3],D)}if(L>M){S.fillStyle=h;q(S,M-P,D+5,L-P,D+5)}}else{S.fillStyle=W;this.draw_read(S,N,J,V,A,R,F[4],F[5],D)}if(N==="Pack"&&R>V){S.fillStyle=this.prefs.label_color;var U=1;if(U===0&&E-S.measureText(K).width<0){S.textAlign="left";S.fillText(K,G+l-P,D+8)}else{S.textAlign="right";S.fillText(K,E-l-P,D+8)}S.fillStyle=W}return[0,0]}});y.Scaler=e;y.SummaryTreePainter=w;y.LinePainter=c;y.LinkedFeaturePainter=s;y.ReadPainter=u;y.VariantPainter=b};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("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(u,t,s){return((u*299)+(t*587)+(s*114))/1000};var e=function(v,u,w,s,r,t){return(Math.max(v,s)-Math.min(v,s))+(Math.max(u,r)-Math.min(u,r))+(Math.max(w,t)-Math.min(w,t))};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,Z){var q=f("class").extend,t=f("slotting"),N=f("painters");var ag=function(ah,ai){this.document=ah;this.default_font=ai!==undefined?ai:"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")};q(ag.prototype,{load_pattern:function(ah,al){var ai=this.patterns,aj=this.dummy_context,ak=new Image();ak.src=image_path+al;ak.onload=function(){ai[ah]=aj.createPattern(ak,"repeat")}},get_pattern:function(ah){return this.patterns[ah]},new_canvas:function(){var ah=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(ah)}ah.manager=this;return ah}});var o={};var m=function(ah,ai){o[ah.attr("id")]=ai};var n=function(ah,aj,al,ak){al=".group";var ai={};o[ah.attr("id")]=ak;ah.bind("drag",{handle:"."+aj,relative:true},function(au,av){var at=$(this);var ay=$(this).parent(),ap=ay.children(),ar=o[$(this).attr("id")],ao,an,aw,am,aq;an=$(this).parents(al);if(an.length!==0){aw=an.position().top;am=aw+an.outerHeight();if(av.offsetY<aw){$(this).insertBefore(an);var ax=o[an.attr("id")];ax.remove_drawable(ar);ax.container.add_drawable_before(ar,ax);return}else{if(av.offsetY>am){$(this).insertAfter(an);var ax=o[an.attr("id")];ax.remove_drawable(ar);ax.container.add_drawable(ar);return}}}an=null;for(aq=0;aq<ap.length;aq++){ao=$(ap.get(aq));aw=ao.position().top;am=aw+ao.outerHeight();if(ao.is(al)&&this!==ao.get(0)&&av.offsetY>=aw&&av.offsetY<=am){if(av.offsetY-aw<am-av.offsetY){ao.find(".content-div").prepend(this)}else{ao.find(".content-div").append(this)}if(ar.container){ar.container.remove_drawable(ar)}o[ao.attr("id")].add_drawable(ar);return}}for(aq=0;aq<ap.length;aq++){if(av.offsetY<$(ap.get(aq)).position().top){break}}if(aq===ap.length){if(this!==ap.get(aq-1)){ay.append(this);o[ay.attr("id")].move_drawable(ar,aq)}}else{if(this!==ap.get(aq)){$(this).insertBefore(ap.get(aq));o[ay.attr("id")].move_drawable(ar,(av.deltaY>0?aq-1:aq))}}}).bind("dragstart",function(){ai["border-top"]=ah.css("border-top");ai["border-bottom"]=ah.css("border-bottom");$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css(ai)})};Z.moveable=n;var af=16,I=9,F=20,U=I+2,A=100,K=12000,S=200,D=5,w=10,M=5000,x=100,p="There was an error in indexing this dataset. ",L="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",G="No data for this chrom/contig.",u="Currently indexing... please wait",y="Tool cannot be rerun: ",a="Loading data...",aa="Ready for display",d=10,v=5,C=5;function ab(ai,ah){if(!ah){ah=0}var aj=Math.pow(10,ah);return Math.round(ai*aj)/aj}var c=function(ah){this.num_elements=ah;this.clear()};q(c.prototype,{get:function(ai){var ah=this.key_ary.indexOf(ai);if(ah!==-1){if(this.obj_cache[ai].stale){this.key_ary.splice(ah,1);delete this.obj_cache[ai]}else{this.move_key_to_end(ai,ah)}}return this.obj_cache[ai]},set:function(ai,aj){if(!this.obj_cache[ai]){if(this.key_ary.length>=this.num_elements){var ah=this.key_ary.shift();delete this.obj_cache[ah]}this.key_ary.push(ai)}this.obj_cache[ai]=aj;return aj},move_key_to_end:function(ai,ah){this.key_ary.splice(ah,1);this.key_ary.push(ai)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var T=function(ai,ah,aj){c.call(this,ai);this.track=ah;this.subset=(aj!==undefined?aj:true)};q(T.prototype,c.prototype,{load_data:function(aq,al,ao,ai,an){var ap=this.track.view.chrom,ak={chrom:ap,low:aq,high:al,mode:ao,resolution:ai,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(ak,an);if(this.track.filters_manager){var ar=[];var ah=this.track.filters_manager.filters;for(var am=0;am<ah.length;am++){ar[ar.length]=ah[am].name}ak.filter_cols=JSON.stringify(ar)}var aj=this;return $.getJSON(this.track.data_url,ak,function(at){aj.set_data(aq,al,ao,at)})},get_data:function(ah,al,am,ai,ak){var aj=this.get_data_from_cache(ah,al,am);if(aj){return aj}aj=this.load_data(ah,al,am,ai,ak);this.set_data(ah,al,am,aj);return aj},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(ap,ak,ao,aj,an,al){var aq=this.get_data_from_cache(ap,ak,ao);if(!aq){console.log("ERROR: no current data for: ",this.track,ap,ak,ao,aj,an);return}aq.stale=true;var ai=ap;if(al===this.DEEP_DATA_REQ){$.extend(an,{start_val:aq.data.length+1})}else{if(al===this.BROAD_DATA_REQ){ai=(aq.max_high?aq.max_high:aq.data[aq.data.length-1][2])+1}}var ah=this,am=this.load_data(ai,ak,ao,aj,an);new_data_available=$.Deferred();this.set_data(ap,ak,ao,new_data_available);$.when(am).then(function(ar){if(ar.data){ar.data=aq.data.concat(ar.data);if(ar.max_low){ar.max_low=aq.max_low}if(ar.message){ar.message=ar.message.replace(/[0-9]+/,ar.data.length)}}ah.set_data(ap,ak,ao,ar);new_data_available.resolve(ar)});return new_data_available},get_data_from_cache:function(ah,ai,aj){return this.get(this.gen_key(ah,ai,aj))},set_data:function(ai,aj,ak,ah){return this.set(this.gen_key(ai,aj,ak),ah)},gen_key:function(ah,aj,ak){var ai=ah+"_"+aj+"_"+ak;return ai},split_key:function(ah){return ah.split("_")}});var J=function(ai,ah,aj){T.call(this,ai,ah,aj)};q(J.prototype,T.prototype,c.prototype,{load_data:function(ah,ak,al,ai,aj){if(ai>1){return{data:null}}return T.prototype.load_data.call(this,ah,ak,al,ai,aj)}});var r=function(ak,ai,ah,aj,al){this.name=ak;this.view=ai;this.container=ah;this.config=new H({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ak}],saved_values:aj,onchange:function(){this.track.set_name(this.track.config.values.name)}});this.prefs=this.config.values;this.drag_handle_class=al;this.is_overview=false};q(r.prototype,{init:function(){},request_draw:function(){},_draw:function(){},to_json:function(){},update_track_icons:function(){},set_name:function(ah){this.old_name=this.name;this.name=ah;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 z=function(al,ak,ai,ah,aj,am){r.call(this,ak,ai,ah,aj,am);this.obj_type=al;this.drawables=[]};q(z.prototype,r.prototype,{init:function(){for(var ah=0;ah<this.drawables.length;ah++){this.drawables[ah].init()}},_draw:function(){for(var ah=0;ah<this.drawables.length;ah++){this.drawables[ah]._draw()}},to_json:function(){var ai=[];for(var ah=0;ah<this.drawables.length;ah++){ai.push(this.drawables[ah].to_json())}return{name:this.name,prefs:this.prefs,obj_type:this.obj_type,drawables:ai}},add_drawable:function(ah){this.drawables.push(ah);ah.container=this},add_drawable_before:function(aj,ah){var ai=this.drawables.indexOf(ah);if(ai!=-1){this.drawables.splice(ai,0,aj);return true}return false},remove_drawable:function(ai){var ah=this.drawables.indexOf(ai);if(ah!=-1){this.drawables.splice(ah,1);ai.container=null;return true}return false},move_drawable:function(ai,aj){var ah=this.drawables.indexOf(ai);if(ah!=-1){this.drawables.splice(ah,1);this.drawables.splice(aj,0,ai);return true}return false}});var R=function(ak,ai,ah,aj){z.call(this,"DrawableGroup",ak,ai,ah,aj,"group-handle");if(!R.id_counter){R.id_counter=0}var al=R.id_counter++;this.container_div=$("<div/>").addClass("group").attr("id","group_"+al).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_"+al+"_content_div").appendTo(this.container_div);m(this.container_div,this);m(this.content_div,this);n(this.container_div,this.drag_handle_class,".group",this);this.update_track_icons()};q(R.prototype,r.prototype,z.prototype,{update_track_icons:function(){var ai=this;var ah={};ah["Edit configuration"]=function(){var al=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},aj=function(){ai.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ak=function(am){if((am.keyCode||am.which)===27){al()}else{if((am.keyCode||am.which)===13){aj()}}};$(window).bind("keypress.check_enter_esc",ak);show_modal("Configure Group",ai.config.build_form(),{Cancel:al,OK:aj})};ah.Remove=function(){ai.remove()};make_popupmenu(ai.name_div,ah)}});var ae=function(ah,ak,aj,ai){z.call(this,"View");this.container=ah;this.chrom=null;this.vis_id=aj;this.dbkey=ai;this.title=ak;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 ag(ah.get(0).ownerDocument);this.reset()};q(ae.prototype,z.prototype,{init:function(){var aj=this.container,ah=this;this.top_container=$("<div/>").addClass("top-container").appendTo(aj);this.browser_content_div=$("<div/>").addClass("content").css("position","relative").appendTo(aj);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(aj);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;m(this.viewport_container,ah);this.intro_div=$("<div/>").addClass("intro");var ak=$("<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 ai=function(al){if(al.type==="focusout"||(al.keyCode||al.which)===13||(al.keyCode||al.which)===27){if((al.keyCode||al.which)!==27){ah.go_to($(this).val())}$(this).hide();$(this).val("");ah.location_span.show();ah.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ai).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.click(function(){ah.location_span.hide();ah.chrom_select.hide();ah.nav_input.val(ah.chrom+":"+ah.low+"-"+ah.high);ah.nav_input.css("display","inline-block");ah.nav_input.select();ah.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(){ah.zoom_out();ah.request_redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){ah.zoom_in();ah.request_redraw()}).appendTo(this.nav_controls);this.load_chroms_deferred=this.load_chroms({low:0});this.chrom_select.bind("change",function(){ah.change_chrom(ah.chrom_select.val())});this.browser_content_div.click(function(al){$(this).find("input").trigger("blur")});this.browser_content_div.bind("dblclick",function(al){ah.zoom_in(al.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(al,am){this.current_x=am.offsetX}).bind("drag",function(al,an){var ao=an.offsetX-this.current_x;this.current_x=an.offsetX;var am=Math.round(ao/ah.viewport_container.width()*(ah.max_high-ah.max_low));ah.move_delta(-am)});this.overview_close.click(function(){ah.reset_overview()});this.viewport_container.bind("draginit",function(al,am){if(al.clientX>ah.viewport_container.width()-16){return false}}).bind("dragstart",function(al,am){am.original_low=ah.low;am.current_height=al.clientY;am.current_x=am.offsetX}).bind("drag",function(an,ap){var al=$(this);var aq=ap.offsetX-ap.current_x;var am=al.scrollTop()-(an.clientY-ap.current_height);al.scrollTop(am);ap.current_height=an.clientY;ap.current_x=ap.offsetX;var ao=Math.round(aq/ah.viewport_container.width()*(ah.high-ah.low));ah.move_delta(ao)}).bind("mousewheel",function(an,ap,am,al){if(am){var ao=Math.round(-am/ah.viewport_container.width()*(ah.high-ah.low));ah.move_delta(ao)}});this.top_labeltrack.bind("dragstart",function(al,am){return $("<div />").css({height:ah.browser_content_div.height()+ah.top_labeltrack.height()+ah.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ap,aq){$(aq.proxy).css({left:Math.min(ap.pageX,aq.startX),width:Math.abs(ap.pageX-aq.startX)});var am=Math.min(ap.pageX,aq.startX)-ah.container.offset().left,al=Math.max(ap.pageX,aq.startX)-ah.container.offset().left,ao=(ah.high-ah.low),an=ah.viewport_container.width();ah.update_location(Math.round(am/an*ao)+ah.low,Math.round(al/an*ao)+ah.low)}).bind("dragend",function(aq,ar){var am=Math.min(aq.pageX,ar.startX),al=Math.max(aq.pageX,ar.startX),ao=(ah.high-ah.low),an=ah.viewport_container.width(),ap=ah.low;ah.low=Math.round(am/an*ao)+ap;ah.high=Math.round(al/an*ao)+ap;$(ar.proxy).remove();ah.request_redraw()});this.add_label_track(new ad(this,{content_div:this.top_labeltrack}));this.add_label_track(new ad(this,{content_div:this.nav_labeltrack}));$(window).bind("resize",function(){ah.resize_window()});$(document).bind("redraw",function(){ah.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(ah,ai){this.location_span.text(commatize(ah)+" - "+commatize(ai));this.nav_input.val(this.chrom+":"+commatize(ah)+"-"+commatize(ai))},load_chroms:function(aj){aj.num=x;$.extend(aj,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var ah=this,ai=$.Deferred();$.ajax({url:chrom_url,data:aj,dataType:"json",success:function(al){if(al.chrom_info.length===0){alert("Invalid chromosome: "+aj.chrom);return}if(al.reference){ah.add_label_track(new B(ah))}ah.chrom_data=al.chrom_info;var ao='<option value="">Select Chrom/Contig</option>';for(var an=0,ak=ah.chrom_data.length;an<ak;an++){var am=ah.chrom_data[an].chrom;ao+='<option value="'+am+'">'+am+"</option>"}if(al.prev_chroms){ao+='<option value="previous">Previous '+x+"</option>"}if(al.next_chroms){ao+='<option value="next">Next '+x+"</option>"}ah.chrom_select.html(ao);ah.chrom_start_index=al.start_index;ai.resolve(al)},error:function(){alert("Could not load chroms for this dbkey:",ah.dbkey)}});return ai},change_chrom:function(am,ai,ao){if(!am||am==="None"){return}var aj=this;if(am==="previous"){aj.load_chroms({low:this.chrom_start_index-x});return}if(am==="next"){aj.load_chroms({low:this.chrom_start_index+x});return}var an=$.grep(aj.chrom_data,function(ap,aq){return ap.chrom===am})[0];if(an===undefined){aj.load_chroms({chrom:am},function(){aj.change_chrom(am,ai,ao)});return}else{if(am!==aj.chrom){aj.chrom=am;aj.chrom_select.val(aj.chrom);aj.max_high=an.len-1;aj.reset();aj.request_redraw(true);for(var al=0,ah=aj.drawables.length;al<ah;al++){var ak=aj.drawables[al];if(ak.init){ak.init()}}}if(ai!==undefined&&ao!==undefined){aj.low=Math.max(ai,0);aj.high=Math.min(ao,aj.max_high)}aj.reset_overview();aj.request_redraw()}},go_to:function(al){var ap=this,ah,ak,ai=al.split(":"),an=ai[0],ao=ai[1];if(ao!==undefined){try{var am=ao.split("-");ah=parseInt(am[0].replace(/,/g,""),10);ak=parseInt(am[1].replace(/,/g,""),10)}catch(aj){return false}}ap.change_chrom(an,ah,ak)},move_fraction:function(aj){var ah=this;var ai=ah.high-ah.low;this.move_delta(aj*ai)},move_delta:function(aj){var ah=this;var ai=ah.high-ah.low;if(ah.low-aj<ah.max_low){ah.low=ah.max_low;ah.high=ah.max_low+ai}else{if(ah.high-aj>ah.max_high){ah.high=ah.max_high;ah.low=ah.max_high-ai}else{ah.high-=aj;ah.low-=aj}}ah.request_redraw()},add_drawable:function(ah){z.prototype.add_drawable.call(this,ah);ah.init();this.has_changes=true;this.update_intro_div()},add_label_track:function(ah){ah.view=this;ah.init();this.label_tracks.push(ah)},remove_drawable:function(aj,ai){z.prototype.remove_drawable.call(this,aj);if(ai){var ah=this;aj.container_div.fadeOut("slow",function(){$(this).remove();ah.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(ap,ah,ao,ai){var an=this,al=(ai?[ai]:an.drawables),aj;var ai;for(var am=0;am<al.length;am++){ai=al[am];aj=-1;for(var ak=0;ak<an.tracks_to_be_redrawn.length;ak++){if(an.tracks_to_be_redrawn[ak][0]===ai){aj=ak;break}}if(aj<0){an.tracks_to_be_redrawn.push([ai,ah,ao])}else{an.tracks_to_be_redrawn[am][1]=ah;an.tracks_to_be_redrawn[am][2]=ao}}requestAnimationFrame(function(){an._redraw(ap)})},_redraw:function(ar){var ao=this.low,ak=this.high;if(ao<this.max_low){ao=this.max_low}if(ak>this.max_high){ak=this.max_high}var aq=this.high-this.low;if(this.high!==0&&aq<this.min_separation){ak=ao+this.min_separation}this.low=Math.floor(ao);this.high=Math.ceil(ak);this.resolution=Math.pow(D,Math.ceil(Math.log((this.high-this.low)/S)/Math.log(D)));this.zoom_res=Math.pow(w,Math.max(0,Math.ceil(Math.log(this.resolution,w)/Math.log(w))));var ah=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var an=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var at=13;this.overview_box.css({left:ah,width:Math.max(at,an)}).show();if(an<at){this.overview_box.css("left",ah-(at-an)/2)}if(this.overview_highlight){this.overview_highlight.css({left:ah,width:an})}this.update_location(this.low,this.high);if(!ar){var aj,ai,ap;for(var al=0,am=this.tracks_to_be_redrawn.length;al<am;al++){aj=this.tracks_to_be_redrawn[al][0];ai=this.tracks_to_be_redrawn[al][1];ap=this.tracks_to_be_redrawn[al][2];if(aj){aj._draw(ai,ap)}}this.tracks_to_be_redrawn=[];for(al=0,am=this.label_tracks.length;al<am;al++){this.label_tracks[al]._draw()}}},zoom_in:function(ai,aj){if(this.max_high===0||this.high-this.low<this.min_separation){return}var ak=this.high-this.low,al=ak/2+this.low,ah=(ak/this.zoom_factor)/2;if(ai){al=ai/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(al-ah);this.high=Math.round(al+ah);this.request_redraw()},zoom_out:function(){if(this.max_high===0){return}var ai=this.high-this.low,aj=ai/2+this.low,ah=(ai*this.zoom_factor)/2;this.low=Math.round(aj-ah);this.high=Math.round(aj+ah);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(aj){if(this.overview_drawable){if(this.overview_drawable.dataset_id===aj.dataset_id){return}this.overview_viewport.find(".track").remove()}var ai=aj.copy({content_div:this.overview_viewport}),ah=this;ai.header_div.hide();ai.is_overview=true;ah.overview_drawable=ai;this.overview_drawable.postdraw_actions=function(){ah.overview_highlight.show().height(ah.overview_drawable.content_div.height());ah.overview_viewport.height(ah.overview_drawable.content_div.height()+ah.overview_box.outerHeight());ah.overview_close.show();ah.resize_window()};this.overview_drawable.init();ah.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 s=function(aj,an){this.track=aj;this.name=an.name;this.params=[];var av=an.params;for(var ak=0;ak<av.length;ak++){var ap=av[ak],ai=ap.name,au=ap.label,al=unescape(ap.html),aw=ap.value,ar=ap.type;if(ar==="number"){this.params[this.params.length]=new g(ai,au,al,aw,ap.min,ap.max)}else{if(ar=="select"){this.params[this.params.length]=new P(ai,au,al,aw)}else{console.log("WARNING: unrecognized tool parameter type:",ai,ar)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(ay){ay.stopPropagation()}).click(function(ay){ay.stopPropagation()}).bind("dblclick",function(ay){ay.stopPropagation()});var at=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var aq=this.params;var ao=this;$.each(this.params,function(az,aC){var aB=$("<div>").addClass("param-row").appendTo(ao.parent_div);var ay=$("<div>").addClass("param-label").text(aC.label).appendTo(aB);var aA=$("<div/>").addClass("slider").html(aC.html).appendTo(aB);aA.find(":input").val(aC.value);$("<div style='clear: both;'/>").appendTo(aB)});this.parent_div.find("input").click(function(){$(this).select()});var ax=$("<div>").addClass("param-row").appendTo(this.parent_div);var am=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(ax);var ah=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(ax);var ao=this;ah.click(function(){ao.run_on_region()});am.click(function(){ao.run_on_dataset()})};q(s.prototype,{get_param_values_dict:function(){var ah={};this.parent_div.find(":input").each(function(){var ai=$(this).attr("name"),aj=$(this).val();ah[ai]=JSON.stringify(aj)});return ah},get_param_values:function(){var ai=[];var ah={};this.parent_div.find(":input").each(function(){var aj=$(this).attr("name"),ak=$(this).val();if(aj){ai[ai.length]=ak}});return ai},run_on_dataset:function(){var ah=this;ah.run({dataset_id:this.track.original_dataset_id,tool_id:ah.name},null,function(ai){show_modal(ah.name+" is Running",ah.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var ai={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},al=this.track,aj=ai.tool_id+al.tool_region_and_parameters_str(ai.chrom,ai.low,ai.high),ah,am;if(al.container===view){var ak=new R(this.name,this.track.view,this.track.container);al.container.add_drawable(ak);al.container.remove_drawable(al);ak.add_drawable(al);al.container_div.appendTo(ak.content_div);ah=ak}else{ah=al.container}if(al instanceof e){am=new W(aj,view,ah,"hda");am.change_mode(al.mode);ah.add_drawable(am)}am.content_div.text("Starting job.");this.run(ai,am,function(an){am.dataset_id=an.dataset_id;am.content_div.text("Running job.");am.init()})},run:function(ai,aj,ak){$.extend(ai,this.get_param_values_dict());var ah=function(){$.getJSON(rerun_tool_url,ai,function(al){if(al==="no converter"){aj.container_div.addClass("error");aj.content_div.text(L)}else{if(al.error){aj.container_div.addClass("error");aj.content_div.text(y+al.message)}else{if(al==="pending"){aj.container_div.addClass("pending");aj.content_div.text("Converting input data so that it can be used quickly with tool.");setTimeout(ah,2000)}else{ak(al)}}}})};ah()}});var P=function(ai,ah,aj,ak){this.name=ai;this.label=ah;this.html=aj;this.value=ak};var g=function(aj,ai,al,am,ak,ah){P.call(this,aj,ai,al,am);this.min=ak;this.max=ah};var h=function(ai,ah,aj,ak){this.name=ai;this.index=ah;this.tool_id=aj;this.tool_exp_name=ak};var X=function(ai,ah,aj,ak){h.call(this,ai,ah,aj,ak);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};q(X.prototype,{applies_to:function(ah){if(ah.length>this.index){return true}return false},keep:function(ah){if(!this.applies_to(ah)){return true}var ai=ah[this.index];return(isNaN(ai)||(ai>=this.low&&ai<=this.high))},update_attrs:function(ai){var ah=false;if(!this.applies_to(ai)){return ah}if(ai[this.index]<this.min){this.min=Math.floor(ai[this.index]);ah=true}if(ai[this.index]>this.max){this.max=Math.ceil(ai[this.index]);ah=true}return ah},update_ui_elt:function(){if(this.min!=this.max){this.container.show()}else{this.container.hide()}var aj=function(am,ak){var al=ak-am;return(al<=2?0.01:1)};var ai=this.slider.slider("option","min"),ah=this.slider.slider("option","max");if(this.min<ai||this.max>ah){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",aj(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var ac=function(at,aA){this.track=at;this.filters=[];for(var av=0;av<aA.length;av++){var aw=aA[av],aB=aw.name,ah=aw.type,aj=aw.index,az=aw.tool_id,ay=aw.tool_exp_name;if(ah==="int"||ah==="float"){this.filters[av]=new X(aB,aj,az,ay)}else{console.log("ERROR: unsupported filter: ",aB,ah)}}var ak=function(aC,aD,aE){aC.click(function(){var aF=aD.text();max=parseFloat(aE.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(aE.slider("option","values")){input_size=2*input_size+1;multi_value=true}aD.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",aF).appendTo(aD).focus().select().click(function(aG){aG.stopPropagation()}).blur(function(){$(this).remove();aD.text(aF)}).keyup(function(aK){if(aK.keyCode===27){$(this).trigger("blur")}else{if(aK.keyCode===13){var aI=aE.slider("option","min"),aG=aE.slider("option","max"),aJ=function(aL){return(isNaN(aL)||aL>aG||aL<aI)},aH=$(this).val();if(!multi_value){aH=parseFloat(aH);if(aJ(aH)){alert("Parameter value must be in the range ["+aI+"-"+aG+"]");return $(this)}}else{aH=aH.split("-");aH=[parseFloat(aH[0]),parseFloat(aH[1])];if(aJ(aH[0])||aJ(aH[1])){alert("Parameter value must be in the range ["+aI+"-"+aG+"]");return $(this)}}aE.slider((multi_value?"values":"value"),aH)}}})})};this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(aC){aC.stopPropagation()}).click(function(aC){aC.stopPropagation()}).bind("dblclick",function(aC){aC.stopPropagation()}).bind("keydown",function(aC){aC.stopPropagation()});var ax=$("<div/>").addClass("sliders").appendTo(this.parent_div);var ap=this;$.each(this.filters,function(aF,aH){aH.container=$("<div/>").addClass("filter-row slider-row").appendTo(ax);var aG=$("<div/>").addClass("elt-label").appendTo(aH.container);var aE=$("<span/>").addClass("slider-name").text(aH.name+" ").appendTo(aG);var aD=$("<span/>");var aJ=$("<span/>").addClass("slider-value").appendTo(aG).append("[").append(aD).append("]");var aC=$("<div/>").addClass("slider").appendTo(aH.container);aH.control_element=$("<div/>").attr("id",aH.name+"-filter-control").appendTo(aC);var aI=[0,0];aH.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(aL,aM){var aK=aM.values;aD.text(aK[0]+"-"+aK[1]);aH.low=aK[0];aH.high=aK[1];ap.track.request_draw(true,true)},change:function(aK,aL){aH.control_element.slider("option","slide").call(aH.control_element,aK,aL)}});aH.slider=aH.control_element;aH.slider_label=aD;ak(aJ,aD,aH.control_element);$("<div style='clear: both;'/>").appendTo(aH.container)});if(this.filters.length!==0){var am=$("<div/>").addClass("param-row").appendTo(ax);var ao=$("<input type='submit'/>").attr("value","Run on complete dataset").appendTo(am);var ai=this;ao.click(function(){ai.run_on_dataset()})}var ar=$("<div/>").addClass("display-controls").appendTo(this.parent_div),au,an,aq,al={Transparency:function(aC){ap.alpha_filter=aC},Height:function(aC){ap.height_filter=aC}};$.each(al,function(aE,aD){au=$("<div/>").addClass("filter-row").appendTo(ar),an=$("<span/>").addClass("elt-label").text(aE+":").appendTo(au),aq=$("<select/>").attr("name",aE+"_dropdown").css("float","right").appendTo(au);$("<option/>").attr("value",-1).text("== None ==").appendTo(aq);for(var aC=0;aC<ap.filters.length;aC++){$("<option/>").attr("value",aC).text(ap.filters[aC].name).appendTo(aq)}aq.change(function(){$(this).children("option:selected").each(function(){var aF=parseInt($(this).val());al[aE]((aF>=0?ap.filters[aF]:null));ap.track.request_draw(true,true)})});$("<div style='clear: both;'/>").appendTo(au)});$("<div style='clear: both;'/>").appendTo(this.parent_div)};q(ac.prototype,{reset_filters:function(){for(var ah=0;ah<this.filters.length;ah++){filter=this.filters[ah];filter.slider.slider("option","values",[filter.min,filter.max])}this.alpha_filter=null;this.height_filter=null},run_on_dataset:function(){var ap=function(au,ar,at){if(!(ar in au)){au[ar]=at}return au[ar]};var aj={},ah,ai,ak;for(var al=0;al<this.filters.length;al++){ah=this.filters[al];if(ah.tool_id){if(ah.min!=ah.low){ai=ap(aj,ah.tool_id,[]);ai[ai.length]=ah.tool_exp_name+" >= "+ah.low}if(ah.max!=ah.high){ai=ap(aj,ah.tool_id,[]);ai[ai.length]=ah.tool_exp_name+" <= "+ah.high}}}var an=[];for(var aq in aj){an[an.length]=[aq,aj[aq]]}var ao=an.length;(function am(ay,av){var at=av[0],au=at[0],ax=at[1],aw="("+ax.join(") and (")+")",ar={cond:aw,input:ay,target_dataset_id:ay,tool_id:au},av=av.slice(1);$.getJSON(run_tool_url,ar,function(az){if(az.error){show_modal("Filter Dataset","Error running tool "+au,{Close:hide_modal})}else{if(av.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{am(az.dataset_id,av)}}})})(this.track.dataset_id,an)}});var E=function(ah,ai){N.Scaler.call(this,ai);this.filter=ah};E.prototype.gen_val=function(ah){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(ah[this.filter.index])-this.filter.low)/(this.filter.high-this.filter.low))};var H=function(ah){this.track=ah.track;this.params=ah.params;this.values={};this.restore_values((ah.saved_values?ah.saved_values:{}));this.onchange=ah.onchange};q(H.prototype,{restore_values:function(ah){var ai=this;$.each(this.params,function(aj,ak){if(ah[ak.key]!==undefined){ai.values[ak.key]=ah[ak.key]}else{ai.values[ak.key]=ak.default_value}})},build_form:function(){var ai=this;var ah=$("<div />");$.each(this.params,function(am,ak){if(!ak.hidden){var aj="param_"+am;var ao=ai.values[ak.key];var ar=$("<div class='form-row' />").appendTo(ah);ar.append($("<label />").attr("for",aj).text(ak.label+":"));if(ak.type==="bool"){ar.append($('<input type="checkbox" />').attr("id",aj).attr("name",aj).attr("checked",ao))}else{if(ak.type==="text"){ar.append($('<input type="text"/>').attr("id",aj).val(ao).click(function(){$(this).select()}))}else{if(ak.type==="color"){var an=$("<input />").attr("id",aj).attr("name",aj).val(ao);var ap=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var al=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(ap);var aq=$("<div/>").appendTo(al).farbtastic({width:100,height:100,callback:an,color:ao});$("<div />").append(an).append(ap).appendTo(ar).bind("click",function(at){ap.css({left:$(this).position().left+($(an).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){ap.hide();$(document).unbind("click.color-picker")});at.stopPropagation()})}else{ar.append($("<input />").attr("id",aj).attr("name",aj).val(ao))}}}}});return ah},update_from_form:function(ah){var aj=this;var ai=false;$.each(this.params,function(ak,am){if(!am.hidden){var an="param_"+ak;var al=ah.find("#"+an).val();if(am.type==="float"){al=parseFloat(al)}else{if(am.type==="int"){al=parseInt(al)}else{if(am.type==="bool"){al=ah.find("#"+an).is(":checked")}}}if(al!==aj.values[am.key]){aj.values[am.key]=al;ai=true}}});if(ai){this.onchange()}}});var b=function(ah,ak,aj,ai,al){this.track=ah;this.index=ak;this.low=ak*S*aj;this.high=(ak+1)*S*aj;this.resolution=aj;this.canvas=$("<div class='track-tile'/>").append(ai);this.data=al;this.stale=false};b.prototype.predisplay_actions=function(){};var l=function(ah,ak,aj,ai,al,am){b.call(this,ah,ak,aj,ai,al);this.max_val=am};q(l.prototype,b.prototype);var Q=function(ah,al,ak,aj,an,ao,am,ai){b.call(this,ah,al,ak,aj,an);this.mode=ao;this.message=am;this.feature_mapper=ai};q(Q.prototype,b.prototype);Q.prototype.predisplay_actions=function(){var ai=this,ah={};if(ai.mode!=="Pack"){return}$(this.canvas).mousemove(function(au){var ao=$(this).offset(),at=au.pageX-ao.left,ar=au.pageY-ao.top,ay=ai.feature_mapper.get_feature_data(at,ar),ap=(ay?ay[0]:null);$(this).siblings(".feature-popup").each(function(){if(!ap||$(this).attr("id")!==ap.toString()){$(this).remove()}});if(ay){var ak=ah[ap];if(!ak){var ap=ay[0],av={name:ay[3],start:ay[1],end:ay[2],strand:ay[4]},an=ai.track.filters_manager.filters,am;for(var aq=0;aq<an.length;aq++){am=an[aq];av[am.name]=ay[am.index]}var ak=$("<div/>").attr("id",ap).addClass("feature-popup"),ax,aw,az=$("<table/>").appendTo(ak),aA;for(ax in av){aw=av[ax];aA=$("<tr/>").appendTo(az);$("<th/>").appendTo(aA).text(ax);$("<td/>").attr("align","left").appendTo(aA).text(typeof(aw)=="number"?ab(aw,2):aw)}ah[ap]=ak}ak.appendTo($(ai.canvas).parent());var al=at+parseInt(ai.canvas.css("left"))+7,aj=ar+parseInt(ai.canvas.css("top"))+7;ak.css("left",al+"px").css("top",aj+"px")}else{if(!au.isPropagationStopped()){au.stopPropagation();$(this).siblings().each(function(){$(this).trigger(au)})}}}).mouseleave(function(){$(this).siblings(".feature-popup").remove()})};var j=function(ak,at,al,ao,au,aj,ai){r.call(this,ak,at,al,{},"draghandle");this.data_url=(aj?aj:default_data_url);this.data_url_extra_params={};this.data_query_wait=(ai?ai:M);this.dataset_check_url=converted_datasets_state_url;if(!j.id_counter){j.id_counter=0}this.id=j.id_counter++;this.container_div=$("<div />").addClass("track").attr("id","track_"+this.id).css("position","relative");if(ao){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 am=this;this.header_div.dblclick(function(av){av.stopPropagation()});this.settings_icon.click(function(){var ax=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},av=function(){am.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},aw=function(ay){if((ay.keyCode||ay.which)===27){ax()}else{if((ay.keyCode||ay.which)===13){av()}}};$(window).bind("keypress.check_enter_esc",aw);show_modal("Configure Track",am.config.build_form(),{Cancel:ax,OK:av})});this.overview_icon.click(function(){am.view.set_overview(am)});this.filters_icon.click(function(){am.filters_div.toggle();am.filters_manager.reset_filters()});this.tools_icon.click(function(){am.dynamic_tool_div.toggle();if(am.dynamic_tool_div.is(":visible")){am.set_name(am.name+am.tool_region_and_parameters_str())}else{am.revert_name()}$(".tipsy").remove()});this.remove_icon.click(function(){$(".tipsy").remove();am.remove()});if(am.display_modes!==undefined){if(am.mode_div===undefined){am.mode_div=$("<div class='right-float menubutton popup' />").appendTo(am.header_div);var an=(am.config&&am.config.values.mode?am.config.values.mode:am.display_modes[0]);am.mode=an;am.mode_div.text(an);var ah={};for(var ap=0,ar=am.display_modes.length;ap<ar;ap++){var aq=am.display_modes[ap];ah[aq]=function(av){return function(){am.change_mode(av)}}(aq)}make_popupmenu(am.mode_div,ah)}else{am.mode_div.hide()}this.header_div.append($("<div/>").css("clear","both"));this.container_div.hover(function(){am.icons_div.show()},function(){am.icons_div.hide()})}}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.container.content_div.append(this.container_div)};q(j.prototype,r.prototype,{get_type:function(){if(this instanceof ad){return"LabelTrack"}else{if(this instanceof B){return"ReferenceTrack"}else{if(this instanceof k){return"LineTrack"}else{if(this instanceof Y){return"ReadTrack"}else{if(this instanceof W){return"ToolDataFeatureTrack"}else{if(this instanceof V){return"VcfTrack"}else{if(this instanceof e){return"FeatureTrack"}}}}}}}return""},init:function(){var ah=this;ah.enabled=false;ah.tile_cache.clear();ah.data_manager.clear();ah.initial_canvas=undefined;ah.content_div.css("height","auto");ah.container_div.removeClass("nodata error pending");if(!ah.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:ah.hda_ldda,dataset_id:ah.dataset_id,chrom:ah.view.chrom},function(ai){if(!ai||ai==="error"||ai.kind==="error"){ah.container_div.addClass("error");ah.content_div.text(p);if(ai.message){var aj=$(" <a href='javascript:void(0);'></a>").text("View error").click(function(){show_modal("Trackster Error","<pre>"+ai.message+"</pre>",{Close:hide_modal})});ah.content_div.append(aj)}}else{if(ai==="no converter"){ah.container_div.addClass("error");ah.content_div.text(L)}else{if(ai==="no data"||(ai.data!==undefined&&(ai.data===null||ai.data.length===0))){ah.container_div.addClass("nodata");ah.content_div.text(G)}else{if(ai==="pending"){ah.container_div.addClass("pending");ah.content_div.text(u);setTimeout(function(){ah.init()},ah.data_query_wait)}else{if(ai.status==="data"){if(ai.valid_chroms){ah.valid_chroms=ai.valid_chroms;ah.update_track_icons()}ah.content_div.text(aa);if(ah.view.chrom){ah.content_div.text("");ah.content_div.css("height",ah.height_px+"px");ah.enabled=true;$.when(ah.predraw_init()).done(function(){ah.container_div.removeClass("nodata error pending");ah.request_draw()})}}}}}}});this.update_track_icons()},predraw_init:function(){}});var O=function(ak,aj){var ai=this,ah=ai.view;n(ai.container_div,ai.drag_handle_class,".group",ai);this.filters_manager=new ac(this,(ak!==undefined?ak:{}));this.filters_available=false;this.filters_visible=false;this.tool=(aj!==undefined&&obj_length(aj)>0?new s(this,aj):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)}}};q(O.prototype,r.prototype,j.prototype,{copy:function(ah){return new this.constructor(this.name,this.view,ah,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(ai){var ah=this;ah.mode_div.text(ai);ah.mode=ai;ah.config.values.mode=ai;ah.tile_cache.clear();ah.request_draw();return ah},update_track_icons:function(){var ah=this;if(ah.filters_available>0){ah.filters_icon.show()}else{ah.filters_icon.hide()}if(ah.tool){ah.tools_icon.show()}else{ah.tools_icon.hide()}},_gen_tile_cache_key:function(ai,aj,ah){return ai+"_"+aj+"_"+ah},request_draw:function(ai,ah){this.view.request_redraw(false,ai,ah,this)},_draw:function(aj,ar){if(!this.enabled){return}if(!(this instanceof B)&&(!this.dataset_id)){return}var aq=this.view.low,an=this.view.high,ao=an-aq,ak=this.view.container.width(),av=ak/ao,am=this.view.resolution,au=$("<div style='position: relative;'></div>");if(this.is_overview){aq=this.view.max_low;an=this.view.max_high;am=Math.pow(D,Math.ceil(Math.log((view.max_high-view.max_low)/S)/Math.log(D)));av=ak/(view.max_high-view.max_low)}if(!ar){this.content_div.children().remove()}this.content_div.append(au);this.max_height=0;var ai=Math.floor(aq/am/S);var ap=true;var at=[];var ah=0;while((ai*S*am)<an){tile=this.draw_helper(aj,ak,ai,am,au,av);if(tile){at.push(tile)}else{ap=false}ai+=1;ah++}var al=this;if(ap){al.postdraw_actions(at,ak,av,ar)}},postdraw_actions:function(al,am,an,ah){var aj=this;var ak=false;for(var ai=0;ai<al.length;ai++){if(al[ai].message){ak=true;break}}if(ak){for(var ai=0;ai<al.length;ai++){tile=al[ai];if(!tile.message){tile.canvas.css("padding-top",F)}}}},draw_helper:function(ai,aj,ak,an,au,ay,av,ao){var al=this,at=this._gen_tile_cache_key(aj,ay,ak),ap=ak*S*an,ax=ap+S*an;var aq=(ai?undefined:al.tile_cache.get(at));if(aq){al.show_tile(aq,au,ay);return aq}var ar=function(az){return("isResolved" in az)};var am=true;var ah=al.data_manager.get_data(ap,ax,al.mode,an,al.data_url_extra_params);if(ar(ah)){am=false}var aw;if(view.reference_track&&ay>view.canvas_manager.char_width_px){aw=view.reference_track.data_manager.get_data(ap,ax,al.mode,an,view.reference_track.data_url_extra_params);if(ar(aw)){am=false}}if(am){q(ah,ao);var aq=al.draw_tile(ah,al.mode,an,ak,ay,aw);if(aq!==undefined){al.tile_cache.set(at,aq);al.show_tile(aq,au,ay)}return aq}$.when(ah,aw).then(function(){view.request_redraw(false,false,false,al)});return null},show_tile:function(an,ap,aq){var aj=this,ai=an.canvas,am=ai;if(an.message){var ar=$("<div/>"),ao=$("<div/>").addClass("tile-message").text(an.message).css({height:F-1,width:an.canvas.width}).appendTo(ar),al=$("<a href='javascript:void(0);'/>").addClass("icon more-down").appendTo(ao),ah=$("<a href='javascript:void(0);'/>").addClass("icon more-across").appendTo(ao);ar.append(ai);am=ar;al.click(function(){an.stale=true;aj.data_manager.get_more_data(an.low,an.high,aj.mode,an.resolution,{},aj.data_manager.DEEP_DATA_REQ);aj.request_draw()}).dblclick(function(at){at.stopPropagation()});ah.click(function(){an.stale=true;aj.data_manager.get_more_data(an.low,an.high,aj.mode,an.resolution,{},aj.data_manager.BROAD_DATA_REQ);aj.request_draw()}).dblclick(function(at){at.stopPropagation()})}an.predisplay_actions();var ak=(an.low-(this.is_overview?this.view.max_low:this.view.low))*aq;if(this.left_offset){ak-=this.left_offset}am.css({position:"absolute",top:0,left:ak,height:""});ap.append(am);aj.max_height=Math.max(aj.max_height,am.height());aj.content_div.css("height",aj.max_height+"px");ap.children().css("height",aj.max_height+"px")},_get_tile_bounds:function(ah,ai){var ak=ah*S*ai,al=S*ai,aj=(ak+al<=this.view.max_high?ak+al:this.view.max_high);return[ak,aj]},tool_region_and_parameters_str:function(aj,ah,ak){var ai=this,al=(aj!==undefined&&ah!==undefined&&ak!==undefined?aj+":"+ah+"-"+ak:"all");return" - region=["+al+"], parameters=["+ai.tool.get_param_values().join(", ")+"]"}});var ad=function(ai,ah){j.call(this,"label",ai,ah,false,{});this.container_div.addClass("label-track")};q(ad.prototype,j.prototype,{init:function(){this.enabled=true},_draw:function(){var aj=this.view,ak=aj.high-aj.low,an=Math.floor(Math.pow(10,Math.floor(Math.log(ak)/Math.log(10)))),ah=Math.floor(aj.low/an)*an,al=this.view.container.width(),ai=$("<div style='position: relative; height: 1.3em;'></div>");while(ah<aj.high){var am=(ah-aj.low)/ak*al;ai.append($("<div class='label'>"+commatize(ah)+"</div>").css({position:"absolute",left:am-1}));ah+=an}this.content_div.children(":first").remove();this.content_div.append(ai)}});var B=function(ah){j.call(this,"reference",ah,{content_div:ah.top_labeltrack},false,{});O.call(this);ah.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:ah.dbkey};this.data_manager=new J(C,this,false);this.tile_cache=new c(v)};q(B.prototype,r.prototype,O.prototype,{init:function(){this.enabled=true},draw_tile:function(ar,an,am,ai,at){var al=this,aj=S*am;if(at>this.view.canvas_manager.char_width_px){if(ar.data===null){al.content_div.css("height","0px");return}var ak=this.view.canvas_manager.new_canvas();var aq=ak.getContext("2d");ak.width=Math.ceil(aj*at+al.left_offset);ak.height=al.height_px;aq.font=aq.canvas.manager.default_font;aq.textAlign="center";ar=ar.data;for(var ao=0,ap=ar.length;ao<ap;ao++){var ah=Math.round(ao*at);aq.fillText(ar[ao],ah+al.left_offset,10)}return new b(al,ai,am,ak,ar)}this.content_div.css("height","0px")}});var k=function(am,ak,aj,an,ah,al){var ai=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";j.call(this,am,ak,aj,al);O.call(this);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=an;this.dataset_id=ah;this.original_dataset_id=ah;this.data_manager=new T(C,this);this.tile_cache=new c(v);this.left_offset=0;this.config=new H({track:this,params:[{key:"name",label:"Name",type:"text",default_value:am},{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:al,onchange:function(){ai.set_name(ai.prefs.name);ai.vertical_range=ai.prefs.max_value-ai.prefs.min_value;$("#linetrack_"+ai.dataset_id+"_minval").text(ai.prefs.min_value);$("#linetrack_"+ai.dataset_id+"_maxval").text(ai.prefs.max_value);ai.tile_cache.clear();ai.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()};q(k.prototype,r.prototype,O.prototype,{add_resize_handle:function(){var ah=this;var ak=false;var aj=false;var ai=$("<div class='track-resize'>");$(ah.container_div).hover(function(){ak=true;ai.show()},function(){ak=false;if(!aj){ai.hide()}});ai.hide().bind("dragstart",function(al,am){aj=true;am.original_height=$(ah.content_div).height()}).bind("drag",function(am,an){var al=Math.min(Math.max(an.original_height+an.deltaY,ah.min_height_px),ah.max_height_px);$(ah.content_div).css("height",al);ah.height_px=al;ah.request_draw(true)}).bind("dragend",function(al,am){ah.tile_cache.clear();aj=false;if(!ak){ai.hide()}ah.config.values.height=ah.height_px}).appendTo(ah.container_div)},predraw_init:function(){var ah=this;ah.vertical_range=undefined;return $.getJSON(ah.data_url,{stats:true,chrom:ah.view.chrom,low:null,high:null,hda_ldda:ah.hda_ldda,dataset_id:ah.dataset_id},function(ai){ah.container_div.addClass("line-track");var ak=ai.data;if(isNaN(parseFloat(ah.prefs.min_value))||isNaN(parseFloat(ah.prefs.max_value))){ah.prefs.min_value=ak.min;ah.prefs.max_value=ak.max;$("#track_"+ah.dataset_id+"_minval").val(ah.prefs.min_value);$("#track_"+ah.dataset_id+"_maxval").val(ah.prefs.max_value)}ah.vertical_range=ah.prefs.max_value-ah.prefs.min_value;ah.total_frequency=ak.total_frequency;ah.container_div.find(".yaxislabel").remove();var al=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ah.dataset_id+"_minval").text(ab(ah.prefs.min_value,3));var aj=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ah.dataset_id+"_maxval").text(ab(ah.prefs.max_value,3));aj.css({position:"absolute",top:"24px",left:"10px"});aj.prependTo(ah.container_div);al.css({position:"absolute",bottom:"2px",left:"10px"});al.prependTo(ah.container_div)})},draw_tile:function(au,am,al,aj,at){if(this.vertical_range===undefined){return}var ah=this._get_tile_bounds(aj,al),an=ah[0],ar=ah[1],ai=Math.ceil((ar-an)*at),ap=this.height_px;var ak=this.view.canvas_manager.new_canvas();ak.width=ai,ak.height=ap;var aq=ak.getContext("2d");var ao=new N.LinePainter(au.data,an,ar,this.prefs,am);ao.draw(aq,ai,ap);return new b(this.track,aj,al,ak,au.data)}});var e=function(ah,an,ai,am,ap,ao,ak,al){var aj=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];j.call(this,ah,an,ai,true,ao);O.call(this,ak,al);this.config=new H({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ah},{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:ao,onchange:function(){aj.set_name(aj.prefs.name);aj.tile_cache.clear();aj.request_draw()}});this.prefs=this.config.values;this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=am;this.dataset_id=ap;this.original_dataset_id=ap;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 T(20,this);this.left_offset=200;this.painter=N.LinkedFeaturePainter};q(e.prototype,r.prototype,O.prototype,{postdraw_actions:function(ax,ah,ay,aw){O.prototype.postdraw_actions.call(this,ax,aw);var ak=this;if(aw){var am=ak.content_div.children();var an=false;for(var al=am.length-1,ar=0;al>=ar;al--){var aj=$(am[al]);if(an){aj.remove()}else{if(aj.children().length!==0){an=true}}}}if(ak.mode=="Histogram"){var aq=-1;for(var al=0;al<ax.length;al++){var av=ax[al].max_val;if(av>aq){aq=av}}for(var al=0;al<ax.length;al++){var au=ax[al];if(au.max_val!==aq){au.canvas.remove();ak.draw_helper(true,ah,au.index,au.resolution,au.canvas.parent(),ay,[],{max:aq})}}}if(ak.filters_manager){var ai=ak.filters_manager.filters;for(var ap=0;ap<ai.length;ap++){ai[ap].update_ui_elt()}var ao=false,at;for(var al=0;al<ax.length;al++){if(ax[al].data.length){at=ax[al].data[0];for(var ap=0;ap<ai.length;ap++){if(ai[ap].applies_to(at)){ao=true;break}}}}if(ak.filters_available!==ao){ak.filters_available=ao;if(!ak.filters_available){ak.filters_div.hide()}ak.update_track_icons()}}},update_auto_mode:function(ah){if(this.mode=="Auto"){if(ah=="no_detail"){ah="feature spans"}else{if(ah=="summary_tree"){ah="coverage histogram"}}this.mode_div.text("Auto ("+ah+")")}},incremental_slots:function(al,ai,ak){var aj=this.view.canvas_manager.dummy_context,ah=this.inc_slots[al];if(!ah||(ah.mode!==ak)){ah=new (t.FeatureSlotter)(al,ak==="Pack",A,function(am){return aj.measureText(am)});ah.mode=ak;this.inc_slots[al]=ah}return ah.slot_features(ai)},get_summary_tree_data:function(al,ao,aj,ax){if(ax>aj-ao){ax=aj-ao}var at=Math.floor((aj-ao)/ax),aw=[],ak=0;var am=0,an=0,ar,av=0,ap=[],au,aq;var ai=function(aA,az,aB,ay){aA[0]=az+aB*ay;aA[1]=az+(aB+1)*ay};while(av<ax&&am!==al.length){var ah=false;for(;av<ax&&!ah;av++){ai(ap,ao,av,at);for(an=am;an<al.length;an++){ar=al[an].slice(1,3);if(is_overlap(ar,ap)){ah=true;break}}if(ah){break}}data_start_index=an;aw[aw.length]=au=[ap[0],0];for(;an<al.length;an++){ar=al[an].slice(1,3);if(is_overlap(ar,ap)){au[1]++}else{break}}if(au[1]>ak){ak=au[1]}av++}return{max:ak,delta:at,data:aw}},draw_tile:function(aw,az,aD,aH,ar,ak){var aA=this,am=aA._get_tile_bounds(aH,aD),aK=am[0],ai=am[1],ay=ai-aK,aB=Math.ceil(ay*ar),aQ=25,al=this.left_offset,ax,an;if(az==="Auto"){if(aw.dataset_type==="summary_tree"){az=aw.dataset_type}else{if(aw.extra_info==="no_detail"||aA.is_overview){az="no_detail"}else{var aP=aw.data;if(this.view.high-this.view.low>K){az="Squish"}else{az="Pack"}}}this.update_auto_mode(az)}if(az==="summary_tree"||az==="Histogram"){an=this.summary_draw_height;this.container_div.find(".yaxislabel").remove();var ah=$("<div />").addClass("yaxislabel");ah.text(aw.max);ah.css({position:"absolute",top:"24px",left:"10px",color:this.prefs.label_color});ah.prependTo(this.container_div);var aj=this.view.canvas_manager.new_canvas();aj.width=aB+al;aj.height=an+U;if(aw.dataset_type!="summary_tree"){var at=this.get_summary_tree_data(aw.data,aK,ai,200);if(aw.max){at.max=aw.max}aw=at}var aM=new N.SummaryTreePainter(aw,aK,ai,this.prefs);var aC=aj.getContext("2d");aC.translate(al,U);aM.draw(aC,aB,an);return new l(aA,aH,aD,aj,aw.data,aw.max)}var ax,ap=1;if(az==="no_detail"||az==="Squish"||az==="Pack"){ap=this.incremental_slots(ar,aw.data,az);ax=this.inc_slots[ar].slots}var aq=[];if(aw.data){var au=this.filters_manager.filters;for(var aE=0,aG=aw.data.length;aE<aG;aE++){var ao=aw.data[aE];var aF=false;var av;for(var aJ=0,aO=au.length;aJ<aO;aJ++){av=au[aJ];av.update_attrs(ao);if(!av.keep(ao)){aF=true;break}}if(!aF){aq.push(ao)}}}var aN=(this.filters_manager.alpha_filter?new E(this.filters_manager.alpha_filter):null);var aL=(this.filters_manager.height_filter?new E(this.filters_manager.height_filter):null);var aM=new (this.painter)(aq,aK,ai,this.prefs,az,aN,aL,ak);var an=Math.max(af,aM.get_required_height(ap));var aj=this.view.canvas_manager.new_canvas();var aI=null;aj.width=aB+al;aj.height=an;var aC=aj.getContext("2d");aC.fillStyle=this.prefs.block_color;aC.font=aC.canvas.manager.default_font;aC.textAlign="right";this.container_div.find(".yaxislabel").remove();if(aw.data){aC.translate(al,0);aI=aM.draw(aC,aB,an,ax);aI.translation=-al}return new Q(aA,aH,aD,aj,aw.data,az,aw.message,aI)}});var V=function(al,aj,ai,an,ah,ak,am){e.call(this,al,aj,ai,an,ah,ak,am);this.painter=N.VariantPainter};q(V.prototype,r.prototype,O.prototype,e.prototype);var Y=function(al,aj,ai,an,ah,ak,am){e.call(this,al,aj,ai,an,ah,ak,am);this.config=new H({track:this,params:[{key:"name",label:"Name",type:"text",default_value:al},{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:ak,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=N.ReadPainter;this.update_track_icons()};q(Y.prototype,r.prototype,O.prototype,e.prototype);var W=function(al,aj,ai,an,ah,ak,am){e.call(this,al,aj,ai,an,ah,ak,am,{});this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};q(W.prototype,r.prototype,O.prototype,e.prototype,{predraw_init:function(){var ai=this;var ah=function(){if(ai.data_manager.size()===0){setTimeout(ah,300)}else{ai.data_url=default_data_url;ai.data_query_wait=M;ai.dataset_state_url=converted_datasets_state_url;$.getJSON(ai.dataset_state_url,{dataset_id:ai.dataset_id,hda_ldda:ai.hda_ldda},function(aj){})}};ah()}});Z.View=ae;Z.DrawableGroup=R;Z.LineTrack=k;Z.FeatureTrack=e;Z.ReadTrack=Y};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(j,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=j;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(G,H){for(var F=0;F<=z;F++){var D=false,I=h[F];if(I!==undefined){for(var C=0,E=I.length;C<E;C++){var B=I[C];if(H>B[0]&&G<B[1]){D=true;break}}}if(!D){return F}}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(k,y){var v=k("class").extend;var q=function(J,B,H,A,G,E){if(E===undefined){E=4}var D=A-B;var C=G-H;var F=Math.floor(Math.sqrt(D*D+C*C)/E);var K=D/F;var I=C/F;var z;for(z=0;z<F;z++,B+=K,H+=I){if(z%2!==0){continue}J.fillRect(B,H,E,1)}};var r=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 e=function(z){this.default_val=(z?z:1)};e.prototype.gen_val=function(z){return this.default_val};var n=function(B,D,z,A,C){this.data=B;this.view_start=D;this.view_end=z;this.prefs=v({},this.default_prefs,A);this.mode=C};n.prototype.default_prefs={};var w=function(B,D,z,A,C){n.call(this,B,D,z,A,C)};w.prototype.default_prefs={show_counts:false};w.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 c=function(z,D,F,G,B){n.call(this,z,D,F,G,B);if(this.prefs.min_value===undefined){var H=Infinity;for(var A=0,C=this.data.length;A<C;A++){H=Math.min(H,this.data[A][1])}this.prefs.min_value=H}if(this.prefs.max_value===undefined){var E=-Infinity;for(var A=0,C=this.data.length;A<C;A++){E=Math.max(E,this.data[A][1])}this.prefs.max_value=E}};c.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};c.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 o=function(z){this.feature_positions={};this.slot_height=z;this.translation=0};o.prototype.map_feature_data=function(A,C,z,B){if(!this.feature_positions[C]){this.feature_positions[C]=[]}this.feature_positions[C].push({data:A,x_start:z,x_end:B})};o.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 p=function(B,E,z,A,D,F,C){n.call(this,B,E,z,A,D);this.alpha_scaler=(F?F:new e());this.height_scaler=(C?C:new e())};p.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};v(p.prototype,{get_required_height:function(A){var z=y_scale=this.get_row_height(),B=this.mode;if(B==="no_detail"||B==="Squish"||B==="Pack"){z=A*y_scale}return z+Math.max(Math.round(y_scale/2),5)},draw:function(L,J,H,G){var R=this.data,E=this.view_start,N=this.view_end;L.save();L.fillStyle=this.prefs.block_color;L.textAlign="right";var I=this.view_end-this.view_start,F=J/I,M=this.get_row_height(),Q=new o(M),C;for(var O=0,P=R.length;O<P;O++){var B=R[O],D=B[0],K=B[1],z=B[2],A=(G&&G[D]!==undefined?G[D]:null);if((K<N&&z>E)&&(this.mode=="Dense"||A!==null)){C=this.draw_element(L,this.mode,B,A,E,N,F,M,J);Q.map_feature_data(B,A,C[0],C[1])}}L.restore();return Q},draw_element:function(F,B,H,D,C,E,G,A,z){console.log("WARNING: Unimplemented function.");return[0,0]}});var d=10,j=3,m=5,x=10,g=1,t=3,f=3,a=9,l=2,h="#ccc";var s=function(B,E,z,A,D,F,C){p.call(this,B,E,z,A,D,F,C)};v(s.prototype,p.prototype,{get_row_height:function(){var A=this.mode,z;if(A==="Dense"){z=d}else{if(A==="no_detail"){z=j}else{if(A==="Squish"){z=m}else{z=x}}}return z},draw_element:function(N,E,W,I,P,ah,al,an,z){var T=W[0],aj=W[1],ab=W[2],R=W[3],ac=Math.floor(Math.max(0,(aj-P)*al)),O=Math.ceil(Math.min(z,Math.max(0,(ab-P)*al))),aa=ac,am=O,Z=(E==="Dense"?0:(0+I))*an,M,af,S=null,ap=null,C=this.prefs.block_color,ae=this.prefs.label_color;N.globalAlpha=this.alpha_scaler.gen_val(W);if(E=="Dense"){I=1}if(E==="no_detail"){N.fillStyle=C;N.fillRect(ac,Z+5,O-ac,g)}else{var L=W[4],Y=W[5],ad=W[6],D=W[7];if(Y&&ad){S=Math.floor(Math.max(0,(Y-P)*al));ap=Math.ceil(Math.min(z,Math.max(0,(ad-P)*al)))}var ak,U;if(E==="Squish"||E==="Dense"){ak=1;U=f}else{ak=5;U=a}if(!D){if(W.strand){if(W.strand==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand_inv")}else{if(W.strand==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand_inv")}}}else{N.fillStyle=C}N.fillRect(ac,Z,O-ac,U)}else{var K,V;if(E==="Squish"||E==="Dense"){N.fillStyle=h;K=Z+Math.floor(f/2)+1;V=1}else{if(L){var K=Z;var V=U;if(L==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand")}else{if(L==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand")}}}else{N.fillStyle=h;K+=(f/2)+1;V=1}}N.fillRect(ac,K,O-ac,V);var F;for(var ai=0,B=D.length;ai<B;ai++){var G=D[ai],A=Math.floor(Math.max(0,(G[0]-P)*al)),X=Math.ceil(Math.min(z,Math.max((G[1]-P)*al)));if(A>X){continue}N.fillStyle=C;N.fillRect(A,Z+(U-ak)/2+1,X-A,ak);if(S!==undefined&&ad>Y&&!(A>ap||X<S)){var ag=Math.max(A,S),J=Math.min(X,ap);N.fillRect(ag,Z+1,J-ag,U);if(D.length==1&&E=="Pack"){if(L==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand_inv")}else{if(L==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand_inv")}}if(ag+14<J){ag+=2;J-=2}N.fillRect(ag,Z+1,J-ag,U)}}}if(E==="Pack"){N.globalAlpha=1;N.fillStyle="white";var H=this.height_scaler.gen_val(W),Q=Math.ceil(U*H),ao=Math.round((U-Q)/2);if(H!==1){N.fillRect(ac,K+1,O-ac,ao);N.fillRect(ac,K+U-ao+1,O-ac,ao)}}}N.globalAlpha=1;if(E==="Pack"&&aj>P){N.fillStyle=ae;if(P===0&&ac-N.measureText(R).width<0){N.textAlign="left";N.fillText(R,O+l,Z+8);am+=N.measureText(R).width+l}else{N.textAlign="right";N.fillText(R,ac-l,Z+8);aa-=N.measureText(R).width+l}}}N.globalAlpha=1;return[aa,am]}});var b=function(B,E,z,A,D,F,C){p.call(this,B,E,z,A,D,F,C)};v(b.prototype,p.prototype,{draw_element:function(S,N,H,D,V,B,K,T,Q){var H=data[i],J=H[0],R=H[1],C=H[2],M=H[3],F=Math.floor(Math.max(0,(R-V)*K)),I=Math.ceil(Math.min(Q,Math.max(0,(C-V)*K))),E=(N==="Dense"?0:(0+D))*T,z,W,A=null,L=null;if(no_label){S.fillStyle=block_color;S.fillRect(F+left_offset,E+5,I-F,1)}else{var U=H[4],P=H[5],G=H[6];z=9;W=1;S.fillRect(F+left_offset,E,I-F,z);if(N!=="Dense"&&M!==undefined&&R>V){S.fillStyle=label_color;if(V===0&&F-S.measureText(M).width<0){S.textAlign="left";S.fillText(M,I+2+left_offset,E+8)}else{S.textAlign="right";S.fillText(M,F-2+left_offset,E+8)}S.fillStyle=block_color}var O=U+" / "+P;if(R>V&&S.measureText(O).width<(I-F)){S.fillStyle="white";S.textAlign="center";S.fillText(O,left_offset+F+(I-F)/2,E+8);S.fillStyle=block_color}}return[F,I]}});var u=function(C,F,z,B,E,G,D,A){p.call(this,C,F,z,B,E,G,D);this.ref_seq=(A?A.data:null)};u.prototype.default_prefs=v({},p.prototype.default_prefs,{show_insertions:false});v(u.prototype,p.prototype,{get_row_height:function(){var z,A=this.mode;if(A==="Dense"){z=d}else{if(A==="Squish"){z=m}else{z=x;if(this.prefs.show_insertions){z*=2}}}return z},draw_read:function(W,R,N,ab,C,V,K,H,G){W.textAlign="center";var U=this,B=[ab,C],Q=0,X=0,T=0,z=W.canvas.manager.char_width_px;var ag=[];if((R==="Pack"||this.mode==="Auto")&&H!==undefined&&N>z){T=Math.round(N/2)}if(!K){K=[[0,H.length]]}for(var O=0,Z=K.length;O<Z;O++){var L=K[O],D="MIDNSHP=X"[L[0]],P=L[1];if(D==="H"||D==="S"){Q-=P}var I=V+Q,af=Math.floor(Math.max(0,(I-ab)*N)),J=Math.floor(Math.max(0,(I+P-ab)*N));if(af===J){J+=1}switch(D){case"H":break;case"S":case"M":case"=":if(is_overlap([I,I+P],B)){var S=H.slice(X,X+P);if(T>0){W.fillStyle=this.prefs.block_color;W.fillRect(af-T,G+1,J-af,9);W.fillStyle=h;for(var ad=0,A=S.length;ad<A;ad++){if(this.prefs.show_differences&&this.ref_seq){var M=this.ref_seq[I-ab+ad];if(!M||M.toLowerCase()===S[ad].toLowerCase()){continue}}if(I+ad>=ab&&I+ad<=C){var ae=Math.floor(Math.max(0,(I+ad-ab)*N));W.fillText(S[ad],ae,G+9)}}}else{W.fillStyle=this.prefs.block_color;W.fillRect(af,G+4,J-af,f)}}X+=P;Q+=P;break;case"N":W.fillStyle=h;W.fillRect(af-T,G+5,J-af,1);Q+=P;break;case"D":W.fillStyle="red";W.fillRect(af-T,G+4,J-af,3);Q+=P;break;case"P":break;case"I":var aa=af-T;if(is_overlap([I,I+P],B)){var S=H.slice(X,X+P);if(this.prefs.show_insertions){var F=af-(J-af)/2;if((R==="Pack"||this.mode==="Auto")&&H!==undefined&&N>z){W.fillStyle="yellow";W.fillRect(F-T,G-9,J-af,9);ag[ag.length]={type:"triangle",data:[aa,G+4,5]};W.fillStyle=h;switch(seq_tile_overlap){case (OVERLAP_START):S=S.slice(ab-I);break;case (OVERLAP_END):S=S.slice(0,I-C);break;case (CONTAINED_BY):break;case (CONTAINS):S=S.slice(ab-I,I-C);break}for(var ad=0,A=S.length;ad<A;ad++){var ae=Math.floor(Math.max(0,(I+ad-ab)*N));W.fillText(S[ad],ae-(J-af)/2,G)}}else{W.fillStyle="yellow";W.fillRect(F,G+(this.mode!=="Dense"?2:5),J-af,(R!=="Dense"?f:t))}}else{if((R==="Pack"||this.mode==="Auto")&&H!==undefined&&N>z){ag[ag.length]={type:"text",data:[S.length,aa,G+9]}}else{}}}X+=P;break;case"X":X+=P;break}}W.fillStyle="yellow";var ac,E,ah;for(var Y=0;Y<ag.length;Y++){ac=ag[Y];E=ac.type;ah=ac.data;if(E==="text"){W.save();W.font="bold "+W.font;W.fillText(ah[0],ah[1],ah[2]);W.restore()}else{if(E=="triangle"){r(W,ah[0],ah[1],ah[2])}}}},draw_element:function(S,N,F,C,V,A,J,T,Q){var I=F[0],R=F[1],B=F[2],K=F[3],E=Math.floor(Math.max(0,(R-V)*J)),G=Math.ceil(Math.min(Q,Math.max(0,(B-V)*J))),D=(N==="Dense"?0:(0+C))*T,W=this.prefs.block_color,H=this.prefs.label_color,P=0;if((N==="Pack"||this.mode==="Auto")&&J>S.canvas.manager.char_width_px){var P=Math.round(J/2)}S.fillStyle=W;if(F[5] instanceof Array){var O=Math.floor(Math.max(0,(F[4][0]-V)*J)),M=Math.ceil(Math.min(Q,Math.max(0,(F[4][1]-V)*J))),L=Math.floor(Math.max(0,(F[5][0]-V)*J)),z=Math.ceil(Math.min(Q,Math.max(0,(F[5][1]-V)*J)));if(F[4][1]>=V&&F[4][0]<=A&&F[4][2]){this.draw_read(S,N,J,V,A,F[4][0],F[4][2],F[4][3],D)}if(F[5][1]>=V&&F[5][0]<=A&&F[5][2]){this.draw_read(S,N,J,V,A,F[5][0],F[5][2],F[5][3],D)}if(L>M){S.fillStyle=h;q(S,M-P,D+5,L-P,D+5)}}else{S.fillStyle=W;this.draw_read(S,N,J,V,A,R,F[4],F[5],D)}if(N==="Pack"&&R>V){S.fillStyle=this.prefs.label_color;var U=1;if(U===0&&E-S.measureText(K).width<0){S.textAlign="left";S.fillText(K,G+l-P,D+8)}else{S.textAlign="right";S.fillText(K,E-l-P,D+8)}S.fillStyle=W}return[0,0]}});y.Scaler=e;y.SummaryTreePainter=w;y.LinePainter=c;y.LinkedFeaturePainter=s;y.ReadPainter=u;y.VariantPainter=b};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("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 b009d6f136421d196ab735e8cd81224ca537d764 -r d0842bf94ff95b7b34cb46f5dbcc9a25167110c7 static/scripts/trackster.js
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -37,7 +37,6 @@
};
})();
-
/**
* Compute the type of overlap between two regions. They are assumed to be on the same chrom/contig.
* The overlap is computed relative to the second region; hence, OVERLAP_START indicates that the first
@@ -74,6 +73,7 @@
return overlap;
};
+
/**
* Returns true if regions overlap.
*/
@@ -82,6 +82,74 @@
return (overlap !== BEFORE && overlap !== AFTER);
};
+/**
+ * Returns a random color in hexadecimal format that is sufficiently different from a single color
+ * or set of colors.
+ * @param colors a color or list of colors in the format '#RRGGBB'
+ */
+var get_random_color = function(colors) {
+ // Default for colors is white.
+ if (!colors) { colors = "#ffffff" };
+
+ // If needed, create list of colors.
+ if ( typeof(colors) === "string" ) {
+ colors = [ colors ];
+ }
+
+ // Convert colors to numbers.
+ for (var i = 0; i < colors.length; i++) {
+ colors[i] = parseInt( colors[i].slice(1), 16 );
+ }
+
+ // -- Perceived brightness and difference formulas are from
+ // -- http://www.w3.org/WAI/ER/WD-AERT/#color-contrast
+
+ // Compute perceived color brightness (based on RGB-YIQ transformation):
+ var brightness = function(r, g, b) {
+ return ( (r * 299) + (g * 587) + (b * 114) ) / 1000;
+ };
+
+ // Compute color difference:
+ var difference = function(r1, g1, b1, r2, g2, b2) {
+ return ( Math.max(r1, r2) - Math.min(r1, r2) ) +
+ ( Math.max(g1, g2) - Math.min(g1, g2) ) +
+ ( Math.max(b1, b2) - Math.min(b1, b2) );
+ };
+
+ // Create new random color.
+ var new_color, nr, ng, nb,
+ other_color, or, og, ob,
+ n_brightness, o_brightness,
+ diff, ok = false;
+ do {
+ // New color is never white b/c random in [0,1)
+ new_color = Math.random() * 0xffffff;
+ nr = new_color | 0xff0000;
+ ng = new_color | 0x00ff00;
+ nb = new_color | 0x0000ff;
+ n_brightness = brightness(nr, ng, nb);
+ ok = true;
+ for (var i = 0; i < colors.length; i++) {
+ other_color = colors[i];
+ or = other_color | 0xff0000;
+ og = other_color | 0x00ff00;
+ ob = other_color | 0x0000ff;
+ o_brightness = brightness(or, og, ob);
+ diff = difference(nr, ng, nb, or, og, ob);
+ // Thresholds for brightness difference and color difference
+ // are from W3C link above.
+ if ( ( Math.abs(n_brightness - o_brightness) < 125 ) ||
+ ( diff < 500 ) ) {
+ ok = false;
+ break;
+ }
+ }
+ } while (!ok);
+
+ // Add 0x1000000 to left pad number with 0s.
+ return '#' + ( 0x1000000 + new_color ).toString(16).substr(1,6);
+};
+
// Encapsulate -- anything to be availabe outside this block is added to exports
var trackster_module = function(require, exports) {
@@ -2941,7 +3009,7 @@
track: this,
params: [
{ key: 'name', label: 'Name', type: 'text', default_value: name },
- { key: 'color', label: 'Color', type: 'color', default_value: 'black' },
+ { 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 },
@@ -3080,7 +3148,7 @@
track: this,
params: [
{ key: 'name', label: 'Name', type: 'text', default_value: name },
- { key: 'block_color', label: 'Block color', type: 'color', default_value: '#444' },
+ { 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 },
@@ -3470,7 +3538,7 @@
track: this,
params: [
{ key: 'name', label: 'Name', type: 'text', default_value: name },
- { key: 'block_color', label: 'Block color', type: 'color', default_value: '#444' },
+ { 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 },
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
3 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/eafac82b3767/
changeset: eafac82b3767
user: jjohnson
date: 2011-10-24 22:02:07
summary: FASTQ de-interlacer - fix for memory leak
affected #: 1 file
diff -r 0509a6aa2a7876648811b5b445ab7fcbbe982d32 -r eafac82b3767e3687916f35194f0e36b2c51f821 tools/fastq/fastq_paired_end_deinterlacer.py
--- a/tools/fastq/fastq_paired_end_deinterlacer.py
+++ b/tools/fastq/fastq_paired_end_deinterlacer.py
@@ -21,12 +21,14 @@
i = None
skip_count = 0
found = {}
- for i, mate1 in enumerate( fastqReader( open( input_filename, 'rb' ), format = type ) ):
+ for i, read in enumerate( fastqReader( open( input_filename, 'rb' ), format = type ) ):
- if mate1.identifier in found:
- del found[mate1.identifier]
+ if read.identifier in found:
+ del found[read.identifier]
continue
+ mate1 = input.get( read.identifier )
+
mate2 = input.get( joiner.get_paired_identifier( mate1 ) )
if mate2:
https://bitbucket.org/galaxy/galaxy-central/changeset/70d41c4b591e/
changeset: 70d41c4b591e
branch: fastq-deinterlacer-memfix
user: jmchilton
date: 2011-10-24 22:27:17
summary: Creating branch for JJ's fastq-deinterlacer memory hole fix.
affected #: 0 files
https://bitbucket.org/galaxy/galaxy-central/changeset/8d405036b501/
changeset: 8d405036b501
branch: fastq-deinterlacer-memfix
user: jmchilton
date: 2011-10-24 22:36:24
summary: Merging JJ fix with new branch for pull request.
affected #: 1 file
diff -r 70d41c4b591e808a738a61ba49f06d188df3d1f1 -r 8d405036b50167803b53cd8e69db5ea518d7b5b8 tools/fastq/fastq_paired_end_deinterlacer.py
--- a/tools/fastq/fastq_paired_end_deinterlacer.py
+++ b/tools/fastq/fastq_paired_end_deinterlacer.py
@@ -21,12 +21,14 @@
i = None
skip_count = 0
found = {}
- for i, mate1 in enumerate( fastqReader( open( input_filename, 'rb' ), format = type ) ):
+ for i, read in enumerate( fastqReader( open( input_filename, 'rb' ), format = type ) ):
- if mate1.identifier in found:
- del found[mate1.identifier]
+ if read.identifier in found:
+ del found[read.identifier]
continue
+ mate1 = input.get( read.identifier )
+
mate2 = input.get( joiner.get_paired_identifier( mate1 ) )
if mate2:
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/ba176739183d/
changeset: ba176739183d
user: dan
date: 2011-10-24 22:32:13
summary: Update for Sam to Fastq.
affected #: 1 file
diff -r 0509a6aa2a7876648811b5b445ab7fcbbe982d32 -r ba176739183db096516eeb274b1120a38d9b6e5c tools/picard/picard_SamToFastq.xml
--- a/tools/picard/picard_SamToFastq.xml
+++ b/tools/picard/picard_SamToFastq.xml
@@ -19,17 +19,17 @@
#end if
INCLUDE_NON_PRIMARY_ALIGNMENTS=${include_non_primary_alignments}
- #if str( $output_per_read_group.output_per_read_group_selector ) == 'per_sam_file':
+ #if str( $output_per_read_group_selector ) == 'per_sam_file':
##OUTPUT_PER_RG=false
FASTQ="${output_fastq1}"
- #if str( $output_per_read_group.single_paired_end_type.single_paired_end_type_selector ) == 'paired':
+ #if str( $single_paired_end_type.single_paired_end_type_selector ) == 'paired':
SECOND_END_FASTQ="${output_fastq2}"
- #if str( $output_per_read_group.single_paired_end_type.read2_trim ):
- READ2_TRIM="${output_per_read_group.single_paired_end_type.read2_trim}"
+ #if str( $single_paired_end_type.read2_trim ):
+ READ2_TRIM="${single_paired_end_type.read2_trim}"
#end if
- #if str( $output_per_read_group.single_paired_end_type.read2_max_bases_to_write ):
- READ2_MAX_BASES_TO_WRITE="${output_per_read_group.single_paired_end_type.read2_max_bases_to_write}"
+ #if str( $single_paired_end_type.read2_max_bases_to_write ):
+ READ2_MAX_BASES_TO_WRITE="${single_paired_end_type.read2_max_bases_to_write}"
#end if
#end if
#else:
@@ -45,29 +45,22 @@
<param name="input_sam" type="data" format="sam" label="SAM file" /><param name="read1_trim" type="integer" value="" optional="True" label="The number of bases to trim from the beginning of read 1." /><param name="read1_max_bases_to_write" type="integer" optional="True" value="" label="The maximum number of bases to write from read 1 after trimming." />
- <conditional name="output_per_read_group">
- <param name="output_per_read_group_selector" type="select" label="Output per read group">
- <option value="per_sam_file" selected="True">Per SAM file</option>
- <option value="per_read_group">Per Read Group</option>
- <validator type="expression" message="Per Read Group selection is not yet implemented">value == 'per_sam_file'</validator>
+ <param name="output_per_read_group_selector" type="select" label="Output per read group">
+ <option value="per_sam_file" selected="True">Per SAM file</option>
+ <!-- <option value="per_read_group">Per Read Group</option> -->
+ <validator type="expression" message="Per Read Group selection is not yet implemented">value == 'per_sam_file'</validator>
+ </param>
+ <conditional name="single_paired_end_type">
+ <param name="single_paired_end_type_selector" type="select" label="Single or Paired end">
+ <option value="single" selected="True">Single</option>
+ <option value="paired">Paired end</option></param>
- <when value="per_sam_file">
- <conditional name="single_paired_end_type">
- <param name="single_paired_end_type_selector" type="select" label="Single or Paired end">
- <option value="single" selected="True">Single</option>
- <option value="paired">Paired end</option>
- </param>
- <when value="single">
- <!-- nothing yet -->
- </when>
- <when value="paired">
- <param name="read2_trim" type="integer" value="" optional="True" label="The number of bases to trim from the beginning of read 2." />
- <param name="read2_max_bases_to_write" type="integer" optional="True" value="" label="The maximum number of bases to write from read 2 after trimming." />
- </when>
- </conditional>
+ <when value="single">
+ <!-- nothing yet --></when>
- <when value="per_read_group">
- <!-- Fix me -->
+ <when value="paired">
+ <param name="read2_trim" type="integer" value="" optional="True" label="The number of bases to trim from the beginning of read 2." />
+ <param name="read2_max_bases_to_write" type="integer" optional="True" value="" label="The maximum number of bases to write from read 2 after trimming." /></when></conditional><param name="re_reverse" type="boolean" truevalue="true" falsevalue="false" checked="True" label="Re-reverse bases and qualities of reads on negative strand"/>
@@ -80,7 +73,7 @@
<outputs><data format="fastqsanger" name="output_fastq1" label="${tool.name} on ${on_string}: FASTQ 1" /><data format="fastqsanger" name="output_fastq2" label="${tool.name} on ${on_string}: FASTQ 2" >
- <filter>output_per_read_group['single_paired_end_type']['single_paired_end_type_selector'] == 'paired'</filter>
+ <filter>single_paired_end_type['single_paired_end_type_selector'] == 'paired'</filter></data></outputs><tests>
@@ -141,20 +134,22 @@
**FastqToSam settings**
This is list of SamToFastq options::
+
+ INPUT=File Input SAM/BAM file to extract reads from Required.
+ FASTQ=File Output fastq file (single-end fastq or, if paired, first end of the pair fastq). Required. Cannot be used in conjuction with option(s) OUTPUT_PER_RG (OPRG)
+ SECOND_END_FASTQ=File Output fastq file (if paired, second end of the pair fastq). Default value: null. Cannot be used in conjuction with option(s) OUTPUT_PER_RG (OPRG)
+ OUTPUT_PER_RG=Boolean Output a fastq file per read group (two fastq files per read group if the group is paired). Default value: false. This option can be set to 'null' to clear the default value. Possible values: {true, false} Cannot be used in conjuction with option(s) SECOND_END_FASTQ (F2) FASTQ (F)
+ OUTPUT_DIR=File Directory in which to output the fastq file(s). Used only when OUTPUT_PER_RG is true. Default value: null.
+ RE_REVERSE=Boolean Re-reverse bases and qualities of reads with negative strand flag set before writing them to fastq Default value: true. This option can be set to 'null' to clear the default value. Possible values: {true, false}
+ INCLUDE_NON_PF_READS=Boolean Include non-PF reads from the SAM file into the output FASTQ files. Default value: false. This option can be set to 'null' to clear the default value. Possible values: {true, false}
+ CLIPPING_ATTRIBUTE=String The attribute that stores the position at which the SAM record should be clipped Default value: null.
+ CLIPPING_ACTION=String The action that should be taken with clipped reads: 'X' means the reads and qualities should be trimmed at the clipped position; 'N' means the bases should be changed to Ns in the clipped region; and any integer means that the base qualities should be set to that value in the clipped region. Default value: null.
+ READ1_TRIM=Integer The number of bases to trim from the beginning of read 1. Default value: 0. This option can be set to 'null' to clear the default value.
+ READ1_MAX_BASES_TO_WRITE=Integer The maximum number of bases to write from read 1 after trimming. If there are fewer than this many bases left after trimming, all will be written. If this value is null then all bases left after trimming will be written. Default value: null.
+ READ2_TRIM=Integer The number of bases to trim from the beginning of read 2. Default value: 0. This option can be set to 'null' to clear the default value.
+ READ2_MAX_BASES_TO_WRITE=Integer The maximum number of bases to write from read 2 after trimming. If there are fewer than this many bases left after trimming, all will be written. If this value is null then all bases left after trimming will be written. Default value: null.
+ INCLUDE_NON_PRIMARY_ALIGNMENTS=Boolean If true, include non-primary alignments in the output. Support of non-primary alignments in SamToFastq is not comprehensive, so there may be exceptions if this is set to true and there are paired reads with non-primary alignments. Default value: false. This option can be set to 'null' to clear the default value. Possible values: {true, false}
-NPUT=File Input SAM/BAM file to extract reads from Required.
-FASTQ=File Output fastq file (single-end fastq or, if paired, first end of the pair fastq). Required. Cannot be used in conjuction with option(s) OUTPUT_PER_RG (OPRG)
-SECOND_END_FASTQ=File Output fastq file (if paired, second end of the pair fastq). Default value: null. Cannot be used in conjuction with option(s) OUTPUT_PER_RG (OPRG)
-OUTPUT_PER_RG=Boolean Output a fastq file per read group (two fastq files per read group if the group is paired). Default value: false. This option can be set to 'null' to clear the default value. Possible values: {true, false} Cannot be used in conjuction with option(s) SECOND_END_FASTQ (F2) FASTQ (F)
-OUTPUT_DIR=File Directory in which to output the fastq file(s). Used only when OUTPUT_PER_RG is true. Default value: null.
-RE_REVERSE=Boolean Re-reverse bases and qualities of reads with negative strand flag set before writing them to fastq Default value: true. This option can be set to 'null' to clear the default value. Possible values: {true, false}
-INCLUDE_NON_PF_READS=Boolean Include non-PF reads from the SAM file into the output FASTQ files. Default value: false. This option can be set to 'null' to clear the default value. Possible values: {true, false}
-CLIPPING_ATTRIBUTE=String The attribute that stores the position at which the SAM record should be clipped Default value: null.
-CLIPPING_ACTION=String The action that should be taken with clipped reads: 'X' means the reads and qualities should be trimmed at the clipped position; 'N' means the bases should be changed to Ns in the clipped region; and any integer means that the base qualities should be set to that value in the clipped region. Default value: null.
-READ1_TRIM=Integer The number of bases to trim from the beginning of read 1. Default value: 0. This option can be set to 'null' to clear the default value.
-READ1_MAX_BASES_TO_WRITE=Integer The maximum number of bases to write from read 1 after trimming. If there are fewer than this many bases left after trimming, all will be written. If this value is null then all bases left after trimming will be written. Default value: null.
-READ2_TRIM=Integer The number of bases to trim from the beginning of read 2. Default value: 0. This option can be set to 'null' to clear the default value.
-READ2_MAX_BASES_TO_WRITE=Integer The maximum number of bases to write from read 2 after trimming. If there are fewer than this many bases left after trimming, all will be written. If this value is null then all bases left after trimming will be written. Default value: null.
-INCLUDE_NON_PRIMARY_ALIGNMENTS=Boolean If true, include non-primary alignments in the output. Support of non-primary alignments in SamToFastq is not comprehensive, so there may be exceptions if this is set to true and there are paired reads with non-primary alignments. Default value: false. This option can be set to 'null' to clear the default value. Possible values: {true, false}
+
</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

commit/galaxy-central: dan: Add Picard tools FASTQ to SAM (makes BAM) tool. Add Picard tools SAM to FASTQ tool.
by Bitbucket 24 Oct '11
by Bitbucket 24 Oct '11
24 Oct '11
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/0509a6aa2a78/
changeset: 0509a6aa2a78
user: dan
date: 2011-10-24 22:11:20
summary: Add Picard tools FASTQ to SAM (makes BAM) tool. Add Picard tools SAM to FASTQ tool.
affected #: 5 files
diff -r 32af86dbaf9a962eaea12a04df817c6f282331df -r 0509a6aa2a7876648811b5b445ab7fcbbe982d32 test-data/picard_fastq_to_sam_out1.bam
Binary file test-data/picard_fastq_to_sam_out1.bam has changed
diff -r 32af86dbaf9a962eaea12a04df817c6f282331df -r 0509a6aa2a7876648811b5b445ab7fcbbe982d32 test-data/picard_fastq_to_sam_out2.bam
Binary file test-data/picard_fastq_to_sam_out2.bam has changed
diff -r 32af86dbaf9a962eaea12a04df817c6f282331df -r 0509a6aa2a7876648811b5b445ab7fcbbe982d32 tool_conf.xml.sample
--- a/tool_conf.xml.sample
+++ b/tool_conf.xml.sample
@@ -295,6 +295,9 @@
<tool file="fastx_toolkit/fastx_trimmer.xml" /></section><section name="NGS: Picard (beta)" id="picard_beta">
+ <label text="Conversion" id="picard_conversion"/>
+ <tool file="picard/picard_FastqToSam.xml" />
+ <tool file="picard/picard_SamToFastq.xml" /><label text="QC/Metrics for sam/bam" id="qcsambam"/><tool file="picard/picard_BamIndexStats.xml" />
@@ -390,7 +393,6 @@
<label text="Filtration" id="gatk_filtration" /><tool file="gatk/variant_filtration.xml" />
- <tool file="gatk/variant_filtration.xml" /><label text="Variant Quality Score Recalibration" id="gatk_variant_quality_score_recalibration" /><tool file="gatk/variant_recalibrator.xml" />
diff -r 32af86dbaf9a962eaea12a04df817c6f282331df -r 0509a6aa2a7876648811b5b445ab7fcbbe982d32 tools/picard/picard_FastqToSam.xml
--- /dev/null
+++ b/tools/picard/picard_FastqToSam.xml
@@ -0,0 +1,143 @@
+<tool id="picard_FastqToSam" name="FASTQ to BAM" version="0.0.1">
+ <description>creates an unaligned BAM file</description>
+ <command>java -XX:DefaultMaxRAMFraction=1 -XX:+UseParallelGC
+ -jar "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/FastqToSam.jar"
+ FASTQ="${input_fastq1}"
+ #if str( $input_fastq2) != "None":
+ FASTQ2="${input_fastq2}"
+ #end if
+ QUALITY_FORMAT="${ dict( fastqsanger='Standard', fastqcssanger='Standard', fastqillumina='Illumina', fastqsolexa='Solexa' )[ $input_fastq1.ext ] }" ##Solexa, Illumina, Standard
+ OUTPUT="${output_bam}"
+ READ_GROUP_NAME="${read_group_name}"
+ SAMPLE_NAME="${sample_name}"
+ #if $param_type.param_type_selector == "advanced":
+ #if str( $param_type.library_name ) != "":
+ LIBRARY_NAME="${param_type.library_name}"
+ #end if
+ #if str( $param_type.platform_unit ) != "":
+ PLATFORM_UNIT="${param_type.platform_unit}"
+ #end if
+ #if str( $param_type.platform ) != "":
+ PLATFORM="${param_type.platform}"
+ #end if
+ #if str( $param_type.sequencing_center ) != "":
+ SEQUENCING_CENTER="${param_type.sequencing_center}"
+ #end if
+ #if str( $param_type.predicted_insert_size ) != "":
+ PREDICTED_INSERT_SIZE="${param_type.predicted_insert_size}"
+ #end if
+ #if str( $param_type.description.value ) != "":
+ DESCRIPTION="${param_type.description}"
+ #end if
+ #if str( $param_type.run_date ) != "":
+ RUN_DATE="${param_type.run_date}"
+ #end if
+ #if str( $param_type.min_q ) != "":
+ MIN_Q="${param_type.min_q}"
+ #end if
+ #if str( $param_type.min_q ) != "":
+ MAX_Q="${param_type.max_q}"
+ #end if
+ SORT_ORDER="${param_type.sort_order}"
+ #else:
+ SORT_ORDER=coordinate ##unsorted, queryname, coordinate; always use coordinate
+ #end if
+ 2>&1
+ || echo "Error running Picard FastqToSAM" >&2
+ </command>
+ <inputs>
+ <param name="input_fastq1" type="data" format="fastqsanger,fastqillumina,fastqsolexa,fastqcssanger" label="FASTQ file" /><!-- confirm that fastqcssanger also works -->
+ <param name="input_fastq2" type="data" format="fastqsanger,fastqillumina,fastqsolexa,fastqcssanger" optional="True" label="Second FASTQ of paired end data" help="Only needed when using paired end data." >
+ <options options_filter_attribute="ext" from_parameter="tool.app.datatypes_registry.datatypes_by_extension" transform_lines="obj.keys()">
+ <column name="name" index="0"/>
+ <column name="value" index="0"/>
+ <filter type="param_value" ref="input_fastq1" ref_attribute="ext" column="0"/>
+ </options>
+ </param>
+ <param name="read_group_name" type="text" value="A" label="Read Group Name" />
+ <param name="sample_name" type="text" value="unknown sample" label="Sample Name" />
+ <conditional name="param_type">
+ <param name="param_type_selector" type="select" label="Basic or Advanced options">
+ <option value="basic" selected="True">Basic</option>
+ <option value="advanced">Advanced</option>
+ </param>
+ <when value="basic">
+ <!-- Do nothing here -->
+ </when>
+ <when value="advanced">
+ <param name="library_name" type="text" value="" label="Library Name" />
+ <param name="platform_unit" type="text" value="" label="Platform Unit" />
+ <param name="platform" type="text" value="" label="Platform" />
+ <param name="sequencing_center" type="text" value="" label="Sequencing Center" />
+ <param name="predicted_insert_size" type="integer" value="" optional="True" label="Predicted Insert Size" />
+ <param name="description" type="text" value="" label="Description" />
+ <param name="run_date" type="text" value="" label="Run Date" />
+ <param name="min_q" type="integer" optional="True" value="0" label="Min Q" />
+ <param name="max_q" type="integer" optional="True" value="93" label="Max Q" />
+ <param name="sort_order" type="select" label="Sort order">
+ <option value="coordinate" selected="True">coordinate</option>
+ <option value="queryname">queryname</option>
+ <option value="unsorted">unsorted</option>
+ </param>
+ </when>
+ </conditional>
+ </inputs>
+ <outputs>
+ <data format="bam" name="output_bam" />
+ </outputs>
+ <tests>
+ <test>
+ <param name="input_fastq1" value="bwa_wrapper_in2.fastqsanger" ftype="fastqsanger" />
+ <param name="input_fastq2" />
+ <param name="read_group_name" value="A" />
+ <param name="sample_name" value="unknown sample" />
+ <param name="param_type_selector" value="basic" />
+ <output name="output_bam" file="picard_fastq_to_sam_out1.bam" ftype="bam"/>
+ </test>
+ <test>
+ <param name="input_fastq1" value="bwa_wrapper_in2.fastqsanger" ftype="fastqsanger" />
+ <param name="input_fastq2" value="bwa_wrapper_in3.fastqsanger" ftype="fastqsanger" />
+ <param name="read_group_name" value="A" />
+ <param name="sample_name" value="unknown sample" />
+ <param name="param_type_selector" value="basic" />
+ <output name="output_bam" file="picard_fastq_to_sam_out2.bam" ftype="bam"/>
+ </test>
+ </tests>
+ <help>
+**What it does**
+
+Picard: FastqToSam converts FASTQ files to unaligned BAM files.
+
+------
+
+Please cite the website "http://picard.sourceforge.net".
+
+------
+
+
+**Input formats**
+
+FastqToSam accepts FASTQ input files. If using paired-end data, you should select two FASTQ files.
+
+------
+
+**Outputs**
+
+The output is in BAM format, see http://samtools.sourceforge.net for more details.
+
+-------
+
+**FastqToSam settings**
+
+This is list of FastqToSam options::
+
+ READ_GROUP_NAME=String Read group name Default value: A. This option can be set to 'null' to clear the default value.
+ SAMPLE_NAME=String Sample name to insert into the read group header Required.
+ LIBRARY_NAME=String The library name to place into the LB attribute in the read group header Default value: null.
+ PLATFORM_UNIT=String The platform unit (often run_barcode.lane) to insert into the read group header Default value: null.
+ PLATFORM=String The platform type (e.g. illumina, solid) to insert into the read group header Default value: null.
+ SEQUENCING_CENTER=String The sequencing center from which the data originated Default value: null.
+ PREDICTED_INSERT_SIZE=Integer Predicted median insert size, to insert into the read group header Default value: null.
+ DESCRIPTION=String Inserted into the read group header Default value: null.
+ </help>
+</tool>
diff -r 32af86dbaf9a962eaea12a04df817c6f282331df -r 0509a6aa2a7876648811b5b445ab7fcbbe982d32 tools/picard/picard_SamToFastq.xml
--- /dev/null
+++ b/tools/picard/picard_SamToFastq.xml
@@ -0,0 +1,160 @@
+<tool id="picard_SamToFastq" name="SAM to FASTQ" version="0.0.1">
+ <description>creates a FASTQ file</description>
+ <command>java -XX:DefaultMaxRAMFraction=1 -XX:+UseParallelGC
+ -jar "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/SamToFastq.jar"
+ INPUT="${input_sam}"
+ RE_REVERSE=${re_reverse}
+ INCLUDE_NON_PF_READS=${include_non_pf_reads}
+ #if str( $clipping_attribute ):
+ CLIPPING_ATTRIBUTE="${clipping_attribute}"
+ #end if
+ #if str( $clipping_action ):
+ CLIPPING_ACTION="${clipping_action}"
+ #end if
+ #if str( $read1_trim ):
+ READ1_TRIM="${read1_trim}"
+ #end if
+ #if str( $read1_max_bases_to_write ):
+ READ1_MAX_BASES_TO_WRITE="${read1_max_bases_to_write}"
+ #end if
+ INCLUDE_NON_PRIMARY_ALIGNMENTS=${include_non_primary_alignments}
+
+ #if str( $output_per_read_group.output_per_read_group_selector ) == 'per_sam_file':
+ ##OUTPUT_PER_RG=false
+ FASTQ="${output_fastq1}"
+
+ #if str( $output_per_read_group.single_paired_end_type.single_paired_end_type_selector ) == 'paired':
+ SECOND_END_FASTQ="${output_fastq2}"
+ #if str( $output_per_read_group.single_paired_end_type.read2_trim ):
+ READ2_TRIM="${output_per_read_group.single_paired_end_type.read2_trim}"
+ #end if
+ #if str( $output_per_read_group.single_paired_end_type.read2_max_bases_to_write ):
+ READ2_MAX_BASES_TO_WRITE="${output_per_read_group.single_paired_end_type.read2_max_bases_to_write}"
+ #end if
+ #end if
+ #else:
+ #raise Exception( 'Per Read Group not yet supported.' )
+ OUTPUT_PER_RG=true
+ OUTPUT_DIR="./picard_sam_to_fastq_tmp_dir/"
+ #end if
+ 2>&1
+ || echo "Error running SamToFastq" >&2
+ ##&& echo "die die die" >&2
+ </command>
+ <inputs>
+ <param name="input_sam" type="data" format="sam" label="SAM file" />
+ <param name="read1_trim" type="integer" value="" optional="True" label="The number of bases to trim from the beginning of read 1." />
+ <param name="read1_max_bases_to_write" type="integer" optional="True" value="" label="The maximum number of bases to write from read 1 after trimming." />
+ <conditional name="output_per_read_group">
+ <param name="output_per_read_group_selector" type="select" label="Output per read group">
+ <option value="per_sam_file" selected="True">Per SAM file</option>
+ <option value="per_read_group">Per Read Group</option>
+ <validator type="expression" message="Per Read Group selection is not yet implemented">value == 'per_sam_file'</validator>
+ </param>
+ <when value="per_sam_file">
+ <conditional name="single_paired_end_type">
+ <param name="single_paired_end_type_selector" type="select" label="Single or Paired end">
+ <option value="single" selected="True">Single</option>
+ <option value="paired">Paired end</option>
+ </param>
+ <when value="single">
+ <!-- nothing yet -->
+ </when>
+ <when value="paired">
+ <param name="read2_trim" type="integer" value="" optional="True" label="The number of bases to trim from the beginning of read 2." />
+ <param name="read2_max_bases_to_write" type="integer" optional="True" value="" label="The maximum number of bases to write from read 2 after trimming." />
+ </when>
+ </conditional>
+ </when>
+ <when value="per_read_group">
+ <!-- Fix me -->
+ </when>
+ </conditional>
+ <param name="re_reverse" type="boolean" truevalue="true" falsevalue="false" checked="True" label="Re-reverse bases and qualities of reads on negative strand"/>
+ <param name="include_non_pf_reads" type="boolean" truevalue="true" falsevalue="false" checked="False" label="Include non-PF reads from the SAM file into the output FASTQ files."/>
+ <param name="clipping_attribute" type="text" value="" label="The attribute that stores the position at which the SAM record should be clipped" help="Leave blank for null" />
+ <param name="clipping_action" type="text" value="" label="The action that should be taken with clipped reads" help="'X' means the reads and qualities should be trimmed at the clipped position; 'N' means the bases should be changed to Ns in the clipped region; and any integer means that the base qualities should be set to that value in the clipped region. Leave blank for null" />
+ <param name="include_non_primary_alignments" type="boolean" truevalue="true" falsevalue="false" checked="False" label="If true, include non-primary alignments in the output." help="Support of non-primary alignments in SamToFastq is not comprehensive, so there may be exceptions if this is set to true and there are paired reads with non-primary alignments."/>
+
+ </inputs>
+ <outputs>
+ <data format="fastqsanger" name="output_fastq1" label="${tool.name} on ${on_string}: FASTQ 1" />
+ <data format="fastqsanger" name="output_fastq2" label="${tool.name} on ${on_string}: FASTQ 2" >
+ <filter>output_per_read_group['single_paired_end_type']['single_paired_end_type_selector'] == 'paired'</filter>
+ </data>
+ </outputs>
+ <tests>
+ <test>
+ <param name="input_sam" value="bfast_out1.sam" ftype="sam" />
+ <param name="output_per_read_group_selector" value="per_sam_file" />
+ <param name="single_paired_end_type_selector" value="single" />
+ <param name="read1_trim" value="" />
+ <param name="read1_max_bases_to_write" value="" />
+ <param name="re_reverse" value="True" />
+ <param name="include_non_pf_reads" value="False" />
+ <param name="clipping_attribute" value="" />
+ <param name="include_non_primary_alignments" value="False" />
+ <output name="output_fastq1" file="random_phiX_1.fastqsanger"/>
+ </test>
+ <test>
+ <param name="input_sam" value="bwa_wrapper_out3.sam" ftype="sam" />
+ <param name="output_per_read_group_selector" value="per_sam_file" />
+ <param name="single_paired_end_type_selector" value="paired" />
+ <param name="read1_trim" value="" />
+ <param name="read1_max_bases_to_write" value="" />
+ <param name="read2_trim" value="" />
+ <param name="read2_max_bases_to_write" value="" />
+ <param name="re_reverse" value="True" />
+ <param name="include_non_pf_reads" value="False" />
+ <param name="clipping_attribute" value="" />
+ <param name="include_non_primary_alignments" value="False" />
+ <output name="output_fastq1" file="bwa_wrapper_in2.fastqsanger" lines_diff="64"/><!-- 16 unaligned fastq blocks not present in original sam file -->
+ <output name="output_fastq2" file="bwa_wrapper_in3.fastqsanger" lines_diff="64"/><!-- 16 unaligned fastq blocks not present in original sam file -->
+ </test>
+ </tests>
+ <help>
+**What it does**
+
+Picard: SamToFastq converts SAM files to FASTQ files.
+
+Extracts read sequences and qualities from the input SAM/BAM file and writes them into the output file in Sanger fastq format. In the RC mode (default is True), if the read is aligned and the alignment is to the reverse strand on the genome, the read's sequence from input SAM file will be reverse-complemented prior to writing it to fastq in order restore correctly the original read sequence as it was generated by the sequencer.
+
+------
+
+Please cite the website "http://picard.sourceforge.net".
+
+------
+
+
+**Input formats**
+
+FastqToSam accepts SAM input files, see http://samtools.sourceforge.net for more details.
+
+------
+
+**Outputs**
+
+The output is in FASTQ format. If using Paired end data, 2 fastq files are created.
+
+-------
+
+**FastqToSam settings**
+
+This is list of SamToFastq options::
+
+NPUT=File Input SAM/BAM file to extract reads from Required.
+FASTQ=File Output fastq file (single-end fastq or, if paired, first end of the pair fastq). Required. Cannot be used in conjuction with option(s) OUTPUT_PER_RG (OPRG)
+SECOND_END_FASTQ=File Output fastq file (if paired, second end of the pair fastq). Default value: null. Cannot be used in conjuction with option(s) OUTPUT_PER_RG (OPRG)
+OUTPUT_PER_RG=Boolean Output a fastq file per read group (two fastq files per read group if the group is paired). Default value: false. This option can be set to 'null' to clear the default value. Possible values: {true, false} Cannot be used in conjuction with option(s) SECOND_END_FASTQ (F2) FASTQ (F)
+OUTPUT_DIR=File Directory in which to output the fastq file(s). Used only when OUTPUT_PER_RG is true. Default value: null.
+RE_REVERSE=Boolean Re-reverse bases and qualities of reads with negative strand flag set before writing them to fastq Default value: true. This option can be set to 'null' to clear the default value. Possible values: {true, false}
+INCLUDE_NON_PF_READS=Boolean Include non-PF reads from the SAM file into the output FASTQ files. Default value: false. This option can be set to 'null' to clear the default value. Possible values: {true, false}
+CLIPPING_ATTRIBUTE=String The attribute that stores the position at which the SAM record should be clipped Default value: null.
+CLIPPING_ACTION=String The action that should be taken with clipped reads: 'X' means the reads and qualities should be trimmed at the clipped position; 'N' means the bases should be changed to Ns in the clipped region; and any integer means that the base qualities should be set to that value in the clipped region. Default value: null.
+READ1_TRIM=Integer The number of bases to trim from the beginning of read 1. Default value: 0. This option can be set to 'null' to clear the default value.
+READ1_MAX_BASES_TO_WRITE=Integer The maximum number of bases to write from read 1 after trimming. If there are fewer than this many bases left after trimming, all will be written. If this value is null then all bases left after trimming will be written. Default value: null.
+READ2_TRIM=Integer The number of bases to trim from the beginning of read 2. Default value: 0. This option can be set to 'null' to clear the default value.
+READ2_MAX_BASES_TO_WRITE=Integer The maximum number of bases to write from read 2 after trimming. If there are fewer than this many bases left after trimming, all will be written. If this value is null then all bases left after trimming will be written. Default value: null.
+INCLUDE_NON_PRIMARY_ALIGNMENTS=Boolean If true, include non-primary alignments in the output. Support of non-primary alignments in SamToFastq is not comprehensive, so there may be exceptions if this is set to true and there are paired reads with non-primary alignments. Default value: false. This option can be set to 'null' to clear the default value. Possible values: {true, false}
+ </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